aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Weinberg <zack@rabi.columbia.edu>1999-04-26 16:41:02 +0000
committerZack Weinberg <zack@gcc.gnu.org>1999-04-26 16:41:02 +0000
commit3caee4a8ee44a285efab9a80cf765c05f3209eb5 (patch)
tree5c575c1ae52f10bc1eebdcf45ba407212d863336
parent641be6fea8860669fb0535babeab8cfbe17b8413 (diff)
downloadgcc-3caee4a8ee44a285efab9a80cf765c05f3209eb5.zip
gcc-3caee4a8ee44a285efab9a80cf765c05f3209eb5.tar.gz
gcc-3caee4a8ee44a285efab9a80cf765c05f3209eb5.tar.bz2
cpphash.c (dump_definition): New function.
1999-04-26 19:16 -0400 Zack Weinberg <zack@rabi.columbia.edu> * cpphash.c (dump_definition): New function. * cpphash.h: Prototype it. * cpplib.c (handle_directive): Don't output anything here. Streamline. (pass_thru_directive): Take a length, not a pointer to the end. All callers changed. (do_define): Handle -dD, -dN, -g3 entirely here. Streamline. (do_include): Handle -dI here. (do_ident): Correct to match cccp. (do_pragma): Copy the pragma through here. (do_assert, do_unassert): Tidy. * cppinit.c (cpp_finish): If -dM was specified, walk the macro hash table and call dump_definition on all the entries. * cppmain.c: cpp_finish may produce output. From-SVN: r26659
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/cpphash.c97
-rw-r--r--gcc/cpphash.h1
-rw-r--r--gcc/cppinit.c19
-rw-r--r--gcc/cpplib.c238
-rw-r--r--gcc/cppmain.c1
6 files changed, 229 insertions, 146 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 59dd0d3..0075916 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,22 @@
+1999-04-26 19:16 -0400 Zack Weinberg <zack@rabi.columbia.edu>
+
+ * cpphash.c (dump_definition): New function.
+ * cpphash.h: Prototype it.
+
+ * cpplib.c (handle_directive): Don't output anything here.
+ Streamline.
+ (pass_thru_directive): Take a length, not a pointer to the
+ end. All callers changed.
+ (do_define): Handle -dD, -dN, -g3 entirely here. Streamline.
+ (do_include): Handle -dI here.
+ (do_ident): Correct to match cccp.
+ (do_pragma): Copy the pragma through here.
+ (do_assert, do_unassert): Tidy.
+
+ * cppinit.c (cpp_finish): If -dM was specified, walk the macro
+ hash table and call dump_definition on all the entries.
+ * cppmain.c: cpp_finish may produce output.
+
Mon Apr 26 15:27:33 1999 Mark Mitchell <mark@codesourcery.com>
* toplev.c (compile_file): Move call to check_global_declarations
diff --git a/gcc/cpphash.c b/gcc/cpphash.c
index 6e601a0..1d8a104 100644
--- a/gcc/cpphash.c
+++ b/gcc/cpphash.c
@@ -1636,3 +1636,100 @@ comp_def_part (first, beg1, len1, beg2, len2, last)
}
return (beg1 != end1) || (beg2 != end2);
}
+
+/* Dump the definition of macro MACRO on stdout. The format is suitable
+ to be read back in again. */
+
+void
+dump_definition (pfile, macro)
+ cpp_reader *pfile;
+ MACRODEF macro;
+{
+ DEFINITION *defn = macro.defn;
+
+ CPP_RESERVE (pfile, macro.symlen + sizeof "#define ");
+ CPP_PUTS_Q (pfile, "#define ", sizeof "#define " -1);
+ CPP_PUTS_Q (pfile, macro.symnam, macro.symlen);
+
+ if (defn->nargs == -1)
+ {
+ CPP_PUTC_Q (pfile, ' ');
+
+ /* The first and last two characters of a macro expansion are
+ always "\r "; this needs to be trimmed out.
+ So we need length-4 chars of space, plus one for the NUL. */
+ CPP_RESERVE (pfile, defn->length - 4 + 1);
+ CPP_PUTS_Q (pfile, defn->expansion + 2, defn->length - 4);
+ CPP_NUL_TERMINATE_Q (pfile);
+ }
+ else
+ {
+ struct reflist *r;
+ unsigned char *argnames = xstrdup (defn->args.argnames);
+ unsigned char **argv = alloca (defn->nargs * sizeof(char *));
+ int *argl = alloca (defn->nargs * sizeof(int));
+ unsigned char *x;
+ int i;
+
+ /* First extract the argument list. */
+ x = argnames;
+ i = defn->nargs;
+ while (i--)
+ {
+ argv[i] = x;
+ while (*x != ',' && *x != '\0') x++;
+ argl[i] = x - argv[i];
+ if (*x == ',')
+ {
+ *x = '\0';
+ x += 2; /* skip the space after the comma */
+ }
+ }
+
+ /* Now print out the argument list. */
+ CPP_PUTC_Q (pfile, '(');
+ for (i = 0; i < defn->nargs; i++)
+ {
+ CPP_RESERVE (pfile, argl[i] + 2);
+ CPP_PUTS_Q (pfile, argv[i], argl[i]);
+ if (i < defn->nargs-1)
+ CPP_PUTS_Q (pfile, ", ", 2);
+ }
+
+ if (defn->rest_args)
+ CPP_PUTS (pfile, "...) ", 5);
+ else
+ CPP_PUTS (pfile, ") ", 2);
+
+ /* Now the definition. */
+ x = defn->expansion;
+ for (r = defn->pattern; r; r = r->next)
+ {
+ i = r->nchars;
+ if (*x == '\r') x += 2, i -= 2;
+ /* i chars for macro text, plus the length of the macro
+ argument name, plus one for a stringify marker, plus two for
+ each concatenation marker. */
+ CPP_RESERVE (pfile,
+ i + argl[r->argno] + r->stringify
+ + (r->raw_before + r->raw_after) * 2);
+
+ if (i > 0) CPP_PUTS_Q (pfile, x, i);
+ if (r->raw_before)
+ CPP_PUTS_Q (pfile, "##", 2);
+ if (r->stringify)
+ CPP_PUTC_Q (pfile, '#');
+ CPP_PUTS_Q (pfile, argv[r->argno], argl[r->argno]);
+ if (r->raw_after && !(r->next && r->next->nchars == 0
+ && r->next->raw_before))
+ CPP_PUTS_Q (pfile, "##", 2);
+
+ x += i;
+ }
+
+ i = defn->length - (x - defn->expansion) - 2;
+ if (*x == '\r') x += 2, i -= 2;
+ if (i > 0) CPP_PUTS (pfile, x, i);
+ CPP_NUL_TERMINATE (pfile);
+ }
+}
diff --git a/gcc/cpphash.h b/gcc/cpphash.h
index d304f1a..bb306d9 100644
--- a/gcc/cpphash.h
+++ b/gcc/cpphash.h
@@ -58,3 +58,4 @@ extern MACRODEF create_definition PARAMS ((U_CHAR *, U_CHAR *,
extern int compare_defs PARAMS ((cpp_reader *, DEFINITION *,
DEFINITION *));
extern void macroexpand PARAMS ((cpp_reader *, HASHNODE *));
+extern void dump_definition PARAMS ((cpp_reader *, MACRODEF));
diff --git a/gcc/cppinit.c b/gcc/cppinit.c
index 6f2a997..9b2ecca 100644
--- a/gcc/cppinit.c
+++ b/gcc/cppinit.c
@@ -1094,6 +1094,25 @@ cpp_finish (pfile)
}
}
}
+
+ if (opts->dump_macros == dump_only)
+ {
+ int i;
+ HASHNODE *h;
+ MACRODEF m;
+ for (i = HASHSIZE; --i >= 0;)
+ {
+ for (h = pfile->hashtab[i]; h; h = h->next)
+ if (h->type == T_MACRO)
+ {
+ m.defn = h->value.defn;
+ m.symnam = h->name;
+ m.symlen = h->length;
+ dump_definition (pfile, m);
+ CPP_PUTC (pfile, '\n');
+ }
+ }
+ }
}
/* Handle one command-line option in (argc, argv).
diff --git a/gcc/cpplib.c b/gcc/cpplib.c
index eb43e3b..bcf40e1 100644
--- a/gcc/cpplib.c
+++ b/gcc/cpplib.c
@@ -511,7 +511,7 @@ handle_directive (pfile)
if (CPP_PEDANTIC (pfile))
cpp_pedwarn (pfile, "`#' followed by integer");
do_line (pfile, NULL);
- goto done_a_directive;
+ return 1;
}
/* Now find the directive name. */
@@ -519,109 +519,54 @@ handle_directive (pfile)
parse_name (pfile, GETC());
ident = pfile->token_buffer + old_written + 1;
ident_length = CPP_PWRITTEN (pfile) - ident;
- if (ident_length == 0 && PEEKC() == '\n')
+ if (ident_length == 0)
{
/* A line of just `#' becomes blank. */
- goto done_a_directive;
- }
-
-#if 0
- if (ident_length == 0 || !is_idstart[*ident]) {
- U_CHAR *p = ident;
- while (is_idchar[*p]) {
- if (*p < '0' || *p > '9')
- break;
- p++;
- }
- /* Avoid error for `###' and similar cases unless -pedantic. */
- if (p == ident) {
- while (*p == '#' || is_hor_space[*p]) p++;
- if (*p == '\n') {
- if (pedantic && !lang_asm)
- cpp_warning (pfile, "invalid preprocessor directive");
+ if (PEEKC() == '\n')
+ return 1;
+ else
return 0;
- }
}
- if (!lang_asm)
- cpp_error (pfile, "invalid preprocessor directive name");
-
- return 0;
- }
-#endif
/*
* Decode the keyword and call the appropriate expansion
* routine, after moving the input pointer up to the next line.
*/
- for (kt = directive_table; ; kt++) {
- if (kt->length <= 0)
- goto not_a_directive;
- if (kt->length == ident_length
- && !strncmp (kt->name, ident, ident_length))
- break;
- }
-
- /* We may want to pass through #define, #undef, #pragma, and #include.
- Other directives may create output, but we don't want the directive
- itself out, so we pop it now. For example conditionals may emit
- #failed ... #endfailed stuff. */
-
- if (! (kt->type == T_DEFINE
- || kt->type == T_PRAGMA
- || (IS_INCLUDE_DIRECTIVE_TYPE (kt->type)
- && CPP_OPTIONS (pfile)->dump_includes)))
- CPP_SET_WRITTEN (pfile, old_written);
-
- (*kt->func) (pfile, kt);
-
- if (kt->type == T_DEFINE)
+ for (kt = directive_table; ; kt++)
{
- if (CPP_OPTIONS (pfile)->dump_macros == dump_names)
- {
- /* Skip "#define". */
- U_CHAR *p = pfile->token_buffer + old_written + 7;
-
- SKIP_WHITE_SPACE (p);
- while (is_idchar[*p]) p++;
- pfile->limit = p;
- CPP_PUTC (pfile, '\n');
- }
- else if (CPP_OPTIONS (pfile)->dump_macros != dump_definitions)
- CPP_SET_WRITTEN (pfile, old_written);
+ if (kt->length <= 0)
+ return 0;
+ if (kt->length == ident_length
+ && !strncmp (kt->name, ident, ident_length))
+ break;
}
- done_a_directive:
- return 1;
+ CPP_SET_WRITTEN (pfile, old_written);
+ (*kt->func) (pfile, kt);
- not_a_directive:
- return 0;
+ return 1;
}
/* Pass a directive through to the output file.
BUF points to the contents of the directive, as a contiguous string.
-m LIMIT points to the first character past the end of the directive.
+ LEN is the length of the string pointed to by BUF.
KEYWORD is the keyword-table entry for the directive. */
static void
-pass_thru_directive (buf, limit, pfile, keyword)
- U_CHAR *buf, *limit;
+pass_thru_directive (buf, len, pfile, keyword)
+ U_CHAR *buf;
+ size_t len;
cpp_reader *pfile;
struct directive *keyword;
{
register unsigned keyword_length = keyword->length;
- CPP_RESERVE (pfile, 1 + keyword_length + (limit - buf));
+ CPP_RESERVE (pfile, 1 + keyword_length + len);
CPP_PUTC_Q (pfile, '#');
CPP_PUTS_Q (pfile, keyword->name, keyword_length);
- if (limit != buf && buf[0] != ' ')
+ if (len != 0 && buf[0] != ' ')
CPP_PUTC_Q (pfile, ' ');
- CPP_PUTS_Q (pfile, buf, limit - buf);
-#if 0
- CPP_PUTS_Q (pfile, '\n');
- /* Count the line we have just made in the output,
- to get in sync properly. */
- pfile->lineno++;
-#endif
+ CPP_PUTS_Q (pfile, buf, len);
}
/* Check a purported macro name SYMNAME, and yield its length.
@@ -658,7 +603,6 @@ check_macro_name (pfile, symname, assertion)
return sym_length;
}
-
/* Process a #define command.
KEYWORD is the keyword-table entry for #define,
or NULL for a "predefined" macro. */
@@ -686,15 +630,9 @@ do_define (pfile, keyword)
CPP_SET_WRITTEN (pfile, here);
-#if 0
- /* If this is a precompiler run (with -pcp) pass thru #define commands. */
- if (pcp_outfile && keyword)
- pass_thru_directive (macro, end, pfile, keyword);
-#endif
-
mdef = create_definition (macro, end, pfile, keyword == NULL);
if (mdef.defn == 0)
- goto nope;
+ return 0;
hashcode = hashf (mdef.symnam, mdef.symlen, HASHSIZE);
@@ -713,35 +651,30 @@ do_define (pfile, keyword)
/* Print the warning if it's not ok. */
if (!ok)
{
- /* If we are passing through #define and #undef directives, do
- that for this re-definition now. */
- if (CPP_OPTIONS (pfile)->debug_output && keyword)
- pass_thru_directive (macro, end, pfile, keyword);
-
cpp_pedwarn (pfile, "`%.*s' redefined", mdef.symlen, mdef.symnam);
if (hp->type == T_MACRO)
- cpp_pedwarn_with_file_and_line (pfile, hp->value.defn->file, hp->value.defn->line,
- "this is the location of the previous definition");
+ cpp_pedwarn_with_file_and_line (pfile, hp->value.defn->file,
+ hp->value.defn->line,
+ "this is the location of the previous definition");
}
/* Replace the old definition. */
hp->type = T_MACRO;
hp->value.defn = mdef.defn;
}
else
+ cpp_install (pfile, mdef.symnam, mdef.symlen, T_MACRO,
+ (char *) mdef.defn, hashcode);
+
+ if (keyword)
{
- /* If we are passing through #define and #undef directives, do
- that for this new definition now. */
- if (CPP_OPTIONS (pfile)->debug_output && keyword)
- pass_thru_directive (macro, end, pfile, keyword);
- cpp_install (pfile, mdef.symnam, mdef.symlen, T_MACRO,
- (char *) mdef.defn, hashcode);
+ if (CPP_OPTIONS (pfile)->debug_output
+ || CPP_OPTIONS (pfile)->dump_macros == dump_definitions)
+ dump_definition (pfile, mdef);
+ else if (CPP_OPTIONS (pfile)->dump_macros == dump_names)
+ pass_thru_directive (mdef.symnam, mdef.symlen, pfile, keyword);
}
return 0;
-
-nope:
-
- return 1;
}
@@ -1020,7 +953,7 @@ do_include (pfile, keyword)
int angle_brackets = 0; /* 0 for "...", 1 for <...> */
int before; /* included before? */
long flen;
- unsigned char *fbeg, *fend;
+ unsigned char *ftok;
cpp_buffer *fp;
enum cpp_token token;
@@ -1046,7 +979,8 @@ do_include (pfile, keyword)
&& !CPP_BUFFER (pfile)->system_header_p && !pfile->import_warning)
{
pfile->import_warning = 1;
- cpp_warning (pfile, "`#import' is obsolete, use an #ifndef wrapper in the header file");
+ cpp_warning (pfile,
+ "#import is obsolete, use an #ifndef wrapper in the header file");
}
pfile->parsing_include_directive++;
@@ -1055,28 +989,20 @@ do_include (pfile, keyword)
if (token == CPP_STRING)
{
- fbeg = pfile->token_buffer + old_written + 1;
- fend = CPP_PWRITTEN (pfile) - 1;
- *fend = '\0';
- if (fbeg[-1] == '<')
- angle_brackets = 1;
+ if (pfile->token_buffer[old_written] == '<')
+ angle_brackets = 1;
}
#ifdef VMS
else if (token == CPP_NAME)
{
- /* Support '#include xyz' like VAX-C to allow for easy use of
- * all the decwindow include files. It defaults to '#include
- * <xyz.h>' and generates a warning. */
+ /* Support '#include xyz' like VAX-C. It is taken as
+ '#include <xyz.h>' and generates a warning. */
cpp_warning (pfile,
- "VAX-C-style include specification found, use '#include <filename.h>' !");
+ "`#include filename' is obsolete, use `#include <filename.h>'");
angle_brackets = 1;
/* Append the missing `.h' to the name. */
- CPP_PUTS (pfile, ".h", 3)
- CPP_NUL_TERMINATE_Q (pfile);
-
- fbeg = pfile->token_buffer + old_written;
- fend = CPP_PWRITTEN (pfile);
+ CPP_PUTS (pfile, ".h", 2);
}
#endif
else
@@ -1088,8 +1014,12 @@ do_include (pfile, keyword)
return 0;
}
- token = get_directive_token (pfile);
- if (token != CPP_VSPACE)
+ flen = CPP_WRITTEN (pfile) - old_written;
+ ftok = alloca (flen + 1);
+ memcpy (ftok, pfile->token_buffer + old_written, flen);
+ ftok[flen] = '\0';
+
+ if (get_directive_token (pfile) != CPP_VSPACE)
{
cpp_error (pfile, "junk at end of `#include'");
skip_rest_of_line (pfile);
@@ -1097,14 +1027,29 @@ do_include (pfile, keyword)
CPP_SET_WRITTEN (pfile, old_written);
- flen = fend - fbeg;
-
if (flen == 0)
{
cpp_error (pfile, "empty file name in `#%s'", keyword->name);
return 0;
}
+ if (CPP_OPTIONS (pfile)->dump_includes)
+ pass_thru_directive (ftok,
+ flen
+#ifdef VMS
+ - ((token == CPP_NAME) ? 2 : 0)
+#endif
+ , pfile, keyword);
+
+#ifdef VMS
+ if (token == CPP_STRING)
+#endif
+ {
+ ftok++;
+ flen -= 2;
+ ftok[flen] = '\0';
+ }
+
search_start = 0;
for (fp = CPP_BUFFER (pfile);
@@ -1116,7 +1061,7 @@ do_include (pfile, keyword)
if (fp == CPP_NULL_BUFFER (pfile))
{
cpp_fatal (pfile, "cpp internal error: fp == NULL_BUFFER in do_include");
- return 1;
+ return 0;
}
/* For #include_next, skip in the search path past the dir in which the
@@ -1149,11 +1094,11 @@ do_include (pfile, keyword)
if (!search_start)
{
- cpp_error (pfile, "No include path in which to find %s", fbeg);
+ cpp_error (pfile, "No include path in which to find %s", ftok);
return 0;
}
- fd = find_include_file (pfile, fbeg, search_start, &ihash, &before);
+ fd = find_include_file (pfile, ftok, search_start, &ihash, &before);
if (fd == -2)
return 0;
@@ -1165,7 +1110,7 @@ do_include (pfile, keyword)
(pfile->system_include_depth > 0)))
{
if (!angle_brackets)
- deps_output (pfile, fbeg, ' ');
+ deps_output (pfile, ftok, ' ');
else
{
char *p;
@@ -1178,13 +1123,13 @@ do_include (pfile, keyword)
ptr = CPP_OPTIONS (pfile)->quote_include;
p = (char *) alloca (strlen (ptr->name)
- + strlen (fbeg) + 2);
+ + strlen (ftok) + 2);
if (*ptr->name != '\0')
{
strcpy (p, ptr->name);
strcat (p, "/");
}
- strcat (p, fbeg);
+ strcat (p, ftok);
deps_output (pfile, p, ' ');
}
}
@@ -1197,9 +1142,9 @@ do_include (pfile, keyword)
else if (CPP_PRINT_DEPS (pfile)
&& (CPP_PRINT_DEPS (pfile)
<= (angle_brackets || (pfile->system_include_depth > 0))))
- cpp_warning (pfile, "No include path in which to find %s", fbeg);
+ cpp_warning (pfile, "No include path in which to find %s", ftok);
else
- cpp_error_from_errno (pfile, fbeg);
+ cpp_error_from_errno (pfile, ftok);
return 0;
}
@@ -1410,12 +1355,6 @@ do_undef (pfile, keyword)
CPP_SET_WRITTEN (pfile, here);
-#if 0
- /* If this is a precompiler run (with -pcp) pass thru #undef commands. */
- if (pcp_outfile && keyword)
- pass_thru_directive (buf, limit, pfile, keyword);
-#endif
-
sym_length = check_macro_name (pfile, buf, 0);
while ((hp = cpp_lookup (pfile, name, sym_length, -1)) != NULL)
@@ -1423,7 +1362,7 @@ do_undef (pfile, keyword)
/* If we are generating additional info for debugging (with -g) we
need to pass through all effective #undef commands. */
if (CPP_OPTIONS (pfile)->debug_output && keyword)
- pass_thru_directive (name, name+sym_length, pfile, keyword);
+ pass_thru_directive (name, sym_length, pfile, keyword);
if (hp->type != T_MACRO)
cpp_warning (pfile, "undefining `%s'", hp->name);
delete_macro (hp);
@@ -1494,7 +1433,10 @@ do_warning (pfile, keyword)
return 0;
}
-/* Report program identification. */
+/* Report program identification.
+ This is not precisely what cccp does with #ident, however I believe
+ it matches `closely enough' (behavior is identical as long as there
+ are no macros on the #ident line, which is pathological in my opinion). */
static int
do_ident (pfile, keyword)
@@ -1505,7 +1447,9 @@ do_ident (pfile, keyword)
if (CPP_PEDANTIC (pfile) && !CPP_BUFFER (pfile)->system_header_p)
cpp_pedwarn (pfile, "ANSI C does not allow `#ident'");
- skip_rest_of_line (pfile); /* Correct? Appears to match cccp. */
+ CPP_PUTS (pfile, "#ident ", 7);
+ cpp_skip_hspace (pfile);
+ copy_rest_of_line (pfile);
return 0;
}
@@ -1518,12 +1462,15 @@ do_pragma (pfile, keyword)
cpp_reader *pfile;
struct directive *keyword ATTRIBUTE_UNUSED;
{
- long here = CPP_WRITTEN (pfile);
+ long here;
U_CHAR *buf;
+
+ CPP_PUTS (pfile, "#pragma ", 8);
+ cpp_skip_hspace (pfile);
+ here = CPP_WRITTEN (pfile);
copy_rest_of_line (pfile);
buf = pfile->token_buffer + here;
- SKIP_WHITE_SPACE (buf);
if (!strncmp (buf, "once", 4))
{
@@ -1547,8 +1494,7 @@ do_pragma (pfile, keyword)
else
ip->ihash->control_macro = ""; /* never repeat */
}
-
- if (!strncmp (buf, "implementation", 14))
+ else if (!strncmp (buf, "implementation", 14))
{
/* Be quiet about `#pragma implementation' for a file only if it hasn't
been included yet. */
@@ -2831,9 +2777,9 @@ do_assert (pfile, keyword)
return 0;
error:
- pfile->limit = (unsigned char *) sym; /* Pop */
skip_rest_of_line (pfile);
- return 1;
+ pfile->limit = (unsigned char *) sym; /* Pop */
+ return 0;
}
static int
@@ -2900,9 +2846,9 @@ do_unassert (pfile, keyword)
pfile->limit = (unsigned char *) sym; /* Pop */
return 0;
error:
- pfile->limit = (unsigned char *) sym; /* Pop */
skip_rest_of_line (pfile);
- return 1;
+ pfile->limit = (unsigned char *) sym; /* Pop */
+ return 0;
}
/* Process STR as if it appeared as the body of an #unassert. */
diff --git a/gcc/cppmain.c b/gcc/cppmain.c
index 5142cad..e7d82b5 100644
--- a/gcc/cppmain.c
+++ b/gcc/cppmain.c
@@ -94,6 +94,7 @@ main (argc, argv)
}
cpp_finish (&parse_in);
+ fwrite (parse_in.token_buffer, 1, CPP_WRITTEN (&parse_in), stdout);
if (parse_in.errors)
exit (FATAL_EXIT_CODE);