------------------------------------------------------------ revno: 117944 committer: martin rudalics branch nick: trunk timestamp: Thu 2014-09-25 09:01:35 +0200 message: Remove code left dead after 2014-07-27 changes. * frame.c (frame_inhibit_resize): * widget.c (EmacsFrameResize): * window.c (resize_frame_windows, Fset_window_configuration): * xdisp.c (expose_frame): * xfns.c (x_change_tool_bar_height): * xmenu.c (update_frame_menubar): * xterm.c (handle_one_xevent, x_new_font, x_set_window_size_1): Remove code left dead after 2014-07-27 changes. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-25 02:01:14 +0000 +++ src/ChangeLog 2014-09-25 07:01:35 +0000 @@ -1,3 +1,14 @@ +2014-09-25 Martin Rudalics + + * frame.c (frame_inhibit_resize): + * widget.c (EmacsFrameResize): + * window.c (resize_frame_windows, Fset_window_configuration): + * xdisp.c (expose_frame): + * xfns.c (x_change_tool_bar_height): + * xmenu.c (update_frame_menubar): + * xterm.c (handle_one_xevent, x_new_font, x_set_window_size_1): + Remove code left dead after 2014-07-27 changes. + 2014-09-25 Paul Eggert Fix local_cons etc. to not exhaust the stack when in a loop. === modified file 'src/frame.c' --- src/frame.c 2014-09-25 02:01:14 +0000 +++ src/frame.c 2014-09-25 07:01:35 +0000 @@ -219,21 +219,6 @@ || FRAME_TERMCAP_P (f) || FRAME_MSDOS_P (f)); } -#if 0 -bool -frame_inhibit_resize (struct frame *f, bool horizontal) -{ - Lisp_Object fullscreen = get_frame_param (f, Qfullscreen); - - return (frame_inhibit_implied_resize - || EQ (fullscreen, Qfullboth) - || EQ (fullscreen, Qfullscreen) - || EQ (fullscreen, Qmaximized) - || (horizontal && EQ (fullscreen, Qfullwidth)) - || (!horizontal && EQ (fullscreen, Qfullheight))); -} -#endif - static void set_menu_bar_lines (struct frame *f, Lisp_Object value, Lisp_Object oldval) { === modified file 'src/widget.c' --- src/widget.c 2014-08-09 09:06:25 +0000 +++ src/widget.c 2014-09-25 07:01:35 +0000 @@ -579,15 +579,6 @@ if (true || frame_resize_pixelwise) { int width, height; -/** int width = (ew->core.width **/ -/** - FRAME_SCROLL_BAR_AREA_WIDTH (f) **/ -/** - FRAME_TOTAL_FRINGE_WIDTH (f) **/ -/** - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/ - -/** int height = (ew->core.height **/ -/** - FRAME_TOOLBAR_HEIGHT (f) **/ -/** - FRAME_SCROLL_BAR_AREA_HEIGHT (f) **/ -/** - 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/ pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height); change_frame_size (f, width, height, 0, 1, 0, 1); === modified file 'src/window.c' --- src/window.c 2014-09-15 00:20:21 +0000 +++ src/window.c 2014-09-25 07:01:35 +0000 @@ -4163,7 +4163,6 @@ new_pixel_size = max (horflag ? size : (size -/** - FRAME_TOP_MARGIN_HEIGHT (f) **/ - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) ? FRAME_LINE_HEIGHT (f) : 0)), @@ -4175,7 +4174,6 @@ new_size = max (horflag ? size : (size -/** - FRAME_TOP_MARGIN (f) **/ - ((FRAME_HAS_MINIBUF_P (f) && !FRAME_MINIBUF_ONLY_P (f)) ? 1 : 0)), @@ -6462,420 +6460,6 @@ } -#if 0 -DEFUN ("set-window-configuration", Fset_window_configuration, - Sset_window_configuration, 1, 1, 0, - doc: /* Set the configuration of windows and buffers as specified by CONFIGURATION. -CONFIGURATION must be a value previously returned -by `current-window-configuration' (which see). -If CONFIGURATION was made from a frame that is now deleted, -only frame-independent values can be restored. In this case, -the return value is nil. Otherwise the value is t. */) - (Lisp_Object configuration) -{ - register struct save_window_data *data; - struct Lisp_Vector *saved_windows; - Lisp_Object new_current_buffer; - Lisp_Object frame; - struct frame *f; - ptrdiff_t old_point = -1; - - CHECK_WINDOW_CONFIGURATION (configuration); - - data = (struct save_window_data *) XVECTOR (configuration); - saved_windows = XVECTOR (data->saved_windows); - - new_current_buffer = data->current_buffer; - if (!BUFFER_LIVE_P (XBUFFER (new_current_buffer))) - new_current_buffer = Qnil; - else - { - if (XBUFFER (new_current_buffer) == current_buffer) - /* The code further down "preserves point" by saving here PT in - old_point and then setting it later back into PT. When the - current-selected-window and the final-selected-window both show - the current buffer, this suffers from the problem that the - current PT is the window-point of the current-selected-window, - while the final PT is the point of the final-selected-window, so - this copy from one PT to the other would end up moving the - window-point of the final-selected-window to the window-point of - the current-selected-window. So we have to be careful which - point of the current-buffer we copy into old_point. */ - if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer) - && WINDOWP (selected_window) - && EQ (XWINDOW (selected_window)->contents, new_current_buffer) - && !EQ (selected_window, data->current_window)) - old_point = marker_position (XWINDOW (data->current_window)->pointm); - else - old_point = PT; - else - /* BUF_PT (XBUFFER (new_current_buffer)) gives us the position of - point in new_current_buffer as of the last time this buffer was - used. This can be non-deterministic since it can be changed by - things like jit-lock by mere temporary selection of some random - window that happens to show this buffer. - So if possible we want this arbitrary choice of "which point" to - be the one from the to-be-selected-window so as to prevent this - window's cursor from being copied from another window. */ - if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer) - /* If current_window = selected_window, its point is in BUF_PT. */ - && !EQ (selected_window, data->current_window)) - old_point = marker_position (XWINDOW (data->current_window)->pointm); - else - old_point = BUF_PT (XBUFFER (new_current_buffer)); - } - - frame = XWINDOW (SAVED_WINDOW_N (saved_windows, 0)->window)->frame; - f = XFRAME (frame); - - /* If f is a dead frame, don't bother rebuilding its window tree. - However, there is other stuff we should still try to do below. */ - if (FRAME_LIVE_P (f)) - { - Lisp_Object window; - Lisp_Object dead_windows = Qnil; - register Lisp_Object tem, par, pers; - register struct window *w; - register struct saved_window *p; - struct window *root_window; - struct window **leaf_windows; - int n_leaf_windows; - ptrdiff_t k; - int i, n; - ptrdiff_t count = SPECPDL_INDEX (); - /* If the frame has been resized since this window configuration was - made, we change the frame to the size specified in the - configuration, restore the configuration, and then resize it - back. We keep track of the prevailing height in these variables. */ - int previous_frame_text_height = FRAME_TEXT_HEIGHT (f); - int previous_frame_text_width = FRAME_TEXT_WIDTH (f); - /* int previous_frame_menu_bar_height = FRAME_MENU_BAR_HEIGHT (f); */ - /* int previous_frame_tool_bar_height = FRAME_TOOL_BAR_HEIGHT (f); */ - /* int previous_frame_lines = FRAME_LINES (f); */ - /* int previous_frame_cols = FRAME_COLS (f); */ - int previous_frame_menu_bar_lines = FRAME_MENU_BAR_LINES (f); - int previous_frame_tool_bar_lines = FRAME_TOOL_BAR_LINES (f); - - /* Don't do this within the main loop below: This may call Lisp - code and is thus potentially unsafe while input is blocked. */ - for (k = 0; k < saved_windows->header.size; k++) - { - p = SAVED_WINDOW_N (saved_windows, k); - window = p->window; - w = XWINDOW (window); - if (BUFFERP (w->contents) - && !EQ (w->contents, p->buffer) - && BUFFER_LIVE_P (XBUFFER (p->buffer))) - /* If a window we restore gets another buffer, record the - window's old buffer. */ - call1 (Qrecord_window_buffer, window); - } - - /* Consider frame unofficial, temporarily. */ - f->official = false; - /* The mouse highlighting code could get screwed up - if it runs during this. */ - block_input (); - - if (data->frame_text_width != previous_frame_text_width - || data->frame_text_height != previous_frame_text_height) - /* Make frame size fit the one in data, so window sizes restored - from data match those of the frame. */ - adjust_frame_size (f, data->frame_text_width, - data->frame_text_height, 5, 0); - - if (data->frame_menu_bar_lines != previous_frame_menu_bar_lines) - { -#ifdef HAVE_WINDOW_SYSTEM - if (FRAME_WINDOW_P (f)) - x_set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines), - make_number (0)); - else /* TTY or MSDOS */ -#endif - set_menu_bar_lines (f, make_number (data->frame_menu_bar_lines), - make_number (0)); - } -#ifdef HAVE_WINDOW_SYSTEM - if (data->frame_tool_bar_lines != previous_frame_tool_bar_lines) - x_set_tool_bar_lines (f, make_number (data->frame_tool_bar_lines), - make_number (0)); -#endif - - /* "Swap out" point from the selected window's buffer - into the window itself. (Normally the pointm of the selected - window holds garbage.) We do this now, before - restoring the window contents, and prevent it from - being done later on when we select a new window. */ - if (! NILP (XWINDOW (selected_window)->contents)) - { - w = XWINDOW (selected_window); - set_marker_both (w->pointm, - w->contents, - BUF_PT (XBUFFER (w->contents)), - BUF_PT_BYTE (XBUFFER (w->contents))); - } - - fset_redisplay (f); - FRAME_WINDOW_SIZES_CHANGED (f) = 1; - - /* Problem: Freeing all matrices and later allocating them again - is a serious redisplay flickering problem. What we would - 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); - n_leaf_windows = get_leaf_windows (root_window, leaf_windows, 0); - - /* Kludge Alert! - Mark all windows now on frame as "deleted". - Restoring the new configuration "undeletes" any that are in it. - - Save their current buffers in their height fields, since we may - need it later, if a buffer saved in the configuration is now - dead. */ - delete_all_child_windows (FRAME_ROOT_WINDOW (f)); - - for (k = 0; k < saved_windows->header.size; k++) - { - p = SAVED_WINDOW_N (saved_windows, k); - window = p->window; - w = XWINDOW (window); - wset_next (w, Qnil); - - if (!NILP (p->parent)) - wset_parent - (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->parent))->window); - else - wset_parent (w, Qnil); - - if (!NILP (p->prev)) - { - wset_prev - (w, SAVED_WINDOW_N (saved_windows, XFASTINT (p->prev))->window); - wset_next (XWINDOW (w->prev), p->window); - } - else - { - wset_prev (w, Qnil); - if (!NILP (w->parent)) - wset_combination (XWINDOW (w->parent), - (XINT (p->total_cols) - != XWINDOW (w->parent)->total_cols), - p->window); - } - - /* If we squirreled away the buffer, restore it now. */ - if (BUFFERP (w->combination_limit)) - wset_buffer (w, w->combination_limit); - w->pixel_left = XFASTINT (p->pixel_left); - w->pixel_top = XFASTINT (p->pixel_top); - w->pixel_width = XFASTINT (p->pixel_width); - w->pixel_height = XFASTINT (p->pixel_height); - w->left_col = XFASTINT (p->left_col); - w->top_line = XFASTINT (p->top_line); - w->total_cols = XFASTINT (p->total_cols); - w->total_lines = XFASTINT (p->total_lines); - wset_normal_cols (w, p->normal_cols); - wset_normal_lines (w, p->normal_lines); - w->hscroll = XFASTINT (p->hscroll); - w->suspend_auto_hscroll = !NILP (p->suspend_auto_hscroll); - w->min_hscroll = XFASTINT (p->min_hscroll); - w->hscroll_whole = XFASTINT (p->hscroll_whole); - wset_display_table (w, p->display_table); - w->left_margin_cols = XINT (p->left_margin_cols); - w->right_margin_cols = XINT (p->right_margin_cols); - w->left_fringe_width = XINT (p->left_fringe_width); - w->right_fringe_width = XINT (p->right_fringe_width); - w->fringes_outside_margins = !NILP (p->fringes_outside_margins); - w->scroll_bar_width = XINT (p->scroll_bar_width); - w->scroll_bar_height = XINT (p->scroll_bar_height); - wset_vertical_scroll_bar_type (w, p->vertical_scroll_bar_type); - wset_horizontal_scroll_bar_type (w, p->horizontal_scroll_bar_type); - wset_dedicated (w, p->dedicated); - wset_combination_limit (w, p->combination_limit); - /* Restore any window parameters that have been saved. - Parameters that have not been saved are left alone. */ - for (tem = p->window_parameters; CONSP (tem); tem = XCDR (tem)) - { - pers = XCAR (tem); - if (CONSP (pers)) - { - if (NILP (XCDR (pers))) - { - par = Fassq (XCAR (pers), w->window_parameters); - if (CONSP (par) && !NILP (XCDR (par))) - /* Reset a parameter to nil if and only if it - has a non-nil association. Don't make new - associations. */ - Fsetcdr (par, Qnil); - } - else - /* Always restore a non-nil value. */ - Fset_window_parameter (window, XCAR (pers), XCDR (pers)); - } - } - - if (BUFFERP (p->buffer) && BUFFER_LIVE_P (XBUFFER (p->buffer))) - /* If saved buffer is alive, install it. */ - { - wset_buffer (w, p->buffer); - w->start_at_line_beg = !NILP (p->start_at_line_beg); - set_marker_restricted (w->start, p->start, w->contents); - set_marker_restricted (w->pointm, p->pointm, w->contents); - set_marker_restricted (w->old_pointm, p->old_pointm, w->contents); - /* As documented in Fcurrent_window_configuration, don't - restore the location of point in the buffer which was - current when the window configuration was recorded. */ - if (!EQ (p->buffer, new_current_buffer) - && XBUFFER (p->buffer) == current_buffer) - Fgoto_char (w->pointm); - } - else if (BUFFERP (w->contents) && BUFFER_LIVE_P (XBUFFER (w->contents))) - /* Keep window's old buffer; make sure the markers are real. */ - { - /* Set window markers at start of visible range. */ - if (XMARKER (w->start)->buffer == 0) - set_marker_restricted_both (w->start, w->contents, 0, 0); - if (XMARKER (w->pointm)->buffer == 0) - set_marker_restricted_both - (w->pointm, w->contents, - BUF_PT (XBUFFER (w->contents)), - BUF_PT_BYTE (XBUFFER (w->contents))); - if (XMARKER (w->old_pointm)->buffer == 0) - set_marker_restricted_both - (w->old_pointm, w->contents, - BUF_PT (XBUFFER (w->contents)), - BUF_PT_BYTE (XBUFFER (w->contents))); - w->start_at_line_beg = 1; - } - else if (!NILP (w->start)) - /* Leaf window has no live buffer, get one. */ - { - /* Get the buffer via other_buffer_safely in order to - avoid showing an unimportant buffer and, if necessary, to - recreate *scratch* in the course (part of Juanma's bs-show - scenario from March 2011). */ - wset_buffer (w, other_buffer_safely (Fcurrent_buffer ())); - /* This will set the markers to beginning of visible - range. */ - set_marker_restricted_both (w->start, w->contents, 0, 0); - set_marker_restricted_both (w->pointm, w->contents, 0, 0); - set_marker_restricted_both (w->old_pointm, w->contents, 0, 0); - w->start_at_line_beg = 1; - if (!NILP (w->dedicated)) - /* Record this window as dead. */ - dead_windows = Fcons (window, dead_windows); - /* Make sure window is no more dedicated. */ - wset_dedicated (w, Qnil); - } - } - - fset_root_window (f, data->root_window); - /* Arrange *not* to restore point in the buffer that was - current when the window configuration was saved. */ - if (EQ (XWINDOW (data->current_window)->contents, new_current_buffer)) - set_marker_restricted (XWINDOW (data->current_window)->pointm, - make_number (old_point), - XWINDOW (data->current_window)->contents); - - /* In the following call to `select-window', prevent "swapping out - point" in the old selected window using the buffer that has - been restored into it. We already swapped out that point from - that window's old buffer. - - Do not record the buffer here. We do that in a separate call - to select_window below. See also Bug#16207. */ - select_window (data->current_window, Qt, 1); - BVAR (XBUFFER (XWINDOW (selected_window)->contents), - last_selected_window) - = selected_window; - - if (NILP (data->focus_frame) - || (FRAMEP (data->focus_frame) - && FRAME_LIVE_P (XFRAME (data->focus_frame)))) - Fredirect_frame_focus (frame, data->focus_frame); - - /* Set the frame size to the value it had before this function. */ - if (previous_frame_text_width != FRAME_TEXT_WIDTH (f) - || previous_frame_text_height != FRAME_TEXT_HEIGHT (f)) - adjust_frame_size (f, previous_frame_text_width, - previous_frame_text_height, 5, 0); - - if (previous_frame_menu_bar_lines != FRAME_MENU_BAR_LINES (f)) - { -#ifdef HAVE_WINDOW_SYSTEM - if (FRAME_WINDOW_P (f)) - x_set_menu_bar_lines (f, - make_number (previous_frame_menu_bar_lines), - make_number (0)); - else /* TTY or MSDOS */ -#endif - set_menu_bar_lines (f, make_number (previous_frame_menu_bar_lines), - make_number (0)); - } -#ifdef HAVE_WINDOW_SYSTEM - if (previous_frame_tool_bar_lines != FRAME_TOOL_BAR_LINES (f)) - x_set_tool_bar_lines (f, make_number (previous_frame_tool_bar_lines), - make_number (0)); -#endif - - /* Now, free glyph matrices in windows that were not reused. */ - for (i = n = 0; i < n_leaf_windows; ++i) - { - if (NILP (leaf_windows[i]->contents)) - free_window_matrices (leaf_windows[i]); - else if (EQ (leaf_windows[i]->contents, new_current_buffer)) - ++n; - } - - /* Make frame official again and apply frame size changes if - needed. */ - f->official = true; - adjust_frame_size (f, -1, -1, 1, 0); - - adjust_frame_glyphs (f); - unblock_input (); - - /* Scan dead buffer windows. */ - for (; CONSP (dead_windows); dead_windows = XCDR (dead_windows)) - { - window = XCAR (dead_windows); - if (WINDOW_LIVE_P (window) && !EQ (window, FRAME_ROOT_WINDOW (f))) - delete_deletable_window (window); - } - - /* Record the selected window's buffer here. The window should - already be the selected one from the call above. */ - select_window (data->current_window, Qnil, 0); - - /* Fselect_window will have made f the selected frame, so we - reselect the proper frame here. Fhandle_switch_frame will change the - selected window too, but that doesn't make the call to - Fselect_window above totally superfluous; it still sets f's - selected window. */ - if (FRAME_LIVE_P (XFRAME (data->selected_frame))) - do_switch_frame (data->selected_frame, 0, 0, Qnil); - - run_window_configuration_change_hook (f); - } - - if (!NILP (new_current_buffer)) - { - Fset_buffer (new_current_buffer); - /* If the new current buffer doesn't appear in the selected - window, go to its old point (see bug#12208). */ - if (!EQ (XWINDOW (data->current_window)->contents, new_current_buffer)) - Fgoto_char (make_number (old_point)); - } - - Vminibuf_scroll_window = data->minibuf_scroll_window; - minibuf_selected_window = data->minibuf_selected_window; - - return (FRAME_LIVE_P (f) ? Qt : Qnil); -} -#endif - void restore_window_configuration (Lisp_Object configuration) { === modified file 'src/xdisp.c' --- src/xdisp.c 2014-09-25 02:01:14 +0000 +++ src/xdisp.c 2014-09-25 07:01:35 +0000 @@ -30145,8 +30145,6 @@ r.x = r.y = 0; r.width = FRAME_TEXT_WIDTH (f); r.height = FRAME_TEXT_HEIGHT (f); -/** r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f); **/ -/** r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f); **/ } else { === modified file 'src/xfns.c' --- src/xfns.c 2014-09-25 02:01:14 +0000 +++ src/xfns.c 2014-09-25 07:01:35 +0000 @@ -1140,10 +1140,8 @@ adjust_frame_size (f, -1, -1, 4, 0); -/** #if !defined USE_X_TOOLKIT **/ if (FRAME_X_WINDOW (f)) x_clear_under_internal_border (f); -/** #endif **/ #endif /* USE_GTK */ } === modified file 'src/xmenu.c' --- src/xmenu.c 2014-09-07 07:04:01 +0000 +++ src/xmenu.c 2014-09-25 07:01:35 +0000 @@ -627,7 +627,6 @@ xg_update_frame_menubar (f); #else struct x_output *x; -/** int columns, rows; **/ eassert (FRAME_X_P (f)); @@ -637,10 +636,6 @@ return; block_input (); - /* Save the size of the frame because the pane widget doesn't accept - to resize itself. So force it. */ -/** columns = FRAME_COLS (f); **/ -/** rows = FRAME_LINES (f); **/ /* Do the voodoo which means "I'm changing lots of things, don't try to refigure sizes until I'm done." */ @@ -661,8 +656,7 @@ XtManageChild (x->edit_widget); lw_refigure_widget (x->column_widget, True); - /* Force the pane widget to resize itself with the right values. */ -/** EmacsFrameSetCharSize (x->edit_widget, columns, rows); **/ + /* Force the pane widget to resize itself. */ adjust_frame_size (f, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f), 2, 0); unblock_input (); #endif === modified file 'src/xterm.c' --- src/xterm.c 2014-09-25 02:01:14 +0000 +++ src/xterm.c 2014-09-25 07:01:35 +0000 @@ -7560,9 +7560,6 @@ SET_FRAME_GARBAGED (f); cancel_mouse_face (f); } - -/** FRAME_PIXEL_WIDTH (f) = event->xconfigure.width; **/ -/** FRAME_PIXEL_HEIGHT (f) = event->xconfigure.height; **/ #endif /* not USE_GTK */ #endif @@ -8647,7 +8644,6 @@ FRAME_LINE_HEIGHT (f) = FONT_HEIGHT (font); #ifndef USE_X_TOOLKIT \ -/** FRAME_TOOL_BAR_HEIGHT (f) = FRAME_TOOL_BAR_LINES (f) * FRAME_LINE_HEIGHT (f); **/ FRAME_MENU_BAR_HEIGHT (f) = FRAME_MENU_BAR_LINES (f) * FRAME_LINE_HEIGHT (f); #endif @@ -9490,18 +9486,6 @@ { int pixelwidth, pixelheight; -/** if (pixelwise) **/ -/** { **/ -/** pixelwidth = FRAME_TEXT_TO_PIXEL_WIDTH (f, width); **/ -/** pixelheight = FRAME_TEXT_TO_PIXEL_HEIGHT (f, height); **/ -/** } **/ -/** else **/ -/** { **/ -/** pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width); **/ -/** pixelheight = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height); **/ -/** } **/ - -/** FRAME_TOOL_BAR_HEIGHT (f) = FRAME_TOOLBAR_HEIGHT (f); **/ pixelwidth = (pixelwise ? FRAME_TEXT_TO_PIXEL_WIDTH (f, width) : FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width)); @@ -9509,16 +9493,6 @@ ? FRAME_TEXT_TO_PIXEL_HEIGHT (f, height) : FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height))); -/** pixelwidth = ((pixelwise ? width : (width * FRAME_COLUMN_WIDTH (f))) **/ -/** + FRAME_SCROLL_BAR_AREA_WIDTH (f) **/ -/** + FRAME_TOTAL_FRINGE_WIDTH (f) **/ -/** + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/ - -/** pixelheight = ((pixelwise ? height : (height * FRAME_LINE_HEIGHT (f))) **/ -/** + FRAME_TOOLBAR_HEIGHT (f) **/ -/** + FRAME_SCROLL_BAR_AREA_HEIGHT (f) **/ -/** + 2 * FRAME_INTERNAL_BORDER_WIDTH (f)); **/ - if (change_gravity) f->win_gravity = NorthWestGravity; x_wm_set_size_hint (f, 0, 0); XResizeWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f), ------------------------------------------------------------ revno: 117943 committer: Paul Eggert branch nick: trunk timestamp: Wed 2014-09-24 19:59:45 -0700 message: * configure.ac (MAKEINFO): Allow 'makeinfo' to be called 'texi2any'. diff: === modified file 'ChangeLog' --- ChangeLog 2014-09-23 18:20:38 +0000 +++ ChangeLog 2014-09-25 02:59:45 +0000 @@ -1,3 +1,7 @@ +2014-09-25 Paul Eggert + + * configure.ac (MAKEINFO): Allow 'makeinfo' to be called 'texi2any'. + 2014-09-23 Paul Eggert Merge from gnulib, incorporating: === modified file 'configure.ac' --- configure.ac 2014-09-22 19:20:45 +0000 +++ configure.ac 2014-09-25 02:59:45 +0000 @@ -1103,10 +1103,10 @@ MAKEINFO=makeinfo fi case `($MAKEINFO --version) 2>/dev/null` in - 'makeinfo (GNU texinfo) '4.[[7-9]]* | \ - 'makeinfo (GNU texinfo) '4.[[1-9][0-9]]* | \ - 'makeinfo (GNU texinfo) '[[5-9]]* | \ - 'makeinfo (GNU texinfo) '[[1-9][0-9]]* ) ;; + *' (GNU texinfo) '4.[[7-9]]* | \ + *' (GNU texinfo) '4.[[1-9][0-9]]* | \ + *' (GNU texinfo) '[[5-9]]* | \ + *' (GNU texinfo) '[[1-9][0-9]]* ) ;; *) MAKEINFO=no;; esac fi ------------------------------------------------------------ revno: 117942 committer: Paul Eggert branch nick: trunk timestamp: Wed 2014-09-24 19:01:14 -0700 message: Fix local_cons etc. to not exhaust the stack when in a loop. Problem reported in: http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00696.html * buffer.c (Fother_buffer, other_buffer_safely, init_buffer): * charset.c (load_charset_map_from_file, Ffind_charset_region) (Ffind_charset_string): * chartab.c (uniprop_encode_value_numeric, uniprop_table): * data.c (wrong_range): * editfns.c (Fpropertize, format2): * emacs.c (init_cmdargs, decode_env_path): * fileio.c (auto_save_error): * fns.c (Fyes_or_no_p): * font.c (font_style_to_value, font_parse_xlfd) (font_parse_family_registry, font_delete_unmatched) (font_add_log): * fontset.c (Fset_fontset_font): * frame.c (x_get_arg): * keyboard.c (echo_dash, safe_run_hooks_error, parse_menu_item) (read_char_minibuf_menu_prompt): * keymap.c (silly_event_symbol_error, describe_vector): * lread.c (load_warn_old_style_backquotes): * menu.c (single_menu_item): * minibuf.c (Fread_buffer): * process.c (status_message, Fformat_network_address) (server_accept_connection): * textprop.c (copy_text_properties): * xdisp.c (Fcurrent_bidi_paragraph_direction): * xfns.c (x_default_scroll_bar_color_parameter): * xfont.c (xfont_open): * xselect.c (x_clipboard_manager_error_1): * xterm.c (x_term_init): Put USE_LOCAL_ALLOCA at the start of the function. * fns.c (maybe_resize_hash_table): Use build_string instead of build_local_string, since we'd otherwise need a conditional USE_LOCAL_ALLOCA here, but this is just debugging output and is not worth the bother of optimization. * font.c (font_delete_unmatched): Remove by-hand code that observed MAX_ALLOCA limit, since it's now done automatically. * keymap.c (Fsingle_key_description): Put USE_SAFE_ALLOCA at top, since build_local_string needs its sa_alloc. * lisp.h (lisp_word_count): New function. (SAFE_ALLOCA_LISP): Use it. (USE_LOCAL_ALLOCA): New macro. (local_cons, make_local_vector, make_local_string): Observe the MAX_ALLOCA limit. (LISP_STRING_OVERHEAD): New constant. (make_local_string): Use it. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-24 20:54:25 +0000 +++ src/ChangeLog 2014-09-25 02:01:14 +0000 @@ -1,3 +1,53 @@ +2014-09-25 Paul Eggert + + Fix local_cons etc. to not exhaust the stack when in a loop. + Problem reported in: + http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00696.html + * buffer.c (Fother_buffer, other_buffer_safely, init_buffer): + * charset.c (load_charset_map_from_file, Ffind_charset_region) + (Ffind_charset_string): + * chartab.c (uniprop_encode_value_numeric, uniprop_table): + * data.c (wrong_range): + * editfns.c (Fpropertize, format2): + * emacs.c (init_cmdargs, decode_env_path): + * fileio.c (auto_save_error): + * fns.c (Fyes_or_no_p): + * font.c (font_style_to_value, font_parse_xlfd) + (font_parse_family_registry, font_delete_unmatched) + (font_add_log): + * fontset.c (Fset_fontset_font): + * frame.c (x_get_arg): + * keyboard.c (echo_dash, safe_run_hooks_error, parse_menu_item) + (read_char_minibuf_menu_prompt): + * keymap.c (silly_event_symbol_error, describe_vector): + * lread.c (load_warn_old_style_backquotes): + * menu.c (single_menu_item): + * minibuf.c (Fread_buffer): + * process.c (status_message, Fformat_network_address) + (server_accept_connection): + * textprop.c (copy_text_properties): + * xdisp.c (Fcurrent_bidi_paragraph_direction): + * xfns.c (x_default_scroll_bar_color_parameter): + * xfont.c (xfont_open): + * xselect.c (x_clipboard_manager_error_1): + * xterm.c (x_term_init): + Put USE_LOCAL_ALLOCA at the start of the function. + * fns.c (maybe_resize_hash_table): Use build_string instead of + build_local_string, since we'd otherwise need a conditional + USE_LOCAL_ALLOCA here, but this is just debugging output and is + not worth the bother of optimization. + * font.c (font_delete_unmatched): Remove by-hand code that + observed MAX_ALLOCA limit, since it's now done automatically. + * keymap.c (Fsingle_key_description): Put USE_SAFE_ALLOCA at top, + since build_local_string needs its sa_alloc. + * lisp.h (lisp_word_count): New function. + (SAFE_ALLOCA_LISP): Use it. + (USE_LOCAL_ALLOCA): New macro. + (local_cons, make_local_vector, make_local_string): + Observe the MAX_ALLOCA limit. + (LISP_STRING_OVERHEAD): New constant. + (make_local_string): Use it. + 2014-09-24 Paul Eggert Default to stack objects on non-GNU/Linux, non-DOS_NT platforms. === modified file 'src/buffer.c' --- src/buffer.c 2014-09-17 15:34:37 +0000 +++ src/buffer.c 2014-09-25 02:01:14 +0000 @@ -1509,8 +1509,9 @@ The buffer is found by scanning the selected or specified frame's buffer list first, followed by the list of all buffers. If no other buffer exists, return the buffer `*scratch*' (creating it if necessary). */) - (register Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame) + (Lisp_Object buffer, Lisp_Object visible_ok, Lisp_Object frame) { + USE_LOCAL_ALLOCA; struct frame *f = decode_any_frame (frame); Lisp_Object tail = f->buffer_list, pred = f->buffer_predicate; Lisp_Object buf, notsogood = Qnil; @@ -1569,6 +1570,7 @@ Lisp_Object other_buffer_safely (Lisp_Object buffer) { + USE_LOCAL_ALLOCA; Lisp_Object tail, buf; FOR_EACH_LIVE_BUFFER (tail, buf) @@ -5238,6 +5240,7 @@ void init_buffer (int initialized) { + USE_LOCAL_ALLOCA; char *pwd; Lisp_Object temp; ptrdiff_t len; === modified file 'src/charset.c' --- src/charset.c 2014-09-16 08:20:08 +0000 +++ src/charset.c 2014-09-25 02:01:14 +0000 @@ -481,6 +481,7 @@ load_charset_map_from_file (struct charset *charset, Lisp_Object mapfile, int control_flag) { + USE_LOCAL_ALLOCA; unsigned min_code = CHARSET_MIN_CODE (charset); unsigned max_code = CHARSET_MAX_CODE (charset); int fd; @@ -1550,6 +1551,7 @@ only `ascii', `eight-bit-control', and `eight-bit-graphic'. */) (Lisp_Object beg, Lisp_Object end, Lisp_Object table) { + USE_LOCAL_ALLOCA; Lisp_Object charsets; ptrdiff_t from, from_byte, to, stop, stop_byte; int i; @@ -1601,6 +1603,7 @@ only `ascii', `eight-bit-control', and `eight-bit-graphic'. */) (Lisp_Object str, Lisp_Object table) { + USE_LOCAL_ALLOCA; Lisp_Object charsets; int i; Lisp_Object val; === modified file 'src/chartab.c' --- src/chartab.c 2014-09-24 11:11:14 +0000 +++ src/chartab.c 2014-09-25 02:01:14 +0000 @@ -1249,6 +1249,7 @@ static Lisp_Object uniprop_encode_value_numeric (Lisp_Object table, Lisp_Object value) { + USE_LOCAL_ALLOCA; Lisp_Object *value_table = XVECTOR (XCHAR_TABLE (table)->extras[4])->contents; int i, size = ASIZE (XCHAR_TABLE (table)->extras[4]); @@ -1292,6 +1293,7 @@ Lisp_Object uniprop_table (Lisp_Object prop) { + USE_LOCAL_ALLOCA; Lisp_Object val, table, result; val = Fassq (prop, Vchar_code_property_alist); === modified file 'src/data.c' --- src/data.c 2014-09-22 19:20:45 +0000 +++ src/data.c 2014-09-25 02:01:14 +0000 @@ -1004,6 +1004,7 @@ static void wrong_range (Lisp_Object min, Lisp_Object max, Lisp_Object wrong) { + USE_LOCAL_ALLOCA; xsignal2 (Qerror, Fconcat (4, ((Lisp_Object []) { build_local_string ("Value should be from "), Fnumber_to_string (min), === modified file 'src/editfns.c' --- src/editfns.c 2014-09-18 11:34:24 +0000 +++ src/editfns.c 2014-09-25 02:01:14 +0000 @@ -3531,6 +3531,7 @@ usage: (propertize STRING &rest PROPERTIES) */) (ptrdiff_t nargs, Lisp_Object *args) { + USE_LOCAL_ALLOCA; Lisp_Object properties, string; struct gcpro gcpro1, gcpro2; ptrdiff_t i; @@ -4362,6 +4363,7 @@ Lisp_Object format2 (const char *string1, Lisp_Object arg0, Lisp_Object arg1) { + USE_LOCAL_ALLOCA; return Fformat (3, ((Lisp_Object []) { build_local_string (string1), arg0, arg1 })); } === modified file 'src/emacs.c' --- src/emacs.c 2014-09-16 08:20:08 +0000 +++ src/emacs.c 2014-09-25 02:01:14 +0000 @@ -396,7 +396,8 @@ static void init_cmdargs (int argc, char **argv, int skip_args, char *original_pwd) { - register int i; + USE_LOCAL_ALLOCA; + int i; Lisp_Object name, dir, handler; ptrdiff_t count = SPECPDL_INDEX (); Lisp_Object raw_name; @@ -2208,6 +2209,7 @@ Lisp_Object decode_env_path (const char *evarname, const char *defalt, bool empty) { + USE_LOCAL_ALLOCA; const char *path, *p; Lisp_Object lpath, element, tem; /* Default is to use "." for empty path elements. === modified file 'src/fileio.c' --- src/fileio.c 2014-09-22 19:20:45 +0000 +++ src/fileio.c 2014-09-25 02:01:14 +0000 @@ -5411,6 +5411,7 @@ static Lisp_Object auto_save_error (Lisp_Object error_val) { + USE_LOCAL_ALLOCA; Lisp_Object msg; int i; struct gcpro gcpro1; === modified file 'src/fns.c' --- src/fns.c 2014-09-17 18:27:36 +0000 +++ src/fns.c 2014-09-25 02:01:14 +0000 @@ -2706,7 +2706,8 @@ if `last-nonmenu-event' is nil, and `use-dialog-box' is non-nil. */) (Lisp_Object prompt) { - register Lisp_Object ans; + USE_LOCAL_ALLOCA; + Lisp_Object ans; struct gcpro gcpro1; CHECK_STRING (prompt); @@ -3996,7 +3997,7 @@ if (HASH_TABLE_P (Vpurify_flag) && XHASH_TABLE (Vpurify_flag) == h) Fmessage (2, ((Lisp_Object []) - { build_local_string ("Growing hash table to: %d"), + { build_string ("Growing hash table to: %d"), make_number (new_size) })); #endif === modified file 'src/font.c' --- src/font.c 2014-09-24 11:11:14 +0000 +++ src/font.c 2014-09-25 02:01:14 +0000 @@ -357,6 +357,7 @@ font_style_to_value (enum font_property_index prop, Lisp_Object val, bool noerror) { + USE_LOCAL_ALLOCA; Lisp_Object table = AREF (font_style_table, prop - FONT_WEIGHT_INDEX); int len; @@ -1049,6 +1050,7 @@ int font_parse_xlfd (char *name, ptrdiff_t len, Lisp_Object font) { + USE_LOCAL_ALLOCA; int i, j, n; char *f[XLFD_LAST_INDEX + 1]; Lisp_Object val; @@ -1758,6 +1760,7 @@ void font_parse_family_registry (Lisp_Object family, Lisp_Object registry, Lisp_Object font_spec) { + USE_LOCAL_ALLOCA; ptrdiff_t len; char *p0, *p1; @@ -2683,11 +2686,10 @@ static Lisp_Object font_delete_unmatched (Lisp_Object vec, Lisp_Object spec, int size) { + USE_LOCAL_ALLOCA; Lisp_Object entity, val; enum font_property_index prop; - /* If USE_STACK_LISP_OBJECTS, MAX is used to avoid unbounded alloca. */ - ptrdiff_t i, max - = (USE_STACK_LISP_OBJECTS ? MAX_ALLOCA / sizeof (struct Lisp_Cons) : 0); + ptrdiff_t i; for (val = Qnil, i = ASIZE (vec) - 1; i >= 0; i--) { @@ -2715,7 +2717,7 @@ } if (NILP (spec)) { - val = --max > 0 ? local_cons (entity, val) : Fcons (entity, val); + val = local_cons (entity, val); continue; } for (prop = FONT_WEIGHT_INDEX; prop < FONT_SIZE_INDEX; prop++) @@ -2746,7 +2748,7 @@ AREF (entity, FONT_AVGWIDTH_INDEX))) prop = FONT_SPEC_MAX; if (prop < FONT_SPEC_MAX) - val = --max > 0 ? local_cons (entity, val) : Fcons (entity, val); + val = local_cons (entity, val); } return (Fvconcat (1, &val)); } @@ -5004,6 +5006,7 @@ void font_add_log (const char *action, Lisp_Object arg, Lisp_Object result) { + USE_LOCAL_ALLOCA; Lisp_Object val; int i; === modified file 'src/fontset.c' --- src/fontset.c 2014-09-18 11:34:24 +0000 +++ src/fontset.c 2014-09-25 02:01:14 +0000 @@ -1420,6 +1420,7 @@ appended. By default, FONT-SPEC overrides the previous settings. */) (Lisp_Object name, Lisp_Object target, Lisp_Object font_spec, Lisp_Object frame, Lisp_Object add) { + USE_LOCAL_ALLOCA; Lisp_Object fontset; Lisp_Object font_def, registry, family; Lisp_Object range_list; === modified file 'src/frame.c' --- src/frame.c 2014-09-23 17:03:48 +0000 +++ src/frame.c 2014-09-25 02:01:14 +0000 @@ -4137,7 +4137,8 @@ x_get_arg (Display_Info *dpyinfo, Lisp_Object alist, Lisp_Object param, const char *attribute, const char *class, enum resource_types type) { - register Lisp_Object tem; + USE_LOCAL_ALLOCA; + Lisp_Object tem; tem = Fassq (param, alist); === modified file 'src/keyboard.c' --- src/keyboard.c 2014-09-24 20:30:28 +0000 +++ src/keyboard.c 2014-09-25 02:01:14 +0000 @@ -597,6 +597,8 @@ static void echo_dash (void) { + USE_LOCAL_ALLOCA; + /* Do nothing if not echoing at all. */ if (NILP (KVAR (current_kboard, echo_string))) return; @@ -1894,6 +1896,7 @@ static Lisp_Object safe_run_hooks_error (Lisp_Object error, ptrdiff_t nargs, Lisp_Object *args) { + USE_LOCAL_ALLOCA; Lisp_Object hook, fun; eassert (nargs == 2); @@ -7700,6 +7703,7 @@ bool parse_menu_item (Lisp_Object item, int inmenubar) { + USE_LOCAL_ALLOCA; Lisp_Object def, tem, item_string, start; Lisp_Object filter; Lisp_Object keyhint; @@ -8523,7 +8527,8 @@ read_char_minibuf_menu_prompt (int commandflag, Lisp_Object map) { - register Lisp_Object name; + USE_LOCAL_ALLOCA; + Lisp_Object name; ptrdiff_t nlength; /* FIXME: Use the minibuffer's frame width. */ ptrdiff_t width = FRAME_COLS (SELECTED_FRAME ()) - 4; === modified file 'src/keymap.c' --- src/keymap.c 2014-09-24 11:11:14 +0000 +++ src/keymap.c 2014-09-25 02:01:14 +0000 @@ -1308,6 +1308,7 @@ static void silly_event_symbol_error (Lisp_Object c) { + USE_LOCAL_ALLOCA; Lisp_Object parsed, base, name, assoc; int modifiers; @@ -2235,6 +2236,8 @@ around function keys and event symbols. */) (Lisp_Object key, Lisp_Object no_angles) { + USE_SAFE_ALLOCA; + if (CONSP (key) && lucid_event_type_list_p (key)) key = Fevent_convert_list (key); @@ -2258,7 +2261,6 @@ if (NILP (no_angles)) { Lisp_Object result; - USE_SAFE_ALLOCA; char *buffer = SAFE_ALLOCA (sizeof "<>" + SBYTES (SYMBOL_NAME (key))); esprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key))); @@ -3416,6 +3418,7 @@ bool partial, Lisp_Object shadow, Lisp_Object entire_map, bool keymap_p, bool mention_shadow) { + USE_LOCAL_ALLOCA; Lisp_Object definition; Lisp_Object tem2; Lisp_Object elt_prefix = Qnil; === modified file 'src/lisp.h' --- src/lisp.h 2014-09-24 20:54:25 +0000 +++ src/lisp.h 2014-09-25 02:01:14 +0000 @@ -4562,11 +4562,27 @@ } while (false) +/* Return floor (NBYTES / WORD_SIZE). */ + +INLINE ptrdiff_t +lisp_word_count (ptrdiff_t nbytes) +{ + if (-1 >> 1 == -1) + switch (word_size) + { + case 2: return nbytes >> 1; + case 4: return nbytes >> 2; + case 8: return nbytes >> 3; + case 16: return nbytes >> 4; + } + return nbytes / word_size - (nbytes % word_size < 0); +} + /* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects. */ #define SAFE_ALLOCA_LISP(buf, nelt) \ do { \ - if ((nelt) <= sa_avail / word_size) \ + if ((nelt) <= lisp_word_count (sa_avail)) \ (buf) = AVAIL_ALLOCA ((nelt) * word_size); \ else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \ { \ @@ -4635,17 +4651,27 @@ # define USE_LOCAL_ALLOCATORS #endif +/* Any function that uses a local allocator should start with either + 'USE_SAFE_ALLOCA; or 'USE_LOCAL_ALLOCA;' (but not both). */ +#ifdef USE_LOCAL_ALLOCATORS +# define USE_LOCAL_ALLOCA ptrdiff_t sa_avail = MAX_ALLOCA +#else +# define USE_LOCAL_ALLOCA +#endif + #ifdef USE_LOCAL_ALLOCATORS /* Return a function-scoped cons whose car is X and cdr is Y. */ # define local_cons(x, y) \ - ({ \ - struct Lisp_Cons *c_ = alloca (sizeof (struct Lisp_Cons)); \ - c_->car = (x); \ - c_->u.cdr = (y); \ - make_lisp_ptr (c_, Lisp_Cons); \ - }) + (sizeof (struct Lisp_Cons) <= sa_avail \ + ? ({ \ + struct Lisp_Cons *c_ = AVAIL_ALLOCA (sizeof (struct Lisp_Cons)); \ + c_->car = (x); \ + c_->u.cdr = (y); \ + make_lisp_ptr (c_, Lisp_Cons); \ + }) \ + : Fcons (x, y)) # define local_list1(a) local_cons (a, Qnil) # define local_list2(a, b) local_cons (a, local_list1 (b)) @@ -4658,33 +4684,33 @@ # define make_local_vector(size, init) \ ({ \ ptrdiff_t size_ = size; \ - Lisp_Object init_ = init; \ Lisp_Object vec_; \ - if (size_ <= (MAX_ALLOCA - header_size) / word_size) \ + if (size_ <= lisp_word_count (sa_avail - header_size)) \ { \ - void *ptr_ = alloca (size_ * word_size + header_size); \ - vec_ = local_vector_init (ptr_, size_, init_); \ + void *ptr_ = AVAIL_ALLOCA (size_ * word_size + header_size); \ + vec_ = local_vector_init (ptr_, size_, init); \ } \ else \ - vec_ = Fmake_vector (make_number (size_), init_); \ + vec_ = Fmake_vector (make_number (size_), init); \ vec_; \ }) +enum { LISP_STRING_OVERHEAD = sizeof (struct Lisp_String) + 1 }; + /* Return a function-scoped string with contents DATA and length NBYTES. */ # define make_local_string(data, nbytes) \ ({ \ - char const *data_ = data; \ ptrdiff_t nbytes_ = nbytes; \ Lisp_Object string_; \ - if (nbytes_ <= MAX_ALLOCA - sizeof (struct Lisp_String) - 1) \ + if (nbytes_ <= sa_avail - LISP_STRING_OVERHEAD) \ { \ - struct Lisp_String *ptr_ \ - = alloca (sizeof (struct Lisp_String) + 1 + nbytes_); \ - string_ = local_string_init (ptr_, data_, nbytes_); \ + struct Lisp_String *ptr_ = AVAIL_ALLOCA (LISP_STRING_OVERHEAD \ + + nbytes_); \ + string_ = local_string_init (ptr_, data, nbytes_); \ } \ else \ - string_ = make_string (data_, nbytes_); \ + string_ = make_string (data, nbytes_); \ string_; \ }) === modified file 'src/lread.c' --- src/lread.c 2014-09-22 06:06:19 +0000 +++ src/lread.c 2014-09-25 02:01:14 +0000 @@ -968,6 +968,7 @@ static void load_warn_old_style_backquotes (Lisp_Object file) { + USE_LOCAL_ALLOCA; if (!NILP (Vold_style_backquotes)) Fmessage (2, ((Lisp_Object []) { build_local_string ("Loading `%s': old-style backquotes detected!"), @@ -3638,6 +3639,7 @@ static Lisp_Object read_list (bool flag, Lisp_Object readcharfun) { + USE_LOCAL_ALLOCA; Lisp_Object val, tail; Lisp_Object elt, tem; struct gcpro gcpro1, gcpro2; === modified file 'src/menu.c' --- src/menu.c 2014-09-15 14:53:23 +0000 +++ src/menu.c 2014-09-25 02:01:14 +0000 @@ -324,6 +324,7 @@ static void single_menu_item (Lisp_Object key, Lisp_Object item, Lisp_Object dummy, void *skp_v) { + USE_LOCAL_ALLOCA; Lisp_Object map, item_string, enabled; struct gcpro gcpro1, gcpro2; bool res; === modified file 'src/minibuf.c' --- src/minibuf.c 2014-09-15 14:53:23 +0000 +++ src/minibuf.c 2014-09-25 02:01:14 +0000 @@ -1123,6 +1123,7 @@ function, instead of the usual behavior. */) (Lisp_Object prompt, Lisp_Object def, Lisp_Object require_match) { + USE_LOCAL_ALLOCA; Lisp_Object result; char *s; ptrdiff_t len; === modified file 'src/process.c' --- src/process.c 2014-09-23 17:03:48 +0000 +++ src/process.c 2014-09-25 02:01:14 +0000 @@ -592,6 +592,7 @@ static Lisp_Object status_message (struct Lisp_Process *p) { + USE_LOCAL_ALLOCA; Lisp_Object status = p->status; Lisp_Object symbol; int code; @@ -1290,6 +1291,8 @@ Returns nil if format of ADDRESS is invalid. */) (Lisp_Object address, Lisp_Object omit_port) { + USE_LOCAL_ALLOCA; + if (NILP (address)) return Qnil; @@ -4003,6 +4006,7 @@ static void server_accept_connection (Lisp_Object server, int channel) { + USE_LOCAL_ALLOCA; Lisp_Object proc, caller, name, buffer; Lisp_Object contact, host, service; struct Lisp_Process *ps= XPROCESS (server); === modified file 'src/textprop.c' --- src/textprop.c 2014-09-15 14:53:23 +0000 +++ src/textprop.c 2014-09-25 02:01:14 +0000 @@ -1913,6 +1913,7 @@ copy_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object src, Lisp_Object pos, Lisp_Object dest, Lisp_Object prop) { + USE_LOCAL_ALLOCA; INTERVAL i; Lisp_Object res; Lisp_Object stuff; === modified file 'src/xdisp.c' --- src/xdisp.c 2014-09-23 16:07:23 +0000 +++ src/xdisp.c 2014-09-25 02:01:14 +0000 @@ -20892,6 +20892,7 @@ See also `bidi-paragraph-direction'. */) (Lisp_Object buffer) { + USE_LOCAL_ALLOCA; struct buffer *buf = current_buffer; struct buffer *old = buf; === modified file 'src/xfns.c' --- src/xfns.c 2014-09-24 04:12:37 +0000 +++ src/xfns.c 2014-09-25 02:01:14 +0000 @@ -1561,6 +1561,7 @@ const char *xprop, const char *xclass, int foreground_p) { + USE_LOCAL_ALLOCA; struct x_display_info *dpyinfo = FRAME_DISPLAY_INFO (f); Lisp_Object tem; @@ -4272,6 +4273,7 @@ void select_visual (struct x_display_info *dpyinfo) { + USE_LOCAL_ALLOCA; Display *dpy = dpyinfo->display; Screen *screen = dpyinfo->screen; === modified file 'src/xfont.c' --- src/xfont.c 2014-09-23 17:03:48 +0000 +++ src/xfont.c 2014-09-25 02:01:14 +0000 @@ -677,6 +677,7 @@ static Lisp_Object xfont_open (struct frame *f, Lisp_Object entity, int pixel_size) { + USE_LOCAL_ALLOCA; Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f); Display *display = dpyinfo->display; char name[512]; === modified file 'src/xselect.c' --- src/xselect.c 2014-09-16 08:20:08 +0000 +++ src/xselect.c 2014-09-25 02:01:14 +0000 @@ -2159,6 +2159,7 @@ static Lisp_Object x_clipboard_manager_error_1 (Lisp_Object err) { + USE_LOCAL_ALLOCA; Fmessage (2, ((Lisp_Object []) { build_local_string ("X clipboard manager error: %s\n\ If the problem persists, set `x-select-enable-clipboard-manager' to nil."), @@ -2212,6 +2213,7 @@ x_clipboard_manager_save_all (void) { /* Loop through all X displays, saving owned clipboards. */ + USE_LOCAL_ALLOCA; struct x_display_info *dpyinfo; Lisp_Object local_selection, local_frame; === modified file 'src/xterm.c' --- src/xterm.c 2014-09-24 07:17:51 +0000 +++ src/xterm.c 2014-09-25 02:01:14 +0000 @@ -10692,6 +10692,7 @@ struct x_display_info * x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) { + USE_LOCAL_ALLOCA; Display *dpy; struct terminal *terminal; struct x_display_info *dpyinfo; ------------------------------------------------------------ revno: 117941 author: Paul Eggert committer: Paul Eggert branch nick: trunk timestamp: Wed 2014-09-24 13:54:25 -0700 message: Default to stack objects on non-GNU/Linux, non-DOS_NT platforms. * lisp.h (USE_STACK_LISP_OBJECTS): Also default to true if !defined DOS_NT && !defined GNU_LINUX. I've tested this on AIX and Solaris and it's likely to work on similar platforms. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-24 20:30:28 +0000 +++ src/ChangeLog 2014-09-24 20:54:25 +0000 @@ -1,5 +1,10 @@ 2014-09-24 Paul Eggert + Default to stack objects on non-GNU/Linux, non-DOS_NT platforms. + * lisp.h (USE_STACK_LISP_OBJECTS): Also default to true + if !defined DOS_NT && !defined GNU_LINUX. I've tested this on AIX + and Solaris and it's likely to work on similar platforms. + Avoid signed integer overflow when converting Time to ptrdiff_t. * keyboard.c (INPUT_EVENT_POS_MAX, INPUT_EVENT_POS_MIN): New macros. === modified file 'src/lisp.h' --- src/lisp.h 2014-09-24 13:42:42 +0000 +++ src/lisp.h 2014-09-24 20:54:25 +0000 @@ -282,13 +282,12 @@ # endif #endif -/* This should work on GNU/Linux with GCC. Other configurations may be - problematic and/or not tested yet. Clang is known to have problems, - see http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00506.html. +/* This should work with GCC on non-DOS_NT. Clang has known problems; see + http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00506.html. Also http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00422.html - describes an issues with 32-bit MS-Windows. */ + describes an issue with 32-bit MS-Windows. */ #ifndef USE_STACK_LISP_OBJECTS -# if defined (GNU_LINUX) && defined (__GNUC__) && !defined (__clang__) +# if defined __GNUC__ && !defined __clang__ && !defined DOS_NT # define USE_STACK_LISP_OBJECTS true # else # define USE_STACK_LISP_OBJECTS false ------------------------------------------------------------ revno: 117940 author: Paul Eggert committer: Paul Eggert branch nick: trunk timestamp: Wed 2014-09-24 13:30:28 -0700 message: Avoid signed integer overflow when converting Time to ptrdiff_t. * keyboard.c (INPUT_EVENT_POS_MAX, INPUT_EVENT_POS_MIN): New macros. (position_to_Time, Time_to_position): New functions. (gen_help_event, kbd_buffer_get_event): Use them. * systime.h (Time) [emacs && !HAVE_X_WINDOWS]: Go back to plain 'unsigned long', so that 'Time' is the same for both X and non-X builds; this is less likely to cause surprise. * termhooks.h: Remove compile-time check that Time and ptrdiff_t are the same size; this is no longer required. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-24 18:25:04 +0000 +++ src/ChangeLog 2014-09-24 20:30:28 +0000 @@ -1,5 +1,16 @@ 2014-09-24 Paul Eggert + Avoid signed integer overflow when converting Time to ptrdiff_t. + * keyboard.c (INPUT_EVENT_POS_MAX, INPUT_EVENT_POS_MIN): + New macros. + (position_to_Time, Time_to_position): New functions. + (gen_help_event, kbd_buffer_get_event): Use them. + * systime.h (Time) [emacs && !HAVE_X_WINDOWS]: + Go back to plain 'unsigned long', so that 'Time' is the same + for both X and non-X builds; this is less likely to cause surprise. + * termhooks.h: Remove compile-time check that Time and ptrdiff_t + are the same size; this is no longer required. + * keyboard.c (make_lispy_event): Avoid unnecessary tests of bit 28 and of whether an unsigned value is negative. This simplifies the code a bit, and pacifies clang 3.4. === modified file 'src/keyboard.c' --- src/keyboard.c 2014-09-24 18:25:04 +0000 +++ src/keyboard.c 2014-09-24 20:30:28 +0000 @@ -3729,6 +3729,34 @@ } } +/* Limit help event positions to this range, to avoid overflow problems. */ +#define INPUT_EVENT_POS_MAX \ + ((ptrdiff_t) min (PTRDIFF_MAX, min (TYPE_MAXIMUM (Time) / 2, \ + MOST_POSITIVE_FIXNUM))) +#define INPUT_EVENT_POS_MIN (-1 - INPUT_EVENT_POS_MAX) + +/* Return a Time that encodes position POS. POS must be in range. */ + +static Time +position_to_Time (ptrdiff_t pos) +{ + eassert (INPUT_EVENT_POS_MIN <= pos && pos <= INPUT_EVENT_POS_MAX); + return pos; +} + +/* Return the position that ENCODED_POS encodes. + Avoid signed integer overflow. */ + +static ptrdiff_t +Time_to_position (Time encoded_pos) +{ + if (encoded_pos <= INPUT_EVENT_POS_MAX) + return encoded_pos; + Time encoded_pos_min = INPUT_EVENT_POS_MIN; + eassert (encoded_pos_min <= encoded_pos); + ptrdiff_t notpos = -1 - encoded_pos; + return -1 - notpos; +} /* Generate a HELP_EVENT input_event and store it in the keyboard buffer. @@ -3752,7 +3780,7 @@ event.arg = object; event.x = WINDOWP (window) ? window : frame; event.y = help; - event.timestamp = pos; + event.timestamp = position_to_Time (pos); kbd_buffer_store_event (&event); } @@ -4084,7 +4112,7 @@ frame = event->frame_or_window; object = event->arg; - position = make_number (event->timestamp); + position = make_number (Time_to_position (event->timestamp)); window = event->x; help = event->y; clear_event (event); === modified file 'src/systime.h' --- src/systime.h 2014-09-24 10:06:53 +0000 +++ src/systime.h 2014-09-24 20:30:28 +0000 @@ -19,7 +19,6 @@ #ifndef EMACS_SYSTIME_H #define EMACS_SYSTIME_H -#include #include INLINE_HEADER_BEGIN @@ -28,7 +27,7 @@ # ifdef HAVE_X_WINDOWS # include # else -typedef size_t Time; +typedef unsigned long Time; # endif #endif === modified file 'src/termhooks.h' --- src/termhooks.h 2014-09-24 07:17:51 +0000 +++ src/termhooks.h 2014-09-24 20:30:28 +0000 @@ -288,9 +288,6 @@ Lisp_Object arg; }; -/* To make sure we don't break HELP_EVENT. */ -verify (sizeof (Time) == sizeof (ptrdiff_t)); - #define EVENT_INIT(event) memset (&(event), 0, sizeof (struct input_event)) /* Bits in the modifiers member of the input_event structure. ------------------------------------------------------------ revno: 117939 fixes bug: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=18518 committer: Stefan Monnier branch nick: trunk timestamp: Wed 2014-09-24 15:23:13 -0400 message: * lisp/find-cmd.el (find-cmd): Use grep's `find-program'. Suggested by . diff: === modified file 'etc/NEWS' --- etc/NEWS 2014-09-22 15:04:12 +0000 +++ etc/NEWS 2014-09-24 19:23:13 +0000 @@ -231,6 +231,9 @@ any reference to a buffer position. The 6th member of the mouse position list returned for such events is now nil. +** Menu items in keymaps do not support the "key shortcut cache" any more. +These slots used to hold key-shortcut data, but have been obsolete since +Emacs-21. * Lisp Changes in Emacs 24.5 === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2014-09-24 17:33:54 +0000 +++ lisp/ChangeLog 2014-09-24 19:23:13 +0000 @@ -1,3 +1,8 @@ +2014-09-24 Stefan Monnier + + * find-cmd.el (find-cmd): Use grep's `find-program' (bug#18518). + Suggested by . + 2014-09-24 Ulf Jasper * net/newst-treeview.el (newsticker--treeview-do-get-node-by-id): @@ -204,7 +209,7 @@ * window.el (fit-window-to-buffer): Doc fix. -2014-09-15 Ivan Shmakov (tiny change) +2014-09-15 Ivan Shmakov * desktop.el (desktop-create-buffer): Check that buffers are still live before burying them (bug#18373). @@ -1585,7 +1590,7 @@ (dbus-register-service): Register it. (Bug#17858) (dbus-managed-objects-handler): Fix docstring. -2014-07-04 Phil Sainty (tiny change) +2014-07-04 Phil Sainty * emacs-lisp/lisp.el (narrow-to-defun-include-comments): New var. (narrow-to-defun): New arg include-comments, defaulting to it @@ -8898,7 +8903,7 @@ Add option to delete file when done. (Bug#15647) (python-shell-send-string, python-shell-send-region): Use it. -2013-11-23 Ivan Shmakov (tiny change) +2013-11-23 Ivan Shmakov * vc/diff-mode.el (diff-mode): Only allow diff-default-read-only to set buffer-read-only to t, never to nil. (Bug#15938) === modified file 'lisp/ChangeLog.14' --- lisp/ChangeLog.14 2014-01-11 03:55:50 +0000 +++ lisp/ChangeLog.14 2014-09-24 19:23:13 +0000 @@ -5178,7 +5178,7 @@ * kmacro.el (kmacro-insert-counter): Doc fix. -2008-11-21 Ivan Shmakov (tiny change) +2008-11-21 Ivan Shmakov * progmodes/tcl.el (tcl-filter): Don't forcibly move point. === modified file 'lisp/ChangeLog.16' --- lisp/ChangeLog.16 2014-09-11 19:44:25 +0000 +++ lisp/ChangeLog.16 2014-09-24 19:23:13 +0000 @@ -7534,7 +7534,7 @@ In doc-strings state whether the argument window has to denote a live, valid or any window. -2012-08-16 Phil Sainty (tiny change) +2012-08-16 Phil Sainty * progmodes/subword.el (subword-forward-function) (subword-backward-function, subword-forward-regexp) === modified file 'lisp/find-cmd.el' --- lisp/find-cmd.el 2014-01-01 07:43:34 +0000 +++ lisp/find-cmd.el 2014-09-24 19:23:13 +0000 @@ -39,6 +39,8 @@ ;;; Code: +(require 'grep) + (defconst find-constituents '((and . find-and) (not . find-not) @@ -145,13 +147,15 @@ `default-directory' is used as the initial search path. The result is a string that should be ready for the command line." - (concat - "find " (shell-quote-argument (expand-file-name default-directory)) " " - (cond - ((cdr subfinds) - (mapconcat 'find-to-string subfinds "")) - (t - (find-to-string (car subfinds)))))) + ;; FIXME: Provide a version that returns a list of strings (ready to pass to + ;; call-process). + (concat find-program " " + (shell-quote-argument (expand-file-name default-directory)) " " + (cond + ((cdr subfinds) + (mapconcat #'find-to-string subfinds "")) + (t + (find-to-string (car subfinds)))))) (defun find-and (form) "And FORMs together, so: @@ -161,7 +165,7 @@ (if (< (length form) 2) (find-to-string (car form)) (concat "\\( " - (mapconcat 'find-to-string form "-and ") + (mapconcat #'find-to-string form "-and ") "\\) "))) (defun find-or (form) @@ -172,7 +176,7 @@ (if (< (length form) 2) (find-to-string (car form)) (concat "\\( " - (mapconcat 'find-to-string form "-or ") + (mapconcat #'find-to-string form "-or ") "\\) "))) (defun find-not (form) @@ -183,7 +187,7 @@ If you wanted the FORMs -and(ed) together instead then this would suffice: \(not \(and \(mtime \"+1\"\) \(name \"something\"\)\)\)" - (concat "-not " (find-or (mapcar 'find-to-string form)))) + (concat "-not " (find-or (mapcar #'find-to-string form)))) (defun find-prune (form) "-or together FORMs postfix '-prune' and then -or that with a @@ -194,7 +198,7 @@ -prune -or -true \\\) -and -name '*.pm' \\\)" (find-or (list - (concat (find-or (mapcar 'find-to-string form)) (find-generic "prune")) + (concat (find-or (mapcar #'find-to-string form)) (find-generic "prune")) (find-generic "true")))) (defun find-generic (option &optional oper argcount args dont-quote) ------------------------------------------------------------ revno: 117938 committer: Paul Eggert branch nick: trunk timestamp: Wed 2014-09-24 11:25:04 -0700 message: * keyboard.c (make_lispy_event): Avoid unnecessary tests of bit 28 and of whether an unsigned value is negative. This simplifies the code a bit, and pacifies clang 3.4. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-24 11:59:13 +0000 +++ src/ChangeLog 2014-09-24 18:25:04 +0000 @@ -1,3 +1,9 @@ +2014-09-24 Paul Eggert + + * keyboard.c (make_lispy_event): Avoid unnecessary tests + of bit 28 and of whether an unsigned value is negative. + This simplifies the code a bit, and pacifies clang 3.4. + 2014-09-24 Eli Zaretskii * systime.h (Time): Define as size_t, to be consistent with 64-bit === modified file 'src/keyboard.c' --- src/keyboard.c 2014-09-24 07:17:51 +0000 +++ src/keyboard.c 2014-09-24 18:25:04 +0000 @@ -5548,30 +5548,27 @@ ARRAYELTS (iso_lispy_function_keys)); #endif - /* Handle system-specific or unknown keysyms. */ - if (event->code & (1 << 28) - || event->code - FUNCTION_KEY_OFFSET < 0 - || (event->code - FUNCTION_KEY_OFFSET - >= ARRAYELTS (lispy_function_keys)) - || !lispy_function_keys[event->code - FUNCTION_KEY_OFFSET]) - { - /* We need to use an alist rather than a vector as the cache - since we can't make a vector long enough. */ - if (NILP (KVAR (current_kboard, system_key_syms))) - kset_system_key_syms (current_kboard, Fcons (Qnil, Qnil)); - return modify_event_symbol (event->code, - event->modifiers, - Qfunction_key, - KVAR (current_kboard, Vsystem_key_alist), - 0, &KVAR (current_kboard, system_key_syms), - PTRDIFF_MAX); - } + if ((FUNCTION_KEY_OFFSET <= event->code + && (event->code + < FUNCTION_KEY_OFFSET + ARRAYELTS (lispy_function_keys))) + && lispy_function_keys[event->code - FUNCTION_KEY_OFFSET]) + return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET, + event->modifiers, + Qfunction_key, Qnil, + lispy_function_keys, &func_key_syms, + ARRAYELTS (lispy_function_keys)); - return modify_event_symbol (event->code - FUNCTION_KEY_OFFSET, + /* Handle system-specific or unknown keysyms. + We need to use an alist rather than a vector as the cache + since we can't make a vector long enough. */ + if (NILP (KVAR (current_kboard, system_key_syms))) + kset_system_key_syms (current_kboard, Fcons (Qnil, Qnil)); + return modify_event_symbol (event->code, event->modifiers, - Qfunction_key, Qnil, - lispy_function_keys, &func_key_syms, - ARRAYELTS (lispy_function_keys)); + Qfunction_key, + KVAR (current_kboard, Vsystem_key_alist), + 0, &KVAR (current_kboard, system_key_syms), + PTRDIFF_MAX); #ifdef HAVE_NTGUI case MULTIMEDIA_KEY_EVENT: ------------------------------------------------------------ revno: 117937 committer: Ulf Jasper branch nick: trunk timestamp: Wed 2014-09-24 19:33:54 +0200 message: Newsticker: Add commands to rearrange treeview groups and document them. (Bug#12560) 2014-09-24 Ulf Jasper * newsticker.texi: Reworked. Document new treeview group commands. Remove VERSION, UPDATED, use EMACSVER instead. Use term 'feed reader'. 2014-09-24 Ulf Jasper * automated/newsticker-tests.el (newsticker--group-find-parent-group), (newsticker--group-do-rename-group): New tests. 2014-09-24 Ulf Jasper * net/newst-treeview.el (newsticker--treeview-do-get-node-by-id): Renamed `newsticker--treeview-do-get-node' to `newsticker--treeview-do-get-node-by-id'. (newsticker--treeview-get-node-by-id): Renamed `newsticker--treeview-get-node' to `newsticker--treeview-get-node-by-id'. (newsticker--treeview-get-current-node): Renamed ` `newsticker--treeview-get-node' to `newsticker--treeview-get-node-by-id'. (newsticker--treeview-buffer-init) (newsticker--treeview-buffer-init): Disable buffer undo. (newsticker--treeview-unfold-node): Adapted to modified `newsticker--group-find-parent-group'. (newsticker--group-do-find-group): Renamed `newsticker--group-do-find-group-for-feed' to `newsticker--group-do-find-group'. Now works for both, groups and feeds. (newsticker--group-find-parent-group): Renamed `newsticker--group-find-group-for-feed' to `newsticker--group-find-parent-group'. Now works for both, groups and feeds. (newsticker--group-do-get-parent-group) (newsticker--group-get-parent-group): Removed. (newsticker-group-add-group): Changed interactive prompts. (newsticker-group-add-group): Finally jump to added group. (newsticker-group-delete-group): Finally jump to current feed. (newsticker--group-do-rename-group, newsticker-group-rename-group) (newsticker--get-group-names, newsticker--group-names): New. (newsticker-group-move-feed): Finally jump to moved feed. (newsticker-group-shift-feed-down, newsticker-group-shift-feed-up) (newsticker-group-shift-group-down) (newsticker-group-shift-group-up, newsticker--group-shift): New (newsticker--group-manage-orphan-feeds): Renamed `newsticker--group-find-group-for-feed' to `newsticker--group-find-parent-group'. (newsticker-treeview-mode-map): New keybindings for new shift commands. (newsticker-treeview-tree-do-click): Renamed `newsticker--treeview-get-node' to `newsticker--treeview-get-node-by-id'. * net/newst-backend.el (newsticker--item-list) (newsticker--item-position, newsticker--prev-message) (newsticker--scrollable-text): Moved to newst-ticker.el. * net/newst-ticker.el (newsticker--item-list) (newsticker--item-position, newsticker--prev-message) (newsticker--scrollable-text): Moved from newst-backend.el. diff: === modified file 'doc/misc/ChangeLog' --- doc/misc/ChangeLog 2014-09-04 02:15:56 +0000 +++ doc/misc/ChangeLog 2014-09-24 17:33:54 +0000 @@ -1,3 +1,9 @@ +2014-09-24 Ulf Jasper + + * newsticker.texi: Reworked. Document new treeview group + commands. Remove VERSION, UPDATED, use EMACSVER instead. Use + term 'feed reader'. + 2014-09-04 Paul Eggert Less chatter in 'make' output. === modified file 'doc/misc/newsticker.texi' --- doc/misc/newsticker.texi 2014-06-10 02:20:31 +0000 +++ doc/misc/newsticker.texi 2014-09-24 17:33:54 +0000 @@ -1,8 +1,8 @@ \input texinfo @c -*-texinfo-*- @comment %**start of header @setfilename ../../info/newsticker.info -@set VERSION 1.99 -@set UPDATED June 2008 +@include emacsver.texi +@set VERSION @value{EMACSVER} @settitle Newsticker @value{VERSION} @syncodeindex vr cp @syncodeindex fn cp @@ -11,7 +11,8 @@ @comment %**end of header @copying -This manual is for Newsticker (version @value{VERSION}, @value{UPDATED}). +This manual documents Newsticker, a feed reader for Emacs. It +corresponds to Emacs version @value{EMACSVER}. @noindent Copyright @copyright{} 2004--2014 Free Software Foundation, Inc. @@ -31,12 +32,11 @@ @dircategory Emacs network features @direntry -* Newsticker: (newsticker). A Newsticker for Emacs. +* Newsticker: (newsticker). A feed reader for Emacs. @end direntry @titlepage -@title Newsticker---a Newsticker for Emacs -@subtitle for version @value{VERSION}, @value{UPDATED} +@title Newsticker---a feed reader for Emacs @author Ulf Jasper @author @email{ulf.jasper@@web.de} @author @uref{http://ulf.epplejasper.de/} @@ -56,136 +56,419 @@ @end ifnottex @menu -* Overview:: General description of newsticker. -* Requirements:: Requirements for using newsticker. -* Installation:: Installing newsticker on your system. -* Usage:: Basic newsticker instructions. -* Configuration:: Customizable newsticker settings. -* Remarks:: Remarks about newsticker. +* Overview:: What is Newsticker? +* Installation:: Things to do before starting Newsticker the first time. +* Retrieving News:: How Newsticker fetches headlines. +* Headline Management:: How Newsticker stores headlines. +* Reading News:: How to read RSS and Atom feeds with Newsticker. +* Automatic Processing:: Automatically process news items. +* Configuration:: Customize Newsticker to your liking. +* Supported Formats:: RSS and Atom formats supported by Newsticker. + * GNU Free Documentation License:: The license for this documentation. -* Index:: Variable, function, and concept index. +* Index:: Variable, function, and concept index. @end menu @node Overview @chapter Overview -Newsticker provides a newsticker for Emacs. A newsticker is a thing -that asynchronously retrieves headlines from a list of news sites, -prepares these headlines for reading, and allows for loading the -corresponding articles in a web browser. - - -Headlines consist of a title and (possibly) a small description. They -are contained in ``RSS'' (RDF Site Summary) or ``Atom'' files. Newsticker -works with the following RSS formats: - -@itemize -@item RSS 0.91 (see @uref{http://backend.userland.com/rss091} or -@uref{http://my.netscape.com/publish/formats/rss-spec-0.91.html}), -@item RSS 0.92 (see @uref{http://backend.userland.com/rss092}), -@item RSS 1.0 (see @uref{http://purl.org/rss/1.0/spec} -@item RSS 2.0 (see @uref{http://blogs.law.harvard.edu/tech/rss}), -@end itemize -@itemize -as well as the following Atom formats: -@item Atom 0.3 -@item Atom 1.0 (see -@uref{https://datatracker.ietf.org/doc/rfc4287/}). -@end itemize - -That makes Newsticker.el an ``Atom aggregator'', ``RSS reader'', ``Feed -aggregator'', or ``Feed reader''. - -Newsticker provides several commands for reading headlines, navigating -through them, marking them as read/unread, hiding old headlines etc. -Headlines can be displayed as plain text or as rendered HTML. - -Headlines can be displayed in the echo area, either scrolling like -messages in a stock-quote ticker, or just changing. - -Newsticker allows for automatic processing of headlines by providing -hooks and (sample) functions for automatically downloading images and -enclosed files (as delivered by, e.g., podcasts). - -@ignore -@ifhtml -Here are screen shots of the @uref{newsticker-1.7.png, version 1.7 -(current version)} and some older screen shots: -@uref{newsticker-1.6.png, version 1.6}, -@uref{newsticker-1.5.png, version 1.5}, -@uref{newsticker-1.4.png, version 1.4} -@uref{newsticker-1.3.png, version 1.3}, -@uref{newsticker-1.0.png, version 1.0}. -@end ifhtml -@end ignore - -@node Requirements -@chapter Requirements - -Newsticker can be used with -@uref{http://www.gnu.org/software/emacs/emacs.html, GNU Emacs} version -21.1 or later as well as @uref{http://www.xemacs.org, XEmacs}. It -requires an XML-parser (@file{xml.el}), which is part of GNU Emacs. If -you are using XEmacs you want to get the @file{net-utils} package -which contains @file{xml.el} for XEmacs. - -Newsticker retrieves headlines either via Emacs's built-in retrieval -functions, by an arbitrary external program that retrieves files via -http and prints them to stdout (like -@uref{http://www.gnu.org/software/wget/wget.html, wget}, or---on a -per feed basis---via an arbitrary Lisp command. - +Newsticker provides a @b{Feed Reader} for Emacs. It retrieves +headlines from a list of news sites, processes them, and provides +frontends for reading and managing them. (Standard headline formats +are RSS and Atom which makes Newsticker an ``RSS Reader'', ``Atom +Reader'' or ``Feed Aggregator''.) + +Headlines (or news items) consist of a title, (mostly) a description, +and a link to the full story. The description may be a brief summary +in plain text or a full HTML-formatted article. A headline may carry +enclosed data such as images, audio or video files, typically in the +case of so ``podcast feeds''. + +Newsticker downloads headlines asynchronously at configurable times, +processes and stores them so that you can read them later. The list +of subscribed feeds, the headline processing, the presentation of the +headlines and almost all other aspects of Newsticker can be +customized to your liking. @node Installation @chapter Installation As Newsticker is part of GNU Emacs there is no need to perform any -installation steps in order to use Newsticker. - -However, if you are using imenu, which allows for navigating with the -help of a menu, you should add the following to your Emacs startup file -(@file{~/.emacs}). +installation steps in order to use it. + +Newsticker is highly customizable. All options have reasonable default +values, so that (in most cases) it is not necessary to customize +anything before you start Newsticker for the first time. + +@node Retrieving News +@chapter Retrieving News + +Newsticker downloads news periodically in the background. This is +triggered as soon as you start reading news (@ref{Reading News}). + +@findex newsticker-start +@findex newsticker-stop +Alternatively you may use the command @code{newsticker-start} +(@code{newsticker-stop}) in order to start (stop) the periodic +download of news without opening the reader. + +The following variables define which feeds are fetched and how this is +done. + +@table @code +@vindex newsticker-url-list-defaults +@item newsticker-url-list-defaults +You may select any number of feeds from this list of (sample) news feeds. + +@vindex newsticker-url-list +@item newsticker-url-list +All your personal news feeds are defined here. Each feed is +identified by its name and an URL. You may set the start-time and the +retrieval interval for each feed as well as the retrieval command +arguments in case that the default values do not fit a certain feed. + +@vindex newsticker-retrieval-method +@vindex newsticker-wget-name +@vindex newsticker-wget-arguments +@item newsticker-retrieval-method +By default Newsticker uses Emacs's built-in download capabilities for +fetching headlines. You may change this to use an external tool like +@code{wget}. In this case you need to set @code{newsticker-wget-name} +and possibly @code{newsticker-wget-arguments}. + +@vindex newsticker-retrieval-interval +@item newsticker-retrieval-interval +The number of seconds between headline retrievals. +@end table + +@node Headline Management +@chapter Headline Management + +@cindex Age +@cindex Status + +Newsticker assigns a status (or ``age'') to each headline which you +can modify manually. This makes it easy to distinguish new headlines +from old ones, to keep important headlines, to hide boring headlines +etc. An item is ``new'' when it has just arrived and has not been +read. You can mark it as ``old'' when you have read it or -- if you +want to keep it -- you can mark it as ``immortal''. You can do that +manually and you can define filters which do that automatically, see +below. When a headline has vanished from the feed it is automatically +marked as ``obsolete'' unless it has the status ``immortal''. +``Obsolete'' headlines get removed automatically after a certain time. + +@table @code +@cindex Filter +@vindex newsticker-auto-mark-filter-list +@item newsticker-auto-mark-filter-list +You may define any number of filters for automatically marking newly +arrived headlines as ``immortal'' or ``old''. A filter looks for a +regular expression in either the title or the description of a +headline and then, if the expression matches, marks the headline as +``immortal'' or as ``old''. This is done only once, when a headline +is fetched for the very first time. + +@vindex newsticker-keep-obsolete-items +@vindex newsticker-obsolete-item-max-age +@item newsticker-keep-obsolete-items +Obsolete headlines are removed immediately unless +@code{newsticker-keep-obsolete-items} is non-nil in which case they +are kept until @code{newsticker-obsolete-item-max-age} is reached. + +@vindex newsticker-automatically-mark-items-as-old +@item newsticker-automatically-mark-items-as-old +If this is set to `t' then a ``new'' item becomes ``old'' as soon as +it is retrieved a second time. + +@end table + +@node Reading News +@chapter Reading News + +@findex newsticker-show-news +Start Newsticker with the command @kbd{M-x newsticker-show-news}. This +will start the asynchronous news download and displays all available +headlines. + +@menu +* Frontends:: Select the way headlines are displayed. +* Navigation:: Move to the next unread headline etc. +* Marking:: Mark important headlines. +* More Actions:: Add new feeds etc.. +@end menu + +@node Frontends +@section Frontends +@cindex Frontends + +@vindex newsticker-frontend +Newsticker provides two different @i{views} for browsing, marking and +reading news. The variable @code{newsticker-frontend} determines the +actual headline reader. + +@subheading Treeview +@cindex Treeview + +In this view separate windows are used for displaying feeds, headlines +and their descriptions. The feeds are shown as a tree on the left +hand side, headlines of the currently selected feed are shown on the +upper right side, and the full contents of the currently selected +headline is shown on the lower right side. + +Feeds can be placed into groups, which themselves can be placed in +groups and so on. This results in the tree which is displayed on the +left. A node represents either a feed or a group of feeds holding a +subtree. The following commands allow for managing groups. + +@table @kbd +@item M-a +@kindex M-a +@findex newsticker-group-add-group +Add a new feed group. Name of the new group and of the parent group +must be entered. If The name of the parent group is the new group +becomes a top-level group. (@code{newsticker-group-add-group}) +@item M-m +@kindex M-m +@findex newsticker-group-move-feed +Moves a feed into a group. The name of the group must be +entered. (@code{newsticker-group-move-feed}) +@end table + +The position of groups and feeds within the tree can be changed with these +commands: + +@table @kbd +@item M-up +@itemx M-down +@kindex M-up +@kindex M-down +@findex newsticker-group-shift-feed-up +@findex newsticker-group-shift-feed-down +Shift the currently selected feed up and down within its group. +@item M-S-up +@itemx M-S-down +@kindex M-S-up +@kindex M-S-down +@findex newsticker-group-shift-group-up +@findex newsticker-group-shift-group-down +Shift the currently selected group up and down within its parent group. +@end table + +The group settings are saved to a file either automatically when +newsticker is being quit or manually when the following command is +executed. + +@table @kbd +@item s +@kindex s +@findex newsticker-treeview-save +Save treeview group settings. +@end table + +The Treeview is updated automatically as soon as new headlines have +arrived. + +The Treeview is used when the variable @code{newsticker-frontend} is +set to the value @code{newsticker-treeview}. (Alternatively it can be +started with the command @code{newsticker-treeview}.) + +@subheading Plainview +@cindex Plainview + +In this view all headlines of all feeds are displayed in a single +buffer (@file{*newsticker*}). The modeline in the @file{*newsticker*} +buffer informs you whenever new headlines have arrived. + +You may want to use imenu with Plainview, which allows for navigating +with the help of a menu. In this case add the following to your Emacs +startup file (@file{~/.emacs}). @lisp (add-hook 'newsticker-mode-hook 'imenu-add-menubar-index) @end lisp -That's it. - -@node Usage -@chapter Usage - -@findex newsticker-show-news -The command @code{newsticker-show-news} will display all available -headlines. It will also start the asynchronous download of headlines. - -You can choose between two different frontends for reading headlines: -@itemize -@item Newsticker's @emph{treeview} uses separate windows for the -feeds (in tree form), a list of headlines for the current feed, and -the content of the current headline. Feeds can be placed into groups, -which themselves can be placed in groups and so on. -@item Newsticker's @emph{plainview} displays all headlines in a -single buffer, called @file{*newsticker*}. The modeline in the -@file{*newsticker*} buffer informs you whenever new headlines have -arrived. -@end itemize -In both views clicking mouse-button 2 or pressing @key{RET} on a -headline will call @code{browse-url} to load the corresponding news -story in your favorite web browser. +(Note that preparing the Plainview takes significantly more time than +starting the Treeview because all headlines are displayed in a single +buffer. When you have subscribed to a large amount of feeds you may +find that Newsticker's efforts of minimizing rendering times, caching +rendered items and so on you may find However, when you have +subscribed to a large amount of feeds you may want to give the +Treeview a try.) + +The Plainview is used when the variable @code{newsticker-frontend} is +set to the value @code{newsticker-plainview}. (Alternatively it can be +started with the command @code{newsticker-plainview}.) + +@subheading Ticker +@cindex Ticker + +Additionally, headlines can be displayed in the echo area in the style of a +news ticker. @findex newsticker-start-ticker @findex newsticker-stop-ticker -The scrolling, or flashing of headlines in the echo area, can be +Headlines can be displayed in the echo area, either scrolling like +messages in a stock-quote ticker, or just changing. This can be started with the command @code{newsticker-start-ticker}. It can be stopped with @code{newsticker-stop-ticker}. -@findex newsticker-start -@findex newsticker-stop -If you just want to start the periodic download of headlines use the -command @code{newsticker-start}. Calling @code{newsticker-stop} will -stop the periodic download, but will call -@code{newsticker-stop-ticker} as well. + +@node Navigation +@section Navigation +@cindex Navigation + +Navigating through the list of feeds and headlines is rather +straightforward. You may do this either with the mouse or with the +keyboard. The following key bindings are provided in both, the +Treeview as well as the Plainview. + +@table @kbd +@item f +@findex newsticker-next-feed +@findex newsticker-treeview-next-feed +Move to next feed (@code{newsticker-next-feed}, +@code{newsticker-treeview-next-feed}). +@item F +@findex newsticker-previous-feed +@findex newsticker-treeview-prev-feed +Move to previous feed (@code{newsticker-previous-feed}, +@code{newsticker-treeview-prev-feed}). +@item n +@findex newsticker-next-item +@findex newsticker-treeview-next-item +Move to next item (@code{newsticker-next-item}, +@code{newsticker-treeview-next-item}). +@item N +@findex newsticker-next-new-item +@findex newsticker-treeview-next-new-item +Move to next new item (possibly in another feed) +(@code{newsticker-next-new-item}, +@code{newsticker-treeview-next-new-item}). +@item p +@findex newsticker-previous-item +@findex newsticker-treeview-prev-item +Move to previous item (@code{newsticker-previous-item}, +@code{newsticker-treeview-prev-item}). +@item P +@findex newsticker-previous-new-item +@findex newsticker-treeview-prev-new-item +Move to previous new item (possibly in another feed) +(@code{newsticker-previous-new-item}, +@code{newsticker-treeview-prev-new-item}). +@end table + +@subheading Treeview +@table @kbd +@item j +@findex newsticker-treeview-jump +Enter the name of a feed and jump to it +(@code{newsticker-treeview-jump}). +@end table + + +@node Marking +@section Marking +@cindex Marking + +The following key bindings are provided in both, the Treeview as well +as the Plainview. + +@table @kbd +@item o +@findex newsticker-mark-item-at-point-as-read +@findex newsticker-treeview-mark-item-old +Mark current item as old. +(@code{newsticker-mark-item-at-point-as-read}, +@code{newsticker-treeview-mark-item-old}). +@item i +@findex newsticker-mark-item-at-point-as-immortal +@findex newsticker-treeview-mark-item-immortal +Mark current item as immortal. Immortal items are kept forever. +(@code{newsticker-mark-item-at-point-as-immortal}, +@code{newsticker-treeview-mark-item-immortal}). +@end table + +@node More Actions +@section More Actions +@cindex More Actions + +@subheading View full article +@table @kbd +@cindex Get News +@item v +@itemx RET +@itemx +@findex newsticker-treeview-browse-url +Open the link to the full article (as contained in the current +headline) in your web browser @code{newsticker-treeview-browse-url}). +@end table + +@subheading Get News +@cindex Get News + +You can force immediate download of news with the following commands. + +@table @kbd +@item g +@findex newsticker-treeview-get-news +Get news for currently shown feed (@code{newsticker-treeview-get-news}). +@item G +@findex newsticker-get-all-news +Get news for all feeds (@code{newsticker-get-all-news}). +@end table + +@subheading Add More Feeds +@cindex Add More Feeds + +@table @kbd +@item a +@findex newsticker-add-url +The command @code{newsticker-add-url} prompts for an URL and a name of +a new feed. It then prepares a customization buffer where the details +of the new feed can be set. +@end table + + +@node Automatic Processing +@chapter Automatic Processing +@cindex Automatic Processing + +Apart from automatic marking of headlines (by means of filters) +Newsticker provides the possibility to fully process newly arrived +headlines. Instead of reading headlines yourself you can tell +Newsticker to do that for you. + +@vindex newsticker-new-item-functions +In order to do so write a function which takes three arguments + +@table @var +@item FEED +the name of the corresponding news feed, +@item TITLE +the title of the headline, +@item DESC +the decoded description of the headline. +@end table + +and add it to @code{newsticker-new-item-functions}. Each function +contained in this list is called once for each new headline. +Depending on the feed, the title and the description of a headline you +can + +@itemize +@item +automatically download images referenced in HTML-formatted +descriptions (for which a function already exists, see +@code{newsticker-download-images}), +@item +automatically save enclosed audio and video files (for which another +function exists as well, see @code{newsticker-download-images}), +@item +flash the screen while playing some sound, +@item +whatever you want. +@end itemize @node Configuration @chapter Configuration @@ -195,11 +478,8 @@ @code{customize-group} and enter @samp{newsticker} for the customization group. -All Newsticker options have reasonable default values, so that in most -cases it is not necessary to customize settings before starting Newsticker -for the first time. - -The following list shows the available groups of newsticker options +@noindent +The following list shows the available groups of Newsticker options and some of the most important options. @itemize @@ -296,13 +576,35 @@ @end itemize +@noindent For the complete list of options please have a look at the customization buffers. -@node Remarks -@chapter Remarks - -Byte-compiling newsticker.el is recommended. +@node Supported Formats +@appendix Supported Formats +@cindex Supported Formats + +Newsticker works with the standard RSS and Atom formats listed below +(being lenient with feeds which break the specifications). + +@subheading RSS formats + +@itemize +@item RSS 0.91 (see @uref{http://backend.userland.com/rss091} or +@uref{http://my.netscape.com/publish/formats/rss-spec-0.91.html}) +@item RSS 0.92 (see @uref{http://backend.userland.com/rss092}) +@item RSS 1.0 (see @uref{http://purl.org/rss/1.0/spec}) +@item RSS 2.0 (see @uref{http://blogs.law.harvard.edu/tech/rss}) +@end itemize +@itemize + +@subheading Atom formats + +@item Atom 0.3 +@item Atom 1.0 (see +@uref{https://datatracker.ietf.org/doc/rfc4287/}) +@end itemize + @node GNU Free Documentation License @appendix GNU Free Documentation License @@ -310,7 +612,7 @@ @node Index @unnumbered Index - @printindex cp + @bye === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2014-09-22 19:20:45 +0000 +++ lisp/ChangeLog 2014-09-24 17:33:54 +0000 @@ -1,3 +1,54 @@ +2014-09-24 Ulf Jasper + + * net/newst-treeview.el (newsticker--treeview-do-get-node-by-id): + Renamed `newsticker--treeview-do-get-node' to + `newsticker--treeview-do-get-node-by-id'. + (newsticker--treeview-get-node-by-id): Renamed + `newsticker--treeview-get-node' to + `newsticker--treeview-get-node-by-id'. + (newsticker--treeview-get-current-node): Renamed ` + `newsticker--treeview-get-node' to + `newsticker--treeview-get-node-by-id'. + (newsticker--treeview-buffer-init) + (newsticker--treeview-buffer-init): Disable buffer undo. + (newsticker--treeview-unfold-node): Adapted to modified + `newsticker--group-find-parent-group'. + (newsticker--group-do-find-group): Renamed + `newsticker--group-do-find-group-for-feed' to + `newsticker--group-do-find-group'. Now works for both, groups and + feeds. + (newsticker--group-find-parent-group): Renamed + `newsticker--group-find-group-for-feed' to + `newsticker--group-find-parent-group'. Now works for both, groups + and feeds. + (newsticker--group-do-get-parent-group) + (newsticker--group-get-parent-group): Removed. + (newsticker-group-add-group): Changed interactive prompts. + (newsticker-group-add-group): Finally jump to added group. + (newsticker-group-delete-group): Finally jump to current feed. + (newsticker--group-do-rename-group, newsticker-group-rename-group) + (newsticker--get-group-names, newsticker--group-names): New. + (newsticker-group-move-feed): Finally jump to moved feed. + (newsticker-group-shift-feed-down, newsticker-group-shift-feed-up) + (newsticker-group-shift-group-down) + (newsticker-group-shift-group-up, newsticker--group-shift): New + (newsticker--group-manage-orphan-feeds): Renamed + `newsticker--group-find-group-for-feed' to + `newsticker--group-find-parent-group'. + (newsticker-treeview-mode-map): New keybindings for new shift commands. + (newsticker-treeview-tree-do-click): Renamed + `newsticker--treeview-get-node' to + `newsticker--treeview-get-node-by-id'. + + * net/newst-backend.el (newsticker--item-list) + (newsticker--item-position, newsticker--prev-message) + (newsticker--scrollable-text): Moved to newst-ticker.el. + + * net/newst-ticker.el (newsticker--item-list) + (newsticker--item-position, newsticker--prev-message) + (newsticker--scrollable-text): Moved from newst-backend.el. + + 2014-09-22 Kan-Ru Chen * window.el (fit-window-to-buffer): When counting buffer width, === modified file 'lisp/net/newst-backend.el' --- lisp/net/newst-backend.el 2014-02-25 18:35:37 +0000 +++ lisp/net/newst-backend.el 2014-09-24 17:33:54 +0000 @@ -6,7 +6,7 @@ ;; Filename: newst-backend.el ;; URL: http://www.nongnu.org/newsticker ;; Keywords: News, RSS, Atom -;; Time-stamp: "13. Mai 2011, 20:47:05 (ulf)" +;; Time-stamp: "23. September 2014, 19:51:10 (ulf)" ;; Package: newsticker ;; ====================================================================== @@ -483,14 +483,6 @@ ;; ====================================================================== ;;; Internal variables ;; ====================================================================== -(defvar newsticker--item-list nil - "List of newsticker items.") -(defvar newsticker--item-position 0 - "Actual position in list of newsticker items.") -(defvar newsticker--prev-message "There was no previous message yet!" - "Last message that the newsticker displayed.") -(defvar newsticker--scrollable-text "" - "The text which is scrolled smoothly in the echo area.") (defvar newsticker--buffer-uptodate-p nil "Tells whether the newsticker buffer is up to date.") (defvar newsticker--latest-update-time (current-time) === modified file 'lisp/net/newst-ticker.el' --- lisp/net/newst-ticker.el 2014-01-01 07:43:34 +0000 +++ lisp/net/newst-ticker.el 2014-09-24 17:33:54 +0000 @@ -6,7 +6,7 @@ ;; Filename: newst-ticker.el ;; URL: http://www.nongnu.org/newsticker ;; Keywords: News, RSS, Atom -;; Time-stamp: "6. Dezember 2009, 19:16:00 (ulf)" +;; Time-stamp: "24. September 2014, 19:07:25 (ulf)" ;; Package: newsticker ;; ====================================================================== @@ -37,6 +37,14 @@ (require 'newst-backend) +(defvar newsticker--item-list nil + "List of newsticker items.") +(defvar newsticker--item-position 0 + "Actual position in list of newsticker items.") +(defvar newsticker--prev-message "There was no previous message yet!" + "Last message that the newsticker displayed.") +(defvar newsticker--scrollable-text "" + "The text which is scrolled smoothly in the echo area.") (defvar newsticker--ticker-timer nil "Timer for newsticker ticker.") === modified file 'lisp/net/newst-treeview.el' --- lisp/net/newst-treeview.el 2014-08-11 18:08:13 +0000 +++ lisp/net/newst-treeview.el 2014-09-24 17:33:54 +0000 @@ -238,23 +238,23 @@ (newsticker--treeview-do-get-node-of-feed feed-name newsticker--treeview-vfeed-tree))) -(defun newsticker--treeview-do-get-node (id startnode) +(defun newsticker--treeview-do-get-node-by-id (id startnode) "Recursively search node with ID starting from STARTNODE." (if (newsticker--treeview-ids-eq id (widget-get startnode :nt-id)) (throw 'found startnode) (let ((children (widget-get startnode :children))) (dolist (w children) - (newsticker--treeview-do-get-node id w))))) + (newsticker--treeview-do-get-node-by-id id w))))) -(defun newsticker--treeview-get-node (id) +(defun newsticker--treeview-get-node-by-id (id) "Return node with ID in newsticker treeview tree." (catch 'found - (newsticker--treeview-do-get-node id newsticker--treeview-feed-tree) - (newsticker--treeview-do-get-node id newsticker--treeview-vfeed-tree))) + (newsticker--treeview-do-get-node-by-id id newsticker--treeview-feed-tree) + (newsticker--treeview-do-get-node-by-id id newsticker--treeview-vfeed-tree))) (defun newsticker--treeview-get-current-node () "Return current node in newsticker treeview tree." - (newsticker--treeview-get-node newsticker--treeview-current-node-id)) + (newsticker--treeview-get-node-by-id newsticker--treeview-current-node-id)) ;; ====================================================================== @@ -1166,12 +1166,14 @@ (unless newsticker--selection-overlay (with-current-buffer (newsticker--treeview-list-buffer) + (setq buffer-undo-list t) (setq newsticker--selection-overlay (make-overlay (point-min) (point-max))) (overlay-put newsticker--selection-overlay 'face 'newsticker-treeview-selection-face))) (unless newsticker--tree-selection-overlay (with-current-buffer (newsticker--treeview-tree-buffer) + (setq buffer-undo-list t) (setq newsticker--tree-selection-overlay (make-overlay (point-min) (point-max))) (overlay-put newsticker--tree-selection-overlay 'face @@ -1218,7 +1220,7 @@ (newsticker-treeview-save)) (defun newsticker-treeview-save () - "Save newsticker data including treeview settings." + "Save treeview group settings." (interactive) (let ((coding-system-for-write 'utf-8) (buf (find-file-noselect (concat newsticker-dir "/groups")))) @@ -1598,10 +1600,8 @@ "Recursively show subtree above the node that represents FEED-NAME." (let ((node (newsticker--treeview-get-node-of-feed feed-name))) (unless node - (let* ((group-name (or (car (newsticker--group-find-group-for-feed - feed-name)) - (newsticker--group-get-parent-group - feed-name)))) + (let* ((group-name (car (newsticker--group-find-parent-group + feed-name)))) (newsticker--treeview-unfold-node group-name)) (setq node (newsticker--treeview-get-node-of-feed feed-name))) (when node @@ -1625,20 +1625,31 @@ ;; ====================================================================== ;;; Groups ;; ====================================================================== -(defun newsticker--group-do-find-group-for-feed (feed-name node) - "Recursively find FEED-NAME in NODE." - (if (member feed-name (cdr node)) - (throw 'found node) +(defun newsticker--group-do-find-group (feed-or-group-name parent-node node) + "Recursively find FEED-OR-GROUP-NAME in PARENT-NODE or NODE." + (cond ((stringp node) + (when (string= feed-or-group-name node) + (throw 'found parent-node))) + ((listp node) + (cond ((string= feed-or-group-name (car node)) + (throw 'found parent-node)) + ((member feed-or-group-name (cdr node)) + (throw 'found node)) + (t + (mapc (lambda (n) + (if (listp n) + (newsticker--group-do-find-group + feed-or-group-name node n))) + (cdr node))))))) + +(defun newsticker--group-find-parent-group (feed-or-group-name) + "Find group containing FEED-OR-GROUP-NAME." + (catch 'found (mapc (lambda (n) - (if (listp n) - (newsticker--group-do-find-group-for-feed feed-name n))) - (cdr node)))) - -(defun newsticker--group-find-group-for-feed (feed-name) - "Find group containing FEED-NAME." - (catch 'found - (newsticker--group-do-find-group-for-feed feed-name - newsticker-groups) + (newsticker--group-do-find-group feed-or-group-name + newsticker-groups + n)) + newsticker-groups) nil)) (defun newsticker--group-do-get-group (name node) @@ -1659,26 +1670,6 @@ newsticker-groups) nil)) -(defun newsticker--group-do-get-parent-group (name node parent) - "Recursively find parent group for NAME from NODE which is a child of PARENT." - (if (string= name (car node)) - (throw 'found parent) - (mapc (lambda (n) - (if (listp n) - (newsticker--group-do-get-parent-group name n (car node)))) - (cdr node)))) - -(defun newsticker--group-get-parent-group (name) - "Find parent group for group named NAME." - (catch 'found - (mapc (lambda (n) - (if (listp n) - (newsticker--group-do-get-parent-group - name n (car newsticker-groups)))) - newsticker-groups) - nil)) - - (defun newsticker--group-get-subgroups (group &optional recursive) "Return list of subgroups for GROUP. If RECURSIVE is non-nil recursively get subgroups and return a nested list." @@ -1714,9 +1705,9 @@ (defun newsticker-group-add-group (name parent) "Add group NAME to group PARENT." (interactive - (list (read-string "Group Name: ") + (list (read-string "Name of new group: ") (let ((completion-ignore-case t)) - (completing-read "Parent Group: " (newsticker--group-all-groups) + (completing-read "Name of parent group (optional): " (newsticker--group-all-groups) nil t)))) (if (newsticker--group-get-group name) (error "Group %s exists already" name)) @@ -1726,46 +1717,154 @@ (unless p (error "Parent %s does not exist" parent)) (setcdr p (cons (list name) (cdr p)))) - (newsticker--treeview-tree-update)) + (newsticker--treeview-tree-update) + (newsticker-treeview-jump newsticker--treeview-current-feed)) + +(defun newsticker-group-delete-group (name) + "Delete group NAME." + (interactive + (list (let ((completion-ignore-case t)) + (completing-read "Delete group: " + (newsticker--group-names) + nil t (car (newsticker--group-find-parent-group + newsticker--treeview-current-feed)))))) + (let ((parent-group (newsticker--group-find-parent-group name))) + (unless parent-group + (error "Parent %s does not exist" parent-group)) + (setcdr parent-group (cl-delete-if (lambda (g) + (and (listp g) + (string= name (car g)))) + (cdr parent-group))) + (newsticker--group-manage-orphan-feeds) + (newsticker--treeview-tree-update) + (newsticker-treeview-update) + (newsticker-treeview-jump newsticker--treeview-current-feed))) + +(defun newsticker--group-do-rename-group (old-name new-name) + "Actually rename group OLD-NAME to NEW-NAME." + (let ((parent-group (newsticker--group-find-parent-group old-name))) + (unless parent-group + (error "Parent of %s does not exist" old-name)) + (mapcar (lambda (elt) + (cond ((and (listp elt) + (string= old-name (car elt))) + (cons new-name (cdr elt))) + (t + elt))) parent-group))) + +(defun newsticker-group-rename-group (old-name new-name) + "Rename group OLD-NAME to NEW-NAME." + (interactive + (list (let* ((completion-ignore-case t)) + (completing-read "Rename group: " + (newsticker--group-names) + nil t (car (newsticker--group-find-parent-group + newsticker--treeview-current-feed)))) + (read-string "Rename to: "))) + (setq newsticker-groups (newsticker--group-do-rename-group old-name new-name)) + (newsticker--group-manage-orphan-feeds) + (newsticker--treeview-tree-update) + (newsticker-treeview-update) + (newsticker-treeview-jump newsticker--treeview-current-feed)) + +(defun newsticker--get-group-names (lst) + "Do get the group names from LST." + (delete nil (cons (car lst) + (apply 'append + (mapcar (lambda (e) + (cond ((listp e) + (newsticker--get-group-names e)) + (t + nil))) + (cdr lst)))))) + +(defun newsticker--group-names () + "Get names of all newsticker groups." + (newsticker--get-group-names newsticker-groups)) (defun newsticker-group-move-feed (name group-name &optional no-update) "Move feed NAME to group GROUP-NAME. Update treeview afterwards unless NO-UPDATE is non-nil." (interactive (let ((completion-ignore-case t)) - (list (completing-read "Feed Name: " - (mapcar 'car newsticker-url-list) + (list (completing-read "Name of feed or group to move: " + (append (mapcar 'car newsticker-url-list) + (newsticker--group-names)) nil t newsticker--treeview-current-feed) - (completing-read "Group Name: " (newsticker--group-all-groups) + (completing-read "Name of new parent group: " (newsticker--group-names) nil t)))) - (let ((group (if (and group-name (not (string= group-name ""))) - (newsticker--group-get-group group-name) - newsticker-groups))) + (let* ((group (if (and group-name (not (string= group-name ""))) + (newsticker--group-get-group group-name) + newsticker-groups)) + (moving-group-p (member name (newsticker--group-names))) + (moved-thing (if moving-group-p + (newsticker--group-get-group name) + name))) (unless group (error "Group %s does not exist" group-name)) (while (let ((old-group - (newsticker--group-find-group-for-feed name))) + (newsticker--group-find-parent-group name))) (when old-group - (delete name old-group)) + (delete moved-thing old-group)) old-group)) - (setcdr group (cons name (cdr group))) + (setcdr group (cons moved-thing (cdr group))) (unless no-update (newsticker--treeview-tree-update) - (newsticker-treeview-update)))) - -(defun newsticker-group-delete-group (name) - "Remove group NAME." - (interactive - (let ((completion-ignore-case t)) - (list (completing-read "Group Name: " (newsticker--group-all-groups) - nil t)))) - (let* ((g (newsticker--group-get-group name)) - (p (or (newsticker--group-get-parent-group name) - newsticker-groups))) - (unless g - (error "Group %s does not exist" name)) - (delete g p)) - (newsticker--treeview-tree-update)) + (newsticker-treeview-update) + (newsticker-treeview-jump name)))) + +(defun newsticker-group-shift-feed-down () + "Shift current feed down in its group." + (interactive) + (newsticker--group-shift 1)) + +(defun newsticker-group-shift-feed-up () + "Shift current feed down in its group." + (interactive) + (newsticker--group-shift -1)) + +(defun newsticker-group-shift-group-down () + "Shift current group down in its group." + (interactive) + (newsticker--group-shift 1 t)) + +(defun newsticker-group-shift-group-up () + "Shift current group down in its group." + (interactive) + (newsticker--group-shift -1 t)) + +(defun newsticker--group-shift (delta &optional move-group) + "Shift current feed or group within its parent group. +DELTA is an integer which specifies the direction and the amount +of the shift. If MOVE-GROUP is nil the currently selected feed +`newsticker--treeview-current-feed' is shifted, if it is t then +the current feed's parent group is shifted.." + (let* ((cur-feed newsticker--treeview-current-feed) + (thing (if move-group + (newsticker--group-find-parent-group cur-feed) + cur-feed)) + (parent-group (newsticker--group-find-parent-group + (if move-group (car thing) thing)))) + (unless parent-group + (error "Group not found!")) + (let* ((siblings (cdr parent-group)) + (pos (cl-position thing siblings :test 'equal)) + (tpos (+ pos delta )) + (new-pos (max 0 (min (length siblings) tpos))) + (beg (cl-subseq siblings 0 (min pos new-pos))) + (end (cl-subseq siblings (+ 1 (max pos new-pos)))) + (p (elt siblings new-pos))) + (when (not (= pos new-pos)) + (setcdr parent-group + (cl-concatenate 'list + beg + (if (> delta 0) + (list p thing) + (list thing p)) + end)) + (newsticker--treeview-tree-update) + (newsticker-treeview-update) + (newsticker-treeview-jump cur-feed))))) (defun newsticker--count-groups (group) "Recursively count number of subgroups of GROUP." @@ -1812,7 +1911,7 @@ (let ((new-feed nil) (grouped-feeds (newsticker--count-grouped-feeds newsticker-groups))) (mapc (lambda (f) - (unless (newsticker--group-find-group-for-feed (car f)) + (unless (newsticker--group-find-parent-group (car f)) (setq new-feed t) (newsticker-group-move-feed (car f) nil t))) (append newsticker-url-list-defaults newsticker-url-list)) @@ -1914,6 +2013,12 @@ ;;(define-key map "\C-m" 'newsticker-treeview-scroll-item) (define-key map "\M-m" 'newsticker-group-move-feed) (define-key map "\M-a" 'newsticker-group-add-group) + (define-key map "\M-d" 'newsticker-group-delete-group) + (define-key map "\M-r" 'newsticker-group-rename-group) + (define-key map [M-down] 'newsticker-group-shift-feed-down) + (define-key map [M-up] 'newsticker-group-shift-feed-up) + (define-key map [M-S-down] 'newsticker-group-shift-group-down) + (define-key map [M-S-up] 'newsticker-group-shift-group-up) map) "Mode map for newsticker treeview.") @@ -1972,10 +2077,10 @@ (newsticker-treeview-show-item)) (t ;; click in tree buffer - (let ((w (newsticker--treeview-get-node nt-id))) + (let ((w (newsticker--treeview-get-node-by-id nt-id))) (when w (newsticker--treeview-tree-update-tag w t t) - (setq w (newsticker--treeview-get-node nt-id)) + (setq w (newsticker--treeview-get-node-by-id nt-id)) (widget-put w :nt-selected t) (widget-apply w :action event) (newsticker--treeview-set-current-node w)))))) === modified file 'test/ChangeLog' --- test/ChangeLog 2014-09-09 14:50:32 +0000 +++ test/ChangeLog 2014-09-24 17:33:54 +0000 @@ -1,3 +1,9 @@ +2014-09-24 Ulf Jasper + + * automated/newsticker-tests.el + (newsticker--group-find-parent-group), + (newsticker--group-do-rename-group): New tests. + 2014-09-09 Eli Zaretskii * automated/fns-tests.el (fns-tests-collate-sort): Bind === modified file 'test/automated/newsticker-tests.el' --- test/automated/newsticker-tests.el 2014-01-01 07:43:34 +0000 +++ test/automated/newsticker-tests.el 2014-09-24 17:33:54 +0000 @@ -143,6 +143,26 @@ (should (equal '("Feeds" "feed3" "feed2" "feed1") newsticker-groups)))) +(ert-deftest newsticker--group-find-parent-group () + "Test `newsticker--group-find-parent-group'." + (let ((newsticker-groups '("g1" "f1a" ("g2" "f2" ("g3" "f3a" "f3b")) "f1b"))) + ;; feeds + (should (equal "g1" (car (newsticker--group-find-parent-group "f1a")))) + (should (equal "g1" (car (newsticker--group-find-parent-group "f1b")))) + (should (equal "g2" (car (newsticker--group-find-parent-group "f2")))) + (should (equal "g3" (car (newsticker--group-find-parent-group "f3b")))) + ;; groups + (should (equal "g1" (car (newsticker--group-find-parent-group "g2")))) + (should (equal "g2" (car (newsticker--group-find-parent-group "g3")))))) + +(ert-deftest newsticker--group-do-rename-group () + "Test `newsticker--group-do-rename-group'." + (let ((newsticker-groups '("g1" "f1a" ("g2" "f2" ("g3" "f3a" "f3b")) "f1b"))) + (should (equal '("g1" "f1a" ("h2" "f2" ("g3" "f3a" "f3b")) "f1b") + (newsticker--group-do-rename-group "g2" "h2"))) + )) + + (provide 'newsticker-tests) ;;; newsticker-tests.el ends here ------------------------------------------------------------ revno: 117936 author: Ken Brown committer: Dmitry Antipov branch nick: trunk timestamp: Wed 2014-09-24 17:42:42 +0400 message: * lisp.h (toplevel) [!USE_STACK_LISP_OBJECTS]: Fix poorly nested conditions (Bug#18544). diff: === modified file 'src/lisp.h' --- src/lisp.h 2014-09-24 11:59:13 +0000 +++ src/lisp.h 2014-09-24 13:42:42 +0000 @@ -289,10 +289,10 @@ describes an issues with 32-bit MS-Windows. */ #ifndef USE_STACK_LISP_OBJECTS # if defined (GNU_LINUX) && defined (__GNUC__) && !defined (__clang__) -# define USE_STACK_LISP_OBJECTS true +# define USE_STACK_LISP_OBJECTS true +# else +# define USE_STACK_LISP_OBJECTS false # endif -#else -# define USE_STACK_LISP_OBJECTS false #endif #if defined HAVE_STRUCT_ATTRIBUTE_ALIGNED && USE_STACK_LISP_OBJECTS ------------------------------------------------------------ revno: 117935 committer: Dmitry Antipov branch nick: trunk timestamp: Wed 2014-09-24 15:59:13 +0400 message: * lisp.h (USE_STACK_LISP_OBJECTS): Enable by default if GNU_LINUX && __GNUC__ && !__clang__. Mention known problems. Adjust comment. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-24 11:11:14 +0000 +++ src/ChangeLog 2014-09-24 11:59:13 +0000 @@ -36,6 +36,9 @@ (font_delete_unmatched): Use local_cons but respect MAX_ALLOCA. * keymap.c (append_key): Use scoped_list1. + * lisp.h (USE_STACK_LISP_OBJECTS): Enable by default if GNU_LINUX + && __GNUC__ && !__clang__. Mention known problems. Adjust comment. + 2014-09-24 Paul Eggert Fix some slow uses and misuses of strcat. === modified file 'src/lisp.h' --- src/lisp.h 2014-09-23 17:03:48 +0000 +++ src/lisp.h 2014-09-24 11:59:13 +0000 @@ -282,7 +282,16 @@ # endif #endif +/* This should work on GNU/Linux with GCC. Other configurations may be + problematic and/or not tested yet. Clang is known to have problems, + see http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00506.html. + Also http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00422.html + describes an issues with 32-bit MS-Windows. */ #ifndef USE_STACK_LISP_OBJECTS +# if defined (GNU_LINUX) && defined (__GNUC__) && !defined (__clang__) +# define USE_STACK_LISP_OBJECTS true +# endif +#else # define USE_STACK_LISP_OBJECTS false #endif @@ -4581,8 +4590,10 @@ better performance because GC is not involved. This feature is experimental and requires careful debugging. - Brave users can compile with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS' - to get into the game. */ + It's enabled by default on GNU/Linux with GCC. On other systems, + brave users can compile with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS' + to get into the game. Also note that this feature requires + GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS. */ /* A struct Lisp_Cons inside a union that is no larger and may be better-aligned. */ ------------------------------------------------------------ revno: 117934 committer: Dmitry Antipov branch nick: trunk timestamp: Wed 2014-09-24 15:11:14 +0400 message: * chartab.c (uniprop_encode_value_numeric): * font.c (font_style_to_value): Use make_local_vector. (font_delete_unmatched): Use local_cons but respect MAX_ALLOCA. * keymap.c (append_key): Use scoped_list1. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-24 10:06:53 +0000 +++ src/ChangeLog 2014-09-24 11:11:14 +0000 @@ -31,6 +31,11 @@ (x_send_scroll_bar_event, xm_scroll_callback, xg_scroll_callback): Prefer enum and explicit enum members to integers and numeric values. + * chartab.c (uniprop_encode_value_numeric): + * font.c (font_style_to_value): Use make_local_vector. + (font_delete_unmatched): Use local_cons but respect MAX_ALLOCA. + * keymap.c (append_key): Use scoped_list1. + 2014-09-24 Paul Eggert Fix some slow uses and misuses of strcat. === modified file 'src/chartab.c' --- src/chartab.c 2014-09-15 14:53:23 +0000 +++ src/chartab.c 2014-09-24 11:11:14 +0000 @@ -1258,13 +1258,8 @@ break; value = make_number (i); if (i == size) - { - Lisp_Object args[2]; - - args[0] = XCHAR_TABLE (table)->extras[4]; - args[1] = Fmake_vector (make_number (1), value); - set_char_table_extras (table, 4, Fvconcat (2, args)); - } + set_char_table_extras (table, 4, Fvconcat (2, ((Lisp_Object []) { + XCHAR_TABLE (table)->extras[4], make_local_vector (1, value) }))); return make_number (i); } === modified file 'src/font.c' --- src/font.c 2014-09-23 17:03:48 +0000 +++ src/font.c 2014-09-24 11:11:14 +0000 @@ -367,7 +367,7 @@ { int i, j; char *s; - Lisp_Object args[2], elt; + Lisp_Object elt; /* At first try exact match. */ for (i = 0; i < len; i++) @@ -399,9 +399,9 @@ eassert (len < 255); elt = Fmake_vector (make_number (2), make_number (100)); ASET (elt, 1, val); - args[0] = table; - args[1] = Fmake_vector (make_number (1), elt); - ASET (font_style_table, prop - FONT_WEIGHT_INDEX, Fvconcat (2, args)); + ASET (font_style_table, prop - FONT_WEIGHT_INDEX, + Fvconcat (2, ((Lisp_Object []) + { table, make_local_vector (1, elt) }))); return (100 << 8) | (i << 4); } else @@ -2685,7 +2685,9 @@ { Lisp_Object entity, val; enum font_property_index prop; - int i; + /* If USE_STACK_LISP_OBJECTS, MAX is used to avoid unbounded alloca. */ + ptrdiff_t i, max + = (USE_STACK_LISP_OBJECTS ? MAX_ALLOCA / sizeof (struct Lisp_Cons) : 0); for (val = Qnil, i = ASIZE (vec) - 1; i >= 0; i--) { @@ -2713,7 +2715,7 @@ } if (NILP (spec)) { - val = Fcons (entity, val); + val = --max > 0 ? local_cons (entity, val) : Fcons (entity, val); continue; } for (prop = FONT_WEIGHT_INDEX; prop < FONT_SIZE_INDEX; prop++) @@ -2744,7 +2746,7 @@ AREF (entity, FONT_AVGWIDTH_INDEX))) prop = FONT_SPEC_MAX; if (prop < FONT_SPEC_MAX) - val = Fcons (entity, val); + val = --max > 0 ? local_cons (entity, val) : Fcons (entity, val); } return (Fvconcat (1, &val)); } === modified file 'src/keymap.c' --- src/keymap.c 2014-09-15 14:53:23 +0000 +++ src/keymap.c 2014-09-24 11:11:14 +0000 @@ -1299,11 +1299,7 @@ static Lisp_Object append_key (Lisp_Object key_sequence, Lisp_Object key) { - Lisp_Object args[2]; - - args[0] = key_sequence; - args[1] = list1 (key); - return Fvconcat (2, args); + return Fvconcat (2, ((Lisp_Object []) { key_sequence, scoped_list1 (key) })); } /* Given a event type C which is a symbol, ------------------------------------------------------------ revno: 117933 committer: Eli Zaretskii branch nick: trunk timestamp: Wed 2014-09-24 13:06:53 +0300 message: Fix fallout on MinGW64 from the previous commit. src/systime.h (Time): Define as size_t, to be consistent with 64-bit Windows builds, where 'long' is a 32-bit type. src/w32inevt.h (w32_console_mouse_position): Update the argument types to use 'Time'. src/w32term.c (w32_mouse_position) (x_horizontal_scroll_bar_report_motion) (x_scroll_bar_report_motion): Update the argument types to use 'Time'. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-24 07:17:51 +0000 +++ src/ChangeLog 2014-09-24 10:06:53 +0000 @@ -1,3 +1,16 @@ +2014-09-24 Eli Zaretskii + + * systime.h (Time): Define as size_t, to be consistent with 64-bit + Windows builds, where 'long' is a 32-bit type. + + * w32inevt.h (w32_console_mouse_position): Update the argument + types to use 'Time'. + + * w32term.c (w32_mouse_position) + (x_horizontal_scroll_bar_report_motion) + (x_scroll_bar_report_motion): Update the argument types to use + 'Time'. + 2014-09-24 Dmitry Antipov * termhooks.h (enum scroll_bar_part): Begin from 0 to allow... === modified file 'src/systime.h' --- src/systime.h 2014-01-01 07:43:34 +0000 +++ src/systime.h 2014-09-24 10:06:53 +0000 @@ -19,6 +19,7 @@ #ifndef EMACS_SYSTIME_H #define EMACS_SYSTIME_H +#include #include INLINE_HEADER_BEGIN @@ -27,7 +28,7 @@ # ifdef HAVE_X_WINDOWS # include # else -typedef unsigned long Time; +typedef size_t Time; # endif #endif === modified file 'src/w32inevt.h' --- src/w32inevt.h 2014-01-01 07:43:34 +0000 +++ src/w32inevt.h 2014-09-24 10:06:53 +0000 @@ -27,6 +27,6 @@ Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, - unsigned long *time); + Time *time); #endif /* EMACS_W32INEVT_H */ === modified file 'src/w32term.c' --- src/w32term.c 2014-09-24 07:17:51 +0000 +++ src/w32term.c 2014-09-24 10:06:53 +0000 @@ -3344,11 +3344,11 @@ static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, enum scroll_bar_part *, Lisp_Object *, Lisp_Object *, - unsigned long *); + Time *); static void x_horizontal_scroll_bar_report_motion (struct frame **, Lisp_Object *, enum scroll_bar_part *, Lisp_Object *, Lisp_Object *, - unsigned long *); + Time *); static void x_check_fullscreen (struct frame *); static void @@ -3380,7 +3380,7 @@ static void w32_mouse_position (struct frame **fp, int insist, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, - unsigned long *time) + Time *time) { struct frame *f1; struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp); @@ -4374,7 +4374,7 @@ x_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, - unsigned long *time) + Time *time) { struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp); struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar; @@ -4424,7 +4424,7 @@ x_horizontal_scroll_bar_report_motion (struct frame **fp, Lisp_Object *bar_window, enum scroll_bar_part *part, Lisp_Object *x, Lisp_Object *y, - unsigned long *time) + Time *time) { struct w32_display_info *dpyinfo = FRAME_DISPLAY_INFO (*fp); struct scroll_bar *bar = dpyinfo->last_mouse_scroll_bar; ------------------------------------------------------------ revno: 117932 committer: Dmitry Antipov branch nick: trunk timestamp: Wed 2014-09-24 11:17:51 +0400 message: * termhooks.h (enum scroll_bar_part): Begin from 0 to allow... (struct input_event): ...unsigned bitfields. Likewise for `event_kind' member. Prefer unsigned for `code' and 'modifiers'. Use `timestamp' for HELP_EVENT position. Add compile-time assert. * keyboard.c (gen_help_event, kbd_buffer_store_help_event) (kbd_buffer_get_event): Adjust users. (scroll_bar_parts): Add Qnil to match scroll_bar_nowhere. (make_scroll_bar_position): New function, refactored out of... (make_lispy_event): ...adjusted user. * nsterm.h (EmacsScroller): Use enum for `last_hit_part' member. * nsterm.m (ns_mouse_position, mouseUp): * term.c (term_mouse_position): * w32inevt.c (w32_console_mouse_position): * w32term.c (w32_mouse_position): * xterm.c (XTmouse_position): Use scroll_bar_above_handle. (x_send_scroll_bar_event, xm_scroll_callback, xg_scroll_callback): Prefer enum and explicit enum members to integers and numeric values. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-24 04:12:37 +0000 +++ src/ChangeLog 2014-09-24 07:17:51 +0000 @@ -1,3 +1,23 @@ +2014-09-24 Dmitry Antipov + + * termhooks.h (enum scroll_bar_part): Begin from 0 to allow... + (struct input_event): ...unsigned bitfields. Likewise for + `event_kind' member. Prefer unsigned for `code' and 'modifiers'. + Use `timestamp' for HELP_EVENT position. Add compile-time assert. + * keyboard.c (gen_help_event, kbd_buffer_store_help_event) + (kbd_buffer_get_event): Adjust users. + (scroll_bar_parts): Add Qnil to match scroll_bar_nowhere. + (make_scroll_bar_position): New function, refactored out of... + (make_lispy_event): ...adjusted user. + * nsterm.h (EmacsScroller): Use enum for `last_hit_part' member. + * nsterm.m (ns_mouse_position, mouseUp): + * term.c (term_mouse_position): + * w32inevt.c (w32_console_mouse_position): + * w32term.c (w32_mouse_position): + * xterm.c (XTmouse_position): Use scroll_bar_above_handle. + (x_send_scroll_bar_event, xm_scroll_callback, xg_scroll_callback): + Prefer enum and explicit enum members to integers and numeric values. + 2014-09-24 Paul Eggert Fix some slow uses and misuses of strcat. === modified file 'src/keyboard.c' --- src/keyboard.c 2014-09-16 08:20:08 +0000 +++ src/keyboard.c 2014-09-24 07:17:51 +0000 @@ -3747,14 +3747,12 @@ { struct input_event event; - EVENT_INIT (event); - event.kind = HELP_EVENT; event.frame_or_window = frame; event.arg = object; event.x = WINDOWP (window) ? window : frame; event.y = help; - event.code = pos; + event.timestamp = pos; kbd_buffer_store_event (&event); } @@ -3771,7 +3769,7 @@ event.arg = Qnil; event.x = Qnil; event.y = help; - event.code = 0; + event.timestamp = 0; kbd_buffer_store_event (&event); } @@ -4086,7 +4084,7 @@ frame = event->frame_or_window; object = event->arg; - position = make_number (event->code); + position = make_number (event->timestamp); window = event->x; help = event->y; clear_event (event); @@ -5201,9 +5199,11 @@ static Lisp_Object Qend_scroll; static Lisp_Object Qratio; -/* An array of scroll bar parts, indexed by an enum scroll_bar_part value. */ +/* An array of scroll bar parts, indexed by an enum scroll_bar_part value. + Note that Qnil corresponds to scroll_bar_nowhere and should not appear + in Lisp events. */ static Lisp_Object *const scroll_bar_parts[] = { - &Qabove_handle, &Qhandle, &Qbelow_handle, + &Qnil, &Qabove_handle, &Qhandle, &Qbelow_handle, &Qup, &Qdown, &Qtop, &Qbottom, &Qend_scroll, &Qratio, &Qbefore_handle, &Qhorizontal_handle, &Qafter_handle, &Qleft, &Qright, &Qleftmost, &Qrightmost, &Qend_scroll, &Qratio @@ -5450,6 +5450,16 @@ #endif } +/* Build the part of Lisp event which represents scroll bar state from + EV. TYPE is one of Qvertical_scroll_bar or Qhorizontal_scroll_bar. */ + +static Lisp_Object +make_scroll_bar_position (struct input_event *ev, Lisp_Object type) +{ + return list5 (ev->frame_or_window, type, Fcons (ev->x, ev->y), + make_number (ev->timestamp), *scroll_bar_parts[ev->part]); +} + /* Given a struct input_event, build the lisp event which represents it. If EVENT is 0, build a mouse movement event from the mouse movement buffer, which should have a movement event in it. @@ -5667,20 +5677,8 @@ } #ifndef USE_TOOLKIT_SCROLL_BARS else - { - /* It's a scrollbar click. */ - Lisp_Object window; - Lisp_Object portion_whole; - Lisp_Object part; - - window = event->frame_or_window; - portion_whole = Fcons (event->x, event->y); - part = *scroll_bar_parts[(int) event->part]; - - position = list5 (window, Qvertical_scroll_bar, - portion_whole, make_number (event->timestamp), - part); - } + /* It's a scrollbar click. */ + position = make_scroll_bar_position (event, Qvertical_scroll_bar); #endif /* not USE_TOOLKIT_SCROLL_BARS */ if (button >= ASIZE (button_down_location)) @@ -5957,14 +5955,9 @@ case SCROLL_BAR_CLICK_EVENT: { - Lisp_Object position, head, window, portion_whole, part; - - window = event->frame_or_window; - portion_whole = Fcons (event->x, event->y); - part = *scroll_bar_parts[(int) event->part]; - - position = list5 (window, Qvertical_scroll_bar, portion_whole, - make_number (event->timestamp), part); + Lisp_Object position, head; + + position = make_scroll_bar_position (event, Qvertical_scroll_bar); /* Always treat scroll bar events as clicks. */ event->modifiers |= click_modifier; @@ -5987,14 +5980,9 @@ case HORIZONTAL_SCROLL_BAR_CLICK_EVENT: { - Lisp_Object position, head, window, portion_whole, part; - - window = event->frame_or_window; - portion_whole = Fcons (event->x, event->y); - part = *scroll_bar_parts[(int) event->part]; - - position = list5 (window, Qhorizontal_scroll_bar, portion_whole, - make_number (event->timestamp), part); + Lisp_Object position, head; + + position = make_scroll_bar_position (event, Qhorizontal_scroll_bar); /* Always treat scroll bar events as clicks. */ event->modifiers |= click_modifier; === modified file 'src/nsterm.h' --- src/nsterm.h 2014-07-27 13:21:30 +0000 +++ src/nsterm.h 2014-09-24 07:17:51 +0000 @@ -401,7 +401,7 @@ CGFloat last_mouse_offset; float min_portion; int pixel_height; - int last_hit_part; + enum scroll_bar_part last_hit_part; BOOL condemned; === modified file 'src/nsterm.m' --- src/nsterm.m 2014-09-15 00:20:21 +0000 +++ src/nsterm.m 2014-09-24 07:17:51 +0000 @@ -1930,10 +1930,9 @@ position = [view convertPoint: position fromView: nil]; remember_mouse_glyph (f, position.x, position.y, &dpyinfo->last_mouse_glyph); -/*fprintf (stderr, "ns_mouse_position: %.0f, %.0f\n", position.x, position.y); */ if (bar_window) *bar_window = Qnil; - if (part) *part = 0; /*scroll_bar_handle; */ + if (part) *part = scroll_bar_above_handle; if (x) XSETINT (*x, lrint (position.x)); if (y) XSETINT (*y, lrint (position.y)); @@ -7505,7 +7504,7 @@ [scroll_repeat_entry release]; scroll_repeat_entry = nil; } - last_hit_part = 0; + last_hit_part = scroll_bar_above_handle; } === modified file 'src/term.c' --- src/term.c 2014-09-07 07:04:01 +0000 +++ src/term.c 2014-09-24 07:17:51 +0000 @@ -2540,7 +2540,7 @@ (*fp)->mouse_moved = 0; *bar_window = Qnil; - *part = 0; + *part = scroll_bar_above_handle; XSETINT (*x, last_mouse_x); XSETINT (*y, last_mouse_y); === modified file 'src/termhooks.h' --- src/termhooks.h 2014-07-27 13:21:30 +0000 +++ src/termhooks.h 2014-09-24 07:17:51 +0000 @@ -28,7 +28,7 @@ INLINE_HEADER_BEGIN enum scroll_bar_part { - scroll_bar_nowhere = -1, + scroll_bar_nowhere, scroll_bar_above_handle, scroll_bar_handle, scroll_bar_below_handle, @@ -255,31 +255,42 @@ struct input_event { /* What kind of event was this? */ - enum event_kind kind; + ENUM_BF (event_kind) kind : 16; + + /* Used in scroll back click events. */ + ENUM_BF (scroll_bar_part) part : 16; /* For an ASCII_KEYSTROKE_EVENT and MULTIBYTE_CHAR_KEYSTROKE_EVENT, this is the character. For a NON_ASCII_KEYSTROKE_EVENT, this is the keysym code. - For a mouse event, this is the button number. - For a HELP_EVENT, this is the position within the object - (stored in ARG below) where the help was found. */ - ptrdiff_t code; - enum scroll_bar_part part; - - int modifiers; /* See enum below for interpretation. */ - + For a mouse event, this is the button number. */ + unsigned code; + + /* See enum below for interpretation. */ + unsigned modifiers; + + /* One would prefer C integers, but HELP_EVENT uses these to + record frame or window object and a help form, respectively. */ Lisp_Object x, y; + + /* Usually a time as reported by window system-specific event loop. + For a HELP_EVENT, this is the position within the object (stored + in ARG below) where the help was found. */ Time timestamp; /* This field is copied into a vector while the event is in the queue, so that garbage collections won't kill it. */ Lisp_Object frame_or_window; - /* Additional event argument. This is used for TOOL_BAR_EVENTs and - HELP_EVENTs and avoids calling Fcons during signal handling. */ + /* This additional argument is used in attempt to avoid extra consing + when building events. Unfortunately some events have to pass much + more data than it's reasonable to pack directly into this structure. */ Lisp_Object arg; }; +/* To make sure we don't break HELP_EVENT. */ +verify (sizeof (Time) == sizeof (ptrdiff_t)); + #define EVENT_INIT(event) memset (&(event), 0, sizeof (struct input_event)) /* Bits in the modifiers member of the input_event structure. === modified file 'src/w32inevt.c' --- src/w32inevt.c 2014-07-27 13:21:30 +0000 +++ src/w32inevt.c 2014-09-24 07:17:51 +0000 @@ -411,7 +411,7 @@ *f = get_frame (); *bar_window = Qnil; - *part = 0; + *part = scroll_bar_above_handle; SELECTED_FRAME ()->mouse_moved = 0; XSETINT (*x, movement_pos.X); === modified file 'src/w32term.c' --- src/w32term.c 2014-09-22 19:20:45 +0000 +++ src/w32term.c 2014-09-24 07:17:51 +0000 @@ -3448,7 +3448,7 @@ dpyinfo->last_mouse_glyph_frame = f1; *bar_window = Qnil; - *part = 0; + *part = scroll_bar_above_handle; *fp = f1; XSETINT (*x, pt.x); XSETINT (*y, pt.y); === modified file 'src/xterm.c' --- src/xterm.c 2014-09-23 17:03:48 +0000 +++ src/xterm.c 2014-09-24 07:17:51 +0000 @@ -4157,7 +4157,7 @@ dpyinfo->last_mouse_glyph_frame = f1; *bar_window = Qnil; - *part = 0; + *part = scroll_bar_above_handle; *fp = f1; XSETINT (*x, win_x); XSETINT (*y, win_y); @@ -4250,7 +4250,8 @@ #ifdef USE_TOOLKIT_SCROLL_BARS -static void x_send_scroll_bar_event (Lisp_Object, int, int, int, bool); +static void x_send_scroll_bar_event (Lisp_Object, enum scroll_bar_part, + int, int, bool); /* Lisp window being scrolled. Set when starting to interact with a toolkit scroll bar, reset to nil when ending the interaction. */ @@ -4371,7 +4372,8 @@ amount to scroll of a whole of WHOLE. */ static void -x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole, bool horizontal) +x_send_scroll_bar_event (Lisp_Object window, enum scroll_bar_part part, + int portion, int whole, bool horizontal) { XEvent event; XClientMessageEvent *ev = &event.xclient; @@ -4504,8 +4506,8 @@ { struct scroll_bar *bar = client_data; XmScrollBarCallbackStruct *cs = call_data; - int part = -1, whole = 0, portion = 0; - int horizontal = bar->horizontal; + enum scroll_bar_part part = scroll_bar_nowhere; + int horizontal = bar->horizontal, whole = 0, portion = 0; switch (cs->reason) { @@ -4569,7 +4571,7 @@ break; }; - if (part >= 0) + if (part != scroll_bar_nowhere) { window_being_scrolled = bar->window; x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal); @@ -4587,8 +4589,9 @@ gdouble value, gpointer user_data) { + int whole = 0, portion = 0; struct scroll_bar *bar = user_data; - int part = -1, whole = 0, portion = 0; + enum scroll_bar_part part = scroll_bar_nowhere; GtkAdjustment *adj = GTK_ADJUSTMENT (gtk_range_get_adjustment (range)); struct frame *f = g_object_get_data (G_OBJECT (range), XG_FRAME_DATA); @@ -4641,7 +4644,7 @@ break; } - if (part >= 0) + if (part != scroll_bar_nowhere) { window_being_scrolled = bar->window; x_send_scroll_bar_event (bar->window, part, portion, whole, bar->horizontal); ------------------------------------------------------------ revno: 117931 committer: Paul Eggert branch nick: trunk timestamp: Tue 2014-09-23 21:12:37 -0700 message: Fix some slow uses and misuses of strcat. * doc.c (get_doc_string): * gtkutil.c (get_utf8_string): * xsmfns.c (x_session_initialize): Avoid recomputation of string length. * ftfont.c (ftfont_spec_pattern): * xfns.c (xic_create_fontsetname): Don't assume output buffer is initially zero. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-23 17:03:48 +0000 +++ src/ChangeLog 2014-09-24 04:12:37 +0000 @@ -1,3 +1,14 @@ +2014-09-24 Paul Eggert + + Fix some slow uses and misuses of strcat. + * doc.c (get_doc_string): + * gtkutil.c (get_utf8_string): + * xsmfns.c (x_session_initialize): + Avoid recomputation of string length. + * ftfont.c (ftfont_spec_pattern): + * xfns.c (xic_create_fontsetname): + Don't assume output buffer is initially zero. + 2014-09-23 Paul Eggert * lisp.h (lispstpcpy): Rename from lispstrcpy, and act like stpcpy. === modified file 'src/doc.c' --- src/doc.c 2014-09-23 17:03:48 +0000 +++ src/doc.c 2014-09-24 04:12:37 +0000 @@ -121,8 +121,8 @@ if (minsize < 8) minsize = 8; name = SAFE_ALLOCA (minsize + SCHARS (file) + 8); - lispstpcpy (name, docdir); - strcat (name, SSDATA (file)); + char *z = lispstpcpy (name, docdir); + strcpy (z, SSDATA (file)); } else { === modified file 'src/ftfont.c' --- src/ftfont.c 2014-09-07 07:04:01 +0000 +++ src/ftfont.c 2014-09-24 04:12:37 +0000 @@ -804,7 +804,7 @@ *otspec = ftfont_get_open_type_spec (val); if (! *otspec) return NULL; - strcat (otlayout, "otlayout:"); + strcpy (otlayout, "otlayout:"); OTF_TAG_STR ((*otspec)->script_tag, otlayout + 9); script = (*otspec)->script; } === modified file 'src/gtkutil.c' --- src/gtkutil.c 2014-09-04 16:14:05 +0000 +++ src/gtkutil.c 2014-09-24 04:12:37 +0000 @@ -508,16 +508,16 @@ && err->code == G_CONVERT_ERROR_ILLEGAL_SEQUENCE) { memcpy (up, p, bytes_written); - sprintf (up + bytes_written, "\\%03o", p[bytes_written]); - up += bytes_written+4; - p += bytes_written+1; + up += bytes_written; + up += sprintf (up, "\\%03o", p[bytes_written]); + p += bytes_written + 1; g_error_free (err); err = NULL; } if (cp) { - strcat (utf8_str, cp); + strcpy (up, cp); g_free (cp); } if (err) === modified file 'src/xfns.c' --- src/xfns.c 2014-09-23 17:03:48 +0000 +++ src/xfns.c 2014-09-24 04:12:37 +0000 @@ -1786,7 +1786,7 @@ len = p - base_fontname + strlen (allcs) + 1; font_allcs = alloca (len); memcpy (font_allcs, base_fontname, p - base_fontname); - strcat (font_allcs, allcs); + strcpy (font_allcs + (p - base_fontname), allcs); /* Build the font spec that matches all families and add-styles. */ @@ -1794,7 +1794,7 @@ font_allfamilies = alloca (len); strcpy (font_allfamilies, allfamilies); memcpy (font_allfamilies + strlen (allfamilies), p1, p - p1); - strcat (font_allfamilies, allcs); + strcpy (font_allfamilies + strlen (allfamilies) + (p - p1), allcs); /* Build the font spec that matches all. */ len = p - p2 + strlen (allcs) + strlen (all) + strlen (allfamilies) + 1; @@ -1802,7 +1802,8 @@ strcpy (font_all, allfamilies); strcat (font_all, all); memcpy (font_all + strlen (all) + strlen (allfamilies), p2, p - p2); - strcat (font_all, allcs); + strcpy (font_all + strlen (all) + strlen (allfamilies) + (p - p2), + allcs); /* Build the actual font set name. */ len = strlen (base_fontname) + strlen (font_allcs) === modified file 'src/xsmfns.c' --- src/xsmfns.c 2014-09-23 17:03:48 +0000 +++ src/xsmfns.c 2014-09-24 04:12:37 +0000 @@ -415,11 +415,11 @@ /* This malloc will not be freed, but it is only done once, and hopefully not very large */ emacs_program = xmalloc (name_len + 1); - emacs_program[0] = '\0'; + char *z = emacs_program; if (! EQ (Vinvocation_directory, Qnil)) - lispstpcpy (emacs_program, Vinvocation_directory); - strcat (emacs_program, SSDATA (Vinvocation_name)); + z = lispstpcpy (z, Vinvocation_directory); + lispstpcpy (z, Vinvocation_name); /* The SM protocol says all callbacks are mandatory, so set up all here and in the mask passed to SmcOpenConnection. */ ------------------------------------------------------------ revno: 117930 committer: Paul Eggert branch nick: trunk timestamp: Tue 2014-09-23 12:21:54 -0700 message: movemail: don't dump core if the current time is outlandish * movemail.c (popmail): Check for mbx_delimit_begin failure. (mbx_delimit_begin): Fail if the current time is so outlandish that localtime would fail or asctime would have undefined behavior. Use strftime to avoid asctime undefined behavior. diff: === modified file 'lib-src/ChangeLog' --- lib-src/ChangeLog 2014-09-01 09:54:12 +0000 +++ lib-src/ChangeLog 2014-09-23 19:21:54 +0000 @@ -1,3 +1,11 @@ +2014-09-23 Paul Eggert + + movemail: don't dump core if the current time is outlandish + * movemail.c (popmail): Check for mbx_delimit_begin failure. + (mbx_delimit_begin): Fail if the current time is so outlandish + that localtime would fail or asctime would have undefined + behavior. Use strftime to avoid asctime undefined behavior. + 2014-09-01 Paul Eggert --enable-silent-rules now suppresses more chatter. === modified file 'lib-src/movemail.c' --- lib-src/movemail.c 2014-07-14 19:23:18 +0000 +++ lib-src/movemail.c 2014-09-23 19:21:54 +0000 @@ -714,8 +714,8 @@ for (i = start; i * increment <= end * increment; i += increment) { - mbx_delimit_begin (mbf); - if (pop_retr (server, i, mbf) != OK) + if (mbx_delimit_begin (mbf) != OK + || pop_retr (server, i, mbf) != OK) { error ("%s", Errmsg, 0); close (mbfi); @@ -832,15 +832,15 @@ static int mbx_delimit_begin (FILE *mbf) { - time_t now; - struct tm *ltime; - char fromline[40] = "From movemail "; - - now = time (NULL); - ltime = localtime (&now); - - strcat (fromline, asctime (ltime)); - + time_t now = time (NULL); + struct tm *ltime = localtime (&now); + if (!ltime) + return NOTOK; + + char fromline[100]; + if (! strftime (fromline, sizeof fromline, + "From movemail %a %b %e %T %Y\n", ltime)) + return NOTOK; if (fputs (fromline, mbf) == EOF) return (NOTOK); return (OK); ------------------------------------------------------------ revno: 117929 committer: Paul Eggert branch nick: trunk timestamp: Tue 2014-09-23 11:20:38 -0700 message: Merge from gnulib. This incorporates: 2014-09-11 fcntl-h: fix compilation with Intel C++ compiler 2014-09-04 pthread, pthread_sigmask, threadlib: port to Ubuntu 14.04 diff: === modified file 'ChangeLog' --- ChangeLog 2014-09-22 19:20:45 +0000 +++ ChangeLog 2014-09-23 18:20:38 +0000 @@ -1,3 +1,9 @@ +2014-09-23 Paul Eggert + + Merge from gnulib, incorporating: + 2014-09-11 fcntl-h: fix compilation with Intel C++ compiler + 2014-09-04 pthread, pthread_sigmask, threadlib: port to Ubuntu 14.04 + 2014-09-22 Jan Djärv * configure.ac: Increase headerpad_extra to 1000, update the comment === modified file 'lib/fcntl.in.h' --- lib/fcntl.in.h 2014-06-15 00:06:30 +0000 +++ lib/fcntl.in.h 2014-09-23 18:20:38 +0000 @@ -34,7 +34,7 @@ extern "C" { ... } block, which leads to errors in C++ mode with the overridden from gnulib. These errors are known to be gone with g++ version >= 4.3. */ -#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) +#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && (defined __ICC || !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))) # include #endif #@INCLUDE_NEXT@ @NEXT_FCNTL_H@ @@ -53,7 +53,7 @@ extern "C" { ... } block, which leads to errors in C++ mode with the overridden from gnulib. These errors are known to be gone with g++ version >= 4.3. */ -#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))) +#if !(defined __GLIBC__ || defined __UCLIBC__) || (defined __cplusplus && defined GNULIB_NAMESPACE && (defined __ICC || !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))) # include #endif /* The include_next requires a split double-inclusion guard. */ === modified file 'm4/pthread_sigmask.m4' --- m4/pthread_sigmask.m4 2014-05-29 15:05:06 +0000 +++ m4/pthread_sigmask.m4 2014-09-23 18:20:38 +0000 @@ -1,4 +1,4 @@ -# pthread_sigmask.m4 serial 14 +# pthread_sigmask.m4 serial 15 dnl Copyright (C) 2011-2014 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -40,7 +40,7 @@ LIBS="$gl_save_LIBS" ]) if test $gl_cv_func_pthread_sigmask_in_LIBMULTITHREAD = yes; then - dnl pthread_sigmask is available with -lpthread. + dnl pthread_sigmask is available with -pthread or -lpthread. LIB_PTHREAD_SIGMASK="$LIBMULTITHREAD" else dnl pthread_sigmask is not available at all. @@ -86,7 +86,7 @@ AC_SUBST([LIB_PTHREAD_SIGMASK]) dnl We don't need a variable LTLIB_PTHREAD_SIGMASK, because when dnl "$gl_threads_api" = posix, $LTLIBMULTITHREAD and $LIBMULTITHREAD are the - dnl same: either both empty or both "-lpthread". + dnl same. dnl Now test for some bugs in the system function. if test $HAVE_PTHREAD_SIGMASK = 1; then @@ -98,6 +98,7 @@ dnl no effect. if test -z "$LIB_PTHREAD_SIGMASK"; then case " $LIBS " in + *' -pthread '*) ;; *' -lpthread '*) ;; *) AC_CACHE_CHECK([whether pthread_sigmask works without -lpthread], ------------------------------------------------------------ revno: 117928 committer: Paul Eggert branch nick: trunk timestamp: Tue 2014-09-23 10:03:48 -0700 message: * lisp.h (lispstpcpy): Rename from lispstrcpy, and act like stpcpy. All callers changed. * xterm.c (x_term_init): Use new functionality to avoid two needs to compute a string length. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-23 16:07:23 +0000 +++ src/ChangeLog 2014-09-23 17:03:48 +0000 @@ -1,5 +1,10 @@ 2014-09-23 Paul Eggert + * lisp.h (lispstpcpy): Rename from lispstrcpy, and act like stpcpy. + All callers changed. + * xterm.c (x_term_init): Use new functionality to avoid two needs + to compute a string length. + * dispextern.h, xdisp.c (window_box_right_offset): Now static. 2014-09-23 Dmitry Antipov === modified file 'src/callproc.c' --- src/callproc.c 2014-09-23 15:49:00 +0000 +++ src/callproc.c 2014-09-23 17:03:48 +0000 @@ -1235,7 +1235,7 @@ #endif temp = pwd_var + 4; memcpy (pwd_var, "PWD=", 4); - lispstrcpy (temp, current_dir); + lispstpcpy (temp, current_dir); #ifndef DOS_NT /* We can't signal an Elisp error here; we're in a vfork. Since === modified file 'src/dbusbind.c' --- src/dbusbind.c 2014-09-23 15:49:00 +0000 +++ src/dbusbind.c 2014-09-23 17:03:48 +0000 @@ -761,7 +761,7 @@ && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object))) && NILP (CDR_SAFE (XD_NEXT_VALUE (object)))) { - lispstrcpy (signature, CAR_SAFE (XD_NEXT_VALUE (object))); + lispstpcpy (signature, CAR_SAFE (XD_NEXT_VALUE (object))); object = CDR_SAFE (XD_NEXT_VALUE (object)); } === modified file 'src/doc.c' --- src/doc.c 2014-09-23 15:49:00 +0000 +++ src/doc.c 2014-09-23 17:03:48 +0000 @@ -121,7 +121,7 @@ if (minsize < 8) minsize = 8; name = SAFE_ALLOCA (minsize + SCHARS (file) + 8); - lispstrcpy (name, docdir); + lispstpcpy (name, docdir); strcat (name, SSDATA (file)); } else === modified file 'src/font.c' --- src/font.c 2014-09-23 15:49:00 +0000 +++ src/font.c 2014-09-23 17:03:48 +0000 @@ -4266,7 +4266,7 @@ { if (NILP (fold_wildcards)) return font_name; - lispstrcpy (name, font_name); + lispstpcpy (name, font_name); namelen = SBYTES (font_name); goto done; } === modified file 'src/frame.c' --- src/frame.c 2014-09-23 15:49:00 +0000 +++ src/frame.c 2014-09-23 17:03:48 +0000 @@ -4036,8 +4036,8 @@ /* Start with emacs.FRAMENAME for the name (the specific one) and with `Emacs' for the class key (the general one). */ - lispstrcpy (name_key, Vx_resource_name); - lispstrcpy (class_key, Vx_resource_class); + lispstpcpy (name_key, Vx_resource_name); + lispstpcpy (class_key, Vx_resource_class); strcat (class_key, "."); strcat (class_key, SSDATA (class)); === modified file 'src/lisp.h' --- src/lisp.h 2014-09-23 15:49:00 +0000 +++ src/lisp.h 2014-09-23 17:03:48 +0000 @@ -4463,12 +4463,15 @@ extern char *xlispstrdup (Lisp_Object) ATTRIBUTE_MALLOC; extern void dupstring (char **, char const *); -/* Like strcpy but uses known length of a Lisp string. */ +/* Make DEST a copy of STRING's data. Return a pointer to DEST's terminating + null byte. This is like stpcpy, except the source is a Lisp string. */ INLINE char * -lispstrcpy (const char *dest, Lisp_Object string) +lispstpcpy (char *dest, Lisp_Object string) { - return memcpy ((void *) dest, SSDATA (string), SBYTES (string) + 1); + ptrdiff_t len = SBYTES (string); + memcpy (dest, SDATA (string), len + 1); + return dest + len; } extern void xputenv (const char *); === modified file 'src/process.c' --- src/process.c 2014-09-23 15:49:00 +0000 +++ src/process.c 2014-09-23 17:03:48 +0000 @@ -2989,7 +2989,7 @@ address_un.sun_family = AF_LOCAL; if (sizeof address_un.sun_path <= SBYTES (service)) error ("Service name too long"); - lispstrcpy (address_un.sun_path, service); + lispstpcpy (address_un.sun_path, service); ai.ai_addr = (struct sockaddr *) &address_un; ai.ai_addrlen = sizeof address_un; goto open_socket; @@ -3680,7 +3680,7 @@ if (sizeof rq.ifr_name <= SBYTES (ifname)) error ("interface name too long"); - lispstrcpy (rq.ifr_name, ifname); + lispstpcpy (rq.ifr_name, ifname); s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); if (s < 0) === modified file 'src/w32fns.c' --- src/w32fns.c 2014-09-23 15:49:00 +0000 +++ src/w32fns.c 2014-09-23 17:03:48 +0000 @@ -5339,7 +5339,7 @@ { char basename[ MAX_PATH ], *str; - lispstrcpy (basename, Vinvocation_name); + lispstpcpy (basename, Vinvocation_name); str = strrchr (basename, '.'); if (str) *str = 0; Vinvocation_name = build_string (basename); === modified file 'src/w32proc.c' --- src/w32proc.c 2014-09-23 15:49:00 +0000 +++ src/w32proc.c 2014-09-23 17:03:48 +0000 @@ -1647,7 +1647,7 @@ strcpy (cmdname, egetenv ("CMDPROXY")); else { - lispstrcpy (cmdname, Vinvocation_directory); + lispstpcpy (cmdname, Vinvocation_directory); strcat (cmdname, "cmdproxy.exe"); } === modified file 'src/xfns.c' --- src/xfns.c 2014-09-23 15:49:00 +0000 +++ src/xfns.c 2014-09-23 17:03:48 +0000 @@ -4289,7 +4289,7 @@ int i, class = -1; XVisualInfo vinfo; - lispstrcpy (s, value); + lispstpcpy (s, value); dash = strchr (s, '-'); if (dash) { === modified file 'src/xfont.c' --- src/xfont.c 2014-09-23 15:49:00 +0000 +++ src/xfont.c 2014-09-23 17:03:48 +0000 @@ -541,7 +541,7 @@ if (STRINGP (XCAR (alter)) && ((r - name) + SBYTES (XCAR (alter))) < 256) { - lispstrcpy (r, XCAR (alter)); + lispstpcpy (r, XCAR (alter)); list = xfont_list_pattern (display, name, registry, script); if (! NILP (list)) break; === modified file 'src/xsmfns.c' --- src/xsmfns.c 2014-09-23 15:49:00 +0000 +++ src/xsmfns.c 2014-09-23 17:03:48 +0000 @@ -418,7 +418,7 @@ emacs_program[0] = '\0'; if (! EQ (Vinvocation_directory, Qnil)) - lispstrcpy (emacs_program, Vinvocation_directory); + lispstpcpy (emacs_program, Vinvocation_directory); strcat (emacs_program, SSDATA (Vinvocation_name)); /* The SM protocol says all callbacks are mandatory, so set up all === modified file 'src/xterm.c' --- src/xterm.c 2014-09-23 15:49:00 +0000 +++ src/xterm.c 2014-09-23 17:03:48 +0000 @@ -10902,8 +10902,9 @@ dpyinfo->x_id = ++x_display_id; dpyinfo->x_id_name = xmalloc (SBYTES (Vinvocation_name) + SBYTES (Vsystem_name) + 2); - strcat (strcat (lispstrcpy (dpyinfo->x_id_name, Vinvocation_name), "@"), - SSDATA (Vsystem_name)); + char *nametail = lispstpcpy (dpyinfo->x_id_name, Vinvocation_name); + *nametail++ = '@'; + lispstpcpy (nametail, Vsystem_name); /* Figure out which modifier bits mean what. */ x_find_modifier_meanings (dpyinfo); ------------------------------------------------------------ revno: 117927 committer: Paul Eggert branch nick: trunk timestamp: Tue 2014-09-23 09:07:23 -0700 message: * dispextern.h, xdisp.c (window_box_right_offset): Now static. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-23 15:49:00 +0000 +++ src/ChangeLog 2014-09-23 16:07:23 +0000 @@ -1,3 +1,7 @@ +2014-09-23 Paul Eggert + + * dispextern.h, xdisp.c (window_box_right_offset): Now static. + 2014-09-23 Dmitry Antipov Use known length of a Lisp string to copy it faster. === modified file 'src/dispextern.h' --- src/dispextern.h 2014-09-22 19:20:45 +0000 +++ src/dispextern.h 2014-09-23 16:07:23 +0000 @@ -3176,7 +3176,6 @@ int window_box_left (struct window *, enum glyph_row_area); int window_box_left_offset (struct window *, enum glyph_row_area); int window_box_right (struct window *, enum glyph_row_area); -int window_box_right_offset (struct window *, enum glyph_row_area); int estimate_mode_line_height (struct frame *, enum face_id); int move_it_to (struct it *, ptrdiff_t, int, int, int, int); void pixel_to_glyph_coords (struct frame *, int, int, int *, int *, === modified file 'src/xdisp.c' --- src/xdisp.c 2014-09-22 19:20:45 +0000 +++ src/xdisp.c 2014-09-23 16:07:23 +0000 @@ -1144,7 +1144,7 @@ area AREA of window W. ANY_AREA means return the right edge of the whole window, to the left of the right fringe of W. */ -int +static int window_box_right_offset (struct window *w, enum glyph_row_area area) { /* Don't return more than the window's pixel width. */ ------------------------------------------------------------ revno: 117926 committer: Dmitry Antipov branch nick: trunk timestamp: Tue 2014-09-23 19:49:00 +0400 message: Use known length of a Lisp string to copy it faster. * lisp.h (lispstrcpy): New function. Add comment. * callproc.c (child_setup): * dbusbind.c (xd_append_arg): * doc.c (get_doc_string): * font.c (Ffont_xlfd_name): * frame.c (xrdb_get_resource): * process.c (Fmake_network_process, network_interface_info): * w32fns.c (Fx_open_connection): * w32proc.c (sys_spawnve): * xfns.c (select_visual): * xfont.c (xfont_list): * xsmfns.c (x_session_initialize): * xterm.c (x_term_init): Use it. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-23 05:42:47 +0000 +++ src/ChangeLog 2014-09-23 15:49:00 +0000 @@ -1,7 +1,24 @@ +2014-09-23 Dmitry Antipov + + Use known length of a Lisp string to copy it faster. + * lisp.h (lispstrcpy): New function. Add comment. + * callproc.c (child_setup): + * dbusbind.c (xd_append_arg): + * doc.c (get_doc_string): + * font.c (Ffont_xlfd_name): + * frame.c (xrdb_get_resource): + * process.c (Fmake_network_process, network_interface_info): + * w32fns.c (Fx_open_connection): + * w32proc.c (sys_spawnve): + * xfns.c (select_visual): + * xfont.c (xfont_list): + * xsmfns.c (x_session_initialize): + * xterm.c (x_term_init): Use it. + 2014-09-23 Paul Eggert Fix SAFE_ALLOCA to not exhaust the stack when in a loop. - Problem reported by Dmietry Antipov in thread leading to: + Problem reported by Dmitry Antipov in thread leading to: http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00713.html This patch fixes only SAFE_ALLOCA, SAFE_NALLOCA, and SAFE_ALLOCA_LISP; the experimental local_* macros enabled by USE_LOCAL_ALLOCATORS === modified file 'src/callproc.c' --- src/callproc.c 2014-09-23 05:42:47 +0000 +++ src/callproc.c 2014-09-23 15:49:00 +0000 @@ -1235,7 +1235,7 @@ #endif temp = pwd_var + 4; memcpy (pwd_var, "PWD=", 4); - strcpy (temp, SSDATA (current_dir)); + lispstrcpy (temp, current_dir); #ifndef DOS_NT /* We can't signal an Elisp error here; we're in a vfork. Since === modified file 'src/dbusbind.c' --- src/dbusbind.c 2014-05-20 08:25:18 +0000 +++ src/dbusbind.c 2014-09-23 15:49:00 +0000 @@ -761,7 +761,7 @@ && STRINGP (CAR_SAFE (XD_NEXT_VALUE (object))) && NILP (CDR_SAFE (XD_NEXT_VALUE (object)))) { - strcpy (signature, SSDATA (CAR_SAFE (XD_NEXT_VALUE (object)))); + lispstrcpy (signature, CAR_SAFE (XD_NEXT_VALUE (object))); object = CDR_SAFE (XD_NEXT_VALUE (object)); } === modified file 'src/doc.c' --- src/doc.c 2014-09-15 14:53:23 +0000 +++ src/doc.c 2014-09-23 15:49:00 +0000 @@ -121,7 +121,7 @@ if (minsize < 8) minsize = 8; name = SAFE_ALLOCA (minsize + SCHARS (file) + 8); - strcpy (name, SSDATA (docdir)); + lispstrcpy (name, docdir); strcat (name, SSDATA (file)); } else === modified file 'src/font.c' --- src/font.c 2014-09-22 19:20:45 +0000 +++ src/font.c 2014-09-23 15:49:00 +0000 @@ -4266,7 +4266,7 @@ { if (NILP (fold_wildcards)) return font_name; - strcpy (name, SSDATA (font_name)); + lispstrcpy (name, font_name); namelen = SBYTES (font_name); goto done; } === modified file 'src/frame.c' --- src/frame.c 2014-09-22 19:20:45 +0000 +++ src/frame.c 2014-09-23 15:49:00 +0000 @@ -4036,8 +4036,8 @@ /* Start with emacs.FRAMENAME for the name (the specific one) and with `Emacs' for the class key (the general one). */ - strcpy (name_key, SSDATA (Vx_resource_name)); - strcpy (class_key, SSDATA (Vx_resource_class)); + lispstrcpy (name_key, Vx_resource_name); + lispstrcpy (class_key, Vx_resource_class); strcat (class_key, "."); strcat (class_key, SSDATA (class)); === modified file 'src/lisp.h' --- src/lisp.h 2014-09-23 05:42:47 +0000 +++ src/lisp.h 2014-09-23 15:49:00 +0000 @@ -4462,6 +4462,15 @@ extern char *xstrdup (const char *) ATTRIBUTE_MALLOC; extern char *xlispstrdup (Lisp_Object) ATTRIBUTE_MALLOC; extern void dupstring (char **, char const *); + +/* Like strcpy but uses known length of a Lisp string. */ + +INLINE char * +lispstrcpy (const char *dest, Lisp_Object string) +{ + return memcpy ((void *) dest, SSDATA (string), SBYTES (string) + 1); +} + extern void xputenv (const char *); extern char *egetenv_internal (const char *, ptrdiff_t); === modified file 'src/process.c' --- src/process.c 2014-09-18 11:34:24 +0000 +++ src/process.c 2014-09-23 15:49:00 +0000 @@ -2989,7 +2989,7 @@ address_un.sun_family = AF_LOCAL; if (sizeof address_un.sun_path <= SBYTES (service)) error ("Service name too long"); - strcpy (address_un.sun_path, SSDATA (service)); + lispstrcpy (address_un.sun_path, service); ai.ai_addr = (struct sockaddr *) &address_un; ai.ai_addrlen = sizeof address_un; goto open_socket; @@ -3680,7 +3680,7 @@ if (sizeof rq.ifr_name <= SBYTES (ifname)) error ("interface name too long"); - strcpy (rq.ifr_name, SSDATA (ifname)); + lispstrcpy (rq.ifr_name, ifname); s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); if (s < 0) === modified file 'src/w32fns.c' --- src/w32fns.c 2014-09-03 15:10:29 +0000 +++ src/w32fns.c 2014-09-23 15:49:00 +0000 @@ -5339,7 +5339,7 @@ { char basename[ MAX_PATH ], *str; - strcpy (basename, SDATA (Vinvocation_name)); + lispstrcpy (basename, Vinvocation_name); str = strrchr (basename, '.'); if (str) *str = 0; Vinvocation_name = build_string (basename); === modified file 'src/w32proc.c' --- src/w32proc.c 2014-09-01 15:07:17 +0000 +++ src/w32proc.c 2014-09-23 15:49:00 +0000 @@ -1647,7 +1647,7 @@ strcpy (cmdname, egetenv ("CMDPROXY")); else { - strcpy (cmdname, SDATA (Vinvocation_directory)); + lispstrcpy (cmdname, Vinvocation_directory); strcat (cmdname, "cmdproxy.exe"); } === modified file 'src/xfns.c' --- src/xfns.c 2014-09-18 11:34:24 +0000 +++ src/xfns.c 2014-09-23 15:49:00 +0000 @@ -4289,7 +4289,7 @@ int i, class = -1; XVisualInfo vinfo; - strcpy (s, SSDATA (value)); + lispstrcpy (s, value); dash = strchr (s, '-'); if (dash) { === modified file 'src/xfont.c' --- src/xfont.c 2014-09-18 11:34:24 +0000 +++ src/xfont.c 2014-09-23 15:49:00 +0000 @@ -541,7 +541,7 @@ if (STRINGP (XCAR (alter)) && ((r - name) + SBYTES (XCAR (alter))) < 256) { - strcpy (r, SSDATA (XCAR (alter))); + lispstrcpy (r, XCAR (alter)); list = xfont_list_pattern (display, name, registry, script); if (! NILP (list)) break; === modified file 'src/xsmfns.c' --- src/xsmfns.c 2014-09-04 05:38:37 +0000 +++ src/xsmfns.c 2014-09-23 15:49:00 +0000 @@ -418,7 +418,7 @@ emacs_program[0] = '\0'; if (! EQ (Vinvocation_directory, Qnil)) - strcpy (emacs_program, SSDATA (Vinvocation_directory)); + lispstrcpy (emacs_program, Vinvocation_directory); strcat (emacs_program, SSDATA (Vinvocation_name)); /* The SM protocol says all callbacks are mandatory, so set up all === modified file 'src/xterm.c' --- src/xterm.c 2014-09-22 19:20:45 +0000 +++ src/xterm.c 2014-09-23 15:49:00 +0000 @@ -10902,7 +10902,7 @@ dpyinfo->x_id = ++x_display_id; dpyinfo->x_id_name = xmalloc (SBYTES (Vinvocation_name) + SBYTES (Vsystem_name) + 2); - strcat (strcat (strcpy (dpyinfo->x_id_name, SSDATA (Vinvocation_name)), "@"), + strcat (strcat (lispstrcpy (dpyinfo->x_id_name, Vinvocation_name), "@"), SSDATA (Vsystem_name)); /* Figure out which modifier bits mean what. */ ------------------------------------------------------------ revno: 117925 committer: Glenn Morris branch nick: trunk timestamp: Tue 2014-09-23 06:21:30 -0400 message: Auto-commit of loaddefs files. diff: === modified file 'lisp/ibuffer.el' --- lisp/ibuffer.el 2014-09-22 14:10:53 +0000 +++ lisp/ibuffer.el 2014-09-23 10:21:30 +0000 @@ -2597,7 +2597,7 @@ ;;; Start of automatically extracted autoloads. -;;;### (autoloads nil "ibuf-ext" "ibuf-ext.el" "e8ce929c4c76419f8d355b444f722c3a") +;;;### (autoloads nil "ibuf-ext" "ibuf-ext.el" "0d2393d1b47136bc7b1ac41593527f02") ;;; Generated autoloads from ibuf-ext.el (autoload 'ibuffer-auto-mode "ibuf-ext" "\ ------------------------------------------------------------ revno: 117924 committer: Paul Eggert branch nick: trunk timestamp: Mon 2014-09-22 22:42:47 -0700 message: Fix SAFE_ALLOCA to not exhaust the stack when in a loop. Problem reported by Dmietry Antipov in thread leading to: http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00713.html This patch fixes only SAFE_ALLOCA, SAFE_NALLOCA, and SAFE_ALLOCA_LISP; the experimental local_* macros enabled by USE_LOCAL_ALLOCATORS remain unfixed. * callproc.c (call_process): Save and restore sa_avail. * lisp.h (USE_SAFE_ALLOCA): Define sa_avail. (AVAIL_ALLOCA): New macro. (SAFE_ALLOCA, SAFE_NALLOCA, SAFE_ALLOCA_LISP): Use it, and check against sa_avail rather than MAX_ALLOCA. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2014-09-22 19:20:45 +0000 +++ src/ChangeLog 2014-09-23 05:42:47 +0000 @@ -1,3 +1,17 @@ +2014-09-23 Paul Eggert + + Fix SAFE_ALLOCA to not exhaust the stack when in a loop. + Problem reported by Dmietry Antipov in thread leading to: + http://lists.gnu.org/archive/html/emacs-devel/2014-09/msg00713.html + This patch fixes only SAFE_ALLOCA, SAFE_NALLOCA, and SAFE_ALLOCA_LISP; + the experimental local_* macros enabled by USE_LOCAL_ALLOCATORS + remain unfixed. + * callproc.c (call_process): Save and restore sa_avail. + * lisp.h (USE_SAFE_ALLOCA): Define sa_avail. + (AVAIL_ALLOCA): New macro. + (SAFE_ALLOCA, SAFE_NALLOCA, SAFE_ALLOCA_LISP): + Use it, and check against sa_avail rather than MAX_ALLOCA. + 2014-09-22 Dmitry Antipov On OSX, do not free font-specific data more than once (Bug#18501). === modified file 'src/callproc.c' --- src/callproc.c 2014-09-14 08:23:48 +0000 +++ src/callproc.c 2014-09-23 05:42:47 +0000 @@ -632,6 +632,7 @@ int volatile fd_error_volatile = fd_error; int volatile filefd_volatile = filefd; ptrdiff_t volatile count_volatile = count; + ptrdiff_t volatile sa_avail_volatile = sa_avail; ptrdiff_t volatile sa_count_volatile = sa_count; char **volatile new_argv_volatile = new_argv; int volatile callproc_fd_volatile[CALLPROC_FDS]; @@ -648,6 +649,7 @@ fd_error = fd_error_volatile; filefd = filefd_volatile; count = count_volatile; + sa_avail = sa_avail_volatile; sa_count = sa_count_volatile; new_argv = new_argv_volatile; === modified file 'src/lisp.h' --- src/lisp.h 2014-09-22 19:20:45 +0000 +++ src/lisp.h 2014-09-23 05:42:47 +0000 @@ -4496,12 +4496,15 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); #define USE_SAFE_ALLOCA \ + ptrdiff_t sa_avail = MAX_ALLOCA; \ ptrdiff_t sa_count = SPECPDL_INDEX (); bool sa_must_free = false +#define AVAIL_ALLOCA(size) (sa_avail -= (size), alloca (size)) + /* SAFE_ALLOCA allocates a simple buffer. */ -#define SAFE_ALLOCA(size) ((size) <= MAX_ALLOCA \ - ? alloca (size) \ +#define SAFE_ALLOCA(size) ((size) <= sa_avail \ + ? AVAIL_ALLOCA (size) \ : (sa_must_free = true, record_xmalloc (size))) /* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER * @@ -4510,8 +4513,8 @@ #define SAFE_NALLOCA(buf, multiplier, nitems) \ do { \ - if ((nitems) <= MAX_ALLOCA / sizeof *(buf) / (multiplier)) \ - (buf) = alloca (sizeof *(buf) * (multiplier) * (nitems)); \ + if ((nitems) <= sa_avail / sizeof *(buf) / (multiplier)) \ + (buf) = AVAIL_ALLOCA (sizeof *(buf) * (multiplier) * (nitems)); \ else \ { \ (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \ @@ -4543,8 +4546,8 @@ #define SAFE_ALLOCA_LISP(buf, nelt) \ do { \ - if ((nelt) <= MAX_ALLOCA / word_size) \ - (buf) = alloca ((nelt) * word_size); \ + if ((nelt) <= sa_avail / word_size) \ + (buf) = AVAIL_ALLOCA ((nelt) * word_size); \ else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \ { \ Lisp_Object arg_; \