changeset 109201:0aaff477ec9f

Merge from mainline.
author Katsumi Yamaoka <katsumi@flagship2>
date Sun, 23 May 2010 11:52:45 +0000
parents 141ddbd4a5e0 (current diff) 3339da3cfeb3 (diff)
children 1a5381cbfe12
files
diffstat 17 files changed, 378 insertions(+), 218 deletions(-) [+]
line wrap: on
line diff
--- a/admin/notes/bugtracker	Sat May 22 03:32:53 2010 +0000
+++ b/admin/notes/bugtracker	Sun May 23 11:52:45 2010 +0000
@@ -553,9 +553,13 @@
 If a non-spam message accidentally gets discarded, just do:
 
 cat /var/lib/mailman/spam/not-really-spam.msg | /usr/lib/debbugs/receive
+chown Debian-debbugs:Debian-debbugs /var/lib/debbugs/spool/incoming/*
 ... check it works ...
 mv /var/lib/mailman/spam/not-really-spam.msg /var/lib/mailman/not-spam/
 
+Also check that the sender was not added to the auto-discard/reject list
+in the debbugs-submit Mailman interface.
+
 ** Administrivia
 
 The debbugs-submit list should have the administrivia option off,
--- a/configure	Sat May 22 03:32:53 2010 +0000
+++ b/configure	Sun May 23 11:52:45 2010 +0000
@@ -9561,7 +9561,10 @@
    fi
    if test $ac_enable_autodepend = yes; then
       DEPFLAGS='-MMD -MF ${DEPDIR}/$*.d'
-      MKDEPDIR='test -d ${DEPDIR} || mkdir ${DEPDIR}'
+      ## In parallel builds, another make might create depdir between
+      ## the first test and mkdir, so stick another test on the end.
+      ## Or use mkinstalldirs?  mkdir -p is not portable.
+      MKDEPDIR='test -d ${DEPDIR} || mkdir ${DEPDIR} || test -d ${DEPDIR}'
       deps_frag=autodeps.mk
    fi
 fi
--- a/doc/lispref/ChangeLog	Sat May 22 03:32:53 2010 +0000
+++ b/doc/lispref/ChangeLog	Sun May 23 11:52:45 2010 +0000
@@ -1,3 +1,8 @@
+2010-05-22  Chong Yidong  <cyd@stupidchicken.com>
+
+	* display.texi (Image Cache): Update documentation about image
+	caching.
+
 2010-05-08  Štěpán Němec  <stepnem@gmail.com>  (tiny change)
 
 	* windows.texi (Textual Scrolling):
--- a/doc/lispref/display.texi	Sat May 22 03:32:53 2010 +0000
+++ b/doc/lispref/display.texi	Sun May 23 11:52:45 2010 +0000
@@ -4730,29 +4730,35 @@
 efficiently.  When Emacs displays an image, it searches the image
 cache for an existing image specification @code{equal} to the desired
 specification.  If a match is found, the image is displayed from the
-cache; otherwise, Emacs loads the image normally.
-
-  Occasionally, you may need to tell Emacs to refresh the images
-associated with a given image specification.  For example, suppose you
-display an image using a specification that contains a @code{:file}
-property.  The image is automatically cached, and subsequent displays
-of that image, with the same image specification, will use the image
-cache.  If the image file changes in the meantime, Emacs would be
-displaying the old version of the image.  In such a situation, you can
-``refresh'' the image by calling @code{image-refresh}.
-
-  In Emacs' current implementation, each graphical terminal possesses
-an image cache, which is shared by all the frames on that terminal
+cache.  Otherwise, Emacs loads the image normally.
+
+@defun image-flush spec &optional frame
+This function removes the image with specification @var{spec} from the
+image cache of frame @var{frame}.  Image specifications are compared
+using @code{equal}.  If @var{frame} is @code{nil}, it defaults to the
+selected frame.  If @var{frame} is @code{t}, the image is flushed on
+all existing frames.
+
+In Emacs' current implementation, each graphical terminal possesses an
+image cache, which is shared by all the frames on that terminal
 (@pxref{Multiple Terminals}).  Thus, refreshing an image in one frame
 also refreshes it in all other frames on the same terminal.
-
-@defun image-refresh spec &optional frame
-This function refreshes any images with image specifications
-@code{equal} to @var{spec} on frame @var{frame}.  If @var{frame} is
-@code{nil}, it defaults to the selected frame.  If @var{frame} is
-@code{t}, the refresh is applied to all existing frames.
 @end defun
 
+  One use for @code{image-flush} is to tell Emacs about a change in an
+image file.  If an image specification contains a @code{:file}
+property, the image is cached based on the file's contents when the
+image is first displayed.  Even if the file subsequently changes,
+Emacs continues displaying the old version of the image.  Calling
+@code{image-flush} flushes the image from the cache, forcing Emacs to
+re-read the file the next time it needs to display that image.
+
+  Another use for @code{image-flush} is for memory conservation.  If
+your Lisp program creates a large number of temporary images over a
+period much shorter than @code{image-cache-eviction-delay} (see
+below), you can opt to flush unused images yourself, instead of
+waiting for Emacs to do it automatically.
+
 @defun clear-image-cache &optional filter
 This function clears an image cache, removing all the images stored in
 it.  If @var{filter} is omitted or @code{nil}, it clears the cache for
@@ -4768,9 +4774,12 @@
 associated memory.
 
 @defvar image-cache-eviction-delay
-This variable specifies the number of seconds an image can remain in the
-cache without being displayed.  When an image is not displayed for this
-length of time, Emacs removes it from the image cache.
+This variable specifies the number of seconds an image can remain in
+the cache without being displayed.  When an image is not displayed for
+this length of time, Emacs removes it from the image cache.
+
+Under some circumstances, if the number of images in the cache grows
+too large, the actual eviction delay may be shorter than this.
 
 If the value is @code{nil}, Emacs does not remove images from the cache
 except when you explicitly clear it.  This mode can be useful for
--- a/lib-src/ChangeLog	Sat May 22 03:32:53 2010 +0000
+++ b/lib-src/ChangeLog	Sun May 23 11:52:45 2010 +0000
@@ -1,3 +1,11 @@
+2010-05-22  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* Makefile.in (STAMP_INST_SCRIPTS, STAMP_SCRIPS): New (Bug #6246).
+	(all): Depend onSTAMP_INST_SCRIPTS, STAMP_SCRIPS (Bug #6246).
+	(stamp-rcs2log, stamp-rcs-checkin, stamp-grep-changelog, stamp-vcdiff):
+	New rules (Bug #6246).
+	(clean): Remove stamp-* (Bug #6246).
+
 2010-05-12  Glenn Morris  <rgm@gnu.org>
 
 	* Makefile.in (INSTALLABLES): Remove @LIB_SRC_EXTRA_INSTALLABLES@.
--- a/lib-src/Makefile.in	Sat May 22 03:32:53 2010 +0000
+++ b/lib-src/Makefile.in	Sun May 23 11:52:45 2010 +0000
@@ -111,6 +111,7 @@
                b2m${EXEEXT} ebrowse${EXEEXT}
 
 INSTALLABLE_SCRIPTS = rcs-checkin grep-changelog
+STAMP_INST_SCRIPTS = stamp-rcs-checkin stamp-grep-changelog
 
 # Things that Emacs runs internally, or during the build process,
 #  which should not be installed in bindir.
@@ -123,6 +124,7 @@
 # Like UTILITIES, but they're not system-dependent, and should not be
 #  deleted by the distclean target.
 SCRIPTS= rcs2log vcdiff
+STAMP_SCRIPTS= stamp-rcs2log stamp-vcdiff
 
 EXECUTABLES= ${UTILITIES} ${INSTALLABLES} ${SCRIPTS} ${INSTALLABLE_SCRIPTS}
 
@@ -180,23 +182,27 @@
 .c.o:
 	${CC} -c ${CPP_CFLAGS} $<
 
-all: ${DONT_INSTALL} ${UTILITIES} ${INSTALLABLES} ${SCRIPTS} ${INSTALLABLE_SCRIPTS}
+all: ${DONT_INSTALL} ${UTILITIES} ${INSTALLABLES} ${SCRIPTS} ${INSTALLABLE_SCRIPTS}  ${STAMP_INST_SCRIPTS} ${STAMP_SCRIPTS}
 
 ## These targets copy the scripts into the build directory so that
 ## they can be run from there in an uninstalled Emacs.
 ## The "-" is prepended because some versions of cp barf when srcdir
 ## is the current directory, and thus the file will be copied into itself.
-rcs2log: $(srcdir)/rcs2log
+stamp-rcs2log: $(srcdir)/rcs2log
 	-cp -p $(srcdir)/rcs2log rcs2log
+	touch $@
 
-rcs-checkin: $(srcdir)/rcs-checkin
+stamp-rcs-checkin: $(srcdir)/rcs-checkin
 	-cp -p $(srcdir)/rcs-checkin rcs-checkin
+	touch $@
 
-grep-changelog: $(srcdir)/grep-changelog
+stamp-grep-changelog: $(srcdir)/grep-changelog
 	-cp -p $(srcdir)/grep-changelog grep-changelog
+	touch $@
 
-vcdiff: $(srcdir)/vcdiff
+stamp-vcdiff: $(srcdir)/vcdiff
 	-cp -p $(srcdir)/vcdiff vcdiff
+	touch $@
 
 ## Only used if we need blessmail, but no harm in always defining.
 ## This makes the actual blessmail executable.
@@ -273,7 +279,7 @@
 
 clean: mostlyclean
 	-rm -f ${INSTALLABLES} ${UTILITIES} ${DONT_INSTALL}
-	-rm -f fns*.el *.tab.c *.tab.h
+	-rm -f fns*.el *.tab.c *.tab.h stamp-*
 
 distclean: clean
 	-rm -f TAGS
--- a/lisp/ChangeLog	Sat May 22 03:32:53 2010 +0000
+++ b/lisp/ChangeLog	Sun May 23 11:52:45 2010 +0000
@@ -1,3 +1,9 @@
+2010-05-22  Chong Yidong  <cyd@stupidchicken.com>
+
+	* image.el (image-refresh): Define as an alias for image-flush.
+
+	* image-mode.el (image-toggle-display-image): Caller changed.
+
 2010-05-21  Juri Linkov  <juri@jurta.org>
 
 	* progmodes/grep.el (grep-read-files): Fix multi-pattern aliases.
--- a/lisp/image-mode.el	Sat May 22 03:32:53 2010 +0000
+++ b/lisp/image-mode.el	Sun May 23 11:52:45 2010 +0000
@@ -448,7 +448,7 @@
 
 (defvar archive-superior-buffer)
 (defvar tar-superior-buffer)
-(declare-function image-refresh "image.c" (spec &optional frame))
+(declare-function image-flush "image.c" (spec &optional frame))
 
 (defun image-toggle-display-image ()
   "Show the image of the image file.
@@ -477,7 +477,7 @@
 	 (inhibit-read-only t)
 	 (buffer-undo-list t)
 	 (modified (buffer-modified-p)))
-    (image-refresh image)
+    (image-flush image)
     (let ((buffer-file-truename nil)) ; avoid changing dir mtime by lock_file
       (add-text-properties (point-min) (point-max) props)
       (restore-buffer-modified-p modified))
--- a/lisp/image.el	Sat May 22 03:32:53 2010 +0000
+++ b/lisp/image.el	Sun May 23 11:52:45 2010 +0000
@@ -30,6 +30,7 @@
   "Image support."
   :group 'multimedia)
 
+(defalias 'image-refresh 'image-flush)
 
 (defconst image-type-header-regexps
   `(("\\`/[\t\n\r ]*\\*.*XPM.\\*/" . xpm)
