GNU getopt hacked for MSDOS

some great stormfowl, whenever he has walked his while bschwart at elbereth.rutgers.edu
Tue Dec 5 15:58:24 AEST 1989



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  readme getopt.c makefile
# Wrapped by trashman at crud on Mon Dec 04 23:38:47 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f readme -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"readme\"
else
echo shar: Extracting \"readme\" \(594 characters\)
sed "s/^X//" >readme <<'END_OF_readme'
XGNU getopt for MSDOS and Microsoft C.
X
XEnclosed:
X
X	*  README		This file (the appetizer).
X	*  GETOPT.C		The main course.
X	*  MAKEFILE		The dessert, an ndmake-file
X				  that makes libraries and a test
X				  program.
X
XThe MSDOS-specific capabilities are invoked
Xby defining MSDOS_FLAGS at compile time.
XIn particular, "/" is allowed as a synonym
Xfor "-" and "/-" as a synonym for "--".
X
XI chose to hack the GNU getopt after hacking
Xthe AT&T getopt and realising that it wouldn't
Xallow for "/" style flags after non-option arguments--
Xnot very MSDOS-like behaviour.
X
X	-- Barry Schwartz, Dec. 1989
END_OF_readme
if test 594 -ne `wc -c <readme`; then
    echo shar: \"readme\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f getopt.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"getopt.c\"
