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