[mod.std.unix] command line arguments

jsq@ut-sally.UUCP (John Quarterman) (06/28/85)

some commands take arguments as

command -abcdefg filename

and some as

command -a -b -c -d -e -f -g filename

It would be great if this was standardised.
Post this if you like: it's gleaned from a book 'Unix for beginners' by
Miller and Boyle at the University of Leeds, UK
-- 
 'He had a certain naive charm, but no muscle!'
                     Frank N. Furter in the Rocky Horror Picture Show.

+-------------------------+------------------------------------------+
| Douglas Spencer         | {decvax,garfield,okstate,philabs,seismo} |
|  Maths Institute        |      !mcvax!ukc!warwick!daisy!maugg      |
|   University of Warwick |------------------------------------------|
|    Coventry CV4 7AL     | If necessary I can also be contacted     |
|     England             | easily by any competent telepath     :-) |
+-------------------------+------------------------------------------+

[ The P1003 draft standard has little to say about commands, as it's
mostly concerned with system calls and library routines.  Varying option
formats are a nuisance, though.  -mod]
-- 

John Quarterman, jsq@ut-sally.ARPA, {ihnp4,seismo,ctvax}!ut-sally!jsq

jsq@ut-sally.UUCP (John Quarterman) (06/30/85)

> some commands take arguments as
> 
> command -abcdefg filename
> 
> and some as
> 
> command -a -b -c -d -e -f -g filename
> 
> It would be great if this was standardised.

Although commands like find will, I suppose always be renegades, doesn't
conformity to getopt() for all future commands not explicitly excused from
conformity by some ANSI committee take care of the problem?  It seems that
this is (or at least SHOULD be) simply a problem of living with history.

By the way, I understand that the central concern of the committee is in
the area of system calls, but aren't y'all going to have a subcommittee
responsible for commands, shells, etc analogous to the C committee's
"library" subcommittee?  I would hope so.

[ Would some more knowledgable P1003 committee member please comment
on this?  -mod]

If this kind of stuff should be sent to ut-sally!std-unix instead of
ut-sally!jsq, let me know.

[ The convention I have adopted is that mail to ut-sally!std-unix
is a submission to the newsgroup, while mail to ut-sally!jsq (or,
better, ut-sally!std-unix-request) is mail about the newsgroup,
though I may, as I did for this message, reply with a request
for permission to post.  -mod]

bc
--
  /  \    Bill Crews
 ( bc )   Cyb Systems, Inc
  \__/    Austin, Texas

[ gatech | ihnp4 | nbires | seismo | ucb-vax ] ! ut-sally ! cyb-eng ! bc
-- 

John Quarterman, jsq@ut-sally.ARPA, {ihnp4,seismo,ctvax}!ut-sally!jsq

jsq@ut-sally.UUCP (John Quarterman) (07/01/85)

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

Topic: getopt (command line arguments)

The previous posting about standardization of command line options
produced several comments about getopt, one of which I have already
posted.  I've picked out new information from the others and included
them here, after an excerpt from the original posting.

If your mail isn't excerpted here, it's not that I'm ignoring you:  it's
merely that either yours duplicated what earlier mail had already said,
or it was mailed to ut-sally!jsq rather than ut-sally!std-unix
and I haven't gotten confirmation, or it never got to me.

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

Date: Thu, 27 Jun 85 18:08:26 bst
From: Douglas Spencer <seismo!mcvax!daisy!maugg>
Subject: Re: mod.std.unix created
To: ut-sally!jsq

> some commands take arguments as
> 
> command -abcdefg filename
> 
> and some as
> 
> command -a -b -c -d -e -f -g filename
> 
> It would be great if this was standardised.

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

Date: Sat, 29 Jun 85 08:42:41 edt
From: Marty Shannon <seismo!allegra!eagle!mjs>
Subject: Re: command line arguments
To: ut-sally!jsq

Perhaps this should really be a followup rather than a reply, but there is a
fairly strong move to standardize command argument parsing by using the getopt
routine.  It deals quite well with the problem, as well as providing a great
deal of flexibility.

	Marty Shannon
UUCP:	ihnp4!eagle!mjs
Phone:	+1 201 522 6063

[ Someone else notes in mail that the AT&T command line argument standard
is included in the System V Interface Definition, page 343 of the Spring
1985 edition, and getopt conforms to this standard. -mod]

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

Date: 29 Jun 85 23:49:35 CDT (Sat)
From: Henry Spencer <ihnp4!utzoo!henry>
Subject: Re: command line arguments
To: ihnp4!ut-sally!std-unix

There is an AT&T standard for command argument syntax, and the getopt(3)
parser which encourages its use.  (Incidentally, the standard says that
both (for example) "ls -al" and "ls -a -l" are legit.)  AT&T has published
its own getopt() sources to encourage use of getopt, and there is also
an explicitly public-domain implementation that was published on the net
some time ago (by me).

