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

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