LMMS
Loading...
Searching...
No Matches
has_strings.h
Go to the documentation of this file.
1#ifndef _WDL_HASSTRINGS_H_
2#define _WDL_HASSTRINGS_H_
3
4#ifndef WDL_HASSTRINGS_EXPORT
5#define WDL_HASSTRINGS_EXPORT
6#endif
7
9{
10 // treat as whitespace when searching for " foo "
11 switch (c)
12 {
13 case 0:
14 case 1:
15 case ' ':
16 case '\t':
17 case '.':
18 case '/':
19 case '\\':
20 return true;
21
22 default:
23 return false;
24 }
25}
26
28 int (*cmp_func)(const char *a, int apos, const char *b, int blen) // if set, returns length of matched string (0 if no match)
29 )
30{
31 if (!lp) return true;
32 const int ntok = lp->getnumtokens();
33 if (ntok<1) return true;
34
35 char stack[1024]; // &1=not bit, 0x10 = ignoring subscopes, &2= state when 0x10 set
36 int stacktop = 0;
37 stack[0]=0;
38
39 const int strlen_name = (int)strlen(name);
40 char matched_local=-1; // -1 = first eval for scope, 0=did not pass scope, 1=OK, 2=ignore rest of scope
41 for (int x = 0; x < ntok; x ++)
42 {
43 const char *n=lp->gettoken_str(x);
44
45 if (n[0] == '(' && !n[1] && !lp->gettoken_quotingchar(x))
46 {
47 if (!(matched_local&1))
48 {
49 stack[stacktop] |= matched_local | 0x10;
50 matched_local=2; // ignore subscope
51 }
52 else
53 {
54 matched_local = -1; // new scope
55 }
56
57 if (stacktop < (int)sizeof(stack) - 1) stack[++stacktop] = 0;
58 }
59 else if (stacktop && n[0] == ')' && !n[1] && !lp->gettoken_quotingchar(x))
60 {
61 if (stack[--stacktop]&0x10)
62 {
63 // restore state
64 matched_local = stack[stacktop]&2;
65 }
66 else
67 {
68 matched_local = (matched_local != 0 ? 1 : 0) ^ (stack[stacktop]&1);
69 }
70 stack[stacktop] = 0;
71 }
72 else if (matched_local != 2 && !strcmp(n,"OR"))
73 {
74 matched_local = (matched_local > 0) ? 2 : -1;
75 stack[stacktop] = 0;
76 }
77 else if (matched_local&1) // matches 1, -1
78 {
79 int ln;
80 if (!strcmp(n,"NOT"))
81 {
82 stack[stacktop]^=1;
83 }
84 else if (!strcmp(n,"AND") && !lp->gettoken_quotingchar(x))
85 {
86 // ignore unquoted uppercase AND
87 }
88 else if ((ln=(int)strlen(n))>0)
89 {
90 int lt=strlen_name;
91 const char *t=name;
92 // ^foo -- string starts (or follows \1 separator with) foo
93 // foo$ -- string ends with foo (or is immediately followed by \1 separator)
94 // " foo ", "foo ", " foo" include end of string/start of string has whitespace
95 int wc_left = 0; // 1=require \1 or start of string, 2=require space or \1 or start
96 int wc_right = 0; // 1=require \1 or \0, 2 = require space or \1 or \0
97 // perhaps wc_left/wc_right of 2 should also match non-alnum characters in addition to space?
98 if (ln>1)
99 {
100 switch (*n)
101 {
102 case ' ':
103 if (*++n != ' ') wc_left=2;
104 // else { multiple characters of whitespace = literal whitespace search (two spaces requires a single space, etc) }
105
106 ln--;
107 break;
108 case '^':
109 ln--;
110 n++;
111 wc_left=1;
112 break;
113 }
114 }
115 if (ln>1)
116 {
117 switch (n[ln-1])
118 {
119 case ' ':
120 if (n[--ln - 1] != ' ') wc_right=2;
121 // else { multiple characters of whitespace = literal whitespace search (two spaces requires a single space, etc) }
122 break;
123 case '$':
124 ln--;
125 wc_right++;
126 break;
127 }
128 }
129
130 bool use_cmp_func = cmp_func != NULL && !(stack[stacktop]&1);
131
132 if (!wc_left && !wc_right && *n)
133 {
134 switch (lp->gettoken_quotingchar(x))
135 {
136 case '\'':
137 case '"':
138 { // if a quoted string has no whitespace in it, treat as whole word search
139 const char *p = n;
140 while (*p && *p != ' ' && *p != '\t') p++;
141 if (!*p)
142 {
143 wc_left=wc_right=2;
144 use_cmp_func = false;
145 }
146 }
147 break;
148 }
149
150 }
151
152 const int min_len = use_cmp_func ? 1 : ln;
153 if (wc_left>0)
154 {
155 unsigned char lastchar = 1;
156 while (lt>=min_len)
157 {
158 int lln;
159 if ((lastchar < 2 || (wc_left>1 && hasStrings_isNonWordChar(lastchar))) && (lln = use_cmp_func ? cmp_func(t,t-name,n,ln) : strnicmp(t,n,ln) ? 0 : ln))
160 {
161 if (wc_right == 0) break;
162 const unsigned char nc=((const unsigned char*)t)[lln];
163 if (nc < 2 || (wc_right > 1 && hasStrings_isNonWordChar(nc))) break;
164 }
165 lastchar = *(unsigned char*)t++;
166 lt--;
167 }
168 }
169 else
170 {
171 while (lt>=min_len)
172 {
173 const int lln = use_cmp_func ? cmp_func(t,t-name,n,ln) : strnicmp(t,n,ln) ? 0 : ln;
174 if (lln)
175 {
176 if (wc_right == 0) break;
177 const unsigned char nc=((const unsigned char*)t)[lln];
178 if (nc < 2 || (wc_right > 1 && hasStrings_isNonWordChar(nc))) break;
179 }
180 t++;
181 lt--;
182 }
183 }
184
185 matched_local = ((lt-min_len)>=0) ^ (stack[stacktop]&1);
186 stack[stacktop]=0;
187 }
188 }
189 }
190 while (stacktop > 0)
191 {
192 if (stack[--stacktop] & 0x10) matched_local=stack[stacktop]&2;
193 else matched_local = (matched_local > 0 ? 1 : 0) ^ (stack[stacktop]&1);
194 }
195
196 return matched_local!=0;
197}
198
200{
201 return WDL_hasStringsEx(name,lp,NULL);
202}
203
205{
206 if (WDL_NOT_NORMALLY(!lp)) return false;
207
208 if (WDL_NOT_NORMALLY(!flt)) flt="";
209
210#ifdef WDL_LINEPARSER_HAS_LINEPARSERINT
211 if (lp->parse_ex(flt,true,false,true)) // allow unterminated quotes
212#else
213 if (lp->parse_ex(flt,true,false))
214#endif
215 {
216 if (*flt) lp->set_one_token(flt); // failed parsing search string, search as a single token
217 }
218
219 return lp->getnumtokens()>0;
220}
221
222#endif
#define NULL
Definition CarlaBridgeFormat.cpp:30
uint8_t a
Definition Spc_Cpu.h:141
WDL_LINEPARSE_IMPL_ONLY.
Definition lineparse.h:297
int WDL_LINEPARSE_PREFIX parse_ex(const char *line, bool ignore_commentchars WDL_LINEPARSE_DEFPARM(true), bool backtickquote WDL_LINEPARSE_DEFPARM(true), bool allowunterminatedquotes WDL_LINEPARSE_DEFPARM(false))
Definition lineparse.h:324
void WDL_LINEPARSE_PREFIX set_one_token(const char *line)
Definition lineparse.h:329
const char *WDL_LINEPARSE_PREFIX gettoken_str(int token) const
Definition lineparse.h:222
char WDL_LINEPARSE_PREFIX gettoken_quotingchar(int token) const
Definition lineparse.h:229
int getnumtokens() const
Definition lineparse.h:55
struct huft * t
Definition inflate.c:943
unsigned x[BMAX+1]
Definition inflate.c:1586
static const char * name
Definition pugl.h:1582
#define WDL_HASSTRINGS_EXPORT
Definition has_strings.h:5
WDL_HASSTRINGS_EXPORT bool WDL_hasStringsEx(const char *name, const LineParser *lp, int(*cmp_func)(const char *a, int apos, const char *b, int blen))
Definition has_strings.h:27
WDL_HASSTRINGS_EXPORT bool WDL_hasStrings(const char *name, const LineParser *lp)
Definition has_strings.h:199
WDL_HASSTRINGS_EXPORT bool hasStrings_isNonWordChar(int c)
Definition has_strings.h:8
WDL_HASSTRINGS_EXPORT bool WDL_makeSearchFilter(const char *flt, LineParser *lp)
Definition has_strings.h:204
#define strnicmp(x, y, z)
Definition swell-types.h:71
int n
Definition crypt.c:458
uch * p
Definition crypt.c:594
return c
Definition crypt.c:175
b
Definition crypt.c:628
typedef int(UZ_EXP MsgFn)()
#define lastchar(ptr, len)
Definition unzpriv.h:1260
#define WDL_NOT_NORMALLY(x)
Definition wdltypes.h:166