Project

General

Profile

Actions

Feature #5896

closed

object representation in rb_enc_vsprintf()

Added by nobu (Nobuyoshi Nakada) about 12 years ago. Updated almost 12 years ago.

Status:
Closed
Target version:
[ruby-dev:45135]

Description

=begin
(({rb_enc_vsprintf()}))で(({VALUE}))を受け付けるようにする拡張です。

文字列化したオブジェクトを含むメッセージを組み立てる場合、
(({StringValueCStr()}))や(({RSTRING_PTR()}))で得られるポインタを(({snprintf()}))などに渡
すというのが定番ですが、これはエンコーディングが保存されない、最適化に
よって元の(({VALUE}))が消されてしまいdangling pointerになってしまう危険性があ
る、などの問題があります。後者は、とくに(({rb_raise()}))のように(({NORETURN}))な関
数に渡すときには、tail-call最適化のために(({RB_GC_GUARD}))があっても安全とは
限りません。前者については今のところほとんど無視されている状態です。

これらの問題を解消するため、(({rb_enc_vsprintf}))(およびこれを使う関数全般)を
(({VALUE}))自体を受けつけるように拡張すべきだと考えています。具体的な指定方法
としては、新しい変換指定子(%vなど)を追加することも考えましたが、gccは割
りと小賢しくチェックを入れてくれるので、警告がジャマになります。

小崎さんによると、Linux Kernelでも(({printk()}))に対する似たような要望は多かっ
たらしく、(({%p}))で始まる複数文字の変換指定子というものが導入されているそう
で、ソース[1]を見ると今ではが20個近くもあるようです。

[1] [[URL|http://lxr.free-electrons.com/source/lib/vsprintf.c#L1116]]

Rubyではオブジェクト自身が文字列化メソッドを持っているため、それを使っ
て変換するもの一つあれば充分です。なるべく被りそうにないものということ
で、(({"%lo\v"}))あたりでよいのではないかと思っています。

以下のコードは、例として((%error.c%))にある(({rb_invalid_str()}))を変更したものです。

void
rb_invalid_str(const char *str, const char *type)
{
VALUE s = rb_str_inspect(rb_str_new2(str));

  rb_raise(rb_eArgError, "invalid value for %s: %"PRIsVALUE, type, s);

}

=end

Updated by kosaki (Motohiro KOSAKI) about 12 years ago

基本的には賛成なのですが、PRIsVALUEはなくちゃダメ?

\StringValue(v);
rb_raise("%p")

と書くよりもコードが汚くなってしまうのは、せっかくのいい提案を殺してしまうような気がします

Updated by nobu (Nobuyoshi Nakada) about 12 years ago

Motohiro KOSAKI wrote:

基本的には賛成なのですが、PRIsVALUEはなくちゃダメ?

\StringValue(v);
rb_raise("%p")

と書くよりもコードが汚くなってしまうのは、せっかくのいい提案を殺してしまうような気がします

VALUEがunsigned longだったりunsigned long longだったりするので、できる
限り警告を避けようと思うとPRIsVALUEは避けようがないんですよねぇ。

ほとんど使われてそうにない%iのほうが%oよりいいかも、という気もしますが。

Actions #3

Updated by nobu (Nobuyoshi Nakada) about 12 years ago

  • Tracker changed from Bug to Feature

Updated by tarui (Masaya Tarui) about 12 years ago

警告については、gccの拡張ですしPRINTF_ARGSを諦めるのどうですか?
拡張した時点でprintf書式に合わないのはしようがないと思います。

Updated by tarui (Masaya Tarui) about 12 years ago

redmineにコメント書いたんですが、MLと連携されてないように見えるので
こちらにも投稿しときます。

警告については、gccの拡張ですしPRINTF_ARGSを諦めるのどうですか?
拡張した時点でprintf書式に合わないのはしようがないと思います。

--
樽家昌也(Masaya TARUI)
No Tool,No Life.

2012年1月16日22:00 Nobuyoshi Nakada :

Issue #5896 has been updated by Nobuyoshi Nakada.

Motohiro KOSAKI wrote:

基本的には賛成なのですが、PRIsVALUEはなくちゃダメ?

\StringValue(v);
rb_raise("%p")

と書くよりもコードが汚くなってしまうのは、せっかくのいい提案を殺してしまうような気がします

VALUEがunsigned longだったりunsigned long longだったりするので、できる
限り警告を避けようと思うとPRIsVALUEは避けようがないんですよねぇ。

ほとんど使われてそうにない%iのほうが%oよりいいかも、という気もしますが。


Bug #5896: object representaion in rb_enc_vsprintf()
https://bugs.ruby-lang.org/issues/5896

Updated by nobu (Nobuyoshi Nakada) about 12 years ago

  • Subject changed from object representaion in rb_enc_vsprintf() to object representation in rb_enc_vsprintf()
Actions #7

Updated by shyouhei (Shyouhei Urabe) about 12 years ago

  • Status changed from Open to Assigned
Actions #8

Updated by nobu (Nobuyoshi Nakada) almost 12 years ago

  • % Done changed from 0 to 100
  • Status changed from Assigned to Closed

This issue was solved with changeset r35776.
Nobuyoshi, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.


Feature #5896

  • vsnprintf.c (BSD_vfprintf): [EXPERIMENTAL] object representation in
    rb_enc_vsprintf(). [Feature #5896]
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0