]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/read-md.c
Add PR target/71395 marker to 71395 fix
[thirdparty/gcc.git] / gcc / read-md.c
CommitLineData
10692477 1/* MD reader for GCC.
818ab71a 2 Copyright (C) 1987-2016 Free Software Foundation, Inc.
10692477
RS
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"
bb933490 23#include "errors.h"
10692477
RS
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
600ab3fc
RS
34/* A singly-linked list of filenames. */
35struct file_name_list {
36 struct file_name_list *next;
37 const char *fname;
38};
39
d2a3ce4e 40/* Obstack used for allocating MD strings. */
10692477
RS
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
d2a3ce4e 52 of conditions that are made up of separate MD strings (such as the split
10692477
RS
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
c5e88b39
RS
59/* The file we are reading. */
60FILE *read_md_file;
10692477 61
c5e88b39
RS
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;
10692477 67
600ab3fc
RS
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
9f418533
RS
88/* A table of md_constant structures, hashed by name. Null if no
89 constant expansion should occur. */
90static htab_t md_constants;
91
24609606
RS
92/* A table of enum_type structures, hashed by name. */
93static htab_t enum_types;
94
600ab3fc
RS
95static void handle_file (directive_handler_t);
96
9f418533
RS
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
10692477
RS
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
d2a3ce4e 135set_md_ptr_loc (const void *ptr, const char *filename, int lineno)
10692477
RS
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 *
d2a3ce4e 151get_md_ptr_loc (const void *ptr)
10692477
RS
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
d2a3ce4e 159copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
10692477 160{
d2a3ce4e 161 const struct ptr_loc *loc = get_md_ptr_loc (old_ptr);
10692477 162 if (loc != 0)
d2a3ce4e 163 set_md_ptr_loc (new_ptr, loc->filename, loc->lineno);
10692477
RS
164}
165
166/* If PTR is associated with a known file position, print a #line
41723253 167 directive for it to OUTF. */
10692477
RS
168
169void
41723253 170fprint_md_ptr_loc (FILE *outf, const void *ptr)
10692477 171{
d2a3ce4e 172 const struct ptr_loc *loc = get_md_ptr_loc (ptr);
10692477 173 if (loc != 0)
41723253
SB
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);
10692477
RS
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
41723253
SB
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
10692477
RS
213 conditions and join the result with "&&". Otherwise print a #line
214 directive for COND if its original file position is known. */
215
216void
41723253 217fprint_c_condition (FILE *outf, const char *cond)
10692477
RS
218{
219 const char **halves = (const char **) htab_find (joined_conditions, &cond);
220 if (halves != 0)
221 {
41723253
SB
222 fprintf (outf, "(");
223 fprint_c_condition (outf, halves[1]);
224 fprintf (outf, " && ");
225 fprint_c_condition (outf, halves[2]);
226 fprintf (outf, ")");
10692477
RS
227 }
228 else
229 {
41723253
SB
230 fputc ('\n', outf);
231 fprint_md_ptr_loc (outf, cond);
232 fprintf (outf, "(%s)", cond);
10692477
RS
233 }
234}
235
41723253
SB
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
bb933490
RS
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)
cc472607 248message_at_1 (file_location loc, const char *msg, va_list ap)
bb933490 249{
cc472607 250 fprintf (stderr, "%s:%d: ", loc.filename, loc.lineno);
bb933490
RS
251 vfprintf (stderr, msg, ap);
252 fputc ('\n', stderr);
253}
254
cc472607
RS
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
8f246310
RS
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
10692477 293/* A printf-like function for reporting an error against the current
c5e88b39 294 position in the MD file. */
10692477
RS
295
296void
c5e88b39 297fatal_with_file_and_line (const char *msg, ...)
10692477
RS
298{
299 char context[64];
300 size_t i;
301 int c;
302 va_list ap;
303
304 va_start (ap, msg);
305
d2a3ce4e 306 fprintf (stderr, "%s:%d: ", read_md_filename, read_md_lineno);
10692477
RS
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 {
c5e88b39 313 c = read_char ();
10692477
RS
314 if (c == EOF)
315 break;
316 if (c == '\r' || c == '\n')
7f7c467f
RS
317 {
318 unread_char (c);
319 break;
320 }
10692477
RS
321 context[i] = c;
322 }
323 context[i] = '\0';
324
325 fprintf (stderr, "%s:%d: following context is `%s'\n",
d2a3ce4e 326 read_md_filename, read_md_lineno, context);
10692477
RS
327
328 va_end (ap);
329 exit (1);
330}
331
332/* Report that we found character ACTUAL when we expected to find
c5e88b39 333 character EXPECTED. */
10692477
RS
334
335void
c5e88b39 336fatal_expected_char (int expected, int actual)
10692477
RS
337{
338 if (actual == EOF)
c5e88b39 339 fatal_with_file_and_line ("expected character `%c', found EOF",
10692477
RS
340 expected);
341 else
c5e88b39 342 fatal_with_file_and_line ("expected character `%c', found `%c'",
10692477
RS
343 expected, actual);
344}
345
c5e88b39 346/* Read chars from the MD file until a non-whitespace char and return that.
10692477
RS
347 Comments, both Lisp style and C style, are treated as whitespace. */
348
349int
c5e88b39 350read_skip_spaces (void)
10692477
RS
351{
352 int c;
353
354 while (1)
355 {
c5e88b39 356 c = read_char ();
10692477
RS
357 switch (c)
358 {
7f7c467f 359 case ' ': case '\t': case '\f': case '\r': case '\n':
10692477
RS
360 break;
361
362 case ';':
363 do
c5e88b39 364 c = read_char ();
10692477 365 while (c != '\n' && c != EOF);
10692477
RS
366 break;
367
368 case '/':
369 {
370 int prevc;
c5e88b39 371 c = read_char ();
10692477 372 if (c != '*')
7f7c467f
RS
373 {
374 unread_char (c);
375 fatal_with_file_and_line ("stray '/' in file");
376 }
10692477
RS
377
378 prevc = 0;
c5e88b39 379 while ((c = read_char ()) && c != EOF)
10692477 380 {
7f7c467f 381 if (prevc == '*' && c == '/')
10692477
RS
382 break;
383 prevc = c;
384 }
385 }
386 break;
387
388 default:
389 return c;
390 }
391 }
392}
393
601070fc
DM
394/* Consume any whitespace, then consume the next non-whitespace
395 character, issuing a fatal error if it is not EXPECTED. */
396
397void
398require_char_ws (char expected)
399{
400 int ch = read_skip_spaces ();
401 if (ch != expected)
402 fatal_expected_char (expected, ch);
403}
404
9f418533
RS
405/* Read an rtx code name into NAME. It is terminated by any of the
406 punctuation chars of rtx printed syntax. */
407
408void
409read_name (struct md_name *name)
410{
411 int c;
412 size_t i;
4fe017f6 413 int angle_bracket_depth;
9f418533
RS
414
415 c = read_skip_spaces ();
416
417 i = 0;
4fe017f6 418 angle_bracket_depth = 0;
9f418533
RS
419 while (1)
420 {
4fe017f6
MC
421 if (c == '<')
422 angle_bracket_depth++;
423
424 if ((c == '>') && (angle_bracket_depth > 0))
425 angle_bracket_depth--;
426
9f418533
RS
427 if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r'
428 || c == EOF)
429 break;
4fe017f6 430 if (angle_bracket_depth == 0)
9f418533 431 {
4fe017f6
MC
432 if (c == ':' || c == ')' || c == ']'
433 || c == '"' || c == '/' || c == '(' || c == '[')
434 {
435 unread_char (c);
436 break;
437 }
9f418533
RS
438 }
439
440 if (i == sizeof (name->buffer) - 1)
441 fatal_with_file_and_line ("name too long");
442 name->buffer[i++] = c;
443
444 c = read_char ();
445 }
446
447 if (i == 0)
448 fatal_with_file_and_line ("missing name or number");
9f418533
RS
449
450 name->buffer[i] = 0;
451 name->string = name->buffer;
452
453 if (md_constants)
454 {
455 /* Do constant expansion. */
456 struct md_constant *def;
457
458 do
459 {
460 struct md_constant tmp_def;
461
462 tmp_def.name = name->string;
463 def = (struct md_constant *) htab_find (md_constants, &tmp_def);
464 if (def)
465 name->string = def->value;
466 }
467 while (def);
468 }
469}
470
10692477
RS
471/* Subroutine of the string readers. Handles backslash escapes.
472 Caller has read the backslash, but not placed it into the obstack. */
473
474static void
c5e88b39 475read_escape (void)
10692477 476{
c5e88b39 477 int c = read_char ();
10692477
RS
478
479 switch (c)
480 {
481 /* Backslash-newline is replaced by nothing, as in C. */
482 case '\n':
10692477
RS
483 return;
484
485 /* \" \' \\ are replaced by the second character. */
486 case '\\':
487 case '"':
488 case '\'':
489 break;
490
491 /* Standard C string escapes:
492 \a \b \f \n \r \t \v
493 \[0-7] \x
494 all are passed through to the output string unmolested.
495 In normal use these wind up in a string constant processed
496 by the C compiler, which will translate them appropriately.
497 We do not bother checking that \[0-7] are followed by up to
498 two octal digits, or that \x is followed by N hex digits.
499 \? \u \U are left out because they are not in traditional C. */
500 case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
501 case '0': case '1': case '2': case '3': case '4': case '5': case '6':
502 case '7': case 'x':
503 obstack_1grow (&string_obstack, '\\');
504 break;
505
506 /* \; makes stuff for a C string constant containing
507 newline and tab. */
508 case ';':
509 obstack_grow (&string_obstack, "\\n\\t", 4);
510 return;
511
512 /* pass anything else through, but issue a warning. */
513 default:
514 fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
d2a3ce4e 515 read_md_filename, read_md_lineno, c);
10692477
RS
516 obstack_1grow (&string_obstack, '\\');
517 break;
518 }
519
520 obstack_1grow (&string_obstack, c);
521}
522
523/* Read a double-quoted string onto the obstack. Caller has scanned
524 the leading quote. */
525
526char *
c5e88b39 527read_quoted_string (void)
10692477
RS
528{
529 int c;
530
531 while (1)
532 {
c5e88b39 533 c = read_char (); /* Read the string */
7f7c467f 534 if (c == '\\')
10692477 535 {
c5e88b39 536 read_escape ();
10692477
RS
537 continue;
538 }
539 else if (c == '"' || c == EOF)
540 break;
541
542 obstack_1grow (&string_obstack, c);
543 }
544
545 obstack_1grow (&string_obstack, 0);
546 return XOBFINISH (&string_obstack, char *);
547}
548
549/* Read a braced string (a la Tcl) onto the string obstack. Caller
550 has scanned the leading brace. Note that unlike quoted strings,
551 the outermost braces _are_ included in the string constant. */
552
553static char *
c5e88b39 554read_braced_string (void)
10692477
RS
555{
556 int c;
557 int brace_depth = 1; /* caller-processed */
d2a3ce4e 558 unsigned long starting_read_md_lineno = read_md_lineno;
10692477
RS
559
560 obstack_1grow (&string_obstack, '{');
561 while (brace_depth)
562 {
c5e88b39 563 c = read_char (); /* Read the string */
10692477 564
7f7c467f 565 if (c == '{')
10692477
RS
566 brace_depth++;
567 else if (c == '}')
568 brace_depth--;
569 else if (c == '\\')
570 {
c5e88b39 571 read_escape ();
10692477
RS
572 continue;
573 }
574 else if (c == EOF)
575 fatal_with_file_and_line
c5e88b39 576 ("missing closing } for opening brace on line %lu",
d2a3ce4e 577 starting_read_md_lineno);
10692477
RS
578
579 obstack_1grow (&string_obstack, c);
580 }
581
582 obstack_1grow (&string_obstack, 0);
583 return XOBFINISH (&string_obstack, char *);
584}
585
586/* Read some kind of string constant. This is the high-level routine
587 used by read_rtx. It handles surrounding parentheses, leading star,
588 and dispatch to the appropriate string constant reader. */
589
590char *
c5e88b39 591read_string (int star_if_braced)
10692477
RS
592{
593 char *stringbuf;
594 int saw_paren = 0;
595 int c, old_lineno;
596
c5e88b39 597 c = read_skip_spaces ();
10692477
RS
598 if (c == '(')
599 {
600 saw_paren = 1;
c5e88b39 601 c = read_skip_spaces ();
10692477
RS
602 }
603
d2a3ce4e 604 old_lineno = read_md_lineno;
10692477 605 if (c == '"')
c5e88b39 606 stringbuf = read_quoted_string ();
10692477
RS
607 else if (c == '{')
608 {
609 if (star_if_braced)
610 obstack_1grow (&string_obstack, '*');
c5e88b39 611 stringbuf = read_braced_string ();
10692477
RS
612 }
613 else
c5e88b39 614 fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c);
10692477
RS
615
616 if (saw_paren)
601070fc 617 require_char_ws (')');
10692477 618
d2a3ce4e 619 set_md_ptr_loc (stringbuf, read_md_filename, old_lineno);
10692477
RS
620 return stringbuf;
621}
622
9b68b6ea
RS
623/* Skip the rest of a construct that started at line LINENO and that
624 is currently nested by DEPTH levels of parentheses. */
625
cc472607
RS
626static void
627read_skip_construct (int depth, file_location loc)
9b68b6ea
RS
628{
629 struct md_name name;
630 int c;
631
632 do
633 {
634 c = read_skip_spaces ();
635 if (c == EOF)
636 {
cc472607 637 error_at (loc, "unterminated construct");
9b68b6ea
RS
638 exit (1);
639 }
640 switch (c)
641 {
642 case '(':
643 depth++;
644 break;
645
646 case ')':
647 depth--;
648 break;
649
650 case ':':
651 case '[':
652 case ']':
653 case '/':
654 break;
655
656 case '\"':
657 case '{':
658 unread_char (c);
659 read_string (false);
660 break;
661
662 default:
663 unread_char (c);
664 read_name (&name);
665 break;
666 }
667 }
668 while (depth > 0);
669 unread_char (c);
670}
671
10692477
RS
672/* Given a string, return the number of comma-separated elements in it.
673 Return 0 for the null string. */
674
675int
676n_comma_elts (const char *s)
677{
678 int n;
679
680 if (*s == '\0')
681 return 0;
682
683 for (n = 1; *s; s++)
684 if (*s == ',')
685 n++;
686
687 return n;
688}
689
690/* Given a pointer to a (char *), return a pointer to the beginning of the
691 next comma-separated element in the string. Advance the pointer given
692 to the end of that element. Return NULL if at end of string. Caller
693 is responsible for copying the string if necessary. White space between
694 a comma and an element is ignored. */
695
696const char *
697scan_comma_elt (const char **pstr)
698{
699 const char *start;
700 const char *p = *pstr;
701
702 if (*p == ',')
703 p++;
c3284718 704 while (ISSPACE (*p))
10692477
RS
705 p++;
706
707 if (*p == '\0')
708 return NULL;
709
710 start = p;
711
712 while (*p != ',' && *p != '\0')
713 p++;
714
715 *pstr = p;
716 return start;
717}
718
24609606
RS
719/* Convert STRING to uppercase. */
720
721void
722upcase_string (char *string)
723{
724 int i;
725
726 for (i = 0; string[i]; i++)
727 string[i] = TOUPPER (string[i]);
728}
729
730/* Add a NAME = VALUE definition to md_constants-style hash table DEFS,
731 where both NAME and VALUE are malloc()ed strings. PARENT_ENUM is the
732 enum to which NAME belongs, or null if NAME is a stand-alone constant. */
733
734static struct md_constant *
735add_constant (htab_t defs, char *name, char *value,
736 struct enum_type *parent_enum)
737{
738 struct md_constant *def, tmp_def;
739 void **entry_ptr;
740
741 tmp_def.name = name;
742 entry_ptr = htab_find_slot (defs, &tmp_def, INSERT);
743 if (*entry_ptr)
744 {
745 def = (struct md_constant *) *entry_ptr;
746 if (strcmp (def->value, value) != 0)
747 fatal_with_file_and_line ("redefinition of `%s', was `%s', now `%s'",
748 def->name, def->value, value);
749 else if (parent_enum || def->parent_enum)
750 fatal_with_file_and_line ("redefinition of `%s'", def->name);
751 free (name);
752 free (value);
753 }
754 else
755 {
756 def = XNEW (struct md_constant);
757 def->name = name;
758 def->value = value;
759 def->parent_enum = parent_enum;
760 *entry_ptr = def;
761 }
762 return def;
763}
764
9f418533
RS
765/* Process a define_constants directive, starting with the optional space
766 after the "define_constants". */
767
600ab3fc
RS
768static void
769handle_constants (void)
9f418533
RS
770{
771 int c;
772 htab_t defs;
773
601070fc 774 require_char_ws ('[');
9f418533
RS
775
776 /* Disable constant expansion during definition processing. */
24609606 777 defs = md_constants;
9f418533
RS
778 md_constants = 0;
779 while ( (c = read_skip_spaces ()) != ']')
780 {
781 struct md_name name, value;
9f418533
RS
782
783 if (c != '(')
784 fatal_expected_char ('(', c);
785
786 read_name (&name);
787 read_name (&value);
24609606 788 add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0);
9f418533 789
601070fc 790 require_char_ws (')');
9f418533
RS
791 }
792 md_constants = defs;
9f418533
RS
793}
794
795/* For every constant definition, call CALLBACK with two arguments:
796 a pointer a pointer to the constant definition and INFO.
797 Stop when CALLBACK returns zero. */
798
799void
800traverse_md_constants (htab_trav callback, void *info)
801{
24609606
RS
802 htab_traverse (md_constants, callback, info);
803}
804
805/* Return a malloc()ed decimal string that represents number NUMBER. */
806
807static char *
09e9c1e0 808md_decimal_string (int number)
24609606
RS
809{
810 /* A safe overestimate. +1 for sign, +1 for null terminator. */
811 char buffer[sizeof (int) * CHAR_BIT + 1 + 1];
812
813 sprintf (buffer, "%d", number);
814 return xstrdup (buffer);
815}
816
817/* Process a define_enum or define_c_enum directive, starting with
818 the optional space after the "define_enum". LINENO is the line
819 number on which the directive started and MD_P is true if the
820 directive is a define_enum rather than a define_c_enum. */
821
822static void
cc472607 823handle_enum (file_location loc, bool md_p)
24609606
RS
824{
825 char *enum_name, *value_name;
826 struct md_name name;
827 struct enum_type *def;
828 struct enum_value *ev;
829 void **slot;
830 int c;
831
832 enum_name = read_string (false);
833 slot = htab_find_slot (enum_types, &enum_name, INSERT);
834 if (*slot)
835 {
836 def = (struct enum_type *) *slot;
837 if (def->md_p != md_p)
cc472607
RS
838 error_at (loc, "redefining `%s' as a different type of enum",
839 enum_name);
24609606
RS
840 }
841 else
842 {
843 def = XNEW (struct enum_type);
844 def->name = enum_name;
845 def->md_p = md_p;
846 def->values = 0;
847 def->tail_ptr = &def->values;
848 def->num_values = 0;
849 *slot = def;
850 }
851
601070fc 852 require_char_ws ('[');
24609606
RS
853
854 while ((c = read_skip_spaces ()) != ']')
855 {
856 if (c == EOF)
857 {
cc472607 858 error_at (loc, "unterminated construct");
24609606
RS
859 exit (1);
860 }
861 unread_char (c);
862 read_name (&name);
863
864 ev = XNEW (struct enum_value);
865 ev->next = 0;
866 if (md_p)
867 {
868 value_name = concat (def->name, "_", name.string, NULL);
869 upcase_string (value_name);
870 ev->name = xstrdup (name.string);
871 }
872 else
873 {
874 value_name = xstrdup (name.string);
875 ev->name = value_name;
876 }
877 ev->def = add_constant (md_constants, value_name,
09e9c1e0 878 md_decimal_string (def->num_values), def);
24609606
RS
879
880 *def->tail_ptr = ev;
881 def->tail_ptr = &ev->next;
882 def->num_values++;
883 }
884}
885
8f4fe86c
RS
886/* Try to find the definition of the given enum. Return null on failure. */
887
888struct enum_type *
889lookup_enum_type (const char *name)
890{
891 return (struct enum_type *) htab_find (enum_types, &name);
892}
893
24609606
RS
894/* For every enum definition, call CALLBACK with two arguments:
895 a pointer to the constant definition and INFO. Stop when CALLBACK
896 returns zero. */
897
898void
899traverse_enum_types (htab_trav callback, void *info)
900{
901 htab_traverse (enum_types, callback, info);
9f418533
RS
902}
903
600ab3fc
RS
904/* Process an "include" directive, starting with the optional space
905 after the "include". Read in the file and use HANDLE_DIRECTIVE
906 to process each unknown directive. LINENO is the line number on
1aa95df7 907 which the "include" occurred. */
10692477 908
600ab3fc 909static void
cc472607 910handle_include (file_location loc, directive_handler_t handle_directive)
10692477 911{
600ab3fc
RS
912 const char *filename;
913 const char *old_filename;
914 int old_lineno;
915 char *pathname;
916 FILE *input_file, *old_file;
917
918 filename = read_string (false);
919 input_file = NULL;
920
921 /* If the specified file name is absolute, skip the include stack. */
922 if (!IS_ABSOLUTE_PATH (filename))
923 {
924 struct file_name_list *stackp;
925
926 /* Search the directory path, trying to open the file. */
927 for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
928 {
929 static const char sep[2] = { DIR_SEPARATOR, '\0' };
930
931 pathname = concat (stackp->fname, sep, filename, NULL);
932 input_file = fopen (pathname, "r");
933 if (input_file != NULL)
934 break;
935 free (pathname);
936 }
937 }
938
939 /* If we haven't managed to open the file yet, try combining the
940 filename with BASE_DIR. */
941 if (input_file == NULL)
942 {
943 if (base_dir)
944 pathname = concat (base_dir, filename, NULL);
945 else
946 pathname = xstrdup (filename);
947 input_file = fopen (pathname, "r");
948 }
949
950 if (input_file == NULL)
951 {
952 free (pathname);
cc472607 953 error_at (loc, "include file `%s' not found", filename);
600ab3fc
RS
954 return;
955 }
956
957 /* Save the old cursor. Note that the LINENO argument to this
958 function is the beginning of the include statement, while
959 read_md_lineno has already been advanced. */
960 old_file = read_md_file;
961 old_filename = read_md_filename;
962 old_lineno = read_md_lineno;
963
964 if (include_callback)
965 include_callback (pathname);
966
967 read_md_file = input_file;
968 read_md_filename = pathname;
969 handle_file (handle_directive);
970
971 /* Restore the old cursor. */
972 read_md_file = old_file;
973 read_md_filename = old_filename;
974 read_md_lineno = old_lineno;
975
976 /* Do not free the pathname. It is attached to the various rtx
977 queue elements. */
978}
979
980/* Process the current file, assuming that read_md_file and
981 read_md_filename are valid. Use HANDLE_DIRECTIVE to handle
982 unknown directives. */
983
984static void
985handle_file (directive_handler_t handle_directive)
986{
987 struct md_name directive;
cc472607 988 int c;
600ab3fc
RS
989
990 read_md_lineno = 1;
991 while ((c = read_skip_spaces ()) != EOF)
992 {
cc472607 993 file_location loc (read_md_filename, read_md_lineno);
600ab3fc
RS
994 if (c != '(')
995 fatal_expected_char ('(', c);
996
997 read_name (&directive);
998 if (strcmp (directive.string, "define_constants") == 0)
999 handle_constants ();
24609606 1000 else if (strcmp (directive.string, "define_enum") == 0)
cc472607 1001 handle_enum (loc, true);
24609606 1002 else if (strcmp (directive.string, "define_c_enum") == 0)
cc472607 1003 handle_enum (loc, false);
600ab3fc 1004 else if (strcmp (directive.string, "include") == 0)
cc472607 1005 handle_include (loc, handle_directive);
9b68b6ea 1006 else if (handle_directive)
cc472607 1007 handle_directive (loc, directive.string);
9b68b6ea 1008 else
cc472607 1009 read_skip_construct (1, loc);
600ab3fc 1010
601070fc 1011 require_char_ws (')');
600ab3fc
RS
1012 }
1013 fclose (read_md_file);
1014}
1015
1016/* Like handle_file, but for top-level files. Set up in_fname and
1017 base_dir accordingly. */
1018
1019static void
1020handle_toplevel_file (directive_handler_t handle_directive)
1021{
ba78087b 1022 const char *base;
600ab3fc
RS
1023
1024 in_fname = read_md_filename;
ba78087b
KT
1025 base = lbasename (in_fname);
1026 if (base == in_fname)
600ab3fc 1027 base_dir = NULL;
ba78087b
KT
1028 else
1029 base_dir = xstrndup (in_fname, base - in_fname);
600ab3fc
RS
1030
1031 handle_file (handle_directive);
1032}
1033
1034/* Parse a -I option with argument ARG. */
1035
1036static void
1037parse_include (const char *arg)
1038{
1039 struct file_name_list *dirtmp;
1040
1041 dirtmp = XNEW (struct file_name_list);
1042 dirtmp->next = 0;
1043 dirtmp->fname = arg;
1044 *last_dir_md_include_ptr = dirtmp;
1045 last_dir_md_include_ptr = &dirtmp->next;
1046 if (strlen (dirtmp->fname) > max_include_len)
1047 max_include_len = strlen (dirtmp->fname);
1048}
1049
1050/* The main routine for reading .md files. Try to process all the .md
1aa95df7 1051 files specified on the command line and return true if no error occurred.
600ab3fc
RS
1052
1053 ARGC and ARGV are the arguments to main.
1054
1055 PARSE_OPT, if nonnull, is passed all unknown command-line arguments.
1056 It should return true if it recognizes the argument or false if a
1057 generic error should be reported.
1058
9b68b6ea
RS
1059 If HANDLE_DIRECTIVE is nonnull, the parser calls it for each
1060 unknown directive, otherwise it just skips such directives.
600ab3fc
RS
1061 See the comment above the directive_handler_t definition for
1062 details about the callback's interface. */
1063
1064bool
66b0fe8f 1065read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *),
600ab3fc
RS
1066 directive_handler_t handle_directive)
1067{
1068 int i;
1069 bool no_more_options;
1070 bool already_read_stdin;
1071 int num_files;
1072
1073 /* Initialize global data. */
10692477
RS
1074 obstack_init (&string_obstack);
1075 ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1076 obstack_init (&ptr_loc_obstack);
1077 joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1078 obstack_init (&joined_conditions_obstack);
24609606
RS
1079 md_constants = htab_create (31, leading_string_hash,
1080 leading_string_eq_p, (htab_del) 0);
1081 enum_types = htab_create (31, leading_string_hash,
1082 leading_string_eq_p, (htab_del) 0);
600ab3fc
RS
1083
1084 /* Unlock the stdio streams. */
1085 unlock_std_streams ();
1086
1087 /* First we loop over all the options. */
1088 for (i = 1; i < argc; i++)
1089 if (argv[i][0] == '-')
1090 {
1091 /* An argument consisting of exactly one dash is a request to
1092 read stdin. This will be handled in the second loop. */
1093 if (argv[i][1] == '\0')
1094 continue;
1095
1096 /* An argument consisting of just two dashes causes option
1097 parsing to cease. */
1098 if (argv[i][1] == '-' && argv[i][2] == '\0')
1099 break;
1100
1101 if (argv[i][1] == 'I')
1102 {
1103 if (argv[i][2] != '\0')
1104 parse_include (argv[i] + 2);
1105 else if (++i < argc)
1106 parse_include (argv[i]);
1107 else
1108 fatal ("directory name missing after -I option");
1109 continue;
1110 }
1111
1112 /* The program may have provided a callback so it can
1113 accept its own options. */
1114 if (parse_opt && parse_opt (argv[i]))
1115 continue;
1116
1117 fatal ("invalid option `%s'", argv[i]);
1118 }
1119
1120 /* Now loop over all input files. */
1121 num_files = 0;
1122 no_more_options = false;
1123 already_read_stdin = false;
1124 for (i = 1; i < argc; i++)
1125 {
1126 if (argv[i][0] == '-')
1127 {
1128 if (argv[i][1] == '\0')
1129 {
1130 /* Read stdin. */
1131 if (already_read_stdin)
1132 fatal ("cannot read standard input twice");
1133
1134 read_md_file = stdin;
1135 read_md_filename = "<stdin>";
1136 handle_toplevel_file (handle_directive);
1137 already_read_stdin = true;
1138 continue;
1139 }
1140 else if (argv[i][1] == '-' && argv[i][2] == '\0')
1141 {
1142 /* No further arguments are to be treated as options. */
1143 no_more_options = true;
1144 continue;
1145 }
1146 else if (!no_more_options)
1147 continue;
1148 }
1149
1150 /* If we get here we are looking at a non-option argument, i.e.
1151 a file to be processed. */
1152 read_md_filename = argv[i];
1153 read_md_file = fopen (read_md_filename, "r");
1154 if (read_md_file == 0)
1155 {
1156 perror (read_md_filename);
1157 return false;
1158 }
1159 handle_toplevel_file (handle_directive);
1160 num_files++;
1161 }
1162
1163 /* If we get to this point without having seen any files to process,
1164 read the standard input now. */
1165 if (num_files == 0 && !already_read_stdin)
1166 {
1167 read_md_file = stdin;
1168 read_md_filename = "<stdin>";
1169 handle_toplevel_file (handle_directive);
1170 }
1171
1172 return !have_error;
10692477 1173}