summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/plugins/Makefile2
-rw-r--r--apps/plugins/databox/Makefile96
-rw-r--r--apps/plugins/databox/databox.c307
-rw-r--r--apps/plugins/databox/databox.h58
-rw-r--r--apps/plugins/databox/editparser.c203
-rw-r--r--apps/plugins/databox/editparser.h34
-rw-r--r--apps/plugins/databox/edittoken.c186
-rw-r--r--apps/plugins/databox/edittoken.h79
8 files changed, 964 insertions, 1 deletions
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
43 43
44#for any recorder and iRiver model 44#for any recorder and iRiver model
45ifneq (,$(strip $(foreach tgt,RECORDER IRIVER,$(findstring $(tgt),$(TARGET))))) 45ifneq (,$(strip $(foreach tgt,RECORDER IRIVER,$(findstring $(tgt),$(TARGET)))))
46 SUBDIRS += rockboy 46 SUBDIRS += rockboy databox
47endif 47endif
48 48
49 49
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 @@
1# __________ __ ___.
2# Open \______ \ ____ ____ | | _\_ |__ _______ ___
3# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
4# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
5# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
6# \/ \/ \/ \/ \/
7# $Id$
8#
9
10INCLUDES = -I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \
11 -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(OUTDIR)
12CFLAGS = $(GCCOPTS) -O3 $(INCLUDES) $(TARGET) $(EXTRA_DEFINES) \
13 -DMEM=${MEMORYSIZE} -DPLUGIN
14
15ifdef APPEXTRA
16 INCLUDES += -I$(APPSDIR)/$(APPEXTRA)
17endif
18
19LINKFILE := $(OBJDIR)/link.lds
20DEPFILE = $(OBJDIR)/dep-databox
21SRC = databox.c editparser.c edittoken.c
22
23SOURCES = $(SRC)
24OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
25DIRS = .
26
27LDS := ../plugin.lds
28OUTPUT = $(OUTDIR)/databox.rock
29
30all: $(OUTPUT)
31
32ifndef SIMVER
33$(OBJDIR)/databox.elf: $(OBJS) $(LINKFILE) $(OUTDIR)/libplugin.a
34 @echo "LD $@"
35 @$(CC) $(GCCOPTS) -O -nostdlib -o $@ $(OBJS) -L$(OUTDIR) -lplugin -lgcc \
36 -T$(LINKFILE) -Wl,-Map,$(OBJDIR)/searchengine.map
37
38$(OUTPUT): $(OBJDIR)/databox.elf
39 @echo "OBJCOPY $<"
40 @$(OC) -O binary $< $@
41else
42
43ifeq ($(SIMVER), x11)
44###################################################
45# This is the X11 simulator version
46
47$(OUTPUT): $(OBJS) $(OUTDIR)/libplugin.a
48 @echo "LD $@"
49 @$(CC) $(CFLAGS) -shared $(OBJS) -L$(OUTDIR) -lplugin -o $@
50ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
51# 'x' must be kept or you'll have "Win32 error 5"
52# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
53# #define ERROR_ACCESS_DENIED 5L
54else
55 @chmod -x $@
56endif
57
58else # end of x11-simulator
59###################################################
60# This is the win32 simulator version
61DLLTOOLFLAGS = --export-all
62DLLWRAPFLAGS = -s --entry _DllMain@12 --target=i386-mingw32 -mno-cygwin
63
64$(OUTPUT): $(OBJS) $(OUTDIR)/libplugin.a
65 @echo "DLL $@"
66 @$(DLLTOOL) $(DLLTOOLFLAGS) -z $(OBJDIR)/$*.def $(OBJS)
67 @$(DLLWRAP) $(DLLWRAPFLAGS) --def $(OBJDIR)/$*.def $(OBJS) \
68 $(OUTDIR)/libplugin.a -o $@
69ifeq ($(findstring CYGWIN,$(UNAME)),CYGWIN)
70# 'x' must be kept or you'll have "Win32 error 5"
71# $ fgrep 5 /usr/include/w32api/winerror.h | head -1
72# #define ERROR_ACCESS_DENIED 5L
73else
74 @chmod -x $@
75endif
76endif # end of win32-simulator
77
78endif # end of simulator section
79
80
81include $(TOOLSDIR)/make.inc
82
83# MEM should be passed on to this makefile with the chosen memory size given
84# in number of MB
85$(LINKFILE): $(LDS)
86 @echo "build $@"
87 @cat $< | $(CC) -DMEMORYSIZE=$(MEMORYSIZE) $(INCLUDES) $(TARGET) $(DEFINES) \
88 -E -P - >$@
89
90clean:
91 @echo "cleaning databox"
92 @rm -rf $(OBJDIR)/databox
93 @rm -f $(OBJDIR)/databox.* $(DEPFILE)
94
95-include $(DEPFILE)
96
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Björn Stenberg
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "databox.h"
20
21/* welcome to the example rockbox plugin */
22
23/* here is a global api struct pointer. while not strictly necessary,
24 it's nice not to have to pass the api pointer in all function calls
25 in the plugin */
26struct plugin_api* rb;
27struct token tokenbuf[200];
28
29struct print printing;
30struct editor editor;
31struct editing editing;
32
33extern int acceptedmask;
34
35void databox_init(void) {
36 printing.fontfixed = rb->font_get(FONT_SYSFIXED);
37 rb->lcd_setfont(FONT_SYSFIXED);
38 printing.font_w = printing.fontfixed->maxwidth;
39 printing.font_h = printing.fontfixed->height;
40 printing.line=0;
41 printing.position=0;
42 editor.editingmode = INVALID_MARK;
43 editor.token = tokenbuf;
44}
45
46void print(char *word, int invert) {
47 int strlen=rb->strlen(word), newpos=printing.position+strlen+1;
48 if(newpos*printing.font_w>LCD_WIDTH) {
49 printing.line++;
50 printing.position=0;
51 newpos=printing.position+strlen+1;
52 }
53 rb->lcd_putsxy(printing.font_w*printing.position,printing.font_h*printing.line,word);
54 if(invert)
55 rb->lcd_invertrect(printing.font_w*printing.position,printing.font_h*printing.line,printing.font_w*strlen,printing.font_h);
56 rb->lcd_update_rect(printing.font_w*printing.position,printing.font_h*printing.line,printing.font_w*strlen,printing.font_h);
57 printing.position=newpos;
58}
59
60void displaytstream(struct token *token) {
61 int index=0;
62 while(token[index].kind!=TOKEN_EOF||index==editor.currentindex) {
63 if(editing.selecting&&index==editor.currentindex) {
64 print(tokentypetostring(editing.selection_candidates[editing.currentselection]),1);
65 }
66 else
67 print(tokentostring(&token[index]),index==editor.currentindex ? 1 : 0);
68 index++;
69 }
70}
71
72void buildchoices(int mask) {
73 int i;
74 for(i=0;i<20;i++)
75 editing.selection_candidates[i]=-1;
76 i=0;
77 if(editing.selecting&&
78 editing.old_token.kind!=TOKEN_EOF &&
79 editing.old_token.kind!=TOKEN_INVALID) {
80 editing.selection_candidates[i++]=TOKEN_EDIT;
81 }
82 if((mask&ACCEPT_EOF)&&editor.valid)
83 editing.selection_candidates[i++]=TOKEN_EOF;
84 if(mask&ACCEPT_NOT)
85 editing.selection_candidates[i++]=TOKEN_NOT;
86 if(mask&ACCEPT_BOOLOP) {
87 editing.selection_candidates[i++]=TOKEN_AND;
88 editing.selection_candidates[i++]=TOKEN_OR;
89 }
90 if(mask&ACCEPT_NUMOP) {
91 editing.selection_candidates[i++]=TOKEN_GT;
92 editing.selection_candidates[i++]=TOKEN_GTE;
93 editing.selection_candidates[i++]=TOKEN_LT;
94 editing.selection_candidates[i++]=TOKEN_LTE;
95 editing.selection_candidates[i++]=TOKEN_NE;
96 editing.selection_candidates[i++]=TOKEN_EQ;
97 }
98 if(mask&ACCEPT_STROP) {
99 editing.selection_candidates[i++]=TOKEN_CONTAINS;
100 editing.selection_candidates[i++]=TOKEN_EQUALS;
101 }
102 if(mask&ACCEPT_LPAREN) {
103 editing.selection_candidates[i++]=TOKEN_LPAREN;
104 }
105 if(mask&ACCEPT_RPAREN) {
106 editing.selection_candidates[i++]=TOKEN_RPAREN;
107 }
108 if(mask&ACCEPT_NUMARG) {
109 editing.selection_candidates[i++]=TOKEN_NUM;
110 editing.selection_candidates[i++]=TOKEN_YEAR;
111 editing.selection_candidates[i++]=TOKEN_RATING;
112 editing.selection_candidates[i++]=TOKEN_PLAYCOUNT;
113 }
114 if(mask&ACCEPT_STRARG) {
115 editing.selection_candidates[i++]=TOKEN_STRING;
116 editing.selection_candidates[i++]=TOKEN_TITLE;
117 editing.selection_candidates[i++]=TOKEN_ARTIST;
118 editing.selection_candidates[i++]=TOKEN_ALBUM;
119 editing.selection_candidates[i++]=TOKEN_GENRE;
120 editing.selection_candidates[i++]=TOKEN_FILENAME;
121 }
122 editing.selectionmax=i;
123}
124
125/* returns tokencount or 0 if error */
126int readtstream(char *filename,struct token *token,int max) {
127 int tokencount=0;
128 int filelen,i;
129 int fd;
130 rb->memset(token,0,max*sizeof(struct token));
131 fd=rb->open(filename,O_RDONLY);
132 if(fd>=0) {
133 filelen=rb->filesize(fd);
134 if(filelen>0) {
135 if(filelen % sizeof(struct token)) {
136 rb->splash(HZ*2,true,"Filesize not a multiple of sizeof(struct token)");
137 rb->close(fd);
138 return 0;
139 }
140 tokencount=(filelen/sizeof(struct token))-1;
141 for(i=0;i<tokencount&&i<max;i++) {
142 rb->read(fd,&token[i],sizeof(struct token));
143 token[i].intvalue=BE32(token[i].intvalue);
144 }
145 }
146 rb->close(fd);
147 }
148 return tokencount;
149}
150
151int writetstream(char *filename,struct token *token) {
152 int fd,i;
153 fd=rb->open(filename,O_WRONLY|O_CREAT|O_TRUNC);
154 if(fd<0)
155 return 0;
156 i=0;
157 while(token[i].kind!=TOKEN_EOF) {
158 token[i].intvalue=BE32(token[i].intvalue);
159 rb->write(fd,&token[i++],sizeof(struct token));
160 }
161 token[i].intvalue=BE32(token[i].intvalue);
162 rb->write(fd,&token[i++],sizeof(struct token));
163 rb->close(fd);
164 return i;
165}
166
167int hcl_button_get(void) {
168 int oldbuttonstate,newbuttonstate,pressed=0;
169 oldbuttonstate = rb->button_status();
170 do {
171 newbuttonstate = rb->button_status();
172 pressed = newbuttonstate & ~oldbuttonstate;
173 oldbuttonstate = newbuttonstate;
174 rb->yield();
175 }
176 while(!pressed);
177 rb->button_clear_queue();
178 return pressed;
179}
180
181/* this is the plugin entry point */
182enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
183{
184 int button,done=0;
185 char filename[100],buf[100];
186 /* this macro should be called as the first thing you do in the plugin.
187 it test that the api version and model the plugin was compiled for
188 matches the machine it is running on */
189 TEST_PLUGIN_API(api);
190
191 /* if you don't use the parameter, you can do like
192 this to avoid the compiler warning about it */
193 (void)parameter;
194
195 /* if you are using a global api pointer, don't forget to copy it!
196 otherwise you will get lovely "I04: IllInstr" errors... :-) */
197 rb = api;
198
199 /* now go ahead and have fun! */
200 rb->splash(HZ*2, true, "Databox! Enter filename ^.^");
201 databox_init();
202 if(rb->kbd_input(filename, 100)) {
203 rb->splash(HZ*2, true, "Something went wrong with the filename.. exiting..");
204 return PLUGIN_ERROR;
205 }
206 /* add / in front if omitted */
207 if(filename[0]!='/') {
208 rb->strncpy(buf+1,filename,99);
209 buf[0]='/';
210 rb->strcpy(filename,buf);
211 }
212 /* add extension if omitted */
213 if(rb->strncasecmp(filename+rb->strlen(filename)-4,".rsp",4)) {
214 rb->strcat(filename,".rsp");
215 }
216 rb->lcd_clear_display();
217 rb->lcd_update();
218 editor.currentindex=editor.tokencount=readtstream(filename,editor.token,200);
219 editing.currentselection=0;
220 editing.selecting=editor.currentindex==0 ? 1 : 0;
221 do {
222 rb->lcd_clear_display();
223 rb->lcd_update();
224 printing.line=0;
225 printing.position=0;
226 displaytstream(editor.token);
227 editor.valid=check_tokenstream(editor.token,editor.editingmode);
228 check_accepted(editor.token,editor.currentindex);
229 rb->lcd_update();
230 button=hcl_button_get();
231 if(editing.selecting) {
232 // button handling, up, down, select,stop
233 // up/right = move currentselection one up
234 // down/left = move currentselection one down
235 // select = build token in place.
236 // stop = cancel editing
237 if(button&BUTTON_LEFT
238#if CONFIG_KEYPAD == IRIVER_H100_PAD
239 ||button&BUTTON_DOWN
240#endif
241 ) {
242 editing.currentselection=(editing.currentselection+
243 1) %editing.selectionmax;
244 }
245 if(button&BUTTON_RIGHT
246#if CONFIG_KEYPAD == IRIVER_H100_PAD
247 ||button&BUTTON_UP
248#endif
249 ) {
250 editing.currentselection=(editing.currentselection +
251 editing.selectionmax-1) % editing.selectionmax;
252 }
253 if(button&BUTTON_SELECT) {
254 buildtoken(editing.selection_candidates[editing.currentselection],&editor.token[editor.currentindex]);
255 editing.selecting=0;
256 if(editor.token[editor.currentindex].kind==TOKEN_EOF)
257 done=1;
258 else if(editor.currentindex==editor.tokencount) {
259 editor.tokencount++;
260 editor.currentindex++;
261 editor.valid=check_tokenstream(editor.token,editor.editingmode);
262 check_accepted(editor.token,editor.currentindex);
263 editing.selecting=1;
264 editing.currentselection=0;
265 buildchoices(acceptedmask);
266 rb->memcpy(&editing.old_token,&editor.token[editor.currentindex],sizeof(struct token));
267 }
268 }
269 }
270 else {
271 // button handling, left, right, select, stop
272 // left/down = move currentindex down
273 // right/up = move currentindex up
274 // select = enter selecting mode.
275 // stop = quit editor.
276 if(button&BUTTON_LEFT
277#if CONFIG_KEYPAD == IRIVER_H100_PAD
278 ||button&BUTTON_DOWN
279#endif
280 ) {
281 editor.currentindex=(editor.currentindex +
282 editor.tokencount) % (editor.tokencount+1);
283 }
284 if(button&BUTTON_RIGHT
285#if CONFIG_KEYPAD == IRIVER_H100_PAD
286 ||button&BUTTON_UP
287#endif
288 ) {
289 editor.currentindex=(editor.currentindex+1) % (editor.tokencount+1);
290 }
291 if(button&BUTTON_SELECT) {
292 editing.selecting=1;
293 editing.currentselection=0;
294 buildchoices(acceptedmask);
295 rb->memcpy(&editing.old_token,&editor.token[editor.currentindex],sizeof(struct token));
296 }
297 }
298 } while (!done);
299 if(writetstream(filename,editor.token)) {
300 rb->splash(HZ*2,true,"Wrote file succesfully ^.^");
301 return PLUGIN_OK;
302 }
303 else {
304 rb->splash(HZ*2,true,"Error while writing rsp :(");
305 return PLUGIN_ERROR;
306 }
307}
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Michiel van der Kolk
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef DATABOX_H
20#define DATABOX_H
21#include <stdio.h>
22#include <stdlib.h>
23#include <plugin.h>
24#include <database.h>
25
26#include "edittoken.h"
27#include "editparser.h"
28
29extern struct plugin_api* rb;
30
31struct print {
32 struct font *fontfixed;
33 int font_w,font_h;
34 int line;
35 int position;
36};
37
38struct editor {
39 struct token *token; /* tokenstream */
40 int currentindex; /* index of the token to change.(+1, 1=0 2=1 3=2 etc.) */
41 int tokencount; /* total amount of tokens */
42 int editingmode; /* defined in databox.h */
43 int valid; /* is the current tokenstream valid ? */
44};
45
46struct editing {
47 int selection_candidates[30]; /* possible options for this selecting */
48 struct token old_token; /* only set when selecting, stores old token */
49 int currentselection; /* current selection index */
50 int selectionmax;
51 int selecting; /* boolean */
52};
53
54extern struct print printing;
55extern struct editor editor;
56extern struct editing editing;
57
58#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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Michiel van der Kolk
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "databox.h"
20#include "edittoken.h"
21#include "editparser.h"
22
23struct token *currenttoken,*lasttoken,*tokenstream;
24int currentindex;
25int lparencount,acceptedmask;
26int tokensleft;
27int invalid;
28int invalid_mode;
29
30void check_accepted(struct token *tstream, int count) {
31 parse_stream(tstream,count+1,INVALID_EXPERT);
32}
33
34void parse_stream(struct token *tstream, int count, int inv_mode) {
35 invalid_mode=inv_mode;
36 acceptedmask=0;
37 lparencount=0;
38 tokensleft=count;
39 currentindex=0;
40 invalid=0;
41 tokenstream=tstream;
42 currenttoken=&tokenstream[currentindex];
43 parseMExpr();
44}
45
46int check_tokenstream(struct token *tstream, int inv_mode) {
47 int inval=0;
48 int i;
49 parse_stream(tstream,-1,inv_mode);
50 inval=invalid;
51 while( (inv_mode==INVALID_STRIP||inv_mode==INVALID_MARK) && invalid)
52 parse_stream(tstream,-1,inv_mode);
53 i=0;
54 while(tstream[i].kind!=TOKEN_EOF)
55 if(tstream[i++].kind==TOKEN_INVALID) {
56 inval=1;
57 break;
58 }
59 return inval==0;
60}
61
62
63void parse_accept_rparen(void) {
64 if(!tokensleft) return;
65 if(lparencount) {
66 acceptedmask|=ACCEPT_RPAREN;
67 }
68}
69
70void parse_accept(int bitmask) {
71 if(!tokensleft) return;
72 acceptedmask|=bitmask;
73 if(lparencount) {
74 acceptedmask&=~ACCEPT_EOF;
75 }
76}
77
78void parse_checktoken() {
79 int ok=0;
80 if(!tokensleft) return;
81 lasttoken=currenttoken;
82 switch(lasttoken->kind) {
83 case TOKEN_EOF:
84 ok=acceptedmask&ACCEPT_EOF;
85 break;
86 case TOKEN_NOT:
87 ok=acceptedmask&ACCEPT_NOT;
88 break;
89 case TOKEN_AND:
90 case TOKEN_OR:
91 ok=acceptedmask&ACCEPT_BOOLOP;
92 break;
93 case TOKEN_GT:
94 case TOKEN_GTE:
95 case TOKEN_LT:
96 case TOKEN_LTE:
97 case TOKEN_NE:
98 case TOKEN_EQ:
99 ok=acceptedmask&ACCEPT_NUMOP;
100 break;
101 case TOKEN_EQUALS:
102 case TOKEN_CONTAINS:
103 ok=acceptedmask&ACCEPT_STROP;
104 break;
105 case TOKEN_STRING:
106 case TOKEN_STRINGIDENTIFIER:
107 ok=acceptedmask&ACCEPT_STRARG;
108 break;
109 case TOKEN_NUM:
110 case TOKEN_NUMIDENTIFIER:
111 ok=acceptedmask&ACCEPT_NUMARG;
112 break;
113 case TOKEN_LPAREN:
114 ok=acceptedmask&ACCEPT_LPAREN;
115 if(ok) lparencount++;
116 break;
117 case TOKEN_RPAREN:
118 ok=acceptedmask&ACCEPT_RPAREN;
119 if(ok) lparencount--;
120 break;
121 case TOKEN_INVALID:
122 if(invalid_mode!=INVALID_STRIP)
123 ok=1;
124 break;
125 }
126 tokensleft--;
127 if(lasttoken->kind==TOKEN_EOF)
128 tokensleft=0;
129 if(!ok&&tokensleft) {
130 // delete token
131 int i=currentindex;
132 //printf("Syntax error. accepted: 0x%x index:%d token: %d %s\n",acceptedmask,currentindex,currenttoken->kind,tokentostring(currenttoken));
133 switch (invalid_mode) {
134 case INVALID_STRIP:
135 do {
136 rb->memcpy(currenttoken,&tokenstream[++i],sizeof(struct token));;
137 currenttoken=&tokenstream[i];
138 } while (currenttoken->kind!=TOKEN_EOF);
139 currenttoken=&tokenstream[currentindex];
140 break;
141 case INVALID_MARK:
142 currenttoken->kind=TOKEN_INVALID;
143 break;
144 }
145 tokensleft=0;
146 invalid=1;
147 }
148 if(tokensleft) {
149 currenttoken=&tokenstream[++currentindex];
150 acceptedmask=0;
151 }
152}
153
154void parseCompareNum() {
155 parse_accept(ACCEPT_NUMOP);
156 parse_checktoken();
157 parse_accept(ACCEPT_NUMARG);
158 parse_checktoken();
159}
160
161void parseCompareString() {
162 parse_accept(ACCEPT_STROP);
163 parse_checktoken();
164 parse_accept(ACCEPT_STRARG);
165 parse_checktoken();
166}
167
168void parseExpr() {
169 if(!tokensleft) return;
170 parse_accept(ACCEPT_NOT|ACCEPT_LPAREN|ACCEPT_NUMARG|ACCEPT_STRARG);
171 parse_checktoken();
172 switch(lasttoken->kind) {
173 case TOKEN_NOT:
174 parseExpr();
175 break;
176 case TOKEN_LPAREN:
177 parseMExpr();
178 break;
179 case TOKEN_NUM:
180 case TOKEN_NUMIDENTIFIER:
181 parseCompareNum();
182 break;
183 case TOKEN_STRING:
184 case TOKEN_STRINGIDENTIFIER:
185 parseCompareString();
186 break;
187 }
188}
189
190void parseMExpr() {
191 parseExpr();
192 parse_accept_rparen();
193 parse_accept(ACCEPT_BOOLOP|ACCEPT_EOF);
194 parse_checktoken();
195 while(lasttoken->kind==TOKEN_OR || lasttoken->kind == TOKEN_AND) {
196 parseExpr();
197 parse_accept_rparen();
198 parse_accept(ACCEPT_BOOLOP|ACCEPT_EOF);
199 parse_checktoken();
200 if(!tokensleft)
201 return;
202 }
203}
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Michiel van der Kolk
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19extern int acceptedmask;
20
21#define INVALID_STRIP 1
22#define INVALID_MARK 2
23#define INVALID_EXPERT 3
24
25void check_accepted(struct token *tstream, int count);
26void parse_stream(struct token *tstream, int count, int inv_mode);
27int check_tokenstream(struct token *tstream, int inv_mode);
28void parser_accept_rparen(void);
29void parser_accept(int bitmask);
30void parse_checktoken(void);
31void parseCompareNum(void);
32void parseCompareString(void);
33void parseExpr(void);
34void 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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Michiel van der Kolk
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "databox.h"
20#include "edittoken.h"
21
22char *tokentypetostring(int tokentype) {
23 switch(tokentype) {
24 case TOKEN_EOF: return "<END>";
25 case TOKEN_NOT: return "not";
26 case TOKEN_AND: return "and";
27 case TOKEN_OR: return "or";
28 case TOKEN_GT: return ">";
29 case TOKEN_GTE: return ">=";
30 case TOKEN_LT: return "<";
31 case TOKEN_LTE: return "<=";
32 case TOKEN_EQ: return "==";
33 case TOKEN_NE: return "!=";
34 case TOKEN_LPAREN: return "(";
35 case TOKEN_RPAREN: return ")";
36 case TOKEN_CONTAINS: return "contains";
37 case TOKEN_EQUALS: return "equals";
38 case TOKEN_NUM: return "<number>";
39 case TOKEN_NUMIDENTIFIER: return "<numberproperty>";
40 case TOKEN_STRING: return "<string>";
41 case TOKEN_STRINGIDENTIFIER: return "<stringproperty>";
42 case TOKEN_INVALID: return "<INVALID>";
43 case TOKEN_EDIT: return tokentostring(&editing.old_token);
44 case TOKEN_YEAR: return "year";
45 case TOKEN_RATING: return "rating";
46 case TOKEN_PLAYCOUNT: return "playcount";
47 case TOKEN_TITLE: return "title";
48 case TOKEN_ARTIST: return "artist";
49 case TOKEN_ALBUM: return "album";
50 case TOKEN_GENRE: return "genre";
51 case TOKEN_FILENAME: return "filename";
52 }
53 return "tokentypeerror";
54}
55
56char *numidtostring(int numid) {
57 switch(numid) {
58 case INTVALUE_YEAR: return "<year>";
59 case INTVALUE_RATING: return "<rating>";
60 case INTVALUE_PLAYCOUNT: return "<playcount>";
61 }
62 return "numiderror";
63}
64
65char *stridtostring(int strid) {
66 switch(strid) {
67 case INTVALUE_TITLE: return "<title>";
68 case INTVALUE_ARTIST: return "<artist>";
69 case INTVALUE_ALBUM: return "<album>";
70 case INTVALUE_GENRE: return "<genre>";
71 case INTVALUE_FILENAME: return "<filename>";
72 }
73 return "striderror";
74}
75
76char bufbla[40];
77
78void buildtoken(int tokentype,struct token *token) {
79 // TODO
80 char buf[200];
81 rb->memset(token,0,sizeof(struct token));
82 rb->memset(buf,0,200);
83 token->kind=tokentype;
84 token->intvalue=0;
85 switch(token->kind) {
86 case TOKEN_STRING:
87 do {
88 rb->splash(HZ*2,true,"Enter String.");
89 } while(rb->kbd_input(token->spelling, 254));
90 break;
91 case TOKEN_YEAR:
92 token->kind=TOKEN_NUMIDENTIFIER;
93 token->intvalue=INTVALUE_YEAR;
94 break;
95 case TOKEN_RATING:
96 token->kind=TOKEN_NUMIDENTIFIER;
97 token->intvalue=INTVALUE_RATING;
98 break;
99 case TOKEN_PLAYCOUNT:
100 token->kind=TOKEN_NUMIDENTIFIER;
101 token->intvalue=INTVALUE_PLAYCOUNT;
102 break;
103 case TOKEN_TITLE:
104 token->kind=TOKEN_STRINGIDENTIFIER;
105 token->intvalue=INTVALUE_TITLE;
106 break;
107 case TOKEN_ARTIST:
108 token->kind=TOKEN_STRINGIDENTIFIER;
109 token->intvalue=INTVALUE_ARTIST;
110 break;
111 case TOKEN_ALBUM:
112 token->kind=TOKEN_STRINGIDENTIFIER;
113 token->intvalue=INTVALUE_ALBUM;
114 break;
115 case TOKEN_GENRE:
116 token->kind=TOKEN_STRINGIDENTIFIER;
117 token->intvalue=INTVALUE_GENRE;
118 break;
119 case TOKEN_FILENAME:
120 token->kind=TOKEN_STRINGIDENTIFIER;
121 token->intvalue=INTVALUE_TITLE;
122 break;
123 case TOKEN_NUM:
124 do {
125 rb->splash(HZ*2,true,"Enter Number.");
126 } while(rb->kbd_input(buf, 199));
127 token->intvalue=rb->atoi(buf);
128 break;
129 case TOKEN_EDIT:
130 rb->memcpy(token,&editing.old_token,sizeof(struct token));
131 break;
132 }
133}
134
135void removetoken(struct token *token,int index) {
136 struct token *currenttoken;
137 currenttoken=&token[index];
138 do {
139 rb->memcpy(currenttoken,&token[++index],sizeof(struct token));
140 currenttoken=&token[index];
141 } while (currenttoken->kind!=TOKEN_EOF);
142}
143
144void inserttoken(struct token *token,int index,int tokentype) {
145 struct token *currenttoken;
146 int max,i;
147 currenttoken=&token[0];
148 for(i=1;currenttoken->kind!=TOKEN_EOF;i++)
149 currenttoken=&token[i];
150 max=i;
151 for(i=max;i>=index;i--) {
152 rb->memcpy(&token[i+1],&token[i],sizeof(struct token));
153 }
154 buildtoken(tokentype,&token[index]);
155}
156
157
158char *tokentostring(struct token *token) {
159 switch(token->kind) {
160 case TOKEN_INVALID:
161 case TOKEN_EOF:
162 case TOKEN_NOT:
163 case TOKEN_AND:
164 case TOKEN_OR:
165 case TOKEN_GT:
166 case TOKEN_GTE:
167 case TOKEN_LT:
168 case TOKEN_LTE:
169 case TOKEN_EQ:
170 case TOKEN_NE:
171 case TOKEN_LPAREN:
172 case TOKEN_RPAREN:
173 case TOKEN_CONTAINS:
174 case TOKEN_EQUALS:
175 return tokentypetostring(token->kind);
176 case TOKEN_NUM: rb->snprintf(bufbla,40,"%d",token->intvalue);
177 return bufbla;
178 case TOKEN_NUMIDENTIFIER:
179 return numidtostring(token->intvalue);
180 case TOKEN_STRING: return token->spelling;
181 case TOKEN_STRINGIDENTIFIER:
182 return stridtostring(token->intvalue);
183 case TOKEN_EDIT: return tokentostring(&editing.old_token);
184 default: return "unknown token";
185 }
186}
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 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2005 by Michiel van der Kolk
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#ifndef EDITTOKEN_H
20#define EDITTOKEN_H
21
22#define TOKEN_INVALID -1
23#define TOKEN_EOF 0 // EOF
24#define TOKEN_NOT 1 // "not"
25#define TOKEN_AND 2 // "and"
26#define TOKEN_OR 3 // "or"
27#define TOKEN_GT 4 // '>'
28#define TOKEN_GTE 5 // '>='
29#define TOKEN_LT 6 // '<'
30#define TOKEN_LTE 7 // '<='
31#define TOKEN_EQ 8 // '=='
32#define TOKEN_NE 9 // '!='
33#define TOKEN_CONTAINS 10 // "contains"
34#define TOKEN_EQUALS 11 // "equals"
35#define TOKEN_LPAREN 12 // '('
36#define TOKEN_RPAREN 13 // ')'
37#define TOKEN_NUM 14 // (0..9)+
38#define TOKEN_NUMIDENTIFIER 15 // year, trackid, bpm, etc.
39#define TOKEN_STRING 16 // (?)+
40#define TOKEN_STRINGIDENTIFIER 17 // album, artist, title, genre ...
41#define TOKEN_YEAR 18
42#define TOKEN_RATING 19
43#define TOKEN_PLAYCOUNT 20
44#define TOKEN_TITLE 21
45#define TOKEN_ARTIST 22
46#define TOKEN_ALBUM 23
47#define TOKEN_GENRE 24
48#define TOKEN_FILENAME 25
49#define TOKEN_EDIT 26
50
51#define ACCEPT_EOF 0x1
52#define ACCEPT_BOOLOP 0x2
53#define ACCEPT_NUMOP 0x4
54#define ACCEPT_STROP 0x8
55#define ACCEPT_LPAREN 0x10
56#define ACCEPT_RPAREN 0x20
57#define ACCEPT_NUMARG 0x40
58#define ACCEPT_STRARG 0x80
59#define ACCEPT_NOT 0x100
60#define ACCEPT_DELETE 0x200
61
62#define INTVALUE_YEAR 1
63#define INTVALUE_RATING 2
64#define INTVALUE_PLAYCOUNT 3
65#define INTVALUE_TITLE 4
66#define INTVALUE_ARTIST 5
67#define INTVALUE_ALBUM 6
68#define INTVALUE_GENRE 7
69#define INTVALUE_FILENAME 8
70
71struct token {
72 char kind;
73 char spelling[255];
74 long intvalue;
75};
76char *tokentypetostring(int tokentype);
77char *tokentostring(struct token *token);
78void buildtoken(int tokentype,struct token *token);
79#endif