Commit a0aa753a authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #1167 from h2so5/refactor-mrb-strdump

Refactor mrb_str_dump
parents 887339dc a4d59b4c
...@@ -2252,105 +2252,119 @@ mrb_str_upcase(mrb_state *mrb, mrb_value self) ...@@ -2252,105 +2252,119 @@ mrb_str_upcase(mrb_state *mrb, mrb_value self)
mrb_value mrb_value
mrb_str_dump(mrb_state *mrb, mrb_value str) mrb_str_dump(mrb_state *mrb, mrb_value str)
{ {
mrb_int len; mrb_int len;
const char *p, *pend; const char *p, *pend;
char *q; char *q;
struct RString *result; struct RString *result;
len = 2; /* "" */
p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
while (p < pend) {
unsigned char c = *p++;
switch (c) {
case '"': case '\\':
case '\n': case '\r':
case '\t': case '\f':
case '\013': case '\010': case '\007': case '\033':
len += 2;
break;
case '#':
len += IS_EVSTR(p, pend) ? 2 : 1;
break;
default: len = 2; /* "" */
if (ISPRINT(c)) { p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
len++; while (p < pend) {
} unsigned char c = *p++;
else { switch (c) {
len += 4; /* \NNN */ case '"': case '\\':
} case '\n': case '\r':
break; case '\t': case '\f':
} case '\013': case '\010': case '\007': case '\033':
len += 2;
break;
case '#':
len += IS_EVSTR(p, pend) ? 2 : 1;
break;
default:
if (ISPRINT(c)) {
len++;
}
else {
len += 4; /* \NNN */
}
break;
} }
}
result = str_new(mrb, 0, len); result = str_new(mrb, 0, len);
str_with_class(mrb, result, str); str_with_class(mrb, result, str);
p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str); p = RSTRING_PTR(str); pend = p + RSTRING_LEN(str);
q = result->ptr; q = result->ptr;
*q++ = '"';
while (p < pend) {
unsigned char c = *p++;
if (c == '"' || c == '\\') { *q++ = '"';
*q++ = '\\'; while (p < pend) {
*q++ = c; unsigned char c = *p++;
}
else if (c == '#') { switch (c) {
if (IS_EVSTR(p, pend)) *q++ = '\\'; case '"':
*q++ = '#'; case '\\':
} *q++ = '\\';
else if (c == '\n') { *q++ = c;
*q++ = '\\'; break;
*q++ = 'n';
} case '\n':
else if (c == '\r') { *q++ = '\\';
*q++ = '\\'; *q++ = 'n';
*q++ = 'r'; break;
}
else if (c == '\t') { case '\r':
*q++ = '\\'; *q++ = '\\';
*q++ = 't'; *q++ = 'r';
} break;
else if (c == '\f') {
*q++ = '\\'; case '\t':
*q++ = 'f'; *q++ = '\\';
} *q++ = 't';
else if (c == '\013') { break;
*q++ = '\\';
*q++ = 'v'; case '\f':
} *q++ = '\\';
else if (c == '\010') { *q++ = 'f';
*q++ = '\\'; break;
*q++ = 'b';
} case '\013':
else if (c == '\007') { *q++ = '\\';
*q++ = '\\'; *q++ = 'v';
*q++ = 'a'; break;
}
else if (c == '\033') { case '\010':
*q++ = '\\'; *q++ = '\\';
*q++ = 'e'; *q++ = 'b';
} break;
else if (ISPRINT(c)) {
case '\007':
*q++ = '\\';
*q++ = 'a';
break;
case '\033':
*q++ = '\\';
*q++ = 'e';
break;
case '#':
if (IS_EVSTR(p, pend)) *q++ = '\\';
*q++ = '#';
break;
default:
if (ISPRINT(c)) {
*q++ = c; *q++ = c;
} }
else { else {
mrb_value octstr; mrb_value octstr;
mrb_value chr; mrb_value chr;
const char *ptr; const char *ptr;
int len; int len;
chr = mrb_fixnum_value(c & 0xff); chr = mrb_fixnum_value(c & 0xff);
octstr = mrb_fixnum_to_str(mrb, chr, 8); octstr = mrb_fixnum_to_str(mrb, chr, 8);
ptr = mrb_str_body(octstr, &len); ptr = mrb_str_body(octstr, &len);
memcpy(q, "\\000", 4); memcpy(q, "\\000", 4);
memcpy(q + 4 - len, ptr, len); memcpy(q + 4 - len, ptr, len);
q += 4; q += 4;
} }
} }
*q++ = '"'; }
return mrb_obj_value(result); *q++ = '"';
return mrb_obj_value(result);
} }
mrb_value mrb_value
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment