* Installed new versions of GLIBC glob library.
authorPaul Smith <psmith@gnu.org>
Thu, 22 Jul 1999 04:20:14 +0000 (04:20 +0000)
committerPaul Smith <psmith@gnu.org>
Thu, 22 Jul 1999 04:20:14 +0000 (04:20 +0000)
* Installed Tim Magill's "graph pruning" performance enhancement.
* Update version to 3.77.90 for the release.
* Require automake 1.4.

15 files changed:
ChangeLog
Makefile.am
configure.in
default.c
dir.c
file.c
filedef.h
glob/ChangeLog
glob/Makefile.am
glob/fnmatch.c
glob/fnmatch.h
glob/glob.c
glob/glob.h
main.c
remake.c

index 331d02e..f3fdffa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,13 @@
 1999-07-21  Paul D. Smith  <psmith@gnu.org>
 
+       * Version 3.77.90 released.
+
+       * Makefile.am (AUTOMAKE_OPTIONS): Require automake 1.4.
+
+       * default.c (default_suffix_rules): Rearrange the default command
+       lines to conform to POSIX rules (put the filename argument $<
+       _after_ the OUTPUT_OPTION, not before it).
+
        * various: Changed !strncmp() calls to strneq() macros.
 
        * misc.c (sindex): Make slightly more efficient.
@@ -18,9 +26,8 @@
        (define_automatic_variables): Ditto.
        * vpath.c (construct_vpath_list): Ditto.
 
-       * misc.c (xrealloc): If PTR is NULL, call malloc to conform to
-       the standard--some older versions of realloc are non-standard so
-       make xrealloc DTRT.
+       * misc.c (xrealloc): Some reallocs are non-standard: work around
+       them in xrealloc by calling malloc if PTR is NULL.
        * main.c (main): Call xrealloc() directly instead of testing for
        NULL.
 
@@ -28,8 +35,8 @@
        non-standard versions of free() don't like it.
 
        * configure.in (--enable-dmalloc): Install some support for using
-       dmalloc (http://www.dmalloc.com) with make.  Use --enable-dmalloc
-       with configure.
+       dmalloc (http://www.dmalloc.com/) with make.  Use --enable-dmalloc
+       with configure to enable it.
 
 1999-07-20  Paul D. Smith  <psmith@gnu.org>
 
        suggested by Howard Chu <hyc@highlandsun.com>.
 
        * configure.in (job-server): New disable option for job server
-       support--it's enabled by default.
+       support--it's enabled by default.  If it works well this will go
+       away.
 
        * NEWS: Summarize the new feature.
 
        kept although it's not needed or used unless you don't have
        waitpid() or wait3().
 
+1999-04-10  Paul D. Smith  <psmith@gnu.org>
+
+       * main.c (main): Reset the considered bit on all the makefiles if
+       something failed to update; we need to examine them again if they
+       appear as normal targets in order to get the proper error message.
+
+1999-04-09  Paul D. Smith  <psmith@gnu.org>
+
+       Performance enhancement from Tim Magill <tim.magill@telops.gte.com>.
+
+       * remake.c (update_file): If you have large numbers of
+       dependencies and you run in parallel, make can spend considerable
+       time each pass through the graph looking at branches it has
+       already seen.  Since we only reap_children() when starting a pass,
+       not in the middle, if a branch has been seen already in that pass
+       nothing interesting can happen until the next pass.  So, we toggle
+       a bit saying whether we've seen this target in this pass or not.
+       (update_goal_chain): Initially set the global considered toggle to
+       1, since all targets initialize their boolean to 0.  At the end of
+       each pass, toggle the global considered variable.  * filedef.h
+       (struct file): Per-file considered toggle bit.  * file.c: New
+       global toggle variable considered.
+
 1999-04-03  Paul D. Smith  <psmith@gnu.org>
 
        * remake.c (f_mtime): If: a) we found a file and b) we didn't
        * config.h.W32: Ditto.
        * configh.dos: Ditto.
 
+       * dir.c (find_directory) [WINDOWS32]: Windows stat() fails if
+       directory names end with `\' so strip it.
+
 1998-08-17  Paul D. Smith  <psmith@gnu.org>
 
        * make.texinfo: Added copyright year to the printed copy.  Removed
index b5d22c6..bf49040 100644 (file)
@@ -1,6 +1,6 @@
 # This is a -*-Makefile-*-, or close enough
 
-AUTOMAKE_OPTIONS = 1.3
+AUTOMAKE_OPTIONS = 1.4
 
 bin_PROGRAMS = make
 
index f62c192..82bb502 100644 (file)
@@ -3,7 +3,7 @@ AC_REVISION([$Id$])
 AC_PREREQ(2.13)dnl             dnl Minimum Autoconf version required.
 AC_INIT(vpath.c)dnl            dnl A distinctive file to look for in srcdir.
 
-AM_INIT_AUTOMAKE(make, 3.77.xx)
+AM_INIT_AUTOMAKE(make, 3.77.90)
 AM_CONFIG_HEADER(config.h)
 
 dnl Regular configure stuff
index 1681144..79f313e 100644 (file)
--- a/default.c
+++ b/default.c
@@ -183,21 +183,21 @@ static char *default_suffix_rules[] =
     ".S.o",
     "$(COMPILE.S) -o $@ $<",
     ".c.o",
-    "$(COMPILE.c) $< $(OUTPUT_OPTION)",
+    "$(COMPILE.c) $(OUTPUT_OPTION) $<",
     ".cc.o",
-    "$(COMPILE.cc) $< $(OUTPUT_OPTION)",
+    "$(COMPILE.cc) $(OUTPUT_OPTION) $<",
     ".C.o",
-    "$(COMPILE.C) $< $(OUTPUT_OPTION)",
+    "$(COMPILE.C) $(OUTPUT_OPTION) $<",
     ".cpp.o",
-    "$(COMPILE.cpp) $< $(OUTPUT_OPTION)",
+    "$(COMPILE.cpp) $(OUTPUT_OPTION) $<",
     ".f.o",
-    "$(COMPILE.f) $< $(OUTPUT_OPTION)",
+    "$(COMPILE.f) $(OUTPUT_OPTION) $<",
     ".p.o",
-    "$(COMPILE.p) $< $(OUTPUT_OPTION)",
+    "$(COMPILE.p) $(OUTPUT_OPTION) $<",
     ".F.o",
-    "$(COMPILE.F) $< $(OUTPUT_OPTION)",
+    "$(COMPILE.F) $(OUTPUT_OPTION) $<",
     ".r.o",
-    "$(COMPILE.r) $< $(OUTPUT_OPTION)",
+    "$(COMPILE.r) $(OUTPUT_OPTION) $<",
     ".mod.o",
     "$(COMPILE.mod) -o $@ $<",
 
@@ -222,9 +222,9 @@ static char *default_suffix_rules[] =
     "@$(RM) $@ \n $(LEX.l) $< > $@",
 
     ".F.f",
-    "$(PREPROCESS.F) $< $(OUTPUT_OPTION)",
+    "$(PREPROCESS.F) $(OUTPUT_OPTION) $<",
     ".r.f",
-    "$(PREPROCESS.r) $< $(OUTPUT_OPTION)",
+    "$(PREPROCESS.r) $(OUTPUT_OPTION) $<",
 
     /* This might actually make lex.yy.c if there's no %R%
        directive in $*.l, but in that case why were you
diff --git a/dir.c b/dir.c
index fc0b6f5..0d0f078 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -332,6 +332,13 @@ find_directory (name)
 #ifdef VMS
       if (vmsstat_dir (name, &st) < 0)
 #else
+
+#ifdef WINDOWS32
+      /* Remove any trailing '\'.  Windows32 stat fails even on valid
+         directories if they end in '\'. */
+      if (p[-1] == '\\')
+        p[-1] = '\0';
+#endif
       if (stat (name, &st) < 0)
 #endif
        {
diff --git a/file.c b/file.c
index 2a9a791..65f3e2d 100644 (file)
--- a/file.c
+++ b/file.c
@@ -38,6 +38,9 @@ static struct file *files[FILE_BUCKETS];
 
 unsigned int num_intermediates = 0;
 
+/* Current value for pruning the scan of the goal chain (toggle 0/1).  */
+
+unsigned int considered = 0;
 
 /* Access the hash table of all file records.
    lookup_file  given a name, return the struct file * for that name,
index c96c2e3..425bb04 100644 (file)
--- a/filedef.h
+++ b/filedef.h
@@ -92,12 +92,18 @@ struct file
     unsigned int ignore_vpath:1;/* Nonzero if we threw out VPATH name.  */
     unsigned int pat_searched:1;/* Nonzero if we already searched for
                                    pattern-specific variables.  */
+    unsigned int considered:1;  /* equal to `considered' if file has been
+                                   considered on current scan of goal chain */
   };
 
 /* Number of intermediate files entered.  */
 
 extern unsigned int num_intermediates;
 
