diff options
| -rw-r--r-- | mrbgems/mruby-sprintf/test/sprintf.rb | 5 | ||||
| -rw-r--r-- | src/fmt_fp.c | 16 |
2 files changed, 18 insertions, 3 deletions
diff --git a/mrbgems/mruby-sprintf/test/sprintf.rb b/mrbgems/mruby-sprintf/test/sprintf.rb index 137812ae7..24d01c9be 100644 --- a/mrbgems/mruby-sprintf/test/sprintf.rb +++ b/mrbgems/mruby-sprintf/test/sprintf.rb @@ -8,6 +8,11 @@ assert('String#%') do assert_equal 15, ("%b" % (1<<14)).size skip unless Object.const_defined?(:Float) assert_equal "1.0", "%3.1f" % 1.01 + assert_equal " 123456789.12", "% 4.2f" % 123456789.123456789 + assert_equal "123456789.12", "%-4.2f" % 123456789.123456789 + assert_equal "+123456789.12", "%+4.2f" % 123456789.123456789 + assert_equal "123456789.12", "%04.2f" % 123456789.123456789 + assert_equal "00000000123456789.12", "%020.2f" % 123456789.123456789 end assert('String#% with inf') do diff --git a/src/fmt_fp.c b/src/fmt_fp.c index 8b1b01559..99ba1e5ff 100644 --- a/src/fmt_fp.c +++ b/src/fmt_fp.c @@ -54,6 +54,8 @@ struct fmt_args { #define PAD_POS (1U<<(' '-' ')) #define MARK_POS (1U<<('+'-' ')) +#define FLAGMASK (ALT_FORM|ZERO_PAD|LEFT_ADJ|PAD_POS|MARK_POS) + static void out(struct fmt_args *f, const char *s, size_t l) { @@ -62,7 +64,7 @@ out(struct fmt_args *f, const char *s, size_t l) #define PAD_SIZE 256 static void -pad(struct fmt_args *f, char c, ptrdiff_t w, ptrdiff_t l, uint8_t fl) +pad(struct fmt_args *f, char c, ptrdiff_t w, ptrdiff_t l, uint32_t fl) { char pad[PAD_SIZE]; if (fl & (LEFT_ADJ | ZERO_PAD) || l >= w) return; @@ -92,7 +94,7 @@ typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double) #endif static int -fmt_fp(struct fmt_args *f, long double y, ptrdiff_t w, ptrdiff_t p, uint8_t fl, int t) +fmt_fp(struct fmt_args *f, long double y, ptrdiff_t w, ptrdiff_t p, uint32_t fl, int t) { uint32_t big[(LDBL_MANT_DIG+28)/29 + 1 // mantissa expansion + (LDBL_MAX_EXP+LDBL_MANT_DIG+28+8)/9]; // exponent expansion @@ -334,12 +336,20 @@ static int fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo) { ptrdiff_t w, p; + uint32_t fl; if (*fmt != '%') { return -1; } ++fmt; + /* Read modifier flags */ + for (fl=0; (unsigned)*fmt-' '<32 && (FLAGMASK&(1U<<(*fmt-' '))); fmt++) + fl |= 1U<<(*fmt-' '); + + /* - and 0 flags are mutually exclusive */ + if (fl & LEFT_ADJ) fl &= ~ZERO_PAD; + for (w = 0; ISDIGIT(*fmt); ++fmt) { w = 10 * w + (*fmt - '0'); } @@ -357,7 +367,7 @@ fmt_core(struct fmt_args *f, const char *fmt, mrb_float flo) switch (*fmt) { case 'e': case 'f': case 'g': case 'a': case 'E': case 'F': case 'G': case 'A': - return fmt_fp(f, flo, w, p, 0, *fmt); + return fmt_fp(f, flo, w, p, fl, *fmt); default: return -1; } |
