-FILE *finput = NULL;
-FILE *foutput = NULL;
-FILE *fdefines = NULL;
-FILE *ftable = NULL;
-FILE *fattrs = NULL;
-FILE *fguard = NULL;
-FILE *faction = NULL;
-FILE *fparser = NULL;
-
-/* File name specified with -o for the output file, or 0 if no -o.  */
-char *spec_outfile;
-
-char *infile;
-char *outfile;
-char *defsfile;
-char *tabfile;
-char *attrsfile;
-char *guardfile;
-char *actfile;
-char *tmpattrsfile;
-char *tmptabfile;
-char *tmpdefsfile;
-
-extern int noparserflag;
-
-extern char    *mktemp();      /* So the compiler won't complain */
-extern char    *getenv();
-extern void    perror();
-
-char *stringappend PARAMS((char *, int, char *));
-void openfiles PARAMS((void));
-void open_extra_files PARAMS((void));
-FILE *tryopen PARAMS((char *, char *));        /* This might be a good idea */
-int tryclose PARAMS((FILE *));
-void done PARAMS((int));
-
-extern char *program_name;
-extern int verboseflag;
-extern int definesflag;
-int fixed_outfiles = 0;
+/* Initializing some values below (such SPEC_NAME_PREFIX to `yy') is
+   tempting, but don't do that: for the time being our handling of the
+   %directive vs --option leaves precedence to the options by deciding
+   that if a %directive sets a variable which is really set (i.e., not
+   NULL), then the %directive is ignored.  As a result, %name-prefix,
+   for instance, will not be honored.  */
+
+char const *spec_outfile = NULL;       /* for -o. */
+char const *spec_file_prefix = NULL;   /* for -b. */
+char const *spec_name_prefix = NULL;   /* for -p. */
+char *spec_verbose_file = NULL;  /* for --verbose. */
+char *spec_graph_file = NULL;    /* for -g. */
+char *spec_xml_file = NULL;      /* for -x. */
+char *spec_defines_file = NULL;  /* for --defines. */
+char *parser_file_name;
+
+/* All computed output file names.  */
+static char **file_names = NULL;
+static int file_names_count = 0;
+
+uniqstr grammar_file = NULL;
+uniqstr current_file = NULL;
+
+/* If --output=dir/foo.c was specified,
+   DIR_PREFIX is `dir/' and ALL_BUT_EXT and ALL_BUT_TAB_EXT are `dir/foo'.
+
+   If --output=dir/foo.tab.c was specified, DIR_PREFIX is `dir/',
+   ALL_BUT_EXT is `dir/foo.tab', and ALL_BUT_TAB_EXT is `dir/foo'.
+
+   If --output was not specified but --file-prefix=dir/foo was specified,
+   ALL_BUT_EXT = `foo.tab' and ALL_BUT_TAB_EXT = `foo'.
+
+   If neither --output nor --file was specified but the input grammar
+   is name dir/foo.y, ALL_BUT_EXT and ALL_BUT_TAB_EXT are `foo'.
+
+   If neither --output nor --file was specified, DIR_PREFIX is the
+   empty string (meaning the current directory); otherwise it is
+   `dir/'.  */
+
+char *all_but_ext;
+static char *all_but_tab_ext;
+char *dir_prefix;
+
+/* C source file extension (the parser source).  */
+static char *src_extension = NULL;
+/* Header file extension (if option ``-d'' is specified).  */
+static char *header_extension = NULL;