From 943e99e62746388456955729e9f8417f3df5f8b5 Mon Sep 17 00:00:00 2001 From: matz Date: Thu, 11 Nov 1999 04:08:26 +0000 Subject: [PATCH] 19991111 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@563 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 9 +++++++++ ToDo | 1 + hash.c | 10 ++++------ regex.c | 7 ------- sprintf.c | 51 ++++++++++++++++++++++++++++++++++++++++++--------- 5 files changed, 56 insertions(+), 22 deletions(-) diff --git a/ChangeLog b/ChangeLog index 7c8817df29..7195394dd5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +Wed Nov 10 21:54:11 1999 EGUCHI Osamu + + * hash.c (rb_any_cmp): Fixed return without value. + +Wed Nov 10 17:57:06 1999 Yukihiro Matsumoto + + * sprintf.c: incorporate 's sprintf patch at + [ruby-dev:7754]. + Wed Nov 10 08:28:53 1999 Yukihiro Matsumoto * eval.c (rb_call0): supply class parameter for each invocation. diff --git a/ToDo b/ToDo index 83a0841674..ce2459a12d 100644 --- a/ToDo +++ b/ToDo @@ -35,6 +35,7 @@ Standard Libraries - hash.fetch(key) raises exception if key is not found. - Array#{first,last,at} - Dir.glob(pat){|f|...} +- sprintf/printf's $ to specify argument order * Dir.glob("**/*.c") ala zsh * Struct::new([name,]member,...) ?? * String#scanf(?) diff --git a/hash.c b/hash.c index 8e30de7dde..5b8b576b2f 100644 --- a/hash.c +++ b/hash.c @@ -79,19 +79,17 @@ static int rb_any_cmp(a, b) VALUE a, b; { + VALUE args[2]; if (FIXNUM_P(a)) { if (FIXNUM_P(b)) return a != b; } else if (TYPE(a) == T_STRING) { if (TYPE(b) == T_STRING) return rb_str_cmp(a, b); } - else { - VALUE args[2]; - args[0] = a; - args[1] = b; - return !rb_with_disable_interrupt(eql, (VALUE)args); - } + args[0] = a; + args[1] = b; + return !rb_with_disable_interrupt(eql, (VALUE)args); } static int diff --git a/regex.c b/regex.c index 1a1662a112..f77d635a0a 100644 --- a/regex.c +++ b/regex.c @@ -48,13 +48,6 @@ # include #endif -#if defined(STDC_HEADERS) -# include -#else -/* We need this for `regex.h', and perhaps for the Emacs include files. */ -# include -#endif - #ifndef __STDC__ # define volatile #endif diff --git a/sprintf.c b/sprintf.c index 3c71e9771f..5bfd403181 100644 --- a/sprintf.c +++ b/sprintf.c @@ -136,7 +136,29 @@ double rb_big2dbl _((VALUE)); } #define GETARG() \ - ((argc == 0)?(rb_raise(rb_eArgError, "too few argument."),0):(argc--,((argv++)[0]))) + ((nextarg >= argc) ? (rb_raise(rb_eArgError, "too few argument."), 0) : argv[nextarg++]) + +#define GETASTER(val) { \ + t = p++; \ + n = 0; \ + for (; p < end && ISDIGIT(*p); p++) { \ + n = 10 * n + (*p - '0'); \ + } \ + if (p >= end) { \ + rb_raise(rb_eArgError, "malformed format string - %%*[0-9]"); \ + } \ + if (*p == '$') { \ + int curarg = nextarg; \ + nextarg = n; \ + tmp = GETARG(); \ + nextarg = curarg; \ + } \ + else { \ + tmp = GETARG(); \ + p = t; \ + } \ + val = NUM2INT(tmp); \ +} VALUE rb_f_sprintf(argc, argv) @@ -149,6 +171,7 @@ rb_f_sprintf(argc, argv) VALUE result; int width, prec, flags = FNONE; + int nextarg = 0; VALUE tmp; VALUE str; @@ -161,6 +184,7 @@ rb_f_sprintf(argc, argv) for (; p < end; p++) { char *t; + int n; for (t = p; t < end && *t != '%'; t++) ; CHECK(t - p); @@ -208,14 +232,20 @@ rb_f_sprintf(argc, argv) case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - flags |= FWIDTH; - width = 0; + n = 0; for (; p < end && ISDIGIT(*p); p++) { - width = 10 * width + (*p - '0'); + n = 10 * n + (*p - '0'); } if (p >= end) { rb_raise(rb_eArgError, "malformed format string - %%[0-9]"); } + if (*p == '$') { + nextarg = n; + p++; + goto retry; + } + width = n; + flags |= FWIDTH; goto retry; case '*': @@ -224,8 +254,7 @@ rb_f_sprintf(argc, argv) } flags |= FWIDTH; - tmp = GETARG(); - width = NUM2INT(tmp); + GETASTER(width); if (width < 0) { flags |= FMINUS; width = -width; @@ -241,8 +270,7 @@ rb_f_sprintf(argc, argv) prec = 0; p++; if (*p == '*') { - tmp = GETARG(); - prec = NUM2INT(tmp); + GETASTER(prec); if (prec > 0) flags |= FPREC; p++; @@ -612,9 +640,14 @@ rb_f_sprintf(argc, argv) } sprint_exit: - if (RTEST(ruby_verbose) && argc > 0) { +#if 0 + /* XXX - We cannot validiate the number of arguments because + * the format string may contain `n$'-style argument selector. + */ + if (RTEST(ruby_verbose) && nextarg < argc) { rb_raise(rb_eArgError, "too many argument for format string"); } +#endif result = rb_str_new(buf, blen); free(buf);