Changeset 331 for EcnlProtoTool/trunk/mruby-1.3.0/src/string.c
- 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/src/string.c
r321 r331 4 4 ** See Copyright Notice in mruby.h 5 5 */ 6 7 #ifdef _MSC_VER 8 # define _CRT_NONSTDC_NO_DEPRECATE 9 #endif 6 10 7 11 #include <float.h> … … 10 14 #include <stdlib.h> 11 15 #include <string.h> 12 #include "mruby.h"13 #include "mruby/array.h"14 #include "mruby/class.h"15 #include "mruby/range.h"16 #include "mruby/string.h"17 #include "mruby/re.h"16 #include <mruby.h> 17 #include <mruby/array.h> 18 #include <mruby/class.h> 19 #include <mruby/range.h> 20 #include <mruby/string.h> 21 #include <mruby/re.h> 18 22 19 23 typedef struct mrb_shared_string { … … 60 64 memcpy(s->as.ary, p, len); 61 65 } 62 } else { 66 } 67 else { 63 68 if (len >= MRB_INT_MAX) { 64 69 mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); … … 115 120 } 116 121 117 static inline void 118 resize_capa(mrb_state *mrb, struct RString *s, mrb_int capacity) 119 { 122 static void 123 resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) 124 { 125 #if SIZE_MAX > MRB_INT_MAX 126 mrb_assert(capacity < MRB_INT_MAX); 127 #endif 120 128 if (RSTR_EMBED_P(s)) { 121 129 if (RSTRING_EMBED_LEN_MAX < capacity) { … … 126 134 s->as.heap.ptr = tmp; 127 135 s->as.heap.len = len; 128 s->as.heap.aux.capa = capacity;136 s->as.heap.aux.capa = (mrb_int)capacity; 129 137 } 130 138 } 131 139 else { 132 s->as.heap.ptr = (char 133 s->as.heap.aux.capa = capacity;140 s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1); 141 s->as.heap.aux.capa = (mrb_int)capacity; 134 142 } 135 143 } … … 148 156 } 149 157 150 if (RSTR_EMBED_P(s)) 151 capa = RSTRING_EMBED_LEN_MAX; 152 else 153 capa = s->as.heap.aux.capa; 154 155 if (RSTR_LEN(s) >= MRB_INT_MAX - (mrb_int)len) { 158 capa = RSTR_CAPA(s); 159 if (capa <= RSTRING_EMBED_LEN_MAX) 160 capa = RSTRING_EMBED_LEN_MAX+1; 161 162 total = RSTR_LEN(s)+len; 163 if (total >= MRB_INT_MAX) { 164 size_error: 156 165 mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); 157 166 } 158 total = RSTR_LEN(s)+len;159 167 if (capa <= total) { 160 168 while (total > capa) { 161 if (capa + 1 >= MRB_INT_MAX / 2) { 162 capa = (total + 4095) / 4096; 163 break; 164 } 165 capa = (capa + 1) * 2; 169 if (capa <= MRB_INT_MAX / 2) { 170 capa *= 2; 171 } 172 else { 173 capa = total; 174 } 175 } 176 if (capa < total || capa > MRB_INT_MAX) { 177 goto size_error; 166 178 } 167 179 resize_capa(mrb, s, capa); … … 270 282 char* p = RSTRING_PTR(str); 271 283 char* e = p; 284 if (RSTRING(str)->flags & MRB_STR_NO_UTF) { 285 return RSTRING_LEN(str); 286 } 272 287 e += len < 0 ? RSTRING_LEN(str) : len; 273 288 while (p<e) { … … 275 290 total++; 276 291 } 292 if (RSTRING_LEN(str) == total) { 293 RSTRING(str)->flags |= MRB_STR_NO_UTF; 294 } 277 295 return total; 278 296 } … … 303 321 304 322 for (b=i=0; b<bi; i++) { 305 n = utf8len (p, p+bi);323 n = utf8len_codepage[(unsigned char)*p]; 306 324 b += n; 307 325 p += n; 308 326 } 327 if (b != bi) return -1; 309 328 return i; 310 329 } 311 330 331 #define BYTES_ALIGN_CHECK(pos) if (pos < 0) return mrb_nil_value(); 312 332 #else 313 333 #define RSTRING_CHAR_LEN(s) RSTRING_LEN(s) 314 334 #define chars2bytes(p, off, ci) (ci) 315 335 #define bytes2chars(p, bi) (bi) 336 #define BYTES_ALIGN_CHECK(pos) 316 337 #endif 317 338 … … 349 370 } 350 371 else if (m == 1) { 351 const unsigned char *ys = y, *ye = ys + n;352 for (; y < ye; ++y) { 353 if (*x == *y)354 return y - ys;355 }356 return -1;372 const unsigned char *ys = (const unsigned char *)memchr(y, *x, n); 373 374 if (ys) 375 return ys - y; 376 else 377 return -1; 357 378 } 358 379 return mrb_memsearch_qs((const unsigned char *)x0, m, (const unsigned char *)y0, n); … … 404 425 405 426 orig = mrb_str_ptr(str); 406 if (RSTR_EMBED_P(orig) ) {427 if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0) { 407 428 s = str_new(mrb, orig->as.ary+beg, len); 408 429 } … … 450 471 if (beg < 0) return mrb_nil_value(); 451 472 } 452 if ( beg + len > clen)473 if (len > clen - beg) 453 474 len = clen - beg; 454 475 if (len <= 0) { … … 489 510 check_frozen(mrb_state *mrb, struct RString *s) 490 511 { 491 if ( RSTR_FROZEN_P(s)) {512 if (MRB_FROZEN_P(s)) { 492 513 mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen string"); 493 514 } … … 500 521 501 522 check_frozen(mrb, s1); 523 if (s1 == s2) return mrb_obj_value(s1); 524 s1->flags &= ~MRB_STR_NO_UTF; 525 s1->flags |= s2->flags&MRB_STR_NO_UTF; 502 526 len = RSTR_LEN(s2); 503 527 if (RSTR_SHARED_P(s1)) { … … 646 670 { 647 671 check_frozen(mrb, s); 672 s->flags &= ~MRB_STR_NO_UTF; 648 673 if (RSTR_SHARED_P(s)) { 649 674 mrb_shared_string *shared = s->as.heap.aux.shared; 650 675 651 if (shared-> refcnt == 1 && s->as.heap.ptr == shared->ptr) {676 if (shared->nofree == 0 && shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) { 652 677 s->as.heap.ptr = shared->ptr; 653 678 s->as.heap.aux.capa = shared->len; … … 661 686 p = RSTR_PTR(s); 662 687 len = s->as.heap.len; 663 ptr = (char *)mrb_malloc(mrb, (size_t)len + 1); 688 if (len < RSTRING_EMBED_LEN_MAX) { 689 RSTR_SET_EMBED_FLAG(s); 690 RSTR_SET_EMBED_LEN(s, len); 691 ptr = RSTR_PTR(s); 692 } 693 else { 694 ptr = (char *)mrb_malloc(mrb, (size_t)len + 1); 695 s->as.heap.ptr = ptr; 696 s->as.heap.aux.capa = len; 697 } 664 698 if (p) { 665 699 memcpy(ptr, p, len); 666 700 } 667 701 ptr[len] = '\0'; 668 s->as.heap.ptr = ptr;669 s->as.heap.aux.capa = len;670 702 str_decref(mrb, shared); 671 703 } … … 675 707 if (RSTR_NOFREE_P(s)) { 676 708 char *p = s->as.heap.ptr; 677 678 s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)s->as.heap.len+1); 709 mrb_int len = s->as.heap.len; 710 711 RSTR_UNSET_NOFREE_FLAG(s); 712 if (len < RSTRING_EMBED_LEN_MAX) { 713 RSTR_SET_EMBED_FLAG(s); 714 RSTR_SET_EMBED_LEN(s, len); 715 } 716 else { 717 s->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1); 718 s->as.heap.aux.capa = len; 719 } 679 720 if (p) { 680 memcpy(RSTR_PTR(s), p, s->as.heap.len); 681 } 682 RSTR_PTR(s)[s->as.heap.len] = '\0'; 683 s->as.heap.aux.capa = s->as.heap.len; 684 RSTR_UNSET_NOFREE_FLAG(s); 721 memcpy(RSTR_PTR(s), p, len); 722 } 723 RSTR_PTR(s)[len] = '\0'; 685 724 return; 686 725 } 687 }688 689 static mrb_value690 mrb_str_freeze(mrb_state *mrb, mrb_value str)691 {692 struct RString *s = mrb_str_ptr(str);693 694 RSTR_SET_FROZEN_FLAG(s);695 return str;696 726 } 697 727 … … 747 777 } 748 778 s2 = mrb_str_ptr(other); 779 if (RSTR_LEN(s2) == 0) { 780 return; 781 } 749 782 len = RSTR_LEN(s1) + RSTR_LEN(s2); 750 783 784 if (len < 0 || len >= MRB_INT_MAX) { 785 mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); 786 } 751 787 if (RSTRING_CAPA(self) < len) { 752 788 resize_capa(mrb, s1, len); … … 932 968 mrb_value tmp = mrb_funcall(mrb, str2, "<=>", 1, str1); 933 969 934 if ( mrb_nil_p(tmp)) return mrb_nil_value();935 if (!mrb_fixnum (tmp)) {970 if (!mrb_nil_p(tmp)) return mrb_nil_value(); 971 if (!mrb_fixnum_p(tmp)) { 936 972 return mrb_funcall(mrb, mrb_fixnum_value(0), "-", 1, tmp); 937 973 } … … 1014 1050 } 1015 1051 1052 MRB_API mrb_int 1053 mrb_string_value_len(mrb_state *mrb, mrb_value ptr) 1054 { 1055 mrb_value str = mrb_str_to_str(mrb, ptr); 1056 return RSTRING_LEN(str); 1057 } 1058 1016 1059 void 1017 1060 mrb_noregexp(mrb_state *mrb, mrb_value self) … … 1059 1102 1060 1103 case MRB_TT_RANGE: 1061 /* check if indx is Range */ 1062 { 1063 mrb_int beg, len; 1064 1065 len = RSTRING_CHAR_LEN(str); 1066 if (mrb_range_beg_len(mrb, indx, &beg, &len, len)) { 1067 return str_subseq(mrb, str, beg, len); 1068 } 1069 else { 1070 return mrb_nil_value(); 1071 } 1072 } 1073 case MRB_TT_FLOAT: 1104 goto range_arg; 1105 1074 1106 default: 1075 1107 indx = mrb_Integer(mrb, indx); 1076 1108 if (mrb_nil_p(indx)) { 1109 range_arg: 1110 { 1111 mrb_int beg, len; 1112 1113 len = RSTRING_CHAR_LEN(str); 1114 switch (mrb_range_beg_len(mrb, indx, &beg, &len, len, TRUE)) { 1115 case 1: 1116 return str_subseq(mrb, str, beg, len); 1117 case 2: 1118 return mrb_nil_value(); 1119 default: 1120 break; 1121 } 1122 } 1077 1123 mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Fixnum"); 1078 1124 } … … 1131 1177 argc = mrb_get_args(mrb, "o|o", &a1, &a2); 1132 1178 if (argc == 2) { 1179 mrb_int n1, n2; 1180 1133 1181 mrb_regexp_check(mrb, a1); 1134 return str_substr(mrb, str, mrb_fixnum(a1), mrb_fixnum(a2)); 1182 mrb_get_args(mrb, "ii", &n1, &n2); 1183 return str_substr(mrb, str, n1, n2); 1135 1184 } 1136 1185 if (argc != 1) { … … 1215 1264 mrb_int rslen; 1216 1265 mrb_int len; 1266 mrb_int argc; 1217 1267 struct RString *s = mrb_str_ptr(str); 1218 1268 1219 1269 mrb_str_modify(mrb, s); 1270 argc = mrb_get_args(mrb, "|S", &rs); 1220 1271 len = RSTR_LEN(s); 1221 if ( mrb_get_args(mrb, "|S", &rs)== 0) {1272 if (argc == 0) { 1222 1273 if (len == 0) return mrb_nil_value(); 1223 1274 smart_chomp: … … 1510 1561 mrb_str_include(mrb_state *mrb, mrb_value self) 1511 1562 { 1512 mrb_int i;1513 1563 mrb_value str2; 1514 mrb_bool include_p; 1515 1516 mrb_get_args(mrb, "o", &str2); 1517 if (mrb_fixnum_p(str2)) { 1518 include_p = (memchr(RSTRING_PTR(self), mrb_fixnum(str2), RSTRING_LEN(self)) != NULL); 1519 } 1520 else { 1521 str2 = mrb_str_to_str(mrb, str2); 1522 i = str_index(mrb, self, str2, 0); 1523 1524 include_p = (i != -1); 1525 } 1526 1527 return mrb_bool_value(include_p); 1564 1565 mrb_get_args(mrb, "S", &str2); 1566 if (str_index(mrb, self, str2, 0) < 0) 1567 return mrb_bool_value(FALSE); 1568 return mrb_bool_value(TRUE); 1528 1569 } 1529 1570 … … 1559 1600 mrb_get_args(mrb, "*", &argv, &argc); 1560 1601 if (argc == 2) { 1561 pos = mrb_fixnum(argv[1]); 1562 sub = argv[0]; 1602 mrb_get_args(mrb, "oi", &sub, &pos); 1563 1603 } 1564 1604 else { … … 1577 1617 } 1578 1618 } 1579 if (pos > =clen) return mrb_nil_value();1619 if (pos > clen) return mrb_nil_value(); 1580 1620 pos = chars2bytes(str, 0, pos); 1581 1621 … … 1598 1638 if (pos == -1) return mrb_nil_value(); 1599 1639 pos = bytes2chars(RSTRING_PTR(str), pos); 1640 BYTES_ALIGN_CHECK(pos); 1600 1641 return mrb_fixnum_value(pos); 1601 1642 } … … 1633 1674 mrb_value str2; 1634 1675 1635 if (mrb_get_args(mrb, "|S", &str2) == 1) { 1636 str_replace(mrb, mrb_str_ptr(self), mrb_str_ptr(str2)); 1637 } 1676 if (mrb_get_args(mrb, "|S", &str2) == 0) { 1677 struct RString *s = str_new(mrb, 0, 0); 1678 str2 = mrb_obj_value(s); 1679 } 1680 str_replace(mrb, mrb_str_ptr(self), mrb_str_ptr(str2)); 1638 1681 return self; 1639 1682 } … … 1743 1786 mrb_str_modify(mrb, mrb_str_ptr(str)); 1744 1787 len = RSTRING_LEN(str); 1745 buf = mrb_malloc(mrb, (size_t)len);1788 buf = (char*)mrb_malloc(mrb, (size_t)len); 1746 1789 p = buf; 1747 1790 e = buf + len; … … 1824 1867 mrb_int argc; 1825 1868 mrb_value sub; 1826 mrb_value vpos;1827 1869 mrb_int pos, len = RSTRING_CHAR_LEN(str); 1828 1870 1829 1871 mrb_get_args(mrb, "*", &argv, &argc); 1830 1872 if (argc == 2) { 1831 sub = argv[0]; 1832 vpos = argv[1]; 1833 pos = mrb_fixnum(vpos); 1873 mrb_get_args(mrb, "oi", &sub, &pos); 1834 1874 if (pos < 0) { 1835 1875 pos += len; … … 1849 1889 } 1850 1890 pos = chars2bytes(str, 0, pos); 1851 len = chars2bytes(str, pos, len);1852 1891 mrb_regexp_check(mrb, sub); 1853 1892 … … 1867 1906 if (pos >= 0) { 1868 1907 pos = bytes2chars(RSTRING_PTR(str), pos); 1908 BYTES_ALIGN_CHECK(pos); 1869 1909 return mrb_fixnum_value(pos); 1870 1910 } … … 1922 1962 mrb_value spat = mrb_nil_value(); 1923 1963 enum {awk, string, regexp} split_type = string; 1924 long i = 0, lim_p;1964 mrb_int i = 0; 1925 1965 mrb_int beg; 1926 1966 mrb_int end; 1927 1967 mrb_int lim = 0; 1968 mrb_bool lim_p; 1928 1969 mrb_value result, tmp; 1929 1970 … … 1998 2039 end = mrb_memsearch(RSTRING_PTR(spat), pat_len, RSTRING_PTR(str)+idx, str_len - idx); 1999 2040 if (end < 0) break; 2000 } else { 2041 } 2042 else { 2001 2043 end = chars2bytes(str, idx, 1); 2002 2044 } … … 2031 2073 2032 2074 MRB_API mrb_value 2033 mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) 2034 { 2035 const char *p; 2075 mrb_str_len_to_inum(mrb_state *mrb, const char *str, size_t len, int base, int badcheck) 2076 { 2077 const char *p = str; 2078 const char *pend = str + len; 2036 2079 char sign = 1; 2037 int c , uscore;2080 int c; 2038 2081 uint64_t n = 0; 2039 2082 mrb_int val; … … 2045 2088 -1) 2046 2089 2047 if (! str) {2090 if (!p) { 2048 2091 if (badcheck) goto bad; 2049 2092 return mrb_fixnum_value(0); 2050 2093 } 2051 while (ISSPACE(*str)) str++; 2052 2053 if (str[0] == '+') { 2054 str++; 2055 } 2056 else if (str[0] == '-') { 2057 str++; 2094 while (p<pend && ISSPACE(*p)) 2095 p++; 2096 2097 if (p[0] == '+') { 2098 p++; 2099 } 2100 else if (p[0] == '-') { 2101 p++; 2058 2102 sign = 0; 2059 2103 } 2060 if (str[0] == '+' || str[0] == '-') {2061 if (badcheck) goto bad;2062 return mrb_fixnum_value(0);2063 }2064 2104 if (base <= 0) { 2065 if ( str[0] == '0') {2066 switch ( str[1]) {2105 if (p[0] == '0') { 2106 switch (p[1]) { 2067 2107 case 'x': case 'X': 2068 2108 base = 16; … … 2079 2119 default: 2080 2120 base = 8; 2121 break; 2081 2122 } 2082 2123 } … … 2090 2131 switch (base) { 2091 2132 case 2: 2092 if ( str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) {2093 str+= 2;2133 if (p[0] == '0' && (p[1] == 'b'||p[1] == 'B')) { 2134 p += 2; 2094 2135 } 2095 2136 break; … … 2097 2138 break; 2098 2139 case 8: 2099 if ( str[0] == '0' && (str[1] == 'o'||str[1] == 'O')) {2100 str+= 2;2140 if (p[0] == '0' && (p[1] == 'o'||p[1] == 'O')) { 2141 p += 2; 2101 2142 } 2102 2143 case 4: case 5: case 6: case 7: 2103 2144 break; 2104 2145 case 10: 2105 if ( str[0] == '0' && (str[1] == 'd'||str[1] == 'D')) {2106 str+= 2;2146 if (p[0] == '0' && (p[1] == 'd'||p[1] == 'D')) { 2147 p += 2; 2107 2148 } 2108 2149 case 9: case 11: case 12: case 13: case 14: case 15: 2109 2150 break; 2110 2151 case 16: 2111 if ( str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) {2112 str+= 2;2152 if (p[0] == '0' && (p[1] == 'x'||p[1] == 'X')) { 2153 p += 2; 2113 2154 } 2114 2155 break; … … 2119 2160 break; 2120 2161 } /* end of switch (base) { */ 2121 if (*str == '0') { /* squeeze preceding 0s */ 2122 uscore = 0; 2123 while ((c = *++str) == '0' || c == '_') { 2124 if (c == '_') { 2125 if (++uscore >= 2) 2126 break; 2127 } 2128 else 2129 uscore = 0; 2130 } 2131 if (!(c = *str) || ISSPACE(c)) --str; 2132 } 2133 c = *str; 2134 c = conv_digit(c); 2135 if (c < 0 || c >= base) { 2162 if (p>=pend) { 2136 2163 if (badcheck) goto bad; 2137 2164 return mrb_fixnum_value(0); 2138 2165 } 2139 2140 uscore = 0; 2141 for (p=str;*p;p++) { 2166 if (*p == '0') { /* squeeze preceding 0s */ 2167 p++; 2168 while (p<pend) { 2169 c = *p++; 2170 if (c == '_') { 2171 if (p<pend && *p == '_') { 2172 if (badcheck) goto bad; 2173 break; 2174 } 2175 continue; 2176 } 2177 if (c != '0') { 2178 p--; 2179 break; 2180 } 2181 } 2182 if (*(p - 1) == '0') 2183 p--; 2184 } 2185 if (p == pend) { 2186 if (badcheck) goto bad; 2187 return mrb_fixnum_value(0); 2188 } 2189 for ( ;p<pend;p++) { 2142 2190 if (*p == '_') { 2143 if (uscore == 0) { 2144 uscore++; 2191 p++; 2192 if (p==pend) { 2193 if (badcheck) goto bad; 2145 2194 continue; 2146 2195 } 2147 if (badcheck) goto bad; 2148 break; 2149 } 2150 uscore = 0; 2196 if (*p == '_') { 2197 if (badcheck) goto bad; 2198 break; 2199 } 2200 } 2201 if (badcheck && *p == '\0') { 2202 goto nullbyte; 2203 } 2151 2204 c = conv_digit(*p); 2152 2205 if (c < 0 || c >= base) { 2153 if (badcheck) goto bad;2154 2206 break; 2155 2207 } 2156 2208 n *= base; 2157 2209 n += c; 2158 if (n > MRB_INT_MAX) { 2159 mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer", mrb_str_new_cstr(mrb, str)); 2160 } 2161 } 2162 val = n; 2210 if (n > (uint64_t)MRB_INT_MAX + (sign ? 0 : 1)) { 2211 mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer", 2212 mrb_str_new(mrb, str, pend-str)); 2213 } 2214 } 2215 val = (mrb_int)n; 2163 2216 if (badcheck) { 2164 2217 if (p == str) goto bad; /* no number */ 2165 while ( *p&& ISSPACE(*p)) p++;2166 if ( *p) goto bad;/* trailing garbage */2218 while (p<pend && ISSPACE(*p)) p++; 2219 if (p<pend) goto bad; /* trailing garbage */ 2167 2220 } 2168 2221 2169 2222 return mrb_fixnum_value(sign ? val : -val); 2170 bad: 2171 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%S)", mrb_str_new_cstr(mrb, str)); 2223 nullbyte: 2224 mrb_raise(mrb, E_ARGUMENT_ERROR, "string contains null byte"); 2225 /* not reached */ 2226 bad: 2227 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid string for number(%S)", 2228 mrb_inspect(mrb, mrb_str_new(mrb, str, pend-str))); 2172 2229 /* not reached */ 2173 2230 return mrb_fixnum_value(0); 2231 } 2232 2233 MRB_API mrb_value 2234 mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) 2235 { 2236 return mrb_str_len_to_inum(mrb, str, strlen(str), base, badcheck); 2174 2237 } 2175 2238 … … 2183 2246 2184 2247 if (!p || p[len] != '\0') { 2248 if (MRB_FROZEN_P(ps)) { 2249 *ptr = str = mrb_str_dup(mrb, str); 2250 ps = mrb_str_ptr(str); 2251 } 2185 2252 mrb_str_modify(mrb, ps); 2186 2253 return RSTR_PTR(ps); … … 2195 2262 mrb_int len; 2196 2263 2197 if (badcheck) { 2198 /* Raises if the string contains a null character (the badcheck) */ 2199 s = mrb_string_value_cstr(mrb, &str); 2200 } 2201 else { 2202 s = mrb_string_value_ptr(mrb, str); 2203 } 2204 if (s) { 2205 len = RSTRING_LEN(str); 2206 if (s[len]) { /* no sentinel somehow */ 2207 struct RString *temp_str = str_new(mrb, s, len); 2208 s = RSTR_PTR(temp_str); 2209 } 2210 } 2211 return mrb_cstr_to_inum(mrb, s, base, badcheck); 2264 s = mrb_string_value_ptr(mrb, str); 2265 len = RSTRING_LEN(str); 2266 return mrb_str_len_to_inum(mrb, s, len, base, badcheck); 2212 2267 } 2213 2268 … … 2260 2315 return 0.0; 2261 2316 } 2262 d = strtod(p, &end);2317 d = mrb_float_read(p, &end); 2263 2318 if (p == end) { 2264 2319 if (badcheck) { … … 2298 2353 } 2299 2354 2300 d = strtod(p, &end);2355 d = mrb_float_read(p, &end); 2301 2356 if (badcheck) { 2302 2357 if (!end || p == end) goto bad; … … 2603 2658 #endif 2604 2659 c = *p; 2605 if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p , pend))) {2660 if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) { 2606 2661 buf[0] = '\\'; buf[1] = c; 2607 2662 mrb_str_cat(mrb, result, buf, 2); … … 2689 2744 mrb_define_method(mrb, s, "chomp", mrb_str_chomp, MRB_ARGS_ANY()); /* 15.2.10.5.9 */ 2690 2745 mrb_define_method(mrb, s, "chomp!", mrb_str_chomp_bang, MRB_ARGS_ANY()); /* 15.2.10.5.10 */ 2691 mrb_define_method(mrb, s, "chop", mrb_str_chop, MRB_ARGS_ REQ(1)); /* 15.2.10.5.11 */2692 mrb_define_method(mrb, s, "chop!", mrb_str_chop_bang, MRB_ARGS_ REQ(1)); /* 15.2.10.5.12 */2746 mrb_define_method(mrb, s, "chop", mrb_str_chop, MRB_ARGS_NONE()); /* 15.2.10.5.11 */ 2747 mrb_define_method(mrb, s, "chop!", mrb_str_chop_bang, MRB_ARGS_NONE()); /* 15.2.10.5.12 */ 2693 2748 mrb_define_method(mrb, s, "downcase", mrb_str_downcase, MRB_ARGS_NONE()); /* 15.2.10.5.13 */ 2694 2749 mrb_define_method(mrb, s, "downcase!", mrb_str_downcase_bang, MRB_ARGS_NONE()); /* 15.2.10.5.14 */ … … 2720 2775 mrb_define_method(mrb, s, "inspect", mrb_str_inspect, MRB_ARGS_NONE()); /* 15.2.10.5.46(x) */ 2721 2776 mrb_define_method(mrb, s, "bytes", mrb_str_bytes, MRB_ARGS_NONE()); 2722 2723 mrb_define_method(mrb, s, "freeze", mrb_str_freeze, MRB_ARGS_NONE()); 2724 } 2777 } 2778 2779 /* 2780 * Source code for the "strtod" library procedure. 2781 * 2782 * Copyright (c) 1988-1993 The Regents of the University of California. 2783 * Copyright (c) 1994 Sun Microsystems, Inc. 2784 * 2785 * Permission to use, copy, modify, and distribute this 2786 * software and its documentation for any purpose and without 2787 * fee is hereby granted, provided that the above copyright 2788 * notice appear in all copies. The University of California 2789 * makes no representations about the suitability of this 2790 * software for any purpose. It is provided "as is" without 2791 * express or implied warranty. 2792 * 2793 * RCS: @(#) $Id$ 2794 */ 2795 2796 #include <ctype.h> 2797 #include <errno.h> 2798 2799 static const int maxExponent = 511; /* Largest possible base 10 exponent. Any 2800 * exponent larger than this will already 2801 * produce underflow or overflow, so there's 2802 * no need to worry about additional digits. 2803 */ 2804 static const double powersOf10[] = {/* Table giving binary powers of 10. Entry */ 2805 10., /* is 10^2^i. Used to convert decimal */ 2806 100., /* exponents into floating-point numbers. */ 2807 1.0e4, 2808 1.0e8, 2809 1.0e16, 2810 1.0e32, 2811 1.0e64, 2812 1.0e128, 2813 1.0e256 2814 }; 2815 2816 MRB_API double 2817 mrb_float_read(const char *string, char **endPtr) 2818 /* const char *string; A decimal ASCII floating-point number, 2819 * optionally preceded by white space. 2820 * Must have form "-I.FE-X", where I is the 2821 * integer part of the mantissa, F is the 2822 * fractional part of the mantissa, and X 2823 * is the exponent. Either of the signs 2824 * may be "+", "-", or omitted. Either I 2825 * or F may be omitted, or both. The decimal 2826 * point isn't necessary unless F is present. 2827 * The "E" may actually be an "e". E and X 2828 * may both be omitted (but not just one). 2829 */ 2830 /* char **endPtr; If non-NULL, store terminating character's 2831 * address here. */ 2832 { 2833 int sign, expSign = FALSE; 2834 double fraction, dblExp; 2835 const double *d; 2836 register const char *p; 2837 register int c; 2838 int exp = 0; /* Exponent read from "EX" field. */ 2839 int fracExp = 0; /* Exponent that derives from the fractional 2840 * part. Under normal circumstatnces, it is 2841 * the negative of the number of digits in F. 2842 * However, if I is very long, the last digits 2843 * of I get dropped (otherwise a long I with a 2844 * large negative exponent could cause an 2845 * unnecessary overflow on I alone). In this 2846 * case, fracExp is incremented one for each 2847 * dropped digit. */ 2848 int mantSize; /* Number of digits in mantissa. */ 2849 int decPt; /* Number of mantissa digits BEFORE decimal 2850 * point. */ 2851 const char *pExp; /* Temporarily holds location of exponent 2852 * in string. */ 2853 2854 /* 2855 * Strip off leading blanks and check for a sign. 2856 */ 2857 2858 p = string; 2859 while (isspace(*p)) { 2860 p += 1; 2861 } 2862 if (*p == '-') { 2863 sign = TRUE; 2864 p += 1; 2865 } 2866 else { 2867 if (*p == '+') { 2868 p += 1; 2869 } 2870 sign = FALSE; 2871 } 2872 2873 /* 2874 * Count the number of digits in the mantissa (including the decimal 2875 * point), and also locate the decimal point. 2876 */ 2877 2878 decPt = -1; 2879 for (mantSize = 0; ; mantSize += 1) 2880 { 2881 c = *p; 2882 if (!isdigit(c)) { 2883 if ((c != '.') || (decPt >= 0)) { 2884 break; 2885 } 2886 decPt = mantSize; 2887 } 2888 p += 1; 2889 } 2890 2891 /* 2892 * Now suck up the digits in the mantissa. Use two integers to 2893 * collect 9 digits each (this is faster than using floating-point). 2894 * If the mantissa has more than 18 digits, ignore the extras, since 2895 * they can't affect the value anyway. 2896 */ 2897 2898 pExp = p; 2899 p -= mantSize; 2900 if (decPt < 0) { 2901 decPt = mantSize; 2902 } 2903 else { 2904 mantSize -= 1; /* One of the digits was the point. */ 2905 } 2906 if (mantSize > 18) { 2907 if (decPt - 18 > 29999) { 2908 fracExp = 29999; 2909 } 2910 else { 2911 fracExp = decPt - 18; 2912 } 2913 mantSize = 18; 2914 } 2915 else { 2916 fracExp = decPt - mantSize; 2917 } 2918 if (mantSize == 0) { 2919 fraction = 0.0; 2920 p = string; 2921 goto done; 2922 } 2923 else { 2924 int frac1, frac2; 2925 frac1 = 0; 2926 for ( ; mantSize > 9; mantSize -= 1) 2927 { 2928 c = *p; 2929 p += 1; 2930 if (c == '.') { 2931 c = *p; 2932 p += 1; 2933 } 2934 frac1 = 10*frac1 + (c - '0'); 2935 } 2936 frac2 = 0; 2937 for (; mantSize > 0; mantSize -= 1) 2938 { 2939 c = *p; 2940 p += 1; 2941 if (c == '.') { 2942 c = *p; 2943 p += 1; 2944 } 2945 frac2 = 10*frac2 + (c - '0'); 2946 } 2947 fraction = (1.0e9 * frac1) + frac2; 2948 } 2949 2950 /* 2951 * Skim off the exponent. 2952 */ 2953 2954 p = pExp; 2955 if ((*p == 'E') || (*p == 'e')) { 2956 p += 1; 2957 if (*p == '-') { 2958 expSign = TRUE; 2959 p += 1; 2960 } 2961 else { 2962 if (*p == '+') { 2963 p += 1; 2964 } 2965 expSign = FALSE; 2966 } 2967 while (isdigit(*p)) { 2968 exp = exp * 10 + (*p - '0'); 2969 if (exp > 19999) { 2970 exp = 19999; 2971 } 2972 p += 1; 2973 } 2974 } 2975 if (expSign) { 2976 exp = fracExp - exp; 2977 } 2978 else { 2979 exp = fracExp + exp; 2980 } 2981 2982 /* 2983 * Generate a floating-point number that represents the exponent. 2984 * Do this by processing the exponent one bit at a time to combine 2985 * many powers of 2 of 10. Then combine the exponent with the 2986 * fraction. 2987 */ 2988 2989 if (exp < 0) { 2990 expSign = TRUE; 2991 exp = -exp; 2992 } 2993 else { 2994 expSign = FALSE; 2995 } 2996 if (exp > maxExponent) { 2997 exp = maxExponent; 2998 errno = ERANGE; 2999 } 3000 dblExp = 1.0; 3001 for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { 3002 if (exp & 01) { 3003 dblExp *= *d; 3004 } 3005 } 3006 if (expSign) { 3007 fraction /= dblExp; 3008 } 3009 else { 3010 fraction *= dblExp; 3011 } 3012 3013 done: 3014 if (endPtr != NULL) { 3015 *endPtr = (char *) p; 3016 } 3017 3018 if (sign) { 3019 return -fraction; 3020 } 3021 return fraction; 3022 }
Note:
See TracChangeset
for help on using the changeset viewer.