OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [binutils/] [nlmheader.y] - Blame information for rev 95

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 15 khays
%{/* nlmheader.y - parse NLM header specification keywords.
2
     Copyright 1993, 1994, 1995, 1997, 1998, 2001, 2002, 2003, 2005, 2007,
3
     2010 Free Software Foundation, Inc.
4
 
5
     This file is part of GNU Binutils.
6
 
7
     This program is free software; you can redistribute it and/or modify
8
     it under the terms of the GNU General Public License as published by
9
     the Free Software Foundation; either version 3 of the License, or
10
     (at your option) any later version.
11
 
12
     This program is distributed in the hope that it will be useful,
13
     but WITHOUT ANY WARRANTY; without even the implied warranty of
14
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
     GNU General Public License for more details.
16
 
17
     You should have received a copy of the GNU General Public License
18
     along with this program; if not, write to the Free Software
19
     Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
20
     MA 02110-1301, USA.  */
21
 
22
/* Written by Ian Lance Taylor .
23
 
24
   This bison file parses the commands recognized by the NetWare NLM
25
   linker, except for lists of object files.  It stores the
26
   information in global variables.
27
 
28
   This implementation is based on the description in the NetWare Tool
29
   Maker Specification manual, edition 1.0.  */
30
 
31
#include "sysdep.h"
32
#include "safe-ctype.h"
33
#include "bfd.h"
34
#include "nlm/common.h"
35
#include "nlm/internal.h"
36
#include "bucomm.h"
37
#include "nlmconv.h"
38
 
39
/* Information is stored in the structures pointed to by these
40
   variables.  */
41
 
42
Nlm_Internal_Fixed_Header *fixed_hdr;
43
Nlm_Internal_Variable_Header *var_hdr;
44
Nlm_Internal_Version_Header *version_hdr;
45
Nlm_Internal_Copyright_Header *copyright_hdr;
46
Nlm_Internal_Extended_Header *extended_hdr;
47
 
48
/* Procedure named by CHECK.  */
49
char *check_procedure;
50
/* File named by CUSTOM.  */
51
char *custom_file;
52
/* Whether to generate debugging information (DEBUG).  */
53
bfd_boolean debug_info;
54
/* Procedure named by EXIT.  */
55
char *exit_procedure;
56
/* Exported symbols (EXPORT).  */
57
struct string_list *export_symbols;
58
/* List of files from INPUT.  */
59
struct string_list *input_files;
60
/* Map file name (MAP, FULLMAP).  */
61
char *map_file;
62
/* Whether a full map has been requested (FULLMAP).  */
63
bfd_boolean full_map;
64
/* File named by HELP.  */
65
char *help_file;
66
/* Imported symbols (IMPORT).  */
67
struct string_list *import_symbols;
68
/* File named by MESSAGES.  */
69
char *message_file;
70
/* Autoload module list (MODULE).  */
71
struct string_list *modules;
72
/* File named by OUTPUT.  */
73
char *output_file;
74
/* File named by SHARELIB.  */
75
char *sharelib_file;
76
/* Start procedure name (START).  */
77
char *start_procedure;
78
/* VERBOSE.  */
79
bfd_boolean verbose;
80
/* RPC description file (XDCDATA).  */
81
char *rpc_file;
82
 
83
/* The number of serious errors that have occurred.  */
84
int parse_errors;
85
 
86
/* The current symbol prefix when reading a list of import or export
87
   symbols.  */
88
static char *symbol_prefix;
89
 
90
/* Parser error message handler.  */
91
#define yyerror(msg) nlmheader_error (msg);
92
 
93
/* Local functions.  */
94
static int yylex (void);
95
static void nlmlex_file_push (const char *);
96
static bfd_boolean nlmlex_file_open (const char *);
97
static int nlmlex_buf_init (void);
98
static char nlmlex_buf_add (int);
99
static long nlmlex_get_number (const char *);
100
static void nlmheader_identify (void);
101
static void nlmheader_warn (const char *, int);
102
static void nlmheader_error (const char *);
103
static struct string_list * string_list_cons (char *, struct string_list *);
104
static struct string_list * string_list_append (struct string_list *,
105
                                                struct string_list *);
106
static struct string_list * string_list_append1 (struct string_list *,
107
                                                 char *);
108
static char *xstrdup (const char *);
109
 
110
%}
111
 
