summaryrefslogtreecommitdiffhomepage
path: root/mrbgems/mruby-sprintf/src/sprintf.c
diff options
context:
space:
mode:
Diffstat (limited to 'mrbgems/mruby-sprintf/src/sprintf.c')
-rw-r--r--mrbgems/mruby-sprintf/src/sprintf.c138
1 files changed, 68 insertions, 70 deletions
diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c
index 31f22975d..33e0931f9 100644
--- a/mrbgems/mruby-sprintf/src/sprintf.c
+++ b/mrbgems/mruby-sprintf/src/sprintf.c
@@ -4,14 +4,14 @@
** See Copyright Notice in mruby.h
*/
-#include "mruby.h"
+#include <mruby.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
-#include "mruby/string.h"
-#include "mruby/hash.h"
-#include "mruby/numeric.h"
+#include <mruby/string.h>
+#include <mruby/hash.h>
+#include <mruby/numeric.h>
#include <math.h>
#include <ctype.h>
@@ -71,18 +71,14 @@ sign_bits(int base, const char *p)
static mrb_value
mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base)
{
- char buf[64], *b = buf + sizeof buf;
+ char buf[66], *b = buf + sizeof buf;
mrb_int num = mrb_fixnum(x);
- unsigned long val = (unsigned long)num;
+ uint64_t val = (uint64_t)num;
char d;
if (base != 2) {
mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %S", mrb_fixnum_value(base));
}
-
- if (val >= (1 << 10))
- val &= 0x3ff;
-
if (val == 0) {
return mrb_str_new_lit(mrb, "0");
}
@@ -178,17 +174,18 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base)
}
#define GETASTER(num) do { \
+ mrb_value tmp_v; \
t = p++; \
n = 0; \
GETNUM(n, val); \
if (*p == '$') { \
- tmp = GETPOSARG(n); \
+ tmp_v = GETPOSARG(n); \
} \
else { \
- tmp = GETARG(); \
+ tmp_v = GETARG(); \
p = t; \
} \
- num = mrb_fixnum(tmp); \
+ num = mrb_fixnum(tmp_v); \
} while (0)
static mrb_value
@@ -233,20 +230,20 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
* ------+--------------------------------------------------------------
* b | Convert argument as a binary number.
* | Negative numbers will be displayed as a two's complement
- * | prefixed with `..1'.
- * B | Equivalent to `b', but uses an uppercase 0B for prefix
+ * | prefixed with '..1'.
+ * B | Equivalent to 'b', but uses an uppercase 0B for prefix
* | in the alternative format by #.
* d | Convert argument as a decimal number.
- * i | Identical to `d'.
+ * i | Identical to 'd'.
* o | Convert argument as an octal number.
* | Negative numbers will be displayed as a two's complement
- * | prefixed with `..7'.
- * u | Identical to `d'.
+ * | prefixed with '..7'.
+ * u | Identical to 'd'.
* x | Convert argument as a hexadecimal number.
* | Negative numbers will be displayed as a two's complement
- * | prefixed with `..f' (representing an infinite string of
+ * | prefixed with '..f' (representing an infinite string of
* | leading 'ff's).
- * X | Equivalent to `x', but uses uppercase letters.
+ * X | Equivalent to 'x', but uses uppercase letters.
*
* Field | Float Format
* ------+--------------------------------------------------------------
@@ -254,7 +251,7 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
* | with one digit before the decimal point as [-]d.dddddde[+-]dd.
* | The precision specifies the number of digits after the decimal
* | point (defaulting to six).
- * E | Equivalent to `e', but uses an uppercase E to indicate
+ * E | Equivalent to 'e', but uses an uppercase E to indicate
* | the exponent.
* f | Convert floating point argument as [-]ddd.dddddd,
* | where the precision specifies the number of digits after
@@ -263,11 +260,11 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
* | if the exponent is less than -4 or greater than or
* | equal to the precision, or in dd.dddd form otherwise.
* | The precision specifies the number of significant digits.
- * G | Equivalent to `g', but use an uppercase `E' in exponent form.
+ * G | Equivalent to 'g', but use an uppercase 'E' in exponent form.
* a | Convert floating point argument as [-]0xh.hhhhp[+-]dd,
* | which is consisted from optional sign, "0x", fraction part
* | as hexadecimal, "p", and exponential part as decimal.
- * A | Equivalent to `a', but use uppercase `X' and `P'.
+ * A | Equivalent to 'a', but use uppercase 'X' and 'P'.
*
* Field | Other Format
* ------+--------------------------------------------------------------
@@ -286,7 +283,7 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
* ---------+---------------+-----------------------------------------
* space | bBdiouxX | Leave a space at the start of
* | aAeEfgG | non-negative numbers.
- * | (numeric fmt) | For `o', `x', `X', `b' and `B', use
+ * | (numeric fmt) | For 'o', 'x', 'X', 'b' and 'B', use
* | | a minus sign with absolute value for
* | | negative values.
* ---------+---------------+-----------------------------------------
@@ -296,27 +293,27 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
* | | sprintf string.
* ---------+---------------+-----------------------------------------
* # | bBoxX | Use an alternative format.
- * | aAeEfgG | For the conversions `o', increase the precision
- * | | until the first digit will be `0' if
+ * | aAeEfgG | For the conversions 'o', increase the precision
+ * | | until the first digit will be '0' if
* | | it is not formatted as complements.
- * | | For the conversions `x', `X', `b' and `B'
- * | | on non-zero, prefix the result with ``0x'',
- * | | ``0X'', ``0b'' and ``0B'', respectively.
- * | | For `a', `A', `e', `E', `f', `g', and 'G',
+ * | | For the conversions 'x', 'X', 'b' and 'B'
+ * | | on non-zero, prefix the result with "0x",
+ * | | "0X", "0b" and "0B", respectively.
+ * | | For 'a', 'A', 'e', 'E', 'f', 'g', and 'G',
* | | force a decimal point to be added,
* | | even if no digits follow.
- * | | For `g' and 'G', do not remove trailing zeros.
+ * | | For 'g' and 'G', do not remove trailing zeros.
* ---------+---------------+-----------------------------------------
* + | bBdiouxX | Add a leading plus sign to non-negative
* | aAeEfgG | numbers.
- * | (numeric fmt) | For `o', `x', `X', `b' and `B', use
+ * | (numeric fmt) | For 'o', 'x', 'X', 'b' and 'B', use
* | | a minus sign with absolute value for
* | | negative values.
* ---------+---------------+-----------------------------------------
* - | all | Left-justify the result of this conversion.
* ---------+---------------+-----------------------------------------
* 0 (zero) | bBdiouxX | Pad with zeros, not spaces.
- * | aAeEfgG | For `o', `x', `X', `b' and `B', radix-1
+ * | aAeEfgG | For 'o', 'x', 'X', 'b' and 'B', radix-1
* | (numeric fmt) | is used for negative numbers formatted as
* | | complements.
* ---------+---------------+-----------------------------------------
@@ -327,21 +324,21 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
*
* Examples of flags:
*
- * # `+' and space flag specifies the sign of non-negative numbers.
+ * # '+' and space flag specifies the sign of non-negative numbers.
* sprintf("%d", 123) #=> "123"
* sprintf("%+d", 123) #=> "+123"
* sprintf("% d", 123) #=> " 123"
*
- * # `#' flag for `o' increases number of digits to show `0'.
- * # `+' and space flag changes format of negative numbers.
+ * # '#' flag for 'o' increases number of digits to show '0'.
+ * # '+' and space flag changes format of negative numbers.
* sprintf("%o", 123) #=> "173"
* sprintf("%#o", 123) #=> "0173"
* sprintf("%+o", -123) #=> "-173"
* sprintf("%o", -123) #=> "..7605"
* sprintf("%#o", -123) #=> "..7605"
*
- * # `#' flag for `x' add a prefix `0x' for non-zero numbers.
- * # `+' and space flag disables complements for negative numbers.
+ * # '#' flag for 'x' add a prefix '0x' for non-zero numbers.
+ * # '+' and space flag disables complements for negative numbers.
* sprintf("%x", 123) #=> "7b"
* sprintf("%#x", 123) #=> "0x7b"
* sprintf("%+x", -123) #=> "-7b"
@@ -349,12 +346,12 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
* sprintf("%#x", -123) #=> "0x..f85"
* sprintf("%#x", 0) #=> "0"
*
- * # `#' for `X' uses the prefix `0X'.
+ * # '#' for 'X' uses the prefix '0X'.
* sprintf("%X", 123) #=> "7B"
* sprintf("%#X", 123) #=> "0X7B"
*
- * # `#' flag for `b' add a prefix `0b' for non-zero numbers.
- * # `+' and space flag disables complements for negative numbers.
+ * # '#' flag for 'b' add a prefix '0b' for non-zero numbers.
+ * # '+' and space flag disables complements for negative numbers.
* sprintf("%b", 123) #=> "1111011"
* sprintf("%#b", 123) #=> "0b1111011"
* sprintf("%+b", -123) #=> "-1111011"
@@ -362,19 +359,19 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
* sprintf("%#b", -123) #=> "0b..10000101"
* sprintf("%#b", 0) #=> "0"
*
- * # `#' for `B' uses the prefix `0B'.
+ * # '#' for 'B' uses the prefix '0B'.
* sprintf("%B", 123) #=> "1111011"
* sprintf("%#B", 123) #=> "0B1111011"
*
- * # `#' for `e' forces to show the decimal point.
+ * # '#' for 'e' forces to show the decimal point.
* sprintf("%.0e", 1) #=> "1e+00"
* sprintf("%#.0e", 1) #=> "1.e+00"
*
- * # `#' for `f' forces to show the decimal point.
+ * # '#' for 'f' forces to show the decimal point.
* sprintf("%.0f", 1234) #=> "1234"
* sprintf("%#.0f", 1234) #=> "1234."
*
- * # `#' for `g' forces to show the decimal point.
+ * # '#' for 'g' forces to show the decimal point.
* # It also disables stripping lowest zeros.
* sprintf("%g", 123.4) #=> "123.4"
* sprintf("%#g", 123.4) #=> "123.400"
@@ -408,7 +405,7 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
*
* Examples of precisions:
*
- * # precision for `d', 'o', 'x' and 'b' is
+ * # precision for 'd', 'o', 'x' and 'b' is
* # minimum number of digits <------>
* sprintf("%20.8d", 123) #=> " 00000123"
* sprintf("%20.8o", 123) #=> " 00000173"
@@ -419,8 +416,8 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
* sprintf("%20.8x", -123) #=> " ..ffff85"
* sprintf("%20.8b", -11) #=> " ..110101"
*
- * # "0x" and "0b" for `#x' and `#b' is not counted for
- * # precision but "0" for `#o' is counted. <------>
+ * # "0x" and "0b" for '#x' and '#b' is not counted for
+ * # precision but "0" for '#o' is counted. <------>
* sprintf("%#20.8d", 123) #=> " 00000123"
* sprintf("%#20.8o", 123) #=> " 00000173"
* sprintf("%#20.8x", 123) #=> " 0x0000007b"
@@ -430,22 +427,22 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)
* sprintf("%#20.8x", -123) #=> " 0x..ffff85"
* sprintf("%#20.8b", -11) #=> " 0b..110101"
*
- * # precision for `e' is number of
+ * # precision for 'e' is number of
* # digits after the decimal point <------>
* sprintf("%20.8e", 1234.56789) #=> " 1.23456789e+03"
*
- * # precision for `f' is number of
+ * # precision for 'f' is number of
* # digits after the decimal point <------>
* sprintf("%20.8f", 1234.56789) #=> " 1234.56789000"
*
- * # precision for `g' is number of
+ * # precision for 'g' is number of
* # significant digits <------->
* sprintf("%20.8g", 1234.56789) #=> " 1234.5679"
*
* # <------->
* sprintf("%20.8g", 123456789) #=> " 1.2345679e+08"
*
- * # precision for `s' is
+ * # precision for 's' is
* # maximum number of characters <------>
* sprintf("%20.8s", "string test") #=> " string t"
*
@@ -500,7 +497,6 @@ mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt)
int nextarg = 1;
int posarg = 0;
mrb_value nextvalue;
- mrb_value tmp;
mrb_value str;
mrb_value hash = mrb_undef_value();
@@ -539,7 +535,7 @@ mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt)
if (t >= end)
goto sprint_exit; /* end of fmt string */
- p = t + 1; /* skip `%' */
+ p = t + 1; /* skip '%' */
width = prec = -1;
nextvalue = mrb_undef_value();
@@ -763,11 +759,11 @@ retry:
case 'B':
case 'u': {
mrb_value val = GETARG();
- char fbuf[32], nbuf[64], *s;
+ char fbuf[32], nbuf[68], *s;
const char *prefix = NULL;
int sign = 0, dots = 0;
char sc = 0;
- mrb_int v = 0, org_v = 0;
+ mrb_int v = 0;
int base;
mrb_int len;
@@ -800,10 +796,6 @@ retry:
bin_retry:
switch (mrb_type(val)) {
case MRB_TT_FLOAT:
- if (FIXABLE(mrb_float(val))) {
- val = mrb_fixnum_value((mrb_int)mrb_float(val));
- goto bin_retry;
- }
val = mrb_flo_to_fixnum(mrb, val);
if (mrb_fixnum_p(val)) goto bin_retry;
break;
@@ -835,20 +827,17 @@ retry:
}
if (base == 2) {
- org_v = v;
- if ( v < 0 && !sign ) {
+ if (v < 0 && !sign) {
val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base);
dots = 1;
}
else {
val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base);
}
- v = mrb_fixnum(mrb_str_to_inum(mrb, val, 10, FALSE));
}
if (sign) {
char c = *p;
if (c == 'i') c = 'd'; /* %d and %i are identical */
- if (base == 2) c = 'd';
if (v < 0) {
v = -v;
sc = '-';
@@ -862,20 +851,29 @@ retry:
sc = ' ';
width--;
}
- snprintf(fbuf, sizeof(fbuf), "%%l%c", c);
- snprintf(nbuf, sizeof(nbuf), fbuf, v);
+ if (base == 2) {
+ snprintf(nbuf, sizeof(nbuf), "%s", RSTRING_PTR(val));
+ }
+ else {
+ snprintf(fbuf, sizeof(fbuf), "%%l%c", c);
+ snprintf(nbuf, sizeof(nbuf), fbuf, v);
+ }
s = nbuf;
}
else {
char c = *p;
if (c == 'X') c = 'x';
- if (base == 2) c = 'd';
s = nbuf;
if (v < 0) {
dots = 1;
}
- snprintf(fbuf, sizeof(fbuf), "%%l%c", c);
- snprintf(++s, sizeof(nbuf) - 1, fbuf, v);
+ if (base == 2) {
+ snprintf(++s, sizeof(nbuf) - 1, "%s", RSTRING_PTR(val));
+ }
+ else {
+ snprintf(fbuf, sizeof(fbuf), "%%l%c", c);
+ snprintf(++s, sizeof(nbuf) - 1, fbuf, v);
+ }
if (v < 0) {
char d;
@@ -965,7 +963,7 @@ retry:
CHECK(prec - len);
if (dots) PUSH("..", 2);
- if (v < 0 || (base == 2 && org_v < 0)) {
+ if (v < 0) {
char c = sign_bits(base, p);
while (len < prec--) {
buf[blen++] = c;