OSDN Git Service

* function.h (struct function): Add arg_pointer_save_area_init.
[pf3gnuchains/gcc-fork.git] / gcc / tradcpp.c
index 206541c..6984886 100644 (file)
@@ -24,6 +24,7 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "version.h"
 #include "cppdefault.h"
 #include "tradcpp.h"
+#include "mkdeps.h"
 
 typedef unsigned char U_CHAR;
 
@@ -40,12 +41,33 @@ size_t max_include_len;
 
 int put_out_comments = 0;
 
+/* mkdeps.h opaque structure that encapsulates dependency information.  */
+struct deps *deps;
+
 /* Nonzero means print the names of included files rather than
    the preprocessed output.  1 means just the #include "...",
    2 means #include <...> as well.  */
 
 int print_deps = 0;
 
+/* Nonzero means print dummy targets for each header file.  */
+
+int print_deps_phony_targets = 0;
+
+/* If true, fopen (deps_file, "a") else fopen (deps_file, "w").  */
+
+int deps_append = 0;
+
+/* File name which deps are being written to.  This is 0 if deps are
+   being written to stdout.  */
+
+const char *deps_file = 0;
+
+/* Nonzero if missing .h files in -M output are assumed to be
+   generated files and not errors.  */
+
+int deps_missing_files = 0;
+       
 /* Nonzero means don't output line number information.  */
 
 int no_line_commands;
@@ -60,6 +82,9 @@ int dump_macros;
 
 int inhibit_warnings = 0;
 
+/* Non-0 means don't output the preprocessed program.  */
+int inhibit_output = 0;
+
 /* Nonzero means warn if slash-star appears in a comment.  */
 
 int warn_comments;
@@ -80,6 +105,7 @@ static const char *user_label_prefix;
    It is zero for rescanning results of macro expansion
    and for expanding macro arguments.  */
 #define INPUT_STACK_MAX 200
