diff options
| author | Paul Eggert | 2017-05-31 22:09:39 -0700 |
|---|---|---|
| committer | Philipp Stephani | 2017-06-02 00:25:48 +0200 |
| commit | 53247108411a1e9d1aa5352c231fa049f3f918aa (patch) | |
| tree | bb550ccc67607f7f3cfc6a135b0838fff4b4c8c9 /src | |
| parent | 0dd1bbb0bb228acab21b8e16f2f2a0b5a17b19ab (diff) | |
| download | emacs-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.c | 56 |
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)) |