[ I find the following articles in net.sources about getopt:

>From: henry@utzoo.UUCP (Henry Spencer)
Subject: public-domain getopt
Message-ID: <3745@utzoo.UUCP>
Date: Thu, 12-Apr-84 16:41:58 CST

>From: hansen@pegasus.UUCP (Tony L. Hansen)
Subject: Re: public domain getopt
Message-ID: <1253@pegasus.UUCP>
Date: Tue, 1-May-84 09:54:16 CDT

>From: henry@utzoo.UUCP (Henry Spencer)
Subject: minor bug in public-domain getopt
Message-ID: <4188@utzoo.UUCP>
Date: Tue, 7-Aug-84 15:31:16 CDT

>From: keith@seismo.UUCP (Keith Bostic)
Subject: public domain getopt(3)
Message-ID: <3360@seismo.UUCP>
Date: Fri, 24-Aug-84 07:54:08 CDT

The first one is Henry's code, the next two are bug fixes to that,
and the last one is a reimplementation by Keith Bostic.  -mod ]

Here at utzoo, most any time that we do significant work on a Bell program,
we retrofit it with getopt unless its established syntax is seriously
incompatible with this.  And of course all our own code uses it.  Getopt
and its syntax have some defects, but uniformity is such a huge win that
it's overwhelmingly worth it.

				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry

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

Date:    Sun, 30 Jun 85  01:00 EDT
From: George M. Weaver <ihnp4!psuvax1!GMW@PSUVM.BITNET>
Subject: Re: command line arguments
To: ut-sally!std-unix

     Frank da Cruz's new C-Kermit adopts a set of command line argument
standards that are worth looking at.  He outlines them briefly, and gives
credit to their creators in the Kermit User Manual, part of which I've
included here (without permission -- hope you don't mind, Frank).

===============================================================================

The C-Kermit command line syntax has been changed from that of earlier releases
of Unix Kermit to conform to the "Proposed Syntax  Standards  for  Unix  System
Commands"  put  forth  by  Kathy  Hemenway  and  Helene  Armitage  of AT&T Bell
Laboratories in Unix/World, Vol.1, No.3, 1984.  The rules that apply are:

   - Command names must be between 2 and 9 characters ("kermit" is 6).
   - Command names must include lower case letters and digits only.
   - An option name is a single character.
   - Options are delimited by '-'.
   - Options with  no  arguments  may  be  grouped  (bundled)  behind  one
     delimiter.
   - Option-arguments cannot be optional.
   - Arguments immediately follow options, separated by whitespace.
   - The order of options does not matter.
   - '-' preceded and followed by whitespace means standard input.

A group of bundled options may end with an option that has an argument.

===============================================================================


George M. Weaver
Penn State Astronomy Dept.
GMW at PSUVM.BITNET
...!allegra!psuvax1!gmw@psuvm.bitnet

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

The moderated newsgroup mod.std.unix is for discussions of UNIX standards,
in particular the one in progress by the IEEE P1003 "UNIX Standards" Committee.

Please mail submissions to mod.std.unix to ut-sally!std-unix,
and comments about the newsgroup to ut-sally!std-unix-request.
Permission for posting to the newsgroup is assumed for mail
to the former address, but mail to the latter address will
not be posted unless explicit permission is included, or obtained
by later negotiation.  Mail to ut-sally!jsq concerning mod.std.unix
will be treated like mail to ut-sally!std-unix-request.
-- 

John Quarterman, jsq@ut-sally.ARPA, {ihnp4,seismo,ctvax}!ut-sally!jsq

jsq@ut-sally.UUCP (John Quarterman) (07/02/85)

From: utastro!nather (Ed Nather)

>      Frank da Cruz's new C-Kermit adopts a set of command line argument
> standards that are worth looking at. 
> [...]
> A group of bundled options may end with an option that has an argument.

This creates confusion in using C-Kermit when you want to send an image
file.  For example:

	send -is filename     < ---  works fine
        send -si filename     < ---  bombs the program

I personally find it hard to remember which is which, since they both seem
equally sensible to me.  I would *much* prefer to bundle the flags, then
have those with arguments pick them up in the same order as the flags are
listed.  In the above case, the "-i" flag doesn't take an argument, so I
think it should be processed but should not "shield" the "-s" flag from its
argument.

But what do I know?

Ed Nather
Astronomy Dept, U of Texas @ Austin
{allegra,ihnp4}!{noao,ut-sally}!utastro!nather
nather%utastro.UTEXAS@ut-sally.ARPA

-- 

John Quarterman, jsq@ut-sally.ARPA, {ihnp4,seismo,ctvax}!ut-sally!jsq

jsq@ut-sally.UUCP (John Quarterman) (07/03/85)

some commands take arguments as

command -abcdefg filename

and some as

command -a -b -c -d -e -f -g filename

It would be great if this was standardised.
Post this if you like: it's gleaned from a book 'Unix for beginners' by
Miller and Boyle at the University of Leeds, UK
-- 
 'He had a certain naive charm, but no muscle!'
                     Frank N. Furter in the Rocky Horror Picture Show.

+-------------------------+------------------------------------------+
| Douglas Spencer         | {decvax,garfield,okstate,philabs,seismo} |
|  Maths Institute        |      !mcvax!ukc!warwick!daisy!maugg      |
|   University of Warwick |------------------------------------------|
|    Coventry CV4 7AL     | If necessary I can also be contacted     |
|     England             | easily by any competent telepath     :-) |
+-------------------------+------------------------------------------+

