root/lib/ubasic/ubasic.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. ubasic_linenumber
  2. ubasic_init
  3. ubasic_get_key_arg
  4. accept
  5. accept_cr
  6. varfactor
  7. shooting_get_near_limit_of_acceptable_sharpness
  8. shooting_get_far_limit_of_acceptable_sharpness
  9. shooting_get_depth_of_field
  10. shooting_get_min_stack_distance
  11. factor
  12. term
  13. expr
  14. relation
  15. jump_linenum
  16. jump_line
  17. jump_label
  18. goto_statement
  19. print_statement
  20. endif_statement
  21. if_statement
  22. else_statement
  23. dec_select_stack
  24. end_select_statement
  25. case_statement
  26. case_else_statement
  27. select_statement
  28. let_statement
  29. rem_statement
  30. cls_statement
  31. gosub_statement
  32. return_statement
  33. next_statement
  34. for_statement
  35. do_statement
  36. until_statement
  37. while_statement
  38. wend_statement
  39. end_statement
  40. click_statement
  41. press_statement
  42. release_statement
  43. action_stack_AS_UBASIC_SLEEP
  44. sleep_delay
  45. sleep_statement
  46. shoot_statement
  47. set_console_layout
  48. set_console_autoredraw
  49. console_redraw_statement
  50. set_yield_statement
  51. get_short_var_statement
  52. get_int_var_statement
  53. get_prop_statement
  54. one_int_param_function
  55. one_short_param_function
  56. set_ev_statement
  57. set_movie_status_statement
  58. set_propcase_statement
  59. set_mf_statement
  60. set_focus_statement
  61. set_led_statement
  62. set_prop_statement
  63. set_autostart_statement
  64. set_capture_mode_canon_statement
  65. reboot_statement
  66. set_config_value_statement
  67. action_stack_AS_UBASIC_WAIT_CLICK
  68. wait_click_statement
  69. is_key_statement
  70. set_exit_key_statement
  71. get_config_value_statement
  72. on_off_statement
  73. shutdown_statement
  74. uB_set_av96
  75. uB_set_av96_direct
  76. uB_set_tv96
  77. uB_set_tv96_direct
  78. uB_set_sv96
  79. uB_set_nd_filter_state
  80. uB_set_iso_real
  81. md_get_cell_diff_statement
  82. md_get_cell_val_statement
  83. md_detect_motion_statement
  84. _shot_histogram_set
  85. statement
  86. line_statement
  87. ubasic_run
  88. ubasic_set_variable
  89. ubasic_get_variable
  90. ubasic_end
  91. ubasic_set_as_ret

   1 /*
   2  * Copyright (c) 2006, Adam Dunkels
   3  * All rights reserved.
   4  *
   5  * Redistribution and use in source and binary forms, with or without
   6  * modification, are permitted provided that the following conditions
   7  * are met:
   8  * 1. Redistributions of source code must retain the above copyright
   9  *    notice, this list of conditions and the following disclaimer.
  10  * 2. Redistributions in binary form must reproduce the above copyright
  11  *    notice, this list of conditions and the following disclaimer in the
  12  *    documentation and/or other materials provided with the distribution.
  13  * 3. Neither the name of the author nor the names of its contributors
  14  *    may be used to endorse or promote products derived from this software
  15  *    without specific prior written permission.
  16  *
  17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  27  * SUCH DAMAGE.
  28  *
  29  */
  30 
  31 #if DEBUG
  32 #define DEBUG_PRINTF(...)  printf(__VA_ARGS__)
  33 #else
  34 #define DEBUG_PRINTF(...)
  35 #endif
  36 
  37 #include "camera_info.h"
  38 #include "shot_histogram.h"
  39 #include "levent.h"
  40 #include "script.h"
  41 #include "console.h"
  42 #include "conf.h"
  43 #include "lang.h"
  44 #include "gui_lang.h"
  45 #include "action_stack.h"
  46 #include "shooting.h"
  47 #include "sd_card.h"
  48 #include "backlight.h"
  49 #include "battery.h"
  50 #include "temperature.h"
  51 #include "clock.h"
  52 #include "file_counter.h"
  53 #include "lens.h"
  54 #include "debug_led.h"
  55 #include "keyboard.h"
  56 #include "usb_remote.h"
  57 #include "shutdown.h"
  58 #include "sound.h"
  59 #include "motion_detector.h"
  60 
  61 #include "string.h"
  62 #include "time.h"
  63 
  64 #ifdef UBASIC_TEST
  65 #include "camera_functions.h"
  66 Conf conf;                      // TODO: initialisation
  67 _cam_info camera_info;          // TOTO: initialisation
  68 #else
  69 #include "script_key_funcs.h"
  70 #include "properties.h"
  71 #endif
  72 
  73 #include "ubasic.h"
  74 #include "tokenizer.h"
  75 
  76 // Forward references
  77 int ubasic_get_variable(int varnum);
  78 void ubasic_set_variable(int varum, int value);
  79 
  80 #define INCLUDE_OLD_GET__SYNTAX
  81 
  82 static char const *program_ptr;
  83 #define MAX_STRINGLEN 40
  84 static char string[MAX_STRINGLEN];
  85 
  86 #define MAX_GOSUB_STACK_DEPTH 10
  87 static short gosub_stack[MAX_GOSUB_STACK_DEPTH];
  88 static int gosub_stack_ptr;
  89 
  90 #define MAX_IF_STACK_DEPTH 4
  91 static short if_stack[MAX_IF_STACK_DEPTH];
  92 static int if_stack_ptr;
  93 
  94 struct select_state {
  95   int select_value;
  96   short case_run;
  97 };
  98 #define MAX_SELECT_STACK_DEPTH 4
  99 static struct select_state select_stack[MAX_SELECT_STACK_DEPTH];
 100 static int select_stack_ptr;
 101 
 102 #define MAX_WHILE_STACK_DEPTH 4
 103 static short while_stack[MAX_WHILE_STACK_DEPTH];
 104 static int while_stack_ptr;
 105 
 106 #define MAX_DO_STACK_DEPTH 4
 107 static short do_stack[MAX_DO_STACK_DEPTH];
 108 static int do_stack_ptr;
 109 
 110 struct for_state {
 111   short line_after_for;
 112   short for_variable;
 113   int to;
 114   int step;
 115 };
 116 #define MAX_FOR_STACK_DEPTH 4
 117 static struct for_state for_stack[MAX_FOR_STACK_DEPTH];
 118 static int for_stack_ptr;
 119 
 120 #define MAX_VARNUM 52
 121 static int variables[MAX_VARNUM];
 122 
 123 static int ended;
 124 
 125 // Variable number to store return values from Action Stack functions (e.g. motion_detect, shoot)
 126 static int ubasic_as_ret_var_num;
 127 
 128 static int expr(void);
 129 static void line_statement(void);
 130 static void statement(void);
 131 static int relation(void);
 132 
 133 /*
 134 ubasic scheduling controls
 135 ubasic returns control to kbd_task as soon as either of the following is is exceeded
 136 defaults is 1 ubasic line per kbd_task cycle, mimicing old behavior
 137 */
 138 #define YIELD_MAX_LINES_DEFAULT 1
 139 #define YIELD_MAX_MS_DEFAULT 10
 140 // maximum number lines before yielding (labels, blank lines and REMs excluded)
 141 static unsigned yield_max_lines;
 142 // maximum number of ticks before yielding
 143 static unsigned yield_max_ms;
 144 // set flag to immediately transfer execution flow to main CHDK to process external action
 145 // TODO a better approach to this might be to check if AS_RUN is on top of the action_stack
 146 static int flag_yield;
 147 
 148 int ubasic_error;
 149 const char *ubasic_errstrings[UBASIC_E_ENDMARK] =
 150 {
 151     "No err",
 152     "Parse err",
 153     "Unk stmt",
 154     "Unk key",
 155     "Unk label",
 156     "gosub: Stack ful",
 157     "bad return",
 158     "if: Stack ful",
 159     "bad endif",
 160     "select: Stack ful",
 161     "bad end_select",
 162     "for: Stack ful",
 163     "bad next",
 164     "do: Stack ful",
 165     "bad until",
 166     "while: Stack ful",
 167     "bad wend",
 168     "Unk err" 
 169 };
 170 
 171 /*---------------------------------------------------------------------------*/
 172 int
 173 ubasic_linenumber()
 174 {
 175   return tokenizer_line_number();
 176 }
 177 
 178 /*---------------------------------------------------------------------------*/
 179 int
 180 ubasic_init(const char *program, __attribute__ ((unused))int is_ptp)
 181 {
 182   program_ptr = program;
 183   flag_yield = 0;
 184   for_stack_ptr = gosub_stack_ptr = while_stack_ptr = do_stack_ptr = if_stack_ptr = select_stack_ptr = 0;
 185   tokenizer_init(program);
 186   ended = 0;
 187   ubasic_error = UBASIC_E_NONE;
 188   yield_max_lines = YIELD_MAX_LINES_DEFAULT;
 189   yield_max_ms = YIELD_MAX_MS_DEFAULT;
 190   return 1;
 191 }
 192 /*---------------------------------------------------------------------------*/
 193 // read a key name and return key id, 
 194 // set error and return 0 if key invalid
 195 static int ubasic_get_key_arg() {
 196   int k;
 197   tokenizer_string(string, sizeof(string));
 198   tokenizer_next();
 199   k = script_keyid_by_name(string);
 200   if (k <= 0)
 201     ubasic_error = UBASIC_E_UNK_KEY;
 202   return k;
 203 }
 204 /*---------------------------------------------------------------------------*/
 205 static void
 206 accept(int token)
 207 {
 208   if(token != tokenizer_token()) {
 209     DEBUG_PRINTF("Token not what was expected (expected %d, got %d)\n",
 210                  token, tokenizer_token());
 211     tokenizer_error_print();
 212      tokenizer_next();
 213      ended = 1;
 214      ubasic_error = UBASIC_E_PARSE;
 215      return;
 216   }
 217   DEBUG_PRINTF("Expected %d, got it\n", token);
 218   tokenizer_next();
 219 }
 220 /*---------------------------------------------------------------------------*/
 221 static void
 222 accept_cr()
 223 {
 224     while(tokenizer_token() != TOKENIZER_CR &&
 225             tokenizer_token() != TOKENIZER_ENDOFINPUT)
 226       tokenizer_next();
 227     accept(TOKENIZER_CR);
 228 }
 229 /*---------------------------------------------------------------------------*/
 230 static int
 231 varfactor(void)
 232 {
 233   int r;
 234   DEBUG_PRINTF("varfactor: obtaining %d from variable %d\n", variables[tokenizer_variable_num()], tokenizer_variable_num());
 235   r = ubasic_get_variable(tokenizer_variable_num());
 236   accept(TOKENIZER_VARIABLE);
 237   return r;
 238 }
 239 /*---------------------------------------------------------------------------*/
 240 static int shooting_get_near_limit_of_acceptable_sharpness()
 241 {
 242   shooting_update_dof_values();
 243   return camera_info.dof_values.near_limit;
 244 }
 245 
 246 static int shooting_get_far_limit_of_acceptable_sharpness()
 247 {
 248   shooting_update_dof_values();
 249   return camera_info.dof_values.far_limit;
 250 }
 251 
 252 static int shooting_get_depth_of_field()
 253 {
 254   shooting_update_dof_values();
 255   return camera_info.dof_values.depth_of_field;
 256 }
 257 
 258 static int shooting_get_min_stack_distance()
 259 {
 260   shooting_update_dof_values();
 261   return camera_info.dof_values.min_stack_distance;
 262 }
 263 
 264 static int factor(void)
 265 {
 266   int r = 0;
 267   tConfigVal configVal;
 268 
 269   DEBUG_PRINTF("factor: token %d\n", tokenizer_token());
 270   switch(tokenizer_token()) {
 271   case TOKENIZER_NUMBER:
 272     r = tokenizer_num();
 273     DEBUG_PRINTF("factor: number %d\n", r);
 274     accept(TOKENIZER_NUMBER);
 275     break;
 276   case TOKENIZER_LEFTPAREN:
 277     accept(TOKENIZER_LEFTPAREN);
 278     r = relation();
 279     accept(TOKENIZER_RIGHTPAREN);
 280     break;
 281   case TOKENIZER_PLUS:
 282     accept(TOKENIZER_PLUS);
 283     r = factor();
 284     break;
 285   case TOKENIZER_MINUS:
 286     accept(TOKENIZER_MINUS);
 287     r = - factor();
 288     break;
 289   case TOKENIZER_LNOT:
 290     accept(TOKENIZER_LNOT);
 291     r = ! relation();
 292     break;
 293   case TOKENIZER_GET_VBATT:
 294     accept(TOKENIZER_GET_VBATT);
 295     r = (unsigned short) stat_get_vbatt();
 296     break;
 297   case TOKENIZER_GET_DAY_SECONDS:
 298     {
 299         accept(TOKENIZER_GET_DAY_SECONDS);
 300         struct tm *ttm;
 301         ttm = get_localtime();
 302         r = ttm->tm_hour * 3600 + ttm->tm_min * 60 + ttm->tm_sec;
 303     }
 304     break;
 305   case TOKENIZER_GET_TICK_COUNT:
 306     accept(TOKENIZER_GET_TICK_COUNT);
 307     r = get_tick_count();     
 308     break;
 309   case TOKENIZER_GET_MODE:
 310     accept(TOKENIZER_GET_MODE);
 311     if (!camera_info.state.mode_play) r = 0;
 312     if (camera_info.state.mode_play) r = 1;
 313     if (!camera_info.state.mode_play && camera_info.state.mode_video) r = 2;
 314   break;
 315   case TOKENIZER_GET_RAW_NR:
 316     accept(TOKENIZER_GET_RAW_NR);
 317     r = conf.raw_nr;     
 318     break;
 319   case TOKENIZER_IS_KEY:
 320     accept(TOKENIZER_IS_KEY);
 321     r = script_key_is_clicked(ubasic_get_key_arg());
 322     break;
 323   case TOKENIZER_SCRIPT_AUTOSTARTED:
 324     accept(TOKENIZER_SCRIPT_AUTOSTARTED);
 325     r = camera_info.state.auto_started;
 326     break;
 327   case TOKENIZER_GET_SCRIPT_AUTOSTART:
 328     accept(TOKENIZER_GET_SCRIPT_AUTOSTART);
 329 #ifdef UBASIC_TEST
 330     r = 0;
 331 #else
 332     r = conf.script_startup;
 333 #endif
 334     break;
 335   case TOKENIZER_GET_USB_POWER:
 336     accept(TOKENIZER_GET_USB_POWER);
 337         int usbpwr = 0 ;
 338         if (tokenizer_token() != TOKENIZER_CR &&
 339         tokenizer_token() != TOKENIZER_ELSE ) {
 340         usbpwr = expr();
 341     }
 342     r = get_usb_power(usbpwr);
 343     break;
 344   case TOKENIZER_GET_EXP_COUNT:
 345     accept(TOKENIZER_GET_EXP_COUNT);
 346     r = get_exposure_counter();
 347     break;
 348   case TOKENIZER_IS_PRESSED:
 349     accept(TOKENIZER_IS_PRESSED);
 350     r = script_key_is_pressed(ubasic_get_key_arg());
 351     break;
 352   case TOKENIZER_RANDOM:
 353     accept(TOKENIZER_RANDOM);
 354     int min = expr();
 355     int max = expr();
 356     // shouldn't srand every time...
 357     srand((int)shooting_get_bv96()+(unsigned short)stat_get_vbatt()+get_tick_count());
 358     // wtf
 359     action_push_delay(rand()%10);
 360     flag_yield=1;
 361     r = min + rand()%(max-min+1);
 362   break;
 363   case TOKENIZER_GET_MOVIE_STATUS:
 364     accept(TOKENIZER_GET_MOVIE_STATUS);
 365     r = get_movie_status();
 366     break;
 367   case TOKENIZER_GET_PLATFORM_ID:
 368     accept(TOKENIZER_GET_PLATFORM_ID);
 369     r = conf.platformid;
 370     break;
 371   case TOKENIZER_GET_DRIVE_MODE:
 372     accept(TOKENIZER_GET_DRIVE_MODE);
 373     r = shooting_get_drive_mode();
 374     break;
 375    case TOKENIZER_GET_FOCUS_MODE:
 376     accept(TOKENIZER_GET_FOCUS_MODE);
 377     r = shooting_get_real_focus_mode();
 378     break;
 379   case TOKENIZER_GET_FOCUS_STATE:
 380     accept(TOKENIZER_GET_FOCUS_STATE);
 381     r = shooting_get_focus_state();
 382     break;
 383   case TOKENIZER_GET_FOCUS_OK:
 384     accept(TOKENIZER_GET_FOCUS_OK);
 385     r = shooting_get_focus_ok();
 386     break;
 387   case TOKENIZER_GET_DISPLAY_MODE:
 388     accept(TOKENIZER_GET_DISPLAY_MODE);
 389     r = shooting_get_display_mode();
 390     break;
 391   case TOKENIZER_GET_FLASH_MODE:
 392     accept(TOKENIZER_GET_FLASH_MODE);
 393     r = shooting_get_flash_mode();
 394     break;
 395   case TOKENIZER_GET_SHOOTING:
 396     accept(TOKENIZER_GET_SHOOTING);
 397     r = shooting_in_progress();
 398     break;
 399   case TOKENIZER_GET_FLASH_READY:
 400     accept(TOKENIZER_GET_FLASH_READY);
 401     r = shooting_is_flash();
 402     break;
 403   case TOKENIZER_GET_IS_MODE:
 404     accept(TOKENIZER_GET_IS_MODE);
 405     r = shooting_get_is_mode();
 406     break;
 407   case TOKENIZER_GET_EV:
 408     accept(TOKENIZER_GET_EV);
 409     r = shooting_get_ev_correction1();
 410     break;
 411   case TOKENIZER_GET_RESOLUTION:
 412     accept(TOKENIZER_GET_RESOLUTION);
 413     r = shooting_get_resolution();
 414     break;
 415   case TOKENIZER_GET_QUALITY:
 416     accept(TOKENIZER_GET_QUALITY);
 417     r = shooting_get_prop(camera_info.props.quality);
 418     break;
 419   case TOKENIZER_GET_ORIENTATION_SENSOR:
 420     accept(TOKENIZER_GET_ORIENTATION_SENSOR);
 421     r = shooting_get_prop(camera_info.props.orientation_sensor);
 422     break;
 423   case TOKENIZER_GET_ZOOM_STEPS:
 424     accept(TOKENIZER_GET_ZOOM_STEPS);
 425     r = zoom_points;
 426     break;
 427   case TOKENIZER_GET_ND_PRESENT:
 428     accept(TOKENIZER_GET_ND_PRESENT);
 429     if (camera_info.cam_has_nd_filter == 0)
 430     {
 431         r = 0;
 432     }
 433     else
 434     {
 435         if (camera_info.cam_has_iris_diaphragm == 0)
 436         {
 437             r = 1;
 438         }
 439         else
 440         {
 441             r = 2;
 442         }
 443     }
 444     break;
 445   case TOKENIZER_GET_PROPSET:
 446     accept(TOKENIZER_GET_PROPSET);
 447     r = camera_info.props.propset;
 448     break;
 449   case TOKENIZER_GET_TV96:
 450     accept(TOKENIZER_GET_TV96);
 451     r = shooting_get_tv96();
 452     break;
 453   case TOKENIZER_GET_USER_TV96:
 454     accept(TOKENIZER_GET_USER_TV96);
 455     r = shooting_get_user_tv96();
 456     break;   
 457   case TOKENIZER_GET_USER_TV_ID:
 458     accept(TOKENIZER_GET_USER_TV_ID);
 459     r = shooting_get_user_tv_id();
 460     break;
 461   case TOKENIZER_GET_AV96:
 462     accept(TOKENIZER_GET_AV96);
 463     r = shooting_get_av96();
 464     break;  
 465   case TOKENIZER_GET_USER_AV96:
 466     accept(TOKENIZER_GET_USER_AV96);
 467     r = shooting_get_user_av96();
 468     break;    
 469   case TOKENIZER_GET_USER_AV_ID:
 470     accept(TOKENIZER_GET_USER_AV_ID);
 471     r = shooting_get_user_av_id();
 472     break;
 473   case TOKENIZER_GET_ZOOM:
 474     accept(TOKENIZER_GET_ZOOM);
 475     r = shooting_get_zoom();
 476     break;
 477   case TOKENIZER_GET_FOCUS:
 478     accept(TOKENIZER_GET_FOCUS);
 479     r = shooting_get_subject_distance();
 480     break;
 481   case TOKENIZER_GET_NEAR_LIMIT:
 482     accept(TOKENIZER_GET_NEAR_LIMIT);
 483     r = shooting_get_near_limit_of_acceptable_sharpness();
 484     break;
 485   case TOKENIZER_GET_FAR_LIMIT:
 486     accept(TOKENIZER_GET_FAR_LIMIT);
 487     r = shooting_get_far_limit_of_acceptable_sharpness();
 488     break;  
 489    case TOKENIZER_GET_DOF:
 490     accept(TOKENIZER_GET_DOF);
 491     r = shooting_get_depth_of_field();
 492     break;
 493   case TOKENIZER_GET_HYPERFOCAL_DIST:
 494     accept(TOKENIZER_GET_HYPERFOCAL_DIST);
 495     r = shooting_get_hyperfocal_distance();
 496     break;  
 497    case TOKENIZER_GET_SD_OVER_MODES:
 498     accept(TOKENIZER_GET_SD_OVER_MODES);
 499     r = sd_over_modes() ;
 500     break;
 501   case TOKENIZER_GET_ISO_MARKET:
 502     accept(TOKENIZER_GET_ISO_MARKET);
 503     r = (int)shooting_get_iso_market();
 504     break;
 505   case TOKENIZER_GET_ISO_REAL:
 506     accept(TOKENIZER_GET_ISO_REAL);
 507     r = (int)shooting_get_iso_real();
 508     break;
 509   case TOKENIZER_GET_BV96:
 510     accept(TOKENIZER_GET_BV96);
 511     r = (int)shooting_get_bv96();
 512     break;  
 513   case TOKENIZER_GET_SV96:
 514     accept(TOKENIZER_GET_SV96);
 515     r = (int)shooting_get_sv96_real();
 516     break;    
 517   case TOKENIZER_GET_ISO_MODE:
 518     accept(TOKENIZER_GET_ISO_MODE);
 519     r = shooting_get_iso_mode();
 520     break;
 521   case TOKENIZER_GET_DISK_SIZE:
 522     accept(TOKENIZER_GET_DISK_SIZE);
 523     r = GetTotalCardSpaceKb();
 524     break;
 525   case TOKENIZER_GET_FREE_DISK_SPACE:
 526     accept(TOKENIZER_GET_FREE_DISK_SPACE);
 527     r = GetFreeCardSpaceKb();
 528     break;
 529   case TOKENIZER_GET_JPG_COUNT:
 530     accept(TOKENIZER_GET_JPG_COUNT);
 531     r = GetJpgCount();
 532     break;
 533   case TOKENIZER_GET_VIDEO_BUTTON:
 534     accept(TOKENIZER_GET_VIDEO_BUTTON);
 535     r = (camera_info.cam_has_video_button) ? 1 : 0;
 536     break;
 537   case TOKENIZER_GET_VIDEO_RECORDING:
 538     accept(TOKENIZER_GET_VIDEO_RECORDING);
 539     r = is_video_recording();
 540     break;
 541   case TOKENIZER_GET_RAW_COUNT:
 542     accept(TOKENIZER_GET_RAW_COUNT);
 543     r = GetRawCount();
 544     break;
 545   case TOKENIZER_GET_PROP:
 546     accept(TOKENIZER_GET_PROP);
 547     int var = expr();
 548     r = shooting_get_prop(var);
 549     break;
 550   case TOKENIZER_GET_HISTO_RANGE:
 551     accept(TOKENIZER_GET_HISTO_RANGE);
 552     int from = expr();
 553     int to = expr();
 554 #ifdef UBASIC_TEST
 555     (void)from; (void)to;
 556     r = 0;
 557 #else
 558     r = (unsigned short)libshothisto->shot_histogram_get_range(from, to);
 559 #endif
 560     break;
 561   case TOKENIZER_GET_TEMPERATURE:
 562     accept(TOKENIZER_GET_TEMPERATURE);
 563     int temp = expr();
 564     switch (temp)
 565     {
 566     case 0:
 567       r = get_optical_temp(); 
 568       break;
 569     case 1:
 570       r = get_ccd_temp(); 
 571       break;
 572     case 2:
 573       r = get_battery_temp();
 574       break;
 575     default: // do something sane if given a bad index
 576       r = 0;
 577     }
 578     break;
 579   case TOKENIZER_GET_TIME:
 580       accept(TOKENIZER_GET_TIME);
 581       int tmode = expr();
 582       static struct tm *ttm;
 583       ttm = get_localtime();
 584       if (tmode==0) r = ttm->tm_sec;
 585       else if (tmode==1) r = ttm->tm_min;
 586       else if (tmode==2) r = ttm->tm_hour;
 587       else if (tmode==3) r = ttm->tm_mday;
 588       else if (tmode==4) r = ttm->tm_mon+1;
 589       else if (tmode==5) r = 1900+ttm->tm_year;
 590       break;
 591  case TOKENIZER_GET_RAW:
 592     accept(TOKENIZER_GET_RAW);
 593 #ifdef UBASIC_TEST
 594     r = 1;
 595 #else
 596     r = conf.save_raw;
 597 #endif    
 598     break;
 599   // get CHDK capture mode value, or 0 if in playback or unknown (broken modemap)
 600   // NOTE: different from get_mode, since this returns the actual value
 601   case TOKENIZER_GET_CAPTURE_MODE:
 602     accept(TOKENIZER_GET_CAPTURE_MODE);
 603     if (camera_info.state.mode_rec) 
 604       r = camera_info.state.mode_shooting;
 605     else
 606       r = 0;
 607     break;
 608   // check if CHDK capture mode exists in modemap of this camera
 609   case TOKENIZER_IS_CAPTURE_MODE_VALID:
 610     accept(TOKENIZER_IS_CAPTURE_MODE_VALID);
 611     int modenum = expr();
 612     if (shooting_mode_chdk2canon(modenum) == -1)
 613       r = 0;
 614     else
 615       r = 1;
 616     break;
 617   case TOKENIZER_GET_FOCAL_LENGTH:
 618     accept(TOKENIZER_GET_FOCAL_LENGTH);
 619     r = get_focal_length(lens_get_zoom_point());
 620     break;
 621   case TOKENIZER_GET_MIN_STACK_DIST:
 622     accept(TOKENIZER_GET_MIN_STACK_DIST);
 623     r = shooting_get_min_stack_distance();
 624     break;
 625   case TOKENIZER_GET_CONFIG_VALUE:
 626     accept(TOKENIZER_GET_CONFIG_VALUE);
 627     int var1 = expr();
 628     int var2 = expr();
 629     if( conf_getValue(var1, &configVal) == CONF_VALUE) r = configVal.numb; else r = var2;
 630     break;
 631   case TOKENIZER_SWAP_PARTITIONS:
 632     accept(TOKENIZER_SWAP_PARTITIONS);
 633     int partNr = expr();
 634     r = swap_partitions(partNr);
 635     break;
 636 
 637   // APEX functions
 638   case TOKENIZER_ISO_TO_SV96:
 639     accept(TOKENIZER_ISO_TO_SV96);
 640     r = shooting_get_sv96_from_iso(expr());
 641     break;
 642   case TOKENIZER_SV96_TO_ISO:
 643     accept(TOKENIZER_SV96_TO_ISO);
 644     r = shooting_get_iso_from_sv96(expr());
 645     break;
 646   case TOKENIZER_ISO_REAL_TO_MARKET:
 647     accept(TOKENIZER_ISO_REAL_TO_MARKET);
 648     r = shooting_iso_real_to_market(expr());
 649     break;
 650   case TOKENIZER_ISO_MARKET_TO_REAL:
 651     accept(TOKENIZER_ISO_MARKET_TO_REAL);
 652     r = shooting_iso_market_to_real(expr());
 653     break;
 654   case TOKENIZER_SV96_REAL_TO_MARKET:
 655     accept(TOKENIZER_SV96_REAL_TO_MARKET);
 656     r = shooting_sv96_real_to_market(expr());
 657     break;
 658   case TOKENIZER_SV96_MARKET_TO_REAL:
 659     accept(TOKENIZER_SV96_MARKET_TO_REAL);
 660     r = shooting_sv96_market_to_real(expr());
 661     break;
 662   case TOKENIZER_APERTURE_TO_AV96:
 663     accept(TOKENIZER_APERTURE_TO_AV96);
 664     r = shooting_get_av96_from_aperture(expr());
 665     break;
 666   case TOKENIZER_AV96_TO_APERTURE:
 667     accept(TOKENIZER_AV96_TO_APERTURE);
 668     r = shooting_get_aperture_from_av96(expr());
 669     break;
 670   case TOKENIZER_USEC_TO_TV96:
 671     accept(TOKENIZER_USEC_TO_TV96);
 672     r = shooting_get_tv96_from_shutter_speed((float)expr()/1000000.0);
 673     break;
 674   case TOKENIZER_TV96_TO_USEC:
 675     accept(TOKENIZER_TV96_TO_USEC);
 676     r = (int)(shooting_get_shutter_speed_from_tv96(expr()) * 1000000.0 + 0.5);
 677     break;
 678   case TOKENIZER_SECONDS_TO_TV96:
 679     accept(TOKENIZER_SECONDS_TO_TV96);
 680     int n = expr();
 681     int d = expr();
 682     r = shooting_get_tv96_from_shutter_speed((float)n/(float)d);
 683     break;
 684   case TOKENIZER_GET_DRAW_TITLE_LINE:    
 685     accept(TOKENIZER_GET_DRAW_TITLE_LINE);  
 686     r = camera_info.state.osd_title_line ;
 687     break;
 688   case TOKENIZER_FORCE_USB_PRESENT:
 689     accept(TOKENIZER_FORCE_USB_PRESENT);
 690     r=force_usb_state(expr()) ;
 691     break;
 692   case TOKENIZER_GET_ALT_MODE:
 693     accept(TOKENIZER_GET_ALT_MODE);
 694     r = (camera_info.state.gui_mode != 0);
 695     break;    
 696   case TOKENIZER_GET_RAW_SUPPORT:
 697     accept(TOKENIZER_GET_RAW_SUPPORT);
 698     r = (is_raw_possible() && !camera_info.state.mode_play);
 699     break;    
 700   case TOKENIZER_GET_CURRENT_AV96:
 701     accept(TOKENIZER_GET_CURRENT_AV96);
 702     r = shooting_get_current_av96();
 703     break;
 704   case TOKENIZER_GET_CURRENT_TV96:
 705     accept(TOKENIZER_GET_CURRENT_TV96);
 706     r = shooting_get_current_tv96();
 707     break;
 708   case TOKENIZER_GET_IMAGER_ACTIVE:
 709     accept(TOKENIZER_GET_IMAGER_ACTIVE);
 710     r = shooting_get_imager_active();
 711     break;
 712   case TOKENIZER_GET_MAX_AV96:
 713     accept(TOKENIZER_GET_MAX_AV96);
 714     r = shooting_get_max_av96(); // NOTE -1 if not available, i.e. playback
 715     break;
 716   case TOKENIZER_GET_MIN_AV96:
 717     accept(TOKENIZER_GET_MIN_AV96);
 718     r = shooting_get_min_av96(); // NOTE -1 if not available, i.e. playback
 719     break;
 720   case TOKENIZER_GET_ND_VALUE_EV96:
 721     accept(TOKENIZER_GET_ND_VALUE_EV96);
 722     r = shooting_get_nd_value_ev96();
 723     break;
 724   case TOKENIZER_GET_ND_CURRENT_EV96:
 725     accept(TOKENIZER_GET_ND_CURRENT_EV96);
 726     r = shooting_get_nd_current_ev96();
 727     break;
 728   case TOKENIZER_GET_DIGIC:
 729     accept(TOKENIZER_GET_DIGIC);
 730     r = camera_info.cam_digic;
 731     break;
 732   //ARM Begin
 733       
 734   default:
 735     r = varfactor();
 736     break;
 737   }
 738   return r;
 739 }
 740 /*---------------------------------------------------------------------------*/
 741 static int
 742 term(void)
 743 {
 744   int f1, f2;
 745   int op;
 746 
 747   f1 = factor();
 748   op = tokenizer_token();
 749   DEBUG_PRINTF("term: token %d\n", op);
 750   while(op == TOKENIZER_ASTR ||
 751         op == TOKENIZER_SLASH ||
 752         op == TOKENIZER_LT ||
 753         op == TOKENIZER_GT ||
 754         op == TOKENIZER_GE ||
 755         op == TOKENIZER_LE ||
 756         op == TOKENIZER_NE ||
 757         op == TOKENIZER_EQ ||
 758         op == TOKENIZER_XOR || 
 759         op == TOKENIZER_OR ||
 760         op == TOKENIZER_MOD) {
 761     tokenizer_next();
 762     f2 = factor();
 763     DEBUG_PRINTF("term: %d %d %d\n", f1, op, f2);
 764     switch(op) {
 765     case TOKENIZER_ASTR:
 766       f1 = f1 * f2;
 767       break;
 768     case TOKENIZER_SLASH:
 769       f1 = f1 / f2;
 770       break;
 771     case TOKENIZER_MOD:
 772       f1 = f1 % f2;
 773       break;
 774     case TOKENIZER_LT:
 775       f1 = f1 < f2;
 776       break;
 777     case TOKENIZER_GT:
 778       f1 = f1 > f2;
 779       break;
 780     case TOKENIZER_EQ:
 781       f1 = f1 == f2;
 782       break;
 783     case TOKENIZER_NE:
 784       f1 = f1 != f2;
 785       break;
 786     case TOKENIZER_LE:
 787       f1 = f1 <= f2;
 788       break;
 789     case TOKENIZER_GE:
 790       f1 = f1 >= f2;
 791       break;
 792     case TOKENIZER_OR:
 793       f1 = f1 | f2;
 794       break;
 795     case TOKENIZER_XOR:
 796       f1 = f1 ^ f2;
 797       break;
 798     }
 799     op = tokenizer_token();
 800   }
 801   DEBUG_PRINTF("term: %d\n", f1);
 802   return f1;
 803 }
 804 /*---------------------------------------------------------------------------*/
 805 static int
 806 expr(void)
 807 {
 808   int t1, t2;
 809   int op;
 810   
 811   t1 = term();
 812   op = tokenizer_token();
 813   DEBUG_PRINTF("expr: token %d\n", op);
 814   while(op == TOKENIZER_PLUS ||
 815         op == TOKENIZER_MINUS ||
 816         op == TOKENIZER_AND ||
 817         op == TOKENIZER_LOR ||
 818         op == TOKENIZER_XOR) {
 819     tokenizer_next();
 820     t2 = term();
 821     DEBUG_PRINTF("expr: %d %d %d\n", t1, op, t2);
 822     switch(op) {
 823     case TOKENIZER_PLUS:
 824       t1 = t1 + t2;
 825       break;
 826     case TOKENIZER_MINUS:
 827       t1 = t1 - t2;
 828       break;
 829     case TOKENIZER_AND:
 830       t1 = t1 & t2;
 831       break;
 832     case TOKENIZER_LOR:
 833       t1 = t1 || t2;
 834       break;
 835     }
 836     op = tokenizer_token();
 837   }
 838   DEBUG_PRINTF("expr: %d\n", t1);
 839   return t1;
 840 }
 841 /*---------------------------------------------------------------------------*/
 842 static int
 843 relation(void)
 844 {
 845   int r1, r2;
 846   int op;
 847   
 848   r1 = expr();
 849   op = tokenizer_token();
 850   DEBUG_PRINTF("relation: token %d\n", op);
 851   while(op == TOKENIZER_LAND) {
 852     tokenizer_next();
 853     r2 = expr();
 854     DEBUG_PRINTF("relation: %d %d %d\n", r1, op, r2);
 855     switch(op) {
 856     case TOKENIZER_LAND:
 857       r1 = r1 && r2;
 858       break;
 859     }
 860     op = tokenizer_token();
 861   }
 862   return r1;
 863 }
 864 
 865 #if 0
 866 /*---------------------------------------------------------------------------*/
 867 static void
 868 jump_linenum(int linenum)
 869 {
 870   tokenizer_init(program_ptr);
 871   while(tokenizer_num() != linenum) {
 872     do {
 873       do {
 874         tokenizer_next();
 875       } while(tokenizer_token() != TOKENIZER_CR &&
 876               tokenizer_token() != TOKENIZER_ENDOFINPUT);
 877       if(tokenizer_token() == TOKENIZER_CR) {
 878         tokenizer_next();
 879       }
 880     } while(tokenizer_token() != TOKENIZER_NUMBER);
 881     DEBUG_PRINTF("jump_linenum: Found line %d\n", tokenizer_num());
 882   }
 883 }
 884 #endif
 885 
 886 /*---------------------------------------------------------------------------*/
 887 static void
 888 jump_line(int linenum)
 889 {
 890   tokenizer_init(program_ptr);
 891   while(tokenizer_line_number() != linenum) {
 892     tokenizer_next();
 893   }
 894   /* swallow the CR that would be read next */
 895   accept(TOKENIZER_CR);
 896 
 897 }
 898 /*---------------------------------------------------------------------------*/
 899 // TODO: error handling?
 900 int
 901 jump_label(char * label)
 902 {
 903   char currLabel[MAX_STRINGLEN];
 904   tokenizer_init(program_ptr);
 905   currLabel[0] = 0;
 906   while(tokenizer_token() != TOKENIZER_ENDOFINPUT) {
 907     tokenizer_next();
 908     if (tokenizer_token() == TOKENIZER_LABEL) {
 909       tokenizer_label(currLabel, sizeof(currLabel));
 910       tokenizer_next();
 911       if(strcmp(label, currLabel) == 0) {
 912         accept(TOKENIZER_CR);
 913         DEBUG_PRINTF("jump_linenum: Found line %d\n", tokenizer_line_number());
 914         break;
 915       }
 916     }
 917   }
 918   if (tokenizer_token() == TOKENIZER_ENDOFINPUT) {
 919     if (camera_info.state.state_kbd_script_run == 1) {  
 920       DEBUG_PRINTF("Label %s not found", label);
 921       ubasic_error = UBASIC_E_UNK_LABEL;
 922     }
 923       return 0;
 924   } else {
 925       return 1;
 926   }
 927 }
 928 /*---------------------------------------------------------------------------*/
 929 static void
 930 goto_statement(void)
 931 {
 932   accept(TOKENIZER_GOTO);
 933   if(tokenizer_token() == TOKENIZER_STRING) {
 934     tokenizer_string(string, sizeof(string));
 935     tokenizer_next();
 936     jump_label(string);
 937   } else {
 938     DEBUG_PRINTF("ubasic.c: goto_statement(): no label specified\n");
 939     ended = 1;
 940     ubasic_error = UBASIC_E_UNK_LABEL;
 941   }
 942 }
 943 /*---------------------------------------------------------------------------*/
 944 static void
 945 print_statement(void)
 946 {
 947   static char buf[128];
 948 
 949   buf[0]=0;
 950   accept(TOKENIZER_PRINT);
 951   do {
 952     DEBUG_PRINTF("Print loop\n");
 953     if(tokenizer_token() == TOKENIZER_STRING) {
 954       tokenizer_string(string, sizeof(string));
 955       sprintf(buf+strlen(buf), "%s", string);
 956       tokenizer_next();
 957     } else if(tokenizer_token() == TOKENIZER_COMMA) {
 958       strcat(buf, " ");
 959       tokenizer_next();
 960     } else if(tokenizer_token() == TOKENIZER_SEMICOLON) {
 961       tokenizer_next();
 962     } else {
 963       sprintf(buf+strlen(buf), "%d", expr());
 964     }
 965   } while(tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ENDOFINPUT && tokenizer_token() != TOKENIZER_ELSE);
 966   script_console_add_line((long)buf);
 967   DEBUG_PRINTF("End of print\n");
 968   accept_cr();
 969 }
 970 /*---------------------------------------------------------------------------*/
 971 /* IF-STATEMENT                                                              */
 972 
 973 static void
 974 endif_statement(void)
 975 {
 976   if(if_stack_ptr > 0) {
 977     accept(TOKENIZER_ENDIF);
 978     accept(TOKENIZER_CR);
 979     if_stack_ptr--;
 980   } else {
 981     DEBUG_PRINTF("ubasic.c: endif_statement(): endif without if-statement\n");
 982     ended = 1;
 983     ubasic_error = UBASIC_E_UNMATCHED_IF;
 984   }
 985 }
 986 /*---------------------------------------------------------------------------*/
 987 static void
 988 if_statement(void)
 989 {
 990   int r, else_cntr,endif_cntr,f_nt,f_sl;
 991   
 992   accept(TOKENIZER_IF);
 993   DEBUG_PRINTF("if_statement: get_relation\n");
 994   r = relation();
 995   DEBUG_PRINTF("if_statement: relation %d\n", r);
 996   accept(TOKENIZER_THEN);
 997   if (ended) {
 998     return;
 999   }
1000 
1001   if (tokenizer_token() == TOKENIZER_CR) {
1002     // CR after then -> multiline IF-Statement
1003     if(if_stack_ptr < MAX_IF_STACK_DEPTH) {
1004       if_stack[if_stack_ptr] = r;
1005       if_stack_ptr++;
1006     } else {
1007       DEBUG_PRINTF("if_statement: IF-stack depth exceeded\n");
1008       ended = 1;
1009       ubasic_error = UBASIC_E_IF_STACK_EXHAUSTED;
1010       return;
1011     }
1012     DEBUG_PRINTF("if_statement: stack_ptr %d\n", if_stack_ptr);
1013     accept(TOKENIZER_CR);
1014     if(r) {
1015       DEBUG_PRINTF("if_statement: result true\n");
1016       return;
1017     }else {
1018       DEBUG_PRINTF("if_statement: result false\n");
1019 
1020       else_cntr=endif_cntr=0; // number of else/endif possible in current nesting
1021       f_nt=f_sl=0; // f_nt flag for additional next token, f_fs flag single line
1022 
1023       while(((tokenizer_token() != TOKENIZER_ELSE &&  tokenizer_token() != TOKENIZER_ENDIF)
1024            || else_cntr || endif_cntr) && tokenizer_token() != TOKENIZER_ENDOFINPUT){
1025         f_nt=0;
1026         // nested if
1027         if( tokenizer_token() == TOKENIZER_IF) {
1028           else_cntr+=1;
1029           endif_cntr+=1;
1030           f_sl=0;
1031           DEBUG_PRINTF("IF: line %d, token %d, else %d, end %d\n", tokenizer_line_number(),tokenizer_token(),else_cntr,endif_cntr);
1032         }
1033         if( tokenizer_token() == TOKENIZER_THEN) {
1034           f_nt=1;
1035           tokenizer_next();
1036           DEBUG_PRINTF("THEN: line %d, token %d, else %d, end %d\n", tokenizer_line_number(),tokenizer_token(),else_cntr,endif_cntr);
1037           if (tokenizer_token() != TOKENIZER_CR) { f_sl=1; }
1038           DEBUG_PRINTF("THEN_SL: line %d, token %d, else %d, end %d\n", tokenizer_line_number(),tokenizer_token(),else_cntr,endif_cntr);
1039         }
1040         if(tokenizer_token() == TOKENIZER_ELSE) {
1041           else_cntr--;
1042           DEBUG_PRINTF("ELSE: line %d, token %d, else %d, end %d\n", tokenizer_line_number(),tokenizer_token(),else_cntr,endif_cntr);
1043           if (else_cntr<0) { 
1044             DEBUG_PRINTF("ubasic.c: if_statement(): else without if-statement\n");
1045             ended = 1;
1046             ubasic_error = UBASIC_E_UNMATCHED_IF;
1047             return;
1048           }
1049         }
1050         if(!f_sl && (tokenizer_token() == TOKENIZER_ENDIF)) {
1051           endif_cntr--;
1052           if (endif_cntr != else_cntr) else_cntr--;
1053           DEBUG_PRINTF("ENDIF: line %d, token %d, else %d, end %d\n", tokenizer_line_number(),tokenizer_token(),else_cntr,endif_cntr);
1054         } else {
1055           if (f_sl && (tokenizer_token() == TOKENIZER_CR))  {
1056             f_sl=0;
1057             endif_cntr--;
1058             if (endif_cntr != else_cntr) else_cntr--;
1059             DEBUG_PRINTF("ENDIF_SL: line %d, token %d, else %d, end %d\n", tokenizer_line_number(),tokenizer_token(),else_cntr,endif_cntr);
1060           }else{
1061             if (tokenizer_token()==TOKENIZER_ENDIF){
1062               DEBUG_PRINTF("ubasic.c: if_statement(): endif in singleline if-statement\n");
1063               ended = 1;
1064               ubasic_error = UBASIC_E_PARSE;
1065               return;
1066             }
1067           }
1068         }
1069         if (!f_nt) { tokenizer_next(); }
1070       }
1071       if(tokenizer_token() == TOKENIZER_ELSE) { return; }
1072     }
1073     endif_statement();
1074   }else {
1075   // Singleline IF-Statement
1076     if(r) {
1077       statement();
1078     } else {
1079       do {
1080         tokenizer_next();
1081       } while(tokenizer_token() != TOKENIZER_ELSE &&
1082         tokenizer_token() != TOKENIZER_CR &&
1083         tokenizer_token() != TOKENIZER_ENDOFINPUT);
1084       if(tokenizer_token() == TOKENIZER_ELSE) {
1085         accept(TOKENIZER_ELSE);
1086         statement();
1087       } else {
1088         accept(TOKENIZER_CR);
1089       }
1090     }
1091   }
1092 }
1093 /*---------------------------------------------------------------------------*/
1094 static void
1095 else_statement(void)
1096 {
1097   int r=0, endif_cntr, f_nt;
1098   
1099   accept(TOKENIZER_ELSE);
1100   if(if_stack_ptr > 0) {
1101     r = if_stack[if_stack_ptr-1];
1102   }
1103   else{
1104     DEBUG_PRINTF("ubasic.c: else_statement(): else without if-statement\n");
1105     ended = 1;
1106     ubasic_error = UBASIC_E_PARSE;
1107     return;
1108   }
1109   DEBUG_PRINTF("else_statement: relation %d\n", r);
1110   
1111   if (tokenizer_token() == TOKENIZER_CR) {
1112           accept(TOKENIZER_CR);
1113           if(!r) {
1114       DEBUG_PRINTF("else_statement: result true\n");
1115       return;
1116     } else {
1117       DEBUG_PRINTF("else_statement: result false\n");
1118       endif_cntr=0;
1119       while(((tokenizer_token() != TOKENIZER_ENDIF )
1120            || endif_cntr) && tokenizer_token() != TOKENIZER_ENDOFINPUT){
1121         f_nt=0;
1122         if( tokenizer_token() == TOKENIZER_IF) {
1123           endif_cntr+=1;
1124         }
1125         if( tokenizer_token() == TOKENIZER_THEN) {
1126           tokenizer_next();
1127           // then followed by CR -> multi line
1128           if (tokenizer_token() == TOKENIZER_CR) {
1129             f_nt=1;
1130           } else { // single line
1131             endif_cntr--;
1132             while(tokenizer_token() != TOKENIZER_ENDIF && tokenizer_token() != TOKENIZER_CR
1133                  && tokenizer_token() != TOKENIZER_ENDOFINPUT){
1134               tokenizer_next();
1135             }
1136             if (tokenizer_token()==TOKENIZER_ENDIF){
1137               DEBUG_PRINTF("ubasic.c: else_statement(): endif in singleline if-statement\n");
1138               ended = 1;
1139               ubasic_error = UBASIC_E_PARSE;
1140               return;
1141             }
1142           }
1143         }
1144         if( tokenizer_token() == TOKENIZER_ENDIF)  { endif_cntr--; }
1145         if (!f_nt) { tokenizer_next(); }
1146       }
1147     }
1148     endif_statement();
1149   }else{
1150     DEBUG_PRINTF("ubasic.c: else_statement(): CR after ELSE expected\n");
1151     ended = 1;
1152     ubasic_error = UBASIC_E_PARSE;
1153   }
1154 }
1155 /*---------------------------------------------------------------------------*/
1156 
1157 /*---------------------------------------------------------------------------*/
1158 /* SELECT-STATEMENT                                                          */
1159 
1160 static void
1161 dec_select_stack(void)
1162 {
1163   if(select_stack_ptr > 0) {
1164       select_stack_ptr--;
1165   } else {
1166     DEBUG_PRINTF("select_statement: SELECT-Stack fail\n");
1167     ended = 1;
1168     ubasic_error = UBASIC_E_UNMATCHED_END_SELECT;
1169   }
1170 }
1171 /*---------------------------------------------------------------------------*/
1172 static void
1173 end_select_statement(void)
1174 {
1175   if(select_stack_ptr > 0) {
1176     accept(TOKENIZER_END_SELECT);
1177     accept(TOKENIZER_CR);
1178     dec_select_stack();
1179   } else {
1180     DEBUG_PRINTF("ubasic.c: end_select_statement(): end_select without select-statement\n");
1181     ended = 1;
1182     ubasic_error = UBASIC_E_UNMATCHED_END_SELECT;
1183   }
1184 }
1185 /*---------------------------------------------------------------------------*/
1186 static void
1187 case_statement(void)
1188 {
1189   int select_value, case_value_1, case_value_2, case_value_eq;
1190   short case_run, case_goto = 0, case_gosub = 0;
1191   int cur_ln, gosub_ln = 0;
1192   
1193   accept(TOKENIZER_CASE);
1194   if(select_stack_ptr > 0) {
1195     select_value = select_stack[select_stack_ptr - 1].select_value;
1196     case_run = select_stack[select_stack_ptr - 1].case_run;
1197   
1198     if (!case_run) {
1199       case_value_1 = expr();
1200       case_value_eq = (select_value == case_value_1);
1201       if (case_value_eq) { DEBUG_PRINTF("case_statement: case_value_eq %d, case_value %d\n", case_value_eq, case_value_1); }  
1202 
1203       if(tokenizer_token() == TOKENIZER_TO) {
1204         accept(TOKENIZER_TO);
1205         case_value_2 = expr();
1206         if (case_value_1 < case_value_2) {
1207           case_value_eq = ((select_value >= case_value_1) && (select_value <= case_value_2));
1208           DEBUG_PRINTF("case_statement: case_value %d to %d\n", case_value_1, case_value_2);
1209         } else {
1210           case_value_eq = ((select_value >= case_value_2) && (select_value <= case_value_1));
1211           DEBUG_PRINTF("case_statement: case_value %d to %d\n", case_value_2, case_value_1);
1212         }
1213       } else if (tokenizer_token() == TOKENIZER_COMMA) {
1214         do {
1215           accept(TOKENIZER_COMMA);
1216           if (case_value_eq) {
1217             case_value_2 = expr();
1218           } else {
1219             case_value_1 = expr();
1220             case_value_eq = (select_value == case_value_1);
1221           }
1222         } while (tokenizer_token() == TOKENIZER_COMMA);
1223         DEBUG_PRINTF("case_statement: case_value_eq %d, case_value_comma %d\n", case_value_eq, case_value_1);
1224       }
1225       
1226       accept(TOKENIZER_SEMICOLON);
1227       if (case_value_eq) {
1228         case_goto = (tokenizer_token() == TOKENIZER_GOTO);
1229         case_gosub = (tokenizer_token() == TOKENIZER_GOSUB);
1230 //GOSUB - save curr linenumber
1231         cur_ln = tokenizer_line_number();
1232 //GOSUB
1233         statement();
1234 //GOSUB  - save new linenumber, reset to curr linenumber
1235       if (case_gosub) { 
1236         gosub_ln = tokenizer_line_number();
1237         jump_line(cur_ln+1);
1238         DEBUG_PRINTF("case_statement: GOSUB: toLN=%d, nextLN=%d\n", gosub_ln, cur_ln+1);
1239       }
1240 //GOSUB
1241         DEBUG_PRINTF("case_statement: case execute\n");
1242         case_run = 1;
1243         select_stack[select_stack_ptr - 1].case_run = case_run;
1244       } else {
1245         DEBUG_PRINTF("case_statement: case jump; case_run: %d\n", case_run);
1246         accept_cr();
1247       }
1248     } else {accept_cr();}
1249 //REM
1250     while ((tokenizer_token() == TOKENIZER_REM) && (!case_goto)) {statement();}
1251 //REM
1252     if (case_goto) { dec_select_stack(); } else {
1253       if ((tokenizer_token() != TOKENIZER_CASE) && (tokenizer_token() != TOKENIZER_CASE_ELSE) && 
1254          (tokenizer_token() != TOKENIZER_END_SELECT)) {
1255          DEBUG_PRINTF("ubasic.c: select_statement(): don't found case, case_else or end_select\n");
1256          ended = 1;
1257          ubasic_error = UBASIC_E_PARSE;
1258       } else { 
1259 //GOSUB test for end_select and set to gosub-linenumber
1260         if (tokenizer_token() == TOKENIZER_END_SELECT) { end_select_statement(); }
1261         if (case_gosub) {
1262           gosub_stack[gosub_stack_ptr-1] = tokenizer_line_number();
1263           jump_line(gosub_ln);
1264           DEBUG_PRINTF("end_select_statement: GOSUB: returnLN=%d\n", gosub_stack[gosub_stack_ptr-1]);
1265         }
1266       }  
1267 //GOSUB        
1268     }
1269   } else {
1270     DEBUG_PRINTF("case_statement: SELECT-Stack fail\n");
1271     ended = 1;
1272     ubasic_error = UBASIC_E_UNMATCHED_END_SELECT;
1273   }
1274 }
1275 /*---------------------------------------------------------------------------*/
1276 static void
1277 case_else_statement(void)
1278 {
1279   short case_goto = 0, case_gosub = 0;
1280   int cur_ln, gosub_ln = 0;
1281   
1282   accept(TOKENIZER_CASE_ELSE);
1283   if(select_stack_ptr > 0) {
1284     if (!select_stack[select_stack_ptr - 1].case_run) {
1285       case_goto = (tokenizer_token() == TOKENIZER_GOTO); 
1286       case_gosub = (tokenizer_token() == TOKENIZER_GOSUB); 
1287 //GOSUB - save curr linenumber
1288       cur_ln = tokenizer_line_number();
1289 //GOSUB
1290       statement();
1291 //GOSUB  - save new linenumber, reset to curr linenumber
1292       if (case_gosub) { 
1293         gosub_ln = tokenizer_line_number();
1294         jump_line(cur_ln+1);
1295         DEBUG_PRINTF("case_else_statement: GOSUB: toLN=%d, nextLN=%d\n", gosub_ln, cur_ln+1);
1296       }
1297 //GOSUB
1298       DEBUG_PRINTF("case_else_statement: case_else execute\n");
1299     } else {
1300       DEBUG_PRINTF("case_else_statement: case_else jump; case_run: %d\n", select_stack[select_stack_ptr - 1].case_run);
1301       accept_cr();
1302     }
1303 //REM
1304     while ((tokenizer_token() == TOKENIZER_REM) && (!case_goto)) {statement();}
1305 //REM
1306     if (case_goto) { dec_select_stack(); } else { 
1307 //GOSUB test for end_select and set to gosub-linenumber
1308       if (tokenizer_token() != TOKENIZER_END_SELECT) {
1309         DEBUG_PRINTF("ubasic.c: select_statement(): don't found end_select\n");
1310         ended = 1;
1311         ubasic_error = UBASIC_E_PARSE;
1312       } else { 
1313           end_select_statement(); 
1314         if (case_gosub) {
1315           gosub_stack[gosub_stack_ptr-1] = tokenizer_line_number();
1316           jump_line(gosub_ln);
1317           DEBUG_PRINTF("end_select_statement: GOSUB: returnLN=%d\n", gosub_stack[gosub_stack_ptr-1]);
1318         }
1319       }  
1320 //GOSUB      
1321     }
1322   } else {
1323     DEBUG_PRINTF("case_else_statement: SELECT-Stack fault\n");
1324     ended = 1;
1325     ubasic_error = UBASIC_E_UNMATCHED_END_SELECT;
1326   }
1327 }
1328 /*---------------------------------------------------------------------------*/
1329 static void
1330 select_statement(void)
1331 {
1332  
1333   int select_value;
1334   
1335   accept(TOKENIZER_SELECT);
1336   select_value = expr();  
1337   accept(TOKENIZER_CR);
1338 //REM
1339     while (tokenizer_token() == TOKENIZER_REM) {statement();}
1340 //REM
1341   
1342   if(select_stack_ptr < MAX_SELECT_STACK_DEPTH) {
1343     select_stack[select_stack_ptr].select_value = select_value;
1344     select_stack[select_stack_ptr].case_run = 0;
1345     DEBUG_PRINTF("select_statement: new select, value %d\n",select_stack[select_stack_ptr].select_value);
1346     select_stack_ptr++;
1347     if (tokenizer_token() != TOKENIZER_CASE) {
1348       DEBUG_PRINTF("ubasic.c: select_statement(): don't found case-statement\n");
1349       ended = 1;
1350       ubasic_error = UBASIC_E_PARSE;
1351     }
1352     else { case_statement(); }
1353   } else {
1354     DEBUG_PRINTF("select_statement: SELECT-stack depth exceeded\n");
1355     ended = 1;
1356     ubasic_error = UBASIC_E_SELECT_STACK_EXHAUSTED;
1357   }
1358 }
1359 /* SELECT-STATEMENT END                                                      */
1360 /*---------------------------------------------------------------------------*/
1361 static void
1362 let_statement(void)
1363 {
1364  
1365   int var;
1366 
1367   var = tokenizer_variable_num();
1368 
1369   accept(TOKENIZER_VARIABLE);
1370   accept(TOKENIZER_EQ);
1371   ubasic_set_variable(var, expr());
1372   DEBUG_PRINTF("let_statement: assign %d to %d\n", variables[var], var);
1373   accept_cr();
1374 }
1375 /*---------------------------------------------------------------------------*/
1376 static void
1377 rem_statement(void)
1378 {
1379   accept(TOKENIZER_REM);
1380   DEBUG_PRINTF("rem_statement\n");
1381   accept(TOKENIZER_CR);
1382 }
1383 /*---------------------------------------------------------------------------*/
1384 static void
1385 cls_statement(void)
1386 {
1387   accept(TOKENIZER_CLS);
1388   console_clear();
1389   DEBUG_PRINTF("cls_statement\n");
1390   accept(TOKENIZER_CR);
1391 }
1392 /*---------------------------------------------------------------------------*/
1393 static void
1394 gosub_statement(void)
1395 {
1396   accept(TOKENIZER_GOSUB);
1397   if(tokenizer_token() == TOKENIZER_STRING) {
1398     tokenizer_string(string, sizeof(string));
1399     do {
1400     tokenizer_next();
1401     } while(tokenizer_token() != TOKENIZER_CR);
1402     accept(TOKENIZER_CR);
1403     if(gosub_stack_ptr < MAX_GOSUB_STACK_DEPTH) {
1404 /*    tokenizer_line_number_inc();*/
1405       gosub_stack[gosub_stack_ptr] = tokenizer_line_number();
1406       gosub_stack_ptr++;
1407       jump_label(string);
1408     } else {
1409       DEBUG_PRINTF("gosub_statement: gosub stack exhausted\n");
1410       ended = 1;
1411       ubasic_error = UBASIC_E_GOSUB_STACK_EXHAUSTED;
1412     }
1413   } else {
1414     DEBUG_PRINTF("ubasic.c: goto_statement(): no label specified\n");
1415     ended = 1;
1416     ubasic_error = UBASIC_E_UNK_LABEL;
1417   }
1418 }
1419 /*---------------------------------------------------------------------------*/
1420 static void
1421 return_statement(void)
1422 {
1423   accept(TOKENIZER_RETURN);
1424   if(gosub_stack_ptr > 0) {
1425     gosub_stack_ptr--;
1426     jump_line(gosub_stack[gosub_stack_ptr]);
1427   } else {
1428     DEBUG_PRINTF("return_statement: non-matching return\n");
1429     ended = 1;
1430     ubasic_error = UBASIC_E_UNMATCHED_RETURN;
1431   }
1432 }
1433 /*---------------------------------------------------------------------------*/
1434 static void
1435 next_statement(void)
1436 {
1437   int var, value;
1438   
1439   accept(TOKENIZER_NEXT);
1440   var = tokenizer_variable_num();
1441   accept(TOKENIZER_VARIABLE);
1442   if(for_stack_ptr > 0 &&
1443      var == for_stack[for_stack_ptr - 1].for_variable) {
1444     value = ubasic_get_variable(var) + for_stack[for_stack_ptr - 1].step;
1445     ubasic_set_variable(var, value);
1446     
1447     if(((for_stack[for_stack_ptr - 1].step > 0) && (value <= for_stack[for_stack_ptr - 1].to)) ||
1448        ((for_stack[for_stack_ptr - 1].step < 0) && (value >= for_stack[for_stack_ptr - 1].to)))
1449         jump_line(for_stack[for_stack_ptr - 1].line_after_for); 
1450     else {
1451       for_stack_ptr--;
1452       accept(TOKENIZER_CR);
1453     }
1454   } else {
1455     DEBUG_PRINTF("next_statement: non-matching next (expected %d, found %d)\n", for_stack[for_stack_ptr - 1].for_variable, var);
1456     ended = 1;
1457     ubasic_error = UBASIC_E_UNMATCHED_NEXT;
1458   }
1459 
1460 }
1461 /*---------------------------------------------------------------------------*/
1462 static void
1463 for_statement(void)
1464 {
1465   int for_variable, to, step;
1466   
1467   accept(TOKENIZER_FOR);
1468   for_variable = tokenizer_variable_num();
1469   accept(TOKENIZER_VARIABLE);
1470   accept(TOKENIZER_EQ);
1471   ubasic_set_variable(for_variable, expr());
1472   accept(TOKENIZER_TO);
1473   to = expr();                     
1474   step = 1;
1475   if (tokenizer_token() != TOKENIZER_CR) {
1476           accept(TOKENIZER_STEP);
1477           step = expr();         
1478   }
1479   accept(TOKENIZER_CR);
1480 
1481   if(for_stack_ptr < MAX_FOR_STACK_DEPTH) {
1482     for_stack[for_stack_ptr].line_after_for = tokenizer_line_number();
1483     for_stack[for_stack_ptr].for_variable = for_variable;
1484     for_stack[for_stack_ptr].to = to;
1485     for_stack[for_stack_ptr].step = step;
1486     DEBUG_PRINTF("for_statement: new for, var %d to %d\n",
1487                  for_stack[for_stack_ptr].for_variable,
1488                  for_stack[for_stack_ptr].to);
1489                  
1490     for_stack_ptr++;
1491   } else {
1492     DEBUG_PRINTF("for_statement: for stack depth exceeded\n");
1493     ended = 1;
1494     ubasic_error = UBASIC_E_FOR_STACK_EXHAUSTED;
1495   }
1496 }
1497 /*---------------------------------------------------------------------------*/
1498 static void
1499 do_statement(void)
1500 {
1501   accept(TOKENIZER_DO);
1502   accept(TOKENIZER_CR);
1503   if(do_stack_ptr < MAX_DO_STACK_DEPTH) {
1504      do_stack[do_stack_ptr] = tokenizer_line_number();
1505      do_stack_ptr++;
1506   } else {
1507     DEBUG_PRINTF("do_statement: do stack depth exceeded\n");
1508     ended = 1;
1509     ubasic_error = UBASIC_E_DO_STACK_EXHAUSTED;
1510   }
1511 }
1512 /*---------------------------------------------------------------------------*/
1513 static void
1514 until_statement(void)
1515 {
1516   int r;
1517   
1518   accept(TOKENIZER_UNTIL);
1519   r = relation();
1520   if(do_stack_ptr > 0) {
1521     if(!r) {
1522       jump_line(do_stack[do_stack_ptr-1]);
1523     } else {
1524       do_stack_ptr--;
1525           accept_cr();
1526     }
1527   } else {
1528     DEBUG_PRINTF("until_statement: unmatched until\n");
1529     ended = 1;
1530     ubasic_error = UBASIC_E_UNMATCHED_UNTIL;
1531   }
1532 }
1533 /*---------------------------------------------------------------------------*/
1534 static void
1535 while_statement(void)
1536 {
1537   int r, while_cntr;
1538   
1539   accept(TOKENIZER_WHILE);
1540   if(while_stack_ptr < MAX_WHILE_STACK_DEPTH) {
1541     if ((while_stack_ptr == 0)||((while_stack_ptr > 0) && (while_stack[while_stack_ptr-1] != tokenizer_line_number()))){
1542       while_stack[while_stack_ptr] = tokenizer_line_number();
1543       while_stack_ptr++;
1544     }
1545   } else {
1546     DEBUG_PRINTF("while_statement: while stack depth exceeded\n");
1547     ended = 1;
1548     ubasic_error = UBASIC_E_WHILE_STACK_EXHAUSTED;
1549     return;
1550   }
1551 
1552   r = relation();
1553   if(while_stack_ptr > 0) {
1554     if(!r) {
1555         while_cntr=0;
1556       while((tokenizer_token() != TOKENIZER_WEND  || while_cntr ) && 
1557               tokenizer_token() != TOKENIZER_ENDOFINPUT){   
1558               if (tokenizer_token() == TOKENIZER_WHILE) while_cntr+=1;
1559               if (tokenizer_token() == TOKENIZER_WEND) while_cntr-=1;           
1560               tokenizer_next();
1561             }  
1562       while_stack_ptr--;
1563     
1564       accept(TOKENIZER_WEND);
1565       accept(TOKENIZER_CR);     
1566     } else {
1567           accept_cr();        
1568     }
1569   } else {
1570     DEBUG_PRINTF("while_statement: unmatched wend\n");
1571     ended = 1;
1572     ubasic_error = UBASIC_E_UNMATCHED_WEND;
1573   }
1574 }
1575 /*---------------------------------------------------------------------------*/
1576 static void
1577 wend_statement(void)
1578 {
1579   accept(TOKENIZER_WEND);
1580   if(while_stack_ptr > 0) {
1581     jump_line(while_stack[while_stack_ptr-1]);
1582   } else {
1583     DEBUG_PRINTF("wend_statement: unmatched wend\n");
1584     ended = 1;
1585     ubasic_error = UBASIC_E_UNMATCHED_WEND;
1586   }
1587 }
1588 /*---------------------------------------------------------------------------*/
1589 static void
1590 end_statement(void)
1591 {
1592   accept(TOKENIZER_END);
1593   ended = 1;
1594 }
1595 /*---------------------------------------------------------------------------*/
1596 static void
1597 click_statement(void)
1598 {
1599   int k;
1600   accept(TOKENIZER_CLICK);
1601   k = ubasic_get_key_arg();
1602   if (k > 0) {
1603     action_push_click(k);
1604     flag_yield=1;
1605   }
1606 
1607   DEBUG_PRINTF("End of click\n");
1608   accept_cr();
1609 }
1610 /*---------------------------------------------------------------------------*/
1611 static void
1612 press_statement(void)
1613 {
1614   int k;
1615   accept(TOKENIZER_PRESS);
1616   k = ubasic_get_key_arg();
1617   if (k > 0) {
1618     action_push_press(k);
1619     flag_yield=1;
1620   }
1621   DEBUG_PRINTF("End of press\n");
1622   accept_cr();
1623 }
1624 /*---------------------------------------------------------------------------*/
1625 static void
1626 release_statement(void)
1627 {
1628   int k;
1629   accept(TOKENIZER_RELEASE);
1630   k = ubasic_get_key_arg();
1631   if (k > 0) {
1632     action_push_release(k);
1633     flag_yield=1;
1634   }
1635   DEBUG_PRINTF("End of release\n");
1636   accept_cr();
1637 }
1638 /*---------------------------------------------------------------------------*/
1639 
1640 // Process a sleep function from the stack
1641 static int action_stack_AS_UBASIC_SLEEP()
1642 {
1643     if (get_tick_count() >= action_top(2))
1644     {
1645         action_pop_func(1);
1646         return 1;
1647     }
1648     return 0;
1649 }
1650 
1651 static int sleep_delay(int delay)
1652 {
1653     /* delay of -1 signals indefinite (actually 1 day) delay */
1654     if (delay == -1)
1655         delay = 86400000;
1656 
1657     if (delay > 0)
1658         return delay + get_tick_count();
1659 
1660     return 0;
1661 }
1662 
1663 static void
1664 sleep_statement(void)
1665 {
1666     accept(TOKENIZER_SLEEP);
1667 
1668     int delay = sleep_delay(expr());
1669     if (delay > 0)
1670     {
1671         action_push(delay);
1672         action_push_func(action_stack_AS_UBASIC_SLEEP);
1673     }
1674 
1675     flag_yield=1;
1676     DEBUG_PRINTF("End of sleep\n");
1677     accept_cr();
1678 }
1679 /*---------------------------------------------------------------------------*/
1680 static void
1681 shoot_statement(void)
1682 {
1683   accept(TOKENIZER_SHOOT);
1684   ubasic_as_ret_var_num = -1;
1685   if (tokenizer_token() != TOKENIZER_CR)
1686   {
1687     ubasic_as_ret_var_num = tokenizer_variable_num();
1688     accept(TOKENIZER_VARIABLE);
1689   }
1690   action_push_shoot(1);
1691   flag_yield=1;
1692   DEBUG_PRINTF("End of shoot\n");
1693   accept_cr();
1694 }
1695 
1696 /*---------------------------------------------------------------------------*/
1697 static void set_console_layout(void)
1698 {
1699   int x1,y1,x2,y2;
1700   accept(TOKENIZER_SET_CONSOLE_LAYOUT);
1701   x1 = expr();
1702   y1 = expr();
1703   x2 = expr();
1704   y2 = expr();
1705   console_set_layout(x1,y1,x2,y2);
1706   accept_cr();  
1707 }
1708 /*---------------------------------------------------------------------------*/
1709 static void set_console_autoredraw(void)
1710 {
1711   accept(TOKENIZER_SET_CONSOLE_AUTOREDRAW);
1712   console_set_autoredraw(expr());
1713   accept_cr();  
1714 }
1715 /*---------------------------------------------------------------------------*/
1716 static void console_redraw_statement(void)
1717 {
1718   accept(TOKENIZER_CONSOLE_REDRAW);
1719   console_redraw();
1720     accept_cr();
1721 }
1722 
1723 static void set_yield_statement()
1724 {
1725     accept(TOKENIZER_SET_YIELD);
1726     int val = expr();
1727     yield_max_lines = val?val:YIELD_MAX_LINES_DEFAULT;
1728     val = expr();
1729     yield_max_ms = val?val:YIELD_MAX_MS_DEFAULT;
1730     accept_cr();
1731 }
1732 
1733 /*---------------------------------------------------------------------------*/
1734 
1735 #ifdef INCLUDE_OLD_GET__SYNTAX
1736 
1737 // Call 'func' to get a CHDK short value and store in named parameter
1738 static void get_short_var_statement(int token, short (*func)(void))
1739 {
1740     int var;
1741     accept(token);
1742     var = tokenizer_variable_num();
1743     accept(TOKENIZER_VARIABLE);
1744     ubasic_set_variable(var, func());
1745     accept_cr();
1746 }
1747 
1748 // Call 'func' to get a CHDK int value and store in named parameter
1749 static void get_int_var_statement(int token, int (*func)(void))
1750 {
1751     int var;
1752     accept(token);
1753     var = tokenizer_variable_num();
1754     accept(TOKENIZER_VARIABLE);
1755     ubasic_set_variable(var, func());
1756     accept_cr();
1757 }
1758 
1759 static void get_prop_statement()
1760 {
1761     int var, var1;
1762     accept(TOKENIZER_GET_PROP);
1763     var = expr();
1764     var1 = tokenizer_variable_num();
1765     accept(TOKENIZER_VARIABLE);
1766     ubasic_set_variable(var1, shooting_get_prop(var));
1767         
1768     accept_cr();
1769 }
1770 
1771 #endif
1772 
1773 // Call CHDK function 'func' with one int parameter
1774 static void one_int_param_function(int token, void (*func)(int))
1775 {
1776     accept(token);
1777     func(expr());
1778     accept_cr();
1779 }
1780 
1781 // Call CHDK function 'func' with one short parameter
1782 static void one_short_param_function(int token, void (*func)(short))
1783 {
1784     accept(token);
1785     func(expr());
1786     accept_cr();
1787 }
1788 
1789 // Call CHDK function 'func' with one int parameter plus a second value 'p2'
1790 // static void one_int_param_plus_const_function(int token, void (*func)(int,short), short p2)
1791 // {
1792 //     accept(token);
1793 //     func(expr(),p2);
1794 //     accept_cr();
1795 // }
1796 
1797 // Call CHDK function 'func' with one short parameter plus a second value 'p2'
1798 // static void one_short_param_plus_const_function(int token, void (*func)(short,short), short p2)
1799 // {
1800 //     accept(token);
1801 //     func(expr(),p2);
1802 //     accept_cr();
1803 // }
1804 
1805 /*---------------------------------------------------------------------------*/
1806 
1807 
1808 static void set_ev_statement()
1809         {
1810             int to;
1811             accept(TOKENIZER_SET_EV);
1812             to = expr();
1813                 shooting_set_prop(camera_info.props.ev_correction_1, to);
1814                 shooting_set_prop(camera_info.props.ev_correction_2, to);
1815             accept_cr();
1816         }
1817 
1818 static void set_movie_status_statement()
1819 {
1820     accept(TOKENIZER_SET_MOVIE_STATUS);
1821     set_movie_status(expr());
1822     accept_cr();
1823 }
1824 
1825 // Set the property 'prop' value from the next expression
1826 static void set_propcase_statement(int token, int prop)
1827 {
1828     accept(token);
1829         shooting_set_prop(prop, expr());
1830     accept_cr();
1831 }
1832 
1833 
1834 static void set_mf_statement()
1835 {
1836    accept(TOKENIZER_SET_MF);
1837    if (expr() > 0) DoMFLock();
1838    else UnlockMF();
1839    accept_cr();
1840 }
1841 
1842 static void set_focus_statement()
1843 {
1844     accept(TOKENIZER_SET_FOCUS);
1845     int sd = expr();
1846     // if sd override not available now, fail immediately without calling set_focus
1847     // to avoid unexpected results with SET_LATER
1848     if(shooting_can_focus()) {
1849         // NOTE duplicated in modules/luascript.c and lib/ubasic/ubasic.c
1850         // in AF lock or MF (canon or set by MF functions), set focus now
1851         if (shooting_get_prop(camera_info.props.af_lock) 
1852           || shooting_get_focus_mode()
1853           || camera_info.state.mode_video)  // TODO video needs to be investigated, carried over from old code
1854         {
1855           shooting_set_focus(sd, SET_NOW);
1856         }
1857         else
1858         {
1859           // in an AF mode, set later
1860           shooting_set_focus(sd, SET_LATER);
1861         }
1862     }
1863     accept_cr();
1864 }
1865 
1866 static void set_led_statement()
1867 {
1868     int to, to1, to2;
1869     accept(TOKENIZER_SET_LED);
1870     to = expr();
1871     to1 = expr();
1872         to2 = 200;
1873         if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
1874                 to2 = expr();
1875     }
1876         camera_set_led(to, to1, to2);
1877     accept_cr();
1878 }
1879 
1880 static void set_prop_statement()
1881 {
1882     int to, to1;
1883     accept(TOKENIZER_SET_PROP);
1884     to = expr();
1885     to1 = expr();
1886         shooting_set_prop(to, to1);
1887     accept_cr();
1888 }
1889 
1890 /*---------------------------------------------------------------------------*/
1891 
1892 static void set_autostart_statement()
1893 {
1894     int to;
1895     accept(TOKENIZER_SET_SCRIPT_AUTOSTART);
1896     to = expr();
1897 #ifndef UBASIC_TEST
1898         if (to >= 0 && to <= 3) conf.script_startup=to;
1899         conf_save();
1900 #endif
1901     accept_cr();
1902 }
1903 
1904 static void set_capture_mode_canon_statement()
1905 {
1906     int to;
1907     accept(TOKENIZER_SET_CAPTURE_MODE_CANON);
1908     to = expr();
1909     // if the value as negative, assume it is a mistakenly sign extended PROPCASE_SHOOTING_MODE value
1910     if( to < 0) 
1911         to &= 0xFFFF;
1912     shooting_set_mode_canon(to);
1913     accept_cr();
1914 }
1915 
1916 static void reboot_statement() {
1917     accept(TOKENIZER_REBOOT);
1918     if(tokenizer_token() == TOKENIZER_STRING) {
1919         tokenizer_string(string, sizeof(string));
1920         tokenizer_next();
1921             reboot(string);
1922     } else {
1923             reboot(NULL);
1924     }
1925 }
1926 
1927 static void set_config_value_statement()
1928 {
1929     int id, value;
1930     tConfigVal configVal = {0};
1931     
1932     accept(TOKENIZER_SET_CONFIG_VALUE);
1933     id = expr();
1934     value = expr();
1935     if( conf_getValue(id, &configVal) == CONF_VALUE ) {
1936         configVal.numb = value;
1937         configVal.isNumb = 1;
1938         conf_setValue(id, configVal);
1939     }
1940     accept_cr();
1941 }
1942 
1943 /*---------------------------------------------------------------------------*/
1944 
1945 // Wait for a button to be pressed and released (or the timeout to expire)
1946 static int action_stack_AS_UBASIC_WAIT_CLICK()
1947 {
1948     // Check key pressed or timeout
1949     if ((get_tick_count() >= action_top(2)) || camera_info.state.kbd_last_clicked)
1950     {
1951         // If timed out set key state to "no_key", otherwise key pressed so set last checked time
1952         if (!camera_info.state.kbd_last_clicked)
1953             camera_info.state.kbd_last_clicked=0xFFFF;
1954         else
1955             camera_info.state.kbd_last_checked_time = camera_info.state.kbd_last_clicked_time;
1956 
1957         action_pop_func(1);
1958         return 1;
1959     }
1960 
1961     return 0;
1962 }
1963 
1964 static void wait_click_statement()
1965 {
1966     accept(TOKENIZER_WAIT_CLICK);
1967 
1968     int delay = -1;
1969     if ((tokenizer_token() != TOKENIZER_CR) && (tokenizer_token() != TOKENIZER_ELSE))
1970     {
1971         delay = expr();
1972         if (delay == 0) delay = -1;
1973     }
1974     delay = sleep_delay(delay);
1975 
1976     accept_cr();
1977 
1978     // Reset 'clicked' key if it has not changed since last time
1979     if (camera_info.state.kbd_last_clicked_time <= camera_info.state.kbd_last_checked_time)
1980     {
1981         camera_info.state.kbd_last_clicked = 0;
1982     }
1983 
1984     // Set up for wait or click testing
1985     action_push(delay);
1986     action_push_func(action_stack_AS_UBASIC_WAIT_CLICK);
1987 
1988     // Check for short delay or key already pressed by calling action stack routine once now
1989     if (action_stack_AS_UBASIC_WAIT_CLICK() == 0)
1990     {
1991         flag_yield=1;
1992     }
1993 }
1994 
1995 static void is_key_statement(void)
1996 {
1997     int var;
1998     accept(TOKENIZER_IS_KEY);
1999     var = tokenizer_variable_num();
2000     accept(TOKENIZER_VARIABLE);
2001     ubasic_set_variable(var, script_key_is_clicked(ubasic_get_key_arg()));
2002     DEBUG_PRINTF("End of is_key\n");
2003     accept_cr();
2004 }
2005 
2006 static void set_exit_key_statement()
2007 {
2008     int k;
2009     accept(TOKENIZER_SET_EXIT_KEY);
2010     if(tokenizer_token() == TOKENIZER_STRING) 
2011     {
2012         tokenizer_string(string, sizeof(string));
2013         k = script_keyid_by_name(string);
2014         if (k <= 0)
2015         {
2016           ubasic_error = UBASIC_E_UNK_KEY;
2017           ended = 1 ;
2018         }
2019         else
2020         {
2021             script_set_terminate_key(k,string);
2022         }
2023     } 
2024     else 
2025     {
2026        DEBUG_PRINTF("ubasic.c: set_exit_key no key specified\n");
2027        ended = 1;
2028        ubasic_error = UBASIC_E_UNK_KEY;
2029     }
2030     accept_cr() ;
2031 }
2032 
2033 static void get_config_value_statement()
2034 {
2035     int var, var1, var2;
2036     tConfigVal configVal;
2037     accept(TOKENIZER_GET_CONFIG_VALUE);
2038     var = expr();
2039     var1 = expr();
2040     var2 = tokenizer_variable_num();
2041     accept(TOKENIZER_VARIABLE);
2042     if( conf_getValue(var, &configVal) == CONF_VALUE ) {
2043         ubasic_set_variable(var2, configVal.numb);
2044     } else {
2045         ubasic_set_variable(var2, var1);
2046     }
2047     accept_cr();
2048 }
2049 
2050 static void on_off_statement(int token, void (*on)(void), void (*off)(void))
2051 {
2052   accept(token);
2053   if (expr() > 0) on();
2054   else off();
2055   accept_cr();
2056 }
2057 
2058 
2059 static void shutdown_statement(void){
2060   accept(TOKENIZER_SHUT_DOWN);
2061   camera_shutdown_in_a_second();
2062   accept_cr();
2063 }
2064 
2065 static void uB_set_av96(int param){
2066   shooting_set_av96( param, shooting_in_progress()?SET_NOW:SET_LATER );
2067   return ;
2068 }
2069 
2070 static void uB_set_av96_direct(int param){
2071   shooting_set_av96_direct( param, shooting_in_progress()?SET_NOW:SET_LATER );
2072   return ;
2073 }
2074 
2075 static void uB_set_tv96(int param){
2076   shooting_set_tv96( param, shooting_in_progress()?SET_NOW:SET_LATER );
2077   return ;
2078 }
2079 
2080 static void uB_set_tv96_direct(int param){
2081   shooting_set_tv96_direct( param, shooting_in_progress()?SET_NOW:SET_LATER);
2082   return ;
2083 }
2084 
2085 static void uB_set_sv96(int param){
2086   shooting_set_sv96( param, shooting_in_progress()?SET_NOW:SET_LATER );
2087   return ;
2088 }
2089 
2090 static void uB_set_nd_filter_state(int param) {
2091    shooting_set_nd_filter_state( param, shooting_in_progress()?SET_NOW:SET_LATER );
2092   return ;
2093 }
2094 
2095 static void uB_set_iso_real(int param) {
2096   shooting_set_iso_real( param, shooting_in_progress()?SET_NOW:SET_LATER );
2097   return ;
2098 }
2099 
2100 /*---------------------------------------------------------------------------*/
2101 
2102 static void md_get_cell_diff_statement()
2103 {
2104     int var, col, row;
2105     accept(TOKENIZER_MD_GET_CELL_DIFF);
2106 
2107     col=expr();tokenizer_next();
2108 
2109     row=expr();tokenizer_next();
2110 
2111     var = tokenizer_variable_num();
2112     accept(TOKENIZER_VARIABLE);
2113     accept_cr();
2114 
2115 #ifdef UBASIC_TEST
2116     // TODO: add something here for ubasic_test
2117 #else
2118     ubasic_set_variable(var, libmotiondetect->md_get_cell_diff(col,row));
2119 #endif
2120 }
2121 
2122 static void md_get_cell_val_statement()
2123 {
2124     int var, col, row;
2125     accept(TOKENIZER_MD_GET_CELL_VAL);
2126 
2127     col=expr();tokenizer_next();
2128 
2129     row=expr();tokenizer_next();
2130 
2131     var = tokenizer_variable_num();
2132     accept(TOKENIZER_VARIABLE);
2133     accept_cr();
2134 
2135 #ifdef UBASIC_TEST
2136     // TODO: add something here for ubasic_test
2137 #else
2138     ubasic_set_variable(var, libmotiondetect->md_get_cell_val(col,row));
2139 #endif
2140 }
2141 
2142 static void md_detect_motion_statement()
2143 {
2144     int columns;
2145     int rows;
2146     int pixel_measure_mode;
2147     int detection_timeout;
2148     int measure_interval;
2149     int threshold;
2150     int draw_grid=0;
2151     int clipping_region_mode=0;
2152     int clipping_region_row1=0;
2153     int clipping_region_column1=0;
2154     int clipping_region_row2=0;
2155     int clipping_region_column2=0;
2156     int parameters=0;
2157     int pixels_step=1;
2158     int msecs_before_trigger=0;
2159 
2160     accept(TOKENIZER_MD_DETECT_MOTION);
2161 
2162     columns=expr();tokenizer_next();
2163 
2164     rows=expr();tokenizer_next();
2165 
2166     pixel_measure_mode=expr();tokenizer_next();
2167 
2168     detection_timeout=expr();tokenizer_next();
2169 
2170     measure_interval=expr();tokenizer_next();
2171 
2172     threshold=expr();tokenizer_next();
2173 
2174     draw_grid=expr();tokenizer_next();
2175 
2176     ubasic_as_ret_var_num = tokenizer_variable_num();
2177 
2178     accept(TOKENIZER_VARIABLE);
2179 
2180     if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE) {
2181         // eat COMA     
2182         //                      tokenizer_next();
2183     }
2184 
2185     if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE) {
2186         tokenizer_next();
2187         clipping_region_mode = expr();
2188     }
2189     if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2190         tokenizer_next();
2191         clipping_region_column1 = expr();
2192     }
2193     if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2194         tokenizer_next();
2195         clipping_region_row1 = expr();
2196     }
2197     if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2198         tokenizer_next();
2199         clipping_region_column2 = expr();
2200     }
2201     if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2202         tokenizer_next();
2203         clipping_region_row2 = expr();
2204     }
2205     if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2206         tokenizer_next();
2207         parameters = expr();
2208     }
2209     if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2210         tokenizer_next();
2211         pixels_step = expr();
2212     }
2213 
2214     if (tokenizer_token() != TOKENIZER_CR && tokenizer_token() != TOKENIZER_ELSE ) {
2215         tokenizer_next();
2216         msecs_before_trigger = expr();
2217     }
2218 
2219     accept_cr();
2220 
2221 #ifdef UBASIC_TEST
2222     // TODO: add something here for ubasic_test
2223 #else
2224     libmotiondetect->md_init_motion_detector(
2225         columns, rows, pixel_measure_mode, detection_timeout, 
2226         measure_interval, threshold, draw_grid,
2227         clipping_region_mode,
2228         clipping_region_column1, clipping_region_row1,
2229         clipping_region_column2, clipping_region_row2,
2230         parameters, pixels_step, msecs_before_trigger);
2231 #endif
2232 
2233     flag_yield=1;
2234 }
2235 
2236 /*---------------------------------------------------------------------------*/
2237 static int _shot_histogram_set(int enable)
2238 {
2239 #ifdef UBASIC_TEST
2240     return 0;
2241 #else
2242     return libshothisto->shot_histogram_set(enable);
2243 #endif
2244 }
2245 
2246 /*---------------------------------------------------------------------------*/
2247 
2248 static void
2249 statement(void)
2250 {
2251   ubasic_token token;
2252 
2253   token = tokenizer_token();
2254 
2255   switch(token) {
2256   // aelock
2257   case TOKENIZER_SET_AELOCK:
2258       on_off_statement(token, DoAELock, UnlockAE);
2259       break;
2260   // aflock
2261   case TOKENIZER_SET_AFLOCK:
2262       on_off_statement(token, DoAFLock, UnlockAF);
2263       break;
2264 
2265   case TOKENIZER_PRINT_SCREEN:
2266       one_int_param_function(token, script_print_screen_statement);
2267       break;
2268   case TOKENIZER_PRINT:
2269       print_statement();
2270       break;
2271 
2272   case TOKENIZER_SLEEP:
2273       sleep_statement();
2274       break;
2275   case TOKENIZER_CLICK:
2276       click_statement();
2277       break;
2278   case TOKENIZER_PRESS:
2279       press_statement();
2280       break;
2281   case TOKENIZER_RELEASE:
2282       release_statement();
2283       break;
2284   case TOKENIZER_SHOOT:
2285       shoot_statement();
2286       break;
2287   case TOKENIZER_SET_CONSOLE_LAYOUT:
2288       set_console_layout();
2289       break;
2290   case TOKENIZER_SET_CONSOLE_AUTOREDRAW:
2291       set_console_autoredraw();
2292       break;
2293   case TOKENIZER_CONSOLE_REDRAW:
2294       console_redraw_statement();
2295       break;
2296 #ifdef INCLUDE_OLD_GET__SYNTAX
2297   case TOKENIZER_GET_TV96:
2298       get_short_var_statement(token, shooting_get_tv96);
2299       break;
2300   case TOKENIZER_GET_USER_TV96:
2301       get_short_var_statement(token, shooting_get_user_tv96);
2302       break;
2303   case TOKENIZER_GET_USER_TV_ID:
2304       get_int_var_statement(token, shooting_get_user_tv_id);
2305       break;
2306   case TOKENIZER_GET_AV96:
2307       get_short_var_statement(token, shooting_get_av96);
2308       break;
2309   case TOKENIZER_GET_USER_AV96:
2310       get_short_var_statement(token, shooting_get_user_av96);
2311       break;
2312   case TOKENIZER_GET_USER_AV_ID:
2313       get_int_var_statement(token, shooting_get_user_av_id);
2314       break;
2315   case TOKENIZER_GET_ZOOM:
2316       get_int_var_statement(token, shooting_get_zoom);
2317       break;
2318   case TOKENIZER_GET_FOCUS:
2319       get_int_var_statement(token, shooting_get_subject_distance);
2320       break;
2321   case TOKENIZER_GET_NEAR_LIMIT:
2322       get_int_var_statement(token, shooting_get_near_limit_of_acceptable_sharpness);
2323       break;
2324   case TOKENIZER_GET_FAR_LIMIT:
2325       get_int_var_statement(token, shooting_get_far_limit_of_acceptable_sharpness);
2326       break;
2327   case TOKENIZER_GET_DOF:
2328       get_int_var_statement(token, shooting_get_depth_of_field);
2329       break;
2330   case TOKENIZER_GET_HYPERFOCAL_DIST:
2331       get_int_var_statement(token, shooting_get_hyperfocal_distance);
2332       break;
2333   case TOKENIZER_GET_ISO_MARKET:
2334       get_short_var_statement(token, shooting_get_iso_market);
2335       break;
2336   case TOKENIZER_GET_ISO_REAL:
2337       get_short_var_statement(token, shooting_get_iso_real);
2338       break;
2339   case TOKENIZER_GET_BV96:
2340       get_short_var_statement(token, shooting_get_bv96);
2341       break;
2342   case TOKENIZER_GET_SV96:
2343       get_short_var_statement(token, shooting_get_sv96_real);
2344       break;
2345   case TOKENIZER_GET_ISO_MODE:
2346       get_int_var_statement(token, shooting_get_iso_mode);
2347       break;
2348   case TOKENIZER_GET_VBATT:
2349       get_int_var_statement(token, (int (*)(void))stat_get_vbatt);
2350       break;
2351   case TOKENIZER_GET_DISK_SIZE:
2352       get_int_var_statement(token, (int (*)(void))GetTotalCardSpaceKb);
2353       break;
2354   case TOKENIZER_GET_FREE_DISK_SPACE:
2355       get_int_var_statement(token, (int (*)(void))GetFreeCardSpaceKb);
2356       break;
2357   case TOKENIZER_GET_JPG_COUNT:
2358       get_int_var_statement(token, (int (*)(void))GetJpgCount);
2359       break;
2360   case TOKENIZER_GET_RAW_COUNT:
2361       get_int_var_statement(token, (int (*)(void))GetRawCount);
2362       break;
2363   case TOKENIZER_GET_PROP:
2364       get_prop_statement();
2365       break;
2366 #endif
2367   case TOKENIZER_SET_TV96_DIRECT:
2368       one_int_param_function(token, uB_set_tv96_direct);
2369       break;
2370   case TOKENIZER_SET_TV96:
2371       one_int_param_function(token, uB_set_tv96);
2372       break;
2373   case TOKENIZER_PLAY_SOUND:
2374       one_int_param_function(token, (void (*)(int))play_sound);
2375       break;
2376   case TOKENIZER_SET_USER_TV96:
2377       one_short_param_function(token, shooting_set_user_tv96);
2378       break;
2379   case TOKENIZER_SET_USER_TV_BY_ID:
2380       one_int_param_function(token, shooting_set_user_tv_by_id);
2381       break;
2382   case TOKENIZER_SET_USER_TV_BY_ID_REL:
2383       one_int_param_function(token, shooting_set_user_tv_by_id_rel);
2384       break;
2385   case TOKENIZER_SET_AV96_DIRECT:
2386       one_int_param_function(token, uB_set_av96_direct );
2387       break;
2388   case TOKENIZER_SET_AV96:
2389       one_int_param_function(token, uB_set_av96 );
2390       break;
2391     
2392   case TOKENIZER_SET_USER_AV96:
2393       one_short_param_function(token, shooting_set_user_av96);
2394       break;
2395   case TOKENIZER_SET_USER_AV_BY_ID:
2396       one_int_param_function(token, shooting_set_user_av_by_id);
2397       break;
2398   case TOKENIZER_SET_USER_AV_BY_ID_REL:
2399       one_int_param_function(token, shooting_set_user_av_by_id_rel);
2400       break;
2401    
2402   case TOKENIZER_SET_ND_FILTER:
2403       one_int_param_function(token, uB_set_nd_filter_state );
2404       break;
2405   
2406   case TOKENIZER_SET_ZOOM:
2407       one_int_param_function(token, shooting_set_zoom);
2408       break;
2409   case TOKENIZER_SET_ZOOM_REL:
2410       one_int_param_function(token, shooting_set_zoom_rel);
2411       break;
2412   case TOKENIZER_SET_ZOOM_SPEED:
2413       one_int_param_function(token, shooting_set_zoom_speed);
2414       break;
2415   case TOKENIZER_SET_FOCUS:
2416       set_focus_statement();
2417       break;
2418   case TOKENIZER_SET_MF:
2419       set_mf_statement();
2420       break;
2421 
2422 /*
2423   case TOKENIZER_SET_ISO_MARKET:
2424       one_int_param_function(token, shooting_set_iso_market);
2425       break;
2426   case TOKENIZER_SET_ISO_DL_F_B:
2427       one_int_param_function(token, shooting_set_iso_real_delta_from_base);
2428       break;
2429 */  
2430   //ARM End
2431   
2432   case TOKENIZER_SET_ISO_REAL:
2433       one_int_param_function(token, uB_set_iso_real );
2434       break;
2435   case TOKENIZER_SET_SV96:
2436       one_int_param_function(token, uB_set_sv96 );
2437       break;
2438 
2439   case TOKENIZER_SET_ISO_MODE:
2440       one_int_param_function(token, shooting_set_iso_mode);
2441       break;
2442 
2443   case TOKENIZER_SET_PROP:
2444       set_prop_statement();
2445       break;
2446   case TOKENIZER_SET_LED:
2447       set_led_statement();
2448       break;
2449 
2450   case TOKENIZER_SET_EV:
2451      set_ev_statement();
2452      break;
2453 
2454   case TOKENIZER_SET_MOVIE_STATUS:
2455       set_movie_status_statement();
2456       break;
2457   case TOKENIZER_SET_RESOLUTION:
2458       set_propcase_statement(token, camera_info.props.resolution);
2459       break;
2460   case TOKENIZER_SET_QUALITY:
2461       set_propcase_statement(token, camera_info.props.quality);
2462       break;
2463 
2464   case TOKENIZER_WAIT_CLICK:
2465       wait_click_statement();
2466       break;
2467   case TOKENIZER_IS_KEY:
2468       is_key_statement();
2469       break;
2470   case TOKENIZER_SET_EXIT_KEY:
2471       set_exit_key_statement();
2472       break;
2473 
2474   case TOKENIZER_WHEEL_LEFT:
2475       accept(token);
2476       JogDial_CCW();
2477       accept_cr();
2478       break;
2479   case TOKENIZER_WHEEL_RIGHT:
2480       accept(token);
2481       JogDial_CW();
2482       accept_cr();
2483       break;
2484 
2485   case TOKENIZER_IF:
2486       if_statement();
2487       break;
2488   case TOKENIZER_ELSE:
2489       else_statement();
2490       break;
2491   case TOKENIZER_ENDIF:
2492       endif_statement();
2493       break;
2494   case TOKENIZER_SELECT:
2495       select_statement();
2496       break;
2497   case TOKENIZER_CASE:
2498       case_statement();
2499       break;
2500   case TOKENIZER_CASE_ELSE:
2501       case_else_statement();
2502       break;
2503   case TOKENIZER_GOTO:
2504       goto_statement();
2505       break;
2506   case TOKENIZER_GOSUB:
2507       gosub_statement();
2508       break;
2509   case TOKENIZER_RETURN:
2510       return_statement();
2511       break;
2512   case TOKENIZER_FOR:
2513       for_statement();
2514       break;
2515   case TOKENIZER_NEXT:
2516       next_statement();
2517       break;
2518   case TOKENIZER_DO:
2519       do_statement();
2520       break;
2521   case TOKENIZER_UNTIL:
2522       until_statement();
2523       break;
2524   case TOKENIZER_WHILE:
2525       while_statement();
2526       break;
2527   case TOKENIZER_WEND:
2528       wend_statement();
2529       break;
2530   case TOKENIZER_END:
2531       end_statement();
2532       break;
2533   case TOKENIZER_LET:
2534       accept(TOKENIZER_LET);
2535       /* Fall through. */
2536   case TOKENIZER_VARIABLE:
2537       let_statement();
2538       break;
2539   case TOKENIZER_REM:
2540       rem_statement();
2541       break;
2542   case TOKENIZER_CLS:
2543       cls_statement();
2544       break;
2545   case TOKENIZER_SET_RAW:
2546       accept(token);
2547       conf.save_raw = expr();
2548       accept_cr();
2549       break;
2550   case TOKENIZER_SET_RAW_NR:
2551       accept(token);
2552       conf.raw_nr = expr();
2553       accept_cr();
2554       break;
2555   case TOKENIZER_SET_SCRIPT_AUTOSTART:
2556       set_autostart_statement();
2557       break;
2558   case TOKENIZER_EXIT_ALT:
2559       accept(token);
2560       exit_alt();
2561       accept_cr();
2562       break;
2563   case TOKENIZER_ENTER_ALT:
2564       accept(token);
2565       enter_alt(1);
2566       accept_cr();
2567       break;      
2568   case TOKENIZER_SHUT_DOWN:
2569       shutdown_statement();
2570   case TOKENIZER_SET_BACKLIGHT:
2571       on_off_statement(token, TurnOnBackLight, TurnOffBackLight);
2572       break;
2573   case TOKENIZER_SET_LCDDISPLAY:
2574       on_off_statement(token, TurnOnDisplay, TurnOffDisplay);
2575       break;
2576   case TOKENIZER_SET_DRAW_TITLE_LINE:
2577       accept(token);
2578       camera_info.state.osd_title_line=expr()?1:0;
2579       accept_cr();
2580       break;
2581       
2582       // >> mx3 . motion detector
2583   case   TOKENIZER_MD_DETECT_MOTION:
2584       md_detect_motion_statement();
2585       break;
2586   case  TOKENIZER_MD_GET_CELL_DIFF:
2587       md_get_cell_diff_statement();
2588       break;
2589   case  TOKENIZER_MD_GET_CELL_VAL:
2590       md_get_cell_val_statement();
2591       break;
2592       // << mx3 . motion_detector
2593 
2594   case TOKENIZER_MD_AF_LED_CONTROL:
2595       accept(token);
2596       camera_info.perf.md_af_on_delay = expr();
2597       camera_info.perf.md_af_on_time = expr();
2598       if ((camera_info.perf.md_af_on_time > 0) && (camera_info.cam_af_led >= 0)) {
2599           camera_info.perf.md_af_tuning = 1;        // Enable MD testing with AF LED
2600           // clear previous values
2601           memset(&camera_info.perf.af_led,0,sizeof(camera_info.perf.af_led));
2602           camera_info.perf.af_led.min = 0xFFFFFFFF;
2603       } else {
2604           camera_info.perf.md_af_tuning = 0;        // Disable MD testing
2605       }
2606       accept_cr();
2607       break;
2608 
2609   case TOKENIZER_SHOT_HISTO_ENABLE:
2610       one_int_param_function(token, (void (*)(int))_shot_histogram_set);
2611       break;
2612 
2613   case TOKENIZER_SET_RECORD:
2614       one_int_param_function(token, shooting_set_playrec_mode);
2615       break;
2616 
2617   case TOKENIZER_SET_CAPTURE_MODE:
2618       one_int_param_function(token, (void (*)(int))shooting_set_mode_chdk);
2619       break;
2620 
2621   case TOKENIZER_SET_CAPTURE_MODE_CANON:
2622       set_capture_mode_canon_statement();
2623       break;
2624 
2625   case TOKENIZER_REBOOT:
2626       reboot_statement();
2627       break;
2628 
2629   case TOKENIZER_GET_CONFIG_VALUE:
2630     get_config_value_statement();
2631     break;
2632 
2633   case TOKENIZER_SET_CONFIG_VALUE:
2634     set_config_value_statement();
2635     break;
2636   case TOKENIZER_SET_YIELD:
2637     set_yield_statement();
2638     break;
2639 
2640   case TOKENIZER_USB_SYNC_WAIT:
2641     accept(TOKENIZER_USB_SYNC_WAIT);
2642 #ifdef UBASIC_TEST
2643     // TODO: add something here for ubasic_test
2644 #else
2645     if (expr()) usb_sync_wait_flag = 1;
2646     else        usb_sync_wait_flag = 0;
2647 #endif
2648     accept_cr();
2649     break;
2650 
2651   case TOKENIZER_SET_REMOTE_TIMING:
2652     accept(TOKENIZER_SET_REMOTE_TIMING);
2653 #ifdef UBASIC_TEST
2654     // TODO: add something here for ubasic_test
2655 #else
2656     int hpenable= expr();
2657     if ( hpenable > 0) start_usb_HPtimer(hpenable);
2658     else stop_usb_HPtimer();
2659 #endif
2660     accept_cr();
2661     break;
2662 
2663   default:
2664       DEBUG_PRINTF("ubasic.c: statement(): not implemented %d\n", token);
2665       ended = 1;
2666       ubasic_error = UBASIC_E_UNK_STATEMENT;
2667   }
2668 }
2669 
2670 /*---------------------------------------------------------------------------*/
2671 static void
2672 line_statement(void)
2673 {
2674   /* line numbers have been removed */
2675   DEBUG_PRINTF("----------- Line number %d ---------\n", tokenizer_line_number());
2676   /*    current_linenum = tokenizer_num();*/
2677 #if 0
2678   if (tokenizer_token() == TOKENIZER_LABEL) {
2679 #ifdef DEBUG
2680       tokenizer_label(string, sizeof(string));
2681       DEBUG_PRINTF("line_statement: label: %s\n", string );
2682 #endif
2683       accept(TOKENIZER_LABEL);
2684       accept(TOKENIZER_CR);
2685       return;
2686   }
2687 #endif 
2688   /* reyalp - eat up to 100 labels or rems at a time so they don't cost 10ms each */
2689   int count = 100;
2690   do {
2691     int r=tokenizer_token();
2692     if ( r == TOKENIZER_LABEL ) {
2693       /* hit limit and we are on a label, return */
2694       if( count == 1 )
2695         return;
2696 #ifdef DEBUG
2697       tokenizer_label(string, sizeof(string));
2698       DEBUG_PRINTF("line_statement: label: %s\n", string );
2699 #endif
2700       accept(TOKENIZER_LABEL);
2701       accept(TOKENIZER_CR);
2702     }
2703     else if ( r == TOKENIZER_REM ) {
2704       rem_statement();
2705     }
2706     else {
2707       break;
2708     }
2709   } while(--count);
2710   statement();
2711   return;
2712 }
2713 /*---------------------------------------------------------------------------*/
2714 int ubasic_run(void)
2715 {
2716     unsigned start_tick = get_tick_count();
2717     unsigned lines = 0;
2718     flag_yield = 0;
2719 
2720     do
2721     {
2722         if ( ended || tokenizer_finished() )
2723         {
2724             DEBUG_PRINTF("uBASIC program finished\n");
2725             if (ubasic_error)
2726             {
2727                 // Generate error message
2728                 char buf[100];
2729                 const char *msg;
2730                 if (ubasic_error >= UBASIC_E_ENDMARK)
2731                 {
2732                     msg = ubasic_errstrings[UBASIC_E_UNKNOWN_ERROR];
2733                 }
2734                 else
2735                 {
2736                     msg = ubasic_errstrings[ubasic_error];
2737                 }
2738                 sprintf(buf, "uBASIC:%d %s ", ubasic_linenumber(), msg);
2739                 // Show error message
2740                 script_console_add_error((long)buf);
2741                 script_console_add_error(LANG_CONSOLE_TEXT_TERMINATED);
2742                 return SCRIPT_RUN_ERROR;
2743             }
2744             // Show 'Finished' message
2745             script_console_add_error(LANG_CONSOLE_TEXT_FINISHED);
2746             return SCRIPT_RUN_ENDED;
2747         }
2748 
2749         line_statement();
2750 
2751         // Return control to CHDK only if external processing required  
2752         if ( flag_yield )
2753             return SCRIPT_RUN_RUNNING;
2754 
2755         lines++;
2756     } while (lines < yield_max_lines && get_tick_count() - start_tick < yield_max_ms);
2757 
2758     return SCRIPT_RUN_RUNNING;
2759 }
2760 /*---------------------------------------------------------------------------*/
2761 void
2762 ubasic_set_variable(int varnum, int value)
2763 {
2764   if(varnum >= 0 && varnum < MAX_VARNUM) {
2765     variables[varnum] = value;
2766   }
2767 }
2768 /*---------------------------------------------------------------------------*/
2769 int
2770 ubasic_get_variable(int varnum)
2771 {
2772   if(varnum >= 0 && varnum < MAX_VARNUM) {
2773     return variables[varnum];
2774   }
2775   return 0;
2776 }
2777 /*---------------------------------------------------------------------------*/
2778 void
2779 ubasic_end() {
2780 }
2781 /*---------------------------------------------------------------------------*/
2782 
2783 // Save Action Stack 'return' value in selected variable
2784 void ubasic_set_as_ret(int md_ret)
2785 {
2786     if (ubasic_as_ret_var_num >= 0)
2787         ubasic_set_variable(ubasic_as_ret_var_num, md_ret);
2788 }

/* [<][>][^][v][top][bottom][index][help] */