
org.codehaus.groovy.tools.shell.util.CommandArgumentParser.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of groovy-groovysh Show documentation
Show all versions of groovy-groovysh Show documentation
Groovy: A powerful, dynamic language for the JVM
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.codehaus.groovy.tools.shell.util
import groovy.transform.CompileStatic
@CompileStatic
class CommandArgumentParser {
/**
* takes a String and tokenizes it according to posix-shell-like rules, meaning
* arguments are separated by blanks or hyphens, and hyphens wrap tokens regardless
* of blanks, other hyphens or escaped hyphens within the wrapping hyphens.
*
* Example: "foo bar 123'456' 'abc\'def\\' ''" has 6 tokens:
* ["foo", "bar", "123", "456", "abc'def\", ""]
*
* @param untrimmedLine
* @param numTokensToCollect stop processing after so many tokens, negative means unlimited
* @return
*/
static List parseLine(final String untrimmedLine, final int numTokensToCollect = -1) {
assert untrimmedLine != null
final String line = untrimmedLine.trim()
List tokens = []
String currentToken = ''
// state machine being either in neutral state, in singleHyphenOpen state, or in doubleHyphenOpen State.
boolean singleHyphenOpen = false
boolean doubleHyphenOpen = false
int index = 0
for (; index < line.length(); index++) {
if (tokens.size() == numTokensToCollect) {
break
}
String ch = line.charAt(index)
// escaped char?
if (ch == '\\' && (singleHyphenOpen || doubleHyphenOpen)) {
ch = (index == line.length() - 1) ? '\\' : line.charAt(index + 1)
index++
currentToken += ch
continue
}
if (ch == '"' && !singleHyphenOpen) {
if (doubleHyphenOpen) {
tokens.add(currentToken)
currentToken = ''
doubleHyphenOpen = false
} else {
if (currentToken.size() > 0) {
tokens.add(currentToken)
currentToken = ''
}
doubleHyphenOpen = true
}
continue
}
if (ch == '\'' && !doubleHyphenOpen) {
if (singleHyphenOpen) {
tokens.add(currentToken)
currentToken = ''
singleHyphenOpen = false
} else {
if (currentToken.size() > 0) {
tokens.add(currentToken)
currentToken = ''
}
singleHyphenOpen = true
}
continue
}
if (ch == ' ' && !doubleHyphenOpen && !singleHyphenOpen) {
if (currentToken.size() > 0) {
tokens.add(currentToken)
currentToken = ''
}
continue
}
currentToken += ch
} // end for char in line
if (index == line.length() && doubleHyphenOpen) {
throw new IllegalArgumentException('Missing closing " in ' + line + ' -- ' + tokens)
}
if (index == line.length() && singleHyphenOpen) {
throw new IllegalArgumentException('Missing closing \' in ' + line + ' -- ' + tokens)
}
if (currentToken.size() > 0) {
tokens.add(currentToken)
}
return tokens
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy