Pattern recognition in C (wanted)
Gary S. Moss (AMXBR-VLD-V)
moss at Brl-Vld.ARPA
Thu Jan 17 13:02:21 AEST 1985
#!/bin/sh
# Josh -
# I wrote a boolean function which mimics UNIX shell file name
# expansion in the attempt to match its first argument with its
# second. Matchtest.c is a test driver for it.
#
#
# Self-unpacking archive format. To unbundle, sh this file.
echo 'match.c' 1>&2
cat >'match.c' <<'END OF match.c'
/*
SCCS id: @(#) match.c 1.3
Last edit: 1/16/85 at 21:18:57
Retrieved: 1/16/85 at 21:19:58
SCCS archive: /vld/moss/work/libWIND/s.match.c
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
(301)278-6647 or AV-283-6647
*/
static
char sccsTag[] = "@(#) match.c 1.3 last edit 1/16/85 at 21:18:57";
#include <stdio.h>
#include <string.h>
#include "./ascii.h"
extern void prnt1Err();
/* m a t c h ( )
if string matches pattern, return 1, else return 0
special characters:
* Matches any string including the null string.
? Matches any single character.
[...] Matches any one of the characters enclosed.
[!..] Matchea any character NOT enclosed.
- May be used inside brackets to specify range
(i.e. str[1-58] matches str1, str2, ... str5, str8)
\ Escapes special characters.
*/
match( pattern, string )
register
char *pattern, *string;
{
do
{
switch( pattern[0] )
{
case '*': /* Match any string including null string. */
if( pattern[1] == NUL || string[0] == NUL )
return 1;
while( string[0] != NUL )
{
if( match( &pattern[1], string ) )
return 1;
++string;
}
return 0;
case '?': /* Match any character. */
break;
case '[': /* Match one of the characters in brackets
unless first is a '!', then match
any character not inside brackets.
*/
{ register char *rgtBracket;
static int negation;
++pattern; /* Skip over left bracket. */
/* Find matching right bracket. */
if( (rgtBracket = strchr( pattern, ']' )) == NULL )
{
prnt1Err( "Unmatched '['." );
return 0;
}
/* Check for negation operator. */
if( pattern[0] == '!' )
{
++pattern;
negation = 1;
}
else {
negation = 0;
}
/* Traverse pattern inside brackets. */
for( ;
pattern < rgtBracket
&& pattern[0] != string[0];
++pattern
)
{
if( pattern[ 0] == '-'
&& pattern[-1] != '\\'
)
{
if( pattern[-1] <= string[0]
&& pattern[-1] != '['
&& pattern[ 1] >= string[0]
&& pattern[ 1] != ']'
)
break;
}
}
if( pattern == rgtBracket )
{
if( ! negation )
{
return 0;
}
}
else
{
if( negation )
{
return 0;
}
}
pattern = rgtBracket; /* Skip to right bracket. */
break;
}
case '\\': /* Escape special character. */
++pattern;
/* WARNING: falls through to default case. */
default: /* Compare characters. */
if( pattern[0] != string[0] )
return 0;
}
++pattern;
++string;
}
while( pattern[0] != NUL && string[0] != NUL );
if( (pattern[0] == NUL || pattern[0] == '*' ) && string[0] == NUL )
{
return 1;
}
else
{
return 0;
}
}
END OF match.c
echo 'matchtest.c' 1>&2
cat >'matchtest.c' <<'END OF matchtest.c'
/*
SCCS id: @(#) matchtest.c 1.2
Last edit: 1/16/85 at 21:19:12
Retrieved: 1/16/85 at 21:20:06
SCCS archive: /vld/moss/work/libWIND/s.matchtest.c
Author: Gary S. Moss
U. S. Army Ballistic Research Laboratory
Aberdeen Proving Ground
Maryland 21005-5066
(301)278-6647 or AV-283-6647
*/
#if ! defined( lint )
static
char sccsTag[] = "@(#) matchtest.c 1.2 last edit 1/16/85 at 21:19:12";
#endif
#include <stdio.h>
extern int match();
char *usage[] = {
"",
"matchtest(1.2)",
"",
"Usage: matchtest [pattern string]",
"",
"If no arguments are given, the program reads words on its standard input.",
"The program writes to its standard output.",
0
};
void prntUsage(), prnt1Err();
static char *pattern, *string;
static char patbuf[BUFSIZ], strbuf[BUFSIZ];
/* m a i n ( )
*/
main( argc, argv )
char *argv[];
{
if( ! parsArgv( argc, argv ) )
{
prntUsage();
exit( 1 );
}
if( pattern != NULL )
{
if( match( pattern, string ) )
{
(void) printf( "'%s' matches '%s'.\n", pattern, string );
exit( 0 );
}
else
{
(void) printf( "'%s' does not match '%s'.\n",
pattern,
string
);
exit( 1 );
}
}
while( scanf( "%s %s", patbuf, strbuf ) == 2 )
{
if( match( patbuf, strbuf ) )
{
(void) printf( "'%s' matches '%s'.\n", patbuf, strbuf );
}
else
{
(void) printf( "'%s' does not match '%s'.\n",
patbuf,
strbuf
);
}
}
exit( 0 );
}
/* p a r s A r g v ( )
*/
parsArgv( argc, argv )
register char **argv;
{
register int c;
extern int optind;
extern char *optarg;
/* Parse options. */
while( (c = getopt( argc, argv, "" )) != EOF )
{
switch( c )
{
case '?' :
return 0;
}
}
if( argc - optind != 2 )
{
if( argc == optind )
{
pattern = string = NULL;
}
else
{
(void) fprintf( stderr, "Arg count wrong!\n" );
return 0;
}
}
else
{
pattern = argv[optind++];
string = argv[optind++];
}
return 1;
}
/* p r n t U s a g e ( )
Print usage message.
*/
void
prntUsage()
{
register char **p = usage;
while( *p )
(void) fprintf( stderr, "%s\n", *p++ );
return;
}
END OF matchtest.c
More information about the Comp.lang.c
mailing list