home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / GETOPTSL.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  7KB  |  205 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4. **  GETOPTS.C - Universal command line options parser
  5. **
  6. **  Original Copyright 1993 by Bob Stout as part of
  7. **  the MicroFirm Function Library (MFL)
  8. **
  9. **  This subset version is hereby donated to the public domain.
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "dirport.h"
  16. #include "getoptsl.h"
  17.  
  18. #define NUL '\0'
  19. #define MAX_XARGS 512
  20.  
  21. int   xargc;
  22. char *xargv[MAX_XARGS];
  23.  
  24. /*
  25. **  getopts()
  26. **
  27. **  Parameters: 1 - argc from main()
  28. **              2 - argv from main()
  29. **              3 - your program's options[] array
  30. **
  31. **  Returns: Number of options specified or -1 if error
  32. **
  33. **  Note: Your program should declare the global options[] array which
  34. **        specifies all options recognized by getopts().
  35. */
  36.  
  37. int getopts_lite(int argc, char *argv[])
  38. {
  39.       int i, count, argidx = 0;
  40.       char *argp;
  41.       struct Option_Tag *ptr;
  42.  
  43.       xargc = argc;
  44.       xargv[argidx++] = argv[0];
  45.       for (i = 1, count = 0; i < argc; ++i)
  46.       {
  47.             if (strchr("-/", argv[i][0]) && !strchr("-/", argv[i][1]))
  48.             {
  49.                   Boolean_T found_it = False_;
  50.  
  51.                   /*
  52.                   ** Found a switch - If the 2nd character is also a switch
  53.                   ** character. If so, then it's a literal and is skipped
  54.                   */
  55.  
  56.                   if (strchr("-/", argv[i][1]))
  57.                         continue;
  58.  
  59.                   for (ptr = options; ptr->buf; ++ptr)
  60.                   {
  61.                         if ((int)argv[i][1] == ptr->letter) switch (ptr->type)
  62.                         {
  63.                         case Boolean_Tag:
  64.                               if ('-' == argv[i][2])
  65.                                     *((Boolean_T *)(ptr->buf)) = False_;
  66.                               else  *((Boolean_T *)(ptr->buf)) = True_;
  67.                               ++count;
  68.                               --xargc;
  69.                               found_it = True_;
  70.                               break;
  71.  
  72.                         case Word_Tag:
  73.                               sscanf(&argv[i][2], "%hd", (short *)(ptr->buf));
  74.                               ++count;
  75.                               --xargc;
  76.                               found_it = True_;
  77.                               break;
  78.  
  79.                         case DWord_Tag:
  80.                               sscanf(&argv[i][2], "%ld", (long *)(ptr->buf));
  81.                               ++count;
  82.                               --xargc;
  83.                               found_it = True_;
  84.                               break;
  85.  
  86.                         case Double_Tag:
  87.                               sscanf(&argv[i][2], "%lg",(double *)(ptr->buf));
  88.                               ++count;
  89.                               --xargc;
  90.                               found_it = True_;
  91.                               break;
  92.  
  93.                         case String_Tag:
  94.                               strncpy(ptr->buf, &argv[i][2], ptr->siz - 1);
  95.                               ++count;
  96.                               --xargc;
  97.                               found_it = True_;
  98.                               break;
  99.  
  100.                         default:
  101.                               return Error_;
  102.                         }
  103.                   }
  104.                   if (!found_it)
  105.                         return Error_;
  106.             }
  107.             else                          /* It must be a file name     */
  108.             {
  109.                   DOSFileData ffblk;
  110.  
  111.                   /* Set argp to point to the filename                  */
  112.  
  113.                   if (strchr("-/", argv[i][0]))
  114.                         argp = &argv[i][1];
  115.                   else  argp =  argv[i];
  116.  
  117.                   /* If no wildcards, just copy it */
  118.  
  119.                   if (!strchr(argp, '*') && !strchr(argp, '?'))
  120.                   {
  121.                         xargv[argidx++] = argp;
  122.                         continue;
  123.                   }
  124.  
  125.                   /* Expand wildcards, if possible                      */
  126.  
  127.                   if (0 == FIND_FIRST(argp, _A_ANY, &ffblk))
  128.                   {
  129.                         char path[FILENAME_MAX], *p;
  130.  
  131.                         /* Save the path for re-attachment              */
  132.  
  133.                         if (NULL == (p = strrchr(argp, '\\')))
  134.                               p = strrchr(argp, '/');
  135.                         if (p)
  136.                         {
  137.                               char ch = *p;
  138.  
  139.                               *p = NUL;
  140.                               strcat(strcpy(path, argp), "\\");
  141.                               *p = ch;
  142.                         }
  143.                         else  *path = NUL;
  144.                         --xargc;
  145.                         do
  146.                         {                             
  147.                               xargv[argidx] = malloc(strlen(ff_name(&ffblk))
  148.                                     + strlen(path) + 2);
  149.                               strcat(strcpy(xargv[argidx], path),
  150.                                     ff_name(&ffblk));
  151.                               ++argidx;
  152.                               ++xargc;
  153.                         
  154.                         } while (0 == FIND_NEXT(&ffblk));
  155.                   }
  156.             }
  157.       }
  158.       return count;
  159. }
  160.  
  161. #ifdef TEST
  162.  
  163. #include <stdlib.h>
  164. #include <conio.h>
  165.  
  166. Boolean_T test1 = True_, test2 = False_;
  167. short test3     = -37;
  168. long  test4     = 100000L;
  169. char  test5[81] = "Default string";
  170.  
  171. struct Option_Tag options[] = {
  172.       {'A',  Boolean_Tag, &test1, 0  },         /* Valid options        */
  173.       {'B',  Boolean_Tag, &test2, 0  },
  174.       {'C',  Word_Tag,    &test3, 0  },
  175.       {'D',  DWord_Tag,   &test4, 0  },
  176.       {'E',  String_Tag,   test5, 81 },
  177.       {'\0', Error_Tag,     NULL, 0  }          /* Terminating record   */
  178. };
  179.  
  180. #define TFprint(v) ((v) ? "TRUE" : "FALSE")
  181.  
  182. int main(int argc, char *argv[])
  183. {
  184.       int i;
  185.  
  186.       printf("Defaults:\ntest1 = %s\ntest2 = %s\ntest3 = %d\ntest4 = %ld\n"
  187.             "test5 = \"%s\"\n\n", TFprint(test1), TFprint(test2), test3,
  188.             test4, test5);
  189.  
  190.       printf("getopts() returned %d\n", getopts_lite(argc, argv));
  191.  
  192.       printf("Options are now:\ntest1 = %s\ntest2 = %s\ntest3 = %d\n"
  193.             "test4 = %ld\ntest5 = \"%s\"\n\n", TFprint(test1),
  194.             TFprint(test2), test3, test4, test5);
  195.  
  196.       puts("Hit any key to continue");
  197.       getch();
  198.       for (i = 0; i < xargc; ++i)
  199.             printf("xargv[%d] = \"%s\"\n", i, xargv[i]);
  200.       printf("\nxargc = %d\n", xargc);
  201.       return 0;
  202. }
  203.  
  204. #endif /* TEST */
  205.