]>
git.saurik.com Git - bison.git/blob - src/files.c
0b958c1ae40d4c0a8414cdab91ce6e88df20f84f
   1 /* Open and close files for bison, 
   2    Copyright 1984, 1986, 1989, 1992, 2000, 2001 Free Software Foundation, Inc. 
   4    This file is part of Bison, the GNU Compiler Compiler. 
   6    Bison is free software; you can redistribute it and/or modify it 
   7    under the terms of the GNU General Public License as published by 
   8    the Free Software Foundation; either version 2, or (at your option) 
  11    Bison is distributed in the hope that it will be useful, but 
  12    WITHOUT ANY WARRANTY; without even the implied warranty of 
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  14    General Public License for more details. 
  16    You should have received a copy of the GNU General Public License 
  17    along with Bison; see the file COPYING.  If not, write to the Free 
  18    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 
  31 struct obstack action_obstack
; 
  32 struct obstack attrs_obstack
; 
  33 struct obstack output_obstack
; 
  35 char *spec_outfile 
= NULL
;      /* for -o. */ 
  36 char *spec_file_prefix 
= NULL
;  /* for -b. */ 
  37 const char *spec_name_prefix 
= "yy";    /* for -p. */ 
  38 char *spec_verbose_file 
= NULL
;   /* for --verbose. */ 
  39 char *spec_graph_file 
= NULL
;   /* for -g. */ 
  40 char *spec_defines_file 
= NULL
; /* for --defines. */ 
  41 char *parser_file_name 
= NULL
; 
  44 char *attrsfile 
= NULL
; 
  46 static char *base_name 
= NULL
; 
  47 static char *short_base_name 
= NULL
; 
  49 /* C source file extension (the parser source).  */ 
  50 const char *src_extension 
= NULL
; 
  51 /* Header file extension (if option ``-d'' is specified).  */ 
  52 const char *header_extension 
= NULL
; 
  55 /*--------------------------. 
  56 | Is SUFFIX ending STRING?  | 
  57 `--------------------------*/ 
  60 strsuffix (const char *string
, const char *suffix
) 
  62   size_t string_len 
= strlen (string
); 
  63   size_t suffix_len 
= strlen (suffix
); 
  64   if (suffix_len 
<= string_len
) 
  65     return !strcmp (string 
+ string_len 
- suffix_len
, suffix
); 
  71 /*-----------------------------------------------------------------. 
  72 | Return a newly allocated string composed of the concatenation of | 
  73 | STRING1, and STRING2.                                            | 
  74 `-----------------------------------------------------------------*/ 
  77 stringappend (const char *string1
, const char *string2
) 
  79   size_t len 
= strlen (string1
) + strlen (string2
); 
  80   char *res 
= XMALLOC (char, len 
+ 1); 
  82   cp 
= stpcpy (res
, string1
); 
  83   cp 
= stpcpy (cp
, string2
); 
  88 /*-----------------------------------------------------------------. 
  89 | Computes the macro name used to avoid double inclusion in the    | 
  90 | header of the parser and store it in header_macro_name.  Be sure | 
  91 | to produce valid CPP names (don't start with digit, remain       | 
  92 | alphanumerical + underscore).                                    | 
  93 `-----------------------------------------------------------------*/ 
  96 compute_header_macro (void) 
  98   const char *prefix 
= "BISON_"; 
  99   char *macro_name
, *cp
; 
 101   if (spec_defines_file
) 
 103       macro_name 
= XMALLOC (char, 
 105                             strlen (spec_defines_file
) + 1); 
 106       cp 
= stpcpy (macro_name
, prefix
); 
 107       cp 
= stpcpy (cp
, spec_defines_file
); 
 111       macro_name 
= XMALLOC (char, 
 114                             strlen (header_extension
) + 1); 
 115       cp 
= stpcpy (macro_name
, prefix
); 
 116       cp 
= stpcpy (cp
, base_name
); 
 117       cp 
= stpcpy (cp
, header_extension
); 
 120   for (cp 
= macro_name
; *cp
; ++cp
) 
 123     else if (!isalnum (*cp
)) 
 130 /*-----------------------------------------------------------------. 
 131 | Try to open file NAME with mode MODE, and print an error message | 
 133 `-----------------------------------------------------------------*/ 
 136 xfopen (const char *name
, const char *mode
) 
 140   ptr 
