From b0e010fc5142acc09b10aa4f6453dd6fbdcb8265 Mon Sep 17 00:00:00 2001 From: Michiel Van Der Kolk Date: Sun, 8 May 2005 14:41:41 +0000 Subject: Databox! The frontend plugin for the searchengine, creates searchengine files (rsp) Its not pretty, but it works. Only compiling for recorder and iriver for now....since i don't know about players... Also, i'm hoping someone will beautify the interface someday. PS. Editing modes aren't fully operational yet. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6432 a1c6a512-1295-4272-9138-f99709370657 --- apps/plugins/Makefile | 2 +- apps/plugins/databox/Makefile | 96 ++++++++++++ apps/plugins/databox/databox.c | 307 ++++++++++++++++++++++++++++++++++++++ apps/plugins/databox/databox.h | 58 +++++++ apps/plugins/databox/editparser.c | 203 +++++++++++++++++++++++++ apps/plugins/databox/editparser.h | 34 +++++ apps/plugins/databox/edittoken.c | 186 +++++++++++++++++++++++ apps/plugins/databox/edittoken.h | 79 ++++++++++ 8 files changed, 964 insertions(+), 1 deletion(-) create mode 100644 apps/plugins/databox/Makefile create mode 100644 apps/plugins/databox/databox.c create mode 100644 apps/plugins/databox/databox.h create mode 100644 apps/plugins/databox/editparser.c create mode 100644 apps/plugins/databox/editparser.h create mode 100644 apps/plugins/databox/edittoken.c create mode 100644 apps/plugins/databox/edittoken.h diff --git a/apps/plugins/Makefile b/apps/plugins/Makefile index 23bc12d71a..a8dc01e4e7 100644 --- a/apps/plugins/Makefile +++ b/apps/plugins/Makefile @@ -43,7 +43,7 @@ SUBDIRS += searchengine #for any recorder and iRiver model ifneq (,$(strip $(foreach tgt,RECORDER IRIVER,$(findstring $(tgt),$(TARGET))))) - SUBDIRS += rockboy + SUBDIRS += rockboy databox endif diff --git a/apps/plugins/databox/Makefile b/apps/plugins/databox/Makefile new file mode 100644 index 0000000000..25457b8c6c --- /dev/null +++ b/apps/plugins/databox/Makefile @@ -0,0 +1,96 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id$ +# + +INCLUDES = -I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \ + -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(OUTDIR) +CFLAGS = $(GCCOPTS) -O3 $(INCLUDES) $(TARGET) $(EXTRA_DEFINES) \ + -DMEM=${MEMORYSIZE} -DPLUGIN + +ifdef APPEXTRA + INCLUDES += -I$(APPSDIR)/$(APPEXTRA) +endif + +LINKFILE := $(OBJDIR)/link.lds +DEPFILE = $(OBJDIR)/dep-databox +SRC = databox.c editparser.c edittoken.c + +SOURCES = $(SRC) +OBJS := $(SRC:%.c=$(OBJDIR)/%.o) +DIRS = . + +LDS := ../plugin.lds +OUTPUT = $(OUTDIR)/databox.rock + +all: $(OUTPUT) + +ifndef SIMVER +$(OBJDIR)/databox.elf: $(OBJS) $(LINKFILE) $(OUTDIR)/libplugin.a + @echo "LD $@" + @$(CC) $(GCCOPTS) -O -nostdlib -o $@ $(OBJS) -L$(OUTDIR) -lplugin -lgcc \ + -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/searchengine.map + +$(OUTPUT): $(OBJDIR)/databox.elf + @echo "OBJCOPY $<" + @$(OC) -O binary $< $@ +else + +ifeq ($(SIMVER), x11) +################################################### +# This is the X11 simulator version + +$(OUTPUT): $(OBJS) $(OUTDIR)/libplugin.a + @echo "LD $@" + @$(CC) $(CFLAGS) -shared $(OBJS) -L$(OUTDIR) -lplugin -o $@ +ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN) +# 'x' must be kept or you'll have "Win32 error 5" +# $ fgrep 5 /usr/include/w32api/winerror.h | head -1 +# #define ERROR_ACCESS_DENIED 5L +else + @chmod -x $@ +endif + +else # end of x11-simulator +################################################### +# This is the win32 simulator version +DLLTOOLFLAGS = --export-all +DLLWRAPFLAGS = -s --entry _DllMain@12 --target=i386-mingw32 -mno-cygwin + +$(OUTPUT): $(OBJS) $(OUTDIR)/libplugin.a + @echo "DLL $@" + @$(DLLTOOL) $(DLLTOOLFLAGS) -z $(OBJDIR)/$*.def $(OBJS) + @$(DLLWRAP) $(DLLWRAPFLAGS) --def $(OBJDIR)/$*.def $(OBJS) \ + $(OUTDIR)/libplugin.a -o $@ +ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN) +# 'x' must be kept or you'll have "Win32 error 5" +# $ fgrep 5 /usr/include/w32api/winerror.h | head -1 +# #define ERROR_ACCESS_DENIED 5L +else + @chmod -x $@ +endif +endif # end of win32-simulator + +endif # end of simulator section + + +include $(TOOLSDIR)/make.inc + +# MEM should be passed on to this makefile with the chosen memory size given +# in number of MB +$(LINKFILE): $(LDS) + @echo "build $@" + @cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) \ + -E -P - >$@ + +clean: + @echo "cleaning databox" + @rm -rf $(OBJDIR)/databox + @rm -f $(OBJDIR)/databox.* $(DEPFILE) + +-include $(DEPFILE) + diff --git a/apps/plugins/databox/databox.c b/apps/plugins/databox/databox.c new file mode 100644 index 0000000000..811b97e222 --- /dev/null +++ b/apps/plugins/databox/databox.c @@ -0,0 +1,307 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 Björn Stenberg + * + * 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" + +/* welcome to the example rockbox plugin */ + +/* here is a global api struct pointer. while not strictly necessary, + it's nice not to have to pass the api pointer in all function calls + in the plugin */ +struct plugin_api* rb; +struct token tokenbuf[200]; + +struct print printing; +struct editor editor; +struct editing editing; + +extern int acceptedmask; + +void databox_init(void) { + printing.fontfixed = rb->font_get(FONT_SYSFIXED); + rb->lcd_setfont(FONT_SYSFIXED); + printing.font_w = printing.fontfixed->maxwidth; + printing.font_h = printing.fontfixed->height; + printing.line=0; + printing.position=0; + editor.editingmode = INVALID_MARK; + editor.token = tokenbuf; +} + +void print(char *word, int invert) { + int strlen=rb->strlen(word), newpos=printing.position+strlen+1; + if(newpos*printing.font_w>LCD_WIDTH) { + printing.line++; + printing.position=0; + newpos=printing.position+strlen+1; + } + rb->lcd_putsxy(printing.font_w*printing.position,printing.font_h*printing.line,word); + if(invert) + rb->lcd_invertrect(printing.font_w*printing.position,printing.font_h*printing.line,printing.font_w*strlen,printing.font_h); + rb->lcd_update_rect(printing.font_w*printing.position,printing.font_h*printing.line,printing.font_w*strlen,printing.font_h); + printing.position=newpos; +} + +void displaytstream(struct token *token) { + int index=0; + while(token[index].kind!=TOKEN_EOF||index==editor.currentindex) { + if(editing.selecting&&index==editor.currentindex) { + print(tokentypetostring(editing.selection_candidates[editing.currentselection]),1); + } + else + print(tokentostring(&token[index]),index==editor.currentindex ? 1 : 0); + index++; + } +} + +void buildchoices(int mask) { + int i; + for(i=0;i<20;i++) + editing.selection_candidates[i]=-1; + i=0; + if(editing.selecting&& + editing.old_token.kind!=TOKEN_EOF && + editing.old_token.kind!=TOKEN_INVALID) { + editing.selection_candidates[i++]=TOKEN_EDIT; + } + if((mask&ACCEPT_EOF)&&editor.valid) + editing.selection_candidates[i++]=TOKEN_EOF; + if(mask&ACCEPT_NOT) + editing.selection_candidates[i++]=TOKEN_NOT; + if(mask&ACCEPT_BOOLOP) { + editing.selection_candidates[i++]=TOKEN_AND; + editing.selection_candidates[i++]=TOKEN_OR; + } + if(mask&ACCEPT_NUMOP) { + editing.selection_candidates[i++]=TOKEN_GT; + editing.selection_candidates[i++]=TOKEN_GTE; + editing.selection_candidates[i++]=TOKEN_LT; + editing.selection_candidates[i++]=TOKEN_LTE; + editing.selection_candidates[i++]=TOKEN_NE; + editing.selection_candidates[i++]=TOKEN_EQ; + } + if(mask&ACCEPT_STROP) { + editing.selection_candidates[i++]=TOKEN_CONTAINS; + editing.selection_candidates[i++]=TOKEN_EQUALS; + } + if(mask&ACCEPT_LPAREN) { + editing.selection_candidates[i++]=TOKEN_LPAREN; + } + if(mask&ACCEPT_RPAREN) { + editing.selection_candidates[i++]=TOKEN_RPAREN; + } + if(mask&ACCEPT_NUMARG) { + editing.selection_candidates[i++]=TOKEN_NUM; + editing.selection_candidates[i++]=TOKEN_YEAR; + editing.selection_candidates[i++]=TOKEN_RATING; + editing.selection_candidates[i++]=TOKEN_PLAYCOUNT; + } + if(mask&ACCEPT_STRARG) { + editing.selection_candidates[i++]=TOKEN_STRING; + editing.selection_candidates[i++]=TOKEN_TITLE; + editing.selection_candidates[i++]=TOKEN_ARTIST; + editing.selection_candidates[i++]=TOKEN_ALBUM; + editing.selection_candidates[i++]=TOKEN_GENRE; + editing.selection_candidates[i++]=TOKEN_FILENAME; + } + editing.selectionmax=i; +} + +/* returns tokencount or 0 if error */ +int readtstream(char *filename,struct token *token,int max) { + int tokencount=0; + int filelen,i; + int fd; + rb->memset(token,0,max*sizeof(struct token)); + fd=rb->open(filename,O_RDONLY); + if(fd>=0) { + filelen=rb->filesize(fd); + if(filelen>0) { + if(filelen % sizeof(struct token)) { + rb->splash(HZ*2,true,"Filesize not a multiple of sizeof(struct token)"); + rb->close(fd); + return 0; + } + tokencount=(filelen/sizeof(struct token))-1; + for(i=0;iread(fd,&token[i],sizeof(struct token)); + token[i].intvalue=BE32(token[i].intvalue); + } + } + rb->close(fd); + } + return tokencount; +} + +int writetstream(char *filename,struct token *token) { + int fd,i; + fd=rb->open(filename,O_WRONLY|O_CREAT|O_TRUNC); + if(fd<0) + return 0; + i=0; + while(token[i].kind!=TOKEN_EOF) { + token[i].intvalue=BE32(token[i].intvalue); + rb->write(fd,&token[i++],sizeof(struct token)); + } + token[i].intvalue=BE32(token[i].intvalue); + rb->write(fd,&token[i++],sizeof(struct token)); + rb->close(fd); + return i; +} + +int hcl_button_get(void) { + int oldbuttonstate,newbuttonstate,pressed=0; + oldbuttonstate = rb->button_status(); + do { + newbuttonstate = rb->button_status(); + pressed = newbuttonstate & ~oldbuttonstate; + oldbuttonstate = newbuttonstate; + rb->yield(); + } + while(!pressed); + rb->button_clear_queue(); + return pressed; +} + +/* this is the plugin entry point */ +enum plugin_status plugin_start(struct plugin_api* api, void* parameter) +{ + int button,done=0; + char filename[100],buf[100]; + /* this macro should be called as the first thing you do in the plugin. + it test that the api version and model the plugin was compiled for + matches the machine it is running on */ + TEST_PLUGIN_API(api); + + /* if you don't use the parameter, you can do like + this to avoid the compiler warning about it */ + (void)parameter; + + /* if you are using a global api pointer, don't forget to copy it! + otherwise you will get lovely "I04: IllInstr" errors... :-) */ + rb = api; + + /* now go ahead and have fun! */ + rb->splash(HZ*2, true, "Databox! Enter filename ^.^"); + databox_init(); + if(rb->kbd_input(filename, 100)) { + rb->splash(HZ*2, true, "Something went wrong with the filename.. exiting.."); + return PLUGIN_ERROR; + } + /* add / in front if omitted */ + if(filename[0]!='/') { + rb->strncpy(buf+1,filename,99); + buf[0]='/'; + rb->strcpy(filename,buf); + } + /* add extension if omitted */ + if(rb->strncasecmp(filename+rb->strlen(filename)-4,".rsp",4)) { + rb->strcat(filename,".rsp"); + } + rb->lcd_clear_display(); + rb->lcd_update(); + editor.currentindex=editor.tokencount=readtstream(filename,editor.token,200); + editing.currentselection=0; + editing.selecting=editor.currentindex==0 ? 1 : 0; + do { + rb->lcd_clear_display(); + rb->lcd_update(); + printing.line=0; + printing.position=0; + displaytstream(editor.token); + editor.valid=check_tokenstream(editor.token,editor.editingmode); + check_accepted(editor.token,editor.currentindex); + rb->lcd_update(); + button=hcl_button_get(); + if(editing.selecting) { + // button handling, up, down, select,stop + // up/right = move currentselection one up + // down/left = move currentselection one down + // select = build token in place. + // stop = cancel editing + if(button&BUTTON_LEFT +#if CONFIG_KEYPAD == IRIVER_H100_PAD + ||button&BUTTON_DOWN +#endif + ) { + editing.currentselection=(editing.currentselection+ + 1) %editing.selectionmax; + } + if(button&BUTTON_RIGHT +#if CONFIG_KEYPAD == IRIVER_H100_PAD + ||button&BUTTON_UP +#endif + ) { + editing.currentselection=(editing.currentselection + + editing.selectionmax-1) % editing.selectionmax; + } + if(button&BUTTON_SELECT) { + buildtoken(editing.selection_candidates[editing.currentselection],&editor.token[editor.currentindex]); + editing.selecting=0; + if(editor.token[editor.currentindex].kind==TOKEN_EOF) + done=1; + else if(editor.currentindex==editor.tokencount) { + editor.tokencount++; + editor.currentindex++; + editor.valid=check_tokenstream(editor.token,editor.editingmode); + check_accepted(editor.token,editor.currentindex); + editing.selecting=1; + editing.currentselection=0; + buildchoices(acceptedmask); + rb->memcpy(&editing.old_token,&editor.token[editor.currentindex],sizeof(struct token)); + } + } + } + else { + // button handling, left, right, select, stop + // left/down = move currentindex down + // right/up = move currentindex up + // select = enter selecting mode. + // stop = quit editor. + if(button&BUTTON_LEFT +#if CONFIG_KEYPAD == IRIVER_H100_PAD + ||button&BUTTON_DOWN +#endif + ) { + editor.currentindex=(editor.currentindex + + editor.tokencount) % (editor.tokencount+1); + } + if(button&BUTTON_RIGHT +#if CONFIG_KEYPAD == IRIVER_H100_PAD + ||button&BUTTON_UP +#endif + ) { + editor.currentindex=(editor.currentindex+1) % (editor.tokencount+1); + } + if(button&BUTTON_SELECT) { + editing.selecting=1; + editing.currentselection=0; + buildchoices(acceptedmask); + rb->memcpy(&editing.old_token,&editor.token[editor.currentindex],sizeof(struct token)); + } + } + } while (!done); + if(writetstream(filename,editor.token)) { + rb->splash(HZ*2,true,"Wrote file succesfully ^.^"); + return PLUGIN_OK; + } + else { + rb->splash(HZ*2,true,"Error while writing rsp :("); + return PLUGIN_ERROR; + } +} diff --git a/apps/plugins/databox/databox.h b/apps/plugins/databox/databox.h new file mode 100644 index 0000000000..ffbaf1d35d --- /dev/null +++ b/apps/plugins/databox/databox.h @@ -0,0 +1,58 @@ +/*************************************************************************** + * __________ __ ___. + * 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. + * + ****************************************************************************/ +#ifndef DATABOX_H +#define DATABOX_H +#include +#include +#include +#include + +#include "edittoken.h" +#include "editparser.h" + +extern struct plugin_api* rb; + +struct print { + struct font *fontfixed; + int font_w,font_h; + int line; + int position; +}; + +struct editor { + struct token *token; /* tokenstream */ + int currentindex; /* index of the token to change.(+1, 1=0 2=1 3=2 etc.) */ + int tokencount; /* total amount of tokens */ + int editingmode; /* defined in databox.h */ + int valid; /* is the current tokenstream valid ? */ +}; + +struct editing { + int selection_candidates[30]; /* possible options for this selecting */ + struct token old_token; /* only set when selecting, stores old token */ + int currentselection; /* current selection index */ + int selectionmax; + int selecting; /* boolean */ +}; + +extern struct print printing; +extern struct editor editor; +extern struct editing editing; + +#endif diff --git a/apps/plugins/databox/editparser.c b/apps/plugins/databox/editparser.c new file mode 100644 index 0000000000..d2fcbc4e6d --- /dev/null +++ b/apps/plugins/databox/editparser.c @@ -0,0 +1,203 @@ +/*************************************************************************** + * __________ __ ___. + * 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: + 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; + } +} diff --git a/apps/plugins/databox/editparser.h b/apps/plugins/databox/editparser.h new file mode 100644 index 0000000000..3a26cbca70 --- /dev/null +++ b/apps/plugins/databox/editparser.h @@ -0,0 +1,34 @@ +/*************************************************************************** + * __________ __ ___. + * 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. + * + ****************************************************************************/ +extern int acceptedmask; + +#define INVALID_STRIP 1 +#define INVALID_MARK 2 +#define INVALID_EXPERT 3 + +void check_accepted(struct token *tstream, int count); +void parse_stream(struct token *tstream, int count, int inv_mode); +int check_tokenstream(struct token *tstream, int inv_mode); +void parser_accept_rparen(void); +void parser_accept(int bitmask); +void parse_checktoken(void); +void parseCompareNum(void); +void parseCompareString(void); +void parseExpr(void); +void parseMExpr(void); diff --git a/apps/plugins/databox/edittoken.c b/apps/plugins/databox/edittoken.c new file mode 100644 index 0000000000..f5b869757b --- /dev/null +++ b/apps/plugins/databox/edittoken.c @@ -0,0 +1,186 @@ +/*************************************************************************** + * __________ __ ___. + * 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" + +char *tokentypetostring(int tokentype) { + switch(tokentype) { + case TOKEN_EOF: return ""; + case TOKEN_NOT: return "not"; + case TOKEN_AND: return "and"; + case TOKEN_OR: return "or"; + case TOKEN_GT: return ">"; + case TOKEN_GTE: return ">="; + case TOKEN_LT: return "<"; + case TOKEN_LTE: return "<="; + case TOKEN_EQ: return "=="; + case TOKEN_NE: return "!="; + case TOKEN_LPAREN: return "("; + case TOKEN_RPAREN: return ")"; + case TOKEN_CONTAINS: return "contains"; + case TOKEN_EQUALS: return "equals"; + case TOKEN_NUM: return ""; + case TOKEN_NUMIDENTIFIER: return ""; + case TOKEN_STRING: return ""; + case TOKEN_STRINGIDENTIFIER: return ""; + case TOKEN_INVALID: return ""; + case TOKEN_EDIT: return tokentostring(&editing.old_token); + case TOKEN_YEAR: return "year"; + case TOKEN_RATING: return "rating"; + case TOKEN_PLAYCOUNT: return "playcount"; + case TOKEN_TITLE: return "title"; + case TOKEN_ARTIST: return "artist"; + case TOKEN_ALBUM: return "album"; + case TOKEN_GENRE: return "genre"; + case TOKEN_FILENAME: return "filename"; + } + return "tokentypeerror"; +} + +char *numidtostring(int numid) { + switch(numid) { + case INTVALUE_YEAR: return ""; + case INTVALUE_RATING: return ""; + case INTVALUE_PLAYCOUNT: return ""; + } + return "numiderror"; +} + +char *stridtostring(int strid) { + switch(strid) { + case INTVALUE_TITLE: return ""; + case INTVALUE_ARTIST: return "<artist>"; + case INTVALUE_ALBUM: return "<album>"; + case INTVALUE_GENRE: return "<genre>"; + case INTVALUE_FILENAME: return "<filename>"; + } + return "striderror"; +} + +char bufbla[40]; + +void buildtoken(int tokentype,struct token *token) { + // TODO + char buf[200]; + rb->memset(token,0,sizeof(struct token)); + rb->memset(buf,0,200); + token->kind=tokentype; + token->intvalue=0; + switch(token->kind) { + case TOKEN_STRING: + do { + rb->splash(HZ*2,true,"Enter String."); + } while(rb->kbd_input(token->spelling, 254)); + break; + case TOKEN_YEAR: + token->kind=TOKEN_NUMIDENTIFIER; + token->intvalue=INTVALUE_YEAR; + break; + case TOKEN_RATING: + token->kind=TOKEN_NUMIDENTIFIER; + token->intvalue=INTVALUE_RATING; + break; + case TOKEN_PLAYCOUNT: + token->kind=TOKEN_NUMIDENTIFIER; + token->intvalue=INTVALUE_PLAYCOUNT; + break; + case TOKEN_TITLE: + token->kind=TOKEN_STRINGIDENTIFIER; + token->intvalue=INTVALUE_TITLE; + break; + case TOKEN_ARTIST: + token->kind=TOKEN_STRINGIDENTIFIER; + token->intvalue=INTVALUE_ARTIST; + break; + case TOKEN_ALBUM: + token->kind=TOKEN_STRINGIDENTIFIER; + token->intvalue=INTVALUE_ALBUM; + break; + case TOKEN_GENRE: + token->kind=TOKEN_STRINGIDENTIFIER; + token->intvalue=INTVALUE_GENRE; + break; + case TOKEN_FILENAME: + token->kind=TOKEN_STRINGIDENTIFIER; + token->intvalue=INTVALUE_TITLE; + break; + case TOKEN_NUM: + do { + rb->splash(HZ*2,true,"Enter Number."); + } while(rb->kbd_input(buf, 199)); + token->intvalue=rb->atoi(buf); + break; + case TOKEN_EDIT: + rb->memcpy(token,&editing.old_token,sizeof(struct token)); + break; + } +} + +void removetoken(struct token *token,int index) { + struct token *currenttoken; + currenttoken=&token[index]; + do { + rb->memcpy(currenttoken,&token[++index],sizeof(struct token)); + currenttoken=&token[index]; + } while (currenttoken->kind!=TOKEN_EOF); +} + +void inserttoken(struct token *token,int index,int tokentype) { + struct token *currenttoken; + int max,i; + currenttoken=&token[0]; + for(i=1;currenttoken->kind!=TOKEN_EOF;i++) + currenttoken=&token[i]; + max=i; + for(i=max;i>=index;i--) { + rb->memcpy(&token[i+1],&token[i],sizeof(struct token)); + } + buildtoken(tokentype,&token[index]); +} + + +char *tokentostring(struct token *token) { + switch(token->kind) { + case TOKEN_INVALID: + case TOKEN_EOF: + case TOKEN_NOT: + case TOKEN_AND: + case TOKEN_OR: + case TOKEN_GT: + case TOKEN_GTE: + case TOKEN_LT: + case TOKEN_LTE: + case TOKEN_EQ: + case TOKEN_NE: + case TOKEN_LPAREN: + case TOKEN_RPAREN: + case TOKEN_CONTAINS: + case TOKEN_EQUALS: + return tokentypetostring(token->kind); + case TOKEN_NUM: rb->snprintf(bufbla,40,"%d",token->intvalue); + return bufbla; + case TOKEN_NUMIDENTIFIER: + return numidtostring(token->intvalue); + case TOKEN_STRING: return token->spelling; + case TOKEN_STRINGIDENTIFIER: + return stridtostring(token->intvalue); + case TOKEN_EDIT: return tokentostring(&editing.old_token); + default: return "unknown token"; + } +} diff --git a/apps/plugins/databox/edittoken.h b/apps/plugins/databox/edittoken.h new file mode 100644 index 0000000000..a5c8d472e1 --- /dev/null +++ b/apps/plugins/databox/edittoken.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * __________ __ ___. + * 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. + * + ****************************************************************************/ +#ifndef EDITTOKEN_H +#define EDITTOKEN_H + +#define TOKEN_INVALID -1 +#define TOKEN_EOF 0 // EOF +#define TOKEN_NOT 1 // "not" +#define TOKEN_AND 2 // "and" +#define TOKEN_OR 3 // "or" +#define TOKEN_GT 4 // '>' +#define TOKEN_GTE 5 // '>=' +#define TOKEN_LT 6 // '<' +#define TOKEN_LTE 7 // '<=' +#define TOKEN_EQ 8 // '==' +#define TOKEN_NE 9 // '!=' +#define TOKEN_CONTAINS 10 // "contains" +#define TOKEN_EQUALS 11 // "equals" +#define TOKEN_LPAREN 12 // '(' +#define TOKEN_RPAREN 13 // ')' +#define TOKEN_NUM 14 // (0..9)+ +#define TOKEN_NUMIDENTIFIER 15 // year, trackid, bpm, etc. +#define TOKEN_STRING 16 // (?)+ +#define TOKEN_STRINGIDENTIFIER 17 // album, artist, title, genre ... +#define TOKEN_YEAR 18 +#define TOKEN_RATING 19 +#define TOKEN_PLAYCOUNT 20 +#define TOKEN_TITLE 21 +#define TOKEN_ARTIST 22 +#define TOKEN_ALBUM 23 +#define TOKEN_GENRE 24 +#define TOKEN_FILENAME 25 +#define TOKEN_EDIT 26 + +#define ACCEPT_EOF 0x1 +#define ACCEPT_BOOLOP 0x2 +#define ACCEPT_NUMOP 0x4 +#define ACCEPT_STROP 0x8 +#define ACCEPT_LPAREN 0x10 +#define ACCEPT_RPAREN 0x20 +#define ACCEPT_NUMARG 0x40 +#define ACCEPT_STRARG 0x80 +#define ACCEPT_NOT 0x100 +#define ACCEPT_DELETE 0x200 + +#define INTVALUE_YEAR 1 +#define INTVALUE_RATING 2 +#define INTVALUE_PLAYCOUNT 3 +#define INTVALUE_TITLE 4 +#define INTVALUE_ARTIST 5 +#define INTVALUE_ALBUM 6 +#define INTVALUE_GENRE 7 +#define INTVALUE_FILENAME 8 + +struct token { + char kind; + char spelling[255]; + long intvalue; +}; +char *tokentypetostring(int tokentype); +char *tokentostring(struct token *token); +void buildtoken(int tokentype,struct token *token); +#endif -- cgit