+/* Current value for pruning the scan of the goal chain (toggle 0/1).  */
+
+extern unsigned int considered;
+
 extern struct file *default_goal_file, *suffix_file, *default_file;
 
 
index b7e85ad..6fa4365 100644 (file)
@@ -1,3 +1,14 @@
+1999-07-21  Paul D. Smith  <psmith@gnu.org>
+
+       * glob.c, glob.h, fnmatch.c, fnmatch.h: Update to latest version
+       from GLIBC.
+
+       * fnmatch.c (internal_fnmatch): Use K&R definition syntax, not ANSI.
+       (__strchrnul): This won't exist outside GLIBC, so create one.
+
+       * glob.c: Move getlogin{,_r} prototypes below glob.h to get __P()
+       macro.
+
 1998-08-05  Paul D. Smith  <psmith@gnu.org>
 
        * configure.in: Remove; configuration for glob is handled by the
index 964ac19..e6359b4 100644 (file)
@@ -1,6 +1,6 @@
 # -*-Makefile-*-, or close enough
 
-AUTOMAKE_OPTIONS =     1.3 foreign
+AUTOMAKE_OPTIONS =     1.4 foreign
 
 noinst_LIBRARIES =     libglob.a
 
index 2d6f6af..4ad86ff 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 93, 96, 97, 98 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    This library is free software; you can redistribute it and/or
@@ -29,7 +29,7 @@
 #include <fnmatch.h>
 #include <ctype.h>
 
-#if HAVE_STRING_H
+#if HAVE_STRING_H || defined _LIBC
 # include <string.h>
 #else
 # include <strings.h>
@@ -127,16 +127,35 @@ extern char *getenv ();
 extern int errno;
 # endif
 
+/* This function doesn't exist on most systems.  */
+
+# if !defined HAVE___STRCHRNUL && !defined _LIBC
+static char *
+__strchrnul (s, c)
+     register const char *s;
+     int c;
+{
+  c = (unsigned char)c;
+  while (*s && *s != c)
+    ++s;
+  return (char *)s;
+}
+# endif
+
 /* Match STRING against the filename pattern PATTERN, returning zero if
    it matches, nonzero if not.  */
-int
-fnmatch (pattern, string, flags)
+static int
+#ifdef _LIBC
+internal_function
+#endif
+internal_fnmatch (pattern, string, no_leading_period, flags)
      const char *pattern;
      const char *string;