--- a/src/.gdbinit	Sat May 22 03:32:53 2010 +0000
+++ b/src/.gdbinit	Sun May 23 11:52:45 2010 +0000
@@ -616,7 +616,7 @@
 end
 
 define prowlims
-  printf "start=%d,end=%d,reversed=%d,cont=%d,at_zv=%d\n", $arg0->start.pos.charpos, $arg0->end.pos.charpos, $arg0->reversed_p, $arg0->continued_p, $arg0->ends_at_zv_p
+  printf "edges=(%d,%d),r2l=%d,cont=%d,trunc=(%d,%d),at_zv=%d\n", $arg0->minpos.charpos, $arg0->maxpos.charpos, $arg0->reversed_p, $arg0->continued_p, $arg0->truncated_on_left_p, $arg0->truncated_on_right_p, $arg0->ends_at_zv_p
 end
 document prowlims
 Print important attributes of a glyph_row structure.
@@ -626,10 +626,13 @@
 define pmtxrows
   set $mtx = $arg0
   set $gl = $mtx->rows
-  set $glend = $mtx->rows + $mtx->nrows
+  set $glend = $mtx->rows + $mtx->nrows - 1
+  set $i = 0
   while ($gl < $glend)
+    printf "%d: ", $i
     prowlims $gl
     set $gl = $gl + 1
