xref: /dragonfly/contrib/gcc-4.7/gcc/read-md.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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 
6 This file is part of GCC.
7 
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
12 
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along 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"
26 #include "errors.h"
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.  */
31 struct ptr_loc {
32   const void *ptr;
33   const char *filename;
34   int lineno;
35 };
36 
37 /* A singly-linked list of filenames.  */
38 struct file_name_list {
39   struct file_name_list *next;
40   const char *fname;
41 };
42 
43 /* Obstack used for allocating MD strings.  */
44 struct obstack string_obstack;
45 
46 /* A table of ptr_locs, hashed on the PTR field.  */
47 static 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.  */
51 static 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
55    of conditions that are made up of separate MD strings (such as the split
56    condition of a define_insn_and_split).  */
57 static htab_t joined_conditions;
58 
59 /* An obstack for allocating joined_conditions entries.  */
60 static struct obstack joined_conditions_obstack;
61 
62 /* The file we are reading.  */
63 FILE *read_md_file;
64 
65 /* The filename of READ_MD_FILE.  */
66 const char *read_md_filename;
67 
68 /* The current line number in READ_MD_FILE.  */
69 int read_md_lineno;
70 
71 /* The name of the toplevel file that indirectly included READ_MD_FILE.  */
72 const char *in_fname;
73 
74 /* The directory part of IN_FNAME.  NULL if IN_FNAME is a bare filename.  */
75 static char *base_dir;
76 
77 /* The first directory to search.  */
78 static struct file_name_list *first_dir_md_include;
79 
80 /* A pointer to the null terminator of the md include chain.  */
81 static 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.  */
85 void (*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.)  */
89 static size_t max_include_len;
90 
91 /* A table of md_constant structures, hashed by name.  Null if no
92    constant expansion should occur.  */
93 static htab_t md_constants;
94 
95 /* A table of enum_type structures, hashed by name.  */
96 static htab_t enum_types;
97 
98 static void handle_file (directive_handler_t);
99 
100 /* Given an object that starts with a char * name field, return a hash
101    code for its name.  */
102 
103 hashval_t
leading_string_hash(const void * def)104 leading_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 
112 int
leading_string_eq_p(const void * def1,const void * def2)113 leading_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 
119 /* Return a hash value for the pointer pointed to by DEF.  */
120 
121 static hashval_t
leading_ptr_hash(const void * def)122 leading_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 
129 static int
leading_ptr_eq_p(const void * def1,const void * def2)130 leading_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 
137 static void
set_md_ptr_loc(const void * ptr,const char * filename,int lineno)138 set_md_ptr_loc (const void *ptr, const char *filename, int lineno)
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 
153 static const struct ptr_loc *
get_md_ptr_loc(const void * ptr)154 get_md_ptr_loc (const void *ptr)
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 
161 void
copy_md_ptr_loc(const void * new_ptr,const void * old_ptr)162 copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
163 {
164   const struct ptr_loc *loc = get_md_ptr_loc (old_ptr);
165   if (loc != 0)
166     set_md_ptr_loc (new_ptr, loc->filename, loc->lineno);
167 }
168 
169 /* If PTR is associated with a known file position, print a #line
170    directive for it.  */
171 
172 void
print_md_ptr_loc(const void * ptr)173 print_md_ptr_loc (const void *ptr)
174 {
175   const struct ptr_loc *loc = get_md_ptr_loc (ptr);
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 
183 const char *
join_c_conditions(const char * cond1,const char * cond2)184 join_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 
212 void
print_c_condition(const char * cond)213 print_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);
227       print_md_ptr_loc (cond);
228       printf ("(%s)", cond);
229     }
230 }
231 
232 /* A vfprintf-like function for reporting an error against line LINENO
233    of the current MD file.  */
234 
235 static void ATTRIBUTE_PRINTF(2,0)
message_with_line_1(int lineno,const char * msg,va_list ap)236 message_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 
243 /* A printf-like function for reporting an error against line LINENO
244    in the current MD file.  */
245 
246 void
message_with_line(int lineno,const char * msg,...)247 message_with_line (int lineno, const char *msg, ...)
248 {
249   va_list ap;
250 
251   va_start (ap, msg);
252   message_with_line_1 (lineno, msg, ap);
253   va_end (ap);
254 }
255 
256 /* Like message_with_line, but treat the condition as an error.  */
257 
258 void
error_with_line(int lineno,const char * msg,...)259 error_with_line (int lineno, const char *msg, ...)
260 {
261   va_list ap;
262 
263   va_start (ap, msg);
264   message_with_line_1 (lineno, msg, ap);
265   va_end (ap);
266   have_error = 1;
267 }
268 
269 /* A printf-like function for reporting an error against the current
270    position in the MD file.  */
271 
272 void
fatal_with_file_and_line(const char * msg,...)273 fatal_with_file_and_line (const char *msg, ...)
274 {
275   char context[64];
276   size_t i;
277   int c;
278   va_list ap;
279 
280   va_start (ap, msg);
281 
282   fprintf (stderr, "%s:%d: ", read_md_filename, read_md_lineno);
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     {
289       c = read_char ();
290       if (c == EOF)
291           break;
292       if (c == '\r' || c == '\n')
293           {
294             unread_char (c);
295             break;
296           }
297       context[i] = c;
298     }
299   context[i] = '\0';
300 
301   fprintf (stderr, "%s:%d: following context is `%s'\n",
302              read_md_filename, read_md_lineno, context);
303 
304   va_end (ap);
305   exit (1);
306 }
307 
308 /* Report that we found character ACTUAL when we expected to find
309    character EXPECTED.  */
310 
311 void
fatal_expected_char(int expected,int actual)312 fatal_expected_char (int expected, int actual)
313 {
314   if (actual == EOF)
315     fatal_with_file_and_line ("expected character `%c', found EOF",
316                                     expected);
317   else
318     fatal_with_file_and_line ("expected character `%c', found `%c'",
319                                     expected, actual);
320 }
321 
322 /* Read chars from the MD file until a non-whitespace char and return that.
323    Comments, both Lisp style and C style, are treated as whitespace.  */
324 
325 int
read_skip_spaces(void)326 read_skip_spaces (void)
327 {
328   int c;
329 
330   while (1)
331     {
332       c = read_char ();
333       switch (c)
334           {
335           case ' ': case '\t': case '\f': case '\r': case '\n':
336             break;
337 
338           case ';':
339             do
340               c = read_char ();
341             while (c != '\n' && c != EOF);
342             break;
343 
344           case '/':
345             {
346               int prevc;
347               c = read_char ();
348               if (c != '*')
349                 {
350                     unread_char (c);
351                     fatal_with_file_and_line ("stray '/' in file");
352                 }
353 
354               prevc = 0;
355               while ((c = read_char ()) && c != EOF)
356                 {
357                     if (prevc == '*' && c == '/')
358                       break;
359                   prevc = c;
360                 }
361             }
362             break;
363 
364           default:
365             return c;
366           }
367     }
368 }
369 
370 /* Read an rtx code name into NAME.  It is terminated by any of the
371    punctuation chars of rtx printed syntax.  */
372 
373 void
read_name(struct md_name * name)374 read_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");
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 
425 /* Subroutine of the string readers.  Handles backslash escapes.
426    Caller has read the backslash, but not placed it into the obstack.  */
427 
428 static void
read_escape(void)429 read_escape (void)
430 {
431   int c = read_char ();
432 
433   switch (c)
434     {
435       /* Backslash-newline is replaced by nothing, as in C.  */
436     case '\n':
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",
469                  read_md_filename, read_md_lineno, c);
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 
480 char *
read_quoted_string(void)481 read_quoted_string (void)
482 {
483   int c;
484 
485   while (1)
486     {
487       c = read_char (); /* Read the string  */
488       if (c == '\\')
489           {
490             read_escape ();
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 
507 static char *
read_braced_string(void)508 read_braced_string (void)
509 {
510   int c;
511   int brace_depth = 1;  /* caller-processed */
512   unsigned long starting_read_md_lineno = read_md_lineno;
513 
514   obstack_1grow (&string_obstack, '{');
515   while (brace_depth)
516     {
517       c = read_char (); /* Read the string  */
518 
519       if (c == '{')
520           brace_depth++;
521       else if (c == '}')
522           brace_depth--;
523       else if (c == '\\')
524           {
525             read_escape ();
526             continue;
527           }
528       else if (c == EOF)
529           fatal_with_file_and_line
530             ("missing closing } for opening brace on line %lu",
531              starting_read_md_lineno);
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 
544 char *
read_string(int star_if_braced)545 read_string (int star_if_braced)
546 {
547   char *stringbuf;
548   int saw_paren = 0;
549   int c, old_lineno;
550 
551   c = read_skip_spaces ();
552   if (c == '(')
553     {
554       saw_paren = 1;
555       c = read_skip_spaces ();
556     }
557 
558   old_lineno = read_md_lineno;
559   if (c == '"')
560     stringbuf = read_quoted_string ();
561   else if (c == '{')
562     {
563       if (star_if_braced)
564           obstack_1grow (&string_obstack, '*');
565       stringbuf = read_braced_string ();
566     }
567   else
568     fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c);
569 
570   if (saw_paren)
571     {
572       c = read_skip_spaces ();
573       if (c != ')')
574           fatal_expected_char (')', c);
575     }
576 
577   set_md_ptr_loc (stringbuf, read_md_filename, old_lineno);
578   return stringbuf;
579 }
580 
581 /* Skip the rest of a construct that started at line LINENO and that
582    is currently nested by DEPTH levels of parentheses.  */
583 
584 void
read_skip_construct(int depth,int lineno)585 read_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 
630 /* Given a string, return the number of comma-separated elements in it.
631    Return 0 for the null string.  */
632 
633 int
n_comma_elts(const char * s)634 n_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 
654 const char *
scan_comma_elt(const char ** pstr)655 scan_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 
677 /* Convert STRING to uppercase.  */
678 
679 void
upcase_string(char * string)680 upcase_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 
692 static struct md_constant *
add_constant(htab_t defs,char * name,char * value,struct enum_type * parent_enum)693 add_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 
723 /* Process a define_constants directive, starting with the optional space
724    after the "define_constants".  */
725 
726 static void
handle_constants(void)727 handle_constants (void)
728 {
729   int c;
730   htab_t defs;
731 
732   c = read_skip_spaces ();
733   if (c != '[')
734     fatal_expected_char ('[', c);
735 
736   /* Disable constant expansion during definition processing.  */
737   defs = md_constants;
738   md_constants = 0;
739   while ( (c = read_skip_spaces ()) != ']')
740     {
741       struct md_name name, value;
742 
743       if (c != '(')
744           fatal_expected_char ('(', c);
745 
746       read_name (&name);
747       read_name (&value);
748       add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0);
749 
750       c = read_skip_spaces ();
751       if (c != ')')
752           fatal_expected_char (')', c);
753     }
754   md_constants = defs;
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 
761 void
traverse_md_constants(htab_trav callback,void * info)762 traverse_md_constants (htab_trav callback, void *info)
763 {
764   htab_traverse (md_constants, callback, info);
765 }
766 
767 /* Return a malloc()ed decimal string that represents number NUMBER.  */
768 
769 static char *
decimal_string(int number)770 decimal_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 
784 static void
handle_enum(int lineno,bool md_p)785 handle_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 /* Try to find the definition of the given enum.  Return null on failure.  */
851 
852 struct enum_type *
lookup_enum_type(const char * name)853 lookup_enum_type (const char *name)
854 {
855   return (struct enum_type *) htab_find (enum_types, &name);
856 }
857 
858 /* For every enum definition, call CALLBACK with two arguments:
859    a pointer to the constant definition and INFO.  Stop when CALLBACK
860    returns zero.  */
861 
862 void
traverse_enum_types(htab_trav callback,void * info)863 traverse_enum_types (htab_trav callback, void *info)
864 {
865   htab_traverse (enum_types, callback, info);
866 }
867 
868 /* Process an "include" directive, starting with the optional space
869    after the "include".  Read in the file and use HANDLE_DIRECTIVE
870    to process each unknown directive.  LINENO is the line number on
871    which the "include" occured.  */
872 
873 static void
handle_include(int lineno,directive_handler_t handle_directive)874 handle_include (int lineno, directive_handler_t handle_directive)
875 {
876   const char *filename;
877   const char *old_filename;
878   int old_lineno;
879   char *pathname;
880   FILE *input_file, *old_file;
881 
882   filename = read_string (false);
883   input_file = NULL;
884 
885   /* If the specified file name is absolute, skip the include stack.  */
886   if (!IS_ABSOLUTE_PATH (filename))
887     {
888       struct file_name_list *stackp;
889 
890       /* Search the directory path, trying to open the file.  */
891       for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
892           {
893             static const char sep[2] = { DIR_SEPARATOR, '\0' };
894 
895             pathname = concat (stackp->fname, sep, filename, NULL);
896             input_file = fopen (pathname, "r");
897             if (input_file != NULL)
898               break;
899             free (pathname);
900           }
901     }
902 
903   /* If we haven't managed to open the file yet, try combining the
904      filename with BASE_DIR.  */
905   if (input_file == NULL)
906     {
907       if (base_dir)
908           pathname = concat (base_dir, filename, NULL);
909       else
910           pathname = xstrdup (filename);
911       input_file = fopen (pathname, "r");
912     }
913 
914   if (input_file == NULL)
915     {
916       free (pathname);
917       error_with_line (lineno, "include file `%s' not found", filename);
918       return;
919     }
920 
921   /* Save the old cursor.  Note that the LINENO argument to this
922      function is the beginning of the include statement, while
923      read_md_lineno has already been advanced.  */
924   old_file = read_md_file;
925   old_filename = read_md_filename;
926   old_lineno = read_md_lineno;
927 
928   if (include_callback)
929     include_callback (pathname);
930 
931   read_md_file = input_file;
932   read_md_filename = pathname;
933   handle_file (handle_directive);
934 
935   /* Restore the old cursor.  */
936   read_md_file = old_file;
937   read_md_filename = old_filename;
938   read_md_lineno = old_lineno;
939 
940   /* Do not free the pathname.  It is attached to the various rtx
941      queue elements.  */
942 }
943 
944 /* Process the current file, assuming that read_md_file and
945    read_md_filename are valid.  Use HANDLE_DIRECTIVE to handle
946    unknown directives.  */
947 
948 static void
handle_file(directive_handler_t handle_directive)949 handle_file (directive_handler_t handle_directive)
950 {
951   struct md_name directive;
952   int c, lineno;
953 
954   read_md_lineno = 1;
955   while ((c = read_skip_spaces ()) != EOF)
956     {
957       lineno = read_md_lineno;
958       if (c != '(')
959           fatal_expected_char ('(', c);
960 
961       read_name (&directive);
962       if (strcmp (directive.string, "define_constants") == 0)
963           handle_constants ();
964       else if (strcmp (directive.string, "define_enum") == 0)
965           handle_enum (lineno, true);
966       else if (strcmp (directive.string, "define_c_enum") == 0)
967           handle_enum (lineno, false);
968       else if (strcmp (directive.string, "include") == 0)
969           handle_include (lineno, handle_directive);
970       else if (handle_directive)
971           handle_directive (lineno, directive.string);
972       else
973           read_skip_construct (1, lineno);
974 
975       c = read_skip_spaces ();
976       if (c != ')')
977           fatal_expected_char (')', c);
978     }
979   fclose (read_md_file);
980 }
981 
982 /* Like handle_file, but for top-level files.  Set up in_fname and
983    base_dir accordingly.  */
984 
985 static void
handle_toplevel_file(directive_handler_t handle_directive)986 handle_toplevel_file (directive_handler_t handle_directive)
987 {
988   const char *base;
989 
990   in_fname = read_md_filename;
991   base = lbasename (in_fname);
992   if (base == in_fname)
993     base_dir = NULL;
994   else
995     base_dir = xstrndup (in_fname, base - in_fname);
996 
997   handle_file (handle_directive);
998 }
999 
1000 /* Parse a -I option with argument ARG.  */
1001 
1002 static void
parse_include(const char * arg)1003 parse_include (const char *arg)
1004 {
1005   struct file_name_list *dirtmp;
1006 
1007   dirtmp = XNEW (struct file_name_list);
1008   dirtmp->next = 0;
1009   dirtmp->fname = arg;
1010   *last_dir_md_include_ptr = dirtmp;
1011   last_dir_md_include_ptr = &dirtmp->next;
1012   if (strlen (dirtmp->fname) > max_include_len)
1013     max_include_len = strlen (dirtmp->fname);
1014 }
1015 
1016 /* The main routine for reading .md files.  Try to process all the .md
1017    files specified on the command line and return true if no error occured.
1018 
1019    ARGC and ARGV are the arguments to main.
1020 
1021    PARSE_OPT, if nonnull, is passed all unknown command-line arguments.
1022    It should return true if it recognizes the argument or false if a
1023    generic error should be reported.
1024 
1025    If HANDLE_DIRECTIVE is nonnull, the parser calls it for each
1026    unknown directive, otherwise it just skips such directives.
1027    See the comment above the directive_handler_t definition for
1028    details about the callback's interface.  */
1029 
1030 bool
read_md_files(int argc,char ** argv,bool (* parse_opt)(const char *),directive_handler_t handle_directive)1031 read_md_files (int argc, char **argv, bool (*parse_opt) (const char *),
1032                  directive_handler_t handle_directive)
1033 {
1034   int i;
1035   bool no_more_options;
1036   bool already_read_stdin;
1037   int num_files;
1038 
1039   /* Initialize global data.  */
1040   obstack_init (&string_obstack);
1041   ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1042   obstack_init (&ptr_loc_obstack);
1043   joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1044   obstack_init (&joined_conditions_obstack);
1045   md_constants = htab_create (31, leading_string_hash,
1046                                     leading_string_eq_p, (htab_del) 0);
1047   enum_types = htab_create (31, leading_string_hash,
1048                                   leading_string_eq_p, (htab_del) 0);
1049 
1050   /* Unlock the stdio streams.  */
1051   unlock_std_streams ();
1052 
1053   /* First we loop over all the options.  */
1054   for (i = 1; i < argc; i++)
1055     if (argv[i][0] == '-')
1056       {
1057           /* An argument consisting of exactly one dash is a request to
1058              read stdin.  This will be handled in the second loop.  */
1059           if (argv[i][1] == '\0')
1060             continue;
1061 
1062           /* An argument consisting of just two dashes causes option
1063              parsing to cease.  */
1064           if (argv[i][1] == '-' && argv[i][2] == '\0')
1065             break;
1066 
1067           if (argv[i][1] == 'I')
1068             {
1069               if (argv[i][2] != '\0')
1070                 parse_include (argv[i] + 2);
1071               else if (++i < argc)
1072                 parse_include (argv[i]);
1073               else
1074                 fatal ("directory name missing after -I option");
1075               continue;
1076             }
1077 
1078           /* The program may have provided a callback so it can
1079              accept its own options.  */
1080           if (parse_opt && parse_opt (argv[i]))
1081             continue;
1082 
1083           fatal ("invalid option `%s'", argv[i]);
1084       }
1085 
1086   /* Now loop over all input files.  */
1087   num_files = 0;
1088   no_more_options = false;
1089   already_read_stdin = false;
1090   for (i = 1; i < argc; i++)
1091     {
1092       if (argv[i][0] == '-')
1093           {
1094             if (argv[i][1] == '\0')
1095               {
1096                 /* Read stdin.  */
1097                 if (already_read_stdin)
1098                     fatal ("cannot read standard input twice");
1099 
1100                 read_md_file = stdin;
1101                 read_md_filename = "<stdin>";
1102                 handle_toplevel_file (handle_directive);
1103                 already_read_stdin = true;
1104                 continue;
1105               }
1106             else if (argv[i][1] == '-' && argv[i][2] == '\0')
1107               {
1108                 /* No further arguments are to be treated as options.  */
1109                 no_more_options = true;
1110                 continue;
1111               }
1112             else if (!no_more_options)
1113               continue;
1114           }
1115 
1116       /* If we get here we are looking at a non-option argument, i.e.
1117            a file to be processed.  */
1118       read_md_filename = argv[i];
1119       read_md_file = fopen (read_md_filename, "r");
1120       if (read_md_file == 0)
1121           {
1122             perror (read_md_filename);
1123             return false;
1124           }
1125       handle_toplevel_file (handle_directive);
1126       num_files++;
1127     }
1128 
1129   /* If we get to this point without having seen any files to process,
1130      read the standard input now.  */
1131   if (num_files == 0 && !already_read_stdin)
1132     {
1133       read_md_file = stdin;
1134       read_md_filename = "<stdin>";
1135       handle_toplevel_file (handle_directive);
1136     }
1137 
1138   return !have_error;
1139 }
1140