[mod.std.unix] Re; bostic's getopt

jbc@mcc-db.UUCP (John B. Chambers) (07/15/85)

From: John Chambers (guest moderator) <ut-sally!std-unix>

Topic: getopt and command line arguments continued

----------------------------------------------------------------------

Date: Wed, 10 Jul 85 15:14:05 edt
From: harvard!talcott!wjh12!mirror!rs@ut-sally.ARPA (Rich Salz)
Subject: Re;  bostic's getopt


I have modified Keith Bostic's getopt code to make three changes:
	1.  my own (warped) esthetics.
	2.  add non-stdio code compile-time flag.
	3.  add trivial code to handle the opterr variable.
This last change is the most important; opterr, if set to 0 in
mainline code, suppresses printing all error messages.

i also cleaned up a couple of things.

feel free to re-post this to std-unix, or even {net,mod}.sourceds
if you think it will be worthwhile...

--
Rich $alz	{mit-eddie, ihnp4!inmet, wjh12, cca, datacube} !mirror!rs
Mirror Systems	2067 Massachusetts Ave.
617-661-0777	Cambridge, MA, 02140

/*
**  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>

/*
**  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)							\
	{								\
	    char	ebuf[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	*/


/* Linked in later. */
extern char	*index();		/* This may be strchr		*/


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 = index(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('?');
}



----------------------------------------------------------------------

-- 

John B. Chambers, Microelectronics and Computer Technology Corp., Austin, TX
{ihnp4,seismo,ctvax}!ut-sally!mcc-db!jbc, jbc@ut-sally.ARPA, chambers@mcc.ARPA