/[bison]/bison/src/files.c
ViewVC logotype

Diff of /bison/src/files.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.51.2.15 by akim, Tue Jan 8 17:30:53 2002 UTC revision 1.51.2.16 by akim, Tue Jan 8 17:41:38 2002 UTC
# Line 27  Line 27 
27  #include "error.h"  #include "error.h"
28  #include "complain.h"  #include "complain.h"
29    
30    /* From basename.c.  Almost a lie, as it returns a char *. */
31    const char *base_name PARAMS ((char const *name));
32    /* From xstrndup.c.  */
33    char *xstrndup PARAMS ((const char *s, size_t n));
34    
35  FILE *finput = NULL;  FILE *finput = NULL;
36    
37  struct obstack action_obstack;  struct obstack action_obstack;
# Line 46  char *spec_defines_file = NULL; /* for - Line 51  char *spec_defines_file = NULL; /* for -
51  char *infile = NULL;  char *infile = NULL;
52  char *attrsfile = NULL;  char *attrsfile = NULL;
53    
54  static char *base_name = NULL;  static char *full_base_name = NULL;
55  static char *short_base_name = NULL;  static char *short_base_name = NULL;
56    
57  /* C source file extension (the parser source).  */  /* C source file extension (the parser source).  */
# Line 113  compute_header_macro (void) Line 118  compute_header_macro (void)
118      {      {
119        macro_name = XMALLOC (char,        macro_name = XMALLOC (char,
120                              strlen (prefix) +                              strlen (prefix) +
121                              strlen (base_name) +                              strlen (full_base_name) +
122                              strlen (header_extension) + 1);                              strlen (header_extension) + 1);
123        cp = stpcpy (macro_name, prefix);        cp = stpcpy (macro_name, prefix);
124        cp = stpcpy (cp, base_name);        cp = stpcpy (cp, full_base_name);
125        cp = stpcpy (cp, header_extension);        cp = stpcpy (cp, header_extension);
126      }      }
127    
# Line 275  tr (const char *in, char from, char to) Line 280  tr (const char *in, char from, char to)
280    return (temp);    return (temp);
281  }  }
282    
 /* 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);  
 }  
   
283  /* Computes extensions from the grammar file extension. */  /* Computes extensions from the grammar file extension. */
284  static void  static void
285  compute_exts_from_gf (const char *ext)  compute_exts_from_gf (const char *ext)
# Line 318  compute_exts_from_src (const char *ext) Line 302  compute_exts_from_src (const char *ext)
302    header_extension = tr (header_extension, 'C', 'H');    header_extension = tr (header_extension, 'C', 'H');
303  }  }
304    
305    
306    /* Decompose FILENAME in four parts: *BASE, *TAB, and *EXT, the fourth
307       part, (the directory) is ranging from FILENAME to the char before
308       *BASE, so we don't need an additional parameter.
309    
310       *EXT points to the last period in the basename, or NULL if none.
311    
312       If there is no *EXT, *TAB is NULL.  Otherwise, *TAB points to
313       `.tab' or `_tab' if present right before *EXT, or is NULL. *TAB
314       cannot be equal to *BASE.
315    
316       None are allocated, they are simply pointers to parts of FILENAME.
317       Examples:
318    
319       '/tmp/foo.tab.c' -> *BASE = 'foo.tab.c', *TAB = '.tab.c', *EXT =
320       '.c'
321    
322       'foo.c' -> *BASE = 'foo.c', *TAB = NULL, *EXT = '.c'
323    
324       'tab.c' -> *BASE = 'tab.c', *TAB = NULL, *EXT = '.c'
325    
326       '.tab.c' -> *BASE = '.tab.c', *TAB = NULL, *EXT = '.c'
327    
328       'foo.tab' -> *BASE = 'foo.tab', *TAB = NULL, *EXT = '.tab'
329    
330       'foo_tab' -> *BASE = 'foo_tab', *TAB = NULL, *EXT = NULL
331    
332       'foo' -> *BASE = 'foo', *TAB = NULL, *EXT = NULL.  */
333    
334    static void
335    filename_split (const char *filename,
336                    const char **base, const char **tab, const char **ext)
337    {
338      *base = base_name (filename);
339    
340      /* Look for the extension, i.e., look for the last dot. */
341      *ext = strrchr (*base, '.');
342      *tab = NULL;
343    
344      /* If there is an exentension, check if there is a `.tab' part right
345         before.  */
346      if (*ext
347          && (*ext - *base) > (int) strlen (".tab")
348          && (!strncmp (*ext - strlen (".tab"), ".tab", strlen (".tab"))
349              || !strncmp (*ext - strlen ("_tab"), "_tab", strlen ("_tab"))))
350        *tab = *ext - strlen (".tab");
351    }
352    
353    
354  /* FIXME: Should use xstrndup. */  /* FIXME: Should use xstrndup. */
355    
356  static void  static void
357  compute_base_names (void)  compute_base_names (void)
358  {  {
359    size_t base_length;    const char *base, *tab, *ext;
   size_t short_base_length;  
   size_t ext_index;  
360    
361    /* If --output=foo.c was specified (SPEC_OUTFILE == foo.c),    /* If --output=foo.c was specified (SPEC_OUTFILE == foo.c),
362       BASE_NAME and SHORT_BASE_NAME are `foo'.       BASE_NAME and SHORT_BASE_NAME are `foo'.
# Line 337  compute_base_names (void) Line 368  compute_base_names (void)
368       files, remove the ".c" or ".tab.c" suffix.  */       files, remove the ".c" or ".tab.c" suffix.  */
369    if (spec_outfile)    if (spec_outfile)
370      {      {
371  #ifdef MSDOS        filename_split (spec_outfile, &base, &tab, &ext);
       strlwr (spec_outfile);  
 #endif /* MSDOS */  
       /* BASE_LENGTH includes ".tab" but not ".c".  */  
       base_length = strlen (spec_outfile);  
372    
373        ext_index = get_extension_index (spec_outfile);        /* The full base name goes up the EXT, excluding it. */
374        /* If the initial segment of extension contains 'c' or a 'C', I assume        full_base_name =
375           that it is a C or C++ source file.  */          xstrndup (spec_outfile,
376        if (ext_index)                    (strlen (spec_outfile) - (ext ? strlen (ext) : 0)));
377          ext_index =        /* The short base name goes up to TAB, excluding it.  */
378            (strspn (spec_outfile + ext_index + 1, "cC")) ? ext_index : 0;        short_base_name =
379        if (ext_index)          xstrndup (spec_outfile,
380          {                    (strlen (spec_outfile)
381            base_length -= strlen (spec_outfile + ext_index);                     - (tab ? strlen (tab) : (ext ? strlen (ext) : 0))));
           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;  
       if (strsuffix (base_name, ".tab") || strsuffix (base_name, "_tab"))  
         short_base_length -= 4;  
       short_base_name = strndup (spec_outfile, short_base_length);  
382    
383        return;        if (ext)
384            compute_exts_from_src (ext);
385      }      }
386    
387    /* If --file-prefix=foo was specified, BASE_NAME and SHORT_BASE_NAME    /* If --file-prefix=foo was specified, FULL_BASE_NAME = `foo.tab'
388       are `foo'.       and SHORT_BASE_NAME = `foo'.
389    
390       Construct names from it.  */       Construct names from it.  */
391    if (spec_file_prefix)    else
392      {      {
393  #ifdef MSDOS        if (spec_file_prefix)
394        strlwr (spec_file_prefix);          {
395  #endif /* MSDOS */            /* If --file-prefix=foo was specified, SHORT_BASE_NAME =
396        short_base_name = xstrdup (spec_file_prefix);               `foo'.  */
397        base_name = XMALLOC (char,            short_base_name = xstrdup (spec_file_prefix);
398                             strlen (short_base_name) + strlen (EXT_TAB) + 1);          }
399        stpcpy (stpcpy (base_name, short_base_name), EXT_TAB);        else if (yacc_flag)
400            {
401        /* Computes the extensions from the garmmar file name.  */            /* If --yacc, then the output is `y.tab.c'. */
402        ext_index = get_extension_index (infile);            short_base_name = xstrdup ("y");
403        /* If the initial segment of extension contains a 'y' or a 'Y', I assume          }
404           that it is a yacc or bison grammar file.  */        else
405        if (ext_index)          {
406          ext_index = strspn (infile + ext_index + 1, "yY") ? ext_index : 0;            /* Otherwise, the short base name is computed from the input
407        if (ext_index)               grammar: `foo.yy' => `foo'.  */
408          compute_exts_from_gf (infile + ext_index);            filename_split (infile, &base, &tab, &ext);
409              short_base_name =
410        return;              xstrndup (infile,
411                          (strlen (infile) - (ext ? strlen (ext) : 0)));
412            }
413    
414          /* In these cases, always append `.tab'. */
415          full_base_name = XMALLOC (char,
416                                    strlen (short_base_name)
417                                    + strlen (EXT_TAB) + 1);
418          stpcpy (stpcpy (full_base_name, short_base_name), EXT_TAB);
419    
420          /* Computes the extensions from the grammar file name.  */
421          filename_split (infile, &base, &tab, &ext);
422          if (ext)
423            compute_exts_from_gf (ext);
424      }      }
   
   /* 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;  
   }  
425  }  }
426    
427    
428  /*-------------------------------------------------------.  /*-------------------------------------------------------.
429  | Close the open files, compute the output files names.  |  | Close the open files, compute the output files names.  |
430  `-------------------------------------------------------*/  `-------------------------------------------------------*/
# Line 442  compute_output_file_names (void) Line 442  compute_output_file_names (void)
442    
443    /* It the defines filename if not given, we create it.  */    /* It the defines filename if not given, we create it.  */
444    if (!spec_defines_file)    if (!spec_defines_file)
445      spec_defines_file = stringappend (base_name, header_extension);      spec_defines_file = stringappend (full_base_name, header_extension);
446    
447    /* It the graph filename if not given, we create it.  */    /* It the graph filename if not given, we create it.  */
448    if (!spec_graph_file)    if (!spec_graph_file)
# Line 499  output_files (void) Line 499  output_files (void)
499    if (spec_outfile)    if (spec_outfile)
500      obstack_save (&table_obstack, spec_outfile);      obstack_save (&table_obstack, spec_outfile);
501    else    else
502      obstack_save (&table_obstack, stringappend (base_name, src_extension));      obstack_save (&table_obstack,
503                      stringappend (full_base_name, src_extension));
504    obstack_free (&table_obstack, NULL);    obstack_free (&table_obstack, NULL);
505    
506    /* Output the header file if wanted. */    /* Output the header file if wanted. */

Legend:
Removed from v.1.51.2.15  
changed lines
  Added in v.1.51.2.16

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26