1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdio.h> 30 #include <string.h> 31 #include "volume_error.h" 32 #include "getopt_ext.h" 33 34 /* 35 * Functions 36 */ 37 38 /* 39 * Identical to getopt(3), except that 40 * 41 * 1. If "-" is the first character of optstring, each non-option argv 42 * element is handled as if it were the argument of an option with 43 * character code GETOPT_NON_OPTION_ARG. The result is that 44 * GETOPT_DONE_PARSING will not be returned until the end of the 45 * argument list has been reached. 46 * 47 * This mirrors the functionality provided by GNU getopt. 48 * 49 * 2. GETOPT_ERR_INVALID_OPT or GETOPT_ERR_MISSING_ARG is returned 50 * instead of '?'. Subsequently "-?" can be used as a valid 51 * option. 52 * 53 * 3. GETOPT_DONE_PARSING, GETOPT_ERR_INVALID_ARG, or 54 * GETOPT_NON_OPTION_ARG is returned instead of -1. 55 * 56 * @param argc 57 * The number of arguments in the array 58 * 59 * @param argv 60 * The argument array 61 * 62 * @param optstring 63 * The option letters, with ':' following options with 64 * required arguments. See note about "-" as the first 65 * character. 66 * 67 * @return GETOPT_ERR_INVALID_OPT 68 * if the option is not found in optstring 69 * 70 * GETOPT_ERR_MISSING_ARG 71 * if the option requires an argument which is missing 72 * 73 * GETOPT_ERR_INVALID_ARG 74 * if "-" is not the first character in optstring and a 75 * non-option argument is encountered 76 * 77 * GETOPT_NON_OPTION_ARG 78 * if "-" is the first character in optstring and a 79 * non-option argument is encountered 80 * 81 * GETOPT_DONE_PARSING 82 * if the end of the argument list is reached 83 * 84 * <optopt> 85 * the option character itself, if none of the above 86 * scenarios applies. 87 */ 88 extern int 89 getopt_ext( 90 int argc, 91 char * const argv[], 92 const char *optstring) 93 { 94 int c; 95 int handle_non_options = (*optstring == '-'); 96 97 /* Is "-" the first character of optstring? */ 98 if (handle_non_options) { 99 /* getopt(3) doesn't understand "-" */ 100 optstring++; 101 } 102 103 switch (c = getopt(argc, argv, optstring)) { 104 105 /* 106 * getopt(3) returns -1 when 1) it encounters a non-option 107 * argument or 2) reaches the end of the argument list. 108 * Distinguish from the two possibilities. 109 */ 110 case -1: 111 if (optind < argc) { 112 optarg = argv[optind]; 113 114 /* Non-option argument found */ 115 if (handle_non_options) { 116 /* Non-option arguments are valid */ 117 c = GETOPT_NON_OPTION_ARG; 118 optind++; 119 } else { 120 /* Non-option arguments are invalid */ 121 c = GETOPT_ERR_INVALID_ARG; 122 } 123 } else { 124 /* End of the argument list reached */ 125 c = GETOPT_DONE_PARSING; 126 } 127 break; 128 129 /* 130 * getopt(3) returns '?' when 1) the "-?" option is 131 * encountered, 2) an invalid option is given or 3) a 132 * valid option requiring an argument is found but no 133 * argument is specified. Distinguish from the three 134 * possibilities. 135 */ 136 case '?': 137 /* Is this an error or was -? encountered? */ 138 if (optopt != '?') { 139 if (strchr(optstring, optopt) == NULL) { 140 /* Invalid option */ 141 c = GETOPT_ERR_INVALID_OPT; 142 optarg = argv[optind-1]; 143 } else { 144 /* Valid option without required argument */ 145 c = GETOPT_ERR_MISSING_ARG; 146 } 147 } 148 } 149 150 return (c); 151 } 152