Skip to content

Commit

Permalink
Support Ruby 1.8 fix GH-1
Browse files Browse the repository at this point in the history
  • Loading branch information
nurse committed Feb 15, 2013
1 parent a10a1de commit a437b41
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 18 deletions.
4 changes: 2 additions & 2 deletions Rakefile
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ file "lib/#{NAME}/#{NAME}.so" =>
Dir.chdir("ext/#{NAME}") do Dir.chdir("ext/#{NAME}") do
# this does essentially the same thing # this does essentially the same thing
# as what RubyGems does # as what RubyGems does
ruby "extconf.rb" ruby "extconf.rb", *ARGV.grep(/\A--/)
sh "make" sh "make", *ARGV.grep(/\A(?!--)/)
end end
cp "ext/#{NAME}/#{NAME}.so", "lib/#{NAME}" cp "ext/#{NAME}/#{NAME}.so", "lib/#{NAME}"
end end
Expand Down
5 changes: 3 additions & 2 deletions ext/iconv/extconf.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
conf = File.exist?(File.join($srcdir, "config.charset")) conf = File.exist?(File.join($srcdir, "config.charset"))
conf = with_config("config-charset", enable_config("config-charset", conf)) conf = with_config("config-charset", enable_config("config-charset", conf))


have_func("rb_enc_get", "ruby/encoding.h") unless have_func("rb_enc_get", "ruby/encoding.h") || have_func("vasprintf", "stdio.h")
have_func("st_lookup", "ruby/st.h") raise "vasprintf is required for Ruby 1.8"
end
if have_func("iconv", "iconv.h") or if have_func("iconv", "iconv.h") or
have_library("iconv", "iconv", "iconv.h") have_library("iconv", "iconv", "iconv.h")
check_signedness("size_t") rescue nil check_signedness("size_t") rescue nil
Expand Down
92 changes: 82 additions & 10 deletions ext/iconv/iconv.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -17,13 +17,60 @@
#include <errno.h> #include <errno.h>
#include <iconv.h> #include <iconv.h>
#include <assert.h> #include <assert.h>
#ifdef HAVE_RUBY_ST_H
#include "ruby/st.h"
#else /* assume 1.8 */
#include "st.h"
#endif
#ifdef HAVE_RUBY_ENCODING_H #ifdef HAVE_RUBY_ENCODING_H
#include "ruby/encoding.h" /* assume Ruby 1.9 or later */
# include "ruby/st.h"
# include "ruby/encoding.h"
#else
# include "st.h"
# include <stdarg.h>
# define rb_f_notimplement rb_notimplement
# define rb_str_subseq(a, b, c) rb_str_substr(a, b, c)
# define rb_str_new_cstr(a) rb_str_new2(a)
NORETURN(static void rb_sys_fail_str(VALUE msg));
static void
rb_sys_fail_str(VALUE msg)
{
rb_sys_fail(RSTRING_PTR(msg));
}
static VALUE
rb_str_equal(str1, str2)
VALUE str1, str2;
{
if (str1 == str2) return Qtrue;
if (TYPE(str2) != T_STRING) {
if (!rb_respond_to(str2, rb_intern("to_str"))) {
return Qfalse;
}
return rb_equal(str2, str1);
}
if (RSTRING(str1)->len == RSTRING(str2)->len &&
rb_str_cmp(str1, str2) == 0) {
return Qtrue;
}
return Qfalse;
}
void
rb_set_errinfo(VALUE err)
{
extern VALUE ruby_errinfo;
ruby_errinfo = err;
}
#define ENCODING_GET(a) 0
VALUE
rb_sprintf(const char *format, ...)
{
va_list ap;
char *ret;
int len;

va_start(ap, format);
len = vasprintf(&ret, format, ap);
va_end(ap);
if (len == -1) return Qnil;

return rb_str_new(ret, len);
}
#endif #endif


