home *** CD-ROM | disk | FTP | other *** search
/ CD Shareware Magazine 1996 December / CD_shareware_12-96.iso / DOS / Programa / CCDL122.ZIP / LIBS / CMDLINE / SOURCE / ARGS.C next >
Encoding:
C/C++ Source or Header  |  1996-06-19  |  3.7 KB  |  133 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_SWITCHSTRING:
  38.               if (cmatch(string[index], ArgList[i].id)) {
  39.         (* ArgList[i].routine)(string[index],&string[index]);
  40.          return (ARG_NEXTCHAR);
  41.           }
  42.           break;
  43.       case ARG_SWITCH:
  44.               if (cmatch(string[index], ArgList[i].id)) {
  45.         (* ArgList[i].routine)(string[index],(char *)TRUE);
  46.          return (ARG_NEXTCHAR);
  47.           }
  48.           break;
  49.       case ARG_BOOL:
  50.           if (cmatch(string[index], ArgList[i].id)) {
  51.         if (string[0] == ARG_SEPTRUE)
  52.           (* ArgList[i].routine)(string[index],(char *)TRUE);
  53.         else
  54.           (* ArgList[i].routine)(string[index],(char *)FALSE);
  55.         return(ARG_NEXTCHAR);
  56.           }
  57.           break;
  58.       case ARG_CONCATSTRING:
  59.           if (cmatch(string[index], ArgList[i].id)) {
  60.         (* ArgList[i].routine)(string[index], string+index+1);
  61.         return(ARG_NEXTARG);
  62.           }
  63.           break;
  64.       case ARG_NOCONCATSTRING:
  65.           if (cmatch(string[index], ArgList[i].id)) {
  66.         if (!arg)
  67.           return(ARG_NOARG);
  68.                 (* ArgList[i].routine)(string[index], arg);
  69.                 return(ARG_NEXTNOCAT);
  70.               }
  71.               break;
  72.     }
  73.   }
  74.   return(ARG_NOMATCH);
  75. }
  76. BOOL parse_args(int *argc, char *argv[], BOOL case_sensitive)
  77. {
  78.   int pos = -1;
  79.  
  80.   BOOL retval = TRUE;
  81.   use_case = case_sensitive;
  82.  
  83.   while(++pos < *argc) {
  84.     if ((argv[pos][0] == ARG_SEPSWITCH) || (argv[pos][0] == ARG_SEPFALSE)
  85.           || (argv[pos][0] == ARG_SEPTRUE)) {
  86.       int argmode;
  87.       int index = 1;
  88.       int done = FALSE;
  89.       do {
  90.         // Scan the present arg
  91.         if (pos < *argc - 1)
  92.           argmode = scan_args(argv[pos], index, argv[pos+1]);
  93.         else
  94.           argmode = scan_args(argv[pos], index, 0);
  95.  
  96.         switch(argmode) {
  97.           case ARG_NEXTCHAR:
  98.                   // If it was a char, go to the next one
  99.                   if (!argv[pos][++index])
  100.                     done = TRUE;
  101.                   break;
  102.           case ARG_NEXTNOCAT:
  103.                   // Otherwise if it was a nocat, remove the extra arg
  104.                   remove_arg(pos, argc, argv);
  105.                   // Fall through to NEXTARG
  106.           case ARG_NEXTARG:
  107.                   // Just a next arg, go do it
  108.                   done = TRUE;
  109.                   break;
  110.           case ARG_NOMATCH:
  111.                   // No such arg, spit an error
  112.                   fprintf(stderr,"Invalid Arg: %s\n", argv[pos]);
  113.                   done = TRUE;
  114.                   retval = FALSE;
  115.                   break;
  116.           case ARG_NOARG:
  117.                   // Missing the arg for a CONCAT type, spit the error
  118.                   fprintf(stderr,"Missing string for Arg %s\n", argv[pos]);
  119.                   done = TRUE;
  120.                   retval = FALSE;
  121.                   break;
  122.         };
  123.  
  124.       } while (!done);
  125.       // We'll always get rid of the present arg
  126.       // And back up one
  127.       remove_arg(pos--, argc, argv);
  128.     }
  129.   }
  130.   return(retval);
  131. }
  132.  
  133.