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