summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--ToDo1
-rw-r--r--hash.c10
-rw-r--r--regex.c7
-rw-r--r--sprintf.c51
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 <eguchi@shizuokanet.ne.jp>
+
+ * hash.c (rb_any_cmp): Fixed return without value.
+
+Wed Nov 10 17:57:06 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * sprintf.c: incorporate <yasuf@big.or.jp>'s sprintf patch at
+ [ruby-dev:7754].
+
Wed Nov 10 08:28:53 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* 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 <sys/types.h>
#endif
-#if defined(STDC_HEADERS)
-# include <stddef.h>
-#else
-/* We need this for `regex.h', and perhaps for the Emacs include files. */
-# include <sys/types.h>
-#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);