mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
symbol can contain non printable characters
This commit is contained in:
@@ -332,6 +332,8 @@ mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, int,...);
|
||||
mrb_value mrb_funcall_argv(mrb_state*, mrb_value, const char*, int, mrb_value*);
|
||||
mrb_value mrb_funcall_with_block(mrb_state*, mrb_value, const char*, int, mrb_value*, mrb_value);
|
||||
mrb_sym mrb_intern(mrb_state*,const char*);
|
||||
mrb_sym mrb_intern2(mrb_state*,const char*, int);
|
||||
mrb_sym mrb_intern_str(mrb_state*,mrb_value);
|
||||
const char *mrb_sym2name(mrb_state*,mrb_sym);
|
||||
mrb_value mrb_str_format(mrb_state *, int, const mrb_value *, mrb_value);
|
||||
|
||||
|
||||
+1
-7
@@ -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;
|
||||
}
|
||||
|
||||
+84
-30
@@ -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 && strcmp(a.name, b.name) == 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;
|
||||
}
|
||||
|
||||
const char*
|
||||
mrb_sym2name(mrb_state *mrb, mrb_sym sym)
|
||||
mrb_sym
|
||||
mrb_intern(mrb_state *mrb, const char *name)
|
||||
{
|
||||
khash_t(s2n) *h = mrb->sym2name;
|
||||
khiter_t k;
|
||||
return mrb_intern2(mrb, name, strlen(name));
|
||||
}
|
||||
|
||||
k = kh_get(s2n, h, sym);
|
||||
if (k == kh_end(h)) {
|
||||
return NULL; /* missing */
|
||||
mrb_sym
|
||||
mrb_intern_str(mrb_state *mrb, mrb_value str)
|
||||
{
|
||||
return mrb_intern2(mrb, RSTRING_PTR(str), RSTRING_LEN(str));
|
||||
}
|
||||
|
||||
static const char*
|
||||
sym2name_len(mrb_state *mrb, mrb_sym sym, int *lenp)
|
||||
{
|
||||
khash_t(n2s) *h = mrb->name2sym;
|
||||
khiter_t k;
|
||||
symbol_name sname;
|
||||
|
||||
for (k = kh_begin(h); k != kh_end(h); k++) {
|
||||
if (kh_exist(h, k)) {
|
||||
if (kh_value(h, k) == sym) break;
|
||||
}
|
||||
}
|
||||
return kh_value(h, k);
|
||||
if (k == kh_end(h)) {
|
||||
*lenp = 0;
|
||||
return NULL; /* missing */
|
||||
}
|
||||
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 = sym2name_len(mrb, id, &len);
|
||||
return mrb_str_new(mrb, p, len);
|
||||
}
|
||||
|
||||
/* 15.2.11.3.4 */
|
||||
@@ -287,19 +324,36 @@ 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 = 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 = 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)
|
||||
|
||||
Reference in New Issue
Block a user