OSDN Git Service

* config/h8300/h8300.c (h8300_adjust_insn_length): Clean up.
[pf3gnuchains/gcc-fork.git] / gcc / protoize.c
index 8b51851..f8d8a9e 100644 (file)
@@ -1,22 +1,23 @@
 /* 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"
@@ -24,12 +25,52 @@ Boston, MA 02111-1307, USA.  */
 
 #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;
@@ -50,6 +91,7 @@ static int directory_specified_p PARAMS ((const char *));
 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));
@@ -93,11 +135,15 @@ static const char * const target_version = DEFAULT_TARGET_VERSION;
 
 /* 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
 
@@ -121,8 +167,8 @@ static char * syscalls_absolute_filename;
 /* 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;
 
@@ -149,7 +195,7 @@ static const unexpansion unexpansions[] = {
 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"
@@ -159,9 +205,9 @@ static const int hash_mask = (HASH_TABLE_SIZE - 1);
 #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
@@ -232,7 +278,7 @@ static const char * const other_var_style = "stdarg";
 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,
@@ -518,19 +564,11 @@ static char * saved_repl_write_ptr;
 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
@@ -617,7 +655,7 @@ safe_read (desc, ptr, len)
       }
     if (nchars == 0)
       break;
-    /* Arithmetic on void pointers is a gcc extention.  */
+    /* Arithmetic on void pointers is a gcc extension.  */
     ptr = (char *) ptr + nchars;
     left -= nchars;
   }
@@ -647,7 +685,7 @@ safe_write (desc, ptr, len, out_fname)
                pname, shortpath (NULL, out_fname), xstrerror (errno_val));
        return;
       }
-    /* Arithmetic on void pointers is a gcc extention.  */
+    /* Arithmetic on void pointers is a gcc extension.  */
     ptr = (char *) ptr + written;
     len -= written;
   }
@@ -678,7 +716,7 @@ static int
 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
@@ -705,14 +743,14 @@ static int
 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;
 }
@@ -734,7 +772,17 @@ file_could_be_converted (const char *path)
     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
@@ -768,7 +816,17 @@ file_normally_convertible (const char *path)
     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
@@ -875,14 +933,14 @@ directory_specified_p (name)
 
   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;
 
@@ -903,7 +961,7 @@ file_excluded_p (name)
 
   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;
@@ -1077,7 +1135,7 @@ unexpand_if_needed (aux_info_line)
               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;
@@ -1107,6 +1165,20 @@ continue_outer: ;
   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
@@ -1123,7 +1195,7 @@ abspath (cwd, rel_filename)
      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;
@@ -1135,13 +1207,24 @@ abspath (cwd, rel_filename)
   {
     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;
@@ -1153,32 +1236,33 @@ abspath (cwd, rel_filename)
   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)
                      {
@@ -1201,7 +1285,7 @@ abspath (cwd, rel_filename)
      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
@@ -1239,13 +1323,14 @@ shortpath (cwd, filename)
   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
@@ -1257,7 +1342,7 @@ shortpath (cwd, filename)
         {
           --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;
@@ -1268,8 +1353,8 @@ shortpath (cwd, filename)
         }
 
       /* 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.
@@ -1286,7 +1371,7 @@ shortpath (cwd, filename)
            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.  */
@@ -1298,7 +1383,7 @@ shortpath (cwd, filename)
       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;
     }
@@ -1421,7 +1506,11 @@ referenced_file_is_newer (l, aux_info_mtime)
   {
     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));
@@ -1479,7 +1568,11 @@ save_def_or_dec (l, is_syscalls)
     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));
@@ -1506,7 +1599,11 @@ save_def_or_dec (l, is_syscalls)
     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';
@@ -1850,6 +1947,7 @@ munge_compile_params (params_list)
     = (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 (;;)
@@ -1896,7 +1994,16 @@ munge_compile_params (params_list)
 
   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;
@@ -1927,7 +2034,7 @@ gen_aux_info_file (base_filename)
   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",
@@ -2116,10 +2223,16 @@ start_over: ;
 
   {
     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",
@@ -2184,7 +2297,11 @@ start_over: ;
   {
     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 == ' ')
@@ -2192,20 +2309,30 @@ start_over: ;
     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
@@ -2297,38 +2424,31 @@ rename_c_file (hp)
 {
   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) */
@@ -2347,20 +2467,20 @@ reverse_def_dec_list (hp)
 {
   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;
@@ -2418,7 +2538,7 @@ find_extern_def (head, user)
      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)
@@ -2705,7 +2825,7 @@ connect_defs_and_decs (hp)
       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
@@ -3340,7 +3460,7 @@ find_rightmost_formals_list (clean_text_p)
          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
@@ -3525,7 +3645,7 @@ add_global_decls (file_p, clean_text_p)
   /* 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;
@@ -3686,7 +3806,7 @@ edit_fn_definition (def_dec_p, clean_text_p)
             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;
@@ -3757,7 +3877,7 @@ do_cleaning (new_clean_text_base, new_clean_text_limit)
             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 = ' ';
@@ -3772,7 +3892,7 @@ do_cleaning (new_clean_text_base, new_clean_text_limit)
             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 = ' ';
@@ -4057,10 +4177,16 @@ edit_file (hp)
 
   {
     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",
@@ -4206,37 +4332,45 @@ edit_file (hp)
        = (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;
+       }
     }
 
   {
@@ -4252,6 +4386,10 @@ edit_file (hp)
                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.  */
   
@@ -4342,9 +4480,9 @@ do_processing ()
     }
 
   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);
@@ -4393,7 +4531,7 @@ do_processing ()
 #endif /* !defined (UNPROTOIZE) */
 }
 \f
-static struct option longopts[] =
+static const struct option longopts[] =
 {
   {"version", 0, 0, 'V'},
   {"file_name", 0, 0, 'p'},
@@ -4428,14 +4566,25 @@ main (argc, argv)
   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)
@@ -4551,8 +4700,7 @@ main (argc, argv)
   {
     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,