zsh-workers
 help / color / mirror / code / Atom feed
* PATCH: Re: Files modified after a given date
@ 1999-08-25 14:20 Sven Wischnowsky
  1999-08-25 15:04 ` Bart Schaefer
  1999-08-26  7:07 ` Andrej Borsenkow
  0 siblings, 2 replies; 15+ messages in thread
From: Sven Wischnowsky @ 1999-08-25 14:20 UTC (permalink / raw)
  To: zsh-workers


Zefram wrote:

> Bruce Stephens wrote:
> >You could write a function using the stat module, but I don't think we
> >have user-defined glob patterns yet?
> 
> That's one of the many things I never got round to.  I was going to
> have patterns like "*(F:func:)" call the shell function "func" with the
> name of each file which otherwise matches the glob pattern, and use its
> return value to decide whether it matches or not.  Should be quite easy
> to implement -- just a few lines.

(I just needed some fun after the bug-hunting...)

This is a not-so-simple implementation (although most of this patch is 
re-indentation and changing the argument lists of the qualifier
functions).

First of all it allows the `*(F:func:)' Zefram mentioned. The function 
will get the filename as its first argument and the return value says
if the name should be included (ir it is zero, of course).

But it also allows one to give additional arguments as in
`*(F:func::arg1::arg2:)' and so on -- these are available as `$2'
etc. in the function. And finally it allows the function to say *what* 
should be included by setting the `reply' or `REPLY' parameter to a
string or array (`REPLY' is only tested for a string value). For
security reasons these are unset by the shell before the function is
called, but we could change that if you prefer.


(Maybe this is going a bit too far?)

Bye
 Sven

diff -u os/exec.c Src/exec.c
--- os/exec.c	Tue Aug 24 14:16:38 1999
+++ Src/exec.c	Tue Aug 24 16:11:36 1999
@@ -1799,8 +1799,11 @@
 	is_exec = 1;
     }
 
-    if (args && !(cflags & BINF_NOGLOB))
+    if (args && !(cflags & BINF_NOGLOB)) {
+	LinkList oargs = args;
 	globlist(args);
+	args=oargs;
+    }
     if (errflag) {
 	lastval = 1;
 	goto err;
diff -u os/glob.c Src/glob.c
--- os/glob.c	Fri Aug 20 15:18:07 1999
+++ Src/glob.c	Wed Aug 25 16:14:01 1999
@@ -106,7 +106,8 @@
 #define TT_KILOBYTES 2
 #define TT_MEGABYTES 3
 
-typedef int (*TestMatchFunc) _((struct stat *, off_t));
+
+typedef int (*TestMatchFunc) _((char *, struct stat *, off_t, LinkList));
 
 struct qual {
     struct qual *next;		/* Next qualifier, must match                */
@@ -117,6 +118,7 @@
     int amc;			/* Flag for which time to test (a, m, c)     */
     int range;			/* Whether to test <, > or = (as per signum) */
     int units;			/* Multiplier for time or size, respectively */
+    LinkList ldata;		/* currently only: shell function to call    */
 };
 
 /* Qualifiers pertaining to current pattern */
@@ -197,6 +199,11 @@
     return l ? lstat(buf, st) : stat(buf, st);
 }
 
+/* This may be set by qualifier functions to an array of strings to insert
+ * into the list instead of the original string. */
+
+char **inserts;
+
 /* add a match to the list */
 
 /**/
@@ -207,6 +214,8 @@
     char *news = s;
     int statted = 0;
 
+    inserts = NULL;
+
     if (gf_listtypes || gf_markdirs) {
 	/* Add the type marker to the end of the filename */
 	mode_t mode;
@@ -235,6 +244,9 @@
 
 	if (!statted && statfullpath(s, &buf, 1))
 	    return;
+
+	news = dyncat(pathbuf, news);
+
 	statted = 1;
 	qo = quals;
 	for (qn = qo; qn && qn->func;) {
@@ -251,7 +263,7 @@
 	    /* Reject the file if the function returned zero *
 	     * and the sense was positive (sense&1 == 0), or *
 	     * vice versa.                                   */
-	    if ((!((qn->func) (bp, qn->data)) ^ qn->sense) & 1) {
+	    if ((!((qn->func) (news, bp, qn->data, qn->ldata)) ^ qn->sense) & 1) {
 		/* Try next alternative, or return if there are no more */
 		if (!(qo = qo->or))
 		    return;
@@ -264,47 +276,53 @@
 	if (statfullpath(s, NULL, 1))
 	    return;
 	statted = 1;
-    }
-    news = dyncat(pathbuf, news);
-    if (colonmod) {
-	/* Handle the remainder of the qualifer:  e.g. (:r:s/foo/bar/). */
-	s = colonmod;
-	modify(&news, &s);
-    }
-    if (!statted && (gf_sorts & GS_NORMAL)) {
-	statfullpath(s, &buf, 1);
-	statted = 1;
-    }
-    if (!(statted & 2) && (gf_sorts & GS_LINKED)) {
-	if (statted) {
-	    if (!S_ISLNK(buf.st_mode) || statfullpath(s, &buf2, 0))
-		memcpy(&buf2, &buf, sizeof(buf));
-	} else if (statfullpath(s, &buf2, 0))
-	    statfullpath(s, &buf2, 1);
-	statted |= 2;
-    }
-    matchptr->name = news;
-    if (statted & 1) {
-	matchptr->size = buf.st_size;
-	matchptr->atime = buf.st_atime;
-	matchptr->mtime = buf.st_mtime;
-	matchptr->ctime = buf.st_ctime;
-	matchptr->links = buf.st_nlink;
-    }
-    if (statted & 2) {
-	matchptr->_size = buf2.st_size;
-	matchptr->_atime = buf2.st_atime;
-	matchptr->_mtime = buf2.st_mtime;
-	matchptr->_ctime = buf2.st_ctime;
-	matchptr->_links = buf2.st_nlink;
-    }
-    matchptr++;
-
-    if (++matchct == matchsz) {
-	matchbuf = (Gmatch )realloc((char *)matchbuf,
-				    sizeof(struct gmatch) * (matchsz *= 2));
+	news = dyncat(pathbuf, news);
+    } else
+	news = dyncat(pathbuf, news);
+
+    while (!inserts || (news = dupstring(*inserts++))) {
+	if (colonmod) {
+	    /* Handle the remainder of the qualifer:  e.g. (:r:s/foo/bar/). */
+	    s = colonmod;
+	    modify(&news, &s);
+	}
+	if (!statted && (gf_sorts & GS_NORMAL)) {
+	    statfullpath(s, &buf, 1);
+	    statted = 1;
+	}
+	if (!(statted & 2) && (gf_sorts & GS_LINKED)) {
+	    if (statted) {
+		if (!S_ISLNK(buf.st_mode) || statfullpath(s, &buf2, 0))
+		    memcpy(&buf2, &buf, sizeof(buf));
+	    } else if (statfullpath(s, &buf2, 0))
+		statfullpath(s, &buf2, 1);
+	    statted |= 2;
+	}
+	matchptr->name = news;
+	if (statted & 1) {
+	    matchptr->size = buf.st_size;
+	    matchptr->atime = buf.st_atime;
+	    matchptr->mtime = buf.st_mtime;
+	    matchptr->ctime = buf.st_ctime;
+	    matchptr->links = buf.st_nlink;
+	}
+	if (statted & 2) {
+	    matchptr->_size = buf2.st_size;
+	    matchptr->_atime = buf2.st_atime;
+	    matchptr->_mtime = buf2.st_mtime;
+	    matchptr->_ctime = buf2.st_ctime;
+	    matchptr->_links = buf2.st_nlink;
+	}
+	matchptr++;
+
+	if (++matchct == matchsz) {
+	    matchbuf = (Gmatch )realloc((char *)matchbuf,
+					sizeof(struct gmatch) * (matchsz *= 2));
 
-	matchptr = matchbuf + matchct;
+	    matchptr = matchbuf + matchct;
+	}
+	if (!inserts)
+	    break;
     }
 }
 
@@ -832,19 +850,21 @@
 		break;
 	if (*s == Inpar && (!isset(EXTENDEDGLOB) || s[1] != Pound)) {
 	    /* Real qualifiers found. */
-	    int sense = 0;	/* bit 0 for match (0)/don't match (1)   */
-				/* bit 1 for follow links (2), don't (0) */
-	    off_t data = 0;	/* Any numerical argument required       */
-	    int (*func) _((Statptr, off_t));
+	    int sense = 0;	   /* bit 0 for match (0)/don't match (1)   */
+				   /* bit 1 for follow links (2), don't (0) */
+	    off_t data = 0;	   /* Any numerical argument required       */
+	    LinkList ldata = NULL; /* Any list argument required            */
+	    int (*func) _((char *, Statptr, off_t, LinkList));
 
 	    str[sl-1] = 0;
 	    *s++ = 0;
 	    while (*s && !colonmod) {
-		func = (int (*) _((Statptr, off_t)))0;
+		func = (int (*) _((char *, Statptr, off_t, LinkList)))0;
 		if (idigit(*s)) {
 		    /* Store numeric argument for qualifier */
 		    func = qualflags;
 		    data = 0;
+		    ldata = NULL;
 		    while (idigit(*s))
 			data = data * 010 + (*s++ - '0');
 		} else if (*s == ',') {
@@ -1169,6 +1189,48 @@
 			    s++;
 			    break;
 			}
+		    case 'F':
+			{
+			    char sav, *tt = get_strarg(s);
+
+			    if (!*tt) {
+				zerr("missing end of function name", NULL, 0);
+				data = 0;
+			    } else {
+				char sep = *s;
+
+				sav = *tt;
+				*tt = '\0';
+				func = qualshfunc;
+				ldata = newlinklist();
+				addlinknode(ldata, dupstring(s + 1));
+				addlinknode(ldata, NULL);
+				*tt = sav;
+				if (sav)
+				    s = tt + 1;
+				else
+				    s = tt;
+				while (*s == sep) {
+				    tt = get_strarg(s);
+				    if (!*tt) {
+					zerr("missing end of argument", NULL, 0);
+					data = 0;
+					ldata = NULL;
+					break;
+				    } else {
+					sav = *tt;
+					*tt = '\0';
+					addlinknode(ldata, dupstring(s + 1));
+					*tt = sav;
+					if (sav)
+					    s = tt + 1;
+					else
+					    s = tt;
+				    }
+				}
+			    }
+			    break;
+			}
 		    case '[':
 		    case Inbrack:
 			{
@@ -1203,6 +1265,7 @@
 		    qn->func = func;
 		    qn->sense = sense;
 		    qn->data = data;
+		    qn->ldata = ldata;
 		    qn->range = range;
 		    qn->units = units;
 		    qn->amc = amc;
@@ -2176,7 +2239,7 @@
 
 /**/
 static int
-qualdev(struct stat *buf, off_t dv)
+qualdev(char *name, struct stat *buf, off_t dv, LinkList dummy)
 {
     return buf->st_dev == dv;
 }
@@ -2185,7 +2248,7 @@
 
 /**/
 static int
-qualnlink(struct stat *buf, off_t ct)
+qualnlink(char *name, struct stat *buf, off_t ct, LinkList dummy)
 {
     return (range < 0 ? buf->st_nlink < ct :
 	    range > 0 ? buf->st_nlink > ct :
@@ -2196,7 +2259,7 @@
 
 /**/
 static int
-qualuid(struct stat *buf, off_t uid)
+qualuid(char *name, struct stat *buf, off_t uid, LinkList dummy)
 {
     return buf->st_uid == uid;
 }
@@ -2205,7 +2268,7 @@
 
 /**/
 static int
-qualgid(struct stat *buf, off_t gid)
+qualgid(char *name, struct stat *buf, off_t gid, LinkList dummy)
 {
     return buf->st_gid == gid;
 }
@@ -2214,7 +2277,7 @@
 
 /**/
 static int
-qualisdev(struct stat *buf, off_t junk)
+qualisdev(char *name, struct stat *buf, off_t junk, LinkList dummy)
 {
     return S_ISBLK(buf->st_mode) || S_ISCHR(buf->st_mode);
 }
@@ -2223,7 +2286,7 @@
 
 /**/
 static int
-qualisblk(struct stat *buf, off_t junk)
+qualisblk(char *name, struct stat *buf, off_t junk, LinkList dummy)
 {
     return S_ISBLK(buf->st_mode);
 }
@@ -2232,7 +2295,7 @@
 
 /**/
 static int
-qualischr(struct stat *buf, off_t junk)
+qualischr(char *name, struct stat *buf, off_t junk, LinkList dummy)
 {
     return S_ISCHR(buf->st_mode);
 }
@@ -2241,7 +2304,7 @@
 
 /**/
 static int
-qualisdir(struct stat *buf, off_t junk)
+qualisdir(char *name, struct stat *buf, off_t junk, LinkList dummy)
 {
     return S_ISDIR(buf->st_mode);
 }
@@ -2250,7 +2313,7 @@
 
 /**/
 static int
-qualisfifo(struct stat *buf, off_t junk)
+qualisfifo(char *name, struct stat *buf, off_t junk, LinkList dummy)
 {
     return S_ISFIFO(buf->st_mode);
 }
@@ -2259,7 +2322,7 @@
 
 /**/
 static int
-qualislnk(struct stat *buf, off_t junk)
+qualislnk(char *name, struct stat *buf, off_t junk, LinkList dummy)
 {
     return S_ISLNK(buf->st_mode);
 }
@@ -2268,7 +2331,7 @@
 
 /**/
 static int
-qualisreg(struct stat *buf, off_t junk)
+qualisreg(char *name, struct stat *buf, off_t junk, LinkList dummy)
 {
     return S_ISREG(buf->st_mode);
 }
@@ -2277,7 +2340,7 @@
 
 /**/
 static int
-qualissock(struct stat *buf, off_t junk)
+qualissock(char *name, struct stat *buf, off_t junk, LinkList dummy)
 {
     return S_ISSOCK(buf->st_mode);
 }
@@ -2286,7 +2349,7 @@
 
 /**/
 static int
-qualflags(struct stat *buf, off_t mod)
+qualflags(char *name, struct stat *buf, off_t mod, LinkList dummy)
 {
     return mode_to_octal(buf->st_mode) & mod;
 }
@@ -2295,7 +2358,7 @@
 
 /**/
 static int
-qualmodeflags(struct stat *buf, off_t mod)
+qualmodeflags(char *name, struct stat *buf, off_t mod, LinkList dummy)
 {
     long v = mode_to_octal(buf->st_mode), y = mod & 07777, n = mod >> 12;
 
@@ -2306,7 +2369,7 @@
 
 /**/
 static int
-qualiscom(struct stat *buf, off_t mod)
+qualiscom(char *name, struct stat *buf, off_t mod, LinkList dummy)
 {
     return S_ISREG(buf->st_mode) && (buf->st_mode & S_IXUGO);
 }
@@ -2315,7 +2378,7 @@
 
 /**/
 static int
-qualsize(struct stat *buf, off_t size)
+qualsize(char *name, struct stat *buf, off_t size, LinkList dummy)
 {
 #if defined(LONG_IS_64_BIT) || defined(OFF_T_IS_64_BIT)
 # define QS_CAST_SIZE()
@@ -2350,7 +2413,7 @@
 
 /**/
 static int
-qualtime(struct stat *buf, off_t days)
+qualtime(char *name, struct stat *buf, off_t days, LinkList dummy)
 {
     time_t now, diff;
 
@@ -2379,4 +2442,45 @@
     return (range < 0 ? diff < days :
 	    range > 0 ? diff > days :
 	    diff == days);
+}
+
+/* call shell function */
+
+/**/
+static int
+qualshfunc(char *name, struct stat *buf, off_t days, LinkList args)
+{
+    List list;
+    char *func = (char *) getdata(firstnode(args));
+
+    if ((list = getshfunc(func)) && list != &dummy_list) {
+	int osc = sfcontext, ef = errflag, lv = lastval, ret;
+
+	unsetparam("reply");
+	unsetparam("REPLY");
+
+	setdata(nextnode(firstnode(args)), dupstring(name));
+	sfcontext = SFC_GLOB;
+	doshfunc(func, list, args, 0, 0);
+	ret = lastval;
+	errflag = ef;
+	lastval = lv;
+	sfcontext = osc;
+
+	if (!(inserts = getaparam("reply")) &&
+	    !(inserts = gethparam("reply"))) {
+	    char *tmp;
+
+	    if ((tmp = getsparam("reply")) || (tmp = getsparam("REPLY"))) {
+		static char *tmparr[2];
+
+		tmparr[0] = tmp;
+		tmparr[1] = NULL;
+
+		inserts = tmparr;
+	    }
+	}
+	return !ret;
+    }
+    return 0;
 }
diff -u os/zsh.h Src/zsh.h
--- os/zsh.h	Fri Aug 20 15:18:10 1999
+++ Src/zsh.h	Wed Aug 25 15:23:38 1999
@@ -819,6 +819,7 @@
 #define SFC_WIDGET   3		/* user defined widget */
 #define SFC_COMPLETE 4		/* called from completion code */
 #define SFC_CWIDGET  5		/* new style completion widget */
+#define SFC_GLOB     6		/* called from the `F' glob qualifier */
 
 /* node in list of function call wrappers */
 
diff -u od/Zsh/expn.yo Doc/Zsh/expn.yo
--- od/Zsh/expn.yo	Mon Aug 23 15:47:49 1999
+++ Doc/Zsh/expn.yo	Wed Aug 25 16:12:30 1999
@@ -1377,6 +1377,24 @@
 permission, and for which other users don't have read or execute
 permission.
 )
