static int strio_data(Value *vret, Value *v, RefNode *node) { RefBytesIO *mb = Value_bytesio(*v); int begin, end; string_substr_position(&begin, &end, mb->buf.p, mb->buf.size, v); *vret = cstr_Value(fs->cls_str, mb->buf.p + begin, end - begin); return TRUE; }
static int strio_tostr(Value *vret, Value *v, RefNode *node) { RefBytesIO *mb = Value_bytesio(*v); if (fg->stk_top > v + 1) { Str s = Str_new(mb->buf.p, mb->buf.size); RefStr *fmt = Value_vp(v[1]); if (!string_format_sub(vret, s, fmt->c, fmt->size, FALSE)) { return FALSE; } } else { *vret = cstr_Value(fs->cls_str, mb->buf.p, mb->buf.size); } return TRUE; }
/** * printf("format", ...) * printf(locale, "format", ...) */ static int textio_printf(Value *vret, Value *v, RefNode *node) { int str = FUNC_INT(node); RefNode *v1_type = Value_type(v[1]); RefStr *s_fmt; Ref *r_loc = NULL; int start_arg; if (v1_type == fs->cls_str) { s_fmt = Value_vp(v[1]); start_arg = 2; } else if (v1_type == fs->cls_locale) { if (fg->stk_top > v + 2) { RefNode *v2_type = Value_type(v[2]); if (v2_type != fs->cls_str) { throw_error_select(THROW_ARGMENT_TYPE__NODE_NODE_INT, fs->cls_str, v2_type, 2); return FALSE; } } else { throw_errorf(fs->mod_lang, "ArgumentError", "2 or more arguments excepted (1 given)"); return FALSE; } r_loc = Value_ref(v[1]); s_fmt = Value_vp(v[2]); start_arg = 3; } else { throw_error_select(THROW_ARGMENT_TYPE2__NODE_NODE_NODE_INT, fs->cls_str, fs->cls_locale, v1_type, 1); return FALSE; } if (str) { // sprintf StrBuf buf; StrBuf_init(&buf, 0); if (!textio_printf_sub(VALUE_NULL, &buf, s_fmt, start_arg, r_loc)) { return FALSE; } *vret = cstr_Value(fs->cls_str, buf.p, buf.size); StrBuf_close(&buf); } else { if (!textio_printf_sub(*v, NULL, s_fmt, start_arg, r_loc)) { return FALSE; } } return TRUE; }
static int mapentry_tostr(Value *vret, Value *v, RefNode *node) { Ref *r = Value_ref(*v); StrBuf buf; StrBuf_init(&buf, 0); if (!StrBuf_printf(&buf, "Entry(%v, %v)", r->v[INDEX_ENTRY_KEY], r->v[INDEX_ENTRY_VAL])) { goto ERROR_END; } *vret = cstr_Value(fs->cls_str, buf.p, buf.size); StrBuf_close(&buf); return TRUE; ERROR_END: StrBuf_close(&buf); return FALSE; }
static int textio_gets_sub(Value *vret, Ref *ref, int trim) { Value stream = ref->v[INDEX_TEXTIO_STREAM]; StrBuf buf; Str result; int ret = TRUE; RefNode *s_type = Value_type(stream); if (s_type == fs->cls_bytesio) { buf.p = NULL; if (!bytesio_gets_sub(&result, stream)) { result.size = 0; } } else { StrBuf_init(&buf, 0); if (!stream_gets_sub(&buf, stream, '\n')) { StrBuf_close(&buf); return FALSE; } result = Str_new(buf.p, buf.size); } if (result.size > 0) { RefTextIO *tio = Value_vp(ref->v[INDEX_TEXTIO_TEXTIO]); if (trim) { // 末尾の改行を取り除く if (result.size > 0 && result.p[result.size - 1] == '\n') { result.size--; if (result.size > 0 && result.p[result.size - 1] == '\r') { result.size--; } } } if (tio->cs == fs->cs_utf8) { if (invalid_utf8_pos(result.p, result.size) >= 0) { if (tio->trans) { // 不正な文字をU+FFFDに置き換える *vret = cstr_Value_conv(result.p, result.size, NULL); } else { throw_error_select(THROW_INVALID_UTF8); ret = FALSE; goto FINALLY; } } else { *vret = cstr_Value(fs->cls_str, result.p, result.size); } } else { StrBuf buf2; if (tio->in.ic == (void*)-1) { if (!IconvIO_open(&tio->in, tio->cs, fs->cs_utf8, tio->trans ? UTF8_ALTER_CHAR : NULL)) { ret = FALSE; goto FINALLY; } } StrBuf_init(&buf2, result.size); if (!IconvIO_conv(&tio->in, &buf2, result.p, result.size, FALSE, TRUE)) { StrBuf_close(&buf2); ret = FALSE; goto FINALLY; } *vret = cstr_Value(fs->cls_str, buf2.p, buf2.size); StrBuf_close(&buf2); } } FINALLY: if (buf.p != NULL) { StrBuf_close(&buf); } return ret; }