v07i011: Getopt program for scripts
sources-request at mirror.UUCP
sources-request at mirror.UUCP
Fri Aug 29 02:59:09 AEST 1986
Submitted by: Rich $alz (mirror!rs)
Mod.sources: Volume 7, Issue 11
Archive-name: getoptprog
#!/bin/sh
# This is a shell archive. Remove anything before this line,
# then unpack it by saving it in a file and typing "sh file".
# Wrapped by mirror!rs on Thu Aug 28 12:55:41 EDT 1986
# Exit status; set to 1 on "wc" errors or if would overwrite.
STATUS=0
# Contents: README Makefile getopt.1 getopt.c
echo x - README
if test -f README ; then
echo README exists, putting output in $$README
OUT=$$README
STATUS=1
else
OUT=README
fi
sed 's/^XX//' > $OUT <<'@//E*O*F README//'
XXThis quick throw-off is a public-domain implementation of the USG
XXgetopt program. Not to be confused with the library routine, this
XXprogram helps scripts parse their options/flags/arguments.
XXAfter unpacking, tweak the Makefile as appropriate and run make. Copy
XXthe examples from the manpage into separate files as verify that they
XXwork ok. Do a "make install". For your final examination, convert
XXlint to use this program. I write more Makefiles for mod.sources
XXsubmissions than I care to, and sometimes I get tired of it; I
XXapologize for the terseness of the one here.
XXIf you don't have getopt(3) in your C run-time library, snip it off
XXthe tail of the source file, and add it, or make it easily, publicly,
XXavailable in some other way.
XX /Rich $alz
@//E*O*F README//
chmod u=rw,g=rw,o=rw $OUT
echo x - Makefile
if test -f Makefile ; then
echo Makefile exists, putting output in $$Makefile
OUT=$$Makefile
STATUS=1
else
OUT=Makefile
fi
sed 's/^XX//' > $OUT <<'@//E*O*F Makefile//'
XX# Pick one
XXCFLAGS = -O -DINDEX=index
XX#CFLAGS = -O -DINDEX=strchr
XX# Pick one
XXM = /usr/man/man1/getopt.1
XX#M = /usr/man/u_man/man1/getopt.1# Is this path right?
XX# Where executable ends up; don't forget the trailing /
XXD = /bin/
XXgetopt: getopt.c
XX $(CC) $(CFLAGS) -o getopt getopt.c
XXinstall: getopt
XX cp getopt $Dgetopt
XX strip $Dgetopt
XX cp getopt.1 $M
@//E*O*F Makefile//
chmod u=rw,g=rw,o=rw $OUT
echo x - getopt.1
if test -f getopt.1 ; then
echo getopt.1 exists, putting output in $$getopt.1
OUT=$$getopt.1
STATUS=1
else
OUT=getopt.1
fi
sed 's/^XX//' > $OUT <<'@//E*O*F getopt.1//'
XX.TH GETOPT 1 LOCAL
XX.SH NAME
XXgetopt \- format flags for shell scripts
XX.SH SYNOPSIS
XX.B getopt
XXflag_spec argument ...
XX.SH DESCRIPTION
XX.I Getopt
XXis a program intended to be called by scripts to ``canonicalize'' their
XXarguments before processing them, just as the
XX.IR getopt (3)
XXroutine does for C programs.
XX(This need for scripts is usually most noticeable in the way
XX.IR lint (1)
XXhandles the
XX.B \-n
XXflag.)
XX.PP
XXThe following two examples provide the initial parsing for a script
XXwhich takes two flags,
XX.B \-a
XXand
XX.BR \-b ,
XXthe second of which takes an argument.
XX.RS
XX.ta +4n +4n +4n +4n
XX.nf
XX# For /bin/csh...
XXset argv = (`getopt "ab:" $*`)
XXif ( $status ) then
XX echo "Read the documentation and try again." >/dev/tty
XX exit 1
XXendif
XXset Aflag=0
XXset Name=NONE
XXwhile "$1" != "--"
XX switch ("$1")
XX case '-a':
XX set Aflag=1
XX breaksw
XX case '-b':
XX shift
XX set Name=$1
XX breaksw
XX endsw
XX shift
XXend
XXshift
XXecho Aflag=$Aflag / Name=$Name / Remaining args are $*
XX# For /bin/sh...
XXset -- `getopt "d:s" $@`
XXif test $? != 0 ; then
XX echo "Read the documentation and try again."
XX exit 1
XXfi
XXAflag=0
XXName=NONE
XXfor f
XXdo
XX case "$f" in
XX -a) Aflag=1
XX ;;
XX -b) shift
XX Name=$2
XX ;;
XX --) break
XX ;;
XX esac
XX shift
XXdone
XXshift
XXecho Aflag=$Aflag / Name=$Name / Remaining args are $*
XX.fi
XX.RE
XX.SH DIAGNOSTICS
XXThe program burps the standard
XX.IR getopt (3)
XXdiagnostics to standard error, and exits with a non-zero status if an
XXerror occurs.
XXIt is arguable wrong that the diagnostics imply that the program
XXis named ``getopt'' rather than the real name of the script.
XXIt is undeniably AT&T\-compatible to do this, however.
XX.SH "SEE ALSO"
XXcsh(1), sh(1), getopt(3)
XX.SH AUTHOR
XX.nf
XXRich $alz
XXMirror Systems
XX(mirror!rs, rs at mirror.TMC.COM)
@//E*O*F getopt.1//
chmod u=rw,g=rw,o=rw $OUT
echo x - getopt.c
if test -f getopt.c ; then
echo getopt.c exists, putting output in $$getopt.c
OUT=$$getopt.c
STATUS=1
else
OUT=getopt.c
fi
sed 's/^XX//' > $OUT <<'@//E*O*F getopt.c//'
XX/*
XX** GETOPT PROGRAM AND LIBRARY ROUTINE
XX**
XX** I wrote main() and AT&T wrote getopt() and we both put our efforts into
XX** the public domain via mod.sources.
XX** Rich $alz
XX** Mirror Systems
XX** (mirror!rs, rs at mirror.TMC.COM)
XX** August 10, 1986
XX*/
XX#include <stdio.h>
XX#ifndef INDEX
XX#define INDEX index
XX#endif
XXextern char *INDEX();
XXextern int optind;
XXextern char *optarg;
XXmain(ac, av)
XX register int ac;
XX register char *av[];
XX{
XX register char *flags;
XX register int c;
XX /* Check usage. */
XX if (ac < 2) {
XX fprintf(stderr, "usage: %s flag-specification arg-list\n", av[0]);
XX exit(2);
XX }
XX /* Play games; remember the flags (first argument), then splice
XX them out so it looks like a "standard" command vector. */
XX flags = av[1];
XX av[1] = av[0];
XX av++;
XX ac--;
XX /* Print flags. */
XX while ((c = getopt(ac, av, flags)) != EOF) {
XX if (c == '?')
XX exit(1);
XX /* We assume that shells collapse multiple spaces in `` expansion. */
XX printf("-%c %s ", c, INDEX(flags, c)[1] == ':' ? optarg : "");
XX }
XX /* End of flags; print rest of options. */
XX printf("-- ");
XX for (av += optind; *av; av++)
XX printf("%s ", *av);
XX exit(0);
XX}
XX
XX/*
XX** This is the public-domain AT&T getopt(3) code. I added the
XX** #ifndef stuff because I include <stdio.h> for the program;
XX** getopt, per se, doesn't need it. I also added the INDEX/index
XX** hack (the original used strchr, of course). And, note that
XX** technically the casts in the write(2) calls shouldn't be there.
XX*/
XX#ifndef NULL
XX#define NULL 0
XX#endif
XX#ifndef EOF
XX#define EOF (-1)
XX#endif
XX#ifndef INDEX
XX#define INDEX index
XX#endif
XX#define ERR(s, c) if(opterr){\
XX extern int strlen(), write();\
XX char errbuf[2];\
XX errbuf[0] = c; errbuf[1] = '\n';\
XX (void) write(2, argv[0], (unsigned)strlen(argv[0]));\
XX (void) write(2, s, (unsigned)strlen(s));\
XX (void) write(2, errbuf, 2);}
XXextern int strcmp();
XXextern char *INDEX();
XXint opterr = 1;
XXint optind = 1;
XXint optopt;
XXchar *optarg;
XXint
XXgetopt(argc, argv, opts)
XXint argc;
XXchar **argv, *opts;
XX{
XX static int sp = 1;
XX register int c;
XX register char *cp;
XX if(sp == 1)
XX if(optind >= argc ||
XX argv[optind][0] != '-' || argv[optind][1] == '\0')
XX return(EOF);
XX else if(strcmp(argv[optind], "--") == NULL) {
XX optind++;
XX return(EOF);
XX }
XX optopt = c = argv[optind][sp];
XX if(c == ':' || (cp=INDEX(opts, c)) == NULL) {
XX ERR(": illegal option -- ", c);
XX if(argv[optind][++sp] == '\0') {
XX optind++;
XX sp = 1;
XX }
XX return('?');
XX }
XX if(*++cp == ':') {
XX if(argv[optind][sp+1] != '\0')
XX optarg = &argv[optind++][sp+1];
XX else if(++optind >= argc) {
XX ERR(": option requires an argument -- ", c);
XX sp = 1;
XX return('?');
XX } else
XX optarg = argv[optind++];
XX sp = 1;
XX } else {
XX if(argv[optind][++sp] == '\0') {
XX sp = 1;
XX optind++;
XX }
XX optarg = NULL;
XX }
XX return(c);
XX}
@//E*O*F getopt.c//
chmod u=rw,g=rw,o=rw $OUT
echo Inspecting for damage in transit...
temp=/tmp/sharin$$; dtemp=/tmp/sharout$$
trap "rm -f $temp $dtemp; exit" 0 1 2 3 15
cat > $temp <<\!!!
15 127 756 README
15 54 348 Makefile
90 292 1707 getopt.1
139 436 2832 getopt.c
259 909 5643 total
!!!
wc README Makefile getopt.1 getopt.c | sed 's=[^ ]*/==' | diff -b $temp - >$dtemp
if test -s $dtemp ; then
echo "Ouch [diff of wc output]:"
cat $dtemp
STATUS=1
elif test $STATUS = 0 ; then
echo "No problems found."
else
echo "WARNING -- PROBLEMS WERE FOUND..."
fi
exit $STATUS
More information about the Mod.sources
mailing list