+item(tt(F)var(name)[var(args)...])(
+The shell function var(name) will be called with the generated
+filename as its first argument and the return value determines if the
+filename should be included in the list (if it is zero) or not (if it
+is non-zero). The first character after the `tt(F)' will be used as a
+separator and anything up to the next matching separator will be taken 
+as the name of the function (`tt([)', `tt({)', and `tt(<)' match
+`tt(])', `tt(})', and `tt(>)' respectively, any other character
+matches itself). Arguments may be given inside consecutive pairs of
+the same separator(s). These strings will be given literally to the
+shell function as the second to last argument.
+
+If the function sets the parameter tt(reply) to an array or to a
+string or if it sets the parameter tt(REPLY) to a string, then these
+strings will be inserted into the generated list instead of the
+original string. For security reasons, these parameters will be unset
+by the shell before the function is called.
+)
 item(tt(d)var(dev))(
 files on the device var(dev)
 )

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PATCH: Re: Files modified after a given date
  1999-08-25 14:20 PATCH: Re: Files modified after a given date Sven Wischnowsky
@ 1999-08-25 15:04 ` Bart Schaefer
  1999-08-26  7:07 ` Andrej Borsenkow
  1 sibling, 0 replies; 15+ messages in thread
From: Bart Schaefer @ 1999-08-25 15:04 UTC (permalink / raw)
  To: zsh-workers

On Aug 25,  4:20pm, Sven Wischnowsky wrote:
} Subject: PATCH: Re: Files modified after a given date
}
} 
} Zefram wrote:
} > That's one of the many things I never got round to.  I was going to
} > have patterns like "*(F:func:)" call the shell function "func" with the
} > name of each file which otherwise matches the glob pattern
} 
} [...] it also allows one to give additional arguments as in
} `*(F:func::arg1::arg2:)' and so on -- these are available as `$2'
} etc. in the function. And finally it allows the function to say *what* 
} should be included by setting the `reply' or `REPLY' parameter to a
} string or array (`REPLY' is only tested for a string value).
} 
} (Maybe this is going a bit too far?)

I don't have a problem with using reply/REPLY, but I think supplying
additional arguments inside the glob qualifier is a bit excessive (and also
accounts for most of the size of this patch, no?).

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: PATCH: Re: Files modified after a given date
  1999-08-25 14:20 PATCH: Re: Files modified after a given date Sven Wischnowsky
  1999-08-25 15:04 ` Bart Schaefer
@ 1999-08-26  7:07 ` Andrej Borsenkow
  1 sibling, 0 replies; 15+ messages in thread
From: Andrej Borsenkow @ 1999-08-26  7:07 UTC (permalink / raw)
  To: Sven Wischnowsky, zsh-workers


> First of all it allows the `*(F:func:)' Zefram mentioned. The function
> will get the filename as its first argument and the return value says
> if the name should be included (ir it is zero, of course).
>

Well, I've read it too late :-)

I was about to suggest more general eval'ing of expression (with some meta to
insert file name in the proper place). I believe, these expressions may oft be
short enough to warrant the whole function ...

