home *** CD-ROM | disk | FTP | other *** search
/ Dr. CD ROM (Annual Premium Edition) / premium.zip / premium / IBMOS2_1 / SC621.ZIP / sc621 / getopt.c < prev    next >
C/C++ Source or Header  |  1992-07-05  |  5KB  |  155 lines

  1. /* getopt.c (emx/gcc) -- Copyright (c) 1990-1992 by Eberhard Mattes */
  2.  
  3. #define _GETOPT_C
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include "getopt.h"
  9.  
  10. char *optarg          = NULL;
  11. int optind            = 0;               /* Default: first call             */
  12. int opterr            = 1;               /* Default: error messages enabled */
  13. char *optswchar       = "-";             /* Default: '-' starts options     */
  14. enum _optmode optmode = GETOPT_UNIX;
  15.  
  16. static char * next_opt;             /* Next character in cluster of options */
  17. static char * empty = "";             /* Empty string                         */
  18.  
  19. static int done;
  20. static char sw_char;
  21.  
  22. static char ** options;            /* List of entries which are options     */
  23. static char ** non_options;        /* List of entries which are not options */
  24. static int options_count;
  25. static int non_options_count;
  26.  
  27. #define BEGIN do {
  28. #define END   } while (0)
  29.  
  30. #define PUT(dst) BEGIN \
  31.                   if (optmode == GETOPT_ANY) \
  32.                     dst[dst##_count++] = argv[optind]; \
  33.                  END
  34.  
  35. int getopt (int argc, char **argv, const char *opt_str)
  36.     {
  37.     char c, *q;
  38.     int i, j;
  39.  
  40.     if (optind == 0)
  41.         {
  42.         optind = 1; done = 0;
  43.         next_opt = empty;
  44.         if (optmode == GETOPT_ANY)
  45.             {
  46.             options = (char **)malloc (argc * sizeof (char *));
  47.             non_options = (char **)malloc (argc * sizeof (char *));
  48.             if (options == NULL || non_options == NULL)
  49.                 {
  50.                 (void)fprintf (stderr, "out of memory (getopt)\n");
  51.                 exit (255);
  52.                 }
  53.             options_count = 0; non_options_count = 0;
  54.             }
  55.         }
  56.     if (done)
  57.         return (EOF);
  58. restart:
  59.     optarg = NULL;
  60.     if (*next_opt == 0)
  61.         {
  62.         if (optind >= argc)
  63.             {
  64.             if (optmode == GETOPT_ANY)
  65.                 {
  66.                 j = 1;
  67.                 for (i = 0; i < options_count; ++i)
  68.                     argv[j++] = options[i];
  69.                 for (i = 0; i < non_options_count; ++i)
  70.                     argv[j++] = non_options[i];
  71.                 optind = options_count+1;
  72.                 free (options); free (non_options);
  73.                 }
  74.             done = 1;
  75.             return (EOF);
  76.             }
  77.         else if (!strchr (optswchar, argv[optind][0]) || argv[optind][1] == 0)
  78.             {
  79.             if (optmode == GETOPT_UNIX)
  80.                 {
  81.                 done = 1;
  82.                 return (EOF);
  83.                 }
  84.             PUT (non_options);
  85.             optarg = argv[optind++];
  86.             if (optmode == GETOPT_ANY)
  87.                 goto restart;
  88.             /* optmode==GETOPT_KEEP */
  89.             return (0);
  90.             }
  91.         else if (argv[optind][0] == argv[optind][1] && argv[optind][2] == 0)
  92.             {
  93.             if (optmode == GETOPT_ANY)
  94.                 {
  95.                 j = 1;
  96.                 for (i = 0; i < options_count; ++i)
  97.                     argv[j++] = options[i];
  98.                 argv[j++] = argv[optind];
  99.                 for (i = 0; i < non_options_count; ++i)
  100.                     argv[j++] = non_options[i];
  101.                 for (i = optind+1; i < argc; ++i)
  102.                     argv[j++] = argv[i];
  103.                 optind = options_count+2;
  104.                 free (options); free (non_options);
  105.                 }
  106.             ++optind;
  107.             done = 1;
  108.             return (EOF);
  109.             }
  110.         else
  111.             {
  112.             PUT (options);
  113.             sw_char = argv[optind][0];
  114.             next_opt = argv[optind]+1;
  115.             }
  116.         }
  117.     c = *next_opt++;
  118.     if (*next_opt == 0)  /* Move to next argument if end of argument reached */
  119.         ++optind;
  120.     if (c == ':' || (q = strchr (opt_str, c)) == NULL)
  121.         {
  122.         if (opterr)
  123.             {
  124.             if (c < ' ' || c >= 127)
  125.                 (void)fprintf (stderr, "Invalid option; character code=0x%.2x\n", c);
  126.             else
  127.                 (void)fprintf (stderr, "Invalid option `%c%c'\n", sw_char, c);
  128.             }
  129.         return ('?');
  130.         }
  131.     if (q[1] == ':')
  132.         {
  133.         if (*next_opt != 0)           /* Argument given */
  134.             {
  135.             optarg = next_opt;
  136.             next_opt = empty;
  137.             ++optind;
  138.             }
  139.         else if (q[2] == ':')
  140.             optarg = NULL;            /* Optional argument missing */
  141.         else if (optind >= argc)
  142.             {                       /* Required argument missing */
  143.             if (opterr)
  144.                 (void)fprintf (stderr, "No argument for `%c%c' option\n", sw_char, c);
  145.             c = '?';
  146.             }
  147.         else
  148.             {
  149.             PUT (options);
  150.             optarg = argv[optind++];
  151.             }
  152.         }
  153.     return (c);
  154.     }
  155.