This source file includes following definitions.
- singlechar
- get_next_token
- tokenizer_init
- tokenizer_token
- tokenizer_next
- tokenizer_num
- tokenizer_string
- tokenizer_label
- tokenizer_error_print
- tokenizer_finished
- tokenizer_variable_num
- tokenizer_line_number
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #if DEBUG
32 #define DEBUG_PRINTF(...) printf(__VA_ARGS__)
33 #else
34 #define DEBUG_PRINTF(...)
35 #endif
36
37 #include "stdlib.h"
38 #include "stddef.h"
39 #include "string.h"
40 #include "ctype.h"
41 #include "stdio.h"
42
43 #include "tokenizer.h"
44
45 static char const *ptr, *nextptr;
46
47 #define MAX_NUMLEN 6
48
49 struct keyword_token {
50 const char *keyword;
51 int token;
52 };
53
54 static ubasic_token current_token = TOKENIZER_ERROR;
55 static int current_line = 0;
56
57 static const struct keyword_token keywords[] = {
58 {"<>", TOKENIZER_NE},
59 {"<=", TOKENIZER_LE},
60 {">=", TOKENIZER_GE},
61 {"<", TOKENIZER_LT},
62 {">", TOKENIZER_GT},
63 {"not", TOKENIZER_LNOT},
64 {"or", TOKENIZER_LOR},
65 {"and", TOKENIZER_LAND},
66
67 {"let", TOKENIZER_LET},
68 {"if", TOKENIZER_IF},
69 {"then", TOKENIZER_THEN},
70 {"else", TOKENIZER_ELSE},
71 {"endif", TOKENIZER_ENDIF},
72 {"select", TOKENIZER_SELECT},
73 {"case_else", TOKENIZER_CASE_ELSE},
74 {"case", TOKENIZER_CASE},
75 {"end_select", TOKENIZER_END_SELECT},
76 {"force_analog_av", TOKENIZER_FORCE_ANALOG_AV},
77 {"for", TOKENIZER_FOR},
78 {"to", TOKENIZER_TO},
79 {"next", TOKENIZER_NEXT},
80 {"step", TOKENIZER_STEP},
81 {"do", TOKENIZER_DO},
82 {"until", TOKENIZER_UNTIL},
83 {"while", TOKENIZER_WHILE},
84 {"wend", TOKENIZER_WEND},
85 {"goto", TOKENIZER_GOTO},
86 {"gosub", TOKENIZER_GOSUB},
87 {"return", TOKENIZER_RETURN},
88 {"rem", TOKENIZER_REM},
89 {"cls", TOKENIZER_CLS},
90 {"print_screen", TOKENIZER_PRINT_SCREEN},
91 {"print", TOKENIZER_PRINT},
92 {"random", TOKENIZER_RANDOM},
93 {"click", TOKENIZER_CLICK},
94 {"playsound", TOKENIZER_PLAY_SOUND},
95 {"press", TOKENIZER_PRESS},
96 {"release", TOKENIZER_RELEASE},
97
98 {"shoot", TOKENIZER_SHOOT},
99 {"set_console_layout", TOKENIZER_SET_CONSOLE_LAYOUT},
100 {"set_console_autoredraw", TOKENIZER_SET_CONSOLE_AUTOREDRAW},
101 {"console_redraw", TOKENIZER_CONSOLE_REDRAW},
102 {"sleep", TOKENIZER_SLEEP},
103
104
105
106 {"get_av96", TOKENIZER_GET_AV96},
107 {"get_av", TOKENIZER_GET_USER_AV_ID},
108 {"get_bv96", TOKENIZER_GET_BV96},
109 {"get_canon_image_format", TOKENIZER_GET_CANON_IMAGE_FORMAT},
110 {"get_canon_raw_support", TOKENIZER_GET_CANON_RAW_SUPPORT},
111 {"get_capture_mode", TOKENIZER_GET_CAPTURE_MODE},
112 {"get_current_av96", TOKENIZER_GET_CURRENT_AV96},
113 {"get_current_tv96", TOKENIZER_GET_CURRENT_TV96},
114 {"get_current_base_sv96", TOKENIZER_GET_CURRENT_BASE_SV96},
115 {"get_current_delta_sv96", TOKENIZER_GET_CURRENT_DELTA_SV96},
116 {"get_digic", TOKENIZER_GET_DIGIC},
117 {"get_display_mode", TOKENIZER_GET_DISPLAY_MODE},
118 {"get_day_seconds", TOKENIZER_GET_DAY_SECONDS},
119 {"get_disk_size", TOKENIZER_GET_DISK_SIZE},
120 {"get_dof", TOKENIZER_GET_DOF},
121 {"get_far_limit", TOKENIZER_GET_FAR_LIMIT},
122 {"get_free_disk_space", TOKENIZER_GET_FREE_DISK_SPACE},
123 {"get_focal_length", TOKENIZER_GET_FOCAL_LENGTH},
124 {"get_focus_mode", TOKENIZER_GET_FOCUS_MODE},
125 {"get_focus_ok", TOKENIZER_GET_FOCUS_OK},
126 {"get_focus_state", TOKENIZER_GET_FOCUS_STATE},
127 {"get_focus", TOKENIZER_GET_FOCUS},
128 {"get_sd_over_modes", TOKENIZER_GET_SD_OVER_MODES},
129 {"get_hyp_dist", TOKENIZER_GET_HYPERFOCAL_DIST},
130 {"get_imager_active", TOKENIZER_GET_IMAGER_ACTIVE},
131 {"get_iso_market", TOKENIZER_GET_ISO_MARKET},
132 {"get_iso_mode", TOKENIZER_GET_ISO_MODE},
133 {"get_iso_real", TOKENIZER_GET_ISO_REAL},
134 {"get_iso", TOKENIZER_GET_ISO_MODE},
135 {"get_jpg_count", TOKENIZER_GET_JPG_COUNT},
136 {"get_max_av96", TOKENIZER_GET_MAX_AV96},
137 {"get_min_av96", TOKENIZER_GET_MIN_AV96},
138 {"get_min_stack_dist", TOKENIZER_GET_MIN_STACK_DIST},
139 {"get_movie_status", TOKENIZER_GET_MOVIE_STATUS},
140 {"get_mode", TOKENIZER_GET_MODE},
141 {"get_nd_value_ev96", TOKENIZER_GET_ND_VALUE_EV96},
142 {"get_nd_current_ev96", TOKENIZER_GET_ND_CURRENT_EV96},
143 {"get_near_limit", TOKENIZER_GET_NEAR_LIMIT},
144 {"get_platform_id", TOKENIZER_GET_PLATFORM_ID},
145 {"get_propset", TOKENIZER_GET_PROPSET},
146 {"get_prop", TOKENIZER_GET_PROP},
147 {"get_quality", TOKENIZER_GET_QUALITY},
148 {"get_raw_support", TOKENIZER_GET_RAW_SUPPORT},
149 {"get_raw_count", TOKENIZER_GET_RAW_COUNT},
150 {"get_raw_nr", TOKENIZER_GET_RAW_NR},
151 {"get_raw", TOKENIZER_GET_RAW},
152 {"get_resolution", TOKENIZER_GET_RESOLUTION},
153 {"get_sv96", TOKENIZER_GET_SV96},
154 {"get_temperature", TOKENIZER_GET_TEMPERATURE},
155 {"get_tick_count", TOKENIZER_GET_TICK_COUNT},
156 {"get_time", TOKENIZER_GET_TIME},
157 {"get_tv96", TOKENIZER_GET_TV96},
158 {"get_user_av_id", TOKENIZER_GET_USER_AV_ID},
159 {"get_user_av96", TOKENIZER_GET_USER_AV96},
160 {"get_user_tv_id", TOKENIZER_GET_USER_TV_ID},
161 {"get_user_tv96", TOKENIZER_GET_USER_TV96},
162 {"get_video_recording", TOKENIZER_GET_VIDEO_RECORDING},
163 {"get_video_button", TOKENIZER_GET_VIDEO_BUTTON},
164 {"get_vbatt", TOKENIZER_GET_VBATT},
165 {"get_zoom_steps", TOKENIZER_GET_ZOOM_STEPS},
166 {"get_zoom", TOKENIZER_GET_ZOOM},
167 {"get_exp_count", TOKENIZER_GET_EXP_COUNT},
168 {"get_config_value", TOKENIZER_GET_CONFIG_VALUE},
169 {"swap_partitions", TOKENIZER_SWAP_PARTITIONS},
170
171 {"set_av96_direct", TOKENIZER_SET_AV96_DIRECT},
172 {"set_av_rel", TOKENIZER_SET_USER_AV_BY_ID_REL},
173 {"set_av96", TOKENIZER_SET_AV96},
174 {"set_av", TOKENIZER_SET_USER_AV_BY_ID},
175 {"set_canon_image_format", TOKENIZER_SET_CANON_IMAGE_FORMAT},
176 {"set_capture_mode_canon", TOKENIZER_SET_CAPTURE_MODE_CANON},
177 {"set_capture_mode", TOKENIZER_SET_CAPTURE_MODE},
178 {"set_backlight", TOKENIZER_SET_BACKLIGHT},
179 {"set_lcd_display", TOKENIZER_SET_LCDDISPLAY},
180 {"set_draw_title_line", TOKENIZER_SET_DRAW_TITLE_LINE},
181 {"get_draw_title_line", TOKENIZER_GET_DRAW_TITLE_LINE},
182 {"set_focus", TOKENIZER_SET_FOCUS},
183 {"set_iso_mode", TOKENIZER_SET_ISO_MODE},
184 {"set_iso_real", TOKENIZER_SET_ISO_REAL},
185 {"set_iso", TOKENIZER_SET_ISO_MODE},
186 {"set_led", TOKENIZER_SET_LED},
187 {"set_movie_status", TOKENIZER_SET_MOVIE_STATUS},
188 {"set_nd_filter", TOKENIZER_SET_ND_FILTER},
189 {"set_prop", TOKENIZER_SET_PROP},
190 {"set_quality", TOKENIZER_SET_QUALITY},
191 {"set_raw_nr", TOKENIZER_SET_RAW_NR},
192 {"set_raw", TOKENIZER_SET_RAW},
193 {"set_resolution", TOKENIZER_SET_RESOLUTION},
194 {"set_remote_timing", TOKENIZER_SET_REMOTE_TIMING},
195 {"set_sv96", TOKENIZER_SET_SV96},
196 {"set_tv96_direct", TOKENIZER_SET_TV96_DIRECT},
197 {"set_tv_rel", TOKENIZER_SET_USER_TV_BY_ID_REL},
198 {"set_tv96", TOKENIZER_SET_TV96},
199 {"set_tv", TOKENIZER_SET_USER_TV_BY_ID},
200 {"set_user_av_by_id_rel", TOKENIZER_SET_USER_AV_BY_ID_REL},
201 {"set_user_av_by_id", TOKENIZER_SET_USER_AV_BY_ID},
202 {"set_user_av96", TOKENIZER_SET_USER_AV96},
203 {"set_user_tv_by_id_rel", TOKENIZER_SET_USER_TV_BY_ID_REL},
204 {"set_user_tv_by_id", TOKENIZER_SET_USER_TV_BY_ID},
205 {"set_user_tv96", TOKENIZER_SET_USER_TV96},
206 {"set_zoom_speed", TOKENIZER_SET_ZOOM_SPEED},
207 {"set_zoom_rel", TOKENIZER_SET_ZOOM_REL},
208 {"set_zoom", TOKENIZER_SET_ZOOM},
209 {"set_record", TOKENIZER_SET_RECORD},
210 {"set_config_value", TOKENIZER_SET_CONFIG_VALUE},
211 {"set_yield", TOKENIZER_SET_YIELD},
212
213 {"wait_click", TOKENIZER_WAIT_CLICK},
214 {"is_pressed", TOKENIZER_IS_PRESSED},
215 {"is_key", TOKENIZER_IS_KEY},
216 {"set_exit_key", TOKENIZER_SET_EXIT_KEY},
217
218 {"wheel_right", TOKENIZER_WHEEL_RIGHT},
219 {"wheel_left", TOKENIZER_WHEEL_LEFT},
220
221 {"@title", TOKENIZER_REM},
222 {"@subtitle", TOKENIZER_REM},
223 {"@param", TOKENIZER_REM},
224 {"@default", TOKENIZER_REM},
225 {"@range", TOKENIZER_REM},
226 {"@values", TOKENIZER_REM},
227 {"@chdk_version", TOKENIZER_REM},
228
229 {"md_detect_motion", TOKENIZER_MD_DETECT_MOTION},
230 {"md_get_cell_diff", TOKENIZER_MD_GET_CELL_DIFF},
231 {"md_get_cell_val", TOKENIZER_MD_GET_CELL_VAL},
232 {"md_af_led_control", TOKENIZER_MD_AF_LED_CONTROL},
233 {"autostarted", TOKENIZER_SCRIPT_AUTOSTARTED},
234 {"get_autostart", TOKENIZER_GET_SCRIPT_AUTOSTART},
235 {"set_autostart", TOKENIZER_SET_SCRIPT_AUTOSTART},
236 {"get_usb_power", TOKENIZER_GET_USB_POWER},
237 {"usb_force_active", TOKENIZER_FORCE_USB_PRESENT},
238 {"usb_sync_wait", TOKENIZER_USB_SYNC_WAIT},
239 {"exit_alt", TOKENIZER_EXIT_ALT},
240 {"enter_alt", TOKENIZER_ENTER_ALT},
241 {"get_alt_mode", TOKENIZER_GET_ALT_MODE},
242 {"shut_down", TOKENIZER_SHUT_DOWN},
243
244 {"get_shooting", TOKENIZER_GET_SHOOTING},
245 {"get_drive_mode", TOKENIZER_GET_DRIVE_MODE},
246 {"get_flash_mode", TOKENIZER_GET_FLASH_MODE},
247 {"get_flash_ready", TOKENIZER_GET_FLASH_READY},
248 {"get_IS_mode", TOKENIZER_GET_IS_MODE},
249 {"set_ev", TOKENIZER_SET_EV},
250 {"get_ev", TOKENIZER_GET_EV},
251 {"get_orientation_sensor", TOKENIZER_GET_ORIENTATION_SENSOR},
252 {"get_nd_present", TOKENIZER_GET_ND_PRESENT},
253 {"get_histo_range", TOKENIZER_GET_HISTO_RANGE},
254 {"shot_histo_enable", TOKENIZER_SHOT_HISTO_ENABLE},
255 {"set_aelock", TOKENIZER_SET_AELOCK},
256 {"set_aflock", TOKENIZER_SET_AFLOCK},
257 {"set_mf", TOKENIZER_SET_MF},
258 {"is_capture_mode_valid", TOKENIZER_IS_CAPTURE_MODE_VALID},
259 {"reboot", TOKENIZER_REBOOT},
260
261
262 {"iso_to_sv96", TOKENIZER_ISO_TO_SV96},
263 {"sv96_to_iso", TOKENIZER_SV96_TO_ISO},
264 {"iso_real_to_market", TOKENIZER_ISO_REAL_TO_MARKET},
265 {"iso_market_to_real", TOKENIZER_ISO_MARKET_TO_REAL},
266 {"sv96_real_to_market", TOKENIZER_SV96_REAL_TO_MARKET},
267 {"sv96_market_to_real", TOKENIZER_SV96_MARKET_TO_REAL},
268 {"aperture_to_av96", TOKENIZER_APERTURE_TO_AV96},
269 {"av96_to_aperture", TOKENIZER_AV96_TO_APERTURE},
270 {"usec_to_tv96", TOKENIZER_USEC_TO_TV96},
271 {"tv96_to_usec", TOKENIZER_TV96_TO_USEC},
272 {"seconds_to_tv96", TOKENIZER_SECONDS_TO_TV96},
273
274 {"end", TOKENIZER_END},
275
276 {NULL, TOKENIZER_ERROR}
277 };
278
279
280 static int
281 singlechar(void)
282 {
283 if(*ptr == '\n') {
284 return TOKENIZER_CR;
285 } else if(*ptr == ',') {
286 return TOKENIZER_COMMA;
287 } else if(*ptr == ';') {
288 return TOKENIZER_SEMICOLON;
289 } else if(*ptr == '+') {
290 return TOKENIZER_PLUS;
291 } else if(*ptr == '-') {
292 return TOKENIZER_MINUS;
293 } else if(*ptr == '&') {
294 return TOKENIZER_AND;
295 } else if(*ptr == '|') {
296 return TOKENIZER_OR;
297 } else if(*ptr == '^') {
298 return TOKENIZER_XOR;
299 } else if(*ptr == '*') {
300 return TOKENIZER_ASTR;
301 } else if(*ptr == '/') {
302 return TOKENIZER_SLASH;
303 } else if(*ptr == '%') {
304 return TOKENIZER_MOD;
305 } else if(*ptr == '(') {
306 return TOKENIZER_LEFTPAREN;
307 } else if(*ptr == ')') {
308 return TOKENIZER_RIGHTPAREN;
309 } else if(*ptr == '=') {
310 return TOKENIZER_EQ;
311 }
312 return 0;
313 }
314
315 static int
316 get_next_token(void)
317 {
318 struct keyword_token const *kt;
319 int i;
320
321 DEBUG_PRINTF("get_next_token(): '%s'\n", ptr);
322
323
324 while(*ptr == ' ' || *ptr == '\t' || *ptr == '\r') ptr++;
325
326 if(*ptr == 0) {
327 return TOKENIZER_ENDOFINPUT;
328 }
329
330
331 nextptr = ptr + 1;
332
333 if(isdigit(*ptr)) {
334 for(i = 0; i < (MAX_NUMLEN+1); ++i) {
335 if(!isdigit(ptr[i])) {
336 if(i > 0) {
337 nextptr = ptr + i;
338 return TOKENIZER_NUMBER;
339 } else {
340 DEBUG_PRINTF("get_next_token: error due to too short number\n");
341 return TOKENIZER_ERROR;
342 }
343 }
344 if(!isdigit(ptr[i])) {
345 DEBUG_PRINTF("get_next_token: error due to malformed number\n");
346 return TOKENIZER_ERROR;
347 }
348 }
349 DEBUG_PRINTF("get_next_token: error due to too long number\n");
350 return TOKENIZER_ERROR;
351 } else if(*ptr == ':') {
352
353 nextptr = ptr;
354 do {
355 ++nextptr;
356 } while(*nextptr != ' ' && *nextptr != '\r' && *nextptr != '\n' && *nextptr != '\t');
357 return TOKENIZER_LABEL;
358 } else if((i=singlechar()) != 0) {
359 if (i == TOKENIZER_CR){
360
361 while (singlechar() == TOKENIZER_CR)
362 {
363 current_line++;
364 ptr++;
365
366 while(*ptr == ' ' || *ptr == '\t' || *ptr == '\r') ptr++;
367 };
368 ptr--;
369
370
371 }
372 nextptr = ptr + 1;
373 return i;
374 } else if(*ptr == '"') {
375 nextptr = ptr;
376 do {
377 ++nextptr;
378 } while(*nextptr != '"');
379 ++nextptr;
380 return TOKENIZER_STRING;
381 } else {
382 for(kt = keywords; kt->keyword != NULL; ++kt) {
383 if(strncmp(ptr, kt->keyword, strlen(kt->keyword)) == 0) {
384 nextptr = ptr + strlen(kt->keyword);
385 if (kt->token == TOKENIZER_REM) {
386 while(*nextptr != 0 && *nextptr != '\r' && *nextptr != '\n') ++nextptr;
387 }
388 return kt->token;
389 }
390 }
391 }
392
393 if((*ptr >= 'a' && *ptr <= 'z') || (*ptr >= 'A' && *ptr <= 'Z')) {
394 nextptr = ptr + 1;
395 return TOKENIZER_VARIABLE;
396 }
397
398
399 return TOKENIZER_ERROR;
400 }
401
402 void
403 tokenizer_init(const char *program)
404 {
405 ptr = program;
406 current_line = 1;
407 current_token = get_next_token();
408 while (current_token==TOKENIZER_CR && !tokenizer_finished()) tokenizer_next();
409 }
410
411 int
412 tokenizer_token(void)
413 {
414 return current_token;
415 }
416
417 void
418 tokenizer_next(void)
419 {
420
421 if(tokenizer_finished()) {
422 return;
423 }
424
425 DEBUG_PRINTF("tokenizer_next: %p\n", nextptr);
426 ptr = nextptr;
427 while((*ptr == ' ') || (*ptr == '\t')) {
428 ++ptr;
429 }
430 current_token = get_next_token();
431 DEBUG_PRINTF("tokenizer_next: '%s' %d\n", ptr, current_token);
432 return;
433 }
434
435 int
436 tokenizer_num(void)
437 {
438 return atoi(ptr);
439 }
440
441 void
442 tokenizer_string(char *dest, int len)
443 {
444 char *string_end;
445 int string_len;
446
447 if(tokenizer_token() != TOKENIZER_STRING) {
448 return;
449 }
450 string_end = strchr(ptr + 1, '"');
451 if(string_end == NULL) {
452 return;
453 }
454 string_len = string_end - ptr - 1;
455 if(len < string_len) {
456 string_len = len;
457 }
458 memcpy(dest, ptr + 1, string_len);
459 dest[string_len] = 0;
460 }
461
462 void
463 tokenizer_label(char *dest, int len)
464 {
465 char *string_end;
466 int string_len;
467
468 if(tokenizer_token() != TOKENIZER_LABEL) {
469 return;
470 }
471
472 string_end = strpbrk(ptr + 1, " \t\r\n");
473
474 if(string_end == NULL) {
475 return;
476 }
477 string_len = string_end - ptr - 1;
478 if(len < string_len) {
479 string_len = len;
480 }
481 memcpy(dest, ptr + 1, string_len);
482 dest[string_len] = 0;
483 }
484
485 void
486 tokenizer_error_print(void)
487 {
488 DEBUG_PRINTF("tokenizer_error_print: '%s'\n", ptr);
489 }
490
491 int
492 tokenizer_finished(void)
493 {
494 return *ptr == 0 || current_token == TOKENIZER_ENDOFINPUT;
495 }
496
497 int
498 tokenizer_variable_num(void)
499 {
500 return *ptr - (*ptr>='a'?'a':('A'-26));
501 }
502
503 int tokenizer_line_number(void)
504 {
505 return current_line;
506 }