* 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>
* time.c (Init_Time): define initialize. [ruby-dev:21469]

View File

@ -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);