diff --git a/ChangeLog b/ChangeLog index 4b89da51d5..66cfd46dd2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Sun Jan 18 23:59:44 2004 Nobuyoshi Nakada + + * ext/iconv/charset_alias.rb: prefer us_EN locale encodings or + former. [ruby-dev:22609] + + * ext/iconv/iconv.c (iconv_create): raise InvalidEncoding + exception when EINVAL. + Sun Jan 18 23:16:34 2004 Nobuyoshi Nakada * class.c, error.c, file.c, io.c, numeric.c, object.c, re.c, struct.c, diff --git a/ext/iconv/charset_alias.rb b/ext/iconv/charset_alias.rb index be2c1412e7..458dc89d4a 100644 --- a/ext/iconv/charset_alias.rb +++ b/ext/iconv/charset_alias.rb @@ -13,10 +13,13 @@ class Hash::Ordered < Hash end def []=(key, val) ary = fetch(key) {return super(key, [self.size, key, val])} and - ary.last = val + ary << val end - def each - values.sort.each {|i, key, val| yield key, val} + def sort + values.sort.collect {|i, *rest| rest} + end + def each(&block) + sort.each(&block) end end @@ -32,17 +35,40 @@ def charset_alias(config_charset, mapfile, target = OS) end case target when /linux|-gnu/ - map.delete('ascii') - when /cygwin/ +# map.delete('ascii') + when /cygwin|os2-emx/ # get rid of tilde/yen problem. map['shift_jis'] = 'cp932' end + st = Hash.new(0) + map = map.sort.collect do |can, *sys| + if sys.grep(/^en_us(?=.|$)/i) {break true} == true + noen = %r"^(?!en_us)\w+_\w+#{Regexp.new($')}$"i + sys.reject! {|s| noen =~ s} + end + sys = sys.first + st[sys] += 1 + [can, sys] + end + st.delete_if {|sys, i| i == 1}.empty? + st.keys.each {|sys| st[sys] = nil} + st.default = nil open(mapfile, "w") do |f| f.puts("require 'iconv.so'") f.puts f.puts(comments) f.puts("class Iconv") - map.each {|can, sys| f.puts(" charset_map['#{can}'.freeze] = '#{sys}'.freeze")} + i = 0 + map.each do |can, sys| + if s = st[sys] + sys = s + elsif st.key?(sys) + sys = (st[sys] = "sys#{i+=1}") + " = '#{sys}'.freeze" + else + sys = "'#{sys}'.freeze" + end + f.puts(" charset_map['#{can}'.freeze] = #{sys}") + end f.puts("end") end end diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index 4b1f4b5073..bceb7ca692 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -53,6 +53,7 @@ struct iconv_env_t VALUE (*append)_((VALUE, VALUE)); }; +static VALUE rb_eIconvInvalidEncoding; static VALUE rb_eIconvFailure; static VALUE rb_eIconvIllegalSeq; static VALUE rb_eIconvInvalidChar; @@ -143,10 +144,15 @@ iconv_create cd = iconv_open(tocode, fromcode); } if (cd == (iconv_t)-1) { - volatile VALUE msg = rb_str_new2("iconv(\""); + int inval = errno == EINVAL; + volatile VALUE msg = rb_str_new2("iconv(\"" + (inval ? 5 : 0)); + char *s; + rb_str_buf_cat2(rb_str_buf_append(msg, to), "\", \""); rb_str_buf_cat2(rb_str_buf_append(msg, from), "\")"); - rb_sys_fail(StringValuePtr(msg)); + s = StringValuePtr(msg); + if (!inval) rb_sys_fail(s); + rb_raise(rb_eIconvInvalidEncoding, "invalid encoding %s", s); } } @@ -847,6 +853,7 @@ Init_iconv _((void)) rb_define_method(rb_eIconvFailure, "failed", iconv_failure_failed, 0); rb_define_method(rb_eIconvFailure, "inspect", iconv_failure_inspect, 0); + rb_eIconvInvalidEncoding = rb_define_class_under(rb_cIconv, "InvalidEncoding", rb_eArgError); rb_eIconvIllegalSeq = rb_define_class_under(rb_cIconv, "IllegalSequence", rb_eArgError); rb_eIconvInvalidChar = rb_define_class_under(rb_cIconv, "InvalidCharacter", rb_eArgError); rb_eIconvOutOfRange = rb_define_class_under(rb_cIconv, "OutOfRange", rb_eRuntimeError);