= fopen (name
, mode
); 
 142     error (2, errno
, _("cannot open file `%s'"), name
); 
 147 /*-------------------------------------------------------------. 
 148 | Try to close file PTR, and print an error message if fails.  | 
 149 `-------------------------------------------------------------*/ 
 159   result 
= fclose (ptr
); 
 161     error (2, errno
, _("cannot close file")); 
 167 /*------------------------------------------------------------------. 
 168 | Return the path to the skeleton which locaction might be given in | 
 169 | ENVVAR, otherwise return SKELETON_NAME.                           | 
 170 `------------------------------------------------------------------*/ 
 173 skeleton_find (const char *envvar
, const char *skeleton_name
) 
 175   const char *res 
= getenv (envvar
); 
 177 #if defined (MSDOS) || defined (_WIN32) 
 180       /* Skeleton file name without path */ 
 181       const char *skel_name 
= strrchr (skeleton_name
, '/'); 
 183         skel_name 
= strrchr (skeleton_name
, '\\'); 
 185         skel_name 
= skeleton_name
; 
 189       /* File doesn't exist in current directory; try in INIT directory.  */ 
 190       const char *cp 
= getenv ("INIT"); 
 193           res 
= XMALLOC (char, strlen (cp
) + strlen (skel_name
) + 2); 
 194           sprintf (res
, "%s%c%s", cp
, '\\', skel_name
); 
 196       else if (access (skel_name
, 4) == 0) /* Look in current dir. */ 
 200           /* Look in program locations dir. */ 
 201           extern char *program_name
; 
 202           cp 
= strrchr(program_name
, '\\'); 
 204             return skeleton_name
; 
 207           res 
= XMALLOC (char, cp 
- program_name 
+ strlen (skel_name
) + 1); 
 208           strncpy (res
, program_name
, cp 
- program_name
); 
 209           strcpy (res 
+ (cp 
- program_name
), skel_name
); 
 212 #endif /* defined (MSDOS) || defined (_WIN32) */ 
 220 /*----------------------------------------------------------------. 
 221 | Compute BASE_NAME, SHORT_BASE_NAME and output files extensions. | 
 222 `----------------------------------------------------------------*/ 
 224 /* Replace all characters FROM by TO in the string IN. 
 225    and returns a new allocated string.  */ 
 227 tr (const char *in
, char from
, char to
) 
 232   out 
= XMALLOC (char, strlen (in
) + 1); 
 234   for (temp 
= out
; *in
; in
++, out
++) 
 243 /* Gets the extension index in FILENAME. Returns 0 if fails to 
 244    find an extension.  */ 
 246 get_extension_index (const char *filename
) 
 250   len 
= strlen (filename
); 
 252   if (filename
[len
-- - 1] == '.') 
 255   while ((len 
> 0) && (filename
[len 
- 1] != '.')) 
 256     if (filename
[len 
- 1] == '/') 
 264 /* Computes extensions from the grammar file extension. */ 
 266 compute_exts_from_gf (const char *ext
) 
 268   src_extension 
= tr (ext
, 'y', 'c'); 
 269   src_extension 
= tr (src_extension
, 'Y', 'C'); 
 270   header_extension 
= tr (ext
, 'y', 'h'); 
 271   header_extension 
= tr (header_extension
, 'Y', 'H'); 
 274 /* Computes extensions from the given c source file extension. */ 
 276 compute_exts_from_src (const char *ext
) 
 278   /* We use this function when the user specifies `-o' or `--output', 
 279      so the extenions must be computed unconditionally from the file name 
 280      given by this option.  */ 
 281   src_extension 
= xstrdup (ext
); 
 282   header_extension 
= tr (ext
, 'c', 'h'); 
 283   header_extension 
= tr (header_extension
, 'C', 'H'); 
 286 /* FIXME: Should use xstrndup. */ 
 289 compute_base_names (void) 
 292   size_t short_base_length
; 
 295   /* If --output=foo.c was specified (SPEC_OUTFILE == foo.c), 
 296      BASE_NAME and SHORT_BASE_NAME are `foo'. 
 298      If --output=foo.tab.c was specified, BASE_NAME is `foo.tab' and 
 299      SHORT_BASE_NAME is `foo'. 
 301      The precise -o name will be used for FTABLE.  For other output 
 302      files, remove the ".c" or ".tab.c" suffix.  */ 
 306       strlwr (spec_outfile
); 
 308       /* BASE_LENGTH includes ".tab" but not ".c".  */ 
 309       base_length 
