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 * ident "%Z%%M% %I% %E% SMI" 24 * 25 * Copyright 1998-2002 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 package com.sun.dhcpmgr.cli.common; 29 30 import java.lang.IllegalArgumentException; 31 import java.text.MessageFormat; 32 33 /** 34 * This class provides the functionality for parsing command line 35 * arguments (similar to getopt(3C)). 36 * After constructing an instance of it, getNextOption() can be used 37 * to get the next option. getOptionArg() can be used to get the argument for 38 * that option. getNextOptionIndex() returns how many arguments are already 39 * processed from the arguments list. 40 * 41 * This code was "borrowed" from the Viper project. We have our own copy of 42 * this code, because the Viper project has deprecated their class and we 43 * have had to modify the original code. 44 */ 45 public class GetOpt { 46 protected int optind = 0; 47 protected String optarg = null; 48 protected String argv[] = null; 49 protected int argc = 0; 50 protected String optionString = null; 51 52 // e.g in -v (- is in 0th position) 53 // 54 int MINUS_POSITION = 0; 55 56 // e.g. in -v (v is in 1st position ) 57 // 58 int OPTION_POSITION = 1; 59 60 // e.g. in -vGoldrush (G is in 2nd position ) 61 // 62 int AFTER_OPTION_POSITION = 2; 63 64 /** 65 * Constructor 66 * @parameter argv -- Array of string arguments. 67 * @parameter optionString -- contains the option letters that 68 * will be recognized; 69 * if a letter is followed by a colon, 70 * the option is expected to have an argument. 71 * if a letter is followed by a semi-colon, 72 * the argument to the letter is optional. 73 * e.g. abdf:e 74 * legal arguments are a, b, d, f, e. 75 * f option requires a argument. 76 */ 77 public GetOpt(String argv[], String optionString) { 78 this.argv = argv; 79 this.optionString = optionString; 80 this.argc = argv.length; 81 } 82 83 /* 84 * Returns the next valid option. 85 * Throws an IllegalArgumentException 86 * a) if option is not valid or 87 * b) an option required an argument and is not provided 88 * Returns -1 if no more options left. 89 */ 90 public int getNextOption() throws IllegalArgumentException { 91 char currentOption; 92 optarg = null; 93 94 // ------------------------------------------------ 95 // Find out if option exists 96 97 if (optind >= argc || (argv[optind].length() < 2) || 98 argv[optind].charAt(MINUS_POSITION) != '-') { 99 100 return -1; 101 } 102 103 // --------------------------------------------------- 104 // So see if it is a legal option 105 106 currentOption = argv[optind].charAt(OPTION_POSITION); 107 108 if (!isValidOption(currentOption)) { 109 optind = optind + 1; 110 String format = ResourceStrings.getString("getopt_illegal_option"); 111 Object[] args = new Object[1]; 112 args[0] = new Character((char)currentOption); 113 String msg = MessageFormat.format(format, args); 114 throw new IllegalArgumentException(msg); 115 } 116 117 // ------------------------------------------------------------ 118 // We have a legal option now, find out if it expected to have optarg. 119 120 if (isOptionArgAllowedByOption(currentOption) && 121 OPTION_POSITION == 1) { 122 123 // ------------------------------------- 124 // Case when optarg is given with the option itself, 125 // like -hlastgas.east. Then extract the optarg out. 126 127 if (argv[optind].length() != 2) { 128 optarg = argv[optind].substring(AFTER_OPTION_POSITION); 129 optind++; 130 } 131 // ------------------------------------------ 132 // Case when optarg is not provided, return error if it was 133 // mandatory 134 135 else if (optind+1 >= argc) { 136 optind++; 137 if (isOptionArgMandatoryByOption(currentOption)) { 138 String format = 139 ResourceStrings.getString("getopt_requires_argument"); 140 Object[] args = new Object[1]; 141 args[0] = new Character((char)currentOption); 142 String msg = MessageFormat.format(format, args); 143 throw new IllegalArgumentException(msg); 144 } 145 } 146 // ------------------------------------------------ 147 // Case when there is a argument that could have been used 148 // as a optarg, but actually it is just another option. 149 150 else if ((argv[optind+1].length() > MINUS_POSITION) && 151 (argv[optind+1].charAt(MINUS_POSITION) == '-') && 152 (isValidOption(argv[optind+1].charAt(OPTION_POSITION)))) { 153 optind++; 154 if (isOptionArgMandatoryByOption(currentOption)) { 155 String format = 156 ResourceStrings.getString("getopt_requires_argument"); 157 Object[] args = new Object[1]; 158 args[0] = new Character((char)currentOption); 159 String msg = MessageFormat.format(format, args); 160 throw new IllegalArgumentException(msg); 161 } 162 } 163 164 // -------------------------------------------- 165 // Finally the good case 166 167 else { 168 optarg = argv[++optind]; 169 optind++; 170 } 171 172 OPTION_POSITION = 1; 173 174 } else if (isOptionArgMandatoryByOption(currentOption)) { 175 String format = ResourceStrings.getString("getopt_cannot_group"); 176 Object[] args = new Object[1]; 177 args[0] = new Character((char)currentOption); 178 String msg = MessageFormat.format(format, args); 179 throw new IllegalArgumentException(msg); 180 } else if (argv[optind].length() == OPTION_POSITION + 1) { 181 OPTION_POSITION = 1; 182 optind++; 183 } else { // illegal argument supplied for option 184 OPTION_POSITION++; 185 } 186 return currentOption; 187 } 188 189 /** 190 * Returns the argument for the option being handled. 191 */ 192 public String getOptionArg() { 193 return optarg; 194 } 195 196 /** 197 * Returns true if option is a valid option 198 */ 199 private boolean isValidOption(char c) { 200 if ((c == ':') || (optionString.indexOf(c) == -1)) { 201 return false; 202 } else { 203 return true; 204 } 205 } 206 207 /** 208 * Returns true if option provided needs a argument. 209 * throws exception if option is not a valid option at first place. 210 */ 211 private boolean isOptionArgMandatoryByOption(char option) { 212 int x = option; 213 if (isValidOption(option) 214 && (optionString.length() > optionString.indexOf(option) + 1) 215 && (optionString.charAt(optionString.indexOf(option) + 1) == ':')) 216 return true; 217 else 218 return false; 219 } 220 221 /** 222 * Returns how many arguments are already processed by the getNextOption() 223 * function. The other way to look at it is what argument is going to be 224 * processed by getNextOption() method next. 225 */ 226 public int getNextOptionIndex() { 227 return optind; 228 } 229 230 /** 231 * Returns true if option provided allows a argument. 232 * throws exception if option is not a valid option at first place. 233 */ 234 private boolean isOptionArgAllowedByOption(char option) { 235 int x = option; 236 if (isValidOption(option) 237 && (optionString.length() > optionString.indexOf(option) + 1) 238 && ((optionString.charAt(optionString.indexOf(option) + 1) == ':') || 239 (optionString.charAt(optionString.indexOf(option) + 1) == ';'))) 240 return true; 241 else 242 return false; 243 } 244 }