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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * See LICENSE.txt included in this distribution for the specific 9 * language governing permissions and limitations under the License. 10 * 11 * When distributing Covered Code, include this CDDL HEADER in each 12 * file and include the License file at LICENSE.txt. 13 * If applicable, add the following below this CDDL HEADER, with the 14 * fields enclosed by brackets "[]" replaced with your own identifying 15 * information: Portions Copyright [yyyy] [name of copyright owner] 16 * 17 * CDDL HEADER END 18 */ 19 20 /* 21 * Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved. 22 */ 23 package org.opengrok.indexer.util; 24 25 import java.text.ParseException; 26 import java.util.ArrayList; 27 import java.util.List; 28 29 /** 30 * A simple implementation of the getopt(3c). It does just implement what I 31 * need ;-) Please note that I dislike the way GNU getopt allows mixing of 32 * options and arguments, so this version will stop processing options as soon 33 * as it encounters an argument. 34 */ 35 public class Getopt { 36 private static class Option { 37 char option; 38 String argument; 39 } 40 41 private final List<Option> options; 42 private int current; 43 private int optind; 44 private final String[] argv; 45 private final String opts; 46 47 /** 48 * Creates a new instance of Getopt. 49 * @param argv argument vector 50 * @param opts the list of allowed options 51 */ Getopt(String[] argv, String opts)52 public Getopt(String[] argv, String opts) { 53 options = new ArrayList<>(); 54 current = -1; 55 optind = -1; 56 this.argv = argv.clone(); 57 this.opts = opts; 58 } 59 60 /** 61 * Parse the command line options. 62 * @throws ParseException if an illegal argument is passed 63 */ parse()64 public void parse() throws ParseException { 65 66 int ii = 0; 67 while (ii < argv.length) { 68 char[] chars = argv[ii].toCharArray(); 69 if (chars.length > 0 && chars[0] == '-') { 70 if (argv[ii].equals("--")) { 71 // End of command line options ;) 72 optind = ii + 1; 73 break; 74 } 75 76 for (int jj = 1; jj < chars.length; ++jj) { 77 int idx = opts.indexOf(chars[jj]); 78 if (idx == -1) { 79 throw new ParseException("Unknown argument: " + argv[ii].substring(jj), ii); 80 } 81 82 Option option = new Option(); 83 option.option = chars[jj]; 84 options.add(option); 85 // does this option take an argument? 86 if ((idx + 1) < opts.length() && (opts.charAt(idx + 1) == ':')) { 87 // next should be an argument 88 if ((jj + 1) < chars.length) { 89 // Rest of this is the argument 90 option.argument = argv[ii].substring(jj + 1); 91 break; 92 } 93 // next argument vector contains the argument 94 ++ii; 95 if (ii < argv.length) { 96 option.argument = argv[ii]; 97 } else { 98 throw new ParseException("Option " + chars[jj] + " requires an argument", ii); 99 } 100 } 101 } 102 ++ii; 103 } else { 104 // End of options 105 optind = ii; 106 break; 107 } 108 } 109 } 110 111 /** 112 * Get the next option in the options string. 113 * @return the next valid option, or -1 if all options are processed 114 */ getOpt()115 public int getOpt() { 116 int ret = -1; 117 118 ++current; 119 if (current < options.size()) { 120 ret = options.get(current).option; 121 } 122 123 return ret; 124 } 125 126 /** 127 * Reset the current pointer so we may traverse all the options again. 128 */ reset()129 public void reset() { 130 current = -1; 131 } 132 133 /** 134 * Get the argument to the current option. 135 * @return the argument or null if none present (or allowed) 136 */ getOptarg()137 public String getOptarg() { 138 String ret = null; 139 140 if (current < options.size()) { 141 ret = options.get(current).argument; 142 } 143 return ret; 144 } 145 146 /** 147 * Get the index of the first argument. 148 * @return the index of the first argument in the original array 149 */ getOptind()150 public int getOptind() { 151 return optind; 152 } 153 } 154