001: /*
002: Copyright 2004-2007 Paul R. Holser, Jr. All rights reserved.
003: Licensed under the Academic Free License version 3.0
004: */
005:
006: package joptsimple;
007:
008: import java.util.NoSuchElementException;
009:
010: /**
011: * Tokenizes a short option specification string as expected by {@link
012: * OptionParser#OptionParser(java.lang.String)}.
013: *
014: * @since 1.0
015: * @author <a href="mailto:pholser@alumni.rice.edu">Paul Holser</a>
016: * @version $Id: OptionSpecTokenizer.java,v 1.15 2007/04/10 20:06:24 pholser Exp $
017: */
018: class OptionSpecTokenizer {
019: private static final char POSIXLY_CORRECT_MARKER = '+';
020:
021: private String specification;
022: private int index;
023:
024: OptionSpecTokenizer(String specification) {
025: if (specification == null)
026: throw new NullPointerException("null option specification");
027:
028: this .specification = specification;
029: }
030:
031: boolean hasMore() {
032: return index < specification.length();
033: }
034:
035: OptionSpec next() {
036: if (!hasMore())
037: throw new NoSuchElementException();
038:
039: OptionSpec spec;
040:
041: String optionCandidate = String.valueOf(specification
042: .charAt(index++));
043:
044: if (ParserRules.RESERVED_FOR_EXTENSIONS.equals(optionCandidate)) {
045: spec = handleReservedForExtensionsToken();
046:
047: if (spec != null)
048: return spec;
049: }
050:
051: ParserRules.checkLegalOption(optionCandidate);
052:
053: if (!hasMore())
054: spec = new NoArgumentOptionSpec(optionCandidate);
055: else if (specification.charAt(index) == ':')
056: spec = handleArgumentAcceptingOption(optionCandidate);
057: else
058: spec = new NoArgumentOptionSpec(optionCandidate);
059:
060: return spec;
061: }
062:
063: void configure(OptionParser parser) {
064: adjustForPosixlyCorrect(parser);
065:
066: while (hasMore())
067: parser.recognize(next());
068: }
069:
070: private void adjustForPosixlyCorrect(OptionParser parser) {
071: if (POSIXLY_CORRECT_MARKER == specification.charAt(0)) {
072: parser.setPosixlyCorrect(true);
073: specification = specification.substring(1);
074: }
075: }
076:
077: private OptionSpec handleReservedForExtensionsToken() {
078: if (!hasMore())
079: return new NoArgumentOptionSpec(
080: ParserRules.RESERVED_FOR_EXTENSIONS);
081:
082: if (specification.charAt(index) == ';') {
083: ++index;
084: return new AlternativeLongOptionSpec();
085: }
086:
087: return null;
088: }
089:
090: private OptionSpec handleArgumentAcceptingOption(String candidate) {
091: index++;
092:
093: if (hasMore() && specification.charAt(index) == ':') {
094: index++;
095: return new OptionalArgumentOptionSpec(candidate);
096: }
097:
098: return new RequiredArgumentOptionSpec(candidate);
099: }
100: }
|