diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-07-02 08:03:48 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-07-02 08:03:48 +0000 |
commit | 3659c10b9d156cf8e12602996aa4719efc437ecd (patch) | |
tree | 0d568ce3dfcc19b1a4883bbb4ca72a21f8747982 /sprintf.c | |
parent | 54336ee19ac75b8b083fdb58c3d6ddd8b4c3dc60 (diff) | |
download | ruby-3659c10b9d156cf8e12602996aa4719efc437ecd.tar.gz |
sprintf.c: get_num
* sprintf.c (get_num): utility function for GETNUM().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46656 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'sprintf.c')
-rw-r--r-- | sprintf.c | 34 |
1 files changed, 21 insertions, 13 deletions
@@ -106,19 +106,8 @@ sign_bits(int base, const char *p) (posarg = -2, rb_hash_lookup2(get_hash(&hash, argc, argv), (id), Qundef))) #define GETNUM(n, val) \ - for (; p < end && rb_enc_isdigit(*p, enc); p++) { \ - int next_n = (n); \ - if (MUL_OVERFLOW_INT_P(10, next_n)) \ - rb_raise(rb_eArgError, #val " too big"); \ - next_n *= 10; \ - if (INT_MAX - (*p - '0') < next_n) \ - rb_raise(rb_eArgError, #val " too big"); \ - next_n += *p - '0'; \ - (n) = next_n; \ - } \ - if (p >= end) { \ - rb_raise(rb_eArgError, "malformed format string - %%*[0-9]"); \ - } + (!(p = get_num(p, end, enc, &(n))) ? \ + rb_raise(rb_eArgError, #val " too big") : (void)0) #define GETASTER(val) do { \ t = p++; \ @@ -134,6 +123,25 @@ sign_bits(int base, const char *p) (val) = NUM2INT(tmp); \ } while (0) +static const char * +get_num(const char *p, const char *end, rb_encoding *enc, int *valp) +{ + int next_n = *valp; + for (; p < end && rb_enc_isdigit(*p, enc); p++) { + if (MUL_OVERFLOW_INT_P(10, next_n)) + return NULL; + next_n *= 10; + if (INT_MAX - (*p - '0') < next_n) + return NULL; + next_n += *p - '0'; + } + if (p >= end) { + rb_raise(rb_eArgError, "malformed format string - %%*[0-9]"); + } + *valp = next_n; + return p; +} + static VALUE get_hash(volatile VALUE *hash, int argc, const VALUE *argv) { |