Path: utzoo!attcan!uunet!crdgw1!sixhub!davidsen From: davidsen@sixhub.UUCP (Wm E. Davidsen Jr) Newsgroups: alt.sources Subject: amatch Message-ID: <3@sixhub.UUCP> Date: 17 Aug 89 02:25:34 GMT Organization: *IX Public Access UNIX Lines: 255 Distribution: In digging for something else the other day I found this, the heart of a routine to do wildcard matching and name expansion in MS-DOS. This procedure does a match between a test string and a wildcard pattern using the Bourne shell conventions. It's sort of like regexp but with another set of conventions. I wrote a man page, and here it is. I will be posting the rest of the package as I get the man pages written, the directory search package and the actual command line expander. If anyone is trying to get things from the archive server, uunet's maps don't seem to show sixhub correctly, mail to it is not bounced, but it doesn't get here, either. Here's how to reach the server: uucp: uunet!crdgw1!sixhub!archive-server inet: sixhub!archive-server@crdgw1.crd.ge.com The message test should include a line with: send index to YOURADDRESS - or - send help to YOURADDRESS where address is either site!user or user@site.domain. #!/bin/sh # shar: Shell Archiver (v1.24) # # Run the following text with /bin/sh to create: # amatch.1 # amatch.c # echo "x - extracting amatch.1 (Text)" sed 's/^X//' << 'SHAR_EOF' > amatch.1 && X.TH AMATCH 3 Local X.SH NAME Xamatch - match string against wildcard pattern using shell conventions X.SH SYNOPSIS X.B amatch Xcompares a test string against a wildacrd pattern using the conventions Xof the Bourne shell, rather than standard regular expressions. This was Xoriginally written for MS-DOS, but may be generally useful. X.SH DESCRIPTION X.ft B X.in +.5i X int amatch(wildcard, teststr) X const char *wildcard, *teststr X.in -.5i X.ft P X.SH EXAMPLES X gets(buffer); X if (!amatch("*.[ch]", buffer)) unlink(buffer); X.SH WARNINGS XAlthough tested and in use for several years, this program may not Xproduce the same output as \fBglob\fP, assuming anyone still uses it. X.SH FILES Xnone. X.SH LIMITATIONS XNone known. X.SH AUTHOR XBill Davidsen, 1985. (davidsen@crdos1.crd.ge.com) X.SH Copyright XCopyright (c) 1985, 1989 by Bill Davidsen. This program may be freely Xgiven, bartered, traded or sold by anyone for any purpose. The supplier Xassumes all risk for any consequences of malfunction. All other rights Xreserved. X SHAR_EOF chmod 0644 amatch.1 || echo "restore of amatch.1 fails" echo "x - extracting amatch.c (Text)" sed 's/^X//' << 'SHAR_EOF' > amatch.c && X/***************************************************************** X | amatch - match a string against a wildcard pattern X |---------------------------------------------------------------- X | Compares a data string against a test pattern using Bourne shell X | wildcard rules (*not* regular expression rules). X | X | This routine is ugly and not well structured. X | X | Author: Bill Davidsen (davidsen@crdos1.crd.ge.com) Mar 24, 1985 X | with helpful suggestions from Andy Robinson X |---------------------------------------------------------------- X | Copyright: X | Copyright (c) 1985, 1989 by Bill Davidsen. This program may be X | freely given, bartered, traded or sold by anyone for any X | purpose. The supplier assumes all risk for any consequences of X | malfunction. All other rights reserved. X |---------------------------------------------------------------- X | Arguments: X | 1 - address of wildcard pattern X | 2 - address of string to test X ****************************************************************/ X X#ifndef TRUE X#define TRUE 1 X#define FALSE 0 X#endif X Xint amatch(ts, cs) Xregister char *ts, *cs; X{ X int low, hi, notf; X X while (1) { /* keep going until done */ X X if (*cs == '\0') { /* out of string */ X for (; *ts == '*'; ++ts) X ; /* get rid of extra '*' */ X return(*ts == '\0'); X } X X switch (*ts) { X X case '\0': X return(FALSE); X X case '[': /* the hardest case (see '*' below) */ X X /* is the not flag set? */ X if (notf = (*(ts + 1) == '!')) X ++ts; /* ! flag set */ X X /* loop through the bracket */ X while (*++ts != ']' && *ts != '\0') { X X if (*ts == '-') { /* a range of values */ X X /* get lower limit */ X if ((*--ts == '[' || *ts == '!') X && *(ts - 1) != '\\') X low = '\0'; X else X low = *ts; X X /* get upper limit */ X if (*(ts += 2) == ']' || *ts == '\0') { X hi = '\377'; X --ts; X } X else { X if (*ts == '\\' && X *++ts == '\0') { X --ts; X hi = '\377'; X } X else X hi = *ts; X } X X /* and compare */ X if (*cs > low && *cs <= hi) X goto foo; X X continue; /* in bracket loop */ X } X X /* process wildcard */ X if (*ts == '\\' && *++ts == '\0') X break; /* bump and check for \0 */ X X /* check if they are the same */ X if (*cs == *ts) X goto foo; X X } /* while */ X X /* get here if no match (out of ts or reached ]) */ X if (!notf) X return(FALSE); X if (*ts) X ++ts; X break; X X /* come here if a match */ X foo: if (notf) X return(FALSE); X ++ts; X while (*ts != '\0' && *ts++ != ']') X ; /* get to end of bracket */ X break; X X case '*': /* a chicken way out! my only recursive part */ X while (*++ts == '*') X ; /* get rid of extra '*' */ X X if (!*ts) /* trailing '*' matches anything */ X return(TRUE); X X do X if (amatch(ts, cs)) X return(TRUE); X while (*++cs); X return(*ts == '\0'); X X case '?': /* just bump the pointers */ X ++ts; X break; X X case '\\': /* this drops through to next one */ X ++ts; X X default: /* if they ain't the same here forget it */ X if (*cs != *ts++) X return(FALSE); X } /* switch */ X X ++cs; X X } /* while (1) */ X X} /* match */ X X/***************************************************************** X | test program for amatch X |---------------------------------------------------------------- X | Reads patterns and paths until none given. X ****************************************************************/ X X#ifdef TEST X#include X Xstatic getline(); X Xmain() { X char data[80], pattern[80]; X int match; X X do { X /* read wildcard patterns */ X printf("Enter pattern: "); X getline(pattern, 80); X if (strlen(pattern)) { X /* read test cases */ X do { X printf(" Enter test data: "); X getline(data, 80); X if (strlen(data)) { X match = amatch(pattern, data); X printf("\t%s\n", (match ? "YES" : "NO")); X } X } while (strlen(data)); X } X } while (strlen(pattern)); X} X Xstatic Xgetline(buffer, len) X char *buffer; X int len; X{ X fgets(buffer, len, stdin); X len = strlen(buffer) - 1; X if (buffer[len] == '\n') buffer[len] = 0; X} X#endif SHAR_EOF chmod 0644 amatch.c || echo "restore of amatch.c fails" exit 0