/** * Copyright 2011 Couchbase, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.couchbase.mock.util; import java.util.ArrayList; import java.util.List; /** * Small class to ease command line parsing. * * @author Trond Norbye <trond.norbye@gmail.com> * @version 1.0 */ public class Getopt { /** * Create a new instance of the option parser */ public Getopt() { options = new ArrayList<CommandLineOption>(); optind = -1; } /** * Add a new option to the list of options we accept * * @param option the new option * @return ourselves so that you may chain the calls */ public Getopt addOption(CommandLineOption option) { options.add(option); return this; } /** * Parse the given hasArgument vector * * @param argv The arguments to parse * @return The user-specified options */ public List<Entry> parse(String[] argv) { optind = -1; List<Entry> ret = new ArrayList<Entry>(); int idx = 0; while (idx < argv.length) { if (argv[idx].equals("--")) { // End of options! ++idx; break; } if (argv[idx].charAt(0) != '-') { // End of options break; } if (argv[idx].startsWith("--")) { idx = parseLongOption(argv, ret, idx); } else if (argv[idx].startsWith("-")) { idx = parseShortOption(argv, ret, idx); } else { break; } ++idx; } if (idx != argv.length) { optind = idx; } return ret; } private int parseShortOption(String[] argv, List<Entry> ret, int idx) { String keys = argv[idx].substring(1); for (char c : keys.toCharArray()) { String key = "-" + c; boolean found = false; for (CommandLineOption o : options) { if (key.charAt(1) == o.shortOption) { found = true; // this is a match :) String value = null; if (o.hasArgument) { if (idx + 1 < argv.length) { value = argv[idx + 1]; ++idx; } else { throw new IllegalArgumentException("option requires an argument -- " + key); } } ret.add(new Entry(key, value)); } } if (!found) { // Illegal option!!!!! throw new IllegalArgumentException("Illegal option -- " + key); } } return idx; } private int parseLongOption(String[] argv, List<Entry> ret, int idx) { String key = argv[idx]; int ii = key.indexOf('='); if (ii != -1) { key = key.substring(0, ii); } // Try to look up the option boolean found = false; for (CommandLineOption o : options) { if (key.equals(o.longOption)) { found = true; // this is a match :) String value = null; if (o.hasArgument) { if (ii != -1) { value = argv[idx].substring(ii + 1); } else if (idx + 1 < argv.length) { value = argv[idx + 1]; ++idx; } else { throw new IllegalArgumentException("option requires an argument -- " + key); } } ret.add(new Entry(key, value)); } } if (!found) { // Illegal option!!!!! throw new IllegalArgumentException("Illegal option -- " + key); } return idx; } /** * Get the index of the first non-argument option. * * @return The position in the argument vector for the first non-argument option */ public int getOptind() { return optind; } private int optind; private final List<CommandLineOption> options; /** * The command line options must be specified with a short and a long option * (note that you may specify null for the short option and the long option * to disable it). */ public static class CommandLineOption { private final char shortOption; private final String longOption; private final boolean hasArgument; /** * Create a new instance of the command line option * * @param shortOption the single character for the option * @param longOption the name of the long option * @param hasArgument if this option takes a mandatory argument */ public CommandLineOption(char shortOption, String longOption, boolean hasArgument) { this.shortOption = shortOption; this.longOption = longOption; this.hasArgument = hasArgument; } } public static class Entry { public final String key; public final String value; public Entry(String k, String v) { key = k; value = v; } } }