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