in how they use the result of formatting.
@defun format string &rest objects
-This function returns a new string that is made by copying
-@var{string} and then replacing any format specification
-in the copy with encodings of the corresponding @var{objects}. The
+This function returns a string equal to @var{string}, replacing any format
+specifications with encodings of the corresponding @var{objects}. The
arguments @var{objects} are the computed values to be formatted.
The characters in @var{string}, other than the format specifications,
are copied directly into the output, including their text properties,
if any. Any text properties of the format specifications are copied
to the produced string representations of the argument @var{objects}.
+
+The output string need not be newly-allocated. For example, if
+@code{x} is the string @code{"foo"}, the expressions @code{(eq x
+(format x))} and @code{(eq x (format "%s" x))} might both yield
+@code{t}.
@end defun
@defun format-message string &rest objects
hosts (eql N (string-to-number (format "%.0f" N))) now returns t for
all Emacs integers N.
++++
+** 'format' is no longer documented to return a newly-allocated string.
+This documentation was not correct, as (eq x (format x)) returned t
+when x was the empty string. 'format' now takes advantage of the doc
+change to avoid making copies of strings in common cases like (format
+"foo") and (format "%s" "foo").
+
---
** Calls that accept floating-point integers (for use on hosts with
limited integer range) now signal an error if arguments are not
{
/* `args' will contain the array of arguments to pass to the function.
`visargs' will contain the same list but in a nicer form, so that if we
- pass it to styled_format it will be understandable to a human. */
+ pass it to Fformat_message it will be understandable to a human. */
Lisp_Object *args, *visargs;
Lisp_Object specs;
Lisp_Object filter_specs;
for (i = 2; *tem; i++)
{
visargs[1] = make_string (tem + 1, strcspn (tem + 1, "\n"));
- callint_message = styled_format (i - 1, visargs + 1, true, false);
+ callint_message = Fformat_message (i - 1, visargs + 1);
switch (*tem)
{
XD_OBJECT_TO_STRING (Lisp_Object object)
{
AUTO_STRING (format, "%s");
- Lisp_Object args[] = { format, object };
- return SSDATA (styled_format (ARRAYELTS (args), args, false, false));
+ return SSDATA (CALLN (Fformat, format, object));
}
#define XD_DBUS_VALIDATE_BUS_ADDRESS(bus) \
static long int tm_gmtoff (struct tm *);
static int tm_diff (struct tm *, struct tm *);
static void update_buffer_properties (ptrdiff_t, ptrdiff_t);
+static Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool);
#ifndef HAVE_TM_GMTOFF
# define HAVE_TM_GMTOFF false
}
else
{
- Lisp_Object val = styled_format (nargs, args, true, false);
+ Lisp_Object val = Fformat_message (nargs, args);
message3 (val);
return val;
}
}
else
{
- Lisp_Object val = styled_format (nargs, args, true, false);
+ Lisp_Object val = Fformat_message (nargs, args);
Lisp_Object pane, menu;
pane = list1 (Fcons (build_string ("OK"), Qt));
usage: (format STRING &rest OBJECTS) */)
(ptrdiff_t nargs, Lisp_Object *args)
{
- return styled_format (nargs, args, false, true);
+ return styled_format (nargs, args, false);
}
DEFUN ("format-message", Fformat_message, Sformat_message, 1, MANY, 0,
usage: (format-message STRING &rest OBJECTS) */)
(ptrdiff_t nargs, Lisp_Object *args)
{
- return styled_format (nargs, args, true, true);
+ return styled_format (nargs, args, true);
}
-/* Implement ‘format-message’ if MESSAGE is true, ‘format’ otherwise.
- If NEW_RESULT, the result is a new string; otherwise, the result
- may be one of the arguments. */
+/* Implement ‘format-message’ if MESSAGE is true, ‘format’ otherwise. */
-Lisp_Object
-styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message,
- bool new_result)
+static Lisp_Object
+styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
{
ptrdiff_t n; /* The number of the next arg to substitute. */
char initial_buffer[4000];
/* The start and end bytepos in the output string. */
ptrdiff_t start, end;
- /* Whether the argument is a newly created string. */
- bool_bf new_string : 1;
-
/* Whether the argument is a string with intervals. */
bool_bf intervals : 1;
} *info;
ptrdiff_t ispec;
ptrdiff_t nspec = 0;
+ /* True if a string needs to be allocated to hold the result. */
+ bool new_result = false;
+
/* If we start out planning a unibyte result,
then discover it has to be multibyte, we jump back to retry. */
retry:
if (nspec < ispec)
{
spec->argument = args[n];
- spec->new_string = false;
spec->intervals = false;
nspec = ispec;
}
{
Lisp_Object noescape = conversion == 'S' ? Qnil : Qt;
spec->argument = arg = Fprin1_to_string (arg, noescape);
- spec->new_string = true;
if (STRING_MULTIBYTE (arg) && ! multibyte)
{
multibyte = true;
goto retry;
}
spec->argument = arg = Fchar_to_string (arg);
- spec->new_string = true;
}
if (!EQ (arg, args[n]))
if (conversion == 's')
{
if (format == end && format - format_start == 2
- && (!new_result || spec->new_string)
&& ! string_intervals (args[0]))
return arg;
extern Lisp_Object make_buffer_string (ptrdiff_t, ptrdiff_t, bool);
extern Lisp_Object make_buffer_string_both (ptrdiff_t, ptrdiff_t, ptrdiff_t,
ptrdiff_t, bool);
-extern Lisp_Object styled_format (ptrdiff_t, Lisp_Object *, bool, bool);
extern void init_editfns (bool);
extern void syms_of_editfns (void);
for (ptrdiff_t i = 1; i <= nargs; i++)
args[i] = va_arg (ap, Lisp_Object);
Lisp_Object msg = Qnil;
- msg = styled_format (nargs, args, true, false);
+ msg = Fformat_message (nargs, args);
ptrdiff_t len = SBYTES (msg) + 1;
USE_SAFE_ALLOCA;
usage: (trace-to-stderr STRING &rest OBJECTS) */)
(ptrdiff_t nargs, Lisp_Object *args)
{
- Lisp_Object s = styled_format (nargs, args, false, false);
+ Lisp_Object s = Fformat (nargs, args);
fwrite (SDATA (s), 1, SBYTES (s), stderr);
return Qnil;
}