home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
112.lha
/
Match.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-11-20
|
9KB
|
359 lines
/*
*************************************************************************
* Match.c
* by Mike Pinson of MicroBotics, Inc. (based on YesNo by Joanne B. Dow)
*
* Version 2.0
*
* Match allows user interactive script files by prompting for
* operator input and comparing the response to a string. It
* returns a warn level error if the match fails. For example:
*
* Match yes|y no|n prompt "Are you sure? (yes/no) :" noblanks
* If not warn
* Echo "You typed 'yes' or 'y'"
* Else
* Echo "You typed 'no' or 'n'"
* EndIf
*
*************************************************************************
* Copyright 14-Feb-86 by Joanne Dow - original released for free
* distribution as long as this copyright notice is retained in the file.
*
* Modified 25-Jan-88 by Mike Pinson (copyright 1988, MicroBotics, Inc.) for
* Manx compile and added prompting and 'NOBLANKS' keywords to allow more
* complex operations (freely usable so long as both J. B. Dow's and
* MicroBotics' copyrights are presented intact.
*************************************************************************
*
* Usage:
* Match "match string"/A [,"fail string"] [,NOCAPS/S]
* [,PROMPT/K "prompt string"] [,NOBLANKS/S]
*
*
* "match string" string that allows a no-error exit
* "fail string" string that allows an error exit
* PROMPT "string" string to prompt with
* NOBLANKS switch to disallow blank lines (user MUST type
* the match string (or the fail string,
* if supplied))
* NOCAPS switch to make user input and match strings
* case-sensitive
*
*
* Example: prompt "Are you sure? (yes/no)"
* then accept only the answers "yes" or "y", "no" or "n"
* (no empty returns)
*
* Match yes|y no|n prompt "Are you sure? (yes/no) :" noblanks
*
* The "match string" MUST come before the "fail string", but this is
* the only ordering requirement. Single word switches will be parsed before
* two word keywords. So, the following line is equivalent in function to the
* line above: (though why you'ld want to write it this way is beyond me...)
*
* Match yes prompt noblanks "Are you sure? (yes/no) :" no
*
* If the user types "\n" or "go away" and you had specified noblanks, he'll
* get the message: "Please type only "match string" or "fail string"
*
* If NOBLANKS is NOT used and user just hits return, the match will fail.
*
*/
#include "stdio.h"
#define NO 6 /* warn level exit code */
#define YES 0 /* No warning exit code */
#define MaxString 255 /* Size of read buffer */
#ifndef TRUE
#define TRUE (1==1)
#define FALSE (1==0)
#endif
/************************************************************************/
/*
General string handling routines
*/
/************************************************************************/
/* upcase - upcase a string */
/************************************************************************/
char *upcase(a)
register char *a;
{
register char *cp;
cp = a;
while (*cp = toupper(*cp)) cp++;
return (a);
}
/************************************************************************/
/* mprint - print a string, decoding all escape sequences in bcpl */
/* or c format without the overhead of linking in printf */
/************************************************************************/
void mprint(a)
register char *a;
{
register char outc;
while (*a!='\0') {
if ((outc=*a) == '\\' || outc == '*') {
if (*(a+(char *)1) != '\0') a++;
switch (toupper(outc=*a)) {
case '0' : outc='\000'; break;
case 'B' : outc='\010'; break;
case 'E' : outc='\033'; break;
case 'F' : outc='\014'; break;
case 'N' : outc='\012'; break;
case 'R' : outc='\012'; break;
case 'T' : outc='\011'; break;
}
}
putchar(outc); a++;
}
}
/************************************************************************/
/* Strip - Strip spaces from beginning and end of a string */
/************************************************************************/
char *strip(s)
register char *s;
{
register int i;
while (s[0] == ' ') for (i=0; i<strlen(s); i++) s[i] = s[i+1];
while (((i=strlen(s))>1) && s[i-1]==' ') s[i-1] = '\0';
return (s);
}
/************************************************************************/
/*
Pattern matching routines
*/
int noblanks, nocaps;
char *strcat(), *strcpy(), *fgets();
char answer[MaxString];
#define MAXPATTERNS 10
typedef char PARRAY[MAXPATTERNS][81];
PARRAY matchpatterns, failpatterns;
/************************************************************************/
/* listp - list patterns in an array of strings */
/************************************************************************/
void listp(s,plist)
char s[];
PARRAY plist;
{
register int i=0,comma=FALSE;
mprint(s);
if (plist[1][0]=='\0') mprint(" ");
else mprint(" one of ");
while (plist[i][0] != '\0' && i<MAXPATTERNS) {
if (comma) mprint(", ");
comma = TRUE;
mprint("'");
mprint(plist[i++]);
mprint("'");
}
}
/************************************************************************/
/* ScanPattern - process match strings into a pattern array */
/************************************************************************/
void ScanPattern(s,plist)
char s[];
PARRAY plist;
{
register int i=0,j=0,k=0;
while (s[i] && j<MAXPATTERNS) {
while (s[i] && s[i]!='|') {
plist[j][k++]=s[i++];
}
strip(&plist[j][0]);
j++; k=0; if (s[i]) i++;
}
while (j<MAXPATTERNS) plist[j++][0] = '\0';
}
/************************************************************************/
/* matches - scan for a string anywhere in a pattern array */
/************************************************************************/
matches(string,plist)
char string[];
PARRAY plist;
{
register int i=0;
while (plist[i][0] != '\0' && i<MAXPATTERNS) {
if (strcmp(plist[i++],string)==0) return TRUE;
}
return FALSE;
}
/************************************************************************/
/* badanswer - if noblanks used, determines when the prompt should */
/* be repeated */
/************************************************************************/
badanswer(nargs,argc)
int nargs;
char *argc[];
{
if (answer[0]=='\n') return TRUE; /* it's bad */
if (matches(answer,matchpatterns)) return FALSE;
if (nargs==3)
if (matches(answer,failpatterns)) return FALSE;
return TRUE;
}
/************************************************************************/
/*
Main program
*/
main(argc, argv)
int argc;
char *argv[];
{
register int i,j,nargs;
int repeat;
char S[MaxString];
char *prompt;
nargs = argc;
/* set one word flags */
repeat = noblanks = nocaps = FALSE;
if (nargs>1) for (i=1; i<nargs;) {
strcpy (S,argv[i]);
upcase (S);
if (strcmp(S,"NOBLANKS") == 0) {
noblanks = TRUE;
if (i<nargs-1) for (j=i;j<nargs-1; j++)
argv[j] = argv[j+1];
argv[--nargs] = '\0';
} else
if (strcmp(S,"NOCAPS") == 0) {
nocaps = TRUE;
if (i<nargs-1) for (j=i;j<nargs-1; j++)
argv[j] = argv[j+1];
argv[--nargs] = '\0';
} else i++;
}
/* set prompt */
prompt = "";
if (nargs>2) for (i=1; i<nargs-1;) {
strcpy (S,argv[i]);
upcase (S);
if (strcmp(S,"PROMPT") == 0) {
prompt = argv[i+1];
if (i<nargs-2) for (j=i;j<nargs-2; j++)
argv[j] = argv[j+2];
argv[nargs-2] = argv[nargs-1] = '\0';
nargs -= 2;
} else i++;
}
/* does user need help? */
if ( nargs<=1 || (nargs==2 && argv[1][0] == '?')) {
if (argc>0) {
mprint("Usage:\n");
mprint(" Match \"match option\"/A,\"fail option\",PROMPT/K,NOCAPS/S,NOBLANKS/S\n");
mprint(" for match on multiple options, separate options with \"|\" as in \"Yes|y|ok\"\n");
mprint("\nCopyright (c)1988 MicroBotics, Inc. Enhancements by Mike Pinson.\n");
mprint( "Copyright (c)1986 Joanne Dow.\n\n");
}
exit(20);
}
/* do I need help? */
#ifdef DEBUG
printf("Prompt is: '%s'\n",prompt);
printf("Fname is: '%s'\n",fname);
printf("NoBlanks is %s.\n", noblanks?"on":"off");
printf("NoCaps is %s.\n", nocaps ?"on":"off");
for (i=0; i<argc-1; i++) printf("arg[%d] : '%s'\n",i,argv[i]);
printf("\n");
#endif
if (!nocaps) {
upcase(argv[1]); /* upcase match string */
if (nargs==3) upcase(argv[2]); /* upcase fail string */
}
ScanPattern(argv[1],matchpatterns);
if (nargs==3) ScanPattern(argv[2],failpatterns);
else ScanPattern("",failpatterns);
do {
if (repeat) {
listp("Please type",matchpatterns);
if (nargs==3) listp(" or",failpatterns);
mprint(".\n");
}
repeat = TRUE;
mprint (prompt);
fgets(answer, MaxString, stdin);
answer[strlen(answer)-1] = '\0'; /* erase newline */
strip(answer);
i=0; /* isolate first word */
while(answer[i]!='\0' && answer[i]!=' ') i++;
answer[i] = '\0';
if (!nocaps) {
upcase(answer); /* upcase user input */
}
} while (noblanks && (badanswer(nargs,argv)));
if (matches(answer,matchpatterns)) exit(YES);
else exit(NO);
}