home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume7 / getoptprog / getopt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  2.8 KB  |  140 lines

  1. /*
  2. **  GETOPT PROGRAM AND LIBRARY ROUTINE
  3. **
  4. **  I wrote main() and AT&T wrote getopt() and we both put our efforts into
  5. **  the public domain via mod.sources.
  6. **    Rich $alz
  7. **    Mirror Systems
  8. **    (mirror!rs, rs@mirror.TMC.COM)
  9. **    August 10, 1986
  10. */
  11.  
  12. #include <stdio.h>
  13.  
  14.  
  15. #ifndef INDEX
  16. #define INDEX index
  17. #endif
  18.  
  19.  
  20. extern char    *INDEX();
  21. extern int     optind;
  22. extern char    *optarg;
  23.  
  24.  
  25. main(ac, av)
  26.     register int     ac;
  27.     register char     *av[];
  28. {
  29.     register char     *flags;
  30.     register int     c;
  31.  
  32.     /* Check usage. */
  33.     if (ac < 2) {
  34.     fprintf(stderr, "usage: %s flag-specification arg-list\n", av[0]);
  35.     exit(2);
  36.     }
  37.  
  38.     /* Play games; remember the flags (first argument), then splice
  39.        them out so it looks like a "standard" command vector. */
  40.     flags = av[1];
  41.     av[1] = av[0];
  42.     av++;
  43.     ac--;
  44.  
  45.     /* Print flags. */
  46.     while ((c = getopt(ac, av, flags)) != EOF) {
  47.     if (c == '?')
  48.         exit(1);
  49.     /* We assume that shells collapse multiple spaces in `` expansion. */
  50.     printf("-%c %s ", c, INDEX(flags, c)[1] == ':' ? optarg : "");
  51.     }
  52.  
  53.     /* End of flags; print rest of options. */
  54.     printf("-- ");
  55.     for (av += optind; *av; av++)
  56.     printf("%s ", *av);
  57.     exit(0);
  58. }
  59.  
  60. /*
  61. **  This is the public-domain AT&T getopt(3) code.  I added the
  62. **  #ifndef stuff because I include <stdio.h> for the program;
  63. **  getopt, per se, doesn't need it.  I also added the INDEX/index
  64. **  hack (the original used strchr, of course).  And, note that
  65. **  technically the casts in the write(2) calls shouldn't be there.
  66. */
  67.  
  68. #ifndef NULL
  69. #define NULL    0
  70. #endif
  71. #ifndef EOF
  72. #define EOF    (-1)
  73. #endif
  74. #ifndef INDEX
  75. #define INDEX index
  76. #endif
  77.  
  78.  
  79. #define ERR(s, c)    if(opterr){\
  80.     extern int strlen(), write();\
  81.     char errbuf[2];\
  82.     errbuf[0] = c; errbuf[1] = '\n';\
  83.     (void) write(2, argv[0], (unsigned)strlen(argv[0]));\
  84.     (void) write(2, s, (unsigned)strlen(s));\
  85.     (void) write(2, errbuf, 2);}
  86.  
  87. extern int strcmp();
  88. extern char *INDEX();
  89.  
  90. int    opterr = 1;
  91. int    optind = 1;
  92. int    optopt;
  93. char    *optarg;
  94.  
  95. int
  96. getopt(argc, argv, opts)
  97. int    argc;
  98. char    **argv, *opts;
  99. {
  100.     static int sp = 1;
  101.     register int c;
  102.     register char *cp;
  103.  
  104.     if(sp == 1)
  105.         if(optind >= argc ||
  106.            argv[optind][0] != '-' || argv[optind][1] == '\0')
  107.             return(EOF);
  108.         else if(strcmp(argv[optind], "--") == NULL) {
  109.             optind++;
  110.             return(EOF);
  111.         }
  112.     optopt = c = argv[optind][sp];
  113.     if(c == ':' || (cp=INDEX(opts, c)) == NULL) {
  114.         ERR(": illegal option -- ", c);
  115.         if(argv[optind][++sp] == '\0') {
  116.             optind++;
  117.             sp = 1;
  118.         }
  119.         return('?');
  120.     }
  121.     if(*++cp == ':') {
  122.         if(argv[optind][sp+1] != '\0')
  123.             optarg = &argv[optind++][sp+1];
  124.         else if(++optind >= argc) {
  125.             ERR(": option requires an argument -- ", c);
  126.             sp = 1;
  127.             return('?');
  128.         } else
  129.             optarg = argv[optind++];
  130.         sp = 1;
  131.     } else {
  132.         if(argv[optind][++sp] == '\0') {
  133.             sp = 1;
  134.             optind++;
  135.         }
  136.         optarg = NULL;
  137.     }
  138.     return(c);
  139. }
  140.