Add chr() function to convert numbers to unicode characters.

master
Torsten Paul 2014-07-13 18:43:44 +02:00
parent 247479ca67
commit 94fd976bad
3 changed files with 66 additions and 0 deletions

View File

@ -527,6 +527,17 @@ Value builtin_str(const Context *, const EvalContext *evalctx)
return Value(stream.str());
}
Value builtin_chr(const Context *, const EvalContext *evalctx)
{
std::stringstream stream;
for (size_t i = 0; i < evalctx->numArgs(); i++) {
const Value v = evalctx->getArgValue(i);
stream << v.chrString();
}
return Value(stream.str());
}
Value builtin_concat(const Context *, const EvalContext *evalctx)
{
Value::VectorType result;
@ -928,6 +939,7 @@ void register_builtin_functions()
Builtins::init("log", new BuiltinFunction(&builtin_log));
Builtins::init("ln", new BuiltinFunction(&builtin_ln));
Builtins::init("str", new BuiltinFunction(&builtin_str));
Builtins::init("chr", new BuiltinFunction(&builtin_chr));
Builtins::init("concat", new BuiltinFunction(&builtin_concat));
Builtins::init("lookup", new BuiltinFunction(&builtin_lookup));
Builtins::init("search", new BuiltinFunction(&builtin_search));

View File

@ -248,6 +248,58 @@ std::string Value::toString() const
return boost::apply_visitor(tostring_visitor(), this->value);
}
class chr_visitor : public boost::static_visitor<std::string> {
public:
template <typename S> std::string operator()(const S &) const
{
return "";
}
std::string operator()(const double &v) const
{
char buf[8];
memset(buf, 0, 8);
if (v > 0) {
const gunichar c = v;
if (g_unichar_validate(c) && (c != 0)) {
g_unichar_to_utf8(c, buf);
}
}
return std::string(buf);
}
std::string operator()(const Value::VectorType &v) const
{
std::stringstream stream;
for (size_t i = 0; i < v.size(); i++) {
stream << v[i].chrString();
}
return stream.str();
}
std::string operator()(const Value::RangeType &v) const
{
const boost::uint32_t steps = v.nbsteps();
if (steps >= 10000) {
PRINTB("WARNING: Bad range parameter in for statement: too many elements (%lu).", steps);
return "";
}
std::stringstream stream;
Value::RangeType range = v;
for (Value::RangeType::iterator it = range.begin();it != range.end();it++) {
const Value value(*it);
stream << value.chrString();
}
return stream.str();
}
};
std::string Value::chrString() const
{
return boost::apply_visitor(chr_visitor(), this->value);
}
const Value::VectorType &Value::toVector() const
{
static VectorType empty;

View File

@ -87,6 +87,7 @@ public:
/// return number of steps, max uint32_t value if step is 0
boost::uint32_t nbsteps() const;
friend class chr_visitor;
friend class tostring_visitor;
friend class bracket_visitor;
};
@ -121,6 +122,7 @@ public:
bool getDouble(double &v) const;
bool toBool() const;
std::string toString() const;
std::string chrString() const;
const VectorType &toVector() const;
bool getVec2(double &x, double &y) const;
bool getVec3(double &x, double &y, double &z, double defaultval = 0.0) const;