Ignore:
Timestamp:
Jan 21, 2018, 12:10:09 AM (6 years ago)
Author:
coas-nagasima
Message:

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

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  
    44** See Copyright Notice in mruby.h
    55*/
     6
     7#ifdef _MSC_VER
     8# define _CRT_NONSTDC_NO_DEPRECATE
     9#endif
    610
    711#include <float.h>
     
    1014#include <stdlib.h>
    1115#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>
    1822
    1923typedef struct mrb_shared_string {
     
    6064      memcpy(s->as.ary, p, len);
    6165    }
    62   } else {
     66  }
     67  else {
    6368    if (len >= MRB_INT_MAX) {
    6469      mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
     
    115120}
    116121
    117 static inline void
    118 resize_capa(mrb_state *mrb, struct RString *s, mrb_int capacity)
    119 {
     122static void
     123resize_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
    120128  if (RSTR_EMBED_P(s)) {
    121129    if (RSTRING_EMBED_LEN_MAX < capacity) {
     
    126134      s->as.heap.ptr = tmp;
    127135      s->as.heap.len = len;
    128       s->as.heap.aux.capa = capacity;
     136      s->as.heap.aux.capa = (mrb_int)capacity;
    129137    }
    130138  }
    131139  else {
    132     s->as.heap.ptr = (char *)mrb_realloc(mrb, RSTR_PTR(s), capacity+1);
    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;
    134142  }
    135143}
     
    148156  }
    149157
    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:
    156165    mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
    157166  }
    158   total = RSTR_LEN(s)+len;
    159167  if (capa <= total) {
    160168    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;
    166178    }
    167179    resize_capa(mrb, s, capa);
     
    270282  char* p = RSTRING_PTR(str);
    271283  char* e = p;
     284  if (RSTRING(str)->flags & MRB_STR_NO_UTF) {
     285    return RSTRING_LEN(str);
     286  }
    272287  e += len < 0 ? RSTRING_LEN(str) : len;
    273288  while (p<e) {
     
    275290    total++;
    276291  }
     292  if (RSTRING_LEN(str) == total) {
     293    RSTRING(str)->flags |= MRB_STR_NO_UTF;
     294  }
    277295  return total;
    278296}
     
    303321
    304322  for (b=i=0; b<bi; i++) {
    305     n = utf8len(p, p+bi);
     323    n = utf8len_codepage[(unsigned char)*p];
    306324    b += n;
    307325    p += n;
    308326  }
     327  if (b != bi) return -1;
    309328  return i;
    310329}
    311330
     331#define BYTES_ALIGN_CHECK(pos) if (pos < 0) return mrb_nil_value();
    312332#else
    313333#define RSTRING_CHAR_LEN(s) RSTRING_LEN(s)
    314334#define chars2bytes(p, off, ci) (ci)
    315335#define bytes2chars(p, bi) (bi)
     336#define BYTES_ALIGN_CHECK(pos)
    316337#endif
    317338
     
    349370  }
    350371  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;
    357378  }
    358379  return mrb_memsearch_qs((const unsigned char *)x0, m, (const unsigned char *)y0, n);
     
    404425
    405426  orig = mrb_str_ptr(str);
    406   if (RSTR_EMBED_P(orig)) {
     427  if (RSTR_EMBED_P(orig) || RSTR_LEN(orig) == 0) {
    407428    s = str_new(mrb, orig->as.ary+beg, len);
    408429  }
     
    450471    if (beg < 0) return mrb_nil_value();
    451472  }
    452   if (beg + len > clen)
     473  if (len > clen - beg)
    453474    len = clen - beg;
    454475  if (len <= 0) {
     
    489510check_frozen(mrb_state *mrb, struct RString *s)
    490511{
    491   if (RSTR_FROZEN_P(s)) {
     512  if (MRB_FROZEN_P(s)) {
    492513    mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen string");
    493514  }
     
    500521
    501522  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;
    502526  len = RSTR_LEN(s2);
    503527  if (RSTR_SHARED_P(s1)) {
     
    646670{
    647671  check_frozen(mrb, s);
     672  s->flags &= ~MRB_STR_NO_UTF;
    648673  if (RSTR_SHARED_P(s)) {
    649674    mrb_shared_string *shared = s->as.heap.aux.shared;
    650675
    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) {
    652677      s->as.heap.ptr = shared->ptr;
    653678      s->as.heap.aux.capa = shared->len;
     
    661686      p = RSTR_PTR(s);
    662687      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      }
    664698      if (p) {
    665699        memcpy(ptr, p, len);
    666700      }
    667701      ptr[len] = '\0';
    668       s->as.heap.ptr = ptr;
    669       s->as.heap.aux.capa = len;
    670702      str_decref(mrb, shared);
    671703    }
     
    675707  if (RSTR_NOFREE_P(s)) {
    676708    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    }
    679720    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';
    685724    return;
    686725  }
    687 }
    688 
    689 static mrb_value
    690 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;
    696726}
    697727
     
    747777  }
    748778  s2 = mrb_str_ptr(other);
     779  if (RSTR_LEN(s2) == 0) {
     780    return;
     781  }
    749782  len = RSTR_LEN(s1) + RSTR_LEN(s2);
    750783
     784  if (len < 0 || len >= MRB_INT_MAX) {
     785    mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big");
     786  }
    751787  if (RSTRING_CAPA(self) < len) {
    752788    resize_capa(mrb, s1, len);
     
    932968      mrb_value tmp = mrb_funcall(mrb, str2, "<=>", 1, str1);
    933969
    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)) {
    936972        return mrb_funcall(mrb, mrb_fixnum_value(0), "-", 1, tmp);
    937973      }
     
    10141050}
    10151051
     1052MRB_API mrb_int
     1053mrb_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
    10161059void
    10171060mrb_noregexp(mrb_state *mrb, mrb_value self)
     
    10591102
    10601103    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
    10741106    default:
    10751107      indx = mrb_Integer(mrb, indx);
    10761108      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        }
    10771123        mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Fixnum");
    10781124      }
     
    11311177  argc = mrb_get_args(mrb, "o|o", &a1, &a2);
    11321178  if (argc == 2) {
     1179    mrb_int n1, n2;
     1180
    11331181    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);
    11351184  }
    11361185  if (argc != 1) {
     
    12151264  mrb_int rslen;
    12161265  mrb_int len;
     1266  mrb_int argc;
    12171267  struct RString *s = mrb_str_ptr(str);
    12181268
    12191269  mrb_str_modify(mrb, s);
     1270  argc = mrb_get_args(mrb, "|S", &rs);
    12201271  len = RSTR_LEN(s);
    1221   if (mrb_get_args(mrb, "|S", &rs) == 0) {
     1272  if (argc == 0) {
    12221273    if (len == 0) return mrb_nil_value();
    12231274  smart_chomp:
     
    15101561mrb_str_include(mrb_state *mrb, mrb_value self)
    15111562{
    1512   mrb_int i;
    15131563  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);
    15281569}
    15291570
     
    15591600  mrb_get_args(mrb, "*", &argv, &argc);
    15601601  if (argc == 2) {
    1561     pos = mrb_fixnum(argv[1]);
    1562     sub = argv[0];
     1602    mrb_get_args(mrb, "oi", &sub, &pos);
    15631603  }
    15641604  else {
     
    15771617    }
    15781618  }
    1579   if (pos >= clen) return mrb_nil_value();
     1619  if (pos > clen) return mrb_nil_value();
    15801620  pos = chars2bytes(str, 0, pos);
    15811621
     
    15981638  if (pos == -1) return mrb_nil_value();
    15991639  pos = bytes2chars(RSTRING_PTR(str), pos);
     1640  BYTES_ALIGN_CHECK(pos);
    16001641  return mrb_fixnum_value(pos);
    16011642}
     
    16331674  mrb_value str2;
    16341675
    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));
    16381681  return self;
    16391682}
     
    17431786    mrb_str_modify(mrb, mrb_str_ptr(str));
    17441787    len = RSTRING_LEN(str);
    1745     buf = mrb_malloc(mrb, (size_t)len);
     1788    buf = (char*)mrb_malloc(mrb, (size_t)len);
    17461789    p = buf;
    17471790    e = buf + len;
     
    18241867  mrb_int argc;
    18251868  mrb_value sub;
    1826   mrb_value vpos;
    18271869  mrb_int pos, len = RSTRING_CHAR_LEN(str);
    18281870
    18291871  mrb_get_args(mrb, "*", &argv, &argc);
    18301872  if (argc == 2) {
    1831     sub = argv[0];
    1832     vpos = argv[1];
    1833     pos = mrb_fixnum(vpos);
     1873    mrb_get_args(mrb, "oi", &sub, &pos);
    18341874    if (pos < 0) {
    18351875      pos += len;
     
    18491889  }
    18501890  pos = chars2bytes(str, 0, pos);
    1851   len = chars2bytes(str, pos, len);
    18521891  mrb_regexp_check(mrb, sub);
    18531892
     
    18671906      if (pos >= 0) {
    18681907        pos = bytes2chars(RSTRING_PTR(str), pos);
     1908        BYTES_ALIGN_CHECK(pos);
    18691909        return mrb_fixnum_value(pos);
    18701910      }
     
    19221962  mrb_value spat = mrb_nil_value();
    19231963  enum {awk, string, regexp} split_type = string;
    1924   long i = 0, lim_p;
     1964  mrb_int i = 0;
    19251965  mrb_int beg;
    19261966  mrb_int end;
    19271967  mrb_int lim = 0;
     1968  mrb_bool lim_p;
    19281969  mrb_value result, tmp;
    19291970
     
    19982039        end = mrb_memsearch(RSTRING_PTR(spat), pat_len, RSTRING_PTR(str)+idx, str_len - idx);
    19992040        if (end < 0) break;
    2000       } else {
     2041      }
     2042      else {
    20012043        end = chars2bytes(str, idx, 1);
    20022044      }
     
    20312073
    20322074MRB_API mrb_value
    2033 mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck)
    2034 {
    2035   const char *p;
     2075mrb_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;
    20362079  char sign = 1;
    2037   int c, uscore;
     2080  int c;
    20382081  uint64_t n = 0;
    20392082  mrb_int val;
     
    20452088     -1)
    20462089
    2047   if (!str) {
     2090  if (!p) {
    20482091    if (badcheck) goto bad;
    20492092    return mrb_fixnum_value(0);
    20502093  }
    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++;
    20582102    sign = 0;
    20592103  }
    2060   if (str[0] == '+' || str[0] == '-') {
    2061     if (badcheck) goto bad;
    2062     return mrb_fixnum_value(0);
    2063   }
    20642104  if (base <= 0) {
    2065     if (str[0] == '0') {
    2066       switch (str[1]) {
     2105    if (p[0] == '0') {
     2106      switch (p[1]) {
    20672107        case 'x': case 'X':
    20682108          base = 16;
     
    20792119        default:
    20802120          base = 8;
     2121          break;
    20812122      }
    20822123    }
     
    20902131  switch (base) {
    20912132    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;
    20942135      }
    20952136      break;
     
    20972138      break;
    20982139    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;
    21012142      }
    21022143    case 4: case 5: case 6: case 7:
    21032144      break;
    21042145    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;
    21072148      }
    21082149    case 9: case 11: case 12: case 13: case 14: case 15:
    21092150      break;
    21102151    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;
    21132154      }
    21142155      break;
     
    21192160      break;
    21202161  } /* 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) {
    21362163    if (badcheck) goto bad;
    21372164    return mrb_fixnum_value(0);
    21382165  }
    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++) {
    21422190    if (*p == '_') {
    2143       if (uscore == 0) {
    2144         uscore++;
     2191      p++;
     2192      if (p==pend) {
     2193        if (badcheck) goto bad;
    21452194        continue;
    21462195      }
    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    }
    21512204    c = conv_digit(*p);
    21522205    if (c < 0 || c >= base) {
    2153       if (badcheck) goto bad;
    21542206      break;
    21552207    }
    21562208    n *= base;
    21572209    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;
    21632216  if (badcheck) {
    21642217    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 */
    21672220  }
    21682221
    21692222  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)));
    21722229  /* not reached */
    21732230  return mrb_fixnum_value(0);
     2231}
     2232
     2233MRB_API mrb_value
     2234mrb_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);
    21742237}
    21752238
     
    21832246
    21842247  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    }
    21852252    mrb_str_modify(mrb, ps);
    21862253    return RSTR_PTR(ps);
     
    21952262  mrb_int len;
    21962263
    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);
    22122267}
    22132268
     
    22602315    return 0.0;
    22612316  }
    2262   d = strtod(p, &end);
     2317  d = mrb_float_read(p, &end);
    22632318  if (p == end) {
    22642319    if (badcheck) {
     
    22982353    }
    22992354
    2300     d = strtod(p, &end);
     2355    d = mrb_float_read(p, &end);
    23012356    if (badcheck) {
    23022357      if (!end || p == end) goto bad;
     
    26032658#endif
    26042659    c = *p;
    2605     if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p, pend))) {
     2660    if (c == '"'|| c == '\\' || (c == '#' && IS_EVSTR(p+1, pend))) {
    26062661      buf[0] = '\\'; buf[1] = c;
    26072662      mrb_str_cat(mrb, result, buf, 2);
     
    26892744  mrb_define_method(mrb, s, "chomp",           mrb_str_chomp,           MRB_ARGS_ANY());  /* 15.2.10.5.9  */
    26902745  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 */
    26932748  mrb_define_method(mrb, s, "downcase",        mrb_str_downcase,        MRB_ARGS_NONE()); /* 15.2.10.5.13 */
    26942749  mrb_define_method(mrb, s, "downcase!",       mrb_str_downcase_bang,   MRB_ARGS_NONE()); /* 15.2.10.5.14 */
     
    27202775  mrb_define_method(mrb, s, "inspect",         mrb_str_inspect,         MRB_ARGS_NONE()); /* 15.2.10.5.46(x) */
    27212776  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
     2799static 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                                     */
     2804static 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
     2816MRB_API double
     2817mrb_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
     3013done:
     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.