bison-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

02-fyi-1-28-filename-split.patch


From: Akim Demaille
Subject: 02-fyi-1-28-filename-split.patch
Date: Tue, 08 Jan 2002 18:27:08 +0100

Index: ChangeLog
from  Akim Demaille  <address@hidden>

        * lib/Makefile.am (libbison_a_SOURCES): Add xstrndup.c.
        * src/getargs.c (AS_FILE_NAME): New.
        (getargs): Use it to convert DOSish file names.
        * src/files.c (base_name): Rename as full_base_name to avoid
        clashes with `base_name ()'.
        (filename_split): New.
        (compute_base_names): N-th rewrite, using filename_split.

Index: src/getargs.c
--- src/getargs.c Tue, 08 Jan 2002 17:53:20 +0100 akim
+++ src/getargs.c Tue, 08 Jan 2002 18:18:14 +0100 akim
@@ -159,6 +159,14 @@ Output:\n\
 | Process the options.  |
 `----------------------*/

+/* Under DOS, there is no difference on the case.  This can be
+   troublesome when looking for `.tab' etc.  */
+#ifdef MSDOS
+# define AS_FILE_NAME(File) (strlwr (File), (File))
+#else
+# define AS_FILE_NAME(File) (File)
+#endif
+
 void
 getargs (int argc, char *argv[])
 {
@@ -186,7 +194,7 @@ Output:\n\
       case 'g':
        /* Here, the -g and --graph=FILE options are differentiated.  */
        graph_flag = 1;
-       spec_graph_file = optarg;
+       spec_graph_file = AS_FILE_NAME (optarg);
        break;

       case 'v':
@@ -194,13 +202,13 @@ Output:\n\
        break;

       case 'S':
-       skeleton = optarg;
+       skeleton = AS_FILE_NAME (optarg);
        break;

       case 'd':
        /* Here, the -d and --defines options are differentiated.  */
        defines_flag = 1;
-       spec_defines_file = optarg;
+       spec_defines_file = AS_FILE_NAME (optarg);
        break;

       case 'l':
@@ -224,11 +232,11 @@ Output:\n\
        break;

       case 'o':
-       spec_outfile = optarg;
+       spec_outfile = AS_FILE_NAME (optarg);
        break;

       case 'b':
-       spec_file_prefix = optarg;
+       spec_file_prefix = AS_FILE_NAME (optarg);
        break;

       case 'p':
Index: src/files.c
--- src/files.c Tue, 08 Jan 2002 17:53:20 +0100 akim
+++ src/files.c Tue, 08 Jan 2002 18:16:14 +0100 akim
@@ -27,6 +27,11 @@
 #include "error.h"
 #include "complain.h"

+/* From basename.c.  Almost a lie, as it returns a char *. */
+const char *base_name PARAMS ((char const *name));
+/* From xstrndup.c.  */
+char *xstrndup PARAMS ((const char *s, size_t n));
+
 FILE *finput = NULL;

 struct obstack action_obstack;
@@ -46,7 +51,7 @@
 char *infile = NULL;
 char *attrsfile = NULL;

-static char *base_name = NULL;
+static char *full_base_name = NULL;
 static char *short_base_name = NULL;

 /* C source file extension (the parser source).  */
@@ -113,10 +118,10 @@
     {
       macro_name = XMALLOC (char,
                            strlen (prefix) +
-                           strlen (base_name) +
+                           strlen (full_base_name) +
                            strlen (header_extension) + 1);
       cp = stpcpy (macro_name, prefix);
-      cp = stpcpy (cp, base_name);
+      cp = stpcpy (cp, full_base_name);
       cp = stpcpy (cp, header_extension);
     }

@@ -318,11 +323,61 @@
   header_extension = tr (header_extension, 'C', 'H');
 }

