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