+     int no_leading_period;
      int flags;
 {
   register const char *p = pattern, *n = string;
-  register char c;
+  register unsigned char c;
 
 /* Note that this evaluates C many times.  */
 # ifdef _LIBC
@@ -154,10 +173,11 @@ fnmatch (pattern, string, flags)
        case '?':
          if (*n == '\0')
            return FNM_NOMATCH;
-         else if ((flags & FNM_FILE_NAME) && *n == '/')
+         else if (*n == '/' && (flags & FNM_FILE_NAME))
            return FNM_NOMATCH;
-         else if ((flags & FNM_PERIOD) && *n == '.' &&
-                  (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+         else if (*n == '.' && no_leading_period
+                  && (n == string
+                      || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
            return FNM_NOMATCH;
          break;
 
@@ -170,18 +190,19 @@ fnmatch (pattern, string, flags)
                return FNM_NOMATCH;
              c = FOLD (c);
            }
-         if (FOLD (*n) != c)
+         if (FOLD ((unsigned char) *n) != c)
            return FNM_NOMATCH;
          break;
 
        case '*':
-         if ((flags & FNM_PERIOD) && *n == '.' &&
-             (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+         if (*n == '.' && no_leading_period
+             && (n == string
+                 || (n[-1] == '/' && (flags & FNM_FILE_NAME))))
            return FNM_NOMATCH;
 
          for (c = *p++; c == '?' || c == '*'; c = *p++)
            {
-             if ((flags & FNM_FILE_NAME) && *n == '/')
+             if (*n == '/' && (flags & FNM_FILE_NAME))
                /* A slash does not match a wildcard under FNM_FILE_NAME.  */
                return FNM_NOMATCH;
              else if (c == '?')
@@ -199,17 +220,65 @@ fnmatch (pattern, string, flags)
            }
 
          if (c == '\0')
-           return 0;
+           /* The wildcard(s) is/are the last element of the pattern.
+              If the name is a file name and contains another slash
+              this does mean it cannot match.  */
+           return ((flags & FNM_FILE_NAME) && strchr (n, '/') != NULL
+                   ? FNM_NOMATCH : 0);
+         else
+           {
+             const char *endp;
 
-         {
-           char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
-           c1 = FOLD (c1);
-           for (--p; *n != '\0'; ++n)
-             if ((c == '[' || FOLD (*n) == c1) &&
-                 fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
-               return 0;
-           return FNM_NOMATCH;
-         }
+             endp = __strchrnul (n, (flags & FNM_FILE_NAME) ? '/' : '\0');
+
+             if (c == '[')
+               {
+                 int flags2 = ((flags & FNM_FILE_NAME)
+                               ? flags : (flags & ~FNM_PERIOD));
+
+                 for (--p; n < endp; ++n)
+                   if (internal_fnmatch (p, n,
+                                         (no_leading_period
+                                          && (n == string
+                                              || (n[-1] == '/'
+                                                  && (flags
+                                                      & FNM_FILE_NAME)))),
+                                         flags2)
+                       == 0)
+                     return 0;
+               }
+             else if (c == '/' && (flags & FNM_FILE_NAME))
+               {
+                 while (*n != '\0' && *n != '/')
+                   ++n;
+                 if (*n == '/'
+                     && (internal_fnmatch (p, n + 1, flags & FNM_PERIOD,
+                                           flags) == 0))
+                   return 0;
+               }
+             else
+               {
+                 int flags2 = ((flags & FNM_FILE_NAME)
+                               ? flags : (flags & ~FNM_PERIOD));
+
+                 if (c == '\\' && !(flags & FNM_NOESCAPE))
+                   c = *p;
+                 c = FOLD (c);
+                 for (--p; n < endp; ++n)
+                   if (FOLD ((unsigned char) *n) == c
+                       && (internal_fnmatch (p, n,
+                                             (no_leading_period
+                                              && (n == string
+                                                  || (n[-1] == '/'
+                                                      && (flags
+                                                          & FNM_FILE_NAME)))),
+                                             flags2) == 0))
+                     return 0;
+               }
+           }
+
+         /* If we come here no match is possible with the wildcard.  */
+         return FNM_NOMATCH;
 
        case '[':
          {
@@ -224,8 +293,10 @@ fnmatch (pattern, string, flags)
            if (*n == '\0')
              return FNM_NOMATCH;
 
-           if (*n == '.' && (flags & FNM_PERIOD) &&
-               (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+           if (*n == '.' && no_leading_period && (n == string
+                                                  || (n[-1] == '/'
+                                                      && (flags
+                                                          & FNM_FILE_NAME))))
              return FNM_NOMATCH;
 
            if (*n == '/' && (flags & FNM_FILE_NAME))
@@ -239,13 +310,14 @@ fnmatch (pattern, string, flags)
            c = *p++;
            for (;;)
              {
-               int fn = FOLD (*n);
+               unsigned char fn = FOLD ((unsigned char) *n);
 
                if (!(flags & FNM_NOESCAPE) && c == '\\')
                  {
                    if (*p == '\0')
                      return FNM_NOMATCH;
-                   c = FOLD (*p++);
+                   c = FOLD ((unsigned char) *p);
+                   ++p;
 
                    if (c == fn)
                      goto matched;
@@ -258,6 +330,7 @@ fnmatch (pattern, string, flags)
 # if defined _LIBC || (defined HAVE_WCTYPE_H && defined HAVE_WCHAR_H)
                    wctype_t wt;
 # endif
+                   const char *startp = p;
 
                    for (;;)
                      {
@@ -272,7 +345,15 @@ fnmatch (pattern, string, flags)
                            p += 2;
                            break;
                          }
-                       str[c1++] = 'c';
+                       if (c < 'a' || c >= 'z')
+                         {
+                           /* This cannot possibly be a character class name.
+                              Match it as a normal range.  */
+                           p = startp;
+                           c = '[';
+                           goto normal_bracket;
+                         }
+                       str[c1++] = c;
                      }
                    str[c1] = '\0';
 
@@ -282,47 +363,52 @@ fnmatch (pattern, string, flags)
                      /* Invalid character class name.  */
                      return FNM_NOMATCH;
 
-                   if (__iswctype (__btowc (*n), wt))
+                   if (__iswctype (__btowc ((unsigned char) *n), wt))
                      goto matched;
 # else
-                   if ((STREQ (str, "alnum") && ISALNUM (*n))
-                       || (STREQ (str, "alpha") && ISALPHA (*n))
-                       || (STREQ (str, "blank") && ISBLANK (*n))
-                       || (STREQ (str, "cntrl") && ISCNTRL (*n))
-                       || (STREQ (str, "digit") && ISDIGIT (*n))
-                       || (STREQ (str, "graph") && ISGRAPH (*n))
-                       || (STREQ (str, "lower") && ISLOWER (*n))
-                       || (STREQ (str, "print") && ISPRINT (*n))
-                       || (STREQ (str, "punct") && ISPUNCT (*n))
-                       || (STREQ (str, "space") && ISSPACE (*n))
-                       || (STREQ (str, "upper") && ISUPPER (*n))
-                       || (STREQ (str, "xdigit") && ISXDIGIT (*n)))
+                   if ((STREQ (str, "alnum") && ISALNUM ((unsigned char) *n))
+                       || (STREQ (str, "alpha") && ISALPHA ((unsigned char) *n))
+                       || (STREQ (str, "blank") && ISBLANK ((unsigned char) *n))
+                       || (STREQ (str, "cntrl") && ISCNTRL ((unsigned char) *n))
+                       || (STREQ (str, "digit") && ISDIGIT ((unsigned char) *n))
+                       || (STREQ (str, "graph") && ISGRAPH ((unsigned char) *n))
+                       || (STREQ (str, "lower") && ISLOWER ((unsigned char) *n))
+                       || (STREQ (str, "print") && ISPRINT ((unsigned char) *n))
+                       || (STREQ (str, "punct") && ISPUNCT ((unsigned char) *n))
+                       || (STREQ (str, "space") && ISSPACE ((unsigned char) *n))
+                       || (STREQ (str, "upper") && ISUPPER ((unsigned char) *n))
+                       || (STREQ (str, "xdigit") && ISXDIGIT ((unsigned char) *n)))
                      goto matched;
 # endif
                  }
                else if (c == '\0')
                  /* [ (unterminated) loses.  */
                  return FNM_NOMATCH;
-               else if (FOLD (c) == fn)
-                 goto matched;
-
-               cold = c;
-               c = *p++;
-
-               if (c == '-' && *p != ']')
+               else
                  {
-                   /* It is a range.  */
-                   char cend = *p++;
-                   if (!(flags & FNM_NOESCAPE) && cend == '\\')
-                     cend = *p++;
-                   if (cend == '\0')
-                     return FNM_NOMATCH;
-
-                   if (cold <= fn && fn <= FOLD (cend))
+                 normal_bracket:
+                   if (FOLD (c) == fn)
                      goto matched;
 
+                   cold = c;
                    c = *p++;
+
+                   if (c == '-' && *p != ']')
+                     {
+                       /* It is a range.  */
+                       unsigned char cend = *p++;
+                       if (!(flags & FNM_NOESCAPE) && cend == '\\')
+                         cend = *p++;
+                       if (cend == '\0')
+                         return FNM_NOMATCH;
+
+                       if (cold <= fn && fn <= FOLD (cend))
+                         goto matched;
+
+                       c = *p++;
+                     }
                  }
+
                if (c == ']')
                  break;
              }
@@ -363,7 +449,7 @@ fnmatch (pattern, string, flags)
          break;
 
        default:
-         if (c != FOLD (*n))
+         if (c != FOLD ((unsigned char) *n))
            return FNM_NOMATCH;
        }
 
@@ -382,4 +468,14 @@ fnmatch (pattern, string, flags)
 # undef FOLD
 }
 
+
+int
+fnmatch (pattern, string, flags)
+     const char *pattern;
+     const char *string;
+     int flags;
+{
+  return internal_fnmatch (pattern, string, flags & FNM_PERIOD, flags);
+}
+
 #endif /* _LIBC or not __GNU_LIBRARY__.  */
index 4d1eb3e..cc3ec37 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1993, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 93, 96, 97, 98, 99 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -24,8 +24,10 @@ extern "C" {
 #endif
 
 #if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
-# undef        __P
-# define __P(protos)   protos
+# if !defined __GLIBC__ || !defined __P
+#  undef       __P
+#  define __P(protos)  protos
+# endif
 #else /* Not C++ or ANSI C.  */
 # undef        __P
 # define __P(protos)   ()
@@ -66,13 +68,13 @@ extern "C" {
    `fnmatch'.  Since this is not the case here it will never be
    returned but the conformance test suites still require the symbol
    to be defined.  */
-#if (_XOPEN_SOURCE - 0) == 500
+#ifdef _XOPEN_SOURCE
 # define FNM_NOSYS     (-1)
 #endif
 
-/* Match STRING against the filename pattern PATTERN,
+/* Match NAME against the filename pattern PATTERN,
    returning zero if it matches, FNM_NOMATCH if not.  */
-extern int fnmatch __P ((__const char *__pattern, __const char *__string,
+extern int fnmatch __P ((__const char *__pattern, __const char *__name,
                         int __flags));
 
 #ifdef __cplusplus
index eab7919..1ab5d8b 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,92,93,94,95,96,97,98 Free Software Foundation, Inc.
+/* Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public License as
@@ -177,10 +177,10 @@ extern void bcopy ();
 
 #if !defined HAVE_MEMPCPY && __GLIBC__ - 0 == 2 && __GLIBC_MINOR__ >= 1
 # define HAVE_MEMPCPY  1
+# undef  mempcpy
 # define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len)
 #endif
 
-
 #ifndef        __GNU_LIBRARY__
 # ifdef        __GNUC__
 __inline
@@ -240,11 +240,17 @@ extern char *alloca ();
 #endif
 
 #ifdef _LIBC
+# undef strdup
 # define strdup(str) __strdup (str)
 # define sysconf(id) __sysconf (id)
 # define closedir(dir) __closedir (dir)
 # define opendir(name) __opendir (name)
 # define readdir(str) __readdir (str)
+# define getpwnam_r(name, bufp, buf, len, res) \
+   __getpwnam_r (name, bufp, buf, len, res)
+# ifndef __stat
+#  define __stat(fname, buf) __xstat (_STAT_VER, fname, buf)
+# endif
 #endif
 
 #if !(defined STDC_HEADERS || defined __GNU_LIBRARY__)
@@ -274,6 +280,12 @@ extern char *alloca ();
 # undef        GLOB_PERIOD
 #endif
 #include <glob.h>
+
+#ifdef HAVE_GETLOGIN_R
+extern int getlogin_r __P ((char *, size_t));
+#else
+extern char *getlogin __P ((void));
+#endif
 \f
 static
 #if __GNUC__ - 0 >= 2
@@ -282,7 +294,7 @@ inline
 const char *next_brace_sub __P ((const char *begin));
 static int glob_in_dir __P ((const char *pattern, const char *directory,
                             int flags,
-                            int (*errfunc) __P ((const char *, int)),
+                            int (*errfunc) (const char *, int),
                             glob_t *pglob));
 static int prefix_array __P ((const char *prefix, char **array, size_t n));
 static int collated_compare __P ((const __ptr_t, const __ptr_t));
@@ -349,7 +361,7 @@ glob (pattern, flags, errfunc, pglob)
      glob_t *pglob;
 {
   const char *filename;
-  char *dirname;
+  const char *dirname;
   size_t dirlen;
   int status;
   int oldcount;
@@ -501,39 +513,40 @@ glob (pattern, flags, errfunc, pglob)
     {
       /* This can mean two things: a simple name or "~name".  The later
         case is nothing but a notation for a directory.  */
-      if ((flags & GLOB_TILDE) && pattern[0] == '~')
+      if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
        {
-         dirname = (char *) pattern;
+         dirname = pattern;
          dirlen = strlen (pattern);
 
-          /* Set FILENAME to NULL as a special flag.  This is ugly but
-             other solutions would require much more code.  We test for
-             this special case below.  */
-          filename = NULL;
+         /* Set FILENAME to NULL as a special flag.  This is ugly but
+            other solutions would require much more code.  We test for
+            this special case below.  */
+         filename = NULL;
        }
       else
        {
-          filename = pattern;
+         filename = pattern;
 #ifdef _AMIGA
-          dirname = (char *) "";
+         dirname = "";
 #else
-          dirname = (char *) ".";
+         dirname = ".";
 #endif
-          dirlen = 0;
-        }
+         dirlen = 0;
+       }
     }
   else if (filename == pattern)
     {
       /* "/pattern".  */
-      dirname = (char *) "/";
+      dirname = "/";
       dirlen = 1;
       ++filename;
     }
   else
     {
+      char *newp;
       dirlen = filename - pattern;
 #if defined __MSDOS__ || defined WINDOWS32
-      if ((*filename == ':')
+      if (*filename == ':'
          || (filename > pattern + 1 && filename[-1] == ':'))
        {
          char *drive_spec;
@@ -555,30 +568,31 @@ glob (pattern, flags, errfunc, pglob)
             from "d:/", since "d:" and "d:/" are not the same.*/
        }
 #endif
-      dirname = (char *) __alloca (dirlen + 1);
+      newp = (char *) __alloca (dirlen + 1);
 #ifdef HAVE_MEMPCPY
-      *((char *) mempcpy (dirname, pattern, dirlen)) = '\0';
+      *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
 #else
-      memcpy (dirname, pattern, dirlen);
-      dirname[dirlen] = '\0';
+      memcpy (newp, pattern, dirlen);
+      newp[dirlen] = '\0';
 #endif
+      dirname = newp;
       ++filename;
 
       if (filename[0] == '\0'
 #if defined __MSDOS__ || defined WINDOWS32
-          && dirname[dirlen-1] != ':'
-          && (dirlen < 3 || dirname[dirlen-2] != ':'
-             || dirname[dirlen-1] != '/')
+          && dirname[dirlen - 1] != ':'
+         && (dirlen < 3 || dirname[dirlen - 2] != ':'
+             || dirname[dirlen - 1] != '/')
 #endif
-          && dirlen > 1)
-      /* "pattern/".  Expand "pattern", appending slashes.  */
-      {
-        int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
-        if (val == 0)
-          pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
-                             | (flags & GLOB_MARK));
-        return val;
-      }
+         && dirlen > 1)
+       /* "pattern/".  Expand "pattern", appending slashes.  */
+       {
+         int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
+         if (val == 0)
+           pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
+                              | (flags & GLOB_MARK));
+         return val;
+       }
     }
 
   if (!(flags & GLOB_APPEND))
@@ -590,12 +604,12 @@ glob (pattern, flags, errfunc, pglob)
   oldcount = pglob->gl_pathc;
 
 #ifndef VMS
-  if ((flags & GLOB_TILDE) && dirname[0] == '~')
+  if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
     {
       if (dirname[1] == '\0' || dirname[1] == '/')
        {
          /* Look up home directory.  */
-         char *home_dir = getenv ("HOME");
+         const char *home_dir = getenv ("HOME");
 # ifdef _AMIGA
          if (home_dir == NULL || home_dir[0] == '\0')
            home_dir = "SYS:";
@@ -607,45 +621,61 @@ glob (pattern, flags, errfunc, pglob)
          if (home_dir == NULL || home_dir[0] == '\0')
            {
              int success;
+             char *name;
 #   if defined HAVE_GETLOGIN_R || defined _LIBC
-             extern int getlogin_r __P ((char *, size_t));
              size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
-             char *name;
 
              if (buflen == 0)
                /* `sysconf' does not support _SC_LOGIN_NAME_MAX.  Try
                   a moderate value.  */
-               buflen = 16;
+               buflen = 20;
              name = (char *) __alloca (buflen);
 
              success = getlogin_r (name, buflen) >= 0;
 #   else
-             extern char *getlogin __P ((void));
-             char *name;
-
              success = (name = getlogin ()) != NULL;
 #   endif
              if (success)
                {
+                 struct passwd *p;
 #   if defined HAVE_GETPWNAM_R || defined _LIBC
                  size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX);
                  char *pwtmpbuf;
-                 struct passwd pwbuf, *p;
+                 struct passwd pwbuf;
+                 int save = errno;
 
+                 if (pwbuflen == -1)
+                   /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
+                      Try a moderate value.  */
+                   pwbuflen = 1024;
                  pwtmpbuf = (char *) __alloca (pwbuflen);
 
-                 success = (__getpwnam_r (name, &pwbuf, pwtmpbuf,
-                                          pwbuflen, &p) >= 0);
+                 while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
+                        != 0)
+                   {
+                     if (errno != ERANGE)
+                       {
+                         p = NULL;
+                         break;
+                       }
+                     pwbuflen *= 2;
+                     pwtmpbuf = (char *) __alloca (pwbuflen);
+                     __set_errno (save);
+                   }
 #   else
-                 struct passwd *p = getpwnam (name);
-                 success = p != NULL;
+                 p = getpwnam (name);
 #   endif
-                 if (success)
+                 if (p != NULL)
                    home_dir = p->pw_dir;
                }
            }
          if (home_dir == NULL || home_dir[0] == '\0')
-           home_dir = (char *) "~"; /* No luck.  */
+           {
+             if (flags & GLOB_TILDE_CHECK)
+               return GLOB_NOMATCH;
+             else
+               home_dir = "~"; /* No luck.  */
+           }
 #  endif /* WINDOWS32 */
 # endif
          /* Now construct the full directory.  */
@@ -670,40 +700,58 @@ glob (pattern, flags, errfunc, pglob)
       else
        {
          char *end_name = strchr (dirname, '/');
-         char *user_name;
-         char *home_dir;
+         const char *user_name;
+         const char *home_dir;
 
          if (end_name == NULL)
            user_name = dirname + 1;
          else
            {
-             user_name = (char *) __alloca (end_name - dirname);
+             char *newp;
+             newp = (char *) __alloca (end_name - dirname);
 # ifdef HAVE_MEMPCPY
-             *((char *) mempcpy (user_name, dirname + 1, end_name - dirname))
+             *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
                = '\0';
 # else
-             memcpy (user_name, dirname + 1, end_name - dirname);
-             user_name[end_name - dirname - 1] = '\0';
+             memcpy (newp, dirname + 1, end_name - dirname);
+             newp[end_name - dirname - 1] = '\0';
 # endif
+             user_name = newp;
            }
 
          /* Look up specific user's home directory.  */
          {
+           struct passwd *p;
 #  if defined HAVE_GETPWNAM_R || defined _LIBC
            size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
-           char *pwtmpbuf = (char *) __alloca (buflen);
-           struct passwd pwbuf, *p;
-           if (__getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) >= 0)
-             home_dir = p->pw_dir;
-           else
-             home_dir = NULL;
+           char *pwtmpbuf;
+           struct passwd pwbuf;
+           int save = errno;
+
+           if (buflen == -1)
+             /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.  Try a
+                moderate value.  */
+             buflen = 1024;
+           pwtmpbuf = (char *) __alloca (buflen);
+
+           while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
+             {
+               if (errno != ERANGE)
+                 {
+                   p = NULL;
+                   break;
+                 }
+               buflen *= 2;
+               pwtmpbuf = __alloca (buflen);
+               __set_errno (save);
+             }
 #  else
-           struct passwd *p = getpwnam (user_name);
+           p = getpwnam (user_name);
+#  endif
            if (p != NULL)
              home_dir = p->pw_dir;
            else
              home_dir = NULL;
-#  endif
          }
          /* If we found a home directory use this.  */
          if (home_dir != NULL)
@@ -722,6 +770,11 @@ glob (pattern, flags, errfunc, pglob)
 #  endif
              dirname = newp;
            }
+         else
+           if (flags & GLOB_TILDE_CHECK)
+             /* We have to regard it as an error if we cannot find the
+                home directory.  */
+             return GLOB_NOMATCH;
        }
 # endif        /* Not Amiga && not WINDOWS32.  */
     }
@@ -850,78 +903,80 @@ glob (pattern, flags, errfunc, pglob)
         flag was set we must return the list consisting of the disrectory
         names followed by the filename.  */
       if (pglob->gl_pathc == oldcount)
-       /* No matches.  */
-       if (flags & GLOB_NOCHECK)
-         {
-           size_t filename_len = strlen (filename) + 1;
-           char **new_pathv;
-           struct stat st;
-
-           /* This is an pessimistic guess about the size.  */
-           pglob->gl_pathv
-             = (char **) realloc (pglob->gl_pathv,
-                                  (pglob->gl_pathc +
-                                   ((flags & GLOB_DOOFFS) ?
-                                    pglob->gl_offs : 0) +
-                                   dirs.gl_pathc + 1) *
-                                  sizeof (char *));
-           if (pglob->gl_pathv == NULL)
-             {
-               globfree (&dirs);
-               return GLOB_NOSPACE;
-             }
+       {
+         /* No matches.  */
+         if (flags & GLOB_NOCHECK)
+           {
+             size_t filename_len = strlen (filename) + 1;
+             char **new_pathv;
+             struct stat st;
+
+             /* This is an pessimistic guess about the size.  */
+             pglob->gl_pathv
+               = (char **) realloc (pglob->gl_pathv,
+                                    (pglob->gl_pathc +
+                                     ((flags & GLOB_DOOFFS) ?
+                                      pglob->gl_offs : 0) +
+                                     dirs.gl_pathc + 1) *
+                                    sizeof (char *));
+             if (pglob->gl_pathv == NULL)
+               {
+                 globfree (&dirs);
+                 return GLOB_NOSPACE;
+               }
 
-           if (flags & GLOB_DOOFFS)
-             while (pglob->gl_pathc < pglob->gl_offs)
-               pglob->gl_pathv[pglob->gl_pathc++] = NULL;
+             if (flags & GLOB_DOOFFS)
+               while (pglob->gl_pathc < pglob->gl_offs)
+                 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
 
-           for (i = 0; i < dirs.gl_pathc; ++i)
-             {
-               const char *dir = dirs.gl_pathv[i];
-               size_t dir_len = strlen (dir);
-
-               /* First check whether this really is a directory.  */
-               if (((flags & GLOB_ALTDIRFUNC)
-                    ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
-                   || !S_ISDIR (st.st_mode))
-                 /* No directory, ignore this entry.  */
-                 continue;
-
-               pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1
-                                                          + filename_len);
-               if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
-                 {
-                   globfree (&dirs);
-                   globfree (pglob);
-                   return GLOB_NOSPACE;
-                 }
+             for (i = 0; i < dirs.gl_pathc; ++i)
+               {
+                 const char *dir = dirs.gl_pathv[i];
+                 size_t dir_len = strlen (dir);
+
+                 /* First check whether this really is a directory.  */
+                 if (((flags & GLOB_ALTDIRFUNC)
+                      ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
+                     || !S_ISDIR (st.st_mode))
+                   /* No directory, ignore this entry.  */
+                   continue;
+
+                 pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1
+                                                            + filename_len);
+                 if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
+                   {
+                     globfree (&dirs);
+                     globfree (pglob);
+                     return GLOB_NOSPACE;
+                   }
 
 #ifdef HAVE_MEMPCPY
-               mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc],
-                                          dir, dir_len),
-                                 "/", 1),
-                        filename, filename_len);
+                 mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc],
+                                            dir, dir_len),
+                                   "/", 1),
+                          filename, filename_len);
 #else
-               memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len);
-               pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/';
-               memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1],
-                       filename, filename_len);
+                 memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len);
+                 pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/';
+                 memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1],
+                         filename, filename_len);
 #endif
-               ++pglob->gl_pathc;
-             }
+                 ++pglob->gl_pathc;
+               }
 
-           pglob->gl_pathv[pglob->gl_pathc] = NULL;
-           pglob->gl_flags = flags;
+             pglob->gl_pathv[pglob->gl_pathc] = NULL;
+             pglob->gl_flags = flags;
 
-           /* Now we know how large the gl_pathv vector must be.  */
-           new_pathv = (char **) realloc (pglob->gl_pathv,
-                                           ((pglob->gl_pathc + 1)
-                                            * sizeof (char *)));
-           if (new_pathv != NULL)
-             pglob->gl_pathv = new_pathv;
-         }
-       else
-         return GLOB_NOMATCH;
+             /* Now we know how large the gl_pathv vector must be.  */
+             new_pathv = (char **) realloc (pglob->gl_pathv,
+                                            ((pglob->gl_pathc + 1)
+                                             * sizeof (char *)));
+             if (new_pathv != NULL)
+               pglob->gl_pathv = new_pathv;
+           }
+         else
+           return GLOB_NOMATCH;
+       }
 
       globfree (&dirs);
     }
