Mercurial > hg > xemacs-beta
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