/* @(#)getopt.c	1.1	11/9/92 */
/*
 *	A Unix System V utility
 *	Copied from 
 *	"Proficient C", Augie Hansen, MicroSoft Press, 1987, pp127-129
 */

#include <stdio.h>
#include <string.h>

/* macros */
#define ERR(s, c)	if(opterr){\
	char errbuf[2];\
	errbuf[0] = c; errbuf[1] = '\n';\
	(void) write(2, argv[0], (unsigned)strlen(argv[0]));\
	(void) write(2, s, (unsigned)strlen(s));\
	(void) write(2, errbuf, 2);}

/* global variables */
int	opterr = 1; /* default to report getopt errors */
int	optind = 1; /* index to first argument following command name */
int	optopt;
char	*optarg;

int
getopt( 
int	argc, 
char	**argv, 
char	*opts)
{
   static int	sp = 1;
   register int	c;
   register char	*cp;

   if( sp == 1) /* a new argument */
      if( optind >= argc ||		/* no arguments */
          argv[optind][0] != '-' ||	/* argument not an option */
          argv[optind][1] == '\0')	/* flag without an option letter */
        return(EOF);
      else if(! strcmp(argv[optind],"--")) {
        		/* special end of options indicator */
        optind++;	/* skip over argument */
        return(EOF);
      }
   optopt = c = argv[optind][sp];
   if( c == ':' || ( cp = strchr(opts, c)) == NULL ) {
      /* option letter not in option string */
      ERR(": illegal option -> ", c);
      if( argv[optind][++sp] == '\0') {
         /* skip onto the next argument */
         optind++;
         sp = 1;
      }
      return('?');
    }
    if( *++cp == ':' ) {
       /* option letter followed by ':' in option string */
       if( argv[optind][sp+1] != '\0')
          /* option argument found */
          /* set optarg to start of argument */
          optarg = &argv[optind++][sp+1];
       else if( ++optind >= argc) {
          ERR(": option requires an argument -> ",c);
          sp = 1;
          return('?');
       } else
          /* option argument found */
          /* set optarg to start of argument */
          optarg = argv[optind++];
       sp = 1;
    } else {
       /* option found */
       if( argv[optind][++sp] == '\0') {
          /* at the end of the argument */
          sp = 1;
          optind++;
       }
       /* clear optarg, argument associated with this option */
       optarg = NULL;
    }
    /* return option letter */
    return( c );
} /* getopt() */

