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

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