[ The P1003 draft standard has little to say about commands, as it's
mostly concerned with system calls and library routines.  Varying option
formats are a nuisance, though.  -mod]
-- 

John Quarterman, jsq@ut-sally.ARPA, {ihnp4,seismo,ctvax}!ut-sally!jsq
-- 
Ron Heiby	netnews@cuae2.UUCP	(via ihnp4)
AT&T-IS, /app/eng, Lisle, IL	(312) 810-6109

jsq@ut-sally.UUCP (John Quarterman) (07/03/85)

> some commands take arguments as
> 
> command -abcdefg filename
> 
> and some as
> 
> command -a -b -c -d -e -f -g filename
> 
> It would be great if this was standardised.

Although commands like find will, I suppose always be renegades, doesn't
conformity to getopt() for all future commands not explicitly excused from
conformity by some ANSI committee take care of the problem?  It seems that
this is (or at least SHOULD be) simply a problem of living with history.

By the way, I understand that the central concern of the committee is in
the area of system calls, but aren't y'all going to have a subcommittee
responsible for commands, shells, etc analogous to the C committee's
"library" subcommittee?  I would hope so.

[ Would some more knowledgable P1003 committee member please comment
on this?  -mod]

If this kind of stuff should be sent to ut-sally!std-unix instead of
ut-sally!jsq, let me know.

[ The convention I have adopted is that mail to ut-sally!std-unix
is a submission to the newsgroup, while mail to ut-sally!jsq (or,
better, ut-sally!std-unix-request) is mail about the newsgroup,
though I may, as I did for this message, reply with a request
for permission to post.  -mod]

bc
--
  /  \    Bill Crews
 ( bc )   Cyb Systems, Inc
  \__/    Austin, Texas

[ gatech | ihnp4 | nbires | seismo | ucb-vax ] ! ut-sally ! cyb-eng ! bc
-- 

John Quarterman, jsq@ut-sally.ARPA, {ihnp4,seismo,ctvax}!ut-sally!jsq
-- 
Ron Heiby	netnews@cuae2.UUCP	(via ihnp4)
AT&T-IS, /app/eng, Lisle, IL	(312) 810-6109

jsq@ut-sally.UUCP (John Quarterman) (07/04/85)

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

Topic: more on getopt (command line arguments)

This article will be followed by one more, containing source and man page
for a public domain getopt.  That should about wrap this subject up.  -mod

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

From: Randy D. Smith <ihnp4!decvax!mcnc!rtp47!smithrd>
Date: Mon, 1 Jul 85 07:58:42 edt
Apparently-To: mcnc!ihnp4!ut-sally!std-unix

P1003 definitely intends to address commands and the command
interface (e.g., sh).  That work has been sidetracked in order
to devote our efforts to getting the current core of the draft
(system call stuff) out the door.  I believe everyone on the
committee fully expects that commands/command line will be a
top priority after the draft goes out, is balloted, and the
ballots are resolved.

There has been some consensus already on the command line interface,
based on "An Enhanced Getopt" by T. C. Jones and L. A. Kennedy
of AT&T Bell Labs.  As mentioned in previous messages, this should
help us in the future, although history already stuck us with
a variety of interfaces to existing commands.
--
				Randy D. Smith	(919) 248-6136
			   Data General, Research Triangle Park, NC
			 <the known world>!mcnc!rti-sel!rtp47!smithrd
<General disclaimer:
	:r jsq's original posting about committee member's opinions
	being their own and not that of the entire committee...
>

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

Date: Wed, 3 Jul 85 11:06:19 edt
From: seismo!ulysses!smb (Steven Bellovin)
To: ut-sally!std-unix
Subject: Re: command line arguments

I believe I heard at Usenix that AT&T has put their version of getopt()
into the public domain.  Can anyone confirm this?

		--Steve Bellovin
		ulysses!smb

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

