Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/src/sprintf.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/mrbgems/mruby-sprintf/src/sprintf.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/src/sprintf.c	(revision 331)
@@ -5,12 +5,12 @@
 */
 
-#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>
@@ -18,5 +18,5 @@
 #define BIT_DIGITS(N)   (((N)*146)/485 + 1)  /* log2(10) =~ 146/485 */
 #define BITSPERDIG MRB_INT_BIT
-#define EXTENDSIGN(n, l) (((~0 << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0 << (n)))
+#define EXTENDSIGN(n, l) (((~0U << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0U << (n)))
 
 mrb_value mrb_str_format(mrb_state *, int, const mrb_value *, mrb_value);
@@ -72,5 +72,5 @@
 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);
   uint64_t val = (uint64_t)num;
@@ -80,8 +80,4 @@
     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");
@@ -121,6 +117,7 @@
 #define CHECK(l) do {\
 /*  int cr = ENC_CODERANGE(result);*/\
-  while (blen + (l) >= bsiz) {\
+  while ((l) >= bsiz - blen) {\
     bsiz*=2;\
+    if (bsiz < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \
   }\
   mrb_str_resize(mrb, result, bsiz);\
@@ -141,27 +138,61 @@
 } while (0)
 
-#define GETARG() (!mrb_undef_p(nextvalue) ? nextvalue : \
-  posarg == -1 ? \
-  (mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with numbered", mrb_fixnum_value(nextarg)), mrb_undef_value()) : \
-  posarg == -2 ? \
-  (mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with named", mrb_fixnum_value(nextarg)), mrb_undef_value()) : \
+static void
+check_next_arg(mrb_state *mrb, int posarg, int nextarg)
+{
+  switch (posarg) {
+  case -1:
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with numbered", mrb_fixnum_value(nextarg));
+    break;
+  case -2:
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with named", mrb_fixnum_value(nextarg));
+    break;
+  default:
+    break;
+  }
+}
+
+static void
+check_pos_arg(mrb_state *mrb, int posarg, int n)
+{
+  if (posarg > 0) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after unnumbered(%S)",
+               mrb_fixnum_value(n), mrb_fixnum_value(posarg));
+  }
+  if (posarg == -2) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after named", mrb_fixnum_value(n));
+  }
+  if (n < 1) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %S$", mrb_fixnum_value(n));
+  }
+}
+
+static void
+check_name_arg(mrb_state *mrb, int posarg, const char *name, int len)
+{
+  if (posarg > 0) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after unnumbered(%S)",
+               mrb_str_new(mrb, (name), (len)), mrb_fixnum_value(posarg));
+  }
+  if (posarg == -1) {
+    mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after numbered", mrb_str_new(mrb, (name), (len)));
+  }
+}
+
+#define GETNEXTARG() (\
+  check_next_arg(mrb, posarg, nextarg),\
   (posarg = nextarg++, GETNTHARG(posarg)))
 
-#define GETPOSARG(n) (posarg > 0 ? \
-  (mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after unnumbered(%S)", mrb_fixnum_value(n), mrb_fixnum_value(posarg)), mrb_undef_value()) : \
-  posarg == -2 ? \
-  (mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after named", mrb_fixnum_value(n)), mrb_undef_value()) : \
-  ((n < 1) ? \
-  (mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %S$", mrb_fixnum_value(n)), mrb_undef_value()) : \
-  (posarg = -1, GETNTHARG(n))))
+#define GETARG() (!mrb_undef_p(nextvalue) ? nextvalue : GETNEXTARG())
+
+#define GETPOSARG(n) (\
+  check_pos_arg(mrb, posarg, n),\
+  (posarg = -1, GETNTHARG(n)))
 
 #define GETNTHARG(nth) \
   ((nth >= argc) ? (mrb_raise(mrb, E_ARGUMENT_ERROR, "too few arguments"), mrb_undef_value()) : argv[nth])
 
-#define GETNAMEARG(id, name, len) ( \
-  posarg > 0 ? \
-  (mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after unnumbered(%S)", mrb_str_new(mrb, (name), (len)), mrb_fixnum_value(posarg)), mrb_undef_value()) : \
-  posarg == -1 ? \
-  (mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after numbered", mrb_str_new(mrb, (name), (len))), mrb_undef_value()) :    \
+#define GETNAMEARG(id, name, len) (\
+  check_name_arg(mrb, posarg, name, len),\
   (posarg = -2, mrb_hash_fetch(mrb, get_hash(mrb, &hash, argc, argv), id, mrb_undef_value())))
 
