ScmObj Scm_KeywordToString(ScmKeyword *k) { #if GAUCHE_KEEP_DISJOINT_KEYWORD_OPTION if (keyword_disjoint_p) { return SCM_OBJ(k->name); } else { return Scm_Substring(k->name, 1, -1, FALSE); } #else /*!GAUCHE_KEEP_DISJOINT_KEYWORD_OPTION*/ return Scm_Substring(k->name, 1, -1, FALSE); #endif /*!GAUCHE_KEEP_DISJOINT_KEYWORD_OPTION*/ }
/* * Scm_WriteLimited - Write to limited length. * * Characters exceeding WIDTH are truncated. * If the output fits within WIDTH, # of characters actually written * is returned. Othewise, -1 is returned. * * Currently this API is only used from Scm_Printf, for 'format' has been * moved to libfmt.scm. I don't like the way this is implemented and would * like to share this with libfmt.scm eventually. */ int Scm_WriteLimited(ScmObj obj, ScmObj p, int mode, int width) { if (!SCM_OPORTP(p)) { Scm_Error("output port required, but got %S", p); } ScmPort *port = SCM_PORT(p); /* The walk pass does not produce any output, so we don't bother to create an intermediate string port. */ if (PORT_LOCK_OWNER_P(port, Scm_VM()) && PORT_WALKER_P(port)) { SCM_ASSERT(PORT_RECURSIVE_P(port)); write_walk(obj, port); return 0; /* doesn't really matter */ } ScmObj out = Scm_MakeOutputStringPort(TRUE); SCM_PORT(out)->writeState = SCM_PORT(port)->writeState; ScmWriteContext ctx; write_context_init(&ctx, mode, 0, width); /* We don't need to lock 'out', nor clean it up, for it is private. */ /* This part is a bit confusing - we only need to call write_ss if we're at the toplevel call. */ if (PORT_RECURSIVE_P(SCM_PORT(port))) { write_rec(obj, SCM_PORT(out), &ctx); } else if (WRITER_NEED_2PASS(&ctx)) { write_ss(obj, SCM_PORT(out), &ctx); } else { write_rec(obj, SCM_PORT(out), &ctx); } ScmString *str = SCM_STRING(Scm_GetOutputString(SCM_PORT(out), 0)); int nc = SCM_STRING_BODY_LENGTH(SCM_STRING_BODY(str)); if (nc > width) { ScmObj sub = Scm_Substring(str, 0, width, FALSE); SCM_PUTS(sub, port); /* this locks port */ return -1; } else { SCM_PUTS(str, port); /* this locks port */ return nc; } }