diff options
author | Michiel Van Der Kolk <not.valid@email.address> | 2005-04-29 21:02:17 +0000 |
---|---|---|
committer | Michiel Van Der Kolk <not.valid@email.address> | 2005-04-29 21:02:17 +0000 |
commit | ec407a86a758925e7ba0c994ae17d29e19dc4b39 (patch) | |
tree | cc2fb9c032aad91a786ecb1dd47c730298efeb37 /apps/plugins/searchengine/parser.c | |
parent | 388d9ff6a3229149c4b37f52321d10b460acc382 (diff) | |
download | rockbox-ec407a86a758925e7ba0c994ae17d29e19dc4b39.tar.gz rockbox-ec407a86a758925e7ba0c994ae17d29e19dc4b39.zip |
Code policy...
Removed tokentool for now since this is not the proper place, but what is?
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6383 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/searchengine/parser.c')
-rw-r--r-- | apps/plugins/searchengine/parser.c | 468 |
1 files changed, 232 insertions, 236 deletions
diff --git a/apps/plugins/searchengine/parser.c b/apps/plugins/searchengine/parser.c index 834c0d4aa1..62423e256f 100644 --- a/apps/plugins/searchengine/parser.c +++ b/apps/plugins/searchengine/parser.c | |||
@@ -29,264 +29,260 @@ int parse_fd; | |||
29 | char errormsg[250]; | 29 | char errormsg[250]; |
30 | 30 | ||
31 | unsigned char *parse(int fd) { | 31 | unsigned char *parse(int fd) { |
32 | unsigned char *ret=0; | 32 | unsigned char *ret=0; |
33 | int i; | 33 | int i; |
34 | syntaxerror=0; | 34 | syntaxerror=0; |
35 | parse_fd=fd; | 35 | parse_fd=fd; |
36 | currentlevel=0; | 36 | currentlevel=0; |
37 | if(nofilter==0) { | 37 | if(nofilter==0) { |
38 | nofilter=my_malloc(sizeof(unsigned char)*rb->tagdbheader->filecount); | 38 | nofilter=my_malloc(sizeof(unsigned char)*rb->tagdbheader->filecount); |
39 | rb->memset(nofilter,1,rb->tagdbheader->filecount); | 39 | rb->memset(nofilter,1,rb->tagdbheader->filecount); |
40 | } | 40 | } |
41 | for(i=0;i<20;i++) | 41 | for(i=0;i<20;i++) |
42 | filter[i]=nofilter; | 42 | filter[i]=nofilter; |
43 | database_init(); | 43 | database_init(); |
44 | parser_acceptIt(); | 44 | parser_acceptIt(); |
45 | currentToken=&curtoken; | 45 | currentToken=&curtoken; |
46 | PUTS("parse"); | 46 | PUTS("parse"); |
47 | ret=parseMExpr(); | 47 | ret=parseMExpr(); |
48 | if(syntaxerror) { | 48 | if(syntaxerror) { |
49 | PUTS("Syntaxerror"); | 49 | PUTS("Syntaxerror"); |
50 | rb->splash(HZ*3,true,errormsg); | 50 | rb->splash(HZ*3,true,errormsg); |
51 | } | 51 | } |
52 | parser_accept(TOKEN_EOF); | 52 | parser_accept(TOKEN_EOF); |
53 | return ret; | 53 | return ret; |
54 | } | 54 | } |
55 | 55 | ||
56 | void parser_acceptIt(void) { | 56 | void parser_acceptIt(void) { |
57 | if(syntaxerror) return; | 57 | if(syntaxerror) return; |
58 | rb->read(parse_fd,&curtoken,sizeof(struct token)); | 58 | rb->read(parse_fd,&curtoken,sizeof(struct token)); |
59 | } | 59 | } |
60 | 60 | ||
61 | int parser_accept(unsigned char kind) { | 61 | int parser_accept(unsigned char kind) { |
62 | if(currentToken->kind!=kind) { | 62 | if(currentToken->kind!=kind) { |
63 | syntaxerror=1; | 63 | syntaxerror=1; |
64 | rb->snprintf(errormsg,250,"'%d' found where '%d' expected\n",currentToken->kind,kind); | 64 | rb->snprintf(errormsg,250,"'%d' found where '%d' expected\n",currentToken->kind,kind); |
65 | return 0; | 65 | return 0; |
66 | } | 66 | } |
67 | else { | 67 | else { |
68 | parser_acceptIt(); | 68 | parser_acceptIt(); |
69 | return 1; | 69 | return 1; |
70 | } | 70 | } |
71 | } | 71 | } |
72 | 72 | ||
73 | unsigned char *parseCompareNum() { | 73 | unsigned char *parseCompareNum() { |
74 | struct token number1,number2; | 74 | struct token number1,number2; |
75 | unsigned char *ret; | 75 | unsigned char *ret; |
76 | int i,n1=-1,n2=-1; | 76 | int i,n1=-1,n2=-1; |
77 | int op; | 77 | int op; |
78 | if(syntaxerror) return 0; | 78 | if(syntaxerror) return 0; |
79 | PUTS("parseCompareNum"); | 79 | PUTS("parseCompareNum"); |
80 | if(currentToken->kind==TOKEN_NUM || | 80 | if(currentToken->kind==TOKEN_NUM || |
81 | currentToken->kind==TOKEN_NUMIDENTIFIER) { | 81 | currentToken->kind==TOKEN_NUMIDENTIFIER) { |
82 | rb->memcpy(&number1,currentToken,sizeof(struct token)); | 82 | rb->memcpy(&number1,currentToken,sizeof(struct token)); |
83 | parser_acceptIt(); | 83 | parser_acceptIt(); |
84 | } | 84 | } |
85 | else { | 85 | else { |
86 | syntaxerror=1; | 86 | syntaxerror=1; |
87 | rb->snprintf(errormsg,250,"'%d' found where NUM/NUMID expected\n",currentToken->kind); | 87 | rb->snprintf(errormsg,250,"'%d' found where NUM/NUMID expected\n",currentToken->kind); |
88 | return 0; | 88 | return 0; |
89 | } | 89 | } |
90 | if(currentToken->kind>=TOKEN_GT && currentToken->kind <= TOKEN_NE) { | 90 | if(currentToken->kind>=TOKEN_GT && currentToken->kind <= TOKEN_NE) { |
91 | op=currentToken->kind; | 91 | op=currentToken->kind; |
92 | parser_acceptIt(); | 92 | parser_acceptIt(); |
93 | } | 93 | } |
94 | else { | 94 | else { |
95 | syntaxerror=1; | 95 | syntaxerror=1; |
96 | rb->snprintf(errormsg,250,"'%d' found where NUMOP expected\n",currentToken->kind); | 96 | rb->snprintf(errormsg,250,"'%d' found where NUMOP expected\n",currentToken->kind); |
97 | return 0; | 97 | return 0; |
98 | } | 98 | } |
99 | if(currentToken->kind==TOKEN_NUM || | 99 | if(currentToken->kind==TOKEN_NUM || |
100 | currentToken->kind==TOKEN_NUMIDENTIFIER) { | 100 | currentToken->kind==TOKEN_NUMIDENTIFIER) { |
101 | rb->memcpy(&number2,currentToken,sizeof(struct token)); | 101 | rb->memcpy(&number2,currentToken,sizeof(struct token)); |
102 | parser_acceptIt(); | 102 | parser_acceptIt(); |
103 | } | ||
104 | else { | ||
105 | syntaxerror=1; | ||
106 | rb->snprintf(errormsg,250,"'%d' found where NUM/NUMID expected\n",currentToken->kind); | ||
107 | return 0; | ||
108 | } | ||
109 | ret=my_malloc(sizeof(unsigned char)*rb->tagdbheader->filecount); | ||
110 | if(number1.kind==TOKEN_NUM) | ||
111 | n1=getvalue(&number1); | ||
112 | if(number2.kind==TOKEN_NUM) | ||
113 | n2=getvalue(&number2); | ||
114 | for(i=0;i<rb->tagdbheader->filecount;i++) | ||
115 | if(filter[currentlevel][i]) { | ||
116 | loadentry(i); | ||
117 | if(number1.kind==TOKEN_NUMIDENTIFIER) | ||
118 | n1=getvalue(&number1); | ||
119 | if(number2.kind==TOKEN_NUMIDENTIFIER) | ||
120 | n2=getvalue(&number2); | ||
121 | switch(op) { | ||
122 | case TOKEN_GT: | ||
123 | ret[i]=n1 > n2; | ||
124 | break; | ||
125 | case TOKEN_GTE: | ||
126 | ret[i]=n1 >= n2; | ||
127 | break; | ||
128 | case TOKEN_LT: | ||
129 | ret[i]=n1 < n2; | ||
130 | break; | ||
131 | case TOKEN_LTE: | ||
132 | ret[i]=n1 <= n2; | ||
133 | break; | ||
134 | case TOKEN_EQ: | ||
135 | ret[i]=n1 == n2; | ||
136 | break; | ||
137 | case TOKEN_NE: | ||
138 | ret[i]=n1 != n2; | ||
139 | break; | ||
140 | } | ||
103 | } | 141 | } |
104 | else { | 142 | return ret; |
105 | syntaxerror=1; | ||
106 | rb->snprintf(errormsg,250,"'%d' found where NUM/NUMID expected\n",currentToken->kind); | ||
107 | return 0; | ||
108 | } | ||
109 | ret=my_malloc(sizeof(unsigned char)*rb->tagdbheader->filecount); | ||
110 | if(number1.kind==TOKEN_NUM) | ||
111 | n1=getvalue(&number1); | ||
112 | if(number2.kind==TOKEN_NUM) | ||
113 | n2=getvalue(&number2); | ||
114 | for(i=0;i<rb->tagdbheader->filecount;i++) | ||
115 | if(filter[currentlevel][i]) { | ||
116 | loadentry(i); | ||
117 | if(number1.kind==TOKEN_NUMIDENTIFIER) | ||
118 | n1=getvalue(&number1); | ||
119 | if(number2.kind==TOKEN_NUMIDENTIFIER) | ||
120 | n2=getvalue(&number2); | ||
121 | switch(op) { | ||
122 | case TOKEN_GT: | ||
123 | ret[i]=n1 > n2; | ||
124 | break; | ||
125 | case TOKEN_GTE: | ||
126 | ret[i]=n1 >= n2; | ||
127 | break; | ||
128 | case TOKEN_LT: | ||
129 | ret[i]=n1 < n2; | ||
130 | break; | ||
131 | case TOKEN_LTE: | ||
132 | ret[i]=n1 <= n2; | ||
133 | break; | ||
134 | case TOKEN_EQ: | ||
135 | ret[i]=n1 == n2; | ||
136 | break; | ||
137 | case TOKEN_NE: | ||
138 | ret[i]=n1 != n2; | ||
139 | break; | ||
140 | } | ||
141 | } | ||
142 | return ret; | ||
143 | } | 143 | } |
144 | 144 | ||
145 | unsigned char *parseCompareString() { | 145 | unsigned char *parseCompareString() { |
146 | struct token string1,string2; | 146 | struct token string1,string2; |
147 | unsigned char *ret; | 147 | unsigned char *ret; |
148 | char *s1=NULL,*s2=NULL; | 148 | char *s1=NULL,*s2=NULL; |
149 | int i,contains; | 149 | int i,contains; |
150 | if(syntaxerror) return 0; | 150 | if(syntaxerror) return 0; |
151 | PUTS("parseCompareString"); | 151 | PUTS("parseCompareString"); |
152 | if(currentToken->kind==TOKEN_STRING || | 152 | if(currentToken->kind==TOKEN_STRING || |
153 | currentToken->kind==TOKEN_STRINGIDENTIFIER) { | 153 | currentToken->kind==TOKEN_STRINGIDENTIFIER) { |
154 | rb->memcpy(&string1,currentToken,sizeof(struct token)); | 154 | rb->memcpy(&string1,currentToken,sizeof(struct token)); |
155 | parser_acceptIt(); | 155 | parser_acceptIt(); |
156 | } | ||
157 | else { | ||
158 | syntaxerror=1; | ||
159 | rb->snprintf(errormsg,250,"'%d' found where STRING/STRINGID expected\n",currentToken->kind); | ||
160 | return 0; | ||
161 | } | ||
162 | if(currentToken->kind==TOKEN_CONTAINS || | ||
163 | currentToken->kind==TOKEN_EQUALS) { | ||
164 | if(currentToken->kind==TOKEN_CONTAINS) { | ||
165 | contains=1; | ||
166 | PUTS("Contains"); | ||
167 | } else { | ||
168 | contains=0; | ||
169 | PUTS("Equals"); | ||
156 | } | 170 | } |
157 | else { | 171 | parser_acceptIt(); |
158 | syntaxerror=1; | 172 | } else { |
159 | rb->snprintf(errormsg,250,"'%d' found where STRING/STRINGID expected\n",currentToken->kind); | 173 | syntaxerror=1; |
160 | return 0; | 174 | rb->snprintf(errormsg,250,"'%d' found where CONTAINS/EQUALS expected\n",currentToken->kind); |
175 | return 0; | ||
176 | } | ||
177 | if(currentToken->kind==TOKEN_STRING || | ||
178 | currentToken->kind==TOKEN_STRINGIDENTIFIER) { | ||
179 | rb->memcpy(&string2,currentToken,sizeof(struct token)); | ||
180 | parser_acceptIt(); | ||
181 | } | ||
182 | else { | ||
183 | syntaxerror=1; | ||
184 | rb->snprintf(errormsg,250,"'%d' found where STRING/STRINGID expected\n",currentToken->kind); | ||
185 | return 0; | ||
186 | } | ||
187 | ret=my_malloc(sizeof(unsigned char)*rb->tagdbheader->filecount); | ||
188 | if(string1.kind==TOKEN_STRING) | ||
189 | s1=getstring(&string1); | ||
190 | if(string2.kind==TOKEN_STRING) | ||
191 | s2=getstring(&string2); | ||
192 | for(i=0;i<rb->tagdbheader->filecount;i++) | ||
193 | if(filter[currentlevel][i]) { | ||
194 | loadentry(i); | ||
195 | if(string1.kind==TOKEN_STRINGIDENTIFIER) | ||
196 | s1=getstring(&string1); | ||
197 | if(string2.kind==TOKEN_STRINGIDENTIFIER) | ||
198 | s2=getstring(&string2); | ||
199 | if(contains) | ||
200 | ret[i]=rb->strcasestr(s1,s2)!=0; | ||
201 | else | ||
202 | ret[i]=rb->strcasecmp(s1,s2)==0; | ||
161 | } | 203 | } |
162 | 204 | return ret; | |
163 | if(currentToken->kind==TOKEN_CONTAINS || | ||
164 | currentToken->kind==TOKEN_EQUALS) { | ||
165 | if(currentToken->kind==TOKEN_CONTAINS) { | ||
166 | contains=1; | ||
167 | PUTS("Contains"); | ||
168 | } | ||
169 | else { | ||
170 | contains=0; | ||
171 | PUTS("Equals"); | ||
172 | } | ||
173 | parser_acceptIt(); | ||
174 | } | ||
175 | else { | ||
176 | syntaxerror=1; | ||
177 | rb->snprintf(errormsg,250,"'%d' found where CONTAINS/EQUALS expected\n",currentToken->kind); | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | if(currentToken->kind==TOKEN_STRING || | ||
182 | currentToken->kind==TOKEN_STRINGIDENTIFIER) { | ||
183 | rb->memcpy(&string2,currentToken,sizeof(struct token)); | ||
184 | parser_acceptIt(); | ||
185 | } | ||
186 | else { | ||
187 | syntaxerror=1; | ||
188 | rb->snprintf(errormsg,250,"'%d' found where STRING/STRINGID expected\n",currentToken->kind); | ||
189 | return 0; | ||
190 | } | ||
191 | ret=my_malloc(sizeof(unsigned char)*rb->tagdbheader->filecount); | ||
192 | if(string1.kind==TOKEN_STRING) | ||
193 | s1=getstring(&string1); | ||
194 | if(string2.kind==TOKEN_STRING) | ||
195 | s2=getstring(&string2); | ||
196 | for(i=0;i<rb->tagdbheader->filecount;i++) | ||
197 | if(filter[currentlevel][i]) { | ||
198 | loadentry(i); | ||
199 | if(string1.kind==TOKEN_STRINGIDENTIFIER) | ||
200 | s1=getstring(&string1); | ||
201 | if(string2.kind==TOKEN_STRINGIDENTIFIER) | ||
202 | s2=getstring(&string2); | ||
203 | if(contains) | ||
204 | ret[i]=rb->strcasestr(s1,s2)!=0; | ||
205 | else | ||
206 | ret[i]=rb->strcasecmp(s1,s2)==0; | ||
207 | } | ||
208 | return ret; | ||
209 | } | 205 | } |
210 | 206 | ||
211 | unsigned char *parseExpr() { | 207 | unsigned char *parseExpr() { |
212 | unsigned char *ret; | 208 | unsigned char *ret; |
213 | int i; | 209 | int i; |
214 | if(syntaxerror) return 0; | 210 | if(syntaxerror) return 0; |
215 | PUTS("parseExpr"); | 211 | PUTS("parseExpr"); |
216 | switch(currentToken->kind) { | 212 | switch(currentToken->kind) { |
217 | case TOKEN_NOT: | 213 | case TOKEN_NOT: |
218 | parser_accept(TOKEN_NOT); | 214 | parser_accept(TOKEN_NOT); |
219 | PUTS("parseNot"); | 215 | PUTS("parseNot"); |
220 | ret = parseExpr(); | 216 | ret = parseExpr(); |
221 | if(ret==NULL) return 0; | 217 | if(ret==NULL) return 0; |
222 | for(i=0;i<rb->tagdbheader->filecount;i++) | 218 | for(i=0;i<rb->tagdbheader->filecount;i++) |
223 | if(filter[currentlevel][i]) | 219 | if(filter[currentlevel][i]) |
224 | ret[i]=!ret[i]; | 220 | ret[i]=!ret[i]; |
225 | break; | 221 | break; |
226 | case TOKEN_LPAREN: | 222 | case TOKEN_LPAREN: |
227 | parser_accept(TOKEN_LPAREN); | 223 | parser_accept(TOKEN_LPAREN); |
228 | currentlevel++; | 224 | currentlevel++; |
229 | ret = parseMExpr(); | 225 | ret = parseMExpr(); |
230 | currentlevel--; | 226 | currentlevel--; |
231 | if(ret==NULL) return 0; | 227 | if(ret==NULL) return 0; |
232 | parser_accept(TOKEN_RPAREN); | 228 | parser_accept(TOKEN_RPAREN); |
233 | break; | 229 | break; |
234 | case TOKEN_NUM: | 230 | case TOKEN_NUM: |
235 | case TOKEN_NUMIDENTIFIER: | 231 | case TOKEN_NUMIDENTIFIER: |
236 | ret = parseCompareNum(); | 232 | ret = parseCompareNum(); |
237 | if(ret==NULL) return 0; | 233 | if(ret==NULL) return 0; |
238 | break; | 234 | break; |
239 | case TOKEN_STRING: | 235 | case TOKEN_STRING: |
240 | case TOKEN_STRINGIDENTIFIER: | 236 | case TOKEN_STRINGIDENTIFIER: |
241 | ret = parseCompareString(); | 237 | ret = parseCompareString(); |
242 | if(ret==NULL) return 0; | 238 | if(ret==NULL) return 0; |
243 | break; | 239 | break; |
244 | default: | 240 | default: |
245 | // error, unexpected symbol | 241 | // error, unexpected symbol |
246 | syntaxerror=1; | 242 | syntaxerror=1; |
247 | rb->snprintf(errormsg,250,"unexpected '%d' found at parseExpr\n",currentToken->kind); | 243 | rb->snprintf(errormsg,250,"unexpected '%d' found at parseExpr\n",currentToken->kind); |
248 | ret=0; | 244 | ret=0; |
249 | break; | 245 | break; |
250 | } | 246 | } |
251 | return ret; | 247 | return ret; |
252 | } | 248 | } |
253 | 249 | ||
254 | unsigned char *parseMExpr() { | 250 | unsigned char *parseMExpr() { |
255 | unsigned char *ret,*ret2; | 251 | unsigned char *ret,*ret2; |
256 | int i; | 252 | int i; |
257 | if(syntaxerror) return 0; | 253 | if(syntaxerror) return 0; |
258 | PUTS("parseMExpr"); | 254 | PUTS("parseMExpr"); |
259 | ret=parseLExpr(); | 255 | ret=parseLExpr(); |
260 | while(currentToken->kind==TOKEN_OR) { | 256 | while(currentToken->kind==TOKEN_OR) { |
261 | parser_accept(TOKEN_OR); | 257 | parser_accept(TOKEN_OR); |
262 | PUTS("parseOr"); | 258 | PUTS("parseOr"); |
263 | ret2 = parseLExpr(); | 259 | ret2 = parseLExpr(); |
264 | if(ret2==NULL) return 0; | 260 | if(ret2==NULL) return 0; |
265 | for(i=0;i<rb->tagdbheader->filecount;i++) | 261 | for(i=0;i<rb->tagdbheader->filecount;i++) |
266 | if(filter[currentlevel][i]) // this should always be true | 262 | if(filter[currentlevel][i]) // this should always be true |
267 | ret[i]=ret[i] || ret2[i]; | 263 | ret[i]=ret[i] || ret2[i]; |
268 | else | 264 | else |
269 | rb->splash(HZ*2,true,"An or is having a filter, bad."); | 265 | rb->splash(HZ*2,true,"An or is having a filter, bad."); |
270 | } | 266 | } |
271 | return ret; | 267 | return ret; |
272 | } | 268 | } |
273 | 269 | ||
274 | unsigned char *parseLExpr() { | 270 | unsigned char *parseLExpr() { |
275 | unsigned char *ret,*ret2; | 271 | unsigned char *ret,*ret2; |
276 | int i; | 272 | int i; |
277 | if(syntaxerror) return 0; | 273 | if(syntaxerror) return 0; |
278 | PUTS("parseLExpr"); | 274 | PUTS("parseLExpr"); |
279 | filter[currentlevel]=nofilter; | 275 | filter[currentlevel]=nofilter; |
280 | ret=parseExpr(); | 276 | ret=parseExpr(); |
281 | filter[currentlevel]=ret; | 277 | filter[currentlevel]=ret; |
282 | while(currentToken->kind==TOKEN_AND) { | 278 | while(currentToken->kind==TOKEN_AND) { |
283 | parser_accept(TOKEN_AND); | 279 | parser_accept(TOKEN_AND); |
284 | PUTS("parseAnd"); | 280 | PUTS("parseAnd"); |
285 | ret2 = parseExpr(); | 281 | ret2 = parseExpr(); |
286 | if(ret2==NULL) return 0; | 282 | if(ret2==NULL) return 0; |
287 | for(i=0;i<rb->tagdbheader->filecount;i++) | 283 | for(i=0;i<rb->tagdbheader->filecount;i++) |
288 | ret[i]=ret[i] && ret2[i]; | 284 | ret[i]=ret[i] && ret2[i]; |
289 | } | 285 | } |
290 | filter[currentlevel]=nofilter; | 286 | filter[currentlevel]=nofilter; |
291 | return ret; | 287 | return ret; |
292 | } | 288 | } |