]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/lex.c
kes Change Bacula trademark owner from John Walker to Kern Sibbald
[bacula/bacula] / bacula / src / lib / lex.c
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2008 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of Kern Sibbald.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  * Lexical scanner for Bacula configuration file
30  *
31  *   Kern Sibbald, 2000
32  *
33  *   Version $Id$
34  *
35  */
36
37 #include "bacula.h"
38 #include "lex.h"
39
40 extern int debug_level;
41
42 /* Debug level for this source file */
43 static const int dbglvl = 5000;
44
45 /*
46  * Scan to "logical" end of line. I.e. end of line,
47  *   or semicolon, but stop on T_EOB (same as end of
48  *   line except it is not eaten).
49  */
50 void scan_to_eol(LEX *lc)
51 {
52    int token;
53    Dmsg0(dbglvl, "start scan to eof\n");
54    while ((token = lex_get_token(lc, T_ALL)) != T_EOL) {
55       if (token == T_EOB) {
56          lex_unget_char(lc);
57          return;
58       }
59    }
60 }
61
62 /*
63  * Get next token, but skip EOL
64  */
65 int scan_to_next_not_eol(LEX * lc)
66 {
67    int token;
68    do {
69       token = lex_get_token(lc, T_ALL);
70    } while (token == T_EOL);
71    return token;
72 }
73
74 /*
75  * Format a scanner error message
76  */
77 static void s_err(const char *file, int line, LEX *lc, const char *msg, ...)
78 {
79    va_list arg_ptr;
80    char buf[MAXSTRING];
81    char more[MAXSTRING];
82
83    va_start(arg_ptr, msg);
84    bvsnprintf(buf, sizeof(buf), msg, arg_ptr);
85    va_end(arg_ptr);
86
87    if (lc->err_type == 0) {     /* M_ERROR_TERM by default */
88       lc->err_type = M_ERROR_TERM;
89    }
90
91    if (lc->line_no > lc->begin_line_no) {
92       bsnprintf(more, sizeof(more),
93                 _("Problem probably begins at line %d.\n"), lc->begin_line_no);
94    } else {
95       more[0] = 0;
96    }  
97    if (lc->line_no > 0) {
98       e_msg(file, line, lc->err_type, 0, _("Config error: %s\n"
99 "            : line %d, col %d of file %s\n%s\n%s"),
100          buf, lc->line_no, lc->col_no, lc->fname, lc->line, more);
101    } else {
102       e_msg(file, line, lc->err_type, 0, _("Config error: %s\n"), buf);
103    }
104 }
105
106 void lex_set_default_error_handler(LEX *lf)
107 {
108    lf->scan_error = s_err;
109 }
110
111 /*
112  * Set err_type used in error_handler
113  * return the old value
114  */
115 int lex_set_error_handler_error_type(LEX *lf, int err_type)
116 {
117    int old = lf->err_type;
118    lf->err_type = err_type;
119    return old;
120 }
121
122 /*
123  * Free the current file, and retrieve the contents
124  * of the previous packet if any.
125  */
126 LEX *lex_close_file(LEX *lf)
127 {
128    LEX *of;
129
130    if (lf == NULL) {
131       Emsg0(M_ABORT, 0, _("Close of NULL file\n"));
132    }
133    Dmsg1(dbglvl, "Close lex file: %s\n", lf->fname);
134
135    of = lf->next;
136    if (lf->bpipe) {
137       close_bpipe(lf->bpipe);
138       lf->bpipe = NULL;
139    } else {
140       fclose(lf->fd);
141    }
142    Dmsg1(dbglvl, "Close cfg file %s\n", lf->fname);
143    free(lf->fname);
144    if (of) {
145       of->options = lf->options;      /* preserve options */
146       memcpy(lf, of, sizeof(LEX));
147       Dmsg1(dbglvl, "Restart scan of cfg file %s\n", of->fname);
148    } else {
149       of = lf;
150       lf = NULL;
151    }
152    free(of);
153    return lf;
154 }
155
156 /*
157  * Open a new configuration file. We push the
158  * state of the current file (lf) so that we
159  * can do includes.  This is a bit of a hammer.
160  * Instead of passing back the pointer to the
161  * new packet, I simply replace the contents
162  * of the caller's packet with the new packet,
163  * and link the contents of the old packet into
164  * the next field.
165  *
166  */
167 LEX *lex_open_file(LEX *lf, const char *filename, LEX_ERROR_HANDLER *scan_error)
168
169 {
170    LEX *nf;
171    FILE *fd;
172    BPIPE *bpipe = NULL;
173    char *fname = bstrdup(filename);
174
175
176    if (fname[0] == '|') {
177       if ((bpipe = open_bpipe(fname+1, 0, "rb")) == NULL) {
178          free(fname);
179          return NULL;
180       }
181       fd = bpipe->rfd;
182    } else if ((fd = fopen(fname, "rb")) == NULL) {
183       free(fname);
184       return NULL;
185    }
186    Dmsg1(400, "Open config file: %s\n", fname);
187    nf = (LEX *)malloc(sizeof(LEX));
188    if (lf) {
189       memcpy(nf, lf, sizeof(LEX));
190       memset(lf, 0, sizeof(LEX));
191       lf->next = nf;                  /* if have lf, push it behind new one */
192       lf->options = nf->options;      /* preserve user options */
193       /*
194        * preserve err_type to prevent bacula exiting on 'reload' 
195        * if config is invalid. Fixes bug #877         
196        */
197       lf->err_type = nf->err_type;    
198    } else {
199       lf = nf;                        /* start new packet */
200       memset(lf, 0, sizeof(LEX));
201       lex_set_error_handler_error_type(lf, M_ERROR_TERM);
202    }
203    if (scan_error) {
204       lf->scan_error = scan_error;
205    } else {
206       lex_set_default_error_handler(lf);
207    }
208    lf->fd = fd;
209    lf->bpipe = bpipe;
210    lf->fname = fname;
211    lf->state = lex_none;
212    lf->ch = L_EOL;
213    Dmsg1(dbglvl, "Return lex=%x\n", lf);
214    return lf;
215 }
216
217 /*
218  * Get the next character from the input.
219  *  Returns the character or
220  *    L_EOF if end of file
221  *    L_EOL if end of line
222  */
223 int lex_get_char(LEX *lf)
224 {
225    if (lf->ch == L_EOF) {
226       Emsg0(M_ABORT, 0, _("get_char: called after EOF."
227          " You may have a open double quote without the closing double quote.\n"));
228    }
229    if (lf->ch == L_EOL) {
230       if (bfgets(lf->line, MAXSTRING, lf->fd) == NULL) {
231          lf->ch = L_EOF;
232          if (lf->next) {
233             lex_close_file(lf);
234          }
235          return lf->ch;
236       }
237       lf->line_no++;
238       lf->col_no = 0;
239       Dmsg2(1000, "fget line=%d %s", lf->line_no, lf->line);
240    }
241    lf->ch = (uint8_t)lf->line[lf->col_no];
242    if (lf->ch == 0) {
243       lf->ch = L_EOL;
244    } else {
245       lf->col_no++;
246    }
247    Dmsg2(dbglvl, "lex_get_char: %c %d\n", lf->ch, lf->ch);
248    return lf->ch;
249 }
250
251 void lex_unget_char(LEX *lf)
252 {
253    if (lf->ch == L_EOL) {
254       lf->ch = 0;                     /* End of line, force read of next one */
255    } else {
256       lf->col_no--;                   /* Backup to re-read char */
257    }
258
259 }
260
261
262 /*
263  * Add a character to the current string
264  */
265 static void add_str(LEX *lf, int ch)
266 {
267    if (lf->str_len >= MAXSTRING-3) {
268       Emsg3(M_ERROR_TERM, 0, _(
269            _("Config token too long, file: %s, line %d, begins at line %d\n")),
270              lf->fname, lf->line_no, lf->begin_line_no);
271    }
272    lf->str[lf->str_len++] = ch;
273    lf->str[lf->str_len] = 0;
274 }
275
276 /*
277  * Begin the string
278  */
279 static void begin_str(LEX *lf, int ch)
280 {
281    lf->str_len = 0;
282    lf->str[0] = 0;
283    if (ch != 0) {
284       add_str(lf, ch);
285    }
286    lf->begin_line_no = lf->line_no;   /* save start string line no */
287 }
288
289 #ifdef DEBUG
290 static const char *lex_state_to_str(int state)
291 {
292    switch (state) {
293    case lex_none:          return _("none");
294    case lex_comment:       return _("comment");
295    case lex_number:        return _("number");
296    case lex_ip_addr:       return _("ip_addr");
297    case lex_identifier:    return _("identifier");
298    case lex_string:        return _("string");
299    case lex_quoted_string: return _("quoted_string");
300    case lex_include:       return _("include");
301    case lex_include_quoted_string: return _("include_quoted_string");
302    case lex_utf8_bom:      return _("UTF-8 Byte Order Mark");
303    case lex_utf16_le_bom:  return _("UTF-16le Byte Order Mark");
304    default:                return "??????";
305    }
306 }
307 #endif
308
309 /*
310  * Convert a lex token to a string
311  * used for debug/error printing.
312  */
313 const char *lex_tok_to_str(int token)
314 {
315    switch(token) {
316    case L_EOF:             return "L_EOF";
317    case L_EOL:             return "L_EOL";
318    case T_NONE:            return "T_NONE";
319    case T_NUMBER:          return "T_NUMBER";
320    case T_IPADDR:          return "T_IPADDR";
321    case T_IDENTIFIER:      return "T_IDENTIFIER";
322    case T_UNQUOTED_STRING: return "T_UNQUOTED_STRING";
323    case T_QUOTED_STRING:   return "T_QUOTED_STRING";
324    case T_BOB:             return "T_BOB";
325    case T_EOB:             return "T_EOB";
326    case T_EQUALS:          return "T_EQUALS";
327    case T_ERROR:           return "T_ERROR";
328    case T_EOF:             return "T_EOF";
329    case T_COMMA:           return "T_COMMA";
330    case T_EOL:             return "T_EOL";
331    case T_UTF8_BOM:        return "T_UTF8_BOM";
332    case T_UTF16_BOM:       return "T_UTF16_BOM";
333    default:                return "??????";
334    }
335 }
336
337 static uint32_t scan_pint(LEX *lf, char *str)
338 {
339    int64_t val = 0;
340    if (!is_a_number(str)) {
341       scan_err1(lf, _("expected a positive integer number, got: %s"), str);
342       /* NOT REACHED */
343    } else {
344       errno = 0;
345       val = str_to_int64(str);
346       if (errno != 0 || val < 0) {
347          scan_err1(lf, _("expected a positive integer number, got: %s"), str);
348          /* NOT REACHED */
349       }
350    }
351    return (uint32_t)val;
352 }
353
354 /*
355  *
356  * Get the next token from the input
357  *
358  */
359 int
360 lex_get_token(LEX *lf, int expect)
361 {
362    int ch;
363    int token = T_NONE;
364    bool esc_next = false;
365    /* Unicode files, especially on Win32, may begin with a "Byte Order Mark"
366       to indicate which transmission format the file is in. The codepoint for
367       this mark is U+FEFF and is represented as the octets EF-BB-BF in UTF-8
368       and as FF-FE in UTF-16le(little endian) and  FE-FF in UTF-16(big endian).
369       We use a distinct state for UTF-8 and UTF-16le, and use bom_bytes_seen
370       to tell which byte we are expecting. */
371    int bom_bytes_seen = 0;
372
373    Dmsg0(dbglvl, "enter lex_get_token\n");
374    while (token == T_NONE) {
375       ch = lex_get_char(lf);
376       switch (lf->state) {
377       case lex_none:
378          Dmsg2(dbglvl, "Lex state lex_none ch=%d,%x\n", ch, ch);
379          if (B_ISSPACE(ch))
380             break;
381          if (B_ISALPHA(ch)) {
382             if (lf->options & LOPT_NO_IDENT || lf->options & LOPT_STRING) {
383                lf->state = lex_string;
384             } else {
385                lf->state = lex_identifier;
386             }
387             begin_str(lf, ch);
388             break;
389          }
390          if (B_ISDIGIT(ch)) {
391             if (lf->options & LOPT_STRING) {
392                lf->state = lex_string;
393             } else {
394                lf->state = lex_number;
395             }
396             begin_str(lf, ch);
397             break;
398          }
399          Dmsg0(dbglvl, "Enter lex_none switch\n");
400          switch (ch) {
401          case L_EOF:
402             token = T_EOF;
403             Dmsg0(dbglvl, "got L_EOF set token=T_EOF\n");
404             break;
405          case '#':
406             lf->state = lex_comment;
407             break;
408          case '{':
409             token = T_BOB;
410             begin_str(lf, ch);
411             break;
412          case '}':
413             token = T_EOB;
414             begin_str(lf, ch);
415             break;
416          case '"':
417             lf->state = lex_quoted_string;
418             begin_str(lf, 0);
419             break;
420          case '=':
421             token = T_EQUALS;
422             begin_str(lf, ch);
423             break;
424          case ',':
425             token = T_COMMA;
426             begin_str(lf, ch);
427             break;
428          case ';':
429             if (expect != T_SKIP_EOL) {
430                token = T_EOL;      /* treat ; like EOL */
431             }
432             break;
433          case L_EOL:
434             Dmsg0(dbglvl, "got L_EOL set token=T_EOL\n");
435             if (expect != T_SKIP_EOL) {
436                token = T_EOL;
437             }
438             break;
439          case '@':
440             lf->state = lex_include;
441             begin_str(lf, 0);
442             break;
443          case 0xEF: /* probably a UTF-8 BOM */
444          case 0xFF: /* probably a UTF-16le BOM */
445          case 0xFE: /* probably a UTF-16be BOM (error)*/
446             if (lf->line_no != 1 || lf->col_no != 1)
447             {
448                lf->state = lex_string;
449                begin_str(lf, ch);
450             } else {
451                bom_bytes_seen = 1;
452                if (ch == 0xEF) {
453                   lf->state = lex_utf8_bom;
454                } else if (ch == 0xFF) {
455                   lf->state = lex_utf16_le_bom;
456                } else {
457                   scan_err0(lf, _("This config file appears to be in an "
458                      "unsupported Unicode format (UTF-16be). Please resave as UTF-8\n"));
459                   return T_ERROR;
460                }
461             }
462             break;
463          default:
464             lf->state = lex_string;
465             begin_str(lf, ch);
466             break;
467          }
468          break;
469       case lex_comment:
470          Dmsg1(dbglvl, "Lex state lex_comment ch=%x\n", ch);
471          if (ch == L_EOL) {
472             lf->state = lex_none;
473             if (expect != T_SKIP_EOL) {
474                token = T_EOL;
475             }
476          } else if (ch == L_EOF) {
477             token = T_ERROR;
478          }
479          break;
480       case lex_number:
481          Dmsg2(dbglvl, "Lex state lex_number ch=%x %c\n", ch, ch);
482          if (ch == L_EOF) {
483             token = T_ERROR;
484             break;
485          }
486          /* Might want to allow trailing specifications here */
487          if (B_ISDIGIT(ch)) {
488             add_str(lf, ch);
489             break;
490          }
491
492          /* A valid number can be terminated by the following */
493          if (B_ISSPACE(ch) || ch == L_EOL || ch == ',' || ch == ';') {
494             token = T_NUMBER;
495             lf->state = lex_none;
496          } else {
497             lf->state = lex_string;
498          }
499          lex_unget_char(lf);
500          break;
501       case lex_ip_addr:
502          if (ch == L_EOF) {
503             token = T_ERROR;
504             break;
505          }
506          Dmsg1(dbglvl, "Lex state lex_ip_addr ch=%x\n", ch);
507          break;
508       case lex_string:
509          Dmsg1(dbglvl, "Lex state lex_string ch=%x\n", ch);
510          if (ch == L_EOF) {
511             token = T_ERROR;
512             break;
513          }
514          if (ch == '\n' || ch == L_EOL || ch == '=' || ch == '}' || ch == '{' ||
515              ch == '\r' || ch == ';' || ch == ',' || ch == '#' || (B_ISSPACE(ch)) ) {
516             lex_unget_char(lf);
517             token = T_UNQUOTED_STRING;
518             lf->state = lex_none;
519             break;
520          }
521          add_str(lf, ch);
522          break;
523       case lex_identifier:
524          Dmsg2(dbglvl, "Lex state lex_identifier ch=%x %c\n", ch, ch);
525          if (B_ISALPHA(ch)) {
526             add_str(lf, ch);
527             break;
528          } else if (B_ISSPACE(ch)) {
529             break;
530          } else if (ch == '\n' || ch == L_EOL || ch == '=' || ch == '}' || ch == '{' ||
531                     ch == '\r' || ch == ';' || ch == ','   || ch == '"' || ch == '#') {
532             lex_unget_char(lf);
533             token = T_IDENTIFIER;
534             lf->state = lex_none;
535             break;
536          } else if (ch == L_EOF) {
537             token = T_ERROR;
538             lf->state = lex_none;
539             begin_str(lf, ch);
540             break;
541          }
542          /* Some non-alpha character => string */
543          lf->state = lex_string;
544          add_str(lf, ch);
545          break;
546       case lex_quoted_string:
547          Dmsg2(dbglvl, "Lex state lex_quoted_string ch=%x %c\n", ch, ch);
548          if (ch == L_EOF) {
549             token = T_ERROR;
550             break;
551          }
552          if (ch == L_EOL) {
553             esc_next = false;
554             break;
555          }
556          if (esc_next) {
557             add_str(lf, ch);
558             esc_next = false;
559             break;
560          }
561          if (ch == '\\') {
562             esc_next = true;
563             break;
564          }
565          if (ch == '"') {
566             token = T_QUOTED_STRING;
567             lf->state = lex_none;
568             break;
569          }
570          add_str(lf, ch);
571          break;
572       case lex_include_quoted_string:
573          if (ch == L_EOF) {
574             token = T_ERROR;
575             break;
576          }
577          if (esc_next) {
578             add_str(lf, ch);
579             esc_next = false;
580             break;
581          }
582          if (ch == '\\') {
583             esc_next = true;
584             break;
585          }
586          if (ch == '"') {
587             /* Keep the original LEX so we can print an error if the included file can't be opened. */
588             LEX* lfori = lf;
589             /* Skip the double quote when restarting parsing */
590             lex_get_char(lf);
591
592             lf->state = lex_none;
593             lf = lex_open_file(lf, lf->str, lf->scan_error);
594             if (lf == NULL) {
595                berrno be;
596                scan_err2(lfori, _("Cannot open included config file %s: %s\n"),
597                   lfori->str, be.bstrerror());
598                return T_ERROR;
599             }
600             break;
601          }
602          add_str(lf, ch);
603          break;
604       case lex_include:            /* scanning a filename */
605          if (ch == L_EOF) {
606             token = T_ERROR;
607             break;
608          }
609          if (ch == '"') {
610             lf->state = lex_include_quoted_string;
611             break;
612          }
613
614
615          if (B_ISSPACE(ch) || ch == '\n' || ch == L_EOL || ch == '}' || ch == '{' ||
616              ch == ';' || ch == ','   || ch == '"' || ch == '#') {
617             /* Keep the original LEX so we can print an error if the included file can't be opened. */
618             LEX* lfori = lf;
619
620             lf->state = lex_none;
621             lf = lex_open_file(lf, lf->str, lf->scan_error);
622             if (lf == NULL) {
623                berrno be;
624                scan_err2(lfori, _("Cannot open included config file %s: %s\n"),
625                   lfori->str, be.bstrerror());
626                return T_ERROR;
627             }
628             break;
629          }
630          add_str(lf, ch);
631          break;
632       case lex_utf8_bom:
633          /* we only end up in this state if we have read an 0xEF 
634             as the first byte of the file, indicating we are probably
635             reading a UTF-8 file */
636          if (ch == 0xBB && bom_bytes_seen == 1) {
637             bom_bytes_seen++;
638          } else if (ch == 0xBF && bom_bytes_seen == 2) {
639             token = T_UTF8_BOM;
640             lf->state = lex_none;
641          } else {
642             token = T_ERROR;
643          }
644          break;
645       case lex_utf16_le_bom:
646          /* we only end up in this state if we have read an 0xFF 
647             as the first byte of the file -- indicating that we are
648             probably dealing with an Intel based (little endian) UTF-16 file*/
649          if (ch == 0xFE) {
650             token = T_UTF16_BOM;
651             lf->state = lex_none;
652          } else {
653             token = T_ERROR;
654          }
655          break;
656       }
657       Dmsg4(dbglvl, "ch=%d state=%s token=%s %c\n", ch, lex_state_to_str(lf->state),
658         lex_tok_to_str(token), ch);
659    }
660    Dmsg2(dbglvl, "lex returning: line %d token: %s\n", lf->line_no, lex_tok_to_str(token));
661    lf->token = token;
662
663    /*
664     * Here is where we check to see if the user has set certain
665     *  expectations (e.g. 32 bit integer). If so, we do type checking
666     *  and possible additional scanning (e.g. for range).
667     */
668    switch (expect) {
669    case T_PINT32:
670       lf->pint32_val = scan_pint(lf, lf->str);
671       lf->pint32_val2 = lf->pint32_val;
672       token = T_PINT32;
673       break;
674
675    case T_PINT32_RANGE:
676       if (token == T_NUMBER) {
677          lf->pint32_val = scan_pint(lf, lf->str);
678          lf->pint32_val2 = lf->pint32_val;
679          token = T_PINT32;
680       } else {
681          char *p = strchr(lf->str, '-');
682          if (!p) {
683             scan_err2(lf, _("expected an integer or a range, got %s: %s"),
684                lex_tok_to_str(token), lf->str);
685             token = T_ERROR;
686             break;
687          }
688          *p++ = 0;                       /* terminate first half of range */
689          lf->pint32_val  = scan_pint(lf, lf->str);
690          lf->pint32_val2 = scan_pint(lf, p);
691          token = T_PINT32_RANGE;
692       }
693       break;
694
695    case T_INT32:
696       if (token != T_NUMBER || !is_a_number(lf->str)) {
697          scan_err2(lf, _("expected an integer number, got %s: %s"),
698                lex_tok_to_str(token), lf->str);
699          token = T_ERROR;
700          break;
701       }
702       errno = 0;
703       lf->int32_val = (int32_t)str_to_int64(lf->str);
704       if (errno != 0) {
705          scan_err2(lf, _("expected an integer number, got %s: %s"),
706                lex_tok_to_str(token), lf->str);
707          token = T_ERROR;
708       } else {
709          token = T_INT32;
710       }
711       break;
712
713    case T_INT64:
714       Dmsg2(dbglvl, "int64=:%s: %f\n", lf->str, strtod(lf->str, NULL));
715       if (token != T_NUMBER || !is_a_number(lf->str)) {
716          scan_err2(lf, _("expected an integer number, got %s: %s"),
717                lex_tok_to_str(token), lf->str);
718          token = T_ERROR;
719          break;
720       }
721       errno = 0;
722       lf->int64_val = str_to_int64(lf->str);
723       if (errno != 0) {
724          scan_err2(lf, _("expected an integer number, got %s: %s"),
725                lex_tok_to_str(token), lf->str);
726          token = T_ERROR;
727       } else {
728          token = T_INT64;
729       }
730       break;
731
732    case T_NAME:
733       if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
734          scan_err2(lf, _("expected a name, got %s: %s"),
735                lex_tok_to_str(token), lf->str);
736          token = T_ERROR;
737       } else if (lf->str_len > MAX_RES_NAME_LENGTH) {
738          scan_err3(lf, _("name %s length %d too long, max is %d\n"), lf->str,
739             lf->str_len, MAX_RES_NAME_LENGTH);
740          token = T_ERROR;
741       }
742       break;
743
744    case T_STRING:
745       if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) {
746          scan_err2(lf, _("expected a string, got %s: %s"),
747                lex_tok_to_str(token), lf->str);
748          token = T_ERROR;
749       } else {
750          token = T_STRING;
751       }
752       break;
753
754
755    default:
756       break;                          /* no expectation given */
757    }
758    lf->token = token;                 /* set possible new token */
759    return token;
760 }