Skip to content

Commit

Permalink
fix builtins implemented in C++ to return UTF-8 Strings
Browse files Browse the repository at this point in the history
added rb_utf8_str_new() helpers for creating UTF-8 Strings
  • Loading branch information
Ladislav Slezak committed Jun 6, 2013
1 parent 6483514 commit d09cdba
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 20 deletions.
9 changes: 5 additions & 4 deletions src/binary/Builtin.cc
Expand Up @@ -31,6 +31,7 @@ extern "C" {
#include "Y2RubyTypeConv.h"
#include "RubyLogger.h"
#include "YRuby.h"
#include "Y2RubyUtils.h"

static VALUE rb_mSCR;
static VALUE rb_mWFM;
Expand Down Expand Up @@ -169,7 +170,7 @@ extern "C" {
std::string utf_res;
if (!recode(res,utf_res))
return Qnil;
return rb_str_new2(utf_res.c_str());
return rb_utf8_str_new(utf_res);
}

// crypt part taken from y2crypt from yast core
Expand Down Expand Up @@ -310,7 +311,7 @@ extern "C" {
char * res = crypt_pass(source, type);
if (!res)
return Qnil;
VALUE ret = rb_str_new2(res);
VALUE ret = rb_utf8_str_new(res);
delete res;
return ret;
}
Expand Down Expand Up @@ -537,7 +538,7 @@ extern "C" {
}

if (result.solved)
return rb_str_new2 (result.result_str.c_str ());
return rb_utf8_str_new(result.result_str);

return Qnil;
}
Expand Down Expand Up @@ -598,7 +599,7 @@ extern "C" {
if (result.solved) {
for (int i = 1; i <= result.match_nb; i++)
{
rb_ary_push(list, rb_str_new2 (result.match_str[i].c_str()));
rb_ary_push(list, rb_utf8_str_new(result.match_str[i]));
}
}

Expand Down
21 changes: 21 additions & 0 deletions src/binary/Y2RubyUtils.cc
@@ -1,11 +1,17 @@
#include <vector>
#include <string>

#include <ruby.h>
#include <ruby/encoding.h>

#include "y2util/stringutil.h"
#include "Y2RubyUtils.h"

using namespace std;

// cache the UTF-8 encoding object
static rb_encoding *utf8;

static VALUE const_get_wrapper(VALUE input)
{
VALUE *data = (VALUE*) input;
Expand All @@ -32,3 +38,18 @@ VALUE y2ruby_nested_const_get(const std::string &name)
}
return module;
}

VALUE rb_utf8_str_new(const std::string &str) {
if (!utf8)
utf8 = rb_enc_find("UTF-8");

return rb_enc_str_new(str.c_str(), str.size(), utf8);
}

VALUE rb_utf8_str_new(const char *str) {
if (!utf8)
utf8 = rb_enc_find("UTF-8");

return rb_enc_str_new(str, strlen(str), utf8);
}

7 changes: 7 additions & 0 deletions src/binary/Y2RubyUtils.h
Expand Up @@ -31,4 +31,11 @@ as published by the Free Software Foundation; either version
*/
VALUE y2ruby_nested_const_get(const std::string &name);

/**
* Create Ruby String object from a C++ string
* The resulting string has UTF-8 encoding
*/
VALUE rb_utf8_str_new(const std::string &str);
VALUE rb_utf8_str_new(const char *str);

#endif
17 changes: 4 additions & 13 deletions src/binary/Y2YCPTypeConv.cc
Expand Up @@ -41,9 +41,8 @@ as published by the Free Software Foundation; either version

#include "YRuby.h"

#include <ruby/encoding.h>

#include "Y2YCPTypeConv.h"
#include "Y2RubyUtils.h"

//must match same magic id as in vica versa conversion
#define YCP_EXTERNAL_MAGIC "Ruby object"
Expand All @@ -58,7 +57,7 @@ ycp_path_to_rb_path( YCPPath ycppath )

VALUE ycp = rb_define_module("YCP");
VALUE cls = rb_const_get(ycp, rb_intern("Path"));
VALUE value = rb_str_new2(ycppath->asString()->value().c_str());
VALUE value = rb_utf8_str_new(ycppath->asString()->value());
return rb_class_new_instance(1,&value,cls);
}

Expand Down Expand Up @@ -117,7 +116,7 @@ ycp_ext_to_rb_ext( YCPExternal ext )
VALUE cls = rb_const_get(ycp, rb_intern("External"));
// FIXME marking and deallocation
VALUE tdata = Data_Wrap_Struct(cls, 0, NULL, new YCPExternal(ext));
VALUE argv[] = {rb_str_new2(ext->magic().c_str())};
VALUE argv[] = {rb_utf8_str_new(ext->magic())};
rb_obj_call_init(tdata, 1, argv);
return tdata;

