emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/src/dispnew.c


From: Richard M . Stallman
Subject: [Emacs-diffs] Changes to emacs/src/dispnew.c
Date: Sun, 07 Aug 2005 13:40:20 -0400

Index: emacs/src/dispnew.c
diff -c emacs/src/dispnew.c:1.352 emacs/src/dispnew.c:1.353
*** emacs/src/dispnew.c:1.352   Sun Aug  7 12:33:16 2005
--- emacs/src/dispnew.c Sun Aug  7 17:40:18 2005
***************
*** 6463,6530 ****
  
  /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
     session's frames, frame names, buffers, buffer-read-only flags, and
!    buffer-modified-flags, and a trailing sentinel (so we don't need to
!    add length checks).  */
  
  static Lisp_Object frame_and_buffer_state;
  
  
  DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
!        Sframe_or_buffer_changed_p, 0, 0, 0,
         doc: /* Return non-nil if the frame and buffer state appears to have 
changed.
! The state variable is an internal vector containing all frames and buffers,
  aside from buffers whose names start with space,
! along with the buffers' read-only and modified flags, which allows a fast
! check to see whether the menu bars might need to be recomputed.
  If this function returns non-nil, it updates the internal vector to reflect
! the current state.  */)
!      ()
  {
!   Lisp_Object tail, frame, buf;
!   Lisp_Object *vecp;
    int n;
  
!   vecp = XVECTOR (frame_and_buffer_state)->contents;
    FOR_EACH_FRAME (tail, frame)
      {
        if (!EQ (*vecp++, frame))
        goto changed;
        if (!EQ (*vecp++, XFRAME (frame)->name))
        goto changed;
      }
!   /* Check that the buffer info matches.
!      No need to test for the end of the vector
!      because the last element of the vector is lambda
!      and that will always cause a mismatch.  */
    for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
      {
        buf = XCDR (XCAR (tail));
        /* Ignore buffers that aren't included in buffer lists.  */
        if (SREF (XBUFFER (buf)->name, 0) == ' ')
        continue;
        if (!EQ (*vecp++, buf))
        goto changed;
        if (!EQ (*vecp++, XBUFFER (buf)->read_only))
        goto changed;
        if (!EQ (*vecp++, Fbuffer_modified_p (buf)))
        goto changed;
      }
    /* Detect deletion of a buffer at the end of the list.  */
    if (EQ (*vecp, Qlambda))
      return Qnil;
   changed:
!   /* Start with 1 so there is room for at least one lambda at the end.  */
    n = 1;
    FOR_EACH_FRAME (tail, frame)
      n += 2;
    for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
      n += 3;
!   /* Reallocate the vector if it's grown, or if it's shrunk a lot.  */
!   if (n > XVECTOR (frame_and_buffer_state)->size
!       || n + 20 < XVECTOR (frame_and_buffer_state)->size / 2)
      /* Add 20 extra so we grow it less often.  */
!     frame_and_buffer_state = Fmake_vector (make_number (n + 20), Qlambda);
!   vecp = XVECTOR (frame_and_buffer_state)->contents;
    FOR_EACH_FRAME (tail, frame)
      {
        *vecp++ = frame;
--- 6463,6568 ----
  
  /* A vector of size >= 2 * NFRAMES + 3 * NBUFFERS + 1, containing the
     session's frames, frame names, buffers, buffer-read-only flags, and
!    buffer-modified-flags.  */
  
  static Lisp_Object frame_and_buffer_state;
  
  
  DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p,
!        Sframe_or_buffer_changed_p, 0, 1, 0,
         doc: /* Return non-nil if the frame and buffer state appears to have 
changed.
! VARIABLE is a variable name whose value is either nil or a state vector
! that will be updated to contain all frames and buffers,
  aside from buffers whose names start with space,
! along with the buffers' read-only and modified flags.  This allows a fast
! check to see whether buffer menus might need to be recomputed.
  If this function returns non-nil, it updates the internal vector to reflect
! the current state.
! 
! If VARIABLE is nil, an internal variable is used.  Users should not
! pass nil for VARIABLE.  */)
!      (variable)
!      Lisp_Object variable;
  {
!   Lisp_Object state, tail, frame, buf;
!   Lisp_Object *vecp, *end;
    int n;
  
!   if (! NILP (variable))
!     {
!       CHECK_SYMBOL (variable);
!       state = Fsymbol_value (variable);
!       if (! VECTORP (state))
!       goto changed;
!     }
!   else
!     state = frame_and_buffer_state;
! 
!   vecp = XVECTOR (state)->contents;
!   end = vecp + XVECTOR (state)->size;
! 
    FOR_EACH_FRAME (tail, frame)
      {
+       if (vecp == end)
+       goto changed;
        if (!EQ (*vecp++, frame))
        goto changed;
+       if (vecp == end)
+       goto changed;
        if (!EQ (*vecp++, XFRAME (frame)->name))
        goto changed;
      }
!   /* Check that the buffer info matches.  */
    for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
      {
        buf = XCDR (XCAR (tail));
        /* Ignore buffers that aren't included in buffer lists.  */
        if (SREF (XBUFFER (buf)->name, 0) == ' ')
        continue;
+       if (vecp == end)
+       goto changed;
        if (!EQ (*vecp++, buf))
        goto changed;
+       if (vecp == end)
+       goto changed;
        if (!EQ (*vecp++, XBUFFER (buf)->read_only))
        goto changed;
+       if (vecp == end)
+       goto changed;
        if (!EQ (*vecp++, Fbuffer_modified_p (buf)))
        goto changed;
      }
+   if (vecp == end)
+     goto changed;
    /* Detect deletion of a buffer at the end of the list.  */
    if (EQ (*vecp, Qlambda))
      return Qnil;
+ 
+   /* Come here if we decide the data has changed.  */
   changed:
!   /* Count the size we will need.
!      Start with 1 so there is room for at least one lambda at the end.  */
    n = 1;
    FOR_EACH_FRAME (tail, frame)
      n += 2;
    for (tail = Vbuffer_alist; CONSP (tail); tail = XCDR (tail))
      n += 3;
!   /* Reallocate the vector if data has grown to need it,
!      or if it has shrunk a lot.  */
!   if (! VECTORP (state)
!       || n > XVECTOR (state)->size
!       || n + 20 < XVECTOR (state)->size / 2)
      /* Add 20 extra so we grow it less often.  */
!     {
!       state = Fmake_vector (make_number (n + 20), Qlambda);
!       if (! NILP (variable))
!       Fset (variable, state);
!       else
!       frame_and_buffer_state = state;
!     }
! 
!   /* Record the new data in the (possibly reallocated) vector.  */
!   vecp = XVECTOR (state)->contents;
    FOR_EACH_FRAME (tail, frame)
      {
        *vecp++ = frame;
***************
*** 6542,6553 ****
      }
    /* Fill up the vector with lambdas (always at least one).  */
    *vecp++ = Qlambda;
!   while  (vecp - XVECTOR (frame_and_buffer_state)->contents
!         < XVECTOR (frame_and_buffer_state)->size)
      *vecp++ = Qlambda;
    /* Make sure we didn't overflow the vector.  */
!   if (vecp - XVECTOR (frame_and_buffer_state)->contents
!       > XVECTOR (frame_and_buffer_state)->size)
      abort ();
    return Qt;
  }
--- 6580,6591 ----
      }
    /* Fill up the vector with lambdas (always at least one).  */
    *vecp++ = Qlambda;
!   while (vecp - XVECTOR (state)->contents
!        < XVECTOR (state)->size)
      *vecp++ = Qlambda;
    /* Make sure we didn't overflow the vector.  */
!   if (vecp - XVECTOR (state)->contents
!       > XVECTOR (state)->size)
      abort ();
    return Qt;
  }




reply via email to

[Prev in Thread] Current Thread [Next in Thread]