Comments?

/andrej


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PATCH: Re: Files modified after a given date
  1999-08-26 11:35 Sven Wischnowsky
  1999-08-26 12:05 ` Zefram
@ 1999-08-30 13:17 ` Peter Stephenson
  1 sibling, 0 replies; 15+ messages in thread
From: Peter Stephenson @ 1999-08-30 13:17 UTC (permalink / raw)
  To: zsh-workers

Sven Wischnowsky wrote:
> The patch would be something like the one below. It allows `*(e:string:)'
> with `$_' being the filename. `reply' and `REPLY' are still used.

do we really need both (at least with all the current complexity)?
how about calling it with ' $_' at the end if it's a single word with no
metacharacters, or something?

-- 
Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PATCH: Re: Files modified after a given date
  1999-08-26  7:08 Sven Wischnowsky
@ 1999-08-30 13:09 ` Peter Stephenson
  0 siblings, 0 replies; 15+ messages in thread
From: Peter Stephenson @ 1999-08-30 13:09 UTC (permalink / raw)
  To: zsh-workers

Sven Wischnowsky wrote:
> But if everyone prefers it without the arguments, I'm ready to take it 
> out.

I think they make it over-complicated.  You can easily write the function as
a wrapper to call a lower level function if you need to pass down
arguments.

