/* * call-seq: * str.dump => new_str * * Produces a version of <i>str</i> with all nonprinting characters replaced by * <code>\nnn</code> notation and all special characters escaped. */ VALUE rb_str_dump(str) VALUE str; { long len; char *p, *pend; char *q, *qend; VALUE result; len = 2; /* "" */ p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len; while (p < pend) { 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: if (ISPRINT(c)) { len++; } else { len += 4; /* \nnn */ } break; } } result = rb_str_new5(str, 0, len); p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len; q = RSTRING(result)->ptr; qend = q + len; *q++ = '"'; while (p < pend) { char c = *p++; if (c == '"' || c == '\\') { *q++ = '\\'; *q++ = c; } else if (c == '#') { if (IS_EVSTR(p, pend)) *q++ = '\\'; *q++ = '#'; } else if (ISPRINT(c)) { *q++ = c; } else if (c == '\n') { *q++ = '\\'; *q++ = 'n'; } else if (c == '\r') { *q++ = '\\'; *q++ = 'r'; } else if (c == '\t') { *q++ = '\\'; *q++ = 't'; } else if (c == '\f') { *q++ = '\\'; *q++ = 'f'; } else if (c == '\013') { *q++ = '\\'; *q++ = 'v'; } else if (c == '\010') { *q++ = '\\'; *q++ = 'b'; } else if (c == '\007') { *q++ = '\\'; *q++ = 'a'; } else if (c == '\033') { *q++ = '\\'; *q++ = 'e'; } else { *q++ = '\\'; sprintf(q, "%03o", c&0xff); q += 3; } } *q++ = '"'; OBJ_INFECT(result, str); return result; }