@@ -1092,6 +1147,8 @@ prefix_array (dirname, array, n)
 }
 
 
+/* We must not compile this function twice.  */
+#if !defined _LIBC || !defined NO_GLOB_PATTERN_P
 /* Return nonzero if PATTERN contains any metacharacters.
    Metacharacters can be quoted with backslashes if QUOTE is nonzero.  */
 int
@@ -1126,8 +1183,9 @@ __glob_pattern_p (pattern, quote)
 
   return 0;
 }
-#ifdef _LIBC
+# ifdef _LIBC
 weak_alias (__glob_pattern_p, glob_pattern_p)
+# endif
 #endif
 
 
@@ -1213,8 +1271,9 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
                    : (__ptr_t) opendir (directory));
          if (stream == NULL)
            {
-             if ((errfunc != NULL && (*errfunc) (directory, errno))
-                 || (flags & GLOB_ERR))
+             if (errno != ENOTDIR
+                 && ((errfunc != NULL && (*errfunc) (directory, errno))
+                     || (flags & GLOB_ERR)))
                return GLOB_ABORTED;
              nfound = 0;
              meta = 0;
@@ -1317,10 +1376,12 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob)
 
   save = errno;
   if (stream != NULL)
-    if (flags & GLOB_ALTDIRFUNC)
-      (*pglob->gl_closedir) (stream);
-    else
-      closedir ((DIR *) stream);
+    {
+      if (flags & GLOB_ALTDIRFUNC)
+       (*pglob->gl_closedir) (stream);
+      else
+       closedir ((DIR *) stream);
+    }
   __set_errno (save);
 
   return nfound == 0 ? GLOB_NOMATCH : 0;
