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

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