From: Nobuyoshi Nakada Date: 2008-07-21T16:31:02+09:00 Subject: [ruby-dev:35614] Re: [request]C APIの拡張 なかだです。 At Mon, 21 Jul 2008 12:23:42 +0900, Goro Fuji wrote in [ruby-dev:35611]: > 1.1 rb_str_catf()の需要 > > このことから,catf()についてはそれなりの需要があるのではないかと考えました。 たしかに需要はそこそこあるようですね。あとは名前かな。ちなみに、 [ruby-dev:35597]のパッチでは実際のcapaを考慮せずに120byte空いて いるとみなしているのでまずいです。 > 1.2 rb_str_newf()の需要 > > それではなぜrb_sprintf()ではなく,s(n)printf()とrb_str_new2() > を使っているのかということになります その多くは、rb_sprintf()が追加される以前からのコードではないでしょ うか。単に、検証済みのコードをわざわざ全部書き直すことはしていな いだけだと思います。 > (1) README.EXT(.ja)に載っていないため 簡単ながら追加しておきました。説明の改善は歓迎です。 > また,今回の議論は,s(n)printf()はバッファサイズの妥当性を検証 > することが難しく,使用を避けた方が良いということを前提としてい > ますが,私はこの点を強く感じすぎているかもしれません。 これは以前取り上げられた問題でして、既存のコードの検証と rb_sprintf()の追加ということになったと思います。 > print()とprintf()の違いがfだけなのでそれで十分かと思ってしまい > ました。名前については特にこだわりはありません。Rubyの慣習に従 > うならば,rb_str_new6()ということになるでしょうか。 もうnew+数字はやめましょうよ。すでにあるものはともかく、今さら増 やすことはないでしょう。 Index: string.c =================================================================== --- string.c (revision 18141) +++ string.c (working copy) @@ -341,4 +341,18 @@ str_frozen_check(VALUE s) } +size_t +rb_str_capacity(VALUE str) +{ + if (STR_EMBED_P(str)) { + return RSTRING_EMBED_LEN_MAX; + } + else if (STR_NOCAPA_P(str)) { + return RSTRING(str)->as.heap.len; + } + else { + return RSTRING(str)->as.heap.aux.capa; + } +} + static inline VALUE str_alloc(VALUE klass) Index: sprintf.c =================================================================== --- sprintf.c (revision 18142) +++ sprintf.c (working copy) @@ -1116,2 +1116,39 @@ rb_sprintf(const char *format, ...) return result; } + +extern size_t rb_str_capacity(VALUE); + +VALUE +rb_append_vsprintf(VALUE str, const char *fmt, va_list ap) +{ + rb_printf_buffer f; + VALUE klass; + + StringValue(str); + rb_str_modify(str); + f._flags = __SWR | __SSTR; + f._bf._size = 0; + f._w = rb_str_capacity(str); + f._bf._base = (unsigned char *)str; + f._p = (unsigned char *)RSTRING_END(str); + klass = RBASIC(str)->klass; + RBASIC(str)->klass = 0; + f.vwrite = ruby__sfvwrite; + BSD_vfprintf(&f, fmt, ap); + RBASIC(str)->klass = klass; + rb_str_resize(str, (char *)f._p - RSTRING_PTR(str)); + + return str; +} + +VALUE +rb_append_sprintf(VALUE str, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + str = rb_append_vsprintf(str, format, ap); + va_end(ap); + + return str; +} -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