/* /*
Expand Down Expand Up @@ -212,7 +259,9 @@ iconv_create(VALUE to, VALUE from, struct rb_iconv_opt_t *opt, int *idx)
iconv_t cd; iconv_t cd;
int retry = 0; int retry = 0;


#ifdef HAVE_RUBY_ENCODING_H
*idx = rb_enc_find_index(tocode); *idx = rb_enc_find_index(tocode);
#endif


if (toopt) { if (toopt) {
toenc = rb_str_plus(to, toopt); toenc = rb_str_plus(to, toopt);
Expand Down Expand Up @@ -499,15 +548,19 @@ iconv_convert(iconv_t cd, VALUE str, long start, long length, int toidx, struct
{ {
if (NIL_P(str)) { if (NIL_P(str)) {
ret = rb_str_new(buffer, outlen); ret = rb_str_new(buffer, outlen);
#ifdef HAVE_RUBY_ENCODING_H
if (toidx >= 0) rb_enc_associate_index(ret, toidx); if (toidx >= 0) rb_enc_associate_index(ret, toidx);
#endif
} }
else { else {
if (ret) { if (ret) {
ret = rb_str_buf_cat(ret, instart, tmpstart - instart); ret = rb_str_buf_cat(ret, instart, tmpstart - instart);
} }
else { else {
ret = rb_str_new(instart, tmpstart - instart); ret = rb_str_new(instart, tmpstart - instart);
#ifdef HAVE_RUBY_ENCODING_H
if (toidx >= 0) rb_enc_associate_index(ret, toidx); if (toidx >= 0) rb_enc_associate_index(ret, toidx);
#endif
OBJ_INFECT(ret, str); OBJ_INFECT(ret, str);
} }
ret = rb_str_buf_cat(ret, buffer, outlen); ret = rb_str_buf_cat(ret, buffer, outlen);
Expand All @@ -529,7 +582,9 @@ iconv_convert(iconv_t cd, VALUE str, long start, long length, int toidx, struct


if (!ret) { if (!ret) {
ret = rb_str_derive(str, instart, inptr - instart); ret = rb_str_derive(str, instart, inptr - instart);
#ifdef HAVE_RUBY_ENCODING_H
if (toidx >= 0) rb_enc_associate_index(ret, toidx); if (toidx >= 0) rb_enc_associate_index(ret, toidx);
#endif
} }
else if (inptr > instart) { else if (inptr > instart) {
rb_str_cat(ret, instart, inptr - instart); rb_str_cat(ret, instart, inptr - instart);
Expand All @@ -555,7 +610,9 @@ iconv_convert(iconv_t cd, VALUE str, long start, long length, int toidx, struct


if (!ret) { if (!ret) {
ret = rb_str_derive(str, instart, inptr - instart); ret = rb_str_derive(str, instart, inptr - instart);
#ifdef HAVE_RUBY_ENCODING_H
if (toidx >= 0) rb_enc_associate_index(ret, toidx); if (toidx >= 0) rb_enc_associate_index(ret, toidx);
#endif
} }
else if (inptr > instart) { else if (inptr > instart) {
rb_str_cat(ret, instart, inptr - instart); rb_str_cat(ret, instart, inptr - instart);
Expand Down Expand Up @@ -673,7 +730,9 @@ iconv_initialize(int argc, VALUE *argv, VALUE self)
iconv_free(check_iconv(self)); iconv_free(check_iconv(self));
DATA_PTR(self) = NULL; DATA_PTR(self) = NULL;
DATA_PTR(self) = (void *)ICONV2VALUE(iconv_create(to, from, &opt, &idx)); DATA_PTR(self) = (void *)ICONV2VALUE(iconv_create(to, from, &opt, &idx));
#ifdef HAVE_RUBY_ENCODING_H
if (idx >= 0) ENCODING_SET(self, idx); if (idx >= 0) ENCODING_SET(self, idx);
#endif
return self; return self;
} }


Expand All @@ -697,7 +756,9 @@ iconv_s_open(int argc, VALUE *argv, VALUE self)
cd = ICONV2VALUE(iconv_create(to, from, &opt, &idx)); cd = ICONV2VALUE(iconv_create(to, from, &opt, &idx));


self = Data_Wrap_Struct(self, NULL, ICONV_FREE, (void *)cd); self = Data_Wrap_Struct(self, NULL, ICONV_FREE, (void *)cd);
#ifdef HAVE_RUBY_ENCODING_H
if (idx >= 0) ENCODING_SET(self, idx); if (idx >= 0) ENCODING_SET(self, idx);
#endif


if (rb_block_given_p()) { if (rb_block_given_p()) {
return rb_ensure(rb_yield, self, (VALUE(*)())iconv_finish, self); return rb_ensure(rb_yield, self, (VALUE(*)())iconv_finish, self);
Expand Down Expand Up @@ -838,7 +899,7 @@ iconv_s_list(void)


args[1] = rb_block_given_p() ? 0 : rb_ary_new(); args[1] = rb_block_given_p() ? 0 : rb_ary_new();
iconvlist(list_iconv, args); iconvlist(list_iconv, args);
state = *(int *)args; state = (int)args[0];
if (state) rb_jump_tag(state); if (state) rb_jump_tag(state);
if (args[1]) return args[1]; if (args[1]) return args[1];
#elif defined(HAVE___ICONV_FREE_LIST) #elif defined(HAVE___ICONV_FREE_LIST)
Expand Down Expand Up @@ -930,27 +991,38 @@ iconv_iconv(int argc, VALUE *argv, VALUE self)


rb_scan_args(argc, argv, "12", &str, &n1, &n2); rb_scan_args(argc, argv, "12", &str, &n1, &n2);
if (!NIL_P(str)) { if (!NIL_P(str)) {
#ifdef HAVE_RUBY_ENCODING_H
VALUE n = rb_str_length(StringValue(str)); VALUE n = rb_str_length(StringValue(str));
slen = NUM2LONG(n); slen = NUM2LONG(n);
#else
slen = RSTRING_LEN(StringValue(str));
#endif
} }
if (argc != 2 || !RTEST(rb_range_beg_len(n1, &start, &length, slen, 0))) { if (argc != 2 || !RTEST(rb_range_beg_len(n1, &start, &length, slen, 0))) {
if (NIL_P(n1) || ((start = NUM2LONG(n1)) < 0 ? (start += slen) >= 0 : start < slen)) { if (NIL_P(n1) || ((start = NUM2LONG(n1)) < 0 ? (start += slen) >= 0 : start < slen)) {
length = NIL_P(n2) ? -1 : NUM2LONG(n2); length = NIL_P(n2) ? -1 : NUM2LONG(n2);
} }
} }
#ifdef HAVE_RUBY_ENCODING_H
if (start > 0 || length > 0) { if (start > 0 || length > 0) {
rb_encoding *enc = rb_enc_get(str); #ifdef HAVE_RUBY_ENCODING_H
const char *s = RSTRING_PTR(str), *e = s + RSTRING_LEN(str); const char *s = RSTRING_PTR(str), *e = s + RSTRING_LEN(str);
const char *ps = s; const char *ps = s;
rb_encoding *enc = rb_enc_get(str);
if (start > 0) { if (start > 0) {
start = (ps = rb_enc_nth(s, e, start, enc)) - s; start = (ps = rb_enc_nth(s, e, start, enc)) - s;
} }
if (length > 0) { if (length > 0) {
length = rb_enc_nth(ps, e, length, enc) - ps; length = rb_enc_nth(ps, e, length, enc) - ps;
} }
} #else
if (start > slen) {
start = slen;
}
if (length > slen - start) {
length = slen - start;
}
#endif #endif
}


return iconv_convert(VALUE2ICONV(cd), str, start, length, ENCODING_GET(self), NULL); return iconv_convert(VALUE2ICONV(cd), str, start, length, ENCODING_GET(self), NULL);
} }
Expand Down
1 change: 1 addition & 0 deletions iconv.gemspec
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ Gem::Specification.new do |gem|
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
gem.require_paths = ["lib"] gem.require_paths = ["lib"]
gem.required_ruby_version = '>= 1.9.2'
end end
2 changes: 1 addition & 1 deletion lib/iconv/version.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,3 +1,3 @@
class Iconv < Data class Iconv < Data
VERSION = "1.0.1" VERSION = "1.0.2"
end end
2 changes: 1 addition & 1 deletion test/test_basic.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,4 +1,4 @@
require_relative "utils.rb" require File.expand_path("../utils.rb", __FILE__)


class TestIconv::Basic < TestIconv class TestIconv::Basic < TestIconv
def test_euc2sjis def test_euc2sjis
Expand Down
2 changes: 1 addition & 1 deletion test/test_option.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,4 +1,4 @@
require_relative "utils.rb" require File.expand_path("../utils.rb", __FILE__)


class TestIconv::Option < TestIconv class TestIconv::Option < TestIconv
def test_ignore_option def test_ignore_option
Expand Down
2 changes: 1 addition & 1 deletion test/test_partial.rb
Original file line number Original file line Diff line number Diff line change
@@ -1,4 +1,4 @@
require_relative "utils.rb" require File.expand_path("../utils.rb", __FILE__)


class TestIconv::Partial < TestIconv class TestIconv::Partial < TestIconv
def test_partial_ascii def test_partial_ascii
Expand Down

0 comments on commit a437b41

Please sign in to comment.