diff options
author | Michiel Van Der Kolk <not.valid@email.address> | 2005-05-08 14:41:41 +0000 |
---|---|---|
committer | Michiel Van Der Kolk <not.valid@email.address> | 2005-05-08 14:41:41 +0000 |
commit | b0e010fc5142acc09b10aa4f6453dd6fbdcb8265 (patch) | |
tree | 10e9186fcc373354ff387efbcb29ff941fee5fcb /apps | |
parent | a559cf2e3949fcc0482b656411ed68c1e79bb245 (diff) | |
download | rockbox-b0e010fc5142acc09b10aa4f6453dd6fbdcb8265.tar.gz rockbox-b0e010fc5142acc09b10aa4f6453dd6fbdcb8265.zip |
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
Diffstat (limited to 'apps')
-rw-r--r-- | apps/plugins/Makefile | 2 | ||||
-rw-r--r-- | apps/plugins/databox/Makefile | 96 | ||||
-rw-r--r-- | apps/plugins/databox/databox.c | 307 | ||||
-rw-r--r-- | apps/plugins/databox/databox.h | 58 | ||||
-rw-r--r-- | apps/plugins/databox/editparser.c | 203 | ||||
-rw-r--r-- | apps/plugins/databox/editparser.h | 34 | ||||
-rw-r--r-- | apps/plugins/databox/edittoken.c | 186 | ||||
-rw-r--r-- | apps/plugins/databox/edittoken.h | 79 |
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 |
45 | ifneq (,$(strip $(foreach tgt,RECORDER IRIVER,$(findstring $(tgt),$(TARGET))))) | 45 | ifneq (,$(strip $(foreach tgt,RECORDER IRIVER,$(findstring $(tgt),$(TARGET))))) |
46 | SUBDIRS += rockboy | 46 | SUBDIRS += rockboy databox |
47 | endif | 47 | endif |
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 | |||
10 | INCLUDES = -I$(APPSDIR) -I.. -I. -I$(FIRMDIR)/include -I$(FIRMDIR)/export \ | ||
11 | -I$(FIRMDIR)/common -I$(FIRMDIR)/drivers -I$(OUTDIR) | ||
12 | CFLAGS = $(GCCOPTS) -O3 $(INCLUDES) $(TARGET) $(EXTRA_DEFINES) \ | ||
13 | -DMEM=${MEMORYSIZE} -DPLUGIN | ||
14 | |||
15 | ifdef APPEXTRA | ||
16 | INCLUDES += -I$(APPSDIR)/$(APPEXTRA) | ||
17 | endif | ||
18 | |||
19 | LINKFILE := $(OBJDIR)/link.lds | ||
20 | DEPFILE = $(OBJDIR)/dep-databox | ||
21 | SRC = databox.c editparser.c edittoken.c | ||
22 | |||
23 | SOURCES = $(SRC) | ||
24 | OBJS := $(SRC:%.c=$(OBJDIR)/%.o) | ||
25 | DIRS = . | ||
26 | |||
27 | LDS := ../plugin.lds | ||
28 | OUTPUT = $(OUTDIR)/databox.rock | ||
29 | |||
30 | all: $(OUTPUT) | ||
31 | |||
32 | ifndef 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 $< $@ | ||
41 | else | ||
42 | |||
43 | ifeq ($(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 $@ | ||
50 | ifeq ($(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 | ||
54 | else | ||
55 | @chmod -x $@ | ||
56 | endif | ||
57 | |||
58 | else # end of x11-simulator | ||
59 | ################################################### | ||
60 | # This is the win32 simulator version | ||
61 | DLLTOOLFLAGS = --export-all | ||
62 | DLLWRAPFLAGS = -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 $@ | ||
69 | ifeq ($(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 | ||
73 | else | ||
74 | @chmod -x $@ | ||
75 | endif | ||
76 | endif # end of win32-simulator | ||
77 | |||
78 | endif # end of simulator section | ||
79 | |||
80 | |||
81 | include $(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 | |||
90 | clean: | ||
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 */ | ||
26 | struct plugin_api* rb; | ||
27 | struct token tokenbuf[200]; | ||
28 | |||
29 | struct print printing; | ||
30 | struct editor editor; | ||
31 | struct editing editing; | ||
32 | |||
33 | extern int acceptedmask; | ||
34 | |||
35 | void 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 | |||
46 | void 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 | |||
60 | void 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 | |||
72 | void 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 */ | ||
126 | int 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 | |||
151 | int 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 | |||
167 | int 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 */ | ||
182 | enum 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 | |||
29 | extern struct plugin_api* rb; | ||
30 | |||
31 | struct print { | ||
32 | struct font *fontfixed; | ||
33 | int font_w,font_h; | ||
34 | int line; | ||
35 | int position; | ||
36 | }; | ||
37 | |||
38 | struct 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 | |||
46 | struct 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 | |||
54 | extern struct print printing; | ||
55 | extern struct editor editor; | ||
56 | extern 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 | |||
23 | struct token *currenttoken,*lasttoken,*tokenstream; | ||
24 | int currentindex; | ||
25 | int lparencount,acceptedmask; | ||
26 | int tokensleft; | ||
27 | int invalid; | ||
28 | int invalid_mode; | ||
29 | |||
30 | void check_accepted(struct token *tstream, int count) { | ||
31 | parse_stream(tstream,count+1,INVALID_EXPERT); | ||
32 | } | ||
33 | |||
34 | void 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 | |||
46 | int 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 | |||
63 | void parse_accept_rparen(void) { | ||
64 | if(!tokensleft) return; | ||
65 | if(lparencount) { | ||
66 | acceptedmask|=ACCEPT_RPAREN; | ||
67 | } | ||
68 | } | ||
69 | |||
70 | void parse_accept(int bitmask) { | ||
71 | if(!tokensleft) return; | ||
72 | acceptedmask|=bitmask; | ||
73 | if(lparencount) { | ||
74 | acceptedmask&=~ACCEPT_EOF; | ||
75 | } | ||
76 | } | ||
77 | |||
78 | void 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 | |||
154 | void parseCompareNum() { | ||
155 | parse_accept(ACCEPT_NUMOP); | ||
156 | parse_checktoken(); | ||
157 | parse_accept(ACCEPT_NUMARG); | ||
158 | parse_checktoken(); | ||
159 | } | ||
160 | |||
161 | void parseCompareString() { | ||
162 | parse_accept(ACCEPT_STROP); | ||
163 | parse_checktoken(); | ||
164 | parse_accept(ACCEPT_STRARG); | ||
165 | parse_checktoken(); | ||
166 | } | ||
167 | |||
168 | void 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 | |||
190 | void 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 | ****************************************************************************/ | ||
19 | extern int acceptedmask; | ||
20 | |||
21 | #define INVALID_STRIP 1 | ||
22 | #define INVALID_MARK 2 | ||
23 | #define INVALID_EXPERT 3 | ||
24 | |||
25 | void check_accepted(struct token *tstream, int count); | ||
26 | void parse_stream(struct token *tstream, int count, int inv_mode); | ||
27 | int check_tokenstream(struct token *tstream, int inv_mode); | ||
28 | void parser_accept_rparen(void); | ||
29 | void parser_accept(int bitmask); | ||
30 | void parse_checktoken(void); | ||
31 | void parseCompareNum(void); | ||
32 | void parseCompareString(void); | ||
33 | void parseExpr(void); | ||
34 | 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 @@ | |||
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 | |||
22 | char *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 | |||
56 | char *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 | |||
65 | char *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 | |||
76 | char bufbla[40]; | ||
77 | |||
78 | void 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 | |||
135 | void 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 | |||
144 | void 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 | |||
158 | char *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 | |||
71 | struct token { | ||
72 | char kind; | ||
73 | char spelling[255]; | ||
74 | long intvalue; | ||
75 | }; | ||
76 | char *tokentypetostring(int tokentype); | ||
77 | char *tokentostring(struct token *token); | ||
78 | void buildtoken(int tokentype,struct token *token); | ||
79 | #endif | ||