2016-09-26 François Dumont <fdumont@gcc.gnu.org>
[official-gcc.git] / gcc / read-md.c
blobf069ba5a88d4a07419be7c45939f19d192bf19e6
1 /* MD reader for GCC.
2 Copyright (C) 1987-2016 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
20 #include "bconfig.h"
21 #include "system.h"
22 #include "coretypes.h"
23 #include "errors.h"
24 #include "read-md.h"
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;
34 /* Obstack used for allocating MD strings. */
35 struct obstack string_obstack;
37 /* A table of ptr_locs, hashed on the PTR field. */
38 static htab_t ptr_locs;
40 /* An obstack for the above. Plain xmalloc is a bit heavyweight for a
41 small structure like ptr_loc. */
42 static struct obstack ptr_loc_obstack;
44 /* A hash table of triples (A, B, C), where each of A, B and C is a condition
45 and A is equivalent to "B && C". This is used to keep track of the source
46 of conditions that are made up of separate MD strings (such as the split
47 condition of a define_insn_and_split). */
48 static htab_t joined_conditions;
50 /* An obstack for allocating joined_conditions entries. */
51 static struct obstack joined_conditions_obstack;
53 /* This callback will be invoked whenever an md include directive is
54 processed. To be used for creation of the dependency file. */
55 void (*include_callback) (const char *);
57 /* Global singleton. */
59 rtx_reader *rtx_reader_ptr;
61 /* A table of md_constant structures, hashed by name. Null if no
62 constant expansion should occur. */
63 static htab_t md_constants;
65 /* A table of enum_type structures, hashed by name. */
66 static htab_t enum_types;
68 /* Given an object that starts with a char * name field, return a hash
69 code for its name. */
71 hashval_t
72 leading_string_hash (const void *def)
74 return htab_hash_string (*(const char *const *) def);
77 /* Given two objects that start with char * name fields, return true if
78 they have the same name. */
80 int
81 leading_string_eq_p (const void *def1, const void *def2)
83 return strcmp (*(const char *const *) def1,
84 *(const char *const *) def2) == 0;
87 /* Return a hash value for the pointer pointed to by DEF. */
89 static hashval_t
90 leading_ptr_hash (const void *def)
92 return htab_hash_pointer (*(const void *const *) def);
95 /* Return true if DEF1 and DEF2 are pointers to the same pointer. */
97 static int
98 leading_ptr_eq_p (const void *def1, const void *def2)
100 return *(const void *const *) def1 == *(const void *const *) def2;
103 /* Associate PTR with the file position given by FILENAME and LINENO. */
105 static void
106 set_md_ptr_loc (const void *ptr, const char *filename, int lineno)
108 struct ptr_loc *loc;
110 loc = (struct ptr_loc *) obstack_alloc (&ptr_loc_obstack,
111 sizeof (struct ptr_loc));
112 loc->ptr = ptr;
113 loc->filename = filename;
114 loc->lineno = lineno;
115 *htab_find_slot (ptr_locs, loc, INSERT) = loc;
118 /* Return the position associated with pointer PTR. Return null if no
119 position was set. */
121 static const struct ptr_loc *
122 get_md_ptr_loc (const void *ptr)
124 return (const struct ptr_loc *) htab_find (ptr_locs, &ptr);
127 /* Associate NEW_PTR with the same file position as OLD_PTR. */
129 void
130 copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
132 const struct ptr_loc *loc = get_md_ptr_loc (old_ptr);
133 if (loc != 0)
134 set_md_ptr_loc (new_ptr, loc->filename, loc->lineno);
137 /* If PTR is associated with a known file position, print a #line
138 directive for it to OUTF. */
140 void
141 fprint_md_ptr_loc (FILE *outf, const void *ptr)
143 const struct ptr_loc *loc = get_md_ptr_loc (ptr);
144 if (loc != 0)
145 fprintf (outf, "#line %d \"%s\"\n", loc->lineno, loc->filename);
148 /* Special fprint_md_ptr_loc for writing to STDOUT. */
149 void
150 print_md_ptr_loc (const void *ptr)
152 fprint_md_ptr_loc (stdout, ptr);
155 /* Return a condition that satisfies both COND1 and COND2. Either string
156 may be null or empty. */
158 const char *
159 join_c_conditions (const char *cond1, const char *cond2)
161 char *result;
162 const void **entry;
164 if (cond1 == 0 || cond1[0] == 0)
165 return cond2;
167 if (cond2 == 0 || cond2[0] == 0)
168 return cond1;
170 if (strcmp (cond1, cond2) == 0)
171 return cond1;
173 result = concat ("(", cond1, ") && (", cond2, ")", NULL);
174 obstack_ptr_grow (&joined_conditions_obstack, result);
175 obstack_ptr_grow (&joined_conditions_obstack, cond1);
176 obstack_ptr_grow (&joined_conditions_obstack, cond2);
177 entry = XOBFINISH (&joined_conditions_obstack, const void **);
178 *htab_find_slot (joined_conditions, entry, INSERT) = entry;
179 return result;
182 /* Print condition COND to OUTF, wrapped in brackets. If COND was created
183 by join_c_conditions, recursively invoke this function for the original
184 conditions and join the result with "&&". Otherwise print a #line
185 directive for COND if its original file position is known. */
187 void
188 fprint_c_condition (FILE *outf, const char *cond)
190 const char **halves = (const char **) htab_find (joined_conditions, &cond);
191 if (halves != 0)
193 fprintf (outf, "(");
194 fprint_c_condition (outf, halves[1]);
195 fprintf (outf, " && ");
196 fprint_c_condition (outf, halves[2]);
197 fprintf (outf, ")");
199 else
201 fputc ('\n', outf);
202 fprint_md_ptr_loc (outf, cond);
203 fprintf (outf, "(%s)", cond);
207 /* Special fprint_c_condition for writing to STDOUT. */
209 void
210 print_c_condition (const char *cond)
212 fprint_c_condition (stdout, cond);
215 /* A vfprintf-like function for reporting an error against line LINENO
216 of the current MD file. */
218 static void ATTRIBUTE_PRINTF(2,0)
219 message_at_1 (file_location loc, const char *msg, va_list ap)
221 fprintf (stderr, "%s:%d: ", loc.filename, loc.lineno);
222 vfprintf (stderr, msg, ap);
223 fputc ('\n', stderr);
226 /* A printf-like function for reporting a message against location LOC. */
228 void
229 message_at (file_location loc, const char *msg, ...)
231 va_list ap;
233 va_start (ap, msg);
234 message_at_1 (loc, msg, ap);
235 va_end (ap);
238 /* Like message_at, but treat the condition as an error. */
240 void
241 error_at (file_location loc, const char *msg, ...)
243 va_list ap;
245 va_start (ap, msg);
246 message_at_1 (loc, msg, ap);
247 va_end (ap);
248 have_error = 1;
251 /* Like message_at, but treat the condition as a fatal error. */
253 void
254 fatal_at (file_location loc, const char *msg, ...)
256 va_list ap;
258 va_start (ap, msg);
259 message_at_1 (loc, msg, ap);
260 va_end (ap);
261 exit (1);
264 /* A printf-like function for reporting an error against the current
265 position in the MD file. */
267 void
268 fatal_with_file_and_line (const char *msg, ...)
270 char context[64];
271 size_t i;
272 int c;
273 va_list ap;
275 va_start (ap, msg);
277 fprintf (stderr, "%s:%d: error: ", rtx_reader_ptr->get_filename (),
278 rtx_reader_ptr->get_lineno ());
279 vfprintf (stderr, msg, ap);
280 putc ('\n', stderr);
282 /* Gather some following context. */
283 for (i = 0; i < sizeof (context)-1; ++i)
285 c = read_char ();
286 if (c == EOF)
287 break;
288 if (c == '\r' || c == '\n')
290 unread_char (c);
291 break;
293 context[i] = c;
295 context[i] = '\0';
297 fprintf (stderr, "%s:%d: note: following context is `%s'\n",
298 rtx_reader_ptr->get_filename (), rtx_reader_ptr->get_lineno (),
299 context);
301 va_end (ap);
302 exit (1);
305 /* Report that we found character ACTUAL when we expected to find
306 character EXPECTED. */
308 void
309 fatal_expected_char (int expected, int actual)
311 if (actual == EOF)
312 fatal_with_file_and_line ("expected character `%c', found EOF",
313 expected);
314 else
315 fatal_with_file_and_line ("expected character `%c', found `%c'",
316 expected, actual);
319 /* Read chars from the MD file until a non-whitespace char and return that.
320 Comments, both Lisp style and C style, are treated as whitespace. */
323 read_skip_spaces (void)
325 int c;
327 while (1)
329 c = read_char ();
330 switch (c)
332 case ' ': case '\t': case '\f': case '\r': case '\n':
333 break;
335 case ';':
337 c = read_char ();
338 while (c != '\n' && c != EOF);
339 break;
341 case '/':
343 int prevc;
344 c = read_char ();
345 if (c != '*')
347 unread_char (c);
348 fatal_with_file_and_line ("stray '/' in file");
351 prevc = 0;
352 while ((c = read_char ()) && c != EOF)
354 if (prevc == '*' && c == '/')
355 break;
356 prevc = c;
359 break;
361 default:
362 return c;
367 /* Consume any whitespace, then consume the next non-whitespace
368 character, issuing a fatal error if it is not EXPECTED. */
370 void
371 require_char_ws (char expected)
373 int ch = read_skip_spaces ();
374 if (ch != expected)
375 fatal_expected_char (expected, ch);
378 /* Read the next character from the file. */
381 rtx_reader::read_char (void)
383 int ch;
385 ch = getc (m_read_md_file);
386 if (ch == '\n')
387 m_read_md_lineno++;
389 return ch;
392 /* Put back CH, which was the last character read from the file. */
394 void
395 rtx_reader::unread_char (int ch)
397 if (ch == '\n')
398 m_read_md_lineno--;
399 ungetc (ch, m_read_md_file);
402 /* Read an rtx code name into NAME. It is terminated by any of the
403 punctuation chars of rtx printed syntax. */
405 void
406 read_name (struct md_name *name)
408 int c;
409 size_t i;
410 int angle_bracket_depth;
412 c = read_skip_spaces ();
414 i = 0;
415 angle_bracket_depth = 0;
416 while (1)
418 if (c == '<')
419 angle_bracket_depth++;
421 if ((c == '>') && (angle_bracket_depth > 0))
422 angle_bracket_depth--;
424 if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r'
425 || c == EOF)
426 break;
427 if (angle_bracket_depth == 0)
429 if (c == ':' || c == ')' || c == ']'
430 || c == '"' || c == '/' || c == '(' || c == '[')
432 unread_char (c);
433 break;
437 if (i == sizeof (name->buffer) - 1)
438 fatal_with_file_and_line ("name too long");
439 name->buffer[i++] = c;
441 c = read_char ();
444 if (i == 0)
445 fatal_with_file_and_line ("missing name or number");
447 name->buffer[i] = 0;
448 name->string = name->buffer;
450 if (md_constants)
452 /* Do constant expansion. */
453 struct md_constant *def;
457 struct md_constant tmp_def;
459 tmp_def.name = name->string;
460 def = (struct md_constant *) htab_find (md_constants, &tmp_def);
461 if (def)
462 name->string = def->value;
464 while (def);
468 /* Subroutine of the string readers. Handles backslash escapes.
469 Caller has read the backslash, but not placed it into the obstack. */
471 static void
472 read_escape (void)
474 int c = read_char ();
476 switch (c)
478 /* Backslash-newline is replaced by nothing, as in C. */
479 case '\n':
480 return;
482 /* \" \' \\ are replaced by the second character. */
483 case '\\':
484 case '"':
485 case '\'':
486 break;
488 /* Standard C string escapes:
489 \a \b \f \n \r \t \v
490 \[0-7] \x
491 all are passed through to the output string unmolested.
492 In normal use these wind up in a string constant processed
493 by the C compiler, which will translate them appropriately.
494 We do not bother checking that \[0-7] are followed by up to
495 two octal digits, or that \x is followed by N hex digits.
496 \? \u \U are left out because they are not in traditional C. */
497 case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
498 case '0': case '1': case '2': case '3': case '4': case '5': case '6':
499 case '7': case 'x':
500 obstack_1grow (&string_obstack, '\\');
501 break;
503 /* \; makes stuff for a C string constant containing
504 newline and tab. */
505 case ';':
506 obstack_grow (&string_obstack, "\\n\\t", 4);
507 return;
509 /* pass anything else through, but issue a warning. */
510 default:
511 fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
512 rtx_reader_ptr->get_filename (), rtx_reader_ptr->get_lineno (),
514 obstack_1grow (&string_obstack, '\\');
515 break;
518 obstack_1grow (&string_obstack, c);
521 /* Read a double-quoted string onto the obstack. Caller has scanned
522 the leading quote. */
524 char *
525 read_quoted_string (void)
527 int c;
529 while (1)
531 c = read_char (); /* Read the string */
532 if (c == '\\')
534 read_escape ();
535 continue;
537 else if (c == '"' || c == EOF)
538 break;
540 obstack_1grow (&string_obstack, c);
543 obstack_1grow (&string_obstack, 0);
544 return XOBFINISH (&string_obstack, char *);
547 /* Read a braced string (a la Tcl) onto the string obstack. Caller
548 has scanned the leading brace. Note that unlike quoted strings,
549 the outermost braces _are_ included in the string constant. */
551 static char *
552 read_braced_string (void)
554 int c;
555 int brace_depth = 1; /* caller-processed */
556 unsigned long starting_read_md_lineno = rtx_reader_ptr->get_lineno ();
558 obstack_1grow (&string_obstack, '{');
559 while (brace_depth)
561 c = read_char (); /* Read the string */
563 if (c == '{')
564 brace_depth++;
565 else if (c == '}')
566 brace_depth--;
567 else if (c == '\\')
569 read_escape ();
570 continue;
572 else if (c == EOF)
573 fatal_with_file_and_line
574 ("missing closing } for opening brace on line %lu",
575 starting_read_md_lineno);
577 obstack_1grow (&string_obstack, c);
580 obstack_1grow (&string_obstack, 0);
581 return XOBFINISH (&string_obstack, char *);
584 /* Read some kind of string constant. This is the high-level routine
585 used by read_rtx. It handles surrounding parentheses, leading star,
586 and dispatch to the appropriate string constant reader. */
588 char *
589 read_string (int star_if_braced)
591 char *stringbuf;
592 int saw_paren = 0;
593 int c, old_lineno;
595 c = read_skip_spaces ();
596 if (c == '(')
598 saw_paren = 1;
599 c = read_skip_spaces ();
602 old_lineno = rtx_reader_ptr->get_lineno ();
603 if (c == '"')
604 stringbuf = read_quoted_string ();
605 else if (c == '{')
607 if (star_if_braced)
608 obstack_1grow (&string_obstack, '*');
609 stringbuf = read_braced_string ();
611 else
612 fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c);
614 if (saw_paren)
615 require_char_ws (')');
617 set_md_ptr_loc (stringbuf, rtx_reader_ptr->get_filename (), old_lineno);
618 return stringbuf;
621 /* Skip the rest of a construct that started at line LINENO and that
622 is currently nested by DEPTH levels of parentheses. */
624 static void
625 read_skip_construct (int depth, file_location loc)
627 struct md_name name;
628 int c;
632 c = read_skip_spaces ();
633 if (c == EOF)
635 error_at (loc, "unterminated construct");
636 exit (1);
638 switch (c)
640 case '(':
641 depth++;
642 break;
644 case ')':
645 depth--;
646 break;
648 case ':':
649 case '[':
650 case ']':
651 case '/':
652 break;
654 case '\"':
655 case '{':
656 unread_char (c);
657 read_string (false);
658 break;
660 default:
661 unread_char (c);
662 read_name (&name);
663 break;
666 while (depth > 0);
667 unread_char (c);
670 /* Given a string, return the number of comma-separated elements in it.
671 Return 0 for the null string. */
674 n_comma_elts (const char *s)
676 int n;
678 if (*s == '\0')
679 return 0;
681 for (n = 1; *s; s++)
682 if (*s == ',')
683 n++;
685 return n;
688 /* Given a pointer to a (char *), return a pointer to the beginning of the
689 next comma-separated element in the string. Advance the pointer given
690 to the end of that element. Return NULL if at end of string. Caller
691 is responsible for copying the string if necessary. White space between
692 a comma and an element is ignored. */
694 const char *
695 scan_comma_elt (const char **pstr)
697 const char *start;
698 const char *p = *pstr;
700 if (*p == ',')
701 p++;
702 while (ISSPACE (*p))
703 p++;
705 if (*p == '\0')
706 return NULL;
708 start = p;
710 while (*p != ',' && *p != '\0')
711 p++;
713 *pstr = p;
714 return start;
717 /* Convert STRING to uppercase. */
719 void
720 upcase_string (char *string)
722 int i;
724 for (i = 0; string[i]; i++)
725 string[i] = TOUPPER (string[i]);
728 /* Add a NAME = VALUE definition to md_constants-style hash table DEFS,
729 where both NAME and VALUE are malloc()ed strings. PARENT_ENUM is the
730 enum to which NAME belongs, or null if NAME is a stand-alone constant. */
732 static struct md_constant *
733 add_constant (htab_t defs, char *name, char *value,
734 struct enum_type *parent_enum)
736 struct md_constant *def, tmp_def;
737 void **entry_ptr;
739 tmp_def.name = name;
740 entry_ptr = htab_find_slot (defs, &tmp_def, INSERT);
741 if (*entry_ptr)
743 def = (struct md_constant *) *entry_ptr;
744 if (strcmp (def->value, value) != 0)
745 fatal_with_file_and_line ("redefinition of `%s', was `%s', now `%s'",
746 def->name, def->value, value);
747 else if (parent_enum || def->parent_enum)
748 fatal_with_file_and_line ("redefinition of `%s'", def->name);
749 free (name);
750 free (value);
752 else
754 def = XNEW (struct md_constant);
755 def->name = name;
756 def->value = value;
757 def->parent_enum = parent_enum;
758 *entry_ptr = def;
760 return def;
763 /* Process a define_constants directive, starting with the optional space
764 after the "define_constants". */
766 static void
767 handle_constants (void)
769 int c;
770 htab_t defs;
772 require_char_ws ('[');
774 /* Disable constant expansion during definition processing. */
775 defs = md_constants;
776 md_constants = 0;
777 while ( (c = read_skip_spaces ()) != ']')
779 struct md_name name, value;
781 if (c != '(')
782 fatal_expected_char ('(', c);
784 read_name (&name);
785 read_name (&value);
786 add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0);
788 require_char_ws (')');
790 md_constants = defs;
793 /* For every constant definition, call CALLBACK with two arguments:
794 a pointer a pointer to the constant definition and INFO.
795 Stop when CALLBACK returns zero. */
797 void
798 traverse_md_constants (htab_trav callback, void *info)
800 htab_traverse (md_constants, callback, info);
803 /* Return a malloc()ed decimal string that represents number NUMBER. */
805 static char *
806 md_decimal_string (int number)
808 /* A safe overestimate. +1 for sign, +1 for null terminator. */
809 char buffer[sizeof (int) * CHAR_BIT + 1 + 1];
811 sprintf (buffer, "%d", number);
812 return xstrdup (buffer);
815 /* Process a define_enum or define_c_enum directive, starting with
816 the optional space after the "define_enum". LINENO is the line
817 number on which the directive started and MD_P is true if the
818 directive is a define_enum rather than a define_c_enum. */
820 static void
821 handle_enum (file_location loc, bool md_p)
823 char *enum_name, *value_name;
824 struct md_name name;
825 struct enum_type *def;
826 struct enum_value *ev;
827 void **slot;
828 int c;
830 enum_name = read_string (false);
831 slot = htab_find_slot (enum_types, &enum_name, INSERT);
832 if (*slot)
834 def = (struct enum_type *) *slot;
835 if (def->md_p != md_p)
836 error_at (loc, "redefining `%s' as a different type of enum",
837 enum_name);
839 else
841 def = XNEW (struct enum_type);
842 def->name = enum_name;
843 def->md_p = md_p;
844 def->values = 0;
845 def->tail_ptr = &def->values;
846 def->num_values = 0;
847 *slot = def;
850 require_char_ws ('[');
852 while ((c = read_skip_spaces ()) != ']')
854 if (c == EOF)
856 error_at (loc, "unterminated construct");
857 exit (1);
859 unread_char (c);
860 read_name (&name);
862 ev = XNEW (struct enum_value);
863 ev->next = 0;
864 if (md_p)
866 value_name = concat (def->name, "_", name.string, NULL);
867 upcase_string (value_name);
868 ev->name = xstrdup (name.string);
870 else
872 value_name = xstrdup (name.string);
873 ev->name = value_name;
875 ev->def = add_constant (md_constants, value_name,
876 md_decimal_string (def->num_values), def);
878 *def->tail_ptr = ev;
879 def->tail_ptr = &ev->next;
880 def->num_values++;
884 /* Try to find the definition of the given enum. Return null on failure. */
886 struct enum_type *
887 lookup_enum_type (const char *name)
889 return (struct enum_type *) htab_find (enum_types, &name);
892 /* For every enum definition, call CALLBACK with two arguments:
893 a pointer to the constant definition and INFO. Stop when CALLBACK
894 returns zero. */
896 void
897 traverse_enum_types (htab_trav callback, void *info)
899 htab_traverse (enum_types, callback, info);
903 /* Constructor for rtx_reader. */
905 rtx_reader::rtx_reader ()
906 : m_toplevel_fname (NULL),
907 m_base_dir (NULL),
908 m_read_md_file (NULL),
909 m_read_md_filename (NULL),
910 m_read_md_lineno (0),
911 m_first_dir_md_include (NULL),
912 m_last_dir_md_include_ptr (&m_first_dir_md_include)
914 /* Set the global singleton pointer. */
915 rtx_reader_ptr = this;
918 /* rtx_reader's destructor. */
920 rtx_reader::~rtx_reader ()
922 /* Clear the global singleton pointer. */
923 rtx_reader_ptr = NULL;
926 /* Process an "include" directive, starting with the optional space
927 after the "include". Read in the file and use HANDLE_DIRECTIVE
928 to process each unknown directive. LINENO is the line number on
929 which the "include" occurred. */
931 void
932 rtx_reader::handle_include (file_location loc)
934 const char *filename;
935 const char *old_filename;
936 int old_lineno;
937 char *pathname;
938 FILE *input_file, *old_file;
940 filename = read_string (false);
941 input_file = NULL;
943 /* If the specified file name is absolute, skip the include stack. */
944 if (!IS_ABSOLUTE_PATH (filename))
946 struct file_name_list *stackp;
948 /* Search the directory path, trying to open the file. */
949 for (stackp = m_first_dir_md_include; stackp; stackp = stackp->next)
951 static const char sep[2] = { DIR_SEPARATOR, '\0' };
953 pathname = concat (stackp->fname, sep, filename, NULL);
954 input_file = fopen (pathname, "r");
955 if (input_file != NULL)
956 break;
957 free (pathname);
961 /* If we haven't managed to open the file yet, try combining the
962 filename with BASE_DIR. */
963 if (input_file == NULL)
965 if (m_base_dir)
966 pathname = concat (m_base_dir, filename, NULL);
967 else
968 pathname = xstrdup (filename);
969 input_file = fopen (pathname, "r");
972 if (input_file == NULL)
974 free (pathname);
975 error_at (loc, "include file `%s' not found", filename);
976 return;
979 /* Save the old cursor. Note that the LINENO argument to this
980 function is the beginning of the include statement, while
981 read_md_lineno has already been advanced. */
982 old_file = m_read_md_file;
983 old_filename = m_read_md_filename;
984 old_lineno = m_read_md_lineno;
986 if (include_callback)
987 include_callback (pathname);
989 m_read_md_file = input_file;
990 m_read_md_filename = pathname;
992 handle_file ();
994 /* Restore the old cursor. */
995 m_read_md_file = old_file;
996 m_read_md_filename = old_filename;
997 m_read_md_lineno = old_lineno;
999 /* Do not free the pathname. It is attached to the various rtx
1000 queue elements. */
1003 /* Process the current file, assuming that read_md_file and
1004 read_md_filename are valid. Use HANDLE_DIRECTIVE to handle
1005 unknown directives. */
1007 void
1008 rtx_reader::handle_file ()
1010 struct md_name directive;
1011 int c;
1013 m_read_md_lineno = 1;
1014 while ((c = read_skip_spaces ()) != EOF)
1016 file_location loc = get_current_location ();
1017 if (c != '(')
1018 fatal_expected_char ('(', c);
1020 read_name (&directive);
1021 if (strcmp (directive.string, "define_constants") == 0)
1022 handle_constants ();
1023 else if (strcmp (directive.string, "define_enum") == 0)
1024 handle_enum (loc, true);
1025 else if (strcmp (directive.string, "define_c_enum") == 0)
1026 handle_enum (loc, false);
1027 else if (strcmp (directive.string, "include") == 0)
1028 handle_include (loc);
1029 else
1030 handle_unknown_directive (loc, directive.string);
1032 require_char_ws (')');
1034 fclose (m_read_md_file);
1037 /* Like handle_file, but for top-level files. Set up m_toplevel_fname
1038 and m_base_dir accordingly. */
1040 void
1041 rtx_reader::handle_toplevel_file ()
1043 const char *base;
1045 m_toplevel_fname = m_read_md_filename;
1046 base = lbasename (m_toplevel_fname);
1047 if (base == m_toplevel_fname)
1048 m_base_dir = NULL;
1049 else
1050 m_base_dir = xstrndup (m_toplevel_fname, base - m_toplevel_fname);
1052 handle_file ();
1055 file_location
1056 rtx_reader::get_current_location () const
1058 return file_location (m_read_md_filename, m_read_md_lineno);
1061 /* Parse a -I option with argument ARG. */
1063 void
1064 rtx_reader::add_include_path (const char *arg)
1066 struct file_name_list *dirtmp;
1068 dirtmp = XNEW (struct file_name_list);
1069 dirtmp->next = 0;
1070 dirtmp->fname = arg;
1071 *m_last_dir_md_include_ptr = dirtmp;
1072 m_last_dir_md_include_ptr = &dirtmp->next;
1075 /* The main routine for reading .md files. Try to process all the .md
1076 files specified on the command line and return true if no error occurred.
1078 ARGC and ARGV are the arguments to main.
1080 PARSE_OPT, if nonnull, is passed all unknown command-line arguments.
1081 It should return true if it recognizes the argument or false if a
1082 generic error should be reported. */
1084 bool
1085 rtx_reader::read_md_files (int argc, const char **argv,
1086 bool (*parse_opt) (const char *))
1088 int i;
1089 bool no_more_options;
1090 bool already_read_stdin;
1091 int num_files;
1093 /* Initialize global data. */
1094 obstack_init (&string_obstack);
1095 ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1096 obstack_init (&ptr_loc_obstack);
1097 joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1098 obstack_init (&joined_conditions_obstack);
1099 md_constants = htab_create (31, leading_string_hash,
1100 leading_string_eq_p, (htab_del) 0);
1101 enum_types = htab_create (31, leading_string_hash,
1102 leading_string_eq_p, (htab_del) 0);
1104 /* Unlock the stdio streams. */
1105 unlock_std_streams ();
1107 /* First we loop over all the options. */
1108 for (i = 1; i < argc; i++)
1109 if (argv[i][0] == '-')
1111 /* An argument consisting of exactly one dash is a request to
1112 read stdin. This will be handled in the second loop. */
1113 if (argv[i][1] == '\0')
1114 continue;
1116 /* An argument consisting of just two dashes causes option
1117 parsing to cease. */
1118 if (argv[i][1] == '-' && argv[i][2] == '\0')
1119 break;
1121 if (argv[i][1] == 'I')
1123 if (argv[i][2] != '\0')
1124 add_include_path (argv[i] + 2);
1125 else if (++i < argc)
1126 add_include_path (argv[i]);
1127 else
1128 fatal ("directory name missing after -I option");
1129 continue;
1132 /* The program may have provided a callback so it can
1133 accept its own options. */
1134 if (parse_opt && parse_opt (argv[i]))
1135 continue;
1137 fatal ("invalid option `%s'", argv[i]);
1140 /* Now loop over all input files. */
1141 num_files = 0;
1142 no_more_options = false;
1143 already_read_stdin = false;
1144 for (i = 1; i < argc; i++)
1146 if (argv[i][0] == '-')
1148 if (argv[i][1] == '\0')
1150 /* Read stdin. */
1151 if (already_read_stdin)
1152 fatal ("cannot read standard input twice");
1154 m_read_md_file = stdin;
1155 m_read_md_filename = "<stdin>";
1156 handle_toplevel_file ();
1157 already_read_stdin = true;
1158 continue;
1160 else if (argv[i][1] == '-' && argv[i][2] == '\0')
1162 /* No further arguments are to be treated as options. */
1163 no_more_options = true;
1164 continue;
1166 else if (!no_more_options)
1167 continue;
1170 /* If we get here we are looking at a non-option argument, i.e.
1171 a file to be processed. */
1172 m_read_md_filename = argv[i];
1173 m_read_md_file = fopen (m_read_md_filename, "r");
1174 if (m_read_md_file == 0)
1176 perror (m_read_md_filename);
1177 return false;
1179 handle_toplevel_file ();
1180 num_files++;
1183 /* If we get to this point without having seen any files to process,
1184 read the standard input now. */
1185 if (num_files == 0 && !already_read_stdin)
1187 m_read_md_file = stdin;
1188 m_read_md_filename = "<stdin>";
1189 handle_toplevel_file ();
1192 return !have_error;
1195 /* class noop_reader : public rtx_reader */
1197 /* A dummy implementation which skips unknown directives. */
1198 void
1199 noop_reader::handle_unknown_directive (file_location loc, const char *)
1201 read_skip_construct (1, loc);