forked from len0rd/rockbox
		
	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;
 | |
|     }
 | |
| }
 |