mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ext/iconv/iconv.c: iconvctl() support. [EXPERIMENTAL]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@9514 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
f4413f1487
commit
1aa48a4ea9
3 changed files with 340 additions and 15 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
Mon Nov 7 20:54:57 2005 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* ext/iconv/iconv.c: iconvctl() support. [EXPERIMENTAL]
|
||||||
|
|
||||||
Mon Nov 7 16:23:23 2005 NAKAMURA Usaku <usa@ruby-lang.org>
|
Mon Nov 7 16:23:23 2005 NAKAMURA Usaku <usa@ruby-lang.org>
|
||||||
|
|
||||||
* ext/openssl/ossl.h: need to include winsock2.h before including
|
* ext/openssl/ossl.h: need to include winsock2.h before including
|
||||||
|
|
|
@ -83,6 +83,14 @@ struct iconv_env_t
|
||||||
VALUE (*append)_((VALUE, VALUE));
|
VALUE (*append)_((VALUE, VALUE));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct rb_iconv_opt_t
|
||||||
|
{
|
||||||
|
VALUE transliterate;
|
||||||
|
VALUE discard_ilseq;
|
||||||
|
};
|
||||||
|
|
||||||
|
static ID id_transliterate, id_discard_ilseq;
|
||||||
|
|
||||||
static VALUE rb_eIconvInvalidEncoding;
|
static VALUE rb_eIconvInvalidEncoding;
|
||||||
static VALUE rb_eIconvFailure;
|
static VALUE rb_eIconvFailure;
|
||||||
static VALUE rb_eIconvIllegalSeq;
|
static VALUE rb_eIconvIllegalSeq;
|
||||||
|
@ -96,20 +104,21 @@ static VALUE iconv_failure_initialize _((VALUE error, VALUE mesg, VALUE success,
|
||||||
static VALUE iconv_failure_success _((VALUE self));
|
static VALUE iconv_failure_success _((VALUE self));
|
||||||
static VALUE iconv_failure_failed _((VALUE self));
|
static VALUE iconv_failure_failed _((VALUE self));
|
||||||
|
|
||||||
static iconv_t iconv_create _((VALUE to, VALUE from));
|
static iconv_t iconv_create _((VALUE to, VALUE from, struct rb_iconv_opt_t *opt));
|
||||||
static void iconv_dfree _((void *cd));
|
static void iconv_dfree _((void *cd));
|
||||||
static VALUE iconv_free _((VALUE cd));
|
static VALUE iconv_free _((VALUE cd));
|
||||||
static VALUE iconv_try _((iconv_t cd, const char **inptr, size_t *inlen, char **outptr, size_t *outlen));
|
static VALUE iconv_try _((iconv_t cd, const char **inptr, size_t *inlen, char **outptr, size_t *outlen));
|
||||||
static VALUE rb_str_derive _((VALUE str, const char* ptr, int len));
|
static VALUE rb_str_derive _((VALUE str, const char* ptr, int len));
|
||||||
static VALUE iconv_convert _((iconv_t cd, VALUE str, int start, int length, struct iconv_env_t* env));
|
static VALUE iconv_convert _((iconv_t cd, VALUE str, int start, int length, struct iconv_env_t* env));
|
||||||
static VALUE iconv_s_allocate _((VALUE klass));
|
static VALUE iconv_s_allocate _((VALUE klass));
|
||||||
static VALUE iconv_initialize _((VALUE self, VALUE to, VALUE from));
|
static VALUE iconv_initialize _((int argc, VALUE *argv, VALUE self));
|
||||||
static VALUE iconv_s_open _((VALUE self, VALUE to, VALUE from));
|
static VALUE iconv_s_open _((int argc, VALUE *argv, VALUE self));
|
||||||
static VALUE iconv_s_convert _((struct iconv_env_t* env));
|
static VALUE iconv_s_convert _((struct iconv_env_t* env));
|
||||||
static VALUE iconv_s_iconv _((int argc, VALUE *argv, VALUE self));
|
static VALUE iconv_s_iconv _((int argc, VALUE *argv, VALUE self));
|
||||||
static VALUE iconv_init_state _((VALUE cd));
|
static VALUE iconv_init_state _((VALUE cd));
|
||||||
static VALUE iconv_finish _((VALUE self));
|
static VALUE iconv_finish _((VALUE self));
|
||||||
static VALUE iconv_iconv _((int argc, VALUE *argv, VALUE self));
|
static VALUE iconv_iconv _((int argc, VALUE *argv, VALUE self));
|
||||||
|
static VALUE iconv_conv _((int argc, VALUE *argv, VALUE self));
|
||||||
|
|
||||||
static VALUE charset_map;
|
static VALUE charset_map;
|
||||||
|
|
||||||
|
@ -140,7 +149,7 @@ map_charset(VALUE *code)
|
||||||
}
|
}
|
||||||
|
|
||||||
static iconv_t
|
static iconv_t
|
||||||
iconv_create(VALUE to, VALUE from)
|
iconv_create(VALUE to, VALUE from, struct rb_iconv_opt_t *opt)
|
||||||
{
|
{
|
||||||
const char* tocode = map_charset(&to);
|
const char* tocode = map_charset(&to);
|
||||||
const char* fromcode = map_charset(&from);
|
const char* fromcode = map_charset(&from);
|
||||||
|
@ -171,6 +180,24 @@ iconv_create(VALUE to, VALUE from)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (opt) {
|
||||||
|
int flag;
|
||||||
|
#ifdef ICONV_SET_TRANSLITERATE
|
||||||
|
if (opt->transliterate != Qundef) {
|
||||||
|
flag = RTEST(opt->transliterate);
|
||||||
|
if (iconvctl(cd, ICONV_SET_TRANSLITERATE, (void *)&flag))
|
||||||
|
rb_sys_fail("ICONV_SET_TRANSLITERATE");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef ICONV_SET_DISCARD_ILSEQ
|
||||||
|
if (opt->discard_ilseq != Qundef) {
|
||||||
|
flag = RTEST(opt->discard_ilseq);
|
||||||
|
if (iconvctl(cd, ICONV_SET_DISCARD_ILSEQ, (void *)&flag))
|
||||||
|
rb_sys_fail("ICONV_SET_DISCARD_ILSEQ");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return cd;
|
return cd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,9 +463,76 @@ iconv_s_allocate(VALUE klass)
|
||||||
return Data_Wrap_Struct(klass, 0, ICONV_FREE, 0);
|
return Data_Wrap_Struct(klass, 0, ICONV_FREE, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
get_iconv_opt_i(VALUE i, VALUE arg)
|
||||||
|
{
|
||||||
|
struct rb_iconv_opt_t *opt = (struct rb_iconv_opt_t *)arg;
|
||||||
|
VALUE name, val;
|
||||||
|
i = rb_Array(i);
|
||||||
|
name = rb_ary_entry(i, 0);
|
||||||
|
val = rb_ary_entry(i, 1);
|
||||||
|
do {
|
||||||
|
if (SYMBOL_P(name)) {
|
||||||
|
ID id = SYM2ID(name);
|
||||||
|
if (id == id_transliterate) {
|
||||||
|
#ifdef ICONV_SET_TRANSLITERATE
|
||||||
|
opt->transliterate = val;
|
||||||
|
#else
|
||||||
|
rb_notimplement();
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (id == id_discard_ilseq) {
|
||||||
|
#ifdef ICONV_SET_DISCARD_ILSEQ
|
||||||
|
opt->discard_ilseq = val;
|
||||||
|
#else
|
||||||
|
rb_notimplement();
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const char *s = StringValueCStr(name);
|
||||||
|
if (strcmp(s, "transliterate") == 0) {
|
||||||
|
#ifdef ICONV_SET_TRANSLITERATE
|
||||||
|
opt->transliterate = val;
|
||||||
|
#else
|
||||||
|
rb_notimplement();
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strcmp(s, "discard_ilseq") == 0) {
|
||||||
|
#ifdef ICONV_SET_DISCARD_ILSEQ
|
||||||
|
opt->discard_ilseq = val;
|
||||||
|
#else
|
||||||
|
rb_notimplement();
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
name = rb_inspect(name);
|
||||||
|
rb_raise(rb_eArgError, "unknown option - %s", StringValueCStr(name));
|
||||||
|
} while (0);
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_iconv_opt(struct rb_iconv_opt_t *opt, VALUE options)
|
||||||
|
{
|
||||||
|
opt->transliterate = Qundef;
|
||||||
|
opt->discard_ilseq = Qundef;
|
||||||
|
if (!NIL_P(options)) {
|
||||||
|
rb_iterate(rb_each, options, get_iconv_opt_i, (VALUE)opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define iconv_ctl(self, func, val) (\
|
||||||
|
iconvctl(VALUE2ICONV(check_iconv(self)), func, (void *)&(val)) ? \
|
||||||
|
rb_sys_fail(#func) : (void)0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Document-method: new
|
* Document-method: new
|
||||||
* call-seq: Iconv.new(to, from)
|
* call-seq: Iconv.new(to, from, [options])
|
||||||
*
|
*
|
||||||
* Creates new code converter from a coding-system designated with +from+
|
* Creates new code converter from a coding-system designated with +from+
|
||||||
* to another one designated with +to+.
|
* to another one designated with +to+.
|
||||||
|
@ -447,6 +541,7 @@ iconv_s_allocate(VALUE klass)
|
||||||
*
|
*
|
||||||
* +to+:: encoding name for destination
|
* +to+:: encoding name for destination
|
||||||
* +from+:: encoding name for source
|
* +from+:: encoding name for source
|
||||||
|
* +options+:: options for converter
|
||||||
*
|
*
|
||||||
* === Exceptions
|
* === Exceptions
|
||||||
*
|
*
|
||||||
|
@ -455,11 +550,16 @@ iconv_s_allocate(VALUE klass)
|
||||||
* SystemCallError:: if <tt>iconv_open(3)</tt> fails
|
* SystemCallError:: if <tt>iconv_open(3)</tt> fails
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
iconv_initialize(VALUE self, VALUE to, VALUE from)
|
iconv_initialize(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
|
VALUE to, from, options;
|
||||||
|
struct rb_iconv_opt_t opt;
|
||||||
|
|
||||||
|
rb_scan_args(argc, argv, "21", &to, &from, &options);
|
||||||
|
get_iconv_opt(&opt, options);
|
||||||
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));
|
DATA_PTR(self) = (void *)ICONV2VALUE(iconv_create(to, from, &opt));
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,9 +572,14 @@ iconv_initialize(VALUE self, VALUE to, VALUE from)
|
||||||
* returned from the block.
|
* returned from the block.
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
iconv_s_open(VALUE self, VALUE to, VALUE from)
|
iconv_s_open(int argc, VALUE *argv, VALUE self)
|
||||||
{
|
{
|
||||||
VALUE cd = ICONV2VALUE(iconv_create(to, from));
|
VALUE to, from, options, cd;
|
||||||
|
struct rb_iconv_opt_t opt;
|
||||||
|
|
||||||
|
rb_scan_args(argc, argv, "21", &to, &from, &options);
|
||||||
|
get_iconv_opt(&opt, options);
|
||||||
|
cd = ICONV2VALUE(iconv_create(to, from, &opt));
|
||||||
|
|
||||||
self = Data_Wrap_Struct(self, NULL, ICONV_FREE, (void *)cd);
|
self = Data_Wrap_Struct(self, NULL, ICONV_FREE, (void *)cd);
|
||||||
if (rb_block_given_p()) {
|
if (rb_block_given_p()) {
|
||||||
|
@ -534,7 +639,7 @@ iconv_s_iconv(int argc, VALUE *argv, VALUE self)
|
||||||
arg.argv = argv + 2;
|
arg.argv = argv + 2;
|
||||||
arg.append = rb_ary_push;
|
arg.append = rb_ary_push;
|
||||||
arg.ret = rb_ary_new2(argc);
|
arg.ret = rb_ary_new2(argc);
|
||||||
arg.cd = iconv_create(argv[0], argv[1]);
|
arg.cd = iconv_create(argv[0], argv[1], NULL);
|
||||||
return rb_ensure(iconv_s_convert, (VALUE)&arg, iconv_free, ICONV2VALUE(arg.cd));
|
return rb_ensure(iconv_s_convert, (VALUE)&arg, iconv_free, ICONV2VALUE(arg.cd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -555,7 +660,7 @@ iconv_s_conv(VALUE self, VALUE to, VALUE from, VALUE str)
|
||||||
arg.argv = &str;
|
arg.argv = &str;
|
||||||
arg.append = rb_str_append;
|
arg.append = rb_str_append;
|
||||||
arg.ret = rb_str_new(0, 0);
|
arg.ret = rb_str_new(0, 0);
|
||||||
arg.cd = iconv_create(to, from);
|
arg.cd = iconv_create(to, from, NULL);
|
||||||
return rb_ensure(iconv_s_convert, (VALUE)&arg, iconv_free, ICONV2VALUE(arg.cd));
|
return rb_ensure(iconv_s_convert, (VALUE)&arg, iconv_free, ICONV2VALUE(arg.cd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,6 +798,160 @@ iconv_iconv(int argc, VALUE *argv, VALUE self)
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Document-method: conv
|
||||||
|
* call-seq: conv(str...)
|
||||||
|
*
|
||||||
|
* Equivalent to
|
||||||
|
*
|
||||||
|
* iconv(nil, str..., nil).join
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
iconv_conv(int argc, VALUE *argv, VALUE self)
|
||||||
|
{
|
||||||
|
iconv_t cd = VALUE2ICONV(check_iconv(self));
|
||||||
|
VALUE str, s;
|
||||||
|
|
||||||
|
str = iconv_convert(cd, Qnil, 0, 0, NULL);
|
||||||
|
if (argc > 0) {
|
||||||
|
do {
|
||||||
|
s = iconv_convert(cd, *argv++, 0, -1, NULL);
|
||||||
|
if (RSTRING(s)->len)
|
||||||
|
rb_str_buf_append(str, s);
|
||||||
|
else
|
||||||
|
str = s;
|
||||||
|
} while (--argc);
|
||||||
|
s = iconv_convert(cd, Qnil, 0, 0, NULL);
|
||||||
|
if (RSTRING(s)->len)
|
||||||
|
rb_str_buf_append(str, s);
|
||||||
|
else
|
||||||
|
str = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Document-method: trivial?
|
||||||
|
* call-seq: trivial?
|
||||||
|
*
|
||||||
|
* Returns trivial flag.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
iconv_trivialp(VALUE self)
|
||||||
|
{
|
||||||
|
#ifdef ICONV_TRIVIALP
|
||||||
|
int trivial = 0;
|
||||||
|
iconv_ctl(self, ICONV_TRIVIALP, trivial);
|
||||||
|
if (trivial) return Qtrue;
|
||||||
|
#else
|
||||||
|
rb_notimplement();
|
||||||
|
#endif
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Document-method: transliterate?
|
||||||
|
* call-seq: transliterate?
|
||||||
|
*
|
||||||
|
* Returns transliterate flag.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
iconv_get_transliterate(VALUE self)
|
||||||
|
{
|
||||||
|
#ifdef ICONV_GET_TRANSLITERATE
|
||||||
|
int trans = 0;
|
||||||
|
iconv_ctl(self, ICONV_GET_TRANSLITERATE, trans);
|
||||||
|
if (trans) return Qtrue;
|
||||||
|
#else
|
||||||
|
rb_notimplement();
|
||||||
|
#endif
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Document-method: transliterate=
|
||||||
|
* call-seq: cd.transliterate = flag
|
||||||
|
*
|
||||||
|
* Sets transliterate flag.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
iconv_set_transliterate(VALUE self, VALUE transliterate)
|
||||||
|
{
|
||||||
|
#ifdef ICONV_SET_TRANSLITERATE
|
||||||
|
int trans = RTEST(transliterate);
|
||||||
|
iconv_ctl(self, ICONV_SET_TRANSLITERATE, trans);
|
||||||
|
#else
|
||||||
|
rb_notimplement();
|
||||||
|
#endif
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Document-method: discard_ilseq?
|
||||||
|
* call-seq: discard_ilseq?
|
||||||
|
*
|
||||||
|
* Returns discard_ilseq flag.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
iconv_get_discard_ilseq(VALUE self)
|
||||||
|
{
|
||||||
|
#ifdef ICONV_GET_DISCARD_ILSEQ
|
||||||
|
int dis = 0;
|
||||||
|
iconv_ctl(self, ICONV_GET_DISCARD_ILSEQ, dis);
|
||||||
|
if (dis) return Qtrue;
|
||||||
|
#else
|
||||||
|
rb_notimplement();
|
||||||
|
#endif
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Document-method: discard_ilseq=
|
||||||
|
* call-seq: cd.discard_ilseq = flag
|
||||||
|
*
|
||||||
|
* Sets discard_ilseq flag.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
iconv_set_discard_ilseq(VALUE self, VALUE discard_ilseq)
|
||||||
|
{
|
||||||
|
#ifdef ICONV_SET_DISCARD_ILSEQ
|
||||||
|
int dis = RTEST(discard_ilseq);
|
||||||
|
iconv_ctl(self, ICONV_SET_DISCARD_ILSEQ, dis);
|
||||||
|
#else
|
||||||
|
rb_notimplement();
|
||||||
|
#endif
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Document-method: ctlmethods
|
||||||
|
* call-seq: Iconv.ctlmethods => array
|
||||||
|
*
|
||||||
|
* Returns available iconvctl() method list.
|
||||||
|
*/
|
||||||
|
static VALUE
|
||||||
|
iconv_s_ctlmethods(VALUE klass)
|
||||||
|
{
|
||||||
|
VALUE ary = rb_ary_new();
|
||||||
|
#ifdef ICONV_TRIVIALP
|
||||||
|
rb_ary_push(ary, ID2SYM(rb_intern("trivial?")));
|
||||||
|
#endif
|
||||||
|
#ifdef ICONV_GET_TRANSLITERATE
|
||||||
|
rb_ary_push(ary, ID2SYM(rb_intern("transliterate?")));
|
||||||
|
#endif
|
||||||
|
#ifdef ICONV_SET_TRANSLITERATE
|
||||||
|
rb_ary_push(ary, ID2SYM(rb_intern("transliterate=")));
|
||||||
|
#endif
|
||||||
|
#ifdef ICONV_GET_DISCARD_ILSEQ
|
||||||
|
rb_ary_push(ary, ID2SYM(rb_intern("discard_ilseq?")));
|
||||||
|
#endif
|
||||||
|
#ifdef ICONV_SET_DISCARD_ILSEQ
|
||||||
|
rb_ary_push(ary, ID2SYM(rb_intern("discard_ilseq=")));
|
||||||
|
#endif
|
||||||
|
return ary;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Document-class: Iconv::Failure
|
* Document-class: Iconv::Failure
|
||||||
*
|
*
|
||||||
|
@ -787,13 +1046,20 @@ Init_iconv(void)
|
||||||
VALUE rb_cIconv = rb_define_class("Iconv", rb_cData);
|
VALUE rb_cIconv = rb_define_class("Iconv", rb_cData);
|
||||||
|
|
||||||
rb_define_alloc_func(rb_cIconv, iconv_s_allocate);
|
rb_define_alloc_func(rb_cIconv, iconv_s_allocate);
|
||||||
rb_define_singleton_method(rb_cIconv, "open", iconv_s_open, 2);
|
rb_define_singleton_method(rb_cIconv, "open", iconv_s_open, -1);
|
||||||
rb_define_singleton_method(rb_cIconv, "iconv", iconv_s_iconv, -1);
|
rb_define_singleton_method(rb_cIconv, "iconv", iconv_s_iconv, -1);
|
||||||
rb_define_singleton_method(rb_cIconv, "conv", iconv_s_conv, 3);
|
rb_define_singleton_method(rb_cIconv, "conv", iconv_s_conv, 3);
|
||||||
rb_define_singleton_method(rb_cIconv, "list", iconv_s_list, 0);
|
rb_define_singleton_method(rb_cIconv, "list", iconv_s_list, 0);
|
||||||
rb_define_method(rb_cIconv, "initialize", iconv_initialize, 2);
|
rb_define_singleton_method(rb_cIconv, "ctlmethods", iconv_s_ctlmethods, 0);
|
||||||
|
rb_define_method(rb_cIconv, "initialize", iconv_initialize, -1);
|
||||||
rb_define_method(rb_cIconv, "close", iconv_finish, 0);
|
rb_define_method(rb_cIconv, "close", iconv_finish, 0);
|
||||||
rb_define_method(rb_cIconv, "iconv", iconv_iconv, -1);
|
rb_define_method(rb_cIconv, "iconv", iconv_iconv, -1);
|
||||||
|
rb_define_method(rb_cIconv, "conv", iconv_conv, -1);
|
||||||
|
rb_define_method(rb_cIconv, "trivial?", iconv_trivialp, 0);
|
||||||
|
rb_define_method(rb_cIconv, "transliterate?", iconv_get_transliterate, 0);
|
||||||
|
rb_define_method(rb_cIconv, "transliterate=", iconv_set_transliterate, 1);
|
||||||
|
rb_define_method(rb_cIconv, "discard_ilseq?", iconv_get_discard_ilseq, 0);
|
||||||
|
rb_define_method(rb_cIconv, "discard_ilseq=", iconv_set_discard_ilseq, 1);
|
||||||
|
|
||||||
rb_eIconvFailure = rb_define_module_under(rb_cIconv, "Failure");
|
rb_eIconvFailure = rb_define_module_under(rb_cIconv, "Failure");
|
||||||
rb_define_method(rb_eIconvFailure, "initialize", iconv_failure_initialize, 3);
|
rb_define_method(rb_eIconvFailure, "initialize", iconv_failure_initialize, 3);
|
||||||
|
@ -814,6 +1080,8 @@ Init_iconv(void)
|
||||||
|
|
||||||
rb_success = rb_intern("success");
|
rb_success = rb_intern("success");
|
||||||
rb_failed = rb_intern("failed");
|
rb_failed = rb_intern("failed");
|
||||||
|
id_transliterate = rb_intern("transliterate");
|
||||||
|
id_discard_ilseq = rb_intern("discard_ilseq");
|
||||||
|
|
||||||
charset_map = rb_hash_new();
|
charset_map = rb_hash_new();
|
||||||
rb_gc_register_address(&charset_map);
|
rb_gc_register_address(&charset_map);
|
||||||
|
|
53
ext/iconv/mkwrapper.rb
Normal file
53
ext/iconv/mkwrapper.rb
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
#! /usr/bin/ruby
|
||||||
|
require 'rbconfig'
|
||||||
|
require 'optparse'
|
||||||
|
|
||||||
|
# http://www.ctan.org/tex-archive/macros/texinfo/texinfo/intl/config.charset
|
||||||
|
# Fri, 30 May 2003 00:09:00 GMT'
|
||||||
|
|
||||||
|
HEADER = <<SRC
|
||||||
|
require 'iconv.so'
|
||||||
|
|
||||||
|
class Iconv
|
||||||
|
case RUBY_PLATFORM
|
||||||
|
SRC
|
||||||
|
|
||||||
|
def charset_alias(config_charset, mapfile = nil)
|
||||||
|
found = nil
|
||||||
|
src = [HEADER]
|
||||||
|
open(config_charset) do |input|
|
||||||
|
input.find {|line| /^case "\$os" in/ =~ line} or return
|
||||||
|
input.each do |line|
|
||||||
|
case line
|
||||||
|
when /^\s*([-\w\*]+(?:\s*\|\s*[-\w\*]+)*)(?=\))/
|
||||||
|
(s = " when ") << $&.split('|').collect {|targ|
|
||||||
|
targ.strip!
|
||||||
|
tail = targ.chomp!("*") ? '' : '\z'
|
||||||
|
head = targ.slice!(/\A\*/) ? '' : '\A'
|
||||||
|
targ.gsub!(/\*/, '.*')
|
||||||
|
"/#{head}#{targ}#{tail}/"
|
||||||
|
}.join(", ")
|
||||||
|
src << s
|
||||||
|
found = {}
|
||||||
|
when /^\s*echo "(?:\$\w+\.)?([-\w*]+)\s+([-\w]+)"/
|
||||||
|
sys, can = $1, $2
|
||||||
|
can.downcase!
|
||||||
|
unless found[can] or (/\Aen_(?!US\z)/ =~ sys && /\ACP437\z/i =~ can)
|
||||||
|
found[can] = true
|
||||||
|
src << " charset_map['#{can}'] = '#{sys}'.freeze"
|
||||||
|
end
|
||||||
|
when /^\s*;;/
|
||||||
|
found = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
src << " end" << "end"
|
||||||
|
if mapfile
|
||||||
|
open(mapfile, "wb") {|f| f.puts *src}
|
||||||
|
else
|
||||||
|
puts *src
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
(1..2) === ARGV.size or abort "usage: #{$0} config_charset [mapfile]"
|
||||||
|
charset_alias(*ARGV)
|
Loading…
Reference in a new issue