libcubescript/src/lib_str.cc

225 lines
7.4 KiB
C++
Raw Normal View History

2016-08-17 19:20:19 +02:00
#include <ostd/functional.hh>
2016-09-07 22:57:28 +02:00
#include "cubescript/cubescript.hh"
namespace cscript {
2016-08-17 19:20:19 +02:00
template<typename F>
2016-08-18 20:38:30 +02:00
static inline void cs_strgcmp(CsValueRange args, CsValue &res, F cfunc) {
2016-08-17 19:20:19 +02:00
bool val;
if (args.size() >= 2) {
val = cfunc(args[0].get_strr(), args[1].get_strr());
for (ostd::Size i = 2; (i < args.size()) && val; ++i) {
val = cfunc(args[i - 1].get_strr(), args[i].get_strr());
}
} else {
2016-08-17 19:21:24 +02:00
val = cfunc(
!args.empty() ? args[0].get_strr() : ostd::ConstCharRange(),
ostd::ConstCharRange()
);
2016-08-17 19:20:19 +02:00
}
res.set_int(CsInt(val));
};
void cs_init_lib_string(CsState &cs) {
cs.new_command("strstr", "ss", [](auto &, auto args, auto &res) {
ostd::ConstCharRange a = args[0].get_strr(), b = args[1].get_strr();
ostd::ConstCharRange s = a;
2016-08-14 18:35:38 +02:00
for (CsInt i = 0; b.size() <= s.size(); ++i) {
if (b == s.slice(0, b.size())) {
res.set_int(i);
return;
}
2016-08-17 19:20:19 +02:00
++s;
}
res.set_int(-1);
});
cs.new_command("strlen", "s", [](auto &, auto args, auto &res) {
2016-08-14 18:35:38 +02:00
res.set_int(CsInt(args[0].get_strr().size()));
});
cs.new_command("strcode", "si", [](auto &, auto args, auto &res) {
ostd::ConstCharRange str = args[0].get_strr();
2016-08-14 18:35:38 +02:00
CsInt i = args[1].get_int();
if (i >= CsInt(str.size())) {
res.set_int(0);
} else {
res.set_int(ostd::byte(str[i]));
}
});
cs.new_command("codestr", "i", [](auto &, auto args, auto &res) {
2016-09-15 23:04:32 +02:00
res.set_str(CsString(1, char(args[0].get_int())));
});
cs.new_command("strlower", "s", [](auto &, auto args, auto &res) {
2016-09-15 23:04:32 +02:00
CsString s = args[0].get_str();
2016-08-17 19:20:19 +02:00
for (auto i: ostd::range(s.size())) {
2016-09-15 23:04:32 +02:00
s[i] = tolower(s[i]);
2016-08-17 19:20:19 +02:00
}
2017-01-25 01:57:33 +01:00
res.set_str(std::move(s));
});
cs.new_command("strupper", "s", [](auto &, auto args, auto &res) {
2016-09-15 23:04:32 +02:00
CsString s = args[0].get_str();
2016-08-17 19:20:19 +02:00
for (auto i: ostd::range(s.size())) {
2016-09-15 23:04:32 +02:00
s[i] = toupper(s[i]);
2016-08-17 19:20:19 +02:00
}
2017-01-25 01:57:33 +01:00
res.set_str(std::move(s));
});
cs.new_command("escape", "s", [](auto &, auto args, auto &res) {
2016-09-15 23:04:32 +02:00
auto s = ostd::appender<CsString>();
util::escape_string(s, args[0].get_strr());
2017-01-25 01:57:33 +01:00
res.set_str(std::move(s.get()));
});
cs.new_command("unescape", "s", [](auto &, auto args, auto &res) {
2016-09-15 23:04:32 +02:00
auto s = ostd::appender<CsString>();
util::unescape_string(s, args[0].get_strr());
2017-01-25 01:57:33 +01:00
res.set_str(std::move(s.get()));
});
cs.new_command("concat", "V", [](auto &, auto args, auto &res) {
2016-08-21 02:34:03 +02:00
auto s = ostd::appender<CsString>();
cscript::util::tvals_concat(s, args, " ");
2017-01-25 01:57:33 +01:00
res.set_str(std::move(s.get()));
});
cs.new_command("concatword", "V", [](auto &, auto args, auto &res) {
2016-08-21 02:34:03 +02:00
auto s = ostd::appender<CsString>();
cscript::util::tvals_concat(s, args);
2017-01-25 01:57:33 +01:00
res.set_str(std::move(s.get()));
});
cs.new_command("format", "V", [](auto &, auto args, auto &res) {
2016-08-17 19:20:19 +02:00
if (args.empty()) {
return;
2016-08-17 19:20:19 +02:00
}
2016-09-15 23:04:32 +02:00
CsString s;
CsString fs = args[0].get_str();
ostd::ConstCharRange f = fs.iter();
while (!f.empty()) {
2016-08-17 19:20:19 +02:00
char c = *f;
++f;
if ((c == '%') && !f.empty()) {
2016-08-17 19:20:19 +02:00
char ic = *f;
++f;
if (ic >= '1' && ic <= '9') {
int i = ic - '0';
2016-09-15 23:04:32 +02:00
if (ostd::Size(i) < args.size()) {
s += args[i].get_str();
}
2016-08-17 19:20:19 +02:00
} else {
2016-09-15 23:04:32 +02:00
s += ic;
2016-08-17 19:20:19 +02:00
}
} else {
2016-09-15 23:04:32 +02:00
s += c;
2016-08-17 19:20:19 +02:00
}
}
2017-01-25 01:57:33 +01:00
res.set_str(std::move(s));
});
cs.new_command("tohex", "ii", [](auto &, auto args, auto &res) {
2016-09-15 23:04:32 +02:00
auto r = ostd::appender<CsString>();
2016-08-17 19:20:19 +02:00
ostd::format(
r, "0x%.*X", ostd::max(args[1].get_int(), CsInt(1)),
args[0].get_int()
2016-08-17 19:20:19 +02:00
);
2017-01-25 01:57:33 +01:00
res.set_str(std::move(r.get()));
});
cs.new_command("substr", "siiN", [](auto &, auto args, auto &res) {
ostd::ConstCharRange s = args[0].get_strr();
2016-08-14 18:35:38 +02:00
CsInt start = args[1].get_int(), count = args[2].get_int();
CsInt numargs = args[3].get_int();
CsInt len = CsInt(s.size()), offset = ostd::clamp(start, CsInt(0), len);
res.set_str(ostd::ConstCharRange(
&s[offset],
(numargs >= 3)
? ostd::clamp(count, CsInt(0), len - offset)
: (len - offset)
));
});
cs.new_command("strcmp", "s1V", [](auto &, auto args, auto &res) {
2016-08-17 19:20:19 +02:00
cs_strgcmp(args, res, ostd::Equal<ostd::ConstCharRange>());
});
cs.new_command("=s", "s1V", [](auto &, auto args, auto &res) {
2016-08-17 19:20:19 +02:00
cs_strgcmp(args, res, ostd::Equal<ostd::ConstCharRange>());
});
cs.new_command("!=s", "s1V", [](auto &, auto args, auto &res) {
2016-08-17 19:20:19 +02:00
cs_strgcmp(args, res, ostd::NotEqual<ostd::ConstCharRange>());
});
cs.new_command("<s", "s1V", [](auto &, auto args, auto &res) {
2016-08-17 19:20:19 +02:00
cs_strgcmp(args, res, ostd::Less<ostd::ConstCharRange>());
});
cs.new_command(">s", "s1V", [](auto &, auto args, auto &res) {
2016-08-17 19:20:19 +02:00
cs_strgcmp(args, res, ostd::Greater<ostd::ConstCharRange>());
});
cs.new_command("<=s", "s1V", [](auto &, auto args, auto &res) {
2016-08-17 19:20:19 +02:00
cs_strgcmp(args, res, ostd::LessEqual<ostd::ConstCharRange>());
});
cs.new_command(">=s", "s1V", [](auto &, auto args, auto &res) {
2016-08-17 19:20:19 +02:00
cs_strgcmp(args, res, ostd::GreaterEqual<ostd::ConstCharRange>());
});
cs.new_command("strreplace", "ssss", [](auto &, auto args, auto &res) {
ostd::ConstCharRange s = args[0].get_strr();
ostd::ConstCharRange oldval = args[1].get_strr(),
newval = args[2].get_strr(),
newval2 = args[3].get_strr();
if (newval2.empty()) {
newval2 = newval;
}
2016-09-15 23:04:32 +02:00
CsString buf;
if (!oldval.size()) {
res.set_str(s);
return;
}
for (ostd::Size i = 0;; ++i) {
ostd::ConstCharRange found;
ostd::ConstCharRange trys = s;
2016-08-17 19:20:19 +02:00
for (; oldval.size() <= trys.size(); ++trys) {
if (trys.slice(0, oldval.size()) == oldval) {
found = trys;
break;
}
}
if (!found.empty()) {
2016-09-15 23:04:32 +02:00
buf += ostd::slice_until(s, found);
buf += (i & 1) ? newval2 : newval;
s = found + oldval.size();
} else {
2016-09-15 23:04:32 +02:00
buf += s;
2017-01-25 01:57:33 +01:00
res.set_str(std::move(buf));
return;
}
}
});
cs.new_command("strsplice", "ssii", [](auto &, auto args, auto &res) {
ostd::ConstCharRange s = args[0].get_strr();
ostd::ConstCharRange vals = args[1].get_strr();
2016-08-14 18:35:38 +02:00
CsInt skip = args[2].get_int(),
count = args[3].get_int();
2016-09-15 23:04:32 +02:00
CsInt offset = ostd::clamp(skip, CsInt(0), CsInt(s.size())),
len = ostd::clamp(count, CsInt(0), CsInt(s.size()) - offset);
CsString p;
p.reserve(s.size() - len + vals.size());
2016-08-17 19:20:19 +02:00
if (offset) {
2016-09-15 23:04:32 +02:00
p += s.slice(0, offset);
2016-08-17 19:20:19 +02:00
}
2016-09-15 23:04:32 +02:00
if (!vals.empty()) {
p += vals;
2016-08-17 19:20:19 +02:00
}
2016-09-15 23:04:32 +02:00
if ((offset + len) < CsInt(s.size())) {
p += s.slice(offset + len, s.size());
2016-08-17 19:20:19 +02:00
}
2017-01-25 01:57:33 +01:00
res.set_str(std::move(p));
});
}
} /* namespace cscript */