usr/src/lib/libc/port/gen/getopt.c
author Jon Tibble <meths@btinternet.com>
Thu, 09 Dec 2010 22:32:39 +0100
changeset 13255 4afa820d78b9
parent 6812 febeba71273d
permissions -rw-r--r--
298 SPARC build fails in smt_pause.o 478 Build needs fixing for pkgdepend flag day Reviewed by: [email protected] Reviewed by: [email protected] Reviewed by: [email protected] Approved by: [email protected]
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
     5
 * Common Development and Distribution License (the "License").
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 */
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
    21
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
    23
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
/*	Copyright (c) 1988 AT&T	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
/*	  All Rights Reserved  	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
    30
#pragma ident	"%Z%%M%	%I%	%E% SMI"
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    31
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 * See getopt(3C) and SUS/XPG getopt() for function definition and
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 * requirements.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 * This actual implementation is a bit looser than the specification
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 * as it allows any character other than ':' and '(' to be used as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
 * a short option character - The specification only guarantees the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
 * alnum characters ([a-z][A-Z][0-9]).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
    42
#pragma weak _getopt = getopt
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
    44
#include "lint.h"
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
#include "_libc_gettext.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
#include <unistd.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
#include <string.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
#include <stdio.h>
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
 * Generalized error processing macro. The parameter i is a pointer to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
 * the failed option string. If it is NULL, the character in c is converted
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
 * to a string and displayed instead. s is the error text.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
 * This could be / should be a static function if it is used more, but
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
 * that would require moving the 'optstring[0]' test outside of the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
 * function.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
#define	ERR(s, c, i)	if (opterr && optstring[0] != ':') { \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
	char errbuf[256]; \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
	char cbuf[2]; \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    63
	cbuf[0] = c; \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
	cbuf[1] = '\0'; \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
	(void) snprintf(errbuf, sizeof (errbuf), s, argv[0], \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
	    (i ? argv[i]+2 : cbuf)); \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
	(void) write(2, errbuf, strlen(errbuf)); }
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
 * _sp is required to keep state between successive calls to getopt() while
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    71
 * extracting aggregated short-options (ie: -abcd). Hence, getopt() is not
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    72
 * thread safe or reentrant, but it really doesn't matter.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    73
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    74
 * So, why isn't this "static" you ask?  Because the historical Bourne
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    75
 * shell has actually latched on to this little piece of private data.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    76
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
int _sp = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
 * Determine if the specified character (c) is present in the string
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
 * (optstring) as a regular, single character option. If the option is found,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
 * return a pointer into optstring pointing at the short-option character,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
 * otherwise return null. The characters ':' and '(' are not allowed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
static char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
parseshort(const char *optstring, const char c)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
	char *cp = (char *)optstring;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
	if (c == ':' || c == '(')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
		if (*cp == c)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
			return (cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
		while (*cp == '(')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
			while (*cp != '\0' && *cp != ')')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
				cp++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
	} while (*cp++ != '\0');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   101
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   102
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   103
 * Determine if the specified string (opt) is present in the string
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   104
 * (optstring) as a long-option contained within parenthesis. If the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   105
 * long-option specifies option-argument, return a pointer to it in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   106
 * longoptarg.  Otherwise set longoptarg to null. If the option is found,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   107
 * return a pointer into optstring pointing at the short-option character
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   108
 * associated with this long-option; otherwise return null.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   109
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   110
 * optstring 	The entire optstring passed to getopt() by the caller
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   111
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   112
 * opt		The long option read from the command line
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   113
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   114
 * longoptarg	The argument to the option is returned in this parameter,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   115
 *              if an option exists. Possible return values in longoptarg
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
 *              are:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
 *                  NULL		No argument was found
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
 *		    empty string ("")	Argument was explicitly left empty
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
 *					by the user (e.g., --option= )
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
 *		    valid string	Argument found on the command line
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
 * returns	Pointer to equivalent short-option in optstring, null
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
 *              if option not found in optstring.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
 * ASSUMES: No parameters are NULL
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
static char *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
parselong(const char *optstring, const char *opt, char **longoptarg)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
	char	*cp;	/* ptr into optstring, beginning of one option spec. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
	char	*ip;	/* ptr into optstring, traverses every char */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
	char	*op;	/* pointer into opt */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
	int	match;	/* nonzero if opt is matching part of optstring */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
	cp = ip = (char *)optstring;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
	do {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
		if (*ip != '(' && *++ip == '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
		if (*ip == ':' && *++ip == '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
		while (*ip == '(') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
			if (*++ip == '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
			op = (char *)opt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
			match = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
			while (*ip != ')' && *ip != '\0' && *op != '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
				match = (*ip++ == *op++ && match);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
			if (match && *ip == ')' &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
			    (*op == '\0' || *op == '=')) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
				if ((*op) == '=') {
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
   152
					/* may be an empty string - OK */
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
   153
					(*longoptarg) = op + 1;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
				} else {
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
   155
					(*longoptarg) = NULL;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
				return (cp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
			if (*ip == ')' && *++ip == '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
				break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
		cp = ip;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
		 * Handle double-colon in optstring ("a::(longa)")
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
		 * The old getopt() accepts it and treats it as a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
		 * required argument.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
		while ((cp > optstring) && ((*cp) == ':')) {
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
   169
			--cp;
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
	} while (*cp != '\0');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   172
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
} /* parselong() */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   174
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
 * External function entry point.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
int
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
getopt(int argc, char *const *argv, const char *optstring)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
	char	c;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
	char	*cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
	int	longopt;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
	char	*longoptarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
	 * Has the end of the options been encountered?  The following
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
	 * implements the SUS requirements:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
	 * If, when getopt() is called:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
	 *	argv[optind]	is a null pointer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
	 *	*argv[optind]	is not the character '-'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
	 *	argv[optind]	points to the string "-"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
	 * getopt() returns -1 without changing optind. If
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
	 *	argv[optind]	points to the string "--"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
	 * getopt() returns -1 after incrementing optind.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	if (_sp == 1) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
		if (optind >= argc || argv[optind][0] != '-' ||
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
		    argv[optind] == NULL || argv[optind][1] == '\0')
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
			return (EOF);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
		else if (strcmp(argv[optind], "--") == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
			optind++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
			return (EOF);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   207
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
	 * Getting this far indicates that an option has been encountered.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
	 * Note that the syntax of optstring applies special meanings to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
	 * the characters ':' and '(', so they are not permissible as
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
	 * option letters. A special meaning is also applied to the ')'
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
	 * character, but its meaning can be determined from context.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
	 * Note that the specification only requires that the alnum
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   215
	 * characters be accepted.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
	 * If the second character of the argument is a '-' this must be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
	 * a long-option, otherwise it must be a short option.  Scan for
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
	 * the option in optstring by the appropriate algorithm. Either
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
	 * scan will return a pointer to the short-option character in
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
	 * optstring if the option is found and NULL otherwise.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
	 * For an unrecognized long-option, optopt will equal 0, but
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
	 * since long-options can't aggregate the failing option can
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	 * be identified by argv[optind-1].
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	optopt = c = (unsigned char)argv[optind][_sp];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	optarg = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
	longopt = (_sp == 1 && c == '-');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
	if (!(longopt ?
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
	    ((cp = parselong(optstring, argv[optind]+2, &longoptarg)) != NULL) :
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	    ((cp = parseshort(optstring, c)) != NULL))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
		ERR(_libc_gettext("%s: illegal option -- %s\n"),
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
		    c, (longopt ? optind : 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
		 * Note: When the long option is unrecognized, optopt
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
		 * will be '-' here, which matches the specification.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
		if (argv[optind][++_sp] == '\0' || longopt) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
			optind++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
			_sp = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
		return ('?');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
	optopt = c = *cp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
	 * A valid option has been identified.  If it should have an
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
	 * option-argument, process that now.  SUS defines the setting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
	 * of optarg as follows:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
	 *   1.	If the option was the last character in the string pointed to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
	 *	by an element of argv, then optarg contains the next element
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
	 *	of argv, and optind is incremented by 2. If the resulting
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
	 *	value of optind is not less than argc, this indicates a
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
	 *	missing option-argument, and getopt() returns an error
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
	 *	indication.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
	 *   2.	Otherwise, optarg points to the string following the option
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
	 *	character in that element of argv, and optind is incremented
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
	 *	by 1.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
	 * The second clause allows -abcd (where b requires an option-argument)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
	 * to be interpreted as "-a -b cd".
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
	 * Note that the option-argument can legally be an empty string,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
	 * such as:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
	 * 	command --option= operand
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
	 * which explicitly sets the value of --option to nil
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
	if (*(cp + 1) == ':') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
		/* The option takes an argument */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
		if (!longopt && argv[optind][_sp+1] != '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
			optarg = &argv[optind++][_sp+1];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
		} else if (longopt && longoptarg) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
			 * The option argument was explicitly set to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
			 * the empty string on the command line (--option=)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
			optind++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
			optarg = longoptarg;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
		} else if (++optind >= argc) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
			ERR(_libc_gettext("%s: option requires an argument" \
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
			    " -- %s\n"), c, (longopt ? optind - 1 : 0));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
			_sp = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
			optarg = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
			return (optstring[0] == ':' ? ':' : '?');
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
			optarg = argv[optind++];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
		_sp = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
		/* The option does NOT take an argument */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
		if (longopt && (longoptarg != NULL)) {
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
   294
			/* User supplied an arg to an option that takes none */
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
   295
			ERR(_libc_gettext(
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
   296
			    "%s: option doesn't take an argument -- %s\n"),
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
   297
			    0, (longopt ? optind : 0));
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
   298
			optarg = longoptarg = NULL;
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 0
diff changeset
   299
			c = '?';
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
		if (longopt || argv[optind][++_sp] == '\0') {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
			_sp = 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
			optind++;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
		optarg = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
	return (c);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
} /* getopt() */