Commit b2ded58d authored by Paul Eggert's avatar Paul Eggert
Browse files

Fix more problems found by GCC 4.6.0's static checks.

parents 37f1c930 12020a9e
2011-04-09 Paul Eggert <eggert@cs.ucla.edu>
* lib/allocator.c: New file, automatically generated by gnulib.
2011-04-07 Glenn Morris <rgm@gnu.org>
* autogen/update_autogen: Ignore comment diffs in ldefs-boot.el.
......
#define _GL_USE_STDLIB_ALLOC 1
#include <config.h>
#include "allocator.h"
#include <stdlib.h>
struct allocator const stdlib_allocator = { malloc, realloc, free, NULL };
......@@ -18,6 +18,7 @@
/* Written by Paul Eggert. */
#ifndef _GL_ALLOCATOR_H
#define _GL_ALLOCATOR_H
#include <stddef.h>
......@@ -30,16 +31,16 @@ struct allocator
attributes do not work with pointers to functions. See
<http://lists.gnu.org/archive/html/bug-gnulib/2011-04/msg00007.html>. */
/* Call MALLOC to allocate memory, like 'malloc'. On failure MALLOC
/* Call ALLOCATE to allocate memory, like 'malloc'. On failure ALLOCATE
should return NULL, though not necessarily set errno. When given
a zero size it may return NULL even if successful. */
void *(*malloc) (size_t);
void *(*allocate) (size_t);
/* If nonnull, call REALLOC to reallocate memory, like 'realloc'.
On failure REALLOC should return NULL, though not necessarily set
/* If nonnull, call REALLOCATE to reallocate memory, like 'realloc'.
On failure REALLOCATE should return NULL, though not necessarily set
errno. When given a zero size it may return NULL even if
successful. */
void *(*realloc) (void *, size_t);
void *(*reallocate) (void *, size_t);
/* Call FREE to free memory, like 'free'. */
void (*free) (void *);
......@@ -50,4 +51,7 @@ struct allocator
void (*die) (void);
};
#endif
/* An allocator using the stdlib functions and a null DIE function. */
extern struct allocator const stdlib_allocator;
#endif /* _GL_ALLOCATOR_H */
......@@ -22,19 +22,12 @@
#include "careadlinkat.h"
#include "allocator.h"
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
/* Use the system functions, not the gnulib overrides, because this
module does not depend on GNU or POSIX semantics. */
#undef malloc
#undef realloc
/* Define this independently so that stdint.h is not a prerequisite. */
#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
......@@ -44,24 +37,24 @@
# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
#endif
#include "allocator.h"
#if ! HAVE_READLINKAT
/* Ignore FD. Get the symbolic link value of FILENAME and put it into
BUFFER, with size BUFFER_SIZE. This function acts like readlink
but has readlinkat's signature. */
/* Get the symbolic link value of FILENAME and put it into BUFFER, with
size BUFFER_SIZE. This function acts like readlink but has
readlinkat's signature. */
ssize_t
careadlinkatcwd (int fd, char const *filename, char *buffer,
size_t buffer_size)
{
(void) fd;
/* FD must be AT_FDCWD here, otherwise the caller is using this
function in contexts for which it was not meant for. */
if (fd != AT_FDCWD)
abort ();
return readlink (filename, buffer, buffer_size);
}
#endif
/* A standard allocator. For now, only careadlinkat needs this, but
perhaps it should be moved to the allocator module. */
static struct allocator const standard_allocator =
{ malloc, realloc, free, NULL };
/* Assuming the current directory is FD, get the symbolic link value
of FILENAME as a null-terminated string and put it into a buffer.
If FD is AT_FDCWD, FILENAME is interpreted relative to the current
......@@ -76,7 +69,10 @@ static struct allocator const standard_allocator =
the returned value if it is nonnull and is not BUFFER. A null
ALLOC stands for the standard allocator.
The PREADLINKAT function specifies how to read links.
The PREADLINKAT function specifies how to read links. It operates
like POSIX readlinkat()
<http://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html>
but can assume that its first argument is the same as FD.
If successful, return the buffer address; otherwise return NULL and
set errno. */
......@@ -94,7 +90,7 @@ careadlinkat (int fd, char const *filename,
char stack_buf[1024];
if (! alloc)
alloc = &standard_allocator;
alloc = &stdlib_allocator;
if (! buffer_size)
{
......@@ -138,16 +134,16 @@ careadlinkat (int fd, char const *filename,
if (buf == stack_buf)
{
char *b = (char *) alloc->malloc (link_size);
char *b = (char *) alloc->allocate (link_size);
if (! b)
break;
memcpy (b, buf, link_size);
buf = b;
}
else if (link_size < buf_size && buf != buffer && alloc->realloc)
else if (link_size < buf_size && buf != buffer && alloc->reallocate)
{
/* Shrink BUF before returning it. */
char *b = (char *) alloc->realloc (buf, link_size);
char *b = (char *) alloc->reallocate (buf, link_size);
if (b)
buf = b;
}
......@@ -164,7 +160,7 @@ careadlinkat (int fd, char const *filename,
buf_size = buf_size_max;
else
break;
buf = (char *) alloc->malloc (buf_size);
buf = (char *) alloc->allocate (buf_size);
}
while (buf);
......
......@@ -18,6 +18,7 @@
/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */
#ifndef _GL_CAREADLINKAT_H
#define _GL_CAREADLINKAT_H
#include <fcntl.h>
#include <unistd.h>
......@@ -37,7 +38,10 @@ struct allocator;
buffer managed by ALLOC. It is the caller's responsibility to free
the returned value if it is nonnull and is not BUFFER.
The PREADLINKAT function specifies how to read links.
The PREADLINKAT function specifies how to read links. It operates
like POSIX readlinkat()
<http://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html>
but can assume that its first argument is the same as FD.
If successful, return the buffer address; otherwise return NULL and
set errno. */
......@@ -49,8 +53,10 @@ char *careadlinkat (int fd, char const *filename,
char *, size_t));
/* Suitable values for careadlinkat's FD and PREADLINKAT arguments,
when doing a plain readlink. */
when doing a plain readlink:
Pass FD = AT_FDCWD and PREADLINKAT = careadlinkatcwd. */
#if HAVE_READLINKAT
/* AT_FDCWD is declared in <fcntl.h>, readlinkat in <unistd.h>. */
# define careadlinkatcwd readlinkat
#else
/* Define AT_FDCWD independently, so that the careadlinkat module does
......
......@@ -21,6 +21,14 @@ libgnu_a_LIBADD = $(gl_LIBOBJS)
libgnu_a_DEPENDENCIES = $(gl_LIBOBJS)
EXTRA_libgnu_a_SOURCES =
## begin gnulib module allocator
libgnu_a_SOURCES += allocator.c
EXTRA_DIST += allocator.h
## end gnulib module allocator
## begin gnulib module arg-nonnull
# The BUILT_SOURCES created by this Makefile snippet are not used via #include
......@@ -73,7 +81,7 @@ EXTRA_DIST += $(top_srcdir)/./c++defs.h
libgnu_a_SOURCES += careadlinkat.c
EXTRA_DIST += allocator.h careadlinkat.h
EXTRA_DIST += careadlinkat.h
## end gnulib module careadlinkat
......
......@@ -255,9 +255,14 @@ _GL_WARN_ON_USE (ptsname, "grantpt is not portable - "
# endif
#endif
/* If _GL_USE_STDLIB_ALLOC is nonzero, the including module does not
rely on GNU or POSIX semantics for malloc and realloc (for example,
by never specifying a zero size), so it does not need malloc or
realloc to be redefined. */
#if @GNULIB_MALLOC_POSIX@
# if @REPLACE_MALLOC@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \
|| _GL_USE_STDLIB_ALLOC)
# undef malloc
# define malloc rpl_malloc
# endif
......@@ -267,7 +272,7 @@ _GL_CXXALIAS_RPL (malloc, void *, (size_t size));
_GL_CXXALIAS_SYS (malloc, void *, (size_t size));
# endif
_GL_CXXALIASWARN (malloc);
#elif defined GNULIB_POSIXCHECK
#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC
# undef malloc
/* Assume malloc is always declared. */
_GL_WARN_ON_USE (malloc, "malloc is not POSIX compliant everywhere - "
......@@ -531,7 +536,8 @@ _GL_WARN_ON_USE (setstate_r, "setstate_r is unportable - "
#if @GNULIB_REALLOC_POSIX@
# if @REPLACE_REALLOC@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# if !((defined __cplusplus && defined GNULIB_NAMESPACE) \
|| _GL_USE_STDLIB_ALLOC)
# undef realloc
# define realloc rpl_realloc
# endif
......@@ -541,7 +547,7 @@ _GL_CXXALIAS_RPL (realloc, void *, (void *ptr, size_t size));
_GL_CXXALIAS_SYS (realloc, void *, (void *ptr, size_t size));
# endif
_GL_CXXALIASWARN (realloc);
#elif defined GNULIB_POSIXCHECK
#elif defined GNULIB_POSIXCHECK && !_GL_USE_STDLIB_ALLOC
# undef realloc
/* Assume realloc is always declared. */
_GL_WARN_ON_USE (realloc, "realloc is not POSIX compliant everywhere - "
......
......@@ -26,6 +26,7 @@ AC_DEFUN([gl_EARLY],
m4_pattern_allow([^gl_LIBOBJS$])dnl a variable
m4_pattern_allow([^gl_LTLIBOBJS$])dnl a variable
AC_REQUIRE([AC_PROG_RANLIB])
# Code from module allocator:
# Code from module arg-nonnull:
# Code from module c++defs:
# Code from module careadlinkat:
......@@ -79,6 +80,7 @@ AC_DEFUN([gl_INIT],
m4_pushdef([gl_LIBSOURCES_DIR], [])
gl_COMMON
gl_source_base='lib'
# Code from module allocator:
# Code from module arg-nonnull:
# Code from module c++defs:
# Code from module careadlinkat:
......@@ -293,6 +295,7 @@ AC_DEFUN([gl_FILE_LIST], [
build-aux/arg-nonnull.h
build-aux/c++defs.h
build-aux/warn-on-use.h
lib/allocator.c
lib/allocator.h
lib/careadlinkat.c
lib/careadlinkat.h
......
2011-04-10 Paul Eggert <eggert@cs.ucla.edu>
Fix more problems found by GCC 4.6.0's static checks.
* xdisp.c (vmessage): Use a better test for character truncation.
* charset.c (load_charset_map): <, not <=, for optimization,
and to avoid potential problems with integer overflow.
* chartab.c (sub_char_table_set_range, char_table_set_range): Likewise.
* casetab.c (set_identity, shuffle): Likewise.
* editfns.c (Fformat): Likewise.
* syntax.c (skip_chars): Likewise.
* xmenu.c (set_frame_menubar): Allocate smaller local vectors.
This also lets GCC 4.6.0 generate slightly better loop code.
* callint.c (Fcall_interactively): <, not <=, for optimization.
(Fcall_interactively): Count the number of arguments produced,
not the number of arguments given. This is simpler and lets GCC
4.6.0 generate slightly better code.
* ftfont.c: Distingish more carefully between FcChar8 and char.
The previous code passed unsigned char * to a functions like
strlen and xstrcasecmp that expect char *, which does not
conform to the C standard.
(get_adstyle_property, ftfont_pattern_entity): Use FcChar8 for
arguments to FcPatternGetString, and explicitly cast FcChar8 * to
char * when the C standard requires it.
* keyboard.c (read_char): Remove unused var.
* eval.c: Port to Windows vsnprintf (Bug#8435).
Include <limits.h>.
(SIZE_MAX): Define if the headers do not.
(verror): Do not give up if vsnprintf returns a negative count.
Instead, grow the buffer. This ports to Windows vsnprintf, which
does not conform to C99. Problem reported by Eli Zaretskii.
Also, simplify the allocation scheme, by avoiding the need for
calling realloc, and removing the ALLOCATED variable.
* eval.c (verror): Initial buffer size is 4000 (not 200) bytes.
Remove invocations of doprnt, as Emacs now uses vsnprintf.
But keep the doprint source code for now, as we might revamp it
and use it again (Bug#8435).
* lisp.h (doprnt): Remove.
* Makefile.in (base_obj): Remove doprnt.o.
* deps.mk (doprnt.o): Remove.
error: Print 32- and 64-bit integers portably (Bug#8435).
Without this change, on typical 64-bit hosts error ("...%d...", N)
was used to print both 32- and 64-bit integers N, which relied on
undefined behavior.
* lisp.h, src/m/amdx86-64.h, src/m/ia64.h, src/m/ibms390x.h (pEd):
New macro.
* lisp.h (error, verror): Mark as printf-like functions.
* eval.c (verror): Use vsnprintf, not doprnt, to do the real work.
Report overflow in size calculations when allocating printf buffer.
Do not truncate output string at its first null byte.
* xdisp.c (vmessage): Use vsnprintf, not doprnt, to do the real work.
Truncate the output at a character boundary, since vsnprintf does not
do that.
* charset.c (check_iso_charset_parameter): Convert internal
character to string before calling 'error', since %c now has the
printf meaning.
* coding.c (Fdecode_sjis_char, Fdecode_big5_char): Avoid int
overflow when computing char to be passed to 'error'. Do not
pass Lisp_Object to 'error'; pass the integer instead.
* nsfns.m (Fns_do_applescript): Use int, not long, since it's
formatted with plain %d.
* eval.c (internal_lisp_condition_case): Don't pass spurious arg.
* keyboard.c (access_keymap_keyremap): Print func name, not garbage.
* coding.c (Fdecode_sjis_char): Don't assume CODE fits in int.
* xterm.c (x_catch_errors): Remove duplicate declaration.
* term.c (maybe_fatal): Mark its 3rd arg as a printf format, too.
* xdisp.c, lisp.h (message_nolog): Remove; unused.
2011-04-10 Jim Meyering <meyering@redhat.com>
use ssize_t and size_t for read- and write-like emacs_gnutls_* functions
......
......@@ -354,7 +354,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
syntax.o $(UNEXEC_OBJ) bytecode.o \
process.o gnutls.o callproc.o \
region-cache.o sound.o atimer.o \
doprnt.o intervals.o textprop.o composite.o xml.o \
intervals.o textprop.o composite.o xml.o \
$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ)
obj = $(base_obj) $(NS_OBJC_OBJ)
......
......@@ -269,8 +269,8 @@ invoke it. If KEYS is omitted or nil, the return value of
recorded as a call to the function named callint_argfuns[varies[i]]. */
int *varies;
register size_t i, j;
size_t count;
register size_t i;
size_t nargs;
int foo;
char prompt1[100];
char *tem1;
......@@ -445,30 +445,29 @@ invoke it. If KEYS is omitted or nil, the return value of
else break;
}
/* Count the number of arguments the interactive spec would have
us give to the function. */
/* Count the number of arguments, which is one plus the number of arguments
the interactive spec would have us give to the function. */
tem = string;
for (j = 0; *tem;)
for (nargs = 1; *tem; )
{
/* 'r' specifications ("point and mark as 2 numeric args")
produce *two* arguments. */
if (*tem == 'r')
j += 2;
nargs += 2;
else
j++;
nargs++;
tem = strchr (tem, '\n');
if (tem)
++tem;
else
break;
}
count = j;
args = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object));
visargs = (Lisp_Object *) alloca ((count + 1) * sizeof (Lisp_Object));
varies = (int *) alloca ((count + 1) * sizeof (int));
args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
visargs = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object));
varies = (int *) alloca (nargs * sizeof (int));
for (i = 0; i < (count + 1); i++)
for (i = 0; i < nargs; i++)
{
args[i] = Qnil;
visargs[i] = Qnil;
......@@ -476,8 +475,8 @@ invoke it. If KEYS is omitted or nil, the return value of
}
GCPRO5 (prefix_arg, function, *args, *visargs, up_event);
gcpro3.nvars = (count + 1);
gcpro4.nvars = (count + 1);
gcpro3.nvars = nargs;
gcpro4.nvars = nargs;
if (!NILP (enable))
specbind (Qenable_recursive_minibuffers, Qt);
......@@ -809,14 +808,14 @@ invoke it. If KEYS is omitted or nil, the return value of
if (arg_from_tty || !NILP (record_flag))
{
visargs[0] = function;
for (i = 1; i < count + 1; i++)
for (i = 1; i < nargs; i++)
{
if (varies[i] > 0)
visargs[i] = Fcons (intern (callint_argfuns[varies[i]]), Qnil);
else
visargs[i] = quotify_arg (args[i]);
}
Vcommand_history = Fcons (Flist (count + 1, visargs),
Vcommand_history = Fcons (Flist (nargs, visargs),
Vcommand_history);
/* Don't keep command history around forever. */
if (INTEGERP (Vhistory_length) && XINT (Vhistory_length) > 0)
......@@ -829,7 +828,7 @@ invoke it. If KEYS is omitted or nil, the return value of
/* If we used a marker to hold point, mark, or an end of the region,
temporarily, convert it to an integer now. */
for (i = 1; i <= count; i++)
for (i = 1; i < nargs; i++)
if (varies[i] >= 1 && varies[i] <= 4)
XSETINT (args[i], marker_position (args[i]));
......@@ -846,7 +845,7 @@ invoke it. If KEYS is omitted or nil, the return value of
specbind (Qcommand_debug_status, Qnil);
temporarily_switch_to_single_kboard (NULL);
val = Ffuncall (count + 1, args);
val = Ffuncall (nargs, args);
UNGCPRO;
return unbind_to (speccount, val);
}
......
......@@ -191,7 +191,8 @@ set_identity (Lisp_Object table, Lisp_Object c, Lisp_Object elt)
{
if (NATNUMP (elt))
{
int from, to;
int from;
unsigned to;
if (CONSP (c))
{
......@@ -200,7 +201,7 @@ set_identity (Lisp_Object table, Lisp_Object c, Lisp_Object elt)
}
else
from = to = XINT (c);
for (; from <= to; from++)
for (to++; from < to; from++)
CHAR_TABLE_SET (table, from, make_number (from));
}
}
......@@ -215,7 +216,8 @@ shuffle (Lisp_Object table, Lisp_Object c, Lisp_Object elt)
{
if (NATNUMP (elt))
{
int from, to;
int from;
unsigned to;
if (CONSP (c))
{
......@@ -225,7 +227,7 @@ shuffle (Lisp_Object table, Lisp_Object c, Lisp_Object elt)
else
from = to = XINT (c);
for (; from <= to; from++)
for (to++; from < to; from++)
{
Lisp_Object tem = Faref (table, elt);
Faset (table, elt, make_number (from));
......
......@@ -128,7 +128,7 @@ the current buffer's category table. */)
table = check_category_table (table);
if (!NILP (CATEGORY_DOCSTRING (table, XFASTINT (category))))
error ("Category `%c' is already defined", XFASTINT (category));
error ("Category `%c' is already defined", (int) XFASTINT (category));
if (!NILP (Vpurify_flag))
docstring = Fpurecopy (docstring);
CATEGORY_DOCSTRING (table, XFASTINT (category)) = docstring;
......@@ -373,7 +373,7 @@ then delete CATEGORY from the category set instead of adding it. */)
table = check_category_table (table);
if (NILP (CATEGORY_DOCSTRING (table, XFASTINT (category))))
error ("Undefined category: %c", XFASTINT (category));
error ("Undefined category: %c", (int) XFASTINT (category));
set_value = NILP (reset) ? Qt : Qnil;
......
......@@ -317,7 +317,7 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
for (i = 0; i < n_entries; i++)
{
unsigned from, to;
int from_index, to_index;
int from_index, to_index, lim_index;
int from_c, to_c;
int idx = i % 0x10000;
......@@ -339,6 +339,7 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
}
if (from_index < 0 || to_index < 0)
continue;
lim_index = to_index + 1;
if (to_c > max_char)
max_char = to_c;
......@@ -348,10 +349,10 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
if (control_flag == 1)
{
if (charset->method == CHARSET_METHOD_MAP)
for (; from_index <= to_index; from_index++, from_c++)
for (; from_index < lim_index; from_index++, from_c++)
ASET (vec, from_index, make_number (from_c));
else
for (; from_index <= to_index; from_index++, from_c++)
for (; from_index < lim_index; from_index++, from_c++)
CHAR_TABLE_SET (Vchar_unify_table,
CHARSET_CODE_OFFSET (charset) + from_index,
make_number (from_c));
......@@ -360,7 +361,7 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
{
if (charset->method == CHARSET_METHOD_MAP
&& CHARSET_COMPACT_CODES_P (charset))
for (; from_index <= to_index; from_index++, from_c++)
for (; from_index < lim_index; from_index++, from_c++)
{
unsigned code = INDEX_TO_CODE_POINT (charset, from_index);
......@@ -368,17 +369,17 @@ load_charset_map (struct charset *charset, struct charset_map_entries *entries,
CHAR_TABLE_SET (table, from_c, make_number (code));
}
else
for (; from_index <= to_index; from_index++, from_c++)
for (; from_index < lim_index; from_index++, from_c++)
{
if (NILP (CHAR_TABLE_REF (table, from_c)))
CHAR_TABLE_SET (table, from_c, make_number (from_index));
}
}
else if (control_flag == 3)
for (; from_index <= to_index; from_index++, from_c++)
for (; from_index < lim_index; from_index++, from_c++)
SET_TEMP_CHARSET_WORK_DECODER (from_c, from_index);
else if (control_flag == 4)
for (; from_index <= to_index; from_index++, from_c++)
for (; from_index < lim_index; from_index++, from_c++)
SET_TEMP_CHARSET_WORK_ENCODER (from_c, from_index);
else /* control_flag == 0 */
{
......@@ -493,7 +494,7 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int co
unbind_to (count, Qnil);
if (fd < 0
|| ! (fp = fdopen (fd, "r")))
error ("Failure in loading charset map: %S", SDATA (mapfile));
error ("Failure in loading charset map: %s", SDATA (mapfile));
/* Use SAFE_ALLOCA instead of alloca, as `charset_map_entries' is
large (larger than MAX_ALLOCA). */
......@@ -1000,7 +1001,7 @@ usage: (define-charset-internal ...) */)
{
CHECK_NUMBER (val);
if (XINT (val) < '0' || XINT (val) > 127)
error ("Invalid iso-final-char: %d", XINT (val));
error ("Invalid iso-final-char: %"pEd, XINT (val));
charset.iso_final = XINT (val);
}
......@@ -1022,7 +1023,7 @@ usage: (define-charset-internal ...) */)
{
CHECK_NATNUM (val);
if ((XINT (val) > 0 && XINT (val) <= 128) || XINT (val) >= 256)
error ("Invalid emacs-mule-id: %d", XINT (val));
error ("Invalid emacs-mule-id: %"pEd, XINT (val));
charset.emacs_mule_id = XINT (val);
}
......@@ -1440,11 +1441,17 @@ check_iso_charset_parameter (Lisp_Object dimension, Lisp_Object chars, Lisp_Obje
CHECK_NATNUM (final_char);
if (XINT (dimension) > 3)
error ("Invalid DIMENSION %d, it should be 1, 2, or 3", XINT (dimension));
error ("Invalid DIMENSION %"pEd", it should be 1, 2, or 3",
XINT (dimension));
if (XINT (chars) != 94 && XINT (chars) != 96)
error ("Invalid CHARS %d, it should be 94 or 96", XINT (chars));
error ("Invalid CHARS %"pEd", it should be 94 or 96", XINT (chars));
if (XINT (final_char) < '0' || XINT (final_char) > '~')
error ("Invalid FINAL-CHAR %c, it should be `0'..`~'", XINT (chars));
{
unsigned char str[MAX_MULTIBYTE_LENGTH + 1];
int len = CHAR_STRING (XINT (chars), str);
str[len] = '\0';
error ("Invalid FINAL-CHAR %s, it should be `0'..`~'", str);
}
}
......
......@@ -392,7 +392,8 @@ sub_char_table_set_range (Lisp_Object *table, int depth, int min_char, int from,
*table = val;
else
{
int i, j;