112
%union
113
{
114
  char *string;
115
  struct string_list *list;
116
};
117
 
118
/* The reserved words.  */
119
 
120
%token CHECK CODESTART COPYRIGHT CUSTOM DATE DEBUG_K DESCRIPTION EXIT
121
%token EXPORT FLAG_ON FLAG_OFF FULLMAP HELP IMPORT INPUT MAP MESSAGES
122
%token MODULE MULTIPLE OS_DOMAIN OUTPUT PSEUDOPREEMPTION REENTRANT
123
%token SCREENNAME SHARELIB STACK START SYNCHRONIZE
124
%token THREADNAME TYPE VERBOSE VERSIONK XDCDATA
125
 
126
/* Arguments.  */
127
 
128
%token  STRING
129
%token  QUOTED_STRING
130
 
131
/* Typed non-terminals.  */
132
%type  symbol_list_opt symbol_list string_list
133
%type  symbol
134
 
135
%%
136
 
137
/* Keywords must start in the leftmost column of the file.  Arguments
138
   may appear anywhere else.  The lexer uses this to determine what
139
   token to return, so we don't have to worry about it here.  */
140
 
141
/* The entire file is just a list of commands.  */
142
 
143
file:
144
          commands
145
        ;
146
 
147
/* A possibly empty list of commands.  */
148
 
149
commands:
150
          /* May be empty.  */
151
        | command commands
152
        ;
153
 
154
/* A single command.  There is where most of the work takes place.  */
155
 
156
command:
157
          CHECK STRING
158
          {
159
            check_procedure = $2;
160
          }
161
        | CODESTART STRING
162
          {
163
            nlmheader_warn (_("CODESTART is not implemented; sorry"), -1);
164
            free ($2);
165
          }
166
        | COPYRIGHT QUOTED_STRING
167
          {
168
            int len;
169
 
170
            strncpy (copyright_hdr->stamp, "CoPyRiGhT=", 10);
171
            len = strlen ($2);
172
            if (len >= NLM_MAX_COPYRIGHT_MESSAGE_LENGTH)
173
              {
174
                nlmheader_warn (_("copyright string is too long"),
175
                                NLM_MAX_COPYRIGHT_MESSAGE_LENGTH - 1);
176
                len = NLM_MAX_COPYRIGHT_MESSAGE_LENGTH - 1;
177
              }
178
            copyright_hdr->copyrightMessageLength = len;
179
            strncpy (copyright_hdr->copyrightMessage, $2, len);
180
            copyright_hdr->copyrightMessage[len] = '\0';
181
            free ($2);
182
          }
183
        | CUSTOM STRING
184
          {
185
            custom_file = $2;
186
          }
187
        | DATE STRING STRING STRING
188
          {
189
            /* We don't set the version stamp here, because we use the
190
               version stamp to detect whether the required VERSION
191
               keyword was given.  */
192
            version_hdr->month = nlmlex_get_number ($2);
193
            version_hdr->day = nlmlex_get_number ($3);
194
            version_hdr->year = nlmlex_get_number ($4);
195
            free ($2);
196
            free ($3);
197
            free ($4);
198
            if (version_hdr->month < 1 || version_hdr->month > 12)
199
              nlmheader_warn (_("illegal month"), -1);
200
            if (version_hdr->day < 1 || version_hdr->day > 31)
201
              nlmheader_warn (_("illegal day"), -1);
202
            if (version_hdr->year < 1900 || version_hdr->year > 3000)
203
              nlmheader_warn (_("illegal year"), -1);
204
          }
205
        | DEBUG_K
206
          {
207
            debug_info = TRUE;
208
          }
209
        | DESCRIPTION QUOTED_STRING
210
          {
211
            int len;
212
 
213
            len = strlen ($2);
214
            if (len > NLM_MAX_DESCRIPTION_LENGTH)
215
              {
216
                nlmheader_warn (_("description string is too long"),
217
                                NLM_MAX_DESCRIPTION_LENGTH);
218
                len = NLM_MAX_DESCRIPTION_LENGTH;
219
              }
220
            var_hdr->descriptionLength = len;
221
            strncpy (var_hdr->descriptionText, $2, len);
222
            var_hdr->descriptionText[len] = '\0';
223
            free ($2);
224
          }
225
        | EXIT STRING
226
          {
227
            exit_procedure = $2;
228
          }
229
        | EXPORT
