2 * glob.c - filename generation
4 * This file is part of zsh, the Z shell.
6 * Copyright (c) 1992-1997 Paul Falstad
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
15 * In no event shall Paul Falstad or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Paul Falstad and the Zsh Development Group have been advised of
19 * the possibility of such damage.
21 * Paul Falstad and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose. The software
24 * provided hereunder is on an "as is" basis, and Paul Falstad and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
33 #if defined(OFF_T_IS_64_BIT) && defined(__GNUC__)
34 # define ALIGN64 __attribute__((aligned(8)))
39 /* flag for CSHNULLGLOB */
41 typedef struct gmatch
*Gmatch
;
46 * Array of sort strings: one for each GS_EXEC sort type in
47 * the glob qualifiers.
60 #ifdef GET_ST_ATIME_NSEC
64 #ifdef GET_ST_MTIME_NSEC
68 #ifdef GET_ST_CTIME_NSEC
78 #define GS_SHIFT_BASE 8
80 #define GS_SIZE (GS_SHIFT_BASE)
81 #define GS_ATIME (GS_SHIFT_BASE << 1)
82 #define GS_MTIME (GS_SHIFT_BASE << 2)
83 #define GS_CTIME (GS_SHIFT_BASE << 3)
84 #define GS_LINKS (GS_SHIFT_BASE << 4)
87 #define GS__SIZE (GS_SIZE << GS_SHIFT)
88 #define GS__ATIME (GS_ATIME << GS_SHIFT)
89 #define GS__MTIME (GS_MTIME << GS_SHIFT)
90 #define GS__CTIME (GS_CTIME << GS_SHIFT)
91 #define GS__LINKS (GS_LINKS << GS_SHIFT)
93 #define GS_DESC (GS_SHIFT_BASE << (2*GS_SHIFT))
94 #define GS_NONE (GS_SHIFT_BASE << (2*GS_SHIFT+1))
96 #define GS_NORMAL (GS_SIZE | GS_ATIME | GS_MTIME | GS_CTIME | GS_LINKS)
97 #define GS_LINKED (GS_NORMAL << GS_SHIFT)
103 int pathpos
; /* position in pathbuf (needed by pattern code) */
106 char *pathbuf
; /* pathname buffer (needed by pattern code) */
108 typedef struct stat
*Statptr
; /* This makes the Ultrix compiler happy. Go figure. */
110 /* modifier for unit conversions */
120 #define TT_POSIX_BLOCKS 1
121 #define TT_KILOBYTES 2
122 #define TT_MEGABYTES 3
125 typedef int (*TestMatchFunc
) _((char *, struct stat
*, off_t
, char *));
128 struct qual
*next
; /* Next qualifier, must match */
129 struct qual
*or; /* Alternative set of qualifiers to match */
130 TestMatchFunc func
; /* Function to call to test match */
131 off_t data ALIGN64
; /* Argument passed to function */
132 int sense
; /* Whether asserting or negating */
133 int amc
; /* Flag for which time to test (a, m, c) */
134 int range
; /* Whether to test <, > or = (as per signum) */
135 int units
; /* Multiplier for time or size, respectively */
136 char *sdata
; /* currently only: expression to eval */
139 /* Prefix, suffix for doing zle trickery */
142 mod_export
char *glob_pre
, *glob_suf
;
144 /* Element of a glob sort */
148 /* Sort code to eval, if type is GS_EXEC */
152 /* Maximum entries in sort array */
153 #define MAX_SORTS (12)
155 /* struct to easily save/restore current state */
161 int gd_matchsz
; /* size of matchbuf */
162 int gd_matchct
; /* number of matches found */
163 int gd_pathbufsz
; /* size of pathbuf */
164 int gd_pathbufcwd
; /* where did we chdir()'ed */
165 Gmatch gd_matchbuf
; /* array of matches */
166 Gmatch gd_matchptr
; /* &matchbuf[matchct] */
167 char *gd_colonmod
; /* colon modifiers in qualifier list */
169 /* Qualifiers pertaining to current pattern */
170 struct qual
*gd_quals
;
172 /* Other state values for current pattern */
173 int gd_qualct
, gd_qualorct
;
174 int gd_range
, gd_amc
, gd_units
;
175 int gd_gf_nullglob
, gd_gf_markdirs
, gd_gf_noglobdots
, gd_gf_listtypes
;
177 int gd_gf_follow
, gd_gf_sorts
, gd_gf_nsorts
;
178 struct globsort gd_gf_sortlist
[MAX_SORTS
];
180 char *gd_glob_pre
, *gd_glob_suf
;
183 /* The variable with the current globbing state and convenience macros */
185 static struct globdata curglobdata
;
187 #define matchsz (curglobdata.gd_matchsz)
188 #define matchct (curglobdata.gd_matchct)
189 #define pathbufsz (curglobdata.gd_pathbufsz)
190 #define pathbufcwd (curglobdata.gd_pathbufcwd)
191 #define matchbuf (curglobdata.gd_matchbuf)
192 #define matchptr (curglobdata.gd_matchptr)
193 #define colonmod (curglobdata.gd_colonmod)
194 #define quals (curglobdata.gd_quals)
195 #define qualct (curglobdata.gd_qualct)
196 #define qualorct (curglobdata.gd_qualorct)
197 #define g_range (curglobdata.gd_range)
198 #define g_amc (curglobdata.gd_amc)
199 #define g_units (curglobdata.gd_units)
200 #define gf_nullglob (curglobdata.gd_gf_nullglob)
201 #define gf_markdirs (curglobdata.gd_gf_markdirs)
202 #define gf_noglobdots (curglobdata.gd_gf_noglobdots)
203 #define gf_listtypes (curglobdata.gd_gf_listtypes)
204 #define gf_numsort (curglobdata.gd_gf_numsort)
205 #define gf_follow (curglobdata.gd_gf_follow)
206 #define gf_sorts (curglobdata.gd_gf_sorts)
207 #define gf_nsorts (curglobdata.gd_gf_nsorts)
208 #define gf_sortlist (curglobdata.gd_gf_sortlist)
210 /* and macros for save/restore */
212 #define save_globstate(N) \
214 memcpy(&(N), &curglobdata, sizeof(struct globdata)); \
215 (N).gd_pathpos = pathpos; \
216 (N).gd_pathbuf = pathbuf; \
217 (N).gd_glob_pre = glob_pre; \
218 (N).gd_glob_suf = glob_suf; \
222 #define restore_globstate(N) \
224 zfree(pathbuf, pathbufsz); \
225 memcpy(&curglobdata, &(N), sizeof(struct globdata)); \
226 pathpos = (N).gd_pathpos; \
227 pathbuf = (N).gd_pathbuf; \
228 glob_pre = (N).gd_glob_pre; \
229 glob_suf = (N).gd_glob_suf; \
232 /* pathname component in filename patterns */
237 int closure
; /* 1 if this is a (foo/)# */
238 int follow
; /* 1 to go thru symlinks */
241 /* Add a component to pathbuf: This keeps track of how *
242 * far we are into a file name, since each path component *
243 * must be matched separately. */
247 addpath(char *s
, int l
)
249 DPUTS(!pathbuf
, "BUG: pathbuf not initialised");
250 while (pathpos
+ l
+ 1 >= pathbufsz
)
251 pathbuf
= realloc(pathbuf
, pathbufsz
*= 2);
253 pathbuf
[pathpos
++] = *s
++;
254 pathbuf
[pathpos
++] = '/';
255 pathbuf
[pathpos
] = '\0';
258 /* stat the filename s appended to pathbuf. l should be true for lstat, *
259 * false for stat. If st is NULL, the file is only checked for existance. *
260 * s == "" is treated as s == ".". This is necessary since on most systems *
261 * foo/ can be used to reference a non-directory foo. Returns nonzero if *
262 * the file does not exists. */
266 statfullpath(const char *s
, struct stat
*st
, int l
)
270 DPUTS(strlen(s
) + !*s
+ pathpos
- pathbufcwd
>= PATH_MAX
,
271 "BUG: statfullpath(): pathname too long");
272 strcpy(buf
, pathbuf
+ pathbufcwd
);
273 strcpy(buf
+ pathpos
- pathbufcwd
, s
);
276 * Don't add the '.' if the path so far is empty, since
277 * then we get bogus empty strings inserted as files.
279 buf
[pathpos
- pathbufcwd
] = '.';
280 buf
[pathpos
- pathbufcwd
+ 1] = '\0';
286 return access(buf
, F_OK
) && (!l
|| readlink(buf
, lbuf
, 1) < 0);
288 return l
? lstat(buf
, st
) : stat(buf
, st
);
291 /* This may be set by qualifier functions to an array of strings to insert
292 * into the list instead of the original string. */
296 /* add a match to the list */
300 insert(char *s
, int checked
)
302 struct stat buf
, buf2
, *bp
;
309 if (gf_listtypes
|| gf_markdirs
) {
310 /* Add the type marker to the end of the filename */
312 checked
= statted
= 1;
313 if (statfullpath(s
, &buf
, 1)) {
319 if (!S_ISLNK(mode
) || statfullpath(s
, &buf2
, 0))
320 memcpy(&buf2
, &buf
, sizeof(buf
));
324 if (gf_listtypes
|| S_ISDIR(mode
)) {
327 news
= (char *) hcalloc(ll
+ 2);
329 news
[ll
] = file_type(mode
);
333 if (qualct
|| qualorct
) {
334 /* Go through the qualifiers, rejecting the file if appropriate */
335 struct qual
*qo
, *qn
;
337 if (!statted
&& statfullpath(s
, &buf
, 1)) {
341 news
= dyncat(pathbuf
, news
);
345 for (qn
= qo
; qn
&& qn
->func
;) {
349 if ((qn
->sense
& 2) && !(statted
& 2)) {
350 /* If (sense & 2), we're following links */
351 if (!S_ISLNK(buf
.st_mode
) || statfullpath(s
, &buf2
, 0))
352 memcpy(&buf2
, &buf
, sizeof(buf
));
355 bp
= (qn
->sense
& 2) ? &buf2
: &buf
;
356 /* Reject the file if the function returned zero *
357 * and the sense was positive (sense&1 == 0), or *
359 if ((!((qn
->func
) (news
, bp
, qn
->data
, qn
->sdata
))
361 /* Try next alternative, or return if there are no more */
362 if (!(qo
= qo
->or)) {
371 } else if (!checked
) {
372 if (statfullpath(s
, NULL
, 1)) {
377 news
= dyncat(pathbuf
, news
);
379 news
= dyncat(pathbuf
, news
);
381 while (!inserts
|| (news
= dupstring(*inserts
++))) {
383 /* Handle the remainder of the qualifier: e.g. (:r:s/foo/bar/). */
387 if (!statted
&& (gf_sorts
& GS_NORMAL
)) {
388 statfullpath(s
, &buf
, 1);
391 if (!(statted
& 2) && (gf_sorts
& GS_LINKED
)) {
393 if (!S_ISLNK(buf
.st_mode
) || statfullpath(s
, &buf2
, 0))
394 memcpy(&buf2
, &buf
, sizeof(buf
));
395 } else if (statfullpath(s
, &buf2
, 0))
396 statfullpath(s
, &buf2
, 1);
399 matchptr
->name
= news
;
401 matchptr
->size
= buf
.st_size
;
402 matchptr
->atime
= buf
.st_atime
;
403 matchptr
->mtime
= buf
.st_mtime
;
404 matchptr
->ctime
= buf
.st_ctime
;
405 matchptr
->links
= buf
.st_nlink
;
406 #ifdef GET_ST_ATIME_NSEC
407 matchptr
->ansec
= GET_ST_ATIME_NSEC(buf
);
409 #ifdef GET_ST_MTIME_NSEC
410 matchptr
->mnsec
= GET_ST_MTIME_NSEC(buf
);
412 #ifdef GET_ST_CTIME_NSEC
413 matchptr
->cnsec
= GET_ST_CTIME_NSEC(buf
);
417 matchptr
->_size
= buf2
.st_size
;
418 matchptr
->_atime
= buf2
.st_atime
;
419 matchptr
->_mtime
= buf2
.st_mtime
;
420 matchptr
->_ctime
= buf2
.st_ctime
;
421 matchptr
->_links
= buf2
.st_nlink
;
422 #ifdef GET_ST_ATIME_NSEC
423 matchptr
->_ansec
= GET_ST_ATIME_NSEC(buf
);
425 #ifdef GET_ST_MTIME_NSEC
426 matchptr
->_mnsec
= GET_ST_MTIME_NSEC(buf
);
428 #ifdef GET_ST_CTIME_NSEC
429 matchptr
->_cnsec
= GET_ST_CTIME_NSEC(buf
);
434 if (++matchct
== matchsz
) {
435 matchbuf
= (Gmatch
)realloc((char *)matchbuf
,
436 sizeof(struct gmatch
) * (matchsz
*= 2));
438 matchptr
= matchbuf
+ matchct
;
446 /* Check to see if str is eligible for filename generation. */
452 /* `[' and `]' are legal even if bad patterns are usually not. */
453 if ((*str
== Inbrack
|| *str
== Outbrack
) && !str
[1])
456 /* If % is immediately followed by ?, then that ? is *
457 * not treated as a wildcard. This is so you don't have *
458 * to escape job references such as %?foo. */
459 if (str
[0] == '%' && str
[1] == Quest
)
462 for (; *str
; str
++) {
473 if (isset(EXTENDEDGLOB
))
481 /* Do the globbing: scanner is called recursively *
482 * with successive bits of the path until we've *
483 * tried all of it. */
491 int pbcwdsav
= pathbufcwd
;
492 int errssofar
= errsfound
;
497 ds
.dirfd
= ds
.level
= -1;
501 if ((closure
= q
->closure
)) {
502 /* (foo/)# - match zero or more dirs */
503 if (q
->closure
== 2) /* (foo/)## - match one or more dirs */
509 /* Now the actual matching for the current path section. */
510 if (p
->flags
& PAT_PURES
) {
512 * It's a straight string to the end of the path section.
514 char *str
= (char *)p
+ p
->startoff
;
517 if (l
+ !l
+ pathpos
- pathbufcwd
>= PATH_MAX
) {
522 err
= lchdir(pathbuf
+ pathbufcwd
, &ds
, 0);
526 zerr("current directory lost during glob");
529 pathbufcwd
= pathpos
;
532 /* Not the last path section. Just add it to the path. */
538 if (q
->closure
&& *pathbuf
) {
539 if (!strcmp(str
, "."))
541 else if (!strcmp(str
, "..")) {
544 add
= (stat("/", &sr
) || stat(pathbuf
, &sc
) ||
545 sr
.st_ino
!= sc
.st_ino
||
546 sr
.st_dev
!= sc
.st_dev
);
551 if (!closure
|| !statfullpath("", NULL
, 1))
552 scanner((q
->closure
) ? q
: q
->next
);
553 pathbuf
[pathpos
= oppos
] = '\0';
558 str
= dupstrpfx(str
, l
);
562 /* Do pattern matching on current path section. */
563 char *fn
= pathbuf
[pathbufcwd
] ? unmeta(pathbuf
+ pathbufcwd
) : ".";
564 int dirs
= !!q
->next
;
565 DIR *lock
= opendir(fn
);
566 char *subdirs
= NULL
;
571 while ((fn
= zreaddir(lock
, 1)) && !errflag
) {
572 /* prefix and suffix are zle trickery */
573 if (!dirs
&& !colonmod
&&
574 ((glob_pre
&& !strpfx(glob_pre
, fn
))
575 || (glob_suf
&& !strsfx(glob_suf
, fn
))))
577 errsfound
= errssofar
;
579 /* if this name matchs the pattern... */
580 if (pbcwdsav
== pathbufcwd
&&
581 strlen(fn
) + pathpos
- pathbufcwd
>= PATH_MAX
) {
584 DPUTS(pathpos
== pathbufcwd
,
585 "BUG: filename longer than PATH_MAX");
586 err
= lchdir(pathbuf
+ pathbufcwd
, &ds
, 0);
590 zerr("current directory lost during glob");
593 pathbufcwd
= pathpos
;
599 * If not the last component in the path:
601 * If we made an approximation in the new path segment,
602 * then it is possible we made too many errors. For
603 * example, (ab)#(cb)# will match the directory abcb
604 * with one error if allowed to, even though it can
605 * match with none. This will stop later parts of the
606 * path matching, so we need to check by reducing the
607 * maximum number of errors and seeing if the directory
608 * still matches. Luckily, this is not a terribly
609 * common case, since complex patterns typically occur
610 * in the last part of the path which is not affected
613 if (errsfound
> errssofar
) {
614 forceerrs
= errsfound
- 1;
615 while (forceerrs
>= errssofar
) {
616 errsfound
= errssofar
;
619 forceerrs
= errsfound
- 1;
621 errsfound
= forceerrs
+ 1;
625 /* if matching multiple directories */
628 if (statfullpath(fn
, &buf
, !q
->follow
)) {
629 if (errno
!= ENOENT
&& errno
!= EINTR
&&
630 errno
!= ENOTDIR
&& !errflag
) {
631 zwarn("%e: %s", errno
, fn
);
635 if (!S_ISDIR(buf
.st_mode
))
639 subdirs
= hrealloc(subdirs
, subdirlen
, subdirlen
+ l
641 strcpy(subdirs
+ subdirlen
, fn
);
643 /* store the count of errors made so far, too */
644 memcpy(subdirs
+ subdirlen
, (char *)&errsfound
,
646 subdirlen
+= sizeof(int);
648 /* if the last filename component, just add it */
656 for (fn
= subdirs
; fn
< subdirs
+subdirlen
; ) {
660 memcpy((char *)&errsfound
, fn
, sizeof(int));
662 scanner((q
->closure
) ? q
: q
->next
); /* scan next level */
663 pathbuf
[pathpos
= oppos
] = '\0';
665 hrealloc(subdirs
, subdirlen
, 0);
668 if (pbcwdsav
< pathbufcwd
) {
670 zerr("current directory lost during glob");
674 pathbufcwd
= pbcwdsav
;
678 /* This function tokenizes a zsh glob pattern */
682 parsecomplist(char *instr
)
687 int compflags
= gf_noglobdots
? (PAT_FILE
|PAT_NOGLD
) : PAT_FILE
;
689 if (instr
[0] == Star
&& instr
[1] == Star
&&
690 (instr
[2] == '/' || (instr
[2] == Star
&& instr
[3] == '/'))) {
691 /* Match any number of directories. */
694 /* with three stars, follow symbolic links */
695 follow
= (instr
[2] == Star
);
696 instr
+= (3 + follow
);
698 /* Now get the next path component if there is one. */
699 l1
= (Complist
) zhalloc(sizeof *l1
);
700 if ((l1
->next
= parsecomplist(instr
)) == NULL
) {
704 l1
->pat
= patcompile(NULL
, compflags
| PAT_ANY
, NULL
);
705 l1
->closure
= 1; /* ...zero or more times. */
710 /* Parse repeated directories such as (dir/)# and (dir/)## */
711 if (*(str
= instr
) == Inpar
&& !skipparens(Inpar
, Outpar
, (char **)&str
) &&
712 *str
== Pound
&& isset(EXTENDEDGLOB
) && str
[-2] == '/') {
714 if (!(p1
= patcompile(instr
, compflags
, &instr
)))
716 if (instr
[0] == '/' && instr
[1] == Outpar
&& instr
[2] == Pound
) {
720 if (*instr
== Pound
) {
724 l1
= (Complist
) zhalloc(sizeof *l1
);
726 l1
->closure
= 1 + pdflag
;
728 l1
->next
= parsecomplist(instr
);
729 return (l1
->pat
) ? l1
: NULL
;
732 /* parse single path component */
733 if (!(p1
= patcompile(instr
, compflags
|PAT_FILET
, &instr
)))
735 /* then do the remaining path components */
736 if (*instr
== '/' || !*instr
) {
737 int ef
= *instr
== '/';
739 l1
= (Complist
) zhalloc(sizeof *l1
);
742 l1
->next
= ef
? parsecomplist(instr
+1) : NULL
;
743 return (ef
&& !l1
->next
) ? NULL
: l1
;
750 /* turn a string into a Complist struct: this has path components */
761 * Check for initial globbing flags, so that they don't form
762 * a bogus path component.
764 if ((*str
== Inpar
&& str
[1] == Pound
&& isset(EXTENDEDGLOB
)) ||
765 (isset(KSHGLOB
) && *str
== '@' && str
[1] == Inpar
&&
767 str
+= (*str
== Inpar
) ? 2 : 3;
768 if (!patgetglobflags(&str
, &assert, &ignore
))
772 /* Now there is no (#X) in front, we can check the path. */
774 pathbuf
= zalloc(pathbufsz
= PATH_MAX
);
775 DPUTS(pathbufcwd
, "BUG: glob changed directory");
776 if (*str
== '/') { /* pattern has absolute path */
779 pathbuf
[pathpos
= 1] = '\0';
780 } else /* pattern is relative to pwd */
781 pathbuf
[pathpos
= 0] = '\0';
783 return parsecomplist(str
);
786 /* get number after qualifier */
795 zerr("number expected");
799 v
= v
* 10 + *(*s
)++ - '0';
803 /* get mode spec after qualifier */
807 qgetmodespec(char **s
)
809 zlong yes
= 0, no
= 0, val
, mask
, t
;
810 char *p
= *s
, c
, how
, end
;
812 if ((c
= *p
) == '=' || c
== Equals
|| c
== '+' || c
== '-' ||
813 c
== '?' || c
== Quest
|| (c
>= '0' && c
<= '7')) {
817 end
= (c
== '<' ? '>' :
820 (c
== Inang
? Outang
:
821 (c
== Inbrack
? Outbrack
:
822 (c
== Inbrace
? Outbrace
: c
))))));
827 while (((c
= *p
) == 'u' || c
== 'g' || c
== 'o' || c
== 'a') && end
) {
829 case 'o': mask
|= 01007; break;
830 case 'g': mask
|= 02070; break;
831 case 'u': mask
|= 04700; break;
832 case 'a': mask
|= 07777; break;
836 how
= ((c
== '+' || c
== '-') ? c
: '=');
837 if (c
== '+' || c
== '-' || c
== '=' || c
== Equals
)
841 while ((c
= *p
++) != ',' && c
!= end
) {
843 case 'x': val
|= 00111; break;
844 case 'w': val
|= 00222; break;
845 case 'r': val
|= 00444; break;
846 case 's': val
|= 06000; break;
847 case 't': val
|= 01000; break;
848 case '0': case '1': case '2': case '3':
849 case '4': case '5': case '6': case '7':
850 t
= ((zlong
) c
- '0');
851 val
|= t
| (t
<< 3) | (t
<< 6);
854 zerr("invalid mode specification");
858 if (how
== '=' || how
== '+') {
862 if (how
== '=' || how
== '-')
864 } else if (!(end
&& c
== end
) && c
!= ',' && c
) {
866 while ((c
= *p
) == '?' || c
== Quest
||
867 (c
>= '0' && c
<= '7')) {
868 if (c
== '?' || c
== Quest
) {
873 val
= (val
<< 3) | ((zlong
) c
- '0');
877 if (end
&& c
!= end
&& c
!= ',') {
878 zerr("invalid mode specification");
882 yes
= (yes
& ~t
) | val
;
883 no
= (no
& ~t
) | (~val
& ~t
);
884 } else if (how
== '+')
889 zerr("invalid mode specification");
892 } while (end
&& c
!= end
);
895 return ((yes
& 07777) | ((no
& 07777) << 12));
899 gmatchcmp(Gmatch a
, Gmatch b
)
904 char **asortstrp
= NULL
, **bsortstrp
= NULL
;
906 for (i
= gf_nsorts
, s
= gf_sortlist
; i
; i
--, s
++) {
907 switch (s
->tp
& ~GS_DESC
) {
909 r
= zstrcmp(b
->name
, a
->name
, gf_numsort
? SORTIT_NUMERICALLY
: 0);
913 char *aptr
= a
->name
, *bptr
= b
->name
;
914 int slasha
= 0, slashb
= 0;
915 /* Count slashes. Trailing slashes don't count. */
916 while (*aptr
&& *aptr
== *bptr
)
919 for (; aptr
[1]; aptr
++)
925 for (; bptr
[1]; bptr
++)
935 asortstrp
= a
->sortstrs
;
936 bsortstrp
= b
->sortstrs
;
941 r
= zstrcmp(*bsortstrp
, *asortstrp
,
942 gf_numsort
? SORTIT_NUMERICALLY
: 0);
945 r
= b
->size
- a
->size
;
948 r
= a
->atime
- b
->atime
;
949 #ifdef GET_ST_ATIME_NSEC
951 r
= a
->ansec
- b
->ansec
;
955 r
= a
->mtime
- b
->mtime
;
956 #ifdef GET_ST_MTIME_NSEC
958 r
= a
->mnsec
- b
->mnsec
;
962 r
= a
->ctime
- b
->ctime
;
963 #ifdef GET_ST_CTIME_NSEC
965 r
= a
->cnsec
- b
->cnsec
;
969 r
= b
->links
- a
->links
;
972 r
= b
->_size
- a
->_size
;
975 r
= a
->_atime
- b
->_atime
;
976 #ifdef GET_ST_ATIME_NSEC
978 r
= a
->_ansec
- b
->_ansec
;
982 r
= a
->_mtime
- b
->_mtime
;
983 #ifdef GET_ST_MTIME_NSEC
985 r
= a
->_mnsec
- b
->_mnsec
;
989 r
= a
->_ctime
- b
->_ctime
;
990 #ifdef GET_ST_CTIME_NSEC
992 r
= a
->_cnsec
- b
->_cnsec
;
996 r
= b
->_links
- a
->_links
;
1000 return (int) ((s
->tp
& GS_DESC
) ? -r
: r
);
1006 * Duplicate a list of qualifiers using the `next' linkage (not the
1007 * `or' linkage). Return the head element and set *last (if last non-NULL)
1008 * to point to the last element of the new list. All allocation is on the
1009 * heap (or off the heap?)
1011 static struct qual
*dup_qual_list(struct qual
*orig
, struct qual
**lastp
)
1013 struct qual
*qfirst
= NULL
, *qlast
= NULL
;
1016 struct qual
*qnew
= (struct qual
*)zhalloc(sizeof(struct qual
));
1018 qnew
->next
= qnew
->or = NULL
;
1036 * Get a glob string for execution, following e or + qualifiers.
1037 * Pointer is character after the e or +.
1042 glob_exec_string(char **sp
)
1044 char sav
, *tt
, *sdata
, *s
= *sp
;
1049 tt
= itype_end(s
, IIDENT
, 0);
1052 zerr("missing identifier after `+'");
1056 tt
= get_strarg(s
, &plus
);
1059 zerr("missing end of string");
1066 sdata
= dupstring(s
+ plus
);
1077 /* Main entry point to the globbing code for filename globbing. *
1078 * np points to a node in the list list which will be expanded *
1079 * into a series of nodes. */
1083 zglob(LinkList list
, LinkNode np
, int nountok
)
1085 struct qual
*qo
, *qn
, *ql
;
1086 LinkNode node
= prevnode(np
);
1087 char *str
; /* the pattern */
1088 int sl
; /* length of the pattern */
1089 Complist q
; /* pattern after parsing */
1090 char *ostr
= (char *)getdata(np
); /* the pattern before the parser */
1092 int first
= 0, end
= -1; /* index of first match to return */
1093 /* and index+1 of the last match */
1094 struct globdata saved
; /* saved glob state */
1095 int nobareglob
= !isset(BAREGLOBQUAL
);
1097 if (unset(GLOBOPT
) || !haswilds(ostr
)) {
1102 save_globstate(saved
);
1104 str
= dupstring(ostr
);
1107 /* quals will hold the complete list of qualifiers (file static). */
1110 * qualct and qualorct indicate we have qualifiers in the last
1111 * alternative, or a set of alternatives, respectively. They
1112 * are not necessarily an accurate count, however.
1114 qualct
= qualorct
= 0;
1116 * colonmod is a concatenated list of all colon modifiers found in
1117 * all sets of qualifiers.
1120 /* The gf_* flags are qualifiers which are applied globally. */
1121 gf_nullglob
= isset(NULLGLOB
);
1122 gf_markdirs
= isset(MARKDIRS
);
1123 gf_listtypes
= gf_follow
= 0;
1124 gf_noglobdots
= unset(GLOBDOTS
);
1125 gf_numsort
= isset(NUMERICGLOBSORT
);
1126 gf_sorts
= gf_nsorts
= 0;
1128 /* Check for qualifiers */
1129 while (!nobareglob
|| isset(EXTENDEDGLOB
)) {
1130 struct qual
*newquals
;
1134 char *sdata
, *newcolonmod
;
1135 int (*func
) _((char *, Statptr
, off_t
, char *));
1138 * Initialise state variables for current file pattern.
1139 * newquals is the root for the linked list of all qualifiers.
1140 * qo is the root of the current list of alternatives.
1141 * ql is the end of the current alternative where the `next' will go.
1142 * qn is the current qualifier node to be added.
1144 * Here is an attempt at a diagram. An `or' is added horizontally
1145 * to the top line, a `next' at the bottom of the right hand line.
1146 * `qn' is usually NULL unless a new `or' has just been added.
1148 * quals -> x -> x -> qo
1154 * In fact, after each loop the complete set is in the file static
1155 * `quals'. Then, if we have a second set of qualifiers, we merge
1156 * the lists together. This is only tricky if one or both have an
1157 * `or' in them; then we need to distribute over all alternatives.
1159 newquals
= qo
= qn
= ql
= NULL
;
1162 if (str
[sl
- 1] != Outpar
)
1165 /* Check these are really qualifiers, not a set of *
1166 * alternatives or exclusions. We can be more *
1167 * lenient with an explicit (#q) than with a bare *
1168 * set of qualifiers. */
1170 for (s
= str
+ sl
- 2; *s
&& (*s
!= Inpar
|| paren
); s
--) {
1173 paren
++; /*FALLTHROUGH*/
1178 if (isset(EXTENDEDGLOB
))
1188 if (isset(EXTENDEDGLOB
) && s
[1] == Pound
) {
1194 } else if (nobareglob
)
1197 /* Real qualifiers found. */
1199 sense
= 0; /* bit 0 for match (0)/don't match (1) */
1200 /* bit 1 for follow links (2), don't (0) */
1201 data
= 0; /* Any numerical argument required */
1202 sdata
= NULL
; /* Any list argument required */
1203 newcolonmod
= NULL
; /* Contains trailing colon modifiers */
1207 while (*s
&& !newcolonmod
) {
1208 func
= (int (*) _((char *, Statptr
, off_t
, char *)))0;
1210 /* Store numeric argument for qualifier */
1215 data
= data
* 010 + (*s
++ - '0');
1216 } else if (*s
== ',') {
1217 /* A comma separates alternative sets of qualifiers */
1221 qn
= (struct qual
*)hcalloc(sizeof *qn
);
1231 /* Remaining arguments are history-type *
1232 * colon substitutions, handled separately. */
1233 newcolonmod
= s
- 1;
1234 untokenize(newcolonmod
);
1236 /* remember we're searching backwards */
1237 colonmod
= dyncat(newcolonmod
, colonmod
);
1239 colonmod
= newcolonmod
;
1243 /* Toggle sense: go from positive to *
1244 * negative match and vice versa. */
1248 /* Toggle matching of symbolic links */
1252 /* Match symbolic links */
1261 /* Match named pipes */
1265 /* Match directories */
1269 /* Match regular files */
1273 /* Match special files: block, *
1274 * character or any device */
1276 s
++, func
= qualisblk
;
1278 s
++, func
= qualischr
;
1283 /* Match executable plain files */
1287 /* Match world-readable files */
1292 /* Match world-writeable files */
1297 /* Match world-executable files */
1314 /* Match files readable by current process */
1319 /* Match files writeable by current process */
1324 /* Match files executable by current process */
1329 /* Match setuid files */
1334 /* Match setgid files */
1343 /* Match device files by device number *
1344 * (as given by stat's st_dev element). */
1349 /* Match files with the given no. of hard links */
1354 /* Match files owned by effective user ID */
1359 /* Match files owned by effective group ID */
1364 /* Match files owned by given user id */
1366 /* either the actual uid... */
1370 /* ... or a user name */
1374 /* Find matching delimiters */
1375 tt
= get_strarg(s
, &arglen
);
1377 zerr("missing end of name");
1385 if ((pw
= getpwnam(s
+ arglen
)))
1388 zerr("unknown user");
1392 #else /* !USE_GETPWNAM */
1394 zerr("unknown user");
1396 #endif /* !USE_GETPWNAM */
1405 /* Given gid or group id... works like `u' */
1407 /* either the actual gid... */
1411 /* ...or a delimited group name. */
1415 tt
= get_strarg(s
, &arglen
);
1417 zerr("missing end of name");
1425 if ((gr
= getgrnam(s
+ arglen
)))
1428 zerr("unknown group");
1432 #else /* !USE_GETGRNAM */
1434 zerr("unknown group");
1436 #endif /* !USE_GETGRNAM */
1445 /* Match modes with chmod-spec. */
1446 func
= qualmodeflags
;
1447 data
= qgetmodespec(&s
);
1450 func
= qualnonemptydir
;
1453 /* Mark directories with a / */
1454 if ((gf_markdirs
= !(sense
& 1)))
1455 gf_follow
= sense
& 2;
1458 /* Mark types in a `ls -F' type fashion */
1459 if ((gf_listtypes
= !(sense
& 1)))
1460 gf_follow
= sense
& 2;
1463 /* Nullglob: remove unmatched patterns. */
1464 gf_nullglob
= !(sense
& 1);
1467 /* Glob dots: match leading dots implicitly */
1468 gf_noglobdots
= sense
& 1;
1471 /* Numeric glob sort */
1472 gf_numsort
= !(sense
& 1);
1475 /* Access time in given range */
1480 /* Modification time in given range */
1485 /* Inode creation time in given range */
1490 /* File size (Length) in given range */
1493 /* Get size multiplier */
1495 if (*s
== 'p' || *s
== 'P')
1496 g_units
= TT_POSIX_BLOCKS
, ++s
;
1497 else if (*s
== 'k' || *s
== 'K')
1498 g_units
= TT_KILOBYTES
, ++s
;
1499 else if (*s
== 'm' || *s
== 'M')
1500 g_units
= TT_MEGABYTES
, ++s
;
1502 /* Get time multiplier */
1506 g_units
= TT_HOURS
, ++s
;
1508 g_units
= TT_MINS
, ++s
;
1510 g_units
= TT_WEEKS
, ++s
;
1512 g_units
= TT_MONTHS
, ++s
;
1514 g_units
= TT_SECONDS
, ++s
;
1516 /* See if it's greater than, equal to, or less than */
1517 if ((g_range
= *s
== '+' ? 1 : *s
== '-' ? -1 : 0))
1528 if (gf_nsorts
== MAX_SORTS
) {
1529 zerr("too many glob sort specifiers");
1530 restore_globstate(saved
);
1534 /* usually just one character */
1537 case 'n': t
= GS_NAME
; break;
1538 case 'L': t
= GS_SIZE
; break;
1539 case 'l': t
= GS_LINKS
; break;
1540 case 'a': t
= GS_ATIME
; break;
1541 case 'm': t
= GS_MTIME
; break;
1542 case 'c': t
= GS_CTIME
; break;
1543 case 'd': t
= GS_DEPTH
; break;
1544 case 'N': t
= GS_NONE
; break;
1549 if ((gf_sortlist
[gf_nsorts
].exec
=
1550 glob_exec_string(&send
)) == NULL
)
1552 restore_globstate(saved
);
1558 zerr("unknown sort specifier");
1559 restore_globstate(saved
);
1563 if ((sense
& 2) && !(t
& (GS_NAME
|GS_DEPTH
)))
1564 t
<<= GS_SHIFT
; /* HERE: GS_EXEC? */
1566 zerr("doubled sort specifier");
1567 restore_globstate(saved
);
1572 gf_sortlist
[gf_nsorts
++].tp
= t
|
1573 (((sense
& 1) ^ (s
[-1] == 'O')) ? GS_DESC
: 0);
1582 tt
= glob_exec_string(&s
);
1598 v
.isarr
= SCANPM_WANTVALS
;
1602 if (getindex(&s
, &v
, 0) || s
== os
) {
1603 zerr("invalid subscript");
1604 restore_globstate(saved
);
1612 zerr("unknown file attribute");
1613 restore_globstate(saved
);
1618 /* Requested test is performed by function func */
1620 qn
= (struct qual
*)hcalloc(sizeof *qn
);
1630 qn
->range
= g_range
;
1631 qn
->units
= g_units
;
1638 restore_globstate(saved
);
1643 if (quals
&& newquals
) {
1644 /* Merge previous group of qualifiers with new set. */
1645 if (quals
->or || newquals
->or) {
1646 /* The hard case. */
1647 struct qual
*qorhead
= NULL
, *qortail
= NULL
;
1649 * Distribute in the most trivial way, by creating
1650 * all possible combinations of the two sets and chaining
1651 * these into one long set of alternatives given
1652 * by qorhead and qortail.
1654 for (qn
= newquals
; qn
; qn
= qn
->or) {
1655 for (qo
= quals
; qo
; qo
= qo
->or) {
1656 struct qual
*qfirst
, *qlast
;
1657 int islast
= !qn
->or && !qo
->or;
1658 /* Generate first set of qualifiers... */
1660 /* Last time round: don't bother copying. */
1662 for (qlast
= qfirst
; qlast
->next
;
1663 qlast
= qlast
->next
)
1666 qfirst
= dup_qual_list(qn
, &qlast
);
1667 /* ... link into new `or' chain ... */
1671 qortail
->or = qfirst
;
1673 /* ... and concatenate second set. */
1674 qlast
->next
= islast
? qo
: dup_qual_list(qo
, NULL
);
1680 * Easy: we can just chain the qualifiers together.
1681 * This is an optimisation; the code above will work, too.
1682 * We retain the original left to right ordering --- remember
1683 * we are searching for sets of qualifiers from the right.
1686 for ( ; newquals
->next
; newquals
= newquals
->next
)
1688 newquals
->next
= quals
;
1691 } else if (newquals
)
1695 if (!q
|| errflag
) { /* if parsing failed */
1696 restore_globstate(saved
);
1697 if (unset(BADPATTERN
)) {
1700 insertlinknode(list
, node
, ostr
);
1704 zerr("bad pattern: %s", ostr
);
1708 gf_sortlist
[0].tp
= gf_sorts
= GS_NAME
;
1711 /* Initialise receptacle for matched files, *
1712 * expanded by insert() where necessary. */
1713 matchptr
= matchbuf
= (Gmatch
)zalloc((matchsz
= 16) *
1714 sizeof(struct gmatch
));
1718 /* The actual processing takes place here: matches go into *
1719 * matchbuf. This is the only top-level call to scanner(). */
1722 /* Deal with failures to match depending on options */
1724 badcshglob
|= 2; /* at least one cmd. line expansion O.K. */
1725 else if (!gf_nullglob
) {
1726 if (isset(CSHNULLGLOB
)) {
1727 badcshglob
|= 1; /* at least one cmd. line expansion failed */
1728 } else if (isset(NOMATCH
)) {
1729 zerr("no matches found: %s", ostr
);
1731 restore_globstate(saved
);
1734 /* treat as an ordinary string */
1735 untokenize(matchptr
->name
= dupstring(ostr
));
1741 if (!(gf_sortlist
[0].tp
& GS_NONE
)) {
1743 * Get the strings to use for sorting by executing
1744 * the code chunk. We allow more than one of these.
1747 struct globsort
*sortp
;
1748 struct globsort
*lastsortp
= gf_sortlist
+ gf_nsorts
;
1750 /* First find out if there are any GS_EXECs, counting them. */
1751 for (sortp
= gf_sortlist
; sortp
< lastsortp
; sortp
++)
1753 if (sortp
->tp
& GS_EXEC
)
1761 /* Yes; allocate enough space for strings for each */
1762 for (tmpptr
= matchbuf
; tmpptr
< matchptr
; tmpptr
++)
1763 tmpptr
->sortstrs
= (char **)zhalloc(nexecs
*sizeof(char*));
1765 /* Loop over each one, incrementing iexec */
1766 for (sortp
= gf_sortlist
; sortp
< lastsortp
; sortp
++)
1768 /* Ignore unless this is a GS_EXEC */
1769 if (sortp
->tp
& GS_EXEC
) {
1772 if ((prog
= parse_string(sortp
->exec
, 0))) {
1773 int ef
= errflag
, lv
= lastval
, ret
;
1775 /* Parsed OK, execute for each name */
1776 for (tmpptr
= matchbuf
; tmpptr
< matchptr
; tmpptr
++) {
1777 setsparam("REPLY", ztrdup(tmpptr
->name
));
1778 execode(prog
, 1, 0);
1780 tmpptr
->sortstrs
[iexec
] =
1781 dupstring(getsparam("REPLY"));
1783 tmpptr
->sortstrs
[iexec
] = tmpptr
->name
;
1790 /* Failed, let's be safe */
1791 for (tmpptr
= matchbuf
; tmpptr
< matchptr
; tmpptr
++)
1792 tmpptr
->sortstrs
[iexec
] = tmpptr
->name
;
1800 /* Sort arguments in to lexical (and possibly numeric) order. *
1801 * This is reversed to facilitate insertion into the list. */
1802 qsort((void *) & matchbuf
[0], matchct
, sizeof(struct gmatch
),
1803 (int (*) _((const void *, const void *)))gmatchcmp
);
1813 else if (end
> matchct
)
1815 if ((end
-= first
) > 0) {
1816 if (gf_sortlist
[0].tp
& GS_NONE
) {
1817 /* Match list was never reversed, so insert back to front. */
1818 matchptr
= matchbuf
+ matchct
- first
- 1;
1820 /* insert matches in the arg list */
1821 insertlinknode(list
, node
, matchptr
->name
);
1825 matchptr
= matchbuf
+ matchct
- first
- end
;
1827 /* insert matches in the arg list */
1828 insertlinknode(list
, node
, matchptr
->name
);
1835 restore_globstate(saved
);
1838 /* Return the trailing character for marking file types */
1842 file_type(mode_t filemode
)
1844 if(S_ISBLK(filemode
))
1846 else if(S_ISCHR(filemode
))
1848 else if(S_ISDIR(filemode
))
1850 else if(S_ISFIFO(filemode
))
1852 else if(S_ISLNK(filemode
))
1854 else if(S_ISREG(filemode
))
1855 return (filemode
& S_IXUGO
) ? '*' : ' ';
1856 else if(S_ISSOCK(filemode
))
1862 /* check to see if str is eligible for brace expansion */
1866 hasbraces(char *str
)
1868 char *lbr
, *mbr
, *comma
;
1870 if (isset(BRACECCL
)) {
1871 /* In this case, any properly formed brace expression *
1872 * will match and expand to the characters in between. */
1875 for (bc
= 0; (c
= *str
); ++str
)
1877 if (!bc
&& str
[1] == Outbrace
)
1878 *str
++ = '{', *str
= '}';
1881 } else if (c
== Outbrace
) {
1889 /* Otherwise we need to look for... */
1890 lbr
= mbr
= comma
= NULL
;
1896 while (idigit(*str
))
1898 if (*str
== '.' && str
[1] == '.') {
1900 while (idigit(*++str
));
1901 if (*str
== Outbrace
&&
1902 (idigit(lbr
[1]) || idigit(str
[-1])))
1908 if (skipparens(Inbrace
, Outbrace
, &str
)) {
1912 if (mbr
&& mbr
< str
)
1914 lbr
= mbr
= comma
= NULL
;
1945 if (mbr
&& mbr
< str
)
1947 lbr
= mbr
= comma
= NULL
;
1953 /* expand stuff like >>*.c */
1957 xpandredir(struct redir
*fn
, LinkList tab
)
1964 /* Stick the name in a list... */
1965 init_list1(fake
, fn
->name
);
1966 /* ...which undergoes all the usual shell expansions */
1967 prefork(&fake
, isset(MULTIOS
) ? 0 : PF_SINGLE
);
1968 /* Globbing is only done for multios. */
1969 if (!errflag
&& isset(MULTIOS
))
1973 if (nonempty(&fake
) && !nextnode(firstnode(&fake
))) {
1974 /* Just one match, the usual case. */
1975 char *s
= peekfirst(&fake
);
1978 if (fn
->type
== REDIR_MERGEIN
|| fn
->type
== REDIR_MERGEOUT
) {
1979 if (s
[0] == '-' && !s
[1])
1980 fn
->type
= REDIR_CLOSE
;
1981 else if (s
[0] == 'p' && !s
[1])
1986 if (!*s
&& s
> fn
->name
)
1987 fn
->fd2
= zstrtol(fn
->name
, NULL
, 10);
1988 else if (fn
->type
== REDIR_MERGEIN
)
1989 zerr("file number expected");
1991 fn
->type
= REDIR_ERRWRITE
;
1994 } else if (fn
->type
== REDIR_MERGEIN
)
1995 zerr("file number expected");
1997 if (fn
->type
== REDIR_MERGEOUT
)
1998 fn
->type
= REDIR_ERRWRITE
;
1999 while ((nam
= (char *)ugetnode(&fake
))) {
2000 /* Loop over matches, duplicating the *
2001 * redirection for each file found. */
2002 ff
= (struct redir
*) zhalloc(sizeof *ff
);
2005 addlinknode(tab
, ff
);
2012 /* brace expansion */
2016 xpandbraces(LinkList list
, LinkNode
*np
)
2018 LinkNode node
= (*np
), last
= prevnode(node
);
2019 char *str
= (char *)getdata(node
), *str3
= str
, *str2
;
2020 int prev
, bc
, comma
, dotdot
;
2022 for (; *str
!= Inbrace
; str
++);
2023 /* First, match up braces and see what we have. */
2024 for (str2
= str
, bc
= comma
= dotdot
= 0; *str2
; ++str2
)
2025 if (*str2
== Inbrace
)
2027 else if (*str2
== Outbrace
) {
2030 } else if (bc
== 1) {
2032 ++comma
; /* we have {foo,bar} */
2033 else if (*str2
== '.' && str2
[1] == '.')
2034 dotdot
++; /* we have {num1..num2} */
2036 DPUTS(bc
, "BUG: unmatched brace in xpandbraces()");
2037 if (!comma
&& dotdot
) {
2038 /* Expand range like 0..10 numerically: comma or recursive
2039 brace expansion take precedence. */
2041 LinkNode olast
= last
;
2042 /* Get the first number of the range */
2043 int rstart
= zstrtol(str
+1,&dots
,10), rend
= 0, err
= 0, rev
= 0;
2044 int wid1
= (dots
- str
) - 1, wid2
= (str2
- dots
) - 2;
2045 int strp
= str
- str3
;
2047 if (dots
== str
+ 1 || *dots
!= '.' || dots
[1] != '.')
2050 /* Get the last number of the range */
2051 rend
= zstrtol(dots
+2,&p
,10);
2052 if (p
== dots
+2 || p
!= str2
)
2056 /* If either no. begins with a zero, pad the output with *
2057 * zeroes. Otherwise, choose a min width to suppress them. */
2058 int minw
= (str
[1] == '0') ? wid1
: (dots
[2] == '0' ) ? wid2
:
2059 (wid2
> wid1
) ? wid1
: wid2
;
2060 if (rstart
> rend
) {
2061 /* Handle decreasing ranges correctly. */
2067 uremnode(list
, node
);
2068 for (; rend
>= rstart
; rend
--) {
2069 /* Node added in at end, so do highest first */
2070 p
= dupstring(str3
);
2071 sprintf(p
+ strp
, "%0*d", minw
, rend
);
2072 strcat(p
+ strp
, str2
+ 1);
2073 insertlinknode(list
, last
, p
);
2074 if (rev
) /* decreasing: add in reverse order. */
2075 last
= nextnode(last
);
2077 *np
= nextnode(olast
);
2081 if (!comma
&& isset(BRACECCL
)) { /* {a-mnop} */
2082 /* Here we expand each character to a separate node, *
2083 * but also ranges of characters like a-m. ccl is a *
2084 * set of flags saying whether each character is present; *
2085 * the final list is in lexical order. */
2087 unsigned char c1
, c2
;
2088 unsigned int len
, pl
;
2091 uremnode(list
, node
);
2092 memset(ccl
, 0, sizeof(ccl
) / sizeof(ccl
[0]));
2093 for (p
= str
+ 1; p
< str2
;) {
2094 if (itok(c1
= *p
++))
2095 c1
= ztokens
[c1
- STOUC(Pound
)];
2096 if ((char) c1
== Meta
)
2099 c2
= ztokens
[c2
- STOUC(Pound
)];
2100 if ((char) c2
== Meta
)
2102 if (c1
== '-' && lastch
>= 0 && p
< str2
&& lastch
<= (int)c2
) {
2103 while (lastch
< (int)c2
)
2107 ccl
[lastch
= c1
] = 1;
2110 len
= pl
+ strlen(++str2
) + 2;
2111 for (p
= ccl
+ 256; p
-- > ccl
;)
2115 str
= hcalloc(len
+ 1);
2117 str
[pl
+1] = c1
^ 32;
2118 strcpy(str
+ pl
+ 2, str2
);
2122 strcpy(str
+ pl
+ 1, str2
);
2124 memcpy(str
, str3
, pl
);
2125 insertlinknode(list
, last
, str
);
2127 *np
= nextnode(last
);
2130 prev
= str
++ - str3
;
2132 uremnode(list
, node
);
2134 /* Finally, normal comma expansion *
2135 * str1{foo,bar}str2 -> str1foostr2 str1barstr2. *
2136 * Any number of intervening commas is allowed. */
2141 for (str4
= str
, cnt
= 0; cnt
|| (*str
!= Comma
&& *str
!=
2143 if (*str
== Inbrace
)
2145 else if (*str
== Outbrace
)
2147 DPUTS(!*str
, "BUG: illegal brace expansion");
2149 /* Concatenate the string before the braces (str3), the section *
2150 * just found (str4) and the text after the braces (str2) */
2151 zz
= (char *) hcalloc(prev
+ (str
- str4
) + strlen(str2
) + 1);
2152 ztrncpy(zz
, str3
, prev
);
2153 strncat(zz
, str4
, str
- str4
);
2155 /* and add this text to the argument list. */
2156 insertlinknode(list
, node
, zz
);
2158 if (*str
!= Outbrace
)
2163 *np
= nextnode(last
);
2166 /* check to see if a matches b (b is not a filename pattern) */
2170 matchpat(char *a
, char *b
)
2172 Patprog p
= patcompile(b
, PAT_STATIC
, NULL
);
2175 zerr("bad pattern: %s", b
);
2178 return pattry(p
, a
);
2181 /* do the ${foo%%bar}, ${foo#bar} stuff */
2182 /* please do not laugh at this code. */
2184 /* Having found a match in getmatch, decide what part of string
2185 * to return. The matched part starts b characters into string s
2186 * and finishes e characters in: 0 <= b <= e <= strlen(s)
2187 * (yes, empty matches should work).
2188 * fl is a set of the SUB_* matches defined in zsh.h from SUB_MATCH onwards;
2189 * the lower parts are ignored.
2190 * replstr is the replacement string for a substitution
2195 get_match_ret(char *s
, int b
, int e
, int fl
, char *replstr
,
2198 char buf
[80], *r
, *p
, *rr
;
2199 int ll
= 0, l
= strlen(s
), bl
= 0, t
= 0, i
;
2201 if (replstr
|| (fl
& SUB_LIST
)) {
2202 if (fl
& SUB_DOSUBST
) {
2203 replstr
= dupstring(replstr
);
2205 untokenize(replstr
);
2207 if ((fl
& (SUB_GLOBAL
|SUB_LIST
)) && repllist
) {
2208 /* We are replacing the chunk, just add this to the list */
2209 Repldata rd
= (Repldata
)
2210 ((fl
& SUB_LIST
) ? zalloc(sizeof(*rd
)) : zhalloc(sizeof(*rd
)));
2213 rd
->replstr
= replstr
;
2215 zaddlinknode(repllist
, rd
);
2217 addlinknode(repllist
, rd
);
2220 ll
+= strlen(replstr
);
2222 if (fl
& SUB_MATCH
) /* matched portion */
2224 if (fl
& SUB_REST
) /* unmatched portion */
2225 ll
+= 1 + (l
- (e
- b
));
2226 if (fl
& SUB_BIND
) {
2227 /* position of start of matched portion */
2228 sprintf(buf
, "%d ", b
+ 1);
2229 ll
+= (bl
= strlen(buf
));
2231 if (fl
& SUB_EIND
) {
2232 /* position of end of matched portion */
2233 sprintf(buf
+ bl
, "%d ", e
+ 1);
2234 ll
+= (bl
= strlen(buf
));
2237 /* length of matched portion */
2238 sprintf(buf
+ bl
, "%d ", e
- b
);
2239 ll
+= (bl
= strlen(buf
));
2244 rr
= r
= (char *) hcalloc(ll
);
2246 if (fl
& SUB_MATCH
) {
2247 /* copy matched portion to new buffer */
2248 for (i
= b
, p
= s
+ b
; i
< e
; i
++)
2252 if (fl
& SUB_REST
) {
2253 /* Copy unmatched portion to buffer. If both portions *
2254 * requested, put a space in between (why?) */
2257 /* there may be unmatched bits at both beginning and end of string */
2258 for (i
= 0, p
= s
; i
< b
; i
++)
2261 for (p
= replstr
; *p
; )
2263 for (i
= e
, p
= s
+ e
; i
< l
; i
++)
2269 /* if there was a buffer (with a numeric result), add it; *
2270 * if there was other stuff too, stick in a space first. */
2279 compgetmatch(char *pat
, int *flp
, char **replstrp
)
2283 * Flags to pattern compiler: use static buffer since we only
2284 * have one pattern at a time; we will try the must-match test ourselves,
2285 * so tell the pattern compiler we are scanning.
2288 /* int patflags = PAT_STATIC|PAT_SCAN|PAT_NOANCH;*/
2290 /* Unfortunately, PAT_STATIC doesn't work if we have a replstr with
2291 * something like ${x#...} in it which will be singsub()ed below because
2292 * that would overwrite the pattern buffer. */
2294 int patflags
= PAT_SCAN
|PAT_NOANCH
| (*replstrp
? 0 : PAT_STATIC
);
2297 * Search is anchored to the end of the string if we want to match
2298 * it all, or if we are matching at the end of the string and not
2301 if ((*flp
& SUB_ALL
) || ((*flp
& SUB_END
) && !(*flp
& SUB_SUBSTR
)))
2302 patflags
&= ~PAT_NOANCH
;
2303 p
= patcompile(pat
, patflags
, NULL
);
2305 zerr("bad pattern: %s", pat
);
2309 if (p
->patnpar
|| (p
->globend
& GF_MATCHREF
)) {
2311 * Either backreferences or match references, so we
2312 * need to re-substitute replstr each time round.
2314 *flp
|= SUB_DOSUBST
;
2317 untokenize(*replstrp
);
2325 * This is called from paramsubst to get the match for ${foo#bar} etc.
2326 * fl is a set of the SUB_* flags defined in zsh.h
2327 * *sp points to the string we have to modify. The n'th match will be
2328 * returned in *sp. The heap is used to get memory for the result string.
2329 * replstr is the replacement string from a ${.../orig/repl}, in
2330 * which case pat is the original.
2332 * n is now ignored unless we are looking for a substring, in
2333 * which case the n'th match from the start is counted such that
2334 * there is no more than one match from each position.
2339 getmatch(char **sp
, char *pat
, int fl
, int n
, char *replstr
)
2343 if (!(p
= compgetmatch(pat
, &fl
, &replstr
)))
2346 return igetmatch(sp
, p
, fl
, n
, replstr
, NULL
);
2350 * This is the corresponding function for array variables.
2351 * Matching is done with the same pattern on each element.
2356 getmatcharr(char ***ap
, char *pat
, int fl
, int n
, char *replstr
)
2358 char **arr
= *ap
, **pp
;
2361 if (!(p
= compgetmatch(pat
, &fl
, &replstr
)))
2364 *ap
= pp
= hcalloc(sizeof(char *) * (arrlen(arr
) + 1));
2365 while ((*pp
= *arr
++))
2366 if (igetmatch(pp
, p
, fl
, n
, replstr
, NULL
))
2371 * Match against str using pattern pp; return a list of
2372 * Repldata matches in the linked list *repllistp; this is
2373 * in permanent storage and to be freed by freematchlist()
2378 getmatchlist(char *str
, Patprog p
, LinkList
*repllistp
)
2383 * We don't care if we have longest or shortest match, but SUB_LONG
2384 * is cheaper since the pattern code does that by default.
2385 * We need SUB_GLOBAL to get all matches.
2386 * We need SUB_SUBSTR to scan through for substrings.
2387 * We need SUB_LIST to activate the special handling of the list
2390 return igetmatch(sp
, p
, SUB_LONG
|SUB_GLOBAL
|SUB_SUBSTR
|SUB_LIST
,
2391 0, NULL
, repllistp
);
2395 freerepldata(void *ptr
)
2397 zfree(ptr
, sizeof(struct repldata
));
2402 freematchlist(LinkList repllist
)
2404 freelinklist(repllist
, freerepldata
);
2409 set_pat_start(Patprog p
, int offs
)
2412 * If we are messing around with the test string by advancing up
2413 * it from the start, we need to tell the pattern matcher that
2414 * a start-of-string assertion, i.e. (#s), should fail. Hence
2415 * we test whether the offset of the real start of string from
2416 * the actual start, passed as offs, is zero.
2419 p
->flags
|= PAT_NOTSTART
;
2421 p
->flags
&= ~PAT_NOTSTART
;
2426 set_pat_end(Patprog p
, char null_me
)
2429 * If we are messing around with the string by shortening it at the
2430 * tail, we need to tell the pattern matcher that an end-of-string
2431 * assertion, i.e. (#e), should fail. Hence we test whether
2432 * the character null_me about to be zapped is or is not already a null.
2435 p
->flags
|= PAT_NOTEND
;
2437 p
->flags
&= ~PAT_NOTEND
;
2441 #ifdef MULTIBYTE_SUPPORT
2444 * Increment *tp over character which may be multibyte.
2445 * Return number of bytes that remain in the character after unmetafication.
2449 static int iincchar(char **tp
)
2452 int mbclen
= mb_metacharlenconv(t
, NULL
);
2469 igetmatch(char **sp
, Patprog p
, int fl
, int n
, char *replstr
,
2470 LinkList
*repllistp
)
2472 char *s
= *sp
, *t
, *tmatch
;
2474 * Note that ioff counts (possibly multibyte) characters in the
2475 * character set (Meta's are not included), while l counts characters in
2476 * the metafied string.
2478 * umlen is a counter for (unmetafied) byte lengths---neither characters
2479 * nor raw byte indices; this is simply an optimisation for allocation.
2480 * umltot is the full length of the string in this scheme.
2482 * l is the raw string length, used together with any pointers into
2483 * the string (typically t).
2485 int ioff
, l
= strlen(*sp
), matched
= 1, umltot
= ztrlen(*sp
);
2486 int umlen
, nmatches
;
2488 * List of bits of matches to concatenate with replacement string.
2489 * The data is a struct repldata. It is not used in cases like
2490 * ${...//#foo/bar} even though SUB_GLOBAL is set, since the match
2491 * is anchored. It goes on the heap.
2493 LinkList repllist
= NULL
;
2495 /* perform must-match test for complex closures */
2499 * Yuk. Probably we should rewrite this whole function to
2500 * use an unmetafied test string.
2502 * Use META_HEAPDUP because we need a terminating NULL.
2504 char *muststr
= metafy((char *)p
+ p
->mustoff
,
2505 p
->patmlen
, META_HEAPDUP
);
2507 if (!strstr(s
, muststr
))
2511 /* in case we used the prog before... */
2512 p
->flags
&= ~(PAT_NOTSTART
|PAT_NOTEND
);
2515 int i
= matched
&& pattry(p
, s
);
2516 *sp
= get_match_ret(*sp
, 0, i
? l
: 0, fl
, i
? replstr
: 0, NULL
);
2517 if (! **sp
&& (((fl
& SUB_MATCH
) && !i
) || ((fl
& SUB_REST
) && i
)))
2523 * The default behaviour is to match at the start; this
2524 * is modified by SUB_END and SUB_SUBSTR. SUB_END matches
2525 * at the end of the string instead of the start. SUB_SUBSTR
2526 * without SUB_END matches substrings searching from the start;
2527 * with SUB_END it matches substrings searching from the end.
2529 * The possibilities are further modified by whether we want the
2530 * longest (SUB_LONG) or shortest possible match.
2532 * SUB_START is only used in the case where we are also
2533 * forcing a match at the end (SUB_END with no SUB_SUBSTR,
2534 * with or without SUB_LONG), to indicate we should match
2535 * the entire string.
2537 switch (fl
& (SUB_END
|SUB_LONG
|SUB_SUBSTR
)) {
2541 * Largest/smallest possible match at head of string.
2542 * First get the longest match...
2545 /* patmatchlen returns metafied length, as we need */
2546 int mlen
= patmatchlen();
2547 if (!(fl
& SUB_LONG
) && !(p
->flags
& PAT_PURES
)) {
2549 * ... now we know whether it's worth looking for the
2550 * shortest, which we do by brute force.
2553 for (t
= s
, umlen
= 0; t
< s
+ mlen
; ) {
2555 if (pattrylen(p
, s
, t
- s
, umlen
, 0)) {
2556 mlen
= patmatchlen();
2559 umlen
+= iincchar(&t
);
2562 *sp
= get_match_ret(*sp
, 0, mlen
, fl
, replstr
, NULL
);
2569 * Smallest possible match at tail of string.
2570 * As we can only be sure we've got wide characters right
2571 * when going forwards, we need to match at every point
2572 * until we fail and record the last successful match.
2574 * It's important that we return the last successful match
2575 * so that match, mbegin, mend and MATCH, MBEGIN, MEND are
2580 for (ioff
= 0, t
= s
, umlen
= umltot
; t
< s
+ l
; ioff
++) {
2581 set_pat_start(p
, t
-s
);
2582 if (pattrylen(p
, t
, s
+ l
- t
, umlen
, ioff
))
2586 umlen
-= iincchar(&t
);
2589 *sp
= get_match_ret(*sp
, tmatch
- s
, l
, fl
, replstr
, NULL
);
2592 if (!(fl
& SUB_START
) && pattrylen(p
, s
+ l
, 0, 0, ioff
)) {
2593 *sp
= get_match_ret(*sp
, l
, l
, fl
, replstr
, NULL
);
2598 case (SUB_END
|SUB_LONG
):
2599 /* Largest possible match at tail of string: *
2600 * move forward along string until we get a match. *
2601 * Again there's no optimisation. */
2603 for (ioff
= 0, t
= s
, umlen
= umltot
; t
< s
+ l
; ioff
++) {
2604 set_pat_start(p
, t
-s
);
2605 if (pattrylen(p
, t
, s
+ l
- t
, umlen
, ioff
)) {
2606 *sp
= get_match_ret(*sp
, t
-s
, l
, fl
, replstr
, NULL
);
2611 umlen
-= iincchar(&t
);
2613 if (!(fl
& SUB_START
) && pattrylen(p
, s
+ l
, 0, 0, ioff
)) {
2614 *sp
= get_match_ret(*sp
, l
, l
, fl
, replstr
, NULL
);
2620 /* Smallest at start, but matching substrings. */
2621 set_pat_start(p
, l
);
2622 if (!(fl
& SUB_GLOBAL
) && pattry(p
, s
+ l
) && !--n
) {
2623 *sp
= get_match_ret(*sp
, 0, 0, fl
, replstr
, NULL
);
2625 } /* fall through */
2626 case (SUB_SUBSTR
|SUB_LONG
):
2627 /* longest or smallest at start with substrings */
2629 if (fl
& SUB_GLOBAL
) {
2630 repllist
= (fl
& SUB_LIST
) ? znewlinklist() : newlinklist();
2632 *repllistp
= repllist
;
2634 ioff
= 0; /* offset into string */
2638 /* loop over all matches for global substitution */
2640 for (; t
< s
+ l
; ioff
++) {
2641 /* Find the longest match from this position. */
2642 set_pat_start(p
, t
-s
);
2643 if (pattrylen(p
, t
, s
+ l
- t
, umlen
, ioff
)) {
2644 char *mpos
= t
+ patmatchlen();
2645 if (!(fl
& SUB_LONG
) && !(p
->flags
& PAT_PURES
)) {
2649 * If searching for the shortest match,
2650 * start with a zero length and increase
2651 * it until we reach the longest possible
2652 * match, accepting the first successful
2655 for (ptr
= t
, umlen2
= 0; ptr
< mpos
;) {
2656 set_pat_end(p
, *ptr
);
2657 if (pattrylen(p
, t
, ptr
- t
, umlen2
, ioff
)) {
2658 mpos
= t
+ patmatchlen();
2661 umlen2
+= iincchar(&ptr
);
2664 if (!--n
|| (n
<= 0 && (fl
& SUB_GLOBAL
))) {
2665 *sp
= get_match_ret(*sp
, t
-s
, mpos
-s
, fl
,
2668 mpos
+= mb_metacharlenconv(mpos
, NULL
);
2670 if (!(fl
& SUB_GLOBAL
)) {
2673 * Looking for a later match: in this case,
2674 * we can continue looking for matches from
2675 * the next character, even if it overlaps
2676 * with what we just found.
2678 umlen
-= iincchar(&t
);
2685 * For a global match, we need to skip the stuff
2686 * which is already marked for replacement.
2691 umlen
-= iincchar(&t
);
2695 umlen
-= iincchar(&t
);
2699 * check if we can match a blank string, if so do it
2700 * at the start. Goodness knows if this is a good idea
2701 * with global substitution, so it doesn't happen.
2703 set_pat_start(p
, l
);
2704 if ((fl
& (SUB_LONG
|SUB_GLOBAL
)) == SUB_LONG
&&
2705 pattry(p
, s
+ l
) && !--n
) {
2706 *sp
= get_match_ret(*sp
, 0, 0, fl
, replstr
, repllist
);
2711 case (SUB_END
|SUB_SUBSTR
):
2712 case (SUB_END
|SUB_LONG
|SUB_SUBSTR
):
2713 /* Longest/shortest at end, matching substrings. */
2714 if (!(fl
& SUB_LONG
)) {
2715 set_pat_start(p
, l
);
2716 if (pattrylen(p
, s
+ l
, 0, 0, umltot
) && !--n
) {
2717 *sp
= get_match_ret(*sp
, l
, l
, fl
, replstr
, NULL
);
2722 * If multibyte characters are present we need to start from the
2723 * beginning. This is a bit unpleasant because we can't tell in
2724 * advance how many times it will match and from where, so if n is
2725 * greater then 1 we will need to count the number of times it
2726 * matched and then go through again until we reach the right
2727 * point. (Either that or record every single match in a list,
2728 * which isn't stupid; it involves more memory management at this
2729 * level but less use of the pattern matcher.)
2734 for (ioff
= 0, t
= s
, umlen
= umltot
; t
< s
+ l
; ioff
++) {
2735 set_pat_start(p
, t
-s
);
2736 if (pattrylen(p
, t
, s
+ l
- t
, umlen
, ioff
)) {
2740 umlen
-= iincchar(&t
);
2746 * We need to find the n'th last match.
2750 for (ioff
= 0, t
= s
, umlen
= umltot
; t
< s
+ l
; ioff
++) {
2751 set_pat_start(p
, t
-s
);
2752 if (pattrylen(p
, t
, s
+ l
- t
, umlen
, ioff
) &&
2757 umlen
-= iincchar(&t
);
2760 mpos
= tmatch
+ patmatchlen();
2761 /* Look for the shortest match if necessary */
2762 if (!(fl
& SUB_LONG
) && !(p
->flags
& PAT_PURES
)) {
2763 for (t
= tmatch
, umlen
= 0; t
< mpos
; ) {
2765 if (pattrylen(p
, tmatch
, t
- tmatch
, umlen
, ioff
)) {
2766 mpos
= tmatch
+ patmatchlen();
2769 umlen
+= iincchar(&t
);
2772 *sp
= get_match_ret(*sp
, tmatch
-s
, mpos
-s
, fl
,
2776 set_pat_start(p
, l
);
2777 if ((fl
& SUB_LONG
) && pattrylen(p
, s
+ l
, 0, 0, umltot
) && !--n
) {
2778 *sp
= get_match_ret(*sp
, l
, l
, fl
, replstr
, NULL
);
2785 if (repllist
&& nonempty(repllist
)) {
2786 /* Put all the bits of a global search and replace together. */
2793 if (!(fl
& SUB_LIST
)) {
2794 lleft
= 0; /* size of returned string */
2795 i
= 0; /* start of last chunk we got from *sp */
2796 for (nd
= firstnode(repllist
); nd
; incnode(nd
)) {
2797 rd
= (Repldata
) getdata(nd
);
2798 lleft
+= rd
->b
- i
; /* previous chunk of *sp */
2799 lleft
+= strlen(rd
->replstr
); /* the replaced bit */
2800 i
= rd
->e
; /* start of next chunk of *sp */
2802 lleft
+= l
- i
; /* final chunk from *sp */
2803 start
= t
= zhalloc(lleft
+1);
2805 for (nd
= firstnode(repllist
); nd
; incnode(nd
)) {
2806 rd
= (Repldata
) getdata(nd
);
2807 memcpy(t
, s
+ i
, rd
->b
- i
);
2814 memcpy(t
, s
+ i
, l
- i
);
2815 start
[lleft
] = '\0';
2816 *sp
= (char *)start
;
2820 if (fl
& SUB_LIST
) /* safety: don't think this can happen */
2823 /* munge the whole string: no match, so no replstr */
2824 *sp
= get_match_ret(*sp
, 0, 0, fl
, 0, 0);
2825 return (fl
& SUB_RETFAIL
) ? 0 : 1;
2832 * Increment pointer which may be on a Meta (x is a pointer variable),
2833 * returning the incremented value (i.e. like pre-increment).
2835 #define METAINC(x) ((x) += (*(x) == Meta) ? 2 : 1)
2839 igetmatch(char **sp
, Patprog p
, int fl
, int n
, char *replstr
,
2840 LinkList
*repllistp
)
2844 * Note that ioff and uml count characters in the character
2845 * set (Meta's are not included), while l counts characters in the
2846 * metafied string. umlen is a counter for (unmetafied) character
2849 int ioff
, l
= strlen(*sp
), uml
= ztrlen(*sp
), matched
= 1, umlen
;
2851 * List of bits of matches to concatenate with replacement string.
2852 * The data is a struct repldata. It is not used in cases like
2853 * ${...//#foo/bar} even though SUB_GLOBAL is set, since the match
2854 * is anchored. It goes on the heap.
2856 LinkList repllist
= NULL
;
2858 /* perform must-match test for complex closures */
2862 * Yuk. Probably we should rewrite this whole function to
2863 * use an unmetafied test string.
2865 * Use META_HEAPDUP because we need a terminating NULL.
2867 char *muststr
= metafy((char *)p
+ p
->mustoff
,
2868 p
->patmlen
, META_HEAPDUP
);
2870 if (!strstr(s
, muststr
))
2874 /* in case we used the prog before... */
2875 p
->flags
&= ~(PAT_NOTSTART
|PAT_NOTEND
);
2878 int i
= matched
&& pattry(p
, s
);
2879 *sp
= get_match_ret(*sp
, 0, i
? l
: 0, fl
, i
? replstr
: 0, NULL
);
2880 if (! **sp
&& (((fl
& SUB_MATCH
) && !i
) || ((fl
& SUB_REST
) && i
)))
2885 switch (fl
& (SUB_END
|SUB_LONG
|SUB_SUBSTR
)) {
2889 * Largest/smallest possible match at head of string.
2890 * First get the longest match...
2893 /* patmatchlen returns metafied length, as we need */
2894 int mlen
= patmatchlen();
2895 if (!(fl
& SUB_LONG
) && !(p
->flags
& PAT_PURES
)) {
2897 * ... now we know whether it's worth looking for the
2898 * shortest, which we do by brute force.
2900 for (t
= s
, umlen
= 0; t
< s
+ mlen
; METAINC(t
), umlen
++) {
2902 if (pattrylen(p
, s
, t
- s
, umlen
, 0)) {
2903 mlen
= patmatchlen();
2908 *sp
= get_match_ret(*sp
, 0, mlen
, fl
, replstr
, NULL
);
2914 /* Smallest possible match at tail of string: *
2915 * move back down string until we get a match. *
2916 * There's no optimization here. */
2917 for (ioff
= uml
, t
= s
+ l
, umlen
= 0; t
>= s
;
2918 t
--, ioff
--, umlen
++) {
2919 if (t
> s
&& t
[-1] == Meta
)
2921 set_pat_start(p
, t
-s
);
2922 if (pattrylen(p
, t
, s
+ l
- t
, umlen
, ioff
)) {
2923 *sp
= get_match_ret(*sp
, t
- s
, l
, fl
, replstr
, NULL
);
2926 if (t
> s
+1 && t
[-2] == Meta
)
2931 case (SUB_END
|SUB_LONG
):
2932 /* Largest possible match at tail of string: *
2933 * move forward along string until we get a match. *
2934 * Again there's no optimisation. */
2935 for (ioff
= 0, t
= s
, umlen
= uml
; t
< s
+ l
;
2936 ioff
++, METAINC(t
), umlen
--) {
2937 set_pat_start(p
, t
-s
);
2938 if (pattrylen(p
, t
, s
+ l
- t
, umlen
, ioff
)) {
2939 *sp
= get_match_ret(*sp
, t
-s
, l
, fl
, replstr
, NULL
);
2948 /* Smallest at start, but matching substrings. */
2949 set_pat_start(p
, l
);
2950 if (!(fl
& SUB_GLOBAL
) && pattry(p
, s
+ l
) && !--n
) {
2951 *sp
= get_match_ret(*sp
, 0, 0, fl
, replstr
, NULL
);
2953 } /* fall through */
2954 case (SUB_SUBSTR
|SUB_LONG
):
2955 /* longest or smallest at start with substrings */
2957 if (fl
& SUB_GLOBAL
) {
2958 repllist
= newlinklist();
2960 *repllistp
= repllist
;
2962 ioff
= 0; /* offset into string */
2965 /* loop over all matches for global substitution */
2967 for (; t
< s
+ l
; METAINC(t
), ioff
++, umlen
--) {
2968 /* Find the longest match from this position. */
2969 set_pat_start(p
, t
-s
);
2970 if (pattrylen(p
, t
, s
+ l
- t
, umlen
, ioff
)) {
2971 char *mpos
= t
+ patmatchlen();
2972 if (!(fl
& SUB_LONG
) && !(p
->flags
& PAT_PURES
)) {
2975 for (ptr
= t
, umlen2
= 0; ptr
< mpos
;
2976 METAINC(ptr
), umlen2
++) {
2977 set_pat_end(p
, *ptr
);
2978 if (pattrylen(p
, t
, ptr
- t
, umlen2
, ioff
)) {
2979 mpos
= t
+ patmatchlen();
2984 if (!--n
|| (n
<= 0 && (fl
& SUB_GLOBAL
))) {
2985 *sp
= get_match_ret(*sp
, t
-s
, mpos
-s
, fl
,
2990 if (!(fl
& SUB_GLOBAL
)) {
2993 * Looking for a later match: in this case,
2994 * we can continue looking for matches from
2995 * the next character, even if it overlaps
2996 * with what we just found.
3004 * For a global match, we need to skip the stuff
3005 * which is already marked for replacement.
3008 for ( ; t
< mpos
; t
++, ioff
++, umlen
--)
3018 * check if we can match a blank string, if so do it
3019 * at the start. Goodness knows if this is a good idea
3020 * with global substitution, so it doesn't happen.
3022 set_pat_start(p
, l
);
3023 if ((fl
& (SUB_LONG
|SUB_GLOBAL
)) == SUB_LONG
&&
3024 pattry(p
, s
+ l
) && !--n
) {
3025 *sp
= get_match_ret(*sp
, 0, 0, fl
, replstr
, repllist
);
3030 case (SUB_END
|SUB_SUBSTR
):
3031 case (SUB_END
|SUB_LONG
|SUB_SUBSTR
):
3032 /* Longest/shortest at end, matching substrings. */
3033 if (!(fl
& SUB_LONG
)) {
3034 set_pat_start(p
, l
);
3035 if (pattrylen(p
, s
+ l
, 0, 0, uml
) && !--n
) {
3036 *sp
= get_match_ret(*sp
, l
, l
, fl
, replstr
, NULL
);
3040 for (ioff
= uml
- 1, t
= s
+ l
- 1, umlen
= 1; t
>= s
;
3041 t
--, ioff
--, umlen
++) {
3042 if (t
> s
&& t
[-1] == Meta
)
3044 set_pat_start(p
, t
-s
);
3045 if (pattrylen(p
, t
, s
+ l
- t
, umlen
, ioff
) && !--n
) {
3046 /* Found the longest match */
3047 char *mpos
= t
+ patmatchlen();
3048 if (!(fl
& SUB_LONG
) && !(p
->flags
& PAT_PURES
)) {
3051 for (ptr
= t
, umlen2
= 0; ptr
< mpos
;
3052 METAINC(ptr
), umlen2
++) {
3053 set_pat_end(p
, *ptr
);
3054 if (pattrylen(p
, t
, ptr
- t
, umlen2
, ioff
)) {
3055 mpos
= t
+ patmatchlen();
3060 *sp
= get_match_ret(*sp
, t
-s
, mpos
-s
, fl
,
3065 set_pat_start(p
, l
);
3066 if ((fl
& SUB_LONG
) && pattrylen(p
, s
+ l
, 0, 0, uml
) && !--n
) {
3067 *sp
= get_match_ret(*sp
, l
, l
, fl
, replstr
, NULL
);
3074 if (repllist
&& nonempty(repllist
)) {
3075 /* Put all the bits of a global search and replace together. */
3078 int lleft
= 0; /* size of returned string */
3082 i
= 0; /* start of last chunk we got from *sp */
3083 for (nd
= firstnode(repllist
); nd
; incnode(nd
)) {
3084 rd
= (Repldata
) getdata(nd
);
3085 lleft
+= rd
->b
- i
; /* previous chunk of *sp */
3086 lleft
+= strlen(rd
->replstr
); /* the replaced bit */
3087 i
= rd
->e
; /* start of next chunk of *sp */
3089 lleft
+= l
- i
; /* final chunk from *sp */
3090 start
= t
= zhalloc(lleft
+1);
3092 for (nd
= firstnode(repllist
); nd
; incnode(nd
)) {
3093 rd
= (Repldata
) getdata(nd
);
3094 memcpy(t
, s
+ i
, rd
->b
- i
);
3101 memcpy(t
, s
+ i
, l
- i
);
3102 start
[lleft
] = '\0';
3103 *sp
= (char *)start
;
3107 /* munge the whole string: no match, so no replstr */
3108 *sp
= get_match_ret(*sp
, 0, 0, fl
, 0, 0);
3113 #endif /* MULTIBYTE_SUPPORT */
3115 /* blindly turn a string into a tokenised expression without lexing */
3125 * shtokenize is used when we tokenize a string with GLOB_SUBST set.
3126 * In that case we need to retain backslashes when we turn the
3127 * pattern back into a string, so that the string is not
3128 * modified if it failed to match a pattern.
3130 * It may be modified by the effect of SH_GLOB which turns off
3131 * various zsh-specific options.
3138 int flags
= ZSHTOK_SUBST
;
3140 flags
|= ZSHTOK_SHGLOB
;
3141 zshtokenize(s
, flags
);
3146 zshtokenize(char *s
, int flags
)
3158 s
[-1] = (flags
& ZSHTOK_SUBST
) ? Bnullkeep
: Bnull
;
3164 if (flags
& ZSHTOK_SHGLOB
)
3167 s
[-1] = (flags
& ZSHTOK_SUBST
) ? Bnullkeep
: Bnull
;
3171 while (idigit(*++s
));
3174 while (idigit(*++s
));
3183 if (flags
& ZSHTOK_SHGLOB
)
3194 for (t
= ztokens
; *t
; t
++)
3197 s
[-1] = (flags
& ZSHTOK_SUBST
) ? Bnullkeep
: Bnull
;
3199 *s
= (t
- ztokens
) + Pound
;
3207 /* remove unnecessary Nulargs */
3217 if (c
== Bnullkeep
) {
3219 * An active backslash that needs to be turned back into
3220 * a real backslash for output. However, we don't
3221 * do that yet since we need to ignore it during
3225 } else if (inull(c
)) {
3228 while ((c
= *s
++)) {
3244 /* qualifier functions: mostly self-explanatory, see glob(). */
3250 qualdev(UNUSED(char *name
), struct stat
*buf
, off_t dv
, UNUSED(char *dummy
))
3252 return (off_t
)buf
->st_dev
== dv
;
3255 /* number of hard links to file */
3259 qualnlink(UNUSED(char *name
), struct stat
*buf
, off_t ct
, UNUSED(char *dummy
))
3261 return (g_range
< 0 ? buf
->st_nlink
< ct
:
3262 g_range
> 0 ? buf
->st_nlink
> ct
:
3263 buf
->st_nlink
== ct
);
3270 qualuid(UNUSED(char *name
), struct stat
*buf
, off_t uid
, UNUSED(char *dummy
))
3272 return buf
->st_uid
== uid
;
3279 qualgid(UNUSED(char *name
), struct stat
*buf
, off_t gid
, UNUSED(char *dummy
))
3281 return buf
->st_gid
== gid
;
3284 /* device special file? */
3288 qualisdev(UNUSED(char *name
), struct stat
*buf
, UNUSED(off_t junk
), UNUSED(char *dummy
))
3290 return S_ISBLK(buf
->st_mode
) || S_ISCHR(buf
->st_mode
);
3293 /* block special file? */
3297 qualisblk(UNUSED(char *name
), struct stat
*buf
, UNUSED(off_t junk
), UNUSED(char *dummy
))
3299 return S_ISBLK(buf
->st_mode
);
3302 /* character special file? */
3306 qualischr(UNUSED(char *name
), struct stat
*buf
, UNUSED(off_t junk
), UNUSED(char *dummy
))
3308 return S_ISCHR(buf
->st_mode
);
3315 qualisdir(UNUSED(char *name
), struct stat
*buf
, UNUSED(off_t junk
), UNUSED(char *dummy
))
3317 return S_ISDIR(buf
->st_mode
);
3324 qualisfifo(UNUSED(char *name
), struct stat
*buf
, UNUSED(off_t junk
), UNUSED(char *dummy
))
3326 return S_ISFIFO(buf
->st_mode
);
3329 /* symbolic link? */
3333 qualislnk(UNUSED(char *name
), struct stat
*buf
, UNUSED(off_t junk
), UNUSED(char *dummy
))
3335 return S_ISLNK(buf
->st_mode
);
3342 qualisreg(UNUSED(char *name
), struct stat
*buf
, UNUSED(off_t junk
), UNUSED(char *dummy
))
3344 return S_ISREG(buf
->st_mode
);
3351 qualissock(UNUSED(char *name
), struct stat
*buf
, UNUSED(off_t junk
), UNUSED(char *dummy
))
3353 return S_ISSOCK(buf
->st_mode
);
3356 /* given flag is set in mode */
3360 qualflags(UNUSED(char *name
), struct stat
*buf
, off_t mod
, UNUSED(char *dummy
))
3362 return mode_to_octal(buf
->st_mode
) & mod
;
3365 /* mode matches specification */
3369 qualmodeflags(UNUSED(char *name
), struct stat
*buf
, off_t mod
, UNUSED(char *dummy
))
3371 long v
= mode_to_octal(buf
->st_mode
), y
= mod
& 07777, n
= mod
>> 12;
3373 return ((v
& y
) == y
&& !(v
& n
));
3376 /* regular executable file? */
3380 qualiscom(UNUSED(char *name
), struct stat
*buf
, UNUSED(off_t mod
), UNUSED(char *dummy
))
3382 return S_ISREG(buf
->st_mode
) && (buf
->st_mode
& S_IXUGO
);
3385 /* size in required range? */
3389 qualsize(UNUSED(char *name
), struct stat
*buf
, off_t size
, UNUSED(char *dummy
))
3391 #if defined(LONG_IS_64_BIT) || defined(OFF_T_IS_64_BIT)
3392 # define QS_CAST_SIZE()
3393 off_t scaled
= buf
->st_size
;
3395 # define QS_CAST_SIZE() (unsigned long)
3396 unsigned long scaled
= (unsigned long)buf
->st_size
;
3400 case TT_POSIX_BLOCKS
:
3414 return (g_range
< 0 ? scaled
< QS_CAST_SIZE() size
:
3415 g_range
> 0 ? scaled
> QS_CAST_SIZE() size
:
3416 scaled
== QS_CAST_SIZE() size
);
3420 /* time in required range? */
3424 qualtime(UNUSED(char *name
), struct stat
*buf
, off_t days
, UNUSED(char *dummy
))
3429 diff
= now
- (g_amc
== 0 ? buf
->st_atime
: g_amc
== 1 ? buf
->st_mtime
:
3431 /* handle multipliers indicating units */
3450 return (g_range
< 0 ? diff
< days
:
3451 g_range
> 0 ? diff
> days
:
3455 /* evaluate a string */
3459 qualsheval(char *name
, UNUSED(struct stat
*buf
), UNUSED(off_t days
), char *str
)
3463 if ((prog
= parse_string(str
, 0))) {
3464 int ef
= errflag
, lv
= lastval
, ret
;
3466 unsetparam("reply");
3467 setsparam("REPLY", ztrdup(name
));
3469 execode(prog
, 1, 0);
3475 if (!(inserts
= getaparam("reply")) &&
3476 !(inserts
= gethparam("reply"))) {
3479 if ((tmp
= getsparam("reply")) || (tmp
= getsparam("REPLY"))) {
3480 static char *tmparr
[2];
3495 qualnonemptydir(char *name
, struct stat
*buf
, UNUSED(off_t days
), UNUSED(char *str
))
3500 char *uname
= unmetafy(dupstring(name
), &unamelen
);
3502 if (!S_ISDIR(buf
->st_mode
))
3505 if (buf
->st_nlink
> 2)
3508 if (!(dirh
= opendir(uname
)))
3511 while ((de
= readdir(dirh
))) {
3512 if (strcmp(de
->d_name
, ".") && strcmp(de
->d_name
, "..")) {