files which are fixed to work correctly with ANSI C and placed in a
directory that GCC will search.
- Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1998, 1999, 2000, 2004 Free Software Foundation, Inc.
This file is part of GCC.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GNU General Public License for more de\atails.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA. */
#include "fixlib.h"
+#include <fnmatch.h>
+#include <sys/stat.h>
+#ifndef SEPARATE_FIX_PROC
+#include <sys/wait.h>
+#endif
+
#if defined( HAVE_MMAP_FILE )
#include <sys/mman.h>
#define BAD_ADDR ((void*)-1)
#endif
-#if ! defined( SIGCHLD ) && defined( SIGCLD )
-# define SIGCHLD SIGCLD
-#endif
#ifndef SEPARATE_FIX_PROC
#include "server.h"
#endif
This had to be done to correct non-standard usages in the\n\
original, manufacturer supplied header file. */\n\n";
-/* Working environment strings. Essentially, invocation 'options'. */
-
-#define _ENV_(v,m,n,t) tCC* v = NULL;
-ENV_TABLE
-#undef _ENV_
-
int find_base_len = 0;
typedef enum {
void
initialize ( int argc, char** argv )
{
- static const char var_not_found[] =
-#ifndef __STDC__
- "fixincl ERROR: %s environment variable not defined\n"
-#else
- "fixincl ERROR: %s environment variable not defined\n"
- "each of these must be defined:\n"
-# define _ENV_(vv,mm,nn,tt) "\t" nn " - " tt "\n"
- ENV_TABLE
-# undef _ENV_
-#endif
- ;
-
xmalloc_set_program_name (argv[0]);
switch (argc)
signal (SIGCHLD, SIG_DFL);
#endif
-#define _ENV_(v,m,n,t) { tSCC var[] = n; \
- v = getenv (var); if (m && (v == NULL)) { \
- fprintf (stderr, var_not_found, var); \
- exit (EXIT_FAILURE); } }
-
-ENV_TABLE
-
-#undef _ENV_
+ initialize_opts ();
if (ISDIGIT ( *pz_verbose ))
verbose_level = (te_verbose)atoi( pz_verbose );
# endif
signal (SIGQUIT, SIG_IGN);
-#ifdef SIGIOT
signal (SIGIOT, SIG_IGN);
-#endif
-#ifdef SIGPIPE
signal (SIGPIPE, SIG_IGN);
-#endif
signal (SIGALRM, SIG_IGN);
signal (SIGTERM, SIG_IGN);
}
static int
machine_matches( tFixDesc* p_fixd )
- {
-# ifndef SEPARATE_FIX_PROC
- tSCC case_fmt[] = "case %s in\n"; /* 9 bytes, plus string */
- tSCC esac_fmt[] =
- " )\n echo %s ;;\n* ) echo %s ;;\nesac";/* 4 bytes */
- tSCC skip[] = "skip"; /* 4 bytes */
- tSCC run[] = "run"; /* 3 bytes */
- /* total bytes to add to machine sum: 49 - see fixincl.tpl */
-
- const char **papz_machs = p_fixd->papz_machs;
- char *pz;
- const char *pz_sep = "";
- tCC *pz_if_true;
- tCC *pz_if_false;
- char cmd_buf[ MACH_LIST_SIZE_LIMIT ]; /* size lim from fixincl.tpl */
-
- /* Start the case statement */
-
- sprintf (cmd_buf, case_fmt, pz_machine);
- pz = cmd_buf + strlen (cmd_buf);
-
- /* Determine if a match means to apply the fix or not apply it */
-
- if (p_fixd->fd_flags & FD_MACH_IFNOT)
- {
- pz_if_true = skip;
- pz_if_false = run;
- }
- else
- {
- pz_if_true = run;
- pz_if_false = skip;
- }
-
- /* Emit all the machine names. If there are more than one,
- then we will insert " | \\\n" between the names */
-
- for (;;)
- {
- const char* pz_mach = *(papz_machs++);
-
- if (pz_mach == (const char*) NULL)
- break;
- sprintf (pz, "%s%s", pz_sep, pz_mach);
- pz += strlen (pz);
- pz_sep = " | \\\n";
- }
-
- /* Now emit the match and not-match actions and the esac */
-
- sprintf (pz, esac_fmt, pz_if_true, pz_if_false);
-
- /* Run the script.
- The result will start either with 's' or 'r'. */
-
- {
- int skip;
- pz = run_shell (cmd_buf);
- skip = (*pz == 's');
- free ( (void*)pz );
- if (skip)
- {
- p_fixd->fd_flags |= FD_SKIP_TEST;
- return BOOL_FALSE;
- }
- }
+{
+ char const ** papz_machs = p_fixd->papz_machs;
+ int have_match = BOOL_FALSE;
- return BOOL_TRUE;
-# else /* is SEPARATE_FIX_PROC */
- const char **papz_machs = p_fixd->papz_machs;
- int invert = (p_fixd->fd_flags & FD_MACH_IFNOT) != 0;
for (;;)
{
- const char* pz_mach = *(papz_machs++);
-
- if (pz_mach == (const char*) NULL)
+ char const * pz_mpat = *(papz_machs++);
+ if (pz_mpat == NULL)
break;
- if (strstr (pz_mach, "dos") != NULL && !invert)
- return BOOL_TRUE;
+ if (fnmatch(pz_mpat, pz_machine, 0) == 0)
+ {
+ have_match = BOOL_TRUE;
+ break;
+ }
}
- p_fixd->fd_flags |= FD_SKIP_TEST;
- return BOOL_FALSE;
-# endif
+ /* Check for sense inversion then set the "skip test" flag, if needed */
+ if (p_fixd->fd_flags & FD_MACH_IFNOT)
+ have_match = ! have_match;
+
+ if (! have_match)
+ p_fixd->fd_flags |= FD_SKIP_TEST;
+
+ return have_match;
}
/* * * * * * * * * * * * *
-
- run_compiles run all the regexp compiles for all the fixes once.
- */
+ *
+ * run_compiles run all the regexp compiles for all the fixes once.
+ */
void
run_compiles (void)
{
tFixDesc *p_fixd = fixDescList;
int fix_ct = FIX_COUNT;
- regex_t *p_re = xcalloc (REGEX_COUNT, sizeof (regex_t));
+ regex_t *p_re = XCNEWVEC (regex_t, REGEX_COUNT);
/* Make sure compile_re does not stumble across invalid data */
*pz_dir = NUL;
if (stat (fname, &stbf) < 0)
{
+#ifdef _WIN32
+ mkdir (fname);
+#else
mkdir (fname, S_IFDIR | S_DIRALL);
+#endif
}
*pz_dir = '/';
* Make the fd passed in the stdin, and the write end of
* the new pipe become the stdout.
*/
- fcntl (fd[1], F_DUPFD, STDOUT_FILENO);
- fcntl (read_fd, F_DUPFD, STDIN_FILENO);
+ dup2 (fd[1], STDOUT_FILENO);
+ dup2 (read_fd, STDIN_FILENO);
apply_fix (p_fixd, pz_curr_file);
exit (0);
if (p_fixd->fd_flags & FD_SUBROUTINE)
{
- tSCC z_applyfix_prog[] = "/fixinc/applyfix";
+ static const char z_applyfix_prog[] =
+ "/../fixincludes/applyfix" EXE_EXT;
+ struct stat buf;
argsize = 32
- + strlen( pz_orig_dir )
- + sizeof( z_applyfix_prog )
- + strlen( pz_fix_file )
- + strlen( pz_file_source )
- + strlen( pz_temp_file );
+ + strlen (pz_orig_dir)
+ + sizeof (z_applyfix_prog)
+ + strlen (pz_fix_file)
+ + strlen (pz_file_source)
+ + strlen (pz_temp_file);
+
+ /* Allocate something sure to be big enough for our purposes */
+ pz_cmd = XNEWVEC (char, argsize);
+ strcpy (pz_cmd, pz_orig_dir);
+ pz_scan = pz_cmd + strlen (pz_orig_dir);
+
+ strcpy (pz_scan, z_applyfix_prog);
- pz_cmd = xmalloc (argsize);
+ /* IF we can't find the "applyfix" executable file at the first guess,
+ try one level higher up */
+ if (stat (pz_cmd, &buf) == -1)
+ {
+ strcpy (pz_scan, "/..");
+ strcpy (pz_scan+3, z_applyfix_prog);
+ }
- strcpy( pz_cmd, pz_orig_dir );
- pz_scan = pz_cmd + strlen( pz_orig_dir );
- strcpy( pz_scan, z_applyfix_prog );
- pz_scan += sizeof( z_applyfix_prog ) - 1;
- *(pz_scan++) = ' ';
+ pz_scan += strlen (pz_scan);
/*
* Now add the fix number and file names that may be needed
*/
- sprintf (pz_scan, "%ld \'%s\' \'%s\' \'%s\'", p_fixd - fixDescList,
+ sprintf (pz_scan, " %ld '%s' '%s'", (long) (p_fixd - fixDescList),
pz_fix_file, pz_file_source, pz_temp_file);
}
else /* NOT an "internal" fix: */
the following bizarre use of 'cat' only works on DOS boxes.
It causes the file to be dropped into a temporary file for
'cat' to read (pipes do not work on DOS). */
- tSCC z_cmd_fmt[] = " \'%s\' | cat > \'%s\'";
+ tSCC z_cmd_fmt[] = " '%s' | cat > '%s'";
#else
/* Don't use positional formatting arguments because some lame-o
implementations cannot cope :-(. */
}
/* Estimated buffer size we will need. */
- pz_scan = pz_cmd = xmalloc (argsize);
+ pz_scan = pz_cmd = XNEWVEC (char, argsize);
/* How much of it do we allot to the program name and its
arguments. */
parg_size = argsize - parg_size;
else
{
tSCC z_cmd_fmt[] = "file='%s'\n%s";
- pz_cmd = xmalloc (strlen (p_fixd->patch_args[2])
+ pz_cmd = XNEWVEC (char, strlen (p_fixd->patch_args[2])
+ sizeof (z_cmd_fmt) + strlen (pz_fix_file));
sprintf (pz_cmd, z_cmd_fmt, pz_fix_file, p_fixd->patch_args[2]);
pz_cmd_save = p_fixd->patch_args[2];
/* * * * * * * * * * * * *
-
- Process the potential fixes for a particular include file.
- Input: the original text of the file and the file's name
- Result: none. A new file may or may not be created. */
-
+ *
+ * Process the potential fixes for a particular include file.
+ * Input: the original text of the file and the file's name
+ * Result: none. A new file may or may not be created.
+ */
static t_bool
fix_applies (tFixDesc* p_fixd)
{
int test_ct;
tTestDesc *p_test;
-# ifdef SEPARATE_FIX_PROC
+#ifdef SEPARATE_FIX_PROC
/*
* There is only one fix that uses a shell script as of this writing.
* I hope to nuke it anyway, it does not apply to DOS and it would
*/
if (p_fixd->fd_flags & (FD_SHELL_SCRIPT | FD_SKIP_TEST))
return BOOL_FALSE;
-# else
+#else
if (p_fixd->fd_flags & FD_SKIP_TEST)
return BOOL_FALSE;
-# endif
+#endif
/* IF there is a file name restriction,
THEN ensure the current file name matches one in the pattern */
if (pz_scan != (char *) NULL)
{
- size_t name_len;
-
while ((pz_fname[0] == '.') && (pz_fname[1] == '/'))
pz_fname += 2;
- name_len = strlen (pz_fname);
for (;;)
{
- pz_scan = strstr (pz_scan + 1, pz_fname);
- /* IF we can't match the string at all,
- THEN bail */
- if (pz_scan == (char *) NULL)
- return BOOL_FALSE;
-
- /* IF the match is surrounded by the '|' markers,
- THEN we found a full match -- time to run the tests */
-
- if ((pz_scan[-1] == '|') && (pz_scan[name_len] == '|'))
+ if (fnmatch (pz_scan, pz_fname, 0) == 0)
break;
+ pz_scan += strlen (pz_scan) + 1;
+ if (*pz_scan == NUL)
+ return BOOL_FALSE;
}
}
{
FILE* out_fp = create_file ();
- fputs (pz_text, out_fp);
+ size_t sz = strlen (pz_text);
+ fwrite (pz_text, sz, 1, out_fp);
+ if (pz_text[ sz-1 ] != '\n')
+ fputc ('\n', out_fp);
fclose (out_fp);
}
}