230
          {
231
            symbol_prefix = NULL;
232
          }
233
          symbol_list_opt
234
          {
235
            export_symbols = string_list_append (export_symbols, $3);
236
          }
237
        | FLAG_ON STRING
238
          {
239
            fixed_hdr->flags |= nlmlex_get_number ($2);
240
            free ($2);
241
          }
242
        | FLAG_OFF STRING
243
          {
244
            fixed_hdr->flags &=~ nlmlex_get_number ($2);
245
            free ($2);
246
          }
247
        | FULLMAP
248
          {
249
            map_file = "";
250
            full_map = TRUE;
251
          }
252
        | FULLMAP STRING
253
          {
254
            map_file = $2;
255
            full_map = TRUE;
256
          }
257
        | HELP STRING
258
          {
259
            help_file = $2;
260
          }
261
        | IMPORT
262
          {
263
            symbol_prefix = NULL;
264
          }
265
          symbol_list_opt
266
          {
267
            import_symbols = string_list_append (import_symbols, $3);
268
          }
269
        | INPUT string_list
270
          {
271
            input_files = string_list_append (input_files, $2);
272
          }
273
        | MAP
274
          {
275
            map_file = "";
276
          }
277
        | MAP STRING
278
          {
279
            map_file = $2;
280
          }
281
        | MESSAGES STRING
282
          {
283
            message_file = $2;
284
          }
285
        | MODULE string_list
286
          {
287
            modules = string_list_append (modules, $2);
288
          }
289
        | MULTIPLE
290
          {
291
            fixed_hdr->flags |= 0x2;
292
          }
293
        | OS_DOMAIN
294
          {
295
            fixed_hdr->flags |= 0x10;
296
          }
297
        | OUTPUT STRING
298
          {
299
            if (output_file == NULL)
300
              output_file = $2;
301
            else
302
              nlmheader_warn (_("ignoring duplicate OUTPUT statement"), -1);
303
          }
304
        | PSEUDOPREEMPTION
305
          {
306
            fixed_hdr->flags |= 0x8;
307
          }
308
        | REENTRANT
309
          {
310
            fixed_hdr->flags |= 0x1;
311
          }
312
        | SCREENNAME QUOTED_STRING
313
          {
314
            int len;
315
 
316
            len = strlen ($2);
317
            if (len >= NLM_MAX_SCREEN_NAME_LENGTH)
318
              {
319
                nlmheader_warn (_("screen name is too long"),
320
                                NLM_MAX_SCREEN_NAME_LENGTH);
321
                len = NLM_MAX_SCREEN_NAME_LENGTH;
322
              }
323
            var_hdr->screenNameLength = len;
324
            strncpy (var_hdr->screenName, $2, len);
325
            var_hdr->screenName[NLM_MAX_SCREEN_NAME_LENGTH] = '\0';
326
            free ($2);
327
          }
328
        | SHARELIB STRING
329
          {
330
            sharelib_file = $2;
331
          }
332
        | STACK STRING
333
          {
334
            var_hdr->stackSize = nlmlex_get_number ($2);
335
            free ($2);
336
          }
337
        | START STRING
338
          {
339
            start_procedure = $2;
340
          }
341
        | SYNCHRONIZE
342
          {
343
            fixed_hdr->flags |= 0x4;
344
          }
345
        | THREADNAME QUOTED_STRING
346
          {
347
            int len;
348
 
349
            len = strlen ($2);
350
            if (len >= NLM_MAX_THREAD_NAME_LENGTH)
351
              {
352
                nlmheader_warn (_("thread name is too long"),
353
                                NLM_MAX_THREAD_NAME_LENGTH);
354
                len = NLM_MAX_THREAD_NAME_LENGTH;
355
              }
356
            var_hdr->threadNameLength = len;
357
            strncpy (var_hdr->threadName, $2, len);
358
            var_hdr->threadName[len] = '\0';
359
            free ($2);
360
          }
361
        | TYPE STRING
362
          {
363
            fixed_hdr->moduleType = nlmlex_get_number ($2);
364
            free ($2);
365
          }
366
        | VERBOSE
367
          {
368
            verbose = TRUE;
369
          }
370
        | VERSIONK STRING STRING STRING
