mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Supports some specifier flags with mrb_float_to_str()
Changed to understand `#`, `0`, `-`, ` ` and `+`. Based on src/stdio/vfprintf.c in git://git.musl-libc.org/musl
This commit is contained in:
@@ -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
|
||||
|
||||
+13
-3
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user