/* transcript/src/getopt.c
 *
 * public domain getopt from mod.sources
 * RCSID: $Header: /home/gene/library/website/docsrc/wel/src/RCS/getopt.c,v 395.1 2008/04/20 17:25:48 gene Exp $
 */

/*
**  This is a public domain version of getopt(3).
**  Bugs, fixes to:
**Keith Bostic
**ARPA: keith@seismo
**UUCP: seismo!keith
**  Added NO_STDIO, opterr handling, Rich $alz (mirror!rs).
*/

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

/*
**  Error macro.  Maybe we want stdio, maybe we don't.
**  The (undocumented?) variable opterr tells us whether or not
**  to print errors.
*/

#ifdef NO_STDIO

#define tell(s)\
if (opterr)\
{\
    charebuf[2];\
    (void)write(2, nargv, (unsigned int)strlen(nargv));\
    (void)write(2, s, (unsigned int)strlen(s));\
    ebuf[0] = optopt;\
    ebuf[1] = '\n';\
    (void)write(2, ebuf, 2);\
}

#else

#define tell(s)\
if (opterr)\
    (void)fputs(*nargv, stderr),\
    (void)fputs(s,stderr),\
    (void)fputc(optopt, stderr),\
    (void)fputc('\n', stderr)

#endif


/* Global variables. */
static char EMSG[] = "";
int opterr = 1;/* undocumented error-suppressor*/
int optind = 1;/* index into argv vector*/
int optopt;/* char checked for validity*/
char*optarg;/* arg associated with option*/



getopt(nargc, nargv, ostr)
     int  nargc;
     char**nargv;
     char *ostr;
{
  static char *place = EMSG;/* option letter processing*/
  register char *oli;/* option letter list index*/

  if (!*place)/* update scanning pointer*/
  {
    if (optind >= nargc || *(place = nargv[optind]) != '-' || !*++place)
      return(EOF);
    if (*place == '-')/* found "--"*/
    {
      optind++;
      return(EOF);
    }
  }
  /* option letter okay? */
  if ((optopt = *place++) == ':' || (oli = strchr(ostr, optopt)) == NULL)
  {
    if (!*place)
      optind++;
    tell(": illegal option -- ");
    goto Bad;
  }
  if (*++oli != ':')/* don't need argument*/
  {
    optarg = NULL;
    if (!*place)
      optind++;
  }
  else/* need an argument*/
  {
    if (*place)
      optarg = place;/* no white space*/
    else
      if (nargc <= ++optind)
      {
        place = EMSG;
        tell(": option requires an argument -- ");
        goto Bad;
      }
    else
      optarg = nargv[optind];/* white space*/
    place = EMSG;
    optind++;
  }
  return(optopt);/* dump back option letter*/
 Bad:
  return('?');
}
