diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dump.c | 6 | ||||
| -rw-r--r-- | src/load.c | 2 | ||||
| -rw-r--r-- | src/string.c | 8 | ||||
| -rw-r--r-- | src/symbol.c | 111 | ||||
| -rw-r--r-- | src/time.c | 114 |
5 files changed, 170 insertions, 71 deletions
diff --git a/src/dump.c b/src/dump.c index f3cbef3a0..7b2199a02 100644 --- a/src/dump.c +++ b/src/dump.c @@ -268,8 +268,10 @@ get_syms_block_size(mrb_state *mrb, mrb_irep *irep, int type) size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type); /* snl(n) */ if (irep->syms[sym_no] != 0) { - name = mrb_sym2name(mrb, irep->syms[sym_no]); - nlen = str_dump_len((char*)name, strlen(name), type); + int len; + + name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len); + nlen = str_dump_len((char*)name, len, type); size += nlen; /* sn(n) */ } } diff --git a/src/load.c b/src/load.c index c0684f1aa..1b607909c 100644 --- a/src/load.c +++ b/src/load.c @@ -477,7 +477,7 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32 memcpy(buf, src, snl); //symbol name src += snl; buf[snl] = '\0'; - irep->syms[i] = mrb_intern(mrb, buf); + irep->syms[i] = mrb_intern2(mrb, buf, snl); } } crc = calc_crc_16_ccitt((unsigned char*)pStart, src - pStart); //Calculate CRC diff --git a/src/string.c b/src/string.c index d09d8942b..805b52a28 100644 --- a/src/string.c +++ b/src/string.c @@ -1616,12 +1616,6 @@ mrb_str_init(mrb_state *mrb, mrb_value self) return self; } -mrb_sym -mrb_intern_str(mrb_state *mrb, mrb_value str) -{ - return mrb_intern(mrb, RSTRING_PTR(str)); -} - /* 15.2.10.5.25 */ /* 15.2.10.5.41 */ /* @@ -2817,7 +2811,7 @@ mrb_str_dump(mrb_state *mrb, mrb_value str) len++; } else { - len += 4; /* \xNN */ + len += 4; /* \NNN */ } break; } diff --git a/src/symbol.c b/src/symbol.c index d09833689..6754325a5 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -17,59 +17,94 @@ #include <stdio.h> /* ------------------------------------------------------ */ -KHASH_INIT(s2n, mrb_sym, const char*, 1, kh_int_hash_func, kh_int_hash_equal) -KHASH_MAP_INIT_STR(n2s, mrb_sym); +typedef struct symbol_name { + int len; + const char *name; +} symbol_name; + +static inline khint_t +sym_hash_func(mrb_state *mrb, const symbol_name s) +{ + khint_t h = 0; + size_t i; + const char *p = s.name; + + for (i=0; i<s.len; i++) { + h = (h << 5) - h + *p++; + } + return h; +} +#define sym_hash_equal(mrb,a, b) (a.len == b.len && memcmp(a.name, b.name, a.len) == 0) + +KHASH_INIT(n2s, symbol_name, mrb_sym, 1, sym_hash_func, sym_hash_equal) /* ------------------------------------------------------ */ mrb_sym -mrb_intern(mrb_state *mrb, const char *name) +mrb_intern2(mrb_state *mrb, const char *name, int len) { khash_t(n2s) *h = mrb->name2sym; - khash_t(s2n) *rh = mrb->sym2name; + symbol_name sname; khiter_t k; - size_t len; - char *p; mrb_sym sym; + char *p; - k = kh_get(n2s, h, name); + sname.len = len; + sname.name = name; + k = kh_get(n2s, h, sname); if (k != kh_end(h)) return kh_value(h, k); sym = ++mrb->symidx; - len = strlen(name); p = mrb_malloc(mrb, len+1); memcpy(p, name, len); p[len] = 0; - k = kh_put(n2s, h, p); + sname.name = (const char*)p; + k = kh_put(n2s, h, sname); kh_value(h, k) = sym; - k = kh_put(s2n, rh, sym); - kh_value(rh, k) = p; - return sym; } +mrb_sym +mrb_intern(mrb_state *mrb, const char *name) +{ + return mrb_intern2(mrb, name, strlen(name)); +} + +mrb_sym +mrb_intern_str(mrb_state *mrb, mrb_value str) +{ + return mrb_intern2(mrb, RSTRING_PTR(str), RSTRING_LEN(str)); +} + const char* -mrb_sym2name(mrb_state *mrb, mrb_sym sym) +mrb_sym2name_len(mrb_state *mrb, mrb_sym sym, int *lenp) { - khash_t(s2n) *h = mrb->sym2name; + khash_t(n2s) *h = mrb->name2sym; khiter_t k; + symbol_name sname; - k = kh_get(s2n, h, sym); + for (k = kh_begin(h); k != kh_end(h); k++) { + if (kh_exist(h, k)) { + if (kh_value(h, k) == sym) break; + } + } if (k == kh_end(h)) { - return NULL; /* missing */ + *lenp = 0; + return NULL; /* missing */ } - return kh_value(h, k); + sname = kh_key(h, k); + *lenp = sname.len; + return sname.name; } void mrb_free_symtbls(mrb_state *mrb) { - khash_t(s2n) *h = mrb->sym2name; + khash_t(n2s) *h = mrb->name2sym; khiter_t k; - for (k = kh_begin(h); k != kh_end(h); ++k) - if (kh_exist(h, k)) mrb_free(mrb, (char*)kh_value(h, k)); - kh_destroy(s2n,mrb->sym2name); + for (k = kh_begin(h); k != kh_end(h); k++) + if (kh_exist(h, k)) mrb_free(mrb, (char*)kh_key(h, k).name); kh_destroy(n2s,mrb->name2sym); } @@ -77,7 +112,6 @@ void mrb_init_symtbl(mrb_state *mrb) { mrb->name2sym = kh_init(n2s, mrb); - mrb->sym2name = kh_init(s2n, mrb); } /********************************************************************** @@ -148,8 +182,11 @@ mrb_value mrb_sym_to_s(mrb_state *mrb, mrb_value sym) { mrb_sym id = SYM2ID(sym); + const char *p; + int len; - return mrb_str_new_cstr(mrb, mrb_sym2name(mrb, id)); + p = mrb_sym2name_len(mrb, id, &len); + return mrb_str_new(mrb, p, len); } /* 15.2.11.3.4 */ @@ -253,7 +290,9 @@ symname_p(const char *name) case '*': if (*++m == '*') ++m; break; - + case '!': + if (*++m == '=') ++m; + break; case '+': case '-': if (*++m == '@') ++m; break; @@ -287,19 +326,35 @@ sym_inspect(mrb_state *mrb, mrb_value sym) { mrb_value str; const char *name; + int len; mrb_sym id = SYM2ID(sym); - name = mrb_sym2name(mrb, id); //mrb_id2name(id); - str = mrb_str_new(mrb, 0, strlen(name)+1); + name = mrb_sym2name_len(mrb, id, &len); + str = mrb_str_new(mrb, 0, len+1); RSTRING(str)->buf[0] = ':'; - strcpy(RSTRING(str)->buf+1, name); - if (!symname_p(name)) { + memcpy(RSTRING(str)->buf+1, name, len); + if (!symname_p(name) || strlen(name) != len) { str = mrb_str_dump(mrb, str); strncpy(RSTRING(str)->buf, ":\"", 2); } return str; } +const char* +mrb_sym2name(mrb_state *mrb, mrb_sym sym) +{ + int len; + const char *name = mrb_sym2name_len(mrb, sym, &len); + + if (!name) return NULL; + if (symname_p(name) && strlen(name) == len) { + return name; + } + else { + mrb_value str = mrb_str_dump(mrb, mrb_str_new(mrb, name, len)); + return RSTRING(str)->buf; + } +} void mrb_init_symbols(mrb_state *mrb) diff --git a/src/time.c b/src/time.c index a6f1e4d1f..862ff57a9 100644 --- a/src/time.c +++ b/src/time.c @@ -363,8 +363,11 @@ mrb_time_minus(mrb_state *mrb, mrb_value self) return mrb_float_value(f); } else { - mrb_get_args(mrb, "f", &f); - return mrb_time_make(mrb, mrb_obj_class(mrb, self), f, tm->timezone); + mrb_float f, f2; + mrb_get_args(mrb, "f", &f2); + + f = ((mrb_float)tm->sec + (mrb_float)tm->usec/1.0e6); + return mrb_time_make(mrb, mrb_obj_class(mrb, self), f-f2, tm->timezone); } } @@ -463,6 +466,39 @@ mrb_time_dstp(mrb_state *mrb, mrb_value self) return mrb_bool_value(tm->datetime.tm_isdst); } +/* 15.2.19.7.8 */ +/* 15.2.19.7.10 */ +/* Returns the Time object of the UTC(GMT) timezone. */ +static mrb_value +mrb_time_getutc(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm, *tm2; + + tm = mrb_get_datatype(mrb, self, &mrb_time_type); + if (!tm) return self; + tm2 = mrb_malloc(mrb, sizeof(*tm)); + *tm2 = *tm; + tm2->timezone = MRB_TIMEZONE_UTC; + mrb_time_update_datetime(tm2); + return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); +} + +/* 15.2.19.7.9 */ +/* Returns the Time object of the LOCAL timezone. */ +static mrb_value +mrb_time_getlocal(mrb_state *mrb, mrb_value self) +{ + struct mrb_time *tm, *tm2; + + tm = mrb_get_datatype(mrb, self, &mrb_time_type); + if (!tm) return self; + tm2 = mrb_malloc(mrb, sizeof(*tm)); + *tm2 = *tm; + tm2->timezone = MRB_TIMEZONE_LOCAL; + mrb_time_update_datetime(tm2); + return mrb_time_wrap(mrb, mrb_obj_class(mrb, self), tm2); +} + /* 15.2.19.7.15 */ /* Returns hour of time. */ static mrb_value @@ -656,41 +692,53 @@ mrb_init_time(mrb_state *mrb) tc = mrb_define_class(mrb, "Time", mrb->object_class); MRB_SET_INSTANCE_TT(tc, MRB_TT_DATA); mrb_include_module(mrb, tc, mrb_class_get(mrb, "Comparable")); - mrb_define_class_method(mrb, tc, "now", mrb_time_now, ARGS_NONE()); - mrb_define_class_method(mrb, tc, "at", mrb_time_at, ARGS_ANY()); - mrb_define_class_method(mrb, tc, "gm", mrb_time_gm, ARGS_REQ(1)|ARGS_OPT(6)); - mrb_define_class_method(mrb, tc, "local", mrb_time_local, ARGS_REQ(1)|ARGS_OPT(6)); + mrb_define_class_method(mrb, tc, "at", mrb_time_at, ARGS_ANY()); /* 15.2.19.6.1 */ + mrb_define_class_method(mrb, tc, "gm", mrb_time_gm, ARGS_REQ(1)|ARGS_OPT(6)); /* 15.2.19.6.2 */ + mrb_define_class_method(mrb, tc, "local", mrb_time_local, ARGS_REQ(1)|ARGS_OPT(6)); /* 15.2.19.6.3 */ + mrb_define_class_method(mrb, tc, "mktime", mrb_time_local, ARGS_REQ(1)|ARGS_OPT(6));/* 15.2.19.6.4 */ + mrb_define_class_method(mrb, tc, "now", mrb_time_now, ARGS_NONE()); /* 15.2.19.6.5 */ + mrb_define_class_method(mrb, tc, "utc", mrb_time_gm, ARGS_REQ(1)|ARGS_OPT(6)); /* 15.2.19.6.6 */ mrb_define_method(mrb, tc, "==" , mrb_time_eq , ARGS_REQ(1)); - mrb_define_method(mrb, tc, "<=>" , mrb_time_cmp , ARGS_REQ(1)); - mrb_define_method(mrb, tc, "+" , mrb_time_plus , ARGS_REQ(1)); - mrb_define_method(mrb, tc, "-" , mrb_time_minus , ARGS_REQ(1)); + mrb_define_method(mrb, tc, "<=>" , mrb_time_cmp , ARGS_REQ(1)); /* 15.2.19.7.1 */ + mrb_define_method(mrb, tc, "+" , mrb_time_plus , ARGS_REQ(1)); /* 15.2.19.7.2 */ + mrb_define_method(mrb, tc, "-" , mrb_time_minus , ARGS_REQ(1)); /* 15.2.19.7.3 */ mrb_define_method(mrb, tc, "to_s" , mrb_time_asctime, ARGS_NONE()); - mrb_define_method(mrb, tc, "asctime", mrb_time_asctime, ARGS_NONE()); - mrb_define_method(mrb, tc, "ctime" , mrb_time_asctime, ARGS_NONE()); - mrb_define_method(mrb, tc, "day" , mrb_time_day , ARGS_NONE()); - mrb_define_method(mrb, tc, "dst?" , mrb_time_dstp , ARGS_NONE()); - mrb_define_method(mrb, tc, "gmt?" , mrb_time_utcp , ARGS_NONE()); - mrb_define_method(mrb, tc, "gmtime" , mrb_time_utc , ARGS_NONE()); - mrb_define_method(mrb, tc, "hour" , mrb_time_hour, ARGS_NONE()); - mrb_define_method(mrb, tc, "localtime", mrb_time_localtime, ARGS_NONE()); - mrb_define_method(mrb, tc, "mday" , mrb_time_mday, ARGS_NONE()); - mrb_define_method(mrb, tc, "min" , mrb_time_min, ARGS_NONE()); + mrb_define_method(mrb, tc, "asctime", mrb_time_asctime, ARGS_NONE()); /* 15.2.19.7.4 */ + mrb_define_method(mrb, tc, "ctime" , mrb_time_asctime, ARGS_NONE()); /* 15.2.19.7.5 */ + mrb_define_method(mrb, tc, "day" , mrb_time_day , ARGS_NONE()); /* 15.2.19.7.6 */ + mrb_define_method(mrb, tc, "dst?" , mrb_time_dstp , ARGS_NONE()); /* 15.2.19.7.7 */ + mrb_define_method(mrb, tc, "getgm" , mrb_time_getutc , ARGS_NONE()); /* 15.2.19.7.8 */ + mrb_define_method(mrb, tc, "getlocal",mrb_time_getlocal,ARGS_NONE()); /* 15.2.19.7.9 */ + mrb_define_method(mrb, tc, "getutc" , mrb_time_getutc , ARGS_NONE()); /* 15.2.19.7.10 */ + mrb_define_method(mrb, tc, "gmt?" , mrb_time_utcp , ARGS_NONE()); /* 15.2.19.7.11 */ + mrb_define_method(mrb, tc, "gmtime" , mrb_time_utc , ARGS_NONE()); /* 15.2.19.7.13 */ + mrb_define_method(mrb, tc, "hour" , mrb_time_hour, ARGS_NONE()); /* 15.2.19.7.15 */ + mrb_define_method(mrb, tc, "localtime", mrb_time_localtime, ARGS_NONE()); /* 15.2.19.7.18 */ + mrb_define_method(mrb, tc, "mday" , mrb_time_mday, ARGS_NONE()); /* 15.2.19.7.19 */ + mrb_define_method(mrb, tc, "min" , mrb_time_min, ARGS_NONE()); /* 15.2.19.7.20 */ - mrb_define_method(mrb, tc, "mon" , mrb_time_mon, ARGS_NONE()); - mrb_define_method(mrb, tc, "month", mrb_time_mon, ARGS_NONE()); + mrb_define_method(mrb, tc, "mon" , mrb_time_mon, ARGS_NONE()); /* 15.2.19.7.21 */ + mrb_define_method(mrb, tc, "month", mrb_time_mon, ARGS_NONE()); /* 15.2.19.7.22 */ - mrb_define_method(mrb, tc, "sec" , mrb_time_sec, ARGS_NONE()); - mrb_define_method(mrb, tc, "to_i", mrb_time_to_i, ARGS_NONE()); - mrb_define_method(mrb, tc, "to_f", mrb_time_to_f, ARGS_NONE()); - mrb_define_method(mrb, tc, "usec", mrb_time_usec, ARGS_NONE()); - mrb_define_method(mrb, tc, "utc" , mrb_time_utc, ARGS_NONE()); - mrb_define_method(mrb, tc, "utc?", mrb_time_utcp, ARGS_NONE()); - mrb_define_method(mrb, tc, "wday", mrb_time_wday, ARGS_NONE()); - mrb_define_method(mrb, tc, "yday", mrb_time_yday, ARGS_NONE()); - mrb_define_method(mrb, tc, "year", mrb_time_year, ARGS_NONE()); - mrb_define_method(mrb, tc, "zone", mrb_time_zone, ARGS_NONE()); + mrb_define_method(mrb, tc, "sec" , mrb_time_sec, ARGS_NONE()); /* 15.2.19.7.23 */ + mrb_define_method(mrb, tc, "to_i", mrb_time_to_i, ARGS_NONE()); /* 15.2.19.7.25 */ + mrb_define_method(mrb, tc, "to_f", mrb_time_to_f, ARGS_NONE()); /* 15.2.19.7.24 */ + mrb_define_method(mrb, tc, "usec", mrb_time_usec, ARGS_NONE()); /* 15.2.19.7.26 */ + mrb_define_method(mrb, tc, "utc" , mrb_time_utc, ARGS_NONE()); /* 15.2.19.7.27 */ + mrb_define_method(mrb, tc, "utc?", mrb_time_utcp, ARGS_NONE()); /* 15.2.19.7.28 */ + mrb_define_method(mrb, tc, "wday", mrb_time_wday, ARGS_NONE()); /* 15.2.19.7.30 */ + mrb_define_method(mrb, tc, "yday", mrb_time_yday, ARGS_NONE()); /* 15.2.19.7.31 */ + mrb_define_method(mrb, tc, "year", mrb_time_year, ARGS_NONE()); /* 15.2.19.7.32 */ + mrb_define_method(mrb, tc, "zone", mrb_time_zone, ARGS_NONE()); /* 15.2.19.7.33 */ - mrb_define_method(mrb, tc, "initialize", mrb_time_initialize, ARGS_REQ(1)); - mrb_define_method(mrb, tc, "initialize_copy", mrb_time_initialize_copy, ARGS_REQ(1)); + mrb_define_method(mrb, tc, "initialize", mrb_time_initialize, ARGS_REQ(1)); /* 15.2.19.7.16 */ + mrb_define_method(mrb, tc, "initialize_copy", mrb_time_initialize_copy, ARGS_REQ(1)); /* 15.2.19.7.17 */ + + /* + methods not available: + gmt_offset(15.2.19.7.12) + gmtoff(15.2.19.7.14) + utc_offset(15.2.19.7.29) + */ } |
