Beispiel #1
0
/*------------------------------------------------------------
 * 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);
    }
}
Beispiel #2
0
/* 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)));
}
Beispiel #3
0
/* 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);
    }
}