1 /* File-name wildcard pattern matching for GNU.
2 Copyright (C) 1985, 1988, 1989, 1990, 1991 Free Software Foundation, Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 1, or (at your option)
9 This program 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
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
20 /* To whomever it may concern: I have never seen the code which most
21 Unix programs use to perform this function. I wrote this from scratch
22 based on specifications for the pattern matching. --RMS. */
28 #include <sys/types.h>
30 #if defined (USGr3) && !defined (DIRENT)
33 #if defined (Xenix) && !defined (SYSNDIR)
37 #if defined (POSIX) || defined (DIRENT) || defined (__GNU_LIBRARY__)
40 #define D_NAMLEN(d) strlen((d)->d_name)
41 #else /* not POSIX or DIRENT or __GNU_LIBRARY__ */
42 #define D_NAMLEN(d) ((d)->d_namlen)
48 #endif /* not SYSNDIR */
52 #endif /* POSIX or DIRENT or __GNU_LIBRARY__ */
54 #if defined (_POSIX_SOURCE)
55 /* Posix does not require that the d_ino field be present, and some
56 systems do not provide it. */
57 #define REAL_DIR_ENTRY(dp) 1
59 #define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
60 #endif /* _POSIX_SOURCE */
62 #if defined (STDC_HEADERS) || defined (__GNU_LIBRARY__)
66 #else /* STDC_HEADERS or __GNU_LIBRARY__ */
80 /* Declaring bcopy causes errors on systems whose declarations are different.
81 If the declaration is omitted, everything works fine. */
84 extern char *malloc ();
85 extern char *realloc ();
91 #endif /* Not STDC_HEADERS or __GNU_LIBRARY__. */
94 #define bcopy(s, d, n) memcpy ((d), (s), (n))
96 #define rindex strrchr
97 #endif /* STDC_STRINGS */
101 #define alloca __builtin_alloca
105 #else /* Not sparc. */
106 extern char *alloca ();
111 /* Nonzero if '*' and '?' do not match an initial '.' for glob_filename. */
112 int noglob_dot_filenames = 1;
114 static int glob_match_after_star ();
117 static int collate_range_cmp(a, b)
124 return (strcoll(s[0], s[1]));
128 /* Return nonzero if PATTERN has any special globbing chars in it. */
131 glob_pattern_p (pattern)
134 register char *p = pattern;
138 while ((c = *p++) != '\0')
145 case '[': /* Only accept an open brace if there is a close */
146 open++; /* brace to match it. Bracket expressions must be */
147 continue; /* complete, according to Posix.2 */
162 /* Match the pattern PATTERN against the string TEXT;
163 return 1 if it matches, 0 otherwise.
165 A match means the entire string TEXT is used up in matching.
167 In the pattern string, `*' matches any sequence of characters,
168 `?' matches any character, [SET] matches any character in the specified set,
169 [!SET] matches any character not in the specified set.
171 A set is composed of characters or ranges; a range looks like
172 character hyphen character (as in 0-9 or A-Z).
173 [0-9a-zA-Z_] is the set of characters allowed in C identifiers.
174 Any other character in the pattern must be matched exactly.
176 To suppress the special syntactic significance of any of `[]*?!-\',
177 and match the character exactly, precede it with a `\'.
179 If DOT_SPECIAL is nonzero,
180 `*' and `?' do not match `.' at the beginning of TEXT. */
183 glob_match (pattern, text, dot_special)
184 char *pattern, *text;
187 register char *p = pattern, *t = text;
190 while ((c = *p++) != '\0')
194 if (*t == '\0' || (dot_special && t == text && *t == '.'))
206 if (dot_special && t == text && *t == '.')
208 return glob_match_after_star (p, t);
212 register char c1 = *t++;
219 invert = (*p == '!');
227 register char cstart = c, cend = c;
240 /* matched a single bracket */
257 if ( collate_range_cmp (c1, cstart) >= 0
258 && collate_range_cmp (c1, cend) <= 0
261 if (c1 >= cstart && c1 <= cend)
272 /* Skip the rest of the [...] construct that already matched. */
297 /* Like glob_match, but match PATTERN against any final segment of TEXT. */
300 glob_match_after_star (pattern, text)
301 char *pattern, *text;
303 register char *p = pattern, *t = text;
306 while ((c = *p++) == '?' || c == '*')
307 if (c == '?' && *t++ == '\0')
321 if ((c == '[' || *t == c1) && glob_match (p, t, 0))
328 /* Return a vector of names of files in directory DIR
329 whose names match glob pattern PAT.
330 The names are not in any particular order.
331 Wildcards at the beginning of PAT do not match an initial period
332 if noglob_dot_filenames is nonzero.
334 The vector is terminated by an element that is a null pointer.
336 To free the space allocated, first free the vector's elements,
337 then free the vector.
339 Return NULL if cannot get enough memory to hold the pointer
342 Return -1 if cannot access directory DIR.
343 Look in errno for more information. */
346 glob_vector (pat, dir)
352 struct globval *next;
357 register struct direct *dp;
358 struct globval *lastlink;
359 register struct globval *nextlink;
360 register char *nextname;
363 register char **name_vector;
364 register unsigned int i;
365 #ifdef ALLOCA_MISSING
366 struct globval *templink;
377 /* Scan the directory, finding all names that match.
378 For each name that matches, allocate a struct globval
379 on the stack and store the name in it.
380 Chain those structs together; lastlink is the front of the chain. */
384 /* Make globbing interruptible in the bash shell. */
385 extern int interrupt_state;
398 if (REAL_DIR_ENTRY (dp)
399 && glob_match (pat, dp->d_name, noglob_dot_filenames))
401 #ifdef ALLOCA_MISSING
402 nextlink = (struct globval *) malloc (sizeof (struct globval));
404 nextlink = (struct globval *) alloca (sizeof (struct globval));
406 nextlink->next = lastlink;
407 i = D_NAMLEN (dp) + 1;
408 nextname = (char *) malloc (i);
409 if (nextname == NULL)
415 nextlink->name = nextname;
416 bcopy (dp->d_name, nextname, i);
424 name_vector = (char **) malloc ((count + 1) * sizeof (char *));
425 lose |= name_vector == NULL;
428 /* Have we run out of memory? */
434 /* Here free the strings we have got. */
437 free (lastlink->name);
438 #ifdef ALLOCA_MISSING
439 templink = lastlink->next;
440 free ((char *) lastlink);
443 lastlink = lastlink->next;
449 /* Copy the name pointers from the linked list into the vector. */
450 for (i = 0; i < count; ++i)
452 name_vector[i] = lastlink->name;
453 #ifdef ALLOCA_MISSING
454 templink = lastlink->next;
455 free ((char *) lastlink);
458 lastlink = lastlink->next;
462 name_vector[count] = NULL;
466 /* Return a new array, replacing ARRAY, which is the concatenation
467 of each string in ARRAY to DIR.
468 Return NULL if out of memory. */
471 glob_dir_to_array (dir, array)
474 register unsigned int i, l;
482 if (dir[l - 1] != '/')
485 for (i = 0; array[i] != NULL; i++)
488 result = (char **) malloc ((i + 1) * sizeof (char *));
492 for (i = 0; array[i] != NULL; i++)
494 result[i] = (char *) malloc (1 + l + add_slash + strlen (array[i]));
495 if (result[i] == NULL)
497 strcpy (result[i], dir);
500 strcpy (result[i] + l + add_slash, array[i]);
504 /* Free the input array. */
505 for (i = 0; array[i] != NULL; i++)
507 free ((char *) array);
511 /* Do globbing on PATHNAME. Return an array of pathnames that match,
512 marking the end of the array with a null-pointer as an element.
513 If no pathnames match, then the array is empty (first element is null).
514 If there isn't enough memory, then return NULL.
515 If a file system error occurs, return -1; `errno' has the error code.
517 Wildcards at the beginning of PAT, or following a slash,
518 do not match an initial period if noglob_dot_filenames is nonzero. */
521 glob_filename (pathname)
525 unsigned int result_size;
526 char *directory_name, *filename;
527 unsigned int directory_len;
529 result = (char **) malloc (sizeof (char *));
536 /* Find the filename. */
537 filename = rindex (pathname, '/');
538 if (filename == NULL)
546 directory_len = (filename - pathname) + 1;
547 #ifdef ALLOCA_MISSING
548 directory_name = (char *) malloc (directory_len + 1);
550 directory_name = (char *) alloca (directory_len + 1);
552 bcopy (pathname, directory_name, directory_len);
553 directory_name[directory_len] = '\0';
557 /* If directory_name contains globbing characters, then we
558 have to expand the previous levels. Just recurse. */
559 if (glob_pattern_p (directory_name))
562 register unsigned int i;
564 if (directory_name[directory_len - 1] == '/')
565 directory_name[directory_len - 1] = '\0';
567 directories = glob_filename (directory_name);
568 #ifdef ALLOCA_MISSING
569 free ((char *) directory_name);
571 if (directories == NULL)
573 else if (directories == (char **) -1)
575 else if (*directories == NULL)
577 free ((char *) directories);
581 /* We have successfully globbed the preceding directory name.
582 For each name in DIRECTORIES, call glob_vector on it and
583 FILENAME. Concatenate the results together. */
584 for (i = 0; directories[i] != NULL; i++)
586 char **temp_results = glob_vector (filename, directories[i]);
587 if (temp_results == NULL)
589 else if (temp_results == (char **) -1)
590 /* This filename is probably not a directory. Ignore it. */
594 char **array = glob_dir_to_array (directories[i], temp_results);
595 register unsigned int l;
598 while (array[l] != NULL)
601 result = (char **) realloc (result,
602 (result_size + l) * sizeof (char *));
606 for (l = 0; array[l] != NULL; ++l)
607 result[result_size++ - 1] = array[l];
608 result[result_size - 1] = NULL;
609 free ((char *) array);
612 /* Free the directories. */
613 for (i = 0; directories[i] != NULL; i++)
614 free (directories[i]);
615 free ((char *) directories);
620 /* If there is only a directory name, return it. */
621 if (*filename == '\0')
623 result = (char **) realloc ((char *) result, 2 * sizeof (char *));
626 result[0] = (char *) malloc (directory_len + 1);
627 if (result[0] == NULL)
629 #ifdef ALLOCA_MISSING
630 free ((char *) directory_name);
634 bcopy (directory_name, result[0], directory_len + 1);
637 #ifdef ALLOCA_MISSING
638 free ((char *) directory_name);
644 /* Otherwise, just return what glob_vector
645 returns appended to the directory name. */
646 char **temp_results = glob_vector (filename,
648 ? "." : directory_name));
650 if (temp_results == NULL || temp_results == (char **) -1)
653 free ((char *) directory_name);
658 temp_results = glob_dir_to_array (directory_name, temp_results);
660 free ((char *) directory_name);
665 /* We get to memory error if the program has run out of memory, or
666 if this is the shell, and we have been interrupted. */
670 register unsigned int i;
671 for (i = 0; result[i] != NULL; ++i)
673 free ((char *) result);
677 extern int interrupt_state;
680 throw_to_top_level ();
695 for (optind = 1; optind < argc; optind++)
697 value = glob_filename (argv[optind]);
699 puts ("virtual memory exhausted");
700 else if (value == (char **) -1)
701 perror (argv[optind]);
703 for (i = 0; value[i] != NULL; i++)