index a546c86..6a3ab18 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1992, 1995, 1996, 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 95, 96, 97, 98 Free Software Foundation, Inc.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public License as
@@ -24,21 +24,42 @@ extern "C" {
 
 #undef __ptr_t
 #if defined __cplusplus || (defined __STDC__ && __STDC__) || defined WINDOWS32
-# undef        __P
-# define __P(protos)   protos
-# define __ptr_t       void *
-# if !defined __GNUC__ || __GNUC__ < 2
-#  undef __const
-#  define __const const
+# if !defined __GLIBC__ || !defined __P
+#  undef __P
+#  undef __PMT
+#  define __P(protos)  protos
+#  define __PMT(protos)        protos
+#  if !defined __GNUC__ || __GNUC__ < 2
+#   undef __const
+#   define __const const
+#  endif
 # endif
+# define __ptr_t       void *
 #else /* Not C++ or ANSI C.  */
 # undef        __P
+# undef __PMT
 # define __P(protos)   ()
+# define __PMT(protos) ()
 # undef        __const
 # define __const
 # define __ptr_t       char *
 #endif /* C++ or ANSI C.  */
 
+/* We need `size_t' for the following definitions.  */
+#ifndef __size_t
+# if defined __GNUC__ && __GNUC__ >= 2
+typedef __SIZE_TYPE__ __size_t;
+# else
+/* This is a guess.  */
+typedef unsigned long int __size_t;
+# endif
+#else
+/* The GNU CC stddef.h version defines __size_t as empty.  We need a real
+   definition.  */
+# undef __size_t
+# define __size_t size_t
+#endif
+
 /* Bits set in the FLAGS argument to `glob'.  */
 #define        GLOB_ERR        (1 << 0)/* Return on read errors.  */
 #define        GLOB_MARK       (1 << 1)/* Append a slash to each name.  */
@@ -57,10 +78,12 @@ extern "C" {
 # define GLOB_NOMAGIC   (1 << 11)/* If no magic chars, return the pattern.  */
 # define GLOB_TILDE     (1 << 12)/* Expand ~user and ~ to home directories. */
 # define GLOB_ONLYDIR   (1 << 13)/* Match only directories.  */
+# define GLOB_TILDE_CHECK (1 << 14)/* Like GLOB_TILDE but return an error
+                                     if the user name is not available.  */
 # define __GLOB_FLAGS  (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \
                         GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND|     \
                         GLOB_PERIOD|GLOB_ALTDIRFUNC|GLOB_BRACE|     \
-                        GLOB_NOMAGIC|GLOB_TILDE|GLOB_ONLYDIR)
+                        GLOB_NOMAGIC|GLOB_TILDE|GLOB_ONLYDIR|GLOB_TILDE_CHECK)
 #else
 # define __GLOB_FLAGS  (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \
                         GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND|     \