+
+/* Decompose FILENAME in four parts: *BASE, *TAB, and *EXT, the fourth
+   part, (the directory) is ranging from FILENAME to the char before
+   *BASE, so we don't need an additional parameter.
+
+   *EXT points to the last period in the basename, or NULL if none.
+
+   If there is no *EXT, *TAB is NULL.  Otherwise, *TAB points to
+   `.tab' or `_tab' if present right before *EXT, or is NULL. *TAB
+   cannot be equal to *BASE.
+
+   None are allocated, they are simply pointers to parts of FILENAME.
+   Examples:
+
+   '/tmp/foo.tab.c' -> *BASE = 'foo.tab.c', *TAB = '.tab.c', *EXT =
+   '.c'
+
+   'foo.c' -> *BASE = 'foo.c', *TAB = NULL, *EXT = '.c'
+
+   'tab.c' -> *BASE = 'tab.c', *TAB = NULL, *EXT = '.c'
+
+   '.tab.c' -> *BASE = '.tab.c', *TAB = NULL, *EXT = '.c'
+
+   'foo.tab' -> *BASE = 'foo.tab', *TAB = NULL, *EXT = '.tab'
+
+   'foo_tab' -> *BASE = 'foo_tab', *TAB = NULL, *EXT = NULL
+
+   'foo' -> *BASE = 'foo', *TAB = NULL, *EXT = NULL.  */
+
+static void
+filename_split (const char *filename,
+               const char **base, const char **tab, const char **ext)
+{
+  *base = base_name (filename);
+
+  /* Look for the extension, i.e., look for the last dot. */
+  *ext = strrchr (*base, '.');
+  *tab = NULL;
+
+  /* If there is an exentension, check if there is a `.tab' part right
+     before.  */
+  if (*ext
+      && (*ext - *base) > strlen (".tab")
+      && (!strncmp (*ext - strlen (".tab"), ".tab", strlen (".tab"))
+         || !strncmp (*ext - strlen ("_tab"), "_tab", strlen ("_tab"))))
+    *tab = *ext - strlen (".tab");
+}
+
+
 /* FIXME: Should use xstrndup. */

 static void
 compute_base_names (void)
 {
+  const char *base, *tab, *ext;
   size_t base_length;
   size_t short_base_length;
   size_t ext_index;
@@ -337,94 +392,64 @@
      files, remove the ".c" or ".tab.c" suffix.  */
   if (spec_outfile)
     {
-#ifdef MSDOS
-      strlwr (spec_outfile);
-#endif /* MSDOS */
-      /* BASE_LENGTH includes ".tab" but not ".c".  */
-      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 (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);
-       }
+      const char *cp;
+      filename_split (spec_outfile, &base, &tab, &ext);

-      base_name = strndup (spec_outfile, base_length);
-      /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c".  */
-      short_base_length = base_length;
-      if (strsuffix (base_name, ".tab") || strsuffix (base_name, "_tab"))
-       short_base_length -= 4;
-      short_base_name = strndup (spec_outfile, short_base_length);
+      /* The full base name goes up the EXT, excluding it. */
+      full_base_name =
+       xstrndup (spec_outfile,
+                 (strlen (spec_outfile) - (ext ? strlen (ext) : 0)));
+      /* The short base name goes up to TAB, excluding it.  */
+      short_base_name =
+       xstrndup (spec_outfile,
+                 (strlen (spec_outfile)
+                  - (tab ? strlen (tab) : (ext ? strlen (ext) : 0))));

-      return;
+      if (ext)
+       compute_exts_from_src (ext);
     }

-  /* If --file-prefix=foo was specified, BASE_NAME and SHORT_BASE_NAME
-     are `foo'.
+  /* If --file-prefix=foo was specified, FULL_BASE_NAME = `foo.tab'
+     and SHORT_BASE_NAME = `foo'.

      Construct names from it.  */
-  if (spec_file_prefix)
+  else
     {
-#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);
-
-      /* 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);
+      if (spec_file_prefix)
+       {
+         /* If --file-prefix=foo was specified, SHORT_BASE_NAME =
+            `foo'.  */
+         short_base_name = xstrdup (spec_file_prefix);
+       }
+      else if (yacc_flag)
+       {
+         /* If --yacc, then the output is `y.tab.c'. */
+         short_base_name = xstrdup ("y");
+       }
+      else
+       {
+         /* Otherwise, the short base name is computed from the input
+            grammar: `foo.yy' => `foo'.  */
+         filename_split (infile, &base, &tab, &ext);
+         short_base_name =
+           xstrndup (infile,
+                     (strlen (infile) - (ext ? strlen (ext) : 0)));
+       }

-      return;
+      /* In these cases, always append `.tab'. */
+      full_base_name = XMALLOC (char,
+                               strlen (short_base_name)
+                               + strlen (EXT_TAB) + 1);
+      stpcpy (stpcpy (full_base_name, short_base_name), EXT_TAB);
+
+      /* Computes the extensions from the grammar file name.  */
+      filename_split (infile, &base, &tab, &ext);
+      if (ext)
+       compute_exts_from_gf (ext);
     }
-
-  /* If neither -o nor --file-prefix were specified, and the input
-     file is foo.y, BASE_NAME is `foo.tab', and SHORT_BASE_NAME is
-     `foo'.
-
-     If --yacc is used, do as if the input file was `y.y'.  */
-  {
-    const char *name_base = yacc_flag ? "y.y" : infile;
-
-    /* BASE_LENGTH gets length of BASE_NAME, sans ".y" suffix if any.  */
-
-    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 (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_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);
-
-    return;
-  }
 }

+
 /*-------------------------------------------------------.
 | Close the open files, compute the output files names.  |
 `-------------------------------------------------------*/
@@ -442,7 +467,7 @@

   /* It the defines filename if not given, we create it.  */
   if (!spec_defines_file)
-    spec_defines_file = stringappend (base_name, header_extension);
+    spec_defines_file = stringappend (full_base_name, header_extension);

   /* It the graph filename if not given, we create it.  */
   if (!spec_graph_file)
@@ -499,7 +524,8 @@
   if (spec_outfile)
     obstack_save (&table_obstack, spec_outfile);
   else
-    obstack_save (&table_obstack, stringappend (base_name, src_extension));
+    obstack_save (&table_obstack,
+                 stringappend (full_base_name, src_extension));
   obstack_free (&table_obstack, NULL);

   /* Output the header file if wanted. */
Index: lib/Makefile.am
--- lib/Makefile.am Tue, 08 Jan 2002 18:11:59 +0100 akim
+++ lib/Makefile.am Tue, 08 Jan 2002 18:16:31 +0100 akim
@@ -32,7 +32,7 @@
   basename.c dirname.h dirname.c \
   getopt.h getopt.c getopt1.c \
   quote.h quote.c quotearg.h quotearg.c \
-  xalloc.h xmalloc.c xstrdup.c
+  xalloc.h xmalloc.c xstrdup.c xstrndup.c

 libbison_a_LIBADD = @LIBOBJS@ @ALLOCA@
 libbison_a_DEPENDENCIES = $(libbison_a_LIBADD)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]