changeset 5048:32e1ae4c1e3a

merge
author Ben Wing <ben@xemacs.org>
date Sat, 20 Feb 2010 23:34:25 -0600
parents 07dcc7000bbf (current diff) 9624523604c5 (diff)
children 548f1f47eb82
files man/ChangeLog man/term.texi src/ChangeLog src/syswindows.h tests/ChangeLog
diffstat 13 files changed, 952 insertions(+), 470 deletions(-) [+]
line wrap: on
line diff
--- a/lib-src/ChangeLog	Sat Feb 20 18:56:01 2010 -0600
+++ b/lib-src/ChangeLog	Sat Feb 20 23:34:25 2010 -0600
@@ -1,3 +1,14 @@
+2010-02-11  Vin Shelton  <acs@xemacs.org>
+ 
+ 	* winclient.c: Bump connection retries to 20 because some people
+	have long startup files.
+	(openConversation): If CreateProcess cannot find
+ 	xemacs.exe, try again with the name of the version-specific
+ 	executable.  This is useful because the cygwin version of XEmacs
+ 	doesn't install an xemacs.exe executable.
+	(parseCommandLine): Fix tracker issue 675 - add current	directory
+	to filenames under cygwin. 
+
 2010-01-26  Ben Wing  <ben@xemacs.org>
 
 	* make-msgfile.lex: Vague hacking on this file, insert a comment
--- a/lib-src/winclient.c	Sat Feb 20 18:56:01 2010 -0600
+++ b/lib-src/winclient.c	Sat Feb 20 23:34:25 2010 -0600
@@ -32,6 +32,11 @@
 #include <ctype.h>
 #include <errno.h>
 
+#ifdef __CYGWIN__
+#include <stdlib.h>
+#include <unistd.h>
+#endif
+
 static void error (const char* s1, const char* s2);
 static void fatal (const char *s1, const char *s2);
 static void * xmalloc (size_t size);
@@ -40,7 +45,7 @@
 /* -- Post-Include Defines -------------------------------------------------- */
 
 /* Timeouts & delays */
-#define CONNECT_RETRIES		10
+#define CONNECT_RETRIES		20
 #define CONNECT_DELAY		500		/* ms */
 #define TRANSACTION_TIMEOUT	5000		/* ms */
 #define MAX_INPUT_IDLE_WAIT     INFINITE	/* ms */
@@ -51,7 +56,8 @@
 #define COMMAND_FORMAT	"[open(\"%s%s\")]"
 
 /* XEmacs program name */
-#define PROGRAM_TO_RUN	"xemacs.exe"
+#define GENERIC_PROGRAM		EMACS_PROGNAME ".exe"
+#define VERSIONED_PROGRAM	EMACS_PROGNAME "-" EMACS_VERSION ".exe"
 
 /* -- Constants ------------------------------------------------------------- */
 
@@ -107,7 +113,7 @@
   HCONV hConv;
   int   ret = 0;
   UINT  uiRet;
-  
+
   /* Initialise the DDEML library */
   uiRet = DdeInitialize (&idInst,
 			 (PFNCALLBACK) ddeCallback,
@@ -134,7 +140,7 @@
       /* Close the conversation */
       closeConversation (hConv);
     }
-  
+
   DdeUninitialize (idInst);
 
   return ret;
@@ -164,7 +170,7 @@
 
       goto error;
     }
