Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!bcm!shell!nuchat!sugar!peter
From: peter@sugar.uu.net (Peter da Silva)
Newsgroups: comp.sys.amiga
Subject: Re: Wildcard Support in dos.library
Message-ID: <3489@sugar.uu.net>
Date: 23 Feb 89 10:40:14 GMT
References: <9303@louie.udel.EDU>
Organization: Sugar Land Unix - Houston, TX
Lines: 284
In article <9303@louie.udel.EDU>, AXTBF%ALASKA.BITNET@cunyvm.cuny.edu (Tim Friest - programmer at large) writes:
> Where is the AmigaDOS equivilent to STR$MATCH_WILD (in VMS)??
-----8<----- it slices, it dices, it juliennes ------------------------------
echo x - PatMatch.c
sed 's/^X//' > PatMatch.c << '//END'
X/* PatMatch.c - Implements AmigaDos Regular Expression Pattern Matching.
X**
X** This program will test whether a string is an AmigaDos regular expression
X** It may be used to implement wild expressions such as:
X**
X** "copy #?.c to
" to copy any file ending in .c
X**
X** The program has two entry points: CmplPat, and Match.
X**
X** CmplPat - takes a pattern and returns an auxilliary integer vector
X** which is used by Match. The pattern is not modified in
X** any way. CmplPat returns 1 if no errors were detected
X** while compiling the pattern; otherwise it returns 0;
X**
X** Match - takes the pattern, the auxilliary vector, and the string
X** to be matched. It returns 1 if the string matches the
X** pattern; otherwise it returns 0;
X**
X** Translated from BCPL by:
X** Jeff Lydiatt
X** Richmond B.C. Canada
X** 16 May 1986.
X**
X** Source: "A Compact Function for Regular Expression Pattern Matching",
X** Software - Practice and Experience, September 1979.
X**
X** Useage:
X** To test if "file.c" matches the regular expression "#?.c"
X** char *Pat = "#?.c";
X** char *Str = "file.c";
X** WORD Aux[128];
X**
X** if ( CmplPat( Pat, Aux ) == 0 )
X** {
X** printf("Bad Wildcard Expression\n");
X** exit(1);
X** }
X** if ( Match( Pat, Aux, Str ) == 1 )
X** printf("String matches the pattern\n");
X** else
X** printf("String does NOT match the pattern\n");
X**/
X
X/*--- Included files ----*/
X
X#include
X#include
X#include
X
X#define EOS '\0'
X
X/*--- Global Variables ---*/
X
Xstatic char Ch; /* The current character in Pattern */
Xstatic char *Pat; /* Pointer to the Pattern */
Xstatic int *Aux; /* Pointer to returned auxilliary vector */
Xstatic int PatP; /* Current position in Pat */
Xstatic int Patlen; /* strlen(pat) */
Xstatic BOOL Errflag; /* TRUE if error */
Xstatic int *Work; /* Pointer to Active work area */
Xstatic int Wp; /* Current position in work */
Xstatic BOOL Succflag;/* True if "str" matches "pat" */
X
X/*----------------------------------------------------------------*/
X/* The Interpreter */
X/*----------------------------------------------------------------*/
X
Xstatic void Put(N)
Xint N;
X{
X register int *ip;
X register int *to;
X
X if ( N == 0 )
X Succflag = TRUE;
X else
X {
X for ( ip = &Work[ 1 ], to = &Work[ Wp ]; ip <= to; ip++)
X if ( *ip == N )
X return;
X Work[ ++Wp ] = N;
X }
X}
X
Xint Match( Pat, Aux, Str )
Xchar Pat[];
Xint Aux[];
Xchar Str[];
X{
X static int W[ 128 ];
X int S = 0;
X int I, N, Q, P, Strlength;
X char K;
X int strlen();
X void Put();
X
X Work = W;
X Wp = 0;
X Succflag = FALSE;
X Strlength = strlen( Str );
X Put( 1 );
X
X if ( Aux[ 0 ] != 0 )
X Put( Aux[ 0 ] );
X
X for(;;)
X {
X /* First complete the closure */
X for( N=1; N <= Wp; N++ )
X {
X P = Work[ N ];
X K = Pat[ P-1 ];
X Q = Aux[ P ];
X switch( K )
X {
X case '#': Put( P + 1 );
X case '%': Put( Q );
X default : break;
X case '(':
X case '|': Put( P + 1);
X if ( Q != 0 )
X Put( Q );
X }
X }
X
X if ( S >= Strlength )
X return Succflag;
X if ( Wp == 0 )
X return FALSE;
X Ch = Str[ S++ ];
X
X /* Now deal with the match items */
X
X N = Wp;
X Wp = 0;
X Succflag = FALSE;
X
X for ( I = 1; I <= N; I++)
X {
X P = Work[ I ];
X K = Pat[ P - 1 ];
X switch( K )
X {
X case '#':
X case '|':
X case '%':
X case '(': break;
X case '\'': K = Pat[ P ];
X default : if ( _toupper( Ch ) != _toupper( K ) )
X break;
X case '?': /* Successful match */
X Put ( Aux[ P ] );
X } /* End Switch */
X } /* End For I */
X } /* End for(;;) */
X}
X
X
X/*----------------------------------------------------------------*/
X/* The Compiler */
X/*----------------------------------------------------------------*/
X
Xstatic void Rch() /* Read next character from Pat */
X{
X if ( PatP >= Patlen )
X Ch = EOS;
X else
X Ch = Pat[ PatP++ ];
X}
X
Xstatic void Nextitem() /* Get next char from Pat; recognize the ' escape char */
X{
X if ( Ch == '\'' )
X Rch();
X Rch();
X}
X
Xstatic void Setexits( List, Val )
Xint List;
Xint Val;
X{
X int A;
X
X do
X {
X A = Aux[ List ];
X Aux[ List ] = Val;
X List = A;
X }
X while ( List != 0 );
X}
X
Xstatic int Join( A, B )
Xint A, B;
X{
X int T = A;
X
X if ( A == 0 )
X return B;
X while ( Aux[ A ] != 0 )
X A = Aux[ A ];
X Aux[ A ] = B;
X return T;
X}
X
Xstatic int Prim() /* Parse a Prim symbol */
X{
X int A = PatP;
X char Op = Ch;
X int Exp();
X void Setexits(), Nextitem();
X
X Nextitem();
X switch( Op )
X {
X case EOS:
X case ')':
X case '|': Errflag = TRUE;
X default : return A;
X case '#': Setexits( Prim(), A ); return A;
X case '(': A = Exp( A );
X if ( Ch != ')' )
X {
X Errflag = TRUE;
X }
X Nextitem();
X return A;
X }
X}
X
Xstatic int Exp( AltP ) /* Parse an expression */
Xint AltP;
X{
X int Exits = 0;
X int A;
X int Prim(), Exits(), Join();
X void Nextitem(), Setexits();
X
X for (;;)
X {
X A = Prim();
X if ( Ch == '|' || Ch == ')' || Ch == EOS )
X {
X Exits = Join( Exits, A );
X if ( Ch != '|' )
X return Exits;
X Aux[ AltP ] = PatP;
X AltP = PatP;
X Nextitem();
X }
X else
X Setexits( A, PatP );
X }
X}
X
Xint CmplPat( Pattern, CmplPattern)
Xchar Pattern[];
Xint CmplPattern[];
X{
X int i, strlen();
X void Rch(), Setexits();
X
X Pat = Pattern;
X Aux = CmplPattern;
X PatP = 0;
X Patlen = strlen( Pat );
X Errflag = FALSE;
X
X for ( i = 0; i <= Patlen; i++ )
X Aux[ i ] = 0;
X Rch();
X Setexits( Exp(0), 0 );
X return (!Errflag);
X}
//END
--
Peter "Have you hugged your wolf today" da Silva `-_-' Hackercorp.
...texbell!sugar!peter, or peter@sugar.uu.net 'U`