001 /*--------------------------------------------------------------------------+
002 $Id: CommandLineTokenStream.java 26283 2010-02-18 11:18:57Z juergens $
003 | |
004 | Copyright 2005-2010 Technische Universitaet Muenchen |
005 | |
006 | Licensed under the Apache License, Version 2.0 (the "License"); |
007 | you may not use this file except in compliance with the License. |
008 | You may obtain a copy of the License at |
009 | |
010 | http://www.apache.org/licenses/LICENSE-2.0 |
011 | |
012 | Unless required by applicable law or agreed to in writing, software |
013 | distributed under the License is distributed on an "AS IS" BASIS, |
014 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
015 | See the License for the specific language governing permissions and |
016 | limitations under the License. |
017 +--------------------------------------------------------------------------*/
018 package edu.tum.cs.commons.options;
019
020 import java.util.LinkedList;
021 import java.util.Queue;
022
023 /**
024 * This class preprocesses the command line arguments by splitting them into
025 * several tokens. It supports the GNU style syntax as described in
026 * {@link edu.tum.cs.commons.options.CommandLine}.
027 *
028 * @author Benjamin Hummel
029 * @author $Author: juergens $
030 *
031 * @version $Rev: 26283 $
032 * @levd.rating GREEN Hash: D702FFBA7BE4D5C8637EEE2993924D3B
033 */
034 public class CommandLineTokenStream {
035
036 /** Queue storing remaining short options (results from option chaining). */
037 private final Queue<Character> shortOptionQueue = new LinkedList<Character>();
038
039 /** Pending parameter (possibly remaining from the last long option read). */
040 private String pendingParam = null;
041
042 /** Queue storing all remaining arguments. */
043 private final Queue<String> argQueue = new LinkedList<String>();
044
045 /**
046 * Constructs a new CommandLineTokenStream on the given arguments.
047 *
048 * @param args
049 */
050 public CommandLineTokenStream(String[] args) {
051 for (String a : args) {
052 argQueue.add(a);
053 }
054 }
055
056 /**
057 * Returns whether a further token is available.
058 */
059 public boolean hasNext() {
060 return !argQueue.isEmpty() || !shortOptionQueue.isEmpty()
061 || pendingParam != null;
062 }
063
064 /**
065 * Returns whether the next token is available and is a short option.
066 */
067 public boolean nextIsShortOption() {
068 if (!shortOptionQueue.isEmpty()) {
069 return true;
070 }
071 if (pendingParam != null || argQueue.isEmpty()) {
072 return false;
073 }
074 String next = argQueue.peek();
075 return next.length() >= 2 && next.charAt(0) == '-'
076 && next.charAt(1) != '-';
077 }
078
079 /**
080 * Returns whether the next token is available and is a long option.
081 */
082 public boolean nextIsLongOption() {
083 if (!shortOptionQueue.isEmpty() || pendingParam != null
084 || argQueue.isEmpty()) {
085 return false;
086 }
087 return argQueue.peek().startsWith("--");
088 }
089
090 /**
091 * Returns whether the next token is available and can be used as a file
092 * argument.
093 */
094 public boolean nextIsFileArgument() {
095 if (!shortOptionQueue.isEmpty() || pendingParam != null
096 || argQueue.isEmpty()) {
097 return false;
098 }
099 return !argQueue.peek().startsWith("-");
100 }
101
102 /**
103 * Returns whether the next token is available and can be used as a
104 * parameter to an option.
105 */
106 public boolean nextIsParameter() {
107 if (!shortOptionQueue.isEmpty()) {
108 return false;
109 }
110 if (pendingParam != null) {
111 return true;
112 }
113 return !argQueue.isEmpty();
114 }
115
116 /**
117 * Returns the next token as a plain string.
118 */
119 public String next() {
120 if (!shortOptionQueue.isEmpty()) {
121 return "-" + shortOptionQueue.poll();
122 }
123 if (pendingParam != null) {
124 String result = pendingParam;
125 pendingParam = null;
126 return result;
127 }
128 return argQueue.poll();
129 }
130
131 /**
132 * Returns the next token as a short option.
133 */
134 public char nextShortOption() {
135 if (!nextIsShortOption()) {
136 throw new IllegalStateException("No short option available!");
137 }
138 if (shortOptionQueue.isEmpty()) {
139 String arg = argQueue.poll();
140 for (int i = 1; i < arg.length(); ++i) {
141 shortOptionQueue.add(arg.charAt(i));
142 }
143 }
144 return shortOptionQueue.poll();
145 }
146
147 /**
148 * Returns the next token as a long option.
149 */
150 public String nextLongOption() {
151 if (!nextIsLongOption()) {
152 throw new IllegalStateException("No long option available!");
153 }
154 String res = argQueue.poll().substring(2);
155 if (res.contains("=")) {
156 String[] parts = res.split("=", 2);
157 res = parts[0];
158 pendingParam = parts[1];
159 }
160 return res;
161 }
162 }