From 70b317b9dababf3527deba01544e157f1c87375d Mon Sep 17 00:00:00 2001 From: nobu Date: Tue, 22 Jul 2008 07:48:00 +0000 Subject: * include/ruby/intern.h, sprintf.c (rb_str_catf, rb_str_vcatf): new functions. [ruby-dev:35597] * string.c (rb_str_capacity): new function to return the capacity. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@18156 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 7 +++++ README.EXT | 16 ++++++++--- README.EXT.ja | 79 ++++++++++++++++++++++++++++----------------------- include/ruby/intern.h | 3 ++ sprintf.c | 35 +++++++++++++++++++++++ string.c | 14 +++++++++ 6 files changed, 115 insertions(+), 39 deletions(-) diff --git a/ChangeLog b/ChangeLog index 60ccdce509..a9e370f9a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Tue Jul 22 16:47:57 2008 Nobuyoshi Nakada + + * include/ruby/intern.h, sprintf.c (rb_str_catf, rb_str_vcatf): new + functions. [ruby-dev:35597] + + * string.c (rb_str_capacity): new function to return the capacity. + Tue Jul 22 16:08:58 2008 NAKAMURA Usaku * ext/socket/socket.c (connect_blocking, socks_connect_blocking, diff --git a/README.EXT b/README.EXT index c4dba7f1f6..4f636d929b 100644 --- a/README.EXT +++ b/README.EXT @@ -185,20 +185,28 @@ listed below: Creates a new tainted Ruby string from a C string. - rb_str_cat(VALUE str, const char *ptr, long len) - - Appends len bytes of data from ptr to the Ruby string. - rb_sprintf(const char *format, ...) rb_vsprintf(const char *format, va_list ap) Creates a new Ruby string with printf(3) format. + rb_str_cat(VALUE str, const char *ptr, long len) + + Appends len bytes of data from ptr to the Ruby string. + rb_str_cat2(VALUE str, const char* ptr) Appends C string ptr to Ruby string str. This function is equivalent to rb_str_cat(str, ptr, strlen(ptr)). + rb_str_catf(VALUE str, const char* format, ...) + rb_str_vcatf(VALUE str, const char* format, va_list ap) + + Appends C string format and successive arguments to Ruby string + str according to a printf-like format. These functions are + equivalent to rb_str_cat2(str, rb_sprintf(format, ...)) and + rb_str_cat2(str, rb_vsprintf(format, ap)), respectively. + Array functions rb_ary_new() diff --git a/README.EXT.ja b/README.EXT.ja index f99987dd10..b78591f38d 100644 --- a/README.EXT.ja +++ b/README.EXT.ja @@ -107,25 +107,25 @@ FIXNUM タを整数に変換する「NUM2INT()」というマクロがあります.この マクロはデータタイプのチェック無しで使えます(整数に変換でき ない場合には例外が発生する).同様にチェック無しで使える変換 -マクロはdoubleを取り出す「NUM2DBL()」があります。 - -char* を取り出す場合、version 1.6 以前では「STR2CSTR()」とい -うマクロを使っていましたが、これは to_str() による暗黙の型変 -換結果が GC される可能性があるため、version 1.7 以降では -obsolete となり、代わりに StringValue() と StringValuePtr() -を使う事を推奨しています。StringValue(var) は var が String -であれば何もせず、そうでなければ var を var.to_str() の結果 -に置き換えるマクロ、StringValuePtr(var) は同様に var を +マクロはdoubleを取り出す「NUM2DBL()」があります. + +char* を取り出す場合,version 1.6 以前では「STR2CSTR()」とい +うマクロを使っていましたが,これは to_str() による暗黙の型変 +換結果が GC される可能性があるため,version 1.7 以降では +obsolete となり,代わりに StringValue() と StringValuePtr() +を使う事を推奨しています.StringValue(var) は var が String +であれば何もせず,そうでなければ var を var.to_str() の結果 +に置き換えるマクロ,StringValuePtr(var) は同様に var を String に置き換えてから var のバイト列表現に対する char* を -返すマクロです。var の内容を直接置き換える処理が入るので、 -var は lvalue である必要があります。 -また、StringValuePtr() に類似した StringValueCStr() というマ -クロもあります。StringValueCStr(var) は var を String に置き -換えてから var の文字列表現に対する char* を返します。返され -る文字列の末尾には nul 文字が付加されます。なお、途中に nul -文字が含まれる場合は ArgumentError が発生します。 -一方、StringValuePtr() では、末尾に nul 文字がある保証はなく、 -途中に nul 文字が含まれている可能性もあります。 +返すマクロです.var の内容を直接置き換える処理が入るので, +var は lvalue である必要があります. +また,StringValuePtr() に類似した StringValueCStr() というマ +クロもあります.StringValueCStr(var) は var を String に置き +換えてから var の文字列表現に対する char* を返します.返され +る文字列の末尾には nul 文字が付加されます.なお,途中に nul +文字が含まれる場合は ArgumentError が発生します. +一方,StringValuePtr() では,末尾に nul 文字がある保証はなく, +途中に nul 文字が含まれている可能性もあります. それ以外のデータタイプは対応するCの構造体があります.対応す る構造体のあるVALUEはそのままキャスト(型変換)すれば構造体の @@ -138,7 +138,7 @@ var ruby.hでは構造体へキャストするマクロも「RXXXXX()」(全部大文 字にしたもの)という名前で提供されています(例: RSTRING()). -構造体からデータを取り出すマクロが提供されています。文字列 +構造体からデータを取り出すマクロが提供されています.文字列 strの長さを得るためには「RSTRING_LEN(str)」とし,文字列strを char*として得るためには「RSTRING_PTR(str)」とします.配列の 場合には,それぞれ「RARRAY_LEN(ary)」,「RARRAY_PTR(ary)」と @@ -212,20 +212,29 @@ Ruby Cの文字列から汚染マークが付加されたRubyの文字列を生成する. - rb_str_cat(VALUE str, const char *ptr, long len) - - Rubyの文字列strにlenバイトの文字列ptrを追加する. - rb_sprintf(const char *format, ...) rb_vsprintf(const char *format, va_list ap) - printf(3)のフォーマットにしたがって,Rubyの文字列を生成する. + Cの文字列formatと続く引数をprintf(3)のフォーマットにしたがって + 整形し,Rubyの文字列を生成する. + + rb_str_cat(VALUE str, const char *ptr, long len) + + Rubyの文字列strにlenバイトの文字列ptrを追加する. rb_str_cat2(VALUE str, const char* ptr) Rubyの文字列strにCの文字列ptrを追加する.この関数の機能は rb_str_cat(str, ptr, strlen(ptr))と同等である. + rb_str_catf(VALUE str, const char* format, ...) + rb_str_vcatf(VALUE str, const char* format, va_list ap) + + Cの文字列formatと続く引数をprintf(3)のフォーマットにしたがって + 整形し,Rubyの文字列strに追加する.この関数の機能は,それぞれ + rb_str_cat2(str, rb_sprintf(format, ...)) や + rb_str_cat2(str, rb_vsprintf(format, ap)) と同等である. + 配列に対する関数 rb_ary_new() @@ -348,20 +357,20 @@ private void rb_define_global_function(const char *name, VALUE (*func)(), int argc) -メソッドの別名を定義するための関数は以下の通りです。 +メソッドの別名を定義するための関数は以下の通りです. void rb_define_alias(VALUE module, const char* new, const char* old); クラスメソッドallocateを定義したり削除したりするための関数は -以下の通りです。 +以下の通りです. void rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE klass)); void rb_undef_alloc_func(VALUE klass); -funcはクラスを引数として受け取って、新しく割り当てられたイン -スタンスを返さなくてはなりません。このインスタンスは、外部リ -ソースなどを含まない、できるだけ「空」のままにしておいたほう -がよいでしょう。 +funcはクラスを引数として受け取って,新しく割り当てられたイン +スタンスを返さなくてはなりません.このインスタンスは,外部リ +ソースなどを含まない,できるだけ「空」のままにしておいたほう +がよいでしょう. 2.1.3 定数定義 @@ -748,9 +757,9 @@ Makefile $LDFLAGS: リンク時に追加的に指定するフラグ(-Lなど) $objs: リンクされるオブジェクトファイル名のリスト -オブジェクトファイルのリストは、通常はソースファイルを検索し -て自動的に生成されますが、makeの途中でソースを生成するような -場合は明示的に指定する必要があります。 +オブジェクトファイルのリストは,通常はソースファイルを検索し +て自動的に生成されますが,makeの途中でソースを生成するような +場合は明示的に指定する必要があります. ライブラリをコンパイルする条件が揃わず,そのライブラリをコン パイルしない時にはcreate_makefileを呼ばなければMakefileは生 @@ -778,7 +787,7 @@ Makefile としてください. -site_ruby ディレクトリでなく、 +site_ruby ディレクトリでなく, vendor_ruby ディレクトリにインストールする場合には 以下のように --vendor オプションを加えてください. @@ -1075,7 +1084,7 @@ char *rb_class2name(VALUE klass) int rb_respond_to(VALUE obj, ID id) - objがidで示されるメソッドを持つかどうかを返す。 + objがidで示されるメソッドを持つかどうかを返す. ** インスタンス変数 diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 3d63c3877b..9a70688546 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -523,6 +523,8 @@ void ruby_default_signal(int); VALUE rb_f_sprintf(int, const VALUE*); PRINTF_ARGS(VALUE rb_sprintf(const char*, ...), 1, 2); VALUE rb_vsprintf(const char*, va_list); +PRINTF_ARGS(VALUE rb_str_catf(VALUE, const char*, ...), 2, 3); +VALUE rb_str_vcatf(VALUE, const char*, va_list); VALUE rb_str_format(int, const VALUE *, VALUE); /* string.c */ VALUE rb_str_new(const char*, long); @@ -578,6 +580,7 @@ void rb_str_setter(VALUE, ID, VALUE*); VALUE rb_str_intern(VALUE); VALUE rb_sym_to_s(VALUE); VALUE rb_str_length(VALUE); +size_t rb_str_capacity(VALUE); #if defined __GNUC__ #define rb_str_new2(str) __extension__ ( \ { \ diff --git a/sprintf.c b/sprintf.c index 9a49c3659d..0fa93f241a 100644 --- a/sprintf.c +++ b/sprintf.c @@ -1115,3 +1115,38 @@ rb_sprintf(const char *format, ...) return result; } + +VALUE +rb_str_vcatf(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_str_catf(VALUE str, const char *format, ...) +{ + va_list ap; + + va_start(ap, format); + str = rb_str_vcatf(str, format, ap); + va_end(ap); + + return str; +} diff --git a/string.c b/string.c index 387786fe07..72240b8506 100644 --- a/string.c +++ b/string.c @@ -343,6 +343,20 @@ 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) { -- cgit v1.2.3