home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / DOS / Programa / CCDL122.ZIP / LIBS / CMDLINE / ARGS.C next >
Encoding:
C/C++ Source or Header  |  1995-10-25  |  3.5 KB  |  128 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include "cmdline.h"
  4.  
  5. extern ARGLIST ArgList[];
  6.  
  7. static BOOL use_case;
  8.  
  9. static void remove_arg(int pos, int *count, char *list[])
  10. {
  11.   int i;
  12.  
  13.   // Decrement length of list
  14.   (*count)--;
  15.  
  16.   // move items down
  17.   for (i=pos; i<*count; i++)
  18.     list[i] = list[i+1];
  19.  
  20. }
  21. static BOOL cmatch(char t1, char t2)
  22. {
  23.   if (use_case)
  24.     return(t1 == t2);
  25.  
  26.   return(toupper(t1) == toupper(t2));
  27. }
  28. // Callbacks of the form
  29. //   void boolcallback( char selectchar, BOOL value)
  30. //   void switchcallback( char selectchar, BOOL value)  ;; value always true
  31. //   void stringcallback( char selectchar, char *string)
  32. static int scan_args(char *string, int index, char *arg)
  33. {
  34.   int i=-1;
  35.   while (ArgList[++i].id) {
  36.     switch( ArgList[i].mode) {
  37.       case ARG_SWITCH:
  38.               if (cmatch(string[index], ArgList[i].id)) {
  39.         (* ArgList[i].routine)(string[index],(char *)TRUE);
  40.          return (ARG_NEXTCHAR);
  41.           }
  42.           break;
  43.       case ARG_BOOL:
  44.           if (cmatch(string[index], ArgList[i].id)) {
  45.         if (string[0] == ARG_SEPTRUE)
  46.           (* ArgList[i].routine)(string[index],(char *)TRUE);
  47.         else
  48.           (* ArgList[i].routine)(string[index],(char *)FALSE);
  49.         return(ARG_NEXTCHAR);
  50.           }
  51.           break;
  52.       case ARG_CONCATSTRING:
  53.           if (cmatch(string[index], ArgList[i].id)) {
  54.         (* ArgList[i].routine)(string[index], string+index+1);
  55.         return(ARG_NEXTARG);
  56.           }
  57.           break;
  58.       case ARG_NOCONCATSTRING:
  59.           if (cmatch(string[index], ArgList[i].id)) {
  60.         if (!arg)
  61.           return(ARG_NOARG);
  62.                 (* ArgList[i].routine)(string[index], arg);
  63.                 return(ARG_NEXTNOCAT);
  64.               }
  65.               break;
  66.     }
  67.   }
  68.   return(ARG_NOMATCH);
  69. }
  70. BOOL parse_args(int *argc, char *argv[], BOOL case_sensitive)
  71. {
  72.   int pos = -1;
  73.  
  74.   BOOL retval = TRUE;
  75.   use_case = case_sensitive;
  76.  
  77.   while(++pos < *argc) {
  78.     if ((argv[pos][0] == ARG_SEPSWITCH) || (argv[pos][0] == ARG_SEPFALSE)
  79.           || (argv[pos][0] == ARG_SEPTRUE)) {
  80.       int argmode;
  81.       int index = 1;
  82.       int done = FALSE;
  83.       do {
  84.         // Scan the present arg
  85.         if (pos < *argc - 1)
  86.           argmode = scan_args(argv[pos], index, argv[pos+1]);
  87.         else
  88.           argmode = scan_args(argv[pos], index, 0);
  89.  
  90.         switch(argmode) {
  91.           case ARG_NEXTCHAR:
  92.                   // If it was a char, go to the next one
  93.                   if (!argv[pos][++index])
  94.                     done = TRUE;
  95.                   break;
  96.           case ARG_NEXTNOCAT:
  97.                   // Otherwise if it was a nocat, remove the extra arg
  98.                   remove_arg(pos, argc, argv);
  99.                   // Fall through to NEXTARG
  100.           case ARG_NEXTARG:
  101.                   // Just a next arg, go do it
  102.                   done = TRUE;
  103.                   break;
  104.           case ARG_NOMATCH:
  105.                   // No such arg, spit an error
  106.                   fprintf(stderr,"Invalid Arg: %s\n", argv[pos]);
  107.                   done = TRUE;
  108.                   retval = FALSE;
  109.                   break;
  110.           case ARG_NOARG:
  111.                   // Missing the arg for a CONCAT type, spit the error
  112.                   fprintf(stderr,"Missing string for Arg %s\n", argv[pos]);
  113.                   done = TRUE;
  114.                   retval = FALSE;
  115.                   break;
  116.         };
  117.  
  118.       } while (!done);
  119.       // We'll always get rid of the present arg
  120.       // And back up one
  121.       remove_arg(pos--, argc, argv);
  122.     }
  123.   }
  124.   return(retval);
  125. }
  126.  
  127.  
  128.