+struct file_name_list;
 struct file_buf {
   const char *fname;
   int lineno;
@@ -95,6 +121,8 @@ struct file_buf {
   struct if_stack *if_stack;
   /* Object to be freed at end of input at this level.  */
   U_CHAR *free_ptr;
+  /* Position to start scanning for #include_next in this file.  */
+  struct file_name_list *next_header_dir;
 } instack[INPUT_STACK_MAX];
 
 typedef struct file_buf FILE_BUF;
@@ -215,6 +243,7 @@ union hashval {
 enum node_type {
  T_DEFINE = 1, /* `#define' */
  T_INCLUDE,    /* `#include' */
+ T_INCLUDE_NEXT,/* `#include_next' */
  T_IFDEF,      /* `#ifdef' */
  T_IFNDEF,     /* `#ifndef' */
  T_IF,         /* `#if' */
@@ -333,6 +362,7 @@ static void do_error        PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
 static void do_warning PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
 static void do_line    PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
 static void do_include PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
+static void do_include_next    PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
 static void do_undef   PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
 static void do_if      PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
 static void do_ifdef   PARAMS ((U_CHAR *, U_CHAR *, FILE_BUF *));
@@ -380,6 +410,7 @@ static void output_line_command PARAMS ((FILE_BUF *, FILE_BUF *,
 
 static int eval_if_expression  PARAMS ((const U_CHAR *, int));
 
+static void output_deps                PARAMS ((void));
 static void initialize_builtins        PARAMS ((void));
 static void run_directive      PARAMS ((const char *, size_t,
                                         enum node_type));
@@ -389,8 +420,11 @@ static void make_assertion PARAMS ((const char *));
 
 static void grow_outbuf        PARAMS ((FILE_BUF *, int));
 static int handle_directive    PARAMS ((FILE_BUF *, FILE_BUF *));
-static void finclude           PARAMS ((int, const char *, FILE_BUF *));
-static void deps_output                PARAMS ((const char *, int));
+static void process_include    PARAMS ((struct file_name_list *,
+                                        const U_CHAR *, int, int, FILE_BUF *));
+static void finclude           PARAMS ((int, const char *,
+                                        struct file_name_list *, FILE_BUF *));
+static void init_dependency_output PARAMS ((void));
 static void rescan             PARAMS ((FILE_BUF *, int));
 static void newline_fix                PARAMS ((U_CHAR *));
 static void name_newline_fix   PARAMS ((U_CHAR *));
@@ -424,6 +458,7 @@ struct directive directive_table[] = {
   {  4, do_elif,    "elif",    T_ELIF    },
   {  5, do_error,   "error",   T_ERROR   },
   {  7, do_warning, "warning", T_WARNING },
+  { 12, do_include_next, "include_next", T_INCLUDE_NEXT },
   {  6, do_assert,  "assert",  T_ASSERT  },
   {  8, do_unassert,"unassert",T_UNASSERT},
   {  -1, 0, "", T_UNUSED},
@@ -452,19 +487,6 @@ struct if_stack {
 typedef struct if_stack IF_STACK_FRAME;
 IF_STACK_FRAME *if_stack = NULL;
 
-/* Buffer of -M output.  */
-
-char *deps_buffer;
-
-/* Number of bytes allocated in above.  */
-int deps_allocated_size;
-
-/* Number of bytes used.  */
-int deps_size;
-
-/* Number of bytes since the last newline.  */
-int deps_column;
-
 /* Nonzero means -I- has been seen,
    so don't look for #include "foo" the source-file directory.  */
 int ignore_srcdir;
@@ -492,14 +514,6 @@ main (argc, argv)
   pending_dir *pend = (pending_dir *) xcalloc (argc, sizeof (pending_dir));
   int no_standard_includes = 0;
 
-  /* Non-0 means don't output the preprocessed program.  */
-  int inhibit_output = 0;
-
-  /* Stream on which to print the dependency information.  */
-  FILE *deps_stream = 0;
-  /* Target-name to write with the dependency information.  */
-  char *deps_target = 0;
-
 #ifdef RLIMIT_STACK
   /* Get rid of any avoidable limit on stack size.  */
   {
@@ -524,6 +538,10 @@ main (argc, argv)
 
   max_include_len = cpp_GCC_INCLUDE_DIR_len + 7;  /* ??? */
 
+  /* It's simplest to just create this struct whether or not it will
+     be needed.  */
+  deps = deps_init ();
+
   /* Process switches and find input file name.  */
 
   for (i = 1; i < argc; i++) {
@@ -540,7 +558,6 @@ main (argc, argv)
       switch (c) {
       case 'E':
       case '$':
-      case 'g':
        break;  /* Ignore for compatibility with ISO/extended cpp.  */
 
       case 'l':
@@ -608,11 +625,56 @@ main (argc, argv)
        break;
 
       case 'M':
-       if (!strcmp (argv[i], "-M"))
-         print_deps = 2;
-       else if (!strcmp (argv[i], "-MM"))
-         print_deps = 1;
-       inhibit_output = 1;
+       {
+         char *p = NULL;
+
+         /* -MD and -MMD for tradcpp are deprecated and undocumented
+            (use -M or -MM with -MF instead), and probably should be
+            removed with the next major GCC version.  For the moment
+            we allow these for the benefit of Automake 1.4, which
+            uses these when dependency tracking is enabled.  Automake
+            1.5 will fix this.  */
+         if (!strncmp (argv[i], "-MD", 3)) {
+           p = argv[i] + 3;
+           print_deps = 2;
+         } else if (!strncmp (argv[i], "-MMD", 4)) {
+           p = argv[i] + 4;
+           print_deps = 1;
+         } else if (!strcmp (argv[i], "-M")) {
+           print_deps = 2;
+         } else if (!strcmp (argv[i], "-MM")) {
+           print_deps = 1;
+         } else if (!strcmp (argv[i], "-MG")) {
+           deps_missing_files = 1;
+         } else if (!strcmp (argv[i], "-MF")) {
+           p = argv[i] + 3;
+         } else if (!strcmp (argv[i], "-MP")) {
+           print_deps_phony_targets = 1;
+         } else if (!strcmp (argv[i], "-MQ") || !strcmp (argv[i], "-MT")) {
+           /* Add a target.  -MQ quotes for Make.  */
+           const char *tgt = argv[i] + 3;
+           int quoted = argv[i][2] == 'Q';
+
+           if (*tgt == '\0' && i + 1 == argc)
+             fatal ("Target missing after %s option", argv[i]);
+           else
+             {
+               if (*tgt == '\0')
+                 tgt = argv[++i];
+             
+               deps_add_target (deps, tgt, quoted);
+             }
+         }
+
+         if (p) {
+           if (*p)
+             deps_file = p;
+           else if (i + 1 == argc)
+             fatal ("Filename missing after %s option", argv[i]);
+           else
+             deps_file = argv[++i];
+         }
+       }
        break;
 
       case 'd':
@@ -716,9 +778,26 @@ main (argc, argv)
     }
   }
 
+  init_dependency_output ();
+
+  /* After checking the environment variables, check if -M or -MM has
+     not been specified, but other -M options have.  */
+  if (print_deps == 0
+      && (deps_missing_files || deps_file || print_deps_phony_targets))
+    fatal ("you must additionally specify either -M or -MM");
+
   if (user_label_prefix == 0)
     user_label_prefix = USER_LABEL_PREFIX;
 
+  if (print_deps)
+    {
+      /* Set the default target (if there is none already), and
+        the dependency on the main file.  */
+      deps_add_default_target (deps, in_fname);
+
+      deps_add_dep (deps, in_fname);
+    }
+
   /* Install __LINE__, etc.  Must follow option processing.  */
   initialize_builtins ();
 
@@ -778,7 +857,12 @@ main (argc, argv)
            perror_with_name (pend[i].arg);
            return FATAL_EXIT_CODE;
          }
-       finclude (fd, pend[i].arg, &outbuf);
+
+       /* For -M, add this file to the dependencies.  */
+       if (print_deps)
+         deps_add_dep (deps, pend[i].arg);
+
+       finclude (fd, pend[i].arg, 0, &outbuf);
       }
   indepth--;
   no_output--;
@@ -798,92 +882,6 @@ main (argc, argv)
   } else if ((f = open (in_fname, O_RDONLY, 0666)) < 0)
     goto sys_error;
 
-  /* Either of two environment variables can specify output of deps.
-     Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
-     where OUTPUT_FILE is the file to write deps info to
-     and DEPS_TARGET is the target to mention in the deps.  */
-
-  if (print_deps == 0
-      && (getenv ("SUNPRO_DEPENDENCIES") != 0
-         || getenv ("DEPENDENCIES_OUTPUT") != 0))
-    {
-      char *spec = getenv ("DEPENDENCIES_OUTPUT");
-      char *s;
-      char *output_file;
-
-      if (spec == 0)
-       {
-         spec = getenv ("SUNPRO_DEPENDENCIES");
-         print_deps = 2;
-       }
-      else
-       print_deps = 1;
-
-      /* Find the space before the DEPS_TARGET, if there is one.  */
-      s = strchr (spec, ' ');
-      if (s)
-       {
-         deps_target = s + 1;
-         output_file = (char *) xmalloc (s - spec + 1);
-         memcpy (output_file, spec, s - spec);
-         output_file[s - spec] = 0;
-       }
-      else
-       {
-         deps_target = 0;
-         output_file = spec;
-       }
-      
-      deps_stream = fopen (output_file, "a");
-      if (deps_stream == 0)
-       pfatal_with_name (output_file);
-    }
-  /* If the -M option was used, output the deps to standard output.  */
-  else if (print_deps)
-    deps_stream = stdout;
-
-  /* For -M, print the expected object file name
-     as the target of this Make-rule.  */
-  if (print_deps) {
-    deps_allocated_size = 200;
-    deps_buffer = (char *) xmalloc (deps_allocated_size);
-    deps_buffer[0] = 0;
-    deps_size = 0;
-    deps_column = 0;
-
-    if (deps_target) {
-      deps_output (deps_target, 0);
-      deps_output (":", 0);
-    } else if (*in_fname == 0)
-      deps_output ("-: ", 0);
-    else {
-      int len;
-      const char *p = in_fname;
-      const char *p1 = p;
-      /* Discard all directory prefixes from P.  */
-      while (*p1) {
-       if (*p1 == '/')
-         p = p1 + 1;
-       p1++;
-      }
-      /* Output P, but remove known suffixes.  */
-      len = strlen (p);
-      if (p[len - 2] == '.'
-         && (p[len - 1] == 'c' || p[len - 1] == 'C' || p[len - 1] == 'S'))
-       deps_output (p, len - 2);
-      else if (p[len - 3] == '.'
-              && p[len - 2] == 'c'
-              && p[len - 1] == 'c')
-       deps_output (p, len - 3);
-      else
-       deps_output (p, 0);
-      /* Supply our own suffix.  */
-      deps_output (".o : ", 0);
-      deps_output (in_fname, 0);
-      deps_output (" ", 0);
-    }
-  }
-
   if (file_size_and_mode (f, &st_mode, &st_size))
     goto sys_error;
   fp->fname = in_fname;
@@ -960,20 +958,16 @@ main (argc, argv)
 
   if (dump_macros)
     dump_all_macros ();
-  else if (! inhibit_output && deps_stream != stdout) {
+  else if (! inhibit_output)
     if (write (fileno (stdout), outbuf.buf, outbuf.bufp - outbuf.buf) < 0)
       fatal ("I/O error on output");
-  }
 
-  if (print_deps) {
-    fputs (deps_buffer, deps_stream);
-    putc ('\n', deps_stream);
-    if (deps_stream != stdout) {
-      fclose (deps_stream);
-      if (ferror (deps_stream))
-       fatal ("I/O error on output");
-    }
-  }
+  /* Don't write the deps file if preprocessing has failed.  */
+  if (print_deps && errors == 0)
+    output_deps ();
+
+  /* Destruct the deps object.  */
+  deps_free (deps);
 
   if (ferror (stdout))
     fatal ("I/O error on output");
@@ -986,6 +980,91 @@ main (argc, argv)
   pfatal_with_name (in_fname);
 }
 
+/* Set up dependency-file output.  */
+static void
+init_dependency_output ()
+{
+  char *spec, *s, *output_file;
+
+  /* Either of two environment variables can specify output of deps.
+     Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
+     where OUTPUT_FILE is the file to write deps info to
+     and DEPS_TARGET is the target to mention in the deps.  */
+
+  if (print_deps == 0)
+    {
+      spec = getenv ("DEPENDENCIES_OUTPUT");
+      if (spec)
+       print_deps = 1;
+      else
+       {
+         spec = getenv ("SUNPRO_DEPENDENCIES");
+         if (spec)
+           print_deps = 2;
+         else
+           return;
+       }
+
+      /* Find the space before the DEPS_TARGET, if there is one.  */
+      s = strchr (spec, ' ');
+      if (s)
+       {
+         /* Let the caller perform MAKE quoting.  */
+         deps_add_target (deps, s + 1, 0);
+         output_file = (char *) xmalloc (s - spec + 1);
+         memcpy (output_file, spec, s - spec);
+         output_file[s - spec] = 0;
+       }
+      else
+       output_file = spec;
+
+      /* Command line overrides environment variables.  */
+      if (deps_file == 0)
+       deps_file = output_file;
+      deps_append = 1;
+    }
+
+  /* If dependencies go to standard output, or -MG is used, we should
+     suppress output.  The user may be requesting other stuff to
+     stdout, with -dM, -v etc.  We let them shoot themselves in the
+     foot.  */
+  if (deps_file == 0 || deps_missing_files)
+    inhibit_output = 1;
+}
+
+/* Use mkdeps.c to output dependency information.  */
+static void
+output_deps ()
+{
+  /* Stream on which to print the dependency information.  */
+  FILE *deps_stream = 0;
+  const char *deps_mode = deps_append ? "a" : "w";
+
+  if (deps_file == 0)
+    deps_stream = stdout;
+  else
+    {
+      deps_stream = fopen (deps_file, deps_mode);
+      if (deps_stream == 0)
+       {
+         error_from_errno (deps_file);
+         return;
+       }
+    }
+
+  deps_write (deps, deps_stream, 72);
+
+  if (print_deps_phony_targets)
+    deps_phony_targets (deps, deps_stream);
+
+  /* Don't close stdout.  */
+  if (deps_file)
+    {
+      if (ferror (deps_stream) || fclose (deps_stream) != 0)
+       fatal ("I/O error on output");
+    }
+}
+
 /* Move all backslash-newline pairs out of embarrassing places.
    Exchange all such pairs following BP
    with any potentially-embarrasing characters that follow them.
@@ -1141,6 +1220,9 @@ rescan (op, output_marks)
   /* Record position of last `real' newline.  */
   U_CHAR *beg_of_line;
 
+  /* This has to be a global bacause of RECACHE.  */
+  U_CHAR *obufp_before_macroname = NULL;
+
 /* Pop the innermost input stack level, assuming it is a macro expansion.  */
 
 #define POPMACRO \
@@ -1158,6 +1240,7 @@ do { ip = &instack[indepth];              \
      op->bufp = obp;                   \
      check_expand (op, limit - ibp);   \
      beg_of_line = 0;                  \
+     obufp_before_macroname += op->bufp - obp;  \
      obp = op->bufp; } while (0)
 
   if (no_output && instack[indepth].fname != 0)
@@ -1568,7 +1651,8 @@ randomchar:
             hp = hp->next) {
 
          if (hp->length == ident_length) {
-           U_CHAR *obufp_before_macroname;
+           /* obufp_before_macroname is used only in this block,
+               but it has to be global because of RECACHE.  */
            int op_lineno_before_macroname;
            register int i = ident_length;
            register U_CHAR *p = hp->name;
@@ -2208,22 +2292,17 @@ do_include (buf, limit, op)
      U_CHAR *buf, *limit;
      FILE_BUF *op;
 {
-  char *fname;         /* Dynamically allocated fname buffer */
   U_CHAR *fbeg, *fend;         /* Beginning and end of fname */
 
   struct file_name_list *stackp = include; /* Chain of dirs to search */
   struct file_name_list dsp[1];        /* First in chain, if #include "..." */
   int flen;
 
-  int f;                       /* file number */
-
   int retried = 0;             /* Have already tried macro
                                   expanding the include line*/
   FILE_BUF trybuf;             /* It got expanded into here */
   int system_header_p = 0;     /* 0 for "...", 1 for <...> */
 
-  f= -1;                       /* JF we iz paranoid! */
-
 get_filename:
 
   fbeg = buf;
@@ -2304,12 +2383,96 @@ get_filename:
   }
 
   flen = fend - fbeg;
+  process_include (stackp, fbeg, flen, system_header_p, op);
+}
+
+static void
+do_include_next (buf, limit, op)
+     U_CHAR *buf, *limit;
+     FILE_BUF *op;
+{
+  U_CHAR *fbeg, *fend;         /* Beginning and end of fname */
+
+  struct file_name_list *stackp; /* Chain of dirs to search */
+  int flen;
+
+  int retried = 0;             /* Have already tried macro
+                                  expanding the include line*/
+  FILE_BUF trybuf;             /* It got expanded into here */
+  int system_header_p = 0;     /* 0 for "...", 1 for <...> */
+
+  /* Treat as plain #include if we don't know where to start
+     looking.  */
+  stackp = instack[indepth].next_header_dir;
+  if (stackp == 0)
+    {
+      do_include (buf, limit, op);
+      return;
+    }
+
+get_filename:
+
+  fbeg = buf;
+  SKIP_WHITE_SPACE (fbeg);
+  /* Discard trailing whitespace so we can easily see
+     if we have parsed all the significant chars we were given.  */
+  while (limit != fbeg && is_nvspace (limit[-1])) limit--;
+
+  switch (*fbeg++) {
+  case '\"':
+    fend = fbeg;
+    while (fend != limit && *fend != '\"')
+      fend++;
+    if (*fend == '\"' && fend + 1 == limit)
+      break;
+    goto fail;
+
+  case '<':
+    fend = fbeg;
+    while (fend != limit && *fend != '>') fend++;
+    if (*fend == '>' && fend + 1 == limit) {
+      system_header_p = 1;
+      break;
+    }
+    goto fail;
+
+  default:
+  fail:
+    if (retried) {
+      error ("#include expects \"fname\" or <fname>");
+      return;
+    } else {
+      trybuf = expand_to_temp_buffer (buf, limit, 0);
+      buf = (U_CHAR *) alloca (trybuf.bufp - trybuf.buf + 1);
+      memcpy (buf, trybuf.buf, trybuf.bufp - trybuf.buf);
+      limit = buf + (trybuf.bufp - trybuf.buf);
+      free (trybuf.buf);
+      retried++;
+      goto get_filename;
+    }
+  }
+
+  flen = fend - fbeg;
+  process_include (stackp, fbeg, flen, system_header_p, op);
+}
+
+static void
+process_include (stackp, fbeg, flen, system_header_p, op)
+     struct file_name_list *stackp;
+     const U_CHAR *fbeg;
+     int flen;
+     int system_header_p;
+     FILE_BUF *op;
+{
+  char *fname;
+  int f = -1;                  /* file number */
+
   fname = (char *) alloca (max_include_len + flen + 2);
   /* + 2 above for slash and terminating null.  */
 
   /* If specified file name is absolute, just open it.  */
 
-  if (*fbeg == '/') {
+  if (IS_ABSOLUTE_PATHNAME (fbeg)) {
     strncpy (fname, (const char *)fbeg, flen);
     fname[flen] = 0;
     f = open (fname, O_RDONLY, 0666);
@@ -2334,19 +2497,37 @@ get_filename:
   if (f < 0) {
     strncpy (fname, (const char *)fbeg, flen);
     fname[flen] = 0;
-    error_from_errno (fname);
+    if (deps_missing_files
+       && print_deps > (system_header_p || (system_include_depth > 0))) {
 
-    /* For -M, add this file to the dependencies.  */
-    if (print_deps > (system_header_p || (system_include_depth > 0))) {
-      if (system_header_p)
-       warning ("nonexistent file <%.*s> omitted from dependency output",
-                flen, fbeg);
+      /* If requested as a system header, assume it belongs in
+        the first system header directory. */
+      if (first_bracket_include)
+       stackp = first_bracket_include;
       else
-       {
-         deps_output ((const char *)fbeg, flen);
-         deps_output (" ", 0);
-       }
-    }
+       stackp = include;
+
+      if (!system_header_p || IS_ABSOLUTE_PATHNAME (fbeg) || !stackp->fname)
+       deps_add_dep (deps, fname);
+      else {
+       char *p;
+       int len = strlen(stackp->fname);
+
+       p = (char *) alloca (len + flen + 2);
+       memcpy (p, stackp->fname, len);
+       p[len++] = '/';
+       memcpy (p + len, fbeg, flen);
+       len += flen;
+       p[len] = '\0';
+       deps_add_dep (deps, p);
+      }
+    } else if (print_deps
+              && print_deps <= (system_header_p
+                                || (system_include_depth > 0)))
+      warning ("No include path in which to find %.*s", flen, fbeg);
+    else
+      error_from_errno (fname);
+
   } else {
 
     /* Check to see if this include file is a once-only include file.
@@ -2376,17 +2557,15 @@ get_filename:
       ptr->fname = xstrdup (fname);
 
       /* For -M, add this file to the dependencies.  */
-      if (print_deps > (system_header_p || (system_include_depth > 0))) {
-       deps_output (fname, strlen (fname));
-       deps_output (" ", 0);
-      }
+      if (print_deps > (system_header_p || (system_include_depth > 0)))
+       deps_add_dep (deps, fname);
     }   
 
     if (system_header_p)
       system_include_depth++;
 
     /* Actually process the file.  */
-    finclude (f, fname, op);
+    finclude (f, fname, stackp->next, op);
 
     if (system_header_p)
       system_include_depth--;
@@ -2399,9 +2578,10 @@ get_filename:
    with output to OP.  */
 
 static void
-finclude (f, fname, op)
+finclude (f, fname, nhd, op)
      int f;
      const char *fname;
+     struct file_name_list *nhd;
      FILE_BUF *op;
 {
   int st_mode;
@@ -2420,6 +2600,7 @@ finclude (f, fname, op)
   fp->length = 0;
   fp->lineno = 1;
   fp->if_stack = if_stack;
+  fp->next_header_dir = nhd;
 
   if (S_ISREG (st_mode)) {
     fp->buf = (U_CHAR *) xmalloc (st_size + 2);
@@ -2584,8 +2765,8 @@ do_define (buf, limit, op)
       }
     }
 
-    ++bp;                      /* skip paren */
-    while (is_nvspace (*bp))   /* and leading whitespace */
+    ++bp;                                      /* skip paren */
+    while (is_nvspace (*bp) && bp < limit)     /* and leading whitespace */
       ++bp;
     /* now everything from bp before limit is the definition. */
     defn = collect_expansion (bp, limit, argno, arg_ptrs);
@@ -2612,7 +2793,7 @@ do_define (buf, limit, op)
     }
   } else {
     /* simple expansion or empty definition; skip leading whitespace */
-    while (is_nvspace (*bp))
+    while (is_nvspace (*bp) && bp < limit)
       ++bp;
     /* now everything from bp before limit is the definition. */
     defn = collect_expansion (bp, limit, -1, 0);
@@ -3934,7 +4115,7 @@ macroexpand (hp, op)
        = macarg ((i < nargs || (nargs == 0 && i == 0)) ? &args[i] : 0);
       if (parse_error)
        {
-         error_with_line (line_for_error (start_line), parse_error);
+         error_with_line (line_for_error (start_line), "%s", parse_error);
          break;
        }
       i++;
@@ -4505,37 +4686,22 @@ v_message (mtype, line, msgid, ap)
 void
 error 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);
 
   v_message (ERROR, 0, msgid, ap);
+  VA_CLOSE (ap);
 }
 
 void
 error_with_line VPARAMS ((int line, const char *msgid, ...))
 {
-#ifndef ANSI_PROTOTYPES
-  int line;
-  const char *msgid;
-#endif
-  va_list ap;
-
-  VA_START(ap, msgid);
-  
-#ifndef ANSI_PROTOTYPES
-  line = va_arg (ap, int);
-  msgid = va_arg (ap, const char *);
-#endif
+  VA_OPEN(ap, msgid);
+  VA_FIXEDARG (ap, int, line);
+  VA_FIXEDARG (ap, const char *, msgid);
 
   v_message (ERROR, line, msgid, ap);
+  VA_CLOSE (ap);
 }
 
 /* Error including a message from `errno'.  */
@@ -4550,35 +4716,21 @@ error_from_errno (name)
 void
 warning 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);
 
   v_message (WARNING, 0, msgid, ap);
+  VA_CLOSE (ap);
 }
 
 void
 fatal 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);
 
   v_message (FATAL, 0, msgid, ap);
+  VA_CLOSE (ap);
   exit (FATAL_EXIT_CODE);
 }
 