+    set $i = $i + 1
   end
 end
 document pmtxrows
--- a/src/ChangeLog	Sat May 22 03:32:53 2010 +0000
+++ b/src/ChangeLog	Sun May 23 11:52:45 2010 +0000
@@ -1,3 +1,59 @@
+2010-05-19  Eli Zaretskii  <eliz@gnu.org>
+
+	Redesign and reimplement bidi-aware edge positions of glyph rows.
+
+	* dispextern.h (struct glyph_row): New members minpos and maxpos.
+	(MATRIX_ROW_START_CHARPOS, MATRIX_ROW_START_BYTEPOS)
+	(MATRIX_ROW_END_CHARPOS, MATRIX_ROW_END_BYTEPOS): Reference minpos
+	and maxpos members instead of start.pos and end.pos, respectively.
+
+	* xdisp.c (display_line): Compare IT_CHARPOS with the position in
+	row->start.pos, rather than with MATRIX_ROW_START_CHARPOS.
+	(cursor_row_p): Use row->end.pos rather than MATRIX_ROW_END_CHARPOS.
+	(try_window_reusing_current_matrix, try_window_id): Use
+	ROW->minpos rather than ROW->start.pos.
+	(init_from_display_pos, init_iterator): Use EMACS_INT for
+	character and byte positions.
+	(find_row_edges): Renamed from find_row_end.  Accept additional
+	arguments for minimum and maximum buffer positions seen by
+	display_line for this row.  Don't use iterator to find the
+	position following the maximum one; instead, increment the
+	position found by display_line directly.  Fix logic; eol_pos
+	should be tested before the rest.  Handle the case of characters
+	delivered from display vector (bug#6036).  Fix tests related to
+	it->method.  Handle the truncated_on_right_p rows.
+	(RECORD_MAX_MIN_POS): New macro.
+	(display_line): Use it to record the minimum and maximum buffer
+	positions for glyphs in the row being assembled.  Record the
+	position of the newline that terminates the line.  If word wrap is
+	in effect, restore minimum and maximum positions seen up to the
+	wrap point, when iterator returns to it.
+	(try_window_reusing_current_matrix): Give up if in bidi-reordered
+	row and cursor not already at point.  Restore original pre-bidi
+	code for unidirectional buffers.
+
+	* dispnew.c (increment_row_positions, check_matrix_invariants):
+	Increment and check row->start.pos and row->end.pos, in addition
+	to MATRIX_ROW_START_CHARPOS and MATRIX_ROW_END_CHARPOS.
+
+	* .gdbinit (prowlims): Display row->minpos and row->maxpos.
+	Display truncated_on_left_p and truncated_on_right_p flags.
+	Formatting fixes.
+	(pmtxrows): Display the ordinal number of each row.  Don't display
+	rows beyond the last one.
+
+	* bidi.c (bidi_cache_iterator_state): Don't zero out new_paragraph:
+	it is not copied by bidi_copy_it.
+
+2010-05-22  Eli Zaretskii  <eliz@gnu.org>
+
+	* w32.c (sys_write): Break writes into chunks smaller than 32MB.
+	(Bug#6237)
+
+2010-05-22  Chong Yidong  <cyd@stupidchicken.com>
+
+	* image.c (Fimage_flush): Rename from image-refresh.
+
 2010-05-21  Chong Yidong  <cyd@stupidchicken.com>
 
 	* xdisp.c (redisplay_internal): Clear caches even if redisplaying
@@ -42,8 +98,6 @@
 	Move static/dynamic dependency stuff to deps.mk/autodeps.mk.
 	* deps.mk, autodeps.mk: New files, extracted from Makefile.in.
 
-2010-05-19  Eli Zaretskii  <eliz@gnu.org>
-
 	* bidi.c (bidi_cache_shrink, bidi_cache_iterator_state): Fix
 	reallocation of the cache.  (Bug#6210)
 
@@ -166,6 +220,8 @@
 	* xdisp.c (Fcurrent_bidi_paragraph_direction): New function.
 	(syms_of_xdisp): Defsubr it.
 
+	* cmds.c (Fforward_char, Fbackward_char): Doc fix.
+
 	* Makefile.in: Fix MSDOS-related comments.
 
 2010-05-15  Glenn Morris  <rgm@gnu.org>
--- a/src/bidi.c	Sat May 22 03:32:53 2010 +0000
+++ b/src/bidi.c	Sun May 23 11:52:45 2010 +0000
@@ -707,7 +707,6 @@
       bidi_copy_it (&bidi_cache[idx], bidi_it);
       if (!resolved)
 	bidi_cache[idx].resolved_level = -1;
-      bidi_cache[idx].new_paragraph = 0;
     }
   else
     {
--- a/src/dispextern.h	Sat May 22 03:32:53 2010 +0000
+++ b/src/dispextern.h	Sun May 23 11:52:45 2010 +0000
@@ -748,21 +748,29 @@
 
   /* First position in this row.  This is the text position, including
      overlay position information etc, where the display of this row
-     started, and can thus be less the position of the first glyph
-     (e.g. due to invisible text or horizontal scrolling).  BIDI Note:
-     This is the smallest character position in the row, but not
-     necessarily the character that is the leftmost on the display.  */
+     started, and can thus be less than the position of the first
+     glyph (e.g. due to invisible text or horizontal scrolling).
+     BIDI Note: In R2L rows, that have its reversed_p flag set, this
+     position is at or beyond the right edge of the row.  */
   struct display_pos start;
 
   /* Text position at the end of this row.  This is the position after
      the last glyph on this row.  It can be greater than the last
-     glyph position + 1, due to truncation, invisible text etc.  In an
-     up-to-date display, this should always be equal to the start
-     position of the next row.  BIDI Note: this is the character whose
-     buffer position is the largest, but not necessarily the rightmost
-     one on the display.  */
+     glyph position + 1, due to a newline that ends the line,
+     truncation, invisible text etc.  In an up-to-date display, this
+     should always be equal to the start position of the next row.
+     BIDI Note: In R2L rows, this position is at or beyond the left
+     edge of the row.  */
   struct display_pos end;
 
+  /* The smallest and the largest buffer positions that contributed to
+     glyphs in this row.  Note that due to bidi reordering, these are
+     in general different from the text positions stored in `start'
+     and `end' members above, and also different from the buffer
+     positions recorded in the glyphs displayed the leftmost and
+     rightmost on the screen.  */
+  struct text_pos minpos, maxpos;
+
   /* Non-zero means the overlay arrow bitmap is on this line.
      -1 means use default overlay arrow bitmap, else
      it specifies actual fringe bitmap number.  */
@@ -947,16 +955,16 @@
    displayed by ROW, which is not necessarily the smallest horizontal
    position.  */
 
-#define MATRIX_ROW_START_CHARPOS(ROW) ((ROW)->start.pos.charpos)
-#define MATRIX_ROW_START_BYTEPOS(ROW) ((ROW)->start.pos.bytepos)
+#define MATRIX_ROW_START_CHARPOS(ROW) ((ROW)->minpos.charpos)
+#define MATRIX_ROW_START_BYTEPOS(ROW) ((ROW)->minpos.bytepos)
 
 /* Return the character/ byte position at which ROW ends.  BIDI Note:
    this is the largest character/byte position among characters in
    ROW, i.e. the last logical-order character displayed by ROW, which
    is not necessarily the largest horizontal position.  */
 
-#define MATRIX_ROW_END_CHARPOS(ROW) ((ROW)->end.pos.charpos)
-#define MATRIX_ROW_END_BYTEPOS(ROW) ((ROW)->end.pos.bytepos)
+#define MATRIX_ROW_END_CHARPOS(ROW) ((ROW)->maxpos.charpos)
+#define MATRIX_ROW_END_BYTEPOS(ROW) ((ROW)->maxpos.bytepos)
 
 /* Return the vertical position of ROW in MATRIX.  */
 
@@ -1789,7 +1797,7 @@
   EMACS_INT next_en_pos;	/* position of next EN char for ET */
   EMACS_INT ignore_bn_limit;	/* position until which to ignore BNs */
   bidi_dir_t sor;		/* direction of start-of-run in effect */
-  int scan_dir;			/* direction of text scan */
+  int scan_dir;			/* direction of text scan, 1: forw, -1: back */
   int stack_idx;		/* index of current data on the stack */
   /* Note: Everything from here on is not copied/saved when the bidi
      iterator state is saved, pushed, or popped.  So only put here
--- a/src/dispnew.c	Sat May 22 03:32:53 2010 +0000
+++ b/src/dispnew.c	Sun May 23 11:52:45 2010 +0000
@@ -1188,6 +1188,10 @@
   MATRIX_ROW_START_BYTEPOS (row) += delta_bytes;
   MATRIX_ROW_END_CHARPOS (row) += delta;
   MATRIX_ROW_END_BYTEPOS (row) += delta_bytes;
+  CHARPOS (row->start.pos) += delta;
+  BYTEPOS (row->start.pos) += delta_bytes;
+  CHARPOS (row->end.pos) += delta;
+  BYTEPOS (row->end.pos) += delta_bytes;
 
   if (!row->enabled_p)
     return;
@@ -1748,13 +1752,19 @@
       /* Check that character and byte positions are in sync.  */
       xassert (MATRIX_ROW_START_BYTEPOS (row)
 	       == CHAR_TO_BYTE (MATRIX_ROW_START_CHARPOS (row)));
+      xassert (BYTEPOS (row->start.pos)
+	       == CHAR_TO_BYTE (CHARPOS (row->start.pos)));
 
       /* CHAR_TO_BYTE aborts when invoked for a position > Z.  We can
 	 have such a position temporarily in case of a minibuffer
 	 displaying something like `[Sole completion]' at its end.  */
       if (MATRIX_ROW_END_CHARPOS (row) < BUF_ZV (current_buffer))
-	xassert (MATRIX_ROW_END_BYTEPOS (row)
-		 == CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row)));
+	{
+	  xassert (MATRIX_ROW_END_BYTEPOS (row)
+		   == CHAR_TO_BYTE (MATRIX_ROW_END_CHARPOS (row)));
+	  xassert (BYTEPOS (row->end.pos)
+		   == CHAR_TO_BYTE (CHARPOS (row->end.pos)));
+	}
 
       /* Check that end position of `row' is equal to start position
 	 of next row.  */
@@ -1764,6 +1774,8 @@
 		   == MATRIX_ROW_START_CHARPOS (next));
 	  xassert (MATRIX_ROW_END_BYTEPOS (row)
 		   == MATRIX_ROW_START_BYTEPOS (next));
