[comp.os.minix] getopt

tholm@uvicctr.UUCP (Terrence W. Holm) (11/01/88)

EFTH MINIX report #54  - November 1988 -  getopt(3)


The recently posted ps(1) requires getopt(3), for those
people missing this subroutine: Here is Henry Spencer's
version, (slightly locally modified).

----------------------------------------------------------
echo x - getopt.c
gres '^X' '' > getopt.c << '/'
X/*
X * getopt - get option letter from argv
X *
X * Copyright (c) Henry Spencer.
X * Written by Henry Spencer.
X *
X * This software is not subject to any license of the American Telephone
X * and Telegraph Company or of the Regents of the University of California.
X *
X * Permission is granted to anyone to use this software for any purpose on
X * any computer system, and to alter it and redistribute it freely, subject
X * to the following restrictions:
X *
X * 1. The author is not responsible for the consequences of use of this
X *    software, no matter how awful, even if they arise from flaws in it.
X *
X * 2. The origin of this software must not be misrepresented, either by
X *    explicit claim or by omission.  Since few users ever read sources,
X *    credits must appear in the documentation.
X *
X * 3. Altered versions must be plainly marked as such, and must not be
X *    misrepresented as being the original software.  Since few users
X *    ever read sources, credits must appear in the documentation.
X *
X * 4. This notice may not be removed or altered.
X */
X
X/*
X * changed index() calls to strchr() - darwin, oct 87.
X *
X * added opterr & optopt     - Terrence W. Holm, Aug. 1988
X */
X
X#include <stdio.h>
X
Xchar	*optarg;	/* Global argument pointer. */
Xint	optind = 0;	/* Global argv index. */
Xint	opterr = 1;	/* Print error flag, default = on */
Xint	optopt;
X
Xstatic char	*scan = NULL;	/* Private scan pointer. */
X
Xextern char	*strchr();
X
Xint
Xgetopt(argc, argv, optstring)
Xint argc;
Xchar *argv[];
Xchar *optstring;
X{
X	register char c;
X	register char *place;
X
X	optarg = NULL;
X
X	if (scan == NULL || *scan == '\0') {
X		if (optind == 0)
X			optind++;
X	
X		if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
X			return(EOF);
X		if (strcmp(argv[optind], "--")==0) {
X			optind++;
X			return(EOF);
X		}
X	
X		scan = argv[optind]+1;
X		optind++;
X	}
X
X	optopt = c = *scan++;
X	place = strchr(optstring, c);
X
X	if (place == NULL || c == ':') {
X		if ( opterr )
X			fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
X		return('?');
X	}
X
X	place++;
X	if (*place == ':') {
X		if (*scan != '\0') {
X			optarg = scan;
X			scan = NULL;
X		} else if (optind < argc) {
X			optarg = argv[optind];
X			optind++;
X		} else {
X			if ( opterr )
X				fprintf(stderr, "%s: -%c argument missing\n", argv[0], c);
X			return('?');
X		}
X	}
X
X	return(c);
X}
/
echo x - getopt.3
gres '^X' '' > getopt.3 << '/'
XSUBROUTINES
X    getopt(3)		- get option letter from argv
X
XINVOCATION
X    extern char *optarg;
X    extern int   optind;
X    extern int   opterr;
X    extern int   optopt;
X
X    int getopt( argc, argv, optstring )
X      int   argc;
X      char *argv[];
X      char *optstring;
X
XEXPLANATION
X    Getopt(3) is used to ease the process of scanning the
X    options on a command line. The <argc> and <argv> given
X    to main() are passed to getopt(3), as well as a string
X    naming all of the single character option names. If
X    an option allows an argument, then a ':' is put after
X    the name in <optstring>.
X
X    For example, the <optstring> "af:x" means that the
X    command accepts the options "-a", "-f" and "-x". The
X    "-f" option has an argument. When a command line is
X    entered the options without a following argument may
X    be grouped together, and there may be space between
X    the "-f" and its argument in the command line. For
X    example,
X
X	cmd -a -xf arg rest of line
X
X    After each call, main() must check the returned option
X    name and, if appropriate, the argument referenced by
X    <optarg>. Main() should continue to call getopt(3) until
X    it returns EOF, at which time main() can use <optind> to
X    determine how many items still remain on the command line.
X
X    The cases for getopt(3) returning EOF are: no more items
X    in the command line, an item does not start with a "-",
X    an item is simply "-" or an item is "--". In the latter
X    case, <optind> is incremented past this item.
X
X    Normally getopt(3) will print an error message on stderr
X    if either an unknown option is encountered or an option
X    is missing an argument. This output may be suppressed by
X    setting <opterr> to 0. Errors cause '?' to be returned and
X    <optopt> to be set to the offending option letter.
X
XRESULTS
X    o/w : Option character, <optarg> points to possible argument.
X    EOF : Finished scanning options, <optind> is next <argv>.
X    '?' : Encountered an illegal option, <optopt> is letter.
X
XAUTHOR
X    Henry Spencer
/
----------------------------------------------------------

		Terrence W. Holm
		  uw-beaver!uvicctr!tholm

ast@cs.vu.nl (Andy Tanenbaum) (05/30/91)

I am trying to figure out what to do with optind, getopt etc.

As far as I can determine, the correct behavior is for all programs to
explicitly include:

 int optind;

and so on explicitly, but the prototype of getopt goes in unistd.h. 

Is there anyone who can confirm or deny this?  Confirmations or denials
should be based on the Truth, not what you think makes sense, as the two
are not always compatible.  In any event, the Truth shall not conflict
with the example in P1003.2 Annex B.7.

I don't particular like this, because unistd.h is huge and makes the new
compiler barf, but if it must be so, it must be so.

Andy Tanenbaum (ast@cs.vu.nl)