2015-06-25 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
[official-gcc.git] / gcc / read-md.c
blob4c6ddef8b6d2bab3f7f7f423c301aa33137ac59c
1 /* MD reader for GCC.
2 Copyright (C) 1987-2015 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 /* A singly-linked list of filenames. */
35 struct file_name_list {
36 struct file_name_list *next;
37 const char *fname;
40 /* Obstack used for allocating MD strings. */
41 struct obstack string_obstack;
43 /* A table of ptr_locs, hashed on the PTR field. */
44 static htab_t ptr_locs;
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;
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;
56 /* An obstack for allocating joined_conditions entries. */
57 static struct obstack joined_conditions_obstack;
59 /* The file we are reading. */
60 FILE *read_md_file;
62 /* The filename of READ_MD_FILE. */
63 const char *read_md_filename;
65 /* The current line number in READ_MD_FILE. */
66 int read_md_lineno;
68 /* The name of the toplevel file that indirectly included READ_MD_FILE. */
69 const char *in_fname;
71 /* The directory part of IN_FNAME. NULL if IN_FNAME is a bare filename. */
72 static char *base_dir;
74 /* The first directory to search. */
75 static struct file_name_list *first_dir_md_include;
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;
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 *);
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;
88 /* A table of md_constant structures, hashed by name. Null if no
89 constant expansion should occur. */
90 static htab_t md_constants;
92 /* A table of enum_type structures, hashed by name. */
93 static htab_t enum_types;
95 static void handle_file (directive_handler_t);
97 /* Given an object that starts with a char * name field, return a hash
98 code for its name. */
100 hashval_t
101 leading_string_hash (const void *def)
103 return htab_hash_string (*(const char *const *) def);
106 /* Given two objects that start with char * name fields, return true if
107 they have the same name. */
110 leading_string_eq_p (const void *def1, const void *def2)
112 return strcmp (*(const char *const *) def1,
113 *(const char *const *) def2) == 0;
116 /* Return a hash value for the pointer pointed to by DEF. */
118 static hashval_t
119 leading_ptr_hash (const void *def)
121 return htab_hash_pointer (*(const void *const *) def);
124 /* Return true if DEF1 and DEF2 are pointers to the same pointer. */
126 static int
127 leading_ptr_eq_p (const void *def1, const void *def2)
129 return *(const void *const *) def1 == *(const void *const *) def2;
132 /* Associate PTR with the file position given by FILENAME and LINENO. */
134 static void
135 set_md_ptr_loc (const void *ptr, const char *filename, int lineno)
137 struct ptr_loc *loc;
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;
147 /* Return the position associated with pointer PTR. Return null if no
148 position was set. */
150 static const struct ptr_loc *
151 get_md_ptr_loc (const void *ptr)
153 return (const struct ptr_loc *) htab_find (ptr_locs, &ptr);
156 /* Associate NEW_PTR with the same file position as OLD_PTR. */
158 void
159 copy_md_ptr_loc (const void *new_ptr, const void *old_ptr)
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);
166 /* If PTR is associated with a known file position, print a #line
167 directive for it to OUTF. */
169 void
170 fprint_md_ptr_loc (FILE *outf, const void *ptr)
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);
177 /* Special fprint_md_ptr_loc for writing to STDOUT. */
178 void
179 print_md_ptr_loc (const void *ptr)
181 fprint_md_ptr_loc (stdout, ptr);
184 /* Return a condition that satisfies both COND1 and COND2. Either string
185 may be null or empty. */
187 const char *
188 join_c_conditions (const char *cond1, const char *cond2)
190 char *result;
191 const void **entry;
193 if (cond1 == 0 || cond1[0] == 0)
194 return cond2;
196 if (cond2 == 0 || cond2[0] == 0)
197 return cond1;
199 if (strcmp (cond1, cond2) == 0)
200 return cond1;
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;
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. */
216 void
217 fprint_c_condition (FILE *outf, const char *cond)
219 const char **halves = (const char **) htab_find (joined_conditions, &cond);
220 if (halves != 0)
222 fprintf (outf, "(");
223 fprint_c_condition (outf, halves[1]);
224 fprintf (outf, " && ");
225 fprint_c_condition (outf, halves[2]);
226 fprintf (outf, ")");
228 else
230 fputc ('\n', outf);
231 fprint_md_ptr_loc (outf, cond);
232 fprintf (outf, "(%s)", cond);
236 /* Special fprint_c_condition for writing to STDOUT. */
238 void
239 print_c_condition (const char *cond)
241 fprint_c_condition (stdout, cond);
244 /* A vfprintf-like function for reporting an error against line LINENO
245 of the current MD file. */
247 static void ATTRIBUTE_PRINTF(2,0)
248 message_with_line_1 (int lineno, const char *msg, va_list ap)
250 fprintf (stderr, "%s:%d: ", read_md_filename, lineno);
251 vfprintf (stderr, msg, ap);
252 fputc ('\n', stderr);
255 /* A printf-like function for reporting an error against line LINENO
256 in the current MD file. */
258 void
259 message_with_line (int lineno, const char *msg, ...)
261 va_list ap;
263 va_start (ap, msg);
264 message_with_line_1 (lineno, msg, ap);
265 va_end (ap);
268 /* Like message_with_line, but treat the condition as an error. */
270 void
271 error_with_line (int lineno, const char *msg, ...)
273 va_list ap;
275 va_start (ap, msg);
276 message_with_line_1 (lineno, msg, ap);
277 va_end (ap);
278 have_error = 1;
281 /* A printf-like function for reporting an error against the current
282 position in the MD file. */
284 void
285 fatal_with_file_and_line (const char *msg, ...)
287 char context[64];
288 size_t i;
289 int c;
290 va_list ap;
292 va_start (ap, msg);
294 fprintf (stderr, "%s:%d: ", read_md_filename, read_md_lineno);
295 vfprintf (stderr, msg, ap);
296 putc ('\n', stderr);
298 /* Gather some following context. */
299 for (i = 0; i < sizeof (context)-1; ++i)
301 c = read_char ();
302 if (c == EOF)
303 break;
304 if (c == '\r' || c == '\n')
306 unread_char (c);
307 break;
309 context[i] = c;
311 context[i] = '\0';
313 fprintf (stderr, "%s:%d: following context is `%s'\n",
314 read_md_filename, read_md_lineno, context);
316 va_end (ap);
317 exit (1);
320 /* Report that we found character ACTUAL when we expected to find
321 character EXPECTED. */
323 void
324 fatal_expected_char (int expected, int actual)
326 if (actual == EOF)
327 fatal_with_file_and_line ("expected character `%c', found EOF",
328 expected);
329 else
330 fatal_with_file_and_line ("expected character `%c', found `%c'",
331 expected, actual);
334 /* Read chars from the MD file until a non-whitespace char and return that.
335 Comments, both Lisp style and C style, are treated as whitespace. */
338 read_skip_spaces (void)
340 int c;
342 while (1)
344 c = read_char ();
345 switch (c)
347 case ' ': case '\t': case '\f': case '\r': case '\n':
348 break;
350 case ';':
352 c = read_char ();
353 while (c != '\n' && c != EOF);
354 break;
356 case '/':
358 int prevc;
359 c = read_char ();
360 if (c != '*')
362 unread_char (c);
363 fatal_with_file_and_line ("stray '/' in file");
366 prevc = 0;
367 while ((c = read_char ()) && c != EOF)
369 if (prevc == '*' && c == '/')
370 break;
371 prevc = c;
374 break;
376 default:
377 return c;
382 /* Read an rtx code name into NAME. It is terminated by any of the
383 punctuation chars of rtx printed syntax. */
385 void
386 read_name (struct md_name *name)
388 int c;
389 size_t i;
391 c = read_skip_spaces ();
393 i = 0;
394 while (1)
396 if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r'
397 || c == EOF)
398 break;
399 if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
400 || c == '(' || c == '[')
402 unread_char (c);
403 break;
406 if (i == sizeof (name->buffer) - 1)
407 fatal_with_file_and_line ("name too long");
408 name->buffer[i++] = c;
410 c = read_char ();
413 if (i == 0)
414 fatal_with_file_and_line ("missing name or number");
416 name->buffer[i] = 0;
417 name->string = name->buffer;
419 if (md_constants)
421 /* Do constant expansion. */
422 struct md_constant *def;
426 struct md_constant tmp_def;
428 tmp_def.name = name->string;
429 def = (struct md_constant *) htab_find (md_constants, &tmp_def);
430 if (def)
431 name->string = def->value;
433 while (def);
437 /* Subroutine of the string readers. Handles backslash escapes.
438 Caller has read the backslash, but not placed it into the obstack. */
440 static void
441 read_escape (void)
443 int c = read_char ();
445 switch (c)
447 /* Backslash-newline is replaced by nothing, as in C. */
448 case '\n':
449 return;
451 /* \" \' \\ are replaced by the second character. */
452 case '\\':
453 case '"':
454 case '\'':
455 break;
457 /* Standard C string escapes:
458 \a \b \f \n \r \t \v
459 \[0-7] \x
460 all are passed through to the output string unmolested.
461 In normal use these wind up in a string constant processed
462 by the C compiler, which will translate them appropriately.
463 We do not bother checking that \[0-7] are followed by up to
464 two octal digits, or that \x is followed by N hex digits.
465 \? \u \U are left out because they are not in traditional C. */
466 case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
467 case '0': case '1': case '2': case '3': case '4': case '5': case '6':
468 case '7': case 'x':
469 obstack_1grow (&string_obstack, '\\');
470 break;
472 /* \; makes stuff for a C string constant containing
473 newline and tab. */
474 case ';':
475 obstack_grow (&string_obstack, "\\n\\t", 4);
476 return;
478 /* pass anything else through, but issue a warning. */
479 default:
480 fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
481 read_md_filename, read_md_lineno, c);
482 obstack_1grow (&string_obstack, '\\');
483 break;
486 obstack_1grow (&string_obstack, c);
489 /* Read a double-quoted string onto the obstack. Caller has scanned
490 the leading quote. */
492 char *
493 read_quoted_string (void)
495 int c;
497 while (1)
499 c = read_char (); /* Read the string */
500 if (c == '\\')
502 read_escape ();
503 continue;
505 else if (c == '"' || c == EOF)
506 break;
508 obstack_1grow (&string_obstack, c);
511 obstack_1grow (&string_obstack, 0);
512 return XOBFINISH (&string_obstack, char *);
515 /* Read a braced string (a la Tcl) onto the string obstack. Caller
516 has scanned the leading brace. Note that unlike quoted strings,
517 the outermost braces _are_ included in the string constant. */
519 static char *
520 read_braced_string (void)
522 int c;
523 int brace_depth = 1; /* caller-processed */
524 unsigned long starting_read_md_lineno = read_md_lineno;
526 obstack_1grow (&string_obstack, '{');
527 while (brace_depth)
529 c = read_char (); /* Read the string */
531 if (c == '{')
532 brace_depth++;
533 else if (c == '}')
534 brace_depth--;
535 else if (c == '\\')
537 read_escape ();
538 continue;
540 else if (c == EOF)
541 fatal_with_file_and_line
542 ("missing closing } for opening brace on line %lu",
543 starting_read_md_lineno);
545 obstack_1grow (&string_obstack, c);
548 obstack_1grow (&string_obstack, 0);
549 return XOBFINISH (&string_obstack, char *);
552 /* Read some kind of string constant. This is the high-level routine
553 used by read_rtx. It handles surrounding parentheses, leading star,
554 and dispatch to the appropriate string constant reader. */
556 char *
557 read_string (int star_if_braced)
559 char *stringbuf;
560 int saw_paren = 0;
561 int c, old_lineno;
563 c = read_skip_spaces ();
564 if (c == '(')
566 saw_paren = 1;
567 c = read_skip_spaces ();
570 old_lineno = read_md_lineno;
571 if (c == '"')
572 stringbuf = read_quoted_string ();
573 else if (c == '{')
575 if (star_if_braced)
576 obstack_1grow (&string_obstack, '*');
577 stringbuf = read_braced_string ();
579 else
580 fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c);
582 if (saw_paren)
584 c = read_skip_spaces ();
585 if (c != ')')
586 fatal_expected_char (')', c);
589 set_md_ptr_loc (stringbuf, read_md_filename, old_lineno);
590 return stringbuf;
593 /* Skip the rest of a construct that started at line LINENO and that
594 is currently nested by DEPTH levels of parentheses. */
596 void
597 read_skip_construct (int depth, int lineno)
599 struct md_name name;
600 int c;
604 c = read_skip_spaces ();
605 if (c == EOF)
607 error_with_line (lineno, "unterminated construct");
608 exit (1);
610 switch (c)
612 case '(':
613 depth++;
614 break;
616 case ')':
617 depth--;
618 break;
620 case ':':
621 case '[':
622 case ']':
623 case '/':
624 break;
626 case '\"':
627 case '{':
628 unread_char (c);
629 read_string (false);
630 break;
632 default:
633 unread_char (c);
634 read_name (&name);
635 break;
638 while (depth > 0);
639 unread_char (c);
642 /* Given a string, return the number of comma-separated elements in it.
643 Return 0 for the null string. */
646 n_comma_elts (const char *s)
648 int n;
650 if (*s == '\0')
651 return 0;
653 for (n = 1; *s; s++)
654 if (*s == ',')
655 n++;
657 return n;
660 /* Given a pointer to a (char *), return a pointer to the beginning of the
661 next comma-separated element in the string. Advance the pointer given
662 to the end of that element. Return NULL if at end of string. Caller
663 is responsible for copying the string if necessary. White space between
664 a comma and an element is ignored. */
666 const char *
667 scan_comma_elt (const char **pstr)
669 const char *start;
670 const char *p = *pstr;
672 if (*p == ',')
673 p++;
674 while (ISSPACE (*p))
675 p++;
677 if (*p == '\0')
678 return NULL;
680 start = p;
682 while (*p != ',' && *p != '\0')
683 p++;
685 *pstr = p;
686 return start;
689 /* Convert STRING to uppercase. */
691 void
692 upcase_string (char *string)
694 int i;
696 for (i = 0; string[i]; i++)
697 string[i] = TOUPPER (string[i]);
700 /* Add a NAME = VALUE definition to md_constants-style hash table DEFS,
701 where both NAME and VALUE are malloc()ed strings. PARENT_ENUM is the
702 enum to which NAME belongs, or null if NAME is a stand-alone constant. */
704 static struct md_constant *
705 add_constant (htab_t defs, char *name, char *value,
706 struct enum_type *parent_enum)
708 struct md_constant *def, tmp_def;
709 void **entry_ptr;
711 tmp_def.name = name;
712 entry_ptr = htab_find_slot (defs, &tmp_def, INSERT);
713 if (*entry_ptr)
715 def = (struct md_constant *) *entry_ptr;
716 if (strcmp (def->value, value) != 0)
717 fatal_with_file_and_line ("redefinition of `%s', was `%s', now `%s'",
718 def->name, def->value, value);
719 else if (parent_enum || def->parent_enum)
720 fatal_with_file_and_line ("redefinition of `%s'", def->name);
721 free (name);
722 free (value);
724 else
726 def = XNEW (struct md_constant);
727 def->name = name;
728 def->value = value;
729 def->parent_enum = parent_enum;
730 *entry_ptr = def;
732 return def;
735 /* Process a define_constants directive, starting with the optional space
736 after the "define_constants". */
738 static void
739 handle_constants (void)
741 int c;
742 htab_t defs;
744 c = read_skip_spaces ();
745 if (c != '[')
746 fatal_expected_char ('[', c);
748 /* Disable constant expansion during definition processing. */
749 defs = md_constants;
750 md_constants = 0;
751 while ( (c = read_skip_spaces ()) != ']')
753 struct md_name name, value;
755 if (c != '(')
756 fatal_expected_char ('(', c);
758 read_name (&name);
759 read_name (&value);
760 add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0);
762 c = read_skip_spaces ();
763 if (c != ')')
764 fatal_expected_char (')', c);
766 md_constants = defs;
769 /* For every constant definition, call CALLBACK with two arguments:
770 a pointer a pointer to the constant definition and INFO.
771 Stop when CALLBACK returns zero. */
773 void
774 traverse_md_constants (htab_trav callback, void *info)
776 htab_traverse (md_constants, callback, info);
779 /* Return a malloc()ed decimal string that represents number NUMBER. */
781 static char *
782 decimal_string (int number)
784 /* A safe overestimate. +1 for sign, +1 for null terminator. */
785 char buffer[sizeof (int) * CHAR_BIT + 1 + 1];
787 sprintf (buffer, "%d", number);
788 return xstrdup (buffer);
791 /* Process a define_enum or define_c_enum directive, starting with
792 the optional space after the "define_enum". LINENO is the line
793 number on which the directive started and MD_P is true if the
794 directive is a define_enum rather than a define_c_enum. */
796 static void
797 handle_enum (int lineno, bool md_p)
799 char *enum_name, *value_name;
800 struct md_name name;
801 struct enum_type *def;
802 struct enum_value *ev;
803 void **slot;
804 int c;
806 enum_name = read_string (false);
807 slot = htab_find_slot (enum_types, &enum_name, INSERT);
808 if (*slot)
810 def = (struct enum_type *) *slot;
811 if (def->md_p != md_p)
812 error_with_line (lineno, "redefining `%s' as a different type of enum",
813 enum_name);
815 else
817 def = XNEW (struct enum_type);
818 def->name = enum_name;
819 def->md_p = md_p;
820 def->values = 0;
821 def->tail_ptr = &def->values;
822 def->num_values = 0;
823 *slot = def;
826 c = read_skip_spaces ();
827 if (c != '[')
828 fatal_expected_char ('[', c);
830 while ((c = read_skip_spaces ()) != ']')
832 if (c == EOF)
834 error_with_line (lineno, "unterminated construct");
835 exit (1);
837 unread_char (c);
838 read_name (&name);
840 ev = XNEW (struct enum_value);
841 ev->next = 0;
842 if (md_p)
844 value_name = concat (def->name, "_", name.string, NULL);
845 upcase_string (value_name);
846 ev->name = xstrdup (name.string);
848 else
850 value_name = xstrdup (name.string);
851 ev->name = value_name;
853 ev->def = add_constant (md_constants, value_name,
854 decimal_string (def->num_values), def);
856 *def->tail_ptr = ev;
857 def->tail_ptr = &ev->next;
858 def->num_values++;
862 /* Try to find the definition of the given enum. Return null on failure. */
864 struct enum_type *
865 lookup_enum_type (const char *name)
867 return (struct enum_type *) htab_find (enum_types, &name);
870 /* For every enum definition, call CALLBACK with two arguments:
871 a pointer to the constant definition and INFO. Stop when CALLBACK
872 returns zero. */
874 void
875 traverse_enum_types (htab_trav callback, void *info)
877 htab_traverse (enum_types, callback, info);
880 /* Process an "include" directive, starting with the optional space
881 after the "include". Read in the file and use HANDLE_DIRECTIVE
882 to process each unknown directive. LINENO is the line number on
883 which the "include" occurred. */
885 static void
886 handle_include (int lineno, directive_handler_t handle_directive)
888 const char *filename;
889 const char *old_filename;
890 int old_lineno;
891 char *pathname;
892 FILE *input_file, *old_file;
894 filename = read_string (false);
895 input_file = NULL;
897 /* If the specified file name is absolute, skip the include stack. */
898 if (!IS_ABSOLUTE_PATH (filename))
900 struct file_name_list *stackp;
902 /* Search the directory path, trying to open the file. */
903 for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
905 static const char sep[2] = { DIR_SEPARATOR, '\0' };
907 pathname = concat (stackp->fname, sep, filename, NULL);
908 input_file = fopen (pathname, "r");
909 if (input_file != NULL)
910 break;
911 free (pathname);
915 /* If we haven't managed to open the file yet, try combining the
916 filename with BASE_DIR. */
917 if (input_file == NULL)
919 if (base_dir)
920 pathname = concat (base_dir, filename, NULL);
921 else
922 pathname = xstrdup (filename);
923 input_file = fopen (pathname, "r");
926 if (input_file == NULL)
928 free (pathname);
929 error_with_line (lineno, "include file `%s' not found", filename);
930 return;
933 /* Save the old cursor. Note that the LINENO argument to this
934 function is the beginning of the include statement, while
935 read_md_lineno has already been advanced. */
936 old_file = read_md_file;
937 old_filename = read_md_filename;
938 old_lineno = read_md_lineno;
940 if (include_callback)
941 include_callback (pathname);
943 read_md_file = input_file;
944 read_md_filename = pathname;
945 handle_file (handle_directive);
947 /* Restore the old cursor. */
948 read_md_file = old_file;
949 read_md_filename = old_filename;
950 read_md_lineno = old_lineno;
952 /* Do not free the pathname. It is attached to the various rtx
953 queue elements. */
956 /* Process the current file, assuming that read_md_file and
957 read_md_filename are valid. Use HANDLE_DIRECTIVE to handle
958 unknown directives. */
960 static void
961 handle_file (directive_handler_t handle_directive)
963 struct md_name directive;
964 int c, lineno;
966 read_md_lineno = 1;
967 while ((c = read_skip_spaces ()) != EOF)
969 lineno = read_md_lineno;
970 if (c != '(')
971 fatal_expected_char ('(', c);
973 read_name (&directive);
974 if (strcmp (directive.string, "define_constants") == 0)
975 handle_constants ();
976 else if (strcmp (directive.string, "define_enum") == 0)
977 handle_enum (lineno, true);
978 else if (strcmp (directive.string, "define_c_enum") == 0)
979 handle_enum (lineno, false);
980 else if (strcmp (directive.string, "include") == 0)
981 handle_include (lineno, handle_directive);
982 else if (handle_directive)
983 handle_directive (lineno, directive.string);
984 else
985 read_skip_construct (1, lineno);
987 c = read_skip_spaces ();
988 if (c != ')')
989 fatal_expected_char (')', c);
991 fclose (read_md_file);
994 /* Like handle_file, but for top-level files. Set up in_fname and
995 base_dir accordingly. */
997 static void
998 handle_toplevel_file (directive_handler_t handle_directive)
1000 const char *base;
1002 in_fname = read_md_filename;
1003 base = lbasename (in_fname);
1004 if (base == in_fname)
1005 base_dir = NULL;
1006 else
1007 base_dir = xstrndup (in_fname, base - in_fname);
1009 handle_file (handle_directive);
1012 /* Parse a -I option with argument ARG. */
1014 static void
1015 parse_include (const char *arg)
1017 struct file_name_list *dirtmp;
1019 dirtmp = XNEW (struct file_name_list);
1020 dirtmp->next = 0;
1021 dirtmp->fname = arg;
1022 *last_dir_md_include_ptr = dirtmp;
1023 last_dir_md_include_ptr = &dirtmp->next;
1024 if (strlen (dirtmp->fname) > max_include_len)
1025 max_include_len = strlen (dirtmp->fname);
1028 /* The main routine for reading .md files. Try to process all the .md
1029 files specified on the command line and return true if no error occurred.
1031 ARGC and ARGV are the arguments to main.
1033 PARSE_OPT, if nonnull, is passed all unknown command-line arguments.
1034 It should return true if it recognizes the argument or false if a
1035 generic error should be reported.
1037 If HANDLE_DIRECTIVE is nonnull, the parser calls it for each
1038 unknown directive, otherwise it just skips such directives.
1039 See the comment above the directive_handler_t definition for
1040 details about the callback's interface. */
1042 bool
1043 read_md_files (int argc, char **argv, bool (*parse_opt) (const char *),
1044 directive_handler_t handle_directive)
1046 int i;
1047 bool no_more_options;
1048 bool already_read_stdin;
1049 int num_files;
1051 /* Initialize global data. */
1052 obstack_init (&string_obstack);
1053 ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1054 obstack_init (&ptr_loc_obstack);
1055 joined_conditions = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1056 obstack_init (&joined_conditions_obstack);
1057 md_constants = htab_create (31, leading_string_hash,
1058 leading_string_eq_p, (htab_del) 0);
1059 enum_types = htab_create (31, leading_string_hash,
1060 leading_string_eq_p, (htab_del) 0);
1062 /* Unlock the stdio streams. */
1063 unlock_std_streams ();
1065 /* First we loop over all the options. */
1066 for (i = 1; i < argc; i++)
1067 if (argv[i][0] == '-')
1069 /* An argument consisting of exactly one dash is a request to
1070 read stdin. This will be handled in the second loop. */
1071 if (argv[i][1] == '\0')
1072 continue;
1074 /* An argument consisting of just two dashes causes option
1075 parsing to cease. */
1076 if (argv[i][1] == '-' && argv[i][2] == '\0')
1077 break;
1079 if (argv[i][1] == 'I')
1081 if (argv[i][2] != '\0')
1082 parse_include (argv[i] + 2);
1083 else if (++i < argc)
1084 parse_include (argv[i]);
1085 else
1086 fatal ("directory name missing after -I option");
1087 continue;
1090 /* The program may have provided a callback so it can
1091 accept its own options. */
1092 if (parse_opt && parse_opt (argv[i]))
1093 continue;
1095 fatal ("invalid option `%s'", argv[i]);
1098 /* Now loop over all input files. */
1099 num_files = 0;
1100 no_more_options = false;
1101 already_read_stdin = false;
1102 for (i = 1; i < argc; i++)
1104 if (argv[i][0] == '-')
1106 if (argv[i][1] == '\0')
1108 /* Read stdin. */
1109 if (already_read_stdin)
1110 fatal ("cannot read standard input twice");
1112 read_md_file = stdin;
1113 read_md_filename = "<stdin>";
1114 handle_toplevel_file (handle_directive);
1115 already_read_stdin = true;
1116 continue;
1118 else if (argv[i][1] == '-' && argv[i][2] == '\0')
1120 /* No further arguments are to be treated as options. */
1121 no_more_options = true;
1122 continue;
1124 else if (!no_more_options)
1125 continue;
1128 /* If we get here we are looking at a non-option argument, i.e.
1129 a file to be processed. */
1130 read_md_filename = argv[i];
1131 read_md_file = fopen (read_md_filename, "r");
1132 if (read_md_file == 0)
1134 perror (read_md_filename);
1135 return false;
1137 handle_toplevel_file (handle_directive);
1138 num_files++;
1141 /* If we get to this point without having seen any files to process,
1142 read the standard input now. */
1143 if (num_files == 0 && !already_read_stdin)
1145 read_md_file = stdin;
1146 read_md_filename = "<stdin>";
1147 handle_toplevel_file (handle_directive);
1150 return !have_error;