+	  xassert (CHARPOS (row->end.pos) == CHARPOS (next->start.pos));
+	  xassert (BYTEPOS (row->end.pos) == BYTEPOS (next->start.pos));
 	}
       row = next;
     }
--- a/src/image.c	Sat May 22 03:32:53 2010 +0000
+++ b/src/image.c	Sun May 23 11:52:45 2010 +0000
@@ -1689,11 +1689,13 @@
 }
 
 
-DEFUN ("image-refresh", Fimage_refresh, Simage_refresh,
+DEFUN ("image-flush", Fimage_flush, Simage_flush,
        1, 2, 0,
-       doc: /* Refresh the image with specification SPEC on frame FRAME.
-If SPEC specifies an image file, the displayed image is updated with
-the current contents of that file.
+       doc: /* Fush the image with specification SPEC on frame FRAME.
+This removes the image from the Emacs image cache.  If SPEC specifies
+an image file, the next redisplay of this image will read from the
+current contents of that file.
+
 FRAME nil or omitted means use the selected frame.
 FRAME t means refresh the image on all frames.  */)
      (spec, frame)
@@ -8526,7 +8528,7 @@
 
   defsubr (&Sinit_image_library);
   defsubr (&Sclear_image_cache);
-  defsubr (&Simage_refresh);
+  defsubr (&Simage_flush);
   defsubr (&Simage_size);
   defsubr (&Simage_mask_p);
   defsubr (&Simage_metadata);
--- a/src/w32.c	Sat May 22 03:32:53 2010 +0000
+++ b/src/w32.c	Sun May 23 11:52:45 2010 +0000
@@ -5700,7 +5700,34 @@
     }
   else
 #endif
