]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/read-md.c
gcc/
[thirdparty/gcc.git] / gcc / read-md.c
CommitLineData
960ebfe7 1/* MD reader for GCC.
d353bf18 2 Copyright (C) 1987-2015 Free Software Foundation, Inc.
960ebfe7 3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
20#include "bconfig.h"
21#include "system.h"
22#include "coretypes.h"
b638f5c8 23#include "errors.h"
960ebfe7 24#include "read-md.h"
25
26/* Associates PTR (which can be a string, etc.) with the file location
27 specified by FILENAME and LINENO. */
28struct ptr_loc {
29 const void *ptr;
30 const char *filename;
31 int lineno;
32};
33
77ba95d0 34/* A singly-linked list of filenames. */
35struct file_name_list {
36 struct file_name_list *next;
37 const char *fname;
38};
39
77c2564f 40/* Obstack used for allocating MD strings. */
960ebfe7 41struct obstack string_obstack;
42
43/* A table of ptr_locs, hashed on the PTR field. */
44static htab_t ptr_locs;
45
46/* An obstack for the above. Plain xmalloc is a bit heavyweight for a
47 small structure like ptr_loc. */
48static struct obstack ptr_loc_obstack;
49
50/* A hash table of triples (A, B, C), where each of A, B and C is a condition
51 and A is equivalent to "B && C". This is used to keep track of the source
77c2564f 52 of conditions that are made up of separate MD strings (such as the split
960ebfe7 53 condition of a define_insn_and_split). */
54static htab_t joined_conditions;
55
56/* An obstack for allocating joined_conditions entries. */
57static struct obstack joined_conditions_obstack;
58
b3453c30 59/* The file we are reading. */
60FILE *read_md_file;
960ebfe7 61
b3453c30 62/* The filename of READ_MD_FILE. */
63const char *read_md_filename;
64
65/* The current line number in READ_MD_FILE. */
66int read_md_lineno;
960ebfe7 67
77ba95d0 68/* The name of the toplevel file that indirectly included READ_MD_FILE. */
69const char *in_fname;
70
71/* The directory part of IN_FNAME. NULL if IN_FNAME is a bare filename. */
72static char *base_dir;
73
74/* The first directory to search. */
75static struct file_name_list *first_dir_md_include;
76
77/* A pointer to the null terminator of the md include chain. */
78static struct file_name_list **last_dir_md_include_ptr = &first_dir_md_include;
79
80/* This callback will be invoked whenever an md include directive is
81 processed. To be used for creation of the dependency file. */
82void (*include_callback) (const char *);
83
84/* The current maximum length of directory names in the search path
85 for include files. (Altered as we get more of them.) */
86static size_t max_include_len;
87
ac0640e5 88/* A table of md_constant structures, hashed by name. Null if no
89 constant expansion should occur. */
90static htab_t md_constants;
91
5d54fceb 92/* A table of enum_type structures, hashed by name. */
93static htab_t enum_types;
94
77ba95d0 95static void handle_file (directive_handler_t);
96
ac0640e5 97/* Given an object that starts with a char * name field, return a hash
98 code for its name. */
99
100hashval_t
101leading_string_hash (const void *def)
102{
103 return htab_hash_string (*(const char *const *) def);
104}
105
106/* Given two objects that start with char * name fields, return true if
107 they have the same name. */
108
109int
110leading_string_eq_p (const void *def1, const void *def2)
111{
112 return strcmp (*(const char *const *) def1,
113 *(const char *const *) def2) == 0;
114}
115
960ebfe7 116/* Return a hash value for the pointer pointed to by DEF. */
117
118static hashval_t
119leading_ptr_hash (const void *def)
120{
121 return htab_hash_pointer (*(const void *const *) def);
122}
123
124/* Return true if DEF1 and DEF2 are pointers to the same pointer. */
125
126static int
127leading_ptr_eq_p (const void *def1, const void *def2)
128{
129 return *(const void *const *) def1 == *(const void *const *) def2;
130}
131
132/* Associate PTR with the file position given by FILENAME and LINENO. */
133
134static void
77c2564f 135set_md_ptr_loc (const void *ptr, const char *filename, int lineno)
960ebfe7 136{
137 struct ptr_loc *loc;
138
139 loc = (struct ptr_loc *) obstack_alloc (&ptr_loc_obstack,
140 sizeof (struct ptr_loc));
141 loc->ptr = ptr;
142 loc->filename = filename;
143 loc->lineno = lineno;
144 *htab_find_slot (ptr_locs, loc, INSERT) = loc;
145}
146
147/* Return the position associated with pointer PTR. Return null if no
148 position was set. */
149
150static const struct ptr_loc *
77c2564f 151get_md_ptr_loc (const void *ptr)
960ebfe7 152{
153 return (const struct ptr_loc *) htab_find (ptr_locs, &ptr);
154}
155
156/* Associate NEW_PTR with the same file position as OLD_PTR. */
157
158void
77c2564f 159copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
960ebfe7 160{
77c2564f 161 const struct ptr_loc *loc = get_md_ptr_loc (old_ptr);
960ebfe7 162 if (loc != 0)
77c2564f 163 set_md_ptr_loc (new_ptr, loc->filename, loc->lineno);
960ebfe7 164}
165
166/* If PTR is associated with a known file position, print a #line
73ed0c67 167 directive for it to OUTF. */
960ebfe7 168
169void
73ed0c67 170fprint_md_ptr_loc (FILE *outf, const void *ptr)
960ebfe7 171{
77c2564f 172 const struct ptr_loc *loc = get_md_ptr_loc (ptr);
960ebfe7 173 if (loc != 0)
73ed0c67 174 fprintf (outf, "#line %d \"%s\"\n", loc->lineno, loc->filename);
175}
176
177/* Special fprint_md_ptr_loc for writing to STDOUT. */
178void
179print_md_ptr_loc (const void *ptr)
180{
181 fprint_md_ptr_loc (stdout, ptr);
960ebfe7 182}
183
184/* Return a condition that satisfies both COND1 and COND2. Either string
185 may be null or empty. */
186
187const char *
188join_c_conditions (const char *cond1, const char *cond2)
189{
190 char *result;
191 const void **entry;
192
193 if (cond1 == 0 || cond1[0] == 0)
194 return cond2;
195
196 if (cond2 == 0 || cond2[0] == 0)
197 return cond1;
198
199 if (strcmp (cond1, cond2) == 0)
200 return cond1;
201
202 result = concat ("(", cond1, ") && (", cond2, ")", NULL);
203 obstack_ptr_grow (&joined_conditions_obstack, result);
204 obstack_ptr_grow (&joined_conditions_obstack, cond1);
205 obstack_ptr_grow (&joined_conditions_obstack, cond2);
206 entry = XOBFINISH (&joined_conditions_obstack, const void **);
207 *htab_find_slot (joined_conditions, entry, INSERT) = entry;
208 return result;
209}
210
73ed0c67 211/* Print condition COND to OUTF, wrapped in brackets. If COND was created
212 by join_c_conditions, recursively invoke this function for the original
960ebfe7 213 conditions and join the result with "&&". Otherwise print a #line
214 directive for COND if its original file position is known. */
215
216void
73ed0c67 217fprint_c_condition (FILE *outf, const char *cond)
960ebfe7 218{
219 const char **halves = (const char **) htab_find (joined_conditions, &cond);
220 if (halves != 0)
221 {
73ed0c67 222 fprintf (outf, "(");
223 fprint_c_condition (outf, halves[1]);
224 fprintf (outf, " && ");
225 fprint_c_condition (outf, halves[2]);
226 fprintf (outf, ")");
960ebfe7 227 }
228 else
229 {
73ed0c67 230 fputc ('\n', outf);
231 fprint_md_ptr_loc (outf, cond);
232 fprintf (outf, "(%s)", cond);
960ebfe7 233 }
234}
235
73ed0c67 236/* Special fprint_c_condition for writing to STDOUT. */
237
238void
239print_c_condition (const char *cond)
240{
241 fprint_c_condition (stdout, cond);
242}
243
b638f5c8 244/* A vfprintf-like function for reporting an error against line LINENO
245 of the current MD file. */
246
247static void ATTRIBUTE_PRINTF(2,0)
36d192df 248message_at_1 (file_location loc, const char *msg, va_list ap)
b638f5c8 249{
36d192df 250 fprintf (stderr, "%s:%d: ", loc.filename, loc.lineno);
b638f5c8 251 vfprintf (stderr, msg, ap);
252 fputc ('\n', stderr);
253}
254
36d192df 255/* A printf-like function for reporting a message against location LOC. */
256
257void
258message_at (file_location loc, const char *msg, ...)
259{
260 va_list ap;
261
262 va_start (ap, msg);
263 message_at_1 (loc, msg, ap);
264 va_end (ap);
265}
266
267/* Like message_at, but treat the condition as an error. */
268
269void
270error_at (file_location loc, const char *msg, ...)
271{
272 va_list ap;
273
274 va_start (ap, msg);
275 message_at_1 (loc, msg, ap);
276 va_end (ap);
277 have_error = 1;
278}
279
e7ff515f 280/* Like message_at, but treat the condition as a fatal error. */
281
282void
283fatal_at (file_location loc, const char *msg, ...)
284{
285 va_list ap;
286
287 va_start (ap, msg);
288 message_at_1 (loc, msg, ap);
289 va_end (ap);
290 exit (1);
291}
292
960ebfe7 293/* A printf-like function for reporting an error against the current
b3453c30 294 position in the MD file. */
960ebfe7 295
296void
b3453c30 297fatal_with_file_and_line (const char *msg, ...)
960ebfe7 298{
299 char context[64];
300 size_t i;
301 int c;
302 va_list ap;
303
304 va_start (ap, msg);
305
77c2564f 306 fprintf (stderr, "%s:%d: ", read_md_filename, read_md_lineno);
960ebfe7 307 vfprintf (stderr, msg, ap);
308 putc ('\n', stderr);
309
310 /* Gather some following context. */
311 for (i = 0; i < sizeof (context)-1; ++i)
312 {
b3453c30 313 c = read_char ();
960ebfe7 314 if (c == EOF)
315 break;
316 if (c == '\r' || c == '\n')
606cf8b8 317 {
318 unread_char (c);
319 break;
320 }
960ebfe7 321 context[i] = c;
322 }
323 context[i] = '\0';
324
325 fprintf (stderr, "%s:%d: following context is `%s'\n",
77c2564f 326 read_md_filename, read_md_lineno, context);
960ebfe7 327
328 va_end (ap);
329 exit (1);
330}
331
332/* Report that we found character ACTUAL when we expected to find
b3453c30 333 character EXPECTED. */
960ebfe7 334
335void
b3453c30 336fatal_expected_char (int expected, int actual)
960ebfe7 337{
338 if (actual == EOF)
b3453c30 339 fatal_with_file_and_line ("expected character `%c', found EOF",
960ebfe7 340 expected);
341 else
b3453c30 342 fatal_with_file_and_line ("expected character `%c', found `%c'",
960ebfe7 343 expected, actual);
344}
345
b3453c30 346/* Read chars from the MD file until a non-whitespace char and return that.
960ebfe7 347 Comments, both Lisp style and C style, are treated as whitespace. */
348
349int
b3453c30 350read_skip_spaces (void)
960ebfe7 351{
352 int c;
353
354 while (1)
355 {
b3453c30 356 c = read_char ();
960ebfe7 357 switch (c)
358 {
606cf8b8 359 case ' ': case '\t': case '\f': case '\r': case '\n':
960ebfe7 360 break;
361
362 case ';':
363 do
b3453c30 364 c = read_char ();
960ebfe7 365 while (c != '\n' && c != EOF);
960ebfe7 366 break;
367
368 case '/':
369 {
370 int prevc;
b3453c30 371 c = read_char ();
960ebfe7 372 if (c != '*')
606cf8b8 373 {
374 unread_char (c);
375 fatal_with_file_and_line ("stray '/' in file");
376 }
960ebfe7 377
378 prevc = 0;
b3453c30 379 while ((c = read_char ()) && c != EOF)
960ebfe7 380 {
606cf8b8 381 if (prevc == '*' && c == '/')
960ebfe7 382 break;
383 prevc = c;
384 }
385 }
386 break;
387
388 default:
389 return c;
390 }
391 }
392}
393
ac0640e5 394/* Read an rtx code name into NAME. It is terminated by any of the
395 punctuation chars of rtx printed syntax. */
396
397void
398read_name (struct md_name *name)
399{
400 int c;
401 size_t i;
402
403 c = read_skip_spaces ();
404
405 i = 0;
406 while (1)
407 {
408 if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r'
409 || c == EOF)
410 break;
411 if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
412 || c == '(' || c == '[')
413 {
414 unread_char (c);
415 break;
416 }
417
418 if (i == sizeof (name->buffer) - 1)
419 fatal_with_file_and_line ("name too long");
420 name->buffer[i++] = c;
421
422 c = read_char ();
423 }
424
425 if (i == 0)
426 fatal_with_file_and_line ("missing name or number");
ac0640e5 427
428 name->buffer[i] = 0;
429 name->string = name->buffer;
430
431 if (md_constants)
432 {
433 /* Do constant expansion. */
434 struct md_constant *def;
435
436 do
437 {
438 struct md_constant tmp_def;
439
440 tmp_def.name = name->string;
441 def = (struct md_constant *) htab_find (md_constants, &tmp_def);
442 if (def)
443 name->string = def->value;
444 }
445 while (def);
446 }
447}
448
960ebfe7 449/* Subroutine of the string readers. Handles backslash escapes.
450 Caller has read the backslash, but not placed it into the obstack. */
451
452static void
b3453c30 453read_escape (void)
960ebfe7 454{
b3453c30 455 int c = read_char ();
960ebfe7 456
457 switch (c)
458 {
459 /* Backslash-newline is replaced by nothing, as in C. */
460 case '\n':
960ebfe7 461 return;
462
463 /* \" \' \\ are replaced by the second character. */
464 case '\\':
465 case '"':
466 case '\'':
467 break;
468
469 /* Standard C string escapes:
470 \a \b \f \n \r \t \v
471 \[0-7] \x
472 all are passed through to the output string unmolested.
473 In normal use these wind up in a string constant processed
474 by the C compiler, which will translate them appropriately.
475 We do not bother checking that \[0-7] are followed by up to
476 two octal digits, or that \x is followed by N hex digits.
477 \? \u \U are left out because they are not in traditional C. */
478 case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
479 case '0': case '1': case '2': case '3': case '4': case '5': case '6':
480 case '7': case 'x':
481 obstack_1grow (&string_obstack, '\\');
482 break;
483
484 /* \; makes stuff for a C string constant containing
485 newline and tab. */
486 case ';':
487 obstack_grow (&string_obstack, "\\n\\t", 4);
488 return;
489
490 /* pass anything else through, but issue a warning. */
491 default:
492 fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
77c2564f 493 read_md_filename, read_md_lineno, c);
960ebfe7 494 obstack_1grow (&string_obstack, '\\');
495 break;
496 }
497
498 obstack_1grow (&string_obstack, c);
499}
500
501/* Read a double-quoted string onto the obstack. Caller has scanned
502 the leading quote. */
503
504char *
b3453c30 505read_quoted_string (void)
960ebfe7 506{
507 int c;
508
509 while (1)
510 {
b3453c30 511 c = read_char (); /* Read the string */
606cf8b8 512 if (c == '\\')
960ebfe7 513 {
b3453c30 514 read_escape ();
960ebfe7 515 continue;
516 }
517 else if (c == '"' || c == EOF)
518 break;
519
520 obstack_1grow (&string_obstack, c);
521 }
522
523 obstack_1grow (&string_obstack, 0);
524 return XOBFINISH (&string_obstack, char *);
525}
526
527/* Read a braced string (a la Tcl) onto the string obstack. Caller
528 has scanned the leading brace. Note that unlike quoted strings,
529 the outermost braces _are_ included in the string constant. */
530
531static char *
b3453c30 532read_braced_string (void)
960ebfe7 533{
534 int c;
535 int brace_depth = 1; /* caller-processed */
77c2564f 536 unsigned long starting_read_md_lineno = read_md_lineno;
960ebfe7 537
538 obstack_1grow (&string_obstack, '{');
539 while (brace_depth)
540 {
b3453c30 541 c = read_char (); /* Read the string */
960ebfe7 542
606cf8b8 543 if (c == '{')
960ebfe7 544 brace_depth++;
545 else if (c == '}')
546 brace_depth--;
547 else if (c == '\\')
548 {
b3453c30 549 read_escape ();
960ebfe7 550 continue;
551 }
552 else if (c == EOF)
553 fatal_with_file_and_line
b3453c30 554 ("missing closing } for opening brace on line %lu",
77c2564f 555 starting_read_md_lineno);
960ebfe7 556
557 obstack_1grow (&string_obstack, c);
558 }
559
560 obstack_1grow (&string_obstack, 0);
561 return XOBFINISH (&string_obstack, char *);
562}
563
564/* Read some kind of string constant. This is the high-level routine
565 used by read_rtx. It handles surrounding parentheses, leading star,
566 and dispatch to the appropriate string constant reader. */
567
568char *
b3453c30 569read_string (int star_if_braced)
960ebfe7 570{
571 char *stringbuf;
572 int saw_paren = 0;
573 int c, old_lineno;
574
b3453c30 575 c = read_skip_spaces ();
960ebfe7 576 if (c == '(')
577 {
578 saw_paren = 1;
b3453c30 579 c = read_skip_spaces ();
960ebfe7 580 }
581
77c2564f 582 old_lineno = read_md_lineno;
960ebfe7 583 if (c == '"')
b3453c30 584 stringbuf = read_quoted_string ();
960ebfe7 585 else if (c == '{')
586 {
587 if (star_if_braced)
588 obstack_1grow (&string_obstack, '*');
b3453c30 589 stringbuf = read_braced_string ();
960ebfe7 590 }
591 else
b3453c30 592 fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c);
960ebfe7 593
594 if (saw_paren)
595 {
b3453c30 596 c = read_skip_spaces ();
960ebfe7 597 if (c != ')')
b3453c30 598 fatal_expected_char (')', c);
960ebfe7 599 }
600
77c2564f 601 set_md_ptr_loc (stringbuf, read_md_filename, old_lineno);
960ebfe7 602 return stringbuf;
603}
604
664c5888 605/* Skip the rest of a construct that started at line LINENO and that
606 is currently nested by DEPTH levels of parentheses. */
607
36d192df 608static void
609read_skip_construct (int depth, file_location loc)
664c5888 610{
611 struct md_name name;
612 int c;
613
614 do
615 {
616 c = read_skip_spaces ();
617 if (c == EOF)
618 {
36d192df 619 error_at (loc, "unterminated construct");
664c5888 620 exit (1);
621 }
622 switch (c)
623 {
624 case '(':
625 depth++;
626 break;
627
628 case ')':
629 depth--;
630 break;
631
632 case ':':
633 case '[':
634 case ']':
635 case '/':
636 break;
637
638 case '\"':
639 case '{':
640 unread_char (c);
641 read_string (false);
642 break;
643
644 default:
645 unread_char (c);
646 read_name (&name);
647 break;
648 }
649 }
650 while (depth > 0);
651 unread_char (c);
652}
653
960ebfe7 654/* Given a string, return the number of comma-separated elements in it.
655 Return 0 for the null string. */
656
657int
658n_comma_elts (const char *s)
659{
660 int n;
661
662 if (*s == '\0')
663 return 0;
664
665 for (n = 1; *s; s++)
666 if (*s == ',')
667 n++;
668
669 return n;
670}
671
672/* Given a pointer to a (char *), return a pointer to the beginning of the
673 next comma-separated element in the string. Advance the pointer given
674 to the end of that element. Return NULL if at end of string. Caller
675 is responsible for copying the string if necessary. White space between
676 a comma and an element is ignored. */
677
678const char *
679scan_comma_elt (const char **pstr)
680{
681 const char *start;
682 const char *p = *pstr;
683
684 if (*p == ',')
685 p++;
9af5ce0c 686 while (ISSPACE (*p))
960ebfe7 687 p++;
688
689 if (*p == '\0')
690 return NULL;
691
692 start = p;
693
694 while (*p != ',' && *p != '\0')
695 p++;
696
697 *pstr = p;
698 return start;
699}
700
5d54fceb 701/* Convert STRING to uppercase. */
702
703void
704upcase_string (char *string)
705{
706 int i;
707
708 for (i = 0; string[i]; i++)
709 string[i] = TOUPPER (string[i]);
710}
711
712/* Add a NAME = VALUE definition to md_constants-style hash table DEFS,
713 where both NAME and VALUE are malloc()ed strings. PARENT_ENUM is the
714 enum to which NAME belongs, or null if NAME is a stand-alone constant. */
715
716static struct md_constant *
717add_constant (htab_t defs, char *name, char *value,
718 struct enum_type *parent_enum)
719{
720 struct md_constant *def, tmp_def;
721 void **entry_ptr;
722
723 tmp_def.name = name;
724 entry_ptr = htab_find_slot (defs, &tmp_def, INSERT);
725 if (*entry_ptr)
726 {
727 def = (struct md_constant *) *entry_ptr;
728 if (strcmp (def->value, value) != 0)
729 fatal_with_file_and_line ("redefinition of `%s', was `%s', now `%s'",
730 def->name, def->value, value);
731 else if (parent_enum || def->parent_enum)
732 fatal_with_file_and_line ("redefinition of `%s'", def->name);
733 free (name);
734 free (value);
735 }
736 else
737 {
738 def = XNEW (struct md_constant);
739 def->name = name;
740 def->value = value;
741 def->parent_enum = parent_enum;
742 *entry_ptr = def;
743 }
744 return def;
745}
746
ac0640e5 747/* Process a define_constants directive, starting with the optional space
748 after the "define_constants". */
749
77ba95d0 750static void
751handle_constants (void)
ac0640e5 752{
753 int c;
754 htab_t defs;
755
ac0640e5 756 c = read_skip_spaces ();
757 if (c != '[')
758 fatal_expected_char ('[', c);
759
760 /* Disable constant expansion during definition processing. */
5d54fceb 761 defs = md_constants;
ac0640e5 762 md_constants = 0;
763 while ( (c = read_skip_spaces ()) != ']')
764 {
765 struct md_name name, value;
ac0640e5 766
767 if (c != '(')
768 fatal_expected_char ('(', c);
769
770 read_name (&name);
771 read_name (&value);
5d54fceb 772 add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0);
ac0640e5 773
774 c = read_skip_spaces ();
775 if (c != ')')
776 fatal_expected_char (')', c);
777 }
778 md_constants = defs;
ac0640e5 779}
780
781/* For every constant definition, call CALLBACK with two arguments:
782 a pointer a pointer to the constant definition and INFO.
783 Stop when CALLBACK returns zero. */
784
785void
786traverse_md_constants (htab_trav callback, void *info)
787{
5d54fceb 788 htab_traverse (md_constants, callback, info);
789}
790
791/* Return a malloc()ed decimal string that represents number NUMBER. */
792
793static char *
8697277d 794md_decimal_string (int number)
5d54fceb 795{
796 /* A safe overestimate. +1 for sign, +1 for null terminator. */
797 char buffer[sizeof (int) * CHAR_BIT + 1 + 1];
798
799 sprintf (buffer, "%d", number);
800 return xstrdup (buffer);
801}
802
803/* Process a define_enum or define_c_enum directive, starting with
804 the optional space after the "define_enum". LINENO is the line
805 number on which the directive started and MD_P is true if the
806 directive is a define_enum rather than a define_c_enum. */
807
808static void
36d192df 809handle_enum (file_location loc, bool md_p)
5d54fceb 810{
811 char *enum_name, *value_name;
812 struct md_name name;
813 struct enum_type *def;
814 struct enum_value *ev;
815 void **slot;
816 int c;
817
818 enum_name = read_string (false);
819 slot = htab_find_slot (enum_types, &enum_name, INSERT);
820 if (*slot)
821 {
822 def = (struct enum_type *) *slot;
823 if (def->md_p != md_p)
36d192df 824 error_at (loc, "redefining `%s' as a different type of enum",
825 enum_name);
5d54fceb 826 }
827 else
828 {
829 def = XNEW (struct enum_type);
830 def->name = enum_name;
831 def->md_p = md_p;
832 def->values = 0;
833 def->tail_ptr = &def->values;
834 def->num_values = 0;
835 *slot = def;
836 }
837
838 c = read_skip_spaces ();
839 if (c != '[')
840 fatal_expected_char ('[', c);
841
842 while ((c = read_skip_spaces ()) != ']')
843 {
844 if (c == EOF)
845 {
36d192df 846 error_at (loc, "unterminated construct");
5d54fceb 847 exit (1);
848 }
849 unread_char (c);
850 read_name (&name);
851
852 ev = XNEW (struct enum_value);
853 ev->next = 0;
854 if (md_p)
855 {
856 value_name = concat (def->name, "_", name.string, NULL);
857 upcase_string (value_name);
858 ev->name = xstrdup (name.string);
859 }
860 else
861 {
862 value_name = xstrdup (name.string);
863 ev->name = value_name;
864 }
865 ev->def = add_constant (md_constants, value_name,
8697277d 866 md_decimal_string (def->num_values), def);
5d54fceb 867
868 *def->tail_ptr = ev;
869 def->tail_ptr = &ev->next;
870 def->num_values++;
871 }
872}
873
d37b1ac9 874/* Try to find the definition of the given enum. Return null on failure. */
875
876struct enum_type *
877lookup_enum_type (const char *name)
878{
879 return (struct enum_type *) htab_find (enum_types, &name);
880}
881
5d54fceb 882/* For every enum definition, call CALLBACK with two arguments:
883 a pointer to the constant definition and INFO. Stop when CALLBACK
884 returns zero. */
885
886void
887traverse_enum_types (htab_trav callback, void *info)
888{
889 htab_traverse (enum_types, callback, info);
ac0640e5 890}
891
77ba95d0 892/* Process an "include" directive, starting with the optional space
893 after the "include". Read in the file and use HANDLE_DIRECTIVE
894 to process each unknown directive. LINENO is the line number on
75de4aa2 895 which the "include" occurred. */
960ebfe7 896
77ba95d0 897static void
36d192df 898handle_include (file_location loc, directive_handler_t handle_directive)
960ebfe7 899{
77ba95d0 900 const char *filename;
901 const char *old_filename;
902 int old_lineno;
903 char *pathname;
904 FILE *input_file, *old_file;
905
906 filename = read_string (false);
907 input_file = NULL;
908
909 /* If the specified file name is absolute, skip the include stack. */
910 if (!IS_ABSOLUTE_PATH (filename))
911 {
912 struct file_name_list *stackp;
913
914 /* Search the directory path, trying to open the file. */
915 for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
916 {
917 static const char sep[2] = { DIR_SEPARATOR, '\0' };
918
919 pathname = concat (stackp->fname, sep, filename, NULL);
920 input_file = fopen (pathname, "r");
921 if (input_file != NULL)
922 break;
923 free (pathname);
924 }
925 }
926
927 /* If we haven't managed to open the file yet, try combining the
928 filename with BASE_DIR. */
929 if (input_file == NULL)
930 {
931 if (base_dir)
932 pathname = concat (base_dir, filename, NULL);
933 else
934 pathname = xstrdup (filename);
935 input_file = fopen (pathname, "r");
936 }
937
938 if (input_file == NULL)
939 {
940 free (pathname);
36d192df 941 error_at (loc, "include file `%s' not found", filename);
77ba95d0 942 return;
943 }
944
945 /* Save the old cursor. Note that the LINENO argument to this
946 function is the beginning of the include statement, while
947 read_md_lineno has already been advanced. */
948 old_file = read_md_file;
949 old_filename = read_md_filename;
950 old_lineno = read_md_lineno;
951
952 if (include_callback)
953 include_callback (pathname);
954
955 read_md_file = input_file;
956 read_md_filename = pathname;
957 handle_file (handle_directive);
958
959 /* Restore the old cursor. */
960 read_md_file = old_file;
961 read_md_filename = old_filename;
962 read_md_lineno = old_lineno;
963
964 /* Do not free the pathname. It is attached to the various rtx
965 queue elements. */
966}
967
968/* Process the current file, assuming that read_md_file and
969 read_md_filename are valid. Use HANDLE_DIRECTIVE to handle
970 unknown directives. */
971
972static void
973handle_file (directive_handler_t handle_directive)
974{
975 struct md_name directive;
36d192df 976 int c;
77ba95d0 977
978 read_md_lineno = 1;
979 while ((c = read_skip_spaces ()) != EOF)
980 {
36d192df 981 file_location loc (read_md_filename, read_md_lineno);
77ba95d0 982 if (c != '(')
983 fatal_expected_char ('(', c);
984
985 read_name (&directive);
986 if (strcmp (directive.string, "define_constants") == 0)
987 handle_constants ();
5d54fceb 988 else if (strcmp (directive.string, "define_enum") == 0)
36d192df 989 handle_enum (loc, true);
5d54fceb 990 else if (strcmp (directive.string, "define_c_enum") == 0)
36d192df 991 handle_enum (loc, false);
77ba95d0 992 else if (strcmp (directive.string, "include") == 0)
36d192df 993 handle_include (loc, handle_directive);
664c5888 994 else if (handle_directive)
36d192df 995 handle_directive (loc, directive.string);
664c5888 996 else
36d192df 997 read_skip_construct (1, loc);
77ba95d0 998
999 c = read_skip_spaces ();
1000 if (c != ')')
1001 fatal_expected_char (')', c);
1002 }
1003 fclose (read_md_file);
1004}
1005
1006/* Like handle_file, but for top-level files. Set up in_fname and
1007 base_dir accordingly. */
1008
1009static void
1010handle_toplevel_file (directive_handler_t handle_directive)
1011{
82715bcd 1012 const char *base;
77ba95d0 1013
1014 in_fname = read_md_filename;
82715bcd 1015 base = lbasename (in_fname);
1016 if (base == in_fname)
77ba95d0 1017 base_dir = NULL;
82715bcd 1018 else
1019 base_dir = xstrndup (in_fname, base - in_fname);
77ba95d0 1020
1021 handle_file (handle_directive);
1022}
1023
1024/* Parse a -I option with argument ARG. */
1025
1026static void
1027parse_include (const char *arg)
1028{
1029 struct file_name_list *dirtmp;
1030
1031 dirtmp = XNEW (struct file_name_list);
1032 dirtmp->next = 0;
1033 dirtmp->fname = arg;
1034 *last_dir_md_include_ptr = dirtmp;
1035 last_dir_md_include_ptr = &dirtmp->next;
1036 if (strlen (dirtmp->fname) > max_include_len)
1037 max_include_len = strlen (dirtmp->fname);
1038}
1039
1040/* The main routine for reading .md files. Try to process all the .md
75de4aa2 1041 files specified on the command line and return true if no error occurred.
77ba95d0 1042
1043 ARGC and ARGV are the arguments to main.
1044
1045 PARSE_OPT, if nonnull, is passed all unknown command-line arguments.
1046 It should return true if it recognizes the argument or false if a
1047 generic error should be reported.
1048
664c5888 1049 If HANDLE_DIRECTIVE is nonnull, the parser calls it for each
1050 unknown directive, otherwise it just skips such directives.
77ba95d0 1051 See the comment above the directive_handler_t definition for
1052 details about the callback's interface. */
1053
1054bool
1055read_md_files (int argc, char **argv, bool (*parse_opt) (const char *),
1056 directive_handler_t handle_directive)
1057{
1058 int i;
1059 bool no_more_options;
1060 bool already_read_stdin;
1061 int num_files;
1062
1063 /* Initialize global data. */
960ebfe7 1064 obstack_init (&string_obstack);
1065 ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1066 obstack_init (&ptr_loc_obstack);
1067 joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1068 obstack_init (&joined_conditions_obstack);
5d54fceb 1069 md_constants = htab_create (31, leading_string_hash,
1070 leading_string_eq_p, (htab_del) 0);
1071 enum_types = htab_create (31, leading_string_hash,
1072 leading_string_eq_p, (htab_del) 0);
77ba95d0 1073
1074 /* Unlock the stdio streams. */
1075 unlock_std_streams ();
1076
1077 /* First we loop over all the options. */
1078 for (i = 1; i < argc; i++)
1079 if (argv[i][0] == '-')
1080 {
1081 /* An argument consisting of exactly one dash is a request to
1082 read stdin. This will be handled in the second loop. */
1083 if (argv[i][1] == '\0')
1084 continue;
1085
1086 /* An argument consisting of just two dashes causes option
1087 parsing to cease. */
1088 if (argv[i][1] == '-' && argv[i][2] == '\0')
1089 break;
1090
1091 if (argv[i][1] == 'I')
1092 {
1093 if (argv[i][2] != '\0')
1094 parse_include (argv[i] + 2);
1095 else if (++i < argc)
1096 parse_include (argv[i]);
1097 else
1098 fatal ("directory name missing after -I option");
1099 continue;
1100 }
1101
1102 /* The program may have provided a callback so it can
1103 accept its own options. */
1104 if (parse_opt && parse_opt (argv[i]))
1105 continue;
1106
1107 fatal ("invalid option `%s'", argv[i]);
1108 }
1109
1110 /* Now loop over all input files. */
1111 num_files = 0;
1112 no_more_options = false;
1113 already_read_stdin = false;
1114 for (i = 1; i < argc; i++)
1115 {
1116 if (argv[i][0] == '-')
1117 {
1118 if (argv[i][1] == '\0')
1119 {
1120 /* Read stdin. */
1121 if (already_read_stdin)
1122 fatal ("cannot read standard input twice");
1123
1124 read_md_file = stdin;
1125 read_md_filename = "<stdin>";
1126 handle_toplevel_file (handle_directive);
1127 already_read_stdin = true;
1128 continue;
1129 }
1130 else if (argv[i][1] == '-' && argv[i][2] == '\0')
1131 {
1132 /* No further arguments are to be treated as options. */
1133 no_more_options = true;
1134 continue;
1135 }
1136 else if (!no_more_options)
1137 continue;
1138 }
1139
1140 /* If we get here we are looking at a non-option argument, i.e.
1141 a file to be processed. */
1142 read_md_filename = argv[i];
1143 read_md_file = fopen (read_md_filename, "r");
1144 if (read_md_file == 0)
1145 {
1146 perror (read_md_filename);
1147 return false;
1148 }
1149 handle_toplevel_file (handle_directive);
1150 num_files++;
1151 }
1152
1153 /* If we get to this point without having seen any files to process,
1154 read the standard input now. */
1155 if (num_files == 0 && !already_read_stdin)
1156 {
1157 read_md_file = stdin;
1158 read_md_filename = "<stdin>";
1159 handle_toplevel_file (handle_directive);
1160 }
1161
1162 return !have_error;
960ebfe7 1163}