summaryrefslogtreecommitdiff
path: root/src/xmenu.c
diff options
context:
space:
mode:
authorKarl Heuer <kwzh@gnu.org>1994-10-27 18:44:47 +0000
committerKarl Heuer <kwzh@gnu.org>1994-10-27 18:44:47 +0000
commitd77dddb61e3271a412c10bafd7f5d3ae61a70ba7 (patch)
treec349692a21b1c7260e05b16609aef9202998f808 /src/xmenu.c
parent5a461ea6ea59a3639215fadc178052ce80a66a94 (diff)
downloademacs-d77dddb61e3271a412c10bafd7f5d3ae61a70ba7.tar.gz
(set_frame_menubar): Don't copy string during GC risk.
Diffstat (limited to 'src/xmenu.c')
-rw-r--r--src/xmenu.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/src/xmenu.c b/src/xmenu.c
index 138f0484aa3..fffcdc4626e 100644
--- a/src/xmenu.c
+++ b/src/xmenu.c
@@ -1377,7 +1377,7 @@ set_frame_menubar (f, first_time)
Widget menubar_widget = f->display.x->menubar_widget;
int id = (int) f;
Lisp_Object tail, items;
- widget_value *wv, *save_wv, *first_wv, *prev_wv = 0;
+ widget_value *wv, *first_wv, *prev_wv = 0;
int i;
BLOCK_INPUT;
@@ -1386,7 +1386,7 @@ set_frame_menubar (f, first_time)
wv->name = "menubar";
wv->value = 0;
wv->enabled = 1;
- save_wv = first_wv = wv;
+ first_wv = wv;
items = FRAME_MENU_BAR_ITEMS (f);
menu_items = f->menu_bar_vector;
menu_items_allocated = XVECTOR (menu_items)->size;
@@ -1405,13 +1405,26 @@ set_frame_menubar (f, first_time)
wv = single_submenu (key, string, maps);
if (prev_wv)
prev_wv->next = wv;
- else
- save_wv->contents = wv;
- wv->name = (char *) XSTRING (string)->data;
+ else
+ first_wv->contents = wv;
+ /* Don't set wv->name here; GC during the loop might relocate it. */
wv->enabled = 1;
prev_wv = wv;
}
+ /* Now GC cannot happen during the lifetime of the widget_value,
+ so it's safe to store data from a Lisp_String. */
+ wv = first_wv->contents;
+ for (i = 0; i < XVECTOR (items)->size; i += 3)
+ {
+ Lisp_Object string;
+ string = XVECTOR (items)->contents[i + 1];
+ if (NILP (string))
+ break;
+ wv->name = (char *) XSTRING (string)->data;
+ wv = wv->next;
+ }
+
finish_menu_items ();
f->menu_bar_vector = menu_items;