home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 5 / FreshFish_July-August1994.bin / bbs / gnu / make-3.71-src.lha / src / amiga / make-3.71 / glob / glob.c < prev    next >
C/C++ Source or Header  |  1993-08-12  |  16KB  |  671 lines

  1. /* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
  2.  
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Library General Public License as
  5. published by the Free Software Foundation; either version 2 of the
  6. License, or (at your option) any later version.
  7.  
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11. Library General Public License for more details.
  12.  
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; see the file COPYING.LIB.  If
  15. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  16. Cambridge, MA 02139, USA.  */
  17.  
  18. /* AIX requires this to be the first thing in the file.  */
  19. #if defined (_AIX) && !defined (__GNUC__)
  20.  #pragma alloca
  21. #endif
  22.  
  23. #ifdef    HAVE_CONFIG_H
  24. #include <config.h>
  25. #endif
  26.  
  27. #include <errno.h>
  28. #include <sys/types.h>
  29.  
  30.  
  31. /* Comment out all this code if we are using the GNU C Library, and are not
  32.    actually compiling the library itself.  This code is part of the GNU C
  33.    Library, but also included in many other GNU distributions.  Compiling
  34.    and linking in this code is a waste when using the GNU C library
  35.    (especially if it is a shared library).  Rather than having every GNU
  36.    program understand `configure --with-gnu-libc' and omit the object files,
  37.    it is simpler to just do this in the source for each such file.  */
  38.  
  39. #if defined (_LIBC) || !defined (__GNU_LIBRARY__)
  40.  
  41.  
  42. #ifdef    STDC_HEADERS
  43. #include <stddef.h>
  44. #endif
  45.  
  46. #ifdef    HAVE_UNISTD_H
  47. #include <unistd.h>
  48. #ifndef POSIX
  49. #ifdef    _POSIX_VERSION
  50. #define    POSIX
  51. #endif
  52. #endif
  53. #endif
  54.  
  55. #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS)
  56. extern int errno;
  57. #endif
  58.  
  59. #ifndef    NULL
  60. #define    NULL    0
  61. #endif
  62.  
  63. #if    defined (POSIX) || defined (DIRENT) || defined (__GNU_LIBRARY__)
  64. #include <dirent.h>
  65. #ifndef    __GNU_LIBRARY__
  66. #define D_NAMLEN(d) strlen((d)->d_name)
  67. #else    /* GNU C library.  */
  68. #define D_NAMLEN(d) ((d)->d_namlen)
  69. #endif    /* Not GNU C library.  */
  70. #else    /* Not POSIX or DIRENT.  */
  71. #define direct dirent
  72. #define D_NAMLEN(d) ((d)->d_namlen)
  73. #ifdef    SYSNDIR
  74. #include <sys/ndir.h>
  75. #endif    /* SYSNDIR */
  76. #ifdef    SYSDIR
  77. #include <sys/dir.h>
  78. #endif    /* SYSDIR */
  79. #ifdef NDIR
  80. #include <ndir.h>
  81. #endif    /* NDIR */
  82. #endif    /* POSIX or DIRENT or __GNU_LIBRARY__.  */
  83.  
  84. #if defined (POSIX) && !defined (__GNU_LIBRARY__)
  85. /* Posix does not require that the d_ino field be present, and some
  86.    systems do not provide it. */
  87. #define REAL_DIR_ENTRY(dp) 1
  88. #else
  89. #define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
  90. #endif /* POSIX */
  91.  
  92. #if    (defined (STDC_HEADERS) || defined (__GNU_LIBRARY__))
  93. #include <stdlib.h>
  94. #include <string.h>
  95. #define    ANSI_STRING
  96. #else    /* No standard headers.  */
  97.  
  98. #ifdef HAVE_STRING_H
  99. #include <string.h>
  100. #define    ANSI_STRING
  101. #else
  102. #include <strings.h>
  103. #endif
  104. #ifdef    HAVE_MEMORY_H
  105. #include <memory.h>
  106. #endif
  107.  
  108. extern char *malloc (), *realloc ();
  109. extern void free ();
  110.  
  111. extern void qsort ();
  112. extern void abort (), exit ();
  113.  
  114. #endif    /* Standard headers.  */
  115.  
  116. #ifndef    ANSI_STRING
  117.  
  118. #ifndef    bzero
  119. extern void bzero ();
  120. #endif
  121. #ifndef    bcopy
  122. extern void bcopy ();
  123. #endif
  124.  
  125. #define    memcpy(d, s, n)    bcopy ((s), (d), (n))
  126. #define    strrchr    rindex
  127. /* memset is only used for zero here, but let's be paranoid.  */
  128. #define    memset(s, better_be_zero, n) \
  129.   ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0)))
  130. #endif    /* Not ANSI_STRING.  */
  131.  
  132. #ifndef    HAVE_STRCOLL
  133. #define    strcoll    strcmp
  134. #endif
  135.  
  136.  
  137. #ifndef    __GNU_LIBRARY__
  138. #ifdef    __GNUC__
  139. __inline
  140. #endif
  141. static char *
  142. my_realloc (p, n)
  143.      char *p;
  144.      unsigned int n;
  145. {
  146.   /* These casts are the for sake of the broken Ultrix compiler,
  147.      which warns of illegal pointer combinations otherwise.  */
  148.   if (p == NULL)
  149.     return (char *) malloc (n);
  150.   return (char *) realloc (p, n);
  151. }
  152. #define    realloc    my_realloc
  153. #endif
  154.  
  155.  
  156. #if    !defined(__alloca) && !defined(__GNU_LIBRARY__)
  157.  
  158. #ifdef    __GNUC__
  159. #undef    alloca
  160. #define    alloca(n)    __builtin_alloca (n)
  161. #else    /* Not GCC.  */
  162. #if    defined (sparc) || defined (HAVE_ALLOCA_H)
  163. #include <alloca.h>
  164. #else    /* Not sparc or HAVE_ALLOCA_H.  */
  165. #ifndef    _AIX
  166. extern char *alloca ();
  167. #endif    /* Not _AIX.  */
  168. #endif    /* sparc or HAVE_ALLOCA_H.  */
  169. #endif    /* GCC.  */
  170.  
  171. #define    __alloca    alloca
  172.  
  173. #endif
  174.  
  175. #ifndef    STDC_HEADERS
  176. #undef    size_t
  177. #define    size_t    unsigned int
  178. #endif
  179.  
  180. /* Some system header files erroneously define these.
  181.    We want our own definitions from <fnmatch.h> to take precedence.  */
  182. #undef    FNM_PATHNAME
  183. #undef    FNM_NOESCAPE
  184. #undef    FNM_PERIOD
  185. #include <fnmatch.h>
  186.  
  187. /* Some system header files erroneously define these.
  188.    We want our own definitions from <glob.h> to take precedence.  */
  189. #undef    GLOB_ERR
  190. #undef    GLOB_MARK
  191. #undef    GLOB_NOSORT
  192. #undef    GLOB_DOOFFS
  193. #undef    GLOB_NOCHECK
  194. #undef    GLOB_APPEND
  195. #undef    GLOB_NOESCAPE
  196. #undef    GLOB_PERIOD
  197. #include <glob.h>
  198.  
  199. __ptr_t (*__glob_opendir_hook) __P ((const char *directory));
  200. const char *(*__glob_readdir_hook) __P ((__ptr_t stream));
  201. void (*__glob_closedir_hook) __P ((__ptr_t stream));
  202.  
  203. static int glob_pattern_p __P ((const char *pattern, int quote));
  204. static int glob_in_dir __P ((const char *pattern, const char *directory,
  205.                  int flags,
  206.                  int (*errfunc) __P ((const char *, int)),
  207.                  glob_t *pglob));
  208. static int prefix_array __P ((const char *prefix, char **array, size_t n));
  209. static int collated_compare __P ((const __ptr_t, const __ptr_t));
  210.  
  211. /* Do glob searching for PATTERN, placing results in PGLOB.
  212.    The bits defined above may be set in FLAGS.
  213.    If a directory cannot be opened or read and ERRFUNC is not nil,
  214.    it is called with the pathname that caused the error, and the
  215.    `errno' value from the failing call; if it returns non-zero
  216.    `glob' returns GLOB_ABEND; if it returns zero, the error is ignored.
  217.    If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
  218.    Otherwise, `glob' returns zero.  */
  219. int
  220. glob (pattern, flags, errfunc, pglob)
  221.      const char *pattern;
  222.      int flags;
  223.      int (*errfunc) __P ((const char *, int));
  224.      glob_t *pglob;
  225. {
  226.   const char *filename;
  227.   char *dirname;
  228.   size_t dirlen;
  229.   int status;
  230.   int oldcount;
  231.  
  232.   if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
  233.     {
  234.       errno = EINVAL;
  235.       return -1;
  236.     }
  237.  
  238.   /* Find the filename.  */
  239.   filename = strrchr (pattern, '/');
  240.   if (filename == NULL)
  241.     {
  242.       filename = pattern;
  243.       dirname = (char *) ".";
  244.       dirlen = 0;
  245.     }
  246.   else if (filename == pattern)
  247.     {
  248.       /* "/pattern".  */
  249.       dirname = (char *) "/";
  250.       dirlen = 1;
  251.       ++filename;
  252.     }
  253.   else
  254.     {
  255.       dirlen = filename - pattern;
  256.       dirname = (char *) __alloca (dirlen + 1);
  257.       memcpy (dirname, pattern, dirlen);
  258.       dirname[dirlen] = '\0';
  259.       ++filename;
  260.     }
  261.  
  262.   if (filename[0] == '\0' && dirlen > 1)
  263.     /* "pattern/".  Expand "pattern", appending slashes.  */
  264.     {
  265.       int ret = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
  266.       if (ret == 0)
  267.     pglob->gl_flags = (pglob->gl_flags & ~GLOB_MARK) | (flags & GLOB_MARK);
  268.       return ret;
  269.     }
  270.  
  271.   if (!(flags & GLOB_APPEND))
  272.     {
  273.       pglob->gl_pathc = 0;
  274.       pglob->gl_pathv = NULL;
  275.     }
  276.  
  277.   oldcount = pglob->gl_pathc;
  278.  
  279.   if (glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
  280.     {
  281.       /* The directory name contains metacharacters, so we
  282.      have to glob for the directory, and then glob for
  283.      the pattern in each directory found.  */
  284.       glob_t dirs;
  285.       register int i;
  286.  
  287.       status = glob (dirname,
  288.              ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) |
  289.               GLOB_NOSORT),
  290.              errfunc, &dirs);
  291.       if (status != 0)
  292.     return status;
  293.  
  294.       /* We have successfully globbed the preceding directory name.
  295.      For each name we found, call glob_in_dir on it and FILENAME,
  296.      appending the results to PGLOB.  */
  297.       for (i = 0; i < dirs.gl_pathc; ++i)
  298.     {
  299.       int oldcount;
  300.  
  301. #ifdef    SHELL
  302.       {
  303.         /* Make globbing interruptible in the bash shell. */
  304.         extern int interrupt_state;
  305.  
  306.         if (interrupt_state)
  307.           {
  308.         globfree (&dirs);
  309.         globfree (&files);
  310.         return GLOB_ABEND;
  311.           }
  312.       }
  313. #endif /* SHELL.  */
  314.  
  315.       oldcount = pglob->gl_pathc;
  316.       status = glob_in_dir (filename, dirs.g