root/lib/ubasic/tokenizer.c

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

DEFINITIONS

This source file includes following definitions.
  1. singlechar
  2. get_next_token
  3. tokenizer_init
  4. tokenizer_token
  5. tokenizer_next
  6. tokenizer_num
  7. tokenizer_string
  8. tokenizer_label
  9. tokenizer_error_print
  10. tokenizer_finished
  11. tokenizer_variable_num
  12. tokenizer_line_number

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

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