зеркало из https://github.com/github/ruby.git
* ext/iconv/iconv.c (iconv_fail): now yield erred substring, and
set error object to $!. * ext/iconv/iconv.c (iconv_convert): error handler block should return appended part and the rest. if rest is nil, the conversion stops. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4650 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
83740fa4bd
Коммит
a70a430f83
|
@ -1,3 +1,12 @@
|
||||||
|
Thu Oct 2 14:19:15 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* ext/iconv/iconv.c (iconv_fail): now yield erred substring, and
|
||||||
|
set error object to $!.
|
||||||
|
|
||||||
|
* ext/iconv/iconv.c (iconv_convert): error handler block should
|
||||||
|
return appended part and the rest. if rest is nil, the
|
||||||
|
conversion stops.
|
||||||
|
|
||||||
Thu Oct 2 12:00:18 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Thu Oct 2 12:00:18 2003 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* variable.c (rb_const_defined_0): look up constants in Object as
|
* variable.c (rb_const_defined_0): look up constants in Object as
|
||||||
|
|
|
@ -214,7 +214,8 @@ iconv_try
|
||||||
size_t *outlen;
|
size_t *outlen;
|
||||||
#endif /* HAVE_PROTOTYPES */
|
#endif /* HAVE_PROTOTYPES */
|
||||||
{
|
{
|
||||||
if (iconv(cd, ICONV_INPTR_CAST inptr, inlen, outptr, outlen) == (size_t)-1) {
|
size_t ret = iconv(cd, ICONV_INPTR_CAST inptr, inlen, outptr, outlen);
|
||||||
|
if (ret == (size_t)-1) {
|
||||||
if (!*inlen)
|
if (!*inlen)
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
switch (errno) {
|
switch (errno) {
|
||||||
|
@ -233,6 +234,9 @@ iconv_try
|
||||||
/* something goes wrong */
|
/* something goes wrong */
|
||||||
return rb_class_new_instance(0, 0, rb_eIconvIllegalSeq);
|
return rb_class_new_instance(0, 0, rb_eIconvIllegalSeq);
|
||||||
}
|
}
|
||||||
|
else if (ret) {
|
||||||
|
return Qnil; /* conversion */
|
||||||
|
}
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +288,8 @@ iconv_fail
|
||||||
{
|
{
|
||||||
error = iconv_failure_initialize(error, success, failed, env);
|
error = iconv_failure_initialize(error, success, failed, env);
|
||||||
if (!rb_block_given_p()) rb_exc_raise(error);
|
if (!rb_block_given_p()) rb_exc_raise(error);
|
||||||
return rb_yield(error);
|
ruby_errinfo = error;
|
||||||
|
return rb_yield(failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -327,6 +332,7 @@ iconv_convert
|
||||||
{
|
{
|
||||||
VALUE ret = Qfalse;
|
VALUE ret = Qfalse;
|
||||||
VALUE error = Qfalse;
|
VALUE error = Qfalse;
|
||||||
|
VALUE rescue;
|
||||||
const char *inptr, *instart;
|
const char *inptr, *instart;
|
||||||
size_t inlen;
|
size_t inlen;
|
||||||
/* I believe ONE CHARACTER never exceed this. */
|
/* I believe ONE CHARACTER never exceed this. */
|
||||||
|
@ -344,9 +350,12 @@ iconv_convert
|
||||||
outptr = buffer;
|
outptr = buffer;
|
||||||
outlen = sizeof(buffer);
|
outlen = sizeof(buffer);
|
||||||
error = iconv_try(cd, &inptr, &inlen, &outptr, &outlen);
|
error = iconv_try(cd, &inptr, &inlen, &outptr, &outlen);
|
||||||
if (error) {
|
if (RTEST(error)) {
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
str = iconv_fail(error, Qnil, Qnil, env);
|
rescue = iconv_fail(error, Qnil, Qnil, env);
|
||||||
|
if (TYPE(rescue) == T_ARRAY) {
|
||||||
|
str = RARRAY(rescue)->len > 0 ? RARRAY(rescue)->ptr[0] : Qnil;
|
||||||
|
}
|
||||||
if (FIXNUM_P(str) && (i = FIX2INT(str)) <= 0xff) {
|
if (FIXNUM_P(str) && (i = FIX2INT(str)) <= 0xff) {
|
||||||
char c = i;
|
char c = i;
|
||||||
str = rb_str_new(&c, 1);
|
str = rb_str_new(&c, 1);
|
||||||
|
@ -387,7 +396,8 @@ iconv_convert
|
||||||
|
|
||||||
if (0 <= outlen && outlen <= sizeof(buffer)) {
|
if (0 <= outlen && outlen <= sizeof(buffer)) {
|
||||||
outlen = sizeof(buffer) - outlen;
|
outlen = sizeof(buffer) - outlen;
|
||||||
if (outlen > inptr - tmpstart || /* input can't contain output */
|
if (NIL_P(error) || /* something converted */
|
||||||
|
outlen > inptr - tmpstart || /* input can't contain output */
|
||||||
(outlen < inptr - tmpstart && inlen > 0) || /* something skipped */
|
(outlen < inptr - tmpstart && inlen > 0) || /* something skipped */
|
||||||
memcmp(buffer, tmpstart, outlen)) /* something differs */
|
memcmp(buffer, tmpstart, outlen)) /* something differs */
|
||||||
{
|
{
|
||||||
|
@ -417,11 +427,27 @@ iconv_convert
|
||||||
error = rb_exc_new2(rb_eIconvOutOfRange, errmsg);
|
error = rb_exc_new2(rb_eIconvOutOfRange, errmsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
if (RTEST(error)) {
|
||||||
|
long len = 0;
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
ret = rb_str_derive(str, instart, inptr - instart);
|
ret = rb_str_derive(str, instart, inptr - instart);
|
||||||
str = rb_str_derive(str, inptr, inlen);
|
str = rb_str_derive(str, inptr, inlen);
|
||||||
rb_str_concat(str, iconv_fail(error, ret, str, env));
|
rescue = iconv_fail(error, ret, str, env);
|
||||||
|
if (TYPE(rescue) == T_ARRAY) {
|
||||||
|
if ((len = RARRAY(rescue)->len) > 0)
|
||||||
|
rb_str_concat(ret, RARRAY(rescue)->ptr[0]);
|
||||||
|
if (len > 1 && !NIL_P(str = RARRAY(rescue)->ptr[1])) {
|
||||||
|
StringValue(str);
|
||||||
|
inlen = length = RSTRING(str)->len;
|
||||||
|
instart = inptr = RSTRING(str)->ptr;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!NIL_P(rescue)) {
|
||||||
|
rb_str_concat(ret, rescue);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} while (inlen > 0);
|
} while (inlen > 0);
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче