in mysqlshdk/libs/utils/utils_general.cc [507:647]
static std::size_t span_quotable_string_literal(
const std::string &s, std::size_t p, std::string *out_string,
bool allow_number_at_beginning = false) {
if (s.size() <= p) return p;
char quote = s[p];
if (quote != '\'' && quote != '"') {
// check if valid initial char
if (!std::isalpha(quote) &&
!(allow_number_at_beginning && std::isdigit(quote)) && quote != '_' &&
quote != '$' && quote != '%')
throw std::runtime_error("Invalid character in string literal");
quote = 0;
} else {
p++;
}
if (quote == 0) {
while (p < s.size()) {
if (!std::isalnum(s[p]) && s[p] != '_' && s[p] != '$' && s[p] != '.' &&
s[p] != '%')
break;
if (out_string) out_string->push_back(s[p]);
++p;
}
} else {
int esc = 0;
bool done = false;
while (p < s.size() && !done) {
if (esc == quote && s[p] != esc) {
done = true;
break;
}
switch (s[p]) {
case '"':
case '\'':
if (quote == s[p]) {
if (esc == quote || esc == '\\') {
if (out_string) out_string->push_back(s[p]);
esc = 0;
} else {
esc = s[p];
}
} else {
if (out_string) out_string->push_back(s[p]);
esc = 0;
}
break;
case '\\':
if (esc == '\\') {
if (out_string) out_string->push_back(s[p]);
esc = 0;
} else if (esc == 0) {
esc = '\\';
} else {
done = true;
}
break;
case 'n':
if (esc == '\\') {
if (out_string) out_string->push_back('\n');
esc = 0;
} else if (esc == 0) {
if (out_string) out_string->push_back(s[p]);
} else {
done = true;
}
break;
case 't':
if (esc == '\\') {
if (out_string) out_string->push_back('\t');
esc = 0;
} else if (esc == 0) {
if (out_string) out_string->push_back(s[p]);
} else {
done = true;
}
break;
case 'b':
if (esc == '\\') {
if (out_string) out_string->push_back('\b');
esc = 0;
} else if (esc == 0) {
if (out_string) out_string->push_back(s[p]);
} else {
done = true;
}
break;
case 'r':
if (esc == '\\') {
if (out_string) out_string->push_back('\r');
esc = 0;
} else if (esc == 0) {
if (out_string) out_string->push_back(s[p]);
} else {
done = true;
}
break;
case '0':
if (esc == '\\') {
if (out_string) out_string->push_back('\0');
esc = 0;
} else if (esc == 0) {
if (out_string) out_string->push_back(s[p]);
} else {
done = true;
}
break;
case 'Z':
if (esc == '\\') {
if (out_string) {
out_string->push_back(26);
}
esc = 0;
} else if (esc == 0) {
if (out_string) out_string->push_back(s[p]);
} else {
done = true;
}
break;
default:
if (esc == '\\') {
if (out_string) out_string->push_back(s[p]);
esc = 0;
} else if (esc == 0) {
if (out_string) out_string->push_back(s[p]);
} else {
done = true;
}
break;
}
++p;
}
if (!done && esc == quote) {
done = true;
} else if (!done) {
throw std::runtime_error("Invalid syntax in string literal");
}
}
return p;
}