Expand All @@ -134,9 +133,6 @@ ycp_ext_to_rb_ext( YCPExternal ext )
extern "C" VALUE
ycpvalue_2_rbvalue( YCPValue ycpval )
{
// cache the UTF-8 encoding object
static rb_encoding *utf8;

// TODO
// YT_BYTEBLOCK YT_CODE YT_RETURN YT_BREAK YT_ENTRY YT_ERROR YT_REFERENCE YT_EXTERNA
if (ycpval.isNull() || ycpval->isVoid())
Expand All @@ -149,13 +145,8 @@ ycpvalue_2_rbvalue( YCPValue ycpval )
}
else if (ycpval->isString())
{
if (!utf8)
{
utf8 = rb_enc_find("UTF-8");
}

// always use UTF-8 encoding
return rb_enc_str_new(ycpval->asString()->value().c_str(), ycpval->asString()->value().size(), utf8);
return rb_utf8_str_new(ycpval->asString()->value());
}
else if (ycpval->isPath())
{
Expand Down
3 changes: 2 additions & 1 deletion src/binary/YCP.cc
Expand Up @@ -40,6 +40,7 @@ as published by the Free Software Foundation; either version

#include "Y2YCPTypeConv.h"
#include "Y2RubyTypeConv.h"
#include "Y2RubyUtils.h"

/*
* Ruby module anchors
Expand Down Expand Up @@ -229,7 +230,7 @@ ycp_module_symbols(VALUE self, VALUE namespace_name)
for (unsigned int i=0; i < ns->symbolCount(); ++i)
{
SymbolEntryPtr s = ns->symbolEntry(i);
VALUE name = rb_str_new2(s->name());
VALUE name = rb_utf8_str_new(s->name());
VALUE type = ID2SYM(rb_intern(s->catString().c_str()));
rb_hash_aset(res,name,type);
}
Expand Down
2 changes: 1 addition & 1 deletion src/binary/YRuby.cc
Expand Up @@ -47,7 +47,7 @@ as published by the Free Software Foundation; either version

void set_last_exception(VALUE& module,const string& message)
{
rb_ivar_set(module,rb_intern("@__last_exception"),rb_str_new2(message.c_str()));
rb_ivar_set(module,rb_intern("@__last_exception"),rb_utf8_str_new(message));
}

YRuby * YRuby::_yRuby = 0;
Expand Down
10 changes: 9 additions & 1 deletion tests/ruby/builtins_test.rb
Expand Up @@ -141,13 +141,19 @@ def test_regexpsub
assert_equal "lest test\tsrst", YCP::Builtins.regexpsub(" lest test\tsrst\t", "^[ \t]*(([^ \t]*[ \t]*[^ \t]+)*)[ \t]*$", "\\1")
assert_equal "", YCP::Builtins.regexpsub("", "^[ \t]*(([^ \t]*[ \t]*[^ \t]+)*)[ \t]*$", "\\1")
assert_equal "", YCP::Builtins.regexpsub(" \t ", "^[ \t]*(([^ \t]*[ \t]*[^ \t]+)*)[ \t]*$", "\\1")

# the result must be UTF-8 string
assert_equal Encoding::UTF_8, YCP::Builtins.regexpsub("aaabbb", "(.*ab)", "s_\\1_e").encoding
end

def test_regexptokenize
assert_equal ["aaabbB"], YCP::Builtins.regexptokenize("aaabbBb", "(.*[A-Z]).*")
assert_equal ["aaab", "bb"], YCP::Builtins.regexptokenize("aaabbb", "(.*ab)(.*)")
assert_equal [], YCP::Builtins.regexptokenize("aaabbb", "(.*ba).*")
assert_equal nil, YCP::Builtins.regexptokenize("aaabbb", "(.*ba).*(");

# the result must be UTF-8 string
assert_equal Encoding::UTF_8, YCP::Builtins.regexptokenize("aaabbBb", "(.*[A-Z]).*").first.encoding
end

def test_tohexstring
Expand Down Expand Up @@ -794,7 +800,9 @@ def test_findlastnotof
def test_float_tolstring
old_lang = ENV["LANG"]
ENV["LANG"] = "cs_CZ.utf-8"
assert_equal "0,5", YCP::Builtins::Float.tolstring(0.52,1)
ret = YCP::Builtins::Float.tolstring(0.52,1)
assert_equal "0,5", ret
assert_equal Encoding::UTF_8, ret.encoding
ENV["LANG"] = old_lang
end

Expand Down

0 comments on commit d09cdba

Please sign in to comment.