split method
Implementation
Iterable<String> split() sync* {
var i = 0;
var lastDollar = -2; // position of last dollar sign we saw
String? inDollarQuote;
String? inQuote;
String? escaped;
String? token;
if (debug) {
print('full input: >$str<');
}
while (true) {
final pos = i;
final char = i < str.length ? str[i++] : null;
if (debug) {
print([
'position: $pos',
'input: >$char<',
'accumulated: $token',
'inQuote: $inQuote',
'inDollarQuote: $inDollarQuote',
'lastDollar: $lastDollar',
'escaped: $escaped'
].join('\n'));
}
// Ran out of characters, we're done
if (char == null) {
if (inQuote != null) {
throw ('Got EOF while in a quoted string');
}
if (escaped != null) {
throw ('Got EOF while in an escape sequence');
}
if (token != null) {
yield token;
}
return;
}
// We were in an escape sequence, complete it
if (escaped != null) {
if (char == '\n') {
// An escaped newline just means to continue the command on the next
// line. We just need to ignore it.
} else if (inQuote != null) {
// If we are in a quote, just accumulate the whole escape sequence,
// as we will interpret escape sequences later.
token = (token ?? '') + escaped + char;
} else {
// Just use the literal character
token = (token ?? '') + char;
}
escaped = null;
continue;
}
if (escapes.contains(char)) {
if (inQuote == null ||
inDollarQuote != null ||
escapedQuotes.contains(inQuote)) {
// We encountered an escape character, which is going to affect how
// we treat the next character.
escaped = char;
continue;
} else {
// This string type doesn't use escape characters. Ignore for now.
}
}
// We were in a string
if (inQuote != null) {
// String is finished. Don't grab the quote character.
if (char == inQuote) {
token = processEscapes(token ?? '', inQuote, inDollarQuote == '\'');
inQuote = null;
inDollarQuote = null;
continue;
}
// String isn't finished yet, accumulate the character
token = (token ?? '') + char;
continue;
}
// This is the start of a new string, don't accumulate the quotation mark
if (quotes.contains(char)) {
inQuote = char;
if (lastDollar == pos - 1) {
if (char == '\'' && !ansiCQuotes) {
// Feature not enabled
} else if (char == '"' && !localeQuotes) {
// Feature not enabled
} else {
inDollarQuote = char;
}
}
token = (token ?? ''); // fixes blank string
if (inDollarQuote != null) {
// Drop the opening $ we captured before
token = token.substring(0, token.length - 1);
}
continue;
}
// This is a dollar sign, record that we saw it in case it's the start of
// an ANSI C or localized string
if (inQuote == null && char == '\$') {
lastDollar = pos;
}
// This is whitespace, so yield the token if we have one
if (whitespace.contains(char)) {
if (token != null) {
yield token;
}
token = null;
continue;
}
// Otherwise, accumulate the character
token = (token ?? '') + char;
}
}