00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "proj.h"
00024 #include "top.h"
00025 #include "bad.h"
00026 #include "com.h"
00027 #include "lex.h"
00028 #include "malloc.h"
00029 #include "src.h"
00030 #include "debug.h"
00031 #include "flags.h"
00032 #include "input.h"
00033 #include "toplev.h"
00034 #include "output.h"
00035 #include "ggc.h"
00036
00037 static void ffelex_append_to_token_ (char c);
00038 static int ffelex_backslash_ (int c, ffewhereColumnNumber col);
00039 static void ffelex_bad_1_ (ffebad errnum, ffewhereLineNumber ln0,
00040 ffewhereColumnNumber cn0);
00041 static void ffelex_bad_2_ (ffebad errnum, ffewhereLineNumber ln0,
00042 ffewhereColumnNumber cn0, ffewhereLineNumber ln1,
00043 ffewhereColumnNumber cn1);
00044 static void ffelex_bad_here_ (int num, ffewhereLineNumber ln0,
00045 ffewhereColumnNumber cn0);
00046 static void ffelex_finish_statement_ (void);
00047 static int ffelex_get_directive_line_ (char **text, FILE *finput);
00048 static int ffelex_hash_ (FILE *f);
00049 static ffewhereColumnNumber ffelex_image_char_ (int c,
00050 ffewhereColumnNumber col);
00051 static void ffelex_include_ (void);
00052 static bool ffelex_is_free_char_ctx_contin_ (ffewhereColumnNumber col);
00053 static bool ffelex_is_free_nonc_ctx_contin_ (ffewhereColumnNumber col);
00054 static void ffelex_next_line_ (void);
00055 static void ffelex_prepare_eos_ (void);
00056 static void ffelex_send_token_ (void);
00057 static ffelexHandler ffelex_swallow_tokens_ (ffelexToken t);
00058 static ffelexToken ffelex_token_new_ (void);
00059
00060
00061
00062
00063 #define FFELEX_columnINITIAL_SIZE_ 255
00064
00065
00066
00067
00068
00069 static char *ffelex_card_image_;
00070 static ffewhereColumnNumber ffelex_card_size_;
00071 static ffewhereColumnNumber ffelex_card_length_;
00072
00073
00074 #define FFELEX_FREE_MAX_COLUMNS_ 132
00075
00076
00077
00078
00079 static bool ffelex_saw_tab_;
00080
00081
00082
00083 static bool ffelex_bad_line_ = FALSE;
00084
00085
00086 static ffewhereColumnNumber ffelex_final_nontab_column_;
00087
00088
00089
00090 static ffelexType ffelex_first_char_[256];
00091
00092
00093
00094
00095
00096 static ffewhereFile ffelex_current_wf_;
00097
00098
00099
00100 static bool ffelex_permit_include_;
00101
00102
00103
00104 static bool ffelex_set_include_;
00105
00106
00107 static FILE *ffelex_include_file_;
00108 static bool ffelex_include_free_form_;
00109 static ffewhereFile ffelex_include_wherefile_;
00110
00111
00112 static ffewhereLineNumber ffelex_linecount_current_;
00113
00114 static ffewhereLineNumber ffelex_linecount_next_;
00115
00116
00117
00118 static ffewhereLine ffelex_current_wl_;
00119 static ffewhereColumn ffelex_current_wc_;
00120
00121
00122
00123
00124
00125 #define FFELEX_columnTOKEN_SIZE_ 63
00126 #if FFELEX_columnTOKEN_SIZE_ < FFEWHERE_indexMAX
00127 #error "token size too small!"
00128 #endif
00129
00130
00131 static ffelexToken ffelex_token_;
00132
00133
00134 static ffelexHandler ffelex_handler_;
00135
00136
00137 static bool ffelex_names_;
00138
00139
00140 static bool ffelex_names_pure_;
00141
00142
00143
00144 static bool ffelex_hexnum_;
00145
00146
00147 static ffelexHandler ffelex_eos_handler_;
00148
00149
00150
00151 static unsigned long int ffelex_number_of_tokens_;
00152
00153
00154
00155
00156 static unsigned long int ffelex_label_tokens_;
00157
00158
00159 static long int ffelex_total_tokens_ = 0;
00160 static long int ffelex_old_total_tokens_ = 1;
00161 static long int ffelex_token_nextid_ = 0;
00162
00163
00164
00165
00166
00167
00168 static long int ffelex_expecting_hollerith_;
00169
00170
00171
00172
00173
00174
00175 static long int ffelex_raw_mode_;
00176
00177
00178 static char ffelex_raw_char_;
00179
00180
00181
00182
00183
00184 static bool ffelex_backslash_reconsider_ = FALSE;
00185
00186
00187 static int *ffelex_kludge_chars_ = NULL;
00188
00189
00190 static bool ffelex_kludge_flag_ = FALSE;
00191
00192
00193 static ffewhereLine ffelex_raw_where_line_;
00194 static ffewhereColumn ffelex_raw_where_col_;
00195
00196
00197
00198
00199
00200
00201 static void
00202 ffelex_append_to_token_ (char c)
00203 {
00204 if (ffelex_token_->text == NULL)
00205 {
00206 ffelex_token_->text
00207 = malloc_new_ksr (malloc_pool_image (), "FFELEX token text",
00208 FFELEX_columnTOKEN_SIZE_ + 1);
00209 ffelex_token_->size = FFELEX_columnTOKEN_SIZE_;
00210 ffelex_token_->length = 0;
00211 }
00212 else if (ffelex_token_->length >= ffelex_token_->size)
00213 {
00214 ffelex_token_->text
00215 = malloc_resize_ksr (malloc_pool_image (),
00216 ffelex_token_->text,
00217 (ffelex_token_->size << 1) + 1,
00218 ffelex_token_->size + 1);
00219 ffelex_token_->size <<= 1;
00220 assert (ffelex_token_->length < ffelex_token_->size);
00221 }
00222 #ifdef MAP_CHARACTER
00223 Sorry, MAP_CHARACTER is not going to work as expected in GNU Fortran,
00224 please contact fortran@gnu.org if you wish to fund work to
00225 port g77 to non-ASCII machines.
00226 #endif
00227 ffelex_token_->text[ffelex_token_->length++] = c;
00228 }
00229
00230
00231
00232
00233 static int
00234 ffelex_backslash_ (int c, ffewhereColumnNumber col)
00235 {
00236 static int state = 0;
00237 static unsigned int count;
00238 static int code;
00239 static unsigned int firstdig = 0;
00240 static int nonnull;
00241 static ffewhereLineNumber line;
00242 static ffewhereColumnNumber column;
00243
00244
00245
00246
00247
00248 #define wide_flag 0
00249 #define warn_traditional 0
00250 #define flag_traditional 0
00251
00252 switch (state)
00253 {
00254 case 0:
00255 if ((c == '\\')
00256 && (ffelex_raw_mode_ != 0)
00257 && ffe_is_backslash ())
00258 {
00259 state = 1;
00260 column = col + 1;
00261 line = ffelex_linecount_current_;
00262 return EOF;
00263 }
00264 return c;
00265
00266 case 1:
00267 state = 0;
00268 switch (c)
00269 {
00270 case 'x':
00271 if (warn_traditional)
00272 {
00273
00274 ffebad_start_msg_lex ("The meaning of `\\x' (at %0) varies with -traditional",
00275 FFEBAD_severityWARNING);
00276 ffelex_bad_here_ (0, line, column);
00277 ffebad_finish ();
00278 }
00279
00280 if (flag_traditional)
00281 return c;
00282
00283 code = 0;
00284 count = 0;
00285 nonnull = 0;
00286 state = 2;
00287 return EOF;
00288
00289 case '0': case '1': case '2': case '3': case '4':
00290 case '5': case '6': case '7':
00291 code = c - '0';
00292 count = 1;
00293 state = 3;
00294 return EOF;
00295
00296 case '\\': case '\'': case '"':
00297 return c;
00298
00299 #if 0
00300 case '\n':
00301 ffelex_next_line_ ();
00302 *ignore_ptr = 1;
00303 return 0;
00304 #endif
00305
00306 case 'n':
00307 return TARGET_NEWLINE;
00308
00309 case 't':
00310 return TARGET_TAB;
00311
00312 case 'r':
00313 return TARGET_CR;
00314
00315 case 'f':
00316 return TARGET_FF;
00317
00318 case 'b':
00319 return TARGET_BS;
00320
00321 case 'a':
00322 if (warn_traditional)
00323 {
00324
00325 ffebad_start_msg_lex ("The meaning of `\\a' (at %0) varies with -traditional",
00326 FFEBAD_severityWARNING);
00327 ffelex_bad_here_ (0, line, column);
00328 ffebad_finish ();
00329 }
00330
00331 if (flag_traditional)
00332 return c;
00333 return TARGET_BELL;
00334
00335 case 'v':
00336 #if 0
00337 if (flag_traditional)
00338 return c;
00339 #endif
00340 return TARGET_VT;
00341
00342 case 'e':
00343 case 'E':
00344 case '(':
00345 case '{':
00346 case '[':
00347 case '%':
00348 if (pedantic)
00349 {
00350 char m[2];
00351
00352 m[0] = c;
00353 m[1] = '\0';
00354
00355 ffebad_start_msg_lex ("Non-ISO-C-standard escape sequence `\\%A' at %0",
00356 FFEBAD_severityPEDANTIC);
00357 ffelex_bad_here_ (0, line, column);
00358 ffebad_string (m);
00359 ffebad_finish ();
00360 }
00361 return (c == 'E' || c == 'e') ? 033 : c;
00362
00363 case '?':
00364 return c;
00365
00366 default:
00367 if (c >= 040 && c < 0177)
00368 {
00369 char m[2];
00370
00371 m[0] = c;
00372 m[1] = '\0';
00373
00374 ffebad_start_msg_lex ("Unknown escape sequence `\\%A' at %0",
00375 FFEBAD_severityPEDANTIC);
00376 ffelex_bad_here_ (0, line, column);
00377 ffebad_string (m);
00378 ffebad_finish ();
00379 }
00380 else if (c == EOF)
00381 {
00382
00383 ffebad_start_msg_lex ("Unterminated escape sequence `\\' at %0",
00384 FFEBAD_severityPEDANTIC);
00385 ffelex_bad_here_ (0, line, column);
00386 ffebad_finish ();
00387 }
00388 else
00389 {
00390 char m[20];
00391
00392 sprintf (&m[0], "%x", c);
00393
00394 ffebad_start_msg_lex ("Unknown escape sequence `\\' followed by char code 0x%A at %0",
00395 FFEBAD_severityPEDANTIC);
00396 ffelex_bad_here_ (0, line, column);
00397 ffebad_string (m);
00398 ffebad_finish ();
00399 }
00400 }
00401 return c;
00402
00403 case 2:
00404 if (ISXDIGIT (c))
00405 {
00406 code = (code * 16) + hex_value (c);
00407 if (code != 0 || count != 0)
00408 {
00409 if (count == 0)
00410 firstdig = code;
00411 count++;
00412 }
00413 nonnull = 1;
00414 return EOF;
00415 }
00416
00417 state = 0;
00418
00419 if (! nonnull)
00420 {
00421
00422 ffebad_start_msg_lex ("\\x used at %0 with no following hex digits",
00423 FFEBAD_severityFATAL);
00424 ffelex_bad_here_ (0, line, column);
00425 ffebad_finish ();
00426 }
00427 else if (count == 0)
00428
00429 ;
00430 else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
00431 || (count > 1
00432 && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4))
00433 <= (int) firstdig)))
00434 {
00435
00436 ffebad_start_msg_lex ("Hex escape at %0 out of range",
00437 FFEBAD_severityPEDANTIC);
00438 ffelex_bad_here_ (0, line, column);
00439 ffebad_finish ();
00440 }
00441 break;
00442
00443 case 3:
00444 if ((c <= '7') && (c >= '0') && (count++ < 3))
00445 {
00446 code = (code * 8) + (c - '0');
00447 return EOF;
00448 }
00449 state = 0;
00450 break;
00451
00452 default:
00453 assert ("bad backslash state" == NULL);
00454 abort ();
00455 }
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 if (!wide_flag
00466 && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT
00467 && code >= (1 << TYPE_PRECISION (char_type_node)))
00468 {
00469
00470 ffebad_start_msg_lex ("Escape sequence at %0 out of range for character",
00471 FFEBAD_severityFATAL);
00472 ffelex_bad_here_ (0, line, column);
00473 ffebad_finish ();
00474 }
00475
00476 if (c == EOF)
00477 {
00478
00479 ffelex_append_to_token_ (code);
00480 if (ffelex_raw_mode_ > 0)
00481 --ffelex_raw_mode_;
00482 return EOF;
00483 }
00484
00485
00486
00487
00488 ffelex_append_to_token_ (code);
00489 if (ffelex_raw_mode_ > 0)
00490 --ffelex_raw_mode_;
00491 ffelex_backslash_reconsider_ = TRUE;
00492 return c;
00493 }
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 static void
00504 ffelex_bad_1_ (ffebad errnum, ffewhereLineNumber ln0, ffewhereColumnNumber cn0)
00505 {
00506 ffewhereLine wl0;
00507 ffewhereColumn wc0;
00508
00509 wl0 = ffewhere_line_new (ln0);
00510 wc0 = ffewhere_column_new (cn0);
00511 ffebad_start_lex (errnum);
00512 ffebad_here (0, wl0, wc0);
00513 ffebad_finish ();
00514 ffewhere_line_kill (wl0);
00515 ffewhere_column_kill (wc0);
00516 }
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527 static void
00528 ffelex_bad_2_ (ffebad errnum, ffewhereLineNumber ln0, ffewhereColumnNumber cn0,
00529 ffewhereLineNumber ln1, ffewhereColumnNumber cn1)
00530 {
00531 ffewhereLine wl0, wl1;
00532 ffewhereColumn wc0, wc1;
00533
00534 wl0 = ffewhere_line_new (ln0);
00535 wc0 = ffewhere_column_new (cn0);
00536 wl1 = ffewhere_line_new (ln1);
00537 wc1 = ffewhere_column_new (cn1);
00538 ffebad_start_lex (errnum);
00539 ffebad_here (0, wl0, wc0);
00540 ffebad_here (1, wl1, wc1);
00541 ffebad_finish ();
00542 ffewhere_line_kill (wl0);
00543 ffewhere_column_kill (wc0);
00544 ffewhere_line_kill (wl1);
00545 ffewhere_column_kill (wc1);
00546 }
00547
00548 static void
00549 ffelex_bad_here_ (int n, ffewhereLineNumber ln0,
00550 ffewhereColumnNumber cn0)
00551 {
00552 ffewhereLine wl0;
00553 ffewhereColumn wc0;
00554
00555 wl0 = ffewhere_line_new (ln0);
00556 wc0 = ffewhere_column_new (cn0);
00557 ffebad_here (n, wl0, wc0);
00558 ffewhere_line_kill (wl0);
00559 ffewhere_column_kill (wc0);
00560 }
00561
00562 static int
00563 ffelex_getc_ (FILE *finput)
00564 {
00565 int c;
00566
00567 if (ffelex_kludge_chars_ == NULL)
00568 return getc (finput);
00569
00570 c = *ffelex_kludge_chars_++;
00571 if (c != 0)
00572 return c;
00573
00574 ffelex_kludge_chars_ = NULL;
00575 return getc (finput);
00576 }
00577
00578 static int
00579 ffelex_cfebackslash_ (int *use_d, int *d, FILE *finput)
00580 {
00581 register int c = getc (finput);
00582 register int code;
00583 register unsigned count;
00584 unsigned firstdig = 0;
00585 int nonnull;
00586
00587 *use_d = 0;
00588
00589 switch (c)
00590 {
00591 case 'x':
00592 if (warn_traditional)
00593 warning ("the meaning of `\\x' varies with -traditional");
00594
00595 if (flag_traditional)
00596 return c;
00597
00598 code = 0;
00599 count = 0;
00600 nonnull = 0;
00601 while (1)
00602 {
00603 c = getc (finput);
00604 if (! ISXDIGIT (c))
00605 {
00606 *use_d = 1;
00607 *d = c;
00608 break;
00609 }
00610 code = (code * 16) + hex_value (c);
00611 if (code != 0 || count != 0)
00612 {
00613 if (count == 0)
00614 firstdig = code;
00615 count++;
00616 }
00617 nonnull = 1;
00618 }
00619 if (! nonnull)
00620 error ("\\x used with no following hex digits");
00621 else if (count == 0)
00622
00623 ;
00624 else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node)
00625 || (count > 1
00626 && (((unsigned) 1
00627 << (TYPE_PRECISION (integer_type_node) - (count - 1)
00628 * 4))
00629 <= firstdig)))
00630 pedwarn ("hex escape out of range");
00631 return code;
00632
00633 case '0': case '1': case '2': case '3': case '4':
00634 case '5': case '6': case '7':
00635 code = 0;
00636 count = 0;
00637 while ((c <= '7') && (c >= '0') && (count++ < 3))
00638 {
00639 code = (code * 8) + (c - '0');
00640 c = getc (finput);
00641 }
00642 *use_d = 1;
00643 *d = c;
00644 return code;
00645
00646 case '\\': case '\'': case '"':
00647 return c;
00648
00649 case '\n':
00650 ffelex_next_line_ ();
00651 *use_d = 2;
00652 return 0;
00653
00654 case EOF:
00655 *use_d = 1;
00656 *d = EOF;
00657 return EOF;
00658
00659 case 'n':
00660 return TARGET_NEWLINE;
00661
00662 case 't':
00663 return TARGET_TAB;
00664
00665 case 'r':
00666 return TARGET_CR;
00667
00668 case 'f':
00669 return TARGET_FF;
00670
00671 case 'b':
00672 return TARGET_BS;
00673
00674 case 'a':
00675 if (warn_traditional)
00676 warning ("the meaning of `\\a' varies with -traditional");
00677
00678 if (flag_traditional)
00679 return c;
00680 return TARGET_BELL;
00681
00682 case 'v':
00683 #if 0
00684 if (flag_traditional)
00685 return c;
00686 #endif
00687 return TARGET_VT;
00688
00689 case 'e':
00690 case 'E':
00691 if (pedantic)
00692 pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c);
00693 return 033;
00694
00695 case '?':
00696 return c;
00697
00698
00699 case '(':
00700 case '{':
00701 case '[':
00702
00703 case '%':
00704 if (pedantic)
00705 pedwarn ("non-ISO escape sequence `\\%c'", c);
00706 return c;
00707 }
00708 if (c >= 040 && c < 0177)
00709 pedwarn ("unknown escape sequence `\\%c'", c);
00710 else
00711 pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c);
00712 return c;
00713 }
00714
00715
00716
00717 static int
00718 ffelex_cfelex_ (ffelexToken *xtoken, FILE *finput, int c)
00719 {
00720 ffelexToken token;
00721 char buff[129];
00722 char *p;
00723 char *q;
00724 char *r;
00725 register unsigned buffer_length;
00726
00727 if ((*xtoken != NULL) && !ffelex_kludge_flag_)
00728 ffelex_token_kill (*xtoken);
00729
00730 switch (c)
00731 {
00732 case '0': case '1': case '2': case '3': case '4':
00733 case '5': case '6': case '7': case '8': case '9':
00734 buffer_length = ARRAY_SIZE (buff);
00735 p = &buff[0];
00736 q = p;
00737 r = &buff[buffer_length];
00738 for (;;)
00739 {
00740 *p++ = c;
00741 if (p >= r)
00742 {
00743 register unsigned bytes_used = (p - q);
00744
00745 buffer_length *= 2;
00746 q = (char *)xrealloc (q, buffer_length);
00747 p = &q[bytes_used];
00748 r = &q[buffer_length];
00749 }
00750 c = ffelex_getc_ (finput);
00751 if (! ISDIGIT (c))
00752 break;
00753 }
00754 *p = '\0';
00755 token = ffelex_token_new_number (q, ffewhere_line_unknown (),
00756 ffewhere_column_unknown ());
00757
00758 if (q != &buff[0])
00759 free (q);
00760
00761 break;
00762
00763 case '\"':
00764 buffer_length = ARRAY_SIZE (buff);
00765 p = &buff[0];
00766 q = p;
00767 r = &buff[buffer_length];
00768 c = ffelex_getc_ (finput);
00769 for (;;)
00770 {
00771 bool done = FALSE;
00772 int use_d = 0;
00773 int d;
00774
00775 switch (c)
00776 {
00777 case '\"':
00778 c = getc (finput);
00779 done = TRUE;
00780 break;
00781
00782 case '\\':
00783 c = ffelex_cfebackslash_ (&use_d, &d, finput);
00784 break;
00785
00786 case EOF:
00787 case '\n':
00788 error ("badly formed directive -- no closing quote");
00789 done = TRUE;
00790 break;
00791
00792 default:
00793 break;
00794 }
00795 if (done)
00796 break;
00797
00798 if (use_d != 2)
00799 {
00800 *p++ = c;
00801 if (p >= r)
00802 {
00803 register unsigned bytes_used = (p - q);
00804
00805 buffer_length = bytes_used * 2;
00806 q = (char *)xrealloc (q, buffer_length);
00807 p = &q[bytes_used];
00808 r = &q[buffer_length];
00809 }
00810 }
00811 if (use_d == 1)
00812 c = d;
00813 else
00814 c = getc (finput);
00815 }
00816 *p = '\0';
00817 token = ffelex_token_new_character (q, ffewhere_line_unknown (),
00818 ffewhere_column_unknown ());
00819
00820 if (q != &buff[0])
00821 free (q);
00822
00823 break;
00824
00825 default:
00826 token = NULL;
00827 break;
00828 }
00829
00830 *xtoken = token;
00831 return c;
00832 }
00833
00834 static void
00835 ffelex_file_pop_ (const char *input_filename)
00836 {
00837 if (input_file_stack->next)
00838 {
00839 struct file_stack *p = input_file_stack;
00840 input_file_stack = p->next;
00841 free (p);
00842 input_file_stack_tick++;
00843 (*debug_hooks->end_source_file) (input_file_stack->line);
00844 }
00845 else
00846 error ("#-lines for entering and leaving files don't match");
00847
00848
00849
00850 if (input_file_stack)
00851 input_file_stack->name = input_filename;
00852 }
00853
00854 static void
00855 ffelex_file_push_ (int old_lineno, const char *input_filename)
00856 {
00857 struct file_stack *p
00858 = (struct file_stack *) xmalloc (sizeof (struct file_stack));
00859
00860 input_file_stack->line = old_lineno;
00861 p->next = input_file_stack;
00862 p->name = input_filename;
00863 input_file_stack = p;
00864 input_file_stack_tick++;
00865
00866 (*debug_hooks->start_source_file) (0, input_filename);
00867
00868
00869
00870 if (input_file_stack)
00871 input_file_stack->name = input_filename;
00872 }
00873
00874
00875
00876
00877
00878
00879
00880 static void
00881 ffelex_prepare_eos_ ()
00882 {
00883 if (ffelex_token_->type != FFELEX_typeNONE)
00884 {
00885 ffelex_backslash_ (EOF, 0);
00886
00887 switch (ffelex_raw_mode_)
00888 {
00889 case -2:
00890 break;
00891
00892 case -1:
00893 ffebad_start_lex ((ffelex_raw_char_ == '\'') ? FFEBAD_NO_CLOSING_APOSTROPHE
00894 : FFEBAD_NO_CLOSING_QUOTE);
00895 ffebad_here (0, ffelex_token_->where_line, ffelex_token_->where_col);
00896 ffebad_here (1, ffelex_current_wl_, ffelex_current_wc_);
00897 ffebad_finish ();
00898 break;
00899
00900 case 0:
00901 break;
00902
00903 default:
00904 {
00905 char num[20];
00906
00907 ffebad_start_lex (FFEBAD_NOT_ENOUGH_HOLLERITH_CHARS);
00908 ffebad_here (0, ffelex_token_->where_line, ffelex_token_->where_col);
00909 ffebad_here (1, ffelex_current_wl_, ffelex_current_wc_);
00910 sprintf (num, "%lu", (unsigned long) ffelex_raw_mode_);
00911 ffebad_string (num);
00912 ffebad_finish ();
00913
00914 do
00915 {
00916 ffelex_append_to_token_ (' ');
00917 } while (--ffelex_raw_mode_ > 0);
00918 break;
00919 }
00920 }
00921 ffelex_raw_mode_ = 0;
00922 ffelex_send_token_ ();
00923 }
00924 ffelex_token_->type = FFELEX_typeEOS;
00925 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
00926 ffelex_token_->where_col = ffewhere_column_use (ffelex_current_wc_);
00927 }
00928
00929 static void
00930 ffelex_finish_statement_ ()
00931 {
00932 if ((ffelex_number_of_tokens_ == 0)
00933 && (ffelex_token_->type == FFELEX_typeNONE))
00934 return;
00935
00936 if (ffelex_token_->type != FFELEX_typeEOS)
00937 ffelex_prepare_eos_ ();
00938
00939 ffelex_permit_include_ = TRUE;
00940 ffelex_send_token_ ();
00941 ffelex_permit_include_ = FALSE;
00942 ffelex_number_of_tokens_ = 0;
00943 ffelex_label_tokens_ = 0;
00944 ffelex_names_ = TRUE;
00945 ffelex_names_pure_ = FALSE;
00946 ffelex_hexnum_ = FALSE;
00947
00948 if (!ffe_is_ffedebug ())
00949 return;
00950
00951
00952
00953 if (ffelex_total_tokens_ != ffelex_old_total_tokens_)
00954 {
00955 fprintf (dmpout, "; token_track had %ld tokens, now have %ld.\n",
00956 ffelex_old_total_tokens_, ffelex_total_tokens_);
00957 ffelex_old_total_tokens_ = ffelex_total_tokens_;
00958 }
00959 }
00960
00961
00962
00963 static int
00964 ffelex_get_directive_line_ (char **text, FILE *finput)
00965 {
00966 static char *directive_buffer = NULL;
00967 static unsigned buffer_length = 0;
00968 register char *p;
00969 register char *buffer_limit;
00970 register int looking_for = 0;
00971 register int char_escaped = 0;
00972
00973 if (buffer_length == 0)
00974 {
00975 directive_buffer = (char *)xmalloc (128);
00976 buffer_length = 128;
00977 }
00978
00979 buffer_limit = &directive_buffer[buffer_length];
00980
00981 for (p = directive_buffer; ; )
00982 {
00983 int c;
00984
00985
00986 if (p >= buffer_limit)
00987 {
00988 register unsigned bytes_used = (p - directive_buffer);
00989
00990 buffer_length *= 2;
00991 directive_buffer
00992 = (char *)xrealloc (directive_buffer, buffer_length);
00993 p = &directive_buffer[bytes_used];
00994 buffer_limit = &directive_buffer[buffer_length];
00995 }
00996
00997 c = getc (finput);
00998
00999
01000 if ((c == ' ' || c == '\t') && p == directive_buffer)
01001 continue;
01002
01003
01004 if ((c == '\n' && looking_for == 0)
01005 || c == EOF)
01006 {
01007 if (looking_for != 0)
01008 error ("bad directive -- missing close-quote");
01009
01010 *p++ = '\0';
01011 *text = directive_buffer;
01012 return c;
01013 }
01014
01015 *p++ = c;
01016 if (c == '\n')
01017 ffelex_next_line_ ();
01018
01019
01020 if (looking_for)
01021 {
01022 if (looking_for == c && !char_escaped)
01023 looking_for = 0;
01024 }
01025 else
01026 if (c == '\'' || c == '"')
01027 looking_for = c;
01028
01029
01030
01031 char_escaped = (c == '\\' && ! char_escaped);
01032 }
01033 }
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044 #if defined HANDLE_PRAGMA
01045
01046 static int
01047 pragma_getc ()
01048 {
01049 return getc (finput);
01050 }
01051
01052 static void
01053 pragma_ungetc (arg)
01054 int arg;
01055 {
01056 ungetc (arg, finput);
01057 }
01058 #endif
01059
01060 static int
01061 ffelex_hash_ (FILE *finput)
01062 {
01063 register int c;
01064 ffelexToken token = NULL;
01065
01066
01067
01068 c = ffelex_getc_ (finput);
01069 while (c == ' ' || c == '\t')
01070 c = ffelex_getc_ (finput);
01071
01072
01073
01074
01075
01076 if (ISALPHA(c))
01077 {
01078 if (c == 'p')
01079 {
01080 if (getc (finput) == 'r'
01081 && getc (finput) == 'a'
01082 && getc (finput) == 'g'
01083 && getc (finput) == 'm'
01084 && getc (finput) == 'a'
01085 && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'
01086 || c == EOF))
01087 {
01088 #if 0
01089 static char buffer [128];
01090 char * buff = buffer;
01091
01092
01093
01094 while (((c = getc (finput)), ISSPACE(c)))
01095 continue;
01096
01097 do
01098 {
01099 * buff ++ = c;
01100 c = getc (finput);
01101 }
01102 while (c != EOF && ! ISSPACE (c) && c != '\n'
01103 && buff < buffer + 128);
01104
01105 pragma_ungetc (c);
01106
01107 * -- buff = 0;
01108 #ifdef HANDLE_PRAGMA
01109 if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, buffer))
01110 goto skipline;
01111 #endif
01112 #ifdef HANDLE_GENERIC_PRAGMAS
01113 if (handle_generic_pragma (buffer))
01114 goto skipline;
01115 #endif
01116
01117
01118
01119
01120 if (warn_unknown_pragmas > 1
01121 || (warn_unknown_pragmas && ! in_system_header))
01122 warning ("ignoring pragma: %s", token_buffer);
01123 #endif
01124 goto skipline;
01125 }
01126 }
01127
01128 else if (c == 'd')
01129 {
01130 if (getc (finput) == 'e'
01131 && getc (finput) == 'f'
01132 && getc (finput) == 'i'
01133 && getc (finput) == 'n'
01134 && getc (finput) == 'e'
01135 && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'
01136 || c == EOF))
01137 {
01138 char *text;
01139
01140 c = ffelex_get_directive_line_ (&text, finput);
01141
01142 if (debug_info_level == DINFO_LEVEL_VERBOSE)
01143 (*debug_hooks->define) (lineno, text);
01144
01145 goto skipline;
01146 }
01147 }
01148 else if (c == 'u')
01149 {
01150 if (getc (finput) == 'n'
01151 && getc (finput) == 'd'
01152 && getc (finput) == 'e'
01153 && getc (finput) == 'f'
01154 && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n'
01155 || c == EOF))
01156 {
01157 char *text;
01158
01159 c = ffelex_get_directive_line_ (&text, finput);
01160
01161 if (debug_info_level == DINFO_LEVEL_VERBOSE)
01162 (*debug_hooks->undef) (lineno, text);
01163
01164 goto skipline;
01165 }
01166 }
01167 else if (c == 'l')
01168 {
01169 if (getc (finput) == 'i'
01170 && getc (finput) == 'n'
01171 && getc (finput) == 'e'
01172 && ((c = getc (finput)) == ' ' || c == '\t'))
01173 goto linenum;
01174 }
01175 else if (c == 'i')
01176 {
01177 if (getc (finput) == 'd'
01178 && getc (finput) == 'e'
01179 && getc (finput) == 'n'
01180 && getc (finput) == 't'
01181 && ((c = getc (finput)) == ' ' || c == '\t'))
01182 {
01183
01184
01185
01186
01187
01188 while (c == ' ' || c == '\t')
01189 c = getc (finput);
01190
01191
01192 if (c == '\n' || c == EOF)
01193 return c;
01194
01195 c = ffelex_cfelex_ (&token, finput, c);
01196
01197 if ((token == NULL)
01198 || (ffelex_token_type (token) != FFELEX_typeCHARACTER))
01199 {
01200 error ("invalid #ident");
01201 goto skipline;
01202 }
01203
01204 if (! flag_no_ident)
01205 {
01206 #ifdef ASM_OUTPUT_IDENT
01207 ASM_OUTPUT_IDENT (asm_out_file,
01208 ffelex_token_text (token));
01209 #endif
01210 }
01211
01212
01213 goto skipline;
01214 }
01215 }
01216
01217 error ("undefined or invalid # directive");
01218 goto skipline;
01219 }
01220
01221 linenum:
01222
01223
01224
01225 while (c == ' ' || c == '\t')
01226 c = ffelex_getc_ (finput);
01227
01228
01229
01230 if (c == '\n' || c == EOF)
01231 return c;
01232
01233
01234
01235 c = ffelex_cfelex_ (&token, finput, c);
01236
01237 if ((token != NULL)
01238 && (ffelex_token_type (token) == FFELEX_typeNUMBER))
01239 {
01240 int old_lineno = lineno;
01241 const char *old_input_filename = input_filename;
01242 ffewhereFile wf;
01243
01244
01245
01246 int l = atoi (ffelex_token_text (token)) - 1;
01247
01248
01249 while (c == ' ' || c == '\t')
01250 c = ffelex_getc_ (finput);
01251 if (c == '\n' || c == EOF)
01252 {
01253
01254 lineno = l;
01255 if (!ffelex_kludge_flag_)
01256 {
01257 ffewhere_file_set (NULL, TRUE, (ffewhereLineNumber) l);
01258
01259 if (token != NULL)
01260 ffelex_token_kill (token);
01261 }
01262 return c;
01263 }
01264
01265
01266
01267
01268 c = ffelex_cfelex_ (&token, finput, c);
01269
01270 if ((token == NULL)
01271 || (ffelex_token_type (token) != FFELEX_typeCHARACTER))
01272 {
01273 error ("invalid #line");
01274 goto skipline;
01275 }
01276
01277 lineno = l;
01278
01279 if (ffelex_kludge_flag_)
01280 input_filename = ggc_strdup (ffelex_token_text (token));
01281 else
01282 {
01283 wf = ffewhere_file_new (ffelex_token_text (token),
01284 ffelex_token_length (token));
01285 input_filename = ffewhere_file_name (wf);
01286 ffewhere_file_set (wf, TRUE, (ffewhereLineNumber) l);
01287 }
01288
01289 #if 0
01290
01291
01292 in_system_header = 0;
01293 #endif
01294
01295 if (main_input_filename == 0)
01296 main_input_filename = input_filename;
01297
01298
01299 while (c == ' ' || c == '\t')
01300 c = getc (finput);
01301 if (c == '\n' || c == EOF)
01302 {
01303 if (!ffelex_kludge_flag_)
01304 {
01305
01306 if (input_file_stack)
01307 input_file_stack->name = input_filename;
01308
01309 if (token != NULL)
01310 ffelex_token_kill (token);
01311 }
01312 return c;
01313 }
01314
01315 c = ffelex_cfelex_ (&token, finput, c);
01316
01317
01318
01319
01320 if ((token != NULL)
01321 && (ffelex_token_type (token) == FFELEX_typeNUMBER))
01322 {
01323 int num = atoi (ffelex_token_text (token));
01324
01325 if (ffelex_kludge_flag_)
01326 {
01327 lineno = 1;
01328 input_filename = old_input_filename;
01329 error ("use `#line ...' instead of `# ...' in first line");
01330 }
01331
01332 if (num == 1)
01333 {
01334
01335 ffelex_file_push_ (old_lineno, input_filename);
01336 }
01337 else if (num == 2)
01338 {
01339
01340 ffelex_file_pop_ (input_filename);
01341 }
01342
01343
01344 while (c == ' ' || c == '\t')
01345 c = getc (finput);
01346 if (c == '\n' || c == EOF)
01347 {
01348 if (token != NULL)
01349 ffelex_token_kill (token);
01350 return c;
01351 }
01352
01353 c = ffelex_cfelex_ (&token, finput, c);
01354 }
01355
01356
01357
01358 #if 0
01359 if ((token != NULL)
01360 && (ffelex_token_type (token) == FFELEX_typeNUMBER)
01361 && (atoi (ffelex_token_text (token)) == 3))
01362 in_system_header = 1;
01363 #endif
01364
01365 while (c == ' ' || c == '\t')
01366 c = getc (finput);
01367 if (((token != NULL)
01368 || (c != '\n' && c != EOF))
01369 && ffelex_kludge_flag_)
01370 {
01371 lineno = 1;
01372 input_filename = old_input_filename;
01373 error ("use `#line ...' instead of `# ...' in first line");
01374 }
01375 if (c == '\n' || c == EOF)
01376 {
01377 if (token != NULL && !ffelex_kludge_flag_)
01378 ffelex_token_kill (token);
01379 return c;
01380 }
01381 }
01382 else
01383 error ("invalid #-line");
01384
01385
01386 skipline:
01387 if ((token != NULL) && !ffelex_kludge_flag_)
01388 ffelex_token_kill (token);
01389 while ((c = getc (finput)) != EOF && c != '\n')
01390 ;
01391 return c;
01392 }
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425 static ffewhereColumnNumber
01426 ffelex_image_char_ (int c, ffewhereColumnNumber column)
01427 {
01428 ffewhereColumnNumber old_column = column;
01429
01430 if (column >= ffelex_card_size_)
01431 {
01432 ffewhereColumnNumber newmax = ffelex_card_size_ << 1;
01433
01434 if (ffelex_bad_line_)
01435 return column;
01436
01437 if ((newmax >> 1) != ffelex_card_size_)
01438 {
01439 overflow:
01440
01441 ffelex_bad_line_ = TRUE;
01442 strcpy (&ffelex_card_image_[column - 3], "...");
01443 ffelex_card_length_ = column;
01444 ffelex_bad_1_ (FFEBAD_LINE_TOO_LONG,
01445 ffelex_linecount_current_, column + 1);
01446 return column;
01447 }
01448
01449 ffelex_card_image_
01450 = malloc_resize_ksr (malloc_pool_image (),
01451 ffelex_card_image_,
01452 newmax + 9,
01453 ffelex_card_size_ + 9);
01454 ffelex_card_size_ = newmax;
01455 }
01456
01457 switch (c)
01458 {
01459 case '\r':
01460 break;
01461
01462 case '\t':
01463 ffelex_saw_tab_ = TRUE;
01464 ffelex_card_image_[column++] = ' ';
01465 while ((column & 7) != 0)
01466 ffelex_card_image_[column++] = ' ';
01467 break;
01468
01469 case '\0':
01470 if (!ffelex_bad_line_)
01471 {
01472 ffelex_bad_line_ = TRUE;
01473 strcpy (&ffelex_card_image_[column], "[\\0]");
01474 ffelex_card_length_ = column + 4;
01475
01476 ffebad_start_msg_lex ("Null character at %0 -- line ignored",
01477 FFEBAD_severityFATAL);
01478 ffelex_bad_here_ (0, ffelex_linecount_current_, column + 1);
01479 ffebad_finish ();
01480 column += 4;
01481 }
01482 break;
01483
01484 default:
01485 ffelex_card_image_[column++] = c;
01486 break;
01487 }
01488
01489 if (column < old_column)
01490 {
01491 column = old_column;
01492 goto overflow;
01493 }
01494
01495 return column;
01496 }
01497
01498 static void
01499 ffelex_include_ ()
01500 {
01501 ffewhereFile include_wherefile = ffelex_include_wherefile_;
01502 FILE *include_file = ffelex_include_file_;
01503
01504
01505
01506 char *card_image;
01507 ffewhereColumnNumber card_size = ffelex_card_size_;
01508 ffewhereColumnNumber card_length = ffelex_card_length_;
01509 ffewhereLine current_wl = ffelex_current_wl_;
01510 ffewhereColumn current_wc = ffelex_current_wc_;
01511 bool saw_tab = ffelex_saw_tab_;
01512 ffewhereColumnNumber final_nontab_column = ffelex_final_nontab_column_;
01513 ffewhereFile current_wf = ffelex_current_wf_;
01514 ffewhereLineNumber linecount_current = ffelex_linecount_current_;
01515 ffewhereLineNumber linecount_offset
01516 = ffewhere_line_filelinenum (current_wl);
01517 int old_lineno = lineno;
01518 const char *old_input_filename = input_filename;
01519
01520 if (card_length != 0)
01521 {
01522 card_image = malloc_new_ks (malloc_pool_image (),
01523 "FFELEX saved card image",
01524 card_length);
01525 memcpy (card_image, ffelex_card_image_, card_length);
01526 }
01527 else
01528 card_image = NULL;
01529
01530 ffelex_set_include_ = FALSE;
01531
01532 ffelex_next_line_ ();
01533
01534 ffewhere_file_set (include_wherefile, TRUE, 0);
01535
01536 ffelex_file_push_ (old_lineno, ffewhere_file_name (include_wherefile));
01537
01538 if (ffelex_include_free_form_)
01539 ffelex_file_free (include_wherefile, include_file);
01540 else
01541 ffelex_file_fixed (include_wherefile, include_file);
01542
01543 ffelex_file_pop_ (ffewhere_file_name (current_wf));
01544
01545 ffewhere_file_set (current_wf, TRUE, linecount_offset);
01546
01547 ffecom_close_include (include_file);
01548
01549 if (card_length != 0)
01550 {
01551 #ifdef REDUCE_CARD_SIZE_AFTER_BIGGY
01552 #error "need to handle possible reduction of card size here!!"
01553 #endif
01554 assert (ffelex_card_size_ >= card_length);
01555 memcpy (ffelex_card_image_, card_image, card_length);
01556 }
01557 ffelex_card_image_[card_length] = '\0';
01558
01559 input_filename = old_input_filename;
01560 lineno = old_lineno;
01561 ffelex_linecount_current_ = linecount_current;
01562 ffelex_current_wf_ = current_wf;
01563 ffelex_final_nontab_column_ = final_nontab_column;
01564 ffelex_saw_tab_ = saw_tab;
01565 ffelex_current_wc_ = current_wc;
01566 ffelex_current_wl_ = current_wl;
01567 ffelex_card_length_ = card_length;
01568 ffelex_card_size_ = card_size;
01569 }
01570
01571
01572
01573
01574
01575
01576
01577
01578
01579
01580
01581 static bool
01582 ffelex_is_free_char_ctx_contin_ (ffewhereColumnNumber col)
01583 {
01584 while (ffelex_card_image_[col] != '\0')
01585 {
01586 if (ffelex_card_image_[col++] != ' ')
01587 return FALSE;
01588 }
01589 return TRUE;
01590 }
01591
01592
01593
01594
01595
01596
01597
01598
01599
01600
01601
01602 static bool
01603 ffelex_is_free_nonc_ctx_contin_ (ffewhereColumnNumber col)
01604 {
01605 while ((ffelex_card_image_[col] != '\0') && (ffelex_card_image_[col] != '!'))
01606 {
01607 if (ffelex_card_image_[col++] != ' ')
01608 return FALSE;
01609 }
01610 return TRUE;
01611 }
01612
01613 static void
01614 ffelex_next_line_ ()
01615 {
01616 ffelex_linecount_current_ = ffelex_linecount_next_;
01617 ++ffelex_linecount_next_;
01618 ++lineno;
01619 }
01620
01621 static void
01622 ffelex_send_token_ ()
01623 {
01624 ++ffelex_number_of_tokens_;
01625
01626 ffelex_backslash_ (EOF, 0);
01627
01628 if (ffelex_token_->text == NULL)
01629 {
01630 if (ffelex_token_->type == FFELEX_typeCHARACTER)
01631 {
01632 ffelex_append_to_token_ ('\0');
01633 ffelex_token_->length = 0;
01634 }
01635 }
01636 else
01637 ffelex_token_->text[ffelex_token_->length] = '\0';
01638
01639 assert (ffelex_raw_mode_ == 0);
01640
01641 if (ffelex_token_->type == FFELEX_typeNAMES)
01642 {
01643 ffewhere_line_kill (ffelex_token_->currentnames_line);
01644 ffewhere_column_kill (ffelex_token_->currentnames_col);
01645 }
01646
01647 assert (ffelex_handler_ != NULL);
01648 ffelex_handler_ = (ffelexHandler) (*ffelex_handler_) (ffelex_token_);
01649 assert (ffelex_handler_ != NULL);
01650
01651 ffelex_token_kill (ffelex_token_);
01652
01653 ffelex_token_ = ffelex_token_new_ ();
01654 ffelex_token_->uses = 1;
01655 ffelex_token_->text = NULL;
01656 if (ffelex_raw_mode_ < 0)
01657 {
01658 ffelex_token_->type = FFELEX_typeCHARACTER;
01659 ffelex_token_->where_line = ffelex_raw_where_line_;
01660 ffelex_token_->where_col = ffelex_raw_where_col_;
01661 ffelex_raw_where_line_ = ffewhere_line_unknown ();
01662 ffelex_raw_where_col_ = ffewhere_column_unknown ();
01663 }
01664 else
01665 {
01666 ffelex_token_->type = FFELEX_typeNONE;
01667 ffelex_token_->where_line = ffewhere_line_unknown ();
01668 ffelex_token_->where_col = ffewhere_column_unknown ();
01669 }
01670
01671 if (ffelex_set_include_)
01672 ffelex_include_ ();
01673 }
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683 static ffelexHandler
01684 ffelex_swallow_tokens_ (ffelexToken t)
01685 {
01686 assert (ffelex_eos_handler_ != NULL);
01687
01688 if ((ffelex_token_type (t) == FFELEX_typeEOS)
01689 || (ffelex_token_type (t) == FFELEX_typeSEMICOLON))
01690 return (ffelexHandler) (*ffelex_eos_handler_) (t);
01691
01692 return (ffelexHandler) ffelex_swallow_tokens_;
01693 }
01694
01695 static ffelexToken
01696 ffelex_token_new_ ()
01697 {
01698 ffelexToken t;
01699
01700 ++ffelex_total_tokens_;
01701
01702 t = (ffelexToken) malloc_new_ks (malloc_pool_image (),
01703 "FFELEX token", sizeof (*t));
01704 t->id_ = ffelex_token_nextid_++;
01705 return t;
01706 }
01707
01708 static const char *
01709 ffelex_type_string_ (ffelexType type)
01710 {
01711 static const char *const types[] = {
01712 "FFELEX_typeNONE",
01713 "FFELEX_typeCOMMENT",
01714 "FFELEX_typeEOS",
01715 "FFELEX_typeEOF",
01716 "FFELEX_typeERROR",
01717 "FFELEX_typeRAW",
01718 "FFELEX_typeQUOTE",
01719 "FFELEX_typeDOLLAR",
01720 "FFELEX_typeHASH",
01721 "FFELEX_typePERCENT",
01722 "FFELEX_typeAMPERSAND",
01723 "FFELEX_typeAPOSTROPHE",
01724 "FFELEX_typeOPEN_PAREN",
01725 "FFELEX_typeCLOSE_PAREN",
01726 "FFELEX_typeASTERISK",
01727 "FFELEX_typePLUS",
01728 "FFELEX_typeMINUS",
01729 "FFELEX_typePERIOD",
01730 "FFELEX_typeSLASH",
01731 "FFELEX_typeNUMBER",
01732 "FFELEX_typeOPEN_ANGLE",
01733 "FFELEX_typeEQUALS",
01734 "FFELEX_typeCLOSE_ANGLE",
01735 "FFELEX_typeNAME",
01736 "FFELEX_typeCOMMA",
01737 "FFELEX_typePOWER",
01738 "FFELEX_typeCONCAT",
01739 "FFELEX_typeDEBUG",
01740 "FFELEX_typeNAMES",
01741 "FFELEX_typeHOLLERITH",
01742 "FFELEX_typeCHARACTER",
01743 "FFELEX_typeCOLON",
01744 "FFELEX_typeSEMICOLON",
01745 "FFELEX_typeUNDERSCORE",
01746 "FFELEX_typeQUESTION",
01747 "FFELEX_typeOPEN_ARRAY",
01748 "FFELEX_typeCLOSE_ARRAY",
01749 "FFELEX_typeCOLONCOLON",
01750 "FFELEX_typeREL_LE",
01751 "FFELEX_typeREL_NE",
01752 "FFELEX_typeREL_EQ",
01753 "FFELEX_typePOINTS",
01754 "FFELEX_typeREL_GE"
01755 };
01756
01757 if (type >= ARRAY_SIZE (types))
01758 return "???";
01759 return types[type];
01760 }
01761
01762 void
01763 ffelex_display_token (ffelexToken t)
01764 {
01765 if (t == NULL)
01766 t = ffelex_token_;
01767
01768 fprintf (dmpout, "; Token #%lu is %s (line %" ffewhereLineNumber_f "u, col %"
01769 ffewhereColumnNumber_f "u)",
01770 t->id_,
01771 ffelex_type_string_ (t->type),
01772 ffewhere_line_number (t->where_line),
01773 ffewhere_column_number (t->where_col));
01774
01775 if (t->text != NULL)
01776 fprintf (dmpout, ": \"%.*s\"\n",
01777 (int) t->length,
01778 t->text);
01779 else
01780 fprintf (dmpout, ".\n");
01781 }
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793 bool
01794 ffelex_expecting_character ()
01795 {
01796 return (ffelex_raw_mode_ != 0);
01797 }
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807 ffelexHandler
01808 ffelex_file_fixed (ffewhereFile wf, FILE *f)
01809 {
01810 register int c = 0;
01811 register ffewhereColumnNumber column = 0;
01812 bool disallow_continuation_line;
01813 bool ignore_disallowed_continuation = FALSE;
01814 int latest_char_in_file = 0;
01815
01816 ffelexType lextype;
01817 ffewhereColumnNumber first_label_char;
01818
01819 char label_string[6];
01820 int labi;
01821 bool finish_statement;
01822 bool have_content;
01823 bool just_do_label;
01824
01825
01826
01827
01828
01829
01830
01831
01832 assert (ffelex_handler_ != NULL);
01833
01834 lineno = 0;
01835 input_filename = ffewhere_file_name (wf);
01836 ffelex_current_wf_ = wf;
01837 disallow_continuation_line = TRUE;
01838 ignore_disallowed_continuation = FALSE;
01839 ffelex_token_->type = FFELEX_typeNONE;
01840 ffelex_number_of_tokens_ = 0;
01841 ffelex_label_tokens_ = 0;
01842 ffelex_current_wl_ = ffewhere_line_unknown ();
01843 ffelex_current_wc_ = ffewhere_column_unknown ();
01844 latest_char_in_file = '\n';
01845
01846 goto first_line;
01847
01848
01849
01850 beginning_of_line:
01851
01852 disallow_continuation_line = FALSE;
01853
01854
01855
01856 beginning_of_line_again:
01857
01858 #ifdef REDUCE_CARD_SIZE_AFTER_BIGGY
01859 if (ffelex_card_size_ != FFELEX_columnINITIAL_SIZE_)
01860 {
01861 ffelex_card_image_
01862 = malloc_resize_ks (malloc_pool_image (),
01863 ffelex_card_image_,
01864 FFELEX_columnINITIAL_SIZE_ + 9,
01865 ffelex_card_size_ + 9);
01866 ffelex_card_size_ = FFELEX_columnINITIAL_SIZE_;
01867 }
01868 #endif
01869
01870 first_line:
01871
01872 c = latest_char_in_file;
01873 if ((c == EOF) || ((c = ffelex_getc_ (f)) == EOF))
01874 {
01875
01876 end_of_file:
01877
01878
01879
01880 ffelex_finish_statement_ ();
01881 ffewhere_line_kill (ffelex_current_wl_);
01882 ffewhere_column_kill (ffelex_current_wc_);
01883 return (ffelexHandler) ffelex_handler_;
01884 }
01885
01886 ffelex_next_line_ ();
01887
01888 ffelex_bad_line_ = FALSE;
01889
01890
01891
01892 while (((lextype = ffelex_first_char_[c]) == FFELEX_typeCOMMENT)
01893 || (lextype == FFELEX_typeERROR)
01894 || (lextype == FFELEX_typeSLASH)
01895 || (lextype == FFELEX_typeHASH))
01896 {
01897
01898 if ((lextype == FFELEX_typeCOMMENT)
01899 || ((lextype == FFELEX_typeSLASH)
01900 && ((c = getc (f)) == '*')))
01901 {
01902
01903 comment_line:
01904
01905 while ((c != '\n') && (c != EOF))
01906 c = getc (f);
01907 }
01908 else if (lextype == FFELEX_typeHASH)
01909 c = ffelex_hash_ (f);
01910 else if (lextype == FFELEX_typeSLASH)
01911 {
01912
01913 ffelex_card_image_[0] = '/';
01914 ffelex_card_image_[1] = c;
01915 column = 2;
01916 goto bad_first_character;
01917 }
01918 else
01919
01920 {
01921
01922 column = ffelex_image_char_ (c, 0);
01923
01924 bad_first_character:
01925
01926 ffelex_bad_line_ = TRUE;
01927 while (((c = getc (f)) != '\n') && (c != EOF))
01928 column = ffelex_image_char_ (c, column);
01929 ffelex_card_image_[column] = '\0';
01930 ffelex_card_length_ = column;
01931 ffelex_bad_1_ (FFEBAD_FIRST_CHAR_INVALID,
01932 ffelex_linecount_current_, 1);
01933 }
01934
01935
01936
01937 if (c == EOF)
01938 {
01939 ffelex_next_line_ ();
01940 goto end_of_file;
01941 }
01942
01943 c = getc (f);
01944
01945 ffelex_next_line_ ();
01946
01947 if (c == EOF)
01948 goto end_of_file;
01949
01950 ffelex_bad_line_ = FALSE;
01951 }
01952
01953 ffelex_saw_tab_
01954 = (c == '&')
01955 || (ffelex_final_nontab_column_ == 0);
01956
01957 if (lextype == FFELEX_typeDEBUG)
01958 c = ' ';
01959
01960
01961 column = ffelex_image_char_ (c, 0);
01962
01963
01964
01965 while (((c = getc (f)) != '\n') && (c != EOF))
01966 column = ffelex_image_char_ (c, column);
01967
01968 if (ffelex_bad_line_)
01969 {
01970 ffelex_card_image_[column] = '\0';
01971 ffelex_card_length_ = column;
01972 goto comment_line;
01973 }
01974
01975
01976
01977 if (!ffelex_saw_tab_ && (column > ffelex_final_nontab_column_))
01978 {
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989 column = ffelex_final_nontab_column_;
01990 }
01991
01992 ffelex_card_image_[column] = '\0';
01993 ffelex_card_length_ = column;
01994
01995
01996
01997
01998 latest_char_in_file = c;
01999
02000 have_content = FALSE;
02001
02002
02003
02004 labi = 0;
02005 first_label_char = FFEWHERE_columnUNKNOWN;
02006 for (column = 0; column < 5; ++column)
02007 {
02008 switch (c = ffelex_card_image_[column])
02009 {
02010 case '\0':
02011 case '!':
02012 goto stop_looking;
02013
02014 case ' ':
02015 break;
02016
02017 case '0':
02018 case '1':
02019 case '2':
02020 case '3':
02021 case '4':
02022 case '5':
02023 case '6':
02024 case '7':
02025 case '8':
02026 case '9':
02027 label_string[labi++] = c;
02028 if (first_label_char == FFEWHERE_columnUNKNOWN)
02029 first_label_char = column + 1;
02030 break;
02031
02032 case '&':
02033 if (column != 0)
02034 {
02035 ffelex_bad_1_ (FFEBAD_LABEL_FIELD_NOT_NUMERIC,
02036 ffelex_linecount_current_,
02037 column + 1);
02038 goto beginning_of_line_again;
02039 }
02040 if (ffe_is_pedantic ())
02041 ffelex_bad_1_ (FFEBAD_AMPERSAND,
02042 ffelex_linecount_current_, 1);
02043 finish_statement = FALSE;
02044 just_do_label = FALSE;
02045 goto got_a_continuation;
02046
02047 case '/':
02048 if (ffelex_card_image_[column + 1] == '*')
02049 goto stop_looking;
02050
02051 default:
02052 ffelex_bad_1_ (FFEBAD_LABEL_FIELD_NOT_NUMERIC,
02053 ffelex_linecount_current_, column + 1);
02054 goto beginning_of_line_again;
02055 }
02056 }
02057
02058 stop_looking:
02059
02060 label_string[labi] = '\0';
02061
02062
02063
02064 if (column == 5)
02065
02066 while ((c = ffelex_card_image_[column]) == ' ')
02067 ++column;
02068
02069
02070
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105 finish_statement = FALSE;
02106 just_do_label = FALSE;
02107
02108 switch (c)
02109 {
02110 case '!':
02111
02112
02113 if (ffe_is_vxt () || (column != 5))
02114 goto no_tokens_on_line;
02115 goto got_a_continuation;
02116
02117 case '/':
02118 if (ffelex_card_image_[column + 1] != '*')
02119 goto some_other_character;
02120
02121 if (column == 5)
02122 {
02123
02124
02125
02126
02127 goto got_a_continuation;
02128 }
02129
02130 case '\0':
02131
02132
02133
02134
02135 no_tokens_on_line:
02136
02137 if (ffe_is_pedantic () && (c == '/'))
02138 ffelex_bad_1_ (FFEBAD_NON_ANSI_COMMENT,
02139 ffelex_linecount_current_, column + 1);
02140 if (first_label_char != FFEWHERE_columnUNKNOWN)
02141 {
02142
02143 finish_statement = TRUE;
02144 have_content = TRUE;
02145 just_do_label = TRUE;
02146 break;
02147 }
02148 goto beginning_of_line_again;
02149
02150 case '0':
02151 if (ffe_is_pedantic () && (column != 5))
02152 ffelex_bad_1_ (FFEBAD_NON_ANSI_CONTINUATION_COLUMN,
02153 ffelex_linecount_current_, column + 1);
02154 finish_statement = TRUE;
02155 goto check_for_content;
02156
02157 case '1':
02158 case '2':
02159 case '3':
02160 case '4':
02161 case '5':
02162 case '6':
02163 case '7':
02164 case '8':
02165 case '9':
02166
02167
02168
02169 got_a_continuation:
02170
02171 if (first_label_char != FFEWHERE_columnUNKNOWN)
02172 {
02173 ffelex_bad_2_ (FFEBAD_LABEL_ON_CONTINUATION,
02174 ffelex_linecount_current_,
02175 first_label_char,
02176 ffelex_linecount_current_,
02177 column + 1);
02178 first_label_char = FFEWHERE_columnUNKNOWN;
02179 }
02180 if (disallow_continuation_line)
02181 {
02182 if (!ignore_disallowed_continuation)
02183 ffelex_bad_1_ (FFEBAD_INVALID_CONTINUATION,
02184 ffelex_linecount_current_, column + 1);
02185 goto beginning_of_line_again;
02186 }
02187 if (ffe_is_pedantic () && (column != 5))
02188 ffelex_bad_1_ (FFEBAD_NON_ANSI_CONTINUATION_COLUMN,
02189 ffelex_linecount_current_, column + 1);
02190 if ((ffelex_raw_mode_ != 0)
02191 && (((c = ffelex_card_image_[column + 1]) != '\0')
02192 || !ffelex_saw_tab_))
02193 {
02194 ++column;
02195 have_content = TRUE;
02196 break;
02197 }
02198
02199 check_for_content:
02200
02201 while ((c = ffelex_card_image_[++column]) == ' ')
02202 ;
02203 if ((c == '\0')
02204 || (c == '!')
02205 || ((c == '/')
02206 && (ffelex_card_image_[column + 1] == '*')))
02207 {
02208 if (ffe_is_pedantic () && (c == '/'))
02209 ffelex_bad_1_ (FFEBAD_NON_ANSI_COMMENT,
02210 ffelex_linecount_current_, column + 1);
02211 just_do_label = TRUE;
02212 }
02213 else
02214 have_content = TRUE;
02215 break;
02216
02217 default:
02218
02219 some_other_character:
02220
02221 if (column == 5)
02222 goto got_a_continuation;
02223
02224
02225
02226
02227 finish_statement = TRUE;
02228 have_content = TRUE;
02229 break;
02230 }
02231
02232 if (have_content
02233 || (first_label_char != FFEWHERE_columnUNKNOWN))
02234 {
02235
02236
02237
02238
02239
02240
02241
02242 if (finish_statement)
02243 ffelex_prepare_eos_ ();
02244
02245 ffewhere_line_kill (ffelex_current_wl_);
02246 ffewhere_column_kill (ffelex_current_wc_);
02247 ffelex_current_wl_ = ffewhere_line_new (ffelex_linecount_current_);
02248 ffelex_current_wc_ = ffewhere_column_new (ffelex_card_length_ + 1);
02249 }
02250
02251
02252
02253
02254
02255
02256
02257 if (finish_statement)
02258 ffelex_finish_statement_ ();
02259
02260
02261
02262 if (first_label_char != FFEWHERE_columnUNKNOWN)
02263 {
02264 assert (ffelex_token_->type == FFELEX_typeNONE);
02265 ffelex_token_->type = FFELEX_typeNUMBER;
02266 ffelex_append_to_token_ ('\0');
02267 strcpy (ffelex_token_->text, label_string);
02268 ffelex_token_->where_line
02269 = ffewhere_line_use (ffelex_current_wl_);
02270 ffelex_token_->where_col = ffewhere_column_new (first_label_char);
02271 ffelex_token_->length = labi;
02272 ffelex_send_token_ ();
02273 ++ffelex_label_tokens_;
02274 }
02275
02276 if (just_do_label)
02277 goto beginning_of_line;
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289 if (ffelex_raw_mode_ != 0)
02290 {
02291
02292 parse_raw_character:
02293
02294 if (c == '\0')
02295 {
02296 ffewhereColumnNumber i;
02297
02298 if (ffelex_saw_tab_ || (column >= ffelex_final_nontab_column_))
02299 goto beginning_of_line;
02300
02301
02302
02303 for (i = column; i < ffelex_final_nontab_column_; ++i)
02304 ffelex_card_image_[i] = ' ';
02305 ffelex_card_image_[i] = '\0';
02306 ffelex_card_length_ = i;
02307 c = ' ';
02308 }
02309
02310 switch (ffelex_raw_mode_)
02311 {
02312 case -3:
02313 c = ffelex_backslash_ (c, column);
02314 if (c == EOF)
02315 break;
02316
02317 if (!ffelex_backslash_reconsider_)
02318 ffelex_append_to_token_ (c);
02319 ffelex_raw_mode_ = -1;
02320 break;
02321
02322 case -2:
02323 if (c == ffelex_raw_char_)
02324 {
02325 ffelex_raw_mode_ = -1;
02326 ffelex_append_to_token_ (c);
02327 }
02328 else
02329 {
02330 ffelex_raw_mode_ = 0;
02331 ffelex_backslash_reconsider_ = TRUE;
02332 }
02333 break;
02334
02335 case -1:
02336 if (c == ffelex_raw_char_)
02337 ffelex_raw_mode_ = -2;
02338 else
02339 {
02340 c = ffelex_backslash_ (c, column);
02341 if (c == EOF)
02342 {
02343 ffelex_raw_mode_ = -3;
02344 break;
02345 }
02346
02347 ffelex_append_to_token_ (c);
02348 }
02349 break;
02350
02351 default:
02352 c = ffelex_backslash_ (c, column);
02353 if (c == EOF)
02354 break;
02355
02356 if (!ffelex_backslash_reconsider_)
02357 {
02358 ffelex_append_to_token_ (c);
02359 --ffelex_raw_mode_;
02360 }
02361 break;
02362 }
02363
02364 if (ffelex_backslash_reconsider_)
02365 ffelex_backslash_reconsider_ = FALSE;
02366 else
02367 c = ffelex_card_image_[++column];
02368
02369 if (ffelex_raw_mode_ == 0)
02370 {
02371 ffelex_send_token_ ();
02372 assert (ffelex_raw_mode_ == 0);
02373 while (c == ' ')
02374 c = ffelex_card_image_[++column];
02375 if ((c == '\0')
02376 || (c == '!')
02377 || ((c == '/')
02378 && (ffelex_card_image_[column + 1] == '*')))
02379 goto beginning_of_line;
02380 goto parse_nonraw_character;
02381 }
02382 goto parse_raw_character;
02383 }
02384
02385 parse_nonraw_character:
02386
02387 switch (ffelex_token_->type)
02388 {
02389 case FFELEX_typeNONE:
02390 switch (c)
02391 {
02392 case '\"':
02393 ffelex_token_->type = FFELEX_typeQUOTE;
02394 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02395 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02396 ffelex_send_token_ ();
02397 break;
02398
02399 case '$':
02400 ffelex_token_->type = FFELEX_typeDOLLAR;
02401 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02402 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02403 ffelex_send_token_ ();
02404 break;
02405
02406 case '%':
02407 ffelex_token_->type = FFELEX_typePERCENT;
02408 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02409 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02410 ffelex_send_token_ ();
02411 break;
02412
02413 case '&':
02414 ffelex_token_->type = FFELEX_typeAMPERSAND;
02415 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02416 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02417 ffelex_send_token_ ();
02418 break;
02419
02420 case '\'':
02421 ffelex_token_->type = FFELEX_typeAPOSTROPHE;
02422 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02423 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02424 ffelex_send_token_ ();
02425 break;
02426
02427 case '(':
02428 ffelex_token_->type = FFELEX_typeOPEN_PAREN;
02429 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02430 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02431 break;
02432
02433 case ')':
02434 ffelex_token_->type = FFELEX_typeCLOSE_PAREN;
02435 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02436 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02437 ffelex_send_token_ ();
02438 break;
02439
02440 case '*':
02441 ffelex_token_->type = FFELEX_typeASTERISK;
02442 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02443 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02444 break;
02445
02446 case '+':
02447 ffelex_token_->type = FFELEX_typePLUS;
02448 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02449 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02450 ffelex_send_token_ ();
02451 break;
02452
02453 case ',':
02454 ffelex_token_->type = FFELEX_typeCOMMA;
02455 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02456 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02457 ffelex_send_token_ ();
02458 break;
02459
02460 case '-':
02461 ffelex_token_->type = FFELEX_typeMINUS;
02462 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02463 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02464 ffelex_send_token_ ();
02465 break;
02466
02467 case '.':
02468 ffelex_token_->type = FFELEX_typePERIOD;
02469 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02470 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02471 ffelex_send_token_ ();
02472 break;
02473
02474 case '/':
02475 ffelex_token_->type = FFELEX_typeSLASH;
02476 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02477 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02478 break;
02479
02480 case '0':
02481 case '1':
02482 case '2':
02483 case '3':
02484 case '4':
02485 case '5':
02486 case '6':
02487 case '7':
02488 case '8':
02489 case '9':
02490 ffelex_token_->type
02491 = ffelex_hexnum_ ? FFELEX_typeNAME : FFELEX_typeNUMBER;
02492 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02493 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02494 ffelex_append_to_token_ (c);
02495 break;
02496
02497 case ':':
02498 ffelex_token_->type = FFELEX_typeCOLON;
02499 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02500 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02501 break;
02502
02503 case ';':
02504 ffelex_token_->type = FFELEX_typeSEMICOLON;
02505 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02506 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02507 ffelex_permit_include_ = TRUE;
02508 ffelex_send_token_ ();
02509 ffelex_permit_include_ = FALSE;
02510 break;
02511
02512 case '<':
02513 ffelex_token_->type = FFELEX_typeOPEN_ANGLE;
02514 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02515 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02516 break;
02517
02518 case '=':
02519 ffelex_token_->type = FFELEX_typeEQUALS;
02520 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02521 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02522 break;
02523
02524 case '>':
02525 ffelex_token_->type = FFELEX_typeCLOSE_ANGLE;
02526 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02527 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02528 break;
02529
02530 case '?':
02531 ffelex_token_->type = FFELEX_typeQUESTION;
02532 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
02533 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02534 ffelex_send_token_ ();
02535 break;
02536
02537 case '_':
02538 if (1 || ffe_is_90 ())
02539 {
02540 ffelex_token_->type = FFELEX_typeUNDERSCORE;
02541 ffelex_token_->where_line
02542 = ffewhere_line_use (ffelex_current_wl_);
02543 ffelex_token_->where_col
02544 = ffewhere_column_new (column + 1);
02545 ffelex_send_token_ ();
02546 break;
02547 }
02548
02549 case 'A':
02550 case 'B':
02551 case 'C':
02552 case 'D':
02553 case 'E':
02554 case 'F':
02555 case 'G':
02556 case 'H':
02557 case 'I':
02558 case 'J':
02559 case 'K':
02560 case 'L':
02561 case 'M':
02562 case 'N':
02563 case 'O':
02564 case 'P':
02565 case 'Q':
02566 case 'R':
02567 case 'S':
02568 case 'T':
02569 case 'U':
02570 case 'V':
02571 case 'W':
02572 case 'X':
02573 case 'Y':
02574 case 'Z':
02575 case 'a':
02576 case 'b':
02577 case 'c':
02578 case 'd':
02579 case 'e':
02580 case 'f':
02581 case 'g':
02582 case 'h':
02583 case 'i':
02584 case 'j':
02585 case 'k':
02586 case 'l':
02587 case 'm':
02588 case 'n':
02589 case 'o':
02590 case 'p':
02591 case 'q':
02592 case 'r':
02593 case 's':
02594 case 't':
02595 case 'u':
02596 case 'v':
02597 case 'w':
02598 case 'x':
02599 case 'y':
02600 case 'z':
02601 c = ffesrc_char_source (c);
02602
02603 if (ffesrc_char_match_init (c, 'H', 'h')
02604 && ffelex_expecting_hollerith_ != 0)
02605 {
02606 ffelex_raw_mode_ = ffelex_expecting_hollerith_;
02607 ffelex_token_->type = FFELEX_typeHOLLERITH;
02608 ffelex_token_->where_line = ffelex_raw_where_line_;
02609 ffelex_token_->where_col = ffelex_raw_where_col_;
02610 ffelex_raw_where_line_ = ffewhere_line_unknown ();
02611 ffelex_raw_where_col_ = ffewhere_column_unknown ();
02612 c = ffelex_card_image_[++column];
02613 goto parse_raw_character;
02614 }
02615
02616 if (ffelex_names_)
02617 {
02618 ffelex_token_->where_line
02619 = ffewhere_line_use (ffelex_token_->currentnames_line
02620 = ffewhere_line_use (ffelex_current_wl_));
02621 ffelex_token_->where_col
02622 = ffewhere_column_use (ffelex_token_->currentnames_col
02623 = ffewhere_column_new (column + 1));
02624 ffelex_token_->type = FFELEX_typeNAMES;
02625 }
02626 else
02627 {
02628 ffelex_token_->where_line
02629 = ffewhere_line_use (ffelex_current_wl_);
02630 ffelex_token_->where_col = ffewhere_column_new (column + 1);
02631 ffelex_token_->type = FFELEX_typeNAME;
02632 }
02633 ffelex_append_to_token_ (c);
02634 break;
02635
02636 default:
02637 ffelex_bad_1_ (FFEBAD_UNRECOGNIZED_CHARACTER,
02638 ffelex_linecount_current_, column + 1);
02639 ffelex_finish_statement_ ();
02640 disallow_continuation_line = TRUE;
02641 ignore_disallowed_continuation = TRUE;
02642 goto beginning_of_line_again;
02643 }
02644 break;
02645
02646 case FFELEX_typeNAME:
02647 switch (c)
02648 {
02649 case 'A':
02650 case 'B':
02651 case 'C':
02652 case 'D':
02653 case 'E':
02654 case 'F':
02655 case 'G':
02656 case 'H':
02657 case 'I':
02658 case 'J':
02659 case 'K':
02660 case 'L':
02661 case 'M':
02662 case 'N':
02663 case 'O':
02664 case 'P':
02665 case 'Q':
02666 case 'R':
02667 case 'S':
02668 case 'T':
02669 case 'U':
02670 case 'V':
02671 case 'W':
02672 case 'X':
02673 case 'Y':
02674 case 'Z':
02675 case 'a':
02676 case 'b':
02677 case 'c':
02678 case 'd':
02679 case 'e':
02680 case 'f':
02681 case 'g':
02682 case 'h':
02683 case 'i':
02684 case 'j':
02685 case 'k':
02686 case 'l':
02687 case 'm':
02688 case 'n':
02689 case 'o':
02690 case 'p':
02691 case 'q':
02692 case 'r':
02693 case 's':
02694 case 't':
02695 case 'u':
02696 case 'v':
02697 case 'w':
02698 case 'x':
02699 case 'y':
02700 case 'z':
02701 c = ffesrc_char_source (c);
02702
02703 case '0':
02704 case '1':
02705 case '2':
02706 case '3':
02707 case '4':
02708 case '5':
02709 case '6':
02710 case '7':
02711 case '8':
02712 case '9':
02713 case '_':
02714 case '$':
02715 if ((c == '$')
02716 && !ffe_is_dollar_ok ())
02717 {
02718 ffelex_send_token_ ();
02719 goto parse_next_character;
02720 }
02721 ffelex_append_to_token_ (c);
02722 break;
02723
02724 default:
02725 ffelex_send_token_ ();
02726 goto parse_next_character;
02727 }
02728 break;
02729
02730 case FFELEX_typeNAMES:
02731 switch (c)
02732 {
02733 case 'A':
02734 case 'B':
02735 case 'C':
02736 case 'D':
02737 case 'E':
02738 case 'F':
02739 case 'G':
02740 case 'H':
02741 case 'I':
02742 case 'J':
02743 case 'K':
02744 case 'L':
02745 case 'M':
02746 case 'N':
02747 case 'O':
02748 case 'P':
02749 case 'Q':
02750 case 'R':
02751 case 'S':
02752 case 'T':
02753 case 'U':
02754 case 'V':
02755 case 'W':
02756 case 'X':
02757 case 'Y':
02758 case 'Z':
02759 case 'a':
02760 case 'b':
02761 case 'c':
02762 case 'd':
02763 case 'e':
02764 case 'f':
02765 case 'g':
02766 case 'h':
02767 case 'i':
02768 case 'j':
02769 case 'k':
02770 case 'l':
02771 case 'm':
02772 case 'n':
02773 case 'o':
02774 case 'p':
02775 case 'q':
02776 case 'r':
02777 case 's':
02778 case 't':
02779 case 'u':
02780 case 'v':
02781 case 'w':
02782 case 'x':
02783 case 'y':
02784 case 'z':
02785 c = ffesrc_char_source (c);
02786
02787 case '0':
02788 case '1':
02789 case '2':
02790 case '3':
02791 case '4':
02792 case '5':
02793 case '6':
02794 case '7':
02795 case '8':
02796 case '9':
02797 case '_':
02798 case '$':
02799 if ((c == '$')
02800 && !ffe_is_dollar_ok ())
02801 {
02802 ffelex_send_token_ ();
02803 goto parse_next_character;
02804 }
02805 if (ffelex_token_->length < FFEWHERE_indexMAX)
02806 {
02807 ffewhere_track (&ffelex_token_->currentnames_line,
02808 &ffelex_token_->currentnames_col,
02809 ffelex_token_->wheretrack,
02810 ffelex_token_->length,
02811 ffelex_linecount_current_,
02812 column + 1);
02813 }
02814 ffelex_append_to_token_ (c);
02815 break;
02816
02817 default:
02818 ffelex_send_token_ ();
02819 goto parse_next_character;
02820 }
02821 break;
02822
02823 case FFELEX_typeNUMBER:
02824 switch (c)
02825 {
02826 case '0':
02827 case '1':
02828 case '2':
02829 case '3':
02830 case '4':
02831 case '5':
02832 case '6':
02833 case '7':
02834 case '8':
02835 case '9':
02836 ffelex_append_to_token_ (c);
02837 break;
02838
02839 default:
02840 ffelex_send_token_ ();
02841 goto parse_next_character;
02842 }
02843 break;
02844
02845 case FFELEX_typeASTERISK:
02846 switch (c)
02847 {
02848 case '*':
02849 ffelex_token_->type = FFELEX_typePOWER;
02850 ffelex_send_token_ ();
02851 break;
02852
02853 default:
02854 ffelex_send_token_ ();
02855 goto parse_next_character;
02856 }
02857 break;
02858
02859 case FFELEX_typeCOLON:
02860 switch (c)
02861 {
02862 case ':':
02863 ffelex_token_->type = FFELEX_typeCOLONCOLON;
02864 ffelex_send_token_ ();
02865 break;
02866
02867 default:
02868 ffelex_send_token_ ();
02869 goto parse_next_character;
02870 }
02871 break;
02872
02873 case FFELEX_typeSLASH:
02874 switch (c)
02875 {
02876 case '/':
02877 ffelex_token_->type = FFELEX_typeCONCAT;
02878 ffelex_send_token_ ();
02879 break;
02880
02881 case ')':
02882 ffelex_token_->type = FFELEX_typeCLOSE_ARRAY;
02883 ffelex_send_token_ ();
02884 break;
02885
02886 case '=':
02887 ffelex_token_->type = FFELEX_typeREL_NE;
02888 ffelex_send_token_ ();
02889 break;
02890
02891 default:
02892 ffelex_send_token_ ();
02893 goto parse_next_character;
02894 }
02895 break;
02896
02897 case FFELEX_typeOPEN_PAREN:
02898 switch (c)
02899 {
02900 case '/':
02901 ffelex_token_->type = FFELEX_typeOPEN_ARRAY;
02902 ffelex_send_token_ ();
02903 break;
02904
02905 default:
02906 ffelex_send_token_ ();
02907 goto parse_next_character;
02908 }
02909 break;
02910
02911 case FFELEX_typeOPEN_ANGLE:
02912 switch (c)
02913 {
02914 case '=':
02915 ffelex_token_->type = FFELEX_typeREL_LE;
02916 ffelex_send_token_ ();
02917 break;
02918
02919 default:
02920 ffelex_send_token_ ();
02921 goto parse_next_character;
02922 }
02923 break;
02924
02925 case FFELEX_typeEQUALS:
02926 switch (c)
02927 {
02928 case '=':
02929 ffelex_token_->type = FFELEX_typeREL_EQ;
02930 ffelex_send_token_ ();
02931 break;
02932
02933 case '>':
02934 ffelex_token_->type = FFELEX_typePOINTS;
02935 ffelex_send_token_ ();
02936 break;
02937
02938 default:
02939 ffelex_send_token_ ();
02940 goto parse_next_character;
02941 }
02942 break;
02943
02944 case FFELEX_typeCLOSE_ANGLE:
02945 switch (c)
02946 {
02947 case '=':
02948 ffelex_token_->type = FFELEX_typeREL_GE;
02949 ffelex_send_token_ ();
02950 break;
02951
02952 default:
02953 ffelex_send_token_ ();
02954 goto parse_next_character;
02955 }
02956 break;
02957
02958 default:
02959 assert ("Serious error!!" == NULL);
02960 abort ();
02961 break;
02962 }
02963
02964 c = ffelex_card_image_[++column];
02965
02966 parse_next_character:
02967
02968 if (ffelex_raw_mode_ != 0)
02969 goto parse_raw_character;
02970
02971 while (c == ' ')
02972 c = ffelex_card_image_[++column];
02973
02974 if ((c == '\0')
02975 || (c == '!')
02976 || ((c == '/')
02977 && (ffelex_card_image_[column + 1] == '*')))
02978 {
02979 if ((ffelex_number_of_tokens_ == ffelex_label_tokens_)
02980 && (ffelex_token_->type == FFELEX_typeNAMES)
02981 && (ffelex_token_->length == 3)
02982 && (ffesrc_strncmp_2c (ffe_case_match (),
02983 ffelex_token_->text,
02984 "END", "end", "End",
02985 3)
02986 == 0))
02987 {
02988 ffelex_finish_statement_ ();
02989 disallow_continuation_line = TRUE;
02990 ignore_disallowed_continuation = FALSE;
02991 goto beginning_of_line_again;
02992 }
02993 goto beginning_of_line;
02994 }
02995 goto parse_nonraw_character;
02996 }
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006 ffelexHandler
03007 ffelex_file_free (ffewhereFile wf, FILE *f)
03008 {
03009 register int c = 0;
03010 register ffewhereColumnNumber column = 0;
03011 bool continuation_line = FALSE;
03012 ffewhereColumnNumber continuation_column;
03013 int latest_char_in_file = 0;
03014
03015
03016
03017
03018
03019
03020
03021
03022 assert (ffelex_handler_ != NULL);
03023
03024 lineno = 0;
03025 input_filename = ffewhere_file_name (wf);
03026 ffelex_current_wf_ = wf;
03027 continuation_line = FALSE;
03028 ffelex_token_->type = FFELEX_typeNONE;
03029 ffelex_number_of_tokens_ = 0;
03030 ffelex_current_wl_ = ffewhere_line_unknown ();
03031 ffelex_current_wc_ = ffewhere_column_unknown ();
03032 latest_char_in_file = '\n';
03033
03034
03035
03036 beginning_of_line:
03037
03038 c = latest_char_in_file;
03039 if ((c == EOF) || ((c = ffelex_getc_ (f)) == EOF))
03040 {
03041
03042 end_of_file:
03043
03044
03045
03046 ffelex_finish_statement_ ();
03047 ffewhere_line_kill (ffelex_current_wl_);
03048 ffewhere_column_kill (ffelex_current_wc_);
03049 return (ffelexHandler) ffelex_handler_;
03050 }
03051
03052 ffelex_next_line_ ();
03053
03054 ffelex_bad_line_ = FALSE;
03055
03056
03057
03058 while ((c == '\n')
03059 || (c == '!')
03060 || (c == '#'))
03061 {
03062 if (c == '#')
03063 c = ffelex_hash_ (f);
03064
03065 comment_line:
03066
03067 while ((c != '\n') && (c != EOF))
03068 c = getc (f);
03069
03070 if (c == EOF)
03071 {
03072 ffelex_next_line_ ();
03073 goto end_of_file;
03074 }
03075
03076 c = getc (f);
03077
03078 ffelex_next_line_ ();
03079
03080 if (c == EOF)
03081 goto end_of_file;
03082 }
03083
03084 ffelex_saw_tab_ = FALSE;
03085
03086 column = ffelex_image_char_ (c, 0);
03087
03088
03089
03090 while (((c = getc (f)) != '\n') && (c != EOF))
03091 column = ffelex_image_char_ (c, column);
03092
03093 if (ffelex_bad_line_)
03094 {
03095 ffelex_card_image_[column] = '\0';
03096 ffelex_card_length_ = column;
03097 goto comment_line;
03098 }
03099
03100
03101
03102 if (!ffelex_saw_tab_ && (column > FFELEX_FREE_MAX_COLUMNS_))
03103 column = FFELEX_FREE_MAX_COLUMNS_;
03104
03105 ffelex_card_image_[column] = '\0';
03106 ffelex_card_length_ = column;
03107
03108
03109
03110
03111 latest_char_in_file = c;
03112
03113 column = 0;
03114 continuation_column = 0;
03115
03116
03117
03118
03119
03120 while ((c = ffelex_card_image_[column]) == ' ')
03121 ++column;
03122
03123 switch (c)
03124 {
03125 case '!':
03126 case '\0':
03127 goto beginning_of_line;
03128
03129 case '&':
03130 continuation_column = column + 1;
03131 break;
03132
03133 default:
03134 break;
03135 }
03136
03137
03138
03139
03140 ffewhere_line_kill (ffelex_current_wl_);
03141 ffewhere_column_kill (ffelex_current_wc_);
03142 ffelex_current_wl_ = ffewhere_line_new (ffelex_linecount_current_);
03143 ffelex_current_wc_ = ffewhere_column_new (ffelex_card_length_ + 1);
03144
03145
03146
03147 if (continuation_line)
03148 {
03149 if (continuation_column == 0)
03150 {
03151 if (ffelex_raw_mode_ != 0)
03152 {
03153 ffelex_bad_1_ (FFEBAD_BAD_CHAR_CONTINUE,
03154 ffelex_linecount_current_, column + 1);
03155 }
03156 else if (ffelex_token_->type != FFELEX_typeNONE)
03157 {
03158 ffelex_bad_1_ (FFEBAD_BAD_LEXTOK_CONTINUE,
03159 ffelex_linecount_current_, column + 1);
03160 }
03161 }
03162 else if (ffelex_is_free_char_ctx_contin_ (continuation_column))
03163 {
03164
03165 ffelex_bad_1_ (FFEBAD_BAD_FREE_CONTINUE,
03166 ffelex_linecount_current_, continuation_column);
03167 goto beginning_of_line;
03168 }
03169 column = continuation_column;
03170 }
03171 else
03172 column = 0;
03173
03174 c = ffelex_card_image_[column];
03175 continuation_line = FALSE;
03176
03177
03178
03179
03180
03181
03182
03183 if (ffelex_raw_mode_ != 0)
03184 {
03185
03186 parse_raw_character:
03187
03188 switch (c)
03189 {
03190 case '&':
03191 if (ffelex_is_free_char_ctx_contin_ (column + 1))
03192 {
03193 continuation_line = TRUE;
03194 goto beginning_of_line;
03195 }
03196 break;
03197
03198 case '\0':
03199 ffelex_finish_statement_ ();
03200 goto beginning_of_line;
03201
03202 default:
03203 break;
03204 }
03205
03206 switch (ffelex_raw_mode_)
03207 {
03208 case -3:
03209 c = ffelex_backslash_ (c, column);
03210 if (c == EOF)
03211 break;
03212
03213 if (!ffelex_backslash_reconsider_)
03214 ffelex_append_to_token_ (c);
03215 ffelex_raw_mode_ = -1;
03216 break;
03217
03218 case -2:
03219 if (c == ffelex_raw_char_)
03220 {
03221 ffelex_raw_mode_ = -1;
03222 ffelex_append_to_token_ (c);
03223 }
03224 else
03225 {
03226 ffelex_raw_mode_ = 0;
03227 ffelex_backslash_reconsider_ = TRUE;
03228 }
03229 break;
03230
03231 case -1:
03232 if (c == ffelex_raw_char_)
03233 ffelex_raw_mode_ = -2;
03234 else
03235 {
03236 c = ffelex_backslash_ (c, column);
03237 if (c == EOF)
03238 {
03239 ffelex_raw_mode_ = -3;
03240 break;
03241 }
03242
03243 ffelex_append_to_token_ (c);
03244 }
03245 break;
03246
03247 default:
03248 c = ffelex_backslash_ (c, column);
03249 if (c == EOF)
03250 break;
03251
03252 if (!ffelex_backslash_reconsider_)
03253 {
03254 ffelex_append_to_token_ (c);
03255 --ffelex_raw_mode_;
03256 }
03257 break;
03258 }
03259
03260 if (ffelex_backslash_reconsider_)
03261 ffelex_backslash_reconsider_ = FALSE;
03262 else
03263 c = ffelex_card_image_[++column];
03264
03265 if (ffelex_raw_mode_ == 0)
03266 {
03267 ffelex_send_token_ ();
03268 assert (ffelex_raw_mode_ == 0);
03269 while (c == ' ')
03270 c = ffelex_card_image_[++column];
03271 if ((c == '\0') || (c == '!'))
03272 {
03273 ffelex_finish_statement_ ();
03274 goto beginning_of_line;
03275 }
03276 if ((c == '&') && ffelex_is_free_nonc_ctx_contin_ (column + 1))
03277 {
03278 continuation_line = TRUE;
03279 goto beginning_of_line;
03280 }
03281 goto parse_nonraw_character_noncontin;
03282 }
03283 goto parse_raw_character;
03284 }
03285
03286 parse_nonraw_character:
03287
03288 if ((c == '&') && ffelex_is_free_nonc_ctx_contin_ (column + 1))
03289 {
03290 continuation_line = TRUE;
03291 goto beginning_of_line;
03292 }
03293
03294 parse_nonraw_character_noncontin:
03295
03296 switch (ffelex_token_->type)
03297 {
03298 case FFELEX_typeNONE:
03299 if (c == ' ')
03300 {
03301
03302
03303 while (c == ' ')
03304 c = ffelex_card_image_[++column];
03305 if ((c == '\0') || (c == '!'))
03306 {
03307 ffelex_finish_statement_ ();
03308 goto beginning_of_line;
03309 }
03310 if ((c == '&') && ffelex_is_free_nonc_ctx_contin_ (column + 1))
03311 {
03312 continuation_line = TRUE;
03313 goto beginning_of_line;
03314 }
03315 }
03316
03317 switch (c)
03318 {
03319 case '\"':
03320 ffelex_token_->type = FFELEX_typeQUOTE;
03321 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03322 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03323 ffelex_send_token_ ();
03324 break;
03325
03326 case '$':
03327 ffelex_token_->type = FFELEX_typeDOLLAR;
03328 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03329 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03330 ffelex_send_token_ ();
03331 break;
03332
03333 case '%':
03334 ffelex_token_->type = FFELEX_typePERCENT;
03335 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03336 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03337 ffelex_send_token_ ();
03338 break;
03339
03340 case '&':
03341 ffelex_token_->type = FFELEX_typeAMPERSAND;
03342 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03343 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03344 ffelex_send_token_ ();
03345 break;
03346
03347 case '\'':
03348 ffelex_token_->type = FFELEX_typeAPOSTROPHE;
03349 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03350 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03351 ffelex_send_token_ ();
03352 break;
03353
03354 case '(':
03355 ffelex_token_->type = FFELEX_typeOPEN_PAREN;
03356 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03357 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03358 break;
03359
03360 case ')':
03361 ffelex_token_->type = FFELEX_typeCLOSE_PAREN;
03362 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03363 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03364 ffelex_send_token_ ();
03365 break;
03366
03367 case '*':
03368 ffelex_token_->type = FFELEX_typeASTERISK;
03369 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03370 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03371 break;
03372
03373 case '+':
03374 ffelex_token_->type = FFELEX_typePLUS;
03375 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03376 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03377 ffelex_send_token_ ();
03378 break;
03379
03380 case ',':
03381 ffelex_token_->type = FFELEX_typeCOMMA;
03382 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03383 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03384 ffelex_send_token_ ();
03385 break;
03386
03387 case '-':
03388 ffelex_token_->type = FFELEX_typeMINUS;
03389 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03390 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03391 ffelex_send_token_ ();
03392 break;
03393
03394 case '.':
03395 ffelex_token_->type = FFELEX_typePERIOD;
03396 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03397 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03398 ffelex_send_token_ ();
03399 break;
03400
03401 case '/':
03402 ffelex_token_->type = FFELEX_typeSLASH;
03403 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03404 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03405 break;
03406
03407 case '0':
03408 case '1':
03409 case '2':
03410 case '3':
03411 case '4':
03412 case '5':
03413 case '6':
03414 case '7':
03415 case '8':
03416 case '9':
03417 ffelex_token_->type
03418 = ffelex_hexnum_ ? FFELEX_typeNAME : FFELEX_typeNUMBER;
03419 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03420 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03421 ffelex_append_to_token_ (c);
03422 break;
03423
03424 case ':':
03425 ffelex_token_->type = FFELEX_typeCOLON;
03426 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03427 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03428 break;
03429
03430 case ';':
03431 ffelex_token_->type = FFELEX_typeSEMICOLON;
03432 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03433 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03434 ffelex_permit_include_ = TRUE;
03435 ffelex_send_token_ ();
03436 ffelex_permit_include_ = FALSE;
03437 break;
03438
03439 case '<':
03440 ffelex_token_->type = FFELEX_typeOPEN_ANGLE;
03441 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03442 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03443 break;
03444
03445 case '=':
03446 ffelex_token_->type = FFELEX_typeEQUALS;
03447 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03448 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03449 break;
03450
03451 case '>':
03452 ffelex_token_->type = FFELEX_typeCLOSE_ANGLE;
03453 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03454 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03455 break;
03456
03457 case '?':
03458 ffelex_token_->type = FFELEX_typeQUESTION;
03459 ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_);
03460 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03461 ffelex_send_token_ ();
03462 break;
03463
03464 case '_':
03465 if (1 || ffe_is_90 ())
03466 {
03467 ffelex_token_->type = FFELEX_typeUNDERSCORE;
03468 ffelex_token_->where_line
03469 = ffewhere_line_use (ffelex_current_wl_);
03470 ffelex_token_->where_col
03471 = ffewhere_column_new (column + 1);
03472 ffelex_send_token_ ();
03473 break;
03474 }
03475
03476 case 'A':
03477 case 'B':
03478 case 'C':
03479 case 'D':
03480 case 'E':
03481 case 'F':
03482 case 'G':
03483 case 'H':
03484 case 'I':
03485 case 'J':
03486 case 'K':
03487 case 'L':
03488 case 'M':
03489 case 'N':
03490 case 'O':
03491 case 'P':
03492 case 'Q':
03493 case 'R':
03494 case 'S':
03495 case 'T':
03496 case 'U':
03497 case 'V':
03498 case 'W':
03499 case 'X':
03500 case 'Y':
03501 case 'Z':
03502 case 'a':
03503 case 'b':
03504 case 'c':
03505 case 'd':
03506 case 'e':
03507 case 'f':
03508 case 'g':
03509 case 'h':
03510 case 'i':
03511 case 'j':
03512 case 'k':
03513 case 'l':
03514 case 'm':
03515 case 'n':
03516 case 'o':
03517 case 'p':
03518 case 'q':
03519 case 'r':
03520 case 's':
03521 case 't':
03522 case 'u':
03523 case 'v':
03524 case 'w':
03525 case 'x':
03526 case 'y':
03527 case 'z':
03528 c = ffesrc_char_source (c);
03529
03530 if (ffesrc_char_match_init (c, 'H', 'h')
03531 && ffelex_expecting_hollerith_ != 0)
03532 {
03533 ffelex_raw_mode_ = ffelex_expecting_hollerith_;
03534 ffelex_token_->type = FFELEX_typeHOLLERITH;
03535 ffelex_token_->where_line = ffelex_raw_where_line_;
03536 ffelex_token_->where_col = ffelex_raw_where_col_;
03537 ffelex_raw_where_line_ = ffewhere_line_unknown ();
03538 ffelex_raw_where_col_ = ffewhere_column_unknown ();
03539 c = ffelex_card_image_[++column];
03540 goto parse_raw_character;
03541 }
03542
03543 if (ffelex_names_pure_)
03544 {
03545 ffelex_token_->where_line
03546 = ffewhere_line_use (ffelex_token_->currentnames_line
03547 = ffewhere_line_use (ffelex_current_wl_));
03548 ffelex_token_->where_col
03549 = ffewhere_column_use (ffelex_token_->currentnames_col
03550 = ffewhere_column_new (column + 1));
03551 ffelex_token_->type = FFELEX_typeNAMES;
03552 }
03553 else
03554 {
03555 ffelex_token_->where_line
03556 = ffewhere_line_use (ffelex_current_wl_);
03557 ffelex_token_->where_col = ffewhere_column_new (column + 1);
03558 ffelex_token_->type = FFELEX_typeNAME;
03559 }
03560 ffelex_append_to_token_ (c);
03561 break;
03562
03563 default:
03564 ffelex_bad_1_ (FFEBAD_UNRECOGNIZED_CHARACTER,
03565 ffelex_linecount_current_, column + 1);
03566 ffelex_finish_statement_ ();
03567 goto beginning_of_line;
03568 }
03569 break;
03570
03571 case FFELEX_typeNAME:
03572 switch (c)
03573 {
03574 case 'A':
03575 case 'B':
03576 case 'C':
03577 case 'D':
03578 case 'E':
03579 case 'F':
03580 case 'G':
03581 case 'H':
03582 case 'I':
03583 case 'J':
03584 case 'K':
03585 case 'L':
03586 case 'M':
03587 case 'N':
03588 case 'O':
03589 case 'P':
03590 case 'Q':
03591 case 'R':
03592 case 'S':
03593 case 'T':
03594 case 'U':
03595 case 'V':
03596 case 'W':
03597 case 'X':
03598 case 'Y':
03599 case 'Z':
03600 case 'a':
03601 case 'b':
03602 case 'c':
03603 case 'd':
03604 case 'e':
03605 case 'f':
03606 case 'g':
03607 case 'h':
03608 case 'i':
03609 case 'j':
03610 case 'k':
03611 case 'l':
03612 case 'm':
03613 case 'n':
03614 case 'o':
03615 case 'p':
03616 case 'q':
03617 case 'r':
03618 case 's':
03619 case 't':
03620 case 'u':
03621 case 'v':
03622 case 'w':
03623 case 'x':
03624 case 'y':
03625 case 'z':
03626 c = ffesrc_char_source (c);
03627
03628 case '0':
03629 case '1':
03630 case '2':
03631 case '3':
03632 case '4':
03633 case '5':
03634 case '6':
03635 case '7':
03636 case '8':
03637 case '9':
03638 case '_':
03639 case '$':
03640 if ((c == '$')
03641 && !ffe_is_dollar_ok ())
03642 {
03643 ffelex_send_token_ ();
03644 goto parse_next_character;
03645 }
03646 ffelex_append_to_token_ (c);
03647 break;
03648
03649 default:
03650 ffelex_send_token_ ();
03651 goto parse_next_character;
03652 }
03653 break;
03654
03655 case FFELEX_typeNAMES:
03656 switch (c)
03657 {
03658 case 'A':
03659 case 'B':
03660 case 'C':
03661 case 'D':
03662 case 'E':
03663 case 'F':
03664 case 'G':
03665 case 'H':
03666 case 'I':
03667 case 'J':
03668 case 'K':
03669 case 'L':
03670 case 'M':
03671 case 'N':
03672 case 'O':
03673 case 'P':
03674 case 'Q':
03675 case 'R':
03676 case 'S':
03677 case 'T':
03678 case 'U':
03679 case 'V':
03680 case 'W':
03681 case 'X':
03682 case 'Y':
03683 case 'Z':
03684 case 'a':
03685 case 'b':
03686 case 'c':
03687 case 'd':
03688 case 'e':
03689 case 'f':
03690 case 'g':
03691 case 'h':
03692 case 'i':
03693 case 'j':
03694 case 'k':
03695 case 'l':
03696 case 'm':
03697 case 'n':
03698 case 'o':
03699 case 'p':
03700 case 'q':
03701 case 'r':
03702 case 's':
03703 case 't':
03704 case 'u':
03705 case 'v':
03706 case 'w':
03707 case 'x':
03708 case 'y':
03709 case 'z':
03710 c = ffesrc_char_source (c);
03711
03712 case '0':
03713 case '1':
03714 case '2':
03715 case '3':
03716 case '4':
03717 case '5':
03718 case '6':
03719 case '7':
03720 case '8':
03721 case '9':
03722 case '_':
03723 case '$':
03724 if ((c == '$')
03725 && !ffe_is_dollar_ok ())
03726 {
03727 ffelex_send_token_ ();
03728 goto parse_next_character;
03729 }
03730 if (ffelex_token_->length < FFEWHERE_indexMAX)
03731 {
03732 ffewhere_track (&ffelex_token_->currentnames_line,
03733 &ffelex_token_->currentnames_col,
03734 ffelex_token_->wheretrack,
03735 ffelex_token_->length,
03736 ffelex_linecount_current_,
03737 column + 1);
03738 }
03739 ffelex_append_to_token_ (c);
03740 break;
03741
03742 default:
03743 ffelex_send_token_ ();
03744 goto parse_next_character;
03745 }
03746 break;
03747
03748 case FFELEX_typeNUMBER:
03749 switch (c)
03750 {
03751 case '0':
03752 case '1':
03753 case '2':
03754 case '3':
03755 case '4':
03756 case '5':
03757 case '6':
03758 case '7':
03759 case '8':
03760 case '9':
03761 ffelex_append_to_token_ (c);
03762 break;
03763
03764 default:
03765 ffelex_send_token_ ();
03766 goto parse_next_character;
03767 }
03768 break;
03769
03770 case FFELEX_typeASTERISK:
03771 switch (c)
03772 {
03773 case '*':
03774 ffelex_token_->type = FFELEX_typePOWER;
03775 ffelex_send_token_ ();
03776 break;
03777
03778 default:
03779 ffelex_send_token_ ();
03780 goto parse_next_character;
03781 }
03782 break;
03783
03784 case FFELEX_typeCOLON:
03785 switch (c)
03786 {
03787 case ':':
03788 ffelex_token_->type = FFELEX_typeCOLONCOLON;
03789 ffelex_send_token_ ();
03790 break;
03791
03792 default:
03793 ffelex_send_token_ ();
03794 goto parse_next_character;
03795 }
03796 break;
03797
03798 case FFELEX_typeSLASH:
03799 switch (c)
03800 {
03801 case '/':
03802 ffelex_token_->type = FFELEX_typeCONCAT;
03803 ffelex_send_token_ ();
03804 break;
03805
03806 case ')':
03807 ffelex_token_->type = FFELEX_typeCLOSE_ARRAY;
03808 ffelex_send_token_ ();
03809 break;
03810
03811 case '=':
03812 ffelex_token_->type = FFELEX_typeREL_NE;
03813 ffelex_send_token_ ();
03814 break;
03815
03816 default:
03817 ffelex_send_token_ ();
03818 goto parse_next_character;
03819 }
03820 break;
03821
03822 case FFELEX_typeOPEN_PAREN:
03823 switch (c)
03824 {
03825 case '/':
03826 ffelex_token_->type = FFELEX_typeOPEN_ARRAY;
03827 ffelex_send_token_ ();
03828 break;
03829
03830 default:
03831 ffelex_send_token_ ();
03832 goto parse_next_character;
03833 }
03834 break;
03835
03836 case FFELEX_typeOPEN_ANGLE:
03837 switch (c)
03838 {
03839 case '=':
03840 ffelex_token_->type = FFELEX_typeREL_LE;
03841 ffelex_send_token_ ();
03842 break;
03843
03844 default:
03845 ffelex_send_token_ ();
03846 goto parse_next_character;
03847 }
03848 break;
03849
03850 case FFELEX_typeEQUALS:
03851 switch (c)
03852 {
03853 case '=':
03854 ffelex_token_->type = FFELEX_typeREL_EQ;
03855 ffelex_send_token_ ();
03856 break;
03857
03858 case '>':
03859 ffelex_token_->type = FFELEX_typePOINTS;
03860 ffelex_send_token_ ();
03861 break;
03862
03863 default:
03864 ffelex_send_token_ ();
03865 goto parse_next_character;
03866 }
03867 break;
03868
03869 case FFELEX_typeCLOSE_ANGLE:
03870 switch (c)
03871 {
03872 case '=':
03873 ffelex_token_->type = FFELEX_typeREL_GE;
03874 ffelex_send_token_ ();
03875 break;
03876
03877 default:
03878 ffelex_send_token_ ();
03879 goto parse_next_character;
03880 }
03881 break;
03882
03883 default:
03884 assert ("Serious error!" == NULL);
03885 abort ();
03886 break;
03887 }
03888
03889 c = ffelex_card_image_[++column];
03890
03891 parse_next_character:
03892
03893 if (ffelex_raw_mode_ != 0)
03894 goto parse_raw_character;
03895
03896 if ((c == '\0') || (c == '!'))
03897 {
03898 ffelex_finish_statement_ ();
03899 goto beginning_of_line;
03900 }
03901 goto parse_nonraw_character;
03902 }
03903
03904
03905
03906 void
03907 ffelex_hash_kludge (FILE *finput)
03908 {
03909
03910
03911
03912 static const char match[] = "# 1 \"";
03913 static int kludge[ARRAY_SIZE (match) + 1];
03914 int c;
03915 const char *p;
03916 int *q;
03917
03918
03919
03920
03921
03922
03923 for (p = &match[0], q = &kludge[0], c = getc (finput);
03924 (c == *p) && (*p != '\0') && (c != EOF);
03925 ++p, ++q, c = getc (finput))
03926 *q = c;
03927
03928 *q = c;
03929 *++q = 0;
03930
03931 ffelex_kludge_chars_ = &kludge[0];
03932
03933 if (*p == 0)
03934 {
03935 ffelex_kludge_flag_ = TRUE;
03936 ++ffelex_kludge_chars_;
03937 ffelex_hash_ (finput);
03938 ffelex_kludge_flag_ = FALSE;
03939 }
03940 }
03941
03942 void
03943 ffelex_init_1 ()
03944 {
03945 unsigned int i;
03946
03947 ffelex_final_nontab_column_ = ffe_fixed_line_length ();
03948 ffelex_card_size_ = FFELEX_columnINITIAL_SIZE_;
03949 ffelex_card_image_ = malloc_new_ksr (malloc_pool_image (),
03950 "FFELEX card image",
03951 FFELEX_columnINITIAL_SIZE_ + 9);
03952 ffelex_card_image_[0] = '\0';
03953
03954 for (i = 0; i < 256; ++i)
03955 ffelex_first_char_[i] = FFELEX_typeERROR;
03956
03957 ffelex_first_char_['\t'] = FFELEX_typeRAW;
03958 ffelex_first_char_['\n'] = FFELEX_typeCOMMENT;
03959 ffelex_first_char_['\v'] = FFELEX_typeCOMMENT;
03960 ffelex_first_char_['\f'] = FFELEX_typeCOMMENT;
03961 ffelex_first_char_['\r'] = FFELEX_typeRAW;
03962 ffelex_first_char_[' '] = FFELEX_typeRAW;
03963 ffelex_first_char_['!'] = FFELEX_typeCOMMENT;
03964 ffelex_first_char_['*'] = FFELEX_typeCOMMENT;
03965 ffelex_first_char_['/'] = FFELEX_typeSLASH;
03966 ffelex_first_char_['&'] = FFELEX_typeRAW;
03967 ffelex_first_char_['#'] = FFELEX_typeHASH;
03968
03969 for (i = '0'; i <= '9'; ++i)
03970 ffelex_first_char_[i] = FFELEX_typeRAW;
03971
03972 if ((ffe_case_match () == FFE_caseNONE)
03973 || ((ffe_case_match () == FFE_caseUPPER)
03974 && (ffe_case_source () != FFE_caseLOWER))
03975 || ((ffe_case_match () == FFE_caseLOWER)
03976 && (ffe_case_source () == FFE_caseLOWER)))
03977 {
03978 ffelex_first_char_['C'] = FFELEX_typeCOMMENT;
03979 ffelex_first_char_['D'] = FFELEX_typeCOMMENT;
03980 }
03981 if ((ffe_case_match () == FFE_caseNONE)
03982 || ((ffe_case_match () == FFE_caseLOWER)
03983 && (ffe_case_source () != FFE_caseUPPER))
03984 || ((ffe_case_match () == FFE_caseUPPER)
03985 && (ffe_case_source () == FFE_caseUPPER)))
03986 {
03987 ffelex_first_char_['c'] = FFELEX_typeCOMMENT;
03988 ffelex_first_char_['d'] = FFELEX_typeCOMMENT;
03989 }
03990
03991 ffelex_linecount_current_ = 0;
03992 ffelex_linecount_next_ = 1;
03993 ffelex_raw_mode_ = 0;
03994 ffelex_set_include_ = FALSE;
03995 ffelex_permit_include_ = FALSE;
03996 ffelex_names_ = TRUE;
03997 ffelex_names_pure_ = FALSE;
03998
03999 ffelex_hexnum_ = FALSE;
04000 ffelex_expecting_hollerith_ = 0;
04001 ffelex_raw_where_line_ = ffewhere_line_unknown ();
04002 ffelex_raw_where_col_ = ffewhere_column_unknown ();
04003
04004 ffelex_token_ = ffelex_token_new_ ();
04005 ffelex_token_->type = FFELEX_typeNONE;
04006 ffelex_token_->uses = 1;
04007 ffelex_token_->where_line = ffewhere_line_unknown ();
04008 ffelex_token_->where_col = ffewhere_column_unknown ();
04009 ffelex_token_->text = NULL;
04010
04011 ffelex_handler_ = NULL;
04012 }
04013
04014
04015
04016
04017
04018
04019
04020
04021
04022
04023 bool
04024 ffelex_is_names_expected ()
04025 {
04026 return ffelex_names_;
04027 }
04028
04029
04030
04031
04032 char *
04033 ffelex_line ()
04034 {
04035 return ffelex_card_image_;
04036 }
04037
04038
04039
04040
04041
04042
04043
04044 ffewhereColumnNumber
04045 ffelex_line_length ()
04046 {
04047 return ffelex_card_length_;
04048 }
04049
04050
04051
04052
04053 ffewhereLineNumber
04054 ffelex_line_number ()
04055 {
04056 return ffelex_linecount_current_;
04057 }
04058
04059
04060
04061
04062
04063
04064
04065
04066
04067
04068
04069
04070
04071
04072
04073
04074
04075
04076
04077
04078
04079
04080
04081
04082
04083
04084
04085
04086
04087
04088
04089
04090
04091
04092
04093
04094
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104
04105 void
04106 ffelex_set_expecting_hollerith (long length, char which,
04107 ffewhereLine line, ffewhereColumn column)
04108 {
04109
04110
04111
04112
04113
04114 ffewhere_line_kill (ffelex_raw_where_line_);
04115 ffewhere_column_kill (ffelex_raw_where_col_);
04116
04117
04118 switch (length)
04119 {
04120 case 0:
04121 ffelex_expecting_hollerith_ = 0;
04122 ffelex_raw_mode_ = 0;
04123 ffelex_raw_where_line_ = ffewhere_line_unknown ();
04124 ffelex_raw_where_col_ = ffewhere_column_unknown ();
04125 return;
04126
04127 case -1:
04128 ffelex_raw_mode_ = -1;
04129 ffelex_raw_char_ = which;
04130 break;
04131
04132 default:
04133 ffelex_expecting_hollerith_ = length;
04134 break;
04135 }
04136
04137
04138
04139 ffelex_raw_where_line_ = ffewhere_line_use (line);
04140 ffelex_raw_where_col_ = ffewhere_column_use (column);
04141 }
04142
04143
04144
04145
04146
04147
04148
04149
04150 void
04151 ffelex_set_handler (ffelexHandler first)
04152 {
04153 ffelex_handler_ = first;
04154 }
04155
04156
04157
04158
04159
04160
04161
04162
04163
04164
04165
04166
04167 void
04168 ffelex_set_hexnum (bool f)
04169 {
04170 ffelex_hexnum_ = f;
04171 }
04172
04173
04174
04175
04176
04177
04178
04179
04180
04181
04182
04183
04184 void
04185 ffelex_set_include (ffewhereFile wf, bool free_form, FILE *fi)
04186 {
04187 assert (ffelex_permit_include_);
04188 assert (!ffelex_set_include_);
04189 ffelex_set_include_ = TRUE;
04190 ffelex_include_free_form_ = free_form;
04191 ffelex_include_file_ = fi;
04192 ffelex_include_wherefile_ = wf;
04193 }
04194
04195
04196
04197
04198
04199
04200
04201
04202
04203
04204
04205
04206 void
04207 ffelex_set_names (bool f)
04208 {
04209 ffelex_names_ = f;
04210 if (!f)
04211 ffelex_names_pure_ = FALSE;
04212 }
04213
04214
04215
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225
04226
04227
04228
04229
04230
04231
04232
04233
04234
04235
04236
04237
04238
04239
04240
04241
04242
04243
04244 void
04245 ffelex_set_names_pure (bool f)
04246 {
04247 ffelex_names_pure_ = f;
04248 ffelex_names_ = f;
04249 }
04250
04251
04252
04253
04254
04255
04256
04257
04258
04259
04260
04261
04262
04263
04264
04265
04266
04267 ffelexHandler
04268 ffelex_splice_tokens (ffelexHandler first, ffelexToken master,
04269 ffeTokenLength start)
04270 {
04271 unsigned char *p;
04272 ffeTokenLength i;
04273 ffelexToken t;
04274
04275 p = ffelex_token_text (master) + (i = start);
04276
04277 while (*p != '\0')
04278 {
04279 if (ISDIGIT (*p))
04280 {
04281 t = ffelex_token_number_from_names (master, i);
04282 p += ffelex_token_length (t);
04283 i += ffelex_token_length (t);
04284 }
04285 else if (ffesrc_is_name_init (*p))
04286 {
04287 t = ffelex_token_name_from_names (master, i, 0);
04288 p += ffelex_token_length (t);
04289 i += ffelex_token_length (t);
04290 }
04291 else if (*p == '$')
04292 {
04293 t = ffelex_token_dollar_from_names (master, i);
04294 ++p;
04295 ++i;
04296 }
04297 else if (*p == '_')
04298 {
04299 t = ffelex_token_uscore_from_names (master, i);
04300 ++p;
04301 ++i;
04302 }
04303 else
04304 {
04305 assert ("not a valid NAMES character" == NULL);
04306 t = NULL;
04307 }
04308 assert (first != NULL);
04309 first = (ffelexHandler) (*first) (t);
04310 ffelex_token_kill (t);
04311 }
04312
04313 return first;
04314 }
04315
04316
04317
04318
04319
04320
04321
04322
04323
04324 ffelexHandler
04325 ffelex_swallow_tokens (ffelexToken t, ffelexHandler handler)
04326 {
04327 assert (handler != NULL);
04328
04329 if ((t != NULL) && ((ffelex_token_type (t) == FFELEX_typeEOS)
04330 || (ffelex_token_type (t) == FFELEX_typeSEMICOLON)))
04331 return (ffelexHandler) (*handler) (t);
04332
04333 ffelex_eos_handler_ = handler;
04334 return (ffelexHandler) ffelex_swallow_tokens_;
04335 }
04336
04337
04338
04339
04340
04341
04342
04343
04344
04345 ffelexToken
04346 ffelex_token_dollar_from_names (ffelexToken t, ffeTokenLength start)
04347 {
04348 ffelexToken nt;
04349
04350 assert (t != NULL);
04351 assert (ffelex_token_type (t) == FFELEX_typeNAMES);
04352 assert (start < t->length);
04353 assert (t->text[start] == '$');
04354
04355
04356
04357 nt = ffelex_token_new_ ();
04358 nt->type = FFELEX_typeDOLLAR;
04359 nt->length = 0;
04360 nt->uses = 1;
04361 ffewhere_set_from_track (&nt->where_line, &nt->where_col, t->where_line,
04362 t->where_col, t->wheretrack, start);
04363 nt->text = NULL;
04364 return nt;
04365 }
04366
04367
04368
04369
04370
04371
04372
04373
04374 void
04375 ffelex_token_kill (ffelexToken t)
04376 {
04377 assert (t != NULL);
04378
04379 assert (t->uses > 0);
04380
04381 if (--t->uses != 0)
04382 return;
04383
04384 --ffelex_total_tokens_;
04385
04386 if (t->type == FFELEX_typeNAMES)
04387 ffewhere_track_kill (t->where_line, t->where_col,
04388 t->wheretrack, t->length);
04389 ffewhere_line_kill (t->where_line);
04390 ffewhere_column_kill (t->where_col);
04391 if (t->text != NULL)
04392 malloc_kill_ksr (malloc_pool_image (), t->text, t->size + 1);
04393 malloc_kill_ks (malloc_pool_image (), t, sizeof (*t));
04394 }
04395
04396
04397
04398 ffelexToken
04399 ffelex_token_name_from_names (ffelexToken t, ffeTokenLength start,
04400 ffeTokenLength len)
04401 {
04402 ffelexToken nt;
04403
04404 assert (t != NULL);
04405 assert (ffelex_token_type (t) == FFELEX_typeNAMES);
04406 assert (start < t->length);
04407 if (len == 0)
04408 len = t->length - start;
04409 else
04410 {
04411 assert (len > 0);
04412 assert ((start + len) <= t->length);
04413 }
04414 assert (ffelex_is_firstnamechar ((unsigned char)(t->text[start])));
04415
04416 nt = ffelex_token_new_ ();
04417 nt->type = FFELEX_typeNAME;
04418 nt->size = len;
04419
04420 nt->length = len;
04421 nt->uses = 1;
04422 ffewhere_set_from_track (&nt->where_line, &nt->where_col, t->where_line,
04423 t->where_col, t->wheretrack, start);
04424 nt->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text",
04425 len + 1);
04426 strncpy (nt->text, t->text + start, len);
04427 nt->text[len] = '\0';
04428 return nt;
04429 }
04430
04431
04432
04433 ffelexToken
04434 ffelex_token_names_from_names (ffelexToken t, ffeTokenLength start,
04435 ffeTokenLength len)
04436 {
04437 ffelexToken nt;
04438
04439 assert (t != NULL);
04440 assert (ffelex_token_type (t) == FFELEX_typeNAMES);
04441 assert (start < t->length);
04442 if (len == 0)
04443 len = t->length - start;
04444 else
04445 {
04446 assert (len > 0);
04447 assert ((start + len) <= t->length);
04448 }
04449 assert (ffelex_is_firstnamechar ((unsigned char)(t->text[start])));
04450
04451 nt = ffelex_token_new_ ();
04452 nt->type = FFELEX_typeNAMES;
04453 nt->size = len;
04454
04455 nt->length = len;
04456 nt->uses = 1;
04457 ffewhere_set_from_track (&nt->where_line, &nt->where_col, t->where_line,
04458 t->where_col, t->wheretrack, start);
04459 ffewhere_track_copy (nt->wheretrack, t->wheretrack, start, len);
04460 nt->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text",
04461 len + 1);
04462 strncpy (nt->text, t->text + start, len);
04463 nt->text[len] = '\0';
04464 return nt;
04465 }
04466
04467
04468
04469 ffelexToken
04470 ffelex_token_new_character (const char *s, ffewhereLine l, ffewhereColumn c)
04471 {
04472 ffelexToken t;
04473
04474 t = ffelex_token_new_ ();
04475 t->type = FFELEX_typeCHARACTER;
04476 t->length = t->size = strlen (s);
04477 t->uses = 1;
04478 t->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text",
04479 t->size + 1);
04480 strcpy (t->text, s);
04481 t->where_line = ffewhere_line_use (l);
04482 t->where_col = ffewhere_column_new (c);
04483 return t;
04484 }
04485
04486
04487
04488 ffelexToken
04489 ffelex_token_new_eof ()
04490 {
04491 ffelexToken t;
04492
04493 t = ffelex_token_new_ ();
04494 t->type = FFELEX_typeEOF;
04495 t->uses = 1;
04496 t->text = NULL;
04497 t->where_line = ffewhere_line_new (ffelex_linecount_current_);
04498 t->where_col = ffewhere_column_new (1);
04499 return t;
04500 }
04501
04502
04503
04504 ffelexToken
04505 ffelex_token_new_name (const char *s, ffewhereLine l, ffewhereColumn c)
04506 {
04507 ffelexToken t;
04508
04509 assert (ffelex_is_firstnamechar ((unsigned char)*s));
04510
04511 t = ffelex_token_new_ ();
04512 t->type = FFELEX_typeNAME;
04513 t->length = t->size = strlen (s);
04514 t->uses = 1;
04515 t->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text",
04516 t->size + 1);
04517 strcpy (t->text, s);
04518 t->where_line = ffewhere_line_use (l);
04519 t->where_col = ffewhere_column_new (c);
04520 return t;
04521 }
04522
04523
04524
04525 ffelexToken
04526 ffelex_token_new_names (const char *s, ffewhereLine l, ffewhereColumn c)
04527 {
04528 ffelexToken t;
04529
04530 assert (ffelex_is_firstnamechar ((unsigned char)*s));
04531
04532 t = ffelex_token_new_ ();
04533 t->type = FFELEX_typeNAMES;
04534 t->length = t->size = strlen (s);
04535 t->uses = 1;
04536 t->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text",
04537 t->size + 1);
04538 strcpy (t->text, s);
04539 t->where_line = ffewhere_line_use (l);
04540 t->where_col = ffewhere_column_new (c);
04541 ffewhere_track_clear (t->wheretrack, t->length);
04542
04543 return t;
04544 }
04545
04546
04547
04548
04549
04550
04551
04552
04553
04554 ffelexToken
04555 ffelex_token_new_number (const char *s, ffewhereLine l, ffewhereColumn c)
04556 {
04557 ffelexToken t;
04558 ffeTokenLength len;
04559
04560
04561
04562 len = strspn (s, "0123456789");
04563
04564
04565
04566 assert (len != 0);
04567
04568
04569
04570 t = ffelex_token_new_ ();
04571 t->type = FFELEX_typeNUMBER;
04572 t->length = t->size = len;
04573 t->uses = 1;
04574 t->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text",
04575 len + 1);
04576 strncpy (t->text, s, len);
04577 t->text[len] = '\0';
04578 t->where_line = ffewhere_line_use (l);
04579 t->where_col = ffewhere_column_new (c);
04580 return t;
04581 }
04582
04583
04584
04585
04586 ffelexToken
04587 ffelex_token_new_simple_ (ffelexType type, ffewhereLine l, ffewhereColumn c)
04588 {
04589 ffelexToken t;
04590
04591 t = ffelex_token_new_ ();
04592 t->type = type;
04593 t->uses = 1;
04594 t->text = NULL;
04595 t->where_line = ffewhere_line_use (l);
04596 t->where_col = ffewhere_column_new (c);
04597 return t;
04598 }
04599
04600
04601
04602
04603
04604
04605 ffelexToken
04606 ffelex_token_number_from_names (ffelexToken t, ffeTokenLength start)
04607 {
04608 ffelexToken nt;
04609 ffeTokenLength len;
04610
04611 assert (t != NULL);
04612 assert (ffelex_token_type (t) == FFELEX_typeNAMES);
04613 assert (start < t->length);
04614
04615
04616
04617 len = strspn (t->text + start, "0123456789");
04618
04619
04620
04621 assert (len != 0);
04622
04623
04624
04625 nt = ffelex_token_new_ ();
04626 nt->type = FFELEX_typeNUMBER;
04627 nt->size = len;
04628
04629 nt->length = len;
04630 nt->uses = 1;
04631 ffewhere_set_from_track (&nt->where_line, &nt->where_col, t->where_line,
04632 t->where_col, t->wheretrack, start);
04633 nt->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text",
04634 len + 1);
04635 strncpy (nt->text, t->text + start, len);
04636 nt->text[len] = '\0';
04637 return nt;
04638 }
04639
04640
04641
04642 ffelexToken
04643 ffelex_token_uscore_from_names (ffelexToken t, ffeTokenLength start)
04644 {
04645 ffelexToken nt;
04646
04647 assert (t != NULL);
04648 assert (ffelex_token_type (t) == FFELEX_typeNAMES);
04649 assert (start < t->length);
04650 assert (t->text[start] == '_');
04651
04652
04653
04654 nt = ffelex_token_new_ ();
04655 nt->type = FFELEX_typeUNDERSCORE;
04656 nt->uses = 1;
04657 ffewhere_set_from_track (&nt->where_line, &nt->where_col, t->where_line,
04658 t->where_col, t->wheretrack, start);
04659 nt->text = NULL;
04660 return nt;
04661 }
04662
04663
04664
04665
04666
04667
04668
04669
04670
04671
04672
04673 ffelexToken
04674 ffelex_token_use (ffelexToken t)
04675 {
04676 if (t == NULL)
04677 assert ("_token_use: null token" == NULL);
04678 t->uses++;
04679 return t;
04680 }