summaryrefslogtreecommitdiff
path: root/ext/iconv
diff options
context:
space:
mode:
Diffstat (limited to 'ext/iconv')
-rw-r--r--ext/iconv/charset_alias.rb13
-rw-r--r--ext/iconv/iconv.c40
2 files changed, 41 insertions, 12 deletions
diff --git a/ext/iconv/charset_alias.rb b/ext/iconv/charset_alias.rb
index 20a7f6406a..48f0fae5f9 100644
--- a/ext/iconv/charset_alias.rb
+++ b/ext/iconv/charset_alias.rb
@@ -1,16 +1,16 @@
#! /usr/bin/ruby
require 'rbconfig'
-# http://www.ctan.org/tex-archive/macros/texinfo/texinfo/intl/config.charset'
+# http://www.ctan.org/tex-archive/macros/texinfo/texinfo/intl/config.charset
# Fri, 30 May 2003 00:09:00 GMT'
OS = Config::CONFIG["target"]
SHELL = Config::CONFIG['SHELL']
-def charset_alias(config_charset, mapfile)
+def charset_alias(config_charset, mapfile, target = OS)
map = {}
comments = []
- IO.foreach("|#{SHELL} #{config_charset} #{OS}") do |list|
+ IO.foreach("|#{SHELL} #{config_charset} #{target}") do |list|
next comments << list if /^\#/ =~ list
next unless /^(\S+)\s+(\S+)$/ =~ list
sys, can = $1, $2
@@ -18,9 +18,12 @@ def charset_alias(config_charset, mapfile)
next if can.downcase! and sys == can
map[can] = sys
end
- case OS
+ case target
when /linux|-gnu/
map.delete('ascii')
+ when /cygwin/
+ # get rid of tilde/yen problem.
+ map['shift_jis'] = 'cp932'
end
open(mapfile, "w") do |f|
f.puts("require 'iconv.so'")
@@ -32,5 +35,5 @@ def charset_alias(config_charset, mapfile)
end
end
-ARGV.size == 2 or abort "usage: #$0 config.status map.rb"
+(2..3) === ARGV.size or abort "usage: #$0 config.status map.rb [target]"
charset_alias(*ARGV)
diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c
index cbb89dca48..b15332e386 100644
--- a/ext/iconv/iconv.c
+++ b/ext/iconv/iconv.c
@@ -59,6 +59,7 @@ static VALUE rb_eIconvOutOfRange;
static ID rb_inserter;
static ID rb_success, rb_failed, rb_mesg;
+static VALUE iconv_fail _((VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env));
static VALUE iconv_failure_initialize _((VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env));
static VALUE iconv_failure_success _((VALUE self));
static VALUE iconv_failure_failed _((VALUE self));
@@ -108,13 +109,17 @@ map_charset
{
VALUE val = *code;
- StringValuePtr(val);
if (RHASH(charset_map)->tbl && RHASH(charset_map)->tbl->num_entries) {
+ val = rb_funcall2(val, rb_intern("downcase"), 0, 0);
+ StringValuePtr(val);
if (st_lookup(RHASH(charset_map)->tbl, val, &val)) {
StringValuePtr(val);
*code = val;
}
}
+ else {
+ StringValuePtr(val);
+ }
return RSTRING(val)->ptr;
}
@@ -231,9 +236,6 @@ iconv_try
return Qfalse;
}
-#define iconv_fail(error, success, failed, env) \
- rb_exc_raise(iconv_failure_initialize(error, success, failed, env))
-
#define FAILED_MAXLEN 16
static VALUE
@@ -271,6 +273,21 @@ iconv_failure_initialize
}
static VALUE
+iconv_fail
+#ifdef HAVE_PROTOTYPES
+ (VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env)
+#else /* HAVE_PROTOTYPES */
+ (error, success, failed, env)
+ VALUE error, success, failed;
+ struct iconv_env_t *env;
+#endif /* HAVE_PROTOTYPES */
+{
+ error = iconv_failure_initialize(error, success, failed, env);
+ if (!rb_block_given_p()) rb_exc_raise(error);
+ return rb_yield(error);
+}
+
+static VALUE
rb_str_derive
#ifdef HAVE_PROTOTYPES
(VALUE str, const char* ptr, int len)
@@ -327,8 +344,17 @@ iconv_convert
outptr = buffer;
outlen = sizeof(buffer);
error = iconv_try(cd, &inptr, &inlen, &outptr, &outlen);
- if (error)
- iconv_fail(error, Qnil, Qnil, env);
+ if (error) {
+ unsigned int i;
+ str = iconv_fail(error, Qnil, Qnil, env);
+ if (FIXNUM_P(str) && (i = FIX2INT(str)) <= 0xff) {
+ char c = i;
+ str = rb_str_new(&c, 1);
+ }
+ else if (!NIL_P(str)) {
+ StringValue(str);
+ }
+ }
inptr = NULL;
length = 0;
@@ -395,7 +421,7 @@ iconv_convert
if (!ret)
ret = rb_str_derive(str, instart, inptr - instart);
str = rb_str_derive(str, inptr, inlen);
- iconv_fail(error, ret, str, env);
+ rb_str_concat(str, iconv_fail(error, ret, str, env));
}
} while (inlen > 0);