371
          {
372
            long val;
373
 
374
            strncpy (version_hdr->stamp, "VeRsIoN#", 8);
375
            version_hdr->majorVersion = nlmlex_get_number ($2);
376
            val = nlmlex_get_number ($3);
377
            if (val < 0 || val > 99)
378
              nlmheader_warn (_("illegal minor version number (must be between 0 and 99)"),
379
                              -1);
380
            else
381
              version_hdr->minorVersion = val;
382
            val = nlmlex_get_number ($4);
383
            if (val < 0)
384
              nlmheader_warn (_("illegal revision number (must be between 0 and 26)"),
385
                              -1);
386
            else if (val > 26)
387
              version_hdr->revision = 0;
388
            else
389
              version_hdr->revision = val;
390
            free ($2);
391
            free ($3);
392
            free ($4);
393
          }
394
        | VERSIONK STRING STRING
395
          {
396
            long val;
397
 
398
            strncpy (version_hdr->stamp, "VeRsIoN#", 8);
399
            version_hdr->majorVersion = nlmlex_get_number ($2);
400
            val = nlmlex_get_number ($3);
401
            if (val < 0 || val > 99)
402
              nlmheader_warn (_("illegal minor version number (must be between 0 and 99)"),
403
                              -1);
404
            else
405
              version_hdr->minorVersion = val;
406
            version_hdr->revision = 0;
407
            free ($2);
408
            free ($3);
409
          }
410
        | XDCDATA STRING
411
          {
412
            rpc_file = $2;
413
          }
414
        ;
415
 
416
/* A possibly empty list of symbols.  */
417
 
418
symbol_list_opt:
419
          /* Empty.  */
420
          {
421
            $$ = NULL;
422
          }
423
        | symbol_list
424
          {
425
            $$ = $1;
426
          }
427
        ;
428
 
429
/* A list of symbols in an import or export list.  Prefixes may appear
430
   in parentheses.  We need to use left recursion here to avoid
431
   building up a large import list on the parser stack.  */
432
 
433
symbol_list:
434
          symbol
435
          {
436
            $$ = string_list_cons ($1, NULL);
437
          }
438
        | symbol_prefix
439
          {
440
            $$ = NULL;
441
          }
442
        | symbol_list symbol
443
          {
444
            $$ = string_list_append1 ($1, $2);
445
          }
446
        | symbol_list symbol_prefix
447
          {
448
            $$ = $1;
449
          }
450
        ;
451
 
452
/* A prefix for subsequent symbols.  */
453
 
454
symbol_prefix:
455
          '(' STRING ')'
456
          {
457
            if (symbol_prefix != NULL)
458
              free (symbol_prefix);
459
            symbol_prefix = $2;
460
          }
461
        ;
462
 
463
/* A single symbol.  */
464
 
465
symbol:
466
          STRING
467
          {
468
            if (symbol_prefix == NULL)
469
              $$ = $1;
470
            else
471
              {
472
                $$ = xmalloc (strlen (symbol_prefix) + strlen ($1) + 2);
473
                sprintf ($$, "%s@%s", symbol_prefix, $1);
474
                free ($1);
475
              }
476
          }
477
        ;
478
 
479
/* A list of strings.  */
480
 
481
string_list:
482
          /* May be empty.  */
483
          {
484
            $$ = NULL;
485
          }
486
        | STRING string_list
487
          {
488
            $$ = string_list_cons ($1, $2);
489
          }
490
        ;
491
 
492
%%
493
 
494
/* If strerror is just a macro, we want to use the one from libiberty
495
   since it will handle undefined values.  */
496
#undef strerror
497
extern char *strerror PARAMS ((int));
498
 
499
/* The lexer is simple, too simple for flex.  Keywords are only
500
   recognized at the start of lines.  Everything else must be an
501
   argument.  A comma is treated as whitespace.  */
502
 
503
/* The states the lexer can be in.  */
504
 
505
enum lex_state
506
{
507
  /* At the beginning of a line.  */
508
  BEGINNING_OF_LINE,
509
  /* In the middle of a line.  */
510
  IN_LINE
511
};
512
 
513
/* We need to keep a stack of files to handle file inclusion.  */
514
 
515
struct input
516
{
517
  /* The file to read from.  */
518
  FILE *file;
519
  /* The name of the file.  */
520
  char *name;
521
  /* The current line number.  */
522
  int lineno;
523
  /* The current state.  */
524
  enum lex_state state;
525
  /* The next file on the stack.  */
526
  struct input *next;
527
};
528
 
