home *** CD-ROM | disk | FTP | other *** search
- /*
- *************************************************************************
- * 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);
- }
-