From: EGUCHI Osamu Date: 1999-08-26T08:58:35+09:00 Subject: [ruby-list:16325] Re: printf の $ について ----Next_Part(Thu_Aug_26_08:56:50_1999_809)-- Content-Type: Text/Plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit えぐち@エスアンドイー です。 >>> In message [ruby-list:16322] Re: printf の $ について On Thu, 26 Aug 1999 01:27:39 +0900, matz@netlab.co.jp (Yukihiro Matsumoto) said: matz> まつもと ゆきひろです matz> matz> In message "[ruby-list:16314] Re: printf の $ について" matz> on 99/08/25, EGUCHI Osamu writes: matz> matz> |matz> sprintf.cのGETARG()マクロとかを書き換えればできるのかなあ。 matz> |matz> しかし、当面私自身が手を付ける気は無いですね。 matz> |matz> 誰かやる? matz> | matz> |やっつけてみました。 matz> | matz> | + % の使える場所に %digit$ を使えるようにした。 matz> | + % を修飾する * の場所に *digit$ を使えるようにした。 matz> | ※digit の取り得る範囲は 1..9 です。 matz> | matz> |という内容です。 matz> matz> このパッチ(正確には[ruby-list:16316]のパッチ)は基本的に取り matz> 込む方向で検討しようと思います。福間さんのパッチと違いがある matz> んですかね。 違いは基本的には、無いはずです。 しいて言えば、私の方にはバグがある事かな ^^;; あと、福間さん版では、 % ./ruby -e 'printf "%2$s - %1$s : %s\n", "One", "Two", "Three"' Two - One : Two % ./ruby -e 'printf "%2$s - %2$s : %s\n", "One", "Two", "Three"' Two - Two : Three となり、最後につかった %n$ により以降の % の パラメータ参照位置が降られます。 ちょっと妙な気がしますが。FreeBSD-3.2-STABLE の printf(3)でも、 SunOS-4.1.1-JLE でも同じですので、こういう物なのでしょう。 #標準では、どのように規定しているかは、まだ調べていません。 #C9X の文書あたればいいのかな、、C9X って年内に成果でるんぢゃろか matz> ただ、こいつは1.4系には取り込みません。 matz> 将来の1.5系以降ですね。 それが良さげですね。 #うぅむ、[ruby-dev:7754](福間版)の方が良いかも知れない ^^;; えぐち 参考までに、 % ./ruby -e 'printf("%*s\n", 4, "foo")' 4 対策版付けます。 ----Next_Part(Thu_Aug_26_08:56:50_1999_809)-- Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Content-Description: sprintf5.diff Content-Disposition: attachment; filename="sprintf5.diff" Index: sprintf.c =================================================================== RCS file: /usr/home/eguchi/cvs.netlab.co.jp//ruby/sprintf.c,v retrieving revision 1.2 diff -d -u -r1.2 sprintf.c --- sprintf.c 1999/08/13 05:45:14 1.2 +++ sprintf.c 1999/08/25 14:08:10 @@ -121,6 +121,7 @@ #define FSPACE 16 #define FWIDTH 32 #define FPREC 64 +#define FVARG 128 #define CHECK(l) {\ while (blen + (l) >= bsiz) {\ @@ -135,8 +136,9 @@ blen += (l);\ } -#define GETARG() \ - ((argc == 0)?(rb_raise(rb_eArgError, "too few argument."),0):(argc--,((argv++)[0]))) +#define GETARG(index) \ + ((index<0||index>=argc)?(rb_raise(rb_eArgError, "too few argument."),0)\ + :argv[index]) VALUE rb_f_sprintf(argc, argv) @@ -148,11 +150,12 @@ int blen, bsiz; VALUE result; - int width, prec, flags = FNONE; + int width, prec, flags = FNONE, index = 0; VALUE tmp; VALUE str; - fmt = GETARG(); + fmt = GETARG(index); + index++; p = str2cstr(fmt, &blen); end = p + blen; blen = 0; @@ -161,6 +164,7 @@ for (; p < end; p++) { char *t; + int i; for (t = p; t < end && *t != '%'; t++) ; CHECK(t - p); @@ -172,6 +176,8 @@ p = t + 1; /* skip `%' */ width = prec = -1; + flags = FNONE; + i = index; retry: switch (*p) { default: @@ -208,6 +214,12 @@ case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': + if (p[1] == '$') { + i = *p - '0'; + p = &p[2]; + flags |= FVARG; + goto retry; + } flags |= FWIDTH; width = 0; for (; p < end && ISDIGIT(*p); p++) { @@ -224,7 +236,19 @@ } flags |= FWIDTH; - tmp = GETARG(); + tmp = GETARG(index); + index++; + if ((flags & FVARG) == 0) i = index; + switch (p[1]) { + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (p[2] == '$') { + int inx = p[1] - '0'; + p = &p[2]; + tmp = GETARG(inx); + } + break; + } width = NUM2INT(tmp); if (width < 0) { flags |= FMINUS; @@ -241,7 +265,19 @@ prec = 0; p++; if (*p == '*') { - tmp = GETARG(); + tmp = GETARG(index); + index++; + if ((flags & FVARG) == 0) i = index; + switch (p[1]) { + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (p[2] == '$') { + int inx = p[1] - '0'; + p = &p[2]; + tmp = GETARG(inx); + } + break; + } prec = NUM2INT(tmp); if (prec > 0) flags |= FPREC; @@ -264,11 +300,11 @@ case '\0': case '%': PUSH("%", 1); - break; + continue; case 'c': { - VALUE val = GETARG(); + VALUE val = GETARG(i); char c; if (!(flags & FMINUS)) @@ -283,7 +319,7 @@ case 's': { - VALUE arg = GETARG(); + VALUE arg = GETARG(i); int len; str = rb_obj_as_string(arg); @@ -329,7 +365,7 @@ case 'b': case 'u': { - volatile VALUE val = GETARG(); + volatile VALUE val = GETARG(i); char fbuf[32], nbuf[64], *s, *t; char *prefix = 0; int sign = 0; @@ -563,7 +599,7 @@ case 'e': case 'E': { - VALUE val = GETARG(); + VALUE val = GETARG(i); double fval; int i, need = 6; char fbuf[32]; @@ -605,7 +641,7 @@ } break; } - flags = FNONE; + index++; } sprint_exit: ----Next_Part(Thu_Aug_26_08:56:50_1999_809)----