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