DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T g

⟦7be8cf005⟧ TextFile

    Length: 3739 (0xe9b)
    Types: TextFile
    Names: »getopt.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/cut/getopt.c« 

TextFile

/*
 * getopt(), a verson of getopt for those who do not have it and do not
 * want to steal the source from those that do.
 *
 * Same as getopt(3).
 *	Returns the next option letter in argv that matches a letter in optstr.
 *	Options are no longer parsed if the special option '--' is found
 *	or an argument that does not start in '-'.
 *	The global optind is set to the next index in argv to be processed.
 *	The global optarg is set to the argument, if the option has one.
 *	The global opterr can be set true if error messages are to be printed
 *	on the standard error file, or false if no message to be printed.
 *
 * ARGUMENTS:
 *	argc, argv - the argument count, and argument list
 *	optstr     - the list of valid options. The character ":" following
 *		     an option letter indicates that this option must have an 
 *		     argument. For example "abc:". This implies that the -:
 *		     is not  a valid option.
 *
 * RETURNS:
 *	Returns the next option letter, or EOF when all done. If an error
 *	encountered then the character '?' is returned.
 *
 * John Weald
 */
#include <stdio.h>

/*
 * Index into error array.
 */
#define BAD_OPT 0	/* option letter not in optstr			*/
#define MIS_ARG 1	/* option must have an argument			*/

char *optarg;
int optind = 1;		/* argv[0] is program name			*/
int opterr = 1;		/* If true print error message			*/

/*
 *
 * The basic data structures are optind, and the pointer "p."
 * optind keeps track of the next index into argv to parse arguments.
 * p is used to walk along the argv items looking for option letters or
 * arguments, when it is NULL the next  argv must be used . 
 * p is always left pointing to the previous option or NULL.
 * Consider the three equivalent valid argv's:
 *		1        2         3
 *		-a	 -b	   eric
 *	        -ab	eric
 *		-aberic
 * 
 */

int
getopt(argc, argv, optstr)
int argc;
char *argv[];
char *optstr;		/* The list of valid options			*/
{
	extern void err();	/* Forward reference			*/

	static char *p = (char *)NULL;

	/*
	 * parsed all the options in this argv[]?
	 */
	if (p == NULL || *++p == '\0' )
	{
		if (optind == argc)
			return(EOF);
		p = argv[optind];

		/*  a '-' by itself is not an option (e.g. see paste(1)) */
		if (*p++ != '-' || *p == '\0') 
			return(EOF);

		/* '--' marks the end of the option list.  */
		if (*p == '-')
		{
			optind++;
			return(EOF);
		}
	}

	optind++;
	/*
	 * Look for a valid option 
	 */
	while (*p != *optstr)
	{	
		if (*optstr == '\0')
		{
			/* Reached end of optstr, option not there */
			err(argv[0], BAD_OPT, *p);
			return((int)'?');
		}
		if (*++optstr == ':')
			optstr++;
	}

	/* If it does not need an argument then we are done.  */
	if (*(optstr + 1) != ':')
		return((int)*optstr);
	
	/*
	 * If there are more characters in this argv then it must
	 * be the argument.
	 */
	if (*++p != '\0')
	{
		optarg = p;
		p = (char *)NULL;
		return((int)*optstr);
	}

	/* 
	 * It needs an argument, but no more argv's left
	 */
	if (optind == argc)
	{
		err(argv[0], MIS_ARG, *optstr);
		p = (char *)NULL;
		return((int)'?');
	}

	/*
	 * Must be in next argv.
	 */
	optarg = argv[optind++];
	p = (char *)NULL;
	return((int)*optstr);
}

static void
err(a0, e, c)
char *a0;		/* argv[0]. i.e. the program name		*/
int e;
char c;
{
#ifdef NO_STDIO
	static char *errors[] = {
		": Illegal option -- ",
		": option requires an argument -- "
	};
	static char eend[] = "c\n";
	

	if (opterr)
	{
		(void)write(2, a0, strlen(a0));
		(void)write(2, errors[e], strlen(errors[e]));
		eend[0] = c;
		(void)write(2, eend, strlen(eend));
	}
#else
	static char *errors[] = {
		"%s: Illegal option -- %c\n",
		"%s: option requires an argument -- %c\n"
	};

	if (opterr)
		fprintf(stderr, errors[e], a0, c);
#endif
}