-- 
Peter Stephenson <pws@ibmth.df.unipi.it>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PATCH: Re: Files modified after a given date
@ 1999-08-30  9:10 Sven Wischnowsky
  0 siblings, 0 replies; 15+ messages in thread
From: Sven Wischnowsky @ 1999-08-30  9:10 UTC (permalink / raw)
  To: zsh-workers


I wrote:

> 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).

badcshglob shoudn't be saved/restored here -- it is in exec.c.

Bye
 Sven

diff -u oos/glob.c Src/glob.c
--- oos/glob.c	Mon Aug 30 10:58:42 1999
+++ Src/glob.c	Mon Aug 30 11:08:45 1999
@@ -121,7 +121,6 @@
 /* struct to easily save/restore current state */
 
 struct globdata {
-    int gd_badcshglob;
     int gd_pathpos;
     char *gd_pathbuf;
 
@@ -176,7 +175,6 @@
 #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; \
@@ -186,7 +184,6 @@
 #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; \

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PATCH: Re: Files modified after a given date
  1999-08-27  8:13 Sven Wischnowsky
@ 1999-08-27 22:39 ` Ollivier Robert
  0 siblings, 0 replies; 15+ messages in thread
From: Ollivier Robert @ 1999-08-27 22:39 UTC (permalink / raw)
  To: zsh-workers

According to Sven Wischnowsky:
> 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).

Sorry, the patch doesn't apply to my -- heavily patched now -- copy. It is
really time to do a pws-2,am I the only one to be lost... ?
-- 
Ollivier ROBERT -=- Eurocontrol EEC/TEC -=- roberto@eurocontrol.fr
The Postman hits! The Postman hits! You have new mail.


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PATCH: Re: Files modified after a given date
@ 1999-08-27  8:13 Sven Wischnowsky
  1999-08-27 22:39 ` Ollivier Robert
  0 siblings, 1 reply; 15+ messages in thread
From: Sven Wischnowsky @ 1999-08-27  8:13 UTC (permalink / raw)
  To: zsh-workers


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


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PATCH: Re: Files modified after a given date
  1999-08-26 12:16 Sven Wischnowsky
@ 1999-08-26 12:27 ` Zefram
  0 siblings, 0 replies; 15+ messages in thread
From: Zefram @ 1999-08-26 12:27 UTC (permalink / raw)
  To: Sven Wischnowsky; +Cc: zsh-workers

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.

-zefram


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PATCH: Re: Files modified after a given date
@ 1999-08-26 12:16 Sven Wischnowsky
  1999-08-26 12:27 ` Zefram
  0 siblings, 1 reply; 15+ messages in thread
From: Sven Wischnowsky @ 1999-08-26 12:16 UTC (permalink / raw)
  To: zsh-workers


Zefram wrote:

> Sven Wischnowsky wrote:
> >          Before the string is executed, expansion is performed on it
> >+with the parameter tt($_) being set to the filename currently being
> >+tested.
> 
> Wouldn't it be easier to use if the string were simply evaluated with $_
> appropriately set, without this extra layer of expansion?

;-) 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.

Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PATCH: Re: Files modified after a given date
  1999-08-26 11:35 Sven Wischnowsky
