]> git.saurik.com Git - bison.git/blobdiff - src/files.c
New file
[bison.git] / src / files.c
index 4946477db8d89d71fd1be154ac608025e6f65ff5..6bf301f906ec9936dda005792ae9afd8c75ac269 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.
 
@@ -34,10 +34,11 @@ struct obstack table_obstack;
 struct obstack defines_obstack;
 struct obstack guard_obstack;
 struct obstack output_obstack;
 struct obstack defines_obstack;
 struct obstack guard_obstack;
 struct obstack output_obstack;
+struct obstack graph_obstack;
 
 char *spec_outfile = NULL;     /* for -o. */
 
 char *spec_outfile = NULL;     /* for -o. */
-char *spec_file_prefix = NULL; /* for -b. */
-char *spec_name_prefix = NULL; /* for -p. */
+char *spec_file_prefix = NULL; /* for -b. */
+char *spec_name_prefix = NULL; /* for -p. */
 
 char *infile = NULL;
 char *attrsfile = NULL;
 
 char *infile = NULL;
 char *attrsfile = NULL;
@@ -45,12 +46,12 @@ char *attrsfile = NULL;
 static char *base_name = NULL;
 static char *short_base_name = NULL;
 
 static char *base_name = NULL;
 static char *short_base_name = NULL;
 
-/* C source file extension (the parser source). */
+/* C source file extension (the parser source).  */
 const char *src_extension = NULL;
 const char *src_extension = NULL;
-/* Header file extension (if option ``-d'' is specified). */
+/* Header file extension (if option ``-d'' is specified).  */
 const char *header_extension = NULL;
 const char *header_extension = NULL;
-
 \f
 \f
+
 /*--------------------------.
 | Is SUFFIX ending STRING?  |
 `--------------------------*/
 /*--------------------------.
 | Is SUFFIX ending STRING?  |
 `--------------------------*/
@@ -83,6 +84,37 @@ stringappend (const char *string1, const char *string2)
   return res;
 }
 
   return res;
 }
 
+
+/*---------------------------------------------------------------.
+|  Computes the macro name used to avoid double inclusion in the |
+|  header of the parser and store it in header_macro_name.       |
+`---------------------------------------------------------------*/
+
+static char *
+compute_header_macro (void)
+{
+  int ite;
+  char *macro_name;
+
+  macro_name = XMALLOC (char,
+                       strlen (base_name) +
+                       strlen (header_extension) + 1);
+
+  stpcpy (macro_name, base_name);
+  strcat (macro_name, header_extension);
+
+  for (ite = 0; macro_name[ite]; ite++)
+    if (macro_name[ite] == '.')
+      macro_name[ite] = '_';
+    else
+      {
+       if (islower (macro_name[ite]))
+         macro_name[ite] -= ('a' - 'A');
+      }
+  return macro_name;
+}
+
+
 /*-----------------------------------------------------------------.
 | Try to open file NAME with mode MODE, and print an error message |
 | if fails.                                                        |
 /*-----------------------------------------------------------------.
 | Try to open file NAME with mode MODE, and print an error message |
 | if fails.                                                        |
@@ -132,6 +164,25 @@ obstack_save (struct obstack *obs, const char *filename)
   xfclose (out);
 }
 
   xfclose (out);
 }
 
+/*---------------------------------------------------------------------.
+| Output double inclusion protection macros and saves defines_obstack  |
+`---------------------------------------------------------------------*/
+
+static void
+defines_obstack_save (const char *filename)
+{
+  FILE *out = xfopen (filename, "w");
+  size_t size = obstack_object_size (&defines_obstack);
+  char *macro_name = compute_header_macro ();
+
+  fprintf (out, "#ifndef %s\n", macro_name);
+  fprintf (out, "# define %s\n\n", macro_name);
+  fwrite (obstack_finish (&defines_obstack), 1, size, out);
+  fprintf (out, "\n#endif /* not %s */\n", macro_name);
+
+  free (macro_name);
+  xfclose (out);
+}
 
 /*------------------------------------------------------------------.
 | Return the path to the skeleton which locaction might be given in |
 
 /*------------------------------------------------------------------.
 | Return the path to the skeleton which locaction might be given in |
@@ -159,16 +210,16 @@ skeleton_find (const char *envvar, const char *skeleton_name)
 
   return res;
 }
 
   return res;
 }
-
 \f
 \f
+
 /*----------------------------------------------------------------.
 | Compute BASE_NAME, SHORT_BASE_NAME and output files extensions. |
 `----------------------------------------------------------------*/
 
 /* Replace all characters FROM by TO in the string IN.
 /*----------------------------------------------------------------.
 | 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. */
+   and returns a new allocated string.  */
 static char *
 static char *
-tr(const char *in, char from, char to)
+tr (const char *in, char from, char to)
 {
   char *temp;
   char *out;
 {
   char *temp;
   char *out;
@@ -184,12 +235,12 @@ tr(const char *in, char from, char to)
   return (temp);
 }
 
   return (temp);
 }
 
-/*  Gets the extension index in FILENAME. Returns 0 if fails to
-    find an extension. */
+/* Gets the extension index in FILENAME. Returns 0 if fails to
+   find an extension.  */
 static int
 static int