529
/* The current input file.  */
530
 
531
static struct input current;
532
 
533
/* The character which introduces comments.  */
534
#define COMMENT_CHAR '#'
535
 
536
/* Start the lexer going on the main input file.  */
537
 
538
bfd_boolean
539
nlmlex_file (const char *name)
540
{
541
  current.next = NULL;
542
  return nlmlex_file_open (name);
543
}
544
 
545
/* Start the lexer going on a subsidiary input file.  */
546
 
547
static void
548
nlmlex_file_push (const char *name)
549
{
550
  struct input *push;
551
 
552
  push = (struct input *) xmalloc (sizeof (struct input));
553
  *push = current;
554
  if (nlmlex_file_open (name))
555
    current.next = push;
556
  else
557
    {
558
      current = *push;
559
      free (push);
560
    }
561
}
562
 
563
/* Start lexing from a file.  */
564
 
565
static bfd_boolean
566
nlmlex_file_open (const char *name)
567
{
568
  current.file = fopen (name, "r");
569
  if (current.file == NULL)
570
    {
571
      fprintf (stderr, "%s:%s: %s\n", program_name, name, strerror (errno));
572
      ++parse_errors;
573
      return FALSE;
574
    }
575
  current.name = xstrdup (name);
576
  current.lineno = 1;
577
  current.state = BEGINNING_OF_LINE;
578
  return TRUE;
579
}
580
 
581
/* Table used to turn keywords into tokens.  */
582
 
583
struct keyword_tokens_struct
584
{
585
  const char *keyword;
586
  int token;
587
};
588
 
589
static struct keyword_tokens_struct keyword_tokens[] =
590
{
591
  { "CHECK", CHECK },
592
  { "CODESTART", CODESTART },
593
  { "COPYRIGHT", COPYRIGHT },
594
  { "CUSTOM", CUSTOM },
595
  { "DATE", DATE },
596
  { "DEBUG", DEBUG_K },
597
  { "DESCRIPTION", DESCRIPTION },
598
  { "EXIT", EXIT },
599
  { "EXPORT", EXPORT },
600
  { "FLAG_ON", FLAG_ON },
601
  { "FLAG_OFF", FLAG_OFF },
602
  { "FULLMAP", FULLMAP },
603
  { "HELP", HELP },
604
  { "IMPORT", IMPORT },
605
  { "INPUT", INPUT },
606
  { "MAP", MAP },
607
  { "MESSAGES", MESSAGES },
608
  { "MODULE", MODULE },
609
  { "MULTIPLE", MULTIPLE },
610
  { "OS_DOMAIN", OS_DOMAIN },
611
  { "OUTPUT", OUTPUT },
612
  { "PSEUDOPREEMPTION", PSEUDOPREEMPTION },
613
  { "REENTRANT", REENTRANT },
614
  { "SCREENNAME", SCREENNAME },
615
  { "SHARELIB", SHARELIB },
616
  { "STACK", STACK },
617
  { "STACKSIZE", STACK },
618
  { "START", START },
619
  { "SYNCHRONIZE", SYNCHRONIZE },
620
  { "THREADNAME", THREADNAME },
621
  { "TYPE", TYPE },
622
  { "VERBOSE", VERBOSE },
623
  { "VERSION", VERSIONK },
624
  { "XDCDATA", XDCDATA }
625
};
626
 
627
#define KEYWORD_COUNT (sizeof (keyword_tokens) / sizeof (keyword_tokens[0]))
628
 
629
/* The lexer accumulates strings in these variables.  */
630
static char *lex_buf;
631
static int lex_size;
632
static int lex_pos;
633
 
634
/* Start accumulating strings into the buffer.  */
635
#define BUF_INIT() \
636
  ((void) (lex_buf != NULL ? lex_pos = 0 : nlmlex_buf_init ()))
637
 
638
static int
639
nlmlex_buf_init (void)
640
{
641
  lex_size = 10;
642
  lex_buf = xmalloc (lex_size + 1);
643
  lex_pos = 0;
644
  return 0;
645
}
646
 
647
/* Finish a string in the buffer.  */
648
#define BUF_FINISH() ((void) (lex_buf[lex_pos] = '\0'))
649
 
650
/* Accumulate a character into the buffer.  */
651
#define BUF_ADD(c) \
652
  ((void) (lex_pos < lex_size \
653
           ? lex_buf[lex_pos++] = (c) \
654
           : nlmlex_buf_add (c)))
