From: Sven Wischnowsky <wischnow@informatik.hu-berlin.de>
To: zsh-workers@sunsite.auc.dk
Subject: Re: PATCH: Re: Files modified after a given date
Date: Fri, 27 Aug 1999 10:13:51 +0200 (MET DST) [thread overview]
Message-ID: <199908270813.KAA17331@beta.informatik.hu-berlin.de> (raw)
In-Reply-To: Zefram's message of Thu, 26 Aug 1999 13:27:29 +0100 (BST)
Zefram wrote:
> Sven Wischnowsky wrote:
> >;-) I first tried to implement it that way, but then... No, we can't
> >do it that way because as soon as something is executed $_ gets set
> >from exec.c to the last command word, as usual. And then it's too late
> >to get at the filname.
>
> Hmm. Probably better to put it in $1 then. Actually, execute the code
> as if it were the body of a shell function.
I couldn't convince myself to do that, so I just turned `REPLY' into
an in/out parameter (initially set to the filename and after the execution the
value is used as before).
Most of this patch is to save/restore the global globbing state,
though (in case the string or a function called from it does itself
some globbing).
Bye
Sven
diff -u os/glob.c Src/glob.c
--- os/glob.c Thu Aug 26 13:36:26 1999
+++ Src/glob.c Fri Aug 27 10:03:29 1999
@@ -82,14 +82,6 @@
/**/
char *pathbuf; /* pathname buffer (needed by pattern code) */
-static int matchsz; /* size of matchbuf */
-static int matchct; /* number of matches found */
-static int pathbufsz; /* size of pathbuf */
-static int pathbufcwd; /* where did we chdir()'ed */
-static Gmatch matchbuf; /* array of matches */
-static Gmatch matchptr; /* &matchbuf[matchct] */
-static char *colonmod; /* colon modifiers in qualifier list */
-
typedef struct stat *Statptr; /* This makes the Ultrix compiler happy. Go figure. */
/* modifier for unit conversions */
@@ -121,20 +113,86 @@
char *sdata; /* currently only: expression to eval */
};
-/* Qualifiers pertaining to current pattern */
-static struct qual *quals;
-
-/* Other state values for current pattern */
-static int qualct, qualorct;
-static int range, amc, units;
-static int gf_nullglob, gf_markdirs, gf_noglobdots, gf_listtypes, gf_follow;
-static int gf_sorts, gf_nsorts, gf_sortlist[11];
-
/* Prefix, suffix for doing zle trickery */
/**/
char *glob_pre, *glob_suf;
+/* struct to easily save/restore current state */
+
+struct globdata {
+ int gd_badcshglob;
+ int gd_pathpos;
+ char *gd_pathbuf;
+
+ int gd_matchsz; /* size of matchbuf */
+ int gd_matchct; /* number of matches found */
+ int gd_pathbufsz; /* size of pathbuf */
+ int gd_pathbufcwd; /* where did we chdir()'ed */
+ Gmatch gd_matchbuf; /* array of matches */
+ Gmatch gd_matchptr; /* &matchbuf[matchct] */
+ char *gd_colonmod; /* colon modifiers in qualifier list */
+
+ /* Qualifiers pertaining to current pattern */
+ struct qual *gd_quals;
+
+ /* Other state values for current pattern */
+ int gd_qualct, gd_qualorct;
+ int gd_range, gd_amc, gd_units;
+ int gd_gf_nullglob, gd_gf_markdirs, gd_gf_noglobdots, gd_gf_listtypes;
+ int gd_gf_follow, gd_gf_sorts, gd_gf_nsorts, gd_gf_sortlist[11];
+
+ char *gd_glob_pre, *gd_glob_suf;
+};
+
+/* The variable with the current globbing state and convenience macros */
+
+static struct globdata curglobdata;
+
+#define matchsz (curglobdata.gd_matchsz)
+#define matchct (curglobdata.gd_matchct)
+#define pathbufsz (curglobdata.gd_pathbufsz)
+#define pathbufcwd (curglobdata.gd_pathbufcwd)
+#define matchbuf (curglobdata.gd_matchbuf)
+#define matchptr (curglobdata.gd_matchptr)
+#define colonmod (curglobdata.gd_colonmod)
+#define quals (curglobdata.gd_quals)
+#define qualct (curglobdata.gd_qualct)
+#define qualorct (curglobdata.gd_qualorct)
+#define g_range (curglobdata.gd_range)
+#define g_amc (curglobdata.gd_amc)
+#define g_units (curglobdata.gd_units)
+#define gf_nullglob (curglobdata.gd_gf_nullglob)
+#define gf_markdirs (curglobdata.gd_gf_markdirs)
+#define gf_noglobdots (curglobdata.gd_gf_noglobdots)
+#define gf_listtypes (curglobdata.gd_gf_listtypes)
+#define gf_follow (curglobdata.gd_gf_follow)
+#define gf_sorts (curglobdata.gd_gf_sorts)
+#define gf_nsorts (curglobdata.gd_gf_nsorts)
+#define gf_sortlist (curglobdata.gd_gf_sortlist)
+
+/* and macros for save/restore */
+
+#define save_globstate(N) \
+ do { \
+ memcpy(&(N), &curglobdata, sizeof(struct globdata)); \
+ (N).gd_badcshglob = badcshglob; \
+ (N).gd_pathpos = pathpos; \
+ (N).gd_pathbuf = pathbuf; \
+ (N).gd_glob_pre = glob_pre; \
+ (N).gd_glob_suf = glob_suf; \
+ } while (0)
+
+#define restore_globstate(N) \
+ do { \
+ memcpy(&curglobdata, &(N), sizeof(struct globdata)); \
+ badcshglob = (N).gd_badcshglob; \
+ pathpos = (N).gd_pathpos; \
+ pathbuf = (N).gd_pathbuf; \
+ glob_pre = (N).gd_glob_pre; \
+ glob_suf = (N).gd_glob_suf; \
+ } while (0)
+
/* pathname component in filename patterns */
struct complist {
@@ -250,9 +308,9 @@
statted = 1;
qo = quals;
for (qn = qo; qn && qn->func;) {
- range = qn->range;
- amc = qn->amc;
- units = qn->units;
+ g_range = qn->range;
+ g_amc = qn->amc;
+ g_units = qn->units;
if ((qn->sense & 2) && !(statted & 2)) {
/* If (sense & 2), we're following links */
if (!S_ISLNK(buf.st_mode) || statfullpath(s, &buf2, 0))
@@ -819,11 +877,15 @@
/* chops it up */
int first = 0, last = -1; /* index of first/last match to */
/* return */
+ struct globdata saved; /* saved glob state */
+
MUSTUSEHEAP("glob");
if (unset(GLOBOPT) || !haswilds(ostr)) {
untokenize(ostr);
return;
}
+ save_globstate(saved);
+
str = dupstring(ostr);
sl = strlen(str);
uremnode(list, np);
@@ -997,7 +1059,7 @@
case 'l':
/* Match files with the given no. of hard links */
func = qualnlink;
- amc = -1;
+ g_amc = -1;
goto getrange;
case 'U':
/* Match files owned by effective user ID */
@@ -1115,48 +1177,48 @@
break;
case 'a':
/* Access time in given range */
- amc = 0;
+ g_amc = 0;
func = qualtime;
goto getrange;
case 'm':
/* Modification time in given range */
- amc = 1;
+ g_amc = 1;
func = qualtime;
goto getrange;
case 'c':
/* Inode creation time in given range */
- amc = 2;
+ g_amc = 2;
func = qualtime;
goto getrange;
case 'L':
/* File size (Length) in given range */
func = qualsize;
- amc = -1;
+ g_amc = -1;
/* Get size multiplier */
- units = TT_BYTES;
+ g_units = TT_BYTES;
if (*s == 'p' || *s == 'P')
- units = TT_POSIX_BLOCKS, ++s;
+ g_units = TT_POSIX_BLOCKS, ++s;
else if (*s == 'k' || *s == 'K')
- units = TT_KILOBYTES, ++s;
+ g_units = TT_KILOBYTES, ++s;
else if (*s == 'm' || *s == 'M')
- units = TT_MEGABYTES, ++s;
+ g_units = TT_MEGABYTES, ++s;
getrange:
/* Get time multiplier */
- if (amc >= 0) {
- units = TT_DAYS;
+ if (g_amc >= 0) {
+ g_units = TT_DAYS;
if (*s == 'h')
- units = TT_HOURS, ++s;
+ g_units = TT_HOURS, ++s;
else if (*s == 'm')
- units = TT_MINS, ++s;
+ g_units = TT_MINS, ++s;
else if (*s == 'w')
- units = TT_WEEKS, ++s;
+ g_units = TT_WEEKS, ++s;
else if (*s == 'M')
- units = TT_MONTHS, ++s;
+ g_units = TT_MONTHS, ++s;
else if (*s == 's')
- units = TT_SECONDS, ++s;
+ g_units = TT_SECONDS, ++s;
}
/* See if it's greater than, equal to, or less than */
- if ((range = *s == '+' ? 1 : *s == '-' ? -1 : 0))
+ if ((g_range = *s == '+' ? 1 : *s == '-' ? -1 : 0))
++s;
data = qgetnum(&s);
break;
@@ -1175,12 +1237,14 @@
case 'c': t = GS_CTIME; break;
default:
zerr("unknown sort specifier", NULL, 0);
+ restore_globstate(saved);
return;
}
if ((sense & 2) && t != GS_NAME)
t <<= GS_SHIFT;
if (gf_sorts & t) {
zerr("doubled sort specifier", NULL, 0);
+ restore_globstate(saved);
return;
}
gf_sorts |= t;
@@ -1202,16 +1266,11 @@
func = qualsheval;
sdata = dupstring(s + 1);
untokenize(sdata);
- if (!parsestr(sdata)) {
- *tt = sav;
- if (sav)
- s = tt + 1;
- else
- s = tt;
- } else {
- func = NULL;
- sdata = NULL;
- }
+ *tt = sav;
+ if (sav)
+ s = tt + 1;
+ else
+ s = tt;
}
break;
}
@@ -1227,6 +1286,7 @@
v.inv = 0;
if (getindex(&s, &v) || s == os) {
zerr("invalid subscript", NULL, 0);
+ restore_globstate(saved);
return;
}
first = v.a;
@@ -1235,6 +1295,7 @@
}
default:
zerr("unknown file attribute", NULL, 0);
+ restore_globstate(saved);
return;
}
if (func) {
@@ -1250,19 +1311,22 @@
qn->sense = sense;
qn->data = data;
qn->sdata = sdata;
- qn->range = range;
- qn->units = units;
- qn->amc = amc;
+ qn->range = g_range;
+ qn->units = g_units;
+ qn->amc = g_amc;
qn = NULL;
qualct++;
}
- if (errflag)
+ if (errflag) {
+ restore_globstate(saved);
return;
+ }
}
}
}
q = parsepat(str);
if (!q || errflag) { /* if parsing failed */
+ restore_globstate(saved);
if (unset(BADPATTERN)) {
untokenize(ostr);
insertlinknode(list, node, ostr);
@@ -1326,6 +1390,8 @@
}
}
free(matchbuf);
+
+ restore_globstate(saved);
}
/* Return the order of two strings, taking into account *
@@ -2234,8 +2300,8 @@
static int
qualnlink(char *name, struct stat *buf, off_t ct, char *dummy)
{
- return (range < 0 ? buf->st_nlink < ct :
- range > 0 ? buf->st_nlink > ct :
+ return (g_range < 0 ? buf->st_nlink < ct :
+ g_range > 0 ? buf->st_nlink > ct :
buf->st_nlink == ct);
}
@@ -2372,7 +2438,7 @@
unsigned long scaled = (unsigned long)buf->st_size;
#endif
- switch (units) {
+ switch (g_units) {
case TT_POSIX_BLOCKS:
scaled += 511l;
scaled /= 512l;
@@ -2387,8 +2453,8 @@
break;
}
- return (range < 0 ? scaled < QS_CAST_SIZE() size :
- range > 0 ? scaled > QS_CAST_SIZE() size :
+ return (g_range < 0 ? scaled < QS_CAST_SIZE() size :
+ g_range > 0 ? scaled > QS_CAST_SIZE() size :
scaled == QS_CAST_SIZE() size);
#undef QS_CAST_SIZE
}
@@ -2402,10 +2468,10 @@
time_t now, diff;
time(&now);
- diff = now - (amc == 0 ? buf->st_atime : amc == 1 ? buf->st_mtime :
+ diff = now - (g_amc == 0 ? buf->st_atime : g_amc == 1 ? buf->st_mtime :
buf->st_ctime);
/* handle multipliers indicating units */
- switch (units) {
+ switch (g_units) {
case TT_DAYS:
diff /= 86400l;
break;
@@ -2423,8 +2489,8 @@
break;
}
- return (range < 0 ? diff < days :
- range > 0 ? diff > days :
+ return (g_range < 0 ? diff < days :
+ g_range > 0 ? diff > days :
diff == days);
}
@@ -2435,19 +2501,12 @@
qualsheval(char *name, struct stat *buf, off_t days, char *str)
{
List list;
- char *usav = underscore;
-
- underscore = name;
- str = dupstring(str);
- singsub(&str);
- underscore = usav;
- untokenize(str);
if ((list = parse_string(str, 0))) {
int ef = errflag, lv = lastval, ret;
unsetparam("reply");
- unsetparam("REPLY");
+ setsparam("REPLY", ztrdup(name));
execlist(list, 1, 0);
diff -u od/Zsh/expn.yo Doc/Zsh/expn.yo
--- od/Zsh/expn.yo Thu Aug 26 13:36:20 1999
+++ Doc/Zsh/expn.yo Fri Aug 27 10:10:21 1999
@@ -1384,17 +1384,16 @@
separator and anything up to the next matching separator will be taken
as the var(string) (`tt([)', `tt({)', and `tt(<)' match `tt(])',
`tt(})', and `tt(>)' respectively, any other character matches
-itself). Before the string is executed, expansion is performed on it
-with the parameter tt($_) being set to the filename currently being
-tested. Note that parameter expansions in the var(string) have to be
-quoted to prevent them from being expanded before globbing is done.
+itself). Note that expansions have to be quoted in the var(string) to
+prevent them from being expanded before globbing is done.
-If during the execution of var(string) the parameter tt(reply) is set
-to an array or to a string or if the parameter tt(REPLY) is set to a
-string, then these strings will be inserted into the generated list
-instead of the original filename. For security reasons, these
-parameters will be unset by the shell before the var(string) is
-executed.
+During the execution of var(string) the parameter tt(REPLY) is set to
+the filename currently being tested. It may also be set to any string
+to make this string be inserted into the list instead of the original
+filename. Also, the parameter tt(reply) may be set to an array or a
+string and if it is, these strings will be inserted instead of the
+value of the tt(REPLY) parameter. For security reasons, tt(reply)
+will be unset by the shell before the var(string) is executed.
)
item(tt(d)var(dev))(
files on the device var(dev)
--
Sven Wischnowsky wischnow@informatik.hu-berlin.de
next reply other threads:[~1999-08-27 8:16 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
1999-08-27 8:13 Sven Wischnowsky [this message]
1999-08-27 22:39 ` Ollivier Robert
-- strict thread matches above, loose matches on Subject: below --
1999-08-30 9:10 Sven Wischnowsky
1999-08-26 12:16 Sven Wischnowsky
1999-08-26 12:27 ` Zefram
1999-08-26 11:35 Sven Wischnowsky
1999-08-26 12:05 ` Zefram
1999-08-30 13:17 ` Peter Stephenson
1999-08-26 9:42 Sven Wischnowsky
1999-08-26 9:58 ` Zefram
1999-08-26 7:08 Sven Wischnowsky
1999-08-30 13:09 ` Peter Stephenson
1999-08-25 14:20 Sven Wischnowsky
1999-08-25 15:04 ` Bart Schaefer
1999-08-26 7:07 ` Andrej Borsenkow
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=199908270813.KAA17331@beta.informatik.hu-berlin.de \
--to=wischnow@informatik.hu-berlin.de \
--cc=zsh-workers@sunsite.auc.dk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.vuxu.org/mirror/zsh/
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).