else
echo shar: Extracting \"getopt.c\" \(18046 characters\)
sed "s/^X//" >getopt.c <<'END_OF_getopt.c'
X/*-
X * GNU getopt, hacked for MSDOS and Microsoft C 5.1 and QuickC. 
X *
X * Barry Schwartz, Dec. 1989 
X *
X * New compile-time defs:
X *   MSDOS			Defined by Microsoft compilers
X *   MSDOS_FLAGS		Allow "/" as a synonym for "-"
X *				and "/-" as a synonym for "--"
X *   PROTO			ANSI-style parameters
X */
X
X/*
X * Getopt for GNU. Copyright (C) 1987 Free Software Foundation, Inc. 
X *
X * NO WARRANTY 
X *
X * BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY NO
X * WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW.  EXCEPT WHEN
X * OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, RICHARD M.
X * STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" WITHOUT
X * WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
X * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
X * PARTICULAR PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
X * OF THE PROGRAM IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU
X * ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 
X *
X * IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. STALLMAN,
X * THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY WHO MAY
X * MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE LIABLE TO
X * YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER
X * SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
X * INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
X * BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
X * FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS
X * PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
X * DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. 
X *
X * GENERAL PUBLIC LICENSE TO COPY 
X *
X * 1. You may copy and distribute verbatim copies of this source file as you
X * receive it, in any medium, provided that you conspicuously and
X * appropriately publish on each copy a valid copyright notice "Copyright
X * (C) 1987 Free Software Foundation, Inc."; and include following the
X * copyright notice a verbatim copy of the above disclaimer of warranty
X * and of this License.  You may charge a distribution fee for the
X * physical act of transferring a copy. 
X *
X * 2. You may modify your copy or copies of this source file or any portion
X * of it, and copy and distribute such modifications under the terms of
X * Paragraph 1 above, provided that you also do the following: 
X *
X * a) cause the modified files to carry prominent notices stating that you
X * changed the files and the date of any change; and 
X *
X * b) cause the whole of any work that you distribute or publish, that in
X * whole or in part contains or is a derivative of this program or any
X * part thereof, to be licensed at no charge to all third parties on terms
X * identical to those contained in this License Agreement (except that you
X * may choose to grant more extensive warranty protection to third
X * parties, at your option). 
X *
X * c) You may charge a distribution fee for the physical act of transferring
X * a copy, and you may at your option offer warranty protection in
X * exchange for a fee. 
X *
X * 3. You may copy and distribute this program or any portion of it in
X * compiled, executable or object code form under the terms of Paragraphs
X * 1 and 2 above provided that you do the following: 
X *
X * a) cause each such copy to be accompanied by the corresponding
X * machine-readable source code, which must be distributed under the terms
X * of Paragraphs 1 and 2 above; or, 
X *
X * b) cause each such copy to be accompanied by a written offer, with no time
X * limit, to give any third party free (except for a nominal shipping
X * charge) a machine readable copy of the corresponding source code, to be
X * distributed under the terms of Paragraphs 1 and 2 above; or, 
X *
X * c) in the case of a recipient of this program in compiled, executable or
X * object code form (without the corresponding source code) you shall
X * cause copies you distribute to be accompanied by a copy of the written
X * offer of source code which you received along with the copy you
X * received. 
X *
X * 4. You may not copy, sublicense, distribute or transfer this program
X * except as expressly provided under this License Agreement.  Any attempt
X * otherwise to copy, sublicense, distribute or transfer this program is
X * void and your rights to use the program under this License agreement
X * shall be automatically terminated.  However, parties who have received
X * computer software programs from you with this License Agreement will
X * not have their licenses terminated so long as such parties remain in
X * full compliance. 
X *
X * 5. If you wish to incorporate parts of this program into other free
X * programs whose distribution conditions are different, write to the Free
X * Software Foundation at 675 Mass Ave, Cambridge, MA 02139.  We have not
X * yet worked out a simple rule that can be stated here, but we will often
X * permit this.  We will be guided by the two goals of preserving the free
X * status of all derivatives of our free software and of promoting the
X * sharing and reuse of software. 
X *
X *
X * In other words, you are welcome to use, share and improve this program.
X * You are forbidden to forbid anyone else to use, share and improve what
X * you give them.   Help stamp out software-hoarding!  
X */
X
X
X/*
X * This version of `getopt' appears to the caller like standard Unix
X * `getopt' but it behaves differently for the user, since it allows the
X * user to intersperse the options with the other arguments. 
X *
X * As `getopt' works, it permutes the elements of `argv' so that, when it is
X * done, all the options precede everything else.  Thus all application
X * programs are extended to handle flexible argument order. 
X *
X * Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
X * Then the behavior is completely standard. 
X *
X * GNU application programs can use a third alternative mode in which they
X * can distinguish the relative order of options and other arguments.  
X */
X
X#include <stdio.h>
X#if defined(MSDOS)
X#include <malloc.h>
X#include <string.h>
X#endif
X
X#if defined(sparc)
X#include <alloca.h>
X#endif
X#if defined(USG) || defined(MSDOS)
X#define bcopy(s, d, l) memcpy((d), (s), (l))
X#define index		strchr
X#endif
X
X/*
X * For communication from `getopt' to the caller. When `getopt' finds an
X * option that takes an argument, the argument value is returned here.
X * Also, when `ordering' is RETURN_IN_ORDER, each non-option ARGV-element
X * is returned here.  
X */
X
Xchar           *optarg = 0;
X
X/*
X * Index in ARGV of the next element to be scanned. This is used for
X * communication to and from the caller and for communication between
X * successive calls to `getopt'. 
X *
X * On entry to `getopt', zero means this is the first call; initialize. 
X *
X * When `getopt' returns EOF, this is the index of the first of the
X * non-option elements that the caller should itself scan. 
X *
X * Otherwise, `optind' communicates from one call to the next how much of
X * ARGV has been scanned so far.  
X */
X
Xint             optind = 0;
X
X/*
X * The next char to be scanned in the option-element in which the last
X * option character we returned was found. This allows us to pick up the
X * scan where we left off. 
X *
X * If this is zero, or a null string, it means resume the scan by advancing
X * to the next ARGV-element.  
X */
X
Xstatic char    *nextchar;
X
X/*
X * Callers store zero here to inhibit the error message for unrecognized
X * options.  
X */
X
Xint             opterr = 1;
X
X/*
X * Describe how to deal with options that follow non-option ARGV-elements. 
X *
X * UNSPECIFIED means the caller did not specify anything; the default is then
X * REQUIRE_ORDER if the environment variable _OPTIONS_FIRST is defined,
X * PERMUTE otherwise. 
X *
X * REQUIRE_ORDER means don't recognize them as options. Stop option
X * processing when the first non-option is seen. This is what Unix does. 
X *
X * PERMUTE is the default.  We permute the contents of `argv' as we scan, so
X * that eventually all the options are at the end.  This allows options to
X * be given in any order, even with programs that were not written to
X * expect this. 
X *
X * RETURN_IN_ORDER is an option available to programs that were written to
X * expect options and other ARGV-elements in any order and that care about
X * the ordering of the two.  We describe each non-option ARGV-element as
X * if it were the argument of an option with character code zero. Using
X * `-' as the first character of the list of option characters requests
X * this mode of operation. 
X *
X * The special argument `--' forces an end of option-scanning regardless of
X * the value of `ordering'.  In the case of RETURN_IN_ORDER, only `--' can
X * cause `getopt' to return EOF with `optind' != ARGC.  
X */
X
Xstatic enum
X{
X    REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
X}               ordering;
X
X
X/* Handle permutation of arguments.  */
X
X/*
X * Describe the part of ARGV that contains non-options that have been
X * skipped.  `first_nonopt' is the index in ARGV of the first of them;
X * `last_nonopt' is the index after the last of them.  
X */
X
Xstatic int      first_nonopt;
Xstatic int      last_nonopt;
X
X/*
X * Exchange two adjacent subsequences of ARGV. One subsequence is elements
X * [first_nonopt,last_nonopt) which contains all the non-options that have
X * been skipped so far. The other is elements [last_nonopt,optind), which
X * contains all the options processed since those non-options were
X * skipped. 
X *
X * `first_nonopt' and `last_nonopt' are relocated so that they describe the
X * new indices of the non-options in ARGV after they are moved.  
X */
X
X#if defined(PROTO)
X
Xstatic void
Xexchange(char **argv)
X
X#else
X
Xstatic void
Xexchange(argv)
Xchar          **argv;
X
X#endif
X{
X    int             nonopts_size
X    = (last_nonopt - first_nonopt) * sizeof(char *);
X    char          **temp = (char **) alloca(nonopts_size);
X
X    /* Interchange the two blocks of data in argv.  */
X
X    bcopy(&argv[first_nonopt], temp, nonopts_size);
X    bcopy(&argv[last_nonopt], &argv[first_nonopt],
X	  (optind - last_nonopt) * sizeof(char *));
X    bcopy(temp, &argv[first_nonopt + optind - last_nonopt],
X	  nonopts_size);
X
X    /* Update records for the slots the non-options now occupy.  */
X
X    first_nonopt += (optind - last_nonopt);
X    last_nonopt = optind;
X}
X
X
X/*
X * Scan elements of ARGV (whose length is ARGC) for option characters
X * given in OPTSTRING. 
X *
X * If an element of ARGV starts with '-', and is not exactly "-" or "--",
X * then it is an option element.  The characters of this element (aside
X * from the initial '-') are option characters.  If `getopt' is called
X * repeatedly, it returns successively each of theoption characters from
X * each of the option elements. 
X *
X * If `getopt' finds another option character, it returns that character,
X * updating `optind' and `nextchar' so that the next call to `getopt' can
X * resume the scan with the following option character or ARGV-element. 
X *
X * If there are no more option characters, `getopt' returns `EOF'. Then
X * `optind' is the index in ARGV of the first ARGV-element that is not an
X * option.  (The ARGV-elements have been permuted so that those that are
X * not options now come last.) 
X *
X * OPTSTRING is a string containing the legitimate option characters. A colon
X * in OPTSTRING means that the previous character is an option that wants
X * an argument.  The argument is taken from the rest of the current
X * ARGV-element, or from the following ARGV-element, and returned in
X * `optarg'. 
X *
X * If an option character is seen that is not listed in OPTSTRING, return '?'
X * after printing an error message.  If you set `opterr' to zero, the
X * error message is suppressed but we still return '?'. 
X *
X * If a char in OPTSTRING is followed by a colon, that means it wants an arg,
X * so the following text in the same ARGV-element, or the text of the
X * following ARGV-element, is returned in `optarg.  Two colons mean an
X * option that wants an optional arg; if there is text in the current
X * ARGV-element, it is returned in `optarg'. 
X *
X * If OPTSTRING starts with `-', it requests a different method of handling
X * the non-option ARGV-elements.  See the comments about RETURN_IN_ORDER,
X * above.  
X */
X
X#if defined(PROTO)
X
Xint
Xgetopt(int argc, char **argv, char *optstring)
X
X#else
X
Xint
Xgetopt(argc, argv, optstring)
Xint             argc;
Xchar          **argv;
Xchar           *optstring;
X
X#endif
X{
X    /*
X     * Initialize the internal data when the first call is made. Start
X     * processing options with ARGV-element 1 (since ARGV-element 0 is the
X     * program name); the sequence of previously skipped non-option
X     * ARGV-elements is empty.  
X     */
X
X    if (optind == 0)
X    {
X	first_nonopt = last_nonopt = optind = 1;
X
X	nextchar = 0;
X
X	/*
X	 * Determine how to handle the ordering of options and nonoptions.  
X	 */
X
X	if (optstring[0] == '-')
X	    ordering = RETURN_IN_ORDER;
X	else
X	if (getenv("_POSIX_OPTION_ORDER") != 0)
X	    ordering = REQUIRE_ORDER;
X	else
X	    ordering = PERMUTE;
X    }
X
X    if (nextchar == 0 || *nextchar == 0)
X    {
X	if (ordering == PERMUTE)
X	{
X	    /*
X	     * If we have just processed some options following some
X	     * non-options, exchange them so that the options come first.  
X	     */
X
X	    if (first_nonopt != last_nonopt && last_nonopt != optind)
X		exchange(argv);
X	    else
X	    if (last_nonopt != optind)
X		first_nonopt = optind;
X
X	    /*
X	     * Now skip any additional non-options and extend the range of
X	     * non-options previously skipped.  
X	     */
X
X	    while (optind < argc
X#if !defined(MSDOS_FLAGS)
X		   && (argv[optind][0] != '-'
X#else
X		   && ((argv[optind][0] != '-' && argv[optind][0] != '/')
X#endif
X		       || argv[optind][1] == 0))
X		optind++;
X	    last_nonopt = optind;
X	}
X
X	/*
X	 * Special ARGV-element `--' means premature end of options. Skip
X	 * it like a null option, then exchange with previous non-options
X	 * as if it were an option, then skip everything else like a
X	 * non-option.  
X	 */
X
X#if !defined(MSDOS_FLAGS)
X	if (optind != argc && !strcmp(argv[optind], "--"))
X#else
X	if (optind != argc &&
X	    !(strcmp(argv[optind], "--") && strcmp(argv[optind], "/-")))
X#endif
X	{
X	    optind++;
X
X	    if (first_nonopt != last_nonopt && last_nonopt != optind)
X		exchange(argv);
X	    else
X	    if (first_nonopt == last_nonopt)
X		first_nonopt = optind;
X	    last_nonopt = argc;
X
X	    optind = argc;
X	}
X
X	/*
X	 * If we have done all the ARGV-elements, stop the scan and back
X	 * over any non-options that we skipped and permuted.  
X	 */
X
X	if (optind == argc)
X	{
X	    /*
X	     * Set the next-arg-index to point at the non-options that we
X	     * previously skipped, so the caller will digest them.  
X	     */
X	    if (first_nonopt != last_nonopt)
X		optind = first_nonopt;
X	    return EOF;
X	}
X
X	/*
X	 * If we have come to a non-option and did not permute it, either
X	 * stop the scan or describe it to the caller and pass it by.  
X	 */
X
X#if !defined(MSDOS_FLAGS)
X	if (argv[optind][0] != '-' || argv[optind][1] == 0)
X#else
X	if ((argv[optind][0] != '-' && argv[optind][0] != '/')
X	    || argv[optind][1] == 0)
X#endif
X	{
X	    if (ordering == REQUIRE_ORDER)
X		return EOF;
X	    optarg = argv[optind++];
X	    return 0;
X	}
X
X	/*
X	 * We have found another option-ARGV-element. Start decoding its
X	 * characters.  
X	 */
X
X	nextchar = argv[optind] + 1;
X    }
X
X    /* Look at and handle the next option-character.  */
X
X    {
X	char            c = *nextchar++;
X	char           *temp = (char *) index(optstring, c);
X
X	/*
X	 * Increment `optind' when we start to process its last character.  
X	 */
X	if (*nextchar == 0)
X	    optind++;
X
X	if (temp == 0 || c == ':')
X	{
X	    if (opterr != 0)
X	    {
X		if (c < 040 || c >= 0177)
X		    fprintf(stderr, "%s: unrecognized option, character code 0%o\n",
X			    argv[0], c);
X		else
X		    fprintf(stderr, "%s: unrecognized option `-%c'\n",
X			    argv[0], c);
X	    }
X	    return '?';
X	}
X	if (temp[1] == ':')
X	{
X	    if (temp[2] == ':')
X	    {
X		/*
X		 * This is an option that accepts an argument optionally.  
X		 */
X		if (*nextchar != 0)
X		{
X		    optarg = nextchar;
X		    optind++;
X		}
X		else
X		    optarg = 0;
X		nextchar = 0;
X	    }
X	    else
X	    {
X		/*
X		 * This is an option that requires an argument.  
X		 */
X		if (*nextchar != 0)
X		{
X		    optarg = nextchar;
X		    /*
X		     * If we end this ARGV-element by taking the rest as
X		     * an arg, we must advance to the next element now.  
X		     */
X		    optind++;
X		}
X		else
X		if (optind == argc)
X		{
X		    if (opterr != 0)
X			fprintf(stderr, "%s: no argument for `-%c' option\n",
X				argv[0], c);
X		    c = '?';
X		}
X		else
X		    /*
X		     * We already incremented `optind' once; increment it
X		     * again when taking next ARGV-elt as argument.  
X		     */
X		    optarg = argv[optind++];
X		nextchar = 0;
X	    }
X	}
X	return c;
X    }
X}
X
X
X#if defined(TEST)
X
X/*
X * Compile with -DTEST to make an executable for use in testing the above
X * definition of `getopt'.  
X */
X
Xint
Xmain(argc, argv)
Xint             argc;
Xchar          **argv;
X{
X    char            c;
X    int             digit_optind = 0;
X
X    while (1)
X    {
X	int             this_option_optind = optind;
X	if ((c = getopt(argc, argv, "abc:d:0123456789")) == EOF)
X	    break;
X
X	switch (c)
X	{
X	case '0':
X	case '1':
X	case '2':
X	case '3':
X	case '4':
X	case '5':
X	case '6':
X	case '7':
X	case '8':
X	case '9':
X	    if (digit_optind != 0 && digit_optind != this_option_optind)
X		printf("digits occur in two different argv-elements.\n");
X	    digit_optind = this_option_optind;
X	    printf("option %c\n", c);
X	    break;
X
X	case 'a':
X	    printf("option a\n");
X	    break;
X
X	case 'b':
X	    printf("option b\n");
X	    break;
X
X	case 'c':
X	    printf("option c with value `%s'\n", optarg);
X	    break;
X
X	case '?':
X	    break;
X
X	default:
X	    printf("?? getopt returned character code 0%o ??\n", c);
X	}
X    }
X
X    if (optind < argc)
X    {
X	printf("non-option ARGV-elements: ");
X	while (optind < argc)
X	    printf("%s ", argv[optind++]);
X	printf("\n");
X    }
X
X    return 0;
X}
X
X#endif
END_OF_getopt.c
if test 18046 -ne `wc -c <getopt.c`; then
    echo shar: \"getopt.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f makefile -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"makefile\"
else
echo shar: Extracting \"makefile\" \(653 characters\)
sed "s/^X//" >makefile <<'END_OF_makefile'
X# Ndmake makefile for GNU getopt libraries
X
XCC	= cl
X# Microsoft C 5.1 and QuickC define MSDOS automatically
XDEFS	= -DMSDOS_FLAGS -DPROTO
XCFLAGS	= -A$(MODEL) $(DEFS)
X
Xall:		done.S done.M done.C done.L
X
Xdone.S:		getopt.c
X	make Sgnuget.lib MODEL=S
Xdone.M:		getopt.c
X	make Mgnuget.lib MODEL=M
Xdone.C:		getopt.c
X	make Cgnuget.lib MODEL=C
Xdone.L:		getopt.c
X	make Lgnuget.lib MODEL=L
X
X$(MODEL)gnuget.lib:	getopt.obj
X	-del $(MODEL)gnuget.lib
X	lib $(MODEL)gnuget +getopt.obj;	
X	del getopt.obj
X	echo done >done.$(MODEL)
X
Xtest.exe:	getopt.c
X	cl -Fetest $(DEFS) -DTEST getopt.c
X
Xclean:
X	-del test.exe
X	-del getopt.obj
X	-del done.?
X
Xclobber:	clean
X	-del ?gnuget.lib
END_OF_makefile
if test 653 -ne `wc -c <makefile`; then
    echo shar: \"makefile\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0
-- 
Barry Schwartz, Chief SAPsucker                  bbs at cdspr.rutgers.edu
Grad Student, Dept. of Elec. and Comp. Engg.     bschwart at elbereth.rutgers.edu
Rutgers University College of Engg.              bbs at hankel.rutgers.edu
Piscataway, NJ 08854    U.S.A.                   rutgers!cdspr!bbs



More information about the Alt.sources mailing list