-  
+
   /* Get the topic name */
   hszTopic = DdeCreateStringHandle (idInst,
 				    TOPIC_NAME,
@@ -186,11 +192,13 @@
       STARTUPINFO         sti;
       PROCESS_INFORMATION pi;
       int                 n;
-      
+
       /* Try to start the program */
       ZeroMemory (&sti, sizeof (sti));
       sti.cb = sizeof (sti);
-      if (!CreateProcess (NULL, PROGRAM_TO_RUN, NULL, NULL, FALSE, 0,
+      if (!CreateProcess (NULL, GENERIC_PROGRAM, NULL, NULL, FALSE, 0,
+			  NULL, NULL, &sti, &pi) &&
+	  !CreateProcess (NULL, VERSIONED_PROGRAM, NULL, NULL, FALSE, 0,
 			  NULL, NULL, &sti, &pi))
 	{
 	  MessageBox (NULL, "Could not start process.",
@@ -205,12 +213,12 @@
       /* Close the handles */
       CloseHandle (pi.hThread);
       CloseHandle (pi.hProcess);
-      
+
       /* Try to connect */
       for (n = 0; n < CONNECT_RETRIES; n++)
 	{
 	  Sleep (CONNECT_DELAY);
-	  
+	
 	  hConv = DdeConnect (idInst, hszService, hszTopic, NULL);
 
 	  if (hConv)
@@ -232,7 +240,7 @@
   DdeFreeStringHandle (idInst, hszTopic);
 
   return hConv;
-  
+
  error:
   if (hConv)
     DdeDisconnect (hConv);
@@ -268,11 +276,11 @@
 {
   char            *buf = NULL;
   unsigned        len;
-  
+
   /* Calculate the buffer length */
   len = strlen (lpszFileName1) + strlen (lpszFileName2)
     + strlen (COMMAND_FORMAT);
-  
+
   /* Allocate a buffer */
   buf = (char *) xmalloc (len);
 
@@ -286,15 +294,14 @@
 
   /* Build the command */
   len = wsprintf (buf, COMMAND_FORMAT, lpszFileName1, lpszFileName2);
+  len++;
 
-  len++;
-  
   /* OK. We're connected. Send the message. */
   DdeClientTransaction (buf, len, hConv, NULL,
 			0, XTYP_EXECUTE, TRANSACTION_TIMEOUT, NULL);
 
   free (buf);
-  
+
   return 0;
 }
 
@@ -319,14 +326,14 @@
   /* If this is the end, return NULL */
   if (!*p)
     return NULL;
-  
+
   /* Remember where we are */
   start = p;
-  
+
   /* Find the next whitespace character outside quotes */
   if (*p == '"')
     all_in_quotes = 1;
-  
+
   while (*p && !quit)
     {
       switch (*p)
@@ -339,7 +346,7 @@
 	case '\\':
 	  if (!in_quotes)
 	    all_in_quotes = 0;
-	  
+	
 	  p++;
 
 	  if (!*p)
@@ -368,13 +375,13 @@
       start++;
       length -= 2;
     }
-  
+
   /* Copy */
   buf = (char *) xmalloc (length + 1);
 
   if (!buf)
     return NULL;
-  
+
   strncpy (buf, start, length);
   buf[length] = '\0';
 
@@ -405,6 +412,38 @@
   /* Retrieve arguments */
   while ((arg = getNextArg ((const char**)&lpszCommandLine, &len)) != NULL)
     {
+      fullpath = NULL;
+#ifdef __CYGWIN__
+      /* If the filename is not an absolute path,
+	 add the current directory to the pathname */
+      if (*arg != '/')
+	{
+	  len = pathconf(".", _PC_PATH_MAX);
+	  fullpath = (char *) xmalloc (len+1);
+	  if (!fullpath)
+	    {
+		MessageBox (NULL, "Not enough memory.", "winclient",
+			    MB_ICONEXCLAMATION | MB_OK);
+		ret = 1;
+		break;
+	    }
+	  if (!getcwd(fullpath, (size_t)len))
+	    {
+	      MessageBox (NULL, "Could not retrieve current directory.",
+			  "winclient", MB_ICONEXCLAMATION | MB_OK);
+	      ret = 1;
+	      break;
+	    }
+          /* Append trailing slash */
+	  strcat(fullpath, "/");
+	  ret = doFile (hConv, fullpath, arg);
+	}
+      else
+	{
+	  /* The arg has already been expanded, so pass it as it is */
+	  ret = doFile (hConv, "", arg);
+	}
+#else
       /* First find the canonical path name */
       fullpath = filepart = NULL;
       pathlen = GetFullPathName (arg, 0, fullpath, &filepart);
@@ -415,10 +454,7 @@
 	{
 	  MessageBox (NULL, "Not enough memory.", "winclient",
 		      MB_ICONEXCLAMATION | MB_OK);
-	  
 	  ret = 1;
-	  free (arg);
-	  
 	  break;
 	}
 
@@ -448,9 +484,10 @@
 
 	  FindClose (hFindFile);
 	}
-
+#endif
       /* Release the path name buffers */
-      free (fullpath);
+      if (fullpath)
+	free (fullpath);
       free (arg);
 
       if (ret)
--- a/man/ChangeLog	Sat Feb 20 18:56:01 2010 -0600
+++ b/man/ChangeLog	Sat Feb 20 23:34:25 2010 -0600
@@ -21,6 +21,31 @@
 	* internals/internals.texi (The Redisplay Mechanism):
 	Integrate the long comment in frame.c into the internals manual.
 
+2010-02-17  Jerry James  <james@xemacs.org>
+
+	* term.texi: Move to the eterm package.
+	* Makefile: Remove all rules relating to term.texi.
+
+2010-02-10  Stephen J. Turnbull  <stephen@xemacs.org>
+
+	* xemacs-faq.texi (Top): Update menu.
+	(Legacy Versions): Update next pointer.
+	(Bleeding Edge):
+	(Q11.0.1):
+	(Q11.0.2):
+	(Q11.0.3):
+	(Q11.0.4):
+	(Q11.0.5):
+	(Q11.1.1):
+	(Q11.2.1):
+	(Q11.2.2):
+	(Q11.2.3):
+	(Q11.2.4):
+	(Q11.2.5):
+	(Q11.2.6):
+	(Q11.2.7):
+	New nodes, describing repositories and VCS usage.
+
 2010-02-08  Ben Wing  <ben@xemacs.org>
 
 	* internals/internals.texi (How Lisp Objects Are Represented in C):
--- a/man/Makefile	Sat Feb 20 18:56:01 2010 -0600
+++ b/man/Makefile	Sat Feb 20 23:34:25 2010 -0600
@@ -54,7 +54,6 @@
 	$(INFODIR)/lispref.info \
 	$(INFODIR)/new-users-guide.info \
 	$(INFODIR)/standards.info \
-	$(INFODIR)/term.info \
 	$(INFODIR)/termcap.info \
 	$(INFODIR)/texinfo.info \
 	$(INFODIR)/widget.info \
@@ -72,7 +71,6 @@
 	$(HTMLDIR)/internals.html \
 	$(HTMLDIR)/new-users-guide.html \
 	$(HTMLDIR)/standards.html \
-	$(HTMLDIR)/term.html \
 	$(HTMLDIR)/termcap.html \
 	$(HTMLDIR)/texinfo.html \
 	$(HTMLDIR)/widget.html \
@@ -90,7 +88,6 @@
 	internals.dvi \
 	new-users-guide.dvi \
 	standards.dvi \
-	term.dvi \
 	termcap.dvi \
 	texinfo.dvi \
 	widget.dvi \
@@ -108,7 +105,6 @@
        internals.pdf \
        new-users-guide.pdf \
        standards.pdf \
-       term.pdf \
        termcap.pdf \
        texinfo.pdf \
        widget.pdf \
@@ -264,9 +260,6 @@
 $(INFODIR)/standards.info : standards.texi
 	$(MAKEINFO) -o $(INFODIR)/standards.info standards.texi
 
-$(INFODIR)/term.info : term.texi
-	$(MAKEINFO) -o $(INFODIR)/term.info term.texi
-
 $(INFODIR)/termcap.info : termcap.texi
 	$(MAKEINFO) -o $(INFODIR)/termcap.info termcap.texi
 
@@ -375,9 +368,6 @@
 $(HTMLDIR)/standards.html : standards.texi
 	$(TEXI2HTML_SPLIT) standards.texi
 
-$(HTMLDIR)/term.html : term.texi
-	$(TEXI2HTML_SPLIT) term.texi
-
 $(HTMLDIR)/termcap.html : termcap.texi
 	$(TEXI2HTML_SPLIT) termcap.texi
 
--- a/man/term.texi	Sat Feb 20 18:56:01 2010 -0600
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,394 +0,0 @@
-@\input texinfo @c -*-texinfo-*-
-@setfilename ../info/term.info
-@settitle XEmacs Terminal Emulator Mode
-
-@titlepage
-@sp 6
-@center @titlefont(XEmacs Terminal Emulator Mode)
-@end titlepage
-
-@ifinfo
-@dircategory XEmacs Editor
-@direntry
-* Term mode: (term).		XEmacs Terminal Emulator Mode.
-@end direntry
-
-@node Top, , (DIR)
-@top Terminal emulator mode
-@end ifinfo
-
-This is some notes about the term Emacs mode.
-
-@menu
-* term mode::
-@end menu
-
-@node term mode
-@chapter XEmacs Terminal Emulator Mode
-
-@menu
-* Overview::
-* Connecting to remote computers::
-* Paging::
-* Terminal escapes::
-@end menu
-
-The @code{term} package includes the major modes @code{term},
-@code{shell}, and @code{gud} (for running gdb or another debugger).
-It is a replacement for the comint mode of Emacs 19,
-as well as shell, gdb, terminal, and telnet modes.
-The package works best with recent releases of Emacs 19,
-but will also work reasonably well with Emacs 18 as well as Lucid Emacs 19.
-
-The file @code{nshell.el} is a wrapper to use unless term mode
-is built into Emacs.  If works around some of the missing
-in older Emacs versions.
-To use it, edit the paths in @code{nshell.el}, appropriately,
-and then @code{M-x load-file nshell.el RET}.
-This will also load in replacement shell and gud modes.
-
-@node Overview
-@section Overview
-
-The @code{term} mode is used to control a program (an "inferior process").
-It sends most keyboard input characters to the program,
-and displays output from the program in the buffer.
-This is similar to the traditional comint mode, and
-modes derived from it (such as shell and gdb modes).
-You can do with the new term-based shell the same sort
-of things you could do with the old shell mode,
-using more or less the same interface.  However, the
-new mode is more flexible, and works somewhat differently.
-
-@menu
-* Output from the inferior::
-* subbuffer:: The sub-buffer
-* altsubbuffer:: The alternate sub-buffer
-* Input to the inferior::
-@end menu
-
-@node Output from the inferior
-@subsection Output from the inferior
-
-In typical usage, output from the inferior is
-added to the end of the buffer.  If needed, the window
-will be scrolled, just like a regular terminal.
-(Only one line at a time will be scrolled, just like
-regular terminals, and in contrast to the old shell mode.)
-Thus the buffer becomes a log of your interaction with the
-inferior, just like the old shell mode.
-
-Like a real terminal, term maintains a "cursor position."
-This is the @code{process-mark} of the inferior process.
-If the process-mark is not at the end of the buffer, output from
-the inferior will overwrite existing text in the buffer.
-This is like a real terminal, but unlike the old shell mode
-(which inserts the output, instead of overwriting).
-
-Some programs (such as Emacs itself) need to control the
-appearance on the screen in detail.  They do this by
-sending special control codes.  The exact control
-codes needed from terminal to terminal, but nowadays
-most terminals and terminal emulators (including xterm)
-understand the so-called "ANSI escape sequences" (first
-popularized by the Digital's VT100 family of terminal).
-The term mode also understands these escape sequences,
-and for each control code does the appropriate thing
-to change the buffer so that the appearance of the window
-will match what it would be on a real terminal.
-(In contrast, the old shell mode doesn't handle
-terminal control codes at all.)
-
-See <...> for the specific control codes.
-
-@node subbuffer
-@subsection The sub-buffer
-
-A program that talks to terminal expects the terminal to have a fixed size. 
-If the program is talking a terminal emulator program such as @code{xterm},
-that size can be changed (if the xterm window is re-sized), but programs
-still assume a logical terminal that has a fixed size independent
-of the amount of output transmitted by the programs.
-
-To programs that use it, the Emacs terminal emulator acts as if it
-too has a fixed size.  The @dfn{sub-buffer} is the part of a @code{term}-mode
-buffer that corresponds to a "normal" terminal.  Most of the time
-(unless you explicitly scroll the window displaying the buffer),
-the sub-buffer is the part of the buffer that is displayed in a window.
-
-The sub-buffer is defined in terms of three buffer-local-variable:
-
-@defvar term-height
-The height of the sub-buffer, in screen lines.
-@end defvar
-
-@defvar term-width
-The width of the sub-buffer, in screen columns.
-@end defvar
-
-@defvar term-home-marker
-The "home" position, that is the top left corner of the sub-buffer.
-@end defvar
-
-The sub-buffer is assumed to be the end part of the buffer;
-the @code{term-home-marker} should never be more than
-@code{term-height} screen lines from the end of the buffer.
-
-@node altsubbuffer
-@subsection The alternate sub-buffer
-
-When a "graphical" program finishes, it is nice to
-restore the screen state to what it was before the program started.
-Many people are used to this behavior from @code{xterm}, and
-its also offered by the @code{term} emulator.
-
-@defun term-switch-to-alternate-sub-buffer set
-If @var{set} is true, and we're not already using the alternate sub-buffer,
-switch to it.  What this means is that the @code{term-home-marker}
-is saved (in the variable @code{term-saved-home-marker}), and the
-@code{term-home-marker} is set to the end of the buffer.
-
-If @var{set} is false and we're using the alternate sub-buffer,
-switch back to the saved sub-buffer.  What this means is that the
-(current, alternate) sub-buffer is deleted (using
-@code{(delete-region term-home-marker (point-max))}), and then the
-@code{term-home-marker} is restored (from @code{term-saved-home-marker}).
-@end defun
-
-@node Input to the inferior
-@subsection Input to the inferior
-
-Characters typed by the user are sent to the inferior.
-How this is done depends on whether the @code{term} buffer
-is in "character" mode or "line" mode.
-(A @code{term} buffer can also be in "pager" mode.
-This is discussed <later>.)
-Which of these is currently active is specified in the mode line.
-The difference between them is the key-bindings available.
-
-In character mode, one character (by default @key{C-c}) is special,
-and is a prefix for various commands.  All other characters are
-sent directly to the inferior process, with no interpretation by Emacs.
-Character mode looks and feels like a real terminal, or a conventional
-terminal emulator such as xterm.
-
-In line mode, key commands mostly have standard Emacs actions.
-Regulars characters insert themselves into the buffer.
-When return is typed, the entire current line of the buffer
-(except possibly the prompt) is sent to the inferior process.
-Line mode is basically the original shell mode from earlier Emacs versions.
-
-To switch from line mode to character mode type @kbd{C-c C-k}.
-To switch from character mode to line mode type @kbd{C-c C-j}.
-
-In either mode, "echoing" of user input is handled by the inferior.
-Therefor, in line mode after an input line at the end of the buffer
-is sent to the inferior, it is deleted from the buffer.
-This is so that the inferior can echo the input, if it wishes
-(which it normally does).
-
-@node Connecting to remote computers
-@section Connecting to remote computers
-
-If you want to login to a remove computer, you can do that just as
-you would expect, using whatever commands you would normally use.
-
-(This is worth emphasizing, because earlier versions of @code{shell}
-mode would not work properly if you tried to log in to some other
-computer, because of the way echoing was handled.  That is why
-there was a separate @code{telnet} mode to partially compensate for
-these problems.  The @code{telnet} mode is no longer needed, and
-is basically obsolete.)
-
-A program that asks you for a password will normally suppress
-echoing of the password, so the password will not show up in the buffer.
-This will happen just as if you were using a real terminal, if
-the buffer is in char mode.  If it is in line mode, the password
-will be temporarily visible, but will be erased when you hit return.
-(This happens automatically; there is no special password processing.)
-
-When you log in to a different machine, you need to specify the
-type of terminal your using.   If you are talking to a Bourne-compatible
-shell, and your system understands the @code{TERMCAP} variable,
-you can use the command @kbd{M-x shell-send-termcap}, which
-sends a string specifying the terminal type and size.
-(This command is also useful after the window has changed size.)
-
-If you need to specify the terminal type manually, you can try the
-terminal types "ansi" or "vt100".
-
-You can of course run gdb on that remote computer.  One useful
-trick:  If you invoke gdb with the @code{--fullname} option,
-it will send special commands to Emacs that will cause Emacs to
-pop up the source files you're debugging.  This will work
-whether or not gdb is running on a different computer than Emacs,
-assuming can access the source files specified by gdb.
-
-@node Paging
-@section Paging
-
-When the pager is enabled, Emacs will "pause" after each screenful
-of output (since the last input sent to the inferior).
-It will enter "pager" mode, which feels a lot like the "more"
-program:  Typing a space requests another screenful of output.
-Other commands request more or less output, or scroll backwards
-in the @code{term} buffer.  In pager mode, type @kbd{h} or @kbd{?}
-to display a help message listing all the available pager mode commands.
-
-In either character or line mode, type @kbd{C-c p} to enable paging,
-and @kbd{C-c D} to disable it.
-
-@node Terminal escapes
-@section Terminal Escape sequences
-
-A program that does "graphics" on a terminal controls the
-terminal by sending strings called @dfn{terminal escape sequences}
-that the terminal (or terminal emulator) interprets as special commands.
-The @code{term} mode includes a terminal emulator that understands
-standard ANSI escape sequences, originally popularized by VT100 terminals,
-and now used by the @code{xterm} program and most modern terminal
-emulator software.
-
-@menu
-* Cursor motion:: Escape sequences to move the cursor
-* Erasing:: Escape commands for erasing text
-* Inserting and deleting:: Escape sequences to insert and delete text
-* Scrolling:: Escape sequences to scroll part of the visible window
-* Command hook::
-* Miscellaneous escapes::
-@end menu
-
-printing chars
-
-tab
-
-LF
-
-@node Cursor motion
-@subsection Escape sequences to move the cursor
-
-@table @kbd
-@item RETURN
-Moves to the beginning of the current screen line.
-
-@item C-b
-Moves backwards one column.  (Tabs are broken up if needed.)
-@comment Line wrap FIXME
-
-@item Esc [ R ; C H
-Move to screen row R, screen column C, where (R=1) is the top row,
-and (C=1) is the leftmost column.  Defaults are R=1 and C=1.
-
-@item Esc [ N A
-Move N (default 1) screen lines up.
-@item Esc [ N B
-Move N (default 1) screen lines down.
-@item Esc [ N C
-Move N (default 1) columns right.
-@item Esc [ N D
-Move N (default 1) columns left.
-@end table
-
-@node Erasing
-@subsection Escape commands for erasing text
-
-These commands "erase" part of the sub-buffer.
-Erasing means replacing by white space; it is not the same as deleting.
-The relative screen positions of things that are not erased remain
-unchanged with each other, as does the relative cursor position.
-
-@table @kbd
-@item E [ J
-Erase from cursor to end of screen.
-@item E [ 0 J
-Same as E [ J.
-@item E [ 1 J
-Erase from home position to point.
-@item E [ 2 J
-Erase whole sub-buffer.
-@item E [ K
-Erase from point to end of screen line.
-@item E [ 0 K
-Same as E [ K.
-@item E [ 1 K
-Erase from beginning of screen line to point.
-@item E [ 2 K
-Erase whole screen line.
-@end table
-
-@node Inserting and deleting
-@subsection Escape sequences to insert and delete text
-
-@table @kbd
-@item Esc [ N L
-Insert N (default 1) blank lines.
-@item Esc [ N M
-Delete N (default 1) lines.
-@item Esc [ N P
-Delete N (default 1) characters.
-@item Esc [ N @@
-Insert N (default 1) spaces.
-@end table
-
-@node Scrolling
-@subsection Escape sequences to scroll part of the visible window
-
-@table @kbd
-@item Esc D
-Scroll forward one screen line.
-
-@item Esc M
-Scroll backwards one screen line.
-
-@item Esc [ T ; B r
-Set the scrolling region to be from lines T down to line B inclusive,
-where line 1 is the topmost line.
-@end table
-
-@node Command hook
-@subsection Command hook
-
-If @kbd{C-z} is seen, any text up to a following @key{LF} is scanned.
-The text in between (not counting the initial C-z or the final LF)
-is passed to the function that is the value of @code{term-command-hook}.
-
-The default value of the @code{term-command-hook} variable
-is the function @code{term-command-hook}, which handles the following:
-
-@table @kbd
-@item C-z C-z FILENAME:LINENUMBER:IGNORED LF
-Set term-pending-frame to @code{(cons "FILENAME" LINENUMBER)}.
-When the buffer is displayed in the current window, show
-the FILENAME in the other window, and show an arrow at LINENUMBER.
-Gdb emits these strings when invoked with the flag --fullname.
-This is used by gdb mode; you can also invoke gdb with this flag
-from shell mode.
-
-@item C-z / DIRNAME LF
-Set the directory of the term buffer to DIRNAME
-
-@item C-z ! LEXPR LF
-Read and evaluate LEXPR as a Lisp expression.
-The result is ignored.
-@end table
-
-@node Miscellaneous escapes
-@subsection Miscellaneous escapes
-
-@table @kbd
-@item C-g (Bell)
-Calls @code{(beep t)}.
-
-@item Esc 7
-Save cursor.
-
-@item Esc 8
-Restore cursor.
-
-@item Esc [ 47 h
-Switch to the alternate sub-buffer,
-@item Esc [ 47 l
-Switch back to the regular sub-buffer,
-@end table
-
-@bye
--- a/man/xemacs-faq.texi	Sat Feb 20 18:56:01 2010 -0600
+++ b/man/xemacs-faq.texi	Sat Feb 20 23:34:25 2010 -0600
@@ -188,7 +188,8 @@
 * Advanced::              Advanced Customization Using XEmacs Lisp.
 * Other Packages::        Other External Packages.
 * Current Events::        What the Future Holds.
-* Legacy Versions::       New information about old XEmacsen.
+* Legacy Versions::       New Information about Old XEmacsen.
+* Bleeding Edge::         Working with XEmacs Source Code Repositories.
 
 @detailmenu
  --- The Detailed Node Listing ---
@@ -567,6 +568,27 @@
 * Q10.0.1::   Gnus 5.10 won't display smileys in XEmacs 21.1.
 * Q10.0.2::   XEmacs won't start on Windows in XEmacs 21.1.
 
+11 Working with XEmacs source code repositories
+
+11.0: The XEmacs repositories
+* Q11.0.1::   Where is the most recent XEmacs development code?
+* Q11.0.2::   Where is the most recent XEmacs stable code?
+* Q11.0.3::   Where is the most recent XEmacs package code?
+* Q11.0.4::   Why isn't @var{package} available? and what to do about it.
+* Q11.0.5::   How do I get commit access?
+
+11.1: Working with CVS
+* Q11.1.1::   How do I keep cool using CVS?
+
+11.2: Working with Mercurial
+* Q11.2.1::   What is Mercurial?
+* Q11.2.2::   Where do I get Mercurial?
+* Q11.2.3::   Do I really have to waste space on history?
+* Q11.2.4::   @code{hg diff} gives bizarre output.
+* Q11.2.5::   How do I recover from a bad commit?  (I already pushed.)
+* Q11.2.6::   How do I recover from a bad commit?  (I haven't pushed yet.)
+* Q11.2.7::   Testing patches with Mercurial Queues.
+
 @end detailmenu
 @end menu
 
@@ -8669,7 +8691,7 @@
 For older news, see the file @file{ONEWS} in the @file{etc} directory of
 the XEmacs distribution.
 
-@node Legacy Versions,  , Current Events, Top
+@node Legacy Versions,  Bleeding Edge, Current Events, Top
 @unnumbered 10 New information about old XEmacsen
 
 This is part 10 of the XEmacs Frequently Asked Questions list.  It will
@@ -8745,4 +8767,550 @@
 binaries, but you can use the 21.1 binaries if you are very paranoid
 about stability.  @xref{Q1.1.2, Are binaries available?}.
 
+
+@node Bleeding Edge, , Legacy Versions, Top
+@unnumbered 10 Working with XEmacs Source Code Repositories.
+
+This is part 11 of the XEmacs Frequently Asked Questions list.  The
+primary purpose is advice on use of the version control systems used to
+keep the history of XEmacs development.
+
+@menu
+11.0: The XEmacs repositories
+* Q11.0.1::   Where is the most recent XEmacs development code?
+* Q11.0.2::   Where is the most recent XEmacs stable code?
+* Q11.0.3::   Where is the most recent XEmacs package code?
+* Q11.0.4::   Why isn't @var{package} available? and what to do about it.
+* Q11.0.5::   How do I get commit access?
+
+11.1: Working with CVS
+* Q11.1.1::   How do I keep cool using CVS?
+
+11.2: Working with Mercurial
+* Q11.2.1::   What is Mercurial?
+* Q11.2.2::   Where do I get Mercurial?
+* Q11.2.3::   Do I really have to waste space on history?
+* Q11.2.4::   @code{hg diff} gives bizarre output.
+* Q11.2.5::   How do I recover from a bad commit?  (I already pushed.)
+* Q11.2.6::   How do I recover from a bad commit?  (I haven't pushed yet.)
+* Q11.2.7::   Testing patches with Mercurial Queues.
+@end menu
+
+
+@node Q11.0.1, Q11.0.2, Bleeding Edge, Bleeding Edge
+@unnumberedsubsec Where is the most recent XEmacs development code?
+
+The most recent XEmacs @emph{development} code is kept in a Mercurial
+repository, hosted by the Debian project.  The read-only URL, for
+anybody who doesn't intend to push upstream directly, is
+
+@example
+http://hg.debian.org/hg/xemacs/xemacs
+@end example
+
+The read-write URL for committers is
+
+@example
+ssh://sperber-guest@@hg.debian.org//hg/xemacs/xemacs
+@end example
+
+Yes, Virginia, that doubled slash is correct.
+
+@xref{Q11.0.5, How do I get commit access?}.
+
+@xref{Q11.2.1, What is Mercurial?}.
+
+@node Q11.0.2, Q11.0.3, Q11.0.1, Bleeding Edge
+@unnumberedsubsec Where is the most recent XEmacs stable code?
+
+The most recent XEmacs @emph{stable} code is kept in a Mercurial
+repository, hosted by the Debian project.  The read-only URL is
+
+@example
+http://hg.debian.org/hg/xemacs/xemacs-21.4
+@end example
+
+If you're @emph{not} Vin, you don't need commit access.  If you
+@emph{are} Vin, you shouldn't need to refer to this FAQ.
+
+@xref{Q11.2.1, What is Mercurial?}.
+
+
+@node Q11.0.3, Q11.0.4, Q11.0.2, Bleeding Edge
+@unnumberedsubsec Where is the most recent XEmacs package code?
+
+The most recent XEmacs @emph{packages} code is kept in a CVS
+repository, hosted by the Debian project.  The read-only @code{CVSROOT},
+for anybody who doesn't intend to push upstream directly, is
+
+@example
+CVSROOT=:pserver:anonymous@@cvs.alioth.debian.org:/cvsroot/xemacs
+@end example
+
+The read-write @code{CVSROOT} for committers is
+
+@example
+CVSROOT=:ext:@var{aliothuser}@@cvs.alioth.debian.org:/cvsroot/xemacs
+@end example
+
+where @var{aliothuser} is your account on @code{alioth.debian.org}.  Then
+
+@example
+cvs checkout packages
+@end example
+
+as usual.  For more information, see
+@uref{http://www.xemacs.org/Develop/cvsaccess.html, XEmacs CVS Archive}
+on the website.
+
+@xref{Q11.1.1, How do I stay cool using CVS?}.
+
+@xref{Q11.0.5, How do I get commit access?}.
+
+
+@node Q11.0.4, Q11.0.5, Q11.0.3, Bleeding Edge
+@unnumberedsubsec Why isn't @var{package} available? and what to do about it.
+
+If a package isn't available from the Packages repository, probably
+nobody has shown enough interest to add it yet.  (Occasionally, there is
+a better package already in the XEmacs repository, of course.)
+
+The first step is to ask about it, and propose addition, on
+@email{xemacs-beta@@xemacs.org, the XEmacs Contributors list}.
+
+Most regular XEmacs contributors already shoulder primary responsibility
+for several packages, and contribute to maintenance of the rest, so you
+are unlikely to get a massively enthusiastic response unless you
+volunteer to become the maintainer of the version packaged for XEmacs
+yourself.  The duties are not terribly onerous if you're an active user
+of the package @ref{(xemacs-devguide)XEmacs Package Maintainer}.
+
+
+@node Q11.0.5, Q11.1.1, Q11.0.4, Bleeding Edge
+@unnumberedsubsec How do I get commit access?
+
+To get commit access to XEmacs code, write to
+@email{xemacs-review@@xemacs.org, the XEmacs Review Board} and request
+it.  Once approved, for the development code, you also need to send
+@email{mike@@xemacs.org, Michael Sperber} your SSH v2 RSA key (Alioth
+policy; v1 and DSA keys aren't acceptable).  A CC to
+@email{xemacs-services@@xemacs.org, the XEmacs Services team} is a good
+idea, although not absolutely necessary.  You should also get an Alioth
+account so that you can publish branches for review.
+
+For packages code, you must get an Alioth account.  Send your account
+name information to @email{xemacs-services@@xemacs.org, the XEmacs
+Services team}.
+
+The stable repository is gated; only the gatekeeper (currently Vin
+Shelton) has commit access.  Patches for the stable repository should be
+submitted to @email{xemacs-patches@@xemacs.org, XEmacs Patches}, as usual.
+
+@uref{http://www.xemacs.org/Develop/hgaccess.html, XEmacs Mercurial Archive}
+
+@uref{http://www.xemacs.org/Develop/cvsaccess.html, XEmacs CVS Archive}
+
+@xref{Q11.1.1, How do I stay cool using CVS?}.
+
+@xref{Q11.2.1, What is Mercurial?}.
+
+
+@node Q11.1.1, Q11.2.1, Q11.0.5, Bleeding Edge
+@unnumberedsubsec How do I keep cool using CVS?
+
+You don't.  CVS is just basically and in detail @emph{un}-cool.
+
+What would be really cool is if you would help us out in moving the
+packages repository to Mercurial.  Volunteer on
+@email{xemacs-beta@@xemacs.org, the XEmacs Contributors list}.  What's
+needed is to figure out how to provide a one step checkout for the whole
+package hierarchy, while restricting commits to one package at a time.
+
+For help using CVS, Google or ask on @email{xemacs-beta@@xemacs.org}.
+Please update this FAQ with one or two of the best references you find.
+
+
+@node Q11.2.1, Q11.2.2, Q11.1.1, Bleeding Edge
+@unnumberedsubsec What is Mercurial?
+
+Mercurial is a @dfn{distributed version control system}, or DVCS.  This
+means that versioning information can be easily exchanged between
+different lines of development, even if located on different hosts.  In
+the older @dfn{centralize version control system} model, when you
+@dfn{commit} a change, it is immediately reflected in the public
+repository.  In a DVCS, each user has a @dfn{local repository}, and
+the commit operation creates a version in that repository.  To
+communicate with the public repository, a separate @dfn{push} operation
+must be executed.  The DVCS model is more appropriate for open source
+development.
+
+@itemize
+@item
+The VCS model mirrors the development organization, where developers
+tend to work independently or in very small groups.
+
+@item
+Users without commit access can conveniently manage their local changes.
+
+@item
+Developers can work, and commit changes, while disconnected from the
+Internet.  Then they merge and push their changes later.
+@end itemize
+
+Use of a DVCS does require some changes in workflow, but the XEmacs
+developers consider that inconvenience to be far more than balanced by
+the advantages.
+
+
+@node Q11.2.2, Q11.2.3, Q11.2.1, Bleeding Edge
+@unnumberedsubsec Where do I get Mercurial?
+
+Most OS distributions (including add-on distributions like
+@uref{http://www.cygwin.com/, Cygwin} and
+@uref{http://www.macports.org/, MacPorts}) include Mercurial packages.
+Of course, you can get the source distribution, as well as pre-built
+packages for most major platforms, from
+@uref{http://mercurial.selenic.com/wiki/, the Mercurial developers}.
+
+
+@node Q11.2.3, Q11.2.4, Q11.2.2, Bleeding Edge
+@unnumberedsubsec Do I really have to waste space on history?
+
+Yes, you do.  It's really not that much, though.  In one of my current
+workspaces, I see
+
+@table @code
+@item XEmacs source files (and other cruft, such as editor backups)
+115464KB
+@item Build products
+49676
+@item Mercurial control files and history
+25644
+@end table
+
+That really does include all of the history available in the main XEmacs
+development branch, and the build products are near twice the size of
+all of the Mercurial-specific information.
+
+
+@node Q11.2.4, Q11.2.5, Q11.2.3, Bleeding Edge
+@unnumberedsubsec @code{hg diff} gives bizarre output.
+
+You may see an unreasonable diff (often large) that doesn't seem to
+reflect your work.
+
+This is usually due to using @code{hg diff} on a @dfn{merge commit}.
+That means the commit has multiple parents, and joins together two lines
+of development that occured concurrently.
+
+You're diffing against the "wrong" one; try the other one.  You get the
+relevent revision number or ID from @code{hg log}.  In more detail:
+
+When there is a merge in Mercurial, it will often be the case that
+one of the parents is the immediate predecessor of the merge
+commit.  @code{hg log} will report something like
+
+@example
+    changeset:   4789:56049bea9231    # revision D, below
+    parent:      4788:5cca06f930ea    # your commit
+    parent:      4787:6e6f7b79c1fc    # diff against this
+    user:        you (or somebody else)
+
+    changeset:   4788:5cca06f930ea    # revision B, below
+    parent:      4760:217abcf015c4    # revision A, below
+    user:        you
+
+    changeset:   4787:6e6f7b79c1fc    # revision C, below
+    parent:      4786:d6cfba1cc388
+    user:        somebody else
+@end example
+
+Note that the divergence took place a long time ago (r4760).
+It's natural to diff against (tip - 1), in the example above,
+@code{hg diff -r 4788}.  But this will give unexpected output!
+
+A picture of this history looks something like
+
+@example
+      B --- D
+     /     /
+    A ... C
+@end example
+
+where A is the common ancestor, B is the commit you did, C is the
+mainline at the time of the merge, and D is the merge commit.  The
+three dots between A and C can represent many commits, and a lot
+of work.  Given no conflicts in the merge, @code{hg diff -r C -r D} is
+the same as @code{hg diff -r A -r B}, @emph{i.e.}, it shows your work.
+Similarly, @code{hg diff -r B -r D} is the same as
+@code{hg diff -r A -r C}.  This latter diff is likely to be quite large,
+and it doesn't show your work.  Unfortunately, that is the typical
+result of diffing against the "previous" commit.
+
+@node Q11.2.5, Q11.2.6, Q11.2.4, Bleeding Edge
+@unnumberedsubsec How do I recover from a bad commit?  (I already pushed.)
+
+Once upon a time, an XEmacs developer wrote:
+
+ > GAAAAK!  What's the best way to restore ChangeLog and its history?
+
+He had just inadvertantly pushed a commit which deleted
+@file{src/ChangeLog}!  The history is still there, not to worry.  (In
+this case, another developer had restored src/ChangeLog already.)  The
+best way depends on a number of things.  First, let's look at the log
+and the state of the DAG (the graph of commits).  Here's the log,
+formatted somewhat differently from the usual output for compactness.
+
+@example
+5025    anne    Restore src/ChangeLog.
+5024    barb    merge
+        parents: 5023 5010
+5023    barb    Error-checking.
+5020    barb    merge
+        parents: 5019 5006 
+5019    barb    Fix non-Mule build.
+5011    barb    Some internals-manual updates.
+        parents: 5002
+5010    cary    Windows fixes for Visual Studio 6.
+        parents: 5008 5009
+5009    cary    Miscellaneous small fixes to Windows VS6 build.
+        parents: 5006
+5008    dana    Add license information.
+5007    dana    Relicense emodules.texi.
+5006    cary    Instantiate compile fix for nt.c.
+5005    edna    Cast correctly.
+5003    edna    #'union doesn't preserve relative order
+5002    barb    Fix some compile bugs.
+@end example
+
+(The gaps at 5003...5005, 5011...5019, and 5020...5023 are filled with
+sequences of commits by the same developers.)  Let's visualize this as a
+graph.  Time increases to the right, the leading "50" is omitted for
+brevity, and the dotted links indicate that several irrelevant commits
+were omitted, also for brevity.
+
+@example
+                        ,------ 09 -----.
+                       /                 \
+02 --- 03 ... 05 --- 06 --- 07 --- 08 --- 10 --- 24 --- 25
+  \                    \                        /
+   `-- 11 ... 19 -------`-- 20 ... 23 ---------'
+@end example
+
+The "problem commit" is 5010, which merges 5008 with 5009, and somehow
+managed to "lose" @file{src/ChangeLog}.  The unobvious consequence is
+that, although the @emph{other} changes made in 5007 and 5008 were
+successfully merged and are present in 5010, the log entry made by
+Dana for 5008 "just disappeared".  (The log entry for 5007 is in a
+different @file{ChangeLog}, so it's safe.)
+
+@subsubheading The safe and simple way for Cary
+
+To recover state file-by-file (also for whole directories), use @code{hg
+revert}.  This does not change the "current" version, @emph{i.e.}, the
+commit that will be the parent for your next commit.
+
+If it's not a merge commit, it's simple to restore the ChangeLog.  It's
+best to do it before making any other commits in your own workspace, and
+before pulling in new commits from others.  If there are a lot of such
+commits in your workspace already, ask for help.  But in this case,
+there was no such problem.  Just
+
+@example
+hg revert -r 5009 src/ChangeLog
+# Add Dana's log entry by hand.
+hg commit -m "Restore src/ChangeLog."
+@end example
+
+5009 is the revision id of the most recent commit that had the correct
+version of the file.  You get that from the "parent" field in @code{hg
+log}, or from the DAG browser (@code{hg view}, requires @code{hgk}
+extension enabled).
+
+Alternatively, Cary could revert from 5008.  This would leave her with
+@emph{her} log entry for 5009 missing, and that would have to be added
+by hand.
+
+Note that in the actual history, Cary didn't realize that Dana's log
+went missing, so Anne had to pick up the slack in 5025.
+
+@subsubheading Recovery by another developer
+
+Another way to recover earlier state is with @code{hg checkout} (or
+@code{hg update}, which is another way to spell the same command).  This
+changes the version that hg sees as "current", as well as reverting the
+workspace.
+
+A common scenario is that another developer, such as Barb in the log
+above, was already working on @file{src/ChangeLog}, saves her copy, then
+tries to merge.  She would then get a modify/delete conflict.  It's
+tempting to just resolve that in favor of keeping the file, and commit.
+This often works, but an alternative way uses the VCS:
+
+@example
+hg checkout 5010
+hg revert -r 5009 src/ChangeLog
+# Add Dana's log entry by hand.
+hg commit -m "Restore src/ChangeLog."
+@end example
+
+to get the same effect as described above, then
+
+@example
+hg merge
+@end example
+
+(making her changes "float to the top" of the log) or
+
+@example
+hg checkout 5023
+hg merge
+@end example
+
+(putting the Cary's branch at the top of the log).  This assumes she has
+no other heads in her workspace.  If she does have other heads she would
+have to use an explicit argument to @code{hg merge}.
+
+Note that in the actual history, Barb didn't realize that Dana's log
+went missing, so Anne (or somebody) had to pick up the slack in 5025.
+
+@subsubheading The hard but accurate way
+
+Suppose Barb did @code{hg pull -u}, but notices the problem before
+resolving conflicts and committing the merge.  Assume Barb was fully committed
+before doing @code{hg pull -u}.
+
+@example
+# Restore the ChangeLog, "covering up" the broken commit.
+# Check out Cary's head.  This nukes the merged files in the workspace,
+# but @emph{the history and versions in Barb's rev. 5023 are preserved
+# in the repository}.  The -C is necessary to overwrite files.
+hg checkout -C 5010
+hg revert -r 5009 src/ChangeLog
+# Merge Dana's branch (yes, again).
+# The repeated merge outside of src/ChangeLog should resolve to a
+# no-op, but the ChangeLog probably conflicts.
+# The -f is needed because revert leaves uncommitted changes.
+hg merge -f 5008
+hg commit -m "Re-merge Dana's branch to recover her logs."
+# Merge Barb's work.
+# If Barb has only two heads, which seems likely, the argument to
+# merge is optional.
+hg merge 5023
+hg commit -m merge
+@end example
+
+Visualizing this with a graph, we have:
+
+@example
+                        ,------ 09 -----.
+                       /                 \
+02 --- 03 ... 05 --- 06 --- 07 --- 08 --- 10 *** 24 --- 25
+  \                    \             \          /      /
+   \                    \             `--------'      /
+    \                    \                           /
+     `-- 11 ... 19 -------`-- 20 ... 23 ------------'
+@end example
+
+Note that the versions 5024 and 5025 in this graph denote
+@emph{different} versions from the actual history.  The starred link
+means that editing work (aside from resolving conflicts) was done, on
+top of the merge.  However, the editing work is actually done by
+Mercurial (the revert command)!
+
+
+@node Q11.2.6, Q11.2.7, Q11.2.5, Bleeding Edge
+@unnumberedsubsec How do I recover from a bad commit?  (I haven't pushed yet.)
+
+If you hadn't yet pushed the commit you now regret, and realize it
+before doing further commits, you can use @code{hg strip tip}.  Then
+just redo the commit, possibly with additional changes before
+committing.
+
+@code{hg strip} is dangerous; for practical purposes it destroys
+history, and it also reverts the files in your workspace.  It's
+probably possible to recover the history, but I don't know how.  And any
+uncommitted changes that might be lost are gone forever.  However, it
+is useful in cases like this.
+
+When in doubt, use the safer method @ref{Q11.2.5}.
+
+
+@node Q11.2.7, , Q11.2.6, Bleeding Edge
+@unnumberedsubsec Testing patches with Mercurial Queues.
+
+When testing a patch proposed on xemacs-beta or xemacs-patches,
+conflicts or new heads often appear later, when using @code{hg pull -u}.
+
+There are both theoretical and practical reasons why this happens,
+and it's unlikely to change.  The current workflow of XEmacs is also
+unlikely to change soon; testing patches is also probably going to
+remain necessary.  One way to avoid this issue is to use Mercurial
+Queues (mq), an extension distributed with Mercurial.
+
+Enable mq by adding
+
+@example
+    [extensions]
+
+    hgext.mq =
+@end example
+
+to your @file{~/.hgrc}.  (Yes, the right hand side is empty.)  If you
+already have an @code{[extensions]} section, don't repeat it.  Add
+@code{hgext.mq =} to the existing extensions section.
+
+When you want to test a patch, you need an hg workspace with no
+uncommitted changes.  If you already have some uncommitted changes,
+you can preserve them with mq as follows:
+
+@example
+    $ hg qnew -f -m "Preserve local changes." local-changes
+@end example
+
+The @code{-m} flag specifies the commit message for the new patch.  The
+@code{-f} flag "forces" qnew to put all of the uncommitted local changes
+into an mq patch, and commits it (you will see a commit with summary
+"Preserve local changes." if you do an @code{hg log} now).
+"local-changes" is the name of the patch.
+
+Now, create an mq patch for the test patch (which we assume was saved
+to @file{/tmp/xemacs.patch}):
+
+    $ hg qimport -P -n test-xemacs-patch /tmp/xemacs.patch
+
+The @code{-n} flag specifies the name of the patch.  Give it a name
+sufficiently explicit so you'll know what it is later.  Remember, it
+may take several weeks for the patch to be pushed to the public
+mainline.  The @code{-P} flag says "apply this patch to the workspace
+now".
+
+When you want to update the workspace, you need to remove the mq
+commits, update, and restore your local changes and the test patch.
+You do it this way:
+
+@example
+    $ hg qpop --all
+    $ hg pull -u                # use your usual method, hg fetch etc.
+    $ hg qpush --all
+@end example
+
+@code{hg qpop --all} undoes all the mq commits, but leaves the patches
+in @file{.hg/patches}.  @code{hg qpush --all} reapplies the patches and
+restores the mq commits.  Of course you hope that the patch will be
+committed upstream.  When it is, you do this:
+
+@example
+    $ hg qpop --all
+    $ hg pull -u
+    $ hg qdelete test-xemacs-patch
+    $ hg qpush --all
+@end example
+
+and you're back in business with the official version of the patch you
+tested, and all your local changes applied.
+
+It's also possible to split your local changes into smaller mq
+patches, but that's out of scope for this answer.
+
 @bye
--- a/nt/ChangeLog	Sat Feb 20 18:56:01 2010 -0600
+++ b/nt/ChangeLog	Sat Feb 20 23:34:25 2010 -0600
@@ -1,3 +1,12 @@
+2010-02-18  Vin Shelton  <acs@xemacs.org>
+
+	* xemacs.mak (INFO_FILES): Removed term.info.
+
+2010-02-11  Vin Shelton  <acs@xemacs.org>
+ 
+ 	* xemacs.mak (LIB_SRC_DEFINES): Added PROGRAM_DEFINES to lib_src
+ 	compilation options so winclient.c can see them.
+ 
 2010-02-03  Jerry James  <james@xemacs.org>
 
 	* xemacs.rc: Add license and copyright boilerplate text for Jonathan
--- a/nt/xemacs.mak	Sat Feb 20 18:56:01 2010 -0600
+++ b/nt/xemacs.mak	Sat Feb 20 23:34:25 2010 -0600
@@ -1065,7 +1065,7 @@
 
 ###################### lib-src programs
 
-LIB_SRC_DEFINES = -DHAVE_CONFIG_H -DWIN32_NATIVE
+LIB_SRC_DEFINES = -DHAVE_CONFIG_H -DWIN32_NATIVE $(PROGRAM_DEFINES)
 
 #
 # Creating config.values to be used by config.el
@@ -1496,7 +1496,6 @@
 	$(INFODIR)\lispref.info \
 	$(INFODIR)\new-users-guide.info \
 	$(INFODIR)\standards.info \
-	$(INFODIR)\term.info \
 	$(INFODIR)\termcap.info \
 	$(INFODIR)\texinfo.info \
 	$(INFODIR)\widget.info \
--- a/src/ChangeLog	Sat Feb 20 18:56:01 2010 -0600
+++ b/src/ChangeLog	Sat Feb 20 23:34:25 2010 -0600
@@ -270,6 +270,26 @@
 	Rename variable `debug-xemacs-searches' to just `debug-searches',
 	consistent with other debug vars.
 
+2010-02-19  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* fns.c (split_string_by_ichar_1):
+	Use better types (e.g., not an Ichar for a buffer size) in this
+	function when dealing with ESCAPECHAR.
+
+2010-02-19  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* fns.c (mapcarX):
+	Correct this function, discarding multiple values when one
+	SEQUENCE is supplied, choosing a better label name.  Correct the
+	comment describing the SOME_OR_EVERY argument.
+
+2010-02-12  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* syswindows.h:
+	Remove the PDWORD_PTR typedef; it's not used in
+	intl-auto-encap-win32.h , and it breaks the build with Visual C++
+	2005 Express Edition and a 2005 copy of the SDK.
+
 2010-02-10  Ben Wing  <ben@xemacs.org>
 
 	* text.h:
@@ -3709,6 +3729,16 @@
 	reasons.
 	
 
+2010-02-07  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* fns.c (split_string_by_ichar_1): Extend this to take UNESCAPE
+	and ESCAPECHAR arguments.
+	(split_external_path, split_env_path, Fsplit_string_by_char)
+	(Fsplit_path):
+	Pass the new arguments to split_string_by_ichar_1(); take a new
+	optional argument, ESCAPE-CHAR, in #'split-string-by-char,
+	allowing SEPCHAR to be escaped.
+
 2010-01-09  Didier Verna  <didier@xemacs.org>
 
 	* glyphs.c (query_string_font): Use proper domain for cachel
--- a/src/fns.c	Sat Feb 20 18:56:01 2010 -0600
+++ b/src/fns.c	Sat Feb 20 23:34:25 2010 -0600
@@ -1053,31 +1053,129 @@
 }
 
 /* Split STRING into a list of substrings.  The substrings are the
-   parts of original STRING separated by SEPCHAR.  */
+   parts of original STRING separated by SEPCHAR.
+
+   If UNESCAPE is non-zero, ESCAPECHAR specifies a character that will quote
+   SEPCHAR, and cause it not to split STRING. A double ESCAPECHAR is
+   necessary for ESCAPECHAR to appear once in a substring. */
+
 static Lisp_Object
 split_string_by_ichar_1 (const Ibyte *string, Bytecount size,
-			  Ichar sepchar)
+                         Ichar sepchar, int unescape, Ichar escapechar)
 {
   Lisp_Object result = Qnil;
   const Ibyte *end = string + size;
 
-  while (1)
+  if (unescape)
     {
-      const Ibyte *p = string;
-      while (p < end)
-	{
-	  if (itext_ichar (p) == sepchar)
-	    break;
-	  INC_IBYTEPTR (p);
-	}
-      result = Fcons (make_string (string, p - string), result);
-      if (p < end)
-	{
-	  string = p;
-	  INC_IBYTEPTR (string);	/* skip sepchar */
-	}
-      else
-	break;
+      Ibyte unescape_buffer[64], *unescape_buffer_ptr = unescape_buffer,
+        escaped[MAX_ICHAR_LEN], *unescape_cursor;
+      Bytecount unescape_buffer_size = countof (unescape_buffer),
+        escaped_len = set_itext_ichar (escaped, escapechar);
+      Boolint deleting_escapes, previous_escaped;
+      Ichar pchar;
+
+      while (1)
+        {
+          const Ibyte *p = string, *cursor;
+          deleting_escapes = 0;
+          previous_escaped = 0;
+
+          while (p < end)
+            {
+              pchar = itext_ichar (p);
+
+              if (pchar == sepchar)
+                {
+                  if (!previous_escaped)
+                    {
+                      break;
+                    }
+                }
+              else if (pchar == escapechar
+                       /* Doubled escapes don't escape: */
+                       && !previous_escaped)
+                {
+                  ++deleting_escapes;
+                  previous_escaped = 1;
+                }
+              else
+                {
+                  previous_escaped = 0;
+                }
+
+              INC_IBYTEPTR (p);
+            }
+
+          if (deleting_escapes)
+            {
+              if (((p - string) - (escaped_len * deleting_escapes))
+                  > unescape_buffer_size)
+                {
+                  unescape_buffer_size =
+                    ((p - string) - (escaped_len * deleting_escapes)) * 1.5;
+                  unescape_buffer_ptr = alloca_ibytes (unescape_buffer_size);
+                }
+
+              cursor = string;
+              unescape_cursor = unescape_buffer_ptr;
+              previous_escaped = 0;
+
+              while (cursor < p)
+                {
+                  pchar = itext_ichar (cursor);
+
+                  if (pchar != escapechar || previous_escaped)
+                    {
+                      memcpy (unescape_cursor, cursor,
+                              itext_ichar_len (cursor));
+                      INC_IBYTEPTR (unescape_cursor);
+                    }
+
+                  previous_escaped = !previous_escaped
+                    && (pchar == escapechar);
+
+                  INC_IBYTEPTR (cursor);
+                }
+
+              result = Fcons (make_string (unescape_buffer_ptr,
+                                           unescape_cursor
+                                           - unescape_buffer_ptr),
+                              result);
+            }
+          else
+            {
+              result = Fcons (make_string (string, p - string), result);
+            }
+          if (p < end)
+            {
+              string = p;
+              INC_IBYTEPTR (string);	/* skip sepchar */
+            }
+          else
+            break;
+        }
+    }
+  else
+    {
+      while (1)
+        {
+          const Ibyte *p = string;
+          while (p < end)
+            {
+              if (itext_ichar (p) == sepchar)
+                break;
+              INC_IBYTEPTR (p);
+            }
+          result = Fcons (make_string (string, p - string), result);
+          if (p < end)
+            {
+              string = p;
+              INC_IBYTEPTR (string);	/* skip sepchar */
+            }
+          else
+            break;
+        }
     }
   return Fnreverse (result);
 }
@@ -1102,7 +1200,7 @@
   if (!newlen)
     return Qnil;
 
-  return split_string_by_ichar_1 (newpath, newlen, SEPCHAR);
+  return split_string_by_ichar_1 (newpath, newlen, SEPCHAR, 0, 0);
 }
 
 Lisp_Object
@@ -1115,22 +1213,34 @@
     path = default_;
   if (!path)
     return Qnil;
-  return split_string_by_ichar_1 (path, qxestrlen (path), SEPCHAR);
+  return split_string_by_ichar_1 (path, qxestrlen (path), SEPCHAR, 0, 0);
 }
 
 /* Ben thinks this function should not exist or be exported to Lisp.
    We use it to define split-path-string in subr.el (not!).  */
 
-DEFUN ("split-string-by-char", Fsplit_string_by_char, 2, 2, 0, /*
+DEFUN ("split-string-by-char", Fsplit_string_by_char, 2, 3, 0, /*
 Split STRING into a list of substrings originally separated by SEPCHAR.
+
+With optional ESCAPE-CHAR, any instances of SEPCHAR preceded by that
+character will not split the string, and a double instance of ESCAPE-CHAR
+will be necessary for a single ESCAPE-CHAR to appear in the output string.
 */
-       (string, sepchar))
+       (string, sepchar, escape_char))
 {
+  Ichar escape_ichar = 0;
+
   CHECK_STRING (string);
   CHECK_CHAR (sepchar);
+  if (!NILP (escape_char))
+    {
+      CHECK_CHAR (escape_char);
+      escape_ichar = XCHAR (escape_char);
+    }
   return split_string_by_ichar_1 (XSTRING_DATA (string),
-				   XSTRING_LENGTH (string),
-				   XCHAR (sepchar));
+                                  XSTRING_LENGTH (string),
+                                  XCHAR (sepchar),
+                                  !NILP (escape_char), escape_ichar);
 }
 
 /* #### This was supposed to be in subr.el, but is used VERY early in
@@ -1154,7 +1264,7 @@
 
   return (split_string_by_ichar_1
 	  (XSTRING_DATA (path), XSTRING_LENGTH (path),
-	   itext_ichar (XSTRING_DATA (Vpath_separator))));
+	   itext_ichar (XSTRING_DATA (Vpath_separator)), 0, 0));
 }
 
 
@@ -3231,7 +3341,8 @@
    taking the elements from SEQUENCES.  If VALS is non-NULL, store the
    results into VALS, a C array of Lisp_Objects; else, if LISP_VALS is
    non-nil, store the results into LISP_VALS, a sequence with sufficient
-   room for CALL_COUNT results. Else, do not accumulate any result.
+   room for CALL_COUNT results (but see the documentation of SOME_OR_EVERY.) 
+   Else, do not accumulate any result.
 
    If VALS is non-NULL, NSEQUENCES is one, and SEQUENCES[0] is a cons,
    mapcarX will store the elements of SEQUENCES[0] in stack and GCPRO them,
@@ -3246,11 +3357,10 @@
 
    If SOME_OR_EVERY is SOME_OR_EVERY_SOME, return the (possibly multiple)
    values given by FUNCTION the first time it is non-nil, and abandon the
-   iterations.  LISP_VALS in this case must be an object created by
-   make_opaque_ptr, dereferenced as pointing to a Lisp object. If
-   SOME_OR_EVERY is SOME_OR_EVERY_EVERY, store Qnil at the Lisp_Object
-   pointer address provided by LISP_VALS if FUNCTION gives nil; otherwise
-   leave it alone. */
+   iterations.  LISP_VALS must be a cons, and the return value will be
+   stored in its car.  If SOME_OR_EVERY is SOME_OR_EVERY_EVERY, store Qnil
+   in the car of LISP_VALS if FUNCTION gives nil; otherwise leave it
+   alone. */
 
 #define SOME_OR_EVERY_NEITHER 0
 #define SOME_OR_EVERY_SOME    1
@@ -3306,7 +3416,7 @@
       for (i = 0; i < call_count; ++i)
 	{
 	  args[1] = vals[i];
-	  vals[i] = Ffuncall (nsequences + 1, args);
+	  vals[i] = IGNORE_MULTIPLE_VALUES (Ffuncall (nsequences + 1, args));
 	}
     }
   else
@@ -3413,7 +3523,7 @@
 			break;
 		      }
 
-		    goto bad_show_or_every_flag;
+		    goto bad_some_or_every_flag;
 		  }
 		case lrecord_type_vector:
 		  {
@@ -3443,7 +3553,7 @@
 		      (void) Faset (lisp_vals, make_int (i), called);
 		    break;
 		  }
-		bad_show_or_every_flag:
+		bad_some_or_every_flag:
 		default:
 		  {
 		    ABORT();
--- a/src/syswindows.h	Sat Feb 20 18:56:01 2010 -0600
+++ b/src/syswindows.h	Sat Feb 20 23:34:25 2010 -0600
@@ -596,7 +596,6 @@
    and cause problems if we used Cygwin headers to generate
    intl-auto-encap-win32.[ch]. */
 typedef LPCVOID PCVOID;
-typedef LPDWORD *PDWORD_PTR;
 
 #endif /* CYGWIN_HEADERS */
 
--- a/tests/ChangeLog	Sat Feb 20 18:56:01 2010 -0600
+++ b/tests/ChangeLog	Sat Feb 20 23:34:25 2010 -0600
@@ -4,6 +4,23 @@
 	* automated/search-tests.el (boundp):
 	debug-xemacs-searches renamed to debug-searches.
 
+2010-02-19  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* automated/lisp-tests.el:
+	Change the #'split-string-by-char text to use US federal
+	government information instead of a couple of sentences from the
+	OED; the latter would probably have qualified as non-infringement,
+	but with the former the question won't arise.
+	(The German text in the same tests is from a very public domain
+	19th-century work.)
+
+2010-02-19  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* automated/lisp-tests.el:
+	Check that multiple values are discarded correctly with #'mapcar
+	and one SEQUENCE.
+	(equal): 
+
 2010-02-05  Jerry James  <james@xemacs.org>
 
 	* DLL/dltest.c: Remove old test.  Building and using any module now
@@ -274,6 +291,11 @@
 	* automated/mule-tests.el (featurep):
 	Use utf-8 as file-name-coding-system under Cygwin 1.7+.
 
+2010-02-07  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* automated/lisp-tests.el (split-string-by-char):
+	Test this function, and its new ESCAPE-CHAR argument.
+
 2010-01-01  Aidan Kehoe  <kehoea@parhasard.net>
 
 	* automated/lisp-tests.el: 
--- a/tests/automated/lisp-tests.el	Sat Feb 20 18:56:01 2010 -0600
+++ b/tests/automated/lisp-tests.el	Sat Feb 20 23:34:25 2010 -0600
@@ -1,4 +1,4 @@
-;; Copyright (C) 1998 Free Software Foundation, Inc.
+;; Copyright (C) 1998 Free Software Foundation, Inc. -*- coding: iso-8859-1 -*-
 
 ;; Author: Martin Buchholz <martin@xemacs.org>
 ;; Maintainer: Martin Buchholz <martin@xemacs.org>
@@ -973,6 +973,12 @@
       (car y))
     x)))
 
+(Assert-eql
+ (length (multiple-value-list
+          (car (mapcar #'(lambda (argument) (floor argument)) (list pi e)))))
+ 1
+ "checking multiple values are correctly discarded in mapcar")
+
 ;;-----------------------------------------------------
 ;; Test vector functions
 ;;-----------------------------------------------------
@@ -1071,6 +1077,76 @@
 	       '("foobar"))
 
 ;;-----------------------------------------------------
+;; Test split-string-by-char
+;;-----------------------------------------------------
+
+(Assert
+ (equal
+  (split-string-by-char
+   #r"re\:ee:this\\is\\text\\\\:oo\ps:
+Eine Sprache, die stagnirt, ist zu vergleichen mit einem See, dem der
+bisherige Quellenzufluß versiegt oder abgeleitet wird. Aus dem Wasser,
+worüber der Geist Gottes schwebte, wird Sumpf und Moder, worüber die
+unreinen\: Geister brüten.\\
+Serum concentrations of vitamin E: (alpha-tocopherol) depend on the liver,
+which takes up the nutrient after the various forms are absorbed from the
+small intestine. The liver preferentially resecretes only alpha-tocopherol
+via the hepatic alpha-tocopherol transfer protein"
+  ?: ?\\)
+  '("re:ee" "this\\is\\text\\\\" "oops" "
+Eine Sprache, die stagnirt, ist zu vergleichen mit einem See, dem der
+bisherige Quellenzufluß versiegt oder abgeleitet wird. Aus dem Wasser,
+worüber der Geist Gottes schwebte, wird Sumpf und Moder, worüber die
+unreinen: Geister brüten.\\
+Serum concentrations of vitamin E" " (alpha-tocopherol) depend on the liver,
+which takes up the nutrient after the various forms are absorbed from the
+small intestine. The liver preferentially resecretes only alpha-tocopherol
+via the hepatic alpha-tocopherol transfer protein")))
+(Assert
+ (equal
+  (split-string-by-char
+   #r"re\:ee:this\\is\\text\\\\:oo\ps:
+Eine Sprache, die stagnirt, ist zu vergleichen mit einem See, dem der
+bisherige Quellenzufluß versiegt oder abgeleitet wird. Aus dem Wasser,
+worüber der Geist Gottes schwebte, wird Sumpf und Moder, worüber die
+unreinen\: Geister brüten.\\
+Serum concentrations of vitamin E: (alpha-tocopherol) depend on the liver,
+which takes up the nutrient after the various forms are absorbed from the
+small intestine. The liver preferentially resecretes only alpha-tocopherol
+via the hepatic alpha-tocopherol transfer protein"
+   ?: ?\x00)
+  '("re\\" "ee" "this\\\\is\\\\text\\\\\\\\" "oo\\ps" "
+Eine Sprache, die stagnirt, ist zu vergleichen mit einem See, dem der
+bisherige Quellenzufluß versiegt oder abgeleitet wird. Aus dem Wasser,
+worüber der Geist Gottes schwebte, wird Sumpf und Moder, worüber die
+unreinen\\" " Geister brüten.\\\\
+Serum concentrations of vitamin E" " (alpha-tocopherol) depend on the liver,
+which takes up the nutrient after the various forms are absorbed from the
+small intestine. The liver preferentially resecretes only alpha-tocopherol
+via the hepatic alpha-tocopherol transfer protein")))
+(Assert
+ (equal
+  (split-string-by-char
+   #r"re\:ee:this\\is\\text\\\\:oo\ps:
+Eine Sprache, die stagnirt, ist zu vergleichen mit einem See, dem der
+bisherige Quellenzufluß versiegt oder abgeleitet wird. Aus dem Wasser,
+worüber der Geist Gottes schwebte, wird Sumpf und Moder, worüber die
+unreinen\: Geister brüten.\\
+Serum concentrations of vitamin E: (alpha-tocopherol) depend on the liver,
+which takes up the nutrient after the various forms are absorbed from the
+small intestine. The liver preferentially resecretes only alpha-tocopherol
+via the hepatic alpha-tocopherol transfer protein" ?\\)
+  '("re" ":ee:this" "" "is" "" "text" "" "" "" ":oo" "ps:
+Eine Sprache, die stagnirt, ist zu vergleichen mit einem See, dem der
+bisherige Quellenzufluß versiegt oder abgeleitet wird. Aus dem Wasser,
+worüber der Geist Gottes schwebte, wird Sumpf und Moder, worüber die
+unreinen" ": Geister brüten." "" "
+Serum concentrations of vitamin E: (alpha-tocopherol) depend on the liver,
+which takes up the nutrient after the various forms are absorbed from the
+small intestine. The liver preferentially resecretes only alpha-tocopherol
+via the hepatic alpha-tocopherol transfer protein")))
+
+;;-----------------------------------------------------
 ;; Test near-text buffer functions.
 ;;-----------------------------------------------------
 (with-temp-buffer