- Timestamp:
- Jan 21, 2018, 12:10:09 AM (6 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-1.3.0
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-sprintf/src/sprintf.c
r321 r331 5 5 */ 6 6 7 #include "mruby.h"7 #include <mruby.h> 8 8 9 9 #include <limits.h> 10 10 #include <stdio.h> 11 11 #include <string.h> 12 #include "mruby/string.h"13 #include "mruby/hash.h"14 #include "mruby/numeric.h"12 #include <mruby/string.h> 13 #include <mruby/hash.h> 14 #include <mruby/numeric.h> 15 15 #include <math.h> 16 16 #include <ctype.h> … … 18 18 #define BIT_DIGITS(N) (((N)*146)/485 + 1) /* log2(10) =~ 146/485 */ 19 19 #define BITSPERDIG MRB_INT_BIT 20 #define EXTENDSIGN(n, l) (((~0 << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0<< (n)))20 #define EXTENDSIGN(n, l) (((~0U << (n)) >> (((n)*(l)) % BITSPERDIG)) & ~(~0U << (n))) 21 21 22 22 mrb_value mrb_str_format(mrb_state *, int, const mrb_value *, mrb_value); … … 72 72 mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) 73 73 { 74 char buf[6 4], *b = buf + sizeof buf;74 char buf[66], *b = buf + sizeof buf; 75 75 mrb_int num = mrb_fixnum(x); 76 76 uint64_t val = (uint64_t)num; … … 80 80 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %S", mrb_fixnum_value(base)); 81 81 } 82 83 if (val >= (1 << 10))84 val &= 0x3ff;85 86 82 if (val == 0) { 87 83 return mrb_str_new_lit(mrb, "0"); … … 121 117 #define CHECK(l) do {\ 122 118 /* int cr = ENC_CODERANGE(result);*/\ 123 while ( blen + (l) >= bsiz) {\119 while ((l) >= bsiz - blen) {\ 124 120 bsiz*=2;\ 121 if (bsiz < 0) mrb_raise(mrb, E_ARGUMENT_ERROR, "too big specifier"); \ 125 122 }\ 126 123 mrb_str_resize(mrb, result, bsiz);\ … … 141 138 } while (0) 142 139 143 #define GETARG() (!mrb_undef_p(nextvalue) ? nextvalue : \ 144 posarg == -1 ? \ 145 (mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with numbered", mrb_fixnum_value(nextarg)), mrb_undef_value()) : \ 146 posarg == -2 ? \ 147 (mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with named", mrb_fixnum_value(nextarg)), mrb_undef_value()) : \ 140 static void 141 check_next_arg(mrb_state *mrb, int posarg, int nextarg) 142 { 143 switch (posarg) { 144 case -1: 145 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with numbered", mrb_fixnum_value(nextarg)); 146 break; 147 case -2: 148 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%S) mixed with named", mrb_fixnum_value(nextarg)); 149 break; 150 default: 151 break; 152 } 153 } 154 155 static void 156 check_pos_arg(mrb_state *mrb, int posarg, int n) 157 { 158 if (posarg > 0) { 159 mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after unnumbered(%S)", 160 mrb_fixnum_value(n), mrb_fixnum_value(posarg)); 161 } 162 if (posarg == -2) { 163 mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after named", mrb_fixnum_value(n)); 164 } 165 if (n < 1) { 166 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %S$", mrb_fixnum_value(n)); 167 } 168 } 169 170 static void 171 check_name_arg(mrb_state *mrb, int posarg, const char *name, int len) 172 { 173 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)); 176 } 177 if (posarg == -1) { 178 mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after numbered", mrb_str_new(mrb, (name), (len))); 179 } 180 } 181 182 #define GETNEXTARG() (\ 183 check_next_arg(mrb, posarg, nextarg),\ 148 184 (posarg = nextarg++, GETNTHARG(posarg))) 149 185 150 #define GETPOSARG(n) (posarg > 0 ? \ 151 (mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after unnumbered(%S)", mrb_fixnum_value(n), mrb_fixnum_value(posarg)), mrb_undef_value()) : \ 152 posarg == -2 ? \ 153 (mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%S) after named", mrb_fixnum_value(n)), mrb_undef_value()) : \ 154 ((n < 1) ? \ 155 (mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %S$", mrb_fixnum_value(n)), mrb_undef_value()) : \ 156 (posarg = -1, GETNTHARG(n)))) 186 #define GETARG() (!mrb_undef_p(nextvalue) ? nextvalue : GETNEXTARG()) 187 188 #define GETPOSARG(n) (\ 189 check_pos_arg(mrb, posarg, n),\ 190 (posarg = -1, GETNTHARG(n))) 157 191 158 192 #define GETNTHARG(nth) \ 159 193 ((nth >= argc) ? (mrb_raise(mrb, E_ARGUMENT_ERROR, "too few arguments"), mrb_undef_value()) : argv[nth]) 160 194 161 #define GETNAMEARG(id, name, len) ( \ 162 posarg > 0 ? \ 163 (mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after unnumbered(%S)", mrb_str_new(mrb, (name), (len)), mrb_fixnum_value(posarg)), mrb_undef_value()) : \ 164 posarg == -1 ? \ 165 (mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%S after numbered", mrb_str_new(mrb, (name), (len))), mrb_undef_value()) : \ 195 #define GETNAMEARG(id, name, len) (\ 196 check_name_arg(mrb, posarg, name, len),\ 166 197 (posarg = -2, mrb_hash_fetch(mrb, get_hash(mrb, &hash, argc, argv), id, mrb_undef_value()))) 167 198 … … 187 218 } \ 188 219 else { \ 189 tmp_v = GET ARG(); \220 tmp_v = GETNEXTARG(); \ 190 221 p = t; \ 191 222 } \ 192 num = mrb_ fixnum(tmp_v); \223 num = mrb_int(mrb, tmp_v); \ 193 224 } while (0) 194 225 … … 536 567 537 568 for (t = p; t < end && *t != '%'; t++) ; 569 if (t + 1 == end) ++t; 538 570 PUSH(p, t - p); 539 571 if (t >= end) … … 680 712 mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character"); 681 713 } 714 mrb_check_type(mrb, tmp, MRB_TT_STRING); 682 715 c = RSTRING_PTR(tmp); 683 716 n = RSTRING_LEN(tmp); 684 717 if (!(flags & FWIDTH)) { 685 CHECK(n); 686 memcpy(buf+blen, c, n); 687 blen += n; 718 PUSH(c, n); 688 719 } 689 720 else if ((flags & FMINUS)) { 690 CHECK(n); 691 memcpy(buf+blen, c, n); 692 blen += n; 693 FILL(' ', width-1); 721 PUSH(c, n); 722 if (width>0) FILL(' ', width-1); 694 723 } 695 724 else { 696 FILL(' ', width-1); 697 CHECK(n); 698 memcpy(buf+blen, c, n); 699 blen += n; 725 if (width>0) FILL(' ', width-1); 726 PUSH(c, n); 700 727 } 701 728 } … … 717 744 RSTRING(result)->flags &= ~MRB_STR_EMBED_LEN_MASK; 718 745 RSTRING(result)->flags |= tmp_n << MRB_STR_EMBED_LEN_SHIFT; 719 } else { 746 } 747 else { 720 748 RSTRING(result)->as.heap.len = blen; 721 749 } … … 734 762 width -= (int)slen; 735 763 if (!(flags&FMINUS)) { 736 CHECK(width); 737 while (width--) { 738 buf[blen++] = ' '; 739 } 764 FILL(' ', width); 740 765 } 741 CHECK(len); 742 memcpy(&buf[blen], RSTRING_PTR(str), len); 743 blen += len; 766 PUSH(RSTRING_PTR(str), len); 744 767 if (flags&FMINUS) { 745 CHECK(width); 746 while (width--) { 747 buf[blen++] = ' '; 748 } 768 FILL(' ', width); 749 769 } 750 770 break; … … 764 784 case 'u': { 765 785 mrb_value val = GETARG(); 766 char fbuf[32], nbuf[64], *s;786 char nbuf[68], *s; 767 787 const char *prefix = NULL; 768 788 int sign = 0, dots = 0; 769 789 char sc = 0; 770 mrb_int v = 0 , org_v = 0;790 mrb_int v = 0; 771 791 int base; 772 792 mrb_int len; … … 775 795 case 'd': 776 796 case 'i': 777 case 'u':778 797 sign = 1; break; 779 case 'o':780 case 'x':781 case 'X':782 case 'b':783 case 'B':784 if (flags&(FPLUS|FSPACE)) sign = 1;785 break;786 798 default: 787 799 break; … … 801 813 switch (mrb_type(val)) { 802 814 case MRB_TT_FLOAT: 803 if (FIXABLE(mrb_float(val))) {804 val = mrb_fixnum_value((mrb_int)mrb_float(val));805 goto bin_retry;806 }807 815 val = mrb_flo_to_fixnum(mrb, val); 808 816 if (mrb_fixnum_p(val)) goto bin_retry; … … 836 844 837 845 if (base == 2) { 838 org_v = v;839 846 if (v < 0 && !sign) { 840 847 val = mrb_fix2binstr(mrb, mrb_fixnum_value(v), base); … … 844 851 val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base); 845 852 } 846 v = mrb_fixnum(mrb_str_to_inum(mrb, val, 10, FALSE));847 853 } 848 854 if (sign) { 849 char c = *p; 850 if (c == 'i') c = 'd'; /* %d and %i are identical */ 851 if (base == 2) c = 'd'; 852 if (v < 0) { 853 v = -v; 854 sc = '-'; 855 width--; 856 } 857 else if (flags & FPLUS) { 858 sc = '+'; 859 width--; 860 } 861 else if (flags & FSPACE) { 862 sc = ' '; 863 width--; 864 } 865 snprintf(fbuf, sizeof(fbuf), "%%l%c", c); 866 snprintf(nbuf, sizeof(nbuf), fbuf, v); 855 if (v > 0) { 856 if (flags & FPLUS) { 857 sc = '+'; 858 width--; 859 } 860 else if (flags & FSPACE) { 861 sc = ' '; 862 width--; 863 } 864 } 865 switch (base) { 866 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 } 867 879 s = nbuf; 868 880 } 869 881 else { 870 char c = *p;871 if (c == 'X') c = 'x';872 if (base == 2) c = 'd';873 882 s = nbuf; 874 if ( v < 0) {883 if (base != 10 && v < 0) { 875 884 dots = 1; 876 885 } 877 snprintf(fbuf, sizeof(fbuf), "%%l%c", c); 878 snprintf(++s, sizeof(nbuf) - 1, fbuf, v); 886 switch (base) { 887 case 2: 888 strncpy(++s, RSTRING_PTR(val), sizeof(nbuf)-1); 889 break; 890 case 8: 891 snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIo, v); 892 break; 893 case 10: 894 snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRId, v); 895 break; 896 case 16: 897 snprintf(++s, sizeof(nbuf)-1, "%" MRB_PRIx, v); 898 break; 899 } 879 900 if (v < 0) { 880 901 char d; … … 950 971 } 951 972 952 if (!(flags&FMINUS)) { 953 CHECK(width); 954 while (width-- > 0) { 955 buf[blen++] = ' '; 956 } 973 if (!(flags&FMINUS) && width > 0) { 974 FILL(' ', width); 957 975 } 958 976 … … 963 981 PUSH(prefix, plen); 964 982 } 965 CHECK(prec - len);966 983 if (dots) PUSH("..", 2); 967 984 968 if (v < 0 || (base == 2 && org_v < 0)) { 969 char c = sign_bits(base, p); 970 while (len < prec--) { 971 buf[blen++] = c; 972 } 973 } 974 else if ((flags & (FMINUS|FPREC)) != FMINUS) { 975 char c = '0'; 976 while (len < prec--) { 977 buf[blen++] = c; 978 } 979 } 980 985 if (prec > len) { 986 CHECK(prec - len); 987 if (v < 0) { 988 char c = sign_bits(base, p); 989 FILL(c, prec - len); 990 } 991 else if ((flags & (FMINUS|FPREC)) != FMINUS) { 992 char c = '0'; 993 FILL(c, prec - len); 994 } 995 } 981 996 PUSH(s, len); 982 CHECK(width); 983 while (width-- > 0) { 984 buf[blen++] = ' '; 997 if (width > 0) { 998 FILL(' ', width); 985 999 } 986 1000 } … … 1003 1017 const char *expr; 1004 1018 const int elen = 3; 1019 char sign = '\0'; 1005 1020 1006 1021 if (isnan(fval)) { … … 1011 1026 } 1012 1027 need = elen; 1013 if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS)) 1014 need++; 1028 if (!isnan(fval) && fval < 0.0) 1029 sign = '-'; 1030 else if (flags & (FPLUS|FSPACE)) 1031 sign = (flags & FPLUS) ? '+' : ' '; 1032 if (sign) 1033 ++need; 1015 1034 if ((flags & FWIDTH) && need < width) 1016 1035 need = width; 1017 1036 1018 CHECK(need + 1); 1019 snprintf(&buf[blen], need + 1, "%*s", need, ""); 1037 if (need < 0) { 1038 mrb_raise(mrb, E_ARGUMENT_ERROR, "width too big"); 1039 } 1040 FILL(' ', need); 1020 1041 if (flags & FMINUS) { 1021 if (!isnan(fval) && fval < 0.0) 1022 buf[blen++] = '-'; 1023 else if (flags & FPLUS) 1024 buf[blen++] = '+'; 1025 else if (flags & FSPACE) 1026 blen++; 1027 memcpy(&buf[blen], expr, elen); 1042 if (sign) 1043 buf[blen - need--] = sign; 1044 memcpy(&buf[blen - need], expr, elen); 1028 1045 } 1029 1046 else { 1030 if (!isnan(fval) && fval < 0.0) 1031 buf[blen + need - elen - 1] = '-'; 1032 else if (flags & FPLUS) 1033 buf[blen + need - elen - 1] = '+'; 1034 else if ((flags & FSPACE) && need > width) 1035 blen++; 1036 memcpy(&buf[blen + need - elen], expr, elen); 1037 } 1038 blen += strlen(&buf[blen]); 1047 if (sign) 1048 buf[blen - elen - 1] = sign; 1049 memcpy(&buf[blen - elen], expr, elen); 1050 } 1039 1051 break; 1040 1052 } … … 1052 1064 need = width; 1053 1065 need += 20; 1066 if (need <= 0) { 1067 mrb_raise(mrb, E_ARGUMENT_ERROR, 1068 (width > prec ? "width too big" : "prec too big")); 1069 } 1054 1070 1055 1071 CHECK(need); 1056 1072 n = snprintf(&buf[blen], need, fbuf, fval); 1073 if (n < 0) { 1074 mrb_raise(mrb, E_RUNTIME_ERROR, "formatting error"); 1075 } 1057 1076 blen += n; 1058 1077 }
Note:
See TracChangeset
for help on using the changeset viewer.