@@ -71,41 +94,52 @@ extern "C" {
 #define        GLOB_NOSPACE    1       /* Ran out of memory.  */
 #define        GLOB_ABORTED    2       /* Read error.  */
 #define        GLOB_NOMATCH    3       /* No matches found.  */
-
+#define GLOB_NOSYS     4       /* Not implemented.  */
 #ifdef _GNU_SOURCE
 /* Previous versions of this file defined GLOB_ABEND instead of
    GLOB_ABORTED.  Provide a compatibility definition here.  */
 # define GLOB_ABEND GLOB_ABORTED
 #endif
 
-/* This value is returned if the implementation does not support
-   `glob'.  Since this is not the case here it will never be
-   returned but the conformance test suites still require the symbol
-   to be defined.  */
-#if (_XOPEN_SOURCE - 0) == 500
-# define GLOB_NOSYS    (-1)
-#endif
-
 /* Structure describing a globbing run.  */
 #if !defined _AMIGA && !defined VMS /* Buggy compiler.   */
 struct stat;
 #endif
 typedef struct
   {
-    int gl_pathc;              /* Count of paths matched by the pattern.  */
+    __size_t gl_pathc;         /* Count of paths matched by the pattern.  */
     char **gl_pathv;           /* List of matched pathnames.  */
-    int gl_offs;               /* Slots to reserve in `gl_pathv'.  */
+    __size_t gl_offs;          /* Slots to reserve in `gl_pathv'.  */
     int gl_flags;              /* Set to FLAGS, maybe | GLOB_MAGCHAR.  */
 
     /* If the GLOB_ALTDIRFUNC flag is set, the following functions
        are used instead of the normal file access functions.  */
-    void (*gl_closedir) __P ((void *));
-    struct dirent *(*gl_readdir) __P ((void *));
-    __ptr_t (*gl_opendir) __P ((__const char *));
-    int (*gl_lstat) __P ((__const char *, struct stat *));
-    int (*gl_stat) __P ((__const char *, struct stat *));
+    void (*gl_closedir) __PMT ((void *));
+    struct dirent *(*gl_readdir) __PMT ((void *));
+    __ptr_t (*gl_opendir) __PMT ((__const char *));
+    int (*gl_lstat) __PMT ((__const char *, struct stat *));
+    int (*gl_stat) __PMT ((__const char *, struct stat *));
   } glob_t;
 
+#ifdef _LARGEFILE64_SOURCE
+struct stat64;
+typedef struct
+  {
+    __size_t gl_pathc;
+    char **gl_pathv;
+    __size_t gl_offs;
+    int gl_flags;
+
+    /* If the GLOB_ALTDIRFUNC flag is set, the following functions
+       are used instead of the normal file access functions.  */
+    void (*gl_closedir) __PMT ((void *));
+    struct dirent64 *(*gl_readdir) __PMT ((void *));
+    __ptr_t (*gl_opendir) __PMT ((__const char *));
+    int (*gl_lstat) __PMT ((__const char *, struct stat64 *));
+    int (*gl_stat) __PMT ((__const char *, struct stat64 *));
+  } glob64_t;
+#endif
+
 /* Do glob searching for PATTERN, placing results in PGLOB.
    The bits defined above may be set in FLAGS.
    If a directory cannot be opened or read and ERRFUNC is not nil,
@@ -114,12 +148,33 @@ typedef struct
    `glob' returns GLOB_ABEND; if it returns zero, the error is ignored.
    If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
    Otherwise, `glob' returns zero.  */
+#if _FILE_OFFSET_BITS != 64
 extern int glob __P ((__const char *__pattern, int __flags,
-                     int (*__errfunc) __P ((__const char *, int)),
+                     int (*__errfunc) (__const char *, int),
                      glob_t *__pglob));
 
 /* Free storage allocated in PGLOB by a previous `glob' call.  */
 extern void globfree __P ((glob_t *__pglob));
+#else
+# if __GNUC__ >= 2
+extern int glob __P ((__const char *__pattern, int __flags,
+                     int (*__errfunc) (__const char *, int),
+                     glob_t *__pglob)) __asm__ ("glob64");
+
+extern void globfree __P ((glob_t *__pglob)) __asm__ ("globfree64");
+# else
+#  define glob glob64
+#  define globfree globfree64
+# endif
+#endif
+
+#ifdef _LARGEFILE64_SOURCE
+extern int glob64 __P ((__const char *__pattern, int __flags,
+                       int (*__errfunc) (__const char *, int),
+                       glob64_t *__pglob));
+
+extern void globfree64 __P ((glob64_t *__pglob));
+#endif
 
 
 #ifdef _GNU_SOURCE
@@ -128,7 +183,6 @@ extern void globfree __P ((glob_t *__pglob));
 
    This function is not part of the interface specified by POSIX.2
    but several programs want to use it.  */
-extern int __glob_pattern_p __P ((__const char *__pattern, int __quote));
 extern int glob_pattern_p __P ((__const char *__pattern, int __quote));
 #endif
 
diff --git a/main.c b/main.c
index f9ba4f4..1950956 100644 (file)
--- a/main.c
+++ b/main.c
@@ -1465,45 +1465,51 @@ int main (int argc, char ** argv)
             struct dep *d;
 
            for (i = 0, d = read_makefiles; d != 0; ++i, d = d->next)
-              if (d->file->updated)
-                {
-                  /* This makefile was updated.  */
-                  if (d->file->update_status == 0)
-                    {
-                      /* It was successfully updated.  */
-                      any_remade |= (file_mtime_no_search (d->file)
-                                     != makefile_mtimes[i]);
-                    }
-                  else if (! (d->changed & RM_DONTCARE))
-                    {
-                      FILE_TIMESTAMP mtime;
-                      /* The update failed and this makefile was not
-                         from the MAKEFILES variable, so we care.  */
-                      error (NILF, "Failed to remake makefile `%s'.",
-                             d->file->name);
-                      mtime = file_mtime_no_search (d->file);
-                      any_remade |= (mtime != (FILE_TIMESTAMP) -1
-                                     && mtime != makefile_mtimes[i]);
-                    }
-                }
-              else
-                /* This makefile was not found at all.  */
-                if (! (d->changed & RM_DONTCARE))
+              {
+                /* Reset the considered flag; we may need to look at the file
+                   again to print an error.  */
+                d->file->considered = 0;
+
+                if (d->file->updated)
                   {
-                    /* This is a makefile we care about.  See how much.  */
-                    if (d->changed & RM_INCLUDED)
-                      /* An included makefile.  We don't need
-                         to die, but we do want to complain.  */
-                      error (NILF, "Included makefile `%s' was not found.",
-                             dep_name (d));
-                    else
+                    /* This makefile was updated.  */
+                    if (d->file->update_status == 0)
                       {
-                        /* A normal makefile.  We must die later.  */
-                        error (NILF, "Makefile `%s' was not found",
-                               dep_name (d));
-                        any_failed = 1;
+                        /* It was successfully updated.  */
+                        any_remade |= (file_mtime_no_search (d->file)
+                                       != makefile_mtimes[i]);
+                      }
+                    else if (! (d->changed & RM_DONTCARE))
+                      {
+                        FILE_TIMESTAMP mtime;
+                        /* The update failed and this makefile was not
+                           from the MAKEFILES variable, so we care.  */
+                        error (NILF, "Failed to remake makefile `%s'.",
+                               d->file->name);
+                        mtime = file_mtime_no_search (d->file);
+                        any_remade |= (mtime != (FILE_TIMESTAMP) -1
+                                       && mtime != makefile_mtimes[i]);
                       }
                   }
+                else
+                  /* This makefile was not found at all.  */
+                  if (! (d->changed & RM_DONTCARE))
+                    {
+                      /* This is a makefile we care about.  See how much.  */
+                      if (d->changed & RM_INCLUDED)
+                        /* An included makefile.  We don't need
+                           to die, but we do want to complain.  */
+                        error (NILF, "Included makefile `%s' was not found.",
+                               dep_name (d));
+                      else
+                        {
+                          /* A normal makefile.  We must die later.  */
+                          error (NILF, "Makefile `%s' was not found",
+                                 dep_name (d));
+                          any_failed = 1;
+                        }
+                    }
+              }
             /* Reset this to empty so we get the right error message below.  */
             read_makefiles = 0;
 
index 75af658..90de313 100644 (file)
--- a/remake.c
+++ b/remake.c
@@ -106,6 +106,9 @@ update_goal_chain (goals, makefiles)
     job_slots = 1;
 #endif
 
+  /* All files start with the considered bit 0, so the global value is 1.  */
+  considered = 1;
+
   /* Update all the goals until they are all finished.  */
 
   while (goals != 0)
@@ -247,6 +250,11 @@ update_goal_chain (goals, makefiles)
              g = g->next;
            }
        }
+
+      /* If we reached the end of the dependency graph toggle the considered
+         flag for the next pass.  */
+      if (g == 0)
+        considered = !considered;
     }
 
   if (makefiles)
@@ -312,6 +320,17 @@ update_file (file, depth)
   register int status = 0;
   register struct file *f;
 
+  /* Prune the dependency graph: if we've already been here on _this_ pass
+     through the dependency graph, we don't have to go any further.  We won't
+     reap_children until we start the next pass, so no state change is
+     possible below here until then.  */
+  if (file->considered == considered)
+    {
+      DEBUGPR ("Pruning file `%s'.\n");
+      return 0;
+    }
+  file->considered = considered;
+
   for (f = file->double_colon ? file->double_colon : file; f != 0; f = f->prev)
     {
       status |= update_file_1 (f, depth);