/* Protoize program - Original version by Ron Guilmette (rfg@segfault.us.com).
- Copyright (C) 1989, 92-98, 1999 Free Software Foundation, Inc.
+ Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
+ 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
-This file is part of GNU CC.
+This file is part of GCC.
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 2, or (at your option) any later
+version.
-GNU CC 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.
+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.
You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
+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. */
#include "config.h"
#include "system.h"
#include <setjmp.h>
#include <signal.h>
+#if ! defined( SIGCHLD ) && defined( SIGCLD )
+# define SIGCHLD SIGCLD
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
#undef abort
+#include "version.h"
-/* Include getopt.h for the sake of getopt_long. */
+/* Include getopt.h for the sake of getopt_long. */
#include "getopt.h"
-extern char *version_string;
+/* Macro to see if the path elements match. */
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+#define IS_SAME_PATH_CHAR(a,b) (TOUPPER (a) == TOUPPER (b))
+#else
+#define IS_SAME_PATH_CHAR(a,b) ((a) == (b))
+#endif
+
+/* Macro to see if the paths match. */
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+#define IS_SAME_PATH(a,b) (strcasecmp (a, b) == 0)
+#else
+#define IS_SAME_PATH(a,b) (strcmp (a, b) == 0)
+#endif
+
+/* Suffix for aux-info files. */
+#ifdef __MSDOS__
+#define AUX_INFO_SUFFIX "X"
+#else
+#define AUX_INFO_SUFFIX ".X"
+#endif
+
+/* Suffix for saved files. */
+#ifdef __MSDOS__
+#define SAVE_SUFFIX "sav"
+#else
+#define SAVE_SUFFIX ".save"
+#endif
+
+/* Suffix for renamed C++ files. */
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+#define CPLUS_FILE_SUFFIX "cc"
+#else
+#define CPLUS_FILE_SUFFIX "C"
+#endif
static void usage PARAMS ((void)) ATTRIBUTE_NORETURN;
static void aux_info_corrupted PARAMS ((void)) ATTRIBUTE_NORETURN;
static int file_excluded_p PARAMS ((const char *));
static char *unexpand_if_needed PARAMS ((const char *));
static char *abspath PARAMS ((const char *, const char *));
+static int is_abspath PARAMS ((const char *));
static void check_aux_info PARAMS ((int));
static const char *find_corresponding_lparen PARAMS ((const char *));
static int referenced_file_is_newer PARAMS ((const char *, time_t));
/* Suffix of aux_info files. */
-static const char * const aux_info_suffix = ".X";
+static const char * const aux_info_suffix = AUX_INFO_SUFFIX;
/* String to attach to filenames for saved versions of original files. */
-static const char * const save_suffix = ".save";
+static const char * const save_suffix = SAVE_SUFFIX;
+
+/* String to attach to C filenames renamed to C++. */
+
+static const char * const cplus_suffix = CPLUS_FILE_SUFFIX;
#ifndef UNPROTOIZE
/* Type of the structure that holds information about macro unexpansions. */
struct unexpansion_struct {
- const char *expanded;
- const char *contracted;
+ const char *const expanded;
+ const char *const contracted;
};
typedef struct unexpansion_struct unexpansion;
static const int hash_mask = (HASH_TABLE_SIZE - 1);
/* Make a table of default system include directories
- just as it is done in cccp.c. */
+ just as it is done in cpp. */
#ifndef STANDARD_INCLUDE_DIR
#define STANDARD_INCLUDE_DIR "/usr/include"
#define LOCAL_INCLUDE_DIR "/usr/local/include"
#endif
-struct default_include { const char *fname;
- const char *component;
- int x1, x2; } include_defaults[]
+static const struct default_include { const char *const fname;
+ const char *const component;
+ const int x1, x2; } include_defaults[]
#ifdef INCLUDE_DEFAULTS
= INCLUDE_DEFAULTS;
#else
static const char * const other_var_style = "varargs";
/* Note that this is a string containing the expansion of va_alist.
But in `main' we discard all but the first token. */
-static const char *varargs_style_indicator = STRINGIFY (va_alist);
+static const char *varargs_style_indicator = STRINGX (va_alist);
#endif /* !defined (UNPROTOIZE) */
/* The following two types are used to create hash tables. In this program,
static void
notice VPARAMS ((const char *msgid, ...))
{
-#ifndef ANSI_PROTOTYPES
- const char *msgid;
-#endif
- va_list ap;
-
- VA_START (ap, msgid);
-
-#ifndef ANSI_PROTOTYPES
- msgid = va_arg (ap, const char *);
-#endif
+ VA_OPEN (ap, msgid);
+ VA_FIXEDARG (ap, const char *, msgid);
vfprintf (stderr, _(msgid), ap);
- va_end (ap);
+ VA_CLOSE (ap);
}
\f
}
if (nchars == 0)
break;
- ptr += nchars;
+ /* Arithmetic on void pointers is a gcc extension. */
+ ptr = (char *) ptr + nchars;
left -= nchars;
}
return len - left;
pname, shortpath (NULL, out_fname), xstrerror (errno_val));
return;
}
- ptr += written;
+ /* Arithmetic on void pointers is a gcc extension. */
+ ptr = (char *) ptr + written;
len -= written;
}
}
is_id_char (ch)
int ch;
{
- return (ISALNUM (ch) || (ch == '_') || (ch == '$'));
+ return (ISIDNUM (ch) || (ch == '$'));
}
/* Give a message indicating the proper way to invoke this program and then
in_system_include_dir (path)
const char *path;
{
- struct default_include *p;
+ const struct default_include *p;
- if (path[0] != '/')
+ if (! is_abspath (path))
abort (); /* Must be an absolutized filename. */
for (p = include_defaults; p->fname; p++)
if (!strncmp (path, p->fname, strlen (p->fname))
- && path[strlen (p->fname)] == '/')
+ && IS_DIR_SEPARATOR (path[strlen (p->fname)]))
return 1;
return 0;
}
char *dir_last_slash;
strcpy (dir_name, path);
- dir_last_slash = strrchr (dir_name, '/');
+ dir_last_slash = strrchr (dir_name, DIR_SEPARATOR);
+#ifdef DIR_SEPARATOR_2
+ {
+ char *slash;
+
+ slash = strrchr (dir_last_slash ? dir_last_slash : dir_name,
+ DIR_SEPARATOR_2);
+ if (slash)
+ dir_last_slash = slash;
+ }
+#endif
if (dir_last_slash)
*dir_last_slash = '\0';
else
char *dir_last_slash;
strcpy (dir_name, path);
- dir_last_slash = strrchr (dir_name, '/');
+ dir_last_slash = strrchr (dir_name, DIR_SEPARATOR);
+#ifdef DIR_SEPARATOR_2
+ {
+ char *slash;
+
+ slash = strrchr (dir_last_slash ? dir_last_slash : dir_name,
+ DIR_SEPARATOR_2);
+ if (slash)
+ dir_last_slash = slash;
+ }
+#endif
if (dir_last_slash)
*dir_last_slash = '\0';
else
for (p = directory_list; p; p = p->next)
if (!strncmp (name, p->name, strlen (p->name))
- && name[strlen (p->name)] == '/')
+ && IS_DIR_SEPARATOR (name[strlen (p->name)]))
{
const char *q = name + strlen (p->name) + 1;
/* If there are more slashes, it's in a subdir, so
this match doesn't count. */
- while (*q)
- if (*q++ == '/')
+ while (*q++)
+ if (IS_DIR_SEPARATOR (*(q-1)))
goto lose;
return 1;
for (p = exclude_list; p; p = p->next)
if (!strcmp (name + len - strlen (p->name), p->name)
- && name[len - strlen (p->name) - 1] == '/')
+ && IS_DIR_SEPARATOR (name[len - strlen (p->name) - 1]))
return 1;
return 0;
strcpy (copy_p, unexp_p->contracted);
copy_p += size;
- /* Assume the there will not be another replacement required
+ /* Assume that there will not be another replacement required
within the text just replaced. */
s += len;
return (got_unexpanded ? savestring (line_buf, copy_p - line_buf) : 0);
}
\f
+/* Return 1 if pathname is absolute. */
+
+static int
+is_abspath (path)
+ const char *path;
+{
+ return (IS_DIR_SEPARATOR (path[0])
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ /* Check for disk name on MS-DOS-based systems. */
+ || (path[0] && path[1] == ':' && IS_DIR_SEPARATOR (path[2]))
+#endif
+ );
+}
+\f
/* Return the absolutized filename for the given relative
filename. Note that if that filename is already absolute, it may
still be returned in a modified form because this routine also
const char *rel_filename;
{
/* Setup the current working directory as needed. */
- const char *cwd2 = (cwd) ? cwd : cwd_buffer;
+ const char *const cwd2 = (cwd) ? cwd : cwd_buffer;
char *const abs_buffer
= (char *) alloca (strlen (cwd2) + strlen (rel_filename) + 2);
char *endp = abs_buffer;
{
const char *src_p;
- if (rel_filename[0] != '/')
+ if (! is_abspath (rel_filename))
{
src_p = cwd2;
while ((*endp++ = *src_p++))
continue;
- *(endp-1) = '/'; /* overwrite null */
+ *(endp-1) = DIR_SEPARATOR; /* overwrite null */
}
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ else if (IS_DIR_SEPARATOR (rel_filename[0]))
+ {
+ /* A path starting with a directory separator is considered absolute
+ for dos based filesystems, but it's really not -- it's just the
+ convention used throughout GCC and it works. However, in this
+ case, we still need to prepend the drive spec from cwd_buffer. */
+ *endp++ = cwd2[0];
+ *endp++ = cwd2[1];
+ }
+#endif
src_p = rel_filename;
while ((*endp++ = *src_p++))
continue;
outp = inp = abs_buffer;
*outp++ = *inp++; /* copy first slash */
#if defined (apollo) || defined (_WIN32) || defined (__INTERIX)
- if (inp[0] == '/')
+ if (IS_DIR_SEPARATOR (inp[0]))
*outp++ = *inp++; /* copy second slash */
#endif
for (;;)
{
if (!inp[0])
break;
- else if (inp[0] == '/' && outp[-1] == '/')
+ else if (IS_DIR_SEPARATOR (inp[0]) && IS_DIR_SEPARATOR (outp[-1]))
{
inp++;
continue;
}
- else if (inp[0] == '.' && outp[-1] == '/')
+ else if (inp[0] == '.' && IS_DIR_SEPARATOR (outp[-1]))
{
if (!inp[1])
break;
- else if (inp[1] == '/')
+ else if (IS_DIR_SEPARATOR (inp[1]))
{
inp += 2;
continue;
}
- else if ((inp[1] == '.') && (inp[2] == 0 || inp[2] == '/'))
+ else if ((inp[1] == '.') && (inp[2] == 0
+ || IS_DIR_SEPARATOR (inp[2])))
{
- inp += (inp[2] == '/') ? 3 : 2;
+ inp += (IS_DIR_SEPARATOR (inp[2])) ? 3 : 2;
outp -= 2;
- while (outp >= abs_buffer && *outp != '/')
+ while (outp >= abs_buffer && ! IS_DIR_SEPARATOR (*outp))
outp--;
if (outp < abs_buffer)
{
the last character of the returned string is *not* a slash. */
*outp = '\0';
- if (outp[-1] == '/')
+ if (IS_DIR_SEPARATOR (outp[-1]))
*--outp = '\0';
/* Make a copy (in the heap) of the stuff left in the absolutization
path_p = abspath (cwd, filename);
rel_buf_p = rel_buffer = (char *) xmalloc (filename_len);
- while (*cwd_p && (*cwd_p == *path_p))
+ while (*cwd_p && IS_SAME_PATH_CHAR (*cwd_p, *path_p))
{
cwd_p++;
path_p++;
}
- if (!*cwd_p && (!*path_p || *path_p == '/')) /* whole pwd matched */
+ if (!*cwd_p && (!*path_p || IS_DIR_SEPARATOR (*path_p)))
{
+ /* whole pwd matched */
if (!*path_p) /* input *is* the current path! */
return ".";
else
{
--cwd_p;
--path_p;
- while (*cwd_p != '/') /* backup to last slash */
+ while (! IS_DIR_SEPARATOR (*cwd_p)) /* backup to last slash */
{
--cwd_p;
--path_p;
}
/* Find out how many directory levels in cwd were *not* matched. */
- while (*cwd_p)
- if (*cwd_p++ == '/')
+ while (*cwd_p++)
+ if (IS_DIR_SEPARATOR (*(cwd_p-1)))
unmatched_slash_count++;
/* Now we know how long the "short name" will be.
return filename;
*rel_buf_p++ = '.';
*rel_buf_p++ = '.';
- *rel_buf_p++ = '/';
+ *rel_buf_p++ = DIR_SEPARATOR;
}
/* Then tack on the unmatched part of the desired file's name. */
while ((*rel_buf_p++ = *path_p++));
--rel_buf_p;
- if (*(rel_buf_p-1) == '/')
+ if (IS_DIR_SEPARATOR (*(rel_buf_p-1)))
*--rel_buf_p = '\0';
return rel_buffer;
}
{
const char *filename_start = p = l + 3;
- while (*p != ':')
+ while (*p != ':'
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ || (*p == ':' && *p && *(p+1) && IS_DIR_SEPARATOR (*(p+1)))
+#endif
+ )
p++;
filename = (char *) alloca ((size_t) (p - filename_start) + 1);
strncpy (filename, filename_start, (size_t) (p - filename_start));
const char *filename_start = p = l + 3;
char *filename;
- while (*p != ':')
+ while (*p != ':'
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ || (*p == ':' && *p && *(p+1) && IS_DIR_SEPARATOR (*(p+1)))
+#endif
+ )
p++;
filename = (char *) alloca ((size_t) (p - filename_start) + 1);
strncpy (filename, filename_start, (size_t) (p - filename_start));
const char *line_number_start = ++p;
char line_number[10];
- while (*p != ':')
+ while (*p != ':'
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ || (*p == ':' && *p && *(p+1) && IS_DIR_SEPARATOR (*(p+1)))
+#endif
+ )
p++;
strncpy (line_number, line_number_start, (size_t) (p - line_number_start));
line_number[p-line_number_start] = '\0';
= (const char **) alloca ((strlen (params_list) + 8) * sizeof (char *));
int param_count = 0;
const char *param;
+ struct stat st;
temp_params[param_count++] = compiler_file_name;
for (;;)
temp_params[param_count++] = "-S";
temp_params[param_count++] = "-o";
- temp_params[param_count++] = "/dev/null";
+
+ if ((stat (HOST_BIT_BUCKET, &st) == 0)
+ && (!S_ISDIR (st.st_mode))
+ && (access (HOST_BIT_BUCKET, W_OK) == 0))
+ temp_params[param_count++] = HOST_BIT_BUCKET;
+ else
+ /* FIXME: This is hardly likely to be right, if HOST_BIT_BUCKET is not
+ writable. But until this is rejigged to use make_temp_file(), this
+ is the best we can do. */
+ temp_params[param_count++] = "/dev/null";
/* Leave room for the input file name argument. */
input_file_name_index = param_count;
compile_params[input_file_name_index] = shortpath (NULL, base_filename);
/* Add .X to source file name to get aux-info file name. */
compile_params[aux_info_file_name_index] =
- concat (compile_params[input_file_name_index], ".X", NULL);
+ concat (compile_params[input_file_name_index], aux_info_suffix, NULL);
if (!quiet_flag)
notice ("%s: compiling `%s'\n",
{
int aux_info_file;
+ int fd_flags;
/* Open the aux_info file. */
- if ((aux_info_file = open (aux_info_filename, O_RDONLY, 0444 )) == -1)
+ fd_flags = O_RDONLY;
+#ifdef O_BINARY
+ /* Use binary mode to avoid having to deal with different EOL characters. */
+ fd_flags |= O_BINARY;
+#endif
+ if ((aux_info_file = open (aux_info_filename, fd_flags, 0444 )) == -1)
{
int errno_val = errno;
notice ("%s: can't open aux info file `%s' for reading: %s\n",
{
char *p = aux_info_base;
- while (*p != ':')
+ while (*p != ':'
+#ifdef HAVE_DOS_BASED_FILE_SYSTEM
+ || (*p == ':' && *p && *(p+1) && IS_DIR_SEPARATOR (*(p+1)))
+#endif
+ )
p++;
p++;
while (*p == ' ')
invocation_filename = p; /* Save a pointer to first byte of path. */
while (*p != ' ')
p++;
- *p++ = '/';
+ *p++ = DIR_SEPARATOR;
*p++ = '\0';
while (*p++ != '\n')
continue;
aux_info_second_line = p;
aux_info_relocated_name = 0;
- if (invocation_filename[0] != '/')
+ if (! is_abspath (invocation_filename))
{
/* INVOCATION_FILENAME is relative;
append it to BASE_SOURCE_FILENAME's dir. */
char *dir_end;
aux_info_relocated_name = xmalloc (base_len + (p-invocation_filename));
strcpy (aux_info_relocated_name, base_source_filename);
- dir_end = strrchr (aux_info_relocated_name, '/');
+ dir_end = strrchr (aux_info_relocated_name, DIR_SEPARATOR);
+#ifdef DIR_SEPARATOR_2
+ {
+ char *slash;
+
+ slash = strrchr (dir_end ? dir_end : aux_info_relocated_name,
+ DIR_SEPARATOR_2);
+ if (slash)
+ dir_end = slash;
+ }
+#endif
if (dir_end)
dir_end++;
else
{
const char *filename = hp->symbol;
int last_char_index = strlen (filename) - 1;
- char *const new_filename = (char *) alloca (strlen (filename) + 1);
+ char *const new_filename = (char *) alloca (strlen (filename)
+ + strlen (cplus_suffix) + 1);
/* Note that we don't care here if the given file was converted or not. It
is possible that the given file was *not* converted, simply because there
was nothing in it which actually required conversion. Even in this case,
we want to do the renaming. Note that we only rename files with the .c
- suffix. */
+ suffix (except for the syscalls file, which is left alone). */
- if (filename[last_char_index] != 'c' || filename[last_char_index-1] != '.')
+ if (filename[last_char_index] != 'c' || filename[last_char_index-1] != '.'
+ || IS_SAME_PATH (syscalls_absolute_filename, filename))
return;
strcpy (new_filename, filename);
- new_filename[last_char_index] = 'C';
+ strcpy (&new_filename[last_char_index], cplus_suffix);
- if (link (filename, new_filename) == -1)
+ if (rename (filename, new_filename) == -1)
{
int errno_val = errno;
- notice ("%s: warning: can't link file `%s' to `%s': %s\n",
+ notice ("%s: warning: can't rename file `%s' to `%s': %s\n",
pname, shortpath (NULL, filename),
shortpath (NULL, new_filename), xstrerror (errno_val));
errors++;
return;
}
-
- if (unlink (filename) == -1)
- {
- int errno_val = errno;
- notice ("%s: warning: can't delete file `%s': %s\n",
- pname, shortpath (NULL, filename), xstrerror (errno_val));
- errors++;
- return;
- }
}
#endif /* !defined (UNPROTOIZE) */
{
file_info *file_p = hp->fip;
def_dec_info *prev = NULL;
- def_dec_info *current = (def_dec_info *)file_p->defs_decs;
+ def_dec_info *current = (def_dec_info *) file_p->defs_decs;
if (!current)
return; /* no list to reverse */
prev = current;
- if (! (current = (def_dec_info *)current->next_in_file))
+ if (! (current = (def_dec_info *) current->next_in_file))
return; /* can't reverse a single list element */
prev->next_in_file = NULL;
while (current)
{
- def_dec_info *next = (def_dec_info *)current->next_in_file;
+ def_dec_info *next = (def_dec_info *) current->next_in_file;
current->next_in_file = prev;
prev = current;
code being converted contains its own definition of a function which
could have been supplied by libc.a. In such cases, we should avoid
issuing the normal warning, and defer to the definition given in the
- user's own code. */
+ user's own code. */
for (dd_p = head; dd_p; dd_p = dd_p->next_for_func)
if (dd_p->is_func_def && !dd_p->is_static)
for (dd_p2 = dd_p->next_for_func; dd_p2; dd_p2 = dd_p2->next_for_func)
if (!dd_p2->is_func_def && dd_p2->is_static
&& !dd_p2->definition && (dd_p2->file == dd_p->file))
- ((NONCONST def_dec_info *)dd_p2)->definition = dd_p->definition;
+ ((NONCONST def_dec_info *) dd_p2)->definition = dd_p->definition;
}
/* Convert any dummy (-1) definitions we created in the step above back to
by an alphabetic character, while others *cannot* validly be followed
by such characters. */
- if ((ch == '{') || ISALPHA ((unsigned char)ch))
+ if ((ch == '{') || ISALPHA ((unsigned char) ch))
break;
/* At this point, we have found a right paren, but we know that it is
/* Now write out full prototypes for all of the things that had been
implicitly declared in this file (but only those for which we were
actually able to find unique matching definitions). Avoid duplicates
- by marking things that we write out as we go. */
+ by marking things that we write out as we go. */
{
int some_decls_added = 0;
have_newlines |= (*scan_orig == '\n');
/* Leave identical whitespace alone. */
if (!ISSPACE ((const unsigned char)*scan_orig))
- *((NONCONST char *)scan_orig) = ' '; /* identical - so whiteout */
+ *((NONCONST char *) scan_orig) = ' '; /* identical - so whiteout */
}
else
have_flotsam = 1;
while (scan_p[1] != '\'' || scan_p[0] == '\\')
{
if (scan_p[0] == '\\'
- && !ISSPACE ((const unsigned char)scan_p[1]))
+ && !ISSPACE ((const unsigned char) scan_p[1]))
scan_p[1] = ' ';
if (!ISSPACE ((const unsigned char)*scan_p))
*scan_p = ' ';
while (scan_p[1] != '"' || scan_p[0] == '\\')
{
if (scan_p[0] == '\\'
- && !ISSPACE ((const unsigned char)scan_p[1]))
+ && !ISSPACE ((const unsigned char) scan_p[1]))
scan_p[1] = ' ';
if (!ISSPACE ((const unsigned char)*scan_p))
*scan_p = ' ';
{
int input_file;
+ int fd_flags;
/* Open the file to be converted in READ ONLY mode. */
- if ((input_file = open (convert_filename, O_RDONLY, 0444)) == -1)
+ fd_flags = O_RDONLY;
+#ifdef O_BINARY
+ /* Use binary mode to avoid having to deal with different EOL characters. */
+ fd_flags |= O_BINARY;
+#endif
+ if ((input_file = open (convert_filename, fd_flags, 0444)) == -1)
{
int errno_val = errno;
notice ("%s: can't open file `%s' for reading: %s\n",
= (char *) xmalloc (strlen (convert_filename) + strlen (save_suffix) + 2);
strcpy (new_filename, convert_filename);
+#ifdef __MSDOS__
+ /* MSDOS filenames are restricted to 8.3 format, so we save `foo.c'
+ as `foo.<save_suffix>'. */
+ new_filename[(strlen (convert_filename) - 1] = '\0';
+#endif
strcat (new_filename, save_suffix);
- if (link (convert_filename, new_filename) == -1)
+
+ /* Don't overwrite existing file. */
+ if (access (new_filename, F_OK) == 0)
+ {
+ if (!quiet_flag)
+ notice ("%s: warning: file `%s' already saved in `%s'\n",
+ pname,
+ shortpath (NULL, convert_filename),
+ shortpath (NULL, new_filename));
+ }
+ else if (rename (convert_filename, new_filename) == -1)
{
int errno_val = errno;
- if (errno_val == EEXIST)
- {
- if (!quiet_flag)
- notice ("%s: warning: file `%s' already saved in `%s'\n",
- pname,
- shortpath (NULL, convert_filename),
- shortpath (NULL, new_filename));
- }
- else
- {
- notice ("%s: can't link file `%s' to `%s': %s\n",
- pname,
- shortpath (NULL, convert_filename),
- shortpath (NULL, new_filename),
- xstrerror (errno_val));
- return;
- }
+ notice ("%s: can't link file `%s' to `%s': %s\n",
+ pname,
+ shortpath (NULL, convert_filename),
+ shortpath (NULL, new_filename),
+ xstrerror (errno_val));
+ return;
}
}
if (unlink (convert_filename) == -1)
{
int errno_val = errno;
- notice ("%s: can't delete file `%s': %s\n",
- pname, shortpath (NULL, convert_filename),
- xstrerror (errno_val));
- return;
+ /* The file may have already been renamed. */
+ if (errno_val != ENOENT)
+ {
+ notice ("%s: can't delete file `%s': %s\n",
+ pname, shortpath (NULL, convert_filename),
+ xstrerror (errno_val));
+ return;
+ }
}
{
xstrerror (errno_val));
return;
}
+#ifdef O_BINARY
+ /* Use binary mode to avoid changing the existing EOL character. */
+ setmode (output_file, O_BINARY);
+#endif
/* Write the output file. */
}
syscalls_len = strlen (syscalls_absolute_filename);
- if (*(syscalls_absolute_filename + syscalls_len - 1) != '/')
+ if (! IS_DIR_SEPARATOR (*(syscalls_absolute_filename + syscalls_len - 1)))
{
- *(syscalls_absolute_filename + syscalls_len++) = '/';
+ *(syscalls_absolute_filename + syscalls_len++) = DIR_SEPARATOR;
*(syscalls_absolute_filename + syscalls_len) = '\0';
}
strcat (syscalls_absolute_filename, syscalls_filename);
#endif /* !defined (UNPROTOIZE) */
}
\f
-static struct option longopts[] =
+static const struct option longopts[] =
{
{"version", 0, 0, 'V'},
{"file_name", 0, 0, 'p'},
int c;
const char *params = "";
- pname = strrchr (argv[0], '/');
+ pname = strrchr (argv[0], DIR_SEPARATOR);
+#ifdef DIR_SEPARATOR_2
+ {
+ char *slash;
+
+ slash = strrchr (pname ? pname : argv[0], DIR_SEPARATOR_2);
+ if (slash)
+ pname = slash;
+ }
+#endif
pname = pname ? pname+1 : argv[0];
-#ifdef HAVE_LC_MESSAGES
- setlocale (LC_MESSAGES, "");
+#ifdef SIGCHLD
+ /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
+ receive the signal. A different setting is inheritable */
+ signal (SIGCHLD, SIG_DFL);
#endif
- (void) bindtextdomain (PACKAGE, localedir);
- (void) textdomain (PACKAGE);
+
+ gcc_init_libintl ();
cwd_buffer = getpwd ();
if (!cwd_buffer)
{
const char *cp;
- for (cp = varargs_style_indicator;
- ISALNUM ((const unsigned char)*cp) || *cp == '_'; cp++)
+ for (cp = varargs_style_indicator; ISIDNUM (*cp); cp++)
continue;
if (*cp != 0)
varargs_style_indicator = savestring (varargs_style_indicator,