-get_extension_index(const char *filename)
+get_extension_index (const char *filename)
 {
 {
-  int  len;
+  int len;
 
   len = strlen (filename);
 
 
   len = strlen (filename);
 
@@ -207,31 +258,34 @@ get_extension_index(const char *filename)
 
 /* Computes extensions from the grammar file extension. */
 static void
 
 /* Computes extensions from the grammar file extension. */
 static void
-compute_exts_from_gf(const char *ext)
+compute_exts_from_gf (const char *ext)
 {
 {
-  if (!src_extension)
+  /* Checks if SRC_EXTENSION is NULL. In the other case, %source_extension
+     was specified in the grammar file.  */
+  if (src_extension == NULL)
     {
     {
-      src_extension = tr(ext, 'y', 'c');
-      src_extension = tr(src_extension, 'Y', 'C');
-    } 
-  if (!header_extension)
+      src_extension = tr (ext, 'y', 'c');
+      src_extension = tr (src_extension, 'Y', 'C');
+    }
+  /* Checks if HEADER_EXTENSION is NULL. In the other case,
+     %header_extension was specified in the grammar file.  */
+  if (header_extension == NULL)
     {
     {
-      header_extension = tr(ext, 'y', 'h');
-      header_extension = tr(header_extension, 'Y', 'H');
+      header_extension = tr (ext, 'y', 'h');
+      header_extension = tr (header_extension, 'Y', 'H');
     }
 }
 
 /* Computes extensions from the given c source file extension. */
 static void
     }
 }
 
 /* Computes extensions from the given c source file extension. */
 static void
-compute_exts_from_src(const char *ext)
+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');
-    }
+  /* We use this function when the user specifies `-o' or `--output',
+     so the extenions must be computed unconditionally from the file name
+     given by this option.  */
+  src_extension = xstrdup (ext);
+  header_extension = tr (ext, 'c', 'h');
+  header_extension = tr (header_extension, 'C', 'H');
 }
 
 /* FIXME: Should use xstrndup. */
 }
 
 /* FIXME: Should use xstrndup. */
@@ -260,14 +314,15 @@ compute_base_names (void)
       base_length = strlen (spec_outfile);
 
       ext_index = get_extension_index (spec_outfile);
       base_length = strlen (spec_outfile);
 
       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 the initial segment of extension contains 'c' or a 'C', I assume
+         that it is a C or C++ source file.  */
       if (ext_index)
       if (ext_index)
-       ext_index = (strspn(spec_outfile + ext_index + 1, "cC")) ? ext_index : 0;
+       ext_index =
+         (strspn (spec_outfile + ext_index + 1, "cC")) ? ext_index : 0;
       if (ext_index)
        {
          base_length -= strlen (spec_outfile + ext_index);
       if (ext_index)
        {
          base_length -= strlen (spec_outfile + ext_index);
-         compute_exts_from_src(spec_outfile + ext_index);
+         compute_exts_from_src (spec_outfile + ext_index);
        }
 
       base_name = strndup (spec_outfile, base_length);
        }
 
       base_name = strndup (spec_outfile, base_length);
@@ -294,6 +349,15 @@ compute_base_names (void)
                           strlen (short_base_name) + strlen (EXT_TAB) + 1);
       stpcpy (stpcpy (base_name, short_base_name), EXT_TAB);
 
                           strlen (short_base_name) + strlen (EXT_TAB) + 1);
       stpcpy (stpcpy (base_name, short_base_name), EXT_TAB);
 
+      /* Computes the extensions from the garmmar file name.  */
+      ext_index = get_extension_index (infile);
+      /* 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 (infile + ext_index + 1, "yY")) ? ext_index : 0;
+      if (ext_index)
+       compute_exts_from_gf (infile + ext_index);
+
       return;
     }
 
       return;
     }
 
@@ -310,14 +374,14 @@ compute_base_names (void)
     base_length = strlen (name_base);
 
     ext_index = get_extension_index (name_base);
     base_length = strlen (name_base);
 
     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 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)
     if (ext_index)
-      ext_index = (strspn(name_base + ext_index + 1, "yY")) ? ext_index : 0;
+      ext_index = (strspn (name_base + ext_index + 1, "yY")) ? ext_index : 0;
     if (ext_index)
       {
        base_length -= strlen (name_base + ext_index);
     if (ext_index)
       {
        base_length -= strlen (name_base + ext_index);
-       compute_exts_from_gf(name_base + ext_index);
+       compute_exts_from_gf (name_base + ext_index);
       }
 
     short_base_length = base_length;
       }
 
     short_base_length = base_length;
@@ -348,6 +412,7 @@ open_files (void)
   obstack_init (&defines_obstack);
   obstack_init (&guard_obstack);
   obstack_init (&output_obstack);
   obstack_init (&defines_obstack);
   obstack_init (&guard_obstack);
   obstack_init (&output_obstack);
+  obstack_init (&graph_obstack);
 }
 
 
 }
 
 
@@ -378,11 +443,11 @@ output_files (void)
   if (spec_outfile)
     obstack_save (&table_obstack, spec_outfile);
   else
   if (spec_outfile)
     obstack_save (&table_obstack, spec_outfile);
   else
-    obstack_save (&table_obstack,  stringappend (base_name, src_extension));
+    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, stringappend (base_name, header_extension));
+    defines_obstack_save (stringappend (base_name, header_extension));
 
   /* If we output only the table, dump the actions in ACTFILE. */
   if (no_parser_flag)
 
   /* If we output only the table, dump the actions in ACTFILE. */
   if (no_parser_flag)
@@ -405,5 +470,9 @@ output_files (void)
   if (verbose_flag)
     /* We used to use just .out if spec_name_prefix (-p) was used, but
        that conflicts with Posix.  */
   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));
+    obstack_save (&output_obstack,
+                 stringappend (short_base_name, EXT_OUTPUT));
+
+  if (graph_flag)
+    obstack_save (&graph_obstack, stringappend (short_base_name, ".vcg"));
 }
 }