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`