-    nchars = _write (fd, buffer, count);
+    {
+      /* Some networked filesystems don't like too large writes, so
+	 break them into smaller chunks.  See the Comments section of
+	 the MSDN documentation of WriteFile for details behind the
+	 choice of the value of CHUNK below.  See also the thread
+	 http://thread.gmane.org/gmane.comp.version-control.git/145294
+	 in the git mailing list.  */
+      const unsigned char *p = buffer;
+      const unsigned chunk = 30 * 1024 * 1024;
+
+      nchars = 0;
+      while (count > 0)
+	{
+	  unsigned this_chunk = count < chunk ? count : chunk;
+	  int n = _write (fd, p, this_chunk);
+
+	  nchars += n;
+	  if (n < 0)
+	    {
+	      nchars = n;
+	      break;
+	    }
+	  else if (n < this_chunk)
+	    break;
+	  count -= n;
+	  p += n;
+	}
+    }
 
   return nchars;
 }
--- a/src/xdisp.c	Sat May 22 03:32:53 2010 +0000
+++ b/src/xdisp.c	Sun May 23 11:52:45 2010 +0000
@@ -2598,7 +2598,7 @@
 init_iterator (it, w, charpos, bytepos, row, base_face_id)
      struct it *it;
      struct window *w;
-     int charpos, bytepos;
+     EMACS_INT charpos, bytepos;
      struct glyph_row *row;
      enum face_id base_face_id;
 {
@@ -3012,7 +3012,7 @@
      struct window *w;
      struct display_pos *pos;
 {
-  int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
+  EMACS_INT charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
   int i, overlay_strings_with_newlines = 0;
 
   /* If POS specifies a position in a display vector, this might
@@ -14975,7 +14975,7 @@
   /* The variable new_start now holds the new window start.  The old
      start `start' can be determined from the current matrix.  */
   SET_TEXT_POS_FROM_MARKER (new_start, w->start);
-  start = start_row->start.pos;
+  start = start_row->minpos;
   start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
 
   /* Clear the desired matrix for the display below.  */
@@ -15014,7 +15014,7 @@
 	    {
 	      /* Advance to the next row as the "start".  */
 	      start_row++;
-	      start = start_row->start.pos;
+	      start = start_row->minpos;
 	      /* If there are no more rows to try, or just one, give up.  */
 	      if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
 		  || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
@@ -15296,39 +15296,26 @@
 	    {
 	      struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
 	      struct glyph *end = glyph + row->used[TEXT_AREA];
-	      struct glyph *orig_glyph = glyph;
-	      struct cursor_pos orig_cursor = w->cursor;
-
-	      for (; glyph < end
-		     && (!BUFFERP (glyph->object)
-			 || glyph->charpos != PT);
-		   glyph++)
-		{
-		  w->cursor.hpos++;
-		  w->cursor.x += glyph->pixel_width;
-		}
-	      /* With bidi reordering, charpos changes non-linearly
-		 with hpos, so the right glyph could be to the
-		 left.  */
-	      if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering)
-		  && (!BUFFERP (glyph->object) || glyph->charpos != PT))
-		{
-		  struct glyph *start_glyph = row->glyphs[TEXT_AREA];
-
-		  glyph = orig_glyph - 1;
-		  orig_cursor.hpos--;
-		  orig_cursor.x -= glyph->pixel_width;
-		  for (; glyph >= start_glyph
-			 && (!BUFFERP (glyph->object)
-			     || glyph->charpos != PT);
-		       glyph--)
-		    {
-		      w->cursor.hpos--;
-		      w->cursor.x -= glyph->pixel_width;
-		    }
-		  if (BUFFERP (glyph->object) && glyph->charpos == PT)
-		    w->cursor = orig_cursor;
-		}
+
+	      /* Can't use this optimization with bidi-reordered glyph
+		 rows, unless cursor is already at point. */
+	      if (!NILP (XBUFFER (w->buffer)->bidi_display_reordering))
+		{
+		  if (!(w->cursor.hpos >= 0
+			&& w->cursor.hpos < row->used[TEXT_AREA]
+			&& BUFFERP (glyph->object)
+			&& glyph->charpos == PT))
+		    return 0;
+		}
+	      else
+		for (; glyph < end
+		       && (!BUFFERP (glyph->object)
+			   || glyph->charpos < PT);
+		     glyph++)
+		  {
+		    w->cursor.hpos++;
+		    w->cursor.x += glyph->pixel_width;
+		  }
 	    }
 	}
 
