diff options
| author | Paul Eggert | 2014-09-29 19:43:23 -0700 |
|---|---|---|
| committer | Paul Eggert | 2014-09-29 19:43:23 -0700 |
| commit | dc4525691c2c236abdb6c074438223413f80091c (patch) | |
| tree | 86305e7415bcf1b5cc6ddad6879e922f9e5e163c /src/menu.c | |
| parent | a19f0977a96ee74b96410b41a8ea793c86f64b58 (diff) | |
| download | emacs-dc4525691c2c236abdb6c074438223413f80091c.tar.gz emacs-dc4525691c2c236abdb6c074438223413f80091c.zip | |
Simplify stack-allocated Lisp objects, and make them more portable.
The build_local_string macro was used in two ways: (1) string
literals for which scoped allocation suffices, and (2) file name
components, where it's not safe in general to assume bounded-size
ASCII data. Simplify by defining a new macro SCOPED_STRING that
allocates a block-scope string, and by using SCOPED_STRING for (1)
and build_string for (2). Furthermore, actually use stack
allocation only for objects known to have sufficient alignment.
This simpler implementation means Emacs can make
USE_STACK_LISP_OBJECTS the default unless GC_MARK_STACK !=
GC_MAKE_GCPROS_NOOPS.
* lisp.h (GCALIGNED): Align even if !USE_STACK_LISP_OBJECTS,
for fewer differences among implementations.
(struct Lisp_String): Now GCALIGNED.
(USE_STACK_LISP_OBJECTS): Default to true, since the
implementation no longer insists on a nonempty GCALIGNED.
But make it false if GC_MARK_STACK != GC_MAKE_GCPROS_NOOPS.
(SCOPED_CONS_INITIALIZER): Remove, since it's no longer needed
separately. Move definiens to scoped_cons. The old definition
was incorrect when GCALIGNED was defined to be empty.
(union Aligned_String): New type.
(USE_STACK_CONS, USE_STACK_STRING): New constants, so that the
implementation ports to compilers that don't align strictly enough.
Don't worry about the union sizes; it's not worth bothering about.
(scoped_cons, scoped_list1, scoped_list3, scoped_list4):
Rewrite using USE_STACK_CONS.
(scoped_cons): Assume the use of union Aligned_Cons.
(lisp_string_size, make_local_string, build_local_string): Remove.
Unless otherwise specified, all callers of build_local_string
changed to use SCOPED_STRING.
(SCOPED_STRING): New macro.
* data.c (wrong_choice):
* menu.c (single_menu_item):
* process.c (Fformat_network_address):
Hoist use of SCOPED_STRING out of a scope, so that its returned
object lives long enough.
* fileio.c (Fexpand_file_name): Use build_string, not SCOPED_STRING,
as the string might be long or might not be ASCII.
Diffstat (limited to 'src/menu.c')
| -rw-r--r-- | src/menu.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/src/menu.c b/src/menu.c index ea8da7a9d62..e63b21f0e08 100644 --- a/src/menu.c +++ b/src/menu.c | |||
| @@ -354,7 +354,7 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk | |||
| 354 | front of them. */ | 354 | front of them. */ |
| 355 | if (!have_boxes ()) | 355 | if (!have_boxes ()) |
| 356 | { | 356 | { |
| 357 | Lisp_Object prefix = Qnil; | 357 | char const *prefix = 0; |
| 358 | Lisp_Object type = AREF (item_properties, ITEM_PROPERTY_TYPE); | 358 | Lisp_Object type = AREF (item_properties, ITEM_PROPERTY_TYPE); |
| 359 | if (!NILP (type)) | 359 | if (!NILP (type)) |
| 360 | { | 360 | { |
| @@ -390,7 +390,7 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk | |||
| 390 | if (!submenu && SREF (tem, 0) != '\0' | 390 | if (!submenu && SREF (tem, 0) != '\0' |
| 391 | && SREF (tem, 0) != '-') | 391 | && SREF (tem, 0) != '-') |
| 392 | ASET (menu_items, idx + MENU_ITEMS_ITEM_NAME, | 392 | ASET (menu_items, idx + MENU_ITEMS_ITEM_NAME, |
| 393 | concat2 (build_local_string (" "), tem)); | 393 | concat2 (SCOPED_STRING (" "), tem)); |
| 394 | idx += MENU_ITEMS_ITEM_LENGTH; | 394 | idx += MENU_ITEMS_ITEM_LENGTH; |
| 395 | } | 395 | } |
| 396 | } | 396 | } |
| @@ -399,24 +399,24 @@ single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *sk | |||
| 399 | 399 | ||
| 400 | /* Calculate prefix, if any, for this item. */ | 400 | /* Calculate prefix, if any, for this item. */ |
| 401 | if (EQ (type, QCtoggle)) | 401 | if (EQ (type, QCtoggle)) |
| 402 | prefix = build_local_string (NILP (selected) ? "[ ] " : "[X] "); | 402 | prefix = NILP (selected) ? "[ ] " : "[X] "; |
| 403 | else if (EQ (type, QCradio)) | 403 | else if (EQ (type, QCradio)) |
| 404 | prefix = build_local_string (NILP (selected) ? "( ) " : "(*) "); | 404 | prefix = NILP (selected) ? "( ) " : "(*) "; |
| 405 | } | 405 | } |
| 406 | /* Not a button. If we have earlier buttons, then we need a prefix. */ | 406 | /* Not a button. If we have earlier buttons, then we need a prefix. */ |
| 407 | else if (!skp->notbuttons && SREF (item_string, 0) != '\0' | 407 | else if (!skp->notbuttons && SREF (item_string, 0) != '\0' |
| 408 | && SREF (item_string, 0) != '-') | 408 | && SREF (item_string, 0) != '-') |
| 409 | prefix = build_local_string (" "); | 409 | prefix = " "; |
| 410 | 410 | ||
| 411 | if (!NILP (prefix)) | 411 | if (prefix) |
| 412 | item_string = concat2 (prefix, item_string); | 412 | item_string = concat2 (SCOPED_STRING (prefix), item_string); |
| 413 | } | 413 | } |
| 414 | 414 | ||
| 415 | if ((FRAME_TERMCAP_P (XFRAME (Vmenu_updating_frame)) | 415 | if ((FRAME_TERMCAP_P (XFRAME (Vmenu_updating_frame)) |
| 416 | || FRAME_MSDOS_P (XFRAME (Vmenu_updating_frame))) | 416 | || FRAME_MSDOS_P (XFRAME (Vmenu_updating_frame))) |
| 417 | && !NILP (map)) | 417 | && !NILP (map)) |
| 418 | /* Indicate visually that this is a submenu. */ | 418 | /* Indicate visually that this is a submenu. */ |
| 419 | item_string = concat2 (item_string, build_local_string (" >")); | 419 | item_string = concat2 (item_string, SCOPED_STRING (" >")); |
| 420 | 420 | ||
| 421 | push_menu_item (item_string, enabled, key, | 421 | push_menu_item (item_string, enabled, key, |
| 422 | AREF (item_properties, ITEM_PROPERTY_DEF), | 422 | AREF (item_properties, ITEM_PROPERTY_DEF), |