f5eae08361
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6454 a1c6a512-1295-4272-9138-f99709370657
205 lines
5.7 KiB
C
205 lines
5.7 KiB
C
/***************************************************************************
|
|
* __________ __ ___.
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
* \/ \/ \/ \/ \/
|
|
* $Id$
|
|
*
|
|
* Copyright (C) 2005 by Michiel van der Kolk
|
|
*
|
|
* All files in this archive are subject to the GNU General Public License.
|
|
* See the file COPYING in the source tree root for full license agreement.
|
|
*
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
* KIND, either express or implied.
|
|
*
|
|
****************************************************************************/
|
|
#include "databox.h"
|
|
#include "edittoken.h"
|
|
#include "editparser.h"
|
|
|
|
struct token *currenttoken,*lasttoken,*tokenstream;
|
|
int currentindex;
|
|
int lparencount,acceptedmask;
|
|
int tokensleft;
|
|
int invalid;
|
|
int invalid_mode;
|
|
|
|
void check_accepted(struct token *tstream, int count) {
|
|
parse_stream(tstream,count+1,INVALID_EXPERT);
|
|
}
|
|
|
|
void parse_stream(struct token *tstream, int count, int inv_mode) {
|
|
invalid_mode=inv_mode;
|
|
acceptedmask=0;
|
|
lparencount=0;
|
|
tokensleft=count;
|
|
currentindex=0;
|
|
invalid=0;
|
|
tokenstream=tstream;
|
|
currenttoken=&tokenstream[currentindex];
|
|
parseMExpr();
|
|
}
|
|
|
|
int check_tokenstream(struct token *tstream, int inv_mode) {
|
|
int inval=0;
|
|
int i;
|
|
parse_stream(tstream,-1,inv_mode);
|
|
inval=invalid;
|
|
while( (inv_mode==INVALID_STRIP||inv_mode==INVALID_MARK) && invalid)
|
|
parse_stream(tstream,-1,inv_mode);
|
|
i=0;
|
|
while(tstream[i].kind!=TOKEN_EOF)
|
|
if(tstream[i++].kind==TOKEN_INVALID) {
|
|
inval=1;
|
|
break;
|
|
}
|
|
return inval==0;
|
|
}
|
|
|
|
|
|
void parse_accept_rparen(void) {
|
|
if(!tokensleft) return;
|
|
if(lparencount) {
|
|
acceptedmask|=ACCEPT_RPAREN;
|
|
}
|
|
}
|
|
|
|
void parse_accept(int bitmask) {
|
|
if(!tokensleft) return;
|
|
acceptedmask|=bitmask;
|
|
if(lparencount) {
|
|
acceptedmask&=~ACCEPT_EOF;
|
|
}
|
|
}
|
|
|
|
void parse_checktoken() {
|
|
int ok=0;
|
|
if(!tokensleft) return;
|
|
lasttoken=currenttoken;
|
|
switch(lasttoken->kind) {
|
|
case TOKEN_EOF:
|
|
ok=acceptedmask&ACCEPT_EOF;
|
|
break;
|
|
case TOKEN_NOT:
|
|
ok=acceptedmask&ACCEPT_NOT;
|
|
break;
|
|
case TOKEN_AND:
|
|
case TOKEN_OR:
|
|
ok=acceptedmask&ACCEPT_BOOLOP;
|
|
break;
|
|
case TOKEN_GT:
|
|
case TOKEN_GTE:
|
|
case TOKEN_LT:
|
|
case TOKEN_LTE:
|
|
case TOKEN_NE:
|
|
case TOKEN_EQ:
|
|
ok=acceptedmask&ACCEPT_NUMOP;
|
|
break;
|
|
case TOKEN_EQUALS:
|
|
case TOKEN_CONTAINS:
|
|
case TOKEN_STARTSWITH:
|
|
case TOKEN_ENDSWITH:
|
|
ok=acceptedmask&ACCEPT_STROP;
|
|
break;
|
|
case TOKEN_STRING:
|
|
case TOKEN_STRINGIDENTIFIER:
|
|
ok=acceptedmask&ACCEPT_STRARG;
|
|
break;
|
|
case TOKEN_NUM:
|
|
case TOKEN_NUMIDENTIFIER:
|
|
ok=acceptedmask&ACCEPT_NUMARG;
|
|
break;
|
|
case TOKEN_LPAREN:
|
|
ok=acceptedmask&ACCEPT_LPAREN;
|
|
if(ok) lparencount++;
|
|
break;
|
|
case TOKEN_RPAREN:
|
|
ok=acceptedmask&ACCEPT_RPAREN;
|
|
if(ok) lparencount--;
|
|
break;
|
|
case TOKEN_INVALID:
|
|
if(invalid_mode!=INVALID_STRIP)
|
|
ok=1;
|
|
break;
|
|
}
|
|
tokensleft--;
|
|
if(lasttoken->kind==TOKEN_EOF)
|
|
tokensleft=0;
|
|
if(!ok&&tokensleft) {
|
|
// delete token
|
|
int i=currentindex;
|
|
//printf("Syntax error. accepted: 0x%x index:%d token: %d %s\n",acceptedmask,currentindex,currenttoken->kind,tokentostring(currenttoken));
|
|
switch (invalid_mode) {
|
|
case INVALID_STRIP:
|
|
do {
|
|
rb->memcpy(currenttoken,&tokenstream[++i],sizeof(struct token));;
|
|
currenttoken=&tokenstream[i];
|
|
} while (currenttoken->kind!=TOKEN_EOF);
|
|
currenttoken=&tokenstream[currentindex];
|
|
break;
|
|
case INVALID_MARK:
|
|
currenttoken->kind=TOKEN_INVALID;
|
|
break;
|
|
}
|
|
tokensleft=0;
|
|
invalid=1;
|
|
}
|
|
if(tokensleft) {
|
|
currenttoken=&tokenstream[++currentindex];
|
|
acceptedmask=0;
|
|
}
|
|
}
|
|
|
|
void parseCompareNum() {
|
|
parse_accept(ACCEPT_NUMOP);
|
|
parse_checktoken();
|
|
parse_accept(ACCEPT_NUMARG);
|
|
parse_checktoken();
|
|
}
|
|
|
|
void parseCompareString() {
|
|
parse_accept(ACCEPT_STROP);
|
|
parse_checktoken();
|
|
parse_accept(ACCEPT_STRARG);
|
|
parse_checktoken();
|
|
}
|
|
|
|
void parseExpr() {
|
|
if(!tokensleft) return;
|
|
parse_accept(ACCEPT_NOT|ACCEPT_LPAREN|ACCEPT_NUMARG|ACCEPT_STRARG);
|
|
parse_checktoken();
|
|
switch(lasttoken->kind) {
|
|
case TOKEN_NOT:
|
|
parseExpr();
|
|
break;
|
|
case TOKEN_LPAREN:
|
|
parseMExpr();
|
|
break;
|
|
case TOKEN_NUM:
|
|
case TOKEN_NUMIDENTIFIER:
|
|
parseCompareNum();
|
|
break;
|
|
case TOKEN_STRING:
|
|
case TOKEN_STRINGIDENTIFIER:
|
|
parseCompareString();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void parseMExpr() {
|
|
parseExpr();
|
|
parse_accept_rparen();
|
|
parse_accept(ACCEPT_BOOLOP|ACCEPT_EOF);
|
|
parse_checktoken();
|
|
while(lasttoken->kind==TOKEN_OR || lasttoken->kind == TOKEN_AND) {
|
|
parseExpr();
|
|
parse_accept_rparen();
|
|
parse_accept(ACCEPT_BOOLOP|ACCEPT_EOF);
|
|
parse_checktoken();
|
|
if(!tokensleft)
|
|
return;
|
|
}
|
|
}
|