@ 1999-08-26 12:05 ` Zefram
  1999-08-30 13:17 ` Peter Stephenson
  1 sibling, 0 replies; 15+ messages in thread
From: Zefram @ 1999-08-26 12:05 UTC (permalink / raw)
  To: Sven Wischnowsky; +Cc: zsh-workers

Sven Wischnowsky wrote:
>          Before the string is executed, expansion is performed on it
>+with the parameter tt($_) being set to the filename currently being
>+tested.

Wouldn't it be easier to use if the string were simply evaluated with $_
appropriately set, without this extra layer of expansion?

-zefram


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PATCH: Re: Files modified after a given date
@ 1999-08-26 11:35 Sven Wischnowsky
  1999-08-26 12:05 ` Zefram
  1999-08-30 13:17 ` Peter Stephenson
  0 siblings, 2 replies; 15+ messages in thread
From: Sven Wischnowsky @ 1999-08-26 11:35 UTC (permalink / raw)
  To: zsh-workers


Zefram wrote:

> Sven Wischnowsky wrote:
> >Hmm, yes that may be an interesting alternative. Wouldn't be hard to
> >implement either and we wouldn't really need any meta character-
> >sequence, we could just set `$FILE' or something like that before
> >evaluating the whole thing.
> 
> I'm in two minds as to which arrangement is better.  I think this one just
> has the edge, in that it makes it possible to invent impromptu functions
> on the command line.  But make it $_ instead of $FILE -- not only is it
> shorter, but it's already used in comparable ways (mail notification).

The patch would be something like the one below. It allows `*(e:string:)'
with `$_' being the filename. `reply' and `REPLY' are still used.

This goes on top of 7482.

Bye
 Sven

diff -u os/glob.c Src/glob.c
--- os/glob.c	Thu Aug 26 11:28:40 1999
+++ Src/glob.c	Thu Aug 26 13:23:51 1999
@@ -107,7 +107,7 @@
 #define TT_MEGABYTES 3
 
 
