return make_clear_multibyte_string (nchars, nbytes, false);
}
-/* Print arguments to BUF according to a FORMAT, then return
- a Lisp_String initialized with the data from BUF. */
+/* Return a Lisp_String according to a doprnt-style FORMAT and args. */
Lisp_Object
-make_formatted_string (char *buf, const char *format, ...)
+make_formatted_string (const char *format, ...)
{
+ char buf[64];
+ char *cstr = buf;
+ ptrdiff_t bufsize = sizeof buf;
va_list ap;
- int length;
va_start (ap, format);
- length = vsprintf (buf, format, ap);
+ ptrdiff_t length = evxprintf (&cstr, &bufsize, buf, -1, format, ap);
va_end (ap);
- return make_string (buf, length);
+ Lisp_Object ret = make_string (cstr, length);
+ if (cstr != buf)
+ xfree (cstr);
+ return ret;
}
/* Pin a unibyte string in place so that it won't move during GC. */
{
#ifdef DBUS_VERSION
int major, minor, micro;
- char s[sizeof ".." + 3 * INT_STRLEN_BOUND (int)];
dbus_get_version (&major, &minor, µ);
Vdbus_runtime_version
- = make_formatted_string (s, "%d.%d.%d", major, minor, micro);
+ = make_formatted_string ("%d.%d.%d", major, minor, micro);
#else
Vdbus_runtime_version = Qnil;
#endif
supports the following Emacs-specific features:
. For %c conversions, it produces a string with the multibyte representation
- of the (`int') argument, suitable for display in an Emacs buffer.
+ of the ('int') argument, suitable for display in an Emacs buffer.
. For %s and %c, when field width is specified (e.g., %25s), it accounts for
the display width of each character, according to char-width-table. That
overflow ptrdiff_t or size_t, to avoid producing strings longer than what
Emacs can handle.
- OTOH, this function supports only a small subset of the standard C formatted
- output facilities. E.g., %u is not supported, precision is ignored
+ On the other hand, this function supports only a small subset of the
+ standard C formatted output facilities. E.g., precision is ignored
in %s and %c conversions, and %lld does not necessarily work and
code should use something like %"pM"d with intmax_t instead.
(See below for the detailed documentation of what is supported.)
also supports the following %-sequences:
%s means print a string argument.
- %S is treated as %s, for loose compatibility with `Fformat_message'.
- %d means print a `signed int' argument in decimal.
- %o means print an `unsigned int' argument in octal.
- %x means print an `unsigned int' argument in hex.
- %e means print a `double' argument in exponential notation.
- %f means print a `double' argument in decimal-point notation.
- %g means print a `double' argument in exponential notation
+ %S is treated as %s, for loose compatibility with 'Fformat_message'.
+ %d means print a 'signed int' argument in decimal.
+ %o means print an 'unsigned int' argument in octal.
+ %u means print an 'unsigned int' argument in decimal.
+ %x means print an 'unsigned int' argument in hex.
+ %e means print a 'double' argument in exponential notation.
+ %f means print a 'double' argument in decimal-point notation.
+ %g means print a 'double' argument in exponential notation
or in decimal-point notation, depending on the value;
this is often (though not always) the shorter of the two notations.
- %c means print a `signed int' argument as a single character.
+ %c means print a 'signed int' argument as a single character.
%% means produce a literal % character.
A %-sequence other than %% may contain optional flags, width, precision,
The + flag character inserts a + before any positive number, while a space
inserts a space before any positive number; these flags only affect %d, %o,
%x, %e, %f, and %g sequences. The - and 0 flags affect the width specifier,
- as described below. For signed numerical arguments only, the ` ' (space)
+ as described below. For signed numerical arguments only, the ' ' (space)
flag causes the result to be prefixed with a space character if it does not
start with a sign (+ or -).
- The l (lower-case letter ell) length modifier is a `long' data type
+ The l (lower-case letter ell) length modifier is a 'long' data type
modifier: it is supported for %d, %o, and %x conversions of integral
arguments, must immediately precede the conversion specifier, and means that
- the respective argument is to be treated as `long int' or `unsigned long
+ the respective argument is to be treated as 'long int' or 'unsigned long
int'. Similarly, the value of the pD macro means to use ptrdiff_t,
the value of the pI macro means to use EMACS_INT or EMACS_UINT, the
value of the PRIdMAX etc. macros means to use intmax_t or uintmax_t,
- and the empty length modifier means `int' or `unsigned int'.
+ and the empty length modifier means 'int' or 'unsigned int'.
The width specifier supplies a lower limit for the length of the printed
representation. The padding, if any, normally goes on the left, but it goes
return nbytes;
}
-/* Generate output from a format-spec FORMAT,
+/* Format to BUFFER (of positive size BUFSIZE) data formated by FORMAT,
terminated at either the first NUL or (if FORMAT_END is non-null
and there are no NUL bytes between FORMAT and FORMAT_END)
- terminated at position FORMAT_END.
+ terminated at position FORMAT_END. AP specifies format arguments.
(*FORMAT_END is not part of the format, but must exist and be readable.)
- Output goes in BUFFER, which has room for BUFSIZE chars.
- BUFSIZE must be positive. If the output does not fit, truncate it
- to fit and return BUFSIZE - 1; if this truncates a multibyte
- sequence, store '\0' into the sequence's first byte.
- Returns the number of bytes stored into BUFFER, excluding
+ If the output does not fit, truncate it to fit and return BUFSIZE - 1;
+ if this truncates a multibyte sequence,
+ store '\0' into the sequence's first byte.
+ Return the number of bytes stored into BUFFER, excluding
the terminating null byte. Output is always null-terminated.
String arguments are passed as C strings.
Integers are passed as C integers.
goto doit;
case 'o':
+ case 'u':
case 'x':
switch (length_modifier)
{
make_terminal_frame (struct terminal *terminal, Lisp_Object parent,
Lisp_Object params)
{
- char name[sizeof "F" + INT_STRLEN_BOUND (tty_frame_count)];
-
if (!terminal->name)
error ("Terminal is not live, can't create new frames on it");
XSETFRAME (frame, f);
Vframe_list = Fcons (frame, Vframe_list);
- fset_name (f, make_formatted_string (name, "F%"PRIdMAX, ++tty_frame_count));
+ fset_name (f, make_formatted_string ("F%"PRIdMAX, ++tty_frame_count));
SET_FRAME_VISIBLE (f, true);
/* If NAME is nil, set the name to F<num>. */
if (NILP (name))
{
- char namebuf[sizeof "F" + INT_STRLEN_BOUND (tty_frame_count)];
-
/* Check for no change needed in this very common case
before we do any consing. */
if (frame_name_fnn_p (SSDATA (f->name), SBYTES (f->name)))
return;
- name = make_formatted_string (namebuf, "F%"PRIdMAX, ++tty_frame_count);
+ name = make_formatted_string ("F%"PRIdMAX, ++tty_frame_count);
}
else
{
{
Lisp_Object tem;
uintmax_t w;
- char buf[INT_BUFSIZE_BOUND (w)];
/* Represent negative positions (off the top or left screen edge)
in a way that Fmodify_frame_parameters will understand correctly. */
warnings. */
w = (uintptr_t) FRAME_NATIVE_WINDOW (f);
store_in_alist (alistptr, Qwindow_id,
- make_formatted_string (buf, "%"PRIuMAX, w));
+ make_formatted_string ("%"PRIuMAX, w));
#ifdef HAVE_X_WINDOWS
#ifdef USE_X_TOOLKIT
/* Tooltip frame may not have this widget. */
#endif
w = (uintptr_t) FRAME_OUTER_WINDOW (f);
store_in_alist (alistptr, Qouter_window_id,
- make_formatted_string (buf, "%"PRIuMAX, w));
+ make_formatted_string ("%"PRIuMAX, w));
#endif
store_in_alist (alistptr, Qicon_name, f->icon_name);
store_in_alist (alistptr, Qvisibility,
gs_load (struct frame *f, struct image *img)
{
uintmax_t printnum1, printnum2;
- char buffer[sizeof " " + 2 * INT_STRLEN_BOUND (intmax_t)];
Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
Lisp_Object frame;
double in_width, in_height;
printnum1 = FRAME_X_DRAWABLE (f);
printnum2 = img->pixmap;
window_and_pixmap_id
- = make_formatted_string (buffer, "%"PRIuMAX" %"PRIuMAX,
+ = make_formatted_string ("%"PRIuMAX" %"PRIuMAX,
printnum1, printnum2);
printnum1 = FRAME_FOREGROUND_PIXEL (f);
printnum2 = FRAME_BACKGROUND_PIXEL (f);
pixel_colors
- = make_formatted_string (buffer, "%"PRIuMAX" %"PRIuMAX,
+ = make_formatted_string ("%"PRIuMAX" %"PRIuMAX,
printnum1, printnum2);
XSETFRAME (frame, f);
extern Lisp_Object bool_vector_fill (Lisp_Object, Lisp_Object);
extern AVOID string_overflow (void);
extern Lisp_Object make_string (const char *, ptrdiff_t);
-extern Lisp_Object make_formatted_string (char *, const char *, ...)
- ATTRIBUTE_FORMAT_PRINTF (2, 3);
+extern Lisp_Object make_formatted_string (const char *, ...)
+ ATTRIBUTE_FORMAT_PRINTF (1, 2);
extern Lisp_Object make_unibyte_string (const char *, ptrdiff_t);
extern ptrdiff_t vectorlike_nbytes (const union vectorlike_header *hdr);
void
dos_set_window_size (int *rows, int *cols)
{
- char video_name[30];
union REGS regs;
Lisp_Object video_mode;
int video_mode_value, have_vga = 0;
use that mode. */
video_mode
= Fsymbol_value (Fintern_soft (make_formatted_string
- (video_name, "screen-dimensions-%dx%d",
+ ("screen-dimensions-%dx%d",
*rows, *cols), Qnil));
if (FIXNUMP (video_mode)
static char const format[] =
"Antialias: %d, Hinting: %d, RGBA: %d, LCDFilter: %d, "
"Hintstyle: %d, DPI: %f";
- enum
- {
- d_formats = 5,
- d_growth = INT_BUFSIZE_BOUND (int) - sizeof "%d",
- lf_formats = 1,
- max_f_integer_digits = DBL_MAX_10_EXP + 1,
- f_precision = 6,
- lf_growth = (sizeof "-." + max_f_integer_digits + f_precision
- - sizeof "%f")
- };
- char buf[sizeof format + d_formats * d_growth + lf_formats * lf_growth];
#ifdef HAVE_XFT
XftDefaultSet (dpyinfo->display, pat);
#else
store_config_changed_event (Qfont_render,
XCAR (dpyinfo->name_list_element));
Vxft_settings
- = make_formatted_string (buf, format,
+ = make_formatted_string (format,
oldsettings.aa, oldsettings.hinting,
oldsettings.rgba, oldsettings.lcdfilter,
oldsettings.hintstyle, oldsettings.dpi);