Date: Sat, 29 Jun 85 16:55:37 edt
From: ihnp4!utcs!ian (Ian F. Darwin)
To: ut-sally!jsq

There is an AT&T standard for command line arguments.
It was published about a year ago (washington??).
It is included in the Sys V interface Definition, page 343
of the Spring 85 edition.

There is a routine called `getopt(3)' that parses options
according to this standard. Bell published the `official'
source at UniForum in Dallas; several public-domain versions
(at least one with cleaner coding style!) have appeared on
the net. Send me mail if you don't have a copy, because
*everybody writing C programs should be using getopt()
to parse their command line options*.

Thanks

Ian Darwin, Toronto
ihnp4!darwin!ian

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

John Quarterman, jsq@ut-sally.ARPA, {ihnp4,seismo,ctvax}!ut-sally!jsq

jsq@ut-sally.UUCP (John Quarterman) (07/04/85)

From: John Quarterman (moderator) <ut-sally!std-unix>
 
Topic: yet more on getopt (command line arguments)
 
Two more messages, the first a followup to a previous posting, and
the second public domain sources and man pages for getopt(3) and getopt(1).
	-mod

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

From: ihnp4!utzoo!henry
Date: 3 Jul 85 18:34:41 CDT (Wed)
To: ihnp4!ut-sally!std-unix
Subject: Re: command line arguments

> > A group of bundled options may end with an option that has an argument.
> 
> This creates confusion in using C-Kermit when you want to send an image
> file.  For example:
> 
> 	send -is filename     < ---  works fine
>         send -si filename     < ---  bombs the program

The AT&T syntax standard (which getopt does not completely enforce)
actually forbids both of these usages.  Options with arguments are not
allowed to be bundled, and they must be separated from their arguments
by a space.

> I would *much* prefer to bundle the flags, then
> have those with arguments pick them up in the same order as the flags are
> listed.

The few existing commands that use such a convention, notably tar(1), are
(in my experience) the worse for it.  It's seriously error-prone.  I think
the AT&T people did the right thing.

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

Date: Tue, 2 Jul 85 13:07:09 edt
From: ihnp4!utcs!ian (Ian F. Darwin)
To: ihnp4!ut-sally!jsq@tzec.UTEXAS.ARPA
Subject: here is getopt

Here is the source for getopt(3), the function that should be in
everybody's C program, and getopt(1), a program that uses it to
make shell programs comprehensible and consistent. There are man
pages for both. Please send these on to the mod. group. Thanks.

[ I have hacked the following shell script slightly so that
it doesn't extract directly into system source directories,
rather into the current directory.  It should be assumed that
this code comes with no warranty from me, Ian Darwin, or anyone
else as to whether it accurately represents getopt as distributed
with System V, or any command line standard, or that it works
at all, or that it will cause no damage when extracted or used. -mod]

