diff options
author | Karl Heuer <kwzh@gnu.org> | 1994-10-27 18:44:47 +0000 |
---|---|---|
committer | Karl Heuer <kwzh@gnu.org> | 1994-10-27 18:44:47 +0000 |
commit | d77dddb61e3271a412c10bafd7f5d3ae61a70ba7 (patch) | |
tree | c349692a21b1c7260e05b16609aef9202998f808 /src/xmenu.c | |
parent | 5a461ea6ea59a3639215fadc178052ce80a66a94 (diff) | |
download | emacs-d77dddb61e3271a412c10bafd7f5d3ae61a70ba7.tar.gz |
(set_frame_menubar): Don't copy string during GC risk.
Diffstat (limited to 'src/xmenu.c')
-rw-r--r-- | src/xmenu.c | 23 |
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; |