void print_foxinfo() { StrBuf sb; StrBuf_init(&sb, 32); StrBuf_add(&sb, "foxw ", -1); StrBuf_printf(&sb, "%d.%d.%d", FOX_VERSION_MAJOR, FOX_VERSION_MINOR, FOX_VERSION_REVISION); StrBuf_printf(&sb, ", %dbit", (int)sizeof(void*) * 8); #ifndef NO_DEBUG StrBuf_add(&sb, " (debug-build)", -1); #endif show_error_message(sb.p, sb.size, TRUE); StrBuf_close(&sb); }
/** * 文字コードを変換しながらStreamに出力する * v : stream (optional,sb==NULLの場合必須) * sb : StrBuf : (optional) */ static int stream_write_sub_s(Value v, StrBuf *sb, const char *s_p, int s_size, RefTextIO *tio) { if (s_size < 0) { s_size = strlen(s_p); } // TODO:未検証 if (v != VALUE_NULL) { RefBytesIO *mb = Value_vp(v); if (mb->rh.type == fs->cls_bytesio) { sb = &mb->buf; } } if (sb != NULL) { // sprintfの場合tio==NULL if (tio == NULL || tio->cs->utf8) { if (!StrBuf_add(sb, s_p, s_size)) { return FALSE; } return TRUE; } else { if (tio->out.ic == (void*)-1) { if (!IconvIO_open(&tio->out, fs->cs_utf8, tio->cs, tio->trans ? "?" : NULL)) { return FALSE; } } if (!IconvIO_conv(&tio->out, sb, s_p, s_size, TRUE, TRUE)) { return FALSE; } return TRUE; } } else { if (tio == NULL || tio->cs->utf8) { return stream_write_data(v, s_p, s_size); } else { Ref *r = Value_ref(v); IconvIO *ic = &tio->out; Value *vmb = &r->v[INDEX_WRITE_MEMIO]; RefBytesIO *mb; int max = Value_integral(r->v[INDEX_WRITE_MAX]); if (max == -1) { throw_error_select(THROW_NOT_OPENED_FOR_WRITE); return FALSE; } if (tio->out.ic == (void*)-1) { if (!IconvIO_open(&tio->out, fs->cs_utf8, tio->cs, tio->trans ? "?" : NULL)) { return FALSE; } } if (*vmb == VALUE_NULL) { *vmb = vp_Value(bytesio_new_sub(NULL, BUFFER_SIZE)); max = BUFFER_SIZE; r->v[INDEX_WRITE_MAX] = int32_Value(max); // STDOUTだけ特別扱い if (fs->cgi_mode) { if (r == Value_vp(fg->v_cio)) { send_headers(); } } } mb = Value_vp(*vmb); ic->inbuf = s_p; ic->inbytesleft = s_size; ic->outbuf = mb->buf.p + mb->buf.size; ic->outbytesleft = max - mb->buf.size; for (;;) { switch (IconvIO_next(ic)) { case ICONV_OK: mb->buf.size = ic->outbuf - mb->buf.p; goto BREAK; case ICONV_OUTBUF: mb->buf.size = ic->outbuf - mb->buf.p; if (!stream_flush_sub(v)) { return FALSE; } ic->outbuf = mb->buf.p; ic->outbytesleft = max; break; case ICONV_INVALID: if (tio->trans) { const char *ptr; if (ic->outbytesleft == 0) { mb->buf.size = ic->outbuf - mb->buf.p; if (!stream_flush_sub(v)) { return FALSE; } ic->outbuf = mb->buf.p; ic->outbytesleft = max; } ptr = ic->inbuf; *ic->outbuf++ = '?'; ic->outbytesleft--; // 1文字進める utf8_next(&ptr, ptr + ic->inbytesleft); ic->inbytesleft -= ptr - ic->inbuf; ic->inbuf = ptr; } else { RefCharset *cs = tio->cs; throw_errorf(fs->mod_lang, "CharsetError", "Cannot convert %U to %S", utf8_codepoint_at(ic->inbuf), cs->name); return FALSE; } break; } } BREAK: return TRUE; } } }