add a line-counting parse_string to util

This commit is contained in:
q66 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( 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( OSTD_EXPORT ostd::ConstCharRange parse_word(
CsState &cs, ostd::ConstCharRange str CsState &cs, ostd::ConstCharRange str
); );

View file

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