#! /bin/sh
#! To unbundle, sh this file
echo x - "(/usr/man/man3/getopt.3)" >&2
echo x - mkdir lib >&2
mkdir lib >&2
echo x - lib/getopt.3 >&2
cat >lib/getopt.3 <<"//SYSIN DD SYSOUT=BD"
.TH GETOPT 3 local
.DA 25 March 1982
.SH NAME
getopt \- get option letter from argv
.SH SYNOPSIS
.ft B
int getopt(argc, argv, optstring)
.br
int argc;
.br
char **argv;
.br
char *optstring;
.sp
extern char *optarg;
.br
extern int optind;
.ft
.SH DESCRIPTION
.I Getopt
returns the next option letter in
.I argv
that matches a letter in
.IR optstring .
.I Optstring
is a string of recognized option letters;
if a letter is followed by a colon, the option is expected to have
an argument that may or may not be separated from it by white space.
.I Optarg
is set to point to the start of the option argument on return from
.IR getopt .
.PP
.I Getopt
places in
.I optind
the
.I argv
index of the next argument to be processed.
Because
.I optind
is external, it is normally initialized to zero automatically
before the first call to 
.IR getopt .
.PP
When all options have been processed (i.e., up to the first
non-option argument),
.I getopt
returns
.BR EOF .
The special option
.B \-\-
may be used to delimit the end of the options;
.B EOF
will be returned, and
.B \-\-
will be skipped.
.SH SEE ALSO
getopt(1)
.SH DIAGNOSTICS
.I Getopt
prints an error message on
.I stderr
and returns a question mark
.RB ( ? )
when it encounters an option letter not included in
.IR optstring .
.SH EXAMPLE
The following code fragment shows how one might process the arguments
for a command that can take the mutually exclusive options
.B a
and
.BR b ,
and the options
.B f
and
.BR o ,
both of which require arguments:
.PP
.RS
.nf
main(argc, argv)
int argc;
char **argv;
{
	int c;
	extern int optind;
	extern char *optarg;
	\&.
	\&.
	\&.
	while ((c = getopt(argc, argv, "abf:o:")) != EOF)
		switch (c) {
		case 'a':
			if (bflg)
				errflg++;
			else
				aflg++;
			break;
		case 'b':
			if (aflg)
				errflg++;
			else
				bproc();
			break;
		case 'f':
			ifile = optarg;
			break;
		case 'o':
			ofile = optarg;
			break;
		case '?':
		default:
			errflg++;
			break;
		}
	if (errflg) {
		fprintf(stderr, "Usage: ...");
		exit(2);
	}
	for (; optind < argc; optind++) {
		\&.
		\&.
		\&.
	}
	\&.
	\&.
	\&.
}
.RE
.PP
A template similar to this can be found in
.IR /usr/pub/template.c .
.SH HISTORY
Written by Henry Spencer, working from a Bell Labs manual page.
Behavior believed identical to the Bell version.
.SH BUGS
It is not obvious how
`\-'
standing alone should be treated;  this version treats it as
a non-option argument, which is not always right.
.PP
Option arguments are allowed to begin with `\-';
this is reasonable but reduces the amount of error checking possible.
.PP
.I Getopt
is quite flexible but the obvious price must be paid:  there is much
it could do that it doesn't, like
checking mutually exclusive options, checking type of
option arguments, etc.
//SYSIN DD SYSOUT=BD
echo x - "(/usr/man/man1/getopt.1)" >&2
echo x - mkdir bin >&2
mkdir bin >&2
echo x - bin/getopt.1 >&2
cat >bin/getopt.1 <<"//SYSIN DD SYSOUT=BD"
.TH GETOPT 1 local
.DA 12 April 1984
.SH NAME
getopt \- parse command options
.SH SYNOPSIS
.B set \-\- \`getopt
optstring
.B $*\`
.SH DESCRIPTION
.I Getopt
is used to break up options in command lines for easy parsing by
shell procedures, and to check for legal options.
.I Optstring
is a string of recognized option letters (see
.IR getopt (3));
if a letter is followed by a colon, the option
is expected to have an argument which may or may not be
separated from it by white space.
The special option
.B \-\-
is used to delimit the end of the options.
.I Getopt
will place
.B \-\-
in the arguments at the end of the options,
or recognize it if used explicitly.
The shell arguments
(\fB$1 $2\fR ...) are reset so that each option is
preceded by a
.B \-
and in its own shell argument;
each option argument is also in its own shell argument.
.SH EXAMPLE
The following code fragment shows how one might process the arguments
for a command that can take the options
.B a
and
.BR b ,
and the option
.BR o ,
which requires an argument.
.PP
.RS
.nf
set \-\- \`getopt abo: $*\`
if test $? != 0
then
	echo 'Usage: ...'
	exit 2
fi
for i
do
	case "$i"
	in
		\-a|\-b)
			flag=$i; shift;;
		\-o)
			oarg=$2; shift; shift;;
		\-\-)
			shift; break;;
	esac
done
.fi
.RE
.PP
This code will accept any of the following as equivalent:
.PP
.RS
.nf
cmd \-aoarg file file
cmd \-a \-o arg file file
cmd \-oarg -a file file
cmd \-a \-oarg \-\- file file
.RE
.PP
A program template similar to this example can be found in
.IR /usr/pub/template.sh .
.SH SEE ALSO
sh(1), getopt(3)
.SH DIAGNOSTICS
.I Getopt
prints an error message on the standard error output when it
encounters an option letter not included in
.IR optstring .
.SH HISTORY
Written by Henry Spencer, working from a Bell Labs manual page.
Behavior believed identical to the Bell version.
.SH BUGS
Whatever
.IR getopt (3)
has.
.PP
Arguments containing white space or imbedded shell metacharacters
generally will not survive intact;  this looks easy to fix but isn't.
.PP
The error message for an invalid option is identified as coming
from
.I getopt
rather than from the shell procedure containing the invocation
of
.IR getopt ;
this again is hard to fix.
.PP
The precise best way to use the
.I set
command to set the arguments without disrupting the value(s) of
shell options varies from one shell version to another.
//SYSIN DD SYSOUT=BD
echo x - "(/usr/src/lib/libc/gen/getopt.c)" >&2
echo x - lib/getopt.c >&2
cat >lib/getopt.c <<"//SYSIN DD SYSOUT=BD"
/*
 * getopt - get option letter from argv
 */

#include <stdio.h>

char	*optarg;	/* Global argument pointer. */
int	optind = 0;	/* Global argv index. */

static char	*scan = NULL;	/* Private scan pointer. */

extern char	*index();

int
getopt(argc, argv, optstring)
int argc;
char *argv[];
char *optstring;
{
	register char c;
	register char *place;

	optarg = NULL;

	if (scan == NULL || *scan == '\0') {
		if (optind == 0)
			optind++;
	
		if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
			return(EOF);
		if (strcmp(argv[optind], "--")==0) {
			optind++;
			return(EOF);
		}
	
		scan = argv[optind]+1;
		optind++;
	}

	c = *scan++;
	place = index(optstring, c);

	if (place == NULL || c == ':') {
		fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
		return('?');
	}

	place++;
	if (*place == ':') {
		if (*scan != '\0') {
			optarg = scan;
			scan = NULL;
		} else if (optind < argc) {
			optarg = argv[optind];
			optind++;
		} else {
			fprintf(stderr, "%s: -%c argument missing\n", argv[0], c);
			return('?');
		}
	}

	return(c);
}
//SYSIN DD SYSOUT=BD
echo x - "(/usr/src/bin/getopt.c)" >&2
echo x - bin/getopt.c >&2
cat >bin/getopt.c <<"//SYSIN DD SYSOUT=BD"
#include <stdio.h>

main(argc, argv)
int argc;
char *argv[];
{
	extern int optind;
	extern char *optarg;
	int c;
	int status = 0;

	optind = 2;	/* Past the program name and the option letters. */
	while ((c = getopt(argc, argv, argv[1])) != EOF)
		switch (c) {
		case '?':
			status = 1;	/* getopt routine gave message */
			break;
		default:
			if (optarg != NULL)
				printf(" -%c %s", c, optarg);
			else
				printf(" -%c", c);
			break;
		}
	printf(" --");
	for (; optind < argc; optind++)
		printf(" %s", argv[optind]);
	printf("\n");
	exit(status);
}
//SYSIN DD SYSOUT=BD
exit 0

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

John Quarterman, jsq@ut-sally.ARPA, {ihnp4,seismo,ctvax}!ut-sally!jsq

jsq@ut-sally.UUCP (John Quarterman) (07/07/85)

From: <jsq@ut-sally.UUCP> John Quarterman (moderator)

Topic: getopt (command line arguments) continued

This looks like it is going to be a backburner discussion for some time.

It has been noted in mail that the other getopt than the one I posted
may be superior, and that it would be good to post whichever is the best
to mod.sources or net.sources again, as those get archived on many hosts.
Negotiations are in progress.

Note the address for submissions to mod.std.unix is ihnp4!ut-sally!std-unix.
Mark Horton is very efficient, but he's got his own newsgroups to moderate....

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

Date: Wed, 3 Jul 85 16:51:43 edt
From: wfmans@ihuxb.uucp
Subject: Re: command line arguments
To: mark@cbosgd.ATT.UUCP
References: <2220@ut-sally.UUCP>

> > some commands take arguments as
> > 
> > command -abcdefg filename
> > 
> > and some as
> > 
> > command -a -b -c -d -e -f -g filename
> > 
> > It would be great if this was standardised.
> 

The thing that burns me about some commands (and these are usually
experimental tools, mind you, real UNIX commands seem to work ok)
is that while most will accept
command -flag           and        command - flag
some will only accept one or the other.
I suppose that its easier to process the latter with a shell script
if you don't use getopt, but it sure is a pain.

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

Date: Wed, 3 Jul 85 12:58:16 cdt
From: neuro1!baylor!peter@rice.uucp (Peter da Silva)
Subject: Re: Re: command line arguments
Newsgroups: mod.std.unix
To: neuro1!mark@cbosgd.ARPA
References: <2210@ut-sally.UUCP> <2226@ut-sally.UUCP>

:-) Look! No quotes!

I doubt the necessity and even the wisdom of seperating an argument from
the option by whitespace. I also dislike the blackballing of multicharacter
options.

Since no arguments are allowed to be optional there's no point in
distinguishing between '-t/dev/tty4' and '-t /dev/tty4'. Since 't'
requires an argument the parsing is unambiguous.

It makes it harder to write transparent shell scripts. Atomic options make
it much easier to pass stuff onto other programs. Parsing options in shell
scripts is pretty much a lossage anyway, so why make things harder?

As for multicharater options: do you intend to kill "tail -30"? Since
changing the number of lines is the most common case what's the problem?
At any rate you should allow a simple '-nnn' for a high-usage.

[ Since tar is the standard for data interchange (actually, only the
format of the tar data, not the tar program, is currently in the draft
standard), I suspect there will always be anomalies.  The advantage
of getopt is not that it's perfect, just that it's close enough and
widespread enough that it has some chance of being adopted everywhere.
 -mod ]

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

The moderated newsgroup mod.std.unix is for discussions of UNIX standards,
in particular of the draft standard in progress by the IEEE P1003
"UNIX Standards" Committee.

Submissions to the newsgroup to:	ut-sally!std-unix
Comments about the newsgroup to:	ut-sally!std-unix-request
Permission to post to the newsgroup is assumed for mail to the former address,
but not for mail to the latter address, nor for mail to my personal addresses.
-- 

John Quarterman, jsq@ut-sally.ARPA, {ihnp4,seismo,ctvax}!ut-sally!jsq

jsq@ut-sally.UUCP (John Quarterman) (07/08/85)

Date: Mon, 8 Jul 85 12:51:54 EDT
From: Keith Bostic <seismo!keith>
To: ut-sally!std-unix
Subject: Public domain version of getopt(3)


John, you posted Henry Spencer's original version of getopt (message
#11, I believe) unless you've posted two versions.  [ I've posted only
one before, which was Henry Spencer's.  -mod ] The reason that I
reimplemented after that version was:

	1: his used the stdio library printf call, thus forcing the
		loading of some large routines even if your program
		didn't need them.
	2: his didn't have the same error messages that the SysV one had.
	3: his didn't use certain external variables (optarg,
		opterr, optind and optopt) that the SysV one had.

Obviously, #3 is the real reason, the others were bug fixes if
anything.  In any case, the version I sent to you (it's included below
if you've lost it) [ I have the one from net.sources, but I thought it
best to get whatever your latest version is.  If you mailed me one
before, it never arrived, possibly because my sun crashed about that
time.  -mod ] is the version that will be released with 4.3BSD and, as
far as I know, is totally compatible with SysV.  [ How about sending
it to mod.sources, as well?  -mod ]

--keith
======================================================================

#include <stdio.h>

/*
 * this is a public domain version of getopt(3).
 * bugs, fixes to:
 *		Keith Bostic
 *			ARPA: keith@seismo
 *			UUCP: seismo!keith
 */

/*
 * get option letter from argument vector
 */
int	opterr = 1,		/* useless, never set or used */
	optind = 1,		/* index into parent argv vector */
	optopt;			/* character checked for validity */
char	*optarg;		/* argument associated with option */

#define BADCH	(int)'?'
#define EMSG	""
#define tell(s)	fputs(*nargv,stderr);fputs(s,stderr); \
		fputc(optopt,stderr);fputc('\n',stderr);return(BADCH);

getopt(nargc,nargv,ostr)
int	nargc;
char	**nargv,
	*ostr;
{
	static char	*place = EMSG;	/* option letter processing */
	register char	*oli;		/* option letter list index */
	char	*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 = (int)*place++) == (int)':' || !(oli = index(ostr,optopt))) {
		if(!*place) ++optind;
		tell(": illegal option -- ");
	}
	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) {	/* no arg */
			place = EMSG;
			tell(": option requires an argument -- ");
		}
	 	else optarg = nargv[optind];	/* white space */
		place = EMSG;
		++optind;
	}
	return(optopt);			/* dump back option letter */
}

-- 

John Quarterman,   UUCP:  {ihnp4,seismo,harvard,gatech}!ut-sally!jsq
ARPA Internet and CSNET:  jsq@ut-sally.ARPA, soon to be jsq@sally.UTEXAS.EDU

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

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

Topic: getopts (command line arguments) continued

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

Date: Mon, 8 Jul 85 14:41:54 PDT
From: UCLA Computer Club <cc1@UCLA-LOCUS.ARPA>
Subject: Re: command line arguments

Regarding getopts and the 'all arguments are proceded by a "-"':
What about arguments that can be on/off switches, or can be positive or
negative numbers? In other words, what is wrong with allowing '+' as an
indicator of arguments? There are some commands that use it already.

Incidently, what happens with getopts if the command line was
command -n -30
and:
Option n is fetched
option 3 is fetched
option 0 is fetched

(No well written program would do all this, but essentially, what happens
if an argument looks like a flag? Or have you never grep'ed for a string
beginning with -?)

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

-- 

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

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

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

Topic: command line arguments

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

Date: Mon, 8 Jul 85 00:52:46 pdt
From: nsc!turtlevax!ken@ihnp4.UUCP (Ken Turkowski)
Subject: Re: command line arguments

Someone suggested that parsing arguments in shell scripts was difficult.
I include the following shell scripts, one for the Bourne shell and one
for the C-shell, which parse arguments of the form:
	-v -O -o outfile file1 file2 file3
as well as
	-vOooutfile file1 file2 file3

=================================================================

# This is a shell archive.  Remove anything before this line, then
# unpack it by saving it in a file and typing "sh file".  (Files
# unpacked will be owned by you and have default permissions.)
#
# This archive contains:
# std.sh std.csh

echo x - std.sh
cat > "std.sh" << '//E*O*F std.sh//'
#! /bin/sh
PATH=/usr/ucb:/bin:/usr/bin:/usr/local/bin
verbose=false
files=
trap 'rm $temp_files; exit' 0 1 2
for arg			# Look for flags
do	while true
	do	case $arg in
		-\?|-help) cat << EOF
This shell script accepts the arguments:
	-v		Verbose
	-o <outfile>	Output directed to <outfile> instead of default
	<file> ...	Files to be processed
It parses the arguments and prints the results of the parse.
EOF
			exit ;;
		-)	echo NULL FLAG; break ;;
		-v*)	verbose=true ;;
		-o*)	outfile=`expr $arg : '-.\(.*\)'` || outfile=UNKNOWN
			break ;;
		-*)	echo Unknown flag: \"$arg\"
			unkflag="$unkflag $arg"
			break ;;
		*)	case UNKNOWN in
			$outfile)	outfile=$arg ;;
			*)		files="$files $arg" ;;
			esac
			break ;;
		esac
		arg=-`expr "$arg" : '-.\(.*\)'` || break
	done
done

set x $files
shift
for arg		# input file processing template
do
	echo processing file \"$arg\"
done

# The following is just for testing this standard script
echo '
Argument' analysis to $0:
echo Flags: -v = $verbose, -o = \"$outfile\"
echo Unknown flags: $unkflag
echo Files: $files
//E*O*F std.sh//

echo x - std.csh
cat > "std.csh" << '//E*O*F std.csh//'
#! /bin/csh -f
unalias *
set path = (/usr/ucb /bin /usr/bin /usr/local/bin)
unset Verbose
set temp_files=
set outfile
set unkflag
set files
onintr cleanup
foreach argument ( $*:q )
    while ( 1 )
        switch ( "$argument" )
	    case -[?]:
	    case -help:
	    cat << EOF
This shell script take the arguments:
	-v		Verbose
	-o <outfile>	Change output file to <outfile> instead of the default.
	-? or -help	Prints this help message
	<file> ...	Input files
It parses them and prints the result of the parse.
EOF
		exit
            case -:
                echo 'NULL FLAG'
                break
            case -v*:
		set Verbose 
		breaksw
            case -o*:    
                set outfile = `expr $argument : '-.\(.*\)'` || set outfile = UNKNOWN
                break
            case -*:    
                echo Unknown flag: \""$argument"\"
                set unkflag = "$unkflag $argument"
                break
            case *:    
                switch ( UNKNOWN )
                    case "$outfile":
			set outfile = $argument
			breaksw
                    default:        
			set files = "$files $argument" 
                endsw
                break
        endsw
        set argument = -`expr "$argument" : '-.\(.*\)'` || break
    end
end

# The following is just for testing this standard script
echo ' Argument analysis to' $0 ':'
echo Flags: -v = ${?Verbose}, -o = \"$outfile\"
echo Unknown flags: $unkflag
echo Files: $files

cleanup:
	rm $temp_files
exit
//E*O*F std.csh//

exit 0
-- 

Ken Turkowski @ CADLINC, Menlo Park, CA
UUCP: {amd,decwrl,hplabs,nsc,seismo,spar}!turtlevax!ken
ARPA: turtlevax!ken@DECWRL.ARPA


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

-- 

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

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

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

Topic: command line arguments continued

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

Date: 8 Jul 85 23:23:03 CDT (Mon)
From: ihnp4!utzoo!henry@ut-sally.ARPA
Subject: Re: command line arguments

> I doubt the necessity and even the wisdom of seperating an argument from
> the option by whitespace.

As I recall it, the AT&T standard does it this way on the grounds of
readability, not necessity.  The "-t/dev/tty" example is an easy one
to pick out, but what about "-dfaglop"?  Which of those letters are
options, and which are an option argument?

> I also dislike the blackballing of multicharacter options.

Unfortunately, they are seriously incompatible with one-character options
and option bundling, both of which are too firmly entrenched to be changed
at this late date.  There were earlier attempts within AT&T to change
the world by legislating a different way of doing things; you don't hear
about them because they were failures.  People ignored them.  Getopt and
the option standard have the virtue of being pretty much compatible with
the bulk of present practice, which makes it far more likely that they
will be *adopted*.

> As for multicharater options: do you intend to kill "tail -30"? Since
> changing the number of lines is the most common case what's the problem?
> At any rate you should allow a simple '-nnn' for a high-usage.

The AT&T people admit that existing high-usage programs cannot be changed
retroactively.  This is a blemish rather than a disaster.  I tend to agree
that "-nnn" would be nice to have, but am not excited enough about it to
fight a battle over it.

				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,linus,decvax}!utzoo!henry



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

-- 

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