From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from gatech.edu (gatech.edu [130.207.244.244]) by werple.mira.net.au (8.6.12/8.6.12) with SMTP id JAA22354 for ; Sat, 23 Sep 1995 09:12:51 +1000 Received: from math (math.skiles.gatech.edu) by gatech.edu with SMTP id AA14066 (5.65c/Gatech-10.0-IDA for ); Fri, 22 Sep 1995 19:15:16 -0400 Received: by math (5.x/SMI-SVR4) id AA28698; Fri, 22 Sep 1995 19:09:05 -0400 Resent-Date: Sat, 23 Sep 1995 00:42:29 +0200 (MET DST) Old-Return-Path: Message-Id: Subject: size glob qualifier patch To: zsh-workers@math.gatech.edu Date: Sat, 23 Sep 1995 00:42:29 +0200 (MET DST) In-Reply-To: <2700.9508301434@pyro.swan.ac.uk> from "P.Stephenson@swansea.ac.uk" at Aug 30, 95 03:34:05 pm From: Thorsten Meinecke Organization: none. Location: Berlin, Germany X-Mailer: ELM [version 2.4 PL23] Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Resent-Message-Id: <"eECV-.0.G07.G8qOm"@math> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/402 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu In message #346, Subject: Re: zshexpn(1) doc suggestion, Peter Stephenson wrote: >This is not exactly relevant, but I've always wanted the L (size) >qualifier to accept k or m (or K or M) as modifiers. I never seem to >want to check for anything smaller than about 50k, in which case >zeros proliferate. This is maybe not exactly what you want, but it is easy to mimic the behaviour of find(1)'s -size option, with modifiers similiar to those used by the time glob qualifiers. The relevant part of the zshexpn.1 man page would then read: L[+|-]n files less than n bytes (-), more than n bytes (+), or exactly n bytes in length. If this flag is directly followed by a k (K), m (M), or p (P) (e.g. Lk+50) the check is per- formed with kilobytes, megabytes, or blocks (of 512 bytes) instead. Since I'm used to the use of Kbyte (2^10) to denote the difference to the SI-prefix k (10^3), it seems preferable to accept these modifiers case-insensitive. What this patch does. Data is passed to the qual*() functions by means of parameter, and of a couple of static vars. Of those, which are reloaded each time before a different function is called, `timef' as time multiplier was renamed to `units' and serves now as size mul- tiplier, too. In qualsize(), the range adjustment for e.g. `*(Lk1)' == `find . -size 1k' == 1 .. 1024 bytes is done by adding factor-1 before the division by factor, thus re- quiring an unsigned var. For size qualifier without unit modifier, operation hasn't changed. Side notes: o The size code has still a hard limit, in that it will break when there are filesizes greater than One Less Than Two Gigabytes (2^31-1) on machines with 32-bit longs. What about POSIX (off_t)? o Is it considered useful to have Yet Another Globbing Qualifier, e.g. B, for size globbing based on the real amount of disk space used, as opposed to the `length' of possibly sparse files now? Cf. du(1) o Would it be fun if there was a zsh shell function as a find(1)- compatible front-end, or converter, to zsh's globbing capabilities? That is, long option names are easier to remember than one-letter qualifiers. This is for hzoli10.3, but should also apply to plain zsh-2.6-beta10. *** Doc/zshexpn.1.ORIG Wed Sep 20 16:33:57 1995 --- Doc/zshexpn.1 Fri Sep 22 15:27:48 1995 *************** *** 643,649 **** .TP \fBL\fI[+|-]n\fR files less than n bytes (-), more than n bytes (+), or ! exactly n bytes in length. .TP \fB^\fP negates all qualifiers following it --- 643,652 ---- .TP \fBL\fI[+|-]n\fR files less than n bytes (-), more than n bytes (+), or ! exactly n bytes in length. If this flag is directly followed by a \fBk\fP ! (\fBK\fP), \fBm\fP (\fBM\fP), or \fBp\fP (\fBP\fP) (e.g. \fBLk+50\fP) ! the check is performed with kilobytes, megabytes, or blocks (of 512 bytes) ! instead. .TP \fB^\fP negates all qualifiers following it *** Src/glob.c.ORIG Wed Sep 20 16:34:03 1995 --- Src/glob.c Fri Sep 22 15:17:38 1995 *************** *** 49,60 **** --- 49,67 ---- typedef struct stat *Statptr; /* This makes the Ultrix compiler happy. Go figure. */ #endif + /* modifier for unit conversions */ + #define TT_DAYS 0 #define TT_HOURS 1 #define TT_MINS 2 #define TT_WEEKS 3 #define TT_MONTHS 4 + #define TT_BYTES 0 + #define TT_POSIX_BLOCKS 1 + #define TT_KILOBYTES 2 + #define TT_MEGABYTES 3 + /* max # of qualifiers */ typedef int (*TestMatchFunc) _((struct stat *, long)); *************** *** 67,73 **** int sense; /* Whether asserting or negating */ int amc; /* Flag for which time to test (a, m, c) */ int range; /* Whether to test <, > or = (as per signum) */ ! int timef; /* Multiplier for time */ }; /* Qualifiers pertaining to current pattern */ --- 74,80 ---- int sense; /* Whether asserting or negating */ 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 */ }; /* Qualifiers pertaining to current pattern */ *************** *** 75,81 **** /* Other state values for current pattern */ static int qualct, qualorct; ! static int range, amc, timef; static int gf_nullglob, gf_markdirs, gf_noglobdots, gf_listtypes; /* Prefix, suffix for doing zle trickery */ --- 82,88 ---- /* 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; /* Prefix, suffix for doing zle trickery */ *************** *** 436,453 **** /* File size (Length) in given range */ func = qualsize; amc = -1; getrange: - timef = TT_DAYS; /* Get time multiplier */ ! if (amc >= 0) if (*s == 'h') ! timef = TT_HOURS, ++s; else if (*s == 'm') ! timef = TT_MINS, ++s; else if (*s == 'w') ! timef = TT_WEEKS, ++s; else if (*s == 'M') ! timef = TT_MONTHS, ++s; /* See if it's greater than, equal to, or less than */ if ((range = *s == '+' ? 1 : *s == '-' ? -1 : 0)) ++s; --- 443,469 ---- /* File size (Length) in given range */ func = qualsize; amc = -1; + /* Get size multiplier */ + units = TT_BYTES; + if (*s == 'p' || *s == 'P') + units = TT_POSIX_BLOCKS, ++s; + else if (*s == 'k' || *s == 'K') + units = TT_KILOBYTES, ++s; + else if (*s == 'm' || *s == 'M') + units = TT_MEGABYTES, ++s; getrange: /* Get time multiplier */ ! if (amc >= 0) { ! units = TT_DAYS; if (*s == 'h') ! units = TT_HOURS, ++s; else if (*s == 'm') ! units = TT_MINS, ++s; else if (*s == 'w') ! units = TT_WEEKS, ++s; else if (*s == 'M') ! units = TT_MONTHS, ++s; ! } /* See if it's greater than, equal to, or less than */ if ((range = *s == '+' ? 1 : *s == '-' ? -1 : 0)) ++s; *************** *** 471,477 **** qn->sense = sense; qn->data = data; qn->range = range; ! qn->timef = timef; qn->amc = amc; qn = NULL; qualct++; --- 487,493 ---- qn->sense = sense; qn->data = data; qn->range = range; ! qn->units = units; qn->amc = amc; qn = NULL; qualct++; *************** *** 656,662 **** for (qn = qo; t && qn && qn->func; qn = qn->next) { range = qn->range; amc = qn->amc; ! timef = qn->timef; if ((qn->sense & 2) && !statted) { /* If (sense & 2), we're following links */ statted = 1; --- 672,678 ---- for (qn = qo; t && qn && qn->func; qn = qn->next) { range = qn->range; amc = qn->amc; ! units = qn->units; if ((qn->sense & 2) && !statted) { /* If (sense & 2), we're following links */ statted = 1; *************** *** 2239,2247 **** int qualsize(struct stat *buf, long size) { ! return (range < 0 ? buf->st_size < size : ! range > 0 ? buf->st_size > size : ! buf->st_size == size); } /* time in required range? */ --- 2255,2280 ---- int qualsize(struct stat *buf, long size) { ! unsigned long scaled = buf->st_size; ! ! switch (units) { ! case TT_POSIX_BLOCKS: ! scaled += 511l; ! scaled /= 512l; ! break; ! case TT_KILOBYTES: ! scaled += 1023l; ! scaled /= 1024l; ! break; ! case TT_MEGABYTES: ! scaled += 1048575l; ! scaled /= 1048576l; ! break; ! } ! ! return (range < 0 ? scaled < size : ! range > 0 ? scaled > size : ! scaled == size); } /* time in required range? */ *************** *** 2256,2262 **** diff = now - (amc == 0 ? buf->st_atime : amc == 1 ? buf->st_mtime : buf->st_ctime); /* handle multipliers indicating units */ ! switch (timef) { case TT_DAYS: diff /= 86400l; break; --- 2289,2295 ---- diff = now - (amc == 0 ? buf->st_atime : amc == 1 ? buf->st_mtime : buf->st_ctime); /* handle multipliers indicating units */ ! switch (units) { case TT_DAYS: diff /= 86400l; break; -- Thorsten Meinecke