-typedef int (*TestMatchFunc) _((char *, struct stat *, off_t, LinkList));
+typedef int (*TestMatchFunc) _((char *, struct stat *, off_t, char *));
 
 struct qual {
     struct qual *next;		/* Next qualifier, must match                */
@@ -118,7 +118,7 @@
     int amc;			/* Flag for which time to test (a, m, c)     */
     int range;			/* Whether to test <, > or = (as per signum) */
     int units;			/* Multiplier for time or size, respectively */
-    LinkList ldata;		/* currently only: shell function to call    */
+    char *sdata;		/* currently only: expression to eval        */
 };
 
 /* Qualifiers pertaining to current pattern */
@@ -263,7 +263,7 @@
 	    /* Reject the file if the function returned zero *
 	     * and the sense was positive (sense&1 == 0), or *
 	     * vice versa.                                   */
-	    if ((!((qn->func) (news, bp, qn->data, qn->ldata)) ^ qn->sense) & 1) {
+	    if ((!((qn->func) (news, bp, qn->data, qn->sdata)) ^ qn->sense) & 1) {
 		/* Try next alternative, or return if there are no more */
 		if (!(qo = qo->or))
 		    return;
@@ -853,18 +853,18 @@
 	    int sense = 0;	   /* bit 0 for match (0)/don't match (1)   */
 				   /* bit 1 for follow links (2), don't (0) */
 	    off_t data = 0;	   /* Any numerical argument required       */
-	    LinkList ldata = NULL; /* Any list argument required            */
-	    int (*func) _((char *, Statptr, off_t, LinkList));
+	    char *sdata = NULL; /* Any list argument required            */
+	    int (*func) _((char *, Statptr, off_t, char *));
 
 	    str[sl-1] = 0;
 	    *s++ = 0;
 	    while (*s && !colonmod) {
-		func = (int (*) _((char *, Statptr, off_t, LinkList)))0;
+		func = (int (*) _((char *, Statptr, off_t, char *)))0;
 		if (idigit(*s)) {
 		    /* Store numeric argument for qualifier */
 		    func = qualflags;
 		    data = 0;
-		    ldata = NULL;
+		    sdata = NULL;
 		    while (idigit(*s))
 			data = data * 010 + (*s++ - '0');
 		} else if (*s == ',') {
@@ -1189,44 +1189,28 @@
 			    s++;
 			    break;
 			}
-		    case 'F':
+		    case 'e':
 			{
 			    char sav, *tt = get_strarg(s);
 
 			    if (!*tt) {
-				zerr("missing end of function name", NULL, 0);
+				zerr("missing end of string", NULL, 0);
 				data = 0;
 			    } else {
-				char sep = *s;
-
 				sav = *tt;
 				*tt = '\0';
-				func = qualshfunc;
-				ldata = newlinklist();
-				addlinknode(ldata, dupstring(s + 1));
-				addlinknode(ldata, NULL);
-				*tt = sav;
-				if (sav)
-				    s = tt + 1;
-				else
-				    s = tt;
-				while (*s == sep) {
-				    tt = get_strarg(s);
-				    if (!*tt) {
-					zerr("missing end of argument", NULL, 0);
-					data = 0;
-					ldata = NULL;
-					break;
-				    } else {
-					sav = *tt;
-					*tt = '\0';
-					addlinknode(ldata, dupstring(s + 1));
-					*tt = sav;
-					if (sav)
-					    s = tt + 1;
-					else
-					    s = tt;
-				    }
+				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;
 				}
 			    }
 			    break;
@@ -1265,7 +1249,7 @@
 		    qn->func = func;
 		    qn->sense = sense;
 		    qn->data = data;
-		    qn->ldata = ldata;
+		    qn->sdata = sdata;
 		    qn->range = range;
 		    qn->units = units;
 		    qn->amc = amc;
@@ -2239,7 +2223,7 @@
 
 /**/
 static int
-qualdev(char *name, struct stat *buf, off_t dv, LinkList dummy)
+qualdev(char *name, struct stat *buf, off_t dv, char *dummy)
 {
     return buf->st_dev == dv;
 }
@@ -2248,7 +2232,7 @@
 
 /**/
 static int
-qualnlink(char *name, struct stat *buf, off_t ct, LinkList dummy)
+qualnlink(char *name, struct stat *buf, off_t ct, char *dummy)
 {
     return (range < 0 ? buf->st_nlink < ct :
 	    range > 0 ? buf->st_nlink > ct :
@@ -2259,7 +2243,7 @@
 
 /**/
 static int
-qualuid(char *name, struct stat *buf, off_t uid, LinkList dummy)
+qualuid(char *name, struct stat *buf, off_t uid, char *dummy)
 {
     return buf->st_uid == uid;
 }
@@ -2268,7 +2252,7 @@
 
 /**/
 static int
-qualgid(char *name, struct stat *buf, off_t gid, LinkList dummy)
+qualgid(char *name, struct stat *buf, off_t gid, char *dummy)
 {
     return buf->st_gid == gid;
 }
@@ -2277,7 +2261,7 @@
 
 /**/
 static int
-qualisdev(char *name, struct stat *buf, off_t junk, LinkList dummy)
+qualisdev(char *name, struct stat *buf, off_t junk, char *dummy)
 {
     return S_ISBLK(buf->st_mode) || S_ISCHR(buf->st_mode);
 }
@@ -2286,7 +2270,7 @@
 
 /**/
 static int
-qualisblk(char *name, struct stat *buf, off_t junk, LinkList dummy)
+qualisblk(char *name, struct stat *buf, off_t junk, char *dummy)
 {
     return S_ISBLK(buf->st_mode);
 }
@@ -2295,7 +2279,7 @@
 
 /**/
 static int
-qualischr(char *name, struct stat *buf, off_t junk, LinkList dummy)
+qualischr(char *name, struct stat *buf, off_t junk, char *dummy)
 {
     return S_ISCHR(buf->st_mode);
 }
@@ -2304,7 +2288,7 @@
 
 /**/
 static int
-qualisdir(char *name, struct stat *buf, off_t junk, LinkList dummy)
+qualisdir(char *name, struct stat *buf, off_t junk, char *dummy)
 {
     return S_ISDIR(buf->st_mode);
 }
@@ -2313,7 +2297,7 @@
 
 /**/
 static int
-qualisfifo(char *name, struct stat *buf, off_t junk, LinkList dummy)
+qualisfifo(char *name, struct stat *buf, off_t junk, char *dummy)
 {
     return S_ISFIFO(buf->st_mode);
 }
@@ -2322,7 +2306,7 @@
 
 /**/
 static int
-qualislnk(char *name, struct stat *buf, off_t junk, LinkList dummy)
+qualislnk(char *name, struct stat *buf, off_t junk, char *dummy)
 {
     return S_ISLNK(buf->st_mode);
 }
@@ -2331,7 +2315,7 @@
 
 /**/
 static int
-qualisreg(char *name, struct stat *buf, off_t junk, LinkList dummy)
+qualisreg(char *name, struct stat *buf, off_t junk, char *dummy)
 {
     return S_ISREG(buf->st_mode);
 }
@@ -2340,7 +2324,7 @@
 
 /**/
 static int
-qualissock(char *name, struct stat *buf, off_t junk, LinkList dummy)
+qualissock(char *name, struct stat *buf, off_t junk, char *dummy)
 {
     return S_ISSOCK(buf->st_mode);
 }
@@ -2349,7 +2333,7 @@
 
 /**/
 static int
-qualflags(char *name, struct stat *buf, off_t mod, LinkList dummy)
+qualflags(char *name, struct stat *buf, off_t mod, char *dummy)
 {
     return mode_to_octal(buf->st_mode) & mod;
 }
@@ -2358,7 +2342,7 @@
 
 /**/
 static int
-qualmodeflags(char *name, struct stat *buf, off_t mod, LinkList dummy)
+qualmodeflags(char *name, struct stat *buf, off_t mod, char *dummy)
 {
     long v = mode_to_octal(buf->st_mode), y = mod & 07777, n = mod >> 12;
 
@@ -2369,7 +2353,7 @@
 
 /**/
 static int
-qualiscom(char *name, struct stat *buf, off_t mod, LinkList dummy)
+qualiscom(char *name, struct stat *buf, off_t mod, char *dummy)
 {
     return S_ISREG(buf->st_mode) && (buf->st_mode & S_IXUGO);
 }
@@ -2378,7 +2362,7 @@
 
 /**/
 static int
-qualsize(char *name, struct stat *buf, off_t size, LinkList dummy)
+qualsize(char *name, struct stat *buf, off_t size, char *dummy)
 {
 #if defined(LONG_IS_64_BIT) || defined(OFF_T_IS_64_BIT)
 # define QS_CAST_SIZE()
@@ -2413,7 +2397,7 @@
 
 /**/
 static int
-qualtime(char *name, struct stat *buf, off_t days, LinkList dummy)
+qualtime(char *name, struct stat *buf, off_t days, char *dummy)
 {
     time_t now, diff;
 
@@ -2444,28 +2428,32 @@
 	    diff == days);
 }
 
-/* call shell function */
+/* evaluate a string */
 
 /**/
 static int
-qualshfunc(char *name, struct stat *buf, off_t days, LinkList args)
+qualsheval(char *name, struct stat *buf, off_t days, char *str)
 {
     List list;
-    char *func = (char *) getdata(firstnode(args));
+    char *usav = underscore;
 
-    if ((list = getshfunc(func)) && list != &dummy_list) {
-	int osc = sfcontext, ef = errflag, lv = lastval, ret;
+    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");
 
-	setdata(nextnode(firstnode(args)), dupstring(name));
-	sfcontext = SFC_GLOB;
-	doshfunc(func, list, args, 0, 0);
+	execlist(list, 1, 0);
+
 	ret = lastval;
 	errflag = ef;
 	lastval = lv;
-	sfcontext = osc;
 
 	if (!(inserts = getaparam("reply")) &&
 	    !(inserts = gethparam("reply"))) {
diff -u os/zsh.h Src/zsh.h
--- os/zsh.h	Thu Aug 26 11:28:43 1999
+++ Src/zsh.h	Thu Aug 26 13:30:26 1999
@@ -819,7 +819,6 @@
 #define SFC_WIDGET   3		/* user defined widget */
 #define SFC_COMPLETE 4		/* called from completion code */
 #define SFC_CWIDGET  5		/* new style completion widget */
-#define SFC_GLOB     6		/* called from the `F' glob qualifier */
 
 /* node in list of function call wrappers */
 
diff -u od/Zsh/expn.yo Doc/Zsh/expn.yo
--- od/Zsh/expn.yo	Thu Aug 26 11:28:35 1999
+++ Doc/Zsh/expn.yo	Thu Aug 26 13:34:23 1999
@@ -1377,23 +1377,24 @@
 permission, and for which other users don't have read or execute
 permission.
 )
-item(tt(F)var(name)[var(args)...])(
-The shell function var(name) will be called with the generated
-filename as its first argument and the return value determines if the
+item(tt(e)var(string))(
+The var(string) will be executed and the return value determines if the
 filename should be included in the list (if it is zero) or not (if it
-is non-zero). The first character after the `tt(F)' will be used as a
+is non-zero). The first character after the `tt(e)' will be used as a
 separator and anything up to the next matching separator will be taken 
-as the name of the function (`tt([)', `tt({)', and `tt(<)' match
-`tt(])', `tt(})', and `tt(>)' respectively, any other character
-matches itself). Arguments may be given inside consecutive pairs of
-the same separator(s). These strings will be given literally to the
-shell function as the second to last argument.
+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.
 
-If the function sets the parameter tt(reply) to an array or to a
-string or if it sets the parameter tt(REPLY) to a string, then these
-strings will be inserted into the generated list instead of the
-original string. For security reasons, these parameters will be unset
-by the shell before the function is called.
+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.
 )
 item(tt(d)var(dev))(
 files on the device var(dev)

--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PATCH: Re: Files modified after a given date
  1999-08-26  9:42 Sven Wischnowsky
@ 1999-08-26  9:58 ` Zefram
  0 siblings, 0 replies; 15+ messages in thread
From: Zefram @ 1999-08-26  9:58 UTC (permalink / raw)
  To: Sven Wischnowsky; +Cc: zsh-workers

Sven Wischnowsky wrote:
>Hmm, yes that may be an interesting alternative. Wouldn't be hard to
>implement either and we wouldn't really need any meta character-
>sequence, we could just set `$FILE' or something like that before
>evaluating the whole thing.

I'm in two minds as to which arrangement is better.  I think this one just
has the edge, in that it makes it possible to invent impromptu functions
on the command line.  But make it $_ instead of $FILE -- not only is it
shorter, but it's already used in comparable ways (mail notification).

-zefram


^ permalink raw reply	[flat|nested] 15+ messages in thread

* RE: PATCH: Re: Files modified after a given date
@ 1999-08-26  9:42 Sven Wischnowsky
  1999-08-26  9:58 ` Zefram
  0 siblings, 1 reply; 15+ messages in thread
From: Sven Wischnowsky @ 1999-08-26  9:42 UTC (permalink / raw)
  To: zsh-workers


Andrej Borsenkow wrote:

> > First of all it allows the `*(F:func:)' Zefram mentioned. The function
> > will get the filename as its first argument and the return value says
> > if the name should be included (ir it is zero, of course).
> >
> 
> Well, I've read it too late :-)
> 
> I was about to suggest more general eval'ing of expression (with some meta to
> insert file name in the proper place). I believe, these expressions may oft be
> short enough to warrant the whole function ...
> 
> Comments?

Hmm, yes that may be an interesting alternative. Wouldn't be hard to
implement either and we wouldn't really need any meta character-
sequence, we could just set `$FILE' or something like that before
evaluating the whole thing.

If enough people say that they prefer this, I'll build a patch.

Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: PATCH: Re: Files modified after a given date
@ 1999-08-26  7:08 Sven Wischnowsky
  1999-08-30 13:09 ` Peter Stephenson
  0 siblings, 1 reply; 15+ messages in thread
From: Sven Wischnowsky @ 1999-08-26  7:08 UTC (permalink / raw)
  To: zsh-workers


Bart Schaefer wrote:

> On Aug 25,  4:20pm, Sven Wischnowsky wrote:
> } Subject: PATCH: Re: Files modified after a given date
> }
> } 
> } Zefram wrote:
> } > That's one of the many things I never got round to.  I was going to
> } > have patterns like "*(F:func:)" call the shell function "func" with the
> } > name of each file which otherwise matches the glob pattern
> } 
> } [...] it also allows one to give additional arguments as in
> } `*(F:func::arg1::arg2:)' and so on -- these are available as `$2'
> } etc. in the function. And finally it allows the function to say *what* 
> } should be included by setting the `reply' or `REPLY' parameter to a
> } string or array (`REPLY' is only tested for a string value).
> } 
> } (Maybe this is going a bit too far?)
> 
> I don't have a problem with using reply/REPLY, but I think supplying
> additional arguments inside the glob qualifier is a bit excessive (and also
> accounts for most of the size of this patch, no?).

No, it's basically the loop in glob() -- 18 lines and without it
qualshfunc() would be slightly bigger. (And it may save someone from
implementing sets of wrapper functions, of course.)

But if everyone prefers it without the arguments, I'm ready to take it 
out.

Bye
 Sven


--
Sven Wischnowsky                         wischnow@informatik.hu-berlin.de


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~1999-08-30 14:20 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-08-25 14:20 PATCH: Re: Files modified after a given date Sven Wischnowsky
1999-08-25 15:04 ` Bart Schaefer
1999-08-26  7:07 ` Andrej Borsenkow
1999-08-26  7:08 Sven Wischnowsky
1999-08-30 13:09 ` Peter Stephenson
1999-08-26  9:42 Sven Wischnowsky
1999-08-26  9:58 ` Zefram
1999-08-26 11:35 Sven Wischnowsky
1999-08-26 12:05 ` Zefram
1999-08-30 13:17 ` Peter Stephenson
1999-08-26 12:16 Sven Wischnowsky
1999-08-26 12:27 ` Zefram
1999-08-27  8:13 Sven Wischnowsky
1999-08-27 22:39 ` Ollivier Robert
1999-08-30  9:10 Sven Wischnowsky

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).