*BSD News Article 11267


Return to BSD News archive

Received: by minnie.vk1xwt.ampr.org with NNTP
	id AA1482 ; Tue, 23 Feb 93 14:43:29 EST
Path: sserve!manuel.anu.edu.au!munnari.oz.au!bruce.cs.monash.edu.au!monu6!escargot!minyos.xx.rmit.OZ.AU!s902113
From: s902113@minyos.xx.rmit.OZ.AU (Luke Mewburn)
Newsgroups: comp.unix.bsd
Subject: 386bsd, net/2 libc/gen/glob.c improvements
Date: 18 Feb 1993 16:23:52 GMT
Organization: RMIT Computer Centre
Lines: 359
Message-ID: <1m0d6oINNaj9@escargot.xx.rmit.OZ.AU>
NNTP-Posting-Host: minyos.xx.rmit.oz.au


I've made a couple of minor improvements to the glob code in 386bsd
(which I assume is the same as, or similar to the version with net/2).
They are:
    - ability to glob . files w/o the need for the explicit . at the
      start of the pattern (add GLOB_DOTFILES to the flags)
    - ability to never glob . or .., no matter what. (add GLOB_NODOT)
    - ability to use ^ instead of ! for the not char. (add
      GLOB_ALTNOT). This came from a similar improvement I saw in the
      hacked version used in tcsh

The diff file follows, with changes to the manual as well. I'll post
my hacks to csh to use this (via 'set dotfiles' and 'set nodot'
respectively). (and the hacks to tcsh - even tho it uses a different
(maybe older?) version of the glob code will be posted RSN too)



*** usr/src/libc/gen/glob.3.PZ	Sat Feb  6 12:30:29 1993
--- usr/src/libc/gen/glob.3	Sat Feb  6 16:15:53 1993
***************
*** 33,39 ****
  .\"
  .\"     @(#)glob.3	5.6 (Berkeley) 7/31/91
  .\"
! .Dd July 31, 1991
  .Dt GLOB 3
  .Os
  .Sh NAME
--- 33,39 ----
  .\"
  .\"     @(#)glob.3	5.6 (Berkeley) 7/31/91
  .\"
! .Dd February 6, 1993
  .Dt GLOB 3
  .Os
  .Sh NAME
***************
*** 119,125 ****
  of any of the following
  values defined in
  .Pa glob.h :
! .Bl -tag -width GLOB_NOCHECK
  .It Dv GLOB_APPEND
  Append pathnames generated to the ones from a previous call (or calls)
  to
--- 119,132 ----
  of any of the following
  values defined in
  .Pa glob.h :
