Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP
Posting-Version: version B 2.10.2 9/5/84; site mcc-db.UUCP
Path: utzoo!decvax!genrad!panda!talcott!harvard!seismo!ut-sally!mcc-db!jbc
From: jbc@mcc-db.UUCP (John B. Chambers)
Newsgroups: mod.std.unix
Subject: Re;  bostic's getopt
Message-ID: <249@mcc-db.UUCP>
Date: Sun, 14-Jul-85 19:56:36 EDT
Article-I.D.: mcc-db.249
Posted: Sun Jul 14 19:56:36 1985
Date-Received: Mon, 15-Jul-85 10:08:24 EDT
Reply-To: std-unix-request@ut-sally
Organization: MCC (Austin, TX)
Lines: 145
Approved: jbc@mcc-db.UUCP

From: John Chambers (guest moderator) 

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 

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