Use SAFE_ALLOCA etc. to avoid unbounded stack allocation.
This follows up on the recent thread in emacs-devel on alloca; see: http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00042.html This patch also cleans up alloca-related glitches noted while examining the code looking for unbounded alloca. * alloc.c (listn): * callproc.c (init_callproc): Rewrite to avoid need for alloca. * buffer.c (mouse_face_overlay_overlaps) (report_overlay_modification): * buffer.h (GET_OVERLAYS_AT): * coding.c (make_subsidiaries): * doc.c (Fsnarf_documentation): * editfns.c (Fuser_full_name): * fileio.c (Ffile_name_directory, Fexpand_file_name) (search_embedded_absfilename, Fsubstitute_in_file_name): * fns.c (Fmake_hash_table): * font.c (font_vconcat_entity_vectors, font_update_drivers): * fontset.c (fontset_pattern_regexp, Ffontset_info): * frame.c (Fmake_terminal_frame, x_set_frame_parameters) (xrdb_get_resource, x_get_resource_string): * ftfont.c (ftfont_get_charset, ftfont_check_otf, ftfont_drive_otf): * ftxfont.c (ftxfont_draw): * image.c (xbm_load, xpm_load, jpeg_load_body): * keyboard.c (echo_add_key, menu_bar_items, tool_bar_items): * keymap.c (Fdescribe_buffer_bindings, describe_map): * lread.c (openp): * menu.c (digest_single_submenu, find_and_call_menu_selection) (find_and_return_menu_selection): * print.c (PRINTFINISH): * process.c (Fformat_network_address): * scroll.c (do_scrolling, do_direct_scrolling, scrolling_1): * search.c (search_buffer, Fmatch_data, Fregexp_quote): * sound.c (wav_play, au_play): * syntax.c (skip_chars): * term.c (tty_menu_activate, tty_menu_show): * textprop.c (get_char_property_and_overlay): * window.c (Fset_window_configuration): * xdisp.c (safe__call, next_overlay_change, vmessage) (compute_overhangs_and_x, draw_glyphs, note_mouse_highlight): * xfaces.c (face_at_buffer_position): * xmenu.c (x_menu_show): Use SAFE_ALLOCA etc. instead of plain alloca, since the allocation size isn't bounded. * callint.c (Fcall_interactively): Redo memory_full check so that it can be done at compile-time on some platforms. * coding.c (MAX_LOOKUP_MAX): New constant. (get_translation_table): Use it. * callproc.c (call_process): Use SAFE_NALLOCA instead of SAFE_ALLOCA, to catch integer overflows on size calculation. (exec_failed) [!DOS_NT]: New function. (child_setup) [!DOS_NT]: Use it. * editfns.c (Ftranspose_regions): Hoist USE_SAFE_ALLOC + SAFE_FREE out of 'if'. * editfns.c (check_translation): Allocate larger buffers on the heap. * eval.c (internal_lisp_condition_case): Check for MAX_ALLOCA overflow. * fns.c (sort_vector): Use SAFE_ALLOCA_LISP rather than Fmake_vector. (Fbase64_encode_region, Fbase64_decode_region): Avoid unnecessary calls to SAFE_FREE before 'error'. * buffer.c (mouse_face_overlay_overlaps): * editfns.c (Fget_pos_property, check_translation): * eval.c (Ffuncall): * font.c (font_unparse_xlfd, font_find_for_lface): * ftfont.c (ftfont_drive_otf): * keyboard.c (echo_add_key, read_decoded_event_from_main_queue) (menu_bar_items, tool_bar_items): * sound.c (Fplay_sound_internal): * xdisp.c (load_overlay_strings, dump_glyph_row): Use an ordinary auto buffer rather than alloca, since the allocation size is fixed and small. * ftfont.c: Include <c-strcase.h>. (matching_prefix): New function. (get_adstyle_property): Use it, to avoid need for alloca. * keyboard.c (echo_add_key): * keymap.c (describe_map): Use ptrdiff_t, not int. * keyboard.c (echo_add_key): Prefer sizeof to strlen. * keymap.c (Fdescribe_buffer_bindings): Use SBYTES, not SCHARS, when counting bytes. * lisp.h (xlispstrdupa): Remove, replacing with ... (SAFE_ALLOCA_STRING): ... new macro with different API. This fixes a portability problem, namely, alloca result passed to another function. All uses changed. (SAFE_ALLOCA, SAFE_ALLOCA_LISP): Check for MAX_ALLOCA, not MAX_ALLOCA - 1. * regex.c (REGEX_USE_SAFE_ALLOCA, REGEX_SAFE_FREE) (REGEX_ALLOCATE): New macros. (REGEX_REALLOCATE, REGEX_ALLOCATE_STACK, REGEX_REALLOCATE_STACK) (REGEX_FREE_STACK, FREE_VARIABLES, re_match_2_internal): Use them. * xdisp.c (message3): Use SAFE_ALLOCA_STRING rather than doing it by hand. (decode_mode_spec_coding): Store directly into buf rather than into an alloca temporary and copying the temporary to the buf. Fixes: debbugs:18410
This commit is contained in:
parent
930fb80f9e
commit
b3bf18b3b8
36 changed files with 688 additions and 403 deletions
|
@ -1,3 +1,101 @@
|
|||
2014-09-07 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Use SAFE_ALLOCA etc. to avoid unbounded stack allocation (Bug#18410).
|
||||
This follows up on the recent thread in emacs-devel on alloca; see:
|
||||
http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00042.html
|
||||
This patch also cleans up alloca-related glitches noted while
|
||||
examining the code looking for unbounded alloca.
|
||||
* alloc.c (listn):
|
||||
* callproc.c (init_callproc):
|
||||
Rewrite to avoid need for alloca.
|
||||
* buffer.c (mouse_face_overlay_overlaps)
|
||||
(report_overlay_modification):
|
||||
* buffer.h (GET_OVERLAYS_AT):
|
||||
* coding.c (make_subsidiaries):
|
||||
* doc.c (Fsnarf_documentation):
|
||||
* editfns.c (Fuser_full_name):
|
||||
* fileio.c (Ffile_name_directory, Fexpand_file_name)
|
||||
(search_embedded_absfilename, Fsubstitute_in_file_name):
|
||||
* fns.c (Fmake_hash_table):
|
||||
* font.c (font_vconcat_entity_vectors, font_update_drivers):
|
||||
* fontset.c (fontset_pattern_regexp, Ffontset_info):
|
||||
* frame.c (Fmake_terminal_frame, x_set_frame_parameters)
|
||||
(xrdb_get_resource, x_get_resource_string):
|
||||
* ftfont.c (ftfont_get_charset, ftfont_check_otf, ftfont_drive_otf):
|
||||
* ftxfont.c (ftxfont_draw):
|
||||
* image.c (xbm_load, xpm_load, jpeg_load_body):
|
||||
* keyboard.c (echo_add_key, menu_bar_items, tool_bar_items):
|
||||
* keymap.c (Fdescribe_buffer_bindings, describe_map):
|
||||
* lread.c (openp):
|
||||
* menu.c (digest_single_submenu, find_and_call_menu_selection)
|
||||
(find_and_return_menu_selection):
|
||||
* print.c (PRINTFINISH):
|
||||
* process.c (Fformat_network_address):
|
||||
* scroll.c (do_scrolling, do_direct_scrolling, scrolling_1):
|
||||
* search.c (search_buffer, Fmatch_data, Fregexp_quote):
|
||||
* sound.c (wav_play, au_play):
|
||||
* syntax.c (skip_chars):
|
||||
* term.c (tty_menu_activate, tty_menu_show):
|
||||
* textprop.c (get_char_property_and_overlay):
|
||||
* window.c (Fset_window_configuration):
|
||||
* xdisp.c (safe__call, next_overlay_change, vmessage)
|
||||
(compute_overhangs_and_x, draw_glyphs, note_mouse_highlight):
|
||||
* xfaces.c (face_at_buffer_position):
|
||||
* xmenu.c (x_menu_show):
|
||||
Use SAFE_ALLOCA etc. instead of plain alloca, since the
|
||||
allocation size isn't bounded.
|
||||
* callint.c (Fcall_interactively): Redo memory_full check
|
||||
so that it can be done at compile-time on some platforms.
|
||||
* coding.c (MAX_LOOKUP_MAX): New constant.
|
||||
(get_translation_table): Use it.
|
||||
* callproc.c (call_process): Use SAFE_NALLOCA instead of
|
||||
SAFE_ALLOCA, to catch integer overflows on size calculation.
|
||||
(exec_failed) [!DOS_NT]: New function.
|
||||
(child_setup) [!DOS_NT]: Use it.
|
||||
* editfns.c (Ftranspose_regions):
|
||||
Hoist USE_SAFE_ALLOC + SAFE_FREE out of 'if'.
|
||||
* editfns.c (check_translation):
|
||||
Allocate larger buffers on the heap.
|
||||
* eval.c (internal_lisp_condition_case):
|
||||
Check for MAX_ALLOCA overflow.
|
||||
* fns.c (sort_vector): Use SAFE_ALLOCA_LISP rather than Fmake_vector.
|
||||
(Fbase64_encode_region, Fbase64_decode_region):
|
||||
Avoid unnecessary calls to SAFE_FREE before 'error'.
|
||||
* buffer.c (mouse_face_overlay_overlaps):
|
||||
* editfns.c (Fget_pos_property, check_translation):
|
||||
* eval.c (Ffuncall):
|
||||
* font.c (font_unparse_xlfd, font_find_for_lface):
|
||||
* ftfont.c (ftfont_drive_otf):
|
||||
* keyboard.c (echo_add_key, read_decoded_event_from_main_queue)
|
||||
(menu_bar_items, tool_bar_items):
|
||||
* sound.c (Fplay_sound_internal):
|
||||
* xdisp.c (load_overlay_strings, dump_glyph_row):
|
||||
Use an ordinary auto buffer rather than alloca, since the
|
||||
allocation size is fixed and small.
|
||||
* ftfont.c: Include <c-strcase.h>.
|
||||
(matching_prefix): New function.
|
||||
(get_adstyle_property): Use it, to avoid need for alloca.
|
||||
* keyboard.c (echo_add_key):
|
||||
* keymap.c (describe_map): Use ptrdiff_t, not int.
|
||||
* keyboard.c (echo_add_key): Prefer sizeof to strlen.
|
||||
* keymap.c (Fdescribe_buffer_bindings): Use SBYTES, not SCHARS,
|
||||
when counting bytes.
|
||||
* lisp.h (xlispstrdupa): Remove, replacing with ...
|
||||
(SAFE_ALLOCA_STRING): ... new macro with different API.
|
||||
This fixes a portability problem, namely, alloca result
|
||||
passed to another function. All uses changed.
|
||||
(SAFE_ALLOCA, SAFE_ALLOCA_LISP): Check for MAX_ALLOCA,
|
||||
not MAX_ALLOCA - 1.
|
||||
* regex.c (REGEX_USE_SAFE_ALLOCA, REGEX_SAFE_FREE)
|
||||
(REGEX_ALLOCATE): New macros.
|
||||
(REGEX_REALLOCATE, REGEX_ALLOCATE_STACK, REGEX_REALLOCATE_STACK)
|
||||
(REGEX_FREE_STACK, FREE_VARIABLES, re_match_2_internal):
|
||||
Use them.
|
||||
* xdisp.c (message3): Use SAFE_ALLOCA_STRING rather than doing it
|
||||
by hand.
|
||||
(decode_mode_spec_coding): Store directly into buf rather than
|
||||
into an alloca temporary and copying the temporary to the buf.
|
||||
|
||||
2014-09-06 Eli Zaretskii <eliz@gnu.org>
|
||||
|
||||
* Makefile.in (EMACS_HEAPSIZE): Remove, no longer used. (Bug#18416)
|
||||
|
|
39
src/alloc.c
39
src/alloc.c
|
@ -2618,29 +2618,28 @@ list5 (Lisp_Object arg1, Lisp_Object arg2, Lisp_Object arg3, Lisp_Object arg4, L
|
|||
Lisp_Object
|
||||
listn (enum constype type, ptrdiff_t count, Lisp_Object arg, ...)
|
||||
{
|
||||
Lisp_Object (*cons) (Lisp_Object, Lisp_Object);
|
||||
switch (type)
|
||||
{
|
||||
case CONSTYPE_PURE: cons = pure_cons; break;
|
||||
case CONSTYPE_HEAP: cons = Fcons; break;
|
||||
default: emacs_abort ();
|
||||
}
|
||||
|
||||
eassume (0 < count);
|
||||
Lisp_Object val = cons (arg, Qnil);
|
||||
Lisp_Object tail = val;
|
||||
|
||||
va_list ap;
|
||||
ptrdiff_t i;
|
||||
Lisp_Object val, *objp;
|
||||
|
||||
/* Change to SAFE_ALLOCA if you hit this eassert. */
|
||||
eassert (count <= MAX_ALLOCA / word_size);
|
||||
|
||||
objp = alloca (count * word_size);
|
||||
objp[0] = arg;
|
||||
va_start (ap, arg);
|
||||
for (i = 1; i < count; i++)
|
||||
objp[i] = va_arg (ap, Lisp_Object);
|
||||
for (ptrdiff_t i = 1; i < count; i++)
|
||||
{
|
||||
Lisp_Object elem = cons (va_arg (ap, Lisp_Object), Qnil);
|
||||
XSETCDR (tail, elem);
|
||||
tail = elem;
|
||||
}
|
||||
va_end (ap);
|
||||
|
||||
for (val = Qnil, i = count - 1; i >= 0; i--)
|
||||
{
|
||||
if (type == CONSTYPE_PURE)
|
||||
val = pure_cons (objp[i], val);
|
||||
else if (type == CONSTYPE_HEAP)
|
||||
val = Fcons (objp[i], val);
|
||||
else
|
||||
emacs_abort ();
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -3620,7 +3619,7 @@ make_save_int_obj (ptrdiff_t a, Lisp_Object b)
|
|||
p->data[1].object = b;
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
#if ! (defined USE_X_TOOLKIT || defined USE_GTK)
|
||||
Lisp_Object
|
||||
make_save_ptr_ptr (void *a, void *b)
|
||||
|
|
17
src/buffer.c
17
src/buffer.c
|
@ -3053,13 +3053,15 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
|
|||
ptrdiff_t end = OVERLAY_POSITION (OVERLAY_END (overlay));
|
||||
ptrdiff_t n, i, size;
|
||||
Lisp_Object *v, tem;
|
||||
Lisp_Object vbuf[10];
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
size = 10;
|
||||
v = alloca (size * sizeof *v);
|
||||
size = ARRAYELTS (vbuf);
|
||||
v = vbuf;
|
||||
n = overlays_in (start, end, 0, &v, &size, NULL, NULL);
|
||||
if (n > size)
|
||||
{
|
||||
v = alloca (n * sizeof *v);
|
||||
SAFE_NALLOCA (v, 1, n);
|
||||
overlays_in (start, end, 0, &v, &n, NULL, NULL);
|
||||
}
|
||||
|
||||
|
@ -3069,6 +3071,7 @@ mouse_face_overlay_overlaps (Lisp_Object overlay)
|
|||
!NILP (tem)))
|
||||
break;
|
||||
|
||||
SAFE_FREE ();
|
||||
return i < n;
|
||||
}
|
||||
|
||||
|
@ -4517,13 +4520,13 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
|
|||
First copy the vector contents, in case some of these hooks
|
||||
do subsequent modification of the buffer. */
|
||||
ptrdiff_t size = last_overlay_modification_hooks_used;
|
||||
Lisp_Object *copy = alloca (size * sizeof *copy);
|
||||
Lisp_Object *copy;
|
||||
ptrdiff_t i;
|
||||
|
||||
USE_SAFE_ALLOCA;
|
||||
SAFE_ALLOCA_LISP (copy, size);
|
||||
memcpy (copy, XVECTOR (last_overlay_modification_hooks)->contents,
|
||||
size * word_size);
|
||||
gcpro1.var = copy;
|
||||
gcpro1.nvars = size;
|
||||
|
||||
for (i = 0; i < size;)
|
||||
{
|
||||
|
@ -4532,6 +4535,8 @@ report_overlay_modification (Lisp_Object start, Lisp_Object end, bool after,
|
|||
overlay_i = copy[i++];
|
||||
call_overlay_mod_hooks (prop_i, overlay_i, after, arg1, arg2, arg3);
|
||||
}
|
||||
|
||||
SAFE_FREE ();
|
||||
}
|
||||
UNGCPRO;
|
||||
}
|
||||
|
|
14
src/buffer.h
14
src/buffer.h
|
@ -1127,15 +1127,15 @@ record_unwind_current_buffer (void)
|
|||
#define GET_OVERLAYS_AT(posn, overlays, noverlays, nextp, chrq) \
|
||||
do { \
|
||||
ptrdiff_t maxlen = 40; \
|
||||
overlays = alloca (maxlen * sizeof *overlays); \
|
||||
noverlays = overlays_at (posn, false, &overlays, &maxlen, \
|
||||
nextp, NULL, chrq); \
|
||||
if (noverlays > maxlen) \
|
||||
SAFE_NALLOCA (overlays, 1, maxlen); \
|
||||
(noverlays) = overlays_at (posn, false, &(overlays), &maxlen, \
|
||||
nextp, NULL, chrq); \
|
||||
if ((noverlays) > maxlen) \
|
||||
{ \
|
||||
maxlen = noverlays; \
|
||||
overlays = alloca (maxlen * sizeof *overlays); \
|
||||
noverlays = overlays_at (posn, false, &overlays, &maxlen, \
|
||||
nextp, NULL, chrq); \
|
||||
SAFE_NALLOCA (overlays, 1, maxlen); \
|
||||
(noverlays) = overlays_at (posn, false, &(overlays), &maxlen, \
|
||||
nextp, NULL, chrq); \
|
||||
} \
|
||||
} while (false)
|
||||
|
||||
|
|
|
@ -297,6 +297,7 @@ invoke it. If KEYS is omitted or nil, the return value of
|
|||
Lisp_Object teml;
|
||||
Lisp_Object up_event;
|
||||
Lisp_Object enable;
|
||||
USE_SAFE_ALLOCA;
|
||||
ptrdiff_t speccount = SPECPDL_INDEX ();
|
||||
|
||||
/* The index of the next element of this_command_keys to examine for
|
||||
|
@ -366,12 +367,8 @@ invoke it. If KEYS is omitted or nil, the return value of
|
|||
wrong_type_argument (Qcommandp, function);
|
||||
}
|
||||
|
||||
/* If SPECS is set to a string, use it as an interactive prompt. */
|
||||
if (STRINGP (specs))
|
||||
/* Make a copy of string so that if a GC relocates specs,
|
||||
`string' will still be valid. */
|
||||
string = xlispstrdupa (specs);
|
||||
else
|
||||
/* If SPECS is not a string, invent one. */
|
||||
if (! STRINGP (specs))
|
||||
{
|
||||
Lisp_Object input;
|
||||
Lisp_Object funval = Findirect_function (function, Qt);
|
||||
|
@ -416,10 +413,16 @@ invoke it. If KEYS is omitted or nil, the return value of
|
|||
args[0] = Qfuncall_interactively;
|
||||
args[1] = function;
|
||||
args[2] = specs;
|
||||
return unbind_to (speccount, Fapply (3, args));
|
||||
Lisp_Object result = unbind_to (speccount, Fapply (3, args));
|
||||
SAFE_FREE ();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/* SPECS is set to a string; use it as an interactive prompt.
|
||||
Copy it so that STRING will be valid even if a GC relocates SPECS. */
|
||||
SAFE_ALLOCA_STRING (string, specs);
|
||||
|
||||
/* Here if function specifies a string to control parsing the defaults. */
|
||||
|
||||
/* Set next_event to point to the first event with parameters. */
|
||||
|
@ -507,14 +510,15 @@ invoke it. If KEYS is omitted or nil, the return value of
|
|||
break;
|
||||
}
|
||||
|
||||
if (min (MOST_POSITIVE_FIXNUM,
|
||||
min (PTRDIFF_MAX, SIZE_MAX) / word_size)
|
||||
< nargs)
|
||||
if (MOST_POSITIVE_FIXNUM < min (PTRDIFF_MAX, SIZE_MAX) / word_size
|
||||
&& MOST_POSITIVE_FIXNUM < nargs)
|
||||
memory_full (SIZE_MAX);
|
||||
|
||||
args = alloca (nargs * sizeof *args);
|
||||
visargs = alloca (nargs * sizeof *visargs);
|
||||
varies = alloca (nargs * sizeof *varies);
|
||||
/* Allocate them all at one go. This wastes a bit of memory, but
|
||||
it's OK to trade space for speed. */
|
||||
SAFE_NALLOCA (args, 3, nargs);
|
||||
visargs = args + nargs;
|
||||
varies = (signed char *) (visargs + nargs);
|
||||
|
||||
for (i = 0; i < nargs; i++)
|
||||
{
|
||||
|
@ -871,7 +875,9 @@ invoke it. If KEYS is omitted or nil, the return value of
|
|||
{
|
||||
Lisp_Object val = Ffuncall (nargs, args);
|
||||
UNGCPRO;
|
||||
return unbind_to (speccount, val);
|
||||
val = unbind_to (speccount, val);
|
||||
SAFE_FREE ();
|
||||
return val;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -466,7 +466,7 @@ call_process (ptrdiff_t nargs, Lisp_Object *args, int filefd,
|
|||
&& SREF (path, 1) == ':')
|
||||
path = Fsubstring (path, make_number (2), Qnil);
|
||||
|
||||
new_argv = SAFE_ALLOCA ((nargs > 4 ? nargs - 2 : 2) * sizeof *new_argv);
|
||||
SAFE_NALLOCA (new_argv, 1, nargs < 4 ? 2 : nargs - 2);
|
||||
|
||||
{
|
||||
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
|
||||
|
@ -1151,6 +1151,25 @@ add_env (char **env, char **new_env, char *string)
|
|||
return new_env;
|
||||
}
|
||||
|
||||
#ifndef DOS_NT
|
||||
|
||||
/* 'exec' failed inside a child running NAME, with error number ERR.
|
||||
Report the error and exit the child. */
|
||||
|
||||
static _Noreturn void
|
||||
exec_failed (char const *name, int err)
|
||||
{
|
||||
/* Avoid deadlock if the child's perror writes to a full pipe; the
|
||||
pipe's reader is the parent, but with vfork the parent can't
|
||||
run until the child exits. Truncate the diagnostic instead. */
|
||||
fcntl (STDERR_FILENO, F_SETFL, O_NONBLOCK);
|
||||
|
||||
errno = err;
|
||||
emacs_perror (name);
|
||||
_exit (err == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* This is the last thing run in a newly forked inferior
|
||||
either synchronous or asynchronous.
|
||||
Copy descriptors IN, OUT and ERR as descriptors 0, 1 and 2.
|
||||
|
@ -1174,8 +1193,6 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
|
|||
int cpid;
|
||||
HANDLE handles[3];
|
||||
#else
|
||||
int exec_errno;
|
||||
|
||||
pid_t pid = getpid ();
|
||||
#endif /* WINDOWSNT */
|
||||
|
||||
|
@ -1196,6 +1213,8 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
|
|||
on that. */
|
||||
pwd_var = xmalloc (i + 5);
|
||||
#else
|
||||
if (MAX_ALLOCA - 5 < i)
|
||||
exec_failed (new_argv[0], ENOMEM);
|
||||
pwd_var = alloca (i + 5);
|
||||
#endif
|
||||
temp = pwd_var + 4;
|
||||
|
@ -1262,6 +1281,8 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
|
|||
}
|
||||
|
||||
/* new_length + 2 to include PWD and terminating 0. */
|
||||
if (MAX_ALLOCA / sizeof *env - 2 < new_length)
|
||||
exec_failed (new_argv[0], ENOMEM);
|
||||
env = new_env = alloca ((new_length + 2) * sizeof *env);
|
||||
/* If we have a PWD envvar, pass one down,
|
||||
but with corrected value. */
|
||||
|
@ -1270,6 +1291,8 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
|
|||
|
||||
if (STRINGP (display))
|
||||
{
|
||||
if (MAX_ALLOCA - sizeof "DISPLAY=" < SBYTES (display))
|
||||
exec_failed (new_argv[0], ENOMEM);
|
||||
char *vdata = alloca (sizeof "DISPLAY=" + SBYTES (display));
|
||||
strcpy (vdata, "DISPLAY=");
|
||||
strcat (vdata, SSDATA (display));
|
||||
|
@ -1345,16 +1368,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
|
|||
tcsetpgrp (0, pid);
|
||||
|
||||
execve (new_argv[0], new_argv, env);
|
||||
exec_errno = errno;
|
||||
|
||||
/* Avoid deadlock if the child's perror writes to a full pipe; the
|
||||
pipe's reader is the parent, but with vfork the parent can't
|
||||
run until the child exits. Truncate the diagnostic instead. */
|
||||
fcntl (STDERR_FILENO, F_SETFL, O_NONBLOCK);
|
||||
|
||||
errno = exec_errno;
|
||||
emacs_perror (new_argv[0]);
|
||||
_exit (exec_errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
|
||||
exec_failed (new_argv[0], errno);
|
||||
|
||||
#else /* MSDOS */
|
||||
pid = run_msdos_command (new_argv, pwd_var + 4, in, out, err, env);
|
||||
|
@ -1543,20 +1557,13 @@ init_callproc_1 (void)
|
|||
void
|
||||
init_callproc (void)
|
||||
{
|
||||
char *data_dir = egetenv ("EMACSDATA");
|
||||
bool data_dir = egetenv ("EMACSDATA") != 0;
|
||||
|
||||
register char * sh;
|
||||
char *sh;
|
||||
Lisp_Object tempdir;
|
||||
#ifdef HAVE_NS
|
||||
if (data_dir == 0)
|
||||
{
|
||||
const char *etc_dir = ns_etc_directory ();
|
||||
if (etc_dir)
|
||||
{
|
||||
data_dir = alloca (strlen (etc_dir) + 1);
|
||||
strcpy (data_dir, etc_dir);
|
||||
}
|
||||
}
|
||||
data_dir == ns_etc_directory () != 0;
|
||||
#endif
|
||||
|
||||
if (!NILP (Vinstallation_directory))
|
||||
|
|
13
src/coding.c
13
src/coding.c
|
@ -6867,6 +6867,11 @@ decode_eol (struct coding_system *coding)
|
|||
}
|
||||
|
||||
|
||||
/* MAX_LOOKUP's maximum value. MAX_LOOKUP is an int and so cannot
|
||||
exceed INT_MAX. Also, MAX_LOOKUP is multiplied by sizeof (int) for
|
||||
alloca, so it cannot exceed MAX_ALLOCA / sizeof (int). */
|
||||
enum { MAX_LOOKUP_MAX = min (INT_MAX, MAX_ALLOCA / sizeof (int)) };
|
||||
|
||||
/* Return a translation table (or list of them) from coding system
|
||||
attribute vector ATTRS for encoding (if ENCODEP) or decoding (if
|
||||
not ENCODEP). */
|
||||
|
@ -6919,7 +6924,7 @@ get_translation_table (Lisp_Object attrs, bool encodep, int *max_lookup)
|
|||
{
|
||||
val = XCHAR_TABLE (translation_table)->extras[1];
|
||||
if (NATNUMP (val) && *max_lookup < XFASTINT (val))
|
||||
*max_lookup = XFASTINT (val);
|
||||
*max_lookup = min (XFASTINT (val), MAX_LOOKUP_MAX);
|
||||
}
|
||||
else if (CONSP (translation_table))
|
||||
{
|
||||
|
@ -6931,7 +6936,7 @@ get_translation_table (Lisp_Object attrs, bool encodep, int *max_lookup)
|
|||
{
|
||||
Lisp_Object tailval = XCHAR_TABLE (XCAR (tail))->extras[1];
|
||||
if (NATNUMP (tailval) && *max_lookup < XFASTINT (tailval))
|
||||
*max_lookup = XFASTINT (tailval);
|
||||
*max_lookup = min (XFASTINT (tailval), MAX_LOOKUP_MAX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10011,7 +10016,8 @@ make_subsidiaries (Lisp_Object base)
|
|||
{
|
||||
Lisp_Object subsidiaries;
|
||||
ptrdiff_t base_name_len = SBYTES (SYMBOL_NAME (base));
|
||||
char *buf = alloca (base_name_len + 6);
|
||||
USE_SAFE_ALLOCA;
|
||||
char *buf = SAFE_ALLOCA (base_name_len + 6);
|
||||
int i;
|
||||
|
||||
memcpy (buf, SDATA (SYMBOL_NAME (base)), base_name_len);
|
||||
|
@ -10021,6 +10027,7 @@ make_subsidiaries (Lisp_Object base)
|
|||
strcpy (buf + base_name_len, suffixes[i]);
|
||||
ASET (subsidiaries, i, intern (buf));
|
||||
}
|
||||
SAFE_FREE ();
|
||||
return subsidiaries;
|
||||
}
|
||||
|
||||
|
|
21
src/doc.c
21
src/doc.c
|
@ -561,6 +561,8 @@ the same file name is found in the `doc-directory'. */)
|
|||
char *p, *name;
|
||||
bool skip_file = 0;
|
||||
ptrdiff_t count;
|
||||
char const *dirname;
|
||||
ptrdiff_t dirlen;
|
||||
/* Preloaded defcustoms using custom-initialize-delay are added to
|
||||
this list, but kept unbound. See http://debbugs.gnu.org/11565 */
|
||||
Lisp_Object delayed_init =
|
||||
|
@ -577,15 +579,21 @@ the same file name is found in the `doc-directory'. */)
|
|||
(0)
|
||||
#endif /* CANNOT_DUMP */
|
||||
{
|
||||
name = alloca (SCHARS (filename) + 14);
|
||||
strcpy (name, "../etc/");
|
||||
static char const sibling_etc[] = "../etc/";
|
||||
dirname = sibling_etc;
|
||||
dirlen = sizeof sibling_etc - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_STRING (Vdoc_directory);
|
||||
name = alloca (SCHARS (filename) + SCHARS (Vdoc_directory) + 1);
|
||||
strcpy (name, SSDATA (Vdoc_directory));
|
||||
dirname = SSDATA (Vdoc_directory);
|
||||
dirlen = SBYTES (Vdoc_directory);
|
||||
}
|
||||
|
||||
count = SPECPDL_INDEX ();
|
||||
USE_SAFE_ALLOCA;
|
||||
name = SAFE_ALLOCA (dirlen + SBYTES (filename) + 1);
|
||||
strcpy (name, dirname);
|
||||
strcat (name, SSDATA (filename)); /*** Add this line ***/
|
||||
|
||||
/* Vbuild_files is nil when temacs is run, and non-nil after that. */
|
||||
|
@ -608,7 +616,6 @@ the same file name is found in the `doc-directory'. */)
|
|||
report_file_errno ("Opening doc string file", build_string (name),
|
||||
open_errno);
|
||||
}
|
||||
count = SPECPDL_INDEX ();
|
||||
record_unwind_protect_int (close_file_unwind, fd);
|
||||
Vdoc_file_name = filename;
|
||||
filled = 0;
|
||||
|
@ -637,7 +644,7 @@ the same file name is found in the `doc-directory'. */)
|
|||
&& (end[-1] == 'o' || end[-1] == 'c'))
|
||||
{
|
||||
ptrdiff_t len = end - p - 2;
|
||||
char *fromfile = alloca (len + 1);
|
||||
char *fromfile = SAFE_ALLOCA (len + 1);
|
||||
memcpy (fromfile, &p[2], len);
|
||||
fromfile[len] = 0;
|
||||
if (fromfile[len-1] == 'c')
|
||||
|
@ -688,6 +695,8 @@ the same file name is found in the `doc-directory'. */)
|
|||
filled -= end - buf;
|
||||
memmove (buf, end, filled);
|
||||
}
|
||||
|
||||
SAFE_FREE ();
|
||||
return unbind_to (count, Qnil);
|
||||
}
|
||||
|
||||
|
|
|
@ -376,13 +376,14 @@ at POSITION. */)
|
|||
set_buffer_temp (XBUFFER (object));
|
||||
|
||||
/* First try with room for 40 overlays. */
|
||||
noverlays = 40;
|
||||
overlay_vec = alloca (noverlays * sizeof *overlay_vec);
|
||||
Lisp_Object overlay_vecbuf[40];
|
||||
noverlays = ARRAYELTS (overlay_vecbuf);
|
||||
overlay_vec = overlay_vecbuf;
|
||||
noverlays = overlays_around (posn, overlay_vec, noverlays);
|
||||
|
||||
/* If there are more than 40,
|
||||
make enough space for all, and try again. */
|
||||
if (noverlays > 40)
|
||||
if (ARRAYELTS (overlay_vecbuf) < noverlays)
|
||||
{
|
||||
SAFE_ALLOCA_LISP (overlay_vec, noverlays);
|
||||
noverlays = overlays_around (posn, overlay_vec, noverlays);
|
||||
|
@ -1325,17 +1326,16 @@ name, or nil if there is no such user. */)
|
|||
/* Substitute the login name for the &, upcasing the first character. */
|
||||
if (q)
|
||||
{
|
||||
register char *r;
|
||||
Lisp_Object login;
|
||||
|
||||
login = Fuser_login_name (make_number (pw->pw_uid));
|
||||
r = alloca (strlen (p) + SCHARS (login) + 1);
|
||||
Lisp_Object login = Fuser_login_name (make_number (pw->pw_uid));
|
||||
USE_SAFE_ALLOCA;
|
||||
char *r = SAFE_ALLOCA (strlen (p) + SBYTES (login) + 1);
|
||||
memcpy (r, p, q - p);
|
||||
r[q - p] = 0;
|
||||
strcat (r, SSDATA (login));
|
||||
r[q - p] = upcase ((unsigned char) r[q - p]);
|
||||
strcat (r, q + 1);
|
||||
full = build_string (r);
|
||||
SAFE_FREE ();
|
||||
}
|
||||
#endif /* AMPERSAND_FULL_NAME */
|
||||
|
||||
|
@ -3012,8 +3012,12 @@ static Lisp_Object
|
|||
check_translation (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t end,
|
||||
Lisp_Object val)
|
||||
{
|
||||
int buf_size = 16, buf_used = 0;
|
||||
int *buf = alloca (sizeof (int) * buf_size);
|
||||
int initial_buf[16];
|
||||
int *buf = initial_buf;
|
||||
ptrdiff_t buf_size = ARRAYELTS (initial_buf);
|
||||
int *bufalloc = 0;
|
||||
ptrdiff_t buf_used = 0;
|
||||
Lisp_Object result = Qnil;
|
||||
|
||||
for (; CONSP (val); val = XCDR (val))
|
||||
{
|
||||
|
@ -3038,12 +3042,11 @@ check_translation (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t end,
|
|||
|
||||
if (buf_used == buf_size)
|
||||
{
|
||||
int *newbuf;
|
||||
|
||||
buf_size += 16;
|
||||
newbuf = alloca (sizeof (int) * buf_size);
|
||||
memcpy (newbuf, buf, sizeof (int) * buf_used);
|
||||
buf = newbuf;
|
||||
bufalloc = xpalloc (bufalloc, &buf_size, 1, -1,
|
||||
sizeof *bufalloc);
|
||||
if (buf == initial_buf)
|
||||
memcpy (bufalloc, buf, sizeof initial_buf);
|
||||
buf = bufalloc;
|
||||
}
|
||||
buf[buf_used++] = STRING_CHAR_AND_LENGTH (p, len1);
|
||||
pos_byte += len1;
|
||||
|
@ -3052,10 +3055,15 @@ check_translation (ptrdiff_t pos, ptrdiff_t pos_byte, ptrdiff_t end,
|
|||
break;
|
||||
}
|
||||
if (i == len)
|
||||
return XCAR (val);
|
||||
{
|
||||
result = XCAR (val);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return Qnil;
|
||||
|
||||
xfree (bufalloc);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -4617,11 +4625,11 @@ Transposing beyond buffer boundaries is an error. */)
|
|||
if (tmp_interval3)
|
||||
set_text_properties_1 (startr1, endr2, Qnil, buf, tmp_interval3);
|
||||
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
/* First region smaller than second. */
|
||||
if (len1_byte < len2_byte)
|
||||
{
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
temp = SAFE_ALLOCA (len2_byte);
|
||||
|
||||
/* Don't precompute these addresses. We have to compute them
|
||||
|
@ -4633,21 +4641,19 @@ Transposing beyond buffer boundaries is an error. */)
|
|||
memcpy (temp, start2_addr, len2_byte);
|
||||
memcpy (start1_addr + len2_byte, start1_addr, len1_byte);
|
||||
memcpy (start1_addr, temp, len2_byte);
|
||||
SAFE_FREE ();
|
||||
}
|
||||
else
|
||||
/* First region not smaller than second. */
|
||||
{
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
temp = SAFE_ALLOCA (len1_byte);
|
||||
start1_addr = BYTE_POS_ADDR (start1_byte);
|
||||
start2_addr = BYTE_POS_ADDR (start2_byte);
|
||||
memcpy (temp, start1_addr, len1_byte);
|
||||
memcpy (start1_addr, start2_addr, len2_byte);
|
||||
memcpy (start1_addr + len2_byte, temp, len1_byte);
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
SAFE_FREE ();
|
||||
graft_intervals_into_buffer (tmp_interval1, start1 + len2,
|
||||
len1, current_buffer, 0);
|
||||
graft_intervals_into_buffer (tmp_interval2, start1,
|
||||
|
|
12
src/eval.c
12
src/eval.c
|
@ -1272,7 +1272,10 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
|
|||
|
||||
{ /* The first clause is the one that should be checked first, so it should
|
||||
be added to handlerlist last. So we build in `clauses' a table that
|
||||
contains `handlers' but in reverse order. */
|
||||
contains `handlers' but in reverse order. SAFE_ALLOCA won't work
|
||||
here due to the setjmp, so impose a MAX_ALLOCA limit. */
|
||||
if (MAX_ALLOCA / word_size < clausenb)
|
||||
memory_full (SIZE_MAX);
|
||||
Lisp_Object *clauses = alloca (clausenb * sizeof *clauses);
|
||||
Lisp_Object *volatile clauses_volatile = clauses;
|
||||
int i = clausenb;
|
||||
|
@ -1311,7 +1314,7 @@ internal_lisp_condition_case (volatile Lisp_Object var, Lisp_Object bodyform,
|
|||
return val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val = eval_sub (bodyform);
|
||||
handlerlist = oldhandlerlist;
|
||||
|
@ -2789,10 +2792,11 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
|
|||
val = (XSUBR (fun)->function.aMANY) (numargs, args + 1);
|
||||
else
|
||||
{
|
||||
Lisp_Object internal_argbuf[8];
|
||||
if (XSUBR (fun)->max_args > numargs)
|
||||
{
|
||||
internal_args = alloca (XSUBR (fun)->max_args
|
||||
* sizeof *internal_args);
|
||||
eassert (XSUBR (fun)->max_args <= ARRAYELTS (internal_argbuf));
|
||||
internal_args = internal_argbuf;
|
||||
memcpy (internal_args, args + 1, numargs * word_size);
|
||||
for (i = numargs; i < XSUBR (fun)->max_args; i++)
|
||||
internal_args[i] = Qnil;
|
||||
|
|
58
src/fileio.c
58
src/fileio.c
|
@ -396,13 +396,6 @@ Otherwise return a directory name.
|
|||
Given a Unix syntax file name, returns a string ending in slash. */)
|
||||
(Lisp_Object filename)
|
||||
{
|
||||
#ifndef DOS_NT
|
||||
register const char *beg;
|
||||
#else
|
||||
register char *beg;
|
||||
Lisp_Object tem_fn;
|
||||
#endif
|
||||
register const char *p;
|
||||
Lisp_Object handler;
|
||||
|
||||
CHECK_STRING (filename);
|
||||
|
@ -417,12 +410,8 @@ Given a Unix syntax file name, returns a string ending in slash. */)
|
|||
return STRINGP (handled_name) ? handled_name : Qnil;
|
||||
}
|
||||
|
||||
#ifdef DOS_NT
|
||||
beg = xlispstrdupa (filename);
|
||||
#else
|
||||
beg = SSDATA (filename);
|
||||
#endif
|
||||
p = beg + SBYTES (filename);
|
||||
char *beg = SSDATA (filename);
|
||||
char const *p = beg + SBYTES (filename);
|
||||
|
||||
while (p != beg && !IS_DIRECTORY_SEP (p[-1])
|
||||
#ifdef DOS_NT
|
||||
|
@ -438,6 +427,11 @@ Given a Unix syntax file name, returns a string ending in slash. */)
|
|||
return Qnil;
|
||||
#ifdef DOS_NT
|
||||
/* Expansion of "c:" to drive and default directory. */
|
||||
Lisp_Object tem_fn;
|
||||
USE_SAFE_ALLOCA;
|
||||
SAFE_ALLOCA_STRING (beg, filename);
|
||||
p = beg + (p - SSDATA (filename));
|
||||
|
||||
if (p[-1] == ':')
|
||||
{
|
||||
/* MAXPATHLEN+1 is guaranteed to be enough space for getdefdir. */
|
||||
|
@ -481,6 +475,7 @@ Given a Unix syntax file name, returns a string ending in slash. */)
|
|||
dostounix_filename (beg);
|
||||
tem_fn = make_specified_string (beg, -1, p - beg, 0);
|
||||
}
|
||||
SAFE_FREE ();
|
||||
return tem_fn;
|
||||
#else /* DOS_NT */
|
||||
return make_specified_string (beg, -1, p - beg, STRING_MULTIBYTE (filename));
|
||||
|
@ -1019,7 +1014,7 @@ filesystem tree, not (expand-file-name ".." dirname). */)
|
|||
#endif
|
||||
|
||||
/* Make a local copy of NAME to protect it from GC in DECODE_FILE below. */
|
||||
nm = xlispstrdupa (name);
|
||||
SAFE_ALLOCA_STRING (nm, name);
|
||||
nmlim = nm + SBYTES (name);
|
||||
|
||||
#ifdef DOS_NT
|
||||
|
@ -1122,12 +1117,12 @@ filesystem tree, not (expand-file-name ".." dirname). */)
|
|||
if (!NILP (Vw32_downcase_file_names))
|
||||
name = Fdowncase (name);
|
||||
#endif
|
||||
return name;
|
||||
#else /* not DOS_NT */
|
||||
if (strcmp (nm, SSDATA (name)) == 0)
|
||||
return name;
|
||||
return make_specified_string (nm, -1, nmlim - nm, multibyte);
|
||||
if (strcmp (nm, SSDATA (name)) != 0)
|
||||
name = make_specified_string (nm, -1, nmlim - nm, multibyte);
|
||||
#endif /* not DOS_NT */
|
||||
SAFE_FREE ();
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1729,7 +1724,8 @@ search_embedded_absfilename (char *nm, char *endp)
|
|||
for (s = p; *s && !IS_DIRECTORY_SEP (*s); s++);
|
||||
if (p[0] == '~' && s > p + 1) /* We've got "/~something/". */
|
||||
{
|
||||
char *o = alloca (s - p + 1);
|
||||
USE_SAFE_ALLOCA;
|
||||
char *o = SAFE_ALLOCA (s - p + 1);
|
||||
struct passwd *pw;
|
||||
memcpy (o, p, s - p);
|
||||
o [s - p] = 0;
|
||||
|
@ -1740,6 +1736,7 @@ search_embedded_absfilename (char *nm, char *endp)
|
|||
block_input ();
|
||||
pw = getpwnam (o + 1);
|
||||
unblock_input ();
|
||||
SAFE_FREE ();
|
||||
if (pw)
|
||||
return p;
|
||||
}
|
||||
|
@ -1788,7 +1785,8 @@ those `/' is discarded. */)
|
|||
/* Always work on a copy of the string, in case GC happens during
|
||||
decode of environment variables, causing the original Lisp_String
|
||||
data to be relocated. */
|
||||
nm = xlispstrdupa (filename);
|
||||
USE_SAFE_ALLOCA;
|
||||
SAFE_ALLOCA_STRING (nm, filename);
|
||||
|
||||
#ifdef DOS_NT
|
||||
dostounix_filename (nm);
|
||||
|
@ -1802,8 +1800,13 @@ those `/' is discarded. */)
|
|||
/* Start over with the new string, so we check the file-name-handler
|
||||
again. Important with filenames like "/home/foo//:/hello///there"
|
||||
which would substitute to "/:/hello///there" rather than "/there". */
|
||||
return Fsubstitute_in_file_name
|
||||
(make_specified_string (p, -1, endp - p, multibyte));
|
||||
{
|
||||
Lisp_Object result
|
||||
= (Fsubstitute_in_file_name
|
||||
(make_specified_string (p, -1, endp - p, multibyte)));
|
||||
SAFE_FREE ();
|
||||
return result;
|
||||
}
|
||||
|
||||
/* See if any variables are substituted into the string. */
|
||||
|
||||
|
@ -1825,6 +1828,7 @@ those `/' is discarded. */)
|
|||
if (!NILP (Vw32_downcase_file_names))
|
||||
filename = Fdowncase (filename);
|
||||
#endif
|
||||
SAFE_FREE ();
|
||||
return filename;
|
||||
}
|
||||
|
||||
|
@ -1843,14 +1847,14 @@ those `/' is discarded. */)
|
|||
{
|
||||
Lisp_Object xname = make_specified_string (xnm, -1, x - xnm, multibyte);
|
||||
|
||||
xname = Fdowncase (xname);
|
||||
return xname;
|
||||
filename = Fdowncase (xname);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
return (xnm == SSDATA (filename)
|
||||
? filename
|
||||
: make_specified_string (xnm, -1, x - xnm, multibyte));
|
||||
if (xnm != SSDATA (filename))
|
||||
filename = make_specified_string (xnm, -1, x - xnm, multibyte);
|
||||
SAFE_FREE ();
|
||||
return filename;
|
||||
}
|
||||
|
||||
/* A slightly faster and more convenient way to get
|
||||
|
|
24
src/fns.c
24
src/fns.c
|
@ -1992,17 +1992,14 @@ sort_vector (Lisp_Object vector, Lisp_Object predicate)
|
|||
return;
|
||||
ptrdiff_t halflen = len >> 1;
|
||||
Lisp_Object *tmp;
|
||||
Lisp_Object tmpvec = Qnil;
|
||||
struct gcpro gcpro1, gcpro2, gcpro3;
|
||||
GCPRO3 (vector, predicate, tmpvec);
|
||||
if (halflen < MAX_ALLOCA / word_size)
|
||||
tmp = alloca (halflen * word_size);
|
||||
else
|
||||
{
|
||||
tmpvec = Fmake_vector (make_number (halflen), make_number (0));
|
||||
tmp = XVECTOR (tmpvec)->contents;
|
||||
}
|
||||
struct gcpro gcpro1, gcpro2;
|
||||
GCPRO2 (vector, predicate);
|
||||
USE_SAFE_ALLOCA;
|
||||
SAFE_ALLOCA_LISP (tmp, halflen);
|
||||
for (ptrdiff_t i = 0; i < halflen; i++)
|
||||
tmp[i] = make_number (0);
|
||||
sort_vector_inplace (predicate, len, XVECTOR (vector)->contents, tmp);
|
||||
SAFE_FREE ();
|
||||
UNGCPRO;
|
||||
}
|
||||
|
||||
|
@ -3289,7 +3286,6 @@ into shorter lines. */)
|
|||
if (encoded_length < 0)
|
||||
{
|
||||
/* The encoding wasn't possible. */
|
||||
SAFE_FREE ();
|
||||
error ("Multibyte character in data for base64 encoding");
|
||||
}
|
||||
|
||||
|
@ -3434,7 +3430,6 @@ If the region can't be decoded, signal an error and don't modify the buffer. */
|
|||
if (decoded_length < 0)
|
||||
{
|
||||
/* The decoding wasn't possible. */
|
||||
SAFE_FREE ();
|
||||
error ("Invalid base64 data");
|
||||
}
|
||||
|
||||
|
@ -4581,12 +4576,12 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
|
|||
{
|
||||
Lisp_Object test, size, rehash_size, rehash_threshold, weak;
|
||||
struct hash_table_test testdesc;
|
||||
char *used;
|
||||
ptrdiff_t i;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
/* The vector `used' is used to keep track of arguments that
|
||||
have been consumed. */
|
||||
used = alloca (nargs * sizeof *used);
|
||||
char *used = SAFE_ALLOCA (nargs * sizeof *used);
|
||||
memset (used, 0, nargs * sizeof *used);
|
||||
|
||||
/* See if there's a `:test TEST' among the arguments. */
|
||||
|
@ -4653,6 +4648,7 @@ usage: (make-hash-table &rest KEYWORD-ARGS) */)
|
|||
if (!used[i])
|
||||
signal_error ("Invalid argument list", args[i]);
|
||||
|
||||
SAFE_FREE ();
|
||||
return make_hash_table (testdesc, size, rehash_size, rehash_threshold, weak);
|
||||
}
|
||||
|
||||
|
|
39
src/font.c
39
src/font.c
|
@ -1299,6 +1299,9 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
|
|||
|
||||
val = AREF (font, FONT_SIZE_INDEX);
|
||||
eassert (NUMBERP (val) || NILP (val));
|
||||
char font_size_index_buf[sizeof "-*"
|
||||
+ MAX (INT_STRLEN_BOUND (EMACS_INT),
|
||||
1 + DBL_MAX_10_EXP + 1)];
|
||||
if (INTEGERP (val))
|
||||
{
|
||||
EMACS_INT v = XINT (val);
|
||||
|
@ -1306,8 +1309,7 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
|
|||
v = pixel_size;
|
||||
if (v > 0)
|
||||
{
|
||||
f[XLFD_PIXEL_INDEX] = p =
|
||||
alloca (sizeof "-*" + INT_STRLEN_BOUND (EMACS_INT));
|
||||
f[XLFD_PIXEL_INDEX] = p = font_size_index_buf;
|
||||
sprintf (p, "%"pI"d-*", v);
|
||||
}
|
||||
else
|
||||
|
@ -1316,21 +1318,22 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
|
|||
else if (FLOATP (val))
|
||||
{
|
||||
double v = XFLOAT_DATA (val) * 10;
|
||||
f[XLFD_PIXEL_INDEX] = p = alloca (sizeof "*-" + 1 + DBL_MAX_10_EXP + 1);
|
||||
f[XLFD_PIXEL_INDEX] = p = font_size_index_buf;
|
||||
sprintf (p, "*-%.0f", v);
|
||||
}
|
||||
else
|
||||
f[XLFD_PIXEL_INDEX] = "*-*";
|
||||
|
||||
char dpi_index_buf[sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT)];
|
||||
if (INTEGERP (AREF (font, FONT_DPI_INDEX)))
|
||||
{
|
||||
EMACS_INT v = XINT (AREF (font, FONT_DPI_INDEX));
|
||||
f[XLFD_RESX_INDEX] = p =
|
||||
alloca (sizeof "-" + 2 * INT_STRLEN_BOUND (EMACS_INT));
|
||||
f[XLFD_RESX_INDEX] = p = dpi_index_buf;
|
||||
sprintf (p, "%"pI"d-%"pI"d", v, v);
|
||||
}
|
||||
else
|
||||
f[XLFD_RESX_INDEX] = "*-*";
|
||||
|
||||
if (INTEGERP (AREF (font, FONT_SPACING_INDEX)))
|
||||
{
|
||||
EMACS_INT spacing = XINT (AREF (font, FONT_SPACING_INDEX));
|
||||
|
@ -1342,13 +1345,16 @@ font_unparse_xlfd (Lisp_Object font, int pixel_size, char *name, int nbytes)
|
|||
}
|
||||
else
|
||||
f[XLFD_SPACING_INDEX] = "*";
|
||||
|
||||
char avgwidth_index_buf[INT_BUFSIZE_BOUND (EMACS_INT)];
|
||||
if (INTEGERP (AREF (font, FONT_AVGWIDTH_INDEX)))
|
||||
{
|
||||
f[XLFD_AVGWIDTH_INDEX] = p = alloca (INT_BUFSIZE_BOUND (EMACS_INT));
|
||||
f[XLFD_AVGWIDTH_INDEX] = p = avgwidth_index_buf;
|
||||
sprintf (p, "%"pI"d", XINT (AREF (font, FONT_AVGWIDTH_INDEX)));
|
||||
}
|
||||
else
|
||||
f[XLFD_AVGWIDTH_INDEX] = "*";
|
||||
|
||||
len = snprintf (name, nbytes, "-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s-%s",
|
||||
f[XLFD_FOUNDRY_INDEX], f[XLFD_FAMILY_INDEX],
|
||||
f[XLFD_WEIGHT_INDEX], f[XLFD_SLANT_INDEX],
|
||||
|
@ -2185,13 +2191,17 @@ font_score (Lisp_Object entity, Lisp_Object *spec_prop)
|
|||
static Lisp_Object
|
||||
font_vconcat_entity_vectors (Lisp_Object list)
|
||||
{
|
||||
int nargs = XINT (Flength (list));
|
||||
Lisp_Object *args = alloca (word_size * nargs);
|
||||
int i;
|
||||
EMACS_INT nargs = XFASTINT (Flength (list));
|
||||
Lisp_Object *args;
|
||||
USE_SAFE_ALLOCA;
|
||||
SAFE_ALLOCA_LISP (args, nargs);
|
||||
ptrdiff_t i;
|
||||
|
||||
for (i = 0; i < nargs; i++, list = XCDR (list))
|
||||
args[i] = XCAR (list);
|
||||
return Fvconcat (nargs, args);
|
||||
Lisp_Object result = Fvconcat (nargs, args);
|
||||
SAFE_FREE ();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -3219,9 +3229,10 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int
|
|||
val = attrs[LFACE_FAMILY_INDEX];
|
||||
val = font_intern_prop (SSDATA (val), SBYTES (val), 1);
|
||||
}
|
||||
Lisp_Object familybuf[3];
|
||||
if (NILP (val))
|
||||
{
|
||||
family = alloca ((sizeof family[0]) * 2);
|
||||
family = familybuf;
|
||||
family[0] = Qnil;
|
||||
family[1] = zero_vector; /* terminator. */
|
||||
}
|
||||
|
@ -3242,7 +3253,7 @@ font_find_for_lface (struct frame *f, Lisp_Object *attrs, Lisp_Object spec, int
|
|||
}
|
||||
else
|
||||
{
|
||||
family = alloca ((sizeof family[0]) * 3);
|
||||
family = familybuf;
|
||||
i = 0;
|
||||
family[i++] = val;
|
||||
if (NILP (AREF (spec, FONT_FAMILY_INDEX)))
|
||||
|
@ -3529,8 +3540,9 @@ font_update_drivers (struct frame *f, Lisp_Object new_drivers)
|
|||
struct font_driver_list **list_table, **next;
|
||||
Lisp_Object tail;
|
||||
int i;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
list_table = alloca (sizeof list_table[0] * (num_font_drivers + 1));
|
||||
SAFE_NALLOCA (list_table, 1, num_font_drivers + 1);
|
||||
for (i = 0, tail = new_drivers; ! NILP (tail); tail = XCDR (tail))
|
||||
{
|
||||
for (list = f->font_driver_list; list; list = list->next)
|
||||
|
@ -3551,6 +3563,7 @@ font_update_drivers (struct frame *f, Lisp_Object new_drivers)
|
|||
next = &(*next)->next;
|
||||
}
|
||||
*next = NULL;
|
||||
SAFE_FREE ();
|
||||
|
||||
if (! f->font_driver_list->on)
|
||||
{ /* None of the drivers is enabled: enable them all.
|
||||
|
|
|
@ -1079,10 +1079,11 @@ fontset_pattern_regexp (Lisp_Object pattern)
|
|||
/* If PATTERN is not full XLFD we convert "*" to ".*". Otherwise
|
||||
we convert "*" to "[^-]*" which is much faster in regular
|
||||
expression matching. */
|
||||
if (ndashes < 14)
|
||||
p1 = regex = alloca (SBYTES (pattern) + 2 * nstars + 2 * nescs + 1);
|
||||
else
|
||||
p1 = regex = alloca (SBYTES (pattern) + 5 * nstars + 2 * nescs + 1);
|
||||
ptrdiff_t regexsize = (SBYTES (pattern)
|
||||
+ (ndashes < 14 ? 2 : 5) * nstars
|
||||
+ 2 * nescs + 1);
|
||||
USE_SAFE_ALLOCA;
|
||||
p1 = regex = SAFE_ALLOCA (regexsize);
|
||||
|
||||
*p1++ = '^';
|
||||
for (p0 = SDATA (pattern); *p0; p0++)
|
||||
|
@ -1110,6 +1111,7 @@ fontset_pattern_regexp (Lisp_Object pattern)
|
|||
|
||||
Vcached_fontset_data = Fcons (build_string (SSDATA (pattern)),
|
||||
build_string ((char *) regex));
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
return CACHED_FONTSET_REGEX;
|
||||
|
@ -1892,7 +1894,9 @@ format is the same as above. */)
|
|||
|
||||
/* Recode fontsets realized on FRAME from the base fontset FONTSET
|
||||
in the table `realized'. */
|
||||
realized[0] = alloca (word_size * ASIZE (Vfontset_table));
|
||||
USE_SAFE_ALLOCA;
|
||||
SAFE_ALLOCA_LISP (realized[0], 2 * ASIZE (Vfontset_table));
|
||||
realized[1] = realized[0] + ASIZE (Vfontset_table);
|
||||
for (i = j = 0; i < ASIZE (Vfontset_table); i++)
|
||||
{
|
||||
elt = FONTSET_FROM_ID (i);
|
||||
|
@ -1903,7 +1907,6 @@ format is the same as above. */)
|
|||
}
|
||||
realized[0][j] = Qnil;
|
||||
|
||||
realized[1] = alloca (word_size * ASIZE (Vfontset_table));
|
||||
for (i = j = 0; ! NILP (realized[0][i]); i++)
|
||||
{
|
||||
elt = FONTSET_DEFAULT (realized[0][i]);
|
||||
|
@ -1995,6 +1998,7 @@ format is the same as above. */)
|
|||
break;
|
||||
}
|
||||
|
||||
SAFE_FREE ();
|
||||
return tables[0];
|
||||
}
|
||||
|
||||
|
|
54
src/frame.c
54
src/frame.c
|
@ -994,22 +994,24 @@ affects all frames on the same terminal device. */)
|
|||
{
|
||||
char *name = 0, *type = 0;
|
||||
Lisp_Object tty, tty_type;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
tty = get_future_frame_param
|
||||
(Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
|
||||
? FRAME_TTY (XFRAME (selected_frame))->name
|
||||
: NULL));
|
||||
if (!NILP (tty))
|
||||
name = xlispstrdupa (tty);
|
||||
SAFE_ALLOCA_STRING (name, tty);
|
||||
|
||||
tty_type = get_future_frame_param
|
||||
(Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
|
||||
? FRAME_TTY (XFRAME (selected_frame))->type
|
||||
: NULL));
|
||||
if (!NILP (tty_type))
|
||||
type = xlispstrdupa (tty_type);
|
||||
SAFE_ALLOCA_STRING (type, tty_type);
|
||||
|
||||
t = init_tty (name, type, 0); /* Errors are not fatal. */
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
f = make_terminal_frame (t);
|
||||
|
@ -3017,14 +3019,14 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
|
|||
#ifdef HAVE_X_WINDOWS
|
||||
bool icon_left_no_change = 0, icon_top_no_change = 0;
|
||||
#endif
|
||||
struct gcpro gcpro1, gcpro2;
|
||||
|
||||
i = 0;
|
||||
for (tail = alist; CONSP (tail); tail = XCDR (tail))
|
||||
i++;
|
||||
|
||||
parms = alloca (i * sizeof *parms);
|
||||
values = alloca (i * sizeof *values);
|
||||
USE_SAFE_ALLOCA;
|
||||
SAFE_ALLOCA_LISP (parms, 2 * i);
|
||||
values = parms + i;
|
||||
|
||||
/* Extract parm names and values into those vectors. */
|
||||
|
||||
|
@ -3041,10 +3043,6 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
|
|||
/* TAIL and ALIST are not used again below here. */
|
||||
alist = tail = Qnil;
|
||||
|
||||
GCPRO2 (*parms, *values);
|
||||
gcpro1.nvars = i;
|
||||
gcpro2.nvars = i;
|
||||
|
||||
/* There is no need to gcpro LEFT, TOP, ICON_LEFT, or ICON_TOP,
|
||||
because their values appear in VALUES and strings are not valid. */
|
||||
top = left = Qunbound;
|
||||
|
@ -3273,7 +3271,7 @@ x_set_frame_parameters (struct frame *f, Lisp_Object alist)
|
|||
#endif /* HAVE_X_WINDOWS */
|
||||
}
|
||||
|
||||
UNGCPRO;
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -4010,10 +4008,6 @@ validate_x_resource_name (void)
|
|||
static Lisp_Object
|
||||
xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Lisp_Object component, Lisp_Object subclass)
|
||||
{
|
||||
register char *value;
|
||||
char *name_key;
|
||||
char *class_key;
|
||||
|
||||
CHECK_STRING (attribute);
|
||||
CHECK_STRING (class);
|
||||
|
||||
|
@ -4028,17 +4022,20 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li
|
|||
|
||||
/* Allocate space for the components, the dots which separate them,
|
||||
and the final '\0'. Make them big enough for the worst case. */
|
||||
name_key = alloca (SBYTES (Vx_resource_name)
|
||||
+ (STRINGP (component)
|
||||
? SBYTES (component) : 0)
|
||||
+ SBYTES (attribute)
|
||||
+ 3);
|
||||
ptrdiff_t name_keysize = (SBYTES (Vx_resource_name)
|
||||
+ (STRINGP (component)
|
||||
? SBYTES (component) : 0)
|
||||
+ SBYTES (attribute)
|
||||
+ 3);
|
||||
|
||||
class_key = alloca (SBYTES (Vx_resource_class)
|
||||
+ SBYTES (class)
|
||||
+ (STRINGP (subclass)
|
||||
? SBYTES (subclass) : 0)
|
||||
+ 3);
|
||||
ptrdiff_t class_keysize = (SBYTES (Vx_resource_class)
|
||||
+ SBYTES (class)
|
||||
+ (STRINGP (subclass)
|
||||
? SBYTES (subclass) : 0)
|
||||
+ 3);
|
||||
USE_SAFE_ALLOCA;
|
||||
char *name_key = SAFE_ALLOCA (name_keysize + class_keysize);
|
||||
char *class_key = name_key + name_keysize;
|
||||
|
||||
/* Start with emacs.FRAMENAME for the name (the specific one)
|
||||
and with `Emacs' for the class key (the general one). */
|
||||
|
@ -4060,7 +4057,8 @@ xrdb_get_resource (XrmDatabase rdb, Lisp_Object attribute, Lisp_Object class, Li
|
|||
strcat (name_key, ".");
|
||||
strcat (name_key, SSDATA (attribute));
|
||||
|
||||
value = x_get_string_resource (rdb, name_key, class_key);
|
||||
char *value = x_get_string_resource (rdb, name_key, class_key);
|
||||
SAFE_FREE();
|
||||
|
||||
if (value && *value)
|
||||
return build_string (value);
|
||||
|
@ -4112,8 +4110,10 @@ x_get_resource_string (const char *attribute, const char *class)
|
|||
|
||||
/* Allocate space for the components, the dots which separate them,
|
||||
and the final '\0'. */
|
||||
char *name_key = SAFE_ALLOCA (invocation_namelen + strlen (attribute) + 2);
|
||||
char *class_key = alloca ((sizeof (EMACS_CLASS) - 1) + strlen (class) + 2);
|
||||
ptrdiff_t name_keysize = invocation_namelen + strlen (attribute) + 2;
|
||||
ptrdiff_t class_keysize = sizeof (EMACS_CLASS) - 1 + strlen (class) + 2;
|
||||
char *name_key = SAFE_ALLOCA (name_keysize + class_keysize);
|
||||
char *class_key = name_key + name_keysize;
|
||||
|
||||
esprintf (name_key, "%s.%s", SSDATA (Vinvocation_name), attribute);
|
||||
sprintf (class_key, "%s.%s", EMACS_CLASS, class);
|
||||
|
|
111
src/ftfont.c
111
src/ftfont.c
|
@ -24,6 +24,8 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#include <fontconfig/fontconfig.h>
|
||||
#include <fontconfig/fcfreetype.h>
|
||||
|
||||
#include <c-strcase.h>
|
||||
|
||||
#include "lisp.h"
|
||||
#include "dispextern.h"
|
||||
#include "frame.h"
|
||||
|
@ -140,6 +142,12 @@ static struct
|
|||
{ NULL }
|
||||
};
|
||||
|
||||
static bool
|
||||
matching_prefix (char const *str, ptrdiff_t len, char const *pat)
|
||||
{
|
||||
return len == strlen (pat) && c_strncasecmp (str, pat, len) == 0;
|
||||
}
|
||||
|
||||
/* Dirty hack for handing ADSTYLE property.
|
||||
|
||||
Fontconfig (actually the underlying FreeType) gives such ADSTYLE
|
||||
|
@ -171,18 +179,10 @@ get_adstyle_property (FcPattern *p)
|
|||
return Qnil;
|
||||
str = (char *) fcstr;
|
||||
for (end = str; *end && *end != ' '; end++);
|
||||
if (*end)
|
||||
{
|
||||
char *newstr = alloca (end - str + 1);
|
||||
memcpy (newstr, str, end - str);
|
||||
newstr[end - str] = '\0';
|
||||
end = newstr + (end - str);
|
||||
str = newstr;
|
||||
}
|
||||
if (xstrcasecmp (str, "Regular") == 0
|
||||
|| xstrcasecmp (str, "Bold") == 0
|
||||
|| xstrcasecmp (str, "Oblique") == 0
|
||||
|| xstrcasecmp (str, "Italic") == 0)
|
||||
if (matching_prefix (str, end - str, "Regular")
|
||||
|| matching_prefix (str, end - str, "Bold")
|
||||
|| matching_prefix (str, end - str, "Oblique")
|
||||
|| matching_prefix (str, end - str, "Italic"))
|
||||
return Qnil;
|
||||
adstyle = font_intern_prop (str, end - str, 1);
|
||||
if (font_style_to_value (FONT_WIDTH_INDEX, adstyle, 0) >= 0)
|
||||
|
@ -573,7 +573,8 @@ static int
|
|||
ftfont_get_charset (Lisp_Object registry)
|
||||
{
|
||||
char *str = SSDATA (SYMBOL_NAME (registry));
|
||||
char *re = alloca (SBYTES (SYMBOL_NAME (registry)) * 2 + 1);
|
||||
USE_SAFE_ALLOCA;
|
||||
char *re = SAFE_ALLOCA (SBYTES (SYMBOL_NAME (registry)) * 2 + 1);
|
||||
Lisp_Object regexp;
|
||||
int i, j;
|
||||
|
||||
|
@ -589,6 +590,7 @@ ftfont_get_charset (Lisp_Object registry)
|
|||
}
|
||||
re[j] = '\0';
|
||||
regexp = make_unibyte_string (re, j);
|
||||
SAFE_FREE ();
|
||||
for (i = 0; fc_charset_table[i].name; i++)
|
||||
if (fast_c_string_match_ignore_case
|
||||
(regexp, fc_charset_table[i].name,
|
||||
|
@ -1688,7 +1690,8 @@ ftfont_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
|
|||
else if (! otf)
|
||||
return 0;
|
||||
for (n = 1; spec->features[i][n]; n++);
|
||||
tags = alloca (sizeof (OTF_Tag) * n);
|
||||
USE_SAFE_ALLOCA;
|
||||
SAFE_NALLOCA (tags, 1, n);
|
||||
for (n = 0, negative = 0; spec->features[i][n]; n++)
|
||||
{
|
||||
if (spec->features[i][n] == 0xFFFFFFFF)
|
||||
|
@ -1698,16 +1701,17 @@ ftfont_check_otf (MFLTFont *font, MFLTOtfSpec *spec)
|
|||
else
|
||||
tags[n] = spec->features[i][n];
|
||||
}
|
||||
#ifdef M17N_FLT_USE_NEW_FEATURE
|
||||
if (OTF_check_features (otf, i == 0, spec->script, spec->langsys,
|
||||
tags, n - negative) != 1)
|
||||
bool passed = true;
|
||||
#ifndef M17N_FLT_USE_NEW_FEATURE
|
||||
passed = n - negative > 0;
|
||||
#endif
|
||||
if (passed)
|
||||
passed = (OTF_check_features (otf, i == 0, spec->script,
|
||||
spec->langsys, tags, n - negative)
|
||||
!= 1);
|
||||
SAFE_FREE ();
|
||||
if (passed)
|
||||
return 0;
|
||||
#else /* not M17N_FLT_USE_NEW_FEATURE */
|
||||
if (n - negative > 0
|
||||
&& OTF_check_features (otf, i == 0, spec->script, spec->langsys,
|
||||
tags, n - negative) != 1)
|
||||
return 0;
|
||||
#endif /* not M17N_FLT_USE_NEW_FEATURE */
|
||||
}
|
||||
return 1;
|
||||
#undef FEATURE_NONE
|
||||
|
@ -1799,11 +1803,15 @@ ftfont_drive_otf (MFLTFont *font,
|
|||
if (len == 0)
|
||||
return from;
|
||||
OTF_tag_name (spec->script, script);
|
||||
|
||||
char langsysbuf[5];
|
||||
if (spec->langsys)
|
||||
{
|
||||
langsys = alloca (5);
|
||||
langsys = langsysbuf;
|
||||
OTF_tag_name (spec->langsys, langsys);
|
||||
}
|
||||
|
||||
USE_SAFE_ALLOCA;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
char *p;
|
||||
|
@ -1811,10 +1819,11 @@ ftfont_drive_otf (MFLTFont *font,
|
|||
if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF)
|
||||
{
|
||||
for (j = 0; spec->features[i][j]; j++);
|
||||
SAFE_NALLOCA (p, 6, j);
|
||||
if (i == 0)
|
||||
p = gsub_features = alloca (6 * j);
|
||||
gsub_features = p;
|
||||
else
|
||||
p = gpos_features = alloca (6 * j);
|
||||
gpos_features = p;
|
||||
for (j = 0; spec->features[i][j]; j++)
|
||||
{
|
||||
if (spec->features[i][j] == 0xFFFFFFFF)
|
||||
|
@ -1846,7 +1855,10 @@ ftfont_drive_otf (MFLTFont *font,
|
|||
gsub_features) < 0)
|
||||
goto simple_copy;
|
||||
if (out->allocated < out->used + otf_gstring.used)
|
||||
return -2;
|
||||
{
|
||||
SAFE_FREE ();
|
||||
return -2;
|
||||
}
|
||||
features = otf->gsub->FeatureList.Feature;
|
||||
for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; )
|
||||
{
|
||||
|
@ -1935,7 +1947,10 @@ ftfont_drive_otf (MFLTFont *font,
|
|||
else if (out)
|
||||
{
|
||||
if (out->allocated < out->used + len)
|
||||
return -2;
|
||||
{
|
||||
SAFE_FREE ();
|
||||
return -2;
|
||||
}
|
||||
for (i = 0; i < len; i++)
|
||||
out->glyphs[out->used++] = in->glyphs[from + i];
|
||||
}
|
||||
|
@ -1947,7 +1962,10 @@ ftfont_drive_otf (MFLTFont *font,
|
|||
|
||||
if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys,
|
||||
gpos_features) < 0)
|
||||
return to;
|
||||
{
|
||||
SAFE_FREE ();
|
||||
return to;
|
||||
}
|
||||
features = otf->gpos->FeatureList.Feature;
|
||||
x_ppem = ft_face->size->metrics.x_ppem;
|
||||
y_ppem = ft_face->size->metrics.y_ppem;
|
||||
|
@ -2069,7 +2087,10 @@ ftfont_drive_otf (MFLTFont *font,
|
|||
{
|
||||
if (OTF_drive_gpos_with_log (otf, &otf_gstring, script, langsys,
|
||||
gpos_features) < 0)
|
||||
return to;
|
||||
{
|
||||
SAFE_FREE ();
|
||||
return to;
|
||||
}
|
||||
features = otf->gpos->FeatureList.Feature;
|
||||
for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used;
|
||||
i++, otfg++)
|
||||
|
@ -2089,9 +2110,11 @@ ftfont_drive_otf (MFLTFont *font,
|
|||
}
|
||||
}
|
||||
}
|
||||
SAFE_FREE ();
|
||||
return to;
|
||||
|
||||
simple_copy:
|
||||
SAFE_FREE ();
|
||||
if (! out)
|
||||
return to;
|
||||
if (out->allocated < out->used + len)
|
||||
|
@ -2129,11 +2152,15 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
|
|||
if (len == 0)
|
||||
return from;
|
||||
OTF_tag_name (spec->script, script);
|
||||
|
||||
char langsysbuf[5];
|
||||
if (spec->langsys)
|
||||
{
|
||||
langsys = alloca (5);
|
||||
langsys = langsysbuf;
|
||||
OTF_tag_name (spec->langsys, langsys);
|
||||
}
|
||||
|
||||
USE_SAFE_ALLOCA;
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
char *p;
|
||||
|
@ -2141,10 +2168,11 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
|
|||
if (spec->features[i] && spec->features[i][1] != 0xFFFFFFFF)
|
||||
{
|
||||
for (j = 0; spec->features[i][j]; j++);
|
||||
SAFE_NALLOCA (p, 6, j);
|
||||
if (i == 0)
|
||||
p = gsub_features = alloca (6 * j);
|
||||
gsub_features = p;
|
||||
else
|
||||
p = gpos_features = alloca (6 * j);
|
||||
gpos_features = p;
|
||||
for (j = 0; spec->features[i][j]; j++)
|
||||
{
|
||||
if (spec->features[i][j] == 0xFFFFFFFF)
|
||||
|
@ -2176,7 +2204,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
|
|||
< 0)
|
||||
goto simple_copy;
|
||||
if (out->allocated < out->used + otf_gstring.used)
|
||||
return -2;
|
||||
{
|
||||
SAFE_FREE ();
|
||||
return -2;
|
||||
}
|
||||
for (i = 0, otfg = otf_gstring.glyphs; i < otf_gstring.used; )
|
||||
{
|
||||
MFLTGlyph *g;
|
||||
|
@ -2227,7 +2258,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
|
|||
else
|
||||
{
|
||||
if (out->allocated < out->used + len)
|
||||
return -2;
|
||||
{
|
||||
SAFE_FREE ();
|
||||
return -2;
|
||||
}
|
||||
for (i = 0; i < len; i++)
|
||||
out->glyphs[out->used++] = in->glyphs[from + i];
|
||||
}
|
||||
|
@ -2239,7 +2273,10 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
|
|||
|
||||
if (OTF_drive_gpos (otf, &otf_gstring, script, langsys, gpos_features)
|
||||
< 0)
|
||||
return to;
|
||||
{
|
||||
SAFE_FREE ();
|
||||
return to;
|
||||
}
|
||||
|
||||
x_ppem = ft_face->size->metrics.x_ppem;
|
||||
y_ppem = ft_face->size->metrics.y_ppem;
|
||||
|
@ -2349,9 +2386,11 @@ ftfont_drive_otf (MFLTFont *font, MFLTOtfSpec *spec, MFLTGlyphString *in,
|
|||
base = g;
|
||||
}
|
||||
}
|
||||
SAFE_FREE ();
|
||||
return to;
|
||||
|
||||
simple_copy:
|
||||
SAFE_FREE ();
|
||||
if (out->allocated < out->used + len)
|
||||
return -2;
|
||||
font->get_metrics (font, in, from, to);
|
||||
|
|
|
@ -271,10 +271,11 @@ ftxfont_draw (struct glyph_string *s, int from, int to, int x, int y,
|
|||
|
||||
n[0] = n[1] = n[2] = n[3] = n[4] = n[5] = n[6] = 0;
|
||||
|
||||
USE_SAFE_ALLOCA;
|
||||
SAFE_NALLOCA (code, 1, len);
|
||||
block_input ();
|
||||
if (with_background)
|
||||
ftxfont_draw_background (f, font, s->gc, x, y, s->width);
|
||||
code = alloca (sizeof (unsigned) * len);
|
||||
for (i = 0; i < len; i++)
|
||||
code[i] = ((XCHAR2B_BYTE1 (s->char2b + from + i) << 8)
|
||||
| XCHAR2B_BYTE2 (s->char2b + from + i));
|
||||
|
@ -322,6 +323,7 @@ ftxfont_draw (struct glyph_string *s, int from, int to, int x, int y,
|
|||
}
|
||||
|
||||
unblock_input ();
|
||||
SAFE_FREE ();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
|
35
src/image.c
35
src/image.c
|
@ -3037,13 +3037,16 @@ xbm_load (struct frame *f, struct image *img)
|
|||
+ SBYTES (data)));
|
||||
else
|
||||
{
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
if (VECTORP (data))
|
||||
{
|
||||
int i;
|
||||
char *p;
|
||||
int nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
|
||||
|
||||
p = bits = alloca (nbytes * img->height);
|
||||
SAFE_NALLOCA (bits, nbytes, img->height);
|
||||
p = bits;
|
||||
for (i = 0; i < img->height; ++i, p += nbytes)
|
||||
{
|
||||
Lisp_Object line = AREF (data, i);
|
||||
|
@ -3064,9 +3067,8 @@ xbm_load (struct frame *f, struct image *img)
|
|||
int nbytes, i;
|
||||
/* Windows mono bitmaps are reversed compared with X. */
|
||||
invertedBits = bits;
|
||||
nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR
|
||||
* img->height;
|
||||
bits = alloca (nbytes);
|
||||
nbytes = (img->width + BITS_PER_CHAR - 1) / BITS_PER_CHAR;
|
||||
SAFE_NALLOCA (bits, nbytes, img->height);
|
||||
for (i = 0; i < nbytes; i++)
|
||||
bits[i] = XBM_BIT_SHUFFLE (invertedBits[i]);
|
||||
}
|
||||
|
@ -3088,6 +3090,8 @@ xbm_load (struct frame *f, struct image *img)
|
|||
img->spec, Qnil);
|
||||
x_clear_image (f, img);
|
||||
}
|
||||
|
||||
SAFE_FREE ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3494,6 +3498,8 @@ xpm_load (struct frame *f, struct image *img)
|
|||
int rc;
|
||||
XpmAttributes attrs;
|
||||
Lisp_Object specified_file, color_symbols;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
#ifdef HAVE_NTGUI
|
||||
HDC hdc;
|
||||
xpm_XImage * xpm_image = NULL, * xpm_mask = NULL;
|
||||
|
@ -3536,7 +3542,7 @@ xpm_load (struct frame *f, struct image *img)
|
|||
{
|
||||
Lisp_Object tail;
|
||||
XpmColorSymbol *xpm_syms;
|
||||
int i, size;
|
||||
ptrdiff_t i, size;
|
||||
|
||||
attrs.valuemask |= XpmColorSymbols;
|
||||
|
||||
|
@ -3546,8 +3552,8 @@ xpm_load (struct frame *f, struct image *img)
|
|||
++attrs.numsymbols;
|
||||
|
||||
/* Allocate an XpmColorSymbol array. */
|
||||
SAFE_NALLOCA (xpm_syms, 1, attrs.numsymbols);
|
||||
size = attrs.numsymbols * sizeof *xpm_syms;
|
||||
xpm_syms = alloca (size);
|
||||
memset (xpm_syms, 0, size);
|
||||
attrs.colorsymbols = xpm_syms;
|
||||
|
||||
|
@ -3569,17 +3575,11 @@ xpm_load (struct frame *f, struct image *img)
|
|||
name = XCAR (XCAR (tail));
|
||||
color = XCDR (XCAR (tail));
|
||||
if (STRINGP (name))
|
||||
{
|
||||
xpm_syms[i].name = alloca (SCHARS (name) + 1);
|
||||
strcpy (xpm_syms[i].name, SSDATA (name));
|
||||
}
|
||||
SAFE_ALLOCA_STRING (xpm_syms[i].name, name);
|
||||
else
|
||||
xpm_syms[i].name = empty_string;
|
||||
if (STRINGP (color))
|
||||
{
|
||||
xpm_syms[i].value = alloca (SCHARS (color) + 1);
|
||||
strcpy (xpm_syms[i].value, SSDATA (color));
|
||||
}
|
||||
SAFE_ALLOCA_STRING (xpm_syms[i].value, color);
|
||||
else
|
||||
xpm_syms[i].value = empty_string;
|
||||
}
|
||||
|
@ -3610,6 +3610,7 @@ xpm_load (struct frame *f, struct image *img)
|
|||
#ifdef ALLOC_XPM_COLORS
|
||||
xpm_free_color_cache ();
|
||||
#endif
|
||||
SAFE_FREE ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3640,6 +3641,7 @@ xpm_load (struct frame *f, struct image *img)
|
|||
#ifdef ALLOC_XPM_COLORS
|
||||
xpm_free_color_cache ();
|
||||
#endif
|
||||
SAFE_FREE ();
|
||||
return 0;
|
||||
}
|
||||
#ifdef HAVE_NTGUI
|
||||
|
@ -3782,6 +3784,7 @@ xpm_load (struct frame *f, struct image *img)
|
|||
#ifdef ALLOC_XPM_COLORS
|
||||
xpm_free_color_cache ();
|
||||
#endif
|
||||
SAFE_FREE ();
|
||||
return rc == XpmSuccess;
|
||||
}
|
||||
|
||||
|
@ -6580,6 +6583,7 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
colors generated, and mgr->cinfo.colormap is a two-dimensional array
|
||||
of color indices in the range 0..mgr->cinfo.actual_number_of_colors.
|
||||
No more than 255 colors will be generated. */
|
||||
USE_SAFE_ALLOCA;
|
||||
{
|
||||
int i, ir, ig, ib;
|
||||
|
||||
|
@ -6595,7 +6599,7 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
a default color, and we don't have to care about which colors
|
||||
can be freed safely, and which can't. */
|
||||
init_color_table ();
|
||||
colors = alloca (mgr->cinfo.actual_number_of_colors * sizeof *colors);
|
||||
SAFE_NALLOCA (colors, 1, mgr->cinfo.actual_number_of_colors);
|
||||
|
||||
for (i = 0; i < mgr->cinfo.actual_number_of_colors; ++i)
|
||||
{
|
||||
|
@ -6638,6 +6642,7 @@ jpeg_load_body (struct frame *f, struct image *img,
|
|||
|
||||
/* Put ximg into the image. */
|
||||
image_put_x_image (f, img, ximg, 0);
|
||||
SAFE_FREE ();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -500,10 +500,12 @@ kset_system_key_syms (struct kboard *kb, Lisp_Object val)
|
|||
static void
|
||||
echo_add_key (Lisp_Object c)
|
||||
{
|
||||
int size = KEY_DESCRIPTION_SIZE + 100;
|
||||
char *buffer = alloca (size);
|
||||
char initbuf[KEY_DESCRIPTION_SIZE + 100];
|
||||
ptrdiff_t size = sizeof initbuf;
|
||||
char *buffer = initbuf;
|
||||
char *ptr = buffer;
|
||||
Lisp_Object echo_string;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
echo_string = KVAR (current_kboard, echo_string);
|
||||
|
||||
|
@ -515,13 +517,13 @@ echo_add_key (Lisp_Object c)
|
|||
else if (SYMBOLP (c))
|
||||
{
|
||||
Lisp_Object name = SYMBOL_NAME (c);
|
||||
int nbytes = SBYTES (name);
|
||||
ptrdiff_t nbytes = SBYTES (name);
|
||||
|
||||
if (size - (ptr - buffer) < nbytes)
|
||||
{
|
||||
int offset = ptr - buffer;
|
||||
ptrdiff_t offset = ptr - buffer;
|
||||
size = max (2 * size, size + nbytes);
|
||||
buffer = alloca (size);
|
||||
buffer = SAFE_ALLOCA (size);
|
||||
ptr = buffer + offset;
|
||||
}
|
||||
|
||||
|
@ -532,14 +534,14 @@ echo_add_key (Lisp_Object c)
|
|||
if ((NILP (echo_string) || SCHARS (echo_string) == 0)
|
||||
&& help_char_p (c))
|
||||
{
|
||||
const char *text = " (Type ? for further options)";
|
||||
int len = strlen (text);
|
||||
static const char text[] = " (Type ? for further options)";
|
||||
int len = sizeof text - 1;
|
||||
|
||||
if (size - (ptr - buffer) < len)
|
||||
{
|
||||
int offset = ptr - buffer;
|
||||
ptrdiff_t offset = ptr - buffer;
|
||||
size += len;
|
||||
buffer = alloca (size);
|
||||
buffer = SAFE_ALLOCA (size);
|
||||
ptr = buffer + offset;
|
||||
}
|
||||
|
||||
|
@ -572,6 +574,7 @@ echo_add_key (Lisp_Object c)
|
|||
kset_echo_string
|
||||
(current_kboard,
|
||||
concat2 (echo_string, make_string (buffer, ptr - buffer)));
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
/* Add C to the echo string, if echoing is going on. C can be a
|
||||
|
@ -1147,7 +1150,7 @@ static Lisp_Object top_level_1 (Lisp_Object);
|
|||
Lisp_Object
|
||||
command_loop (void)
|
||||
{
|
||||
#ifdef HAVE_STACK_OVERFLOW_HANDLING
|
||||
#ifdef HAVE_STACK_OVERFLOW_HANDLING
|
||||
/* At least on GNU/Linux, saving signal mask is important here. */
|
||||
if (sigsetjmp (return_to_command_loop, 1) != 0)
|
||||
{
|
||||
|
@ -2351,14 +2354,15 @@ read_decoded_event_from_main_queue (struct timespec *end_time,
|
|||
{ /* An encoded byte sequence, let's try to decode it. */
|
||||
struct coding_system *coding
|
||||
= TERMINAL_KEYBOARD_CODING (terminal);
|
||||
unsigned char *src = alloca (n);
|
||||
unsigned char src[MAX_ENCODED_BYTES];
|
||||
unsigned char dest[4 * sizeof src];
|
||||
int i;
|
||||
for (i = 0; i < n; i++)
|
||||
src[i] = XINT (events[i]);
|
||||
if (meta_key != 2)
|
||||
for (i = 0; i < n; i++)
|
||||
src[i] &= ~0x80;
|
||||
coding->destination = alloca (n * 4);
|
||||
coding->destination = dest;
|
||||
coding->dst_bytes = n * 4;
|
||||
decode_coding_c_string (coding, src, n, Qnil);
|
||||
eassert (coding->produced_char <= n);
|
||||
|
@ -7434,11 +7438,14 @@ menu_bar_items (Lisp_Object old)
|
|||
in the current keymaps, or nil where it is not a prefix. */
|
||||
Lisp_Object *maps;
|
||||
|
||||
Lisp_Object mapsbuf[3];
|
||||
Lisp_Object def, tail;
|
||||
|
||||
ptrdiff_t mapno;
|
||||
Lisp_Object oquit;
|
||||
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
/* In order to build the menus, we need to call the keymap
|
||||
accessors. They all call QUIT. But this function is called
|
||||
during redisplay, during which a quit is fatal. So inhibit
|
||||
|
@ -7467,7 +7474,7 @@ menu_bar_items (Lisp_Object old)
|
|||
&& !NILP (Voverriding_local_map))
|
||||
{
|
||||
/* Yes, use them (if non-nil) as well as the global map. */
|
||||
maps = alloca (3 * sizeof (maps[0]));
|
||||
maps = mapsbuf;
|
||||
nmaps = 0;
|
||||
if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
|
||||
maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
|
||||
|
@ -7484,7 +7491,7 @@ menu_bar_items (Lisp_Object old)
|
|||
Lisp_Object tem;
|
||||
ptrdiff_t nminor;
|
||||
nminor = current_minor_maps (NULL, &tmaps);
|
||||
maps = alloca ((nminor + 4) * sizeof *maps);
|
||||
SAFE_NALLOCA (maps, 1, nminor + 4);
|
||||
nmaps = 0;
|
||||
tem = KVAR (current_kboard, Voverriding_terminal_local_map);
|
||||
if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag))
|
||||
|
@ -7556,6 +7563,7 @@ menu_bar_items (Lisp_Object old)
|
|||
}
|
||||
|
||||
Vinhibit_quit = oquit;
|
||||
SAFE_FREE ();
|
||||
return menu_bar_items_vector;
|
||||
}
|
||||
|
||||
|
@ -7992,9 +8000,11 @@ Lisp_Object
|
|||
tool_bar_items (Lisp_Object reuse, int *nitems)
|
||||
{
|
||||
Lisp_Object *maps;
|
||||
Lisp_Object mapsbuf[3];
|
||||
ptrdiff_t nmaps, i;
|
||||
Lisp_Object oquit;
|
||||
Lisp_Object *tmaps;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
*nitems = 0;
|
||||
|
||||
|
@ -8018,7 +8028,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
|
|||
&& !NILP (Voverriding_local_map))
|
||||
{
|
||||
/* Yes, use them (if non-nil) as well as the global map. */
|
||||
maps = alloca (3 * sizeof *maps);
|
||||
maps = mapsbuf;
|
||||
nmaps = 0;
|
||||
if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
|
||||
maps[nmaps++] = KVAR (current_kboard, Voverriding_terminal_local_map);
|
||||
|
@ -8035,7 +8045,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
|
|||
Lisp_Object tem;
|
||||
ptrdiff_t nminor;
|
||||
nminor = current_minor_maps (NULL, &tmaps);
|
||||
maps = alloca ((nminor + 4) * sizeof *maps);
|
||||
SAFE_NALLOCA (maps, 1, nminor + 4);
|
||||
nmaps = 0;
|
||||
tem = KVAR (current_kboard, Voverriding_terminal_local_map);
|
||||
if (!NILP (tem) && !NILP (Voverriding_local_map_menu_flag))
|
||||
|
@ -8064,6 +8074,7 @@ tool_bar_items (Lisp_Object reuse, int *nitems)
|
|||
|
||||
Vinhibit_quit = oquit;
|
||||
*nitems = ntool_bar_items / TOOL_BAR_ITEM_NSLOTS;
|
||||
SAFE_FREE ();
|
||||
return tool_bar_items_vector;
|
||||
}
|
||||
|
||||
|
|
18
src/keymap.c
18
src/keymap.c
|
@ -2883,13 +2883,14 @@ You type Translation\n\
|
|||
if (!SYMBOLP (modes[i]))
|
||||
emacs_abort ();
|
||||
|
||||
p = title = alloca (42 + SCHARS (SYMBOL_NAME (modes[i])));
|
||||
USE_SAFE_ALLOCA;
|
||||
p = title = SAFE_ALLOCA (42 + SBYTES (SYMBOL_NAME (modes[i])));
|
||||
*p++ = '\f';
|
||||
*p++ = '\n';
|
||||
*p++ = '`';
|
||||
memcpy (p, SDATA (SYMBOL_NAME (modes[i])),
|
||||
SCHARS (SYMBOL_NAME (modes[i])));
|
||||
p += SCHARS (SYMBOL_NAME (modes[i]));
|
||||
SBYTES (SYMBOL_NAME (modes[i])));
|
||||
p += SBYTES (SYMBOL_NAME (modes[i]));
|
||||
*p++ = '\'';
|
||||
memcpy (p, " Minor Mode Bindings", strlen (" Minor Mode Bindings"));
|
||||
p += strlen (" Minor Mode Bindings");
|
||||
|
@ -2898,6 +2899,7 @@ You type Translation\n\
|
|||
describe_map_tree (maps[i], 1, shadow, prefix,
|
||||
title, nomenu, 0, 0, 0);
|
||||
shadow = Fcons (maps[i], shadow);
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
start1 = get_local_map (BUF_PT (XBUFFER (buffer)),
|
||||
|
@ -3184,10 +3186,10 @@ describe_map (Lisp_Object map, Lisp_Object prefix,
|
|||
|
||||
/* These accumulate the values from sparse keymap bindings,
|
||||
so we can sort them and handle them in order. */
|
||||
int length_needed = 0;
|
||||
ptrdiff_t length_needed = 0;
|
||||
struct describe_map_elt *vect;
|
||||
int slots_used = 0;
|
||||
int i;
|
||||
ptrdiff_t slots_used = 0;
|
||||
ptrdiff_t i;
|
||||
|
||||
suppress = Qnil;
|
||||
|
||||
|
@ -3207,7 +3209,8 @@ describe_map (Lisp_Object map, Lisp_Object prefix,
|
|||
for (tail = map; CONSP (tail); tail = XCDR (tail))
|
||||
length_needed++;
|
||||
|
||||
vect = alloca (length_needed * sizeof *vect);
|
||||
USE_SAFE_ALLOCA;
|
||||
SAFE_NALLOCA (vect, 1, length_needed);
|
||||
|
||||
for (tail = map; CONSP (tail); tail = XCDR (tail))
|
||||
{
|
||||
|
@ -3350,6 +3353,7 @@ describe_map (Lisp_Object map, Lisp_Object prefix,
|
|||
}
|
||||
}
|
||||
|
||||
SAFE_FREE ();
|
||||
UNGCPRO;
|
||||
}
|
||||
|
||||
|
|
20
src/lisp.h
20
src/lisp.h
|
@ -4451,12 +4451,6 @@ egetenv (const char *var)
|
|||
return egetenv_internal (var, strlen (var));
|
||||
}
|
||||
|
||||
/* Copy Lisp string to temporary (allocated on stack) C string. */
|
||||
|
||||
#define xlispstrdupa(string) \
|
||||
memcpy (alloca (SBYTES (string) + 1), \
|
||||
SSDATA (string), SBYTES (string) + 1)
|
||||
|
||||
/* Set up the name of the machine we're running on. */
|
||||
extern void init_system_name (void);
|
||||
|
||||
|
@ -4484,7 +4478,7 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
|
|||
|
||||
/* SAFE_ALLOCA allocates a simple buffer. */
|
||||
|
||||
#define SAFE_ALLOCA(size) ((size) < MAX_ALLOCA \
|
||||
#define SAFE_ALLOCA(size) ((size) <= MAX_ALLOCA \
|
||||
? alloca (size) \
|
||||
: (sa_must_free = true, record_xmalloc (size)))
|
||||
|
||||
|
@ -4504,6 +4498,14 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
|
|||
} \
|
||||
} while (false)
|
||||
|
||||
/* SAFE_ALLOCA_STRING allocates a C copy of a Lisp string. */
|
||||
|
||||
#define SAFE_ALLOCA_STRING(ptr, string) \
|
||||
do { \
|
||||
(ptr) = SAFE_ALLOCA (SBYTES (string) + 1); \
|
||||
memcpy (ptr, SDATA (string), SBYTES (string) + 1); \
|
||||
} while (false)
|
||||
|
||||
/* SAFE_FREE frees xmalloced memory and enables GC as needed. */
|
||||
|
||||
#define SAFE_FREE() \
|
||||
|
@ -4519,9 +4521,9 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1));
|
|||
|
||||
#define SAFE_ALLOCA_LISP(buf, nelt) \
|
||||
do { \
|
||||
if ((nelt) < MAX_ALLOCA / word_size) \
|
||||
if ((nelt) <= MAX_ALLOCA / word_size) \
|
||||
(buf) = alloca ((nelt) * word_size); \
|
||||
else if ((nelt) < min (PTRDIFF_MAX, SIZE_MAX) / word_size) \
|
||||
else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \
|
||||
{ \
|
||||
Lisp_Object arg_; \
|
||||
(buf) = xmalloc ((nelt) * word_size); \
|
||||
|
|
10
src/lread.c
10
src/lread.c
|
@ -1473,6 +1473,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
|||
ptrdiff_t max_suffix_len = 0;
|
||||
int last_errno = ENOENT;
|
||||
int save_fd = -1;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
/* The last-modified time of the newest matching file found.
|
||||
Initialize it to something less than all valid timestamps. */
|
||||
|
@ -1513,7 +1514,10 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
|||
this path element/specified file name and any possible suffix. */
|
||||
want_length = max_suffix_len + SBYTES (filename);
|
||||
if (fn_size <= want_length)
|
||||
fn = alloca (fn_size = 100 + want_length);
|
||||
{
|
||||
fn_size = 100 + want_length;
|
||||
fn = SAFE_ALLOCA (fn_size);
|
||||
}
|
||||
|
||||
/* Loop over suffixes. */
|
||||
for (tail = NILP (suffixes) ? list1 (empty_unibyte_string) : suffixes;
|
||||
|
@ -1579,6 +1583,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
|||
/* We succeeded; return this descriptor and filename. */
|
||||
if (storeptr)
|
||||
*storeptr = string;
|
||||
SAFE_FREE ();
|
||||
UNGCPRO;
|
||||
return -2;
|
||||
}
|
||||
|
@ -1651,6 +1656,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
|||
/* We succeeded; return this descriptor and filename. */
|
||||
if (storeptr)
|
||||
*storeptr = string;
|
||||
SAFE_FREE ();
|
||||
UNGCPRO;
|
||||
return fd;
|
||||
}
|
||||
|
@ -1661,6 +1667,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
|||
{
|
||||
if (storeptr)
|
||||
*storeptr = save_string;
|
||||
SAFE_FREE ();
|
||||
UNGCPRO;
|
||||
return save_fd;
|
||||
}
|
||||
|
@ -1670,6 +1677,7 @@ openp (Lisp_Object path, Lisp_Object str, Lisp_Object suffixes,
|
|||
break;
|
||||
}
|
||||
|
||||
SAFE_FREE ();
|
||||
UNGCPRO;
|
||||
errno = last_errno;
|
||||
return -1;
|
||||
|
|
22
src/menu.c
22
src/menu.c
|
@ -632,8 +632,9 @@ digest_single_submenu (int start, int end, bool top_level_items)
|
|||
widget_value **submenu_stack;
|
||||
bool panes_seen = 0;
|
||||
struct frame *f = XFRAME (Vmenu_updating_frame);
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
submenu_stack = alloca (menu_items_used * sizeof *submenu_stack);
|
||||
SAFE_NALLOCA (submenu_stack, 1, menu_items_used);
|
||||
wv = make_widget_value ("menu", NULL, true, Qnil);
|
||||
wv->button_type = BUTTON_TYPE_NONE;
|
||||
first_wv = wv;
|
||||
|
@ -835,11 +836,12 @@ digest_single_submenu (int start, int end, bool top_level_items)
|
|||
that was originally a button, return it by itself. */
|
||||
if (top_level_items && first_wv->contents && first_wv->contents->next == 0)
|
||||
{
|
||||
wv = first_wv->contents;
|
||||
xfree (first_wv);
|
||||
return wv;
|
||||
wv = first_wv;
|
||||
first_wv = first_wv->contents;
|
||||
xfree (wv);
|
||||
}
|
||||
|
||||
SAFE_FREE ();
|
||||
return first_wv;
|
||||
}
|
||||
|
||||
|
@ -890,9 +892,10 @@ find_and_call_menu_selection (struct frame *f, int menu_bar_items_used,
|
|||
Lisp_Object *subprefix_stack;
|
||||
int submenu_depth = 0;
|
||||
int i;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
entry = Qnil;
|
||||
subprefix_stack = alloca (menu_bar_items_used * sizeof *subprefix_stack);
|
||||
SAFE_NALLOCA (subprefix_stack, 1, menu_bar_items_used);
|
||||
prefix = Qnil;
|
||||
i = 0;
|
||||
|
||||
|
@ -954,11 +957,13 @@ find_and_call_menu_selection (struct frame *f, int menu_bar_items_used,
|
|||
buf.arg = entry;
|
||||
kbd_buffer_store_event (&buf);
|
||||
|
||||
return;
|
||||
break;
|
||||
}
|
||||
i += MENU_ITEMS_ITEM_LENGTH;
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
#endif /* USE_X_TOOLKIT || USE_GTK || HAVE_NS || HAVE_NTGUI */
|
||||
|
@ -973,10 +978,11 @@ find_and_return_menu_selection (struct frame *f, bool keymaps, void *client_data
|
|||
int i;
|
||||
Lisp_Object *subprefix_stack;
|
||||
int submenu_depth = 0;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
prefix = entry = Qnil;
|
||||
i = 0;
|
||||
subprefix_stack = alloca (menu_items_used * word_size);
|
||||
SAFE_ALLOCA_LISP (subprefix_stack, menu_items_used);
|
||||
|
||||
while (i < menu_items_used)
|
||||
{
|
||||
|
@ -1018,11 +1024,13 @@ find_and_return_menu_selection (struct frame *f, bool keymaps, void *client_data
|
|||
if (!NILP (subprefix_stack[j]))
|
||||
entry = Fcons (subprefix_stack[j], entry);
|
||||
}
|
||||
SAFE_FREE ();
|
||||
return entry;
|
||||
}
|
||||
i += MENU_ITEMS_ITEM_LENGTH;
|
||||
}
|
||||
}
|
||||
SAFE_FREE ();
|
||||
return Qnil;
|
||||
}
|
||||
#endif /* HAVE_NS */
|
||||
|
|
|
@ -169,11 +169,13 @@ bool print_output_debug_flag EXTERNALLY_VISIBLE = 1;
|
|||
if (print_buffer_pos != print_buffer_pos_byte \
|
||||
&& NILP (BVAR (current_buffer, enable_multibyte_characters)))\
|
||||
{ \
|
||||
unsigned char *temp = alloca (print_buffer_pos + 1); \
|
||||
USE_SAFE_ALLOCA; \
|
||||
unsigned char *temp = SAFE_ALLOCA (print_buffer_pos + 1); \
|
||||
copy_text ((unsigned char *) print_buffer, temp, \
|
||||
print_buffer_pos_byte, 1, 0); \
|
||||
insert_1_both ((char *) temp, print_buffer_pos, \
|
||||
print_buffer_pos, 0, 1, 0); \
|
||||
SAFE_FREE (); \
|
||||
} \
|
||||
else \
|
||||
insert_1_both (print_buffer, print_buffer_pos, \
|
||||
|
|
|
@ -1386,9 +1386,10 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
|
|||
(ptrdiff_t nargs, Lisp_Object *args)
|
||||
{
|
||||
Lisp_Object buffer, name, program, proc, current_dir, tem;
|
||||
register unsigned char **new_argv;
|
||||
unsigned char **new_argv;
|
||||
ptrdiff_t i;
|
||||
ptrdiff_t count = SPECPDL_INDEX ();
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
buffer = args[1];
|
||||
if (!NILP (buffer))
|
||||
|
@ -1464,7 +1465,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
|
|||
val = Vcoding_system_for_read;
|
||||
if (NILP (val))
|
||||
{
|
||||
args2 = alloca ((nargs + 1) * sizeof *args2);
|
||||
SAFE_ALLOCA_LISP (args2, nargs + 1);
|
||||
args2[0] = Qstart_process;
|
||||
for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
|
||||
GCPRO2 (proc, current_dir);
|
||||
|
@ -1483,7 +1484,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
|
|||
{
|
||||
if (EQ (coding_systems, Qt))
|
||||
{
|
||||
args2 = alloca ((nargs + 1) * sizeof *args2);
|
||||
SAFE_ALLOCA_LISP (args2, nargs + 1);
|
||||
args2[0] = Qstart_process;
|
||||
for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
|
||||
GCPRO2 (proc, current_dir);
|
||||
|
@ -1578,7 +1579,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
|
|||
|
||||
/* Now that everything is encoded we can collect the strings into
|
||||
NEW_ARGV. */
|
||||
new_argv = alloca ((nargs - 1) * sizeof *new_argv);
|
||||
SAFE_NALLOCA (new_argv, 1, nargs - 1);
|
||||
new_argv[nargs - 2] = 0;
|
||||
|
||||
for (i = nargs - 2; i-- != 0; )
|
||||
|
@ -1592,6 +1593,7 @@ usage: (start-process NAME BUFFER PROGRAM &rest PROGRAM-ARGS) */)
|
|||
else
|
||||
create_pty (proc);
|
||||
|
||||
SAFE_FREE ();
|
||||
return unbind_to (count, proc);
|
||||
}
|
||||
|
||||
|
@ -2071,8 +2073,10 @@ get_lisp_to_sockaddr_size (Lisp_Object address, int *familyp)
|
|||
&& VECTORP (XCDR (address)))
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
*familyp = XINT (XCAR (address));
|
||||
p = XVECTOR (XCDR (address));
|
||||
if (MAX_ALLOCA - sizeof sa->sa_family < p->header.size)
|
||||
return 0;
|
||||
*familyp = XINT (XCAR (address));
|
||||
return p->header.size + sizeof (sa->sa_family);
|
||||
}
|
||||
return 0;
|
||||
|
@ -4973,18 +4977,17 @@ read_and_dispose_of_process_output (struct Lisp_Process *p, char *chars,
|
|||
for decoding. */
|
||||
|
||||
static int
|
||||
read_process_output (Lisp_Object proc, register int channel)
|
||||
read_process_output (Lisp_Object proc, int channel)
|
||||
{
|
||||
register ssize_t nbytes;
|
||||
char *chars;
|
||||
register struct Lisp_Process *p = XPROCESS (proc);
|
||||
ssize_t nbytes;
|
||||
struct Lisp_Process *p = XPROCESS (proc);
|
||||
struct coding_system *coding = proc_decode_coding_system[channel];
|
||||
int carryover = p->decoding_carryover;
|
||||
int readmax = 4096;
|
||||
enum { readmax = 4096 };
|
||||
ptrdiff_t count = SPECPDL_INDEX ();
|
||||
Lisp_Object odeactivate;
|
||||
char chars[sizeof coding->carryover + readmax];
|
||||
|
||||
chars = alloca (carryover + readmax);
|
||||
if (carryover)
|
||||
/* See the comment above. */
|
||||
memcpy (chars, SDATA (p->decoding_buf), carryover);
|
||||
|
@ -6837,7 +6840,7 @@ add_timer_wait_descriptor (int fd)
|
|||
{
|
||||
FD_SET (fd, &input_wait_mask);
|
||||
FD_SET (fd, &non_keyboard_wait_mask);
|
||||
FD_SET (fd, &non_process_wait_mask);
|
||||
FD_SET (fd, &non_process_wait_mask);
|
||||
fd_callback_info[fd].func = timerfd_callback;
|
||||
fd_callback_info[fd].data = NULL;
|
||||
fd_callback_info[fd].condition |= FOR_READ;
|
||||
|
|
36
src/regex.c
36
src/regex.c
|
@ -457,11 +457,17 @@ init_syntax_once (void)
|
|||
|
||||
# endif /* not alloca */
|
||||
|
||||
# define REGEX_ALLOCATE alloca
|
||||
# ifdef emacs
|
||||
# define REGEX_USE_SAFE_ALLOCA USE_SAFE_ALLOCA
|
||||
# define REGEX_SAFE_FREE() SAFE_FREE ()
|
||||
# define REGEX_ALLOCATE SAFE_ALLOCA
|
||||
# else
|
||||
# define REGEX_ALLOCATE alloca
|
||||
# endif
|
||||
|
||||
/* Assumes a `char *destination' variable. */
|
||||
# define REGEX_REALLOCATE(source, osize, nsize) \
|
||||
(destination = alloca (nsize), \
|
||||
(destination = REGEX_ALLOCATE (nsize), \
|
||||
memcpy (destination, source, osize))
|
||||
|
||||
/* No need to do anything to free, after alloca. */
|
||||
|
@ -469,6 +475,11 @@ init_syntax_once (void)
|
|||
|
||||
#endif /* not REGEX_MALLOC */
|
||||
|
||||
#ifndef REGEX_USE_SAFE_ALLOCA
|
||||
# define REGEX_USE_SAFE_ALLOCA ((void) 0)
|
||||
# define REGEX_SAFE_FREE() ((void) 0)
|
||||
#endif
|
||||
|
||||
/* Define how to allocate the failure stack. */
|
||||
|
||||
#if defined REL_ALLOC && defined REGEX_MALLOC
|
||||
|
@ -482,22 +493,10 @@ init_syntax_once (void)
|
|||
|
||||
#else /* not using relocating allocator */
|
||||
|
||||
# ifdef REGEX_MALLOC
|
||||
# define REGEX_ALLOCATE_STACK(size) REGEX_ALLOCATE (size)
|
||||
# define REGEX_REALLOCATE_STACK(source, o, n) REGEX_REALLOCATE (source, o, n)
|
||||
# define REGEX_FREE_STACK(ptr) REGEX_FREE (ptr)
|
||||
|
||||
# define REGEX_ALLOCATE_STACK malloc
|
||||
# define REGEX_REALLOCATE_STACK(source, osize, nsize) realloc (source, nsize)
|
||||
# define REGEX_FREE_STACK free
|
||||
|
||||
# else /* not REGEX_MALLOC */
|
||||
|
||||
# define REGEX_ALLOCATE_STACK alloca
|
||||
|
||||
# define REGEX_REALLOCATE_STACK(source, osize, nsize) \
|
||||
REGEX_REALLOCATE (source, osize, nsize)
|
||||
/* No need to explicitly free anything. */
|
||||
# define REGEX_FREE_STACK(arg) ((void)0)
|
||||
|
||||
# endif /* not REGEX_MALLOC */
|
||||
#endif /* not using relocating allocator */
|
||||
|
||||
|
||||
|
@ -4579,6 +4578,7 @@ static int bcmp_translate (re_char *s1, re_char *s2,
|
|||
FREE_VAR (regend); \
|
||||
FREE_VAR (best_regstart); \
|
||||
FREE_VAR (best_regend); \
|
||||
REGEX_SAFE_FREE (); \
|
||||
} while (0)
|
||||
#else
|
||||
# define FREE_VARIABLES() ((void)0) /* Do nothing! But inhibit gcc warning. */
|
||||
|
@ -5018,6 +5018,8 @@ re_match_2_internal (struct re_pattern_buffer *bufp, const_re_char *string1,
|
|||
|
||||
DEBUG_PRINT ("\n\nEntering re_match_2.\n");
|
||||
|
||||
REGEX_USE_SAFE_ALLOCA;
|
||||
|
||||
INIT_FAIL_STACK ();
|
||||
|
||||
#ifdef MATCH_MAY_ALLOCATE
|
||||
|
|
28
src/scroll.c
28
src/scroll.c
|
@ -245,18 +245,20 @@ do_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
|
|||
{
|
||||
struct matrix_elt *p;
|
||||
int i, j, k;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
/* True if we have set a terminal window with set_terminal_window. */
|
||||
bool terminal_window_p = 0;
|
||||
|
||||
/* A queue for line insertions to be done. */
|
||||
struct queue { int count, pos; };
|
||||
struct queue *queue_start
|
||||
= alloca (current_matrix->nrows * sizeof *queue_start);
|
||||
struct queue *queue_start;
|
||||
SAFE_NALLOCA (queue_start, 1, current_matrix->nrows);
|
||||
struct queue *queue = queue_start;
|
||||
|
||||
char *retained_p = alloca (window_size * sizeof *retained_p);
|
||||
int *copy_from = alloca (window_size * sizeof *copy_from);
|
||||
char *retained_p = SAFE_ALLOCA (window_size);
|
||||
int *copy_from;
|
||||
SAFE_NALLOCA (copy_from, 1, window_size);
|
||||
|
||||
/* Zero means line is empty. */
|
||||
memset (retained_p, 0, window_size * sizeof (char));
|
||||
|
@ -378,6 +380,7 @@ do_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
|
|||
|
||||
if (terminal_window_p)
|
||||
set_terminal_window (frame, 0);
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -649,10 +652,12 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
|
|||
{
|
||||
struct matrix_elt *p;
|
||||
int i, j;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
/* A queue of deletions and insertions to be performed. */
|
||||
struct alt_queue { int count, pos, window; };
|
||||
struct alt_queue *queue_start = alloca (window_size * sizeof *queue_start);
|
||||
struct alt_queue *queue_start;
|
||||
SAFE_NALLOCA (queue_start, 1, window_size);
|
||||
struct alt_queue *queue = queue_start;
|
||||
|
||||
/* True if a terminal window has been set with set_terminal_window. */
|
||||
|
@ -667,11 +672,12 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
|
|||
bool write_follows_p = 1;
|
||||
|
||||
/* For each row in the new matrix what row of the old matrix it is. */
|
||||
int *copy_from = alloca (window_size * sizeof *copy_from);
|
||||
int *copy_from;
|
||||
SAFE_NALLOCA (copy_from, 1, window_size);
|
||||
|
||||
/* Non-zero for each row in the new matrix that is retained from the
|
||||
old matrix. Lines not retained are empty. */
|
||||
char *retained_p = alloca (window_size * sizeof *retained_p);
|
||||
char *retained_p = SAFE_ALLOCA (window_size);
|
||||
|
||||
memset (retained_p, 0, window_size * sizeof (char));
|
||||
|
||||
|
@ -787,6 +793,7 @@ do_direct_scrolling (struct frame *frame, struct glyph_matrix *current_matrix,
|
|||
|
||||
if (terminal_window_p)
|
||||
set_terminal_window (frame, 0);
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
|
||||
|
@ -796,8 +803,9 @@ scrolling_1 (struct frame *frame, int window_size, int unchanged_at_top,
|
|||
int unchanged_at_bottom, int *draw_cost, int *old_draw_cost,
|
||||
unsigned *old_hash, unsigned *new_hash, int free_at_end)
|
||||
{
|
||||
struct matrix_elt *matrix
|
||||
= alloca ((window_size + 1) * (window_size + 1) * sizeof *matrix);
|
||||
USE_SAFE_ALLOCA;
|
||||
struct matrix_elt *matrix;
|
||||
SAFE_NALLOCA (matrix, window_size + 1, window_size + 1);
|
||||
|
||||
if (FRAME_SCROLL_REGION_OK (frame))
|
||||
{
|
||||
|
@ -817,6 +825,8 @@ scrolling_1 (struct frame *frame, int window_size, int unchanged_at_top,
|
|||
frame->current_matrix, matrix, window_size,
|
||||
unchanged_at_top);
|
||||
}
|
||||
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
|
||||
|
|
73
src/search.c
73
src/search.c
|
@ -1318,6 +1318,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
|
|||
translation. Otherwise set to zero later. */
|
||||
int char_base = -1;
|
||||
bool boyer_moore_ok = 1;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
/* MULTIBYTE says whether the text to be searched is multibyte.
|
||||
We must convert PATTERN to match that, or we will not really
|
||||
|
@ -1335,7 +1336,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
|
|||
raw_pattern_size_byte
|
||||
= count_size_as_multibyte (SDATA (string),
|
||||
raw_pattern_size);
|
||||
raw_pattern = alloca (raw_pattern_size_byte + 1);
|
||||
raw_pattern = SAFE_ALLOCA (raw_pattern_size_byte + 1);
|
||||
copy_text (SDATA (string), raw_pattern,
|
||||
SCHARS (string), 0, 1);
|
||||
}
|
||||
|
@ -1349,7 +1350,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
|
|||
the chosen single-byte character set can possibly match. */
|
||||
raw_pattern_size = SCHARS (string);
|
||||
raw_pattern_size_byte = SCHARS (string);
|
||||
raw_pattern = alloca (raw_pattern_size + 1);
|
||||
raw_pattern = SAFE_ALLOCA (raw_pattern_size + 1);
|
||||
copy_text (SDATA (string), raw_pattern,
|
||||
SBYTES (string), 1, 0);
|
||||
}
|
||||
|
@ -1357,7 +1358,7 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
|
|||
/* Copy and optionally translate the pattern. */
|
||||
len = raw_pattern_size;
|
||||
len_byte = raw_pattern_size_byte;
|
||||
patbuf = alloca (len * MAX_MULTIBYTE_LENGTH);
|
||||
SAFE_NALLOCA (patbuf, MAX_MULTIBYTE_LENGTH, len);
|
||||
pat = patbuf;
|
||||
base_pat = raw_pattern;
|
||||
if (multibyte)
|
||||
|
@ -1497,13 +1498,15 @@ search_buffer (Lisp_Object string, ptrdiff_t pos, ptrdiff_t pos_byte,
|
|||
len_byte = pat - patbuf;
|
||||
pat = base_pat = patbuf;
|
||||
|
||||
if (boyer_moore_ok)
|
||||
return boyer_moore (n, pat, len_byte, trt, inverse_trt,
|
||||
pos_byte, lim_byte,
|
||||
char_base);
|
||||
else
|
||||
return simple_search (n, pat, raw_pattern_size, len_byte, trt,
|
||||
pos, pos_byte, lim, lim_byte);
|
||||
EMACS_INT result
|
||||
= (boyer_moore_ok
|
||||
? boyer_moore (n, pat, len_byte, trt, inverse_trt,
|
||||
pos_byte, lim_byte,
|
||||
char_base)
|
||||
: simple_search (n, pat, raw_pattern_size, len_byte, trt,
|
||||
pos, pos_byte, lim, lim_byte));
|
||||
SAFE_FREE ();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2809,7 +2812,8 @@ Return value is undefined if the last search failed. */)
|
|||
|
||||
prev = Qnil;
|
||||
|
||||
data = alloca ((2 * search_regs.num_regs + 1) * sizeof *data);
|
||||
USE_SAFE_ALLOCA;
|
||||
SAFE_NALLOCA (data, 1, 2 * search_regs.num_regs + 1);
|
||||
|
||||
len = 0;
|
||||
for (i = 0; i < search_regs.num_regs; i++)
|
||||
|
@ -2852,25 +2856,28 @@ Return value is undefined if the last search failed. */)
|
|||
|
||||
/* If REUSE is not usable, cons up the values and return them. */
|
||||
if (! CONSP (reuse))
|
||||
return Flist (len, data);
|
||||
|
||||
/* If REUSE is a list, store as many value elements as will fit
|
||||
into the elements of REUSE. */
|
||||
for (i = 0, tail = reuse; CONSP (tail);
|
||||
i++, tail = XCDR (tail))
|
||||
reuse = Flist (len, data);
|
||||
else
|
||||
{
|
||||
/* If REUSE is a list, store as many value elements as will fit
|
||||
into the elements of REUSE. */
|
||||
for (i = 0, tail = reuse; CONSP (tail);
|
||||
i++, tail = XCDR (tail))
|
||||
{
|
||||
if (i < len)
|
||||
XSETCAR (tail, data[i]);
|
||||
else
|
||||
XSETCAR (tail, Qnil);
|
||||
prev = tail;
|
||||
}
|
||||
|
||||
/* If we couldn't fit all value elements into REUSE,
|
||||
cons up the rest of them and add them to the end of REUSE. */
|
||||
if (i < len)
|
||||
XSETCAR (tail, data[i]);
|
||||
else
|
||||
XSETCAR (tail, Qnil);
|
||||
prev = tail;
|
||||
XSETCDR (prev, Flist (len - i, data + i));
|
||||
}
|
||||
|
||||
/* If we couldn't fit all value elements into REUSE,
|
||||
cons up the rest of them and add them to the end of REUSE. */
|
||||
if (i < len)
|
||||
XSETCDR (prev, Flist (len - i, data + i));
|
||||
|
||||
SAFE_FREE ();
|
||||
return reuse;
|
||||
}
|
||||
|
||||
|
@ -3075,7 +3082,8 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
|
|||
|
||||
CHECK_STRING (string);
|
||||
|
||||
temp = alloca (SBYTES (string) * 2);
|
||||
USE_SAFE_ALLOCA;
|
||||
SAFE_NALLOCA (temp, 2, SBYTES (string));
|
||||
|
||||
/* Now copy the data into the new string, inserting escapes. */
|
||||
|
||||
|
@ -3093,10 +3101,13 @@ DEFUN ("regexp-quote", Fregexp_quote, Sregexp_quote, 1, 1, 0,
|
|||
*out++ = *in;
|
||||
}
|
||||
|
||||
return make_specified_string (temp,
|
||||
SCHARS (string) + backslashes_added,
|
||||
out - temp,
|
||||
STRING_MULTIBYTE (string));
|
||||
Lisp_Object result
|
||||
= make_specified_string (temp,
|
||||
SCHARS (string) + backslashes_added,
|
||||
out - temp,
|
||||
STRING_MULTIBYTE (string));
|
||||
SAFE_FREE ();
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Like find_newline, but doesn't use the cache, and only searches forward. */
|
||||
|
|
15
src/sound.c
15
src/sound.c
|
@ -564,12 +564,11 @@ wav_play (struct sound *s, struct sound_device *sd)
|
|||
SBYTES (s->data) - sizeof *header);
|
||||
else
|
||||
{
|
||||
char *buffer;
|
||||
ptrdiff_t nbytes = 0;
|
||||
ptrdiff_t blksize = sd->period_size ? sd->period_size (sd) : 2048;
|
||||
ptrdiff_t data_left = header->data_length;
|
||||
|
||||
buffer = alloca (blksize);
|
||||
USE_SAFE_ALLOCA;
|
||||
char *buffer = SAFE_ALLOCA (blksize);
|
||||
lseek (s->fd, sizeof *header, SEEK_SET);
|
||||
while (data_left > 0
|
||||
&& (nbytes = emacs_read (s->fd, buffer, blksize)) > 0)
|
||||
|
@ -582,6 +581,7 @@ wav_play (struct sound *s, struct sound_device *sd)
|
|||
|
||||
if (nbytes < 0)
|
||||
sound_perror ("Error reading sound file");
|
||||
SAFE_FREE ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -656,19 +656,20 @@ au_play (struct sound *s, struct sound_device *sd)
|
|||
else
|
||||
{
|
||||
ptrdiff_t blksize = sd->period_size ? sd->period_size (sd) : 2048;
|
||||
char *buffer;
|
||||
ptrdiff_t nbytes;
|
||||
|
||||
/* Seek */
|
||||
lseek (s->fd, header->data_offset, SEEK_SET);
|
||||
|
||||
/* Copy sound data to the device. */
|
||||
buffer = alloca (blksize);
|
||||
USE_SAFE_ALLOCA;
|
||||
char *buffer = SAFE_ALLOCA (blksize);
|
||||
while ((nbytes = emacs_read (s->fd, buffer, blksize)) > 0)
|
||||
sd->write (sd, buffer, nbytes);
|
||||
|
||||
if (nbytes < 0)
|
||||
sound_perror ("Error reading sound file");
|
||||
SAFE_FREE ();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1309,7 +1310,6 @@ Internal use only, use `play-sound' instead. */)
|
|||
struct gcpro gcpro1, gcpro2;
|
||||
Lisp_Object args[2];
|
||||
#else /* WINDOWSNT */
|
||||
int len = 0;
|
||||
Lisp_Object lo_file = {0};
|
||||
char * psz_file = NULL;
|
||||
unsigned long ui_volume_tmp = UINT_MAX;
|
||||
|
@ -1326,7 +1326,8 @@ Internal use only, use `play-sound' instead. */)
|
|||
current_sound_device = xzalloc (sizeof *current_sound_device);
|
||||
current_sound = xzalloc (sizeof *current_sound);
|
||||
record_unwind_protect_void (sound_cleanup);
|
||||
current_sound->header = alloca (MAX_SOUND_HEADER_BYTES);
|
||||
char headerbuf[MAX_SOUND_HEADER_BYTES];
|
||||
current_sound->header = headerbuf;
|
||||
|
||||
if (STRINGP (attrs[SOUND_FILE]))
|
||||
{
|
||||
|
|
|
@ -1567,6 +1567,7 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
|
|||
const unsigned char *str;
|
||||
int len;
|
||||
Lisp_Object iso_classes;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
CHECK_STRING (string);
|
||||
iso_classes = Qnil;
|
||||
|
@ -1699,7 +1700,7 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
|
|||
memcpy (himap, fastmap + 0200, 0200);
|
||||
himap[0200] = 0;
|
||||
memset (fastmap + 0200, 0, 0200);
|
||||
char_ranges = alloca (sizeof *char_ranges * 128 * 2);
|
||||
SAFE_NALLOCA (char_ranges, 2, 128);
|
||||
i = 0;
|
||||
|
||||
while ((p1 = memchr (himap + i, 1, 0200 - i)))
|
||||
|
@ -1723,7 +1724,7 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
|
|||
}
|
||||
else /* STRING is multibyte */
|
||||
{
|
||||
char_ranges = alloca (sizeof *char_ranges * SCHARS (string) * 2);
|
||||
SAFE_NALLOCA (char_ranges, 2, SCHARS (string));
|
||||
|
||||
while (i_byte < size_byte)
|
||||
{
|
||||
|
@ -2032,6 +2033,7 @@ skip_chars (bool forwardp, Lisp_Object string, Lisp_Object lim,
|
|||
SET_PT_BOTH (pos, pos_byte);
|
||||
immediate_quit = 0;
|
||||
|
||||
SAFE_FREE ();
|
||||
return make_number (PT - start_point);
|
||||
}
|
||||
}
|
||||
|
|
10
src/term.c
10
src/term.c
|
@ -3191,6 +3191,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
|
|||
Lisp_Object selectface;
|
||||
int first_item = 0;
|
||||
int col, row;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
/* Don't allow non-positive x0 and y0, lest the menu will wrap
|
||||
around the display. */
|
||||
|
@ -3199,7 +3200,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
|
|||
if (y0 <= 0)
|
||||
y0 = 1;
|
||||
|
||||
state = alloca (menu->panecount * sizeof (struct tty_menu_state));
|
||||
SAFE_NALLOCA (state, 1, menu->panecount);
|
||||
memset (state, 0, sizeof (*state));
|
||||
faces[0]
|
||||
= lookup_derived_face (sf, intern ("tty-menu-disabled-face"),
|
||||
|
@ -3421,6 +3422,7 @@ tty_menu_activate (tty_menu *menu, int *pane, int *selidx,
|
|||
discard_mouse_events ();
|
||||
if (!kbd_buffer_events_waiting ())
|
||||
clear_input_pending ();
|
||||
SAFE_FREE ();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3606,6 +3608,7 @@ tty_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
item_y = y += f->top_pos;
|
||||
|
||||
/* Create all the necessary panes and their items. */
|
||||
USE_SAFE_ALLOCA;
|
||||
maxwidth = maxlines = lines = i = 0;
|
||||
lpane = TTYM_FAILURE;
|
||||
while (i < menu_items_used)
|
||||
|
@ -3674,9 +3677,7 @@ tty_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
|
||||
if (!NILP (descrip))
|
||||
{
|
||||
/* If alloca is fast, use that to make the space,
|
||||
to reduce gc needs. */
|
||||
item_data = (char *) alloca (maxwidth + SBYTES (descrip) + 1);
|
||||
item_data = SAFE_ALLOCA (maxwidth + SBYTES (descrip) + 1);
|
||||
memcpy (item_data, SSDATA (item_name), SBYTES (item_name));
|
||||
for (j = SCHARS (item_name); j < maxwidth; j++)
|
||||
item_data[j] = ' ';
|
||||
|
@ -3829,6 +3830,7 @@ tty_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
|
||||
tty_menu_end:
|
||||
|
||||
SAFE_FREE ();
|
||||
unbind_to (specpdl_count, Qnil);
|
||||
return entry;
|
||||
}
|
||||
|
|
|
@ -660,6 +660,7 @@ get_char_property_and_overlay (Lisp_Object position, register Lisp_Object prop,
|
|||
|
||||
set_buffer_temp (XBUFFER (object));
|
||||
|
||||
USE_SAFE_ALLOCA;
|
||||
GET_OVERLAYS_AT (XINT (position), overlay_vec, noverlays, NULL, 0);
|
||||
noverlays = sort_overlays (overlay_vec, noverlays, w);
|
||||
|
||||
|
@ -674,9 +675,11 @@ get_char_property_and_overlay (Lisp_Object position, register Lisp_Object prop,
|
|||
if (overlay)
|
||||
/* Return the overlay we got the property from. */
|
||||
*overlay = overlay_vec[noverlays];
|
||||
SAFE_FREE ();
|
||||
return tem;
|
||||
}
|
||||
}
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
if (overlay)
|
||||
|
|
|
@ -6124,6 +6124,7 @@ the return value is nil. Otherwise the value is t. */)
|
|||
Lisp_Object frame;
|
||||
struct frame *f;
|
||||
ptrdiff_t old_point = -1;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
CHECK_WINDOW_CONFIGURATION (configuration);
|
||||
|
||||
|
@ -6231,8 +6232,8 @@ the return value is nil. Otherwise the value is t. */)
|
|||
really like to do is to free only those matrices not reused
|
||||
below. */
|
||||
root_window = XWINDOW (FRAME_ROOT_WINDOW (f));
|
||||
leaf_windows = alloca (count_windows (root_window)
|
||||
* sizeof *leaf_windows);
|
||||
int nwindows = count_windows (root_window);
|
||||
SAFE_NALLOCA (leaf_windows, 1, nwindows);
|
||||
n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0);
|
||||
|
||||
/* Kludge Alert!
|
||||
|
@ -6456,6 +6457,7 @@ the return value is nil. Otherwise the value is t. */)
|
|||
Vminibuf_scroll_window = data->minibuf_scroll_window;
|
||||
minibuf_selected_window = data->minibuf_selected_window;
|
||||
|
||||
SAFE_FREE ();
|
||||
return (FRAME_LIVE_P (f) ? Qt : Qnil);
|
||||
}
|
||||
|
||||
|
|
41
src/xdisp.c
41
src/xdisp.c
|
@ -2626,15 +2626,14 @@ safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
|
|||
{
|
||||
ptrdiff_t i;
|
||||
ptrdiff_t count = SPECPDL_INDEX ();
|
||||
struct gcpro gcpro1;
|
||||
Lisp_Object *args = alloca (nargs * word_size);
|
||||
Lisp_Object *args;
|
||||
USE_SAFE_ALLOCA;
|
||||
SAFE_ALLOCA_LISP (args, nargs);
|
||||
|
||||
args[0] = func;
|
||||
for (i = 1; i < nargs; i++)
|
||||
args[i] = va_arg (ap, Lisp_Object);
|
||||
|
||||
GCPRO1 (args[0]);
|
||||
gcpro1.nvars = nargs;
|
||||
specbind (Qinhibit_redisplay, Qt);
|
||||
if (inhibit_quit)
|
||||
specbind (Qinhibit_quit, Qt);
|
||||
|
@ -2642,7 +2641,7 @@ safe__call (bool inhibit_quit, ptrdiff_t nargs, Lisp_Object func, va_list ap)
|
|||
so there is no possibility of wanting to redisplay. */
|
||||
val = internal_condition_case_n (Ffuncall, nargs, args, Qt,
|
||||
safe_eval_handler);
|
||||
UNGCPRO;
|
||||
SAFE_FREE ();
|
||||
val = unbind_to (count, val);
|
||||
}
|
||||
|
||||
|
@ -3659,6 +3658,7 @@ next_overlay_change (ptrdiff_t pos)
|
|||
ptrdiff_t i, noverlays;
|
||||
ptrdiff_t endpos;
|
||||
Lisp_Object *overlays;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
/* Get all overlays at the given position. */
|
||||
GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
|
||||
|
@ -3675,6 +3675,7 @@ next_overlay_change (ptrdiff_t pos)
|
|||
endpos = min (endpos, oendpos);
|
||||
}
|
||||
|
||||
SAFE_FREE ();
|
||||
return endpos;
|
||||
}
|
||||
|
||||
|
@ -5735,10 +5736,11 @@ load_overlay_strings (struct it *it, ptrdiff_t charpos)
|
|||
Lisp_Object overlay, window, str, invisible;
|
||||
struct Lisp_Overlay *ov;
|
||||
ptrdiff_t start, end;
|
||||
ptrdiff_t size = 20;
|
||||
ptrdiff_t n = 0, i, j;
|
||||
int invis_p;
|
||||
struct overlay_entry *entries = alloca (size * sizeof *entries);
|
||||
struct overlay_entry entriesbuf[20];
|
||||
ptrdiff_t size = ARRAYELTS (entriesbuf);
|
||||
struct overlay_entry *entries = entriesbuf;
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
if (charpos <= 0)
|
||||
|
@ -10191,9 +10193,9 @@ message3 (Lisp_Object m)
|
|||
{
|
||||
ptrdiff_t nbytes = SBYTES (m);
|
||||
bool multibyte = STRING_MULTIBYTE (m);
|
||||
char *buffer;
|
||||
USE_SAFE_ALLOCA;
|
||||
char *buffer = SAFE_ALLOCA (nbytes);
|
||||
memcpy (buffer, SDATA (m), nbytes);
|
||||
SAFE_ALLOCA_STRING (buffer, m);
|
||||
message_dolog (buffer, nbytes, 1, multibyte);
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
@ -10395,11 +10397,13 @@ vmessage (const char *m, va_list ap)
|
|||
{
|
||||
ptrdiff_t len;
|
||||
ptrdiff_t maxsize = FRAME_MESSAGE_BUF_SIZE (f);
|
||||
char *message_buf = alloca (maxsize + 1);
|
||||
USE_SAFE_ALLOCA;
|
||||
char *message_buf = SAFE_ALLOCA (maxsize + 1);
|
||||
|
||||
len = doprnt (message_buf, maxsize, m, 0, ap);
|
||||
|
||||
message3 (make_string (message_buf, len));
|
||||
SAFE_FREE ();
|
||||
}
|
||||
else
|
||||
message1 (0);
|
||||
|
@ -18695,10 +18699,10 @@ dump_glyph_row (struct glyph_row *row, int vpos, int glyphs)
|
|||
else if (glyphs == 1)
|
||||
{
|
||||
int area;
|
||||
char s[SHRT_MAX + 4];
|
||||
|
||||
for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
|
||||
{
|
||||
char *s = alloca (row->used[area] + 4);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < row->used[area]; ++i)
|
||||
|
@ -22690,10 +22694,8 @@ decode_mode_spec_coding (Lisp_Object coding_system, register char *buf, int eol_
|
|||
}
|
||||
else if (CHARACTERP (eoltype))
|
||||
{
|
||||
unsigned char *tmp = alloca (MAX_MULTIBYTE_LENGTH);
|
||||
int c = XFASTINT (eoltype);
|
||||
eol_str_len = CHAR_STRING (c, tmp);
|
||||
eol_str = tmp;
|
||||
return buf + CHAR_STRING (c, (unsigned char *) buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -24609,7 +24611,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
|
|||
face_id = (row)->glyphs[area][START].face_id; \
|
||||
\
|
||||
s = alloca (sizeof *s); \
|
||||
char2b = alloca ((END - START) * sizeof *char2b); \
|
||||
SAFE_NALLOCA (char2b, 1, (END) - (START)); \
|
||||
INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
|
||||
append_glyph_string (&HEAD, &TAIL, s); \
|
||||
s->x = (X); \
|
||||
|
@ -24637,7 +24639,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
|
|||
struct glyph_string *first_s = NULL; \
|
||||
int n; \
|
||||
\
|
||||
char2b = alloca (cmp->glyph_len * sizeof *char2b); \
|
||||
SAFE_NALLOCA (char2b, 1, cmp->glyph_len); \
|
||||
\
|
||||
/* Make glyph_strings for each glyph sequence that is drawable by \
|
||||
the same face, and append them to HEAD/TAIL. */ \
|
||||
|
@ -24672,7 +24674,7 @@ compute_overhangs_and_x (struct glyph_string *s, int x, int backward_p)
|
|||
gstring = (composition_gstring_from_id \
|
||||
((row)->glyphs[area][START].u.cmp.id)); \
|
||||
s = alloca (sizeof *s); \
|
||||
char2b = alloca (LGSTRING_GLYPH_LEN (gstring) * sizeof *char2b); \
|
||||
SAFE_NALLOCA (char2b, 1, LGSTRING_GLYPH_LEN (gstring)); \
|
||||
INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
|
||||
append_glyph_string (&(HEAD), &(TAIL), s); \
|
||||
s->x = (X); \
|
||||
|
@ -24824,6 +24826,7 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
|
|||
BUILD_GLYPH_STRINGS will modify its start parameter. That's
|
||||
the reason we use a separate variable `i'. */
|
||||
i = start;
|
||||
USE_SAFE_ALLOCA;
|
||||
BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
|
||||
if (tail)
|
||||
x_reached = tail->x + tail->background_width;
|
||||
|
@ -25023,6 +25026,7 @@ draw_glyphs (struct window *w, int x, struct glyph_row *row,
|
|||
|
||||
RELEASE_HDC (hdc, f);
|
||||
|
||||
SAFE_FREE ();
|
||||
return x_reached;
|
||||
}
|
||||
|
||||
|
@ -29291,6 +29295,8 @@ note_mouse_highlight (struct frame *f, int x, int y)
|
|||
/* Is this char mouse-active or does it have help-echo? */
|
||||
position = make_number (pos);
|
||||
|
||||
USE_SAFE_ALLOCA;
|
||||
|
||||
if (BUFFERP (object))
|
||||
{
|
||||
/* Put all the overlays we want in a vector in overlay_vec. */
|
||||
|
@ -29572,6 +29578,7 @@ note_mouse_highlight (struct frame *f, int x, int y)
|
|||
BEGV = obegv;
|
||||
ZV = ozv;
|
||||
current_buffer = obuf;
|
||||
SAFE_FREE ();
|
||||
}
|
||||
|
||||
set_cursor:
|
||||
|
|
|
@ -5980,6 +5980,7 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
|
|||
endpos = XINT (end);
|
||||
|
||||
/* Look at properties from overlays. */
|
||||
USE_SAFE_ALLOCA;
|
||||
{
|
||||
ptrdiff_t next_overlay;
|
||||
|
||||
|
@ -6006,7 +6007,10 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
|
|||
/* Optimize common cases where we can use the default face. */
|
||||
if (noverlays == 0
|
||||
&& NILP (prop))
|
||||
return default_face->id;
|
||||
{
|
||||
SAFE_FREE ();
|
||||
return default_face->id;
|
||||
}
|
||||
|
||||
/* Begin with attributes from the default face. */
|
||||
memcpy (attrs, default_face->lface, sizeof attrs);
|
||||
|
@ -6034,6 +6038,8 @@ face_at_buffer_position (struct window *w, ptrdiff_t pos,
|
|||
|
||||
*endptr = endpos;
|
||||
|
||||
SAFE_FREE ();
|
||||
|
||||
/* Look up a realized face with the given face attributes,
|
||||
or realize a new one for ASCII characters. */
|
||||
return lookup_face (f, attrs);
|
||||
|
|
25
src/xmenu.c
25
src/xmenu.c
|
@ -2023,7 +2023,8 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
Window root;
|
||||
XMenu *menu;
|
||||
int pane, selidx, lpane, status;
|
||||
Lisp_Object entry, pane_prefix;
|
||||
Lisp_Object entry = Qnil;
|
||||
Lisp_Object pane_prefix;
|
||||
char *datap;
|
||||
int ulx, uly, width, height;
|
||||
int dispwidth, dispheight;
|
||||
|
@ -2045,6 +2046,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
return Qnil;
|
||||
}
|
||||
|
||||
USE_SAFE_ALLOCA;
|
||||
block_input ();
|
||||
|
||||
/* Figure out which root window F is on. */
|
||||
|
@ -2057,8 +2059,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
if (menu == NULL)
|
||||
{
|
||||
*error_name = "Can't create menu";
|
||||
unblock_input ();
|
||||
return Qnil;
|
||||
goto return_entry;
|
||||
}
|
||||
|
||||
/* Don't GC while we prepare and show the menu,
|
||||
|
@ -2101,8 +2102,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
{
|
||||
XMenuDestroy (FRAME_X_DISPLAY (f), menu);
|
||||
*error_name = "Can't create pane";
|
||||
unblock_input ();
|
||||
return Qnil;
|
||||
goto return_entry;
|
||||
}
|
||||
i += MENU_ITEMS_PANE_LENGTH;
|
||||
|
||||
|
@ -2146,9 +2146,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
|
||||
if (!NILP (descrip))
|
||||
{
|
||||
/* if alloca is fast, use that to make the space,
|
||||
to reduce gc needs. */
|
||||
item_data = alloca (maxwidth + SBYTES (descrip) + 1);
|
||||
item_data = SAFE_ALLOCA (maxwidth + SBYTES (descrip) + 1);
|
||||
memcpy (item_data, SSDATA (item_name), SBYTES (item_name));
|
||||
for (j = SCHARS (item_name); j < maxwidth; j++)
|
||||
item_data[j] = ' ';
|
||||
|
@ -2166,8 +2164,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
{
|
||||
XMenuDestroy (FRAME_X_DISPLAY (f), menu);
|
||||
*error_name = "Can't add selection to menu";
|
||||
unblock_input ();
|
||||
return Qnil;
|
||||
goto return_entry;
|
||||
}
|
||||
i += MENU_ITEMS_ITEM_LENGTH;
|
||||
lines++;
|
||||
|
@ -2241,7 +2238,7 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
status = XMenuActivate (FRAME_X_DISPLAY (f), menu, &pane, &selidx,
|
||||
x, y, ButtonReleaseMask, &datap,
|
||||
menu_help_callback);
|
||||
entry = pane_prefix = Qnil;
|
||||
pane_prefix = Qnil;
|
||||
|
||||
switch (status)
|
||||
{
|
||||
|
@ -2300,10 +2297,10 @@ x_menu_show (struct frame *f, int x, int y, int menuflags,
|
|||
break;
|
||||
}
|
||||
|
||||
return_entry:
|
||||
unblock_input ();
|
||||
unbind_to (specpdl_count, Qnil);
|
||||
|
||||
return entry;
|
||||
SAFE_FREE ();
|
||||
return unbind_to (specpdl_count, entry);
|
||||
}
|
||||
|
||||
#endif /* not USE_X_TOOLKIT */
|
||||
|
|
Loading…
Add table
Reference in a new issue