/*------------------------------------------------------------ * Vport puts */ static void vport_puts(ScmString *s, ScmPort *p) { vport *data = (vport*)p->src.vt.data; const ScmStringBody *b = SCM_STRING_BODY(s); SCM_ASSERT(data != NULL); if (!SCM_FALSEP(data->puts_proc)) { Scm_ApplyRec(data->puts_proc, SCM_LIST1(SCM_OBJ(s))); } else if (SCM_STRING_BODY_INCOMPLETE_P(b) || (SCM_FALSEP(data->putc_proc) && !SCM_FALSEP(data->putb_proc))) { /* we perform binary output */ vport_putz(SCM_STRING_BODY_START(b), SCM_STRING_BODY_SIZE(b), p); } else if (!SCM_FALSEP(data->putc_proc)) { ScmChar c; int i; const char *cp = SCM_STRING_BODY_START(b); for (i=0; i < (int)SCM_STRING_BODY_LENGTH(b); i++) { SCM_CHAR_GET(cp, c); cp += SCM_CHAR_NFOLLOWS(*cp)+1; Scm_ApplyRec(data->putc_proc, SCM_LIST1(SCM_MAKE_CHAR(c))); } } else { Scm_PortError(p, SCM_PORT_ERROR_OTHER, "cannot perform output to the port %S", p); } }
/* If symbol S has a prefix P, returns a symbol without the prefix. Otherwise, returns #f. */ ScmObj Scm_SymbolSansPrefix(ScmSymbol *s, ScmSymbol *p) { const ScmStringBody *bp = SCM_STRING_BODY(SCM_SYMBOL_NAME(p)); const ScmStringBody *bs = SCM_STRING_BODY(SCM_SYMBOL_NAME(s)); int zp = SCM_STRING_BODY_SIZE(bp); int zs = SCM_STRING_BODY_SIZE(bs); const char *cp = SCM_STRING_BODY_START(bp); const char *cs = SCM_STRING_BODY_START(bs); if (zp > zs || memcmp(cp, cs, zp) != 0) return SCM_FALSE; return Scm_Intern(SCM_STRING(Scm_MakeString(cs + zp, zs - zp, -1, SCM_STRING_IMMUTABLE))); }
/* internal function to write symbol name, with proper escaping */ void Scm_WriteSymbolName(ScmString *snam, ScmPort *port, ScmWriteContext *ctx, u_int flags) { /* See if we have special characters, and use |-escape if necessary. */ /* TODO: For now, we regard chars over 0x80 is all "printable". Need a more consistent mechanism. */ const ScmStringBody *b = SCM_STRING_BODY(snam); const char *p = SCM_STRING_BODY_START(b); int siz = SCM_STRING_BODY_SIZE(b); int escape = FALSE; int spmask = (Scm_WriteContextCase(ctx) == SCM_WRITE_CASE_FOLD)? 0x12 : 0x02; if (siz == 0) { /* special case */ if (!(flags & SCM_SYMBOL_WRITER_NOESCAPE_EMPTY)) { SCM_PUTZ("||", -1, port); } return; } if (siz == 1 && (*p == '+' || *p == '-')) { SCM_PUTC((unsigned)*p, port); return; } if ((unsigned int)*p < 128 && (special[(unsigned int)*p]&1) #if GAUCHE_UNIFY_SYMBOL_KEYWORD && (*p != ':') #endif && (!(flags & SCM_SYMBOL_WRITER_NOESCAPE_INITIAL))) { escape = TRUE; } else { const char *q = p; for (int i=0; i<siz; i++, q++) { if ((unsigned int)*q < 128 && (special[(unsigned int)*q]&spmask)) { escape = TRUE; break; } } } if (escape) { SCM_PUTC('|', port); for (const char *q=p; q<p+siz; ) { unsigned int ch; SCM_CHAR_GET(q, ch); q += SCM_CHAR_NBYTES(ch); if (ch < 128) { if (special[ch] & 8) { SCM_PUTC('\\', port); SCM_PUTC(ch, port); } else if (special[ch] & 4) { Scm_Printf(port, "\\x%02x;", ch); } else { SCM_PUTC(ch, port); } } else { SCM_PUTC(ch, port); } } SCM_PUTC('|', port); return; } else { SCM_PUTS(snam, port); } }