From 4d5204c990aad34cae43048218d89519c59b74bc Mon Sep 17 00:00:00 2001 From: nobu Date: Thu, 2 Oct 2003 11:33:52 +0000 Subject: * ext/iconv/iconv.c (iconv_failure_initialize): conform with orthodox initialization method. * ext/iconv/iconv.c (iconv_fail): initialize exception instance from the class, and do not share instance variables with the others. [ruby-dev:21470] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4654 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 9 ++++++ ext/iconv/iconv.c | 92 +++++++++++++++++++++++++++++-------------------------- 2 files changed, 58 insertions(+), 43 deletions(-) diff --git a/ChangeLog b/ChangeLog index 1f910097c2..752aee6c5c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Thu Oct 2 20:33:49 2003 Nobuyoshi Nakada + + * ext/iconv/iconv.c (iconv_failure_initialize): conform with + orthodox initialization method. + + * ext/iconv/iconv.c (iconv_fail): initialize exception instance + from the class, and do not share instance variables with the + others. [ruby-dev:21470] + Thu Oct 2 18:20:27 2003 Nobuyoshi Nakada * time.c (Init_Time): define initialize. [ruby-dev:21469] diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index 03e7dac0a7..8e978b8730 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -50,17 +50,17 @@ struct iconv_env_t int argc; VALUE *argv; VALUE ret; + VALUE (*append)_((VALUE, VALUE)); }; static VALUE rb_eIconvFailure; static VALUE rb_eIconvIllegalSeq; static VALUE rb_eIconvInvalidChar; 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 ID rb_success, rb_failed; +static VALUE iconv_fail _((VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env, const char *mesg)); +static VALUE iconv_failure_initialize _((VALUE error, VALUE mesg, VALUE success, VALUE failed)); static VALUE iconv_failure_success _((VALUE self)); static VALUE iconv_failure_failed _((VALUE self)); @@ -223,16 +223,16 @@ iconv_try /* try the left in next loop */ break; case EILSEQ: - return rb_class_new_instance(0, 0, rb_eIconvIllegalSeq); + return rb_eIconvIllegalSeq; case EINVAL: - return rb_class_new_instance(0, 0, rb_eIconvInvalidChar); + return rb_eIconvInvalidChar; default: rb_sys_fail("iconv"); } } else if (*inlen > 0) { /* something goes wrong */ - return rb_class_new_instance(0, 0, rb_eIconvIllegalSeq); + return rb_eIconvIllegalSeq; } else if (ret) { return Qnil; /* conversion */ @@ -242,35 +242,15 @@ iconv_try #define FAILED_MAXLEN 16 -static VALUE -iconv_failure_initialize +static VALUE iconv_failure_initialize #ifdef HAVE_PROTOTYPES - (VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env) + (VALUE error, VALUE mesg, VALUE success, VALUE failed) #else /* HAVE_PROTOTYPES */ - (error, success, failed, env) - VALUE error; - VALUE success; - VALUE failed; - struct iconv_env_t *env; + (error, mesg, success, failed) + VALUE error, mesg, success, failed; #endif /* HAVE_PROTOTYPES */ { - if (NIL_P(rb_attr_get(error, rb_mesg))) { - if (TYPE(failed) != T_STRING || RSTRING(failed)->len < FAILED_MAXLEN) { - rb_ivar_set(error, rb_mesg, rb_inspect(failed)); - } - else { - VALUE mesg = rb_inspect(rb_str_substr(failed, 0, FAILED_MAXLEN)); - rb_str_cat2(mesg, "..."); - rb_ivar_set(error, rb_mesg, mesg); - } - } - if (env) { - success = rb_funcall3(env->ret, rb_inserter, 1, &success); - if (env->argc > 0) { - *(env->argv) = failed; - failed = rb_ary_new4(env->argc, env->argv); - } - } + rb_call_super(1, &mesg); rb_ivar_set(error, rb_success, success); rb_ivar_set(error, rb_failed, failed); return error; @@ -279,14 +259,36 @@ iconv_failure_initialize static VALUE iconv_fail #ifdef HAVE_PROTOTYPES - (VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env) + (VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env, const char *mesg) #else /* HAVE_PROTOTYPES */ - (error, success, failed, env) + (error, success, failed, env, mesg) VALUE error, success, failed; struct iconv_env_t *env; + const char *mesg; #endif /* HAVE_PROTOTYPES */ { - error = iconv_failure_initialize(error, success, failed, env); + VALUE args[3]; + + if (mesg && *mesg) { + args[0] = rb_str_new2(mesg); + } + else if (TYPE(failed) != T_STRING || RSTRING(failed)->len < FAILED_MAXLEN) { + args[0] = rb_inspect(failed); + } + else { + args[0] = rb_inspect(rb_str_substr(failed, 0, FAILED_MAXLEN)); + rb_str_cat2(args[0], "..."); + } + args[1] = success; + args[2] = failed; + if (env) { + args[1] = env->append(rb_obj_dup(env->ret), success); + if (env->argc > 0) { + *(env->argv) = failed; + args[2] = rb_ary_new4(env->argc, env->argv); + } + } + error = rb_class_new_instance(3, args, error); if (!rb_block_given_p()) rb_exc_raise(error); ruby_errinfo = error; return rb_yield(failed); @@ -352,7 +354,7 @@ iconv_convert error = iconv_try(cd, &inptr, &inlen, &outptr, &outlen); if (RTEST(error)) { unsigned int i; - rescue = iconv_fail(error, Qnil, Qnil, env); + rescue = iconv_fail(error, Qnil, Qnil, env, 0); if (TYPE(rescue) == T_ARRAY) { str = RARRAY(rescue)->len > 0 ? RARRAY(rescue)->ptr[0] : Qnil; } @@ -388,10 +390,12 @@ iconv_convert inlen = length; do { + char errmsg[50]; const char *tmpstart = inptr; outptr = buffer; outlen = sizeof(buffer); + errmsg[0] = 0; error = iconv_try(cd, &inptr, &inlen, &outptr, &outlen); if (0 <= outlen && outlen <= sizeof(buffer)) { @@ -422,9 +426,8 @@ iconv_convert } else { /* Some iconv() have a bug, return *outlen out of range */ - char errmsg[50]; sprintf(errmsg, "bug?(output length = %d)", sizeof(buffer) - outlen); - error = rb_exc_new2(rb_eIconvOutOfRange, errmsg); + error = rb_eIconvOutOfRange; } if (RTEST(error)) { @@ -432,8 +435,10 @@ iconv_convert if (!ret) ret = rb_str_derive(str, instart, inptr - instart); + else if (inptr > instart) + rb_str_cat(ret, instart, inptr - instart); str = rb_str_derive(str, inptr, inlen); - rescue = iconv_fail(error, ret, str, env); + rescue = iconv_fail(error, ret, str, env, errmsg); if (TYPE(rescue) == T_ARRAY) { if ((len = RARRAY(rescue)->len) > 0) rb_str_concat(ret, RARRAY(rescue)->ptr[0]); @@ -568,13 +573,13 @@ iconv_s_convert for (; env->argc > 0; --env->argc, ++env->argv) { VALUE s = iconv_convert(env->cd, last = *(env->argv), 0, -1, env); - rb_funcall3(env->ret, rb_inserter, 1, &s); + env->append(env->ret, s); } if (!NIL_P(last)) { VALUE s = iconv_convert(env->cd, Qnil, 0, 0, env); if (RSTRING(s)->len) - rb_funcall3(env->ret, rb_inserter, 1, &s); + env->append(env->ret, s); } return env->ret; @@ -598,6 +603,7 @@ iconv_s_iconv arg.argc = argc -= 2; arg.argv = argv + 2; + arg.append = rb_ary_push; arg.ret = rb_ary_new2(argc); arg.cd = iconv_create(argv[0], argv[1]); return rb_ensure(iconv_s_convert, (VALUE)&arg, iconv_free, ICONV2VALUE(arg.cd)); @@ -616,6 +622,7 @@ iconv_s_conv arg.argc = 1; arg.argv = &str; + arg.append = rb_str_append; arg.ret = rb_str_new(0, 0); arg.cd = iconv_create(to, from); return rb_ensure(iconv_s_convert, (VALUE)&arg, iconv_free, ICONV2VALUE(arg.cd)); @@ -840,6 +847,7 @@ Init_iconv _((void)) rb_define_method(rb_cIconv, "iconv", iconv_iconv, -1); rb_eIconvFailure = rb_define_module_under(rb_cIconv, "Failure"); + rb_define_method(rb_eIconvFailure, "initialize", iconv_failure_initialize, 3); rb_define_method(rb_eIconvFailure, "success", iconv_failure_success, 0); rb_define_method(rb_eIconvFailure, "failed", iconv_failure_failed, 0); rb_define_method(rb_eIconvFailure, "inspect", iconv_failure_inspect, 0); @@ -851,10 +859,8 @@ Init_iconv _((void)) rb_include_module(rb_eIconvInvalidChar, rb_eIconvFailure); rb_include_module(rb_eIconvOutOfRange, rb_eIconvFailure); - rb_inserter = rb_intern("<<"); rb_success = rb_intern("success"); rb_failed = rb_intern("failed"); - rb_mesg = rb_intern("mesg"); charset_map = rb_hash_new(); rb_gc_register_address(&charset_map); -- cgit v1.2.3