]> git.saurik.com Git - bison.git/blobdiff - src/files.c
* src/print_graph.c (quote): New.
[bison.git] / src / files.c
index 32a4a8d54b5db9959891bcb12d026a80aa32cc96..721f1e5e6bce29ae79fb1867e1cee2b79c817edc 100644 (file)
@@ -1,5 +1,5 @@
 /* Open and close files for bison,
 /* Open and close files for bison,
-   Copyright 1984, 1986, 1989, 1992, 2000 Free Software Foundation, Inc.
+   Copyright 1984, 1986, 1989, 1992, 2000, 2001 Free Software Foundation, Inc.
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 
    This file is part of Bison, the GNU Compiler Compiler.
 
 #include "complain.h"
 
 FILE *finput = NULL;
 #include "complain.h"
 
 FILE *finput = NULL;
-FILE *foutput = NULL;
-FILE *fguard = NULL;
 
 struct obstack action_obstack;
 struct obstack attrs_obstack;
 struct obstack table_obstack;
 struct obstack defines_obstack;
 
 struct obstack action_obstack;
 struct obstack attrs_obstack;
 struct obstack table_obstack;
 struct obstack defines_obstack;
+struct obstack guard_obstack;
+struct obstack output_obstack;
+struct obstack graph_obstack;
 
 
-/* File name specified with -o for the output file, or 0 if no -o.  */
-char *spec_outfile;
+char *spec_outfile = NULL;     /* for -o. */
+char *spec_file_prefix = NULL; /* for -b. */
+char *spec_name_prefix = NULL; /* for -p. */
 
 
-char *infile;
-char *attrsfile;
-char *guardfile;
+char *infile = NULL;
+char *attrsfile = NULL;
+
+static char *base_name = NULL;
+static char *short_base_name = NULL;
+
+/* C source file extension (the parser source). */
+const char *src_extension = NULL;
+/* Header file extension (if option ``-d'' is specified). */
+const char *header_extension = NULL;
 
 
-static char *outfile;
-static char *defsfile;
-static char *tabfile;
-static char *actfile;
 \f
 /*--------------------------.
 | Is SUFFIX ending STRING?  |
 \f
 /*--------------------------.
 | Is SUFFIX ending STRING?  |
@@ -131,11 +136,11 @@ obstack_save (struct obstack *obs, const char *filename)
 
 /*------------------------------------------------------------------.
 | Return the path to the skeleton which locaction might be given in |
 
 /*------------------------------------------------------------------.
 | Return the path to the skeleton which locaction might be given in |
-| ENVVAR, otherwise return SKELETON.                                |
+| ENVVAR, otherwise return SKELETON_NAME.                           |
 `------------------------------------------------------------------*/
 
 const char *
 `------------------------------------------------------------------*/
 
 const char *
-skeleton_find (const char *envvar, const char *skeleton)
+skeleton_find (const char *envvar, const char *skeleton_name)
 {
   const char *res = getenv (envvar);
 
 {
   const char *res = getenv (envvar);
 
@@ -145,29 +150,99 @@ skeleton_find (const char *envvar, const char *skeleton)
   /* File doesn't exist in current directory; try in INIT directory.  */
   if (!res && (cp = getenv ("INIT")))
     {
   /* File doesn't exist in current directory; try in INIT directory.  */
   if (!res && (cp = getenv ("INIT")))
     {
-      res = XMALLOC (char, strlen (cp) + strlen (skeleton) + 2);
-      sprintf (res, "%s%c%s", cp, '/', skeleton);
+      res = XMALLOC (char, strlen (cp) + strlen (skeleton_name) + 2);
+      sprintf (res, "%s%c%s", cp, '/', skeleton_name);
     }
 #endif /* !MSDOS */
 
   if (!res)
     }
 #endif /* !MSDOS */
 
   if (!res)
-    res = skeleton;
+    res = skeleton_name;
 
   return res;
 }
 
 \f
 
   return res;
 }
 
 \f
-/*----------------------------------------.
-| Compute BASE_NAME and SHORT_BASE_NAME.  |
-`----------------------------------------*/
+/*----------------------------------------------------------------.
+| Compute BASE_NAME, SHORT_BASE_NAME and output files extensions. |
+`----------------------------------------------------------------*/
+
+/* Replace all characters FROM by TO in the string IN.
+   and returns a new allocated string. */
+static char *
+tr(const char *in, char from, char to)
+{
+  char *temp;
+  char *out;
+
+  out = XMALLOC (char, strlen (in) + 1);
+
+  for (temp = out; *in; in++, out++)
+    if (*in == from)
+      *out = to;
+    else
+      *out = *in;
+  *out = 0;
+  return (temp);
+}
+
+/*  Gets the extension index in FILENAME. Returns 0 if fails to
+    find an extension. */
+static int
+get_extension_index(const char *filename)
+{
+  int  len;
+
+  len = strlen (filename);
+
+  if (filename[len-- - 1] == '.')
+    return (0);
+
+  while ((len > 0) && (filename[len - 1] != '.'))
+    if (filename[len - 1] == '/')
+      return (0);
+    else
+      len--;
+
+  return (len - 1);
+}
+
+/* Computes extensions from the grammar file extension. */
+static void
+compute_exts_from_gf(const char *ext)
+{
+  if (!src_extension)
+    {
+      src_extension = tr(ext, 'y', 'c');
+      src_extension = tr(src_extension, 'Y', 'C');
+    }
+  if (!header_extension)
+    {
+      header_extension = tr(ext, 'y', 'h');
+      header_extension = tr(header_extension, 'Y', 'H');
+    }
+}
+
+/* Computes extensions from the given c source file extension. */
+static void
+compute_exts_from_src(const char *ext)
+{
+  if (!src_extension)
+    src_extension = xstrdup(ext);
+  if (!header_extension)
+    {
+      header_extension = tr(ext, 'c', 'h');
+      header_extension = tr(header_extension, 'C', 'H');
+    }
+}
 
 /* FIXME: Should use xstrndup. */
 
 static void
 
 /* FIXME: Should use xstrndup. */
 
 static void
