home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 112.lha / Match.c < prev    next >
C/C++ Source or Header  |  1986-11-20  |  9KB  |  359 lines

  1. /*
  2.  *************************************************************************
  3.  * Match.c 
  4.  * by Mike Pinson of MicroBotics, Inc. (based on YesNo by Joanne B. Dow)
  5.  *
  6.  * Version 2.0
  7.  *
  8.  *    Match allows user interactive script files by prompting for
  9.  *    operator input and comparing the response to a string.  It
  10.  *    returns a warn level error if the match fails.   For example:
  11.  *
  12.  *    Match yes|y no|n prompt "Are you sure? (yes/no) :" noblanks
  13.  *    If not warn
  14.  *      Echo "You typed 'yes' or 'y'"
  15.  *    Else
  16.  *      Echo "You typed 'no' or 'n'"
  17.  *    EndIf
  18.  *
  19.  *************************************************************************
  20.  * Copyright 14-Feb-86  by Joanne Dow   - original released for free
  21.  * distribution as long as this copyright notice is retained in the file.
  22.  *
  23.  * Modified 25-Jan-88 by Mike Pinson (copyright 1988, MicroBotics, Inc.) for
  24.  * Manx compile and added prompting and 'NOBLANKS' keywords to allow more
  25.  * complex operations (freely usable so long as both J. B. Dow's and
  26.  * MicroBotics' copyrights are presented intact.
  27.  *************************************************************************
  28.  *
  29.  * Usage:
  30.  *    Match "match string"/A [,"fail string"] [,NOCAPS/S]
  31.  *                 [,PROMPT/K "prompt string"] [,NOBLANKS/S]
  32.  *
  33.  *
  34.  *    "match string"        string that allows a no-error exit
  35.  *    "fail string"        string that allows an error exit
  36.  *    PROMPT "string"        string to prompt with
  37.  *    NOBLANKS        switch to disallow blank lines (user MUST type
  38.  *                    the match string (or the fail string,
  39.  *                    if supplied))
  40.  *    NOCAPS            switch to make user input and match strings
  41.  *                    case-sensitive
  42.  *
  43.  *
  44.  * Example:    prompt "Are you sure? (yes/no)"
  45.  *        then accept only the answers "yes" or "y", "no" or "n"
  46.  *            (no empty returns)
  47.  *
  48.  *    Match yes|y no|n prompt "Are you sure? (yes/no) :" noblanks
  49.  *
  50.  * The "match string" MUST come before the "fail string", but this is
  51.  * the only ordering requirement.  Single word switches will be parsed before
  52.  * two word keywords.  So, the following line is equivalent in function to the
  53.  * line above: (though why you'ld want to write it this way is beyond me...)
  54.  *
  55.  *    Match yes prompt noblanks "Are you sure? (yes/no) :" no
  56.  *
  57.  * If the user types "\n" or "go away" and you had specified noblanks, he'll
  58.  * get the message: "Please type only "match string" or "fail string"
  59.  *
  60.  * If NOBLANKS is NOT used and user just hits return, the match will fail.
  61.  *
  62.  */
  63.  
  64. #include "stdio.h"
  65.  
  66. #define NO      6       /* warn level exit code */
  67. #define YES     0       /* No warning exit code */
  68.  
  69. #define  MaxString 255    /* Size of read buffer    */
  70.  
  71. #ifndef  TRUE
  72. #define  TRUE  (1==1)
  73. #define  FALSE (1==0)
  74. #endif
  75.  
  76. /************************************************************************/
  77. /*
  78.  
  79.  
  80.         General string handling routines
  81.  
  82.  
  83. */
  84.  
  85. /************************************************************************/
  86. /*    upcase - upcase a string                    */
  87. /************************************************************************/
  88. char *upcase(a)
  89. register char *a;
  90. {
  91.     register char *cp;
  92.  
  93.     cp = a;
  94.     while (*cp = toupper(*cp)) cp++;
  95.  
  96.     return (a);
  97. }
  98.  
  99. /************************************************************************/
  100. /*    mprint - print a string, decoding all escape sequences in bcpl    */
  101. /*        or c format without the overhead of linking in printf    */
  102. /************************************************************************/
  103. void mprint(a)
  104. register char *a;
  105. {
  106.     register char outc;
  107.  
  108.     while (*a!='\0') {
  109.         if ((outc=*a) == '\\' || outc == '*') {
  110.             if (*(a+(char *)1) != '\0') a++;
  111.             switch (toupper(outc=*a)) {
  112.  
  113.                 case '0' : outc='\000'; break;
  114.                 case 'B' : outc='\010'; break;
  115.                 case 'E' : outc='\033'; break;
  116.                 case 'F' : outc='\014'; break;
  117.                 case 'N' : outc='\012'; break;
  118.                 case 'R' : outc='\012'; break;
  119.                 case 'T' : outc='\011'; break;
  120.             }
  121.         }
  122.         putchar(outc); a++;
  123.     }
  124.  
  125. }
  126.  
  127. /************************************************************************/
  128. /*    Strip - Strip spaces from beginning and end of a string        */
  129. /************************************************************************/
  130. char *strip(s)
  131. register char *s;
  132. {
  133.     register int i;
  134.  
  135.     while (s[0] == ' ') for (i=0; i<strlen(s); i++) s[i] = s[i+1];
  136.  
  137.     while (((i=strlen(s))>1) && s[i-1]==' ') s[i-1] = '\0';
  138.  
  139.     return (s);
  140. }
  141.  
  142. /************************************************************************/
  143. /*
  144.  
  145.  
  146.         Pattern matching routines
  147.  
  148.  
  149. */
  150.  
  151. int    noblanks, nocaps;
  152. char    *strcat(), *strcpy(), *fgets();
  153. char    answer[MaxString];
  154.  
  155. #define MAXPATTERNS 10
  156.  
  157. typedef    char PARRAY[MAXPATTERNS][81];
  158.  
  159. PARRAY    matchpatterns, failpatterns;
  160.  
  161.  
  162. /************************************************************************/
  163. /*    listp - list patterns in an array of strings            */
  164. /************************************************************************/
  165. void listp(s,plist)
  166. char s[];
  167. PARRAY plist;
  168. {
  169.     register int i=0,comma=FALSE;
  170.  
  171.     mprint(s);
  172.     if (plist[1][0]=='\0') mprint(" ");
  173.     else mprint(" one of ");
  174.  
  175.     while (plist[i][0] != '\0' && i<MAXPATTERNS) {
  176.         if (comma) mprint(", ");
  177.         comma = TRUE;
  178.         mprint("'");
  179.         mprint(plist[i++]);
  180.         mprint("'");
  181.     }
  182. }
  183.  
  184. /************************************************************************/
  185. /*    ScanPattern - process match strings into a pattern array    */
  186. /************************************************************************/
  187. void ScanPattern(s,plist)
  188. char    s[];
  189. PARRAY    plist;
  190. {
  191.     register int i=0,j=0,k=0;
  192.  
  193.     while (s[i] && j<MAXPATTERNS) {
  194.         while (s[i] && s[i]!='|') {
  195.             plist[j][k++]=s[i++];
  196.         }
  197.         strip(&plist[j][0]);
  198.         j++; k=0; if (s[i]) i++;
  199.     }
  200.  
  201.     while (j<MAXPATTERNS) plist[j++][0] = '\0';
  202.  
  203. }
  204.  
  205. /************************************************************************/
  206. /*    matches - scan for a string anywhere in a pattern array        */
  207. /************************************************************************/
  208. matches(string,plist)
  209. char string[];
  210. PARRAY plist;
  211. {
  212.     register int i=0;
  213.  
  214.     while (plist[i][0] != '\0' && i<MAXPATTERNS) {
  215.         if (strcmp(plist[i++],string)==0) return TRUE;
  216.     }
  217.     return FALSE;
  218. }
  219.  
  220. /************************************************************************/
  221. /*    badanswer - if noblanks used, determines when the prompt should */
  222. /*        be repeated                        */
  223. /************************************************************************/
  224. badanswer(nargs,argc)
  225. int nargs;
  226. char *argc[];
  227. {
  228.     if (answer[0]=='\n') return TRUE;    /* it's bad */
  229.  
  230.     if (matches(answer,matchpatterns)) return FALSE;
  231.  
  232.     if (nargs==3)
  233.         if (matches(answer,failpatterns)) return FALSE;
  234.  
  235.     return TRUE;
  236. }
  237.  
  238. /************************************************************************/
  239. /*
  240.  
  241.  
  242.         Main program
  243.  
  244.  
  245. */
  246.  
  247. main(argc, argv)
  248. int argc;
  249. char *argv[];
  250.  
  251. {
  252.     register int    i,j,nargs;
  253.     int    repeat;
  254.     char    S[MaxString];
  255.     char    *prompt;
  256.  
  257.     nargs = argc;
  258.  
  259. /* set one word flags */
  260.  
  261.     repeat = noblanks = nocaps = FALSE;
  262.  
  263.     if (nargs>1) for (i=1; i<nargs;) {
  264.         strcpy (S,argv[i]);
  265.         upcase (S);
  266.  
  267.         if (strcmp(S,"NOBLANKS") == 0) {
  268.             noblanks = TRUE;
  269.             if (i<nargs-1) for (j=i;j<nargs-1; j++)
  270.                 argv[j] = argv[j+1];
  271.             argv[--nargs] = '\0';
  272.         } else
  273.         if (strcmp(S,"NOCAPS") == 0) {
  274.             nocaps = TRUE;
  275.             if (i<nargs-1) for (j=i;j<nargs-1; j++)
  276.                 argv[j] = argv[j+1];
  277.             argv[--nargs] = '\0';
  278.         } else i++;
  279.     }
  280.  
  281. /* set prompt */
  282.  
  283.     prompt = "";
  284.  
  285.     if (nargs>2) for (i=1; i<nargs-1;) {
  286.         strcpy (S,argv[i]);
  287.         upcase (S);
  288.         if (strcmp(S,"PROMPT") == 0) {
  289.             prompt = argv[i+1];
  290.             if (i<nargs-2) for (j=i;j<nargs-2; j++)
  291.                 argv[j] = argv[j+2];
  292.             argv[nargs-2] = argv[nargs-1] = '\0';
  293.             nargs -= 2;
  294.         } else i++;
  295.     }
  296.  
  297. /* does user need help? */
  298.  
  299.     if ( nargs<=1 || (nargs==2 && argv[1][0] == '?')) {
  300.         if (argc>0) {
  301.         mprint("Usage:\n");
  302.         mprint("  Match \"match option\"/A,\"fail option\",PROMPT/K,NOCAPS/S,NOBLANKS/S\n");
  303.         mprint("   for match on multiple options, separate options with \"|\" as in \"Yes|y|ok\"\n");
  304.  
  305.         mprint("\nCopyright (c)1988 MicroBotics, Inc. Enhancements by Mike Pinson.\n");
  306.         mprint(  "Copyright (c)1986 Joanne Dow.\n\n");
  307.         }
  308.         exit(20);
  309.     }
  310.  
  311. /* do I need help? */
  312.  
  313. #ifdef DEBUG
  314.     printf("Prompt is: '%s'\n",prompt);
  315.     printf("Fname  is: '%s'\n",fname);
  316.  
  317.     printf("NoBlanks is %s.\n", noblanks?"on":"off");
  318.     printf("NoCaps   is %s.\n", nocaps  ?"on":"off");
  319.  
  320.     for (i=0; i<argc-1; i++) printf("arg[%d] : '%s'\n",i,argv[i]);
  321.     printf("\n");
  322. #endif
  323.  
  324.     if (!nocaps) {
  325.         upcase(argv[1]);        /* upcase match string */
  326.         if (nargs==3) upcase(argv[2]);    /* upcase fail string */
  327.     }
  328.  
  329.     ScanPattern(argv[1],matchpatterns);
  330.     if (nargs==3) ScanPattern(argv[2],failpatterns);
  331.          else ScanPattern("",failpatterns);
  332.  
  333.     do {
  334.         if (repeat) {
  335.             listp("Please type",matchpatterns);
  336.             if (nargs==3) listp(" or",failpatterns);
  337.             mprint(".\n");
  338.         }
  339.         repeat = TRUE;
  340.         mprint (prompt);
  341.         fgets(answer, MaxString, stdin);
  342.  
  343.         answer[strlen(answer)-1] = '\0';    /* erase newline */
  344.  
  345.         strip(answer);
  346.         i=0;                /* isolate first word */
  347.         while(answer[i]!='\0' && answer[i]!=' ') i++;
  348.         answer[i] = '\0';
  349.  
  350.         if (!nocaps) {
  351.             upcase(answer);        /* upcase user input */
  352.         }
  353.  
  354.     } while (noblanks && (badanswer(nargs,argv)));
  355.  
  356.     if (matches(answer,matchpatterns)) exit(YES);
  357.     else exit(NO);
  358. }
  359.