kbuild.c: added todo for #80.
[kbuild-mirror.git] / src / kmk / glob / glob.c
blobee282c077e61deea0a773ff0e3bd479764735118
1 /* Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 Free
2 Software Foundation, Inc.
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to the Free
16 Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
17 USA. */
19 /* AIX requires this to be the first thing in the file. */
20 #if defined _AIX && !defined __GNUC__
21 #pragma alloca
22 #endif
24 #ifdef HAVE_CONFIG_H
25 # include <config.h>
26 #endif
28 /* Enable GNU extensions in glob.h. */
29 #ifndef _GNU_SOURCE
30 # define _GNU_SOURCE 1
31 #endif
33 #include <errno.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
37 /* Outcomment the following line for production quality code. */
38 /* #define NDEBUG 1 */
39 #include <assert.h>
41 #include <stdio.h> /* Needed on stupid SunOS for assert. */
44 /* Comment out all this code if we are using the GNU C Library, and are not
45 actually compiling the library itself. This code is part of the GNU C
46 Library, but also included in many other GNU distributions. Compiling
47 and linking in this code is a waste when using the GNU C library
48 (especially if it is a shared library). Rather than having every GNU
49 program understand `configure --with-gnu-libc' and omit the object files,
50 it is simpler to just do this in the source for each such file. */
52 #define GLOB_INTERFACE_VERSION 1
53 #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
54 # include <gnu-versions.h>
55 # if _GNU_GLOB_INTERFACE_VERSION == GLOB_INTERFACE_VERSION
56 # define ELIDE_CODE
57 # endif
58 #endif
60 #ifndef ELIDE_CODE
62 #if defined STDC_HEADERS || defined __GNU_LIBRARY__
63 # include <stddef.h>
64 #endif
66 #if defined HAVE_UNISTD_H || defined _LIBC
67 # include <unistd.h>
68 # ifndef POSIX
69 # ifdef _POSIX_VERSION
70 # define POSIX
71 # endif
72 # endif
73 #endif
75 #if !defined _AMIGA && !defined VMS && !defined WINDOWS32
76 # include <pwd.h>
77 #endif
79 #if !defined __GNU_LIBRARY__ && !defined STDC_HEADERS
80 extern int errno;
81 #endif
82 #ifndef __set_errno
83 # define __set_errno(val) errno = (val)
84 #endif
86 #ifndef NULL
87 # define NULL 0
88 #endif
91 #if defined HAVE_DIRENT_H || defined __GNU_LIBRARY__
92 # include <dirent.h>
93 # define NAMLEN(dirent) strlen((dirent)->d_name)
94 #else
95 # define dirent direct
96 # define NAMLEN(dirent) (dirent)->d_namlen
97 # ifdef HAVE_SYS_NDIR_H
98 # include <sys/ndir.h>
99 # endif
100 # ifdef HAVE_SYS_DIR_H
101 # include <sys/dir.h>
102 # endif
103 # ifdef HAVE_NDIR_H
104 # include <ndir.h>
105 # endif
106 # ifdef HAVE_VMSDIR_H
107 # include "vmsdir.h"
108 # endif /* HAVE_VMSDIR_H */
109 #endif
112 /* In GNU systems, <dirent.h> defines this macro for us. */
113 #ifdef _D_NAMLEN
114 # undef NAMLEN
115 # define NAMLEN(d) _D_NAMLEN(d)
116 #endif
118 /* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available
119 if the `d_type' member for `struct dirent' is available. */
120 #ifdef _DIRENT_HAVE_D_TYPE
121 # define HAVE_D_TYPE 1
122 #endif
125 #if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__
126 /* Posix does not require that the d_ino field be present, and some
127 systems do not provide it. */
128 # define REAL_DIR_ENTRY(dp) 1
129 #else
130 # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
131 #endif /* POSIX */
133 #if defined STDC_HEADERS || defined __GNU_LIBRARY__
134 # include <stdlib.h>
135 # include <string.h>
136 # define ANSI_STRING
137 #else /* No standard headers. */
139 extern char *getenv ();
141 # ifdef HAVE_STRING_H
142 # include <string.h>
143 # define ANSI_STRING
144 # else
145 # include <strings.h>
146 # endif
147 # ifdef HAVE_MEMORY_H
148 # include <memory.h>
149 # endif
151 extern char *malloc (), *realloc ();
152 extern void free ();
154 extern void qsort ();
155 extern void abort (), exit ();
157 #endif /* Standard headers. */
159 #ifndef ANSI_STRING
161 # ifndef bzero
162 extern void bzero ();
163 # endif
164 # ifndef bcopy
165 extern void bcopy ();
166 # endif
168 # define memcpy(d, s, n) bcopy ((s), (d), (n))
169 # define strrchr rindex
170 /* memset is only used for zero here, but let's be paranoid. */
171 # define memset(s, better_be_zero, n) \
172 ((void) ((better_be_zero) == 0 ? (bzero((s), (n)), 0) : (abort(), 0)))
173 #endif /* Not ANSI_STRING. */
175 #if !defined HAVE_STRCOLL && !defined _LIBC
176 # define strcoll strcmp
177 #endif
179 #if !defined HAVE_MEMPCPY && __GLIBC__ - 0 == 2 && __GLIBC_MINOR__ >= 1
180 # define HAVE_MEMPCPY 1
181 # undef mempcpy
182 # define mempcpy(Dest, Src, Len) __mempcpy (Dest, Src, Len)
183 #endif
185 #if !defined(__GNU_LIBRARY__) && !defined(ELECTRIC_HEAP) && !defined(__APPLE__) /* bird (last two) */
186 # ifdef __GNUC__
187 __inline
188 # endif
189 # ifndef __SASC
190 # ifdef WINDOWS32
191 # include <malloc.h>
192 static void *
193 my_realloc (void *p, unsigned int n)
194 # elif defined(__DJGPP__)
195 static void *
196 my_realloc (void *p, size_t n)
197 # else
198 static char *
199 my_realloc (p, n)
200 char *p;
201 unsigned int n;
202 # endif
204 /* These casts are the for sake of the broken Ultrix compiler,
205 which warns of illegal pointer combinations otherwise. */
206 if (p == NULL)
207 return (char *) malloc (n);
208 return (char *) realloc (p, n);
210 # define realloc my_realloc
211 # endif /* __SASC */
212 #endif /* __GNU_LIBRARY__ */
215 #if !defined __alloca && !defined __GNU_LIBRARY__
217 # ifdef __GNUC__
218 # undef alloca
219 # define alloca(n) __builtin_alloca (n)
220 # else /* Not GCC. */
221 # ifdef HAVE_ALLOCA_H
222 # include <alloca.h>
223 # else /* Not HAVE_ALLOCA_H. */
224 # ifndef _AIX
225 # ifdef WINDOWS32
226 # include <malloc.h>
227 # else
228 extern char *alloca ();
229 # endif /* WINDOWS32 */
230 # endif /* Not _AIX. */
231 # endif /* sparc or HAVE_ALLOCA_H. */
232 # endif /* GCC. */
234 # define __alloca alloca
236 #endif
238 #ifndef __GNU_LIBRARY__
239 # define __stat stat
240 # ifdef STAT_MACROS_BROKEN
241 # undef S_ISDIR
242 # endif
243 # ifndef S_ISDIR
244 # define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
245 # endif
246 #endif
248 #ifdef _LIBC
249 # undef strdup
250 # define strdup(str) __strdup (str)
251 # define sysconf(id) __sysconf (id)
252 # define closedir(dir) __closedir (dir)
253 # define opendir(name) __opendir (name)
254 # define readdir(str) __readdir (str)
255 # define getpwnam_r(name, bufp, buf, len, res) \
256 __getpwnam_r (name, bufp, buf, len, res)
257 # ifndef __stat
258 # define __stat(fname, buf) __xstat (_STAT_VER, fname, buf)
259 # endif
260 #endif
262 #if !(defined STDC_HEADERS || defined __GNU_LIBRARY__)
263 # undef size_t
264 # define size_t unsigned int
265 #endif
267 /* Some system header files erroneously define these.
268 We want our own definitions from <fnmatch.h> to take precedence. */
269 #ifndef __GNU_LIBRARY__
270 # undef FNM_PATHNAME
271 # undef FNM_NOESCAPE
272 # undef FNM_PERIOD
273 #endif
274 #include <fnmatch.h>
276 /* Some system header files erroneously define these.
277 We want our own definitions from <glob.h> to take precedence. */
278 #ifndef __GNU_LIBRARY__
279 # undef GLOB_ERR
280 # undef GLOB_MARK
281 # undef GLOB_NOSORT
282 # undef GLOB_DOOFFS
283 # undef GLOB_NOCHECK
284 # undef GLOB_APPEND
285 # undef GLOB_NOESCAPE
286 # undef GLOB_PERIOD
287 #endif
288 #include <glob.h>
290 #ifdef HAVE_GETLOGIN_R
291 extern int getlogin_r __P ((char *, size_t));
292 #else
293 extern char *getlogin __P ((void));
294 #endif
296 static
297 #if __GNUC__ - 0 >= 2
298 inline
299 #endif
300 const char *next_brace_sub __P ((const char *begin));
301 static int glob_in_dir __P ((const char *pattern, const char *directory,
302 int flags,
303 int (*errfunc) (const char *, int),
304 glob_t *pglob));
305 static int prefix_array __P ((const char *prefix, char **array, size_t n));
306 static int collated_compare __P ((const __ptr_t, const __ptr_t));
308 #if !defined _LIBC || !defined NO_GLOB_PATTERN_P
309 int __glob_pattern_p __P ((const char *pattern, int quote));
310 #endif
312 /* Find the end of the sub-pattern in a brace expression. We define
313 this as an inline function if the compiler permits. */
314 static
315 #if __GNUC__ - 0 >= 2
316 inline
317 #endif
318 const char *
319 next_brace_sub (begin)
320 const char *begin;
322 unsigned int depth = 0;
323 const char *cp = begin;
325 while (1)
327 if (depth == 0)
329 if (*cp != ',' && *cp != '}' && *cp != '\0')
331 if (*cp == '{')
332 ++depth;
333 ++cp;
334 continue;
337 else
339 while (*cp != '\0' && (*cp != '}' || depth > 0))
341 if (*cp == '}')
342 --depth;
343 ++cp;
345 if (*cp == '\0')
346 /* An incorrectly terminated brace expression. */
347 return NULL;
349 continue;
351 break;
354 return cp;
357 /* Do glob searching for PATTERN, placing results in PGLOB.
358 The bits defined above may be set in FLAGS.
359 If a directory cannot be opened or read and ERRFUNC is not nil,
360 it is called with the pathname that caused the error, and the
361 `errno' value from the failing call; if it returns non-zero
362 `glob' returns GLOB_ABORTED; if it returns zero, the error is ignored.
363 If memory cannot be allocated for PGLOB, GLOB_NOSPACE is returned.
364 Otherwise, `glob' returns zero. */
366 glob (pattern, flags, errfunc, pglob)
367 const char *pattern;
368 int flags;
369 int (*errfunc) __P ((const char *, int));
370 glob_t *pglob;
372 const char *filename;
373 const char *dirname;
374 size_t dirlen;
375 int status;
376 __size_t oldcount; /* bird: correct type. */
378 if (pattern == NULL || pglob == NULL || (flags & ~__GLOB_FLAGS) != 0)
380 __set_errno (EINVAL);
381 return -1;
384 if (flags & GLOB_BRACE)
386 const char *begin = strchr (pattern, '{');
387 if (begin != NULL)
389 /* Allocate working buffer large enough for our work. Note that
390 we have at least an opening and closing brace. */
391 size_t firstc;
392 char *alt_start;
393 const char *p;
394 const char *next;
395 const char *rest;
396 size_t rest_len;
397 #ifdef __GNUC__
398 char onealt[strlen (pattern) - 1];
399 #else
400 char *onealt = (char *) malloc (strlen (pattern) - 1);
401 if (onealt == NULL)
403 if (!(flags & GLOB_APPEND))
404 globfree (pglob);
405 return GLOB_NOSPACE;
407 #endif
409 /* We know the prefix for all sub-patterns. */
410 #ifdef HAVE_MEMPCPY
411 alt_start = mempcpy (onealt, pattern, begin - pattern);
412 #else
413 memcpy (onealt, pattern, begin - pattern);
414 alt_start = &onealt[begin - pattern];
415 #endif
417 /* Find the first sub-pattern and at the same time find the
418 rest after the closing brace. */
419 next = next_brace_sub (begin + 1);
420 if (next == NULL)
422 /* It is an illegal expression. */
423 #ifndef __GNUC__
424 free (onealt);
425 #endif
426 return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
429 /* Now find the end of the whole brace expression. */
430 rest = next;
431 while (*rest != '}')
433 rest = next_brace_sub (rest + 1);
434 if (rest == NULL)
436 /* It is an illegal expression. */
437 #ifndef __GNUC__
438 free (onealt);
439 #endif
440 return glob (pattern, flags & ~GLOB_BRACE, errfunc, pglob);
443 /* Please note that we now can be sure the brace expression
444 is well-formed. */
445 rest_len = strlen (++rest) + 1;
447 /* We have a brace expression. BEGIN points to the opening {,
448 NEXT points past the terminator of the first element, and END
449 points past the final }. We will accumulate result names from
450 recursive runs for each brace alternative in the buffer using
451 GLOB_APPEND. */
453 if (!(flags & GLOB_APPEND))
455 /* This call is to set a new vector, so clear out the
456 vector so we can append to it. */
457 pglob->gl_pathc = 0;
458 pglob->gl_pathv = NULL;
460 firstc = pglob->gl_pathc;
462 p = begin + 1;
463 while (1)
465 int result;
467 /* Construct the new glob expression. */
468 #ifdef HAVE_MEMPCPY
469 mempcpy (mempcpy (alt_start, p, next - p), rest, rest_len);
470 #else
471 memcpy (alt_start, p, next - p);
472 memcpy (&alt_start[next - p], rest, rest_len);
473 #endif
475 result = glob (onealt,
476 ((flags & ~(GLOB_NOCHECK|GLOB_NOMAGIC))
477 | GLOB_APPEND), errfunc, pglob);
479 /* If we got an error, return it. */
480 if (result && result != GLOB_NOMATCH)
482 #ifndef __GNUC__
483 free (onealt);
484 #endif
485 if (!(flags & GLOB_APPEND))
486 globfree (pglob);
487 return result;
490 if (*next == '}')
491 /* We saw the last entry. */
492 break;
494 p = next + 1;
495 next = next_brace_sub (p);
496 assert (next != NULL);
499 #ifndef __GNUC__
500 free (onealt);
501 #endif
503 if (pglob->gl_pathc != firstc)
504 /* We found some entries. */
505 return 0;
506 else if (!(flags & (GLOB_NOCHECK|GLOB_NOMAGIC)))
507 return GLOB_NOMATCH;
511 /* Find the filename. */
512 filename = strrchr (pattern, '/');
513 #if defined __MSDOS__ || defined WINDOWS32
514 /* The case of "d:pattern". Since `:' is not allowed in
515 file names, we can safely assume that wherever it
516 happens in pattern, it signals the filename part. This
517 is so we could some day support patterns like "[a-z]:foo". */
518 if (filename == NULL)
519 filename = strchr (pattern, ':');
520 #endif /* __MSDOS__ || WINDOWS32 */
521 if (filename == NULL)
523 /* This can mean two things: a simple name or "~name". The later
524 case is nothing but a notation for a directory. */
525 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && pattern[0] == '~')
527 dirname = pattern;
528 dirlen = strlen (pattern);
530 /* Set FILENAME to NULL as a special flag. This is ugly but
531 other solutions would require much more code. We test for
532 this special case below. */
533 filename = NULL;
535 else
537 filename = pattern;
538 #ifdef _AMIGA
539 dirname = "";
540 #else
541 dirname = ".";
542 #endif
543 dirlen = 0;
546 else if (filename == pattern)
548 /* "/pattern". */
549 dirname = "/";
550 dirlen = 1;
551 ++filename;
553 else
555 char *newp;
556 dirlen = filename - pattern;
557 #if defined __MSDOS__ || defined WINDOWS32
558 if (*filename == ':'
559 || (filename > pattern + 1 && filename[-1] == ':'))
561 char *drive_spec;
563 ++dirlen;
564 drive_spec = (char *) __alloca (dirlen + 1);
565 #ifdef HAVE_MEMPCPY
566 *((char *) mempcpy (drive_spec, pattern, dirlen)) = '\0';
567 #else
568 memcpy (drive_spec, pattern, dirlen);
569 drive_spec[dirlen] = '\0';
570 #endif
571 /* For now, disallow wildcards in the drive spec, to
572 prevent infinite recursion in glob. */
573 if (__glob_pattern_p (drive_spec, !(flags & GLOB_NOESCAPE)))
574 return GLOB_NOMATCH;
575 /* If this is "d:pattern", we need to copy `:' to DIRNAME
576 as well. If it's "d:/pattern", don't remove the slash
577 from "d:/", since "d:" and "d:/" are not the same.*/
579 #endif
580 newp = (char *) __alloca (dirlen + 1);
581 #ifdef HAVE_MEMPCPY
582 *((char *) mempcpy (newp, pattern, dirlen)) = '\0';
583 #else
584 memcpy (newp, pattern, dirlen);
585 newp[dirlen] = '\0';
586 #endif
587 dirname = newp;
588 ++filename;
590 if (filename[0] == '\0'
591 #if defined __MSDOS__ || defined WINDOWS32
592 && dirname[dirlen - 1] != ':'
593 && (dirlen < 3 || dirname[dirlen - 2] != ':'
594 || dirname[dirlen - 1] != '/')
595 #endif
596 && dirlen > 1)
597 /* "pattern/". Expand "pattern", appending slashes. */
599 int val = glob (dirname, flags | GLOB_MARK, errfunc, pglob);
600 if (val == 0)
601 pglob->gl_flags = ((pglob->gl_flags & ~GLOB_MARK)
602 | (flags & GLOB_MARK));
603 return val;
607 if (!(flags & GLOB_APPEND))
609 pglob->gl_pathc = 0;
610 pglob->gl_pathv = NULL;
613 oldcount = pglob->gl_pathc;
615 #ifndef VMS
616 if ((flags & (GLOB_TILDE|GLOB_TILDE_CHECK)) && dirname[0] == '~')
618 if (dirname[1] == '\0' || dirname[1] == '/')
620 /* Look up home directory. */
621 #ifdef VMS
622 /* This isn't obvious, RTLs of DECC and VAXC know about "HOME" */
623 const char *home_dir = getenv ("SYS$LOGIN");
624 #else
625 const char *home_dir = getenv ("HOME");
626 #endif
627 # ifdef _AMIGA
628 if (home_dir == NULL || home_dir[0] == '\0')
629 home_dir = "SYS:";
630 # else
631 # ifdef WINDOWS32
632 if (home_dir == NULL || home_dir[0] == '\0')
633 home_dir = "c:/users/default"; /* poor default */
634 # else
635 # ifdef VMS
636 /* Again, this isn't obvious, if "HOME" isn't known "SYS$LOGIN" should be set */
637 if (home_dir == NULL || home_dir[0] == '\0')
638 home_dir = "SYS$DISK:[]";
639 # else
640 if (home_dir == NULL || home_dir[0] == '\0')
642 int success;
643 char *name;
644 # if defined HAVE_GETLOGIN_R || defined _LIBC
645 size_t buflen = sysconf (_SC_LOGIN_NAME_MAX) + 1;
647 if (buflen == 0)
648 /* `sysconf' does not support _SC_LOGIN_NAME_MAX. Try
649 a moderate value. */
650 buflen = 20;
651 name = (char *) __alloca (buflen);
653 success = getlogin_r (name, buflen) >= 0;
654 # else
655 success = (name = getlogin ()) != NULL;
656 # endif
657 if (success)
659 struct passwd *p;
660 # if defined HAVE_GETPWNAM_R || defined _LIBC
661 size_t pwbuflen = sysconf (_SC_GETPW_R_SIZE_MAX);
662 char *pwtmpbuf;
663 struct passwd pwbuf;
664 int save = errno;
666 if (pwbuflen == -1)
667 /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX.
668 Try a moderate value. */
669 pwbuflen = 1024;
670 pwtmpbuf = (char *) __alloca (pwbuflen);
672 while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
673 != 0)
675 if (errno != ERANGE)
677 p = NULL;
678 break;
680 pwbuflen *= 2;
681 pwtmpbuf = (char *) __alloca (pwbuflen);
682 __set_errno (save);
684 # else
685 p = getpwnam (name);
686 # endif
687 if (p != NULL)
688 home_dir = p->pw_dir;
691 if (home_dir == NULL || home_dir[0] == '\0')
693 if (flags & GLOB_TILDE_CHECK)
694 return GLOB_NOMATCH;
695 else
696 home_dir = "~"; /* No luck. */
698 # endif /* VMS */
699 # endif /* WINDOWS32 */
700 # endif
701 /* Now construct the full directory. */
702 if (dirname[1] == '\0')
703 dirname = home_dir;
704 else
706 char *newp;
707 size_t home_len = strlen (home_dir);
708 newp = (char *) __alloca (home_len + dirlen);
709 # ifdef HAVE_MEMPCPY
710 mempcpy (mempcpy (newp, home_dir, home_len),
711 &dirname[1], dirlen);
712 # else
713 memcpy (newp, home_dir, home_len);
714 memcpy (&newp[home_len], &dirname[1], dirlen);
715 # endif
716 dirname = newp;
719 # if !defined _AMIGA && !defined WINDOWS32 && !defined VMS
720 else
722 char *end_name = strchr (dirname, '/');
723 const char *user_name;
724 const char *home_dir;
726 if (end_name == NULL)
727 user_name = dirname + 1;
728 else
730 char *newp;
731 newp = (char *) __alloca (end_name - dirname);
732 # ifdef HAVE_MEMPCPY
733 *((char *) mempcpy (newp, dirname + 1, end_name - dirname))
734 = '\0';
735 # else
736 memcpy (newp, dirname + 1, end_name - dirname);
737 newp[end_name - dirname - 1] = '\0';
738 # endif
739 user_name = newp;
742 /* Look up specific user's home directory. */
744 struct passwd *p;
745 # if defined HAVE_GETPWNAM_R || defined _LIBC
746 size_t buflen = sysconf (_SC_GETPW_R_SIZE_MAX);
747 char *pwtmpbuf;
748 struct passwd pwbuf;
749 int save = errno;
751 if (buflen == -1)
752 /* `sysconf' does not support _SC_GETPW_R_SIZE_MAX. Try a
753 moderate value. */
754 buflen = 1024;
755 pwtmpbuf = (char *) __alloca (buflen);
757 while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
759 if (errno != ERANGE)
761 p = NULL;
762 break;
764 buflen *= 2;
765 pwtmpbuf = __alloca (buflen);
766 __set_errno (save);
768 # else
769 p = getpwnam (user_name);
770 # endif
771 if (p != NULL)
772 home_dir = p->pw_dir;
773 else
774 home_dir = NULL;
776 /* If we found a home directory use this. */
777 if (home_dir != NULL)
779 char *newp;
780 size_t home_len = strlen (home_dir);
781 size_t rest_len = end_name == NULL ? 0 : strlen (end_name);
782 newp = (char *) __alloca (home_len + rest_len + 1);
783 # ifdef HAVE_MEMPCPY
784 *((char *) mempcpy (mempcpy (newp, home_dir, home_len),
785 end_name, rest_len)) = '\0';
786 # else
787 memcpy (newp, home_dir, home_len);
788 memcpy (&newp[home_len], end_name, rest_len);
789 newp[home_len + rest_len] = '\0';
790 # endif
791 dirname = newp;
793 else
794 if (flags & GLOB_TILDE_CHECK)
795 /* We have to regard it as an error if we cannot find the
796 home directory. */
797 return GLOB_NOMATCH;
799 # endif /* Not Amiga && not WINDOWS32 && not VMS. */
801 #endif /* Not VMS. */
803 /* Now test whether we looked for "~" or "~NAME". In this case we
804 can give the answer now. */
805 if (filename == NULL)
807 struct stat st;
809 /* Return the directory if we don't check for error or if it exists. */
810 if ((flags & GLOB_NOCHECK)
811 || (((flags & GLOB_ALTDIRFUNC)
812 ? (*pglob->gl_stat) (dirname, &st)
813 : __stat (dirname, &st)) == 0
814 && S_ISDIR (st.st_mode)))
816 pglob->gl_pathv
817 = (char **) realloc (pglob->gl_pathv,
818 (pglob->gl_pathc +
819 ((flags & GLOB_DOOFFS) ?
820 pglob->gl_offs : 0) +
821 1 + 1) *
822 sizeof (char *));
823 if (pglob->gl_pathv == NULL)
824 return GLOB_NOSPACE;
826 if (flags & GLOB_DOOFFS)
827 while (pglob->gl_pathc < pglob->gl_offs)
828 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
830 #if defined HAVE_STRDUP || defined _LIBC
831 pglob->gl_pathv[pglob->gl_pathc] = strdup (dirname);
832 #else
834 size_t len = strlen (dirname) + 1;
835 char *dircopy = malloc (len);
836 if (dircopy != NULL)
837 pglob->gl_pathv[pglob->gl_pathc] = memcpy (dircopy, dirname,
838 len);
840 #endif
841 if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
843 free (pglob->gl_pathv);
844 return GLOB_NOSPACE;
846 pglob->gl_pathv[++pglob->gl_pathc] = NULL;
847 pglob->gl_flags = flags;
849 return 0;
852 /* Not found. */
853 return GLOB_NOMATCH;
856 if (__glob_pattern_p (dirname, !(flags & GLOB_NOESCAPE)))
858 /* The directory name contains metacharacters, so we
859 have to glob for the directory, and then glob for
860 the pattern in each directory found. */
861 glob_t dirs;
862 register __size_t i; /* bird: correct type. */
864 status = glob (dirname,
865 ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE))
866 | GLOB_NOSORT | GLOB_ONLYDIR),
867 errfunc, &dirs);
868 if (status != 0)
869 return status;
871 /* We have successfully globbed the preceding directory name.
872 For each name we found, call glob_in_dir on it and FILENAME,
873 appending the results to PGLOB. */
874 for (i = 0; i < dirs.gl_pathc; ++i)
876 int old_pathc;
878 #ifdef SHELL
880 /* Make globbing interruptible in the bash shell. */
881 extern int interrupt_state;
883 if (interrupt_state)
885 globfree (&dirs);
886 globfree (&files);
887 return GLOB_ABORTED;
890 #endif /* SHELL. */
892 old_pathc = pglob->gl_pathc;
893 status = glob_in_dir (filename, dirs.gl_pathv[i],
894 ((flags | GLOB_APPEND)
895 & ~(GLOB_NOCHECK | GLOB_ERR)),
896 errfunc, pglob);
897 if (status == GLOB_NOMATCH)
898 /* No matches in this directory. Try the next. */
899 continue;
901 if (status != 0)
903 globfree (&dirs);
904 globfree (pglob);
905 return status;
908 /* Stick the directory on the front of each name. */
909 if (prefix_array (dirs.gl_pathv[i],
910 &pglob->gl_pathv[old_pathc],
911 pglob->gl_pathc - old_pathc))
913 globfree (&dirs);
914 globfree (pglob);
915 return GLOB_NOSPACE;
919 flags |= GLOB_MAGCHAR;
921 /* We have ignored the GLOB_NOCHECK flag in the `glob_in_dir' calls.
922 But if we have not found any matching entry and thie GLOB_NOCHECK
923 flag was set we must return the list consisting of the disrectory
924 names followed by the filename. */
925 if (pglob->gl_pathc == oldcount)
927 /* No matches. */
928 if (flags & GLOB_NOCHECK)
930 size_t filename_len = strlen (filename) + 1;
931 char **new_pathv;
932 struct stat st;
934 /* This is an pessimistic guess about the size. */
935 pglob->gl_pathv
936 = (char **) realloc (pglob->gl_pathv,
937 (pglob->gl_pathc +
938 ((flags & GLOB_DOOFFS) ?
939 pglob->gl_offs : 0) +
940 dirs.gl_pathc + 1) *
941 sizeof (char *));
942 if (pglob->gl_pathv == NULL)
944 globfree (&dirs);
945 return GLOB_NOSPACE;
948 if (flags & GLOB_DOOFFS)
949 while (pglob->gl_pathc < pglob->gl_offs)
950 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
952 for (i = 0; i < dirs.gl_pathc; ++i)
954 const char *dir = dirs.gl_pathv[i];
955 size_t dir_len = strlen (dir);
957 /* First check whether this really is a directory. */
958 if (((flags & GLOB_ALTDIRFUNC)
959 ? (*pglob->gl_stat) (dir, &st) : __stat (dir, &st)) != 0
960 || !S_ISDIR (st.st_mode))
961 /* No directory, ignore this entry. */
962 continue;
964 pglob->gl_pathv[pglob->gl_pathc] = malloc (dir_len + 1
965 + filename_len);
966 if (pglob->gl_pathv[pglob->gl_pathc] == NULL)
968 globfree (&dirs);
969 globfree (pglob);
970 return GLOB_NOSPACE;
973 #ifdef HAVE_MEMPCPY
974 mempcpy (mempcpy (mempcpy (pglob->gl_pathv[pglob->gl_pathc],
975 dir, dir_len),
976 "/", 1),
977 filename, filename_len);
978 #else
979 memcpy (pglob->gl_pathv[pglob->gl_pathc], dir, dir_len);
980 pglob->gl_pathv[pglob->gl_pathc][dir_len] = '/';
981 memcpy (&pglob->gl_pathv[pglob->gl_pathc][dir_len + 1],
982 filename, filename_len);
983 #endif
984 ++pglob->gl_pathc;
987 pglob->gl_pathv[pglob->gl_pathc] = NULL;
988 pglob->gl_flags = flags;
990 /* Now we know how large the gl_pathv vector must be. */
991 new_pathv = (char **) realloc (pglob->gl_pathv,
992 ((pglob->gl_pathc + 1)
993 * sizeof (char *)));
994 if (new_pathv != NULL)
995 pglob->gl_pathv = new_pathv;
997 else
998 return GLOB_NOMATCH;
1001 globfree (&dirs);
1003 else
1005 status = glob_in_dir (filename, dirname, flags, errfunc, pglob);
1006 if (status != 0)
1007 return status;
1009 if (dirlen > 0)
1011 /* Stick the directory on the front of each name. */
1012 __size_t ignore = oldcount; /* bird: correct type. */
1014 if ((flags & GLOB_DOOFFS) && ignore < pglob->gl_offs)
1015 ignore = pglob->gl_offs;
1017 if (prefix_array (dirname,
1018 &pglob->gl_pathv[ignore],
1019 pglob->gl_pathc - ignore))
1021 globfree (pglob);
1022 return GLOB_NOSPACE;
1027 if (flags & GLOB_MARK)
1029 /* Append slashes to directory names. */
1030 __size_t i; /* bird: correct type. */
1031 struct stat st;
1032 for (i = oldcount; i < pglob->gl_pathc; ++i)
1033 if (((flags & GLOB_ALTDIRFUNC)
1034 ? (*pglob->gl_stat) (pglob->gl_pathv[i], &st)
1035 : __stat (pglob->gl_pathv[i], &st)) == 0
1036 && S_ISDIR (st.st_mode))
1038 size_t len = strlen (pglob->gl_pathv[i]) + 2;
1039 char *new = realloc (pglob->gl_pathv[i], len);
1040 if (new == NULL)
1042 globfree (pglob);
1043 return GLOB_NOSPACE;
1045 strcpy (&new[len - 2], "/");
1046 pglob->gl_pathv[i] = new;
1050 if (!(flags & GLOB_NOSORT))
1052 /* Sort the vector. */
1053 int non_sort = oldcount;
1055 if ((flags & GLOB_DOOFFS) && pglob->gl_offs > oldcount)
1056 non_sort = pglob->gl_offs;
1058 qsort ((__ptr_t) &pglob->gl_pathv[non_sort],
1059 pglob->gl_pathc - non_sort,
1060 sizeof (char *), collated_compare);
1063 return 0;
1067 /* Free storage allocated in PGLOB by a previous `glob' call. */
1068 void
1069 globfree (pglob)
1070 register glob_t *pglob;
1072 if (pglob->gl_pathv != NULL)
1074 register __size_t i; /* bird: correct type */
1075 for (i = 0; i < pglob->gl_pathc; ++i)
1076 if (pglob->gl_pathv[i] != NULL)
1077 free ((__ptr_t) pglob->gl_pathv[i]);
1078 free ((__ptr_t) pglob->gl_pathv);
1083 /* Do a collated comparison of A and B. */
1084 static int
1085 collated_compare (a, b)
1086 const __ptr_t a;
1087 const __ptr_t b;
1089 const char *const s1 = *(const char *const * const) a;
1090 const char *const s2 = *(const char *const * const) b;
1092 if (s1 == s2)
1093 return 0;
1094 if (s1 == NULL)
1095 return 1;
1096 if (s2 == NULL)
1097 return -1;
1098 return strcoll (s1, s2);
1102 /* Prepend DIRNAME to each of N members of ARRAY, replacing ARRAY's
1103 elements in place. Return nonzero if out of memory, zero if successful.
1104 A slash is inserted between DIRNAME and each elt of ARRAY,
1105 unless DIRNAME is just "/". Each old element of ARRAY is freed. */
1106 static int
1107 prefix_array (dirname, array, n)
1108 const char *dirname;
1109 char **array;
1110 size_t n;
1112 register size_t i;
1113 size_t dirlen = strlen (dirname);
1114 #if defined __MSDOS__ || defined WINDOWS32
1115 int sep_char = '/';
1116 # define DIRSEP_CHAR sep_char
1117 #else
1118 # define DIRSEP_CHAR '/'
1119 #endif
1121 if (dirlen == 1 && dirname[0] == '/')
1122 /* DIRNAME is just "/", so normal prepending would get us "//foo".
1123 We want "/foo" instead, so don't prepend any chars from DIRNAME. */
1124 dirlen = 0;
1125 #if defined __MSDOS__ || defined WINDOWS32
1126 else if (dirlen > 1)
1128 if (dirname[dirlen - 1] == '/' && dirname[dirlen - 2] == ':')
1129 /* DIRNAME is "d:/". Don't prepend the slash from DIRNAME. */
1130 --dirlen;
1131 else if (dirname[dirlen - 1] == ':')
1133 /* DIRNAME is "d:". Use `:' instead of `/'. */
1134 --dirlen;
1135 sep_char = ':';
1138 #endif
1140 for (i = 0; i < n; ++i)
1142 size_t eltlen = strlen (array[i]) + 1;
1143 char *new = (char *) malloc (dirlen + 1 + eltlen);
1144 if (new == NULL)
1146 while (i > 0)
1147 free ((__ptr_t) array[--i]);
1148 return 1;
1151 #ifdef HAVE_MEMPCPY
1153 char *endp = (char *) mempcpy (new, dirname, dirlen);
1154 *endp++ = DIRSEP_CHAR;
1155 mempcpy (endp, array[i], eltlen);
1157 #else
1158 memcpy (new, dirname, dirlen);
1159 new[dirlen] = DIRSEP_CHAR;
1160 memcpy (&new[dirlen + 1], array[i], eltlen);
1161 #endif
1162 free ((__ptr_t) array[i]);
1163 array[i] = new;
1166 return 0;
1170 /* We must not compile this function twice. */
1171 #if !defined _LIBC || !defined NO_GLOB_PATTERN_P
1172 /* Return nonzero if PATTERN contains any metacharacters.
1173 Metacharacters can be quoted with backslashes if QUOTE is nonzero. */
1175 __glob_pattern_p (pattern, quote)
1176 const char *pattern;
1177 int quote;
1179 register const char *p;
1180 int open = 0;
1182 for (p = pattern; *p != '\0'; ++p)
1183 switch (*p)
1185 case '?':
1186 case '*':
1187 return 1;
1189 case '\\':
1190 if (quote && p[1] != '\0')
1191 ++p;
1192 break;
1194 case '[':
1195 open = 1;
1196 break;
1198 case ']':
1199 if (open)
1200 return 1;
1201 break;
1204 return 0;
1206 # ifdef _LIBC
1207 weak_alias (__glob_pattern_p, glob_pattern_p)
1208 # endif
1209 #endif
1212 /* Like `glob', but PATTERN is a final pathname component,
1213 and matches are searched for in DIRECTORY.
1214 The GLOB_NOSORT bit in FLAGS is ignored. No sorting is ever done.
1215 The GLOB_APPEND flag is assumed to be set (always appends). */
1216 static int
1217 glob_in_dir (pattern, directory, flags, errfunc, pglob)
1218 const char *pattern;
1219 const char *directory;
1220 int flags;
1221 int (*errfunc) __P ((const char *, int));
1222 glob_t *pglob;
1224 __ptr_t stream = NULL;
1226 struct globlink
1228 struct globlink *next;
1229 char *name;
1231 struct globlink *names = NULL;
1232 size_t nfound;
1233 int meta;
1234 int save;
1236 #ifdef VMS
1237 if (*directory == 0)
1238 directory = "[]";
1239 #endif
1240 meta = __glob_pattern_p (pattern, !(flags & GLOB_NOESCAPE));
1241 if (meta == 0)
1243 if (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))
1244 /* We need not do any tests. The PATTERN contains no meta
1245 characters and we must not return an error therefore the
1246 result will always contain exactly one name. */
1247 flags |= GLOB_NOCHECK;
1248 else
1250 /* Since we use the normal file functions we can also use stat()
1251 to verify the file is there. */
1252 struct stat st;
1253 size_t patlen = strlen (pattern);
1254 size_t dirlen = strlen (directory);
1255 char *fullname = (char *) __alloca (dirlen + 1 + patlen + 1);
1257 # ifdef HAVE_MEMPCPY
1258 mempcpy (mempcpy (mempcpy (fullname, directory, dirlen),
1259 "/", 1),
1260 pattern, patlen + 1);
1261 # else
1262 memcpy (fullname, directory, dirlen);
1263 fullname[dirlen] = '/';
1264 memcpy (&fullname[dirlen + 1], pattern, patlen + 1);
1265 # endif
1266 if (((flags & GLOB_ALTDIRFUNC)
1267 ? (*pglob->gl_stat) (fullname, &st)
1268 : __stat (fullname, &st)) == 0)
1269 /* We found this file to be existing. Now tell the rest
1270 of the function to copy this name into the result. */
1271 flags |= GLOB_NOCHECK;
1274 nfound = 0;
1276 else
1278 if (pattern[0] == '\0')
1280 /* This is a special case for matching directories like in
1281 "*a/". */
1282 names = (struct globlink *) __alloca (sizeof (struct globlink));
1283 names->name = (char *) malloc (1);
1284 if (names->name == NULL)
1285 goto memory_error;
1286 names->name[0] = '\0';
1287 names->next = NULL;
1288 nfound = 1;
1289 meta = 0;
1291 else
1293 stream = ((flags & GLOB_ALTDIRFUNC)
1294 ? (*pglob->gl_opendir) (directory)
1295 : (__ptr_t) opendir (directory));
1296 if (stream == NULL)
1298 if (errno != ENOTDIR
1299 && ((errfunc != NULL && (*errfunc) (directory, errno))
1300 || (flags & GLOB_ERR)))
1301 return GLOB_ABORTED;
1302 nfound = 0;
1303 meta = 0;
1305 else
1307 int fnm_flags = ((!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0)
1308 | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
1309 #if defined HAVE_CASE_INSENSITIVE_FS
1310 | FNM_CASEFOLD
1311 #endif
1313 nfound = 0;
1314 flags |= GLOB_MAGCHAR;
1316 while (1)
1318 const char *name;
1319 size_t len;
1320 struct dirent *d = ((flags & GLOB_ALTDIRFUNC)
1321 ? (*pglob->gl_readdir) (stream)
1322 : readdir ((DIR *) stream));
1323 if (d == NULL)
1324 break;
1325 if (! REAL_DIR_ENTRY (d))
1326 continue;
1328 #ifdef HAVE_D_TYPE
1329 /* If we shall match only directories use the information
1330 provided by the dirent call if possible. */
1331 if ((flags & GLOB_ONLYDIR)
1332 && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR)
1333 continue;
1334 #endif
1336 name = d->d_name;
1338 if (fnmatch (pattern, name, fnm_flags) == 0)
1340 struct globlink *new = (struct globlink *)
1341 __alloca (sizeof (struct globlink));
1342 len = NAMLEN (d);
1343 new->name = (char *) malloc (len + 1);
1344 if (new->name == NULL)
1345 goto memory_error;
1346 #ifdef HAVE_MEMPCPY
1347 *((char *) mempcpy ((__ptr_t) new->name, name, len))
1348 = '\0';
1349 #else
1350 memcpy ((__ptr_t) new->name, name, len);
1351 new->name[len] = '\0';
1352 #endif
1353 new->next = names;
1354 names = new;
1355 ++nfound;
1362 if (nfound == 0 && (flags & GLOB_NOCHECK))
1364 size_t len = strlen (pattern);
1365 nfound = 1;
1366 names = (struct globlink *) __alloca (sizeof (struct globlink));
1367 names->next = NULL;
1368 names->name = (char *) malloc (len + 1);
1369 if (names->name == NULL)
1370 goto memory_error;
1371 #ifdef HAVE_MEMPCPY
1372 *((char *) mempcpy (names->name, pattern, len)) = '\0';
1373 #else
1374 memcpy (names->name, pattern, len);
1375 names->name[len] = '\0';
1376 #endif
1379 if (nfound != 0)
1381 pglob->gl_pathv
1382 = (char **) realloc (pglob->gl_pathv,
1383 (pglob->gl_pathc +
1384 ((flags & GLOB_DOOFFS) ? pglob->gl_offs : 0) +
1385 nfound + 1) *
1386 sizeof (char *));
1387 if (pglob->gl_pathv == NULL)
1388 goto memory_error;
1390 if (flags & GLOB_DOOFFS)
1391 while (pglob->gl_pathc < pglob->gl_offs)
1392 pglob->gl_pathv[pglob->gl_pathc++] = NULL;
1394 for (; names != NULL; names = names->next)
1395 pglob->gl_pathv[pglob->gl_pathc++] = names->name;
1396 pglob->gl_pathv[pglob->gl_pathc] = NULL;
1398 pglob->gl_flags = flags;
1401 save = errno;
1402 if (stream != NULL)
1404 if (flags & GLOB_ALTDIRFUNC)
1405 (*pglob->gl_closedir) (stream);
1406 else
1407 closedir ((DIR *) stream);
1409 __set_errno (save);
1411 return nfound == 0 ? GLOB_NOMATCH : 0;
1413 memory_error:
1415 int save = errno;
1416 if (flags & GLOB_ALTDIRFUNC)
1417 (*pglob->gl_closedir) (stream);
1418 else
1419 closedir ((DIR *) stream);
1420 __set_errno (save);
1422 while (names != NULL)
1424 if (names->name != NULL)
1425 free ((__ptr_t) names->name);
1426 names = names->next;
1428 return GLOB_NOSPACE;
1431 #endif /* Not ELIDE_CODE. */