Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
emacs
emacs
Commits
9f496c59
Commit
9f496c59
authored
Jun 05, 2017
by
Michael Albinus
Browse files
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
parents
751d5920
13e9493e
Changes
15
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
250 additions
and
218 deletions
+250
-218
doc/lispref/strings.texi
doc/lispref/strings.texi
+6
-7
lisp/desktop.el
lisp/desktop.el
+4
-0
lisp/linum.el
lisp/linum.el
+10
-1
lisp/progmodes/elisp-mode.el
lisp/progmodes/elisp-mode.el
+1
-1
src/data.c
src/data.c
+4
-6
src/dynlib.c
src/dynlib.c
+15
-19
src/dynlib.h
src/dynlib.h
+11
-5
src/editfns.c
src/editfns.c
+66
-88
src/emacs-module.c
src/emacs-module.c
+85
-77
src/emacs-module.h
src/emacs-module.h
+3
-0
src/eval.c
src/eval.c
+5
-2
src/lisp.h
src/lisp.h
+9
-7
src/print.c
src/print.c
+28
-2
test/Makefile.in
test/Makefile.in
+1
-1
test/src/emacs-module-tests.el
test/src/emacs-module-tests.el
+2
-2
No files found.
doc/lispref/strings.texi
View file @
9f496c59
...
@@ -926,7 +926,8 @@ digit.
...
@@ -926,7 +926,8 @@ digit.
@item %%
@item %%
Replace the specification with a single @samp{%}. This format
Replace the specification with a single @samp{%}. This format
specification is unusual in that it does not use a value. For example,
specification is unusual in that its only form is plain
@samp{%%} and that it does not use a value. For example,
@code{(format "%% %d" 30)} returns @code{"% 30"}.
@code{(format "%% %d" 30)} returns @code{"% 30"}.
@end table
@end table
...
@@ -965,10 +966,9 @@ extra values to be formatted are ignored.
...
@@ -965,10 +966,9 @@ extra values to be formatted are ignored.
decimal number immediately after the initial @samp{%}, followed by a
decimal number immediately after the initial @samp{%}, followed by a
literal dollar sign @samp{$}. It causes the format specification to
literal dollar sign @samp{$}. It causes the format specification to
convert the argument with the given number instead of the next
convert the argument with the given number instead of the next
argument. Field numbers start at 1. A field number should differ
argument. Field numbers start at 1. A format can contain either
from the other field numbers in the same format. A format can contain
numbered or unnumbered format specifications but not both, except that
either numbered or unnumbered format specifications but not both,
@samp{%%} can be mixed with numbered specifications.
except that @samp{%%} can be mixed with numbered specifications.
@example
@example
(format "%2$s, %3$s, %%, %1$s" "x" "y" "z")
(format "%2$s, %3$s, %%, %1$s" "x" "y" "z")
...
@@ -1026,8 +1026,7 @@ ignored.
...
@@ -1026,8 +1026,7 @@ ignored.
A specification can have a @dfn{width}, which is a decimal number
A specification can have a @dfn{width}, which is a decimal number
that appears after any field number and flags. If the printed
that appears after any field number and flags. If the printed
representation of the object contains fewer characters than this
representation of the object contains fewer characters than this
width, @code{format} extends it with padding. The width is
width, @code{format} extends it with padding. Any padding introduced by
ignored for the @samp{%%} specification. Any padding introduced by
the width normally consists of spaces inserted on the left:
the width normally consists of spaces inserted on the left:
@example
@example
...
...
lisp/desktop.el
View file @
9f496c59
...
@@ -733,6 +733,10 @@ if different)."
...
@@ -733,6 +733,10 @@ if different)."
(
condition-case
err
(
condition-case
err
(
unless
(
or
(
eq
frame
this
)
(
unless
(
or
(
eq
frame
this
)
(
eq
frame
mini
)
(
eq
frame
mini
)
;; Don't delete daemon's initial frame, or
;; we'll never be able to close the last
;; client's frame (Bug#26912).
(
if
(
daemonp
)
(
not
(
frame-parameter
frame
'client
)))
(
frame-parameter
frame
'desktop-dont-clear
))
(
frame-parameter
frame
'desktop-dont-clear
))
(
delete-frame
frame
))
(
delete-frame
frame
))
(
error
(
error
...
...
lisp/linum.el
View file @
9f496c59
...
@@ -112,7 +112,16 @@ Linum mode is a buffer-local minor mode."
...
@@ -112,7 +112,16 @@ Linum mode is a buffer-local minor mode."
(
define-globalized-minor-mode
global-linum-mode
linum-mode
linum-on
)
(
define-globalized-minor-mode
global-linum-mode
linum-mode
linum-on
)
(
defun
linum-on
()
(
defun
linum-on
()
(
unless
(
minibufferp
)
(
unless
(
or
(
minibufferp
)
;; Turning linum-mode in the daemon's initial frame
;; could significantly slow down startup, if the buffer
;; in which this is done is large, because Emacs thinks
;; the "window" spans the entire buffer then. This
;; could happen when restoring session via desktop.el,
;; if some large buffer was under linum-mode when
;; desktop was saved. So we disable linum-mode for
;; non-client frames in a daemon session.
(
and
(
daemonp
)
(
null
(
frame-parameter
nil
'client
))))
(
linum-mode
1
)))
(
linum-mode
1
)))
(
defun
linum-delete-overlays
()
(
defun
linum-delete-overlays
()
...
...
lisp/progmodes/elisp-mode.el
View file @
9f496c59
...
@@ -1372,7 +1372,7 @@ or elsewhere, return a 1-line docstring."
...
@@ -1372,7 +1372,7 @@ or elsewhere, return a 1-line docstring."
(
condition-case
nil
(
documentation
sym
t
)
(
condition-case
nil
(
documentation
sym
t
)
(
invalid-function
nil
))
(
invalid-function
nil
))
sym
))
sym
))
(
car
doc
))
(
substitute-command-keys
(
car
doc
))
)
(
t
(
help-function-arglist
sym
)))))
(
t
(
help-function-arglist
sym
)))))
;; Stringify, and store before highlighting, downcasing, etc.
;; Stringify, and store before highlighting, downcasing, etc.
(
elisp--last-data-store
sym
(
elisp-function-argstring
args
)
(
elisp--last-data-store
sym
(
elisp-function-argstring
args
)
...
...
src/data.c
View file @
9f496c59
...
@@ -700,12 +700,10 @@ global value outside of any lexical scope. */)
...
@@ -700,12 +700,10 @@ global value outside of any lexical scope. */)
return
(
EQ
(
valcontents
,
Qunbound
)
?
Qnil
:
Qt
);
return
(
EQ
(
valcontents
,
Qunbound
)
?
Qnil
:
Qt
);
}
}
/* FIXME: It has been previously suggested to make this function an
/* It has been previously suggested to make this function an alias for
alias for symbol-function, but upon discussion at Bug#23957,
symbol-function, but upon discussion at Bug#23957, there is a risk
there is a risk breaking backward compatibility, as some users of
breaking backward compatibility, as some users of fboundp may
fboundp may expect `t' in particular, rather than any true
expect `t' in particular, rather than any true value. */
value. An alias is still welcome so long as the compatibility
issues are addressed. */
DEFUN
(
"fboundp"
,
Ffboundp
,
Sfboundp
,
1
,
1
,
0
,
DEFUN
(
"fboundp"
,
Ffboundp
,
Sfboundp
,
1
,
1
,
0
,
doc
:
/* Return t if SYMBOL's function definition is not void. */
)
doc
:
/* Return t if SYMBOL's function definition is not void. */
)
(
register
Lisp_Object
symbol
)
(
register
Lisp_Object
symbol
)
...
...
src/dynlib.c
View file @
9f496c59
...
@@ -28,6 +28,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
...
@@ -28,6 +28,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
#include "dynlib.h"
#include "dynlib.h"
#include <stddef.h>
#ifdef WINDOWSNT
#ifdef WINDOWSNT
/* MS-Windows systems. */
/* MS-Windows systems. */
...
@@ -120,7 +122,7 @@ dynlib_sym (dynlib_handle_ptr h, const char *sym)
...
@@ -120,7 +122,7 @@ dynlib_sym (dynlib_handle_ptr h, const char *sym)
return
(
void
*
)
sym_addr
;
return
(
void
*
)
sym_addr
;
}
}
bool
void
dynlib_addr
(
void
*
addr
,
const
char
**
fname
,
const
char
**
symname
)
dynlib_addr
(
void
*
addr
,
const
char
**
fname
,
const
char
**
symname
)
{
{
static
char
dll_filename
[
MAX_UTF8_PATH
];
static
char
dll_filename
[
MAX_UTF8_PATH
];
...
@@ -128,7 +130,6 @@ dynlib_addr (void *addr, const char **fname, const char **symname)
...
@@ -128,7 +130,6 @@ dynlib_addr (void *addr, const char **fname, const char **symname)
static
GetModuleHandleExA_Proc
s_pfn_Get_Module_HandleExA
=
NULL
;
static
GetModuleHandleExA_Proc
s_pfn_Get_Module_HandleExA
=
NULL
;
char
*
dll_fn
=
NULL
;
char
*
dll_fn
=
NULL
;
HMODULE
hm_kernel32
=
NULL
;
HMODULE
hm_kernel32
=
NULL
;
bool
result
=
false
;
HMODULE
hm_dll
=
NULL
;
HMODULE
hm_dll
=
NULL
;
wchar_t
mfn_w
[
MAX_PATH
];
wchar_t
mfn_w
[
MAX_PATH
];
char
mfn_a
[
MAX_PATH
];
char
mfn_a
[
MAX_PATH
];
...
@@ -206,23 +207,18 @@ dynlib_addr (void *addr, const char **fname, const char **symname)
...
@@ -206,23 +207,18 @@ dynlib_addr (void *addr, const char **fname, const char **symname)
dynlib_last_err
=
GetLastError
();
dynlib_last_err
=
GetLastError
();
}
}
if
(
dll_fn
)
if
(
dll_fn
)
{
dostounix_filename
(
dll_fn
);
dostounix_filename
(
dll_fn
);
/* We cannot easily produce the function name, since
typically all of the module functions will be unexported,
and probably even static, which means the symbols can be
obtained only if we link against libbfd (and the DLL can
be stripped anyway). So we just show the address and the
file name; they can use that with addr2line or GDB to
recover the symbolic name. */
sprintf
(
addr_str
,
"at 0x%x"
,
(
DWORD_PTR
)
addr
);
*
symname
=
addr_str
;
result
=
true
;
}
}
}
*
fname
=
dll_fn
;
*
fname
=
dll_fn
;
return
result
;
/* We cannot easily produce the function name, since typically all
of the module functions will be unexported, and probably even
static, which means the symbols can be obtained only if we link
against libbfd (and the DLL can be stripped anyway). So we just
show the address and the file name; they can use that with
addr2line or GDB to recover the symbolic name. */
*
symname
=
NULL
;
}
}
const
char
*
const
char
*
...
@@ -283,19 +279,19 @@ dynlib_sym (dynlib_handle_ptr h, const char *sym)
...
@@ -283,19 +279,19 @@ dynlib_sym (dynlib_handle_ptr h, const char *sym)
return
dlsym
(
h
,
sym
);
return
dlsym
(
h
,
sym
);
}
}
bool
void
dynlib_addr
(
void
*
ptr
,
const
char
**
path
,
const
char
**
sym
)
dynlib_addr
(
void
*
ptr
,
const
char
**
path
,
const
char
**
sym
)
{
{
*
path
=
NULL
;
*
sym
=
NULL
;
#ifdef HAVE_DLADDR
#ifdef HAVE_DLADDR
Dl_info
info
;
Dl_info
info
;
if
(
dladdr
(
ptr
,
&
info
)
&&
info
.
dli_fname
&&
info
.
dli_sname
)
if
(
dladdr
(
ptr
,
&
info
)
&&
info
.
dli_fname
&&
info
.
dli_sname
)
{
{
*
path
=
info
.
dli_fname
;
*
path
=
info
.
dli_fname
;
*
sym
=
info
.
dli_sname
;
*
sym
=
info
.
dli_sname
;
return
true
;
}
}
#endif
#endif
return
false
;
}
}
const
char
*
const
char
*
...
...
src/dynlib.h
View file @
9f496c59
...
@@ -24,11 +24,17 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
...
@@ -24,11 +24,17 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
typedef
void
*
dynlib_handle_ptr
;
typedef
void
*
dynlib_handle_ptr
;
dynlib_handle_ptr
dynlib_open
(
const
char
*
path
);
dynlib_handle_ptr
dynlib_open
(
const
char
*
path
);
void
*
dynlib_sym
(
dynlib_handle_ptr
h
,
const
char
*
sym
);
typedef
struct
dynlib_function_ptr_nonce
*
(
*
dynlib_function_ptr
)
(
void
);
dynlib_function_ptr
dynlib_func
(
dynlib_handle_ptr
h
,
const
char
*
sym
);
bool
dynlib_addr
(
void
*
ptr
,
const
char
**
path
,
const
char
**
sym
);
const
char
*
dynlib_error
(
void
);
int
dynlib_close
(
dynlib_handle_ptr
h
);
int
dynlib_close
(
dynlib_handle_ptr
h
);
const
char
*
dynlib_error
(
void
);
ATTRIBUTE_MAY_ALIAS
void
*
dynlib_sym
(
dynlib_handle_ptr
h
,
const
char
*
sym
);
typedef
struct
dynlib_function_ptr_nonce
*
(
ATTRIBUTE_MAY_ALIAS
*
dynlib_function_ptr
)
(
void
);
dynlib_function_ptr
dynlib_func
(
dynlib_handle_ptr
h
,
const
char
*
sym
);
/* Sets *FILE to the file name from which PTR was loaded, and *SYM to
its symbol name. If the file or symbol name could not be
determined, set the corresponding argument to NULL. */
void
dynlib_addr
(
void
*
ptr
,
const
char
**
file
,
const
char
**
sym
);
#endif
/* DYNLIB_H */
#endif
/* DYNLIB_H */
src/editfns.c
View file @
9f496c59
...
@@ -3891,8 +3891,8 @@ the next available argument, or the argument explicitly specified:
...
@@ -3891,8 +3891,8 @@ the next available argument, or the argument explicitly specified:
The argument used for %d, %o, %x, %e, %f, %g or %c must be a number.
The argument used for %d, %o, %x, %e, %f, %g or %c must be a number.
Use %% to put a single % into the output.
Use %% to put a single % into the output.
A %-sequence may contain optional field number, flag,
width, and
A %-sequence
other than %%
may contain optional field number, flag,
precision specifiers, as follows:
width, and
precision specifiers, as follows:
%<field><flags><width><precision>character
%<field><flags><width><precision>character
...
@@ -3901,10 +3901,9 @@ where field is [0-9]+ followed by a literal dollar "$", flags is
...
@@ -3901,10 +3901,9 @@ where field is [0-9]+ followed by a literal dollar "$", flags is
followed by [0-9]+.
followed by [0-9]+.
If a %-sequence is numbered with a field with positive value N, the
If a %-sequence is numbered with a field with positive value N, the
Nth argument is substituted instead of the next one. A field number
Nth argument is substituted instead of the next one. A format can
should differ from the other field numbers in the same format. A
contain either numbered or unnumbered %-sequences but not both, except
format can contain either numbered or unnumbered %-sequences but not
that %% can be mixed with numbered %-sequences.
both, except that %% can be mixed with numbered %-sequences.
The + flag character inserts a + before any positive number, while a
The + flag character inserts a + before any positive number, while a
space inserts a space before any positive number; these flags only
space inserts a space before any positive number; these flags only
...
@@ -3980,49 +3979,40 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
...
@@ -3980,49 +3979,40 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
bool arg_intervals = false;
bool arg_intervals = false;
USE_SAFE_ALLOCA;
USE_SAFE_ALLOCA;
/* Each element records, for one field,
/* Information recorded for each format spec. */
the corresponding argument,
the start and end bytepos in the output string,
whether the argument has been converted to string (e.g., due to "%S"),
and whether the argument is a string with intervals. */
struct info
struct info
{
{
/* The corresponding argument, converted to string if conversion
was needed. */
Lisp_Object argument;
Lisp_Object argument;
/* The start and end bytepos in the output string. */
ptrdiff_t start, end;
ptrdiff_t start, end;
bool_bf converted_to_string : 1;
/* Whether the argument is a string with intervals. */
bool_bf intervals : 1;
bool_bf intervals : 1;
} *info;
} *info;
CHECK_STRING (args[0]);
CHECK_STRING (args[0]);
char *format_start = SSDATA (args[0]);
char *format_start = SSDATA (args[0]);
bool multibyte_format = STRING_MULTIBYTE (args[0]);
ptrdiff_t formatlen = SBYTES (args[0]);
ptrdiff_t formatlen = SBYTES (args[0]);
/* The number of percent characters is a safe upper bound for the
/* Upper bound on number of format specs. Each uses at least 2 chars. */
number of format fields. */
ptrdiff_t nspec_bound = SCHARS (args[0]) >> 1;
ptrdiff_t num_percent = 0;
for (ptrdiff_t i = 0; i < formatlen; ++i)
if (format_start[i] == '%')
++num_percent;
/* Allocate the info and discarded tables. */
/* Allocate the info and discarded tables. */
ptrdiff_t alloca_size;
ptrdiff_t alloca_size;
if (INT_MULTIPLY_WRAPV (num_percent, sizeof *info, &alloca_size)
if (INT_MULTIPLY_WRAPV (nspec_bound, sizeof *info, &alloca_size)
|| INT_ADD_WRAPV (sizeof *info, alloca_size, &alloca_size)
|| INT_ADD_WRAPV (formatlen, alloca_size, &alloca_size)
|| INT_ADD_WRAPV (formatlen, alloca_size, &alloca_size)
|| SIZE_MAX < alloca_size)
|| SIZE_MAX < alloca_size)
memory_full (SIZE_MAX);
memory_full (SIZE_MAX);
/* info[0] is unused. Unused elements have -1 for start. */
info = SAFE_ALLOCA (alloca_size);
info = SAFE_ALLOCA (alloca_size);
memset (info, 0, alloca_size);
for (ptrdiff_t i = 0; i < num_percent + 1; i++)
{
info[i].argument = Qunbound;
info[i].start = -1;
}
/* discarded[I] is 1 if byte I of the format
/* discarded[I] is 1 if byte I of the format
string was not copied into the output.
string was not copied into the output.
It is 2 if byte I was not the first byte of its character. */
It is 2 if byte I was not the first byte of its character. */
char *discarded = (char *) &info[num_percent + 1];
char *discarded = (char *) &info[nspec_bound];
memset (discarded, 0, formatlen);
/* Try to determine whether the result should be multibyte.
/* Try to determine whether the result should be multibyte.
This is not always right; sometimes the result needs to be multibyte
This is not always right; sometimes the result needs to be multibyte
...
@@ -4030,8 +4020,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
...
@@ -4030,8 +4020,6 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
or because a grave accent or apostrophe is requoted,
or because a grave accent or apostrophe is requoted,
and in that case, we won't know it here. */
and in that case, we won't know it here. */
/* True if the format is multibyte. */
bool multibyte_format = STRING_MULTIBYTE (args[0]);
/* True if the output should be a multibyte string,
/* True if the output should be a multibyte string,
which is true if any of the inputs is one. */
which is true if any of the inputs is one. */
bool multibyte = multibyte_format;
bool multibyte = multibyte_format;
...
@@ -4042,6 +4030,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
...
@@ -4042,6 +4030,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
int quoting_style = message ? text_quoting_style () : -1;
int quoting_style = message ? text_quoting_style () : -1;
ptrdiff_t ispec;
ptrdiff_t ispec;
ptrdiff_t nspec = 0;
/* If we start out planning a unibyte result,
/* If we start out planning a unibyte result,
then discover it has to be multibyte, we jump back to retry. */
then discover it has to be multibyte, we jump back to retry. */
...
@@ -4155,11 +4144,14 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
...
@@ -4155,11 +4144,14 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
if (! (n < nargs))
if (! (n < nargs))
error ("Not enough arguments for format string");
error ("Not enough arguments for format string");
eassert (ispec < num_percent);
struct info *spec = &info[ispec++];
++ispec;
if (nspec < ispec)
{
if (EQ (info[ispec].argument, Qunbound))
spec->argument = args[n];
info[ispec].argument = args[n];
spec->intervals = false;
nspec = ispec;
}
Lisp_Object arg = spec->argument;
/* For 'S', prin1 the argument, and then treat like 's'.
/* For 'S', prin1 the argument, and then treat like 's'.
For 's', princ any argument that is not a string or
For 's', princ any argument that is not a string or
...
@@ -4167,16 +4159,13 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
...
@@ -4167,16 +4159,13 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
happen after retrying. */
happen after retrying. */
if ((conversion == 'S'
if ((conversion == 'S'
|| (conversion == 's'
|| (conversion == 's'
&& ! STRINGP (info[ispec].argument)
&& ! STRINGP (arg) && ! SYMBOLP (arg))))
&& ! SYMBOLP (info[ispec].argument))))
{
{
if (
! info[ispec].converted_to_string
)
if (
EQ (arg, args[n])
)
{
{
Lisp_Object noescape = conversion == 'S' ? Qnil : Qt;
Lisp_Object noescape = conversion == 'S' ? Qnil : Qt;
info[ispec].argument =
spec->argument = arg = Fprin1_to_string (arg, noescape);
Fprin1_to_string (info[ispec].argument, noescape);
if (STRING_MULTIBYTE (arg) && ! multibyte)
info[ispec].converted_to_string = true;
if (STRING_MULTIBYTE (info[ispec].argument) && ! multibyte)
{
{
multibyte = true;
multibyte = true;
goto retry;
goto retry;
...
@@ -4186,29 +4175,25 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
...
@@ -4186,29 +4175,25 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
}
}
else if (conversion == 'c')
else if (conversion == 'c')
{
{
if (INTEGERP (info[ispec].argument)
if (INTEGERP (arg) && ! ASCII_CHAR_P (XINT (arg)))
&& ! ASCII_CHAR_P (XINT (info[ispec].argument)))
{
{
if (!multibyte)
if (!multibyte)
{
{
multibyte = true;
multibyte = true;
goto retry;
goto retry;
}
}
info[ispec].argument =
spec->argument = arg = Fchar_to_string (arg);
Fchar_to_string (info[ispec].argument);
info[ispec].converted_to_string = true;
}
}
if (
info[ispec].converted_to_string
)
if (
!EQ (arg, args[n])
)
conversion = 's';
conversion = 's';
zero_flag = false;
zero_flag = false;
}
}
if (SYMBOLP (
info[ispec].argument
))
if (SYMBOLP (
arg
))
{
{
info[ispec].argument =
spec->argument = arg = SYMBOL_NAME (arg);
SYMBOL_NAME (info[ispec].argument);
if (STRING_MULTIBYTE (arg) && ! multibyte)
if (STRING_MULTIBYTE (info[ispec].argument) && ! multibyte)
{
{
multibyte = true;
multibyte = true;
goto retry;
goto retry;
...
@@ -4239,12 +4224,11 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
...
@@ -4239,12 +4224,11 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
else
else
{
{
ptrdiff_t nch, nby;
ptrdiff_t nch, nby;
width = lisp_string_width (info[ispec].argument,
width = lisp_string_width (arg, prec, &nch, &nby);
prec, &nch, &nby);
if (prec < 0)
if (prec < 0)
{
{
nchars_string = SCHARS (
info[ispec].argument
);
nchars_string = SCHARS (
arg
);
nbytes = SBYTES (
info[ispec].argument
);
nbytes = SBYTES (
arg
);
}
}
else
else
{
{
...
@@ -4254,11 +4238,8 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
...
@@ -4254,11 +4238,8 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
}
}
convbytes = nbytes;
convbytes = nbytes;
if (convbytes && multibyte &&
if (convbytes && multibyte && ! STRING_MULTIBYTE (arg))
! STRING_MULTIBYTE (info[ispec].argument))
convbytes = count_size_as_multibyte (SDATA (arg), nbytes);
convbytes =
count_size_as_multibyte (SDATA (info[ispec].argument),
nbytes);
ptrdiff_t padding
ptrdiff_t padding
= width < field_width ? field_width - width : 0;
= width < field_width ? field_width - width : 0;
...
@@ -4274,20 +4255,18 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
...
@@ -4274,20 +4255,18 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
p += padding;
p += padding;
nchars += padding;
nchars += padding;
}
}
info[i
spec
].
start = nchars;
spec
->
start = nchars;
if (p > buf
if (p > buf
&& multibyte
&& multibyte
&& !ASCII_CHAR_P (*((unsigned char *) p - 1))
&& !ASCII_CHAR_P (*((unsigned char *) p - 1))
&& STRING_MULTIBYTE (
info[ispec].argument
)
&& STRING_MULTIBYTE (
arg
)
&& !CHAR_HEAD_P (SREF (
info[ispec].argument
, 0)))
&& !CHAR_HEAD_P (SREF (
arg
, 0)))
maybe_combine_byte = true;
maybe_combine_byte = true;
p += copy_text (SDATA (info[ispec].argument),
p += copy_text (SDATA (arg), (unsigned char *) p,
(unsigned char *) p,
nbytes,
nbytes,
STRING_MULTIBYTE (info[ispec].argument),
STRING_MULTIBYTE (arg), multibyte);
multibyte);
nchars += nchars_string;
nchars += nchars_string;
...
@@ -4297,12 +4276,12 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
...
@@ -4297,12 +4276,12 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
p += padding;
p += padding;
nchars += padding;
nchars += padding;
}
}
info[i
spec
].
end = nchars;
spec
->
end = nchars;
/* If this argument has text properties, record where
/* If this argument has text properties, record where
in the result string it appears. */
in the result string it appears. */
if (string_intervals (
info[ispec].argument
))
if (string_intervals (
arg
))
info[i
spec
].
intervals = arg_intervals = true;
spec
->
intervals = arg_intervals = true;
continue;
continue;
}
}
...
@@ -4313,8 +4292,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
...
@@ -4313,8 +4292,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
|| conversion == 'X'))
|| conversion == 'X'))
error ("Invalid format operation %%%c",
error ("Invalid format operation %%%c",
STRING_CHAR ((unsigned char *) format - 1));
STRING_CHAR ((unsigned char *) format - 1));
else if (! (INTEGERP (info[ispec].argument)
else if (! (INTEGERP (arg) || (FLOATP (arg) && conversion != 'c')))
|| (FLOATP (info[ispec].argument) && conversion != 'c')))
error ("Format specifier doesn't match argument type");
error ("Format specifier doesn't match argument type");
else
else
{
{
...
@@ -4376,7 +4354,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
...
@@ -4376,7 +4354,7 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
if (INT_AS_LDBL)
if (INT_AS_LDBL)
{
{
*f = 'L';
*f = 'L';
f += INTEGERP (
info[ispec].argument
);
f += INTEGERP (
arg
);
}
}
}
}
else if (conversion != 'c')
else if (conversion != 'c')
...
@@ -4408,22 +4386,22 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
...
@@ -4408,22 +4386,22 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message)
ptrdiff_t sprintf_bytes;
ptrdiff_t sprintf_bytes;
if (float_conversion)
if (float_conversion)
{
{
if (INT_AS_LDBL && INTEGERP (
info[ispec].argument
))
if (INT_AS_LDBL && INTEGERP (
arg
))
{
{
/* Although long double may have a rounding error if
/* Although long double may have a rounding error if
DIG_BITS_LBOUND * LDBL_MANT_DIG < FIXNUM_BITS - 1,
DIG_BITS_LBOUND * LDBL_MANT_DIG < FIXNUM_BITS - 1,
it is more accurate than plain 'double'. */
it is more accurate than plain 'double'. */
long double x = XINT (
info[ispec].argument
);
long double x = XINT (
arg
);
sprintf_bytes = sprintf (sprintf_buf, convspec, prec, x);