Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
size glob qualifier patch
- X-seq: zsh-workers 402
- From: Thorsten Meinecke <kaefer@xxxxxxxxxxxxxxx>
- To: zsh-workers@xxxxxxxxxxxxxxx
- Subject: size glob qualifier patch
- Date: Sat, 23 Sep 1995 00:42:29 +0200 (MET DST)
- In-reply-to: <2700.9508301434@xxxxxxxxxxxxxxx> from "P.Stephenson@xxxxxxxxxxxxx" at Aug 30, 95 03:34:05 pm
- Organization: none. Location: Berlin, Germany
In message #346, Subject: Re: zshexpn(1) doc suggestion,
Peter Stephenson <P.Stephenson@xxxxxxxxxxxxx> 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
<kaefer@xxxxxxxxxxxxxxx>
Messages sorted by:
Reverse Date,
Date,
Thread,
Author