allow escaping spaces in simple patterns
Costa Tsaousis (ktsaou) committed
Dec 9, 2017 at 03:00 UTC
1b0be11955001c5966a67ac22198bb42de93a890
1 file changed
+47
-39
src/simple_pattern.c
+47
-39
@@ -12,12 +12,11 @@ struct simple_pattern {
12
struct simple_pattern *next;
13
};
14
15
-static inline struct simple_pattern *parse_pattern(const char *str, SIMPLE_PREFIX_MODE default_mode) {
15
+static inline struct simple_pattern *parse_pattern(char *str, SIMPLE_PREFIX_MODE default_mode) {
16
SIMPLE_PREFIX_MODE mode;
17
struct simple_pattern *child = NULL;
18
19
- char *buf = strdupz(str);
20
- char *s = buf, *c = buf;
19
+ char *s = str, *c = str;
20
21
// skip asterisks in front
22
while(*c == '*') c++;
@@ -64,8 +63,6 @@ static inline struct simple_pattern *parse_pattern(const char *str, SIMPLE_PREFI
63
64
m->child = child;
65
67
- freez(buf);
68
-
66
return m;
67
}
68
@@ -74,51 +71,62 @@ SIMPLE_PATTERN *simple_pattern_create(const char *list, SIMPLE_PREFIX_MODE defau
71
72
if(unlikely(!list || !*list)) return root;
73
77
- char *buf = strdupz(list);
78
- if(buf && *buf) {
79
- char *s = buf;
74
+ char *buf = mallocz(strlen(list) + 1);
75
+ const char *s = list;
76
81
- while(s && *s) {
82
- char negative = 0;
77
+ while(s && *s) {
78
+ buf[0] = '\0';
79
+ char *c = buf;
80
84
- // skip all spaces
85
- while(isspace(*s)) s++;
81
+ char negative = 0;
82
87
- if(*s == '!') {
88
- negative = 1;
89
- s++;
90
- }
83
+ // skip all spaces
84
+ while(isspace(*s))
85
+ s++;
86
92
- // empty string
93
- if(unlikely(!*s)) break;
87
+ if(*s == '!') {
88
+ negative = 1;
89
+ s++;
90
+ }
91
95
- // find the next space
96
- char *c = s;
97
- while(*c && !isspace(*c)) c++;
92
+ // empty string
93
+ if(unlikely(!*s))
94
+ break;
95
99
- // find the next word
100
- char *n;
101
- if(likely(*c)) n = c + 1;
102
- else n = NULL;
96
+ // find the next space
97
+ char escape = 0;
98
+ while(*s) {
99
+ if(*s == '\\' && !escape) {
100
+ escape = 1;
101
+ s++;
102
+ }
103
+ else {
104
+ if (isspace(*s) && !escape) {
105
+ s++;
106
+ break;
107
+ }
108
104
- // terminate our string
105
- *c = '\0';
109
+ *c++ = *s++;
110
+ escape = 0;
111
+ }
112
+ }
113
107
- struct simple_pattern *m = parse_pattern(s, default_mode);
108
- m->negative = negative;
114
+ // terminate our string
115
+ *c = '\0';
116
110
- if(likely(n)) *c = ' ';
117
+ // if we matched the empty string, skip it
118
+ if(!*buf)
119
+ continue;
120
112
- // link it at the end
113
- if(unlikely(!root))
114
- root = last = m;
115
- else {
116
- last->next = m;
117
- last = m;
118
- }
121
+ struct simple_pattern *m = parse_pattern(buf, default_mode);
122
+ m->negative = negative;
123
120
- // prepare for next loop
121
- s = n;
124
+ // link it at the end
125
+ if(unlikely(!root))
126
+ root = last = m;
127
+ else {
128
+ last->next = m;
129
+ last = m;
130
}
131
}
132