[comp.sources.d] PD version of "gmatch"?

alter@ttidca.TTI.COM (Steve Alter) (10/13/88)

Can someone point me to a public-domain (or at least legally copyable)
version of the "gmatch" routine?

Common programs such as "sh", "csh" and "find" use a function called
gmatch (csh actually calls it Gmatch) which has a header sort of like
this:

int
gmatch (string, pattern)
char  *string, *pattern;

and the function returns non-zero if the string fits the pattern.  The
pattern may contain '*', '?', or '[a-z]' style constructs.  You've all
seen this before; I'm just clarifying this to tell it apart from
regular expressions, which are entirely different beasts.

I've got a program that currently uses gmatch borrowed from the "find"
program and I can't post it to the net until I get a legally copyable
version of gmatch into it.

Thanks in advance,

-- Steve Alter
...!{csun,psivax,pyramid,quad1,rdlvax,retix}!ttidca!alter  or  alter@tti.com
Citicorp/TTI, Santa Monica CA  (213) 452-9191 x2541
-- 

-- Steve Alter
...!{csun,psivax,pyramid,quad1,rdlvax,retix}!ttidca!alter  or  alter@tti.com
Citicorp/TTI, Santa Monica CA  (213) 452-9191 x2541

jgreely@oz.cis.ohio-state.edu (J Greely) (10/14/88)

In article <3286@ttidca.TTI.COM> Steve Alter (alter@ttidca.tti.com) writes:
>Can someone point me to a public-domain (or at least legally copyable)
>version of the "gmatch" routine?

No, but I've got a quick substitute.

>and the function returns non-zero if the string fits the pattern.  The
>pattern may contain '*', '?', or '[a-z]' style constructs.  You've all
>seen this before;

>I'm just clarifying this to tell it apart from
>regular expressions, which are entirely different beasts.

Only in syntax.  And it's easy to transform between the two.

Use the regex package (Berkeley calls them re_comp and re_exec).  In
your pattern string, replace '?' with '.', '*' with '.*', and '[a-z]'
with itself.  re_exec will return 1 if the string matched the most
recently compiled pattern.  If you're going to use the same pattern
frequently, you'll probably (ok, definitely) want to compile it
outside your gmatch routine for efficiency.

  Don't have a good regex package?  Look in comp.sources.unix,
volume 7 (if you don't have an archive site nearby, I can send
it to you).
-- 
J Greely (jgreely@cis.ohio-state.edu; osu-cis!cis.ohio-state.edu!jgreely)
"The motto of the place is 'Knowledge in pursuit of excellence'.
 Not truth, not beauty, not art or science.  Just excellence."

oz@yunexus.UUCP (Ozan Yigit) (10/16/88)

gmatch is usually known as glob. I mailed you three different
versions, all of which are pd. Enjoy.

oz
-- 
To err is human; 	        	| Usenet: ...!utzoo!yunexus!oz
to really foul things up takes		|   ...uunet!mnetor!yunexus!oz
		SUN and AT&T...		| Bitnet: oz@[yulibra|yuyetti]
			  anon.		| Phonet: +1 416 736-5257x3976

alan@oetl.UUCP (Alan Strassberg) (10/18/88)

In article <3286@ttidca.TTI.COM> alter@ttidca.tti.com (Steve Alter) writes:
>
>Can someone point me to a public-domain (or at least legally copyable)
>version of the "gmatch" routine?

	[ from the posting in comp.os.minix of sh ]

/* -------- gmatch.c -------- */
/*
 * int gmatch(string, pattern)
 * char *string, *pattern;
 *
 * Match a pattern as in sh(1).
 */

#define	NULL	0
#define	CMASK	0377
#define	QUOTE	0200
#define	QMASK	(CMASK&~QUOTE)
#define	NOT	'!'	/* might use ^ */

static	char	*cclass();

int
gmatch(s, p)
register char *s, *p;
{
	register int sc, pc;

	if (s == NULL || p == NULL)
		return(0);
	while ((pc = *p++ & CMASK) != '\0') {
		sc = *s++ & QMASK;
		switch (pc) {
		case '[':
			if ((p = cclass(p, sc)) == NULL)
				return(0);
			break;

		case '?':
			if (sc == 0)
				return(0);
			break;

		case '*':
			s--;
			do {
				if (*p == '\0' || gmatch(s, p))
					return(1);
			} while (*s++ != '\0');
			return(0);

		default:
			if (sc != (pc&~QUOTE))
				return(0);
		}
	}
	return(*s == 0);
}

static char *
cclass(p, sub)
register char *p;
register int sub;
{
	register int c, d, not, found;

	if ((not = *p == NOT) != 0)
		p++;
	found = not;
	do {
		if (*p == '\0')
			return(NULL);
		c = *p & CMASK;
		if (p[1] == '-' && p[2] != ']') {
			d = p[2] & CMASK;
			p++;
		} else
			d = c;
		if (c == sub || c <= sub && sub <= d)
			found = !not;
	} while (*++p != ']');
	return(found? p+1: NULL);
}

-- 
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Alan Strassberg		UUCP: ..!{pyramid,leadsv}!oetl!alan
work (408) 425-6126		alan@oetl   (alan@leadsv)
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

henry@utzoo.uucp (Henry Spencer) (10/23/88)

In article <3286@ttidca.TTI.COM> alter@ttidca.tti.com (Steve Alter) writes:
>... I'm just clarifying this to tell it apart from
>regular expressions, which are entirely different beasts.

No, this is just another kind of regular expression.  Slightly different
syntax, same underlying concept.
-- 
The meek can have the Earth;    |    Henry Spencer at U of Toronto Zoology
the rest of us have other plans.|uunet!attcan!utzoo!henry henry@zoo.toronto.edu

john@basser.oz (John Mackin) (10/23/88)

In article <24641@tut.cis.ohio-state.edu>,
	jgreely@oz.cis.ohio-state.edu (J Greely) writes:

> In article <3286@ttidca.TTI.COM> Steve Alter (alter@ttidca.tti.com) writes:

> >and the function returns non-zero if the string fits the pattern.  The
> >pattern may contain '*', '?', or '[a-z]' style constructs.  You've all
> >seen this before;
> >I'm just clarifying this to tell it apart from
> >regular expressions, which are entirely different beasts.
> 
> Only in syntax.  And it's easy to transform between the two.
> 
> Use the regex package (Berkeley calls them re_comp and re_exec).  In
> your pattern string, replace '?' with '.', '*' with '.*', and '[a-z]'
> with itself.

Unfortunately, this doesn't work.  You have neglected to consider
the fact that the pattern given to gmatch may contain characters
that are metacharacters to regex but not gmatch: .[]^$ spring to
mind instantly.  If it was just .^$ you could easily add \ in
front of them, but character classes complicate it to where it's
barely worth doing in my opinion, and when you start to consider
the semantics of \ itself in the gmatch pattern, it's certainly
no harder to just write gmatch than it is to translate a gmatch
pattern into a regular expression.

John Mackin, Basser Department of Computer Science,
	     University of Sydney, Sydney, Australia

john@basser.oz.AU (john%basser.oz.AU@UUNET.UU.NET)
{uunet,mcvax,ukc,nttlab}!munnari!basser.oz!john