Change license from GPLv2+ to GPLv3+.
[pspp-builds.git] / src / language / lexer / lexer.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 1997-9, 2000, 2006 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include "lexer.h"
19 #include <libpspp/message.h>
20 #include <ctype.h>
21 #include <errno.h>
22 #include <limits.h>
23 #include <math.h>
24 #include <stdarg.h>
25 #include <stdlib.h>
26 #include <libpspp/alloc.h>
27 #include <libpspp/assertion.h>
28 #include <language/command.h>
29 #include <libpspp/message.h>
30 #include <libpspp/magic.h>
31 #include <data/settings.h>
32 #include <libpspp/getl.h>
33 #include <libpspp/str.h>
34
35 #include "size_max.h"
36
37 #include "gettext.h"
38 #define _(msgid) gettext (msgid)
39 #define N_(msgid) msgid
40
41
42 #define DUMP_TOKENS 0
43
44
45 struct lexer
46 {
47   struct string line_buffer;
48
49   struct source_stream *ss;
50
51   int token;      /* Current token. */
52   double tokval;  /* T_POS_NUM, T_NEG_NUM: the token's value. */
53
54   char tokid [LONG_NAME_LEN + 1];   /* T_ID: the identifier. */
55
56   struct string tokstr;   /* T_ID, T_STRING: token string value.
57                             For T_ID, this is not truncated as is
58                             tokid. */
59
60   char *prog; /* Pointer to next token in line_buffer. */
61   bool dot;   /* True only if this line ends with a terminal dot. */
62
63   int put_token ; /* If nonzero, next token returned by lex_get().
64                     Used only in exceptional circumstances. */
65
66   struct string put_tokstr;
67   double put_tokval;
68 };
69
70
71 static int parse_id (struct lexer *);
72
73 /* How a string represents its contents. */
74 enum string_type
75   {
76     CHARACTER_STRING,   /* Characters. */
77     BINARY_STRING,      /* Binary digits. */
78     OCTAL_STRING,       /* Octal digits. */
79     HEX_STRING          /* Hexadecimal digits. */
80   };
81
82 static int parse_string (struct lexer *, enum string_type);
83
84 #if DUMP_TOKENS
85 static void dump_token (struct lexer *);
86 #endif
87 \f
88 /* Initialization. */
89
90 /* Initializes the lexer. */
91 struct lexer *
92 lex_create (struct source_stream *ss)
93 {
94   struct lexer *lexer = xzalloc (sizeof (*lexer));
95
96   ds_init_empty (&lexer->tokstr);
97   ds_init_empty (&lexer->put_tokstr);
98   ds_init_empty (&lexer->line_buffer);
99   lexer->ss = ss;
100
101   return lexer;
102 }
103
104 struct source_stream *
105 lex_get_source_stream (const struct lexer *lex)
106 {
107   return lex->ss;
108 }
109
110
111 void
112 lex_destroy (struct lexer *lexer)
113 {
114   if ( NULL != lexer )
115     {
116       ds_destroy (&lexer->put_tokstr);
117       ds_destroy (&lexer->tokstr);
118       ds_destroy (&lexer->line_buffer);
119
120       free (lexer);
121     }
122 }
123
124 \f
125 /* Common functions. */
126
127 /* Copies put_token, lexer->put_tokstr, put_tokval into token, tokstr,
128    tokval, respectively, and sets tokid appropriately. */
129 static void
130 restore_token (struct lexer *lexer)
131 {
132   assert (lexer->put_token != 0);
133   lexer->token = lexer->put_token;
134   ds_assign_string (&lexer->tokstr, &lexer->put_tokstr);
135   str_copy_trunc (lexer->tokid, sizeof lexer->tokid, ds_cstr (&lexer->tokstr));
136   lexer->tokval = lexer->put_tokval;
137   lexer->put_token = 0;
138 }
139
140 /* Copies token, tokstr, lexer->tokval into lexer->put_token, put_tokstr,
141    put_lexer->tokval respectively. */
142 static void
143 save_token (struct lexer *lexer)
144 {
145   lexer->put_token = lexer->token;
146   ds_assign_string (&lexer->put_tokstr, &lexer->tokstr);
147   lexer->put_tokval = lexer->tokval;
148 }
149
150 /* Parses a single token, setting appropriate global variables to
151    indicate the token's attributes. */
152 void
153 lex_get (struct lexer *lexer)
154 {
155   /* Find a token. */
156   for (;;)
157     {
158       if (NULL == lexer->prog && ! lex_get_line (lexer) )
159         {
160           lexer->token = T_STOP;
161           return;
162         }
163
164   /* If a token was pushed ahead, return it. */
165   if (lexer->put_token)
166     {
167       restore_token (lexer);
168 #if DUMP_TOKENS
169           dump_token (lexer);
170 #endif
171       return;
172     }
173
174   for (;;)
175     {
176       /* Skip whitespace. */
177           while (isspace ((unsigned char) *lexer->prog))
178             lexer->prog++;
179
180           if (*lexer->prog)
181             break;
182
183           if (lexer->dot)
184             {
185               lexer->dot = 0;
186               lexer->token = '.';
187 #if DUMP_TOKENS
188               dump_token (lexer);
189 #endif
190               return;
191             }
192           else if (!lex_get_line (lexer))
193             {
194               lexer->prog = NULL;
195               lexer->token = T_STOP;
196 #if DUMP_TOKENS
197               dump_token (lexer);
198 #endif
199               return;
200             }
201
202           if (lexer->put_token)
203             {
204               restore_token (lexer);
205 #if DUMP_TOKENS
206               dump_token (lexer);
207 #endif
208               return;
209             }
210         }
211
212
213       /* Actually parse the token. */
214       ds_clear (&lexer->tokstr);
215
216       switch (*lexer->prog)
217         {
218         case '-': case '.':
219         case '0': case '1': case '2': case '3': case '4':
220         case '5': case '6': case '7': case '8': case '9':
221           {
222             char *tail;
223
224             /* `-' can introduce a negative number, or it can be a
225                token by itself.  If it is not followed by a digit or a
226                decimal point, it is definitely not a number.
227                Otherwise, it might be either, but most of the time we
228                want it as a number.  When the syntax calls for a `-'
229                token, lex_negative_to_dash() must be used to break
230                negative numbers into two tokens. */
231             if (*lexer->prog == '-')
232               {
233                 ds_put_char (&lexer->tokstr, *lexer->prog++);
234                 while (isspace ((unsigned char) *lexer->prog))
235                   lexer->prog++;
236
237                 if (!isdigit ((unsigned char) *lexer->prog) && *lexer->prog != '.')
238                   {
239                     lexer->token = '-';
240                     break;
241                   }
242                 lexer->token = T_NEG_NUM;
243               }
244             else
245               lexer->token = T_POS_NUM;
246
247             /* Parse the number, copying it into tokstr. */
248             while (isdigit ((unsigned char) *lexer->prog))
249               ds_put_char (&lexer->tokstr, *lexer->prog++);
250             if (*lexer->prog == '.')
251               {
252                 ds_put_char (&lexer->tokstr, *lexer->prog++);
253                 while (isdigit ((unsigned char) *lexer->prog))
254                   ds_put_char (&lexer->tokstr, *lexer->prog++);
255               }
256             if (*lexer->prog == 'e' || *lexer->prog == 'E')
257               {
258                 ds_put_char (&lexer->tokstr, *lexer->prog++);
259                 if (*lexer->prog == '+' || *lexer->prog == '-')
260                   ds_put_char (&lexer->tokstr, *lexer->prog++);
261                 while (isdigit ((unsigned char) *lexer->prog))
262                   ds_put_char (&lexer->tokstr, *lexer->prog++);
263               }
264
265             /* Parse as floating point. */
266             lexer->tokval = strtod (ds_cstr (&lexer->tokstr), &tail);
267             if (*tail)
268               {
269                 msg (SE, _("%s does not form a valid number."),
270                      ds_cstr (&lexer->tokstr));
271                 lexer->tokval = 0.0;
272
273                 ds_clear (&lexer->tokstr);
274                 ds_put_char (&lexer->tokstr, '0');
275               }
276
277             break;
278           }
279
280         case '\'': case '"':
281           lexer->token = parse_string (lexer, CHARACTER_STRING);
282           break;
283
284         case '(': case ')': case ',': case '=': case '+': case '/':
285           lexer->token = *lexer->prog++;
286           break;
287
288         case '*':
289           if (*++lexer->prog == '*')
290             {
291               lexer->prog++;
292               lexer->token = T_EXP;
293             }
294           else
295             lexer->token = '*';
296           break;
297
298         case '<':
299           if (*++lexer->prog == '=')
300             {
301               lexer->prog++;
302               lexer->token = T_LE;
303             }
304           else if (*lexer->prog == '>')
305             {
306               lexer->prog++;
307               lexer->token = T_NE;
308             }
309           else
310             lexer->token = T_LT;
311           break;
312
313         case '>':
314           if (*++lexer->prog == '=')
315             {
316               lexer->prog++;
317               lexer->token = T_GE;
318             }
319           else
320             lexer->token = T_GT;
321           break;
322
323         case '~':
324           if (*++lexer->prog == '=')
325             {
326               lexer->prog++;
327               lexer->token = T_NE;
328             }
329           else
330             lexer->token = T_NOT;
331           break;
332
333         case '&':
334           lexer->prog++;
335           lexer->token = T_AND;
336           break;
337
338         case '|':
339           lexer->prog++;
340           lexer->token = T_OR;
341           break;
342
343         case 'b': case 'B':
344           if (lexer->prog[1] == '\'' || lexer->prog[1] == '"')
345             lexer->token = parse_string (lexer, BINARY_STRING);
346           else
347             lexer->token = parse_id (lexer);
348           break;
349
350         case 'o': case 'O':
351           if (lexer->prog[1] == '\'' || lexer->prog[1] == '"')
352             lexer->token = parse_string (lexer, OCTAL_STRING);
353           else
354             lexer->token = parse_id (lexer);
355           break;
356
357         case 'x': case 'X':
358           if (lexer->prog[1] == '\'' || lexer->prog[1] == '"')
359             lexer->token = parse_string (lexer, HEX_STRING);
360           else
361             lexer->token = parse_id (lexer);
362           break;
363
364         default:
365           if (lex_is_id1 (*lexer->prog))
366             {
367               lexer->token = parse_id (lexer);
368               break;
369             }
370           else
371             {
372               if (isgraph ((unsigned char) *lexer->prog))
373                 msg (SE, _("Bad character in input: `%c'."), *lexer->prog++);
374               else
375                 msg (SE, _("Bad character in input: `\\%o'."), *lexer->prog++);
376               continue;
377             }
378         }
379       break;
380     }
381
382 #if DUMP_TOKENS
383   dump_token (lexer);
384 #endif
385 }
386
387 /* Parses an identifier at the current position into tokid and
388    tokstr.
389    Returns the correct token type. */
390 static int
391 parse_id (struct lexer *lexer)
392 {
393   struct substring rest_of_line
394     = ss_substr (ds_ss (&lexer->line_buffer),
395                  ds_pointer_to_position (&lexer->line_buffer, lexer->prog),
396                  SIZE_MAX);
397   struct substring id = ss_head (rest_of_line,
398                                  lex_id_get_length (rest_of_line));
399   lexer->prog += ss_length (id);
400
401   ds_assign_substring (&lexer->tokstr, id);
402   str_copy_trunc (lexer->tokid, sizeof lexer->tokid, ds_cstr (&lexer->tokstr));
403   return lex_id_to_token (id);
404 }
405
406 /* Reports an error to the effect that subcommand SBC may only be
407    specified once. */
408 void
409 lex_sbc_only_once (const char *sbc)
410 {
411   msg (SE, _("Subcommand %s may only be specified once."), sbc);
412 }
413
414 /* Reports an error to the effect that subcommand SBC is
415    missing. */
416 void
417 lex_sbc_missing (struct lexer *lexer, const char *sbc)
418 {
419   lex_error (lexer, _("missing required subcommand %s"), sbc);
420 }
421
422 /* Prints a syntax error message containing the current token and
423    given message MESSAGE (if non-null). */
424 void
425 lex_error (struct lexer *lexer, const char *message, ...)
426 {
427   char *token_rep;
428   char where[128];
429
430   token_rep = lex_token_representation (lexer);
431   if (lexer->token == T_STOP)
432     strcpy (where, "end of file");
433   else if (lexer->token == '.')
434     strcpy (where, "end of command");
435   else
436     snprintf (where, sizeof where, "`%s'", token_rep);
437   free (token_rep);
438
439   if (message)
440     {
441       char buf[1024];
442       va_list args;
443
444       va_start (args, message);
445       vsnprintf (buf, 1024, message, args);
446       va_end (args);
447
448       msg (SE, _("Syntax error %s at %s."), buf, where);
449     }
450   else
451     msg (SE, _("Syntax error at %s."), where);
452 }
453
454 /* Checks that we're at end of command.
455    If so, returns a successful command completion code.
456    If not, flags a syntax error and returns an error command
457    completion code. */
458 int
459 lex_end_of_command (struct lexer *lexer)
460 {
461   if (lexer->token != '.')
462     {
463       lex_error (lexer, _("expecting end of command"));
464       return CMD_FAILURE;
465     }
466   else
467     return CMD_SUCCESS;
468 }
469 \f
470 /* Token testing functions. */
471
472 /* Returns true if the current token is a number. */
473 bool
474 lex_is_number (struct lexer *lexer)
475 {
476   return lexer->token == T_POS_NUM || lexer->token == T_NEG_NUM;
477 }
478
479
480 /* Returns true if the current token is a string. */
481 bool
482 lex_is_string (struct lexer *lexer)
483 {
484   return lexer->token == T_STRING;
485 }
486
487
488 /* Returns the value of the current token, which must be a
489    floating point number. */
490 double
491 lex_number (struct lexer *lexer)
492 {
493   assert (lex_is_number (lexer));
494   return lexer->tokval;
495 }
496
497 /* Returns true iff the current token is an integer. */
498 bool
499 lex_is_integer (struct lexer *lexer)
500 {
501   return (lex_is_number (lexer)
502           && lexer->tokval != NOT_LONG
503           && lexer->tokval >= LONG_MIN
504           && lexer->tokval <= LONG_MAX
505           && floor (lexer->tokval) == lexer->tokval);
506 }
507
508 /* Returns the value of the current token, which must be an
509    integer. */
510 long
511 lex_integer (struct lexer *lexer)
512 {
513   assert (lex_is_integer (lexer));
514   return lexer->tokval;
515 }
516 \f
517 /* Token matching functions. */
518
519 /* If TOK is the current token, skips it and returns true
520    Otherwise, returns false. */
521 bool
522 lex_match (struct lexer *lexer, int t)
523 {
524   if (lexer->token == t)
525     {
526       lex_get (lexer);
527       return true;
528     }
529   else
530     return false;
531 }
532
533 /* If the current token is the identifier S, skips it and returns
534    true.  The identifier may be abbreviated to its first three
535    letters.
536    Otherwise, returns false. */
537 bool
538 lex_match_id (struct lexer *lexer, const char *s)
539 {
540   if (lexer->token == T_ID
541       && lex_id_match (ss_cstr (s), ss_cstr (lexer->tokid)))
542     {
543       lex_get (lexer);
544       return true;
545     }
546   else
547     return false;
548 }
549
550 /* If the current token is integer N, skips it and returns true.
551    Otherwise, returns false. */
552 bool
553 lex_match_int (struct lexer *lexer, int x)
554 {
555   if (lex_is_integer (lexer) && lex_integer (lexer) == x)
556     {
557       lex_get (lexer);
558       return true;
559     }
560   else
561     return false;
562 }
563 \f
564 /* Forced matches. */
565
566 /* If this token is identifier S, fetches the next token and returns
567    nonzero.
568    Otherwise, reports an error and returns zero. */
569 bool
570 lex_force_match_id (struct lexer *lexer, const char *s)
571 {
572   if (lex_match_id (lexer, s))
573     return true;
574   else
575     {
576       lex_error (lexer, _("expecting `%s'"), s);
577       return false;
578     }
579 }
580
581 /* If the current token is T, skips the token.  Otherwise, reports an
582    error and returns from the current function with return value false. */
583 bool
584 lex_force_match (struct lexer *lexer, int t)
585 {
586   if (lexer->token == t)
587     {
588       lex_get (lexer);
589       return true;
590     }
591   else
592     {
593       lex_error (lexer, _("expecting `%s'"), lex_token_name (t));
594       return false;
595     }
596 }
597
598 /* If this token is a string, does nothing and returns true.
599    Otherwise, reports an error and returns false. */
600 bool
601 lex_force_string (struct lexer *lexer)
602 {
603   if (lexer->token == T_STRING)
604     return true;
605   else
606     {
607       lex_error (lexer, _("expecting string"));
608       return false;
609     }
610 }
611
612 /* If this token is an integer, does nothing and returns true.
613    Otherwise, reports an error and returns false. */
614 bool
615 lex_force_int (struct lexer *lexer)
616 {
617   if (lex_is_integer (lexer))
618     return true;
619   else
620     {
621       lex_error (lexer, _("expecting integer"));
622       return false;
623     }
624 }
625
626 /* If this token is a number, does nothing and returns true.
627    Otherwise, reports an error and returns false. */
628 bool
629 lex_force_num (struct lexer *lexer)
630 {
631   if (lex_is_number (lexer))
632     return true;
633
634   lex_error (lexer, _("expecting number"));
635   return false;
636 }
637
638 /* If this token is an identifier, does nothing and returns true.
639    Otherwise, reports an error and returns false. */
640 bool
641 lex_force_id (struct lexer *lexer)
642 {
643   if (lexer->token == T_ID)
644     return true;
645
646   lex_error (lexer, _("expecting identifier"));
647   return false;
648 }
649
650 /* Weird token functions. */
651
652 /* Returns the first character of the next token, except that if the
653    next token is not an identifier, the character returned will not be
654    a character that can begin an identifier.  Specifically, the
655    hexstring lead-in X' causes lookahead() to return '.  Note that an
656    alphanumeric return value doesn't guarantee an ID token, it could
657    also be a reserved-word token. */
658 int
659 lex_look_ahead (struct lexer *lexer)
660 {
661   if (lexer->put_token)
662     return lexer->put_token;
663
664   for (;;)
665     {
666       if (NULL == lexer->prog && ! lex_get_line (lexer) )
667         return 0;
668
669       for (;;)
670         {
671           while (isspace ((unsigned char) *lexer->prog))
672             lexer->prog++;
673           if (*lexer->prog)
674             break;
675
676           if (lexer->dot)
677             return '.';
678           else if (!lex_get_line (lexer))
679             return 0;
680
681           if (lexer->put_token)
682             return lexer->put_token;
683         }
684
685       if ((toupper ((unsigned char) *lexer->prog) == 'X'
686            || toupper ((unsigned char) *lexer->prog) == 'B'
687            || toupper ((unsigned char) *lexer->prog) == 'O')
688           && (lexer->prog[1] == '\'' || lexer->prog[1] == '"'))
689         return '\'';
690
691       return *lexer->prog;
692     }
693 }
694
695 /* Makes the current token become the next token to be read; the
696    current token is set to T. */
697 void
698 lex_put_back (struct lexer *lexer, int t)
699 {
700   save_token (lexer);
701   lexer->token = t;
702 }
703
704 /* Makes the current token become the next token to be read; the
705    current token is set to the identifier ID. */
706 void
707 lex_put_back_id (struct lexer *lexer, const char *id)
708 {
709   assert (lex_id_to_token (ss_cstr (id)) == T_ID);
710   save_token (lexer);
711   lexer->token = T_ID;
712   ds_assign_cstr (&lexer->tokstr, id);
713   str_copy_trunc (lexer->tokid, sizeof lexer->tokid, ds_cstr (&lexer->tokstr));
714 }
715 \f
716 /* Weird line processing functions. */
717
718 /* Returns the entire contents of the current line. */
719 const char *
720 lex_entire_line (const struct lexer *lexer)
721 {
722   return ds_cstr (&lexer->line_buffer);
723 }
724
725 const struct string *
726 lex_entire_line_ds (const struct lexer *lexer)
727 {
728   return &lexer->line_buffer;
729 }
730
731 /* As lex_entire_line(), but only returns the part of the current line
732    that hasn't already been tokenized. */
733 const char *
734 lex_rest_of_line (const struct lexer *lexer)
735 {
736   return lexer->prog;
737 }
738
739 /* Returns true if the current line ends in a terminal dot,
740    false otherwise. */
741 bool
742 lex_end_dot (const struct lexer *lexer)
743 {
744   return lexer->dot;
745 }
746
747 /* Causes the rest of the current input line to be ignored for
748    tokenization purposes. */
749 void
750 lex_discard_line (struct lexer *lexer)
751 {
752   ds_cstr (&lexer->line_buffer);  /* Ensures ds_end points to something valid */
753   lexer->prog = ds_end (&lexer->line_buffer);
754   lexer->dot = false;
755   lexer->put_token = 0;
756 }
757
758
759 /* Discards the rest of the current command.
760    When we're reading commands from a file, we skip tokens until
761    a terminal dot or EOF.
762    When we're reading commands interactively from the user,
763    that's just discarding the current line, because presumably
764    the user doesn't want to finish typing a command that will be
765    ignored anyway. */
766 void
767 lex_discard_rest_of_command (struct lexer *lexer)
768 {
769   if (!getl_is_interactive (lexer->ss))
770     {
771       while (lexer->token != T_STOP && lexer->token != '.')
772         lex_get (lexer);
773     }
774   else
775     lex_discard_line (lexer);
776 }
777 \f
778 /* Weird line reading functions. */
779
780 /* Remove C-style comments in STRING, begun by slash-star and
781    terminated by star-slash or newline. */
782 static void
783 strip_comments (struct string *string)
784 {
785   char *cp;
786   int quote;
787   bool in_comment;
788
789   in_comment = false;
790   quote = EOF;
791   for (cp = ds_cstr (string); *cp; )
792     {
793       /* If we're not in a comment, check for quote marks. */
794       if (!in_comment)
795         {
796           if (*cp == quote)
797             quote = EOF;
798           else if (*cp == '\'' || *cp == '"')
799             quote = *cp;
800         }
801
802       /* If we're not inside a quotation, check for comment. */
803       if (quote == EOF)
804         {
805           if (cp[0] == '/' && cp[1] == '*')
806             {
807               in_comment = true;
808               *cp++ = ' ';
809               *cp++ = ' ';
810               continue;
811             }
812           else if (in_comment && cp[0] == '*' && cp[1] == '/')
813             {
814               in_comment = false;
815               *cp++ = ' ';
816               *cp++ = ' ';
817               continue;
818             }
819         }
820
821       /* Check commenting. */
822       if (in_comment)
823         *cp = ' ';
824       cp++;
825     }
826 }
827
828 /* Prepares LINE, which is subject to the given SYNTAX rules, for
829    tokenization by stripping comments and determining whether it
830    is the beginning or end of a command and storing into
831    *LINE_STARTS_COMMAND and *LINE_ENDS_COMMAND appropriately. */
832 void
833 lex_preprocess_line (struct string *line,
834                      enum getl_syntax syntax,
835                      bool *line_starts_command,
836                      bool *line_ends_command)
837 {
838   strip_comments (line);
839   ds_rtrim (line, ss_cstr (CC_SPACES));
840   *line_ends_command = (ds_chomp (line, get_endcmd ())
841                         || (ds_is_empty (line) && get_nulline ()));
842   *line_starts_command = false;
843   if (syntax == GETL_BATCH)
844     {
845       int first = ds_first (line);
846       *line_starts_command = !isspace (first);
847       if (first == '+' || first == '-')
848         *ds_data (line) = ' ';
849     }
850 }
851
852 /* Reads a line, without performing any preprocessing.
853    Sets *SYNTAX, if SYNTAX is non-null, to the line's syntax
854    mode. */
855 bool
856 lex_get_line_raw (struct lexer *lexer, enum getl_syntax *syntax)
857 {
858   enum getl_syntax dummy;
859   bool ok = getl_read_line (lexer->ss, &lexer->line_buffer,
860                               syntax != NULL ? syntax : &dummy);
861   return ok;
862 }
863
864 /* Reads a line for use by the tokenizer, and preprocesses it by
865    removing comments, stripping trailing whitespace and the
866    terminal dot, and removing leading indentors. */
867 bool
868 lex_get_line (struct lexer *lexer)
869 {
870   bool line_starts_command;
871   enum getl_syntax syntax;
872
873   if (!lex_get_line_raw (lexer, &syntax))
874     {
875       lexer->prog = NULL;
876     return false;
877     }
878
879   lex_preprocess_line (&lexer->line_buffer, syntax,
880                        &line_starts_command, &lexer->dot);
881
882   if (line_starts_command)
883     lexer->put_token = '.';
884
885   lexer->prog = ds_cstr (&lexer->line_buffer);
886   return true;
887 }
888 \f
889 /* Token names. */
890
891 /* Returns the name of a token. */
892 const char *
893 lex_token_name (int token)
894 {
895   if (lex_is_keyword (token))
896     return lex_id_name (token);
897   else if (token < 256)
898     {
899       static char t[256][2];
900       char *s = t[token];
901       s[0] = token;
902       s[1] = '\0';
903       return s;
904     }
905   else
906     NOT_REACHED ();
907 }
908
909 /* Returns an ASCII representation of the current token as a
910    malloc()'d string. */
911 char *
912 lex_token_representation (struct lexer *lexer)
913 {
914   char *token_rep;
915
916   switch (lexer->token)
917     {
918     case T_ID:
919     case T_POS_NUM:
920     case T_NEG_NUM:
921       return ds_xstrdup (&lexer->tokstr);
922       break;
923
924     case T_STRING:
925       {
926         int hexstring = 0;
927         char *sp, *dp;
928
929         for (sp = ds_cstr (&lexer->tokstr); sp < ds_end (&lexer->tokstr); sp++)
930           if (!isprint ((unsigned char) *sp))
931             {
932               hexstring = 1;
933               break;
934             }
935
936         token_rep = xmalloc (2 + ds_length (&lexer->tokstr) * 2 + 1 + 1);
937
938         dp = token_rep;
939         if (hexstring)
940           *dp++ = 'X';
941         *dp++ = '\'';
942
943         if (!hexstring)
944           for (sp = ds_cstr (&lexer->tokstr); *sp; )
945             {
946               if (*sp == '\'')
947                 *dp++ = '\'';
948               *dp++ = (unsigned char) *sp++;
949             }
950         else
951           for (sp = ds_cstr (&lexer->tokstr); sp < ds_end (&lexer->tokstr); sp++)
952             {
953               *dp++ = (((unsigned char) *sp) >> 4)["0123456789ABCDEF"];
954               *dp++ = (((unsigned char) *sp) & 15)["0123456789ABCDEF"];
955             }
956         *dp++ = '\'';
957         *dp = '\0';
958
959         return token_rep;
960       }
961     break;
962
963     case T_STOP:
964       token_rep = xmalloc (1);
965       *token_rep = '\0';
966       return token_rep;
967
968     case T_EXP:
969       return xstrdup ("**");
970
971     default:
972       return xstrdup (lex_token_name (lexer->token));
973     }
974
975   NOT_REACHED ();
976 }
977 \f
978 /* Really weird functions. */
979
980 /* Most of the time, a `-' is a lead-in to a negative number.  But
981    sometimes it's actually part of the syntax.  If a dash can be part
982    of syntax then this function is called to rip it off of a
983    number. */
984 void
985 lex_negative_to_dash (struct lexer *lexer)
986 {
987   if (lexer->token == T_NEG_NUM)
988     {
989       lexer->token = T_POS_NUM;
990       lexer->tokval = -lexer->tokval;
991       ds_assign_substring (&lexer->tokstr, ds_substr (&lexer->tokstr, 1, SIZE_MAX));
992       save_token (lexer);
993       lexer->token = '-';
994     }
995 }
996
997 /* Skip a COMMENT command. */
998 void
999 lex_skip_comment (struct lexer *lexer)
1000 {
1001   for (;;)
1002     {
1003       if (!lex_get_line (lexer))
1004         {
1005           lexer->put_token = T_STOP;
1006           lexer->prog = NULL;
1007           return;
1008         }
1009
1010       if (lexer->put_token == '.')
1011         break;
1012
1013       ds_cstr (&lexer->line_buffer); /* Ensures ds_end will point to a valid char */
1014       lexer->prog = ds_end (&lexer->line_buffer);
1015       if (lexer->dot)
1016         break;
1017     }
1018 }
1019 \f
1020 /* Private functions. */
1021
1022 /* When invoked, tokstr contains a string of binary, octal, or
1023    hex digits, according to TYPE.  The string is converted to
1024    characters having the specified values. */
1025 static void
1026 convert_numeric_string_to_char_string (struct lexer *lexer,
1027                                        enum string_type type)
1028 {
1029   const char *base_name;
1030   int base;
1031   int chars_per_byte;
1032   size_t byte_cnt;
1033   size_t i;
1034   char *p;
1035
1036   switch (type)
1037     {
1038     case BINARY_STRING:
1039       base_name = _("binary");
1040       base = 2;
1041       chars_per_byte = 8;
1042       break;
1043     case OCTAL_STRING:
1044       base_name = _("octal");
1045       base = 8;
1046       chars_per_byte = 3;
1047       break;
1048     case HEX_STRING:
1049       base_name = _("hex");
1050       base = 16;
1051       chars_per_byte = 2;
1052       break;
1053     default:
1054       NOT_REACHED ();
1055     }
1056
1057   byte_cnt = ds_length (&lexer->tokstr) / chars_per_byte;
1058   if (ds_length (&lexer->tokstr) % chars_per_byte)
1059     msg (SE, _("String of %s digits has %d characters, which is not a "
1060                "multiple of %d."),
1061          base_name, (int) ds_length (&lexer->tokstr), chars_per_byte);
1062
1063   p = ds_cstr (&lexer->tokstr);
1064   for (i = 0; i < byte_cnt; i++)
1065     {
1066       int value;
1067       int j;
1068
1069       value = 0;
1070       for (j = 0; j < chars_per_byte; j++, p++)
1071         {
1072           int v;
1073
1074           if (*p >= '0' && *p <= '9')
1075             v = *p - '0';
1076           else
1077             {
1078               static const char alpha[] = "abcdef";
1079               const char *q = strchr (alpha, tolower ((unsigned char) *p));
1080
1081               if (q)
1082                 v = q - alpha + 10;
1083               else
1084                 v = base;
1085             }
1086
1087           if (v >= base)
1088             msg (SE, _("`%c' is not a valid %s digit."), *p, base_name);
1089
1090           value = value * base + v;
1091         }
1092
1093       ds_cstr (&lexer->tokstr)[i] = (unsigned char) value;
1094     }
1095
1096   ds_truncate (&lexer->tokstr, byte_cnt);
1097 }
1098
1099 /* Parses a string from the input buffer into tokstr.  The input
1100    buffer pointer lexer->prog must point to the initial single or double
1101    quote.  TYPE indicates the type of string to be parsed.
1102    Returns token type. */
1103 static int
1104 parse_string (struct lexer *lexer, enum string_type type)
1105 {
1106   if (type != CHARACTER_STRING)
1107     lexer->prog++;
1108
1109   /* Accumulate the entire string, joining sections indicated by +
1110      signs. */
1111   for (;;)
1112     {
1113       /* Single or double quote. */
1114       int c = *lexer->prog++;
1115
1116       /* Accumulate section. */
1117       for (;;)
1118         {
1119           /* Check end of line. */
1120           if (*lexer->prog == '\0')
1121             {
1122               msg (SE, _("Unterminated string constant."));
1123               goto finish;
1124             }
1125
1126           /* Double quote characters to embed them in strings. */
1127           if (*lexer->prog == c)
1128             {
1129               if (lexer->prog[1] == c)
1130                 lexer->prog++;
1131               else
1132                 break;
1133             }
1134
1135           ds_put_char (&lexer->tokstr, *lexer->prog++);
1136         }
1137       lexer->prog++;
1138
1139       /* Skip whitespace after final quote mark. */
1140       if (lexer->prog == NULL)
1141         break;
1142       for (;;)
1143         {
1144           while (isspace ((unsigned char) *lexer->prog))
1145             lexer->prog++;
1146           if (*lexer->prog)
1147             break;
1148
1149           if (lexer->dot)
1150             goto finish;
1151
1152           if (!lex_get_line (lexer))
1153             goto finish;
1154         }
1155
1156       /* Skip plus sign. */
1157       if (*lexer->prog != '+')
1158         break;
1159       lexer->prog++;
1160
1161       /* Skip whitespace after plus sign. */
1162       if (lexer->prog == NULL)
1163         break;
1164       for (;;)
1165         {
1166           while (isspace ((unsigned char) *lexer->prog))
1167             lexer->prog++;
1168           if (*lexer->prog)
1169             break;
1170
1171           if (lexer->dot)
1172             goto finish;
1173
1174           if (!lex_get_line (lexer))
1175             {
1176               msg (SE, _("Unexpected end of file in string concatenation."));
1177               goto finish;
1178             }
1179         }
1180
1181       /* Ensure that a valid string follows. */
1182       if (*lexer->prog != '\'' && *lexer->prog != '"')
1183         {
1184           msg (SE, _("String expected following `+'."));
1185           goto finish;
1186         }
1187     }
1188
1189   /* We come here when we've finished concatenating all the string sections
1190      into one large string. */
1191 finish:
1192   if (type != CHARACTER_STRING)
1193     convert_numeric_string_to_char_string (lexer, type);
1194
1195   if (ds_length (&lexer->tokstr) > 255)
1196     {
1197       msg (SE, _("String exceeds 255 characters in length (%d characters)."),
1198            (int) ds_length (&lexer->tokstr));
1199       ds_truncate (&lexer->tokstr, 255);
1200     }
1201
1202   return T_STRING;
1203 }
1204 \f
1205 #if DUMP_TOKENS
1206 /* Reads one token from the lexer and writes a textual representation
1207    on stdout for debugging purposes. */
1208 static void
1209 dump_token (struct lexer *lexer)
1210 {
1211   {
1212     const char *curfn;
1213     int curln;
1214
1215     curln = getl_source_location (lexer->ss);
1216     curfn = getl_source_name (lexer->ss);
1217     if (curfn)
1218       fprintf (stderr, "%s:%d\t", curfn, curln);
1219   }
1220
1221   switch (lexer->token)
1222     {
1223     case T_ID:
1224       fprintf (stderr, "ID\t%s\n", lexer->tokid);
1225       break;
1226
1227     case T_POS_NUM:
1228     case T_NEG_NUM:
1229       fprintf (stderr, "NUM\t%f\n", lexer->tokval);
1230       break;
1231
1232     case T_STRING:
1233       fprintf (stderr, "STRING\t\"%s\"\n", ds_cstr (&lexer->tokstr));
1234       break;
1235
1236     case T_STOP:
1237       fprintf (stderr, "STOP\n");
1238       break;
1239
1240     case T_EXP:
1241       fprintf (stderr, "MISC\tEXP\"");
1242       break;
1243
1244     case 0:
1245       fprintf (stderr, "MISC\tEOF\n");
1246       break;
1247
1248     default:
1249       if (lex_is_keyword (lexer->token))
1250         fprintf (stderr, "KEYWORD\t%s\n", lex_token_name (lexer->token));
1251       else
1252         fprintf (stderr, "PUNCT\t%c\n", lexer->token);
1253       break;
1254     }
1255 }
1256 #endif /* DUMP_TOKENS */
1257
1258
1259 /* Token Accessor Functions */
1260
1261 int
1262 lex_token (const struct lexer *lexer)
1263 {
1264   return lexer->token;
1265 }
1266
1267 double
1268 lex_tokval (const struct lexer *lexer)
1269 {
1270   return lexer->tokval;
1271 }
1272
1273 const char *
1274 lex_tokid (const struct lexer *lexer)
1275 {
1276   return lexer->tokid;
1277 }
1278
1279 const struct string *
1280 lex_tokstr (const struct lexer *lexer)
1281 {
1282   return &lexer->tokstr;
1283 }