1
2 // parse.c
3
4 // includes
5
6 #include <string.h>
7
8 #include "parse.h"
9 #include "util.h"
10
11 // variables
12
13 char * Star[STAR_NUMBER];
14
15 // prototypes
16
17 static bool match_rec (char string[], const char pattern[], char * star[]);
18
19 // functions
20
21 // match()
22
match(char string[],const char pattern[])23 bool match(char string[], const char pattern[]) {
24
25 ASSERT(string!=NULL);
26 ASSERT(pattern!=NULL);
27
28 ASSERT(strstr(pattern,"**")==NULL);
29
30 return match_rec(string,pattern,Star);
31 }
32
33 // match_rec()
34
match_rec(char string[],const char pattern[],char * star[])35 static bool match_rec(char string[], const char pattern[], char * star[]) {
36
37 int c;
38
39 ASSERT(string!=NULL);
40 ASSERT(pattern!=NULL);
41 ASSERT(star!=NULL);
42
43 // iterative matches
44
45 while ((c=*pattern++) != '*') {
46 if (FALSE) {
47 } else if (c == '\0') { // end of pattern
48 while (*string == ' ') string++; // skip trailing spaces
49 return *string == '\0';
50 } else if (c == ' ') { // spaces
51 if (*string++ != ' ') return FALSE; // mismatch
52 while (*string == ' ') string++; // skip trailing spaces
53 } else { // normal character
54 if (*string++ != c) return FALSE; // mismatch
55 }
56 }
57
58 // recursive wildcard match
59
60 ASSERT(c=='*');
61
62 while (*string == ' ') string++; // skip leading spaces
63 *star++ = string; // remember beginning of star
64
65 while ((c=*string++) != '\0') { // reject empty-string match
66 if (c != ' ' && match_rec(string,pattern,star)) { // shortest match
67 ASSERT(string>star[-1]);
68 *string = '\0'; // truncate star
69 return TRUE;
70 }
71 }
72
73 return FALSE;
74 }
75
76 // parse_is_ok()
77
parse_is_ok(const parse_t * parse)78 bool parse_is_ok(const parse_t * parse) {
79
80 if (parse == NULL) return FALSE;
81 if (parse->string == NULL) return FALSE;
82 if (parse->pos < 0 || parse->pos > (int) strlen(parse->string)) return FALSE;
83 if (parse->keyword_nb < 0 || parse->keyword_nb >= KEYWORD_NUMBER) return FALSE;
84
85 return TRUE;
86 }
87
88 // parse_open()
89
parse_open(parse_t * parse,const char string[])90 void parse_open(parse_t * parse, const char string[]) {
91
92 ASSERT(parse!=NULL);
93 ASSERT(string!=NULL);
94
95 parse->string = string;
96 parse->pos = 0;
97 parse->keyword_nb = 0;
98 }
99
100 // parse_close()
101
parse_close(parse_t * parse)102 void parse_close(parse_t * parse) {
103
104 int i;
105
106 ASSERT(parse_is_ok(parse));
107
108 parse->string = NULL;
109 parse->pos = 0;
110
111 for (i = 0; i < parse->keyword_nb; i++) {
112 my_string_clear(&parse->keyword[i]);
113 }
114
115 parse->keyword_nb = 0;
116 }
117
118 // parse_add_keyword()
119
parse_add_keyword(parse_t * parse,const char keyword[])120 void parse_add_keyword(parse_t * parse, const char keyword[]) {
121
122 const char * * string;
123
124 ASSERT(parse_is_ok(parse));
125 ASSERT(keyword!=NULL);
126
127 if (parse->keyword_nb < KEYWORD_NUMBER) {
128
129 string = &parse->keyword[parse->keyword_nb];
130 parse->keyword_nb++;
131
132 *string = NULL;
133 my_string_set(string,keyword);
134 }
135 }
136
137 // parse_get_word()
138
parse_get_word(parse_t * parse,char string[],int size)139 bool parse_get_word(parse_t * parse, char string[], int size) {
140
141 int pos;
142 int c;
143
144 ASSERT(parse!=NULL);
145 ASSERT(string!=NULL);
146 ASSERT(size>=256);
147
148 // skip blanks
149
150 for (; parse->string[parse->pos] == ' '; parse->pos++)
151 ;
152
153 ASSERT(parse->string[parse->pos]!=' ');
154
155 // copy word
156
157 pos = 0;
158
159 while (TRUE) {
160
161 c = parse->string[parse->pos];
162 if (c == ' ' || pos >= size-1) c = '\0';
163
164 string[pos] = c;
165 if (c == '\0') break;
166
167 parse->pos++;
168 pos++;
169 }
170
171 ASSERT(strchr(string,' ')==NULL);
172
173 return pos > 0; // non-empty word?
174 }
175
176 // parse_get_string()
177
parse_get_string(parse_t * parse,char string[],int size)178 bool parse_get_string(parse_t * parse, char string[], int size) {
179
180 int pos;
181 parse_t parse_2[1];
182 char word[StringSize];
183 int i;
184 int c;
185
186 ASSERT(parse!=NULL);
187 ASSERT(string!=NULL);
188 ASSERT(size>=256);
189
190 // skip blanks
191
192 for (; parse->string[parse->pos] == ' '; parse->pos++)
193 ;
194
195 ASSERT(parse->string[parse->pos]!=' ');
196
197 // copy string
198
199 pos = 0;
200
201 while (TRUE) {
202
203 parse_open(parse_2,&parse->string[parse->pos]);
204
205 if (!parse_get_word(parse_2,word,StringSize)) {
206 string[pos] = '\0';
207 parse_close(parse_2);
208 goto finished;
209 }
210
211 for (i = 0; i < parse->keyword_nb; i++) {
212 if (my_string_equal(parse->keyword[i],word)) {
213 string[pos] = '\0';
214 parse_close(parse_2);
215 goto finished;
216 }
217 }
218
219 parse_close(parse_2);
220
221 // copy spaces
222
223 while (TRUE) {
224
225 c = parse->string[parse->pos];
226 if (c != ' ') break;
227
228 if (pos >= size-1) c = '\0';
229
230 string[pos] = c;
231 if (c == '\0') break;
232
233 parse->pos++;
234 pos++;
235 }
236
237 // copy non spaces
238
239 while (TRUE) {
240
241 c = parse->string[parse->pos];
242 if (c == ' ' || pos >= size-1) c = '\0';
243
244 string[pos] = c;
245 if (c == '\0') break;
246
247 parse->pos++;
248 pos++;
249 }
250
251 string[pos] = '\0';
252 }
253
254 finished: ;
255
256 return pos > 0; // non-empty string?
257 }
258
259 // end of parse.cpp
260
261