= strlen (spec_outfile
); 
 311       ext_index 
= get_extension_index (spec_outfile
); 
 312       /* If the initial segment of extension contains 'c' or a 'C', I assume 
 313          that it is a C or C++ source file.  */ 
 316           (strspn (spec_outfile 
+ ext_index 
+ 1, "cC")) ? ext_index 
: 0; 
 319           base_length 
-= strlen (spec_outfile 
+ ext_index
); 
 320           compute_exts_from_src (spec_outfile 
+ ext_index
); 
 323       base_name 
= strndup (spec_outfile
, base_length
); 
 324       /* SHORT_BASE_LENGTH includes neither ".tab" nor ".c".  */ 
 325       short_base_length 
= base_length
; 
 326       if (strsuffix (base_name
, ".tab") || strsuffix (base_name
, "_tab")) 
 327         short_base_length 
-= 4; 
 328       short_base_name 
= strndup (spec_outfile
, short_base_length
); 
 333   /* If --file-prefix=foo was specified, BASE_NAME and SHORT_BASE_NAME 
 336      Construct names from it.  */ 
 337   if (spec_file_prefix
) 
 340       strlwr (spec_file_prefix
); 
 342       short_base_name 
= xstrdup (spec_file_prefix
); 
 343       base_name 
= XMALLOC (char, 
 344                            strlen (short_base_name
) + strlen (EXT_TAB
) + 1); 
 345       stpcpy (stpcpy (base_name
, short_base_name
), EXT_TAB
); 
 347       /* Computes the extensions from the garmmar file name.  */ 
 348       ext_index 
= get_extension_index (infile
); 
 349       /* If the initial segment of extension contains a 'y' or a 'Y', I assume 
 350          that it is a yacc or bison grammar file.  */ 
 352         ext_index 
= (strspn (infile 
+ ext_index 
+ 1, "yY")) ? ext_index 
: 0; 
 354         compute_exts_from_gf (infile 
+ ext_index
); 
 359   /* If neither -o nor --file-prefix were specified, and the input 
 360      file is foo.y, BASE_NAME is `foo.tab', and SHORT_BASE_NAME is 
 363      If --yacc is used, do as if the input file was `y.y'.  */ 
 365     const char *name_base 
= yacc_flag 
? "y.y" : infile
; 
 367     /* BASE_LENGTH gets length of BASE_NAME, sans ".y" suffix if any.  */ 
 369     base_length 
= strlen (name_base
); 
 371     ext_index 
= get_extension_index (name_base
); 
 372     /* If the initial segment of extension contains a 'y' or a 'Y', I assume 
 373        that it is a yacc or bison grammar file.  */ 
 375       ext_index 
= (strspn (name_base 
+ ext_index 
+ 1, "yY")) ? ext_index 
: 0; 
 378         base_length 
-= strlen (name_base 
+ ext_index
); 
 379         compute_exts_from_gf (name_base 
+ ext_index
); 
 382     short_base_length 
= base_length
; 
 383     short_base_name 
= strndup (name_base
, short_base_length
); 
 385     base_name 
= XMALLOC (char, 
 386                          strlen (short_base_name
) + strlen (EXT_TAB
) + 1); 
 387     stpcpy (stpcpy (base_name
, short_base_name
), EXT_TAB
); 
 393 /*-------------------------------------------------------. 
 394 | Close the open files, compute the output files names.  | 
 395 `-------------------------------------------------------*/ 
 398 compute_output_file_names (void) 
 400   compute_base_names (); 
 403     spec_outfile 
? spec_outfile 
: stringappend (base_name
, src_extension
); 
 405   /* If not yet done. */ 
 407     src_extension 
= ".c"; 
 408   if (!header_extension
) 
 409     header_extension 
= ".h"; 
 411   /* It the defines filename if not given, we create it.  */ 
 412   if (!spec_defines_file
) 
 413     spec_defines_file 
= stringappend (base_name
, header_extension
); 
 415   /* It the graph filename if not given, we create it.  */ 
 416   if (!spec_graph_file
) 
 417     spec_graph_file 
= stringappend (short_base_name
, ".vcg"); 
 419   spec_verbose_file 
= stringappend (short_base_name
, EXT_OUTPUT
); 
 421   attrsfile 
= stringappend (short_base_name
, EXT_STYPE_H
); 
 423   attrsfile 
= stringappend (attrsfile
, header_extension
);