aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2017-05-31 22:09:39 -0700
committerPhilipp Stephani2017-06-02 00:25:48 +0200
commit53247108411a1e9d1aa5352c231fa049f3f918aa (patch)
treebb550ccc67607f7f3cfc6a135b0838fff4b4c8c9 /src
parent0dd1bbb0bb228acab21b8e16f2f2a0b5a17b19ab (diff)
downloademacs-53247108411a1e9d1aa5352c231fa049f3f918aa.tar.gz
emacs-53247108411a1e9d1aa5352c231fa049f3f918aa.zip
Minor improvements to format field numbers
* src/editfns.c (styled_format): Allow field numbers in a %% spec. No need for a special diagnostic for field numbers greater than PTRDIFF_MAX. Reword diagnostic for field 0. * test/src/editfns-tests.el (format-with-field): Adjust to match.
Diffstat (limited to 'src')
-rw-r--r--src/editfns.c56
1 files changed, 20 insertions, 36 deletions
diff --git a/src/editfns.c b/src/editfns.c
index 44341cef2d3..98187df5d97 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -4046,9 +4046,8 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4046 field-width ::= [0-9]+ 4046 field-width ::= [0-9]+
4047 precision ::= '.' [0-9]* 4047 precision ::= '.' [0-9]*
4048 4048
4049 If a field-number is specified, it specifies the argument 4049 If present, a field-number specifies the argument number
4050 number to substitute. Otherwise, the next argument is 4050 to substitute. Otherwise, the next argument is taken.
4051 taken.
4052 4051
4053 If a field-width is specified, it specifies to which width 4052 If a field-width is specified, it specifies to which width
4054 the output should be padded with blanks, if the output 4053 the output should be padded with blanks, if the output
@@ -4058,28 +4057,20 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4058 digits to print after the '.' for floats, or the max. 4057 digits to print after the '.' for floats, or the max.
4059 number of chars to print from a string. */ 4058 number of chars to print from a string. */
4060 4059
4061 char *field_end; 4060 uintmax_t num;
4062 uintmax_t raw_field = strtoumax (format, &field_end, 10); 4061 char *num_end;
4063 bool has_field = false; 4062 if (c_isdigit (*format))
4064 if (c_isdigit (*format) && *field_end == '$') 4063 {
4065 { 4064 num = strtoumax (format, &num_end, 10);
4066 if (raw_field < 1 || raw_field >= PTRDIFF_MAX) 4065 if (*num_end == '$')
4067 { 4066 {
4068 /* doprnt doesn't support %.*s, so we need to copy 4067 if (num == 0)
4069 the field number string. */ 4068 error ("Invalid format field number 0");
4070 ptrdiff_t length = field_end - format; 4069 n = min (num, PTRDIFF_MAX);
4071 eassert (length > 0); 4070 n--;
4072 eassert (length < PTRDIFF_MAX); 4071 format = num_end + 1;
4073 char *field = SAFE_ALLOCA (length + 1); 4072 }
4074 memcpy (field, format, length); 4073 }
4075 field[length] = '\0';
4076 error ("Invalid field number `%s'", field);
4077 }
4078 has_field = true;
4079 /* n is incremented below. */
4080 n = raw_field - 1;
4081 format = field_end + 1;
4082 }
4083 4074
4084 bool minus_flag = false; 4075 bool minus_flag = false;
4085 bool plus_flag = false; 4076 bool plus_flag = false;
@@ -4104,11 +4095,10 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4104 space_flag &= ! plus_flag; 4095 space_flag &= ! plus_flag;
4105 zero_flag &= ! minus_flag; 4096 zero_flag &= ! minus_flag;
4106 4097
4107 char *num_end; 4098 num = strtoumax (format, &num_end, 10);
4108 uintmax_t raw_field_width = strtoumax (format, &num_end, 10); 4099 if (max_bufsize <= num)
4109 if (max_bufsize <= raw_field_width)
4110 string_overflow (); 4100 string_overflow ();
4111 ptrdiff_t field_width = raw_field_width; 4101 ptrdiff_t field_width = num;
4112 4102
4113 bool precision_given = *num_end == '.'; 4103 bool precision_given = *num_end == '.';
4114 uintmax_t precision = (precision_given 4104 uintmax_t precision = (precision_given
@@ -4123,13 +4113,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
4123 memset (&discarded[format0 - format_start], 1, 4113 memset (&discarded[format0 - format_start], 1,
4124 format - format0 - (conversion == '%')); 4114 format - format0 - (conversion == '%'));
4125 if (conversion == '%') 4115 if (conversion == '%')
4126 { 4116 goto copy_char;
4127 if (has_field)
4128 /* FIXME: `error' doesn't appear to support `%%'. */
4129 error ("Field number specified together with `%c' conversion",
4130 '%');
4131 goto copy_char;
4132 }
4133 4117
4134 ++n; 4118 ++n;
4135 if (! (n < nargs)) 4119 if (! (n < nargs))