splitLiveShellLine function
Splits a shell line into words the way a POSIX shell does: whitespace
separates words, quotes group them, a backslash escapes the next
character, and # at the start of a word begins a comment.
Throws a FormatException when a quote isn't closed.
Implementation
List<String> splitLiveShellLine(String line) {
final List<String> words = [];
final StringBuffer word = StringBuffer();
bool inWord = false;
String? quote;
for (int i = 0; i < line.length; i++) {
final String char = line[i];
if (quote != null) {
if (char == quote) {
quote = null;
} else if (quote == '"' &&
char == r'\' &&
i + 1 < line.length &&
r'"\$`'.contains(line[i + 1])) {
word.write(line[++i]);
} else {
word.write(char);
}
continue;
}
if (char == "'" || char == '"') {
quote = char;
inWord = true;
} else if (char == r'\' && i + 1 < line.length) {
word.write(line[++i]);
inWord = true;
} else if (char.trim().isEmpty) {
if (inWord) {
words.add(word.toString());
word.clear();
inWord = false;
}
} else if (char == '#' && !inWord) {
break;
} else {
word.write(char);
inWord = true;
}
}
if (quote != null) {
throw FormatException('Missing a closing $quote.');
}
if (inWord) words.add(word.toString());
return words;
}