655
 
656
static char
657
nlmlex_buf_add (int c)
658
{
659
  if (lex_pos >= lex_size)
660
    {
661
      lex_size *= 2;
662
      lex_buf = xrealloc (lex_buf, lex_size + 1);
663
    }
664
 
665
  return lex_buf[lex_pos++] = c;
666
}
667
 
668
/* The lexer proper.  This is called by the bison generated parsing
669
   code.  */
670
 
671
static int
672
yylex (void)
673
{
674
  int c;
675
 
676
tail_recurse:
677
 
678
  c = getc (current.file);
679
 
680
  /* Commas are treated as whitespace characters.  */
681
  while (ISSPACE (c) || c == ',')
682
    {
683
      current.state = IN_LINE;
684
      if (c == '\n')
685
        {
686
          ++current.lineno;
687
          current.state = BEGINNING_OF_LINE;
688
        }
689
      c = getc (current.file);
690
    }
691
 
692
  /* At the end of the file we either pop to the previous file or
693
     finish up.  */
694
  if (c == EOF)
695
    {
696
      fclose (current.file);
697
      free (current.name);
698
      if (current.next == NULL)
699
        return 0;
700
      else
701
        {
702
          struct input *next;
703
 
704
          next = current.next;
705
          current = *next;
706
          free (next);
707
          goto tail_recurse;
708
        }
709
    }
710
 
711
  /* A comment character always means to drop everything until the
712
     next newline.  */
713
  if (c == COMMENT_CHAR)
714
    {
715
      do
716
        {
717
          c = getc (current.file);
718
        }
719
      while (c != '\n');
720
      ++current.lineno;
721
      current.state = BEGINNING_OF_LINE;
722
      goto tail_recurse;
723
    }
724
 
725
  /* An '@' introduces an include file.  */
726
  if (c == '@')
727
    {
728
      do
729
        {
730
          c = getc (current.file);
731
          if (c == '\n')
732
            ++current.lineno;
733
        }
734
      while (ISSPACE (c));
735
      BUF_INIT ();
736
      while (! ISSPACE (c) && c != EOF)
737
        {
738
          BUF_ADD (c);
739
          c = getc (current.file);
740
        }
741
      BUF_FINISH ();
742
 
743
      ungetc (c, current.file);
744
 
745
      nlmlex_file_push (lex_buf);
746
      goto tail_recurse;
747
    }
748
 
749
  /* A non-space character at the start of a line must be the start of
750
     a keyword.  */
751
  if (current.state == BEGINNING_OF_LINE)
752
    {
753
      BUF_INIT ();
754
      while (ISALNUM (c) || c == '_')
755
        {
756
          BUF_ADD (TOUPPER (c));
757
          c = getc (current.file);
758
        }
759
      BUF_FINISH ();
760
 
761
      if (c != EOF && ! ISSPACE (c) && c != ',')
762
        {
763
          nlmheader_identify ();
764
          fprintf (stderr, _("%s:%d: illegal character in keyword: %c\n"),
765
                   current.name, current.lineno, c);
766
        }
767
      else
768
        {
769
          unsigned int i;
770
 
771
          for (i = 0; i < KEYWORD_COUNT; i++)
772
            {
773
              if (lex_buf[0] == keyword_tokens[i].keyword[0]
774
                  && strcmp (lex_buf, keyword_tokens[i].keyword) == 0)
775
                {
776
                  /* Pushing back the final whitespace avoids worrying
777
                     about \n here.  */
778
                  ungetc (c, current.file);
779
                  current.state = IN_LINE;
780
                  return keyword_tokens[i].token;
781
                }
782
            }
783
 
784
          nlmheader_identify ();
785
          fprintf (stderr, _("%s:%d: unrecognized keyword: %s\n"),
786
                   current.name, current.lineno, lex_buf);
787
        }
788
 
789
      ++parse_errors;
790
      /* Treat the rest of this line as a comment.  */
791
      ungetc (COMMENT_CHAR, current.file);
792
      goto tail_recurse;
793
    }
794
 
795
  /* Parentheses just represent themselves.  */
796
  if (c == '(' || c == ')')
797
    return c;
798
 
799
  /* Handle quoted strings.  */
800
  if (c == '"' || c == '\'')
801
    {
802
      int quote;
803
      int start_lineno;
804
 
805
      quote = c;
806
      start_lineno = current.lineno;
807
 
808
      c = getc (current.file);
809
      BUF_INIT ();
810
      while (c != quote && c != EOF)
811
        {
812
          BUF_ADD (c);
813
          if (c == '\n')
814
            ++current.lineno;
815
          c = getc (current.file);
816
        }
817
      BUF_FINISH ();
818
 
819
      if (c == EOF)
820
        {
821
          nlmheader_identify ();
822
          fprintf (stderr, _("%s:%d: end of file in quoted string\n"),
823
                   current.name, start_lineno);
824
          ++parse_errors;
825
        }
826
 
827
      /* FIXME: Possible memory leak.  */
828
      yylval.string = xstrdup (lex_buf);
829
      return QUOTED_STRING;
830
    }
831
 
832
  /* Gather a generic argument.  */
833
  BUF_INIT ();
834
  while (! ISSPACE (c)
835
         && c != ','
836
         && c != COMMENT_CHAR
837
         && c != '('
838
         && c != ')')
839
    {
840
      BUF_ADD (c);
841
      c = getc (current.file);
842
    }
843
  BUF_FINISH ();
844
 
845
  ungetc (c, current.file);
846
 
847
  /* FIXME: Possible memory leak.  */
848
  yylval.string = xstrdup (lex_buf);
849
  return STRING;
850
}
851
 
852
/* Get a number from a string.  */
853
 
854
static long
855
nlmlex_get_number (const char *s)
856
{
857
  long ret;
858
  char *send;
859
 
860
  ret = strtol (s, &send, 10);
861
  if (*send != '\0')
862
    nlmheader_warn (_("bad number"), -1);
863
  return ret;
864
}
865
 
866
/* Prefix the nlmconv warnings with a note as to where they come from.
867
   We don't use program_name on every warning, because then some
868
   versions of the emacs next-error function can't recognize the line
869
   number.  */
870
 
871
static void
872
nlmheader_identify (void)
873
{
874
  static int done;
875
 
876
  if (! done)
877
    {
878
      fprintf (stderr, _("%s: problems in NLM command language input:\n"),
879
               program_name);
880
      done = 1;
881
    }
882
}
883
 
884
/* Issue a warning.  */
885
 
886
static void
887
nlmheader_warn (const char *s, int imax)
888
{
889
  nlmheader_identify ();
890
  fprintf (stderr, "%s:%d: %s", current.name, current.lineno, s);
891
  if (imax != -1)
892
    fprintf (stderr, " (max %d)", imax);
893
  fprintf (stderr, "\n");
894
}
895
 
896
/* Report an error.  */
897
 
898
static void
899
nlmheader_error (const char *s)
900
{
901
  nlmheader_warn (s, -1);
902
  ++parse_errors;
903
}
904
 
905
/* Add a string to a string list.  */
906
 
907
static struct string_list *
908
string_list_cons (char *s, struct string_list *l)
909
{
910
  struct string_list *ret;
911
 
912
  ret = (struct string_list *) xmalloc (sizeof (struct string_list));
913
  ret->next = l;
914
  ret->string = s;
915
  return ret;
916
}
917
 
918
/* Append a string list to another string list.  */
919
 
920
static struct string_list *
921
string_list_append (struct string_list *l1, struct string_list *l2)
922
{
923
  register struct string_list **pp;
924
 
925
  for (pp = &l1; *pp != NULL; pp = &(*pp)->next)
926
    ;
927
  *pp = l2;
928
  return l1;
929
}
930
 
931
/* Append a string to a string list.  */
932
 
933
static struct string_list *
934
string_list_append1 (struct string_list *l, char *s)
935
{
936
  struct string_list *n;
937
  register struct string_list **pp;
938
 
939
  n = (struct string_list *) xmalloc (sizeof (struct string_list));
940
  n->next = NULL;
941
  n->string = s;
942
  for (pp = &l; *pp != NULL; pp = &(*pp)->next)
943
    ;
944
  *pp = n;
945
  return l;
946
}
947
 
948
/* Duplicate a string in memory.  */
949
 
950
static char *
951
xstrdup (const char *s)
952
{
953
  unsigned long len;
954
  char *ret;
955
 
956
  len = strlen (s);
957
  ret = xmalloc (len + 1);
958
  strcpy (ret, s);
959
  return ret;
960
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.