-base_names (char **base_name, char **short_base_name)
+compute_base_names (void)
 {
   size_t base_length;
   size_t short_base_length;
 {
   size_t base_length;
   size_t short_base_length;
+  size_t ext_index;
 
   /* If --output=foo.c was specified (SPEC_OUTFILE == foo.c),
      BASE_NAME and SHORT_BASE_NAME are `foo'.
 
   /* If --output=foo.c was specified (SPEC_OUTFILE == foo.c),
      BASE_NAME and SHORT_BASE_NAME are `foo'.
@@ -184,14 +259,24 @@ base_names (char **base_name, char **short_base_name)
 #endif /* MSDOS */
       /* BASE_LENGTH includes ".tab" but not ".c".  */
       base_length = strlen (spec_outfile);
 #endif /* MSDOS */
       /* BASE_LENGTH includes ".tab" but not ".c".  */
       base_length = strlen (spec_outfile);
-      if (strsuffix (spec_outfile, ".c"))
-       base_length -= 2;
+
+      ext_index = get_extension_index (spec_outfile);
+      /* if the initial segment of extension contains 'c' or a 'C', I assume
+        that it is a C or C++ source file */
+      if (ext_index)
+       ext_index = (strspn(spec_outfile + ext_index + 1, "cC")) ? ext_index : 0;
+      if (ext_index)
+       {
+         base_length -= strlen (spec_outfile + ext_index);
+         compute_exts_from_src(spec_outfile + ext_index);
+       }
+
+      base_name = strndup (spec_outfile, base_length);
       /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c".  */
       short_base_length = base_length;
       /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c".  */
       short_base_length = base_length;
-      if (strsuffix (spec_outfile, ".tab") || strsuffix (spec_outfile, "_tab"))
+      if (strsuffix (base_name, ".tab") || strsuffix (base_name, "_tab"))
        short_base_length -= 4;
        short_base_length -= 4;
-      *base_name = strndup (spec_outfile, base_length);
-      *short_base_name = strndup (spec_outfile, short_base_length);
+      short_base_name = strndup (spec_outfile, short_base_length);
 
       return;
     }
 
       return;
     }
@@ -205,11 +290,10 @@ base_names (char **base_name, char **short_base_name)
 #ifdef MSDOS
       strlwr (spec_file_prefix);
 #endif /* MSDOS */
 #ifdef MSDOS
       strlwr (spec_file_prefix);
 #endif /* MSDOS */
-      *short_base_name = xstrdup (spec_file_prefix);
-
-      *base_name = XMALLOC (char,
-                           strlen (*short_base_name) + strlen (EXT_TAB) + 1);
-      stpcpy (stpcpy (*base_name, *short_base_name), EXT_TAB);
+      short_base_name = xstrdup (spec_file_prefix);
+      base_name = XMALLOC (char,
+                          strlen (short_base_name) + strlen (EXT_TAB) + 1);
+      stpcpy (stpcpy (base_name, short_base_name), EXT_TAB);
 
       return;
     }
 
       return;
     }
@@ -225,14 +309,24 @@ base_names (char **base_name, char **short_base_name)
     /* BASE_LENGTH gets length of BASE_NAME, sans ".y" suffix if any.  */
 
     base_length = strlen (name_base);
     /* BASE_LENGTH gets length of BASE_NAME, sans ".y" suffix if any.  */
 
     base_length = strlen (name_base);
-    if (strsuffix (name_base, ".y"))
-      base_length -= 2;
+
+    ext_index = get_extension_index (name_base);
+    /* if the initial segment of extension contains a 'y' or a 'Y', I assume
+       that it is a yacc or bison grammar file */
+    if (ext_index)
+      ext_index = (strspn(name_base + ext_index + 1, "yY")) ? ext_index : 0;
+    if (ext_index)
+      {
+       base_length -= strlen (name_base + ext_index);
+       compute_exts_from_gf(name_base + ext_index);
+      }
+
     short_base_length = base_length;
     short_base_length = base_length;