@@ -15908,13 +15895,13 @@
 	 as is, without changing glyph positions since no text has
 	 been added/removed in front of the window end.  */
       r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
-      if (TEXT_POS_EQUAL_P (start, r0->start.pos)
+      if (TEXT_POS_EQUAL_P (start, r0->minpos)
 	  /* PT must not be in a partially visible line.  */
 	  && !(PT >= MATRIX_ROW_START_CHARPOS (row)
 	       && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
 	{
 	  /* We have to compute the window end anew since text
-	     can have been added/removed after it.  */
+	     could have been added/removed after it.  */
 	  w->window_end_pos
 	    = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
 	  w->window_end_bytepos
@@ -15946,7 +15933,7 @@
      start is not in changed text, otherwise positions would not be
      comparable.  */
   row = MATRIX_FIRST_TEXT_ROW (current_matrix);
-  if (!TEXT_POS_EQUAL_P (start, row->start.pos))
+  if (!TEXT_POS_EQUAL_P (start, row->minpos))
     GIVE_UP (16);
 
   /* Give up if the window ends in strings.  Overlay strings
@@ -17338,7 +17325,7 @@
 {
   int cursor_row_p = 1;
 
-  if (PT == MATRIX_ROW_END_CHARPOS (row))
+  if (PT == CHARPOS (row->end.pos))
     {
       /* Suppose the row ends on a string.
 	 Unless the row is continued, that means it ends on a newline
@@ -17375,14 +17362,15 @@
 	{
 	  /* If the row ends in middle of a real character,
 	     and the line is continued, we want the cursor here.
-	     That's because MATRIX_ROW_END_CHARPOS would equal
+	     That's because CHARPOS (ROW->end.pos) would equal
 	     PT if PT is before the character.  */
 	  if (!row->ends_in_ellipsis_p)
 	    cursor_row_p = row->continued_p;
 	  else
 	  /* If the row ends in an ellipsis, then
-	     MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
-	     We want that position to be displayed after the ellipsis.  */
+	     CHARPOS (ROW->end.pos) will equal point after the
+	     invisible text.  We want that position to be displayed
+	     after the ellipsis.  */
 	    cursor_row_p = 0;
 	}
       /* If the row ends at ZV, display the cursor at the end of that
@@ -17518,122 +17506,87 @@
     glyph[-n] = *glyph;
 }
 
-/* Find the positions in a bidi-reordered ROW to serve as ROW->start
-   and ROW->end.  */
-static struct display_pos
-find_row_end (it, row)
+/* Find the positions in a bidi-reordered ROW to serve as ROW->minpos
+   and ROW->maxpos.  */
+static void
+find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos)
      struct it *it;
      struct glyph_row *row;
+     EMACS_INT min_pos, min_bpos, max_pos, max_bpos;
 {
   /* FIXME: Revisit this when glyph ``spilling'' in continuation
      lines' rows is implemented for bidi-reordered rows.  */
-  EMACS_INT min_pos = ZV + 1, max_pos = 0;
-  struct glyph *g;
-  struct it save_it;
-  struct text_pos tpos;
-  struct display_pos row_end = it->current;
-
-  for (g = row->glyphs[TEXT_AREA];
-       g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
-       g++)
-    {
-      if (BUFFERP (g->object))
-	{
-	  if (g->charpos > 0 && g->charpos < min_pos)
-	    min_pos = g->charpos;
-	  if (g->charpos > max_pos)
-	    max_pos = g->charpos;
-	}
-    }
-  /* Empty lines have a valid buffer position at their first
-     glyph, but that glyph's OBJECT is zero, as if it didn't come
-     from a buffer.  If we didn't find any valid buffer positions
-     in this row, maybe we have such an empty line.  */
-  if (max_pos == 0 && row->used[TEXT_AREA])
-    {
-      for (g = row->glyphs[TEXT_AREA];
-	   g < row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
-	   g++)
-	{
-	  if (INTEGERP (g->object))
-	    {
-	      if (g->charpos > 0 && g->charpos < min_pos)
-		min_pos = g->charpos;
-	      if (g->charpos > max_pos)
-		max_pos = g->charpos;
-	    }
-	}
-    }
-
-  /* ROW->start is the value of min_pos, the minimal buffer position
+
+  /* ROW->minpos is the value of min_pos, the minimal buffer position
      we have in ROW.  */
   if (min_pos <= ZV)
-    {
-      /* Avoid calling the costly CHAR_TO_BYTE if possible.  */
-      if (min_pos != row->start.pos.charpos)
-	SET_TEXT_POS (row->start.pos, min_pos, CHAR_TO_BYTE (min_pos));
-      if (max_pos == 0)
-	max_pos = min_pos;
-    }
-
-  /* For ROW->end, we need the position that is _after_ max_pos, in
-     the logical order, unless we are at ZV.  */
+    SET_TEXT_POS (row->minpos, min_pos, min_bpos);
+  else
+    {
+      /* We didn't find _any_ valid buffer positions in any of the
+	 glyphs, so we must trust the iterator's computed
+	 positions.  */
+      row->minpos = row->start.pos;
+      max_pos = CHARPOS (it->current.pos);
+      max_bpos = BYTEPOS (it->current.pos);
+    }
+
+  if (!max_pos)
+    abort ();
+
+  /* Here are the various use-cases for ending the row, and the
+     corresponding values for ROW->maxpos:
+
+     Line ends in a newline from buffer       eol_pos + 1
+     Line is continued from buffer            max_pos + 1
+     Line is truncated on right               it->current.pos
+     Line ends in a newline from string       max_pos
+     Line is continued from string            max_pos
+     Line is continued from display vector    max_pos
+     Line is entirely from a string           min_pos == max_pos
+     Line is entirely from a display vector   min_pos == max_pos
+     Line that ends at ZV                     ZV
+
+     If you discover other use-cases, please add them here as
+     appropriate.  */
   if (row->ends_at_zv_p)
-    {
-      if (!row->used[TEXT_AREA])
-	row->start.pos = row_end.pos;
-    }
-  else if (row->used[TEXT_AREA] && max_pos)
-    {
-      int at_eol_p;
-
-      SET_TEXT_POS (tpos, max_pos, CHAR_TO_BYTE (max_pos));
-      save_it = *it;
-      it->bidi_p = 0;
-      reseat (it, tpos, 0);
-      if (!get_next_display_element (it))
-	abort ();	/* this row cannot be at ZV, see above */
-      at_eol_p = ITERATOR_AT_END_OF_LINE_P (it);
-      set_iterator_to_next (it, 1);
-      row_end = it->current;
-      /* If the character at max_pos is not a newline and the
-	 characters at max_pos+1 is a newline, skip that newline as
-	 well.  Note that this may skip some invisible text.  */
-      if (!at_eol_p
-	  && get_next_display_element (it)
-	  && ITERATOR_AT_END_OF_LINE_P (it))
-	{
-	  set_iterator_to_next (it, 1);
-	  /* Record the position after the newline of a continued row.
-	     We will need that to set ROW->end of the last row
-	     produced for a continued line.  */
-	  if (row->continued_p)
-	    save_it.eol_pos = it->current.pos;
-	  else
-	    {
-	      row_end = it->current;
-	      save_it.eol_pos.charpos = save_it.eol_pos.bytepos = 0;
-	    }
-	}
-      else if (!row->continued_p
-	       && MATRIX_ROW_CONTINUATION_LINE_P (row)
-	       && it->eol_pos.charpos > 0)
-	{
-	  /* Last row of a continued line.  Use the position recorded
-	     in IT->eol_pos, to the effect that the newline belongs to
-	     this row, not to the row which displays the character
-	     with the largest buffer position before the newline.  */
-	  row_end.pos = it->eol_pos;
-	  it->eol_pos.charpos = it->eol_pos.bytepos = 0;
-	}
-      *it = save_it;
-      /* The members of ROW->end that are not taken from buffer
-	 positions are copied from IT->current.  */
-      row_end.string_pos = it->current.string_pos;
-      row_end.overlay_string_index = it->current.overlay_string_index;
-      row_end.dpvec_index = it->current.dpvec_index;
-    }
-  return row_end;
+    row->maxpos = it->current.pos;
+  else if (row->used[TEXT_AREA])
+    {
+      if (row->ends_in_newline_from_string_p)
+	SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
+      else if (CHARPOS (it->eol_pos) > 0)
+	SET_TEXT_POS (row->maxpos,
+		      CHARPOS (it->eol_pos) + 1, BYTEPOS (it->eol_pos) + 1);
+      else if (row->continued_p)
+	{
+	  /* If max_pos is different from IT's current position, it
+	     means IT->method does not belong to the display element
+	     at max_pos.  However, it also means that the display
+	     element at max_pos was displayed in its entirety on this
+	     line, which is equivalent to saying that the next line
+	     starts at the next buffer position.  */
+	  if (IT_CHARPOS (*it) == max_pos && it->method != GET_FROM_BUFFER)
+	    SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
+	  else
+	    {
+	      INC_BOTH (max_pos, max_bpos);
+	      SET_TEXT_POS (row->maxpos, max_pos, max_bpos);
+	    }
+	}
+      else if (row->truncated_on_right_p)
+	/* display_line already called reseat_at_next_visible_line_start,
+	   which puts the iterator at the beginning of the next line, in
+	   the logical order. */
+	row->maxpos = it->current.pos;
+      else if (max_pos == min_pos && it->method != GET_FROM_BUFFER)
+	/* A line that is entirely from a string/image/stretch...  */
+	row->maxpos = row->minpos;
+      else
+	abort ();
+    }
+  else
+    row->maxpos = it->current.pos;
 }
 
 /* Construct the glyph row IT->glyph_row in the desired matrix of
@@ -17653,7 +17606,10 @@
   int wrap_row_used = -1, wrap_row_ascent, wrap_row_height;
   int wrap_row_phys_ascent, wrap_row_phys_height;
   int wrap_row_extra_line_spacing;
+  EMACS_INT wrap_row_min_pos, wrap_row_min_bpos;
+  EMACS_INT wrap_row_max_pos, wrap_row_max_bpos;
   int cvpos;
+  EMACS_INT min_pos = ZV + 1, min_bpos, max_pos = 0, max_bpos;
 
   /* We always start displaying at hpos zero even if hscrolled.  */
   xassert (it->hpos == 0 && it->current_x == 0);
@@ -17710,6 +17666,23 @@
   row->phys_height = it->max_phys_ascent + it->max_phys_descent;
   row->extra_line_spacing = it->max_extra_line_spacing;
 
+/* Utility macro to record max and min buffer positions seen until now.  */
+#define RECORD_MAX_MIN_POS(IT)					\
+  do								\
+    {								\
+      if (IT_CHARPOS (*(IT)) < min_pos)				\
+	{							\
+	  min_pos = IT_CHARPOS (*(IT));				\
+	  min_bpos = IT_BYTEPOS (*(IT));			\
+	}							\
+      if (IT_CHARPOS (*(IT)) > max_pos)				\
+	{							\
+	  max_pos = IT_CHARPOS (*(IT));				\
+	  max_bpos = IT_BYTEPOS (*(IT));			\
+	}							\
+    }								\
+  while (0)
+
   /* Loop generating characters.  The loop is left with IT on the next
      character to display.  */
   while (1)
@@ -17744,7 +17717,8 @@
 	  row->ends_at_zv_p = 1;
 	  /* A row that displays right-to-left text must always have
 	     its last face extended all the way to the end of line,
-	     even if this row ends in ZV.  */
+	     even if this row ends in ZV, because we still write to th
+	     screen left to right.  */
 	  if (row->reversed_p)
 	    extend_face_to_end_of_line (it);
 	  break;
@@ -17778,6 +17752,10 @@
 		  wrap_row_phys_ascent = row->phys_ascent;
 		  wrap_row_phys_height = row->phys_height;
 		  wrap_row_extra_line_spacing = row->extra_line_spacing;
+		  wrap_row_min_pos = min_pos;
+		  wrap_row_min_bpos = min_bpos;
+		  wrap_row_max_pos = max_pos;
+		  wrap_row_max_bpos = max_bpos;
 		  may_wrap = 0;
 		}
 	    }
