2 Copyright (C) 1987-2023 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
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
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 /* This file is compiled twice: once for the generator programs
21 once for the compiler. */
28 #include "coretypes.h"
31 #endif /* #ifdef GENERATOR_FILE */
32 #include "statistics.h"
36 #ifndef GENERATOR_FILE
38 /* Minimal reimplementation of errors.cc for use by RTL frontend
43 #endif /* #ifndef GENERATOR_FILE */
46 /* This callback will be invoked whenever an md include directive is
47 processed. To be used for creation of the dependency file. */
48 void (*include_callback
) (const char *);
50 /* Global singleton. */
52 md_reader
*md_reader_ptr
;
54 /* Given an object that starts with a char * name field, return a hash
58 leading_string_hash (const void *def
)
60 return htab_hash_string (*(const char *const *) def
);
63 /* Given two objects that start with char * name fields, return true if
64 they have the same name. */
67 leading_string_eq_p (const void *def1
, const void *def2
)
69 return strcmp (*(const char *const *) def1
,
70 *(const char *const *) def2
) == 0;
73 /* Return a hash value for the pointer pointed to by DEF. */
76 leading_ptr_hash (const void *def
)
78 return htab_hash_pointer (*(const void *const *) def
);
81 /* Return true if DEF1 and DEF2 are pointers to the same pointer. */
84 leading_ptr_eq_p (const void *def1
, const void *def2
)
86 return *(const void *const *) def1
== *(const void *const *) def2
;
89 /* Associate PTR with the file position given by FILE_LOC. */
92 md_reader::set_md_ptr_loc (const void *ptr
, file_location file_loc
)
96 loc
= (struct ptr_loc
*) obstack_alloc (&m_ptr_loc_obstack
,
97 sizeof (struct ptr_loc
));
100 *htab_find_slot (m_ptr_locs
, loc
, INSERT
) = loc
;
103 /* Return the position associated with pointer PTR. Return null if no
106 const md_reader::ptr_loc
*
107 md_reader::get_md_ptr_loc (const void *ptr
)
109 return (const struct ptr_loc
*) htab_find (m_ptr_locs
, &ptr
);
112 /* Associate NEW_PTR with the same file position as OLD_PTR. */
115 md_reader::copy_md_ptr_loc (const void *new_ptr
, const void *old_ptr
)
117 const struct ptr_loc
*loc
= get_md_ptr_loc (old_ptr
);
119 set_md_ptr_loc (new_ptr
, loc
->loc
);
122 /* If PTR is associated with a known file position, print a #line
123 directive for it to OUTF. */
126 md_reader::fprint_md_ptr_loc (FILE *outf
, const void *ptr
)
128 const struct ptr_loc
*loc
= get_md_ptr_loc (ptr
);
130 fprintf (outf
, "#line %d \"%s\"\n", loc
->loc
.lineno
, loc
->loc
.filename
);
133 /* Special fprint_md_ptr_loc for writing to STDOUT. */
135 md_reader::print_md_ptr_loc (const void *ptr
, FILE *file
)
137 fprint_md_ptr_loc (file
, ptr
);
140 /* Return a condition that satisfies both COND1 and COND2. Either string
141 may be null or empty. */
144 md_reader::join_c_conditions (const char *cond1
, const char *cond2
)
149 if (cond1
== 0 || cond1
[0] == 0)
152 if (cond2
== 0 || cond2
[0] == 0)
155 if (strcmp (cond1
, cond2
) == 0)
158 result
= concat ("(", cond1
, ") && (", cond2
, ")", NULL
);
159 obstack_ptr_grow (&m_joined_conditions_obstack
, result
);
160 obstack_ptr_grow (&m_joined_conditions_obstack
, cond1
);
161 obstack_ptr_grow (&m_joined_conditions_obstack
, cond2
);
162 entry
= XOBFINISH (&m_joined_conditions_obstack
, const void **);
163 *htab_find_slot (m_joined_conditions
, entry
, INSERT
) = entry
;
167 /* Print condition COND to OUTF, wrapped in brackets. If COND was created
168 by join_c_conditions, recursively invoke this function for the original
169 conditions and join the result with "&&". Otherwise print a #line
170 directive for COND if its original file position is known. */
173 md_reader::fprint_c_condition (FILE *outf
, const char *cond
)
175 const char **halves
= (const char **) htab_find (m_joined_conditions
, &cond
);
179 fprint_c_condition (outf
, halves
[1]);
180 fprintf (outf
, " && ");
181 fprint_c_condition (outf
, halves
[2]);
187 fprint_md_ptr_loc (outf
, cond
);
188 fprintf (outf
, "(%s)", cond
);
192 /* Special fprint_c_condition for writing to STDOUT. */
195 md_reader::print_c_condition (const char *cond
)
197 fprint_c_condition (stdout
, cond
);
200 /* A vfprintf-like function for reporting an error against line LINENO
201 of the current MD file. */
203 static void ATTRIBUTE_PRINTF(2,0)
204 message_at_1 (file_location loc
, const char *msg
, va_list ap
)
206 fprintf (stderr
, "%s:%d:%d: ", loc
.filename
, loc
.lineno
, loc
.colno
);
207 vfprintf (stderr
, msg
, ap
);
208 fputc ('\n', stderr
);
211 /* A printf-like function for reporting a message against location LOC. */
214 message_at (file_location loc
, const char *msg
, ...)
219 message_at_1 (loc
, msg
, ap
);
223 /* Like message_at, but treat the condition as an error. */
226 error_at (file_location loc
, const char *msg
, ...)
231 message_at_1 (loc
, msg
, ap
);
236 /* Like message_at, but treat the condition as a fatal error. */
239 fatal_at (file_location loc
, const char *msg
, ...)
244 message_at_1 (loc
, msg
, ap
);
249 /* A printf-like function for reporting an error against the current
250 position in the MD file. */
253 fatal_with_file_and_line (const char *msg
, ...)
262 fprintf (stderr
, "%s:%d:%d: error: ", md_reader_ptr
->get_filename (),
263 md_reader_ptr
->get_lineno (),
264 md_reader_ptr
->get_colno ());
265 vfprintf (stderr
, msg
, ap
);
268 /* Gather some following context. */
269 for (i
= 0; i
< sizeof (context
)-1; ++i
)
274 if (c
== '\r' || c
== '\n')
283 fprintf (stderr
, "%s:%d:%d: note: following context is `%s'\n",
284 md_reader_ptr
->get_filename (),
285 md_reader_ptr
->get_lineno (),
286 md_reader_ptr
->get_colno (), context
);
292 /* Report that we found character ACTUAL when we expected to find
293 character EXPECTED. */
296 fatal_expected_char (int expected
, int actual
)
299 fatal_with_file_and_line ("expected character `%c', found EOF",
302 fatal_with_file_and_line ("expected character `%c', found `%c'",
306 /* Read chars from the MD file until a non-whitespace char and return that.
307 Comments, both Lisp style and C style, are treated as whitespace. */
310 read_skip_spaces (void)
319 case ' ': case '\t': case '\f': case '\r': case '\n':
325 while (c
!= '\n' && c
!= EOF
);
335 fatal_with_file_and_line ("stray '/' in file");
339 while ((c
= read_char ()) && c
!= EOF
)
341 if (prevc
== '*' && c
== '/')
354 /* Consume the next character, issuing a fatal error if it is not
358 md_reader::require_char (char expected
)
360 int ch
= read_char ();
362 fatal_expected_char (expected
, ch
);
365 /* Consume any whitespace, then consume the next non-whitespace
366 character, issuing a fatal error if it is not EXPECTED. */
369 md_reader::require_char_ws (char expected
)
371 int ch
= read_skip_spaces ();
373 fatal_expected_char (expected
, ch
);
376 /* Consume any whitespace, then consume the next word (as per read_name),
377 issuing a fatal error if it is not EXPECTED. */
380 md_reader::require_word_ws (const char *expected
)
384 if (strcmp (name
.string
, expected
))
385 fatal_with_file_and_line ("missing '%s'", expected
);
388 /* Read the next character from the file. */
391 md_reader::read_char (void)
395 ch
= getc (m_read_md_file
);
399 m_last_line_colno
= m_read_md_colno
;
405 /* If we're filtering lines, treat everything before the range of
406 interest as a space, and as EOF for everything after. */
407 if (m_first_line
&& m_last_line
)
409 if (m_read_md_lineno
< m_first_line
)
411 if (m_read_md_lineno
> m_last_line
)
418 /* Put back CH, which was the last character read from the file. */
421 md_reader::unread_char (int ch
)
426 m_read_md_colno
= m_last_line_colno
;
430 ungetc (ch
, m_read_md_file
);
433 /* Peek at the next character from the file without consuming it. */
436 md_reader::peek_char (void)
438 int ch
= read_char ();
443 /* Read an rtx code name into NAME. It is terminated by any of the
444 punctuation chars of rtx printed syntax. */
447 md_reader::read_name_1 (struct md_name
*name
, file_location
*out_loc
)
451 int angle_bracket_depth
;
453 c
= read_skip_spaces ();
455 *out_loc
= get_current_location ();
458 angle_bracket_depth
= 0;
462 angle_bracket_depth
++;
464 if ((c
== '>') && (angle_bracket_depth
> 0))
465 angle_bracket_depth
--;
467 if (c
== ' ' || c
== '\n' || c
== '\t' || c
== '\f' || c
== '\r'
470 if (angle_bracket_depth
== 0)
472 if (c
== ':' || c
== ')' || c
== ']'
473 || c
== '"' || c
== '/' || c
== '(' || c
== '[')
480 if (i
== sizeof (name
->buffer
) - 1)
481 fatal_with_file_and_line ("name too long");
482 name
->buffer
[i
++] = c
;
491 name
->string
= name
->buffer
;
495 /* Do constant expansion. */
496 struct md_constant
*def
;
500 struct md_constant tmp_def
;
502 tmp_def
.name
= name
->string
;
503 def
= (struct md_constant
*) htab_find (m_md_constants
, &tmp_def
);
505 name
->string
= def
->value
;
513 /* Read an rtx code name into NAME. It is terminated by any of the
514 punctuation chars of rtx printed syntax. */
517 md_reader::read_name (struct md_name
*name
)
520 if (!read_name_1 (name
, &loc
))
521 fatal_with_file_and_line ("missing name or number");
526 md_reader::read_name_or_nil (struct md_name
*name
)
529 if (!read_name_1 (name
, &loc
))
531 file_location loc
= get_current_location ();
532 read_skip_construct (0, loc
);
536 name
->string
= name
->buffer
;
541 /* Subroutine of the string readers. Handles backslash escapes.
542 Caller has read the backslash, but not placed it into the obstack. */
545 md_reader::read_escape ()
547 int c
= read_char ();
551 /* Backslash-newline is replaced by nothing, as in C. */
555 /* \" \' \\ are replaced by the second character. */
561 /* Standard C string escapes:
564 all are passed through to the output string unmolested.
565 In normal use these wind up in a string constant processed
566 by the C compiler, which will translate them appropriately.
567 We do not bother checking that \[0-7] are followed by up to
568 two octal digits, or that \x is followed by N hex digits.
569 \? \u \U are left out because they are not in traditional C. */
570 case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
571 case '0': case '1': case '2': case '3': case '4': case '5': case '6':
573 obstack_1grow (&m_string_obstack
, '\\');
576 /* \; makes stuff for a C string constant containing
579 obstack_grow (&m_string_obstack
, "\\n\\t", 4);
582 /* pass anything else through, but issue a warning. */
584 fprintf (stderr
, "%s:%d: warning: unrecognized escape \\%c\n",
585 get_filename (), get_lineno (),
587 obstack_1grow (&m_string_obstack
, '\\');
591 obstack_1grow (&m_string_obstack
, c
);
594 /* Read a double-quoted string onto the obstack. Caller has scanned
595 the leading quote. */
598 md_reader::read_quoted_string ()
604 c
= read_char (); /* Read the string */
610 else if (c
== '"' || c
== EOF
)
613 obstack_1grow (&m_string_obstack
, c
);
616 obstack_1grow (&m_string_obstack
, 0);
617 return XOBFINISH (&m_string_obstack
, char *);
620 /* Read a braced string (a la Tcl) onto the string obstack. Caller
621 has scanned the leading brace. Note that unlike quoted strings,
622 the outermost braces _are_ included in the string constant. */
625 md_reader::read_braced_string ()
628 int brace_depth
= 1; /* caller-processed */
629 unsigned long starting_read_md_lineno
= get_lineno ();
631 obstack_1grow (&m_string_obstack
, '{');
634 c
= read_char (); /* Read the string */
646 fatal_with_file_and_line
647 ("missing closing } for opening brace on line %lu",
648 starting_read_md_lineno
);
650 obstack_1grow (&m_string_obstack
, c
);
653 obstack_1grow (&m_string_obstack
, 0);
654 return XOBFINISH (&m_string_obstack
, char *);
657 /* Read some kind of string constant. This is the high-level routine
658 used by read_rtx. It handles surrounding parentheses, leading star,
659 and dispatch to the appropriate string constant reader. */
662 md_reader::read_string (int star_if_braced
)
668 c
= read_skip_spaces ();
672 c
= read_skip_spaces ();
675 file_location loc
= get_current_location ();
677 stringbuf
= read_quoted_string ();
681 obstack_1grow (&m_string_obstack
, '*');
682 stringbuf
= read_braced_string ();
684 else if (saw_paren
&& c
== 'n')
686 /* Handle (nil) by returning NULL. */
689 require_char_ws (')');
693 fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c
);
696 require_char_ws (')');
698 set_md_ptr_loc (stringbuf
, loc
);
702 /* Skip the rest of a construct that started at line LINENO and that
703 is currently nested by DEPTH levels of parentheses. */
706 md_reader::read_skip_construct (int depth
, file_location loc
)
713 c
= read_skip_spaces ();
716 error_at (loc
, "unterminated construct");
751 /* Given a string, return the number of comma-separated elements in it.
752 Return 0 for the null string. */
755 n_comma_elts (const char *s
)
769 /* Given a pointer to a (char *), return a pointer to the beginning of the
770 next comma-separated element in the string. Advance the pointer given
771 to the end of that element. Return NULL if at end of string. Caller
772 is responsible for copying the string if necessary. White space between
773 a comma and an element is ignored. */
776 scan_comma_elt (const char **pstr
)
779 const char *p
= *pstr
;
791 while (*p
!= ',' && *p
!= '\0')
798 /* Convert STRING to uppercase. */
801 upcase_string (char *string
)
805 for (i
= 0; string
[i
]; i
++)
806 string
[i
] = TOUPPER (string
[i
]);
809 /* Add a NAME = VALUE definition to md_constants-style hash table DEFS,
810 where both NAME and VALUE are malloc()ed strings. PARENT_ENUM is the
811 enum to which NAME belongs, or null if NAME is a stand-alone constant. */
813 static struct md_constant
*
814 add_constant (htab_t defs
, char *name
, char *value
,
815 struct enum_type
*parent_enum
)
817 struct md_constant
*def
, tmp_def
;
821 entry_ptr
= htab_find_slot (defs
, &tmp_def
, INSERT
);
824 def
= (struct md_constant
*) *entry_ptr
;
825 if (strcmp (def
->value
, value
) != 0)
826 fatal_with_file_and_line ("redefinition of `%s', was `%s', now `%s'",
827 def
->name
, def
->value
, value
);
828 else if (parent_enum
|| def
->parent_enum
)
829 fatal_with_file_and_line ("redefinition of `%s'", def
->name
);
835 def
= XNEW (struct md_constant
);
838 def
->parent_enum
= parent_enum
;
844 /* Process a define_constants directive, starting with the optional space
845 after the "define_constants". */
848 md_reader::handle_constants ()
853 require_char_ws ('[');
855 /* Disable constant expansion during definition processing. */
856 defs
= m_md_constants
;
858 while ( (c
= read_skip_spaces ()) != ']')
860 struct md_name name
, value
;
863 fatal_expected_char ('(', c
);
867 add_constant (defs
, xstrdup (name
.string
), xstrdup (value
.string
), 0);
869 require_char_ws (')');
871 m_md_constants
= defs
;
874 /* For every constant definition, call CALLBACK with two arguments:
875 a pointer a pointer to the constant definition and INFO.
876 Stop when CALLBACK returns zero. */
879 md_reader::traverse_md_constants (htab_trav callback
, void *info
)
881 htab_traverse (get_md_constants (), callback
, info
);
884 /* Return a malloc()ed decimal string that represents number NUMBER. */
887 md_decimal_string (int number
)
889 /* A safe overestimate. +1 for sign, +1 for null terminator. */
890 char buffer
[sizeof (int) * CHAR_BIT
+ 1 + 1];
892 sprintf (buffer
, "%d", number
);
893 return xstrdup (buffer
);
896 /* Process a define_enum or define_c_enum directive, starting with
897 the optional space after the "define_enum". LINENO is the line
898 number on which the directive started and MD_P is true if the
899 directive is a define_enum rather than a define_c_enum. */
902 md_reader::handle_enum (file_location loc
, bool md_p
)
904 char *enum_name
, *value_name
;
905 unsigned int cur_value
;
906 struct md_name name
, value
;
907 struct enum_type
*def
;
908 struct enum_value
*ev
;
912 enum_name
= read_string (false);
913 slot
= htab_find_slot (m_enum_types
, &enum_name
, INSERT
);
916 def
= (struct enum_type
*) *slot
;
917 if (def
->md_p
!= md_p
)
918 error_at (loc
, "redefining `%s' as a different type of enum",
923 def
= XNEW (struct enum_type
);
924 def
->name
= enum_name
;
927 def
->tail_ptr
= &def
->values
;
932 cur_value
= def
->num_values
;
933 require_char_ws ('[');
935 while ((c
= read_skip_spaces ()) != ']')
939 error_at (loc
, "unterminated construct");
946 require_char_ws (')');
947 cur_value
= atoi (value
.string
);
955 ev
= XNEW (struct enum_value
);
959 value_name
= concat (def
->name
, "_", name
.string
, NULL
);
960 upcase_string (value_name
);
961 ev
->name
= xstrdup (name
.string
);
965 value_name
= xstrdup (name
.string
);
966 ev
->name
= value_name
;
968 ev
->def
= add_constant (get_md_constants (), value_name
,
969 md_decimal_string (cur_value
), def
);
972 def
->tail_ptr
= &ev
->next
;
978 /* Try to find the definition of the given enum. Return null on failure. */
981 md_reader::lookup_enum_type (const char *name
)
983 return (struct enum_type
*) htab_find (m_enum_types
, &name
);
986 /* For every enum definition, call CALLBACK with two arguments:
987 a pointer to the constant definition and INFO. Stop when CALLBACK
991 md_reader::traverse_enum_types (htab_trav callback
, void *info
)
993 htab_traverse (m_enum_types
, callback
, info
);
997 /* Constructor for md_reader. */
999 md_reader::md_reader (bool compact
)
1000 : m_compact (compact
),
1001 m_toplevel_fname (NULL
),
1003 m_read_md_file (NULL
),
1004 m_read_md_filename (NULL
),
1005 m_read_md_lineno (0),
1006 m_read_md_colno (0),
1007 m_first_dir_md_include (NULL
),
1008 m_last_dir_md_include_ptr (&m_first_dir_md_include
),
1011 m_first_overload (NULL
),
1012 m_next_overload_ptr (&m_first_overload
),
1013 m_overloads_htab (NULL
)
1015 /* Set the global singleton pointer. */
1016 md_reader_ptr
= this;
1018 obstack_init (&m_string_obstack
);
1020 m_ptr_locs
= htab_create (161, leading_ptr_hash
, leading_ptr_eq_p
, 0);
1021 obstack_init (&m_ptr_loc_obstack
);
1023 m_joined_conditions
= htab_create (161, leading_ptr_hash
, leading_ptr_eq_p
, 0);
1024 obstack_init (&m_joined_conditions_obstack
);
1026 m_md_constants
= htab_create (31, leading_string_hash
,
1027 leading_string_eq_p
, (htab_del
) 0);
1029 m_enum_types
= htab_create (31, leading_string_hash
,
1030 leading_string_eq_p
, (htab_del
) 0);
1032 /* Unlock the stdio streams. */
1033 unlock_std_streams ();
1036 /* md_reader's destructor. */
1038 md_reader::~md_reader ()
1042 htab_delete (m_enum_types
);
1044 htab_delete (m_md_constants
);
1046 obstack_free (&m_joined_conditions_obstack
, NULL
);
1047 htab_delete (m_joined_conditions
);
1049 obstack_free (&m_ptr_loc_obstack
, NULL
);
1050 htab_delete (m_ptr_locs
);
1052 obstack_free (&m_string_obstack
, NULL
);
1054 /* Clear the global singleton pointer. */
1055 md_reader_ptr
= NULL
;
1058 /* Process an "include" directive, starting with the optional space
1059 after the "include". Read in the file and use HANDLE_DIRECTIVE
1060 to process each unknown directive. LINENO is the line number on
1061 which the "include" occurred. */
1064 md_reader::handle_include (file_location loc
)
1066 const char *filename
;
1067 const char *old_filename
;
1068 int old_lineno
, old_colno
;
1070 FILE *input_file
, *old_file
;
1072 filename
= read_string (false);
1075 /* If the specified file name is absolute, skip the include stack. */
1076 if (!IS_ABSOLUTE_PATH (filename
))
1078 struct file_name_list
*stackp
;
1080 /* Search the directory path, trying to open the file. */
1081 for (stackp
= m_first_dir_md_include
; stackp
; stackp
= stackp
->next
)
1083 static const char sep
[2] = { DIR_SEPARATOR
, '\0' };
1085 pathname
= concat (stackp
->fname
, sep
, filename
, NULL
);
1086 input_file
= fopen (pathname
, "r");
1087 if (input_file
!= NULL
)
1093 /* If we haven't managed to open the file yet, try combining the
1094 filename with BASE_DIR. */
1095 if (input_file
== NULL
)
1098 pathname
= concat (m_base_dir
, filename
, NULL
);
1100 pathname
= xstrdup (filename
);
1101 input_file
= fopen (pathname
, "r");
1104 if (input_file
== NULL
)
1107 error_at (loc
, "include file `%s' not found", filename
);
1111 /* Save the old cursor. Note that the LINENO argument to this
1112 function is the beginning of the include statement, while
1113 read_md_lineno has already been advanced. */
1114 old_file
= m_read_md_file
;
1115 old_filename
= m_read_md_filename
;
1116 old_lineno
= m_read_md_lineno
;
1117 old_colno
= m_read_md_colno
;
1119 if (include_callback
)
1120 include_callback (pathname
);
1122 m_read_md_file
= input_file
;
1123 m_read_md_filename
= pathname
;
1127 /* Restore the old cursor. */
1128 m_read_md_file
= old_file
;
1129 m_read_md_filename
= old_filename
;
1130 m_read_md_lineno
= old_lineno
;
1131 m_read_md_colno
= old_colno
;
1133 /* Do not free the pathname. It is attached to the various rtx
1137 /* Process the current file, assuming that read_md_file and
1138 read_md_filename are valid. Use HANDLE_DIRECTIVE to handle
1139 unknown directives. */
1142 md_reader::handle_file ()
1144 struct md_name directive
;
1147 m_read_md_lineno
= 1;
1148 m_read_md_colno
= 0;
1149 while ((c
= read_skip_spaces ()) != EOF
)
1151 file_location loc
= get_current_location ();
1153 fatal_expected_char ('(', c
);
1155 read_name (&directive
);
1156 if (strcmp (directive
.string
, "define_constants") == 0)
1157 handle_constants ();
1158 else if (strcmp (directive
.string
, "define_enum") == 0)
1159 handle_enum (loc
, true);
1160 else if (strcmp (directive
.string
, "define_c_enum") == 0)
1161 handle_enum (loc
, false);
1162 else if (strcmp (directive
.string
, "include") == 0)
1163 handle_include (loc
);
1165 handle_unknown_directive (loc
, directive
.string
);
1167 require_char_ws (')');
1169 fclose (m_read_md_file
);
1172 /* Like handle_file, but for top-level files. Set up m_toplevel_fname
1173 and m_base_dir accordingly. */
1176 md_reader::handle_toplevel_file ()
1180 m_toplevel_fname
= m_read_md_filename
;
1181 base
= lbasename (m_toplevel_fname
);
1182 if (base
== m_toplevel_fname
)
1185 m_base_dir
= xstrndup (m_toplevel_fname
, base
- m_toplevel_fname
);
1191 md_reader::get_current_location () const
1193 return file_location (m_read_md_filename
, m_read_md_lineno
, m_read_md_colno
);
1196 /* Parse a -I option with argument ARG. */
1199 md_reader::add_include_path (const char *arg
)
1201 struct file_name_list
*dirtmp
;
1203 dirtmp
= XNEW (struct file_name_list
);
1205 dirtmp
->fname
= arg
;
1206 *m_last_dir_md_include_ptr
= dirtmp
;
1207 m_last_dir_md_include_ptr
= &dirtmp
->next
;
1210 #ifdef GENERATOR_FILE
1212 /* The main routine for reading .md files. Try to process all the .md
1213 files specified on the command line and return true if no error occurred.
1215 ARGC and ARGV are the arguments to main.
1217 PARSE_OPT, if nonnull, is passed all unknown command-line arguments.
1218 It should return true if it recognizes the argument or false if a
1219 generic error should be reported. */
1222 md_reader::read_md_files (int argc
, const char **argv
,
1223 bool (*parse_opt
) (const char *))
1226 bool no_more_options
;
1227 bool already_read_stdin
;
1230 /* First we loop over all the options. */
1231 for (i
= 1; i
< argc
; i
++)
1232 if (argv
[i
][0] == '-')
1234 /* An argument consisting of exactly one dash is a request to
1235 read stdin. This will be handled in the second loop. */
1236 if (argv
[i
][1] == '\0')
1239 /* An argument consisting of just two dashes causes option
1240 parsing to cease. */
1241 if (argv
[i
][1] == '-' && argv
[i
][2] == '\0')
1244 if (argv
[i
][1] == 'I')
1246 if (argv
[i
][2] != '\0')
1247 add_include_path (argv
[i
] + 2);
1248 else if (++i
< argc
)
1249 add_include_path (argv
[i
]);
1251 fatal ("directory name missing after -I option");
1255 /* The program may have provided a callback so it can
1256 accept its own options. */
1257 if (parse_opt
&& parse_opt (argv
[i
]))
1260 fatal ("invalid option `%s'", argv
[i
]);
1263 /* Now loop over all input files. */
1265 no_more_options
= false;
1266 already_read_stdin
= false;
1267 for (i
= 1; i
< argc
; i
++)
1269 if (argv
[i
][0] == '-')
1271 if (argv
[i
][1] == '\0')
1274 if (already_read_stdin
)
1275 fatal ("cannot read standard input twice");
1277 m_read_md_file
= stdin
;
1278 m_read_md_filename
= "<stdin>";
1279 handle_toplevel_file ();
1280 already_read_stdin
= true;
1283 else if (argv
[i
][1] == '-' && argv
[i
][2] == '\0')
1285 /* No further arguments are to be treated as options. */
1286 no_more_options
= true;
1289 else if (!no_more_options
)
1293 /* If we get here we are looking at a non-option argument, i.e.
1294 a file to be processed. */
1295 m_read_md_filename
= argv
[i
];
1296 m_read_md_file
= fopen (m_read_md_filename
, "r");
1297 if (m_read_md_file
== 0)
1299 perror (m_read_md_filename
);
1302 handle_toplevel_file ();
1306 /* If we get to this point without having seen any files to process,
1307 read the standard input now. */
1308 if (num_files
== 0 && !already_read_stdin
)
1310 m_read_md_file
= stdin
;
1311 m_read_md_filename
= "<stdin>";
1312 handle_toplevel_file ();
1318 #endif /* #ifdef GENERATOR_FILE */
1320 /* Read FILENAME. */
1323 md_reader::read_file (const char *filename
)
1325 m_read_md_filename
= filename
;
1326 m_read_md_file
= fopen (m_read_md_filename
, "r");
1327 if (m_read_md_file
== 0)
1329 perror (m_read_md_filename
);
1332 handle_toplevel_file ();
1336 /* Read FILENAME, filtering to just the given lines. */
1339 md_reader::read_file_fragment (const char *filename
,
1343 m_read_md_filename
= filename
;
1344 m_read_md_file
= fopen (m_read_md_filename
, "r");
1345 if (m_read_md_file
== 0)
1347 perror (m_read_md_filename
);
1350 m_first_line
= first_line
;
1351 m_last_line
= last_line
;
1352 handle_toplevel_file ();
1356 /* class noop_reader : public md_reader */
1358 /* A dummy implementation which skips unknown directives. */
1360 noop_reader::handle_unknown_directive (file_location loc
, const char *)
1362 read_skip_construct (1, loc
);