[前][次][番号順一覧][スレッド一覧]

ruby-changes:11465

From: nobu <ko1@a...>
Date: Sat, 28 Mar 2009 08:50:22 +0900 (JST)
Subject: [ruby-changes:11465] Ruby:r23090 (trunk): * sprintf.c (rb_str_format): checks if named argument given twice.

nobu	2009-03-28 08:49:52 +0900 (Sat, 28 Mar 2009)

  New Revision: 23090

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=23090

  Log:
    * sprintf.c (rb_str_format): checks if named argument given twice.

  Modified files:
    trunk/ChangeLog
    trunk/sprintf.c
    trunk/test/ruby/test_sprintf.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 23089)
+++ ChangeLog	(revision 23090)
@@ -1,5 +1,7 @@
-Sat Mar 28 06:18:27 2009  Nobuyoshi Nakada  <nobu@r...>
+Sat Mar 28 08:49:47 2009  Nobuyoshi Nakada  <nobu@r...>
 
+	* sprintf.c (rb_str_format): checks if named argument given twice.
+
 	* sprintf.c (GETNAMEARG): remembers named arg is used, to get rid
 	  of too many arguments warning.
 
Index: sprintf.c
===================================================================
--- sprintf.c	(revision 23089)
+++ sprintf.c	(revision 23090)
@@ -119,11 +119,12 @@
 #define GETNTHARG(nth) \
     ((nth >= argc) ? (rb_raise(rb_eArgError, "too few arguments"), 0) : argv[nth])
 
-#define GETNAMEARG(id) (posarg > 0 ? \
-    (rb_raise(rb_eArgError, "named after unnumbered(%d)", posarg), 0) : \
+#define GETNAMEARG(id, name, len) ( \
+    posarg > 0 ? \
+    (rb_raise(rb_eArgError, "named%.*s after unnumbered(%d)", (len), (name), posarg), 0) : \
     posarg == -1 ? \
-    (rb_raise(rb_eArgError, "named after numbered"), 0) : \
-    (posarg = -2, rb_hash_lookup(get_hash(&hash, argc, argv), id)))
+    (rb_raise(rb_eArgError, "named%.*s after numbered", (len), (name)), 0) :	\
+    (posarg = -2, rb_hash_lookup2(get_hash(&hash, argc, argv), id, Qundef)))
 
 #define GETNUM(n, val) \
     for (; p < end && rb_enc_isdigit(*p, enc); p++) {	\
@@ -472,6 +473,7 @@
     for (; p < end; p++) {
 	const char *t;
 	int n;
+	ID id = 0;
 
 	for (t = p; t < end && *t != '%'; t++) ;
 	PUSH(p, t - p);
@@ -544,7 +546,6 @@
 	    {
 		const char *start = p;
 		char term = (*p == '<') ? '>' : '}';
-		ID id;
 
 		for (; p < end && *p != term; ) {
 		    p += rb_enc_mbclen(p, end, enc);
@@ -552,8 +553,15 @@
 		if (p >= end) {
 		    rb_raise(rb_eArgError, "malformed name - unmatched parenthesis");
 		}
+		if (id) {
+		    rb_raise(rb_eArgError, "name%.*s after <%s>",
+			     (int)(p - start + 1), start, rb_id2name(id));
+		}
 		id = rb_intern3(start + 1, p - start - 1, enc);
-		nextvalue = GETNAMEARG(ID2SYM(id));
+		nextvalue = GETNAMEARG(ID2SYM(id), start, (int)(p - start + 1));
+		if (nextvalue == Qundef) {
+		    rb_raise(rb_eKeyError, "key%.*s not found", (int)(p - start + 1), start);
+		}
 		if (term == '}') goto format_s;
 		p++;
 		goto retry;
Index: test/ruby/test_sprintf.rb
===================================================================
--- test/ruby/test_sprintf.rb	(revision 23089)
+++ test/ruby/test_sprintf.rb	(revision 23090)
@@ -273,4 +273,10 @@
     b2 = (/\.\./ =~ s2) != nil
     assert(b1 == b2, "[ruby-dev:33224]")
   end
+
+  def test_named
+    assert_equal("value", sprintf("%<key>s", :key => "value"))
+    assert_raise(ArgumentError) {sprintf("%1$<key2>s", :key => "value")}
+    assert_raise(ArgumentError) {sprintf("%<key><key2>s", :key => "value")}
+  end
 end

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]