diff options
Diffstat (limited to 'src/editfns.c')
| -rw-r--r-- | src/editfns.c | 49 |
1 files changed, 38 insertions, 11 deletions
diff --git a/src/editfns.c b/src/editfns.c index b03eb947dec..e326604467c 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -74,7 +74,6 @@ static Lisp_Object format_time_string (char const *, ptrdiff_t, struct timespec, | |||
| 74 | static long int tm_gmtoff (struct tm *); | 74 | static long int tm_gmtoff (struct tm *); |
| 75 | static int tm_diff (struct tm *, struct tm *); | 75 | static int tm_diff (struct tm *, struct tm *); |
| 76 | static void update_buffer_properties (ptrdiff_t, ptrdiff_t); | 76 | static void update_buffer_properties (ptrdiff_t, ptrdiff_t); |
| 77 | static Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool); | ||
| 78 | 77 | ||
| 79 | #ifndef HAVE_TM_GMTOFF | 78 | #ifndef HAVE_TM_GMTOFF |
| 80 | # define HAVE_TM_GMTOFF false | 79 | # define HAVE_TM_GMTOFF false |
| @@ -187,7 +186,8 @@ tzlookup (Lisp_Object zone, bool settz) | |||
| 187 | if (sec != 0) | 186 | if (sec != 0) |
| 188 | prec += 2, numzone = 100 * numzone + sec; | 187 | prec += 2, numzone = 100 * numzone + sec; |
| 189 | } | 188 | } |
| 190 | sprintf (tzbuf, tzbuf_format, prec, numzone, | 189 | sprintf (tzbuf, tzbuf_format, prec, |
| 190 | XINT (zone) < 0 ? -numzone : numzone, | ||
| 191 | &"-"[XINT (zone) < 0], hour, min, sec); | 191 | &"-"[XINT (zone) < 0], hour, min, sec); |
| 192 | zone_string = tzbuf; | 192 | zone_string = tzbuf; |
| 193 | } | 193 | } |
| @@ -3958,7 +3958,7 @@ usage: (message FORMAT-STRING &rest ARGS) */) | |||
| 3958 | } | 3958 | } |
| 3959 | else | 3959 | else |
| 3960 | { | 3960 | { |
| 3961 | Lisp_Object val = Fformat_message (nargs, args); | 3961 | Lisp_Object val = styled_format (nargs, args, true, false); |
| 3962 | message3 (val); | 3962 | message3 (val); |
| 3963 | return val; | 3963 | return val; |
| 3964 | } | 3964 | } |
| @@ -3984,7 +3984,7 @@ usage: (message-box FORMAT-STRING &rest ARGS) */) | |||
| 3984 | } | 3984 | } |
| 3985 | else | 3985 | else |
| 3986 | { | 3986 | { |
| 3987 | Lisp_Object val = Fformat_message (nargs, args); | 3987 | Lisp_Object val = styled_format (nargs, args, true, false); |
| 3988 | Lisp_Object pane, menu; | 3988 | Lisp_Object pane, menu; |
| 3989 | 3989 | ||
| 3990 | pane = list1 (Fcons (build_string ("OK"), Qt)); | 3990 | pane = list1 (Fcons (build_string ("OK"), Qt)); |
| @@ -4140,7 +4140,7 @@ produced text. | |||
| 4140 | usage: (format STRING &rest OBJECTS) */) | 4140 | usage: (format STRING &rest OBJECTS) */) |
| 4141 | (ptrdiff_t nargs, Lisp_Object *args) | 4141 | (ptrdiff_t nargs, Lisp_Object *args) |
| 4142 | { | 4142 | { |
| 4143 | return styled_format (nargs, args, false); | 4143 | return styled_format (nargs, args, false, true); |
| 4144 | } | 4144 | } |
| 4145 | 4145 | ||
| 4146 | DEFUN ("format-message", Fformat_message, Sformat_message, 1, MANY, 0, | 4146 | DEFUN ("format-message", Fformat_message, Sformat_message, 1, MANY, 0, |
| @@ -4156,13 +4156,16 @@ and right quote replacement characters are specified by | |||
| 4156 | usage: (format-message STRING &rest OBJECTS) */) | 4156 | usage: (format-message STRING &rest OBJECTS) */) |
| 4157 | (ptrdiff_t nargs, Lisp_Object *args) | 4157 | (ptrdiff_t nargs, Lisp_Object *args) |
| 4158 | { | 4158 | { |
| 4159 | return styled_format (nargs, args, true); | 4159 | return styled_format (nargs, args, true, true); |
| 4160 | } | 4160 | } |
| 4161 | 4161 | ||
| 4162 | /* Implement ‘format-message’ if MESSAGE is true, ‘format’ otherwise. */ | 4162 | /* Implement ‘format-message’ if MESSAGE is true, ‘format’ otherwise. |
| 4163 | If NEW_RESULT, the result is a new string; otherwise, the result | ||
| 4164 | may be one of the arguments. */ | ||
| 4163 | 4165 | ||
| 4164 | static Lisp_Object | 4166 | Lisp_Object |
| 4165 | styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | 4167 | styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message, |
| 4168 | bool new_result) | ||
| 4166 | { | 4169 | { |
| 4167 | ptrdiff_t n; /* The number of the next arg to substitute. */ | 4170 | ptrdiff_t n; /* The number of the next arg to substitute. */ |
| 4168 | char initial_buffer[4000]; | 4171 | char initial_buffer[4000]; |
| @@ -4192,6 +4195,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4192 | /* The start and end bytepos in the output string. */ | 4195 | /* The start and end bytepos in the output string. */ |
| 4193 | ptrdiff_t start, end; | 4196 | ptrdiff_t start, end; |
| 4194 | 4197 | ||
| 4198 | /* Whether the argument is a newly created string. */ | ||
| 4199 | bool_bf new_string : 1; | ||
| 4200 | |||
| 4195 | /* Whether the argument is a string with intervals. */ | 4201 | /* Whether the argument is a string with intervals. */ |
| 4196 | bool_bf intervals : 1; | 4202 | bool_bf intervals : 1; |
| 4197 | } *info; | 4203 | } *info; |
| @@ -4341,7 +4347,10 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4341 | memset (&discarded[format0 - format_start], 1, | 4347 | memset (&discarded[format0 - format_start], 1, |
| 4342 | format - format0 - (conversion == '%')); | 4348 | format - format0 - (conversion == '%')); |
| 4343 | if (conversion == '%') | 4349 | if (conversion == '%') |
| 4344 | goto copy_char; | 4350 | { |
| 4351 | new_result = true; | ||
| 4352 | goto copy_char; | ||
| 4353 | } | ||
| 4345 | 4354 | ||
| 4346 | ++n; | 4355 | ++n; |
| 4347 | if (! (n < nargs)) | 4356 | if (! (n < nargs)) |
| @@ -4351,6 +4360,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4351 | if (nspec < ispec) | 4360 | if (nspec < ispec) |
| 4352 | { | 4361 | { |
| 4353 | spec->argument = args[n]; | 4362 | spec->argument = args[n]; |
| 4363 | spec->new_string = false; | ||
| 4354 | spec->intervals = false; | 4364 | spec->intervals = false; |
| 4355 | nspec = ispec; | 4365 | nspec = ispec; |
| 4356 | } | 4366 | } |
| @@ -4368,6 +4378,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4368 | { | 4378 | { |
| 4369 | Lisp_Object noescape = conversion == 'S' ? Qnil : Qt; | 4379 | Lisp_Object noescape = conversion == 'S' ? Qnil : Qt; |
| 4370 | spec->argument = arg = Fprin1_to_string (arg, noescape); | 4380 | spec->argument = arg = Fprin1_to_string (arg, noescape); |
| 4381 | spec->new_string = true; | ||
| 4371 | if (STRING_MULTIBYTE (arg) && ! multibyte) | 4382 | if (STRING_MULTIBYTE (arg) && ! multibyte) |
| 4372 | { | 4383 | { |
| 4373 | multibyte = true; | 4384 | multibyte = true; |
| @@ -4386,6 +4397,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4386 | goto retry; | 4397 | goto retry; |
| 4387 | } | 4398 | } |
| 4388 | spec->argument = arg = Fchar_to_string (arg); | 4399 | spec->argument = arg = Fchar_to_string (arg); |
| 4400 | spec->new_string = true; | ||
| 4389 | } | 4401 | } |
| 4390 | 4402 | ||
| 4391 | if (!EQ (arg, args[n])) | 4403 | if (!EQ (arg, args[n])) |
| @@ -4408,6 +4420,11 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4408 | 4420 | ||
| 4409 | if (conversion == 's') | 4421 | if (conversion == 's') |
| 4410 | { | 4422 | { |
| 4423 | if (format == end && format - format_start == 2 | ||
| 4424 | && (!new_result || spec->new_string) | ||
| 4425 | && ! string_intervals (args[0])) | ||
| 4426 | return arg; | ||
| 4427 | |||
| 4411 | /* handle case (precision[n] >= 0) */ | 4428 | /* handle case (precision[n] >= 0) */ |
| 4412 | 4429 | ||
| 4413 | ptrdiff_t prec = -1; | 4430 | ptrdiff_t prec = -1; |
| @@ -4486,6 +4503,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4486 | if (string_intervals (arg)) | 4503 | if (string_intervals (arg)) |
| 4487 | spec->intervals = arg_intervals = true; | 4504 | spec->intervals = arg_intervals = true; |
| 4488 | 4505 | ||
| 4506 | new_result = true; | ||
| 4489 | continue; | 4507 | continue; |
| 4490 | } | 4508 | } |
| 4491 | } | 4509 | } |
| @@ -4753,6 +4771,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4753 | } | 4771 | } |
| 4754 | spec->end = nchars; | 4772 | spec->end = nchars; |
| 4755 | 4773 | ||
| 4774 | new_result = true; | ||
| 4756 | continue; | 4775 | continue; |
| 4757 | } | 4776 | } |
| 4758 | } | 4777 | } |
| @@ -4771,9 +4790,13 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4771 | } | 4790 | } |
| 4772 | convsrc = format_char == '`' ? uLSQM : uRSQM; | 4791 | convsrc = format_char == '`' ? uLSQM : uRSQM; |
| 4773 | convbytes = 3; | 4792 | convbytes = 3; |
| 4793 | new_result = true; | ||
| 4774 | } | 4794 | } |
| 4775 | else if (format_char == '`' && quoting_style == STRAIGHT_QUOTING_STYLE) | 4795 | else if (format_char == '`' && quoting_style == STRAIGHT_QUOTING_STYLE) |
| 4776 | convsrc = "'"; | 4796 | { |
| 4797 | convsrc = "'"; | ||
| 4798 | new_result = true; | ||
| 4799 | } | ||
| 4777 | else | 4800 | else |
| 4778 | { | 4801 | { |
| 4779 | /* Copy a single character from format to buf. */ | 4802 | /* Copy a single character from format to buf. */ |
| @@ -4797,6 +4820,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4797 | int c = BYTE8_TO_CHAR (format_char); | 4820 | int c = BYTE8_TO_CHAR (format_char); |
| 4798 | convbytes = CHAR_STRING (c, str); | 4821 | convbytes = CHAR_STRING (c, str); |
| 4799 | convsrc = (char *) str; | 4822 | convsrc = (char *) str; |
| 4823 | new_result = true; | ||
| 4800 | } | 4824 | } |
| 4801 | } | 4825 | } |
| 4802 | 4826 | ||
| @@ -4843,6 +4867,9 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 4843 | if (bufsize < p - buf) | 4867 | if (bufsize < p - buf) |
| 4844 | emacs_abort (); | 4868 | emacs_abort (); |
| 4845 | 4869 | ||
| 4870 | if (! new_result) | ||
| 4871 | return args[0]; | ||
| 4872 | |||
| 4846 | if (maybe_combine_byte) | 4873 | if (maybe_combine_byte) |
| 4847 | nchars = multibyte_chars_in_text ((unsigned char *) buf, p - buf); | 4874 | nchars = multibyte_chars_in_text ((unsigned char *) buf, p - buf); |
| 4848 | Lisp_Object val = make_specified_string (buf, nchars, p - buf, multibyte); | 4875 | Lisp_Object val = make_specified_string (buf, nchars, p - buf, multibyte); |