@@ -17828,6 +17806,10 @@
 					 it->max_extra_line_spacing);
 	  if (it->current_x - it->pixel_width < it->first_visible_x)
 	    row->x = x - it->first_visible_x;
+	  /* Record the maximum and minimum buffer positions seen so
+	     far in glyphs that will be displayed by this row.  */
+	  if (it->bidi_p)
+	    RECORD_MAX_MIN_POS (it);
 	}
       else
 	{
@@ -17861,6 +17843,11 @@
 		      it->current_x = new_x;
 		      it->continuation_lines_width += new_x;
 		      ++it->hpos;
+		      /* Record the maximum and minimum buffer
+			 positions seen so far in glyphs that will be
+			 displayed by this row.  */
+		      if (it->bidi_p)
+			RECORD_MAX_MIN_POS (it);
 		      if (i == nglyphs - 1)
 			{
 			  /* If line-wrap is on, check if a previous
@@ -17935,6 +17922,10 @@
 		      row->phys_ascent = wrap_row_phys_ascent;
 		      row->phys_height = wrap_row_phys_height;
 		      row->extra_line_spacing = wrap_row_extra_line_spacing;
+		      min_pos = wrap_row_min_pos;
+		      min_bpos = wrap_row_min_bpos;
+		      max_pos = wrap_row_max_pos;
+		      max_bpos = wrap_row_max_bpos;
 		      row->continued_p = 1;
 		      row->ends_at_zv_p = 0;
 		      row->exact_window_width_line_p = 0;
@@ -17997,6 +17988,12 @@
 		  /* Increment number of glyphs actually displayed.  */
 		  ++it->hpos;
 
+		  /* Record the maximum and minimum buffer positions
+		     seen so far in glyphs that will be displayed by
+		     this row.  */
+		  if (it->bidi_p)
+		    RECORD_MAX_MIN_POS (it);
+
 		  if (x < it->first_visible_x)
 		    /* Glyph is partially visible, i.e. row starts at
 		       negative X position.  */
@@ -18048,6 +18045,10 @@
 	  if (used_before == 0)
 	    row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
 
+	  /* Record the position of the newline, for use in
+	     find_row_edges.  */
+	  it->eol_pos = it->current.pos;
+
 	  /* Consume the line end.  This skips over invisible lines.  */
 	  set_iterator_to_next (it, 1);
 	  it->continuation_lines_width = 0;
@@ -18127,7 +18128,7 @@
   /* If line is not empty and hscrolled, maybe insert truncation glyphs
      at the left window margin.  */
   if (it->first_visible_x
-      && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
+      && IT_CHARPOS (*it) != CHARPOS (row->start.pos))
     {
       if (!FRAME_WINDOW_P (it->f))
 	insert_left_trunc_glyphs (it);
@@ -18181,12 +18182,19 @@
 
   /* Remember the position at which this line ends.  */
   row->end = it->current;
-  /* ROW->start and ROW->end must be the smallest and the largest
-     buffer positions in ROW.  But if ROW was bidi-reordered, these
-     two positions can be anywhere in the row, so we must rescan all
-     of the ROW's glyphs to find them.  */
-  if (it->bidi_p)
-    row->end = find_row_end (it, row);
+  if (!it->bidi_p)
+    {
+      row->minpos = row->start.pos;
+      row->maxpos = row->end.pos;
+    }
+  else
+    {
+      /* ROW->minpos and ROW->maxpos must be the smallest and
+	 `1 + the largest' buffer positions in ROW.  But if ROW was
+	 bidi-reordered, these two positions can be anywhere in the
+	 row, so we must determine them now.  */
+      find_row_edges (it, row, min_pos, min_bpos, max_pos, max_bpos);
+    }
 
   /* Record whether this row ends inside an ellipsis.  */
   row->ends_in_ellipsis_p
@@ -18232,6 +18240,7 @@
      row to be used.  */
   it->current_x = it->hpos = 0;
   it->current_y += row->height;
+  SET_TEXT_POS (it->eol_pos, 0, 0);
   ++it->vpos;
   ++it->glyph_row;
   /* The next row should by default use the same value of the
@@ -18242,6 +18251,8 @@
     it->glyph_row->reversed_p = row->reversed_p;
   it->start = row->end;
   return row->displays_text_p;
+
+#undef RECORD_MAX_MIN_POS
 }
 
 DEFUN ("current-bidi-paragraph-direction", Fcurrent_bidi_paragraph_direction,