my version
[IRC.git] / Robust / Transactions / jcarderbenchmarks / mysrc / com / enea / jcarder / util / OptionParser.java
1 /*
2  * JCarder -- cards Java programs to keep threads disentangled
3  *
4  * Copyright (C) 2006-2007 Enea AB
5  * Copyright (C) 2007 Ulrik Svensson
6  * Copyright (C) 2007 Joel Rosdahl
7  *
8  * This program is made available under the GNU GPL version 2, with a special
9  * exception for linking with JUnit. See the accompanying file LICENSE.txt for
10  * details.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.
15  */
16
17 package com.enea.jcarder.util;
18
19 import java.util.ArrayList;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 /**
26  * This class parses command-line options.
27  */
28 public class OptionParser {
29     private class OptionData {
30         String valueName;
31         String description;
32     }
33
34     private final List<String> mArguments = new ArrayList<String>();
35     private final Map<String, String> mParsedOptions =
36         new HashMap<String, String>();
37     private final Map<String, OptionData> mValidOptions =
38         new HashMap<String, OptionData>();
39
40     public OptionParser() {
41     }
42
43     /**
44      * Tell the parser to recognize a new option.
45      *
46      * Options can be given on the following forms:
47      *
48      * <ul>
49      * <li>-option</li>
50      * <li>-option foo</li>
51      * </ul>
52      *
53      * The first form specifies an option without a value and the second
54      * specifies an option with a value.
55      *
56      * @param option
57      *            The option.
58      * @param description
59      *            Description of the option.
60      */
61     public void addOption(String option, String description) {
62         final int spacePos = option.indexOf(' ');
63         final String flag;
64         final String valueName;
65         if (spacePos == -1) {
66             flag = option;
67             valueName = null;
68         } else {
69             flag = option.substring(0, spacePos);
70             valueName = option.substring(spacePos + 1);
71         }
72         OptionData data = new OptionData();
73         data.valueName = valueName;
74         data.description = description;
75         mValidOptions.put(flag, data);
76     }
77
78     /**
79      * Get arguments remaining after options (and their values) have been
80      * parsed.
81      *
82      * @return The arguments.
83      */
84     public List<String> getArguments() {
85         return mArguments;
86     }
87
88     /**
89      * Get a string containing help text describing available options.
90      *
91      * @return The help text.
92      */
93     public String getOptionHelp() {
94         StringBuilder sb = new StringBuilder();
95         OptionFormatter formatter = new OptionFormatter(2, 23, 79);
96         ArrayList<String> options = new ArrayList<String>();
97         options.addAll(mValidOptions.keySet());
98         Collections.sort(options);
99         for (String option : options) {
100             final OptionData data = mValidOptions.get(option);
101             final String optAndVal;
102             if (data.valueName == null) {
103                 optAndVal = option;
104             } else {
105                 optAndVal = option + " " + data.valueName;
106             }
107             formatter.format(sb, optAndVal, data.description);
108         }
109         return sb.toString();
110     }
111
112     /**
113      * Get parsed options.
114      *
115      * The map is keyed on option and the values are the option values (null if
116      * no parameter was expected).
117      *
118      * @return The option map.
119      */
120     public Map<String, String> getOptions() {
121         return mParsedOptions;
122     }
123
124     /**
125      * Parse arguments.
126      *
127      * @param arguments
128      *            The arguments to parse.
129      * @throws InvalidOptionException
130      *             If an invalid option is encountered.
131      */
132     public void parse(String[] arguments) throws InvalidOptionException {
133         mArguments.clear();
134         boolean reachedNonOption = false;
135         for (int i = 0; i < arguments.length; ++i) {
136             if (!reachedNonOption
137                     && (arguments[i].length() == 0
138                             || arguments[i].charAt(0) != '-')) {
139                 reachedNonOption = true;
140             }
141             if (reachedNonOption) {
142                 mArguments.add(arguments[i]);
143             } else {
144                 String option = arguments[i];
145                 if (mValidOptions.containsKey(option)) {
146                     OptionData data = mValidOptions.get(option);
147                     String optionArgument;
148                     if (data.valueName != null) {
149                         ++i;
150                         if (i < arguments.length) {
151                             optionArgument = arguments[i];
152                         } else {
153                             String message = "value missing to flag " + option;
154                             throw new InvalidOptionException(message);
155                         }
156                     } else {
157                         optionArgument = null;
158                     }
159                     mParsedOptions.put(option, optionArgument);
160                 } else {
161                     throw new InvalidOptionException("invalid flag: "
162                                                      + arguments[i]);
163                 }
164             }
165         }
166     }
167 }