1/*
2 * This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 *
6 * Copyright 1997 - July 2008 CWI, August 2008 - 2019 MonetDB B.V.
7 */
8
9/**
10 * glob
11 * Fabian Groffen
12 * Limited globbing within merovingian's tags.
13 * The rules are kept simple for the time being:
14 * - * expands to an arbitrary string
15 */
16
17#include "monetdb_config.h"
18#include "glob.h"
19
20/**
21 * Returns if haystack matches expr, using tag globbing.
22 */
23char
24db_glob(const char *expr, const char *haystack)
25{
26 const char *haymem = NULL;
27 const char *exprmem = NULL;
28 char escape = 0;
29
30 /* probably need to implement this using libpcre once we get
31 * advanced users, doing even more advanced things */
32
33 while (*expr != '\0') {
34 if (*expr == '\\') {
35 escape = !escape;
36 if (escape) {
37 expr++;
38 continue; /* skip over escape */
39 }
40 }
41 switch (*expr) {
42 case '*':
43 if (!escape) {
44 /* store expression position for retry lateron */
45 exprmem = expr;
46 /* skip over haystack till the next char from expr */
47 do {
48 expr++;
49 if (*expr == '\0') {
50 /* this will always match the rest */
51 return(1);
52 } else if (!escape && *expr == '*') {
53 continue;
54 } else if (*expr == '\\') {
55 escape = !escape;
56 if (!escape)
57 break;
58 } else {
59 break;
60 }
61 } while(1);
62 while (*haystack != '\0' && *haystack != *expr)
63 haystack++;
64 /* store match position, for retry lateron */
65 haymem = haystack + 1;
66 if (*haystack == '\0')
67 /* couldn't find it, so no match */
68 return(0);
69 break;
70 }
71 /* do asterisk match if escaped */
72 /* fall through */
73 default:
74 if (*expr != *haystack) {
75 if (haymem != NULL) {
76 return(db_glob(exprmem, haymem));
77 } else {
78 return(0);
79 }
80 }
81 break;
82 }
83 expr++;
84 haystack++;
85 escape = 0;
86 }
87 return(*haystack == '\0');
88}
89