redo (un)escape_string around output iterators
parent
320fdbaefd
commit
10b2a81cec
|
@ -8,6 +8,7 @@
|
|||
#include <optional>
|
||||
#include <functional>
|
||||
#include <type_traits>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "cubescript_conf.hh"
|
||||
|
@ -664,37 +665,25 @@ OSTD_EXPORT cs_strref value_list_concat(
|
|||
|
||||
namespace util {
|
||||
template<typename R>
|
||||
inline R &&escape_string(R &&writer, std::string_view str) {
|
||||
inline R escape_string(R writer, std::string_view str) {
|
||||
using namespace ostd::string_literals;
|
||||
writer.put('"');
|
||||
*writer++ = '"';
|
||||
for (auto c: str) {
|
||||
switch (c) {
|
||||
case '\n':
|
||||
ostd::range_put_all(writer, "^n"_sr);
|
||||
break;
|
||||
case '\t':
|
||||
ostd::range_put_all(writer, "^t"_sr);
|
||||
break;
|
||||
case '\f':
|
||||
ostd::range_put_all(writer, "^f"_sr);
|
||||
break;
|
||||
case '"':
|
||||
ostd::range_put_all(writer, "^\""_sr);
|
||||
break;
|
||||
case '^':
|
||||
ostd::range_put_all(writer, "^^"_sr);
|
||||
break;
|
||||
default:
|
||||
writer.put(c);
|
||||
break;
|
||||
case '\n': *writer++ = '^'; *writer++ = 'n'; break;
|
||||
case '\t': *writer++ = '^'; *writer++ = 't'; break;
|
||||
case '\f': *writer++ = '^'; *writer++ = 'f'; break;
|
||||
case '"': *writer++ = '^'; *writer++ = '"'; break;
|
||||
case '^': *writer++ = '^'; *writer++ = '^'; break;
|
||||
default: *writer++ = c; break;
|
||||
}
|
||||
}
|
||||
writer.put('"');
|
||||
return std::forward<R>(writer);
|
||||
*writer++ = '"';
|
||||
return writer;
|
||||
}
|
||||
|
||||
template<typename R>
|
||||
inline R &&unescape_string(R &&writer, std::string_view str) {
|
||||
inline R unescape_string(R writer, std::string_view str) {
|
||||
for (auto it = str.begin(); it != str.end(); ++it) {
|
||||
if (*it == '^') {
|
||||
++it;
|
||||
|
@ -702,24 +691,12 @@ namespace util {
|
|||
break;
|
||||
}
|
||||
switch (*it) {
|
||||
case 'n':
|
||||
writer.put('\n');
|
||||
break;
|
||||
case 't':
|
||||
writer.put('\r');
|
||||
break;
|
||||
case 'f':
|
||||
writer.put('\f');
|
||||
break;
|
||||
case '"':
|
||||
writer.put('"');
|
||||
break;
|
||||
case '^':
|
||||
writer.put('^');
|
||||
break;
|
||||
default:
|
||||
writer.put(*it);
|
||||
break;
|
||||
case 'n': *writer++ = '\n'; break;
|
||||
case 't': *writer++ = '\r'; break;
|
||||
case 'f': *writer++ = '\f'; break;
|
||||
case '"': *writer++ = '"'; break;
|
||||
case '^': *writer++ = '^'; break;
|
||||
default: *writer++ = *it; break;
|
||||
}
|
||||
} else if (*it == '\\') {
|
||||
++it;
|
||||
|
@ -735,12 +712,12 @@ namespace util {
|
|||
}
|
||||
continue;
|
||||
}
|
||||
writer.put('\\');
|
||||
*writer++ = '\\';
|
||||
} else {
|
||||
writer.put(str.front());
|
||||
*writer++ = *it;
|
||||
}
|
||||
}
|
||||
return std::forward<R>(writer);
|
||||
return writer;
|
||||
}
|
||||
|
||||
OSTD_EXPORT char const *parse_string(
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
#ifndef LIBCUBESCRIPT_CUBESCRIPT_CONF_HH
|
||||
#define LIBCUBESCRIPT_CUBESCRIPT_CONF_HH
|
||||
|
||||
#include <limits.h>
|
||||
#include <functional>
|
||||
#include <span>
|
||||
#include <ostd/range.hh>
|
||||
|
||||
/* do not modify */
|
||||
namespace cscript {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <ctype.h>
|
||||
|
||||
#include <limits>
|
||||
#include <iterator>
|
||||
|
||||
namespace cscript {
|
||||
|
||||
|
@ -20,10 +21,9 @@ std::string_view cs_gen_state::get_str() {
|
|||
}
|
||||
|
||||
cs_charbuf cs_gen_state::get_str_dup() {
|
||||
auto str = get_str();
|
||||
auto app = ostd::appender<cs_charbuf>(cs);
|
||||
util::unescape_string(app, str);
|
||||
return std::move(app.get());
|
||||
cs_charbuf buf{cs};
|
||||
util::unescape_string(std::back_inserter(buf), get_str());
|
||||
return buf;
|
||||
}
|
||||
|
||||
std::string_view cs_gen_state::read_macro_name() {
|
||||
|
@ -199,12 +199,14 @@ static inline void compileunescapestr(cs_gen_state &gs) {
|
|||
);
|
||||
size_t bufs = (gs.code.capacity() - gs.code.size()) * sizeof(uint32_t);
|
||||
char *buf = new char[bufs + 1];
|
||||
auto writer = ostd::char_range(buf, buf + bufs);
|
||||
size_t len = util::unescape_string(ostd::counting_sink(writer), str).get_written();
|
||||
memset(&buf[len], 0, sizeof(uint32_t) - len % sizeof(uint32_t));
|
||||
gs.code.back() |= len << 8;
|
||||
char *wbuf = util::unescape_string(&buf[0], str);
|
||||
memset(
|
||||
&buf[wbuf - buf], 0,
|
||||
sizeof(uint32_t) - (wbuf - buf) % sizeof(uint32_t)
|
||||
);
|
||||
gs.code.back() |= (wbuf - buf) << 8;
|
||||
uint32_t *ubuf = reinterpret_cast<uint32_t *>(buf);
|
||||
gs.code.append(ubuf, ubuf + (len / sizeof(uint32_t) + 1));
|
||||
gs.code.append(ubuf, ubuf + ((wbuf - buf) / sizeof(uint32_t) + 1));
|
||||
delete[] buf;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
#include "cs_util.hh"
|
||||
#include "cs_vm.hh"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <iterator>
|
||||
|
||||
namespace cscript {
|
||||
|
||||
|
@ -529,9 +530,9 @@ OSTD_EXPORT std::size_t list_count(cs_list_parse_state &ps, cs_state &cs) {
|
|||
|
||||
OSTD_EXPORT cs_strref list_get_item(cs_list_parse_state &ps, cs_state &cs) {
|
||||
if (!ps.quoted_item.empty() && (ps.quoted_item.front() == '"')) {
|
||||
auto app = ostd::appender<cs_charbuf>(cs);
|
||||
util::unescape_string(app, ps.item);
|
||||
return cs_strref{cs, app.get().str()};
|
||||
cs_charbuf buf{cs};
|
||||
util::unescape_string(std::back_inserter(buf), ps.item);
|
||||
return cs_strref{cs, buf.str()};
|
||||
}
|
||||
return cs_strref{cs, ps.item};
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "cs_vm.hh"
|
||||
#include "cs_util.hh"
|
||||
|
||||
#include <ostd/io.hh>
|
||||
#include <limits>
|
||||
|
||||
namespace cscript {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <functional>
|
||||
#include <iterator>
|
||||
|
||||
#include <cubescript/cubescript.hh>
|
||||
#include "cs_util.hh"
|
||||
|
@ -423,7 +424,7 @@ end:
|
|||
});
|
||||
|
||||
gcs.new_command("prettylist", "ss", [](auto &cs, auto args, auto &res) {
|
||||
auto buf = ostd::appender<cs_charbuf>(cs);
|
||||
cs_charbuf buf{cs};
|
||||
std::string_view s = args[0].get_str();
|
||||
std::string_view conj = args[1].get_str();
|
||||
cs_list_parse_state p{s};
|
||||
|
@ -431,22 +432,22 @@ end:
|
|||
size_t n = 0;
|
||||
for (p.set_input(s); list_parse(p, cs); ++n) {
|
||||
if (!p.quoted_item.empty() && (p.quoted_item.front() == '"')) {
|
||||
util::unescape_string(buf, p.item);
|
||||
util::unescape_string(std::back_inserter(buf), p.item);
|
||||
} else {
|
||||
buf.get().append(p.item);
|
||||
buf.append(p.item);
|
||||
}
|
||||
if ((n + 1) < len) {
|
||||
if ((len > 2) || conj.empty()) {
|
||||
buf.put(',');
|
||||
buf.push_back(',');
|
||||
}
|
||||
if ((n + 2 == len) && !conj.empty()) {
|
||||
buf.put(' ');
|
||||
buf.get().append(conj);
|
||||
buf.push_back(' ');
|
||||
buf.append(conj);
|
||||
}
|
||||
buf.put(' ');
|
||||
buf.push_back(' ');
|
||||
}
|
||||
}
|
||||
res.set_str(buf.get().str());
|
||||
res.set_str(buf.str());
|
||||
});
|
||||
|
||||
gcs.new_command("indexof", "ss", [](auto &cs, auto args, auto &res) {
|
||||
|
@ -567,7 +568,7 @@ static void cs_list_sort(
|
|||
size_t nuniq = items.size();
|
||||
if (body) {
|
||||
ListSortFun f = { cs, xval, yval, body };
|
||||
ostd::sort_cmp(ostd::iter(items.buf), f);
|
||||
std::sort(items.buf.begin(), items.buf.end(), f);
|
||||
if (!cs_code_is_empty(unique)) {
|
||||
f.body = unique;
|
||||
totaluniq = items[0].quote.size();
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include <functional>
|
||||
#include <iterator>
|
||||
|
||||
#include <cubescript/cubescript.hh>
|
||||
|
||||
|
@ -59,7 +60,7 @@ void cs_init_lib_string(cs_state &cs) {
|
|||
auto inps = std::string_view{args[0].get_str()};
|
||||
auto *ics = cs_get_sstate(ccs);
|
||||
auto *buf = ics->strman->alloc_buf(inps.size());
|
||||
for (auto i: ostd::range(inps.size())) {
|
||||
for (std::size_t i = 0; i < inps.size(); ++i) {
|
||||
buf[i] = tolower(inps[i]);
|
||||
}
|
||||
auto const *cbuf = ics->strman->steal(buf);
|
||||
|
@ -72,7 +73,7 @@ void cs_init_lib_string(cs_state &cs) {
|
|||
auto inps = std::string_view{args[0].get_str()};
|
||||
auto *ics = cs_get_sstate(ccs);
|
||||
auto *buf = ics->strman->alloc_buf(inps.size());
|
||||
for (auto i: ostd::range(inps.size())) {
|
||||
for (std::size_t i = 0; i < inps.size(); ++i) {
|
||||
buf[i] = toupper(inps[i]);
|
||||
}
|
||||
auto const *cbuf = ics->strman->steal(buf);
|
||||
|
@ -82,15 +83,15 @@ void cs_init_lib_string(cs_state &cs) {
|
|||
});
|
||||
|
||||
cs.new_command("escape", "s", [](auto &ccs, auto args, auto &res) {
|
||||
auto s = ostd::appender<cs_charbuf>(ccs);
|
||||
util::escape_string(s, args[0].get_str());
|
||||
res.set_str(s.get().str());
|
||||
cs_charbuf s{ccs};
|
||||
util::escape_string(std::back_inserter(s), args[0].get_str());
|
||||
res.set_str(s.str());
|
||||
});
|
||||
|
||||
cs.new_command("unescape", "s", [](auto &ccs, auto args, auto &res) {
|
||||
auto s = ostd::appender<cs_charbuf>(ccs);
|
||||
util::unescape_string(s, args[0].get_str());
|
||||
res.set_str(s.get().str());
|
||||
cs_charbuf s{ccs};
|
||||
util::unescape_string(std::back_inserter(s), args[0].get_str());
|
||||
res.set_str(s.str());
|
||||
});
|
||||
|
||||
cs.new_command("concat", "V", [](auto &ccs, auto args, auto &res) {
|
||||
|
|
Loading…
Reference in New Issue