@@ -5049,38 +5201,6 @@ make_assertion (str)
   run_directive (str, count, type);
 }
 \f
-/* Add output to `deps_buffer' for the -M switch.
-   STRING points to the text to be output.
-   SIZE is the number of bytes, or 0 meaning output until a null.
-   If SIZE is nonzero, we break the line first, if it is long enough.  */
-static void
-deps_output (string, size)
-     const char *string;
-     int size;
-{
-#ifndef MAX_OUTPUT_COLUMNS
-#define MAX_OUTPUT_COLUMNS 75
-#endif
-  if (size != 0 && deps_column != 0
-      && size + deps_column > MAX_OUTPUT_COLUMNS) {
-    deps_output ("\\\n  ", 0);
-    deps_column = 0;
-  }
-
-  if (size == 0)
-    size = strlen (string);
-
-  if (deps_size + size + 1 > deps_allocated_size) {
-    deps_allocated_size = deps_size + size + 50;
-    deps_allocated_size *= 2;
-    deps_buffer = (char *) xrealloc (deps_buffer, deps_allocated_size);
-  }
-  memcpy (&deps_buffer[deps_size], string, size);
-  deps_size += size;
-  deps_column += size;
-  deps_buffer[deps_size] = 0;
-}
-
 /* Get the file-mode and data size of the file open on FD
    and store them in *MODE_POINTER and *SIZE_POINTER.  */