15 #include <string_view>
27 (std::istream&
in)
const
31 std::string openQuoteLine;
32 unsigned int nLines = 0U;
36 std::getline(in, line, in.widen(fParams.EOL));
37 bool const isEOF = in.eof();
38 if (!isEOF || !line.empty()) ++nLines;
39 openQuoteLine.append(line);
41 if (isQuotationUnclosed(make_view(openQuoteLine))) {
42 if (isCharacterEscaped(line.begin(), line.end())) {
43 fullLine.append(openQuoteLine);
44 throw Error{
"Parser error: escaped end-of-line inside a quotation:\n"
48 if (!isEOF) openQuoteLine += fParams.EOL;
51 fullLine.append(openQuoteLine);
52 openQuoteLine.clear();
54 if (!isCharacterEscaped(fullLine.begin(), fullLine.end()))
break;
59 fullLine.append(openQuoteLine);
61 return { std::move(fullLine), nLines };
67 -> std::pair<std::string_view, QuotSpec_t const*>
73 std::size_t
const startPos = sv.find_first_of(fQuoteStarts);
76 if (startPos == std::string_view::npos)
break;
79 if (isCharacterEscaped(sv.begin(), sv.begin() + startPos)) {
80 sv.remove_prefix(std::min(startPos + 1, sv.length()));
84 sv.remove_prefix(std::min(startPos, sv.length()));
88 for (
auto const& qSpec: fParams.quotes) {
91 if (sv.compare(0, qSpec.first.length(), qSpec.first) == 0)
92 return { sv, &qSpec };
101 return { make_view(sv.end(), sv.end()),
nullptr };
107 (std::string_view sv, std::string
const& quotEnd)
const
109 while (!sv.empty()) {
111 std::size_t
const pos = sv.find(quotEnd);
112 if (pos == std::string_view::npos)
break;
114 if (!isCharacterEscaped(sv.begin(), sv.begin() + pos)) {
115 sv.remove_prefix(pos);
119 sv.remove_prefix(pos + 1);
123 return make_view(sv.end(), sv.end());
130 while (!sv.empty()) {
133 if (!qptr)
return false;
135 qsv.remove_prefix(qptr->first.length());
138 if (qsv.empty())
return true;
140 qsv.remove_prefix(qptr->second.length());
153 { make_view(sv.begin(), sep.begin()), sep, make_view(sep.end(), sv.end()) };
161 std::string::const_iterator iSrc =
s.begin(), send =
s.end();
162 std::string::iterator iDest =
s.begin();
165 while (iSrc != send) {
166 char const ch = *iSrc++;
167 *iDest++ = (isEscape(ch) && (iSrc != send))? *iSrc++: ch;
170 s.erase(iDest, send);
178 std::string_view sv = make_view(
s);
179 std::string::iterator iDest =
s.begin();
181 while (!sv.empty()) {
184 auto const [ fromQ, qptr ] = findQuotationStart(sv);
187 iDest =
std::copy(sv.begin(), fromQ.begin(), iDest);
192 sv.remove_prefix(qptr->first.length());
195 std::string_view
const afterQ = findQuotationEnd(sv, qptr->second);
197 if (afterQ.empty()) {
199 iDest =
std::copy(fromQ.begin(), fromQ.end(), iDest);
200 sv.remove_prefix(sv.length());
205 iDest =
std::copy(sv.begin(), afterQ.begin(), iDest);
208 sv.remove_prefix(qptr->second.length());
214 s.erase(iDest,
s.end());
222 fParams = std::move(params);
227 std::size_t
const al = a.first.length(), bl = b.first.length();
228 return (al != bl)? (al > bl): (a < b);
230 std::sort(fParams.quotes.begin(), fParams.quotes.end(), byOpeningLength);
234 for (
QuotSpec_t const& quotSpec: fParams.quotes)
235 fQuoteStarts += quotSpec.first.front();
236 std::sort(fQuoteStarts.begin(), fQuoteStarts.end());
238 (std::unique(fQuoteStarts.begin(), fQuoteStarts.end()), fQuoteStarts.end());
if &&[-z"$BASH_VERSION"] then echo Attempting to switch to bash bash shellSwitch exit fi &&["$1"= 'shellSwitch'] shift declare a IncludeDirectives for Dir in
then echo File list $list not found else cat $list while read file do echo $file sed s