-/* Protoize program - Original version by Ron Guilmette at MCC.
-
- Copyright (C) 1989, 1992 Free Software Foundation, Inc.
+/* Protoize program - Original version by Ron Guilmette (rfg@segfault.us.com).
+ Copyright (C) 1989, 92-96, 1997 Free Software Foundation, Inc.
This file is part of GNU CC.
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
/* Any reasonable C++ compiler should have all of the same features
as __STDC__ plus more, so make sure that __STDC__ is defined if
- __cplusplus is defined. */
+ __cplusplus is defined. */
#if defined(__cplusplus) && !defined(__STDC__)
#define __STDC__ 1
#ifdef POSIX /* We should be able to define _POSIX_SOURCE unconditionally,
but some systems respond in buggy ways to it,
- including Sunos 4.1.1. Which we don't classify as POSIX. */
+ including SunOS 4.1.1. Which we don't classify as POSIX. */
/* In case this is a POSIX system with an ANSI C compiler,
ask for definition of all POSIX facilities. */
#undef _POSIX_SOURCE
#define _POSIX_SOURCE
#endif
+#include <varargs.h>
+/* On some systems stdio.h includes stdarg.h;
+ we must bring in varargs.h first. */
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef POSIX
+#if ! defined (_WIN32) || defined (__CYGWIN32__)
+#if defined(POSIX) || defined(CONCURRENT)
#include <dirent.h>
#else
#include <sys/dir.h>
#endif
+#endif
#include <setjmp.h>
-#include "gvarargs.h"
+
+#include "gansidecl.h"
/* Include getopt.h for the sake of getopt_long.
We don't need the declaration of getopt, and it could conflict
with something from a system header file, so effectively nullify that. */
#define getopt getopt_loser
#include "getopt.h"
+#undef getopt
+#ifndef errno
extern int errno;
+#endif
+
+#ifndef HAVE_STRERROR
+extern int sys_nerr;
+#if defined(bsd4_4)
+extern const char *const sys_errlist[];
+#else
extern char *sys_errlist[];
+#endif
+#else
+extern char *strerror();
+#endif
+
extern char *version_string;
/* Systems which are compatible only with POSIX 1003.1-1988 (but *not*
#define my_access(file,flag) access((char *)file, flag)
#define my_stat(file,pkt) stat((char *)file, pkt)
-#define my_execvp(prog,argv) execvp((char *)prog, (char **)argv)
#define my_link(file1, file2) link((char *)file1, (char *)file2)
#define my_unlink(file) unlink((char *)file)
#define my_open(file, mode, flag) open((char *)file, mode, flag)
extern char *getpwd ();
+extern char *choose_temp_base PROTO ((void));
+
+extern int pexecute PROTO ((const char *, char * const *, const char *,
+ const char *, char **, char **, int));
+extern int pwait PROTO ((int, int *, int));
+/* Flag arguments to pexecute. */
+#define PEXECUTE_FIRST 1
+#define PEXECUTE_LAST 2
+#define PEXECUTE_SEARCH 4
+
/* Aliases for pointers to void.
These were made to facilitate compilation with old brain-dead DEC C
compilers which didn't properly grok `void*' types. */
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
-#include <string.h>
+#include <sys/wait.h>
#else /* !defined(POSIX) */
#define X_OK 1 /* Test for eXecute permission */
#define F_OK 0 /* Test for existence of File */
+#ifndef O_RDONLY
#define O_RDONLY 0
+#endif
+
+#ifndef O_WRONLY
#define O_WRONLY 1
+#endif
+
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(S) (((S) & 0xff) != 0 && ((S) & 0xff) != 0x7f)
+#endif
+#ifndef WTERMSIG
+#define WTERMSIG(S) ((S) & 0x7f)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(S) (((S) & 0xff) == 0)
+#endif
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(S) (((S) & 0xff00) >> 8)
+#endif
/* Declaring stat or __flsbuf with a prototype
causes conflicts with system headers on some systems. */
#ifndef abort
-extern VOLATILE void abort ();
+typedef void voidfn ();
+extern VOLATILE voidfn abort;
#endif
-extern int kill ();
extern int creat ();
#if 0 /* These conflict with stdio.h on some systems. */
extern int fprintf (FILE *, const char *, ...);
extern int open (const char *, int, ...);
#endif /* 0 */
extern void exit ();
-extern pointer_type malloc ();
-extern pointer_type realloc ();
extern void free ();
extern int read ();
extern int write ();
extern int link ();
extern int unlink ();
extern int access ();
-extern int execvp ();
-#ifndef setjmp
-extern int setjmp ();
-#endif
-#ifndef longjmp
-extern void longjmp ();
-#endif
-extern char * strcat ();
-extern int strcmp ();
-extern char * strcpy ();
#if 0 /* size_t from sys/types.h may fail to match GCC.
If so, we would get a warning from this. */
extern size_t strlen ()
#endif
-extern int strncmp ();
-extern char * strncpy ();
-extern char * strrchr ();
/* Fork is not declared because the declaration caused a conflict
on the HPPA. */
#endif /* !defined (POSIX) */
+extern char *rindex ();
+
/* Look for these where the `const' qualifier is intentionally cast aside. */
#define NONCONST
#endif /* !defined (UNPROTOIZE) */
-/* Type of the structure that holds information about macro unexpansions. */
+/* Type of the structure that holds information about macro unexpansions. */
struct unexpansion_struct {
const char *expanded;
#define LOCAL_INCLUDE_DIR "/usr/local/include"
#endif
-struct default_include { const char *fname; int cplusplus; } include_defaults[]
+struct default_include { const char *fname; int x1, x2; } include_defaults[]
#ifdef INCLUDE_DEFAULTS
= INCLUDE_DEFAULTS;
#else
= {
/* Pick up GNU C++ specific include files. */
- { GPLUSPLUS_INCLUDE_DIR, 1},
- { GCC_INCLUDE_DIR, 0},
+ { GPLUSPLUS_INCLUDE_DIR, 1, 1 },
#ifdef CROSS_COMPILE
+ /* This is the dir for fixincludes. Put it just before
+ the files that we fix. */
+ { GCC_INCLUDE_DIR, 0, 0 },
/* For cross-compilation, this dir name is generated
automatically in Makefile.in. */
- { CROSS_INCLUDE_DIR, 0 },
+ { CROSS_INCLUDE_DIR, 0, 0 },
+ /* This is another place that the target system's headers might be. */
+ { TOOL_INCLUDE_DIR, 0, 0 },
#else /* not CROSS_COMPILE */
- { LOCAL_INCLUDE_DIR, 0},
+ /* This should be /use/local/include and should come before
+ the fixincludes-fixed header files. */
+ { LOCAL_INCLUDE_DIR, 0, 1 },
+ /* This is here ahead of GCC_INCLUDE_DIR because assert.h goes here.
+ Likewise, behind LOCAL_INCLUDE_DIR, where glibc puts its assert.h. */
+ { TOOL_INCLUDE_DIR, 0, 0 },
+ /* This is the dir for fixincludes. Put it just before
+ the files that we fix. */
+ { GCC_INCLUDE_DIR, 0, 0 },
/* Some systems have an extra dir of include files. */
#ifdef SYSTEM_INCLUDE_DIR
- { SYSTEM_INCLUDE_DIR, 0},
+ { SYSTEM_INCLUDE_DIR, 0, 0 },
#endif
- { STANDARD_INCLUDE_DIR, 0},
+ { STANDARD_INCLUDE_DIR, 0, 0},
#endif /* not CROSS_COMPILE */
- { 0, 0}
+ { 0, 0, 0}
};
#endif /* no INCLUDE_DEFAULTS */
static int local_flag = 0; /* Insert new local decls (when?). */
static int global_flag = 0; /* set by -g option */
static int cplusplus_flag = 0; /* Rename converted files to *.C. */
-static const char* nondefault_syscalls_dir = 0; /* Dir to look for
+static const char *nondefault_syscalls_dir = 0; /* Dir to look for
SYSCALLS.c.X in. */
#endif /* !defined (UNPROTOIZE) */
/* Pointer to relative root string (taken from aux_info file) which indicates
where directory the user was in when he did the compilation step that
- produced the containing aux_info file. */
+ produced the containing aux_info file. */
static const char *invocation_filename;
static const char *shortpath ();
\f
+char *
+my_strerror(e)
+ int e;
+{
+
+#ifdef HAVE_STRERROR
+ return strerror(e);
+
+#else
+
+ static char buffer[30];
+ if (!e)
+ return "";
+
+ if (e > 0 && e < sys_nerr)
+ return sys_errlist[e];
+
+ sprintf (buffer, "Unknown error %d", e);
+ return buffer;
+#endif
+}
+\f
/* Allocate some space, but check that the allocation was successful. */
/* alloca.c uses this, so don't make it static. */
{
pointer_type rv;
- rv = malloc (byte_count);
+ rv = (pointer_type) malloc (byte_count);
if (rv == NULL)
{
- fprintf (stderr, "\n%s: fatal error: can't allocate %u more bytes of memory\n",
- pname, byte_count);
- exit (1);
+ fprintf (stderr, "\n%s: virtual memory exceeded\n", pname);
+ exit (FATAL_EXIT_CODE);
return 0; /* avoid warnings */
}
else
{
pointer_type rv;
- rv = realloc (old_space, byte_count);
+ rv = (pointer_type) realloc (old_space, byte_count);
if (rv == NULL)
{
- fprintf (stderr, "\n%s: fatal error: can't allocate %u more bytes of memory\n",
- pname, byte_count);
- exit (1);
+ fprintf (stderr, "\n%s: virtual memory exceeded\n", pname);
+ exit (FATAL_EXIT_CODE);
return 0; /* avoid warnings */
}
else
fancy_abort ()
{
fprintf (stderr, "%s: internal abort\n", pname);
- exit (1);
+ exit (FATAL_EXIT_CODE);
}
\f
-/* Make a duplicate of a given string in a newly allocated area. */
-
-static char *
-dupstr (s)
- const char *s;
-{
- return strcpy ((char *) xmalloc (strlen (s) + 1), s);
-}
-
/* Make a duplicate of the first N bytes of a given string in a newly
allocated area. */
const char *s;
size_t n;
{
- char *ret_val = strncpy ((char *) xmalloc (n + 1), s, n);
+ char *ret_val = (char *) xmalloc (n + 1);
+ strncpy (ret_val, s, n);
ret_val[n] = '\0';
return ret_val;
}
return 0;
}
\f
+/* Read LEN bytes at PTR from descriptor DESC, for file FILENAME,
+ retrying if necessary. Return the actual number of bytes read. */
+
+static int
+safe_read (desc, ptr, len)
+ int desc;
+ char *ptr;
+ int len;
+{
+ int left = len;
+ while (left > 0) {
+ int nchars = read (desc, ptr, left);
+ if (nchars < 0)
+ {
+#ifdef EINTR
+ if (errno == EINTR)
+ continue;
+#endif
+ return nchars;
+ }
+ if (nchars == 0)
+ break;
+ ptr += nchars;
+ left -= nchars;
+ }
+ return len - left;
+}
+
+/* Write LEN bytes at PTR to descriptor DESC,
+ retrying if necessary, and treating any real error as fatal. */
+
+static void
+safe_write (desc, ptr, len, out_fname)
+ int desc;
+ char *ptr;
+ int len;
+ char *out_fname;
+{
+ while (len > 0) {
+ int written = write (desc, ptr, len);
+ if (written < 0)
+ {
+#ifdef EINTR
+ if (errno == EINTR)
+ continue;
+#endif
+ fprintf (stderr, "%s: error writing file `%s': %s\n",
+ pname, shortpath (NULL, out_fname), my_strerror(errno));
+ return;
+ }
+ ptr += written;
+ len -= written;
+ }
+}
+\f
/* Get setup to recover in case the edit we are about to do goes awry. */
void
repl_write_ptr = saved_repl_write_ptr;
}
-/* Return true if the given character is a legal identifier character. */
+/* Return true if the given character is a valid identifier character. */
static int
is_id_char (ch)
fprintf (stderr, "%s: usage '%s [ -VqfnkN ] [ -i <istring> ] [ filename ... ]'\n",
pname, pname);
#else /* !defined (UNPROTOIZE) */
- fprintf (stderr, "%s: usage '%s [ -VqfnkNlgC ] [ -B <diname> ] [ filename ... ]'\n",
+ fprintf (stderr, "%s: usage '%s [ -VqfnkNlgC ] [ -B <dirname> ] [ filename ... ]'\n",
pname, pname);
#endif /* !defined (UNPROTOIZE) */
- exit (1);
+ exit (FATAL_EXIT_CODE);
}
/* Return true if the given filename (assumed to be an absolute filename)
char *dir_last_slash;
strcpy (dir_name, path);
- dir_last_slash = strrchr (dir_name, '/');
+ dir_last_slash = rindex (dir_name, '/');
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 = rindex (dir_name, '/');
if (dir_last_slash)
*dir_last_slash = '\0';
else
#ifndef UNPROTOIZE
- /* ... and if we a protoizing and this function is in old style ... */
+ /* ... and if we a protoizing and this function is in old style ... */
!ddp->prototyped
- /* ... and if this a definition or is a decl with an associated def ... */
+ /* ... and if this a definition or is a decl with an associated def ... */
&& (ddp->is_func_def || (!ddp->is_func_def && ddp->definition))
#else /* defined (UNPROTOIZE) */
- /* ... and if we are unprotoizing and this function is in new style ... */
+ /* ... and if we are unprotoizing and this function is in new style ... */
ddp->prototyped
#endif /* defined (UNPROTOIZE) */
const char *s;
{
p->hash_next = NULL;
- p->symbol = dupstr (s);
+ p->symbol = savestring (s, strlen (s));
p->ddip = NULL;
p->fip = NULL;
return p;
{
static char *line_buf = 0;
static int line_buf_size = 0;
- const unexpansion* unexp_p;
+ const unexpansion *unexp_p;
int got_unexpanded = 0;
const char *s;
char *copy_p = line_buf;
copy_p = line_buf + offset;
}
*copy_p++ = '\n';
- *copy_p++ = '\0';
+ *copy_p = '\0';
- return (got_unexpanded ? dupstr (line_buf) : 0);
+ return (got_unexpanded ? savestring (line_buf, copy_p - line_buf) : 0);
}
\f
/* Return the absolutized filename for the given relative
while (outp >= abs_buffer && *outp != '/')
outp--;
if (outp < abs_buffer)
- {
- /* Catch cases like /.. where we try to backup to a
- point above the absolute root of the logical file
- system. */
-
- fprintf (stderr, "%s: invalid file name: %s\n",
- pname, rel_filename);
- exit (1);
- }
+ {
+ /* Catch cases like /.. where we try to backup to a
+ point above the absolute root of the logical file
+ system. */
+
+ fprintf (stderr, "%s: invalid file name: %s\n",
+ pname, rel_filename);
+ exit (FATAL_EXIT_CODE);
+ }
*++outp = '\0';
continue;
- }
+ }
}
*outp++ = *inp++;
}
/* Make a copy (in the heap) of the stuff left in the absolutization
buffer and return a pointer to the copy. */
- return dupstr (abs_buffer);
+ return savestring (abs_buffer, outp - abs_buffer);
}
\f
/* Given a filename (and possibly a directory name from which the filename
{
if (my_stat (filename, &stat_buf) == -1)
{
- fprintf (stderr, "%s: error: can't get status of `%s': %s\n",
- pname, shortpath (NULL, filename), sys_errlist[errno]);
+ fprintf (stderr, "%s: %s: can't get status: %s\n",
+ pname, shortpath (NULL, filename), my_strerror(errno));
stat_buf.st_mtime = (time_t) -1;
}
}
{
fprintf (stderr, "\n%s: fatal error: aux info file corrupted at line %d\n",
pname, current_aux_info_lineno);
- exit (1);
+ exit (FATAL_EXIT_CODE);
}
/* ??? This comment is vague. Say what the condition is for. */
}
/* Given a pointer to the closing right parenthesis for a particular formals
- list (in a aux_info file) find the corresponding left parenthesis and
+ list (in an aux_info file) find the corresponding left parenthesis and
return a pointer to it. */
static const char *
/* Check that this record describes a new-style, old-style, or implicit
definition or declaration. */
- p++; /* Skip over the `:'. */
+ p++; /* Skip over the `:'. */
check_aux_info ((*p == 'N') || (*p == 'O') || (*p == 'I'));
/* Is this a new style (ANSI prototyped) definition or declaration? */
def_dec_p->ansi_decl
= dupnstr (ansi_start, (size_t) ((semicolon_p+1) - ansi_start));
- }
- /* Backup and point at the final right paren of the final argument list. */
+ /* Backup and point at the final right paren of the final argument list. */
+
+ p--;
+
+#ifndef UNPROTOIZE
+ def_dec_p->f_list_chain = NULL;
+#endif /* !defined (UNPROTOIZE) */
- p--;
+ while (p != ansi_start && (p[-1] == ' ' || p[-1] == '\t')) p--;
+ if (*p != ')')
+ {
+ free_def_dec (def_dec_p);
+ return;
+ }
+ }
/* Now isolate a whole set of formal argument lists, one-by-one. Normally,
there will only be one list to isolate, but there could be more. */
def_dec_p->f_list_count = 0;
-#ifndef UNPROTOIZE
- def_dec_p->f_list_chain = NULL;
-#endif /* !defined (UNPROTOIZE) */
-
for (;;)
{
const char *left_paren_p = find_corresponding_lparen (p);
#ifndef UNPROTOIZE
{
- f_list_chain_item *cip =
- (f_list_chain_item *) xmalloc (sizeof (f_list_chain_item));
+ f_list_chain_item *cip
+ = (f_list_chain_item *) xmalloc (sizeof (f_list_chain_item));
cip->formals_list
= dupnstr (left_paren_p + 1, (size_t) (p - (left_paren_p+1)));
{
if (strcmp (def_dec_p->ansi_decl, other->ansi_decl))
{
- fprintf (stderr, "%s: error: declaration of function `%s' at %s(%d) takes different forms\n",
- pname,
- def_dec_p->hash_entry->symbol,
+ fprintf (stderr, "%s:%d: declaration of function `%s' takes different forms\n",
def_dec_p->file->hash_entry->symbol,
- def_dec_p->line);
- exit (1);
+ def_dec_p->line,
+ def_dec_p->hash_entry->symbol);
+ exit (FATAL_EXIT_CODE);
}
free_def_dec (def_dec_p);
return;
check_aux_info (*++p == '(');
{
- const char *kr_names_start = ++p; /* Point just inside '('. */
+ const char *kr_names_start = ++p; /* Point just inside '('. */
while (*p++ != ')')
continue;
}
/* Do a recompilation for the express purpose of generating a new aux_info
- file to go with a specific base source file. */
+ file to go with a specific base source file.
+
+ The result is a boolean indicating success. */
static int
gen_aux_info_file (base_filename)
const char *base_filename;
{
- int child_pid;
-
if (!input_file_name_index)
munge_compile_params ("");
fprintf (stderr, "%s: compiling `%s'\n",
pname, compile_params[input_file_name_index]);
- if (child_pid = fork ())
- {
- if (child_pid == -1)
- {
- fprintf (stderr, "%s: error: could not fork process: %s\n",
- pname, sys_errlist[errno]);
- return 0;
- }
-
-#if 0
- /* Print out the command line that the other process is now executing. */
+ {
+ char *errmsg_fmt, *errmsg_arg;
+ int wait_status, pid;
+ char *temp_base = choose_temp_base ();
- if (!quiet_flag)
- {
- const char **arg;
-
- fputs ("\t", stderr);
- for (arg = compile_params; *arg; arg++)
- {
- fputs (*arg, stderr);
- fputc (' ', stderr);
- }
- fputc ('\n', stderr);
- fflush (stderr);
- }
-#endif /* 0 */
+ pid = pexecute (compile_params[0], (char * const *) compile_params,
+ pname, temp_base, &errmsg_fmt, &errmsg_arg,
+ PEXECUTE_FIRST | PEXECUTE_LAST | PEXECUTE_SEARCH);
+ if (pid == -1)
{
- int wait_status;
+ int errno_val = errno;
+ fprintf (stderr, "%s: ", pname);
+ fprintf (stderr, errmsg_fmt, errmsg_arg);
+ fprintf (stderr, ": %s\n", my_strerror (errno_val));
+ return 0;
+ }
- if (wait (&wait_status) == -1)
- {
- fprintf (stderr, "%s: wait failed: %s\n",
- pname, sys_errlist[errno]);
- return 0;
- }
- if ((wait_status & 0x7F) != 0)
- {
- fprintf (stderr, "%s: subprocess got fatal signal %d",
- pname, (wait_status & 0x7F));
- return 0;
- }
- if (((wait_status & 0xFF00) >> 8) != 0)
+ pid = pwait (pid, &wait_status, 0);
+ if (pid == -1)
+ {
+ fprintf (stderr, "%s: wait: %s\n", pname, my_strerror (errno));
+ return 0;
+ }
+ if (WIFSIGNALED (wait_status))
+ {
+ fprintf (stderr, "%s: subprocess got fatal signal %d\n",
+ pname, WTERMSIG (wait_status));
+ return 0;
+ }
+ if (WIFEXITED (wait_status))
+ {
+ if (WEXITSTATUS (wait_status) != 0)
{
fprintf (stderr, "%s: %s exited with status %d\n",
- pname, base_filename, ((wait_status & 0xFF00) >> 8));
+ pname, compile_params[0], WEXITSTATUS (wait_status));
return 0;
}
return 1;
}
- }
- else
- {
- if (my_execvp (compile_params[0], (char *const *) compile_params))
- {
- int e = errno, f = fileno (stderr);
- write (f, pname, strlen (pname));
- write (f, ": ", 2);
- write (f, compile_params[0], strlen (compile_params[0]));
- write (f, ": ", 2);
- write (f, sys_errlist[e], strlen (sys_errlist[e]));
- write (f, "\n", 1);
- _exit (1);
- }
- return 1; /* Never executed. */
- }
+ abort ();
+ }
}
\f
/* Read in all of the information contained in a single aux_info file.
/* Check that the aux_info file exists and is readable. If it does not
exist, try to create it (once only). */
-start_over: ;
-
/* If file doesn't exist, set must_create.
Likewise if it exists and we can read it but it is obsolete.
Otherwise, report an error. */
must_create = 0;
+
+ /* Come here with must_create set to 1 if file is out of date. */
+start_over: ;
+
if (my_access (aux_info_filename, R_OK) == -1)
{
if (errno == ENOENT)
}
else
{
- fprintf (stderr, "%s: error: can't read aux info file `%s': %s\n",
+ fprintf (stderr, "%s: can't read aux info file `%s': %s\n",
pname, shortpath (NULL, aux_info_filename),
- sys_errlist[errno]);
+ my_strerror(errno));
errors++;
return;
}
}
if (my_access (aux_info_filename, R_OK) == -1)
{
- fprintf (stderr, "%s: error: can't read aux info file `%s': %s\n",
+ fprintf (stderr, "%s: can't read aux info file `%s': %s\n",
pname, shortpath (NULL, aux_info_filename),
- sys_errlist[errno]);
+ my_strerror(errno));
errors++;
return;
}
if (my_stat (aux_info_filename, &stat_buf) == -1)
{
- fprintf (stderr, "%s: error: can't get status of aux info file `%s': %s\n",
+ fprintf (stderr, "%s: can't get status of aux info file `%s': %s\n",
pname, shortpath (NULL, aux_info_filename),
- sys_errlist[errno]);
+ my_strerror(errno));
errors++;
return;
}
contains information about are at least this old or older. */
aux_info_mtime = stat_buf.st_mtime;
+
+ if (!is_syscalls)
+ {
+ /* Compare mod time with the .c file; update .X file if obsolete.
+ The code later on can fail to check the .c file
+ if it did not directly define any functions. */
+
+ if (my_stat (base_source_filename, &stat_buf) == -1)
+ {
+ fprintf (stderr, "%s: can't get status of aux info file `%s': %s\n",
+ pname, shortpath (NULL, base_source_filename),
+ my_strerror(errno));
+ errors++;
+ return;
+ }
+ if (stat_buf.st_mtime > aux_info_mtime)
+ {
+ must_create = 1;
+ goto start_over;
+ }
+ }
}
{
if ((aux_info_file = my_open (aux_info_filename, O_RDONLY, 0444 )) == -1)
{
- fprintf (stderr, "%s: error: can't open aux info file `%s' for reading: %s\n",
+ fprintf (stderr, "%s: can't open aux info file `%s' for reading: %s\n",
pname, shortpath (NULL, aux_info_filename),
- sys_errlist[errno]);
+ my_strerror(errno));
return;
}
/* Read the aux_info file into memory. */
- if (read (aux_info_file, aux_info_base, aux_info_size) != aux_info_size)
+ if (safe_read (aux_info_file, aux_info_base, aux_info_size) != aux_info_size)
{
- fprintf (stderr, "%s: error: while reading aux info file `%s': %s\n",
+ fprintf (stderr, "%s: error reading aux info file `%s': %s\n",
pname, shortpath (NULL, aux_info_filename),
- sys_errlist[errno]);
+ my_strerror(errno));
free (aux_info_base);
close (aux_info_file);
return;
if (close (aux_info_file))
{
- fprintf (stderr, "%s: error: while closing aux info file `%s': %s\n",
+ fprintf (stderr, "%s: error closing aux info file `%s': %s\n",
pname, shortpath (NULL, aux_info_filename),
- sys_errlist[errno]);
+ my_strerror(errno));
free (aux_info_base);
close (aux_info_file);
return;
/* Delete the aux_info file (unless requested not to). If the deletion
fails for some reason, don't even worry about it. */
- if (!keep_it)
+ if (must_create && !keep_it)
if (my_unlink (aux_info_filename) == -1)
- fprintf (stderr, "%s: error: can't delete aux info file `%s': %s\n",
+ fprintf (stderr, "%s: can't delete aux info file `%s': %s\n",
pname, shortpath (NULL, aux_info_filename),
- sys_errlist[errno]);
+ my_strerror(errno));
/* Save a pointer into the first line of the aux_info file which
contains the filename of the directory from which the compiler
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 = rindex (aux_info_relocated_name, '/');
if (dir_end)
dir_end++;
else
xfree (aux_info_relocated_name);
if (keep_it && my_unlink (aux_info_filename) == -1)
{
- fprintf (stderr, "%s: error: can't delete file `%s': %s\n",
+ fprintf (stderr, "%s: can't delete file `%s': %s\n",
pname, shortpath (NULL, aux_info_filename),
- sys_errlist[errno]);
+ my_strerror(errno));
return;
}
+ must_create = 1;
goto start_over;
}
{
fprintf (stderr, "%s: warning: can't link file `%s' to `%s': %s\n",
pname, shortpath (NULL, filename),
- shortpath (NULL, new_filename), sys_errlist[errno]);
+ shortpath (NULL, new_filename), my_strerror(errno));
errors++;
return;
}
if (my_unlink (filename) == -1)
{
fprintf (stderr, "%s: warning: can't delete file `%s': %s\n",
- pname, shortpath (NULL, filename), sys_errlist[errno]);
+ pname, shortpath (NULL, filename), my_strerror(errno));
errors++;
return;
}
const hash_table_entry *hp;
{
file_info *file_p = hp->fip;
- const def_dec_info *prev = NULL;
- const def_dec_info *current = file_p->defs_decs;
+ def_dec_info *prev = NULL;
+ def_dec_info *current = (def_dec_info *)file_p->defs_decs;
- if (!( current = file_p->defs_decs))
+ if (!current)
return; /* no list to reverse */
prev = current;
- if (! (current = current->next_in_file))
+ if (! (current = (def_dec_info *)current->next_in_file))
return; /* can't reverse a single list element */
- ((NONCONST def_dec_info *) prev)->next_in_file = NULL;
+ prev->next_in_file = NULL;
while (current)
{
- const def_dec_info *next = current->next_in_file;
+ def_dec_info *next = (def_dec_info *)current->next_in_file;
- ((NONCONST def_dec_info *) current)->next_in_file = prev;
+ current->next_in_file = prev;
prev = current;
current = next;
}
if (dd_p->is_func_def && !dd_p->is_static)
{
if (!extern_def_p) /* Previous definition? */
- extern_def_p = dd_p; /* Remember the first definition found. */
+ extern_def_p = dd_p; /* Remember the first definition found. */
else
{
/* Ignore definition just found if it came from SYSCALLS.c.X. */
if (!conflict_noted) /* first time we noticed? */
{
conflict_noted = 1;
- fprintf (stderr, "%s: error: conflicting extern definitions of '%s'\n",
+ fprintf (stderr, "%s: conflicting extern definitions of '%s'\n",
pname, head->hash_entry->symbol);
if (!quiet_flag)
{
\f
/* Find the (only?) static definition for a particular function name in a
given file. Here we get the function-name and the file info indirectly
- from the def_dec_info record pointer which is passed in. */
+ from the def_dec_info record pointer which is passed in. */
static const def_dec_info *
find_static_definition (user)
}
else if (num_static_defs > 1)
{
- fprintf (stderr, "%s: error: multiple static defs of `%s' in file `%s'\n",
+ fprintf (stderr, "%s: multiple static defs of `%s' in file `%s'\n",
pname, head->hash_entry->symbol,
shortpath (NULL, user->file->hash_entry->symbol));
return NULL;
}
/* Given a pointer to a character in the cleaned text buffer, return a pointer
- to the next non-whitepace character which follows it. */
+ to the next non-whitespace character which follows it. */
static const char *
forward_to_next_token_char (ptr)
buffer (which may include original comments and preprocessing directives)
will be copied into the output buffer.
- Note that the request implide when this routine is called includes the
+ Note that the request implied when this routine is called includes the
byte pointed to by the argument pointer `p'. */
static void
/* See if we have a stdarg function, or a function which has stdarg style
parameters or a stdarg style return type. */
- return (int) substr (ansi_header, "...");
+ return substr (ansi_header, "...") != 0;
#else /* !defined (UNPROTOIZE) */
return 0;
}
-/* Given a pointer to a byte in the clean text buffer which points to the
- beginning of a line that contains a "follower" token for a function
- definition header, do whatever is necessary to find the right closing
- paren for the rightmost formals list of the function definition header.
-*/
+/* Given a pointer to a byte in the clean text buffer which points to
+ the beginning of a line that contains a "follower" token for a
+ function definition header, do whatever is necessary to find the
+ right closing paren for the rightmost formals list of the function
+ definition header. */
static const char *
find_rightmost_formals_list (clean_text_p)
sure that this is in fact the right paren that we were looking for.
The one we were looking for *must* be followed by either a '{' or
- by an alphabetic character, while others *cannot* legally be followed
+ by an alphabetic character, while others *cannot* validly be followed
by such characters. */
if ((ch == '{') || isalpha (ch))
/* Now scan forward for the first non-whitespace character. In theory,
this should be the first character of the following function definition
- header. We will put in the added declarations just prior to that. */
+ header. We will put in the added declarations just prior to that. */
scan_p++;
while (isspace (*scan_p))
output_string ("\n");
}
#else /* !defined (UNPROTOIZE) */
- /* If we are protoizing, there may be some flotsum & jetsum (like comments
+ /* If we are protoizing, there may be some flotsam & jetsam (like comments
and preprocessing directives) after the old formals list but before
the following { and we would like to preserve that stuff while effectively
deleting the existing K&R formal parameter declarations. We do so here
const char *start_body_orig;
const char *scan;
const char *scan_orig;
- int have_flotsum = 0;
+ int have_flotsam = 0;
int have_newlines = 0;
for (start_body = end_formals + 1; *start_body != '{';)
*((NONCONST char *)scan_orig) = ' '; /* identical - so whiteout */
}
else
- have_flotsum = 1;
+ have_flotsam = 1;
}
- if (have_flotsum)
+ if (have_flotsam)
output_bytes (end_formals_orig + 1,
(size_t) (start_body_orig - end_formals_orig) - 1);
else
}
/* Clean up the clean text buffer. Do this by converting comments and
- preprocessor directives into spaces. Also convert line continuations
+ preprocessing directives into spaces. Also convert line continuations
into whitespace. Also, whiteout string and character literals. */
static void
if (++scan_p >= new_clean_text_limit)
abort ();
}
- *scan_p++ = ' ';
+ if (!isspace (*scan_p))
+ *scan_p = ' ';
+ scan_p++;
break;
case '\\': /* Handle line continuations. */
{
char *func_name = (char *) alloca (id_length + 1);
static const char * const stmt_keywords[]
- = { "if", "while", "for", "switch", "return", 0 };
+ = { "if", "else", "do", "while", "for", "switch", "case", "return", 0 };
const char * const *stmt_keyword;
strncpy (func_name, id_start, id_length);
/* Do all editing operations for a single source file (either a "base" file
or an "include" file). To do this we read the file into memory, keep a
virgin copy there, make another cleaned in-core copy of the original file
- (i.e. one in which all of the comments and preprocessor directives have
+ (i.e. one in which all of the comments and preprocessing directives have
been replaced with whitespace), then use these two in-core copies of the
file to make a new edited in-core copy of the file. Finally, rename the
original file (as a way of saving it), and then write the edited version
of the file from core to a disk file of the same name as the original.
Note that the trick of making a copy of the original sans comments &
- preprocessor directives make the editing a whole lot easier. */
+ preprocessing directives make the editing a whole lot easier. */
static void
edit_file (hp)
/* The cast avoids an erroneous warning on AIX. */
if (my_stat ((char *)convert_filename, &stat_buf) == -1)
{
- fprintf (stderr, "%s: error: can't get status for file `%s': %s\n",
- pname, shortpath (NULL, convert_filename), sys_errlist[errno]);
+ fprintf (stderr, "%s: can't get status for file `%s': %s\n",
+ pname, shortpath (NULL, convert_filename), my_strerror(errno));
return;
}
orig_size = stat_buf.st_size;
if ((input_file = my_open (convert_filename, O_RDONLY, 0444)) == -1)
{
- fprintf (stderr, "%s: error: can't open file `%s' for reading: %s\n",
+ fprintf (stderr, "%s: can't open file `%s' for reading: %s\n",
pname, shortpath (NULL, convert_filename),
- sys_errlist[errno]);
+ my_strerror(errno));
return;
}
in one swell fwoop. Then figure out where the end of the text is and
make sure that it ends with a newline followed by a null. */
- if (read (input_file, new_orig_text_base, orig_size) != orig_size)
+ if (safe_read (input_file, new_orig_text_base, orig_size) != orig_size)
{
close (input_file);
- fprintf (stderr, "\n%s: error: while reading input file `%s': %s\n",
+ fprintf (stderr, "\n%s: error reading input file `%s': %s\n",
pname, shortpath (NULL, convert_filename),
- sys_errlist[errno]);
+ my_strerror(errno));
return;
}
strcat (clean_filename, ".clean");
if ((clean_file = creat (clean_filename, 0666)) == -1)
{
- fprintf (stderr, "%s: error: can't create/open clean file `%s': %s\n",
+ fprintf (stderr, "%s: can't create/open clean file `%s': %s\n",
pname, shortpath (NULL, clean_filename),
- sys_errlist[errno]);
+ my_strerror(errno));
return;
}
/* Write the clean file. */
- if (write (clean_file, new_clean_text_base, clean_size) != clean_size)
- fprintf (stderr, "%s: error: while writing file `%s': %s\n",
- pname, shortpath (NULL, clean_filename), sys_errlist[errno]);
+ safe_write (clean_file, new_clean_text_base, clean_size, clean_filename);
close (clean_file);
}
if (!nosave_flag)
{
- char *new_filename =
- (char *) xmalloc (strlen (convert_filename) + strlen (save_suffix) + 2);
+ char *new_filename
+ = (char *) xmalloc (strlen (convert_filename) + strlen (save_suffix) + 2);
strcpy (new_filename, convert_filename);
strcat (new_filename, save_suffix);
}
else
{
- fprintf (stderr, "%s: error: can't link file `%s' to `%s': %s\n",
+ fprintf (stderr, "%s: can't link file `%s' to `%s': %s\n",
pname,
shortpath (NULL, convert_filename),
shortpath (NULL, new_filename),
- sys_errlist[errno]);
+ my_strerror(errno));
return;
}
}
if (my_unlink (convert_filename) == -1)
{
- fprintf (stderr, "%s: error: can't delete file `%s': %s\n",
- pname, shortpath (NULL, convert_filename), sys_errlist[errno]);
+ fprintf (stderr, "%s: can't delete file `%s': %s\n",
+ pname, shortpath (NULL, convert_filename), my_strerror(errno));
return;
}
if ((output_file = creat (convert_filename, 0666)) == -1)
{
- fprintf (stderr, "%s: error: can't create/open output file `%s': %s\n",
+ fprintf (stderr, "%s: can't create/open output file `%s': %s\n",
pname, shortpath (NULL, convert_filename),
- sys_errlist[errno]);
+ my_strerror(errno));
return;
}
{
unsigned int out_size = (repl_write_ptr + 1) - repl_text_base;
- if (write (output_file, repl_text_base, out_size) != out_size)
- fprintf (stderr, "%s: error: while writing file `%s': %s\n",
- pname, shortpath (NULL, convert_filename),
- sys_errlist[errno]);
+ safe_write (output_file, repl_text_base, out_size, convert_filename);
}
close (output_file);
/* The cast avoids an erroneous warning on AIX. */
if (my_chmod ((char *)convert_filename, stat_buf.st_mode) == -1)
- fprintf (stderr, "%s: error: can't change mode of file `%s': %s\n",
- pname, shortpath (NULL, convert_filename), sys_errlist[errno]);
+ fprintf (stderr, "%s: can't change mode of file `%s': %s\n",
+ pname, shortpath (NULL, convert_filename), my_strerror(errno));
/* Note: We would try to change the owner and group of the output file
to match those of the input file here, except that may not be a good
int c;
const char *params = "";
- pname = strrchr (argv[0], '/');
+ pname = rindex (argv[0], '/');
pname = pname ? pname+1 : argv[0];
cwd_buffer = getpwd ();
if (!cwd_buffer)
{
fprintf (stderr, "%s: cannot get working directory: %s\n",
- pname, sys_errlist[errno]);
- exit (1);
+ pname, my_strerror(errno));
+ exit (FATAL_EXIT_CODE);
}
/* By default, convert the files in the current directory. */
#endif
longopts, &longind)) != EOF)
{
- if (c == 0) /* Long option. */
+ if (c == 0) /* Long option. */
c = longopts[longind].val;
switch (c)
{
/* Now actually make a list of the base source filenames. */
- base_source_filenames =
- (const char **) xmalloc ((n_base_source_files + 1) * sizeof (char *));
+ base_source_filenames
+ = (const char **) xmalloc ((n_base_source_files + 1) * sizeof (char *));
n_base_source_files = 0;
for (; optind < argc; optind++)
{
fprintf (stderr, "%s: %s\n", pname, version_string);
do_processing ();
}
- if (errors)
- exit (1);
- else
- exit (0);
+
+ exit (errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
+
return 1;
}