@@ -187,8 +218,8 @@
   } \
   else { \
-    tmp_v = GETARG(); \
+    tmp_v = GETNEXTARG(); \
     p = t; \
   } \
-  num = mrb_fixnum(tmp_v); \
+  num = mrb_int(mrb, tmp_v); \
 } while (0)
 
@@ -536,4 +567,5 @@
 
     for (t = p; t < end && *t != '%'; t++) ;
+    if (t + 1 == end) ++t;
     PUSH(p, t - p);
     if (t >= end)
@@ -680,22 +712,17 @@
           mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character");
         }
+        mrb_check_type(mrb, tmp, MRB_TT_STRING);
         c = RSTRING_PTR(tmp);
         n = RSTRING_LEN(tmp);
         if (!(flags & FWIDTH)) {
-          CHECK(n);
-          memcpy(buf+blen, c, n);
-          blen += n;
+          PUSH(c, n);
         }
         else if ((flags & FMINUS)) {
-          CHECK(n);
-          memcpy(buf+blen, c, n);
-          blen += n;
-          FILL(' ', width-1);
+          PUSH(c, n);
+          if (width>0) FILL(' ', width-1);
         }
         else {
-          FILL(' ', width-1);
-          CHECK(n);
-          memcpy(buf+blen, c, n);
-          blen += n;
+          if (width>0) FILL(' ', width-1);
+          PUSH(c, n);
         }
       }
@@ -717,5 +744,6 @@
           RSTRING(result)->flags &= ~MRB_STR_EMBED_LEN_MASK;
           RSTRING(result)->flags |= tmp_n << MRB_STR_EMBED_LEN_SHIFT;
-        } else {
+        }
+        else {
           RSTRING(result)->as.heap.len = blen;
         }
@@ -734,17 +762,9 @@
             width -= (int)slen;
             if (!(flags&FMINUS)) {
-              CHECK(width);
-              while (width--) {
-                buf[blen++] = ' ';
-              }
+              FILL(' ', width);
             }
-            CHECK(len);
-            memcpy(&buf[blen], RSTRING_PTR(str), len);
-            blen += len;
+            PUSH(RSTRING_PTR(str), len);
             if (flags&FMINUS) {
-              CHECK(width);
-              while (width--) {
-                buf[blen++] = ' ';
-              }
+              FILL(' ', width);
             }
             break;
@@ -764,9 +784,9 @@
       case 'u': {
         mrb_value val = GETARG();
-        char fbuf[32], nbuf[64], *s;
+        char 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;
@@ -775,13 +795,5 @@
           case 'd':
           case 'i':
-          case 'u':
             sign = 1; break;
-          case 'o':
-          case 'x':
-          case 'X':
-          case 'b':
-          case 'B':
-            if (flags&(FPLUS|FSPACE)) sign = 1;
-            break;
           default:
             break;
@@ -801,8 +813,4 @@
         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;
@@ -836,5 +844,4 @@
 
         if (base == 2) {
-          org_v = v;
           if (v < 0 && !sign) {
             val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base);
@@ -844,37 +851,51 @@
             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 = '-';
-            width--;
-          }
-          else if (flags & FPLUS) {
-            sc = '+';
-            width--;
-          }
-          else if (flags & FSPACE) {
-            sc = ' ';
-            width--;
-          }
-          snprintf(fbuf, sizeof(fbuf), "%%l%c", c);
-          snprintf(nbuf, sizeof(nbuf), fbuf, v);
+          if (v > 0) {
+            if (flags & FPLUS) {
+              sc = '+';
+              width--;
+            }
+            else if (flags & FSPACE) {
+              sc = ' ';
+              width--;
+            }
+          }
+          switch (base) {
+          case 2:
+            strncpy(nbuf, RSTRING_PTR(val), sizeof(nbuf));
+            break;
+          case 8:
+            snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIo, v);
+            break;
+          case 10:
+            snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v);
+            break;
+          case 16:
+            snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIx, v);
+            break;
+          }
           s = nbuf;
         }
         else {
-          char c = *p;
-          if (c == 'X') c = 'x';
-          if (base == 2) c = 'd';
           s = nbuf;
-          if (v < 0) {
+          if (base != 10 && v < 0) {
             dots = 1;
           }
-          snprintf(fbuf, sizeof(fbuf), "%%l%c", c);
-          snprintf(++s, sizeof(nbuf) - 1, fbuf, v);
+          switch (base) {
+          case 2:
+            strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-1);
+            break;
+          case 8:
+            snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIo, v);
+            break;
+          case 10:
+            snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRId, v);
+            break;
+          case 16:
+            snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIx, v);
+            break;
+          }
           if (v < 0) {
             char d;
@@ -950,9 +971,6 @@
         }
 
