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