Subject: enhancements to glob code
To: None <current-users@sun-lamp.cs.berkeley.edu>
From: Luke Mewburn <lm@rmit.edu.au>
List: current-users
Date: 01/05/1994 16:47:57
Many moons ago (earlier this year) I hacked the glob code (in its pre-brace
and tilde days) to give it some extra functionality. The extra flags
are:
- GLOB_ALTNOT use ^ instead of ! inside [...] (from tcsh 6.04)
- GLOB_DOTFILES match .files without specifying `.' at the start
of the pattern.
- GLOB_NODOT never match . or .. (When used with with DOTFILES,
`*' will match every file in the current directory
sans `.' and `..' - useful huh? :)
A minor manpage typo is fixed, as well as updates to the manual to
reflect my changes.
Would there be any major objections to my request to get this added to the
main distribution?
Oh, I've got patches to csh (and tcsh 6.04) to add 2 new variables `dotfiles'
and `nodot' which change the effects of globbing as you'd expect. If this
code is committed, I'll forward on the csh hacks too.
PS: my patch has some code like:
static int not_c, m_not_c;
Will this break shared libraries (cause each application may want to set
their own internal values of this)? I don't think it should, but I've never
written code to go into shared libs before ;)
--- context diff follows (cwd was /usr/src)
*** include/glob.h.ORIG Fri Dec 17 06:18:00 1993
--- include/glob.h Wed Jan 5 16:29:33 1994
***************
*** 78,83 ****
--- 78,86 ----
#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */
#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */
#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */
+ #define GLOB_DOTFILES 0x1000 /* Match . files without explicit . */
+ #define GLOB_NODOT 0x2000 /* Never glob . or .. */
+ #define GLOB_ALTNOT 0x4000 /* Use ^ instead of ! as NOT char */
#endif
#define GLOB_NOSPACE (-1) /* Malloc call failed. */
*** lib/libc/gen/glob.c.ORIG Fri Dec 17 06:23:00 1993
--- lib/libc/gen/glob.c Wed Jan 5 15:30:03 1994
***************
*** 34,39 ****
--- 34,43 ----
* SUCH DAMAGE.
*/
+ /*
+ * GLOB_{DOTFILES,NODOT,ALTNOT} added by Luke Mewburn <lm@rmit.edu.au> 940105
+ */
+
#if defined(LIBC_SCCS) && !defined(lint)
/* from: static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; */
static char *rcsid = "$Id: glob.c,v 1.4 1993/11/06 01:10:18 cgd Exp $";
***************
*** 60,65 ****
--- 64,75 ----
* expand ~user/foo to the /home/dir/of/user/foo
* GLOB_BRACE:
* expand {1,2}{a,b} to 1a 1b 2a 2b
+ * GLOB_DOTFILES:
+ * . files don't need to be explicitly matched with '.*'
+ * GLOB_NODOT:
+ * Never match '.' or '..' (mainly used with GLOB_DOTFILES)
+ * GLOB_ALTNOT:
+ * Use ^ instead of ! for NOT.
* gl_matchc:
* Number of matches in the current invocation of glob.
*/
***************
*** 82,87 ****
--- 92,98 ----
#define EOS '\0'
#define LBRACKET '['
#define NOT '!'
+ #define ALTNOT '^'
#define QUESTION '?'
#define QUOTE '\\'
#define RANGE '-'
***************
*** 121,126 ****
--- 132,138 ----
#define M_ALL META('*')
#define M_END META(']')
#define M_NOT META('!')
+ #define M_ALTNOT META('^')
#define M_ONE META('?')
#define M_RNG META('-')
#define M_SET META('[')
***************
*** 149,154 ****
--- 161,169 ----
static void qprintf __P((const char *, Char *));
#endif
+ static int not_c, m_not_c;
+
+
int
glob(pattern, flags, errfunc, pglob)
const char *pattern;
***************
*** 170,175 ****
--- 185,198 ----
pglob->gl_errfunc = errfunc;
pglob->gl_matchc = 0;
+ if (flags & GLOB_ALTNOT) {
+ not_c = ALTNOT;
+ m_not_c = M_ALTNOT;
+ } else {
+ not_c = NOT;
+ m_not_c = M_NOT;
+ }
+
bufnext = patbuf;
bufend = bufnext + MAXPATHLEN;
if (flags & GLOB_QUOTE) {
***************
*** 410,427 ****
switch (c) {
case LBRACKET:
c = *qpatnext;
! if (c == NOT)
++qpatnext;
if (*qpatnext == EOS ||
g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
*bufnext++ = LBRACKET;
! if (c == NOT)
--qpatnext;
break;
}
*bufnext++ = M_SET;
! if (c == NOT)
! *bufnext++ = M_NOT;
c = *qpatnext++;
do {
*bufnext++ = CHAR(c);
--- 433,450 ----
switch (c) {
case LBRACKET:
c = *qpatnext;
! if (c == not_c)
++qpatnext;
if (*qpatnext == EOS ||
g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) {
*bufnext++ = LBRACKET;
! if (c == not_c)
--qpatnext;
break;
}
*bufnext++ = M_SET;
! if (c == not_c)
! *bufnext++ = m_not_c;
c = *qpatnext++;
do {
*bufnext++ = CHAR(c);
***************
*** 596,604 ****
register u_char *sc;
register Char *dc;
! /* Initial DOT must be matched literally. */
! if (dp->d_name[0] == DOT && *pattern != DOT)
! continue;
for (sc = (u_char *) dp->d_name, dc = pathend;
(*dc++ = *sc++) != EOS;)
continue;
--- 619,635 ----
register u_char *sc;
register Char *dc;
! /* Initial DOT must be matched literally, unless GLOB_DOTFILES */
! if (dp->d_name[0] == DOT) {
! if (pglob->gl_flags & GLOB_NODOT)
! if ((dp->d_name[1] == EOS) ||
! (dp->d_name[1] == DOT &&
! dp->d_name[2] == EOS))
! continue;
! if (!(pglob->gl_flags & GLOB_DOTFILES))
! if (*pattern != DOT)
! continue;
! }
for (sc = (u_char *) dp->d_name, dc = pathend;
(*dc++ = *sc++) != EOS;)
continue;
***************
*** 700,706 ****
ok = 0;
if ((k = *name++) == EOS)
return(0);
! if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS)
++pat;
while (((c = *pat++) & M_MASK) != M_END)
if ((*pat & M_MASK) == M_RNG) {
--- 731,737 ----
ok = 0;
if ((k = *name++) == EOS)
return(0);
! if ((negate_range = ((*pat & M_MASK) == m_not_c)) != EOS)
++pat;
while (((c = *pat++) & M_MASK) != M_END)
if ((*pat & M_MASK) == M_RNG) {
*** lib/libc/gen/glob.3.ORIG Fri Dec 17 06:23:00 1993
--- lib/libc/gen/glob.3 Wed Jan 5 16:24:09 1994
***************
*** 31,40 ****
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
! .\" from: @(#)glob.3 8.1 (Berkeley) 6/9/93
.\" $Id: glob.3,v 1.7 1993/12/03 23:02:05 cgd Exp $
.\"
! .Dd June 9, 1993
.Dt GLOB 3
.Os
.Sh NAME
--- 31,40 ----
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
! .\" from: @(#)glob.3 8.1 (Berkeley) 1/5/94
.\" $Id: glob.3,v 1.7 1993/12/03 23:02:05 cgd Exp $
.\"
! .Dd January 5, 1994
.Dt GLOB 3
.Os
.Sh NAME
***************
*** 217,222 ****
--- 217,228 ----
This extension is provided to allow programs such as
.Xr restore 8
to provide globbing from directories stored on tape.
+ .It Dv GLOB_ALTNOT
+ Use
+ .Ql ^
+ instead of
+ .Ql !
+ as the negation character inside brackets.
.It Dv GLOB_BRACE
Pre-process the pattern string to expand
.Ql {pat,pat,...}
***************
*** 230,235 ****
--- 236,248 ----
of
.Xr find 1
patterns).
+ .It Dv GLOB_DOTFILES
+ Match files that start with a
+ .Ql \&. ,
+ without the explicit need for a
+ .Ql \&.
+ at the start of
+ .Fa pattern .
.It Dv GLOB_MAGCHAR
Set by the
.Fn glob
***************
*** 237,242 ****
--- 250,260 ----
See the description of the usage of the
.Fa gl_matchc
structure member for more details.
+ .It Dv GLOB_NODOT
+ Never match the filenames
+ .Dq \&.
+ and
+ .Dq \&.. .
.It Dv GLOB_NOMAGIC
Is the same as
.Dv GLOB_NOCHECK
***************
*** 413,419 ****
can be obtained with the
following code:
.Bd -literal -offset indent
! GLOB_t g;
g.gl_offs = 2;
glob("*.c", GLOB_DOOFFS, NULL, &g);
--- 431,437 ----
can be obtained with the
following code:
.Bd -literal -offset indent
! glob_t g;
g.gl_offs = 2;
glob("*.c", GLOB_DOOFFS, NULL, &g);
--
Luke Mewburn Programmer, Technical Services Group,
Email: <lm@rmit.edu.au> Department of Computer Science, RMIT
------------------------------------------------------------------------------