- Timestamp:
- Jul 9, 2020, 8:51:43 AM (4 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-2.1.1
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-sprintf/src/sprintf.c
r331 r439 7 7 #include <mruby.h> 8 8 9 #ifdef MRB_DISABLE_STDIO 10 # error sprintf conflicts 'MRB_DISABLE_STDIO' configuration in your 'build_config.rb' 11 #endif 12 9 13 #include <limits.h> 10 #include <stdio.h>11 14 #include <string.h> 12 15 #include <mruby/string.h> 13 16 #include <mruby/hash.h> 14 17 #include <mruby/numeric.h> 18 #ifndef MRB_WITHOUT_FLOAT 15 19 #include <math.h> 20 #endif 16 21 #include <ctype.h> 17 22 … … 20 25 #define EXTENDSIGN(n, l) (((~0U << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0U << (n))) 21 26 22 mrb_value mrb_str_format(mrb_state *, int, const mrb_value *, mrb_value); 27 mrb_value mrb_str_format(mrb_state *, mrb_int, const mrb_value *, mrb_value); 28 #ifndef MRB_WITHOUT_FLOAT 23 29 static void fmt_setup(char*,size_t,int,int,mrb_int,mrb_int); 30 #endif 24 31 25 32 static char* … … 78 85 79 86 if (base != 2) { 80 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix % S", mrb_fixnum_value(base));87 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %d", base); 81 88 } 82 89 if (val == 0) { … … 116 123 117 124 #define CHECK(l) do {\ 118 /* int cr = ENC_CODERANGE(result);*/\119 125 while ((l) >= bsiz - blen) {\ 126 if (bsiz > MRB_INT_MAX/2) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \ 120 127 bsiz*=2;\ 121 if (bsiz < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \122 128 }\ 123 129 mrb_str_resize(mrb, result, bsiz);\ 124 /* ENC_CODERANGE_SET(result, cr);*/\125 130 buf = RSTRING_PTR(result);\ 126 131 } while (0) … … 129 134 CHECK(l);\ 130 135 memcpy(&buf[blen], s, l);\ 131 blen += ( l);\136 blen += (mrb_int)(l);\ 132 137 } while (0) 133 138 … … 143 148 switch (posarg) { 144 149 case -1: 145 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(% S) mixed with numbered", mrb_fixnum_value(nextarg));150 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with numbered", nextarg); 146 151 break; 147 152 case -2: 148 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(% S) mixed with named", mrb_fixnum_value(nextarg));153 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with named", nextarg); 149 154 break; 150 155 default: … … 154 159 155 160 static void 156 check_pos_arg(mrb_state *mrb, int posarg, int n)161 check_pos_arg(mrb_state *mrb, int posarg, mrb_int n) 157 162 { 158 163 if (posarg > 0) { 159 mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(% S) after unnumbered(%S)",160 mrb_fixnum_value(n), mrb_fixnum_value(posarg));164 mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%i) after unnumbered(%d)", 165 n, posarg); 161 166 } 162 167 if (posarg == -2) { 163 mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(% S) after named", mrb_fixnum_value(n));168 mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%i) after named", n); 164 169 } 165 170 if (n < 1) { 166 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - % S$", mrb_fixnum_value(n));171 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %i$", n); 167 172 } 168 173 } 169 174 170 175 static void 171 check_name_arg(mrb_state *mrb, int posarg, const char *name, int len)176 check_name_arg(mrb_state *mrb, int posarg, const char *name, size_t len) 172 177 { 173 178 if (posarg > 0) { 174 mrb_raisef(mrb, E_ARGUMENT_ERROR, "named% S after unnumbered(%S)",175 mrb_str_new(mrb, (name), (len)), mrb_fixnum_value(posarg));179 mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%l after unnumbered(%d)", 180 name, len, posarg); 176 181 } 177 182 if (posarg == -1) { 178 mrb_raisef(mrb, E_ARGUMENT_ERROR, "named% S after numbered", mrb_str_new(mrb, (name), (len)));183 mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%l after numbered", name, len); 179 184 } 180 185 } … … 199 204 #define GETNUM(n, val) \ 200 205 for (; p < end && ISDIGIT(*p); p++) {\ 201 int next_n = 10 * n + (*p - '0'); \ 202 if (next_n / 10 != n) {\ 206 if (n > (MRB_INT_MAX - (*p - '0'))/10) {\ 203 207 mrb_raise(mrb, E_ARGUMENT_ERROR, #val " too big"); \ 204 208 } \ 205 n = next_n; \209 n = 10 * n + (*p - '0'); \ 206 210 } \ 207 211 if (p >= end) { \ … … 225 229 226 230 static mrb_value 227 get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv)231 get_hash(mrb_state *mrb, mrb_value *hash, mrb_int argc, const mrb_value *argv) 228 232 { 229 233 mrb_value tmp; … … 233 237 mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required"); 234 238 } 235 tmp = mrb_check_ convert_type(mrb, argv[1], MRB_TT_HASH, "Hash", "to_hash");239 tmp = mrb_check_hash_type(mrb, argv[1]); 236 240 if (mrb_nil_p(tmp)) { 237 241 mrb_raise(mrb, E_ARGUMENT_ERROR, "one hash required"); … … 519 523 520 524 mrb_value 521 mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt)525 mrb_str_format(mrb_state *mrb, mrb_int argc, const mrb_value *argv, mrb_value fmt) 522 526 { 523 527 const char *p, *end; … … 529 533 mrb_int width; 530 534 mrb_int prec; 531 int flags = FNONE;532 535 int nextarg = 1; 533 536 int posarg = 0; … … 553 556 ++argc; 554 557 --argv; 555 fmt = mrb_str_to_str(mrb, fmt);558 mrb_to_str(mrb, fmt); 556 559 p = RSTRING_PTR(fmt); 557 560 end = p + RSTRING_LEN(fmt); 558 561 blen = 0; 559 562 bsiz = 120; 560 result = mrb_str_ buf_new(mrb, bsiz);563 result = mrb_str_new_capa(mrb, bsiz); 561 564 buf = RSTRING_PTR(result); 562 565 memset(buf, 0, bsiz); … … 565 568 const char *t; 566 569 mrb_sym id = 0; 570 int flags = FNONE; 567 571 568 572 for (t = p; t < end && *t != '%'; t++) ; … … 580 584 switch (*p) { 581 585 default: 582 mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - \\%%S", mrb_str_new(mrb, p, 1));586 mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - %%%c", *p); 583 587 break; 584 588 … … 619 623 if (*p == '$') { 620 624 if (!mrb_undef_p(nextvalue)) { 621 mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - % S$", mrb_fixnum_value(n));625 mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - %i$", n); 622 626 } 623 627 nextvalue = GETPOSARG(n); … … 639 643 p++; 640 644 if (id) { 641 mrb_raisef(mrb, E_ARGUMENT_ERROR, "name% S after <%S>",642 mrb_str_new(mrb, start, p - start + 1), mrb_sym2str(mrb, id));645 mrb_raisef(mrb, E_ARGUMENT_ERROR, "name%l after <%n>", 646 start, p - start + 1, id); 643 647 } 644 648 symname = mrb_str_new(mrb, start + 1, p - start - 1); 645 649 id = mrb_intern_str(mrb, symname); 646 nextvalue = GETNAMEARG(mrb_symbol_value(id), start, (int)(p - start + 1));650 nextvalue = GETNAMEARG(mrb_symbol_value(id), start, p - start + 1); 647 651 if (mrb_undef_p(nextvalue)) { 648 mrb_raisef(mrb, E_KEY_ERROR, "key% S not found", mrb_str_new(mrb, start, p - start + 1));652 mrb_raisef(mrb, E_KEY_ERROR, "key%l not found", start, p - start + 1); 649 653 } 650 654 if (term == '}') goto format_s; … … 702 706 tmp = mrb_check_string_type(mrb, val); 703 707 if (!mrb_nil_p(tmp)) { 704 if ( mrb_fixnum(mrb_funcall(mrb, tmp, "size", 0)) != 1) {708 if (RSTRING_LEN(tmp) != 1) { 705 709 mrb_raise(mrb, E_ARGUMENT_ERROR, "%c requires a character"); 706 710 } 707 711 } 708 712 else if (mrb_fixnum_p(val)) { 709 tmp = mrb_funcall(mrb, val, "chr", 0); 713 mrb_int n = mrb_fixnum(val); 714 715 if (n < 0x80) { 716 char buf[1]; 717 718 buf[0] = (char)n; 719 tmp = mrb_str_new(mrb, buf, 1); 720 } 721 else { 722 tmp = mrb_funcall(mrb, val, "chr", 0); 723 mrb_check_type(mrb, tmp, MRB_TT_STRING); 724 } 710 725 } 711 726 else { 712 727 mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character"); 713 728 } 714 mrb_check_type(mrb, tmp, MRB_TT_STRING);715 729 c = RSTRING_PTR(tmp); 716 730 n = RSTRING_LEN(tmp); … … 756 770 char *p = RSTRING_PTR(str) + prec; 757 771 slen = prec; 758 len = p - RSTRING_PTR(str);772 len = (mrb_int)(p - RSTRING_PTR(str)); 759 773 } 760 774 /* need to adjust multi-byte string pos */ … … 792 806 mrb_int len; 793 807 794 switch (*p) {795 case 'd':796 case 'i':797 sign = 1; break;798 default:799 break;800 }801 808 if (flags & FSHARP) { 802 809 switch (*p) { … … 812 819 bin_retry: 813 820 switch (mrb_type(val)) { 821 #ifndef MRB_WITHOUT_FLOAT 814 822 case MRB_TT_FLOAT: 815 823 val = mrb_flo_to_fixnum(mrb, val); 816 824 if (mrb_fixnum_p(val)) goto bin_retry; 817 825 break; 826 #endif 818 827 case MRB_TT_STRING: 819 828 val = mrb_str_to_inum(mrb, val, 0, TRUE); … … 839 848 case 'd': 840 849 case 'i': 850 sign = 1; 851 /* fall through */ 841 852 default: 842 853 base = 10; break; 843 854 } 844 855 845 if (base == 2) {846 if (v < 0 && !sign) {847 val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base);848 dots = 1;849 }850 else {851 val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base);852 }853 }854 856 if (sign) { 855 if (v > 0) {857 if (v >= 0) { 856 858 if (flags & FPLUS) { 857 859 sc = '+'; … … 863 865 } 864 866 } 867 else { 868 sc = '-'; 869 width--; 870 } 871 mrb_assert(base == 10); 872 snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v); 873 s = nbuf; 874 if (v < 0) s++; /* skip minus sign */ 875 } 876 else { 877 s = nbuf; 878 if (v < 0) { 879 dots = 1; 880 } 865 881 switch (base) { 866 882 case 2: 867 strncpy(nbuf, RSTRING_PTR(val), sizeof(nbuf)); 868 break; 869 case 8: 870 snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIo, v); 871 break; 872 case 10: 873 snprintf(nbuf, sizeof(nbuf), "%" MRB_PRId, v); 874 break; 875 case 16: 876 snprintf(nbuf, sizeof(nbuf), "%" MRB_PRIx, v); 877 break; 878 } 879 s = nbuf; 880 } 881 else { 882 s = nbuf; 883 if (base != 10 && v < 0) { 884 dots = 1; 885 } 886 switch (base) { 887 case 2: 883 if (v < 0) { 884 val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base); 885 } 886 else { 887 val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base); 888 } 888 889 strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-1); 889 890 break; 890 891 case 8: 891 892 snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIo, v); 892 break;893 case 10:894 snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRId, v);895 893 break; 896 894 case 16: … … 921 919 } 922 920 923 if (dots) {924 prec -= 2;925 width -= 2;926 }927 928 921 if (*p == 'X') { 929 922 char *pp = s; … … 973 966 if (!(flags&FMINUS) && width > 0) { 974 967 FILL(' ', width); 968 width = 0; 975 969 } 976 970 … … 981 975 PUSH(prefix, plen); 982 976 } 983 if (dots) PUSH("..", 2); 977 if (dots) { 978 prec -= 2; 979 width -= 2; 980 PUSH("..", 2); 981 } 984 982 985 983 if (prec > len) { 986 984 CHECK(prec - len); 987 if (v < 0) { 985 if ((flags & (FMINUS|FPREC)) != FMINUS) { 986 char c = '0'; 987 FILL(c, prec - len); 988 } else if (v < 0) { 988 989 char c = sign_bits(base, p); 989 FILL(c, prec - len);990 }991 else if ((flags & (FMINUS|FPREC)) != FMINUS) {992 char c = '0';993 990 FILL(c, prec - len); 994 991 } … … 1001 998 break; 1002 999 1000 #ifndef MRB_WITHOUT_FLOAT 1003 1001 case 'f': 1004 1002 case 'g': … … 1010 1008 mrb_value val = GETARG(); 1011 1009 double fval; 1012 int i,need = 6;1010 mrb_int need = 6; 1013 1011 char fbuf[32]; 1014 1012 … … 1016 1014 if (!isfinite(fval)) { 1017 1015 const char *expr; 1018 const int elen = 3;1016 const mrb_int elen = 3; 1019 1017 char sign = '\0'; 1020 1018 … … 1031 1029 sign = (flags & FPLUS) ? '+' : ' '; 1032 1030 if (sign) 1033 1031 ++need; 1034 1032 if ((flags & FWIDTH) && need < width) 1035 1033 need = width; … … 1055 1053 need = 0; 1056 1054 if (*p != 'e' && *p != 'E') { 1057 i = INT_MIN;1055 int i; 1058 1056 frexp(fval, &i); 1059 1057 if (i > 0) 1060 1058 need = BIT_DIGITS(i); 1061 1059 } 1060 if (need > MRB_INT_MAX - ((flags&FPREC) ? prec : 6)) { 1061 too_big_width: 1062 mrb_raise(mrb, E_ARGUMENT_ERROR, 1063 (width > prec ? "width too big" : "prec too big")); 1064 } 1062 1065 need += (flags&FPREC) ? prec : 6; 1063 1066 if ((flags&FWIDTH) && need < width) 1064 1067 need = width; 1068 if (need > MRB_INT_MAX - 20) { 1069 goto too_big_width; 1070 } 1065 1071 need += 20; 1066 if (need <= 0) {1067 mrb_raise(mrb, E_ARGUMENT_ERROR,1068 (width > prec ? "width too big" : "prec too big"));1069 }1070 1072 1071 1073 CHECK(need); 1072 1074 n = snprintf(&buf[blen], need, fbuf, fval); 1073 if (n < 0 ) {1075 if (n < 0 || n >= need) { 1074 1076 mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error"); 1075 1077 } … … 1077 1079 } 1078 1080 break; 1081 #endif 1079 1082 } 1080 1083 flags = FNONE; … … 1088 1091 const char *mesg = "too many arguments for format string"; 1089 1092 if (mrb_test(ruby_debug)) mrb_raise(mrb, E_ARGUMENT_ERROR, mesg); 1090 if (mrb_test(ruby_verbose)) mrb_warn(mrb, "% S", mrb_str_new_cstr(mrb, mesg));1093 if (mrb_test(ruby_verbose)) mrb_warn(mrb, "%s", mesg); 1091 1094 } 1092 1095 #endif … … 1096 1099 } 1097 1100 1101 #ifndef MRB_WITHOUT_FLOAT 1098 1102 static void 1099 1103 fmt_setup(char *buf, size_t size, int c, int flags, mrb_int width, mrb_int prec) … … 1122 1126 *buf = '\0'; 1123 1127 } 1128 #endif
Note:
See TracChangeset
for help on using the changeset viewer.