-        if (!(flags&FMINUS)) {
-          CHECK(width);
-          while (width-- > 0) {
-            buf[blen++] = ' ';
-          }
+        if (!(flags&FMINUS) && width > 0) {
+          FILL(' ', width);
         }
 
@@ -963,24 +981,20 @@
           PUSH(prefix, plen);
         }
-        CHECK(prec - len);
         if (dots) PUSH("..", 2);
 
-        if (v < 0 || (base == 2 && org_v < 0)) {
-          char c = sign_bits(base, p);
-          while (len < prec--) {
-            buf[blen++] = c;
-          }
-        }
-        else if ((flags & (FMINUS|FPREC)) != FMINUS) {
-          char c = '0';
-          while (len < prec--) {
-            buf[blen++] = c;
-          }
-        }
-
+        if (prec > len) {
+          CHECK(prec - len);
+          if (v < 0) {
+            char c = sign_bits(base, p);
+            FILL(c, prec - len);
+          }
+          else if ((flags & (FMINUS|FPREC)) != FMINUS) {
+            char c = '0';
+            FILL(c, prec - len);
+          }
+        }
         PUSH(s, len);
-        CHECK(width);
-        while (width-- > 0) {
-          buf[blen++] = ' ';
+        if (width > 0) {
+          FILL(' ', width);
         }
       }
@@ -1003,4 +1017,5 @@
           const char *expr;
           const int elen = 3;
+          char sign = '\0';
 
           if (isnan(fval)) {
@@ -1011,30 +1026,27 @@
           }
           need = elen;
-          if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS))
-            need++;
+          if (!isnan(fval) && fval < 0.0)
+            sign = '-';
+          else if (flags & (FPLUS|FSPACE))
+            sign = (flags & FPLUS) ? '+' : ' ';
+          if (sign)
+	    ++need;
           if ((flags & FWIDTH) && need < width)
             need = width;
 
-          CHECK(need + 1);
-          snprintf(&buf[blen], need + 1, "%*s", need, "");
+          if (need < 0) {
+            mrb_raise(mrb, E_ARGUMENT_ERROR, "width too big");
+          }
+          FILL(' ', need);
           if (flags & FMINUS) {
-            if (!isnan(fval) && fval < 0.0)
-              buf[blen++] = '-';
-            else if (flags & FPLUS)
-              buf[blen++] = '+';
-            else if (flags & FSPACE)
-              blen++;
-            memcpy(&buf[blen], expr, elen);
+            if (sign)
+              buf[blen - need--] = sign;
+            memcpy(&buf[blen - need], expr, elen);
           }
           else {
-            if (!isnan(fval) && fval < 0.0)
-              buf[blen + need - elen - 1] = '-';
-            else if (flags & FPLUS)
-              buf[blen + need - elen - 1] = '+';
-            else if ((flags & FSPACE) && need > width)
-              blen++;
-            memcpy(&buf[blen + need - elen], expr, elen);
-          }
-          blen += strlen(&buf[blen]);
+            if (sign)
+              buf[blen - elen - 1] = sign;
+            memcpy(&buf[blen - elen], expr, elen);
+          }
           break;
         }
@@ -1052,7 +1064,14 @@
           need = width;
         need += 20;
+        if (need <= 0) {
+          mrb_raise(mrb, E_ARGUMENT_ERROR,
+                    (width > prec ? "width too big" : "prec too big"));
+        }
 
         CHECK(need);
         n = snprintf(&buf[blen], need, fbuf, fval);
+        if (n < 0) {
+          mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error");
+        }
         blen += n;
       }
