Metropoli BBS
VIEWER: amatch.c MODE: TEXT (ASCII)
/*****************************************************************
 | amatch - match a string against a wildcard pattern
 |----------------------------------------------------------------
 |  Compares a data string against a test pattern using Bourne shell
 |  wildcard rules (*not* regular expression rules).
 |
 |  This routine is ugly and not well structured.
 |
 |  Author: Bill Davidsen (davidsen@crdos1.crd.ge.com) Mar 24, 1985
 |        with helpful suggestions from Andy Robinson
 |----------------------------------------------------------------
 |  Copyright:
 |    Copyright (c) 1985, 1989 by Bill Davidsen. This program may be
 |    freely given, bartered, traded or sold by anyone for any
 |    purpose. The supplier assumes all risk for any consequences of
 |    malfunction. All other rights reserved.
 |----------------------------------------------------------------
 |  Arguments:
 |   1 - address of wildcard pattern
 |   2 - address of string to test
 ****************************************************************/

#include <string.h>

#ifndef TRUE
#define TRUE    1
#define FALSE   0
#endif

int amatch(register char *ts, register char *cs)
{
	int low, hi, notf;

	while (1) { /* keep going until done */

		if (*cs == '\0') { /* out of string */
			for (; *ts == '*'; ++ts)
				; /* get rid of extra '*' */
			return(*ts == '\0');
		}

		switch (*ts) {

		case '\0':
			return(FALSE);

		case '[': /* the hardest case (see '*' below) */

			   /* is the not flag set? */
			if (notf = (*(ts + 1) == '!'))
				++ts; /* ! flag set */

			   /* loop through the bracket */
			while (*++ts != ']' && *ts != '\0') {

				if (*ts == '-') { /* a range of values */

					    /* get lower limit */
					if ((*--ts == '[' || *ts == '!')
							   && *(ts - 1) != '\\')
						low = '\0';
					else
						low = *ts;

					    /* get upper limit */
					if (*(ts += 2) == ']' || *ts == '\0') {
						hi = '\377';
						--ts;
					}
					else {
						if (*ts == '\\' &&
								*++ts == '\0') {
							--ts;
							hi = '\377';
						}
						else
							hi = *ts;
					}

					     /* and compare */
					if (*cs > (char) low && *cs <= (char) hi)
						goto foo;

					continue; /* in bracket loop */
				}

				    /* process wildcard */
				if (*ts == '\\' && *++ts == '\0')
					break; /* bump and check for \0 */

				/* check if they are the same */
				if (*cs == *ts)
					goto foo;

			} /* while */

			/* get here if no match (out of ts or reached ]) */
			if (!notf)
				return(FALSE);
			if (*ts)
				++ts;
			break;

			/* come here if a match */
		foo:    if (notf)
				return(FALSE);
			++ts;
			while (*ts != '\0' && *ts++ != ']')
				; /* get to end of bracket */
			break;

		case '*': /* a chicken way out! my only recursive part */
			while (*++ts == '*')
				; /* get rid of extra '*' */

			if (!*ts) /* trailing '*' matches anything */
				return(TRUE);

			do
				if (amatch(ts, cs))
					return(TRUE);
			while (*++cs);
			return(*ts == '\0');

		case '?': /* just bump the pointers */
			++ts;
			break;

		case '\\': /* this drops through to next one */
			++ts;

		default: /* if they ain't the same here forget it */
			if (*cs != *ts++)
				return(FALSE);
		} /* switch */

		++cs;

	} /* while (1) */

} /* match */

/*****************************************************************
 |  test program for amatch
 |----------------------------------------------------------------
 |  Reads patterns and paths until none given.
 ****************************************************************/

#ifdef	TEST
#include <stdio.h>

static void getline(char *buffer, int len);

void main(void)
{
	char data[80], pattern[80];
	int match;

	do {
		/* read wildcard patterns */
		printf("Enter pattern: ");
		getline(pattern, 80);
		if (strlen(pattern)) {
			/* read test cases */
			do {
				printf("  Enter test data: ");
				getline(data, 80);
				if (strlen(data)) {
					match = amatch(pattern, data);
					printf("\t%s\n", (match ? "YES" : "NO"));
				}
			} while (strlen(data));
		}
	} while (strlen(pattern));
}

static void getline(char *buffer, int len)
{
	fgets(buffer, len, stdin);
	len = strlen(buffer) - 1;
	if (buffer[len] == '\n') buffer[len] = 0;
}
#endif
[ RETURN TO DIRECTORY ]