! .Bl -tag -width GLOB_DOTFILES
! .It Dv GLOB_ALTNOT
! Use
! .Ql ^
! instead of
! .Ql !
! as the negation character following a
! .Ql [ .
  .It Dv GLOB_APPEND
  Append pathnames generated to the ones from a previous call (or calls)
  to
***************
*** 139,144 ****
--- 146,158 ----
  .Fn globfree
  for
  .Fa pglob .
+ .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_DOOFFS
  Make use of the
  .Fa gl_offs
***************
*** 187,192 ****
--- 201,211 ----
  If
  .Dv GLOB_QUOTE
  is set, its effect is present in the pattern returned.
+ .It Dv GLOB_NODOT
+ Never match the filenames
+ .Dq \&.
+ and
+ .Dq \&.. .
  .It Dv GLOB_NOMAGIC
  Is the same as 
  .Dv GLOB_NOCHECK 
***************
*** 343,352 ****
  function is expected to be
  .St -p1003.2
  compatible with the exception
! that the flag 
! .Dv GLOB_QUOTE
  and the fields 
! .Fa gl_matchc
  and 
  .Fa gl_flags
  should not be used by applications striving for strict
--- 362,375 ----
  function is expected to be
  .St -p1003.2
  compatible with the exception
! that the flags
! .Dv GLOB_ALTNOT ,
! .Dv GLOB_DOTFILES ,
! .Dv GLOB_NODOT ,
! and
! .Dv GLOB_QUOTE ,
  and the fields 
! .Fa gl_matchc ,
  and 
  .Fa gl_flags
  should not be used by applications striving for strict
***************
*** 358,364 ****
  can be obtained with the
  following code:
  .Bd -literal -offset indent
! GLOB_t g;
  
  g.gl_offs = 2;
  glob("*.c", GLOB_DOOFFS, NULL, &g);
--- 381,387 ----
  can be obtained with the
  following code:
  .Bd -literal -offset indent
! glob_t g;
  
  g.gl_offs = 2;
  glob("*.c", GLOB_DOOFFS, NULL, &g);
*** usr/src/libc/gen/glob.c.PZ	Mon Jun 24 15:35:42 1991
--- usr/src/libc/gen/glob.c	Sat Feb  6 16:18:15 1993
***************
*** 48,55 ****
--- 48,61 ----
   * GLOB_QUOTE:
   *	Escaping convention: \ inhibits any special meaning the following
   *	character might have (except \ at end of string is retained).
+  * GLOB_DOTFILES:
+  *	.files don't need to explicitly matched with '.*' or the like.
+  * GLOB_NODOT:
+  *	Never match "." and ".."
   * GLOB_MAGCHAR:
   *	Set in gl_flags if pattern contained a globbing character.
+  * GLOB_ALTNOT:
+  *	Use ^ instead of ! for "not".
   * gl_matchc:
   *	Number of matches in the current invocation of glob.
   */
***************
*** 70,75 ****
--- 76,82 ----
  #define	EOS		'\0'
  #define	LBRACKET	'['
  #define	NOT		'!'
+ #define	ALTNOT		'^'
  #define	QUESTION	'?'
  #define	QUOTE		'\\'
  #define	RANGE		'-'
***************
*** 89,94 ****
--- 96,102 ----
  #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('[')
***************
*** 111,116 ****
--- 119,126 ----
  static void	 qprintf __P((Char *));
  #endif
  
+ static int	not_c, m_not_c;
+ 
  /*
   * The main glob() routine: compiles the pattern (optionally processing
   * quotes), calls glob1() to do the real pattern matching, and finally
***************
*** 139,144 ****
--- 149,162 ----
  	oldpathc = pglob->gl_pathc;
  	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;
  	compilebuf = bufnext;
***************
*** 169,186 ****
  		case LBRACKET:
  			pglob->gl_flags |= GLOB_MAGCHAR;
  			c = *qpatnext;
! 			if (c == NOT)
  				++qpatnext;
  			if (*qpatnext == EOS ||
  			    g_strchr(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);
--- 187,204 ----
  		case LBRACKET:
  			pglob->gl_flags |= GLOB_MAGCHAR;
  			c = *qpatnext;
! 			if (c == not_c)
  				++qpatnext;
  			if (*qpatnext == EOS ||
  			    g_strchr(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);
***************
*** 332,341 ****
  	    
  	if (!(dirp = g_opendir(pathbuf)))
  		/* TODO: don't call for ENOENT or ENOTDIR? */
! 		if (pglob->gl_errfunc &&
! 		    (*pglob->gl_errfunc)(pathbuf, errno) ||
! 		    (pglob->gl_flags & GLOB_ERR))
  			return(GLOB_ABEND);
  		else
  			return(0);
  
--- 350,365 ----
  	    
  	if (!(dirp = g_opendir(pathbuf)))
  		/* TODO: don't call for ENOENT or ENOTDIR? */
! 		if (pglob->gl_errfunc) {
! 		    char buf[MAXPATHLEN];
! 
! 		    g_Ctoc(pathbuf, buf);
! 		    if ((*pglob->gl_errfunc)(buf, errno) ||
! 			(pglob->gl_flags & GLOB_ERR))
  			return(GLOB_ABEND);
+ 		    else
+ 			return(0);
+ 		}
  		else
  			return(0);
  
***************
*** 346,354 ****
  		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++;);
  		if (!match(pathend, pattern, restpattern)) {
--- 370,386 ----
  		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 != '.')
! 					continue;
! 		}
  		for (sc = (u_char *) dp->d_name, dc = pathend; 
  		     *dc++ = *sc++;);
  		if (!match(pathend, pattern, restpattern)) {
***************
*** 442,448 ****
  		case M_SET:
  			ok = 0;
  			k = *name++;
! 			if (negate_range = ((*pat & M_MASK) == M_NOT))
  				++pat;
  			while (((c = *pat++) & M_MASK) != M_END)
  				if ((*pat & M_MASK) == M_RNG) {
--- 474,480 ----
  		case M_SET:
  			ok = 0;
  			k = *name++;
! 			if (negate_range = ((*pat & M_MASK) == m_not_c))
  				++pat;
  			while (((c = *pat++) & M_MASK) != M_END)
  				if ((*pat & M_MASK) == M_RNG) {
***************
*** 544,556 ****
  	register Char *p;
  
  	for (p = s; *p; p++)
! 		(void)printf("%c", *p & 0xff);
  	(void)printf("\n");
  	for (p = s; *p; p++)
  		(void)printf("%c", *p & M_PROTECT ? '"' : ' ');
  	(void)printf("\n");
  	for (p = s; *p; p++)
! 		(void)printf("%c", *p & M_META ? '_' : ' ');
  	(void)printf("\n");
  }
  #endif
--- 576,588 ----
  	register Char *p;
  
  	for (p = s; *p; p++)
! 		(void)printf("%c", CHAR(*p));
  	(void)printf("\n");
  	for (p = s; *p; p++)
  		(void)printf("%c", *p & M_PROTECT ? '"' : ' ');
  	(void)printf("\n");
  	for (p = s; *p; p++)
! 		(void)printf("%c", ismeta(*p) ? '_' : ' ');
  	(void)printf("\n");
  }
  #endif
*** usr/include/glob.h.PZ	Sat Feb  6 12:28:02 1993
--- usr/include/glob.h	Sat Feb  6 15:56:03 1993
***************
*** 59,64 ****
--- 59,67 ----
  #define	GLOB_NOSORT	0x40	/* don't sort */
  #ifndef _POSIX_SOURCE
  #define	GLOB_QUOTE	0x80	/* quote special chars with \ */
+ #define GLOB_DOTFILES	0x100	/* match .* files with * */
+ #define GLOB_NODOT	0x200	/* never match . and .. */
+ #define GLOB_ALTNOT	0x400	/* use ^ instead of ! as [ not char */
  #endif
  
  #define	GLOB_NOSPACE	(-1)	/* malloc call failed */