1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2005 by Michiel van der Kolk
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "searchengine.h"
23 #include "dbinterface.h"
26 struct token
*currentToken
, curtoken
;
27 unsigned char *filter
[20],*nofilter
=0;
33 unsigned char *parse(int fd
) {
40 nofilter
=my_malloc(sizeof(unsigned char)*rb
->tagdbheader
->filecount
);
41 rb
->memset(nofilter
,1,rb
->tagdbheader
->filecount
);
47 currentToken
=&curtoken
;
52 rb
->splash(HZ
*3,errormsg
);
54 parser_accept(TOKEN_EOF
);
58 void parser_acceptIt(void) {
59 if(syntaxerror
) return;
60 rb
->read(parse_fd
,&curtoken
,sizeof(struct token
));
63 int parser_accept(unsigned char kind
) {
64 if(currentToken
->kind
!=kind
) {
66 rb
->snprintf(errormsg
,250,"'%d' found where '%d' expected\n",currentToken
->kind
,kind
);
75 unsigned char *parseCompareNum() {
76 struct token number1
,number2
;
80 if(syntaxerror
) return 0;
81 PUTS("parseCompareNum");
82 if(currentToken
->kind
==TOKEN_NUM
||
83 currentToken
->kind
==TOKEN_NUMIDENTIFIER
) {
84 rb
->memcpy(&number1
,currentToken
,sizeof(struct token
));
89 rb
->snprintf(errormsg
,250,"'%d' found where NUM/NUMID expected\n",currentToken
->kind
);
92 if(currentToken
->kind
>=TOKEN_GT
&& currentToken
->kind
<= TOKEN_NE
) {
93 op
=currentToken
->kind
;
98 rb
->snprintf(errormsg
,250,"'%d' found where NUMOP expected\n",currentToken
->kind
);
101 if(currentToken
->kind
==TOKEN_NUM
||
102 currentToken
->kind
==TOKEN_NUMIDENTIFIER
) {
103 rb
->memcpy(&number2
,currentToken
,sizeof(struct token
));
108 rb
->snprintf(errormsg
,250,"'%d' found where NUM/NUMID expected\n",currentToken
->kind
);
111 ret
=my_malloc(sizeof(unsigned char)*rb
->tagdbheader
->filecount
);
112 if(number1
.kind
==TOKEN_NUM
)
113 n1
=getvalue(&number1
);
114 if(number2
.kind
==TOKEN_NUM
)
115 n2
=getvalue(&number2
);
116 for(i
=0;i
<rb
->tagdbheader
->filecount
;i
++)
117 if(filter
[currentlevel
][i
]) {
119 if(number1
.kind
==TOKEN_NUMIDENTIFIER
)
120 n1
=getvalue(&number1
);
121 if(number2
.kind
==TOKEN_NUMIDENTIFIER
)
122 n2
=getvalue(&number2
);
147 unsigned char *parseCompareString() {
148 struct token string1
,string2
;
150 char *s1
=NULL
,*s2
=NULL
;
153 if(syntaxerror
) return 0;
154 PUTS("parseCompareString");
155 if(currentToken
->kind
==TOKEN_STRING
||
156 currentToken
->kind
==TOKEN_STRINGIDENTIFIER
) {
157 rb
->memcpy(&string1
,currentToken
,sizeof(struct token
));
162 rb
->snprintf(errormsg
,250,"'%d' found where STRING/STRINGID expected\n",currentToken
->kind
);
165 op
=currentToken
->kind
;
166 if(op
>=TOKEN_CONTAINS
&&op
<=TOKEN_ENDSWITH
) {
170 rb
->snprintf(errormsg
,250,"'%d' found where STROP expected\n",op
);
173 if(currentToken
->kind
==TOKEN_STRING
||
174 currentToken
->kind
==TOKEN_STRINGIDENTIFIER
) {
175 rb
->memcpy(&string2
,currentToken
,sizeof(struct token
));
180 rb
->snprintf(errormsg
,250,"'%d' found where STRING/STRINGID expected\n",currentToken
->kind
);
183 ret
=my_malloc(sizeof(unsigned char)*rb
->tagdbheader
->filecount
);
184 if(string1
.kind
==TOKEN_STRING
)
185 s1
=getstring(&string1
);
186 if(string2
.kind
==TOKEN_STRING
)
187 s2
=getstring(&string2
);
188 for(i
=0;i
<rb
->tagdbheader
->filecount
;i
++)
189 if(filter
[currentlevel
][i
]) {
191 if(string1
.kind
==TOKEN_STRINGIDENTIFIER
)
192 s1
=getstring(&string1
);
193 if(string2
.kind
==TOKEN_STRINGIDENTIFIER
)
194 s2
=getstring(&string2
);
197 ret
[i
]=rb
->strcasestr(s1
,s2
)!=0;
200 ret
[i
]=rb
->strcasecmp(s1
,s2
)==0;
202 case TOKEN_STARTSWITH
:
203 ret
[i
]=rb
->strncasecmp(s1
,s2
,rb
->strlen(s2
))==0;
207 ret
[i
]=rb
->strncasecmp(s1
+rb
->strlen(s1
)-i2
,s2
,i2
)==0;
214 unsigned char *parseExpr() {
217 if(syntaxerror
) return 0;
219 switch(currentToken
->kind
) {
221 parser_accept(TOKEN_NOT
);
224 if(ret
==NULL
) return 0;
225 for(i
=0;i
<rb
->tagdbheader
->filecount
;i
++)
226 if(filter
[currentlevel
][i
])
230 parser_accept(TOKEN_LPAREN
);
234 if(ret
==NULL
) return 0;
235 parser_accept(TOKEN_RPAREN
);
238 case TOKEN_NUMIDENTIFIER
:
239 ret
= parseCompareNum();
240 if(ret
==NULL
) return 0;
243 case TOKEN_STRINGIDENTIFIER
:
244 ret
= parseCompareString();
245 if(ret
==NULL
) return 0;
248 // error, unexpected symbol
250 rb
->snprintf(errormsg
,250,"unexpected '%d' found at parseExpr\n",currentToken
->kind
);
257 unsigned char *parseMExpr() {
258 unsigned char *ret
,*ret2
;
260 if(syntaxerror
) return 0;
263 while(currentToken
->kind
==TOKEN_OR
) {
264 parser_accept(TOKEN_OR
);
267 if(ret2
==NULL
) return 0;
268 for(i
=0;i
<rb
->tagdbheader
->filecount
;i
++)
269 if(filter
[currentlevel
][i
]) // this should always be true
270 ret
[i
]=ret
[i
] || ret2
[i
];
272 rb
->splash(HZ
*2,"An or is having a filter, bad.");
277 unsigned char *parseLExpr() {
278 unsigned char *ret
,*ret2
;
280 if(syntaxerror
) return 0;
282 filter
[currentlevel
]=nofilter
;
284 filter
[currentlevel
]=ret
;
285 while(currentToken
->kind
==TOKEN_AND
) {
286 parser_accept(TOKEN_AND
);
289 if(ret2
==NULL
) return 0;
290 for(i
=0;i
<rb
->tagdbheader
->filecount
;i
++)
291 ret
[i
]=ret
[i
] && ret2
[i
];
293 filter
[currentlevel
]=nofilter
;