emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 8de2581 2/2: Limit format fields to more POSIX-like


From: Paul Eggert
Subject: [Emacs-diffs] master 8de2581 2/2: Limit format fields to more POSIX-like spec
Date: Thu, 1 Jun 2017 19:06:43 -0400 (EDT)

branch: master
commit 8de2581a64dac3785fc3877f7cd87c4164fd2936
Author: Paul Eggert <address@hidden>
Commit: Paul Eggert <address@hidden>

    Limit format fields to more POSIX-like spec
    
    * doc/lispref/strings.texi (Formatting Strings):
    Don’t allow mixing numbered with unnumbered format specs.
    * src/editfns.c (styled_format): Don’t bother checking for field 0,
    since it doesn’t crash and the behavior is not specified.
    * test/src/editfns-tests.el (format-with-field): Adjust tests to
    match current doc.  Add more tests for out-of-range fields.
---
 doc/lispref/strings.texi  | 13 +++++--------
 src/editfns.c             |  8 ++++----
 test/src/editfns-tests.el | 28 ++++++++++++++++++++++------
 3 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/doc/lispref/strings.texi b/doc/lispref/strings.texi
index 4d33e55..e80e778 100644
--- a/doc/lispref/strings.texi
+++ b/doc/lispref/strings.texi
@@ -965,16 +965,13 @@ extra values to be formatted are ignored.
 decimal number immediately after the initial @samp{%}, followed by a
 literal dollar sign @samp{$}.  It causes the format specification to
 convert the argument with the given number instead of the next
-argument.  Argument 1 is the argument just after the format.
-
-  You can mix specifications with and without field numbers.  A
-specification without a field number that follows a specification with
-a field number will convert the argument after the one specified by
-the field number:
+argument.  Field numbers start at 1.  A format can contain either
+numbered or unnumbered format specifications but not both, except that
address@hidden can be mixed with numbered specifications.
 
 @example
-(format "Argument %2$s, then %s, then %1$s" "x" "y" "z")
-     @result{} "Argument y, then z, then x"
+(format "%2$s, %3$s, %%, %1$s" "x" "y" "z")
+     @result{} "y, z, %, x"
 @end example
 
 @cindex flags in format specifications
diff --git a/src/editfns.c b/src/editfns.c
index 1dbae8f..29af25a 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -3900,8 +3900,10 @@ where field is [0-9]+ followed by a literal dollar "$", 
flags is
 [+ #-0]+, width is [0-9]+, and precision is a literal period "."
 followed by [0-9]+.
 
-If field is given, it must be a one-based argument number; the given
-argument is substituted instead of the next one.
+If a %-sequence is numbered with a field with positive value N, the
+Nth argument is substituted instead of the next one.  A format can
+contain either numbered or unnumbered %-sequences but not both, except
+that %% can be mixed with numbered %-sequences.
 
 The + flag character inserts a + before any positive number, while a
 space inserts a space before any positive number; these flags only
@@ -4081,8 +4083,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool 
message)
              num = str2num (format, &num_end);
              if (*num_end == '$')
                {
-                 if (num == 0)
-                   error ("Invalid format field number 0");
                  n = num - 1;
                  format = num_end + 1;
                }
diff --git a/test/src/editfns-tests.el b/test/src/editfns-tests.el
index c5923aa..54fb743 100644
--- a/test/src/editfns-tests.el
+++ b/test/src/editfns-tests.el
@@ -178,17 +178,33 @@
                                (concat (make-string 2048 ?X) "0")))))
 
 (ert-deftest format-with-field ()
-  (should (equal (format "First argument %2$s, then %s, then %1$s" 1 2 3)
+  (should (equal (format "First argument %2$s, then %3$s, then %1$s" 1 2 3)
                  "First argument 2, then 3, then 1"))
-  (should (equal (format "a %2$s %d %1$d %2$S %d %d b" 11 "22" 33 44)
+  (should (equal (format "a %2$s %3$d %1$d %2$S %3$d %4$d b" 11 "22" 33 44)
                  "a 22 33 11 \"22\" 33 44 b"))
-  (should (equal (format "a %08$s %s b" 1 2 3 4 5 6 7 8 9) "a 8 9 b"))
+  (should (equal (format "a %08$s %0000000000000000009$s b" 1 2 3 4 5 6 7 8 9)
+                 "a 8 9 b"))
   (should (equal (should-error (format "a %999999$s b" 11))
                  '(error "Not enough arguments for format string")))
+  (should (equal (should-error (format "a %2147483647$s b"))
+                 '(error "Not enough arguments for format string")))
+  (should (equal (should-error (format "a %9223372036854775807$s b"))
+                 '(error "Not enough arguments for format string")))
+  (should (equal (should-error (format "a %9223372036854775808$s b"))
+                 '(error "Not enough arguments for format string")))
+  (should (equal (should-error (format "a %18446744073709551615$s b"))
+                 '(error "Not enough arguments for format string")))
+  (should (equal (should-error (format "a %18446744073709551616$s b"))
+                 '(error "Not enough arguments for format string")))
+  (should (equal (should-error
+                  (format (format "a %%%d$d b" most-positive-fixnum)))
+                 '(error "Not enough arguments for format string")))
+  (should (equal (should-error
+                  (format (format "a %%%d$d b" (+ 1.0 most-positive-fixnum))))
+                 '(error "Not enough arguments for format string")))
   (should (equal (should-error (format "a %$s b" 11))
                  '(error "Invalid format operation %$")))
-  (should (equal (should-error (format "a %0$s b" 11))
-                 '(error "Invalid format field number 0")))
-  (should (equal (format "a %1$% %s b" 11) "a % 11 b")))
+  (should (equal (should-error (format "a %-1$s b" 11))
+                 '(error "Invalid format operation %$"))))
 
 ;;; editfns-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]