add a line-counting parse_string to util

master
Daniel Kolesa 2016-10-11 21:15:23 +02:00
parent 27affb1057
commit 0a88a10d99
2 changed files with 24 additions and 8 deletions

View File

@ -742,9 +742,16 @@ namespace util {
}
OSTD_EXPORT ostd::ConstCharRange parse_string(
CsState &cs, ostd::ConstCharRange str
CsState &cs, ostd::ConstCharRange str, ostd::Size &nlines
);
inline ostd::ConstCharRange parse_string(
CsState &cs, ostd::ConstCharRange str
) {
ostd::Size nlines;
return parse_string(cs, str, nlines);
}
OSTD_EXPORT ostd::ConstCharRange parse_word(
CsState &cs, ostd::ConstCharRange str
);

View File

@ -187,13 +187,16 @@ done:
namespace util {
OSTD_EXPORT ostd::ConstCharRange parse_string(
CsState &cs, ostd::ConstCharRange str
CsState &cs, ostd::ConstCharRange str, ostd::Size &nlines
) {
ostd::Size nl = 0;
nlines = nl;
if (str.empty() || (*str != '\"')) {
return str;
}
ostd::ConstCharRange orig = str;
++str;
++nl;
while (!str.empty()) {
switch (*str) {
case '\r':
@ -201,25 +204,31 @@ namespace util {
case '\"':
goto end;
case '^':
case '\\': {
bool needn = (*str == '\\');
++str;
if (!str.empty()) {
break;
if (str.empty()) {
goto end;
}
goto end;
case '\\':
++str;
if (!str.empty() && ((*str == '\r') || (*str == '\n'))) {
if ((*str == '\r') || (*str == '\n')) {
char c = *str;
++str;
++nl;
if (!str.empty() && (c == '\r') && (*str == '\n')) {
++str;
}
} else if (needn) {
goto end;
} else {
++str;
}
continue;
}
}
++str;
}
end:
nlines = nl;
if (str.empty() || (*str != '\"')) {
throw CsErrorException(
cs, "unfinished string '%s'", ostd::slice_until(orig, str)