-    *short_base_name = strndup (name_base, short_base_length);
+    short_base_name = strndup (name_base, short_base_length);
 
 
-    *base_name = XMALLOC (char,
-                         strlen (*short_base_name) + strlen (EXT_TAB) + 1);
-    stpcpy (stpcpy (*base_name, *short_base_name), EXT_TAB);
+    base_name = XMALLOC (char,
+                        strlen (short_base_name) + strlen (EXT_TAB) + 1);
+    stpcpy (stpcpy (base_name, short_base_name), EXT_TAB);
 
     return;
   }
 
     return;
   }
@@ -246,46 +340,16 @@ base_names (char **base_name, char **short_base_name)
 void
 open_files (void)
 {
 void
 open_files (void)
 {
-  char *base_name;
-  char *short_base_name;
-
-  base_names (&base_name, &short_base_name);
-
   finput = xfopen (infile, "r");
 
   finput = xfopen (infile, "r");
 
-  if (verbose_flag)
-    {
-      /* We used to use just .out if spec_name_prefix (-p) was used,
-         but that conflicts with Posix.  */
-      outfile = stringappend (base_name, EXT_OUTPUT);
-      foutput = xfopen (outfile, "w");
-    }
-
-  if (no_parser_flag)
-    {
-      /* use permanent name for actions file */
-      actfile = stringappend (short_base_name, ".act");
-    }
-
-  if (defines_flag)
-    {
-      defsfile = stringappend (base_name, ".h");
-    }
-
-  /* These are opened by `done' or `open_extra_files', if at all */
-  if (spec_outfile)
-    tabfile = spec_outfile;
-  else
-    tabfile = stringappend (base_name, ".c");
-
-  attrsfile = stringappend (short_base_name, EXT_STYPE_H);
-  guardfile = stringappend (short_base_name, EXT_GUARD_C);
-
   /* Initialize the obstacks. */
   obstack_init (&action_obstack);
   obstack_init (&attrs_obstack);
   obstack_init (&table_obstack);
   obstack_init (&defines_obstack);
   /* Initialize the obstacks. */
   obstack_init (&action_obstack);
   obstack_init (&attrs_obstack);
   obstack_init (&table_obstack);
   obstack_init (&defines_obstack);
+  obstack_init (&guard_obstack);
+  obstack_init (&output_obstack);
+  obstack_init (&graph_obstack);
 }
 
 
 }
 
 
@@ -297,24 +361,54 @@ open_files (void)
 void
 output_files (void)
 {
 void
 output_files (void)
 {
-  xfclose (fguard);
   xfclose (finput);
   xfclose (finput);
-  xfclose (foutput);
+
+  compute_base_names ();
+
+  /* Set default extensions */
+  if (!src_extension)
+    src_extension = ".c";
+  if (!header_extension)
+    header_extension = ".h";
+
+  attrsfile = stringappend (short_base_name, EXT_STYPE_H);
+#ifndef MSDOS
+  stringappend (attrsfile, header_extension);
+#endif /* MSDOS */
 
   /* Output the main file.  */
 
   /* Output the main file.  */
-  obstack_save (&table_obstack, tabfile);
+  if (spec_outfile)
+    obstack_save (&table_obstack, spec_outfile);
+  else
+    obstack_save (&table_obstack,  stringappend (base_name, src_extension));
 
   /* Output the header file if wanted. */
   if (defines_flag)
 
   /* Output the header file if wanted. */
   if (defines_flag)
-    obstack_save (&defines_obstack, defsfile);
+    obstack_save (&defines_obstack, stringappend (base_name, header_extension));
 
 
-  /* If we output only the table, dump the actions in ACTFILE.
-     */
+  /* If we output only the table, dump the actions in ACTFILE. */
   if (no_parser_flag)
   if (no_parser_flag)
-    obstack_save (&action_obstack, actfile);
+    obstack_save (&action_obstack, stringappend (short_base_name, ".act"));
 
   /* If we produced a semantic parser ATTRS_OBSTACK must be dumped
      into its own file, ATTTRSFILE.  */
   if (semantic_parser)
 
   /* If we produced a semantic parser ATTRS_OBSTACK must be dumped
      into its own file, ATTTRSFILE.  */
   if (semantic_parser)
-    obstack_save (&attrs_obstack, attrsfile);
+    {
+      char *temp_name;
+
+      obstack_save (&attrs_obstack, attrsfile);
+      temp_name = stringappend (short_base_name, EXT_GUARD_C);
+#ifndef MSDOS
+      temp_name = stringappend (temp_name, src_extension);
+#endif /* MSDOS */
+      obstack_save (&guard_obstack, temp_name);
+    }
+
+  if (verbose_flag)
+    /* We used to use just .out if spec_name_prefix (-p) was used, but
+       that conflicts with Posix.  */
+    obstack_save (&output_obstack, stringappend (short_base_name, EXT_OUTPUT));
+
+  if (graph_flag)
+    obstack_save (&graph_obstack, stringappend (short_base_name, ".vcg"));
 }
 }