* 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
This commit is contained in:
nobu 2003-10-02 11:33:52 +00:00
parent 38d1922038
commit 4d5204c990
2 changed files with 58 additions and 43 deletions

View File

@ -1,3 +1,12 @@
Thu Oct 2 20:33:49 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* 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 <nobu@ruby-lang.org> Thu Oct 2 18:20:27 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
* time.c (Init_Time): define initialize. [ruby-dev:21469] * time.c (Init_Time): define initialize. [ruby-dev:21469]

View File

@ -50,17 +50,17 @@ struct iconv_env_t
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE ret; VALUE ret;
VALUE (*append)_((VALUE, VALUE));
}; };
static VALUE rb_eIconvFailure; static VALUE rb_eIconvFailure;
static VALUE rb_eIconvIllegalSeq; static VALUE rb_eIconvIllegalSeq;
static VALUE rb_eIconvInvalidChar; static VALUE rb_eIconvInvalidChar;
static VALUE rb_eIconvOutOfRange; static VALUE rb_eIconvOutOfRange;
static ID rb_inserter;
static ID rb_success, rb_failed, rb_mesg; static ID rb_success, rb_failed;
static VALUE iconv_fail _((VALUE error, VALUE success, VALUE failed, struct iconv_env_t* env)); 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 success, VALUE failed, struct iconv_env_t* env)); static VALUE iconv_failure_initialize _((VALUE error, VALUE mesg, VALUE success, VALUE failed));
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));
@ -223,16 +223,16 @@ iconv_try
/* try the left in next loop */ /* try the left in next loop */
break; break;
case EILSEQ: case EILSEQ:
return rb_class_new_instance(0, 0, rb_eIconvIllegalSeq); return rb_eIconvIllegalSeq;
case EINVAL: case EINVAL:
return rb_class_new_instance(0, 0, rb_eIconvInvalidChar); return rb_eIconvInvalidChar;
default: default:
rb_sys_fail("iconv"); rb_sys_fail("iconv");
} }
} }
else if (*inlen > 0) { else if (*inlen > 0) {
/* something goes wrong */ /* something goes wrong */
return rb_class_new_instance(0, 0, rb_eIconvIllegalSeq); return rb_eIconvIllegalSeq;
} }
else if (ret) { else if (ret) {
return Qnil; /* conversion */ return Qnil; /* conversion */
@ -242,35 +242,15 @@ iconv_try
#define FAILED_MAXLEN 16 #define FAILED_MAXLEN 16
static VALUE static VALUE iconv_failure_initialize
iconv_failure_initialize
#ifdef HAVE_PROTOTYPES #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 */ #else /* HAVE_PROTOTYPES */
(error, success, failed, env) (error, mesg, success, failed)
VALUE error; VALUE error, mesg, success, failed;
VALUE success;
VALUE failed;
struct iconv_env_t *env;
#endif /* HAVE_PROTOTYPES */ #endif /* HAVE_PROTOTYPES */
{ {
if (NIL_P(rb_attr_get(error, rb_mesg))) { rb_call_super(1, &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_ivar_set(error, rb_success, success); rb_ivar_set(error, rb_success, success);
rb_ivar_set(error, rb_failed, failed); rb_ivar_set(error, rb_failed, failed);
return error; return error;
@ -279,14 +259,36 @@ iconv_failure_initialize
static VALUE static VALUE
iconv_fail iconv_fail
#ifdef HAVE_PROTOTYPES #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 */ #else /* HAVE_PROTOTYPES */
(error, success, failed, env) (error, success, failed, env, mesg)
VALUE error, success, failed; VALUE error, success, failed;
struct iconv_env_t *env; struct iconv_env_t *env;
const char *mesg;
#endif /* HAVE_PROTOTYPES */ #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); if (!rb_block_given_p()) rb_exc_raise(error);
ruby_errinfo = error; ruby_errinfo = error;
return rb_yield(failed); return rb_yield(failed);
@ -352,7 +354,7 @@ iconv_convert
error = iconv_try(cd, &inptr, &inlen, &outptr, &outlen); error = iconv_try(cd, &inptr, &inlen, &outptr, &outlen);
if (RTEST(error)) { if (RTEST(error)) {
unsigned int i; unsigned int i;
rescue = iconv_fail(error, Qnil, Qnil, env); rescue = iconv_fail(error, Qnil, Qnil, env, 0);
if (TYPE(rescue) == T_ARRAY) { if (TYPE(rescue) == T_ARRAY) {
str = RARRAY(rescue)->len > 0 ? RARRAY(rescue)->ptr[0] : Qnil; str = RARRAY(rescue)->len > 0 ? RARRAY(rescue)->ptr[0] : Qnil;
} }
@ -388,10 +390,12 @@ iconv_convert
inlen = length; inlen = length;
do { do {
char errmsg[50];
const char *tmpstart = inptr; const char *tmpstart = inptr;
outptr = buffer; outptr = buffer;
outlen = sizeof(buffer); outlen = sizeof(buffer);
errmsg[0] = 0;
error = iconv_try(cd, &inptr, &inlen, &outptr, &outlen); error = iconv_try(cd, &inptr, &inlen, &outptr, &outlen);
if (0 <= outlen && outlen <= sizeof(buffer)) { if (0 <= outlen && outlen <= sizeof(buffer)) {
@ -422,9 +426,8 @@ iconv_convert
} }
else { else {
/* Some iconv() have a bug, return *outlen out of range */ /* Some iconv() have a bug, return *outlen out of range */
char errmsg[50];
sprintf(errmsg, "bug?(output length = %d)", sizeof(buffer) - outlen); sprintf(errmsg, "bug?(output length = %d)", sizeof(buffer) - outlen);
error = rb_exc_new2(rb_eIconvOutOfRange, errmsg); error = rb_eIconvOutOfRange;
} }
if (RTEST(error)) { if (RTEST(error)) {
@ -432,8 +435,10 @@ iconv_convert
if (!ret) if (!ret)
ret = rb_str_derive(str, instart, inptr - instart); 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); 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 (TYPE(rescue) == T_ARRAY) {
if ((len = RARRAY(rescue)->len) > 0) if ((len = RARRAY(rescue)->len) > 0)
rb_str_concat(ret, RARRAY(rescue)->ptr[0]); rb_str_concat(ret, RARRAY(rescue)->ptr[0]);
@ -568,13 +573,13 @@ iconv_s_convert
for (; env->argc > 0; --env->argc, ++env->argv) { for (; env->argc > 0; --env->argc, ++env->argv) {
VALUE s = iconv_convert(env->cd, last = *(env->argv), 0, -1, env); 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)) { if (!NIL_P(last)) {
VALUE s = iconv_convert(env->cd, Qnil, 0, 0, env); VALUE s = iconv_convert(env->cd, Qnil, 0, 0, env);
if (RSTRING(s)->len) if (RSTRING(s)->len)
rb_funcall3(env->ret, rb_inserter, 1, &s); env->append(env->ret, s);
} }
return env->ret; return env->ret;
@ -598,6 +603,7 @@ iconv_s_iconv
arg.argc = argc -= 2; arg.argc = argc -= 2;
arg.argv = argv + 2; arg.argv = argv + 2;
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]);
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));
@ -616,6 +622,7 @@ iconv_s_conv
arg.argc = 1; arg.argc = 1;
arg.argv = &str; arg.argv = &str;
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);
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));
@ -840,6 +847,7 @@ Init_iconv _((void))
rb_define_method(rb_cIconv, "iconv", iconv_iconv, -1); rb_define_method(rb_cIconv, "iconv", iconv_iconv, -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, "success", iconv_failure_success, 0); 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, "failed", iconv_failure_failed, 0);
rb_define_method(rb_eIconvFailure, "inspect", iconv_failure_inspect, 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_eIconvInvalidChar, rb_eIconvFailure);
rb_include_module(rb_eIconvOutOfRange, rb_eIconvFailure); rb_include_module(rb_eIconvOutOfRange, rb_eIconvFailure);
rb_inserter = rb_intern("<<");
rb_success = rb_intern("success"); rb_success = rb_intern("success");
rb_failed = rb_intern("failed"); rb_failed = rb_intern("failed");
rb_mesg = rb_intern("mesg");
charset_map = rb_hash_new(); charset_map = rb_hash_new();
rb_gc_register_address(&charset_map); rb_gc_register_address(&charset_map);