simple patterns can now extract the wildcarded part of the matched string
Costa Tsaousis (ktsaou) committed
Dec 9, 2017 at 15:30 UTC
85559800cfc6ede174ab1b91e9e7ba182cc82d54
3 files changed
+66
-16
src/main.c
+6
-5
@@ -771,18 +771,19 @@ int main(int argc, char **argv) {
771
772
const char *heystack = argv[optind];
773
const char *needle = argv[optind + 1];
774
+ size_t len = strlen(needle) + 1;
775
+ char wildcarded[len];
776
775
- SIMPLE_PATTERN *p = simple_pattern_create(heystack
776
- , SIMPLE_PATTERN_EXACT);
777
- int ret = simple_pattern_matches(p, needle);
777
+ SIMPLE_PATTERN *p = simple_pattern_create(heystack, SIMPLE_PATTERN_EXACT);
778
+ int ret = simple_pattern_matches_extract(p, needle, wildcarded, len);
779
simple_pattern_free(p);
780
781
if(ret) {
781
- fprintf(stdout, "RESULT: MATCHED - pattern '%s' matches '%s'\n", heystack, needle);
782
+ fprintf(stdout, "RESULT: MATCHED - pattern '%s' matches '%s', wildcarded '%s'\n", heystack, needle, wildcarded);
783
return 0;
784
}
785
else {
785
- fprintf(stdout, "RESULT: NOT MATCHED - pattern '%s' does not match '%s'\n", heystack, needle);
786
+ fprintf(stdout, "RESULT: NOT MATCHED - pattern '%s' does not match '%s', wildcarded '%s'\n", heystack, needle, wildcarded);
787
return 1;
788
}
789
}
src/simple_pattern.c
+57
-11
@@ -13,6 +13,8 @@ struct simple_pattern {
13
};
14
15
static inline struct simple_pattern *parse_pattern(char *str, SIMPLE_PREFIX_MODE default_mode) {
16
+ // fprintf(stderr, "PARSING PATTERN: '%s'\n", str);
17
+
18
SIMPLE_PREFIX_MODE mode;
19
struct simple_pattern *child = NULL;
20
@@ -115,9 +117,10 @@ SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MODE defau
117
*c = '\0';
118
119
// if we matched the empty string, skip it
118
- if(!*buf)
120
+ if(unlikely(!*buf))
121
continue;
122
123
+ // fprintf(stderr, "FOUND PATTERN: '%s'\n", buf);
124
struct simple_pattern *m = parse_pattern(buf, default_mode);
125
m->negative = negative;
126
@@ -134,28 +137,58 @@ SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MODE defau
137
return (SIMPLE_PATTERN *)root;
138
}
139
137
-static inline int match_pattern(struct simple_pattern *m, const char *str, size_t len) {
138
- char *s;
140
+static inline char *add_wildcarded(const char *matched, size_t matched_size, char *wildcarded, size_t *wildcarded_size) {
141
+ //if(matched_size) {
142
+ // char buf[matched_size + 1];
143
+ // strncpyz(buf, matched, matched_size);
144
+ // fprintf(stderr, "ADD WILDCARDED '%s' of length %zu\n", buf, matched_size);
145
+ //}
146
+
147
+ if(matched && *matched && matched_size && wildcarded && *wildcarded_size) {
148
+ size_t wss = *wildcarded_size - 1;
149
+ size_t len = (matched_size < wss)?matched_size:wss;
150
+ if(len) {
151
+ strncpyz(wildcarded, matched, len);
152
+
153
+ *wildcarded_size -= len;
154
+ return &wildcarded[len];
155
+ }
156
+ }
157
+
158
+ return wildcarded;
159
+}
160
+
161
+static inline int match_pattern(struct simple_pattern *m, const char *str, size_t len, char *wildcarded, const size_t *wildcarded_size) {
162
+ char *s, *ws = wildcarded;
163
+ size_t wss = *wildcarded_size;
164
165
if(m->len <= len) {
166
switch(m->mode) {
167
case SIMPLE_PATTERN_SUBSTRING:
168
if(!m->len) return 1;
169
if((s = strstr(str, m->match))) {
145
- if(!m->child) return 1;
146
- return match_pattern(m->child, &s[m->len], len - (s - str) - m->len);
170
+ ws = add_wildcarded(str, s - str, ws, &wss);
171
+ if(!m->child) {
172
+ ws = add_wildcarded(&s[m->len], len - (&s[m->len] - str), ws, &wss);
173
+ return 1;
174
+ }
175
+ return match_pattern(m->child, &s[m->len], len - (s - str) - m->len, ws, &wss);
176
}
177
break;
178
179
case SIMPLE_PATTERN_PREFIX:
180
if(unlikely(strncmp(str, m->match, m->len) == 0)) {
152
- if(!m->child) return 1;
153
- return match_pattern(m->child, &str[m->len], len - m->len);
181
+ if(!m->child) {
182
+ ws = add_wildcarded(&str[m->len], len - m->len, ws, &wss);
183
+ return 1;
184
+ }
185
+ return match_pattern(m->child, &str[m->len], len - m->len, ws, &wss);
186
}
187
break;
188
189
case SIMPLE_PATTERN_SUFFIX:
190
if(unlikely(strcmp(&str[len - m->len], m->match) == 0)) {
191
+ ws = add_wildcarded(str, len - m->len, ws, &wss);
192
if(!m->child) return 1;
193
return 0;
194
}
@@ -174,21 +207,34 @@ static inline int match_pattern(struct simple_pattern *m, const char *str, size_
207
return 0;
208
}
209
177
-int simple_pattern_matches(SIMPLE_PATTERN *list, const char *str) {
210
+int simple_pattern_matches_extract(SIMPLE_PATTERN *list, const char *str, char *wildcarded, size_t wildcarded_size) {
211
struct simple_pattern *m, *root = (struct simple_pattern *)list;
212
213
if(unlikely(!root || !str || !*str)) return 0;
214
215
size_t len = strlen(str);
183
- for(m = root; m ; m = m->next)
184
- if(match_pattern(m, str, len)) {
185
- if(m->negative) return 0;
216
+ for(m = root; m ; m = m->next) {
217
+ char *ws = wildcarded;
218
+ size_t wss = wildcarded_size;
219
+ if(unlikely(ws)) *ws = '\0';
220
+
221
+ if (match_pattern(m, str, len, ws, &wss)) {
222
+
223
+ //if(ws && wss)
224
+ // fprintf(stderr, "FINAL WILDCARDED '%s' of length %zu\n", ws, strlen(ws));
225
+
226
+ if (m->negative) return 0;
227
return 1;
228
}
229
+ }
230
231
return 0;
232
}
233
234
+int simple_pattern_matches(SIMPLE_PATTERN *list, const char *str) {
235
+ return simple_pattern_matches_extract(list, str, NULL, 0);
236
+}
237
+
238
static inline void free_pattern(struct simple_pattern *m) {
239
if(!m) return;
240
src/simple_pattern.h
+3
@@ -18,6 +18,9 @@ extern SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MOD
18
// test if string str is matched from the pattern
19
extern int simple_pattern_matches(SIMPLE_PATTERN *list, const char *str);
20
21
+// test if string str is matched from the pattern and fill 'wildcarded' with the parts matched by '*'
22
+extern int simple_pattern_matches_extract(SIMPLE_PATTERN *list, const char *str, char *wildcarded, size_t wildcarded_size);
23
+
24
// free a simple_pattern that was created with simple_pattern_create()
25
// list can be NULL, in which case, this does nothing.
26
extern void simple_pattern_free(SIMPLE_PATTERN *list);