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 | */ |
23 | char |
24 | db_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 | |