changeset 5292:e4305eb6fb8c

Merge some permissions corrections to trunk.
author Stephen J. Turnbull <stephen@xemacs.org>
date Mon, 18 Oct 2010 23:21:23 +0900
parents 85bd42a1e544 (current diff) 99de5fd48e87 (diff)
children 63f247c5da0a
files lisp/ChangeLog lisp/gtk-widget-accessors.el src/ChangeLog tests/ChangeLog
diffstat 73 files changed, 3870 insertions(+), 1563 deletions(-) [+]
line wrap: on
line diff
--- a/lisp/ChangeLog	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/ChangeLog	Mon Oct 18 23:21:23 2010 +0900
@@ -45,6 +45,226 @@
 	* mule/kinsoku.el:
 	Add "part of XEmacs" text to permission notice.
 
+2010-10-14  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* byte-optimize.el (side-effect-free-fns): 
+	* cl-macs.el (remf, getf): 
+	* cl-extra.el (tailp, cl-set-getf, cl-do-remf): 
+	* cl.el (ldiff, endp):
+	Tighten up Common Lisp compatibility for #'ldiff, #'endp, #'tailp;
+	add circularity checking for the first two.
+
+	#'cl-set-getf and #'cl-do-remf were Lisp implementations of
+	#'plist-put and #'plist-remprop; change the names to aliases,
+	changes the macros that use them to using #'plist-put and
+	#'plist-remprop directly.
+
+2010-10-12  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* abbrev.el (fundamental-mode-abbrev-table, global-abbrev-table):
+	Create both these abbrev tables using the usual
+	#'define-abbrev-table calls, rather than attempting to
+	special-case them.
+	* cl-extra.el: Force cl-macs to be loaded here, if cl-extra.el is
+	being loaded interpreted.  Previously other, later files would
+	redundantly call (load "cl-macs") when interpreted, it's more
+	reasonable to do it here, once.
+	* cmdloop.el (read-quoted-char-radix): Use defcustom here, we
+	don't have any dump-order dependencies that would prevent that.
+	* custom.el (eval-when-compile): Don't load cl-macs when
+	interpreted or when byte-compiling, rely on cl-extra.el in the
+	former case and the appropriate entry in bytecomp-load-hook in the
+	latter.  Get rid of custom-declare-variable-list, we have no
+	dump-time dependencies that would require it.
+	* faces.el (eval-when-compile): Don't load cl-macs when
+	interpreted or when byte-compiling.
+	* packages.el: Remove some inaccurate comments. 
+	* post-gc.el (cleanup-simple-finalizers): Use #'delete-if-not
+	here, now the order of preloaded-file-list has been changed to
+	make it available.
+	* subr.el (custom-declare-variable-list): Remove. No need for it.
+	Also remove a stub define-abbrev-table from this file, given the
+	current order of preloaded-file-list there's no need for it.
+
+2010-10-10  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* bytecomp.el (byte-compile-constp) Forms quoted with FUNCTION are
+	also constant.
+	(byte-compile-initial-macro-environment): In #'the, if FORM is
+	constant and does not match TYPE, warn at byte-compile time.
+
+2010-10-10  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* backquote.el (bq-vector-contents, bq-list*): Remove; the former
+	is equivalent to (append VECTOR nil), the latter to (list* ...).
+	(bq-process-2): Use (append VECTOR nil) instead of using
+	#'bq-vector-contents to convert to a list.
+	(bq-process-1): Now we use list* instead of bq-list
+	* subr.el (list*): Moved from cl.el, since it is now required to
+	be available the first time a backquoted form is encountered.
+	* cl.el (list*): Move to subr.el.
+
+2010-09-16  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* test-harness.el (Check-Message):
+	Add an omitted comma here, thank you the buildbot.
+
+2010-09-16  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* hash-table.el (hash-table-key-list, hash-table-value-list)
+	(hash-table-key-value-alist, hash-table-key-value-plist):
+	Remove some useless #'nreverse calls in these files; our hash
+	tables have no order, it's not helpful to pretend they do.
+	* behavior.el (read-behavior):
+	Do the same in this file, in some code evidently copied from
+	hash-table.el.
+
+2010-09-16  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* info.el (Info-insert-dir):
+	* format.el (format-deannotate-region):
+	* files.el (cd, save-buffers-kill-emacs):
+	Use #'some, #'every and related functions for applying boolean
+	operations to lists, instead of rolling our own ones that cons and
+	don't short-circuit.
+
+2010-09-16  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* bytecomp.el (byte-compile-initial-macro-environment):
+	* cl-macs.el (the):
+	Rephrase the docstring, make its implementation when compiling
+	files a little nicer.
+
+2010-09-16  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* descr-text.el (unidata-initialize-unicodedata-database)
+	(unidata-initialize-unihan-database, describe-char-unicode-data)
+	(describe-char-unicode-data):
+	Wrap calls to the database functions with (with-fboundp ...),
+	avoiding byte compile warnings on builds without support for the
+	database functions.
+	(describe-char): (reduce #'max ...), not (apply #'max ...), no
+	need to cons needlessly.
+	(describe-char): Remove a redundant lambda wrapping
+	#'extent-properties. 
+	(describe-char-unicode-data): Call #'nsubst when replacing "" with
+	nil in the result of #'split-string, instead of consing inside
+	mapcar.
+
+2010-09-16  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* x-faces.el (x-available-font-sizes): 
+	* specifier.el (let-specifier): 
+	* package-ui.el (pui-add-required-packages): 
+	* msw-faces.el (mswindows-available-font-sizes): 
+	* modeline.el (modeline-minor-mode-menu): 
+	* minibuf.el (minibuf-directory-files):
+	Replace the O2N (delq nil (mapcar (lambda (W) (and X Y)) Z)) with
+	the ON (mapcan (lambda (W) (and X (list Y))) Z) in these files.
+
+2010-09-16  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* cl-macs.el (= < > <= >=):
+	When these functions are handed more than two arguments, and those
+	arguments have no side effects, transform to a series of two
+	argument calls, avoiding funcall in the byte-compiled code.
+	* mule/mule-cmds.el (finish-set-language-environment):
+	Take advantage of this change in a function called 256 times at
+	startup.
+
+2010-09-16  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* bytecomp.el (byte-compile-function-form, byte-compile-quote)
+	(byte-compile-quote-form):
+	Warn at compile time, and error at runtime, if a (quote ...) or a
+	(function ...) form attempts to quote more than one object.
+
+2010-09-16  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* byte-optimize.el (byte-optimize-apply): Transform (apply 'nconc
+	(mapcar ...)) to (mapcan ...); warn about use of the first idiom.
+
+	* update-elc.el (do-autoload-commands): 
+	* packages.el (packages-find-package-library-path): 
+	* frame.el (frame-list): 
+	* extents.el (extent-descendants): 
+	* etags.el (buffer-tag-table-files): 
+	* dumped-lisp.el (preloaded-file-list): 
+	* device.el (device-list): 
+	* bytecomp-runtime.el (proclaim-inline, proclaim-notinline)
+	Use #'mapcan, not (apply #'nconc (mapcar ...) in all these files.
+
+	* bytecomp-runtime.el (eval-when-compile, eval-and-compile):
+	In passing, mention that these macros also evaluate the body when
+	interpreted. 
+
+2010-09-16  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* cl-macs.el (the): Add a docstring and an implementation for this
+	macro.
+	* bytecomp.el (byte-compile-initial-macro-environment): Add #'the
+	to this, checking byte-compile-delete-errors to decide whether to
+	make the type assertion. Change the initvalue to use backquote and
+	preceding commas for the lambda expressions, to allow the latter
+	to be compiled.
+
+2010-09-06  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* cl-seq.el (replace):
+	Move this function, with added bounds-checking per ANSI Common
+	Lisp, to fns.c.
+
+2010-09-05  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* x-compose.el (define-compose-map, compose-map)
+	(decide-on-bindings): Support the precomposed characters with
+	stroke here too, necessary for Polish and Danish, among others.
+	* x-init.el (x-initialize-compose): Add the appropriate map
+	autoloads and bindings here.
+
+2010-09-03  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* cl-extra.el (coerce):
+	Add fixnum as an accepted destination type.
+
+2010-09-02  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* obsolete.el (process-get):
+	Make #'process-get, #'process-put, #'process-plist,
+	#'set-process-plist available as aliases to the more general
+	functions #'get, #'put, #'object-plist, #'object-setplist, for GNU
+	compatibility.
+
+2010-08-20  Mike Sperber  <mike@xemacs.org>
+
+	* files.el (save-some-buffers-action-alist): Add.
+	(save-some-buffers-1): Use (synching with (GPLv2) FSF Emacs.
+
+2010-08-18  Mike Sperber  <mike@xemacs.org>
+
+	* files.el (diff-files-for-recover): Abstract this out out
+	`recover-file'.
+	(diff-buffer-with-file): Add from (GPLv2) FSF Emacs.
+	(recover-file): Use `diff-files-for-recover'.
+
+2010-08-15  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* specifier.el (canonicalize-inst-pair, canonicalize-spec):
+	If a specifier tag set is correct, but an instantiator is not in
+	an accepted format, don't error with the message "Invalid
+	specifier tag set".
+	Also, when we error, use error-symbols, for better structured
+	error handling and more ease when testing.
+
+2010-07-24  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* cl-extra.el (concatenate):
+	* cl-seq.el (remove*, cl-delete-duplicates):
+	Bit vectors are also sequences; enforce this in these functions.
+	* cl-macs.el (concatenate):
+	If TYPE is constant, don't inline #'concatenate, replace it by a
+	call to the appropriate C functions.
+
 2010-06-13  Stephen J. Turnbull  <stephen@xemacs.org>
 
 	* gnome.el:
--- a/lisp/abbrev.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/abbrev.el	Mon Oct 18 23:21:23 2010 +0900
@@ -120,31 +120,12 @@
     (setplist sym (or count 0))
     name))
 
+(define-abbrev-table 'fundamental-mode-abbrev-table nil)
+(and (eq major-mode 'fundamental-mode)
+     (not local-abbrev-table)
+     (setq local-abbrev-table fundamental-mode-abbrev-table))
 
-;; Fixup stuff from bootstrap def of define-abbrev-table in subr.el
-(let ((l abbrev-table-name-list))
-  (while l
-    (let ((fixup (car l)))
-      (if (consp fixup)
-          (progn
-            (setq abbrev-table-name-list (delq fixup abbrev-table-name-list))
-            (define-abbrev-table (car fixup) (cdr fixup))))
-      (setq l (cdr l))))
-  ;; These are no longer initialized by C code
-  (if (not global-abbrev-table)
-      (progn
-        (setq global-abbrev-table (make-abbrev-table))
-        (setq abbrev-table-name-list (cons 'global-abbrev-table
-                                           abbrev-table-name-list))))
-  (if (not fundamental-mode-abbrev-table)
-      (progn
-        (setq fundamental-mode-abbrev-table (make-abbrev-table))
-        (setq abbrev-table-name-list (cons 'fundamental-mode-abbrev-table
-                                           abbrev-table-name-list))))
-  (and (eq major-mode 'fundamental-mode)
-       (not local-abbrev-table)
-       (setq local-abbrev-table fundamental-mode-abbrev-table)))
-
+(define-abbrev-table 'global-abbrev-table nil)
 
 (defun define-global-abbrev (name expansion)
   "Define ABBREV as a global abbreviation for EXPANSION."
--- a/lisp/backquote.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/backquote.el	Mon Oct 18 23:21:23 2010 +0900
@@ -184,19 +184,10 @@
 
 ;;; ----------------------------------------------------------------
 
-(defun bq-vector-contents (vec)
-  (let ((contents nil)
-	(n (length vec)))
-    (while (> n 0)
-      (setq n (1- n))
-      (setq contents (cons (aref vec n) contents)))
-    contents))
-
 ;;; This does the expansion from table 2.
 (defun bq-process-2 (code)
   (cond ((vectorp code)
-	 (let* ((dflag-d
-		 (bq-process-2 (bq-vector-contents code))))
+	 (let* ((dflag-d (bq-process-2 (append code nil))))
 	   (cons 'vector (bq-process-1 (car dflag-d) (cdr dflag-d)))))
 	((atom code)
 	 (cond ((null code) (cons nil nil))
@@ -278,26 +269,7 @@
 	 (list  'quote thing))
 	((eq flag 'vector)
 	 (list 'apply '(function vector) thing))
-	(t (cons (cdr
-		  (assq flag
-			'((cons . cons)
-			  (list* . bq-list*)
-			  (list . list)
-			  (append . append)
-			  (nconc . nconc))))
-		 thing))))
-
-;;; ----------------------------------------------------------------
-
-(defmacro bq-list* (&rest args)
-  "Return a list of its arguments with last cons a dotted pair."
-  (setq args (reverse args))
-  (let ((result (car args)))
-    (setq args (cdr args))
-    (while args
-      (setq result (list 'cons (car args) result))
-      (setq args (cdr args)))
-    result))
+	(t (cons flag thing))))
 
 (provide 'backquote)
 
--- a/lisp/behavior.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/behavior.el	Mon Oct 18 23:21:23 2010 +0900
@@ -349,15 +349,11 @@
   (let ((result
 	 (completing-read
 	  prompt
-	  (let ((table (let (lis)
-			 (maphash #'(lambda (key val)
-				      (push (cons key val) lis))
-				  behavior-hash-table)
-			 (nreverse lis))))
-	    (mapc #'(lambda (aentry)
-		      (setcar aentry (symbol-name (car aentry))))
-		  table)
-	    table)
+	  (let (list)
+	    (maphash #'(lambda (key value)
+			 (push (cons (symbol-name key) value) list))
+		     behavior-hash-table)
+	    list)
 	  nil must-match initial-contents (or history 'behavior-history)
 	  default-value)))
     (if (and result (stringp result))
--- a/lisp/byte-optimize.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/byte-optimize.el	Mon Oct 18 23:21:23 2010 +0900
@@ -1119,17 +1119,26 @@
   ;; The funcall optimizer can then transform (funcall 'foo ...) -> (foo ...).
   (let ((fn (nth 1 form))
 	(last (nth (1- (length form)) form))) ; I think this really is fastest
-    (or (if (or (null last)
-		(eq (car-safe last) 'quote))
-	    (if (listp (nth 1 last))
-		(let ((butlast (nreverse (cdr (reverse (cdr (cdr form)))))))
-		  (nconc (list 'funcall fn) butlast
-			 (mapcar #'(lambda (x) (list 'quote x)) (nth 1 last))))
-	      (byte-compile-warn
-	       "last arg to apply can't be a literal atom: %s"
-	       (prin1-to-string last))
-	      nil))
-	form)))
+    (if (and (eq last (third form))
+             (consp last)
+             (eq 'mapcar (car last))
+             (equal fn ''nconc))
+        (progn
+          (byte-compile-warn
+           "(apply 'nconc (mapcar ..)), use #'mapcan instead: %s" last)
+          (cons 'mapcan (cdr last)))
+      (or (if (or (null last)
+                  (eq (car-safe last) 'quote))
+              (if (listp (nth 1 last))
+                  (let ((butlast (nreverse (cdr (reverse (cdr (cdr form)))))))
+                    (nconc (list 'funcall fn) butlast
+                           (mapcar #'(lambda (x) (list 'quote x))
+                                   (nth 1 last))))
+                (byte-compile-warn
+                 "last arg to apply can't be a literal atom: %s"
+                 (prin1-to-string last))
+                nil))
+          form))))
 
 (put 'funcall 'byte-optimizer 'byte-optimize-funcall)
 (put 'apply   'byte-optimizer 'byte-optimize-apply)
@@ -1216,7 +1225,7 @@
 	 ;; coordinates-in-window-p not in XEmacs
 	 copy-marker cos count-lines
 	 default-boundp default-value denominator documentation downcase
-	 elt exp expt fboundp featurep
+	 elt endp exp expt fboundp featurep
 	 file-directory-p file-exists-p file-locked-p file-name-absolute-p
 	 file-newer-than-file-p file-readable-p file-symlink-p file-writable-p
 	 float floor format
--- a/lisp/bytecomp-runtime.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/bytecomp-runtime.el	Mon Oct 18 23:21:23 2010 +0900
@@ -53,30 +53,26 @@
   "Cause the named functions to be open-coded when called from compiled code.
 They will only be compiled open-coded when `byte-optimize' is true."
   (cons 'eval-and-compile
-	(apply
-	 'nconc
-	 (mapcar
-	  #'(lambda (x)
-	      `((or (memq (get ',x 'byte-optimizer)
-			  '(nil byte-compile-inline-expand))
-		    (error
-		     "%s already has a byte-optimizer, can't make it inline"
-		     ',x))
-		(put ',x 'byte-optimizer 'byte-compile-inline-expand)))
-	  fns))))
+        (mapcan
+         #'(lambda (x)
+             `((or (memq (get ',x 'byte-optimizer)
+                         '(nil byte-compile-inline-expand))
+                   (error
+                    "%s already has a byte-optimizer, can't make it inline"
+                    ',x))
+               (put ',x 'byte-optimizer 'byte-compile-inline-expand)))
+         fns)))
 
 
 (defmacro proclaim-notinline (&rest fns)
   "Cause the named functions to no longer be open-coded."
   (cons 'eval-and-compile
-	(apply
-	 'nconc
-	 (mapcar
-	  #'(lambda (x)
-	      `((if (eq (get ',x 'byte-optimizer)
-			'byte-compile-inline-expand)
-		    (put ',x 'byte-optimizer nil))))
-	  fns))))
+        (mapcan
+         #'(lambda (x)
+             `((if (eq (get ',x 'byte-optimizer)
+                       'byte-compile-inline-expand)
+                   (put ',x 'byte-optimizer nil))))
+         fns)))
 
 ;; This has a special byte-hunk-handler in bytecomp.el.
 (defmacro defsubst (name arglist &rest body)
@@ -163,7 +159,7 @@
 
 (put 'eval-when-compile 'lisp-indent-hook 0)
 (defmacro eval-when-compile (&rest body)
-  "Like `progn', but evaluates the body at compile time.
+  "Like `progn', but evaluates BODY at compile time, and when interpeted.
 The result of the body appears to the compiler as a quoted constant."
   ;; Not necessary because we have it in b-c-initial-macro-environment
   ;; (list 'quote (eval (cons 'progn body)))
@@ -171,7 +167,8 @@
 
 (put 'eval-and-compile 'lisp-indent-hook 0)
 (defmacro eval-and-compile (&rest body)
-  "Like `progn', but evaluates the body at compile time and at load time."
+  "Like `progn', but evaluates the body at compile time and at load time,
+and when interpreted."
   ;; Remember, it's magic.
   (cons 'progn body))
 
--- a/lisp/bytecomp.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/bytecomp.el	Mon Oct 18 23:21:23 2010 +0900
@@ -493,13 +493,25 @@
 	  (fset (car elt) (cdr elt)))))))
 
 (defconst byte-compile-initial-macro-environment
-  '((byte-compiler-options . (lambda (&rest forms)
-			       (apply 'byte-compiler-options-handler forms)))
-    (eval-when-compile . (lambda (&rest body)
-			   (list 'quote (byte-compile-eval (cons 'progn body)))))
-    (eval-and-compile . (lambda (&rest body)
-			  (byte-compile-eval (cons 'progn body))
-			  (cons 'progn body))))
+  `((byte-compiler-options
+      . ,#'(lambda (&rest forms)
+	     (apply 'byte-compiler-options-handler forms)))
+    (eval-when-compile
+      . ,#'(lambda (&rest body)
+	     (list 'quote (byte-compile-eval (cons 'progn body)))))
+    (eval-and-compile
+      . ,#'(lambda (&rest body)
+	     (byte-compile-eval (cons 'progn body))
+	     (cons 'progn body)))
+    (the .
+      ,#'(lambda (type form)
+	   (if (cl-const-expr-p form)
+	       (or (eval (cl-make-type-test form type))
+		   (byte-compile-warn
+		    "%s is not of type %s" form type)))
+	   (if byte-compile-delete-errors
+	       form
+	     (funcall (cdr (symbol-function 'the)) type form)))))
   "The default macro-environment passed to macroexpand by the compiler.
 Placing a macro here will cause a macro to have different semantics when
 expanded by the compiler as when expanded by the interpreter.")
@@ -1383,7 +1395,7 @@
 
 (defmacro byte-compile-constp (form)
   ;; Returns non-nil if FORM is a constant.
-  `(cond ((consp ,form) (eq (car ,form) 'quote))
+  `(cond ((consp ,form) (memq (car ,form) '(quote function)))
 	 ((symbolp ,form) (byte-compile-constant-symbol-p ,form))
 	 (t)))
 
@@ -3573,10 +3585,13 @@
 ;; and (funcall (function foo)) will lose with autoloads.
 
 (defun byte-compile-function-form (form)
-  (byte-compile-constant
-   (cond ((symbolp (nth 1 form))
-	  (nth 1 form))
-	 ((byte-compile-lambda (nth 1 form))))))
+  (if (cddr form)
+      (byte-compile-normal-call
+       `(signal 'wrong-number-of-arguments '(function ,(length (cdr form)))))
+    (byte-compile-constant
+     (cond ((symbolp (nth 1 form))
+            (nth 1 form))
+           ((byte-compile-lambda (nth 1 form)))))))
 
 (defun byte-compile-insert (form)
   (cond ((null (cdr form))
@@ -3706,11 +3721,16 @@
 
 
 (defun byte-compile-quote (form)
-  (byte-compile-constant (car (cdr form))))
+  (if (cddr form)
+      (byte-compile-normal-call
+       `(signal 'wrong-number-of-arguments '(quote ,(length (cdr form)))))
+    (byte-compile-constant (car (cdr form)))))
 
 (defun byte-compile-quote-form (form)
-  (byte-compile-constant (byte-compile-top-level (nth 1 form))))
-
+  (if (cddr form)
+      (byte-compile-normal-call
+       `(signal 'wrong-number-of-arguments '(quote ,(length (cdr form)))))
+    (byte-compile-constant (byte-compile-top-level (nth 1 form)))))
 
 ;;; control structures
 
--- a/lisp/cl-extra.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/cl-extra.el	Mon Oct 18 23:21:23 2010 +0900
@@ -64,11 +64,11 @@
 	((and (eq type 'character) (symbolp x)) (coerce (symbol-name x) type))
 	;; XEmacs addition character <-> integer coercions
 	((and (eq type 'character) (char-int-p x)) (int-char x))
-	((and (eq type 'integer) (characterp x)) (char-int x))
+	((and (memq type '(integer fixnum)) (characterp x)) (char-int x))
 	((eq type 'float) (float x))
 	;; XEmacs addition: enhanced numeric type coercions
 	((and-fboundp 'coerce-number
-	   (memq type '(integer ratio bigfloat))
+	   (memq type '(integer ratio bigfloat fixnum))
 	   (coerce-number x type)))
 	;; XEmacs addition: bit-vector coercion
 	((or (eq type 'bit-vector)
@@ -392,6 +392,7 @@
     (vector (apply 'vconcat seqs))
     (string (apply 'concat seqs))
     (list   (apply 'append (append seqs '(nil))))
+    (bit-vector (apply 'bvconcat seqs))
     (t (error 'invalid-argument "Not a sequence type name" type))))
 
 ;;; List functions.
@@ -404,18 +405,17 @@
   "Equivalent to (nconc (nreverse X) Y)."
   (nconc (nreverse x) y))
 
-(defun list-length (list)
-  "Return the length of LIST.  Return nil if LIST is circular."
-  (if (listp list)
-      (condition-case nil (length list) (circular-list))
-    ;; Error on not-a-list:
-    (car list)))
-
+;; XEmacs; check LIST for type and circularity.
 (defun tailp (sublist list)
   "Return true if SUBLIST is a tail of LIST."
-  (while (and (consp list) (not (eq sublist list)))
-    (setq list (cdr list)))
-  (if (numberp sublist) (equal sublist list) (eq sublist list)))
+  (check-argument-type #'listp list)
+  (let ((before list) (evenp t))
+    (while (and (consp list) (not (eq sublist list)))
+      (setq list (cdr list)
+	    evenp (not evenp))
+      (if evenp (setq before (cdr before)))
+      (if (eq before list) (error 'circular-list list)))
+    (eql sublist list)))
 
 (defalias 'cl-copy-tree 'copy-tree)
 
@@ -425,17 +425,9 @@
 (defalias 'get* 'get)
 (defalias 'getf 'plist-get)
 
-(defun cl-set-getf (plist tag val)
-  (let ((p plist))
-    (while (and p (not (eq (car p) tag))) (setq p (cdr (cdr p))))
-    (if p (progn (setcar (cdr p) val) plist) (list* tag val plist))))
-
-(defun cl-do-remf (plist tag)
-  (let ((p (cdr plist)))
-    (while (and (cdr p) (not (eq (car (cdr p)) tag))) (setq p (cdr (cdr p))))
-    (and (cdr p) (progn (setcdr p (cdr (cdr (cdr p)))) t))))
-
-;; XEmacs change: we have a builtin remprop
+;; XEmacs; these are built-in.
+(defalias 'cl-set-getf 'plist-put)
+(defalias 'cl-do-remf 'plist-remprop)
 (defalias 'cl-remprop 'remprop)
 
 (defun get-properties (plist indicator-list)
@@ -663,6 +655,11 @@
     (prog1 (cl-prettyprint form)
       (message ""))))
 
+;; XEmacs addition; force cl-macs to be available from here on when
+;; compiling files to be dumped.  This is more reasonable than forcing other
+;; files to do the same, multiple times.
+(eval-when-compile (or (cl-compiling-file) (load "cl-macs")))
+
 (run-hooks 'cl-extra-load-hook)
 
 ;; XEmacs addition
--- a/lisp/cl-macs.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/cl-macs.el	Mon Oct 18 23:21:23 2010 +0900
@@ -1962,7 +1962,19 @@
 ;;;###autoload
 (defmacro locally (&rest body) (cons 'progn body))
 ;;;###autoload
-(defmacro the (type form) form)
+(defmacro the (type form)
+  "Assert that FORM gives a result of type TYPE, and return that result.
+
+TYPE is a Common Lisp type specifier.
+
+If macro expansion of a `the' form happens during byte compilation, and the
+byte compiler customization variable `byte-compile-delete-errors' is
+non-nil, `the' is equivalent to FORM without any type checks."
+  (if (cl-safe-expr-p form)
+      `(prog1 ,form (assert ,(cl-make-type-test form type) t))
+    (let ((saved (gensym)))
+      `(let ((,saved ,form))
+        (prog1 ,saved (assert ,(cl-make-type-test saved type) t))))))
 
 (defvar cl-proclaim-history t)    ; for future compilers
 (defvar cl-declare-stack t)       ; for future compilers
@@ -2395,7 +2407,7 @@
 	  (append (nth 1 method) (list tag def))
 	  (list store-temp)
 	  (list 'let (list (list (car (nth 2 method))
-				 (list 'cl-set-getf (nth 4 method)
+				 (list 'plist-put (nth 4 method)
 				       tag-temp store-temp)))
 		(nth 3 method) store-temp)
 	  (list 'getf (nth 4 method) tag-temp def-temp))))
@@ -2585,7 +2597,7 @@
 		(list 'progn
 		      (cl-setf-do-store (nth 1 method) (list 'cddr tval))
 		      t)
-		(list 'cl-do-remf tval ttag)))))
+		(list 'plist-remprop tval ttag)))))
 
 ;;;###autoload
 (defmacro shiftf (place &rest args)
@@ -3751,6 +3763,35 @@
                                     :test #'equal))
         ,stack-depth))))
 
+(define-compiler-macro concatenate (&whole form type &rest seqs)
+  (if (and (cl-const-expr-p type) (memq (cl-const-expr-val type)
+                                        '(vector bit-vector list string)))
+      (case (cl-const-expr-val type)
+        (list (append (list 'append) (cddr form) '(nil)))
+        (vector (cons 'vconcat (cddr form)))
+        (bit-vector (cons 'bvconcat (cddr form)))
+        (string (cons 'concat (cddr form))))
+    form))
+
+(map nil
+     #'(lambda (function)
+         ;; There are byte codes for the two-argument versions of these
+         ;; functions; if the form has more arguments and those arguments
+         ;; have no side effects, transform to a series of two-argument
+         ;; calls.
+         (put function 'cl-compiler-macro
+              #'(lambda (form &rest arguments)
+                  (if (or (null (nthcdr 3 form))
+                          (notevery #'cl-safe-expr-p (cdr form)))
+                      form
+                    (cons 'and (mapcon
+                                #'(lambda (rest)
+                                    (and (cdr rest)
+                                         `((,(car form) ,(pop rest)
+                                            ,(car rest)))))
+                                (cdr form)))))))
+     '(= < > <= >=))
+
 (mapc
  #'(lambda (y)
      (put (car y) 'side-effect-free t)
@@ -3764,7 +3805,7 @@
  '((first 'car x) (second 'cadr x) (third 'caddr x) (fourth 'cadddr x)
    (fifth 'nth 4 x) (sixth 'nth 5 x) (seventh 'nth 6 x)
    (eighth 'nth 7 x) (ninth 'nth 8 x) (tenth 'nth 9 x)
-   (rest 'cdr x) (endp 'null x) (plusp '> x 0) (minusp '< x 0)
+   (rest 'cdr x) (plusp '> x 0) (minusp '< x 0)
    (oddp  'eq (list 'logand x 1) 1)
    (evenp 'eq (list 'logand x 1) 0)
    (caar car car) (cadr car cdr) (cdar cdr car) (cddr cdr cdr)
--- a/lisp/cl-seq.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/cl-seq.el	Mon Oct 18 23:21:23 2010 +0900
@@ -142,48 +142,7 @@
 (defvar cl-if) (defvar cl-if-not)
 (defvar cl-key)
 
-(defun replace (cl-seq1 cl-seq2 &rest cl-keys)
-  "Replace the elements of SEQ1 with the elements of SEQ2.
-SEQ1 is destructively modified, then returned.
-Keywords supported:  :start1 :end1 :start2 :end2
-:start1 and :end1 specify a subsequence of SEQ1, and :start2 and :end2 a
-subsequence of SEQ2; see `search' for more information."
-  (cl-parsing-keywords ((:start1 0) :end1 (:start2 0) :end2) ()
-    (if (and (eq cl-seq1 cl-seq2) (<= cl-start2 cl-start1))
-	(or (= cl-start1 cl-start2)
-	    (let* ((cl-len (length cl-seq1))
-		   (cl-n (min (- (or cl-end1 cl-len) cl-start1)
-			      (- (or cl-end2 cl-len) cl-start2))))
-	      (while (>= (setq cl-n (1- cl-n)) 0)
-		(cl-set-elt cl-seq1 (+ cl-start1 cl-n)
-			    (elt cl-seq2 (+ cl-start2 cl-n))))))
-      (if (listp cl-seq1)
-	  (let ((cl-p1 (nthcdr cl-start1 cl-seq1))
-		(cl-n1 (if cl-end1 (- cl-end1 cl-start1) 4000000)))
-	    (if (listp cl-seq2)
-		(let ((cl-p2 (nthcdr cl-start2 cl-seq2))
-		      (cl-n (min cl-n1
-				 (if cl-end2 (- cl-end2 cl-start2) 4000000))))
-		  (while (and cl-p1 cl-p2 (>= (setq cl-n (1- cl-n)) 0))
-		    (setcar cl-p1 (car cl-p2))
-		    (setq cl-p1 (cdr cl-p1) cl-p2 (cdr cl-p2))))
-	      (setq cl-end2 (min (or cl-end2 (length cl-seq2))
-				 (+ cl-start2 cl-n1)))
-	      (while (and cl-p1 (< cl-start2 cl-end2))
-		(setcar cl-p1 (aref cl-seq2 cl-start2))
-		(setq cl-p1 (cdr cl-p1) cl-start2 (1+ cl-start2)))))
-	(setq cl-end1 (min (or cl-end1 (length cl-seq1))
-			   (+ cl-start1 (- (or cl-end2 (length cl-seq2))
-					   cl-start2))))
-	(if (listp cl-seq2)
-	    (let ((cl-p2 (nthcdr cl-start2 cl-seq2)))
-	      (while (< cl-start1 cl-end1)
-		(aset cl-seq1 cl-start1 (car cl-p2))
-		(setq cl-p2 (cdr cl-p2) cl-start1 (1+ cl-start1))))
-	  (while (< cl-start1 cl-end1)
-	    (aset cl-seq1 cl-start1 (aref cl-seq2 cl-start2))
-	    (setq cl-start2 (1+ cl-start2) cl-start1 (1+ cl-start1))))))
-    cl-seq1))
+;; XEmacs; #'replace is in fns.c.
 
 (defun remove* (cl-item cl-seq &rest cl-keys)
   "Remove all occurrences of ITEM in SEQ.
@@ -215,8 +174,11 @@
 						 (list :end (1+ cl-i))
 					       (list :start cl-i))
 					     cl-keys))))
-		  (if (listp cl-seq) cl-res
-		    (if (stringp cl-seq) (concat cl-res) (vconcat cl-res))))
+                  (typecase cl-seq
+                    (list cl-res)
+                    (string (concat cl-res))
+                    (vector (vconcat cl-res))
+                    (bit-vector (bvconcat cl-res))))
 	      cl-seq))
 	(setq cl-end (- (or cl-end 8000000) cl-start))
 	(if (= cl-start 0)
@@ -382,7 +344,10 @@
 	      (setq cl-end (1- cl-end) cl-start (1+ cl-start)))
 	    cl-seq)))
     (let ((cl-res (cl-delete-duplicates (append cl-seq nil) cl-keys nil)))
-      (if (stringp cl-seq) (concat cl-res) (vconcat cl-res)))))
+      (typecase cl-seq
+        (string (concat cl-res))
+        (vector (vconcat cl-res))
+        (bit-vector (bvconcat cl-res))))))
 
 (defun substitute (cl-new cl-old cl-seq &rest cl-keys)
   "Substitute NEW for OLD in SEQ.
--- a/lisp/cl.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/cl.el	Mon Oct 18 23:21:23 2010 +0900
@@ -365,7 +365,13 @@
 
 (defalias 'first 'car)
 (defalias 'rest 'cdr)
-(defalias 'endp 'null)
+
+;; XEmacs change; this needs to error if handed a non-list.
+(defun endp (list)
+  "Return t if LIST is nil, or nil if LIST is a cons. Error otherwise."
+  (prog1
+      (null list)
+    (and list (atom list) (error 'wrong-type-argument #'listp list))))
 
 ;; XEmacs change: make it a real function
 (defun second (x)
@@ -519,24 +525,28 @@
 
 ;;; `last' is implemented as a C primitive, as of 1998-11
 
-(defun list* (arg &rest rest)   ; See compiler macro in cl-macs.el
-  "Return a new list with specified args as elements, cons'd to last arg.
-Thus, `(list* A B C D)' is equivalent to `(nconc (list A B C) D)', or to
-`(cons A (cons B (cons C D)))'."
-  (cond ((not rest) arg)
-	((not (cdr rest)) (cons arg (car rest)))
-	(t (let* ((n (length rest))
-		  (copy (copy-sequence rest))
-		  (last (nthcdr (- n 2) copy)))
-	     (setcdr last (car (cdr last)))
-	     (cons arg copy)))))
+;;; XEmacs: `list*' is in subr.el.
+
+;; XEmacs; handle dotted lists properly, error on circularity and if LIST is
+;; not a list.
+(defun ldiff (list sublist)
+  "Return a copy of LIST with the tail SUBLIST removed.
 
-(defun ldiff (list sublist)
-  "Return a copy of LIST with the tail SUBLIST removed."
-  (let ((res nil))
-    (while (and (consp list) (not (eq list sublist)))
-      (push (pop list) res))
-    (nreverse res)))
+If SUBLIST is the same Lisp object as LIST, return nil.  If SUBLIST is
+not present in the list structure of LIST (that is, it is not the cdr
+of some cons making up LIST), this function is equivalent to
+`copy-list'.  LIST may be dotted."
+  (check-argument-type #'listp list)
+  (and list (not (eq list sublist))
+       (let ((before list) (evenp t) result)
+	 (prog1
+	     (setq result (list (car list)))
+	   (while (and (setq list (cdr-safe list)) (not (eql list sublist)))
+	     (setf (cdr result) (if (consp list) (list (car list)) list)
+		   result (cdr result)
+		   evenp (not evenp))
+	     (if evenp (setq before (cdr before)))
+	     (if (eq before list) (error 'circular-list list)))))))
 
 ;;; `copy-list' is implemented as a C primitive, as of 1998-11
 
--- a/lisp/cmdloop.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/cmdloop.el	Mon Oct 18 23:21:23 2010 +0900
@@ -564,12 +564,7 @@
 
 ;; BEGIN SYNCHED WITH FSF 21.2.
 
-(defvar read-quoted-char-radix 8
-  "*Radix for \\[quoted-insert] and other uses of `read-quoted-char'.
-Legitimate radix values are 8, 10 and 16.")
-
-(custom-declare-variable-early
- 'read-quoted-char-radix 8 
+(defcustom read-quoted-char-radix 8 
  "*Radix for \\[quoted-insert] and other uses of `read-quoted-char'.
 Legitimate radix values are 8, 10 and 16."
   :type '(choice (const 8) (const 10) (const 16))
--- a/lisp/custom.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/custom.el	Mon Oct 18 23:21:23 2010 +0900
@@ -44,12 +44,10 @@
 (provide 'custom)
 
 (eval-when-compile
-  (load "cl-macs" nil t)
   ;; To elude warnings.
   (require 'cus-face))
 
 (autoload 'custom-declare-face "cus-face")
-(autoload 'defun* "cl-macs")
 
 (require 'widget)
 
@@ -1056,12 +1054,7 @@
 
 ;;; The End.
 
-;; Process the defcustoms for variables loaded before this file.
-;; `custom-declare-variable-list' is defvar'd in subr.el.  Utility programs
-;; run from temacs that do not load subr.el should defvar it themselves.
-;; (As of 21.5.11, make-docfile.el.)
-(while custom-declare-variable-list
-  (apply 'custom-declare-variable (car custom-declare-variable-list))
-  (setq custom-declare-variable-list (cdr custom-declare-variable-list)))
+;; XEmacs; we order preloaded-file-list such that there's no need for
+;; custom-declare-variable-list.
 
 ;; custom.el ends here
--- a/lisp/descr-text.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/descr-text.el	Mon Oct 18 23:21:23 2010 +0900
@@ -457,98 +457,100 @@
   (check-argument-type #'file-readable-p unidata-file-name)
   (unless unidata-database-format
     (error 'unimplemented "No (non-SQL) DB support available"))
-  (let* ((database-format unidata-database-format)
-         (size (eighth (file-attributes unidata-file-name)))
-         (database-file-name
-          (unidata-generate-database-file-name unidata-file-name
-                                               size database-format))
-         (database-handle (open-database database-file-name database-format 
-                                         nil "rw+" #o644 'no-conversion-unix))
-         (coding-system-for-read 'no-conversion-unix)
-         (buffer-size 32768)
-         (offset-start 0)
-         (offset-end buffer-size)
-         (range-information (make-range-table 'start-closed-end-closed))
-         (range-staging (make-hash-table :test 'equal))
-         (message "Initializing UnicodeData database cache: ")
-         (loop-count 1)
-         range-startinfo)
-    (with-temp-buffer
-      (progress-feedback-with-label 'describe-char-unicodedata-file
-                                    "%s" 0 message)
-      (while (progn
-               (delete-region (point-min) (point-max))
-               (insert-file-contents unidata-file-name nil
-                                     offset-start offset-end)
-               ;; If we've reached the end of the data, pass nil back to
-               ;; the while loop test.
-               (not (= (point-min) (point-max))))
+  (with-fboundp '(open-database put-database close-database)
+    (let* ((database-format unidata-database-format)
+	   (size (eighth (file-attributes unidata-file-name)))
+	   (database-file-name
+	    (unidata-generate-database-file-name unidata-file-name
+						 size database-format))
+	   (database-handle (open-database database-file-name database-format 
+					   nil "rw+" #o644
+					   'no-conversion-unix))
+	   (coding-system-for-read 'no-conversion-unix)
+	   (buffer-size 32768)
+	   (offset-start 0)
+	   (offset-end buffer-size)
+	   (range-information (make-range-table 'start-closed-end-closed))
+	   (range-staging (make-hash-table :test 'equal))
+	   (message "Initializing UnicodeData database cache: ")
+	   (loop-count 1)
+	   range-startinfo)
+      (with-temp-buffer
+	(progress-feedback-with-label 'describe-char-unicodedata-file
+				      "%s" 0 message)
+	(while (progn
+		 (delete-region (point-min) (point-max))
+		 (insert-file-contents unidata-file-name nil
+				       offset-start offset-end)
+		 ;; If we've reached the end of the data, pass nil back to
+		 ;; the while loop test.
+		 (not (= (point-min) (point-max))))
 
-        (when (= buffer-size (- (point-max) (point-min)))
-          ;; If we're in the body of the file, and there's a trailing
-          ;; incomplete end-line, delete it, and adjust offset-end
-          ;; appropriately.
-          (goto-char (point-max))
-          (search-backward "\n")
-          (forward-char)
-          (delete-region (point) (point-max))
-          (setq offset-end (+ offset-start (- (point) (point-min)))))
+	  (when (= buffer-size (- (point-max) (point-min)))
+	    ;; If we're in the body of the file, and there's a trailing
+	    ;; incomplete end-line, delete it, and adjust offset-end
+	    ;; appropriately.
+	    (goto-char (point-max))
+	    (search-backward "\n")
+	    (forward-char)
+	    (delete-region (point) (point-max))
+	    (setq offset-end (+ offset-start (- (point) (point-min)))))
 
-        (progress-feedback-with-label 'describe-char-unicodedata-file
-                                      "%s" (truncate 
-                                            (* (/ offset-start size) 100))
-                                      (concat message
-                                              (make-string
-                                               (mod loop-count 39) ?.)))
-        (incf loop-count)
-        (goto-char (point-min))
-        (while (re-search-forward 
-                #r"^\([0-9A-F]\{4,6\}\);\([^;]*\);.*$" nil t)
-          (cond
-           ((and (> (- (match-end 2) (match-beginning 2)) 7)
-                 (equal (substring (match-string 2) -7)
-                        " First>"))
-            ;; Start of a range. Save the start info in range-staging.
-            (puthash (substring (match-string 2) 0 -7)
-                     (list (string-to-int (match-string 1) 16)
-                           (+ offset-start (1- (match-beginning 0))))
-                     range-staging))
-           ((and (> (- (match-end 2) (match-beginning 2)) 7)
-                 (equal (substring (match-string 2) -6)
-                        " Last>"))
-            ;; End of a range. Combine with the start info, save it to the
-            ;; range-information range table. 
-            (setq range-startinfo
-                  (gethash (substring (match-string 2) 0 -6) range-staging))
-            (assert range-startinfo nil
-                    "Unexpected order for range information.")
-            (put-range-table 
-             (first range-startinfo)
-             (string-to-int (match-string 1) 16)
-             (list (second range-startinfo) 
+	  (progress-feedback-with-label 'describe-char-unicodedata-file
+					"%s" (truncate 
+					      (* (/ offset-start size) 100))
+					(concat message
+						(make-string
+						 (mod loop-count 39) ?.)))
+	  (incf loop-count)
+	  (goto-char (point-min))
+	  (while (re-search-forward 
+		  #r"^\([0-9A-F]\{4,6\}\);\([^;]*\);.*$" nil t)
+	    (cond
+	     ((and (> (- (match-end 2) (match-beginning 2)) 7)
+		   (equal (substring (match-string 2) -7)
+			  " First>"))
+	      ;; Start of a range. Save the start info in range-staging.
+	      (puthash (substring (match-string 2) 0 -7)
+		       (list (string-to-int (match-string 1) 16)
+			     (+ offset-start (1- (match-beginning 0))))
+		       range-staging))
+	     ((and (> (- (match-end 2) (match-beginning 2)) 7)
+		   (equal (substring (match-string 2) -6)
+			  " Last>"))
+	      ;; End of a range. Combine with the start info, save it to the
+	      ;; range-information range table. 
+	      (setq range-startinfo
+		    (gethash (substring (match-string 2) 0 -6) range-staging))
+	      (assert range-startinfo nil
+		      "Unexpected order for range information.")
+	      (put-range-table 
+	       (first range-startinfo)
+	       (string-to-int (match-string 1) 16)
+	       (list (second range-startinfo) 
                    (+ offset-start (1- (match-end 0))))
-             range-information)
-            (remhash (substring (match-string 2) 0 -6) range-staging))
-           (t
-            ;; Normal character. Save the associated information in the
-            ;; database directly.
-            (put-database (match-string 1)
-                          (format "(%d %d)"
-                                  (+ offset-start (1- (match-beginning 0)))
-                                  (+ offset-start (1- (match-end 0))))
-                          database-handle))))
-        (goto-char (point-min))
-        (setq offset-start offset-end
-              offset-end (+ buffer-size offset-end))))
-    ;; Save the range information as such in the database. 
-    (put-database "range-information"
-                  (let ((print-readably t))
-                    (prin1-to-string range-information))
-                  database-handle) 
-    (close-database database-handle)
-    (progress-feedback-with-label 'describe-char-unicodedata-file
-                                  "%s" 100 message)
-    database-file-name))
+	       range-information)
+	      (remhash (substring (match-string 2) 0 -6) range-staging))
+	     (t
+	      ;; Normal character. Save the associated information in the
+	      ;; database directly.
+	      (put-database (match-string 1)
+			    (format "(%d %d)"
+				    (+ offset-start (1- (match-beginning 0)))
+				    (+ offset-start (1- (match-end 0))))
+			    database-handle))))
+	  (goto-char (point-min))
+	  (setq offset-start offset-end
+		offset-end (+ buffer-size offset-end))))
+      ;; Save the range information as such in the database. 
+      (put-database "range-information"
+		    (let ((print-readably t))
+		      (prin1-to-string range-information))
+		    database-handle) 
+      (close-database database-handle)
+      (progress-feedback-with-label 'describe-char-unicodedata-file
+				    "%s" 100 message)
+      database-file-name)))
 
 (defun unidata-initialize-unihan-database (unihan-file-name)
   "Init the berkeley or gdbm lookup table for UNIHAN-FILE-NAME.
@@ -562,114 +564,115 @@
   (check-argument-type #'file-readable-p unihan-file-name)
   (unless unidata-database-format
     (error 'unimplemented "No (non-SQL) DB support available"))
-  (let* ((database-format unidata-database-format)
-         (size (eighth (file-attributes unihan-file-name)))
-         (database-file-name
-          (unidata-generate-database-file-name unihan-file-name
-                                               size database-format))
-         (database-handle (open-database database-file-name database-format 
-                                         nil "rw+" #o644 'no-conversion-unix))
-         (coding-system-for-read 'no-conversion-unix)
-         (buffer-size 65536)
-         (offset-start 0)
-         (offset-end buffer-size)
-         (message "Initializing Unihan database cache: ")
-         (loop-count 1)
-         trailing-unicode leading-unicode character-start character-end)
-    (with-temp-buffer
-      (progress-feedback-with-label 'describe-char-unihan-file
-                                    "%s" 0 message)
-      (while (progn
-               (delete-region (point-min) (point-max))
-               (insert-file-contents unihan-file-name nil
-                                     offset-start offset-end)
-               ;; If we've reached the end of the data, return nil to the
-               ;; while.
-               (not (= (point-min) (point-max))))
+  (with-fboundp '(open-database put-database close-database)
+    (let* ((database-format unidata-database-format)
+	   (size (eighth (file-attributes unihan-file-name)))
+	   (database-file-name
+	    (unidata-generate-database-file-name unihan-file-name
+						 size database-format))
+	   (database-handle (open-database database-file-name database-format 
+					   nil "rw+" #o644
+					   'no-conversion-unix))
+	   (coding-system-for-read 'no-conversion-unix)
+	   (buffer-size 65536)
+	   (offset-start 0)
+	   (offset-end buffer-size)
+	   (message "Initializing Unihan database cache: ")
+	   (loop-count 1)
+	   trailing-unicode leading-unicode character-start character-end)
+      (with-temp-buffer
+	(progress-feedback-with-label 'describe-char-unihan-file
+				      "%s" 0 message)
+	(while (progn
+		 (delete-region (point-min) (point-max))
+		 (insert-file-contents unihan-file-name nil
+				       offset-start offset-end)
+		 ;; If we've reached the end of the data, return nil to the
+		 ;; while.
+		 (not (= (point-min) (point-max))))
 
-        (incf loop-count)
-        (progress-feedback-with-label 'describe-char-unihan-file
-                                      "%s" (truncate
-                                            (* (/ offset-start size) 100))
-                                      (concat message
-                                              (make-string
-                                               (mod loop-count 44) ?.)))
-        (block 'dealing-with-chars
-          (when (= buffer-size (- (point-max) (point-min)))
-            ;; If we're in the body of the file, we need to delete the
-            ;; character info for the last character, and set offset-end
-            ;; appropriately. Otherwise, we may not be able to pick where
-            ;; the actual description of a character ends and
-            ;; begins. 
-            ;;
-            ;; This breaks if any single Unihan character description is
-            ;; greater than the buffer size in length.
-            (goto-char (point-max))
-            (beginning-of-line)
+	  (incf loop-count)
+	  (progress-feedback-with-label 'describe-char-unihan-file
+					"%s" (truncate
+					      (* (/ offset-start size) 100))
+					(concat message
+						(make-string
+						 (mod loop-count 44) ?.)))
+	  (block 'dealing-with-chars
+	    (when (= buffer-size (- (point-max) (point-min)))
+	      ;; If we're in the body of the file, we need to delete the
+	      ;; character info for the last character, and set offset-end
+	      ;; appropriately. Otherwise, we may not be able to pick where
+	      ;; the actual description of a character ends and begins.
+	      ;;
+	      ;; This breaks if any single Unihan character description is
+	      ;; greater than the buffer size in length.
+	      (goto-char (point-max))
+	      (beginning-of-line)
 
-            (when (< (- (point-max) (point)) (eval-when-compile
-                                               (length "U+ABCDEF\t")))
-              ;; If the character ID of the last line may have been cut off,
-              ;; we need to delete all of that line here.
-              (delete-region (point) (point-max))
-              (forward-line -1))
+	      (when (< (- (point-max) (point)) (eval-when-compile
+						 (length "U+ABCDEF\t")))
+		;; If the character ID of the last line may have been cut off,
+		;; we need to delete all of that line here.
+		(delete-region (point) (point-max))
+		(forward-line -1))
 
-            (when (looking-at "^\\(U\\+[0-9A-F]\\{4,6\\}\\)\t")
-              (setq trailing-unicode (match-string 1)
-                    trailing-unicode
-                    (format "^%s\t" (regexp-quote trailing-unicode)))
+	      (when (looking-at "^\\(U\\+[0-9A-F]\\{4,6\\}\\)\t")
+		(setq trailing-unicode (match-string 1)
+		      trailing-unicode
+		      (format "^%s\t" (regexp-quote trailing-unicode)))
 
-              (end-of-line)
+		(end-of-line)
 
-              ;; Go back until we hit a line that doesn't start with this
-              ;; character info.
-              (while (re-search-backward trailing-unicode nil t))
+		;; Go back until we hit a line that doesn't start with this
+		;; character info.
+		(while (re-search-backward trailing-unicode nil t))
 
-              ;; The re-search-backward failed, so point is still at the end
-              ;; of the last match. Move to its beginning.
-              (beginning-of-line)
-              (delete-region (point) (point-max))
-              (setq offset-end (+ offset-start (- (point) (point-min))))))
-          (goto-char (point-min))
-          (while t
-            (when (= (point) (point-max))
-              ;; We're at the end of this part of the file.
-              (return-from 'dealing-with-chars))
+		;; The re-search-backward failed, so point is still at the end
+		;; of the last match. Move to its beginning.
+		(beginning-of-line)
+		(delete-region (point) (point-max))
+		(setq offset-end (+ offset-start (- (point) (point-min))))))
+	    (goto-char (point-min))
+	    (while t
+	      (when (= (point) (point-max))
+		;; We're at the end of this part of the file.
+		(return-from 'dealing-with-chars))
 
-            (unless (re-search-forward "^\\(U\\+[0-9A-F]\\{4,6\\}\\)\t"
-                                     nil t)
-              ;; We're probably in the comments at the start of the file. No
-              ;; need to look for character info.
-              (return-from 'dealing-with-chars))
+	      (unless (re-search-forward "^\\(U\\+[0-9A-F]\\{4,6\\}\\)\t"
+					 nil t)
+		;; We're probably in the comments at the start of the
+		;; file. No need to look for character info.
+		(return-from 'dealing-with-chars))
 
-            ;; Store where the character started. 
-            (beginning-of-line)
-            (setq character-start (point))
+	      ;; Store where the character started. 
+	      (beginning-of-line)
+	      (setq character-start (point))
 
-            (setq leading-unicode 
-                  (format "^%s\t" (regexp-quote (match-string 1))))
+	      (setq leading-unicode 
+		    (format "^%s\t" (regexp-quote (match-string 1))))
 
-            ;; Loop until we get past this entry.
-            (while (re-search-forward leading-unicode nil t))
+	      ;; Loop until we get past this entry.
+	      (while (re-search-forward leading-unicode nil t))
 
-            ;; Now, store the information.
-            (setq leading-unicode
-                  (string-to-number (substring leading-unicode 3) 16)
-                  leading-unicode (format "%04X" leading-unicode)
-                  character-end (prog2 (end-of-line) (point)))
-            (put-database leading-unicode
-                          (format "(%d %d)"
-                                  (+ offset-start (1- character-start))
-                                  (+ offset-start (1- character-end)))
-                          database-handle)
-            (forward-line)))
-        (setq offset-start offset-end
-              offset-end (+ buffer-size offset-end))))
-    (close-database database-handle)
-    (progress-feedback-with-label 'describe-char-unihan-file
-                                  "%s" 100
-                                  message)
-    database-file-name))
+	      ;; Now, store the information.
+	      (setq leading-unicode
+		    (string-to-number (substring leading-unicode 3) 16)
+		    leading-unicode (format "%04X" leading-unicode)
+		    character-end (prog2 (end-of-line) (point)))
+	      (put-database leading-unicode
+			    (format "(%d %d)"
+				    (+ offset-start (1- character-start))
+				    (+ offset-start (1- character-end)))
+			    database-handle)
+	      (forward-line)))
+	  (setq offset-start offset-end
+		offset-end (+ buffer-size offset-end))))
+      (close-database database-handle)
+      (progress-feedback-with-label 'describe-char-unihan-file
+				    "%s" 100
+				    message)
+      database-file-name)))
 ;; End XEmacs additions.
 
 (defun describe-char-unicode-data (char)
@@ -688,52 +691,55 @@
     (with-temp-buffer
       (let ((coding-system-for-read coding-system-for-read)
             database-handle key lookup)
-        (if (and describe-char-use-cache
-                 (prog1
-                     (setq database-handle
-                           (open-database
-                            (unidata-generate-database-file-name
-                             describe-char-unicodedata-file
-                             (eighth (file-attributes
-                                      describe-char-unicodedata-file))
-                             unidata-database-format)
-                            unidata-database-format
-                            nil "r"
-                            #o644 'no-conversion-unix))
-                   (unless database-handle
-                     (warn "Could not open %s as a %s database"
-                           (unidata-generate-database-file-name
-                            describe-char-unicodedata-file
-                            (eighth (file-attributes
-                                     describe-char-unicodedata-file))
-                            unidata-database-format)
-                           unidata-database-format))))
-            (progn
-              ;; Use the database info.
-              (setq coding-system-for-read 'no-conversion-unix
-                    key (format "%04X" char)
-                    lookup (get-database key database-handle))
-              (if lookup
-                  ;; Okay, we have information on that character in particular.
-                  (progn (setq lookup (read lookup))
-                         (insert-file-contents describe-char-unicodedata-file
-                                               nil (first lookup)
-                                               (second lookup)))
-                ;; No information on that character in particular. Do we
-                ;; have range information? If so, load and check for our
-                ;; desired character.
-                (setq lookup (get-database "range-information" database-handle)
-                      lookup (if lookup (read lookup))
-                      lookup (if lookup (get-range-table char lookup)))
-                (when lookup 
-                  (insert-file-contents describe-char-unicodedata-file nil
-                                        (first lookup) (second lookup))))
-              (close-database database-handle))
-          ;; Otherwise, insert the whole file (the FSF approach).
-          (set-buffer (get-buffer-create " *Unicode Data*"))
-          (when (zerop (buffer-size))
-            ;; Don't use -literally in case of DOS line endings.
-            (insert-file-contents describe-char-unicodedata-file))))
+        (with-fboundp '(open-database get-database close-database)
+          (if (and describe-char-use-cache
+                   (prog1
+                       (setq database-handle
+                             (open-database
+                              (unidata-generate-database-file-name
+                               describe-char-unicodedata-file
+                               (eighth (file-attributes
+                                        describe-char-unicodedata-file))
+                               unidata-database-format)
+                              unidata-database-format
+                              nil "r"
+                              #o644 'no-conversion-unix))
+                     (unless database-handle
+                       (warn "Could not open %s as a %s database"
+                             (unidata-generate-database-file-name
+                              describe-char-unicodedata-file
+                              (eighth (file-attributes
+                                       describe-char-unicodedata-file))
+                              unidata-database-format)
+                             unidata-database-format))))
+              (progn
+                ;; Use the database info.
+                (setq coding-system-for-read 'no-conversion-unix
+                      key (format "%04X" char)
+                      lookup (get-database key database-handle))
+                (if lookup
+                    ;; Okay, we have information on that character in
+                    ;; particular.
+                    (progn (setq lookup (read lookup))
+                           (insert-file-contents describe-char-unicodedata-file
+                                                 nil (first lookup)
+                                                 (second lookup)))
+                  ;; No information on that character in particular. Do we
+                  ;; have range information? If so, load and check for our
+                  ;; desired character.
+                  (setq lookup (get-database "range-information"
+                                             database-handle)
+                        lookup (if lookup (read lookup))
+                        lookup (if lookup (get-range-table char lookup)))
+                  (when lookup 
+                    (insert-file-contents describe-char-unicodedata-file nil
+                                          (first lookup) (second lookup))))
+                (close-database database-handle))
+            ;; Otherwise, insert the whole file (the FSF approach).
+            (set-buffer (get-buffer-create " *Unicode Data*"))
+            (when (zerop (buffer-size))
+              ;; Don't use -literally in case of DOS line endings.
+              (insert-file-contents describe-char-unicodedata-file)))))
       (goto-char (point-min))
       (let ((hex (format "%04X" char))
             found first last unihan-match unihan-info unihan-database-handle
@@ -755,14 +761,11 @@
 		   last (<= char last))
 	      (setq found t)))
 	(if found
-	    (let ((fields (mapcar (lambda (elt)
-				    (if (> (length elt) 0)
-					elt))
-				  (cdr (split-string
-					(buffer-substring
-					 (line-beginning-position)
-					 (line-end-position))
-					";")))))
+	    (let ((fields (cdr (nsubst nil "" (split-string
+					       (buffer-substring
+						(line-beginning-position)
+						(line-end-position)) ";")
+				       :test 'equal))))
 	      ;; The length depends on whether the last field was empty.
 	      (unless (or (= 13 (length fields))
 			  (= 14 (length fields)))
@@ -919,45 +922,46 @@
                (if (and (> (length (nth 0 fields)) 13)
                         (equal "<CJK Ideograph"
                                (substring (nth 0 fields) 0 14)))
-                   (if (and describe-char-unihan-file
-                            (setq unihan-database-handle
-                                  (open-database
-                                   (unidata-generate-database-file-name
-                                    describe-char-unihan-file
-                                    (eighth (file-attributes
-                                             describe-char-unihan-file))
-                                    unidata-database-format)
-                                   unidata-database-format
-                                   nil "r" #o644 'no-conversion-unix))
-                            (setq unihan-match
-                                  (get-database (format "%04X" char)
-                                                unihan-database-handle)
-                                  unihan-match
-                                  (and unihan-match (read unihan-match))))
-                       (with-temp-buffer
-                         (insert-file-contents describe-char-unihan-file
-                                               nil (first unihan-match)
-                                               (second unihan-match))
-                         (goto-char (point-min))
-                         (while (re-search-forward
-                                 "^U\\+[0-9A-F]+\t\\(k[^\t]+\\)\t\\(.*\\)$"
-                                 nil t)
-                           (push
-                            (list
-                             (or (gethash
-                                  (match-string 1)
-                                  describe-char-unihan-field-descriptions)
-                                 (match-string 1))
-                             (decode-coding-string (match-string 2) 'utf-8))
-                            unihan-info))
-                         (close-database unihan-database-handle)
-                         unihan-info)
+                   (with-fboundp '(open-database get-database close-database)
+                     (if (and describe-char-unihan-file
+                              (setq unihan-database-handle
+                                    (open-database
+                                     (unidata-generate-database-file-name
+                                      describe-char-unihan-file
+                                      (eighth (file-attributes
+                                               describe-char-unihan-file))
+                                      unidata-database-format)
+                                     unidata-database-format
+                                     nil "r" #o644 'no-conversion-unix))
+                              (setq unihan-match
+                                    (get-database (format "%04X" char)
+                                                  unihan-database-handle)
+                                    unihan-match
+                                    (and unihan-match (read unihan-match))))
+                         (with-temp-buffer
+                           (insert-file-contents describe-char-unihan-file
+                                                 nil (first unihan-match)
+                                                 (second unihan-match))
+                           (goto-char (point-min))
+                           (while (re-search-forward
+                                   "^U\\+[0-9A-F]+\t\\(k[^\t]+\\)\t\\(.*\\)$"
+                                   nil t)
+                             (push
+                              (list
+                               (or (gethash
+                                    (match-string 1)
+                                    describe-char-unihan-field-descriptions)
+                                   (match-string 1))
+                               (decode-coding-string (match-string 2) 'utf-8))
+                              unihan-info))
+                           (close-database unihan-database-handle)
+                           unihan-info)
                      ;; It's a Han character, but Unihan.txt is not
                      ;; available. Tell the user.
                      (list
                       '("Unihan"
                         "No Unihan information available; is \
-`describe-char-unihan-file' set, and its cache initialized?")))))))))))
+`describe-char-unihan-file' set, and its cache initialized?"))))))))))))
 
 ;; Return information about how CHAR is displayed at the buffer
 ;; position POS.  If the selected frame is on a graphic display,
@@ -1030,8 +1034,7 @@
           (specifier-instance current-display-table (selected-window)))
 	 (disp-table-entry (and display-table
                                 (get-display-table char display-table)))
-	 (extents (mapcar #'(lambda (o) (extent-properties o))
-			   (extents-at pos)))
+	 (extents (mapcar #'extent-properties (extents-at pos)))
 	 (char-description (single-key-description char))
 	 (text-props-desc
 	  (let ((tmp-buf (generate-new-buffer " *text-props*")))
@@ -1202,9 +1205,9 @@
 				       (describe-char-unicode-data unicode)))
 		(if unicodedata
 		    (cons (list "Unicode data" " ") unicodedata)))))
-    (setq max-width (apply #'max (mapcar #'(lambda (x)
-					     (if (cadr x) (length (car x)) 0))
-					 item-list)))
+    (setq max-width
+          (reduce #'max (remove-if-not #'cadr item-list) :initial-value 0
+                  :key #'(lambda (object) (length (car object)))))
     (when (and unicodedata (> max-width max-unicode-description-width))
       (setq max-width max-unicode-description-width)
       (with-temp-buffer
--- a/lisp/device.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/device.el	Mon Oct 18 23:21:23 2010 +0900
@@ -45,7 +45,7 @@
 
 (defun device-list ()
   "Return a list of all devices."
-  (apply 'nconc (mapcar 'console-device-list (console-list))))
+  (mapcan 'console-device-list (console-list)))
 
 (defun device-type (&optional device)
   "Return the type of the specified device (e.g. `x' or `tty').
--- a/lisp/dumped-lisp.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/dumped-lisp.el	Mon Oct 18 23:21:23 2010 +0900
@@ -23,28 +23,19 @@
 
        "backquote" 		; needed for defsubst etc.
        "bytecomp-runtime"	; define defsubst
-       "find-paths"
-       "packages"		; Bootstrap run-time lisp environment
-       "setup-paths"
-
-       ;; use custom-declare-variable-early, not defcustom, in these files
-
        "subr" 			; load the most basic Lisp functions
+       "cl"
+       "cl-extra"	; also loads cl-macs if we're running interpreted.
+       "cl-seq"
        "post-gc"
-       "replace" 		; match-string used in version.el.
-
        "version"
-
-       "cl"
-       "cl-extra"
-       "cl-seq"
+       "custom"		; Before the world so everything can be customized
+       "cus-start"	; for customization of builtin variables
+       "find-paths"
+       "packages"
+       "setup-paths"
+       "replace"
        "widget"
-       "custom"		; Before the world so everything can be
-			; customized
-       "cus-start"	; for customization of builtin variables
-
-       ;; OK, you can use defcustom from here on
-
        "cmdloop"
        "keymap"
        "syntax"
@@ -300,7 +291,4 @@
 	))
 
 (setq preloaded-file-list
-      (apply #'nconc
-	     (mapcar #'(lambda (x)
-			 (if (listp x) x (list x)))
-		     preloaded-file-list)))
+      (mapcan #'(lambda (x) (if (listp x) x (list x))) preloaded-file-list))
--- a/lisp/etags.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/etags.el	Mon Oct 18 23:21:23 2010 +0900
@@ -439,8 +439,7 @@
 (defun buffer-tag-table-files ()
   "Returns a list of all files referenced by all TAGS tables that 
 this buffer uses."
-  (apply #'append
-	 (mapcar #'tag-table-files (buffer-tag-table-list))))
+  (mapcan #'tag-table-files (buffer-tag-table-list)))
 
 
 ;; Building the completion table
--- a/lisp/extents.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/extents.el	Mon Oct 18 23:21:23 2010 +0900
@@ -109,7 +109,7 @@
 EXTENT, until no more children can be found."
   (let ((children (extent-children extent)))
     (if children
-	(apply 'nconc (mapcar 'extent-descendants children))
+	(mapcan 'extent-descendants children)
       (list extent))))
 
 (defun set-extent-keymap (extent keymap)
--- a/lisp/faces.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/faces.el	Mon Oct 18 23:21:23 2010 +0900
@@ -49,9 +49,7 @@
 
 ;; To elude the warnings for font functions. (Normally autoloaded when
 ;; font-create-object is called)
-(eval-when-compile
-  (require 'font)
-  (load "cl-macs"))
+(eval-when-compile (require 'font))
 
 (defgroup faces nil
   "Support for multiple text attributes (fonts, colors, ...)
--- a/lisp/files.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/files.el	Mon Oct 18 23:21:23 2010 +0900
@@ -606,15 +606,10 @@
 	(setq cd-path (or (and trypath
 			       (mapcar #'file-name-as-directory trypath))
 			  (list (file-name-as-directory "")))))
-      (or (catch 'found
-	    (mapc #'(lambda (x)
-                      (let ((f (expand-file-name (concat x dir))))
-                        (if (file-directory-p f)
-                            (progn
-                              (cd-absolute f)
-                              (throw 'found t)))))
-                  cd-path)
-	    nil)
+      (or (some #'(lambda (x)
+                    (let ((f (expand-file-name (concat x dir))))
+                      (when (file-directory-p f) (cd-absolute f))))
+                cd-path)
 	  ;; jwz: give a better error message to those of us with the
 	  ;; good taste not to use a kludge like $CDPATH.
 	  (if (equal cd-path '("./"))
@@ -3060,6 +3055,122 @@
 	(basic-save-buffer-1))
     'continue-save-buffer))
 
+(defun diff-buffer-with-file (&optional buffer)
+  "View the differences between BUFFER and its associated file.
+This requires the external program `diff' to be in your `exec-path'."
+  (interactive "bBuffer: ")
+  (with-current-buffer (get-buffer (or buffer (current-buffer)))
+    (if (and buffer-file-name
+	     (file-exists-p buffer-file-name))
+	(let ((tempfile (make-temp-file "buffer-content-")))
+	  (unwind-protect
+	      (save-restriction
+		(widen)
+		(write-region (point-min) (point-max) tempfile nil 'nomessage)
+		(diff-files-for-recover "File" 
+					buffer-file-name tempfile buffer-file-name tempfile
+					buffer-file-coding-system)
+		(sit-for 0))
+	    (when (file-exists-p tempfile)
+	      (delete-file tempfile))))
+      (message "Buffer %s has no associated file on disc" (buffer-name))
+      ;; Display that message for 1 second so that user can read it
+      ;; in the minibuffer.
+      (sit-for 1)))
+  ;; return always nil, so that save-buffers-kill-emacs will not move
+  ;; over to the next unsaved buffer when calling `d'.
+  nil)
+
+(defvar save-some-buffers-action-alist
+  ;;instead of this we just say "yes all", "no all", etc.
+  ;;"save all the rest"
+  ;;"save only this buffer" "save no more buffers")
+  ;; this is rather bogus. --ben
+  ;; (it makes the dialog box too big, and you get an error
+  ;; "wrong type argument: framep, nil" when you hit q after
+  ;; choosing the option from the dialog box)
+
+  ;; We should fix the dialog box rather than disabling
+  ;; this!  --hniksic
+  (list (list ?\C-r (lambda (buf)
+		      ;; #### FSF has an EXIT-ACTION argument
+		      ;; to `view-buffer'.
+		      (view-buffer buf
+;				   (function
+;				    (lambda (ignore)
+;				      (exit-recursive-edit))))
+				   )
+		      (with-boundp 'view-exit-action
+			(setq view-exit-action
+			      (lambda (ignore)
+				(exit-recursive-edit))))
+		      (recursive-edit)
+		      ;; Return nil to ask about BUF again.
+		      nil)
+	      "%_Display Buffer") 
+	(list ?d (lambda (buf)
+		   (save-window-excursion (diff-buffer-with-file buf))
+		   (view-buffer (get-buffer-create "*File Diff*") t)
+		   (with-boundp 'view-exit-action
+		     (setq view-exit-action 
+			   (lambda (ignore)
+			     (exit-recursive-edit))))
+		   (recursive-edit)
+		   ;; Return nil to ask about BUF again.
+		   nil)
+	      "View %_Changes in Buffer")))
+
+(defun diff-files-for-recover (purpose file-1 file-2
+			       failed-file-1 failed-file-2
+			       coding-system)
+  "Diff two files for recovering or comparing against the last saved version.
+PURPOSE is an informational string used for naming the resulting buffer.
+FILE-1 and FILE-2 are the two files to compare.
+FAILED-FILE-1 and FAILED-FILE-2 are the names of files for which we should 
+generate directory listings on failure.
+CODING-SYSTEM is the coding system of the resulting buffer."
+  (with-output-to-temp-buffer (concat "*" purpose " Diff*")
+    (buffer-disable-undo standard-output)
+    (let ((coding-system-for-read coding-system))
+	(condition-case ferr
+	     (progn
+	      (apply #'call-process
+		     recover-file-diff-program
+		     nil standard-output nil
+		     (append
+		      recover-file-diff-arguments
+		      (list file-1 file-2)))
+	      (if (fboundp 'diff-mode)
+		  (save-excursion
+		    (set-buffer standard-output)
+		    (declare-fboundp (diff-mode)))))
+	(io-error
+	 (save-excursion
+	   (let ((switches
+		  (declare-boundp
+		   dired-listing-switches)))
+	     (if (file-symlink-p failed-file-2)
+		 (setq switches (concat switches "L")))
+	     (set-buffer standard-output)
+	     ;; XEmacs had the following line, not in FSF.
+	     (setq default-directory (file-name-directory failed-file-2))
+	     ;; Use insert-directory-safely,
+	     ;; not insert-directory, because
+	     ;; these files might not exist.
+	     ;; In particular, FAILED-FILE-2 might not
+	     ;; exist if the auto-save file
+	     ;; was for a buffer that didn't
+	     ;; visit a file, such as
+	     ;; "*mail*".  The code in v20.x
+	     ;; called `ls' directly, so we
+	     ;; need to emulate what `ls' did
+	     ;; in that case.
+	     (insert-directory-safely failed-file-1 switches)
+	     (insert-directory-safely failed-file-2 switches))
+	   (terpri)
+	   (princ "Error during diff: ")
+	   (display-error ferr standard-output)))))))
+
 (defcustom save-some-buffers-query-display-buffer t
   "*Non-nil makes `\\[save-some-buffers]' switch to the buffer offered for saving."
   :type 'boolean
@@ -3138,32 +3249,7 @@
 	       (error nil)))
 	   (buffer-list)
 	   '("buffer" "buffers" "save")
-	   ;;instead of this we just say "yes all", "no all", etc.
-	   ;;"save all the rest"
-	   ;;"save only this buffer" "save no more buffers")
-	   ;; this is rather bogus. --ben
-	   ;; (it makes the dialog box too big, and you get an error
-	   ;; "wrong type argument: framep, nil" when you hit q after
-	   ;; choosing the option from the dialog box)
-
-	   ;; We should fix the dialog box rather than disabling
-	   ;; this!  --hniksic
-	   (list (list ?\C-r (lambda (buf)
-			       ;; #### FSF has an EXIT-ACTION argument
-			       ;; to `view-buffer'.
-			       (view-buffer buf
-; 					    (function
-; 					     (lambda (ignore)
-; 					       (exit-recursive-edit))))
-			       )
-			       (with-boundp 'view-exit-action
-				 (setq view-exit-action
-				       (lambda (ignore)
-					 (exit-recursive-edit))))
-			       (recursive-edit)
-			       ;; Return nil to ask about BUF again.
-			       nil)
-		       "%_Display Buffer"))))
+	   save-some-buffers-action-alist))
 	 (abbrevs-done
 	  (and save-abbrevs abbrevs-changed
 	       (progn
@@ -3689,44 +3775,7 @@
 					 'escape-quoted))
 				    (write-region (point-min) (point-max)
 						  temp nil 'silent)))
-				(with-output-to-temp-buffer "*Autosave Diff*"
-				  (buffer-disable-undo standard-output)
-				  (let ((coding-system-for-read
-					 'escape-quoted))
-				    (condition-case ferr
-					(apply #'call-process
-					       recover-file-diff-program
-					       nil standard-output nil
-					       (append
-						recover-file-diff-arguments
-						(list temp file-name)))
-				      (io-error
-				       (save-excursion
-					 (let ((switches
-						(declare-boundp
-						 dired-listing-switches)))
-					   (if (file-symlink-p file)
-					       (setq switches (concat switches "L")))
-					   (set-buffer standard-output)
-					   ;; XEmacs had the following line, not in FSF.
-					   (setq default-directory (file-name-directory file))
-					   ;; Use insert-directory-safely,
-					   ;; not insert-directory, because
-					   ;; these files might not exist.
-					   ;; In particular, FILE might not
-					   ;; exist if the auto-save file
-					   ;; was for a buffer that didn't
-					   ;; visit a file, such as
-					   ;; "*mail*".  The code in v20.x
-					   ;; called `ls' directly, so we
-					   ;; need to emulate what `ls' did
-					   ;; in that case.
-					   (insert-directory-safely file switches)
-					   (insert-directory-safely file-name switches))
-					 (terpri)
-					 (princ "Error during diff: ")
-					 (display-error ferr
-							standard-output)))))))
+				(diff-files-for-recover "Autosave" temp file-name file file-name 'escape-quoted))
 			    (ignore-errors (kill-buffer buffer))
 			    (ignore-file-errors
 			     (delete-file temp)))))))))))))))
@@ -4400,9 +4449,10 @@
 With prefix arg, silently save all file-visiting buffers, then kill."
   (interactive "P")
   (save-some-buffers arg t)
-  (and (or (not (memq t (mapcar #'(lambda (buf) (and (buffer-file-name buf)
-						     (buffer-modified-p buf)))
-				(buffer-list))))
+  (and (or (not (some #'(lambda (buf)
+                          (and (buffer-file-name buf)
+			       (buffer-modified-p buf)))
+                      (buffer-list)))
 	   (yes-or-no-p "Modified buffers exist; exit anyway? "))
        (or (not (fboundp 'process-list))
 	   ;; process-list is not defined on VMS.
--- a/lisp/format.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/format.el	Mon Oct 18 23:21:23 2010 +0900
@@ -604,9 +604,8 @@
 			  (if (member top-name ans)
 			      ;; This annotation is listed, but still have to
 			      ;; check if multiple annotations are satisfied
-			      (if (member nil (mapcar (lambda (r)
-							(assoc r open-ans))
-						      ans))
+			      (if (notevery (lambda (r) (assoc r open-ans))
+					    ans)
 				  nil	; multiple ans not satisfied
 				;; If there are multiple annotations going
 				;; into one text property, split up the other
--- a/lisp/frame.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/frame.el	Mon Oct 18 23:21:23 2010 +0900
@@ -861,7 +861,7 @@
 (defun frame-list ()
   "Return a list of all frames on all devices/consoles."
   ;; Lists are copies, so nconc is safe here.
-  (apply 'nconc (mapcar 'device-frame-list (device-list))))
+  (mapcan #'device-frame-list (device-list)))
 
 (defun frame-type (&optional frame)
   "Return the type of the specified frame (e.g. `x' or `tty').
--- a/lisp/hash-table.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/hash-table.el	Mon Oct 18 23:21:23 2010 +0900
@@ -37,34 +37,27 @@
 
 (defun hash-table-key-list (hash-table)
   "Return a list of all keys in HASH-TABLE."
-  (let (lis)
-    (maphash #'(lambda (key val)
-		 (push key lis))
-	     hash-table)
-    (nreverse lis)))
+  (let (list)
+    (maphash #'(lambda (key value) (push key list)) hash-table)
+    list))
 
 (defun hash-table-value-list (hash-table)
   "Return a list of all values in HASH-TABLE."
-  (let (lis)
-    (maphash #'(lambda (key val)
-		 (push val lis))
-	     hash-table)
-    (nreverse lis)))
+  (let (list)
+    (maphash #'(lambda (key value) (push value list)) hash-table)
+    list))
 
 (defun hash-table-key-value-alist (hash-table)
   "Return an alist of (KEY . VALUE) for all keys and values in HASH-TABLE."
-  (let (lis)
-    (maphash #'(lambda (key val)
-		 (push (cons key val) lis))
+  (let (list)
+    (maphash #'(lambda (key value) (setq list (acons key value list)))
 	     hash-table)
-    (nreverse lis)))
+    list))
 
 (defun hash-table-key-value-plist (hash-table)
   "Return a plist for all keys and values in HASH-TABLE.
 A plist is a simple list containing alternating keys and values."
-  (let (lis)
-    (maphash #'(lambda (key val)
-		 (push key lis)
-		 (push val lis))
+  (let (list)
+    (maphash #'(lambda (key value) (setq list (list* key value list)))
 	     hash-table)
-    (nreverse lis)))
+    list))
--- a/lisp/info.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/info.el	Mon Oct 18 23:21:23 2010 +0900
@@ -864,14 +864,13 @@
   (if (and Info-dir-contents Info-dir-file-attributes
 	   ;; Verify that none of the files we used has changed
 	   ;; since we used it.
-	   (eval (cons 'and
-		       (mapcar #'(lambda (elt)
-				   (let ((curr (file-attributes (car elt))))
-				     ;; Don't compare the access time.
-				     (if curr (setcar (nthcdr 4 curr) 0))
-				     (setcar (nthcdr 4 (cdr elt)) 0)
-				     (equal (cdr elt) curr)))
-			       Info-dir-file-attributes))))
+	   (every #'(lambda (elt)
+                      (let ((curr (file-attributes (car elt))))
+                        ;; Don't compare the access time.
+                        (if curr (setcar (nthcdr 4 curr) 0))
+                        (setcar (nthcdr 4 (cdr elt)) 0)
+                        (equal (cdr elt) curr)))
+                  Info-dir-file-attributes))
       (insert Info-dir-contents)
     (let ((dirs (reverse Info-directory-list))
 	  buffers lbuffers buffer others nodes dirs-done)
--- a/lisp/minibuf.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/minibuf.el	Mon Oct 18 23:21:23 2010 +0900
@@ -1569,12 +1569,13 @@
 (defun minibuf-directory-files (dir &optional match-regexp files-only)
   (let ((want-file (or (eq files-only nil) (eq files-only t)))
         (want-dirs (or (eq files-only nil) (not (eq files-only t)))))
-    (delete nil
-            (mapcar (function (lambda (f)
-                                (if (file-directory-p (expand-file-name f dir))
-                                    (and want-dirs (file-name-as-directory f))
-                                  (and want-file f))))
-                    (delete "." (directory-files dir nil match-regexp))))))
+    (mapcan
+     #'(lambda (f)
+         (and (not (equal "." f))
+              (if (file-directory-p (expand-file-name f dir))
+                  (and want-dirs (list (file-name-as-directory f)))
+                (and want-file (list f)))))
+     (directory-files dir nil match-regexp))))
 
 
 (defun read-file-name-2 (history prompt dir default
--- a/lisp/modeline.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/modeline.el	Mon Oct 18 23:21:23 2010 +0900
@@ -524,35 +524,31 @@
      (cons
       "Minor Mode Toggles"
       (sort
-       (delq nil (mapcar
-		 #'(lambda (x)
-		     (let* ((toggle-sym (car x))
-			    (toggle-fun (or (get toggle-sym
-						 'modeline-toggle-function)
-					    (and (commandp toggle-sym)
-						 toggle-sym)))
-			    (menu-tag (symbol-name (if (symbolp toggle-fun)
-						       toggle-fun
-						     toggle-sym))
-				      ;; Here a function should
-				      ;; maybe be invoked to
-				      ;; beautify the symbol's
-				      ;; menu appearance.
-				      ))
-		       (and toggle-fun
-			    (vector menu-tag
-				    toggle-fun
-				    ;; The following two are wrong
-				    ;; because of possible name
-				    ;; clashes.
-				    ;:active (get toggle-sym :active t)
-				    ;:included (get toggle-sym :included t)
-				    :style 'toggle
-				    :selected (and (boundp toggle-sym)
-						   toggle-sym)))))
-		 minor-mode-alist))
-       (lambda (e1 e2)
-	 (string< (aref e1 0) (aref e2 0)))))
+       (mapcan
+        #'(lambda (x)
+            (let* ((toggle-sym (car x))
+                   (toggle-fun (or (get toggle-sym
+                                        'modeline-toggle-function)
+                                   (and (commandp toggle-sym)
+                                        toggle-sym)))
+                   (menu-tag (symbol-name (if (symbolp toggle-fun)
+                                              toggle-fun
+                                            toggle-sym))
+                             ;; Here a function should maybe be invoked to
+                             ;; beautify the symbol's menu appearance.
+                             ))
+              (and toggle-fun
+                   (list (vector menu-tag
+                                 toggle-fun
+                                 ;; The following two are wrong because of
+                                 ;; possible name clashes.
+                                 ;:active (get toggle-sym :active t)
+                                 ;:included (get toggle-sym :included t)
+                                 :style 'toggle
+                                 :selected (and (boundp toggle-sym)
+                                                toggle-sym))))))
+		 minor-mode-alist)
+       (lambda (e1 e2) (string< (aref e1 0) (aref e2 0)))))
      event)))
 
 (defvar modeline-minor-mode-map (make-sparse-keymap 'modeline-minor-mode-map)
--- a/lisp/msw-faces.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/msw-faces.el	Mon Oct 18 23:21:23 2010 +0900
@@ -268,12 +268,11 @@
 	(concat (substring font 0 (match-beginning 3))
 		(substring font (match-end 3) (match-end 0))))
   (sort
-   (delq nil
-	 (mapcar #'(lambda (name)
-		     (and (string-match mswindows-font-regexp name)
-			  (string-to-int (substring name (match-beginning 3)
-						    (match-end 3)))))
-		 (font-list font device)))
+   (mapcan #'(lambda (name)
+               (and (string-match mswindows-font-regexp name)
+                    (list (string-to-int (substring name (match-beginning 3)
+						    (match-end 3))))))
+           (font-list font device))
    #'<))
 
 (defun mswindows-frob-font-size (font up-p device)
--- a/lisp/mule/mule-cmds.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/mule/mule-cmds.el	Mon Oct 18 23:21:23 2010 +0900
@@ -789,8 +789,7 @@
 	     (setq string (format "%c" unicode-error-lookup)))
            ;; Treat control characters specially:
            (setq first-char (aref string 0))
-           (when (or (and (>= first-char #x00) (<= first-char #x1f))
-                     (and (>= first-char #x80) (<= first-char #x9f)))
+           (when (or (<= #x00 first-char #x1f) (<= #x80 first-char #x9f))
 	     (setq string (format "^%c" (+ ?@ (aref string 0))))))
          (setq glyph (make-glyph (vector 'string :data string)))
          (set-glyph-face glyph 'unicode-invalid-sequence-warning-face)
--- a/lisp/obsolete.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/obsolete.el	Mon Oct 18 23:21:23 2010 +0900
@@ -428,5 +428,10 @@
 (define-function 'purecopy 'identity)
 (make-obsolete 'purecopy "purespace is not available in XEmacs.")
 
+(define-compatible-function-alias 'process-get 'get)
+(define-compatible-function-alias 'process-put 'put)
+(define-compatible-function-alias 'process-plist 'object-plist)
+(define-compatible-function-alias 'set-process-plist 'object-setplist)
+
 (provide 'obsolete)
 ;;; obsolete.el ends here
--- a/lisp/package-ui.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/package-ui.el	Mon Oct 18 23:21:23 2010 +0900
@@ -408,26 +408,25 @@
   (let ((tmpbuf "*Required-Packages*") do-select)
     (if pui-selected-packages
 	(let ((dependencies
-               (delq nil (mapcar
-                          (lambda (pkg)
-                            (let ((installed
-                                   (package-get-key pkg :version))
-                                  (current
-                                   (package-get-info-prop
-                                    (package-get-info-version
-                                     (package-get-info-find-package
-                                      package-get-base pkg) nil)
-                                    'version)))
-                              (if (or (null installed)
-                                     (< (if (stringp installed)
-                                         (string-to-number installed)
-                                       installed)
-                                     (if (stringp current)
-                                         (string-to-number current)
-                                       current)))
-                                  pkg
-                                nil)))
-                          (package-get-dependencies pui-selected-packages)))))
+               (mapcan
+                (lambda (pkg)
+                  (let ((installed
+                         (package-get-key pkg :version))
+                        (current
+                         (package-get-info-prop
+                          (package-get-info-version
+                           (package-get-info-find-package
+                            package-get-base pkg) nil)
+                          'version)))
+                    (if (or (null installed)
+                            (< (if (stringp installed)
+                                   (string-to-number installed)
+                                 installed)
+                               (if (stringp current)
+                                   (string-to-number current)
+                                 current)))
+                        (list pkg))))
+                (package-get-dependencies pui-selected-packages))))
 	  ;; Don't change window config when asking the user if he really
 	  ;; wants to add the packages.  We do this to avoid messing up
 	  ;; the window configuration if errors occur (we don't want to
--- a/lisp/packages.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/packages.el	Mon Oct 18 23:21:23 2010 +0900
@@ -31,23 +31,7 @@
 ;; This file is dumped with XEmacs.
 
 ;; This file provides low level facilities for XEmacs startup --
-;; particularly regarding the package setup.  This code has to run in
-;; what we call "bare temacs" -- i.e. XEmacs without the usual Lisp
-;; environment.  Pay special attention:
-
-;; - not to use the `lambda' macro.  Use #'(lambda ...) instead.
-;;   (this goes for any package loaded before `subr.el'.)
-;;
-;; - not to use macros, because they are not yet available (and this
-;;   file must be loadable uncompiled.)  Built in macros, such as
-;;   `when' and `unless' are fine, of course.
-;;
-;; - not to use `defcustom'.  If you must add user-customizable
-;;   variables here, use `defvar', and add the variable to
-;;   `cus-start.el'.
-
-;; Because of all this, make sure that the stuff you put here really
-;; belongs here.
+;; particularly regarding the package setup.
 
 ;; This file requires find-paths.el.
 
@@ -467,13 +451,11 @@
 PACKAGE-HIERARCHIES is a list of package hierarchies.
 SUFFIXES is a list of names of hierarchy subdirectories to look for."
   (let ((directories
-	 (apply
-	  #'nconc
-	  (mapcar #'(lambda (hierarchy)
-		      (mapcar #'(lambda (suffix)
-				  (file-name-as-directory (concat hierarchy suffix)))
-			      suffixes))
-		  package-hierarchies))))
+         (mapcan #'(lambda (hierarchy)
+                     (mapcar #'(lambda (suffix)
+                                 (file-name-as-directory (concat hierarchy suffix)))
+                             suffixes))
+                 package-hierarchies)))
     (paths-directories-which-exist directories)))
 
 (defun packages-find-package-load-path (package-hierarchies)
--- a/lisp/post-gc.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/post-gc.el	Mon Oct 18 23:21:23 2010 +0900
@@ -56,15 +56,8 @@
 
 (defun cleanup-simple-finalizers (alist)
   "Clean up `simple-finalizer-ephemerons'."
-  ;; We have to do this by hand because DELETE-IF isn't defined yet.
-  (let ((current simple-finalizer-ephemerons)
-	(prev nil))
-    (while (not (null current))
-      (if (not (ephemeron-ref (car current)))
-	  (if (null prev)
-	      (setq simple-finalizer-ephemerons (cdr current))
-	    (setcdr prev (cdr current)))
-	(setq prev current))
-      (setq current (cdr current)))))
+  (and simple-finalizer-ephemerons
+       (setq simple-finalizer-ephemerons
+	     (delete-if-not #'ephemeron-ref simple-finalizer-ephemerons))))
 
 (add-hook 'post-gc-hook 'cleanup-simple-finalizers)
--- a/lisp/specifier.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/specifier.el	Mon Oct 18 23:21:23 2010 +0900
@@ -105,20 +105,23 @@
 	   ;; this will signal an appropriate error.
 	   (check-valid-instantiator inst-pair specifier-type)))
 
-	((and (valid-specifier-tag-p (car inst-pair))
-	      (valid-instantiator-p (cdr inst-pair) specifier-type))
+	((not (valid-instantiator-p (cdr inst-pair) specifier-type))
+	 (if noerror
+	     t
+	   (check-valid-instantiator (cdr inst-pair) specifier-type)))
+
+	((valid-specifier-tag-p (car inst-pair))
 	 ;; case (b)
 	 (cons (list (car inst-pair)) (cdr inst-pair)))
 
-	((and (valid-specifier-tag-set-p (car inst-pair))
-	      (valid-instantiator-p (cdr inst-pair) specifier-type))
+	((valid-specifier-tag-set-p (car inst-pair))
 	 ;; case (c)
 	 inst-pair)
 	 
 	(t
 	 (if noerror t
-	   (signal 'error (list "Invalid specifier tag set"
-				(car inst-pair)))))))
+	   (error 'invalid-argument "Invalid specifier tag set"
+		  (car inst-pair))))))
 
 (defun canonicalize-inst-list (inst-list specifier-type &optional noerror)
   "Canonicalize the given INST-LIST (a list of inst-pairs).
@@ -199,9 +202,14 @@
 
 	(if (not (valid-specifier-locale-p (car spec)))
 	    ;; invalid locale.
-	    (if noerror t
-	      (signal 'error (list "Invalid specifier locale" (car spec))))
-
+	    (if noerror
+		t
+	      (if (consp (car spec))
+		  ;; If it's a cons, they're probably not passing a locale
+		  (error 'invalid-argument
+			 "Not a valid instantiator list" spec)
+		(error 'invalid-argument
+		       "Invalid specifier locale" (car spec))))
 	  ;; case (b)
 	  (let ((result (canonicalize-inst-list (cdr spec) specifier-type
 						noerror)))
@@ -513,10 +521,9 @@
 			       varlist)))
       ;; Bind the appropriate variables.
       `(let* (,@(mapcan #'(lambda (varel)
-			    (delq nil (mapcar
-				       #'(lambda (varcons)
-					   (and (cdr varcons) varcons))
-				       varel)))
+			    (mapcan #'(lambda (varcons)
+                                        (and (cdr varcons) (list varcons)))
+				       varel))
 			varlist)
 		,@oldvallist)
 	 (unwind-protect
--- a/lisp/subr.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/subr.el	Mon Oct 18 23:21:23 2010 +0900
@@ -39,18 +39,9 @@
 
 ;; BEGIN SYNCHED WITH FSF 21.2
 
-;;; Code:
-(defvar custom-declare-variable-list nil
-  "Record `defcustom' calls made before `custom.el' is loaded to handle them.
-Each element of this list holds the arguments to one call to `defcustom'.")
+;; XEmacs; no need for custom-declare-variable-list, preloaded-file-list is
+;; ordered to make it unnecessary.
 
-;; Use this, rather than defcustom, in subr.el and other files loaded
-;; before custom.el.  See dumped-lisp.el.
-(defun custom-declare-variable-early (&rest arguments)
-  (setq custom-declare-variable-list
-	(cons arguments custom-declare-variable-list)))
-
-
 (defun macro-declaration-function (macro decl)
   "Process a declaration found in a macro definition.
 This is set as the value of the variable `macro-declaration-function'.
@@ -66,7 +57,20 @@
 	   (message "Unknown declaration %s" d)))))
 
 (setq macro-declaration-function 'macro-declaration-function)
-
+
+;; XEmacs; this is here because we use it in backquote.el, so it needs to be
+;; available the first time a `(...) form is expanded.
+(defun list* (first &rest rest)   ; See compiler macro in cl-macs.el
+  "Return a new list with specified args as elements, cons'd to last arg.
+Thus, `(list* A B C D)' is equivalent to `(nconc (list A B C) D)', or to
+`(cons A (cons B (cons C D)))'."
+  (cond ((not rest) first)
+	((not (cdr rest)) (cons first (car rest)))
+	(t (let* ((n (length rest))
+		  (copy (copy-sequence rest))
+		  (last (nthcdr (- n 2) copy)))
+	     (setcdr last (car (cdr last)))
+	     (cons first copy)))))
 
 ;;;; Lisp language features.
 
@@ -1573,19 +1577,6 @@
 (define-function 'eval-in-buffer 'with-current-buffer)
 (make-obsolete 'eval-in-buffer 'with-current-buffer)
 
-;;; The real defn is in abbrev.el but some early callers
-;;;  (eg lisp-mode-abbrev-table) want this before abbrev.el is loaded...
-
-(if (not (fboundp 'define-abbrev-table))
-    (progn
-      (setq abbrev-table-name-list '())
-      (fset 'define-abbrev-table
-	    (function (lambda (name defs)
-			;; These are fixed-up when abbrev.el loads.
-			(setq abbrev-table-name-list
-			      (cons (cons name defs)
-				    abbrev-table-name-list)))))))
-
 ;;; `functionp' has been moved into C.
 
 ;;(defun functionp (object)
--- a/lisp/test-harness.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/test-harness.el	Mon Oct 18 23:21:23 2010 +0900
@@ -502,7 +502,7 @@
 			       `(quote ,(car body))
 			     `(quote (progn ,@body)))))
 	  `(Skip-Test-Unless (fboundp 'defadvice) "can't defadvice"
-	    expected-message-regexp
+	    ,expected-message-regexp
 	    (let ((messages ""))
 	      (defadvice message (around collect activate)
 		(defvar messages)
--- a/lisp/update-elc.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/update-elc.el	Mon Oct 18 23:21:23 2010 +0900
@@ -367,21 +367,19 @@
 	   ;; load-ignore-elc-files because byte-optimize gets autoloaded
 	   ;; from bytecomp.
 	   (let ((recompile-bc-bootstrap
-		  (apply #'nconc
-			 (mapcar
-			  #'(lambda (arg)
-			      (when (member arg update-elc-files-to-compile)
-				(append '("-f" "batch-byte-compile-one-file")
-					(list arg))))
-			  bc-bootstrap)))
+                  (mapcan
+                   #'(lambda (arg)
+                       (when (member arg update-elc-files-to-compile)
+                         (append '("-f" "batch-byte-compile-one-file")
+                                 (list arg))))
+                   bc-bootstrap))
 		 (recompile-bootstrap-other
-		  (apply #'nconc
-			 (mapcar
-			  #'(lambda (arg)
-			      (when (member arg update-elc-files-to-compile)
-				(append '("-f" "batch-byte-compile-one-file")
-					(list arg))))
-			  bootstrap-other))))
+                  (mapcan
+                   #'(lambda (arg)
+                       (when (member arg update-elc-files-to-compile)
+                         (append '("-f" "batch-byte-compile-one-file")
+                                 (list arg))))
+                   bootstrap-other)))
 	     (mapc
 	      #'(lambda (arg)
 		  (setq update-elc-files-to-compile
--- a/lisp/x-compose.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/x-compose.el	Mon Oct 18 23:21:23 2010 +0900
@@ -156,7 +156,7 @@
     compose-cedilla-map compose-diaeresis-map compose-circumflex-map
     compose-tilde-map compose-ring-map compose-caron-map compose-macron-map
     compose-breve-map compose-dot-map compose-doubleacute-map
-    compose-ogonek-map compose-hook-map compose-horn-map))
+    compose-ogonek-map compose-hook-map compose-horn-map compose-stroke-map))
 
 (define-key compose-map 'acute	    compose-acute-map)
 (define-key compose-map 'grave	    compose-grave-map)
@@ -171,6 +171,7 @@
 (define-key compose-map 'ogonek     compose-ogonek-map)
 (define-key compose-map 'breve      compose-breve-map)
 (define-key compose-map 'abovedot   compose-dot-map)
+(define-key compose-map 'stroke     compose-stroke-map)
 
 ;;(define-key function-key-map [multi-key] compose-map)
 
@@ -195,6 +196,7 @@
 (define-key compose-map [~]		compose-tilde-map)
 (define-key compose-map [degree]	compose-ring-map)
 (define-key compose-map [?*]		compose-ring-map)
+(define-key compose-map [stroke]		compose-stroke-map)
 
 (loop
   for (keysym character-code map)
@@ -564,7 +566,42 @@
    (compose-horn-map [?O] #x01A0) ;; CAPITAL O WITH HORN
    (compose-horn-map [?U] #x01AF) ;; CAPITAL U WITH HORN
    (compose-horn-map [?o] #x01A1) ;; SMALL O WITH HORN
-   (compose-horn-map [?u] #x01B0))) ;; SMALL U WITH HORN
+   (compose-horn-map [?u] #x01B0) ;; SMALL U WITH HORN
+   (compose-stroke-map [?A] #x023a) ;; CAPITAL A WITH STROKE
+   (compose-stroke-map [?a] #x2c65) ;; SMALL A WITH STROKE
+   (compose-stroke-map [?B] #x0243) ;; CAPITAL B WITH STROKE
+   (compose-stroke-map [?b] #x0180) ;; SMALL B WITH STROKE
+   (compose-stroke-map [?C] #x023b) ;; CAPITAL C WITH STROKE
+   (compose-stroke-map [?c] #x023c) ;; SMALL C WITH STROKE
+   (compose-stroke-map [?D] #x0110) ;; CAPITAL D WITH STROKE
+   (compose-stroke-map [?d] #x0111) ;; SMALL D WITH STROKE
+   (compose-stroke-map [?E] #x0246) ;; CAPITAL E WITH STROKE
+   (compose-stroke-map [?e] #x0247) ;; SMALL E WITH STROKE
+   (compose-stroke-map [?G] #x01e4) ;; CAPITAL G WITH STROKE
+   (compose-stroke-map [?g] #x01e5) ;; SMALL G WITH STROKE
+   (compose-stroke-map [?H] #x0126) ;; CAPITAL H WITH STROKE
+   (compose-stroke-map [?h] #x0127) ;; SMALL H WITH STROKE
+   (compose-stroke-map [?I] #x0197) ;; CAPITAL I WITH STROKE
+   (compose-stroke-map [?i] #x0268) ;; SMALL I WITH STROKE
+   (compose-stroke-map [?J] #x0248) ;; CAPITAL J WITH STROKE
+   (compose-stroke-map [?j] #x0249) ;; SMALL J WITH STROKE
+   (compose-stroke-map [?K] #xa740) ;; CAPITAL K WITH STROKE
+   (compose-stroke-map [?k] #xa741) ;; SMALL K WITH STROKE
+   (compose-stroke-map [?L] #x0141) ;; CAPITAL L WITH STROKE
+   (compose-stroke-map [?l] #x0142) ;; SMALL L WITH STROKE
+   (compose-stroke-map [?O] #x00d8) ;; CAPITAL O WITH STROKE
+   (compose-stroke-map [?o] #x00f8) ;; SMALL O WITH STROKE
+   (compose-stroke-map [?P] #x2c63) ;; CAPITAL P WITH STROKE
+   (compose-stroke-map [?p] #x1d7d) ;; SMALL P WITH STROKE
+   (compose-stroke-map [?R] #x024c) ;; CAPITAL R WITH STROKE
+   (compose-stroke-map [?r] #x024d) ;; SMALL R WITH STROKE
+   (compose-stroke-map [?T] #x0166) ;; CAPITAL T WITH STROKE
+   (compose-stroke-map [?t] #x0167) ;; SMALL T WITH STROKE
+   (compose-stroke-map [?Y] #x024e) ;; CAPITAL Y WITH STROKE
+   (compose-stroke-map [?y] #x024f) ;; SMALL Y WITH STROKE
+   (compose-stroke-map [?Z] #x01b5) ;; CAPITAL Z WITH STROKE
+   (compose-stroke-map [?z] #x01b6) ;; SMALL Z WITH STROKE
+))
 
 
 ;;; The rest of the compose-map.  These are the composed characters
--- a/lisp/x-faces.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/x-faces.el	Mon Oct 18 23:21:23 2010 +0900
@@ -434,17 +434,17 @@
 	       (concat (substring font 0 (match-beginning 1)) "*"
 		       (substring font (match-end 1) (match-end 0))))))
   (sort
-   (delq nil
-	 (mapcar (function
-		  (lambda (name)
-		    (and (string-match x-font-regexp name)
-			 (list
-			  (string-to-int (substring name (match-beginning 5)
-						    (match-end 5)))
-			  (string-to-int (substring name (match-beginning 6)
-						    (match-end 6)))
-			  name))))
-		 (font-list font device)))
+   (mapcan (function
+            (lambda (name)
+              (and (string-match x-font-regexp name)
+                   (list
+                    (list
+                     (string-to-int (substring name (match-beginning 5)
+                                               (match-end 5)))
+                     (string-to-int (substring name (match-beginning 6)
+                                               (match-end 6)))
+                     name)))))
+           (font-list font device))
    (function (lambda (x y) (if (= (nth 1 x) (nth 1 y))
 			       (< (nth 0 x) (nth 0 y))
 			       (< (nth 1 x) (nth 1 y)))))))
--- a/lisp/x-init.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/lisp/x-init.el	Mon Oct 18 23:21:23 2010 +0900
@@ -92,7 +92,7 @@
                      compose-ring-map compose-caron-map compose-macron-map
                      compose-breve-map compose-dot-map
                      compose-doubleacute-map compose-ogonek-map
-                     compose-hook-map compose-horn-map)
+                     compose-hook-map compose-horn-map compose-stroke-map)
     do (autoload map "x-compose" nil t 'keymap))
 
   (loop 
@@ -208,7 +208,8 @@
          (dead-doubleacute      compose-doubleacute-map)
          (dead-ogonek           compose-ogonek-map)
          (dead-hook             compose-hook-map)
-         (dead-horn             compose-horn-map))
+         (dead-horn             compose-horn-map)
+	 (dead-stroke		compose-stroke-map))
     
     ;; Get the correct value for function-key-map
     with function-key-map = (symbol-value-in-console 'function-key-map
--- a/man/ChangeLog	Mon Oct 18 23:03:27 2010 +0900
+++ b/man/ChangeLog	Mon Oct 18 23:21:23 2010 +0900
@@ -1,3 +1,36 @@
+2010-09-02  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* lispref/os.texi (Time Conversion):
+	Document the new #'format-time-string flags for Roman month
+	numbers.
+
+2010-08-30  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* lispref/eval.texi (Evaluation, Multiple values):
+	Document our implementation of multiple values; point the reader
+	to the CLTL or the Hyperspec for details of exactly when values
+	are discarded.
+
+	* lispref/numbers.texi (Numeric Conversions): Document the
+	optional DIVISOR arguments to the rounding functions, and
+	document that they all return multiple values.
+	(Rounding Operations): Ditto.
+
+	* cl.texi (Multiple Values):
+	Document that we've moved the multiple values implementation to
+	core code, and cross-reference to the Lispref.
+	(Numerical Functions): The various rounding functions are now
+	identical to the built-in rounding functions, with the exception
+	that they return lists, not multiple values; document this.
+
+2010-08-21  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* lispref/objects.texi (Character Type):
+	Go into more detail here on the specific type of error provoked on
+	overlong hex character escapes and non-Latin-1 octal character
+	escapes; give details of why the latter may be encountered, and
+	what to do with such code.
+
 2010-06-13  Stephen J. Turnbull  <stephen@xemacs.org>
 
 	* external-widget.texi: Correct FSF address in permission notice.
--- a/man/cl.texi	Mon Oct 18 23:03:27 2010 +0900
+++ b/man/cl.texi	Mon Oct 18 23:21:23 2010 +0900
@@ -2987,44 +2987,8 @@
 @node Multiple Values, , Loop Facility, Control Structure
 @section Multiple Values
 
-@noindent
-Common Lisp functions can return zero or more results.  Emacs Lisp
-functions, by contrast, always return exactly one result.  This
-package makes no attempt to emulate Common Lisp multiple return
-values; Emacs versions of Common Lisp functions that return more
-than one value either return just the first value (as in
-@code{compiler-macroexpand}) or return a list of values (as in
-@code{get-setf-method}).  This package @emph{does} define placeholders
-for the Common Lisp functions that work with multiple values, but
-in Emacs Lisp these functions simply operate on lists instead.
-The @code{values} form, for example, is a synonym for @code{list}
-in Emacs.
-
-@defspec multiple-value-bind (var@dots{}) values-form forms@dots{}
-This form evaluates @var{values-form}, which must return a list of
-values.  It then binds the @var{var}s to these respective values,
-as if by @code{let}, and then executes the body @var{forms}.
-If there are more @var{var}s than values, the extra @var{var}s
-are bound to @code{nil}.  If there are fewer @var{var}s than
-values, the excess values are ignored.
-@end defspec
-
-@defspec multiple-value-setq (var@dots{}) form
-This form evaluates @var{form}, which must return a list of values.
-It then sets the @var{var}s to these respective values, as if by
-@code{setq}.  Extra @var{var}s or values are treated the same as
-in @code{multiple-value-bind}.
-@end defspec
-
-The older Quiroz package attempted a more faithful (but still
-imperfect) emulation of Common Lisp multiple values.  The old
-method ``usually'' simulated true multiple values quite well,
-but under certain circumstances would leave spurious return
-values in memory where a later, unrelated @code{multiple-value-bind}
-form would see them.
-
-Since a perfect emulation is not feasible in Emacs Lisp, this
-package opts to keep it as simple and predictable as possible.
+This functionality has been moved to core XEmacs, and is documented in
+the XEmacs Lisp reference, @pxref{(lispref.info)Multiple values}.
 
 @node Macros, Declarations, Control Structure, Top
 @chapter Macros
@@ -3506,58 +3470,6 @@
 square root of the argument.
 @end defun
 
-@defun floor* number &optional divisor
-This function implements the Common Lisp @code{floor} function.
-It is called @code{floor*} to avoid name conflicts with the
-simpler @code{floor} function built-in to Emacs 19.
-
-With one argument, @code{floor*} returns a list of two numbers:
-The argument rounded down (toward minus infinity) to an integer,
-and the ``remainder'' which would have to be added back to the
-first return value to yield the argument again.  If the argument
-is an integer @var{x}, the result is always the list @code{(@var{x} 0)}.
-If the argument is an Emacs 19 floating-point number, the first
-result is a Lisp integer and the second is a Lisp float between
-0 (inclusive) and 1 (exclusive).
-
-With two arguments, @code{floor*} divides @var{number} by
-@var{divisor}, and returns the floor of the quotient and the
-corresponding remainder as a list of two numbers.  If
-@code{(floor* @var{x} @var{y})} returns @code{(@var{q} @var{r})},
-then @code{@var{q}*@var{y} + @var{r} = @var{x}}, with @var{r}
-between 0 (inclusive) and @var{r} (exclusive).  Also, note
-that @code{(floor* @var{x})} is exactly equivalent to
-@code{(floor* @var{x} 1)}.
-
-This function is entirely compatible with Common Lisp's @code{floor}
-function, except that it returns the two results in a list since
-Emacs Lisp does not support multiple-valued functions.
-@end defun
-
-@defun ceiling* number &optional divisor
-This function implements the Common Lisp @code{ceiling} function,
-which is analogous to @code{floor} except that it rounds the
-argument or quotient of the arguments up toward plus infinity.
-The remainder will be between 0 and minus @var{r}.
-@end defun
-
-@defun truncate* number &optional divisor
-This function implements the Common Lisp @code{truncate} function,
-which is analogous to @code{floor} except that it rounds the
-argument or quotient of the arguments toward zero.  Thus it is
-equivalent to @code{floor*} if the argument or quotient is
-positive, or to @code{ceiling*} otherwise.  The remainder has
-the same sign as @var{number}.
-@end defun
-
-@defun round* number &optional divisor
-This function implements the Common Lisp @code{round} function,
-which is analogous to @code{floor} except that it rounds the
-argument or quotient of the arguments to the nearest integer.
-In the case of a tie (the argument or quotient is exactly
-halfway between two integers), it rounds to the even integer.
-@end defun
-
 @defun mod* number divisor
 This function returns the same value as the second return value
 of @code{floor}.
@@ -3568,7 +3480,24 @@
 of @code{truncate}.
 @end defun
 
-These definitions are compatible with those in the Quiroz
+@noindent
+The following functions are identical to their built-in counterparts,
+without the trailing @code{*} in their names, but they return lists
+instead of multiple values. @pxref{(lispref.info)Rounding Operations}
+
+@defun floor* number &optional divisor
+@end defun
+
+@defun ceiling* number &optional divisor
+@end defun
+
+@defun truncate* number &optional divisor
+@end defun
+
+@defun round* number &optional divisor
+@end defun
+
+All the above definitions are compatible with those in the Quiroz
 @file{cl.el} package, except that this package appends @samp{*}
 to certain function names to avoid conflicts with existing
 Emacs 19 functions, and that the mechanism for returning
--- a/man/lispref/eval.texi	Mon Oct 18 23:03:27 2010 +0900
+++ b/man/lispref/eval.texi	Mon Oct 18 23:21:23 2010 +0900
@@ -24,6 +24,7 @@
 * Eval::        How to invoke the Lisp interpreter explicitly.
 * Forms::       How various sorts of objects are evaluated.
 * Quoting::     Avoiding evaluation (to put constants in the program).
+* Multiple values:: Functions may return more than one result.
 @end menu
 
 @node Intro Eval
@@ -708,3 +709,102 @@
 Functions}), which causes an anonymous lambda expression written in Lisp
 to be compiled, and @samp{`} (@pxref{Backquote}), which is used to quote
 only part of a list, while computing and substituting other parts.
+
+@node Multiple values
+@section Multiple values
+@cindex multiple values
+
+@noindent
+Under XEmacs, expressions can return zero or more results, using the
+@code{values} and @code{values-list} functions. Results other than the
+first are typically discarded, but special operators are provided to
+access them.
+
+@defun values arguments@dots{}
+This function returns @var{arguments} as multiple values. Callers will
+always receive the first element of @var{arguments}, but must use
+various special operators, described below, to access other elements of
+@var{arguments}. 
+
+The idiom @code{(values (function-call argument))}, with one
+argument, is the normal mechanism to avoid passing multiple values to
+the calling form where that is not desired.
+
+XEmacs implements the Common Lisp specification when it comes to the
+exact details of when to discard and when to preserve multiple values;
+see Common Lisp the Language or the Common Lisp hyperspec for more
+details.  The most important thing to keep in mind is when multiple
+values are passed as an argument to a function, all but the first are
+discarded.
+@end defun
+
+@defun values-list argument
+This function returns the elements of the lst @var{argument} as multiple
+values.
+@end defun
+
+@defspec multiple-value-bind (var@dots{}) values-form forms@dots{}
+This special operator evaluates @var{values-form}, which may return
+multiple values.  It then binds the @var{var}s to these respective values,
+as if by @code{let}, and then executes the body @var{forms}.
+If there are more @var{var}s than values, the extra @var{var}s
+are bound to @code{nil}.  If there are fewer @var{var}s than
+values, the excess values are ignored.
+@end defspec
+
+@defspec multiple-value-setq (var@dots{}) form
+This special operator evaluates @var{form}, which may return multiple
+values. It then sets the @var{var}s to these respective values, as if by
+@code{setq}.  Extra @var{var}s or values are treated the same as
+in @code{multiple-value-bind}.
+@end defspec
+
+@defspec multiple-value-call function forms@dots{}
+This special operator evaluates function, discarding any multiple
+values.  It then evaluates @var{forms}, preserving any multiple values,
+and calls @var{function} as a function with the results.  Conceptually, this
+function is a version of @code{apply'}that by-passes the multiple values
+infrastructure, treating multiple values as intercalated lists.
+@end defspec
+
+@defspec multiple-value-list form
+This special operator evaluates @var{form} and returns a list of the
+multiple values given by it.
+@end defspec
+
+@defspec multiple-value-prog1 first body@dots{}
+This special operator evaluates the form @var{first}, then the
+forms @var{body}.  It returns the value given by @var{first}, preserving
+any multiple values.  This is identical to @code{prog1}, except that
+@code{prog1} always discards multiple values.
+@end defspec
+
+@defspec nth-value n form
+This special operator evaluates @var{form} and returns the @var{n}th
+value it gave.  @var{n} must be an integer of value zero or more.
+If @var{form} gave insufficient multiple values, @code{nth-value}
+returns @code{nil}.
+@end defspec
+
+@defvar multiple-values-limit
+This constant describes the exclusive upper bound on the number of
+multiple values that @code{values} accepts and that
+@code{multiple-value-bind}, etc. will consume.
+@end defvar
+
+To take full advantage of multiple values, Emacs Lisp code must have
+been compiled by XEmacs 21.5 or later, which is not yet true of the
+XEmacs packages.  Matched @code{values} and @code{multiple-value-bind}
+calls will work in code included in the XEmacs packages when run on
+21.5, though the following incantation may be necessary at the start of
+your file, until appropriate code is included in XEmacs 21.4:
+
+@example
+(eval-when-compile (when (eq 'list (symbol-function 'values))
+                     (define-compiler-macro values (&rest args)
+                       (cons 'list args))
+                     (define-compiler-macro values-list (list) list)))
+@end example
+
+Such code cannot, unfortunately, rely on XEmacs to discard multiple
+values where that is appropriate.
--- a/man/lispref/numbers.texi	Mon Oct 18 23:03:27 2010 +0900
+++ b/man/lispref/numbers.texi	Mon Oct 18 23:21:23 2010 +0900
@@ -871,9 +871,15 @@
 
 There are four functions to convert floating point numbers to integers;
 they differ in how they round.  These functions accept integer arguments
-also, and return such arguments unchanged.
+also, and return such arguments unchanged.  They return multiple values,
+@pxref{(cl.info)Multiple values}.
 
-@defun truncate number
+All these functions take optional @var{divisor} arguments, and if this
+argument is specified, the @var{number} argument is divided by
+@var{divisor} before the calculation is made.  An @code{arith-error}
+results if @var{divisor} is 0.
+
+@defun truncate number &optional divisor
 This returns @var{number}, converted to an integer by rounding towards
 zero.
 @end defun
@@ -881,23 +887,21 @@
 @defun floor number &optional divisor
 This returns @var{number}, converted to an integer by rounding downward
 (towards negative infinity).
-
-If @var{divisor} is specified, @var{number} is divided by @var{divisor}
-before the floor is taken; this is the division operation that
-corresponds to @code{mod}.  An @code{arith-error} results if
-@var{divisor} is 0.
 @end defun
 
-@defun ceiling number
+@defun ceiling number &optional divisor
 This returns @var{number}, converted to an integer by rounding upward
 (towards positive infinity).
 @end defun
 
-@defun round number
+@defun round number &optional divisor
 This returns @var{number}, converted to an integer by rounding towards the
-nearest integer.  Rounding a value equidistant between two integers
-may choose the integer closer to zero, or it may prefer an even integer,
-depending on your machine.
+nearest integer.
+
+Rounding a value equidistant between two integers chooses the even
+integer.  GNU Emacs and older XEmacs did not guarantee this, and the
+direction of rounding depended on the underlying machine and the C
+implementation.
 @end defun
 
 @node Arithmetic Operations
@@ -1154,24 +1158,35 @@
 @code{ftruncate}, the nearest integer in the direction towards zero;
 @code{fround}, the nearest integer.
 
-@defun ffloor number
+All these functions take optional @var{divisor} arguments, and if this
+argument is specified, the @var{number} argument is divided by
+@var{divisor} before the calculation is made.  An @code{arith-error}
+results if @var{divisor} is 0.  Also, they return multiple values,
+@pxref{(cl.info)Multiple values}; the second value is the remainder.
+
+@defun ffloor number &optional divisor
 This function rounds @var{number} to the next lower integral value, and
 returns that value as a floating point number.
 @end defun
 
-@defun fceiling number
+@defun fceiling number &optional divisor
 This function rounds @var{number} to the next higher integral value, and
 returns that value as a floating point number.
 @end defun
 
-@defun ftruncate number
+@defun ftruncate number &optional divisor
 This function rounds @var{number} towards zero to an integral value, and
 returns that value as a floating point number.
 @end defun
 
-@defun fround number
+@defun fround number &optional divisor
 This function rounds @var{number} to the nearest integral value,
 and returns that value as a floating point number.
+
+Rounding a value equidistant between two integral values chooses the
+even value.  While this is specified by Common Lisp, GNU Emacs and older
+XEmacs did not make this guarantee, and the direction of rounding
+depended on the underlying machine and the C implementation.
 @end defun
 
 @node Bitwise Operations
--- a/man/lispref/objects.texi	Mon Oct 18 23:03:27 2010 +0900
+++ b/man/lispref/objects.texi	Mon Oct 18 23:21:23 2010 +0900
@@ -623,6 +623,8 @@
 @cindex backslash in character constant
 @cindex octal character code
 @cindex hexadecimal character code
+@cindex Overlong hex character escape
+@cindex Non-ISO-8859-1 octal character escape
 
   Finally, there are two read syntaxes involving character codes.
 It is not possible to represent multibyte or wide characters in this
@@ -643,14 +645,21 @@
 @samp{?\001} for the character @kbd{C-a}, and @code{?\002} for the
 character @kbd{C-b}.  The reader will finalize the character and start
 reading the next token when a non-octal-digit is encountered or three
-octal digits are read. 
+octal digits are read.  When a given character code is above
+@code{#o377}, the Lisp reader signals an @code{invalid-read-syntax}
+error.  Such errors are typically provoked by code written for older
+versions of GNU Emacs, where the absence of the #o octal syntax for
+integers made the character syntax convenient for non-character
+values.  Those older versions of GNU Emacs are long obsolete, so
+changing the code to use the #o integer escape is the best
+solution. @pxref{Numbers}.
 
   The second consists of a question mark followed by a backslash, the
 character @samp{x}, and the character code in hexadecimal (up to two
 hexadecimal digits); thus, @samp{?\x41} for the character @kbd{A},
 @samp{?\x1} for the character @kbd{C-a}, and @code{?\x2} for the
 character @kbd{C-b}.  If more than two hexadecimal codes are given, the
-reader signals an error.
+reader signals an @code{invalid-read-syntax} error.
 
 @example
 @group
--- a/man/lispref/os.texi	Mon Oct 18 23:03:27 2010 +0900
+++ b/man/lispref/os.texi	Mon Oct 18 23:21:23 2010 +0900
@@ -1026,6 +1026,10 @@
 This stands for the year with century.
 @item %Z
 This stands for the time zone abbreviation.
+@item %\xe6 (the ISO-8859-1 lowercase ae character)
+This stands for the month as a lowercase Roman number (i-xii)
+@item %\xc6 (the ISO-8859-1 uppercase AE character)
+This stands for the month as an uppercase Roman number (I-XII)
 @end table
 @end defun
 
--- a/src/ChangeLog	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/ChangeLog	Mon Oct 18 23:21:23 2010 +0900
@@ -3,11 +3,292 @@
 	* ui-byhand.c:
 	* gtk-glue.c:
 	Add copyright notice based on internal evidence.
-	
+
 2010-06-14  Stephen J. Turnbull  <stephen@xemacs.org>
 
 	* number.h: Another permission consistency fix.
 
+2010-10-14  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* fns.c (Fnbutlast, Fbutlast):
+	Tighten up Common Lisp compatibility for these two functions; they
+	need to operate on dotted lists without erroring.
+
+2010-10-12  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* fns.c (list_merge):
+	Circularity checking here needs to be done independently for each
+	list, they can't share a loop counter. Thank you for the bug
+	report, Robert Pluim!
+
+2010-09-20  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* lisp.h (GET_DEFUN_LISP_OBJECT): Make the NEW_GC version of this
+	work, remove a needless and unhelpful semicolon.
+	(GET_DEFUN_LISP_OBJECT): Remove a needless semicolon from the
+	non-NEW_GC version of this.
+	(PARSE_KEYWORDS): Fix the indentation for the DEBUG_XEMACS
+	version of this macro.
+	(PARSE_KEYWORDS): Use GET_DEFUN_LISP_OBJECT() for both the NEW_GC
+	and non-NEW_GC versions of this macro, when working out the
+	function's min args. 
+
+2010-09-18  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* lisp.h (PARSE_KEYWORDS):
+	Turns out #elsif is not valid preprocessor syntax, who knew!
+
+2010-09-18  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* lisp.h (PARSE_KEYWORDS):
+	Correct the NEW_GC non-DEBUG_XEMACS version of this macro; under
+	such builds S##function is a pointer, not a Lisp_Subr structure.
+
+2010-09-18  Aidan Kehoe  <kehoea@parhasard.net>
+
+	Simplify the API of PARSE_KEYWORDS for callers.
+
+	* lisp.h (PARSE_KEYWORDS): Simply the API, while making the
+	implementation a little more complex; work out KEYWORDS_OFFSET
+	from the appropriate Lisp_Subr struct, take the function name as
+	the C name of the DEFUN rather than a symbol visible as a
+	Lisp_Object, on debug builds assert that we're actually in the
+	function so we choke on badly-done copy-and-pasting,
+
+	* lisp.h (PARSE_KEYWORDS_8): New. This is the old PARSE_KEYWORDS.
+
+	* fns.c (Fmerge, FsortX, Ffill, Freduce, Freplace):
+	Change to use the new PARSE_KEYWORDS syntax.
+	* elhash.c (Fmake_hash_table): Chance to the new PARSE_KEYWORDS
+	syntax, rename a define to correspond to what other files use.
+	
+	* symbols.c (intern_massaging_name):
+	* buffer.c (ADD_INT):
+	Rename intern_converting_underscores_to_dashes() to
+	intern_massaging_name(), now it does a little more.
+
+2010-09-18  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* termcap.c:
+	Add a couple of missing includes here, which should fix builds
+	that use this file. (I have no access to such builds, but Mats'
+	buildbot shows output that indicates they fail at link time since
+	DEVICE_BAUD_RATE and IS_DIRECTORY_SEP are available.)
+
+2010-09-18  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* fns.c (Freduce):
+	Move statements outside of the braces surrounding the
+	EXTERNAL_LIST_LOOP_3 macro, fixing strict C89 builds. Thank you
+	for the report, Vin!
+
+2010-09-16  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* fns.c (Flist_length): New, moved here from cl-extra.el, needed
+	by the next function.
+	(shortest_length_among_sequences): New.
+	(Fmapconcat, FmapcarX, Fmapvector, Fmapcan, Fmapc, Fmap)
+	(Fmap_into, Fsome, Fevery):
+	Use shortest_length_among_sequences() when working out how many
+	iterations to do, only giving circular list errors if all
+	arguments are circular.
+
+2010-09-16  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* fns.c (Fsubseq):
+	Change the string code to better fit in with the rest of this
+	function (it still uses get_string_range_char(), though, which *may*
+	diverge algorithmically from what we're doing).
+
+	If dealing with a cons, only call #'length if we have reason to
+	believe that the START and END arguments are badly specified, and
+	check for circular lists ourselves when that's appropriate.
+
+	If dealing with a vector, call Fvector() on the appropriate subset
+	of the old vector's data directly, don't initialise the result
+	with nil and then copy.
+
+	(Ffill):
+	Only check the range arguments for a cons SEQUENCE if we have good
+	reason to think they were badly specified.
+	
+	(Freduce):
+	Handle multiple values properly. Add bounds checking to this
+	function, as specificied by ANSI Common Lisp.
+
+2010-09-16  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* eval.c (Ffunction, Fquote):
+	Add argument information in the arguments: () format for these two
+	special operators.
+
+2010-09-07  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* fns.c (Freplace): 
+	Replace an accidental double semi-colon with a single semi-colon,
+	hopefully fixing Vin's Visual Studio 6 build. (Visual Studio 2005
+	had no problem with it, oddly.)
+
+2010-09-06  Aidan Kehoe  <kehoea@parhasard.net>
+
+	Move #'replace to C; add bounds checking to it and to #'fill.
+
+	* fns.c (Fsubseq, Ffill, mapcarX):
+	Don't #'nreverse in #'subseq, use fill_string_range and check
+	bounds in #'fill, use replace_string_range() in #'map-into
+	avoiding quadratic time when modfiying the string.
+
+	* fns.c (check_sequence_range, fill_string_range)
+	(replace_string_range, replace_string_range_1, Freplace):
+	New functions; check that arguments fit sequence dimensions, fill
+	a string range with a given character, replace a string range from
+	an Ibyte pointer.
+
+2010-09-05  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* chartab.c (char_table_default_for_type,
+	chartab_default_validate): New. 
+	(print_char_table, Freset_char_table, chartab_default_validate)
+	(chartab_instantiate, structure_type_create_chartab):
+	Accept keyword :default in the read syntax for char tables, and
+	print the default when it is not what was expected for the
+	time. Makes it a little easier to debug things.
+
+2010-09-05  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* editfns.c (Fformat_time_string):
+	Use two backslashes so that there is at least one present in the
+	output of describe function, when describing the Roman month
+	number syntax in this function's docstring. Thanks for provoking
+	me to look at this, Stephen Turnbull.
+
+2010-09-03  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* symsinit.h: Declare reinit_process_early() here, fixing the C++
+	build; thank you for pointing this out, Adam Sjøgren!
+	* fontcolor-msw.c (mswindows_string_to_color):
+	Cast the result of bsearch() to a colormap_t pointer, fixing the
+	Visual Studio 2005 build.
+
+2010-09-02  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* strftime.c (roman_upper, roman_lower, strftime):
+	Implement Roman month numbers, as used in central and eastern
+	Europe.
+	* editfns.c (Fformat_time_string):
+	Document two new escapes, to allow uppercase and lowercase Roman
+	month numbers. Remove documentation of a bug that we didn't
+	actually have.
+	* text.h (Qtime_function_encoding): We know the text encoding
+	coming from strftime(), because we always use the one in
+	strftime.c. Don't use Qnative.
+
+2010-09-01  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* fns.c (list_merge, list_array_merge_into_list)
+	(list_array_merge_into_array):
+	Avoid algorithmic complexity surprises when checking for
+	circularity in these functions.
+	(Freduce): Fix some formatting, in passing.
+
+	(mapcarX): Drop the SOME_OR_EVERY argument to this function;
+	instead, take CALLER, a symbol reflecting the Lisp-visible
+	function that called mapcarX(). Use CALLER with
+	mapping_interaction_error() when sequences are modified
+	illegally. Don't cons with #'some, #'every, not even a little.
+	(Fmapconcat, FmapcarX, Fmapvector, Fmapcan, Fmapc, Fmap)
+	(Fmap_into, Fsome, Fevery): Call mapcarX() with its new
+	arguments.
+	(Fmapcan): Don't unnecessarily complicate the nconc call.
+
+	(maplist): Take CALLER, a symbol reflecting the Lisp-visible
+	function that called maplist(), rather than having separate
+	arguments to indicate mapl vs. mapcon.
+	Avoid algorithmic complexity surprises when checking for
+	circularity. In #'mapcon, check a given stretch of
+	result for well-formedness once, which was not previously the
+	case, despite what the comments said.
+	(Fmaplist, Fmapl, Fmapcon):
+	Call maplist() with its new arguments.	
+
+2010-09-02  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* process.c (process_getprop, process_putprop, process_remprop)
+	(process_plist, process_setplist, reinit_process_early):
+	Add functions to modify a process's property list.
+	* process-slots.h (MARKED_SLOT): Add a plist slot.
+
+	* fns.c (Fobject_setplist): New function, analogous to #'setplist,
+	but more general.
+	Update the documentation in the other plist functions to reflect
+	that processes now have property lists.
+	* emacs.c (main_1): Call reinit_process_early(), now processes have
+	plist methods that need to be initialised.
+	* symbols.c (reinit_symbol_objects_early): Fsetplist is the named
+	setplist method for symbols.
+
+2010-08-30  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* floatfns.c (ceiling_one_mundane_arg, floor_one_mundane_arg)
+	(round_one_mundane_arg, truncate_one_mundane_arg):
+	INTEGERP is always available, no need to wrap calls to it with
+	#ifdef HAVE_BIGNUM.
+	(Fceiling, Ffloor, Fround, Ftruncate, Ffceiling, Fffloor)
+	(Ffround, Fftruncate):
+	Correct some code formatting here.
+	* doprnt.c (emacs_doprnt_1):
+	Remove some needless #ifdef WITH_NUMBER_TYPES, now number.h is
+	always #included. 
+
+2010-08-26  Adam Sjøgren <asjo@koldfront.dk>
+
+	* glyphs-eimage.c (gif_instantiate): Try harder to find an
+	appropriate GIF colormap and then flag an error if one can't be
+	found.
+
+2010-08-21  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* lread.c (read_escape):
+	Make error messages better reflect the text that was encountered,
+	when overlong hex character escapes or non-Latin-1 octal character
+	escapes are encountered.
+
+2010-08-15  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* print.c (print_symbol):
+	Escape any symbols that look like ratios, in the same way we do
+	symbols that look like floats or integers. Prevents confusion in
+	the Lisp reader.
+	* lread.c (isratio_string): Make this available even on builds
+	without HAVE_RATIO, so we can print symbols that look like ratios
+	with the appropriate escapes.
+	* lisp.h:
+	Make isratio_string available even if HAVE_RATIO is not defined.
+
+2010-07-24  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* lisp.h (PARSE_KEYWORDS):
+	Always accept a nil :allow-other-keys keyword argument, as
+	described in the ALLOW-OTHER-KEYS-NIL Common Lisp issue writeup,
+	and as necessary for Paul Dietz' tests for #'reduce.
+
+	* fns.c (mapping_interaction_error): New.
+	(Freduce): Call mapping_interaction_error when KEY or FUNCTION
+	have modified a string SEQUENCE such that the byte length of the
+	string has changed, or such that the current cursor pointer
+	doesn't point to the beginning of a character.
+	Cf. the MAPPING-DESTRUCTIVE-INTERACTION Common Lisp issue
+	writeup.
+	When traversing a list, GCPRO the part of it we still have to
+	traverse, to avoid any crashes if FUNCTION or KEY amputate it
+	behind us and force a garbage collection.
+
+2010-06-05  Marcus Crestani  <crestani@informatik.uni-tuebingen.de>
+
+	* gc.c:
+	* mc-alloc.c:
+	Document the new allocator and the new garbage collector.
+
 2010-06-13  Stephen J. Turnbull  <stephen@xemacs.org>
 
 	* elhash.c:
--- a/src/buffer.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/buffer.c	Mon Oct 18 23:21:23 2010 +0900
@@ -1819,10 +1819,10 @@
 
 #define ADD_INT(field) \
   plist = cons3 (make_int (b->text->field), \
-		 intern_converting_underscores_to_dashes (#field), plist)
+		 intern_massaging_name (#field), plist)
 #define ADD_BOOL(field) \
   plist = cons3 (b->text->field ? Qt : Qnil, \
-		 intern_converting_underscores_to_dashes (#field), plist)
+		 intern_massaging_name (#field), plist)
   ADD_INT (bufz);
   ADD_INT (z);
 #ifdef OLD_BYTE_CHAR
--- a/src/chartab.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/chartab.c	Mon Oct 18 23:21:23 2010 +0900
@@ -42,7 +42,7 @@
 #include "chartab.h"
 #include "syntax.h"
 
-Lisp_Object Qchar_tablep, Qchar_table;
+Lisp_Object Qchar_tablep, Qchar_table, Q_default;
 
 Lisp_Object Vall_syntax_tables;
 
@@ -301,6 +301,30 @@
   return Qnil; /* not reached */
 }
 
+static Lisp_Object
+char_table_default_for_type (enum char_table_type type)
+{
+  switch (type)
+    {
+    case CHAR_TABLE_TYPE_CHAR:
+      return make_char (0);
+      break;
+    case CHAR_TABLE_TYPE_DISPLAY:
+    case CHAR_TABLE_TYPE_GENERIC:
+#ifdef MULE
+    case CHAR_TABLE_TYPE_CATEGORY:
+#endif /* MULE */
+      return Qnil;
+      break;
+
+    case CHAR_TABLE_TYPE_SYNTAX:
+      return make_integer (Sinherit);
+      break;
+    }
+  ABORT();
+  return Qzero;
+}
+
 struct ptemap
 {
   Lisp_Object printcharfun;
@@ -336,8 +360,15 @@
   arg.printcharfun = printcharfun;
   arg.first = 1;
 
-  write_fmt_string_lisp (printcharfun, "#s(char-table :type %s :data (",
-			 1, char_table_type_to_symbol (ct->type));
+  write_fmt_string_lisp (printcharfun,
+			 "#s(char-table :type %s", 1,
+			 char_table_type_to_symbol (ct->type));
+  if (!(EQ (ct->default_, char_table_default_for_type (ct->type))))
+    {
+      write_fmt_string_lisp (printcharfun, " :default %S", 1, ct->default_);
+    }
+
+  write_ascstring (printcharfun, " :data (");
   map_char_table (obj, &range, print_table_entry, &arg);
   write_ascstring (printcharfun, "))");
 
@@ -492,37 +523,13 @@
        (char_table))
 {
   Lisp_Char_Table *ct;
-  Lisp_Object def;
 
   CHECK_CHAR_TABLE (char_table);
   ct = XCHAR_TABLE (char_table);
 
-  switch (ct->type)
-    {
-    case CHAR_TABLE_TYPE_CHAR:
-      def = make_char (0);
-      break;
-    case CHAR_TABLE_TYPE_DISPLAY:
-    case CHAR_TABLE_TYPE_GENERIC:
-#ifdef MULE
-    case CHAR_TABLE_TYPE_CATEGORY:
-#endif /* MULE */
-      def = Qnil;
-      break;
-
-    case CHAR_TABLE_TYPE_SYNTAX:
-      def = make_int (Sinherit);
-      break;
-
-    default:
-      ABORT ();
-      def = Qnil;
-      break;
-    }
-
   /* Avoid doubly updating the syntax table by setting the default ourselves,
      since set_char_table_default() also updates. */
-  ct->default_ = def;
+  ct->default_ = char_table_default_for_type (ct->type);
   fill_char_table (ct, Qunbound);
 
   return Qnil;
@@ -1543,12 +1550,22 @@
   return 1;
 }
 
+static int
+chartab_default_validate (Lisp_Object UNUSED (keyword),
+			  Lisp_Object UNUSED (value),
+			  Error_Behavior UNUSED (errb))
+{
+  /* We can't yet validate this, since we don't know what the type of the
+     char table is. We do the validation below in chartab_instantiate(). */
+  return 1;
+}
+
 static Lisp_Object
 chartab_instantiate (Lisp_Object plist)
 {
   Lisp_Object chartab;
   Lisp_Object type = Qgeneric;
-  Lisp_Object dataval = Qnil;
+  Lisp_Object dataval = Qnil, default_ = Qunbound;
 
   if (KEYWORDP (Fcar (plist)))
     {
@@ -1562,6 +1579,10 @@
 	    {
 	      type = value;
 	    }
+	  else if (EQ (key, Q_default))
+	    {
+	      default_ = value;
+	    }
 	  else if (!KEYWORDP (key))
 	    {
 	      signal_error
@@ -1598,6 +1619,13 @@
 #endif /* NEED_TO_HANDLE_21_4_CODE */
 
   chartab = Fmake_char_table (type);
+  if (!UNBOUNDP (default_))
+    {
+      check_valid_char_table_value (default_, XCHAR_TABLE_TYPE (chartab),
+				    ERROR_ME);
+      set_char_table_default (chartab, default_);
+      set_char_table_default (XCHAR_TABLE (chartab)->mirror_table, default_);
+    }
 
   while (!NILP (dataval))
     {
@@ -1872,6 +1900,7 @@
 
   DEFSYMBOL (Qchar_table);
   DEFSYMBOL_MULTIWORD_PREDICATE (Qchar_tablep);
+  DEFKEYWORD (Q_default);
 
   DEFSUBR (Fchar_table_p);
   DEFSUBR (Fchar_table_type_list);
@@ -1926,6 +1955,7 @@
 
   define_structure_type_keyword (st, Q_type, chartab_type_validate);
   define_structure_type_keyword (st, Q_data, chartab_data_validate);
+  define_structure_type_keyword (st, Q_default, chartab_default_validate);
 }
 
 void
--- a/src/doprnt.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/doprnt.c	Mon Oct 18 23:21:23 2010 +0900
@@ -591,11 +591,7 @@
 	      Lisp_Object obj = largs[spec->argnum - 1];
 	      if (CHARP (obj))
 		obj = make_int (XCHAR (obj));
-#ifdef WITH_NUMBER_TYPES
 	      if (!NUMBERP (obj))
-#else
-	      if (!INT_OR_FLOATP (obj))
-#endif
 		{
 		  /* WARNING!  This MUST be big enough for the sprintf below */
 		  CIbyte msg[48];
@@ -606,9 +602,10 @@
 		}
 	      else if (strchr (double_converters, ch))
 		{
-#ifdef WITH_NUMBER_TYPES
-		  if (INTP (obj) || FLOATP (obj))
-		    arg.d = XFLOATINT (obj);
+		  if (INTP (obj))
+		    arg.d = XINT (obj);
+		  else if (FLOATP (obj))
+		    arg.d = XFLOAT_DATA (obj);
 #ifdef HAVE_BIGNUM
 		  else if (BIGNUMP (obj))
 		    arg.d = bignum_to_double (XBIGNUM_DATA (obj));
@@ -631,9 +628,6 @@
 			}
 		    }
 #endif
-#else /* !WITH_NUMBER_TYPES */
-		  arg.d = XFLOATINT (obj);
-#endif /* WITH_NUMBER_TYPES */
 		}
 	      else
 		{
--- a/src/editfns.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/editfns.c	Mon Oct 18 23:21:23 2010 +0900
@@ -1044,11 +1044,10 @@
 %Y is replaced by the year with century.
 %z is replaced by the time zone as a numeric offset (e.g +0530, -0800 etc.)
 %Z is replaced by the time zone abbreviation.
+%\\xe6 is replaced by the month as a lowercase Roman number (i-xii)
+%\\xc6 is replaced by the month as an uppercase Roman number (I-XII)
 
 The number of options reflects the `strftime' function.
-
-BUG: If the charset used by the current locale is not ISO 8859-1, the
-characters appearing in the day and month names may be incorrect.
 */
        (format_string, time_))
 {
--- a/src/elhash.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/elhash.c	Mon Oct 18 23:21:23 2010 +0900
@@ -962,7 +962,7 @@
           else if (EQ (key, Qrehash_threshold)) rehash_threshold = value;
           else if (EQ (key, Qweakness))	    weakness	     = value;
           else if (EQ (key, Qdata))		    data	     = value;
-#ifndef NO_NEED_TO_HANDLE_21_4_CODE
+#ifdef NEED_TO_HANDLE_21_4_CODE
           else if (EQ (key, Qtype))/*obsolete*/ weakness	     = value;
 #endif
           else if (KEYWORDP (key))
@@ -1109,14 +1109,14 @@
 */
        (int nargs, Lisp_Object *args))
 {
-#ifdef NO_NEED_TO_HANDLE_21_4_CODE
-  PARSE_KEYWORDS (Qmake_hash_table, nargs, args, 0, 5,
+#ifndef NEED_TO_HANDLE_21_4_CODE
+  PARSE_KEYWORDS (Fmake_hash_table, nargs, args, 5,
                   (test, size, rehash_size, rehash_threshold, weakness),
-                  NULL, 0);
+                  NULL);
 #else
-  PARSE_KEYWORDS (Qmake_hash_table, nargs, args, 0, 6,
+  PARSE_KEYWORDS (Fmake_hash_table, nargs, args, 6,
                   (test, size, rehash_size, rehash_threshold, weakness,
-		   type), (type = Qunbound, weakness = Qunbound), 0);
+		   type), (type = Qunbound, weakness = Qunbound));
 
   if (EQ (weakness, Qunbound))
     {
--- a/src/emacs.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/emacs.c	Mon Oct 18 23:21:23 2010 +0900
@@ -1468,6 +1468,7 @@
       reinit_alloc_early ();
       reinit_gc_early ();
       reinit_symbols_early ();
+      reinit_process_early ();
 #ifndef NEW_GC
       reinit_opaque_early ();
 #endif /* not NEW_GC */
--- a/src/eval.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/eval.c	Mon Oct 18 23:21:23 2010 +0900
@@ -1270,6 +1270,8 @@
 object preceded by `''. Thus, `'x' is equivalent to `(quote x)', in all
 contexts.  A print function may use either.  Internally the expression is
 represented as `(quote x)').
+
+arguments: (OBJECT)
 */
        (args))
 {
@@ -1350,6 +1352,8 @@
 object preceded by `#''. Thus, #'x is equivalent to (function x), in all
 contexts.  A print function may use either.  Internally the expression is
 represented as `(function x)').
+
+arguments: (SYMBOL-OR-LAMBDA)
 */
        (args))
 {
--- a/src/floatfns.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/floatfns.c	Mon Oct 18 23:21:23 2010 +0900
@@ -1300,11 +1300,7 @@
     }
   else
     {
-#ifdef HAVE_BIGNUM
       if (INTEGERP (number))
-#else
-      if (INTP (number))
-#endif
 	{
 	  return values2 (number, Qzero);
 	}
@@ -1566,11 +1562,7 @@
 floor_one_mundane_arg (Lisp_Object number, Lisp_Object divisor,
 		       int return_float)
 {
-#ifdef HAVE_BIGNUM
   if (INTEGERP (number))
-#else
-  if (INTP (number))
-#endif
     {
       if (return_float)
 	{
@@ -1971,11 +1963,7 @@
 round_one_mundane_arg (Lisp_Object number, Lisp_Object divisor,
 		       int return_float)
 {
-#ifdef HAVE_BIGNUM
   if (INTEGERP (number))
-#else
-  if (INTP (number))
-#endif
     {
       if (return_float)
 	{
@@ -2258,11 +2246,7 @@
 truncate_one_mundane_arg (Lisp_Object number, Lisp_Object divisor,
 			  int return_float)
 {
-#ifdef HAVE_BIGNUM
   if (INTEGERP (number))
-#else
-  if (INTP (number))
-#endif
     {
       if (return_float)
 	{
@@ -2301,7 +2285,7 @@
 */
        (number, divisor))
 {
-  ROUNDING_CONVERT(ceiling, 0);
+  ROUNDING_CONVERT (ceiling, 0);
 }
 
 DEFUN ("floor", Ffloor, 1, 2, 0, /*
@@ -2316,7 +2300,7 @@
 */
        (number, divisor))
 {
-  ROUNDING_CONVERT(floor, 0);
+  ROUNDING_CONVERT (floor, 0);
 }
 
 DEFUN ("round", Fround, 1, 2, 0, /*
@@ -2333,7 +2317,7 @@
 */
        (number, divisor))
 {
-  ROUNDING_CONVERT(round, 0);
+  ROUNDING_CONVERT (round, 0);
 }
 
 DEFUN ("truncate", Ftruncate, 1, 2, 0, /*
@@ -2347,7 +2331,7 @@
 */
        (number, divisor))
 {
-  ROUNDING_CONVERT(truncate, 0);
+  ROUNDING_CONVERT (truncate, 0);
 }
 
 /* Float-rounding functions. */
@@ -2364,7 +2348,7 @@
 */
        (number, divisor))
 {
-  ROUNDING_CONVERT(ceiling, 1);
+  ROUNDING_CONVERT (ceiling, 1);
 }
 
 DEFUN ("ffloor", Fffloor, 1, 2, 0, /*
@@ -2379,7 +2363,7 @@
 */
        (number, divisor))
 {
-  ROUNDING_CONVERT(floor, 1);
+  ROUNDING_CONVERT (floor, 1);
 }
 
 DEFUN ("fround", Ffround, 1, 2, 0, /*
@@ -2395,7 +2379,7 @@
 */
        (number, divisor))
 {
-  ROUNDING_CONVERT(round, 1);
+  ROUNDING_CONVERT (round, 1);
 }
 
 DEFUN ("ftruncate", Fftruncate, 1, 2, 0, /*
@@ -2410,7 +2394,7 @@
 */
        (number, divisor))
 {
-  ROUNDING_CONVERT(truncate, 1);
+  ROUNDING_CONVERT (truncate, 1);
 }
 
 #ifdef FLOAT_CATCH_SIGILL
--- a/src/fns.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/fns.c	Mon Oct 18 23:21:23 2010 +0900
@@ -54,9 +54,12 @@
 /* NOTE: This symbol is also used in lread.c */
 #define FEATUREP_SYNTAX
 
-Lisp_Object Qstring_lessp, Qsort, Qmerge, Qfill;
+Lisp_Object Qstring_lessp, Qsort, Qmerge, Qfill, Qreplace;
 Lisp_Object Qidentity;
-Lisp_Object Qvector, Qarray, Qbit_vector, QsortX, Qreduce, Q_from_end, Q_initial_value;
+Lisp_Object Qvector, Qarray, Qbit_vector, QsortX, Q_from_end, Q_initial_value;
+Lisp_Object Qmapconcat, QmapcarX, Qmapvector, Qmapcan, Qmapc, Qmap, Qmap_into;
+Lisp_Object Qsome, Qevery, Qmaplist, Qmapl, Qmapcon, Qreduce;
+Lisp_Object Q_start1, Q_start2, Q_end1, Q_end2;
 
 Lisp_Object Qbase64_conversion_error;
 
@@ -65,6 +68,26 @@
 static int internal_old_equal (Lisp_Object, Lisp_Object, int);
 Lisp_Object safe_copy_tree (Lisp_Object arg, Lisp_Object vecp, int depth);
 
+static DOESNT_RETURN
+mapping_interaction_error (Lisp_Object func, Lisp_Object object)
+{
+  invalid_state_2 ("object modified while traversing it", func, object);
+}
+
+static void
+check_sequence_range (Lisp_Object sequence, Lisp_Object start,
+		      Lisp_Object end, Lisp_Object length)
+{
+  Elemcount starting = XINT (start), ending, len = XINT (length);
+
+  ending = NILP (end) ? XINT (length) : XINT (end);
+
+  if (!(0 <= starting && starting <= ending && ending <= len))
+    {
+      args_out_of_range_3 (sequence, start, make_int (ending));
+    }
+}
+
 static Lisp_Object
 mark_bit_vector (Lisp_Object UNUSED (obj))
 {
@@ -316,6 +339,29 @@
   return make_int (len);
 }
 
+/* This is almost the above, but is defined by Common Lisp. We need it in C
+   for shortest_length_among_sequences(), below, for the various sequence
+   functions that can usefully operate on circular lists. */
+
+DEFUN ("list-length", Flist_length, 1, 1, 0, /*
+Return the length of LIST.  Return nil if LIST is circular.
+*/
+       (list))
+{
+  Lisp_Object hare, tortoise;
+  Elemcount len;
+
+  for (hare = tortoise = list, len = 0;
+       CONSP (hare) && (! EQ (hare, tortoise) || len == 0);
+       hare = XCDR (hare), len++)
+    {
+      if (len & 1)
+	tortoise = XCDR (tortoise);
+    }
+
+  return EQ (hare, tortoise) && len != 0 ? Qnil : make_int (len);
+}
+
 /*** string functions. ***/
 
 DEFUN ("string-equal", Fstring_equal, 2, 2, 0, /*
@@ -877,7 +923,7 @@
 	    {
 	      CHECK_CHAR_COERCE_INT (elt);
 	      string_result_ptr += set_itext_ichar (string_result_ptr,
-						       XCHAR (elt));
+						    XCHAR (elt));
 	    }
 	}
       if (args_mse)
@@ -988,7 +1034,9 @@
 DEFUN ("subseq", Fsubseq, 2, 3, 0, /*
 Return the subsequence of SEQUENCE starting at START and ending before END.
 END may be omitted; then the subsequence runs to the end of SEQUENCE.
-If START or END is negative, it counts from the end.
+
+If START or END is negative, it counts from the end, in contravention of
+Common Lisp.
 The returned subsequence is always of the same type as SEQUENCE.
 If SEQUENCE is a string, relevant parts of the string-extent-data
 are copied to the new string.
@@ -998,89 +1046,139 @@
 */
        (sequence, start, end))
 {
-  EMACS_INT len, s, e;
-
-  if (STRINGP (sequence))
-    {
-      Charcount ccstart, ccend;
-      Bytecount bstart, blen;
-      Lisp_Object val;
-
-      CHECK_INT (start);
-      get_string_range_char (sequence, start, end, &ccstart, &ccend,
-                             GB_HISTORICAL_STRING_BEHAVIOR);
-      bstart = string_index_char_to_byte (sequence, ccstart);
-      blen = string_offset_char_to_byte_len (sequence, bstart, ccend - ccstart);
-      val = make_string (XSTRING_DATA (sequence) + bstart, blen);
-      /* Copy any applicable extent information into the new string. */
-      copy_string_extents (val, sequence, 0, bstart, blen);
-      return val;
-    }
+  Elemcount len, ss, ee = EMACS_INT_MAX, ii;
+  Lisp_Object result = Qnil;
 
   CHECK_SEQUENCE (sequence);
-
-  len = XINT (Flength (sequence));
-
   CHECK_INT (start);
-  s = XINT (start);
-  if (s < 0)
-    s = len + s;
-
-  if (NILP (end))
-    e = len;
-  else
+  ss = XINT (start);
+
+  if (!NILP (end))
     {
       CHECK_INT (end);
-      e = XINT (end);
-      if (e < 0)
-	e = len + e;
-    }
-
-  if (!(0 <= s && s <= e && e <= len))
-    args_out_of_range_3 (sequence, make_int (s), make_int (e));
-
-  if (VECTORP (sequence))
-    {
-      Lisp_Object result = make_vector (e - s, Qnil);
-      EMACS_INT i;
-      Lisp_Object *in_elts  = XVECTOR_DATA (sequence);
-      Lisp_Object *out_elts = XVECTOR_DATA (result);
-
-      for (i = s; i < e; i++)
-	out_elts[i - s] = in_elts[i];
-      return result;
-    }
-  else if (LISTP (sequence))
-    {
-      Lisp_Object result = Qnil;
-      EMACS_INT i;
-
-      sequence = Fnthcdr (make_int (s), sequence);
-
-      for (i = s; i < e; i++)
-	{
-	  result = Fcons (Fcar (sequence), result);
+      ee = XINT (end);
+    }
+
+  if (STRINGP (sequence))
+    {
+      Bytecount bstart, blen;
+
+      get_string_range_char (sequence, start, end, &ss, &ee,
+                             GB_HISTORICAL_STRING_BEHAVIOR);
+      bstart = string_index_char_to_byte (sequence, ss);
+      blen = string_offset_char_to_byte_len (sequence, bstart, ee - ss);
+
+      result = make_string (XSTRING_DATA (sequence) + bstart, blen);
+      /* Copy any applicable extent information into the new string. */
+      copy_string_extents (result, sequence, 0, bstart, blen);
+    }
+  else if (CONSP (sequence))
+    {
+      Lisp_Object result_tail, saved = sequence;
+
+      if (ss < 0 || ee < 0)
+        {
+          len = XINT (Flength (sequence));
+	  if (ss < 0)
+	    {
+	      ss = len + ss;
+	      start = make_integer (ss);
+	    }
+
+	  if (ee < 0)
+	    {
+	      ee  = len + ee;
+	      end = make_integer (ee);
+	    }
+	  else
+	    {
+	      ee = min (ee, len);
+	    }
+        }
+
+      if (0 != ss)
+        {
+          sequence = Fnthcdr (make_int (ss), sequence);
+        }
+
+      if (ss < ee && !NILP (sequence))
+        {
+	  result = result_tail = Fcons (Fcar (sequence), Qnil);
 	  sequence = Fcdr (sequence);
-	}
-
-      return Fnreverse (result);
-    }
-  else if (BIT_VECTORP (sequence))
-    {
-      Lisp_Object result = make_bit_vector (e - s, Qzero);
-      EMACS_INT i;
-
-      for (i = s; i < e; i++)
-	set_bit_vector_bit (XBIT_VECTOR (result), i - s,
-			    bit_vector_bit (XBIT_VECTOR (sequence), i));
-      return result;
+	  ii = ss + 1;
+
+	  {
+	    EXTERNAL_LIST_LOOP_2 (elt, sequence)
+	      {
+		if (!(ii < ee))
+		  {
+		    break;
+		  }
+
+		XSETCDR (result_tail, Fcons (elt, Qnil));
+		result_tail = XCDR (result_tail);
+		ii++;
+	      }
+	  }
+        }
+
+      if (NILP (result) || (ii < ee && !NILP (end)))
+        {
+          /* We were handed a cons, which definitely has elements. nil
+             result means either ss >= ee or SEQUENCE was nil after the
+             nthcdr; in both cases that means START and END were incorrectly
+             specified for this sequence. ii < ee with a non-nil end means
+             the user handed us a bogus end value. */
+          check_sequence_range (saved, start, end, Flength (saved));
+        }
     }
   else
     {
-      ABORT (); /* unreachable, since CHECK_SEQUENCE (sequence) did not
-                   error */
-      return Qnil;
-    }
+      len = XINT (Flength (sequence));
+      if (ss < 0)
+	{
+	  ss = len + ss;
+	  start = make_integer (ss);
+	}
+
+      if (ee < 0)
+	{
+	  ee = len + ee;
+	  end = make_integer (ee);
+	}
+      else
+	{
+	  ee = min (len, ee);
+	}
+
+      check_sequence_range (sequence, start, end, make_int (len));
+
+      if (VECTORP (sequence))
+        {
+          result = Fvector (ee - ss, XVECTOR_DATA (sequence) + ss);
+        }
+      else if (BIT_VECTORP (sequence))
+        {
+          result = make_bit_vector (ee - ss, Qzero);
+
+          for (ii = ss; ii < ee; ii++)
+            {
+              set_bit_vector_bit (XBIT_VECTOR (result), ii - ss,
+                                  bit_vector_bit (XBIT_VECTOR (sequence), ii));
+            }
+        }
+      else if (NILP (sequence))
+        {
+          DO_NOTHING;
+        }
+      else
+        {
+          /* Won't happen, since CHECK_SEQUENCE didn't error. */
+          ABORT ();
+        }
+    }
+
+  return result;
 }
 
 DEFUN ("substring-no-properties", Fsubstring_no_properties, 1, 3, 0, /* 
@@ -1472,72 +1570,99 @@
 
 DEFUN ("nbutlast", Fnbutlast, 1, 2, 0, /*
 Modify LIST to remove the last N (default 1) elements.
+
 If LIST has N or fewer elements, nil is returned and LIST is unmodified.
+Otherwise, LIST may be dotted, but not circular.
 */
        (list, n))
 {
-  EMACS_INT int_n;
+  Elemcount int_n = 1;
 
   CHECK_LIST (list);
 
-  if (NILP (n))
-    int_n = 1;
-  else
+  if (!NILP (n))
     {
       CHECK_NATNUM (n);
       int_n = XINT (n);
     }
 
-  {
-    Lisp_Object last_cons = list;
-
-    EXTERNAL_LIST_LOOP_1 (list)
-      {
-	if (int_n-- < 0)
-	  last_cons = XCDR (last_cons);
-      }
-
-    if (int_n >= 0)
-      return Qnil;
-
-    XCDR (last_cons) = Qnil;
-    return list;
-  }
+  if (CONSP (list))
+    {
+      Lisp_Object last_cons = list;
+
+      EXTERNAL_LIST_LOOP_3 (elt, list, tail)
+	{
+	  if (int_n-- < 0)
+	    {
+	      last_cons = XCDR (last_cons);
+	    }
+
+	  if (!CONSP (XCDR (tail)))
+	    {
+	      break;
+	    }
+	}
+
+      if (int_n >= 0)
+	{
+	  return Qnil;
+	}
+
+      XCDR (last_cons) = Qnil;
+    }
+
+  return list;
 }
 
 DEFUN ("butlast", Fbutlast, 1, 2, 0, /*
 Return a copy of LIST with the last N (default 1) elements removed.
+
 If LIST has N or fewer elements, nil is returned.
+Otherwise, LIST may be dotted, but not circular, and `(butlast LIST 0)'
+converts a dotted into a true list.
 */
        (list, n))
 {
-  EMACS_INT int_n;
+  Lisp_Object retval = Qnil, retval_tail = Qnil;
+  Elemcount int_n = 1;
 
   CHECK_LIST (list);
 
-  if (NILP (n))
-    int_n = 1;
-  else
+  if (!NILP (n))
     {
       CHECK_NATNUM (n);
       int_n = XINT (n);
     }
 
-  {
-    Lisp_Object retval = Qnil;
-    Lisp_Object tail = list;
-
-    EXTERNAL_LIST_LOOP_1 (list)
-      {
-	if (--int_n < 0)
-	  {
-	    retval = Fcons (XCAR (tail), retval);
-	    tail = XCDR (tail);
-	  }
-      }
-
-    return Fnreverse (retval);
-  }
+  if (CONSP (list))
+    {
+      Lisp_Object tail = list;
+
+      EXTERNAL_LIST_LOOP_3 (elt, list, list_tail)
+	{
+	  if (--int_n < 0)
+	    {
+	      if (NILP (retval_tail))
+		{
+		  retval = retval_tail = Fcons (XCAR (tail), Qnil);
+		}
+	      else
+		{
+		  XSETCDR (retval_tail, Fcons (XCAR (tail), Qnil));
+		  retval_tail = XCDR (retval_tail);
+		}
+
+	      tail = XCDR (tail);
+	    }
+
+	  if (!CONSP (XCDR (list_tail)))
+	    {
+	      break;
+	    }
+	}
+    }
+
+  return retval;
 }
 
 DEFUN ("member", Fmember, 2, 2, 0, /*
@@ -2057,13 +2182,16 @@
   Lisp_Object tail;
   Lisp_Object tem;
   Lisp_Object l1, l2;
-  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
-  int looped = 0;
+  Lisp_Object tortoises[2];
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
+  int l1_count = 0, l2_count = 0;
 
   l1 = org_l1;
   l2 = org_l2;
   tail = Qnil;
   value = Qnil;
+  tortoises[0] = org_l1;
+  tortoises[1] = org_l2; 
 
   if (NULL == c_predicate)
     {
@@ -2075,7 +2203,8 @@
      When l1 and l2 are updated, we copy the new values
      back into the org_ vars.  */
 
-  GCPRO4 (org_l1, org_l2, predicate, value);
+  GCPRO5 (org_l1, org_l2, predicate, value, tortoises[0]);
+  gcpro5.nvars = 2;
 
   while (1)
     {
@@ -2101,32 +2230,56 @@
 	  tem = l1;
 	  l1 = Fcdr (l1);
 	  org_l1 = l1;
+
+	  if (l1_count++ > CIRCULAR_LIST_SUSPICION_LENGTH)
+	    {
+	      if (l1_count & 1)
+		{
+		  if (!CONSP (tortoises[0]))
+		    {
+		      mapping_interaction_error (Qmerge, tortoises[0]);
+		    }
+
+		  tortoises[0] = XCDR (tortoises[0]);
+		}
+
+	      if (EQ (org_l1, tortoises[0]))
+		{
+		  signal_circular_list_error (org_l1);
+		}
+	    }
 	}
       else
 	{
 	  tem = l2;
 	  l2 = Fcdr (l2);
 	  org_l2 = l2;
+
+	  if (l2_count++ > CIRCULAR_LIST_SUSPICION_LENGTH)
+	    {
+	      if (l2_count & 1)
+		{
+		  if (!CONSP (tortoises[1]))
+		    {
+		      mapping_interaction_error (Qmerge, tortoises[1]);
+		    }
+
+		  tortoises[1] = XCDR (tortoises[1]);
+		}
+
+	      if (EQ (org_l2, tortoises[1]))
+		{
+		  signal_circular_list_error (org_l2);
+		}
+	    }
 	}
+
       if (NILP (tail))
 	value = tem;
       else
 	Fsetcdr (tail, tem);
+
       tail = tem;
-
-      if (++looped % CIRCULAR_LIST_SUSPICION_LENGTH) continue;
-
-      /* Just check the lists aren't circular:*/
-      {
-        EXTERNAL_LIST_LOOP_1 (l1)
-          {
-          }
-      }
-      {
-        EXTERNAL_LIST_LOOP_1 (l2)
-          {
-          }
-      }
     }
 }
 
@@ -2224,12 +2377,12 @@
                             Lisp_Object predicate, Lisp_Object key_func,
                             Boolint reverse_order)
 {
-  Lisp_Object tail = Qnil, value = Qnil;
-  struct gcpro gcpro1, gcpro2, gcpro3;
+  Lisp_Object tail = Qnil, value = Qnil, tortoise = list;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   Elemcount array_index = 0;
   int looped = 0;
 
-  GCPRO3 (list, tail, value);
+  GCPRO4 (list, tail, value, tortoise);
 
   while (1)
     {
@@ -2291,13 +2444,18 @@
           ++array_index;
         }
 
-      if (++looped % CIRCULAR_LIST_SUSPICION_LENGTH) continue;
-
-      {
-        EXTERNAL_LIST_LOOP_1 (list)
-          {
-          }
-      }
+      if (++looped > CIRCULAR_LIST_SUSPICION_LENGTH)
+        {
+          if (looped & 1)
+            {
+              tortoise = XCDR (tortoise);
+            }
+
+          if (EQ (list, tortoise))
+            {
+              signal_circular_list_error (list);
+            }
+        }
     }
 }
 
@@ -2371,7 +2529,7 @@
         {
           if (array_len - array_index != output_len - output_index)
             {
-              invalid_state ("List length modified during merge", Qunbound);
+	      mapping_interaction_error (Qmerge, list);
             }
 
           while (array_index < array_len)
@@ -2463,7 +2621,7 @@
   Lisp_Object (*c_predicate) (Lisp_Object, Lisp_Object, Lisp_Object,
 			      Lisp_Object);
 
-  PARSE_KEYWORDS (Qmerge, nargs, args, 4, 1, (key), NULL, 0);
+  PARSE_KEYWORDS (Fmerge, nargs, args, 1, (key), NULL);
 
   CHECK_SEQUENCE (sequence_one);
   CHECK_SEQUENCE (sequence_two);
@@ -2715,7 +2873,7 @@
                               Lisp_Object);
   Elemcount sequence_len, i;
 
-  PARSE_KEYWORDS (QsortX, nargs, args, 2, 1, (key), NULL, 0);
+  PARSE_KEYWORDS (FsortX, nargs, args, 1, (key), NULL);
 
   CHECK_SEQUENCE (sequence);
 
@@ -3523,7 +3681,8 @@
 This is the last VALUE stored with `(put OBJECT PROPERTY VALUE)'.
 If there is no such property, return optional third arg DEFAULT
 \(which defaults to `nil').  OBJECT can be a symbol, string, extent,
-face, or glyph.  See also `put', `remprop', and `object-plist'.
+face, glyph, or process.  See also `put', `remprop', `object-plist', and
+`object-setplist'.
 */
        (object, property, default_))
 {
@@ -3567,9 +3726,10 @@
 
 DEFUN ("remprop", Fremprop, 2, 2, 0, /*
 Remove, from OBJECT's property list, PROPERTY and its corresponding value.
-OBJECT can be a symbol, string, extent, face, or glyph.  Return non-nil
-if the property list was actually modified (i.e. if PROPERTY was present
-in the property list).  See also `get', `put', and `object-plist'.
+OBJECT can be a symbol, string, extent, face, glyph, or process.
+Return non-nil if the property list was actually modified (i.e. if PROPERTY
+was present in the property list).  See also `get', `put', `object-plist',
+and `object-setplist'.
 */
        (object, property))
 {
@@ -3606,6 +3766,26 @@
   return Qnil;
 }
 
+DEFUN ("object-setplist", Fobject_setplist, 2, 2, 0, /*
+Set OBJECT's property list to NEWPLIST, and return NEWPLIST.
+For a symbol, this is equivalent to `setplist'.
+
+OBJECT can be a symbol or a process, other objects with visible plists do
+not allow their modification with `object-setplist'.
+*/
+       (object, newplist))
+{
+  if (LRECORDP (object) && XRECORD_LHEADER_IMPLEMENTATION (object)->setplist)
+    {
+      return XRECORD_LHEADER_IMPLEMENTATION (object)->setplist (object,
+								newplist);
+    }
+
+  invalid_operation ("Not possible to set object's plist", object);
+  return Qnil;
+}
+
+
 
 static Lisp_Object
 tweaked_internal_equal (Lisp_Object obj1, Lisp_Object obj2,
@@ -3828,6 +4008,29 @@
 }
 
 
+static Lisp_Object replace_string_range_1 (Lisp_Object dest,
+					   Lisp_Object start,
+					   Lisp_Object end,
+					   const Ibyte *source,
+					   const Ibyte *source_limit,
+					   Lisp_Object item);
+
+/* Fill the substring of DEST beginning at START and ending before END with
+   the character ITEM. If DEST does not have sufficient space for END -
+   START characters at START, write as many as is possible without changing
+   the character length of DEST.  Update the string modification flag and do
+   any sledgehammer checks we have turned on.
+
+   START must be a Lisp integer. END can be nil, indicating the length of the
+   string, or a Lisp integer.  The condition (<= 0 START END (length DEST))
+   must hold, or fill_string_range() will signal an error. */
+static Lisp_Object
+fill_string_range (Lisp_Object dest, Lisp_Object item, Lisp_Object start,
+		   Lisp_Object end)
+{
+  return replace_string_range_1 (dest, start, end, NULL, NULL, item);
+}
+
 DEFUN ("fill", Ffill, 2, MANY, 0, /*
 Destructively modify SEQUENCE by replacing each element with ITEM.
 SEQUENCE is a list, vector, bit vector, or string.
@@ -3837,21 +4040,20 @@
 exclusive upper bound on the elements of SEQUENCE to be modified, and
 defaults to the length of SEQUENCE.
 
-arguments: (SEQUENCE ITEM &key (START 0) END)
+arguments: (SEQUENCE ITEM &key (START 0) (END (length SEQUENCE)))
 */
        (int nargs, Lisp_Object *args))
 {
   Lisp_Object sequence = args[0];
   Lisp_Object item = args[1];
-  Elemcount starting = 0, ending = EMACS_INT_MAX, ii;
-
-  PARSE_KEYWORDS (Qfill, nargs, args, 2, 2, (start, end),
-                  (start = Qzero, end = Qunbound), 0);
+  Elemcount starting = 0, ending = EMACS_INT_MAX, ii, len;
+
+  PARSE_KEYWORDS (Ffill, nargs, args, 2, (start, end), (start = Qzero));
 
   CHECK_NATNUM (start);
   starting = XINT (start);
 
-  if (!UNBOUNDP (end))
+  if (!NILP (end))
     {
       CHECK_NATNUM (end);
       ending = XINT (end);
@@ -3860,49 +4062,21 @@
  retry:
   if (STRINGP (sequence))
     {
-      Bytecount prefix_bytecount, item_bytecount, delta;
-      Ibyte item_buf[MAX_ICHAR_LEN];
-      Ibyte *p, *pend;
-
       CHECK_CHAR_COERCE_INT (item);
-
       CHECK_LISP_WRITEABLE (sequence);
-      sledgehammer_check_ascii_begin (sequence);
-      item_bytecount = set_itext_ichar (item_buf, XCHAR (item));
-
-      p = XSTRING_DATA (sequence);
-      p = (Ibyte *) itext_n_addr (p, starting);
-      prefix_bytecount = p - XSTRING_DATA (sequence);
-
-      ending = min (ending, string_char_length (sequence));
-      pend = (Ibyte *) itext_n_addr (p, ending - starting); 
-      delta = ((ending - starting) * item_bytecount) - (pend - p);
-
-      /* Resize the string if the bytecount for the area being modified is
-	 different. */
-      if (delta)
-	{
-	  resize_string (sequence, prefix_bytecount, delta);
-	  /* No need to zero-terminate the string, resize_string has done
-	     that for us. */
-	  p = XSTRING_DATA (sequence) + prefix_bytecount;
-	  pend = p + ((ending - starting) * item_bytecount);
-	}
-
-      for (; p < pend; p += item_bytecount)
-	memcpy (p, item_buf, item_bytecount);
-
-
-      init_string_ascii_begin (sequence);
-      bump_string_modiff (sequence);
-      sledgehammer_check_ascii_begin (sequence);
+
+      fill_string_range (sequence, item, start, end);
     }
   else if (VECTORP (sequence))
     {
       Lisp_Object *p = XVECTOR_DATA (sequence);
+
       CHECK_LISP_WRITEABLE (sequence);
-
-      ending = min (ending, XVECTOR_LENGTH (sequence));
+      len = XVECTOR_LENGTH (sequence);
+
+      check_sequence_range (sequence, start, end, make_int (len));
+      ending = min (ending, len);
+
       for (ii = starting; ii < ending; ++ii)
         {
           p[ii] = item;
@@ -3912,11 +4086,15 @@
     {
       Lisp_Bit_Vector *v = XBIT_VECTOR (sequence);
       int bit;
+
       CHECK_BIT (item);
       bit = XINT (item);
       CHECK_LISP_WRITEABLE (sequence);
-
-      ending = min (ending, bit_vector_length (v));
+      len = bit_vector_length (v);
+
+      check_sequence_range (sequence, start, end, make_int (len));
+      ending = min (ending, len);
+
       for (ii = starting; ii < ending; ++ii)
         {
           set_bit_vector_bit (v, ii, bit);
@@ -3941,6 +4119,11 @@
             }
           ++counting;
         }
+
+      if (counting < starting || (counting != ending && !NILP (end)))
+	{
+	  check_sequence_range (args[0], start, end, Flength (args[0]));
+	}
     }
   else
     {
@@ -4085,6 +4268,24 @@
 }
 
 
+/* Replace the substring of DEST beginning at START and ending before END
+   with the text at SOURCE, which is END - START characters long and
+   SOURCE_LIMIT - SOURCE octets long.  If DEST does not have sufficient
+   space for END - START characters at START, write as many as is possible
+   without changing the length of DEST.  Update the string modification flag
+   and do any sledgehammer checks we have turned on in this build.
+
+   START must be a Lisp integer. END can be nil, indicating the length of the
+   string, or a Lisp integer.  The condition (<= 0 START END (length DEST))
+   must hold, or replace_string_range() will signal an error. */
+static Lisp_Object
+replace_string_range (Lisp_Object dest, Lisp_Object start, Lisp_Object end,
+                      const Ibyte *source, const Ibyte *source_limit)
+{
+  return replace_string_range_1 (dest, start, end, source, source_limit,
+				 Qnil);
+}
+
 /* This is the guts of several mapping functions.
 
    Call FUNCTION CALL_COUNT times, with NSEQUENCES arguments each time,
@@ -4099,35 +4300,35 @@
    so FUNCTION cannot insert a non-cons into SEQUENCES[0] and throw off
    mapcarX.
 
-   Otherwise, mapcarX signals a wrong-type-error if it encounters a
-   non-cons, non-array when traversing SEQUENCES.  Common Lisp specifies in
+   Otherwise, mapcarX signals an invalid state error (see
+   mapping_interaction_error(), above) if it encounters a non-cons,
+   non-array when traversing SEQUENCES.  Common Lisp specifies in
    MAPPING-DESTRUCTIVE-INTERACTION that it is an error when FUNCTION
    destructively modifies SEQUENCES in a way that might affect the ongoing
    traversal operation.
 
-   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 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
-#define SOME_OR_EVERY_EVERY   2
+   CALLER is a symbol describing the Lisp-visible function that was called,
+   and any errors thrown because SEQUENCES was modified will reflect it.
+
+   If CALLER is Qsome, return the (possibly multiple) values given by
+   FUNCTION the first time it is non-nil, and abandon the iterations.
+   LISP_VALS must be the result of calling STORE_VOID_IN_LISP on the address
+   of a Lisp object, and the return value will be stored at that address.
+   If CALLER is Qevery, LISP_VALS must also reflect a pointer to a Lisp
+   object, and Qnil will be stored at that address if FUNCTION gives nil;
+   otherwise it will be left alone. */
 
 static void
 mapcarX (Elemcount call_count, Lisp_Object *vals, Lisp_Object lisp_vals,
 	 Lisp_Object function, int nsequences, Lisp_Object *sequences, 
-	 int some_or_every)
+	 Lisp_Object caller)
 {
   Lisp_Object called, *args;
   struct gcpro gcpro1, gcpro2;
+  Ibyte *lisp_vals_staging, *cursor;
   int i, j;
-  enum lrecord_type lisp_vals_type;
-
-  assert (LRECORDP (lisp_vals));
-  lisp_vals_type = (enum lrecord_type) XRECORD_LHEADER (lisp_vals)->type;
+
+  assert ((EQ (caller, Qsome) || EQ (caller, Qevery)) ? vals == NULL : 1);
 
   args = alloca_array (Lisp_Object, nsequences + 1);
   args[0] = function;
@@ -4171,12 +4372,27 @@
     }
   else
     {
+      enum lrecord_type lisp_vals_type;
       Binbyte *sequence_types = alloca_array (Binbyte, nsequences);
       for (j = 0; j < nsequences; ++j)
 	{
 	  sequence_types[j] = XRECORD_LHEADER (sequences[j])->type;
 	}
 
+      if (!EQ (caller, Qsome) && !EQ (caller, Qevery))
+        {
+          assert (LRECORDP (lisp_vals));
+
+          lisp_vals_type
+            = (enum lrecord_type) XRECORD_LHEADER (lisp_vals)->type;
+
+	  if (lrecord_type_string == lisp_vals_type)
+	    {
+	      lisp_vals_staging = cursor
+		= alloca_ibytes (call_count * MAX_ICHAR_LEN);
+	    }
+        }
+
       for (i = 0; i < call_count; ++i)
 	{
 	  for (j = 0; j < nsequences; ++j)
@@ -4187,13 +4403,12 @@
 		  {
 		    if (!CONSP (sequences[j]))
 		      {
-			/* This means FUNCTION has probably messed
-			   around with a cons in one of the sequences,
-			   since we checked the type
-			   (CHECK_SEQUENCE()) and the length and
+			/* This means FUNCTION has messed around with a cons
+			   in one of the sequences, since we checked the
+			   type (CHECK_SEQUENCE()) and the length and
 			   structure (with Flength()) correctly in our
 			   callers. */
-			dead_wrong_type_argument (Qconsp, sequences[j]);
+                        mapping_interaction_error (caller, sequences[j]);
 		      }
 		    args[j + 1] = XCAR (sequences[j]);
 		    sequences[j] = XCDR (sequences[j]);
@@ -4226,96 +4441,128 @@
 	      vals[i] = IGNORE_MULTIPLE_VALUES (called);
 	      gcpro2.nvars += 1;
 	    }
-	  else
-	    {
-	      switch (lisp_vals_type)
-		{
-		case lrecord_type_symbol:
-		  break;
-		case lrecord_type_cons:
-		  {
-		    if (SOME_OR_EVERY_NEITHER == some_or_every)
-		      {
-			called = IGNORE_MULTIPLE_VALUES (called);
-			if (!CONSP (lisp_vals))
-			  {
-			    /* If FUNCTION has inserted a non-cons non-nil
-			       cdr into the list before we've processed the
-			       relevant part, error. */
-			    dead_wrong_type_argument (Qconsp, lisp_vals);
-			  }
-
-			XSETCAR (lisp_vals, called);
-			lisp_vals = XCDR (lisp_vals);
-			break;
-		      }
-
-		    if (SOME_OR_EVERY_SOME == some_or_every)
-		      {
-			if (!NILP (IGNORE_MULTIPLE_VALUES (called)))
-			  {
-			    XCAR (lisp_vals) = called;
-			    UNGCPRO;
-			    return;
-			  }
-			break;
-		      }
-
-		    if (SOME_OR_EVERY_EVERY == some_or_every)
-		      {
-			called = IGNORE_MULTIPLE_VALUES (called);
-			if (NILP (called))
-			  {
-			    XCAR (lisp_vals) = Qnil;
-			    UNGCPRO;
-			    return;
-			  }
-			break;
-		      }
-
-		    goto bad_some_or_every_flag;
-		  }
-		case lrecord_type_vector:
-		  {
-		    called = IGNORE_MULTIPLE_VALUES (called);
-		    i < XVECTOR_LENGTH (lisp_vals) ?
-		      (XVECTOR_DATA (lisp_vals)[i] = called) :
-		      /* Let #'aset error. */
-		      Faset (lisp_vals, make_int (i), called);
-		    break;
-		  }
-		case lrecord_type_string:
-		  {
-		    /* If this ever becomes a code hotspot, we can keep
-		       around pointers into the data of the string, checking
-		       each time that it hasn't been relocated. */
-		    called = IGNORE_MULTIPLE_VALUES (called);
-		    Faset (lisp_vals, make_int (i), called);
-		    break;
-		  }
-		case lrecord_type_bit_vector:
-		  {
-		    called = IGNORE_MULTIPLE_VALUES (called);
-		    (BITP (called) &&
-		     i < bit_vector_length (XBIT_VECTOR (lisp_vals))) ?
-		      set_bit_vector_bit (XBIT_VECTOR (lisp_vals), i,
-					  XINT (called)) :
-		      (void) Faset (lisp_vals, make_int (i), called);
-		    break;
-		  }
-		bad_some_or_every_flag:
-		default:
-		  {
-		    ABORT();
-		    break;
-		  }
-		}
-	    }
+          else if (EQ (Qsome, caller))
+            {
+              if (!NILP (IGNORE_MULTIPLE_VALUES (called)))
+                {
+                  Lisp_Object *result
+                    = (Lisp_Object *) GET_VOID_FROM_LISP (lisp_vals);
+                  *result = called;
+                  UNGCPRO;
+                  return;
+                }
+            }
+          else if (EQ (Qevery, caller))
+            {
+	      if (NILP (IGNORE_MULTIPLE_VALUES (called)))
+                {
+                  Lisp_Object *result
+                    = (Lisp_Object *) GET_VOID_FROM_LISP (lisp_vals);
+                  *result = Qnil;
+                  UNGCPRO;
+                  return;
+                }
+            }
+          else
+            {
+              called = IGNORE_MULTIPLE_VALUES (called);
+              switch (lisp_vals_type)
+                {
+                case lrecord_type_symbol:
+		  /* Discard the result of funcall. */
+                  break;
+                case lrecord_type_cons:
+                  {
+                    if (!CONSP (lisp_vals))
+                      {
+                        /* If FUNCTION has inserted a non-cons non-nil
+                           cdr into the list before we've processed the
+                           relevant part, error. */
+                        mapping_interaction_error (caller, lisp_vals);
+                      }
+                    XSETCAR (lisp_vals, called);
+                    lisp_vals = XCDR (lisp_vals);
+                    break;
+                  }
+                case lrecord_type_vector:
+                  {
+                    i < XVECTOR_LENGTH (lisp_vals) ?
+                      (XVECTOR_DATA (lisp_vals)[i] = called) :
+                      /* Let #'aset error. */
+                      Faset (lisp_vals, make_int (i), called);
+                    break;
+                  }
+                case lrecord_type_string:
+                  {
+		    CHECK_CHAR_COERCE_INT (called);
+		    cursor += set_itext_ichar (cursor, XCHAR (called));
+                    break;
+                  }
+                case lrecord_type_bit_vector:
+                  {
+                    (BITP (called) &&
+                     i < bit_vector_length (XBIT_VECTOR (lisp_vals))) ?
+                      set_bit_vector_bit (XBIT_VECTOR (lisp_vals), i,
+                                          XINT (called)) :
+                      (void) Faset (lisp_vals, make_int (i), called);
+                    break;
+                  }
+                default:
+                  {
+                    ABORT();
+                    break;
+                  }
+                }
+            }
 	}
-    }
+
+      if (!EQ (caller, Qsome) && !EQ (caller, Qevery) &&
+	  lrecord_type_string == lisp_vals_type)
+	{
+	  replace_string_range (lisp_vals, Qzero, make_int (call_count),
+				lisp_vals_staging, cursor);
+	}
+    }
+
   UNGCPRO;
 }
 
+/* Given NSEQUENCES objects at the address pointed to by SEQUENCES, return
+   the length of the shortest sequence. Error if all are circular, or if any
+   one of them is not a sequence. */
+static Elemcount
+shortest_length_among_sequences (int nsequences, Lisp_Object *sequences)
+{
+  Elemcount len = EMACS_INT_MAX;
+  Lisp_Object length;
+  int i;
+
+  for (i = 0; i < nsequences; ++i)
+    {
+      if (CONSP (sequences[i]))
+        {
+          length = Flist_length (sequences[i]);
+          if (!NILP (length))
+            {
+              len = min (len, XINT (length));
+            }
+        }
+      else
+        {
+          CHECK_SEQUENCE (sequences[i]);
+          length = Flength (sequences[i]);
+          len = min (len, XINT (length));
+        }
+    }
+
+  if (NILP (length))
+    {
+      signal_circular_list_error (sequences[0]);
+    }
+
+  return len;
+}
+
 DEFUN ("mapconcat", Fmapconcat, 3, MANY, 0, /*
 Call FUNCTION on each element of SEQUENCE, and concat results to a string.
 Between each pair of results, insert SEPARATOR.
@@ -4343,11 +4590,7 @@
   args[2] = sequence;
   args[1] = separator;
 
-  for (i = 2; i < nargs; ++i)
-    {
-      CHECK_SEQUENCE (args[i]);
-      len = min (len, XINT (Flength (args[i])));
-    }
+  len = shortest_length_among_sequences (nargs - 2, args + 2);
 
   if (len == 0) return build_ascstring ("");
 
@@ -4367,8 +4610,7 @@
     }
   else
     {
-      mapcarX (len, args0, Qnil, function, nargs - 2, args + 2,
-	       SOME_OR_EVERY_NEITHER);
+      mapcarX (len, args0, Qnil, function, nargs - 2, args + 2, Qmapconcat);
     }
 
   for (i = len - 1; i >= 0; i--)
@@ -4395,19 +4637,11 @@
        (int nargs, Lisp_Object *args))
 {
   Lisp_Object function = args[0];
-  Elemcount len = EMACS_INT_MAX;
+  Elemcount len = shortest_length_among_sequences (nargs - 1, args + 1);
   Lisp_Object *args0;
-  int i;
-
-  for (i = 1; i < nargs; ++i)
-    {
-      CHECK_SEQUENCE (args[i]);
-      len = min (len, XINT (Flength (args[i])));
-    }
 
   args0 = alloca_array (Lisp_Object, len);
-  mapcarX (len, args0, Qnil, function, nargs - 1, args + 1,
-	   SOME_OR_EVERY_NEITHER);
+  mapcarX (len, args0, Qnil, function, nargs - 1, args + 1, QmapcarX);
 
   return Flist ((int) len, args0);
 }
@@ -4427,26 +4661,16 @@
        (int nargs, Lisp_Object *args))
 {
   Lisp_Object function = args[0];
-  Elemcount len = EMACS_INT_MAX;
-  Lisp_Object result;
+  Elemcount len = shortest_length_among_sequences (nargs - 1, args + 1);
+  Lisp_Object result = make_vector (len, Qnil);
+
   struct gcpro gcpro1;
-  int i;
-
-  for (i = 1; i < nargs; ++i)
-    {
-      CHECK_SEQUENCE (args[i]);
-      len = min (len, XINT (Flength (args[i])));
-    }
-
-  result = make_vector (len, Qnil);
   GCPRO1 (result);
   /* Don't pass result as the lisp_object argument, we want mapcarX to protect 
      a single list argument's elements from being garbage-collected. */
   mapcarX (len, XVECTOR_DATA (result), Qnil, function, nargs - 1, args +1,
-	   SOME_OR_EVERY_NEITHER);
-  UNGCPRO;
-
-  return result;
+           Qmapvector);
+  RETURN_UNGCPRO (result);
 }
 
 DEFUN ("mapcan", Fmapcan, 2, MANY, 0, /*
@@ -4464,40 +4688,13 @@
 */
        (int nargs, Lisp_Object *args))
 {
-  Lisp_Object function = args[0], nconcing;
-  Elemcount len = EMACS_INT_MAX;
-  Lisp_Object *args0;
-  struct gcpro gcpro1;
-  int i;
-
-  for (i = 1; i < nargs; ++i)
-    {
-      CHECK_SEQUENCE (args[i]);
-      len = min (len, XINT (Flength (args[i])));
-    }
-
-  args0 = alloca_array (Lisp_Object, len + 1);
-  mapcarX (len, args0 + 1, Qnil, function, nargs - 1, args + 1,
-	   SOME_OR_EVERY_NEITHER);
-
-  if (len < 2)
-    {
-      return len ? args0[1] : Qnil;
-    }
-
-  /* bytecode_nconc2 can signal and return, we need to GCPRO the args, since
-     mapcarX is no longer doing this for us. */
-  args0[0] = Fcons (Qnil, Qnil);
-  GCPRO1 (args0[0]);
-  gcpro1.nvars = len + 1;
-
-  for (i = 0; i < len; ++i)
-    {
-      nconcing = bytecode_nconc2 (args0 + i);
-      args0[i + 1] = nconcing;
-    }
-
-  RETURN_UNGCPRO (XCDR (nconcing));
+  Elemcount len = shortest_length_among_sequences (nargs - 1, args + 1);
+  Lisp_Object function = args[0], *result = alloca_array (Lisp_Object, len);
+
+  mapcarX (len, result, Qnil, function, nargs - 1, args + 1, Qmapcan);
+
+  /* #'nconc GCPROs its args in case of signals and error. */
+  return Fnconc (len, result);
 }
 
 DEFUN ("mapc", Fmapc, 2, MANY, 0, /*
@@ -4518,23 +4715,14 @@
 */
        (int nargs, Lisp_Object *args))
 {
-  Elemcount len = EMACS_INT_MAX;
+  Elemcount len = shortest_length_among_sequences (nargs - 1, args + 1);
   Lisp_Object sequence = args[1];
   struct gcpro gcpro1;
-  int i;
-
-  for (i = 1; i < nargs; ++i)
-    {
-      CHECK_SEQUENCE (args[i]);
-      len = min (len, XINT (Flength (args[i])));
-    }
-
   /* We need to GCPRO sequence, because mapcarX will modify the
      elements of the args array handed to it, and this may involve
      elements of sequence getting garbage collected. */
   GCPRO1 (sequence);
-  mapcarX (len, NULL, Qnil, args[0], nargs - 1, args + 1,
-	   SOME_OR_EVERY_NEITHER);
+  mapcarX (len, NULL, Qnil, args[0], nargs - 1, args + 1, Qmapc);
   RETURN_UNGCPRO (sequence);
 }
 
@@ -4559,23 +4747,15 @@
   Lisp_Object function = args[1];
   Lisp_Object result = Qnil;
   Lisp_Object *args0 = NULL;
-  Elemcount len = EMACS_INT_MAX;
-  int i;
+  Elemcount len = shortest_length_among_sequences (nargs - 2, args + 2);
   struct gcpro gcpro1;
 
-  for (i = 2; i < nargs; ++i)
-    {
-      CHECK_SEQUENCE (args[i]);
-      len = min (len, XINT (Flength (args[i])));
-    }
-
   if (!NILP (type))
     {
       args0 = alloca_array (Lisp_Object, len);
     }
 
-  mapcarX (len, args0, Qnil, function, nargs - 2, args + 2,
-	   SOME_OR_EVERY_NEITHER);
+  mapcarX (len, args0, Qnil, function, nargs - 2, args + 2, Qmap);
 
   if (EQ (type, Qnil))
     {
@@ -4625,22 +4805,17 @@
 */
        (int nargs, Lisp_Object *args))
 {
-  Elemcount len = EMACS_INT_MAX;
+  Elemcount len;
   Lisp_Object result_sequence = args[0];
   Lisp_Object function = args[1];
-  int i;
 
   args[0] = function;
   args[1] = result_sequence;
 
-  for (i = 1; i < nargs; ++i)
-    {
-      CHECK_SEQUENCE (args[i]);
-      len = min (len, XINT (Flength (args[i])));
-    }
+  len = shortest_length_among_sequences (nargs - 1, args + 1);
 
   mapcarX (len, NULL, result_sequence, function, nargs - 2, args + 2,
-	   SOME_OR_EVERY_NEITHER);
+           Qmap_into);
 
   return result_sequence;
 }
@@ -4657,23 +4832,13 @@
 */
        (int nargs, Lisp_Object *args))
 {
-  Lisp_Object result_box = Fcons (Qnil, Qnil);
-  struct gcpro gcpro1;
-  Elemcount len = EMACS_INT_MAX;
-  int i;
-
-  GCPRO1 (result_box);
-
-  for (i = 1; i < nargs; ++i)
-    {
-      CHECK_SEQUENCE (args[i]);
-      len = min (len, XINT (Flength (args[i])));
-    }
-
-  mapcarX (len, NULL, result_box, args[0], nargs - 1, args +1,
-	   SOME_OR_EVERY_SOME);
-
-  RETURN_UNGCPRO (XCAR (result_box));
+  Lisp_Object result = Qnil,
+    result_ptr = STORE_VOID_IN_LISP ((void *) &result);
+  Elemcount len = shortest_length_among_sequences (nargs - 1, args + 1);
+
+  mapcarX (len, NULL, result_ptr, args[0], nargs - 1, args +1, Qsome);
+
+  return result;
 }
 
 DEFUN ("every", Fevery, 2, MANY, 0, /* 
@@ -4688,43 +4853,35 @@
 */
        (int nargs, Lisp_Object *args))
 {
-  Lisp_Object result_box = Fcons (Qt, Qnil);
-  struct gcpro gcpro1;
-  Elemcount len = EMACS_INT_MAX;
-  int i;
-
-  GCPRO1 (result_box);
-
-  for (i = 1; i < nargs; ++i)
-    {
-      CHECK_SEQUENCE (args[i]);
-      len = min (len, XINT (Flength (args[i])));
-    }
-
-  mapcarX (len, NULL, result_box, args[0], nargs - 1, args +1,
-	   SOME_OR_EVERY_EVERY);
-
-  RETURN_UNGCPRO (XCAR (result_box));
+  Lisp_Object result = Qt, result_ptr = STORE_VOID_IN_LISP ((void *) &result);
+  Elemcount len = shortest_length_among_sequences (nargs - 1, args + 1);
+
+  mapcarX (len, NULL, result_ptr, args[0], nargs - 1, args +1, Qevery);
+
+  return result;
 }
 
 /* Call FUNCTION with NLISTS arguments repeatedly, each Nth argument
    corresponding to the result of calling (nthcdr ITERATION-COUNT LISTS[N]),
    until that #'nthcdr expression gives nil for some element of LISTS.
 
-   If MAPLP is zero, return LISTS[0]. Otherwise, return a list of the return
-   values from FUNCTION; if NCONCP is non-zero, nconc them together.
+   CALLER is a symbol reflecting the Lisp-visible function that was called,
+   and any errors thrown because SEQUENCES was modified will reflect it.
+
+   If CALLER is Qmapl, return LISTS[0]. Otherwise, return a list of the
+   return values from FUNCTION; if caller is Qmapcan, nconc them together.
 
    In contrast to mapcarX, we don't require our callers to check LISTS for
    well-formedness, we signal wrong-type-argument if it's not a list, or
    circular-list if it's circular. */
 
 static Lisp_Object
-maplist (Lisp_Object function, int nlists, Lisp_Object *lists, int maplp,
-	 int nconcp)
-{
-  Lisp_Object result = maplp ? lists[0] : Fcons (Qnil, Qnil), funcalled;
-  Lisp_Object nconcing[2], accum = result, *args;
-  struct gcpro gcpro1, gcpro2, gcpro3;
+maplist (Lisp_Object function, int nlists, Lisp_Object *lists,
+         Lisp_Object caller)
+{
+  Lisp_Object nconcing[2], accum = Qnil, *args, *tortoises, funcalled;
+  Lisp_Object result = EQ (caller, Qmapl) ? lists[0] : Qnil;
+  struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
   int i, j, continuing = (nlists > 0), called_count = 0;
 
   args = alloca_array (Lisp_Object, nlists + 1);
@@ -4734,18 +4891,23 @@
       args[i] = Qnil;
     }
 
-  if (nconcp)
-    {
-      nconcing[0] = result;
+  tortoises = alloca_array (Lisp_Object, nlists);
+  memcpy (tortoises, lists, nlists * sizeof (Lisp_Object));
+
+  if (EQ (caller, Qmapcon))
+    {
+      nconcing[0] = Qnil;
       nconcing[1] = Qnil;
-      GCPRO3 (args[0], nconcing[0], result);
+      GCPRO4 (args[0], nconcing[0], tortoises[0], result);
       gcpro1.nvars = 1;
       gcpro2.nvars = 2;
+      gcpro3.nvars = nlists;
     }
   else
     {
-      GCPRO2 (args[0], result);
+      GCPRO3 (args[0], tortoises[0], result);
       gcpro1.nvars = 1;
+      gcpro2.nvars = nlists;
     }
 
   while (continuing)
@@ -4764,45 +4926,64 @@
 	    }
 	  else
 	    {
-	      dead_wrong_type_argument (Qlistp, lists[j]);
+	      lists[j] = wrong_type_argument (Qlistp, lists[j]);
 	    }
 	}
       if (!continuing) break;
       funcalled = IGNORE_MULTIPLE_VALUES (Ffuncall (nlists + 1, args));
-      if (!maplp)
+
+      if (EQ (caller, Qmapl))
 	{
-	  if (nconcp)
-	    {
-	      /* This order of calls means we check that each list is
-		 well-formed once and once only. The last result does
-		 not have to be a list. */
-	      nconcing[1] = funcalled;
-	      nconcing[0] = bytecode_nconc2 (nconcing);
-	    }
-	  else
-	    {
-	      /* Add to the end, avoiding the need to call nreverse
-		 once we're done: */
-	      XSETCDR (accum, Fcons (funcalled, Qnil));
-	      accum = XCDR (accum);
-	    }
+          DO_NOTHING;
+        }
+      else if (EQ (caller, Qmapcon))
+        {
+          nconcing[1] = funcalled;
+          accum = bytecode_nconc2 (nconcing);
+          if (NILP (result))
+            {
+              result = accum;
+            }
+          /* Only check a given stretch of result for well-formedness
+             once: */
+          nconcing[0] = funcalled;
+        }
+      else if (NILP (accum))
+        {
+          accum = result = Fcons (funcalled, Qnil);
+        }
+      else
+        {
+          /* Add to the end, avoiding the need to call nreverse
+             once we're done: */
+          XSETCDR (accum, Fcons (funcalled, Qnil));
+          accum = XCDR (accum);
 	}
 
-      if (++called_count % CIRCULAR_LIST_SUSPICION_LENGTH) continue;
-
-      for (j = 0; j < nlists; ++j)
-	{
-	  EXTERNAL_LIST_LOOP_1 (lists[j])
-	    {
-	      /* Just check the lists aren't circular, using the
-		 EXTERNAL_LIST_LOOP_1 macro. */
-	    }
-	}
-    }
-
-  if (!maplp)
-    {
-      result = XCDR (result);
+      if (++called_count > CIRCULAR_LIST_SUSPICION_LENGTH)
+        {
+          if (called_count & 1)
+            {
+              for (j = 0; j < nlists; ++j)
+                {
+                  tortoises[j] = XCDR (tortoises[j]);
+                  if (EQ (lists[j], tortoises[j]))
+                    {
+                      signal_circular_list_error (lists[j]);
+                    }
+                }
+            }
+          else
+            {
+              for (j = 0; j < nlists; ++j)
+                {
+                  if (EQ (lists[j], tortoises[j]))
+                    {
+                      signal_circular_list_error (lists[j]);
+                    }
+                }
+            }
+        }
     }
 
   RETURN_UNGCPRO (result);
@@ -4817,7 +4998,7 @@
 */
        (int nargs, Lisp_Object *args))
 {
-  return maplist (args[0], nargs - 1, args + 1, 0, 0);
+  return maplist (args[0], nargs - 1, args + 1, Qmaplist);
 }
 
 DEFUN ("mapl", Fmapl, 2, MANY, 0, /*
@@ -4827,7 +5008,7 @@
 */
        (int nargs, Lisp_Object *args))
 {
-  return maplist (args[0], nargs - 1, args + 1, 1, 0);
+  return maplist (args[0], nargs - 1, args + 1, Qmapl);
 }
 
 DEFUN ("mapcon", Fmapcon, 2, MANY, 0, /*
@@ -4840,7 +5021,7 @@
 */
        (int nargs, Lisp_Object *args))
 {
-  return maplist (args[0], nargs - 1, args + 1, 0, 1);
+  return maplist (args[0], nargs - 1, args + 1, Qmapcon);
 }
 
 /* Extra random functions */
@@ -4870,16 +5051,19 @@
   Lisp_Object function = args[0], sequence = args[1], accum = Qunbound;
   Elemcount starting, ending = EMACS_INT_MAX, ii = 0;
 
-  PARSE_KEYWORDS (Qreduce, nargs, args, 2, 5,
+  PARSE_KEYWORDS (Freduce, nargs, args, 5,
                   (start, end, from_end, initial_value, key),
-                  (start = Qzero, initial_value = Qunbound), 0);
+                  (start = Qzero, initial_value = Qunbound));
 
   CHECK_SEQUENCE (sequence);
   CHECK_NATNUM (start);
 
   CHECK_KEY_ARGUMENT (key);
 
-#define KEY(key, item) (EQ (key, Qidentity) ? item : call1 (key, item))
+#define KEY(key, item) (EQ (Qidentity, key) ? item :			\
+			IGNORE_MULTIPLE_VALUES (call1 (key, item)))
+#define CALL2(function, accum, item)				\
+  IGNORE_MULTIPLE_VALUES (call2 (function, accum, item))
 
   starting = XINT (start);
   if (!NILP (end))
@@ -4888,16 +5072,24 @@
       ending = XINT (end);
     }
 
+  if (!(starting <= ending))
+    {
+      check_sequence_range (sequence, start, end, Flength (sequence));
+    }
+
   if (VECTORP (sequence))
     {
       Lisp_Vector *vv = XVECTOR (sequence);
+
+      check_sequence_range (sequence, start, end, make_int (vv->size));
+
       ending = min (ending, vv->size);
 
       if (!UNBOUNDP (initial_value))
         {
           accum = initial_value;
         }
-      else if (ending - starting && starting < ending)
+      else if (ending - starting)
         {
           if (NILP (from_end))
             {
@@ -4915,14 +5107,14 @@
         {
           for (ii = starting; ii < ending; ++ii)
             {
-              accum = call2 (function, accum, KEY (key, vv->contents[ii]));
+              accum = CALL2 (function, accum, KEY (key, vv->contents[ii]));
             }
         }
       else
         {
           for (ii = ending - 1; ii >= starting; --ii)
             {
-              accum = call2 (function, KEY (key, vv->contents[ii]), accum);
+              accum = CALL2 (function, KEY (key, vv->contents[ii]), accum);
             }
         }
     }
@@ -4930,13 +5122,15 @@
     {
       Lisp_Bit_Vector *bv = XBIT_VECTOR (sequence);
 
+      check_sequence_range (sequence, start, end, make_int (bv->size));
+
       ending = min (ending, bv->size);
 
       if (!UNBOUNDP (initial_value))
         {
           accum = initial_value;
         }
-      else if (ending - starting && starting < ending)
+      else if (ending - starting)
         {
           if (NILP (from_end))
             {
@@ -4954,7 +5148,7 @@
         {
           for (ii = starting; ii < ending; ++ii)
             {
-              accum = call2 (function, accum,
+              accum = CALL2 (function, accum,
                              KEY (key, make_int (bit_vector_bit (bv, ii))));
             }
         }
@@ -4962,13 +5156,12 @@
         {
           for (ii = ending - 1; ii >= starting; --ii)
             {
-              accum = call2 (function, KEY (key,
+              accum = CALL2 (function, KEY (key,
                                             make_int (bit_vector_bit (bv,
                                                                       ii))),
                              accum);
             }
         }
-
     }
   else if (STRINGP (sequence))
     {
@@ -4989,38 +5182,56 @@
             {
               accum = initial_value;
             }
-          else if (ending - starting && starting < ending)
+          else if (ending - starting)
             {
               accum = KEY (key, make_char (itext_ichar (cursor)));
               starting++;
               startp = XSTRING_DATA (sequence);
               cursor = startp + cursor_offset;
+
+              if (byte_len != XSTRING_LENGTH (sequence)
+                  || !valid_ibyteptr_p (cursor))
+                {
+                  mapping_interaction_error (Qreduce, sequence);
+                }
+
               INC_IBYTEPTR (cursor);
               cursor_offset = cursor - startp;
             }
 
-          while (cursor_offset < byte_len && starting < ending)
+          while (cursor_offset < byte_len && ii < ending)
             {
-              if (cursor_offset > XSTRING_LENGTH (sequence))
+              accum = CALL2 (function, accum, 
+                             KEY (key, make_char (itext_ichar (cursor))));
+
+	      startp = XSTRING_DATA (sequence);
+	      cursor = startp + cursor_offset;
+
+              if (byte_len != XSTRING_LENGTH (sequence)
+                  || !valid_ibyteptr_p (cursor))
                 {
-                  invalid_state ("sequence modified during reduce", sequence);
+                  mapping_interaction_error (Qreduce, sequence);
                 }
 
-              startp = XSTRING_DATA (sequence);
-              cursor = startp + cursor_offset;
-              accum = call2 (function, accum,
-                             KEY (key, make_char (itext_ichar (cursor))));
               INC_IBYTEPTR (cursor);
               cursor_offset = cursor - startp;
-              ++starting;
+              ++ii;
             }
+
+	  if (ii < starting || (ii < ending && !NILP (end)))
+	    {
+	      check_sequence_range (sequence, start, end, Flength (sequence));
+	      ABORT ();
+	    }
         }
       else
         {
           Elemcount len = string_char_length (sequence);
-          Bytecount cursor_offset;
+          Bytecount cursor_offset, byte_len = XSTRING_LENGTH (sequence);
           const Ibyte *cursor;
 
+	  check_sequence_range (sequence, start, end, make_int (len));
+
           ending = min (ending, len);
           cursor = string_char_addr (sequence, ending - 1);
           cursor_offset = cursor - XSTRING_DATA (sequence);
@@ -5029,12 +5240,19 @@
             {
               accum = initial_value;
             }
-          else if (ending - starting && starting < ending)
+          else if (ending - starting)
             {
               accum = KEY (key, make_char (itext_ichar (cursor)));
               ending--;
               if (ending > 0)
                 {
+		  cursor = XSTRING_DATA (sequence) + cursor_offset;
+
+                  if (!valid_ibyteptr_p (cursor))
+                    {
+                      mapping_interaction_error (Qreduce, sequence);
+                    }
+
                   DEC_IBYTEPTR (cursor);
                   cursor_offset = cursor - XSTRING_DATA (sequence);
                 }
@@ -5042,18 +5260,19 @@
 
           for (ii = ending - 1; ii >= starting; --ii)
             {
-              if (cursor_offset > XSTRING_LENGTH (sequence))
-                {
-                  invalid_state ("sequence modified during reduce", sequence);
-                }
-
-              cursor = XSTRING_DATA (sequence) + cursor_offset;
-              accum = call2 (function, KEY (key,
+              accum = CALL2 (function, KEY (key,
                                             make_char (itext_ichar (cursor))),
                              accum);
-              if (ii > 1)
+              if (ii > 0)
                 {
                   cursor = XSTRING_DATA (sequence) + cursor_offset;
+
+                  if (byte_len != XSTRING_LENGTH (sequence)
+                      || !valid_ibyteptr_p (cursor))
+                    {
+                      mapping_interaction_error (Qreduce, sequence);
+                    }
+
                   DEC_IBYTEPTR (cursor);
                   cursor_offset = cursor - XSTRING_DATA (sequence);
                 }
@@ -5064,45 +5283,64 @@
     {
       if (NILP (from_end))
         {
+	  struct gcpro gcpro1;
+	  Lisp_Object tailed = Qnil;
+
+	  GCPRO1 (tailed);
+
           if (!UNBOUNDP (initial_value))
             {
               accum = initial_value;
             }
-          else if (ending - starting && starting < ending)
+          else if (ending - starting)
             {
-              Elemcount counting = 0;
               EXTERNAL_LIST_LOOP_3 (elt, sequence, tail)
                 {
-                  if (counting == starting)
+		  /* KEY may amputate the list behind us; make sure what
+		     remains to be processed is still reachable.  */
+		  tailed = tail;
+                  if (ii == starting)
                     {
                       accum = KEY (key, elt);
                       starting++;
                       break;
                     }
-                  ++counting;
+                  ++ii;
                 }
             }
 
-          if (ending - starting && starting < ending)
+	  ii = 0;
+
+          if (ending - starting)
             {
-              Elemcount counting = 0;
-
               EXTERNAL_LIST_LOOP_3 (elt, sequence, tail)
                 {
-                  if (counting >= starting)
+		  /* KEY or FUNCTION may amputate the list behind us; make
+		     sure what remains to be processed is still
+		     reachable.  */
+		  tailed = tail;
+                  if (ii >= starting)
                     {
-                      if (counting < ending)
+                      if (ii < ending)
                         {
-                          accum = call2 (function, accum, KEY (key, elt));
+                          accum = CALL2 (function, accum, KEY (key, elt));
                         }
-                      else if (counting == ending)
+                      else if (ii == ending)
                         {
                           break;
                         }
                     }
-                  ++counting;
+                  ++ii;
                 }
             }
+
+	  UNGCPRO;
+
+	  if (ii < starting || (ii < ending && !NILP (end)))
+	    {
+	      check_sequence_range (sequence, start, end, Flength (sequence));
+	      ABORT ();
+	    }
         }
       else
         {
@@ -5111,10 +5349,9 @@
           Elemcount counting = 0, len = 0;
 	  struct gcpro gcpro1;
 
-          if (ending - starting && starting < ending && EMACS_INT_MAX == ending)
-            {
-              ending = XINT (Flength (sequence));
-            }
+	  len = XINT (Flength (sequence));
+	  check_sequence_range (sequence, start, end, make_int (len));
+	  ending = min (ending, len);
 
           /* :from-end with a list; make an alloca copy of the relevant list
              data, attempting to go backwards isn't worth the trouble. */
@@ -5171,7 +5408,7 @@
           for (ii = len; ii != 0;)
             {
               --ii;
-              accum = call2 (function, KEY (key, subsequence[ii]), accum);
+              accum = CALL2 (function, KEY (key, subsequence[ii]), accum);
             }
 
 	  if (subsequence != NULL)
@@ -5186,7 +5423,7 @@
      arguments. */
   if (UNBOUNDP (accum))
     {
-      accum = call0 (function);
+      accum = IGNORE_MULTIPLE_VALUES (call0 (function));
     }
 
   return accum;
@@ -5232,6 +5469,588 @@
   return old;
 }
 
+/* This function is the implementation of fill_string_range() and
+   replace_string_range(); see the comments for those functions. */
+static Lisp_Object
+replace_string_range_1 (Lisp_Object dest, Lisp_Object start, Lisp_Object end,
+			const Ibyte *source, const Ibyte *source_limit,
+			Lisp_Object item)
+{
+  Ibyte *destp = XSTRING_DATA (dest), *p = destp,
+    *pend = p + XSTRING_LENGTH (dest), *pcursor, item_buf[MAX_ICHAR_LEN];
+  Bytecount prefix_bytecount, source_len = source_limit - source;
+  Charcount ii = 0, starting = XINT (start), ending, len;
+  Elemcount delta;
+
+  while (ii < starting && p < pend)
+    {
+      INC_IBYTEPTR (p);
+      ii++;
+    }
+
+  pcursor = p;
+
+  if (NILP (end))
+    {
+      while (pcursor < pend)
+	{
+	  INC_IBYTEPTR (pcursor);
+	  ii++;
+	}
+
+      ending = len = ii;
+    }
+  else
+    {
+      ending = XINT (end);
+      while (ii < ending && pcursor < pend)
+	{
+	  INC_IBYTEPTR (pcursor);
+	  ii++;
+	}
+    }
+
+  if (pcursor == pend)
+    {
+      /* We have the length, check it for our callers. */
+      check_sequence_range (dest, start, end, make_int (ii));
+    }
+
+  if (!(p == pend || p == pcursor))
+    {
+      prefix_bytecount = p - destp;
+
+      if (!NILP (item))
+	{
+	  assert (source == NULL && source_limit == NULL);
+	  source_len = set_itext_ichar (item_buf, XCHAR (item));
+	  delta = (source_len * (ending - starting)) - (pcursor - p);
+	}
+      else
+	{
+	  assert (source != NULL && source_limit != NULL);
+	  delta = source_len - (pcursor - p);
+	}
+
+      if (delta)
+        {
+          resize_string (dest, prefix_bytecount, delta);
+          destp = XSTRING_DATA (dest);
+          pcursor = destp + prefix_bytecount + (pcursor - p);
+          p = destp + prefix_bytecount;
+        }
+
+      if (CHARP (item))
+	{
+	  while (starting < ending)
+	    {
+	      memcpy (p, item_buf, source_len);
+	      p += source_len;
+	      starting++;
+	    }
+	}
+      else
+	{
+	  while (starting < ending && source < source_limit)
+	    {
+	      source_len = itext_copy_ichar (source, p);
+	      p += source_len, source += source_len;
+	    }
+	}
+
+      init_string_ascii_begin (dest);
+      bump_string_modiff (dest);
+      sledgehammer_check_ascii_begin (dest);
+    }
+
+  return dest;
+}
+
+DEFUN ("replace", Freplace, 2, MANY, 0, /*
+Replace the elements of SEQUENCE-ONE with the elements of SEQUENCE-TWO.
+
+SEQUENCE-ONE is destructively modified, and returned.  Its length is not
+changed.
+
+Keywords :start1 and :end1 specify a subsequence of SEQUENCE-ONE, and
+:start2 and :end2 a subsequence of SEQUENCE-TWO.  See `search' for more
+information.
+
+arguments: (SEQUENCE-ONE SEQUENCE-TWO &key (START1 0) (END1 (length SEQUENCE-ONE)) (START2 0) (END2 (length SEQUENCE-TWO)))
+*/
+       (int nargs, Lisp_Object *args))
+{
+  Lisp_Object sequence1 = args[0], sequence2 = args[1],
+    result = sequence1;
+  Elemcount starting1, ending1 = EMACS_INT_MAX, starting2;
+  Elemcount ending2 = EMACS_INT_MAX, counting = 0, startcounting;
+  Boolint sequence1_listp, sequence2_listp,
+    overwriting = EQ (sequence1, sequence2);
+
+  PARSE_KEYWORDS (Freplace, nargs, args, 4, (start1, end1, start2, end2),
+                  (start1 = start2 = Qzero));
+
+  CHECK_SEQUENCE (sequence1);
+  CHECK_LISP_WRITEABLE (sequence1);
+
+  CHECK_SEQUENCE (sequence2);
+
+  CHECK_NATNUM (start1);
+  starting1 = XINT (start1);
+  CHECK_NATNUM (start2);
+  starting2 = XINT (start2);
+
+  if (!NILP (end1))
+    {
+      CHECK_NATNUM (end1);
+      ending1 = XINT (end1);
+
+      if (!(starting1 <= ending1))
+        {
+          args_out_of_range_3 (sequence1, start1, end1);
+        }
+    }
+
+  if (!NILP (end2))
+    {
+      CHECK_NATNUM (end2);
+      ending2 = XINT (end2);
+
+      if (!(starting2 <= ending2))
+        {
+          args_out_of_range_3 (sequence1, start2, end2);
+        }
+    }
+
+  sequence1_listp = LISTP (sequence1);
+  sequence2_listp = LISTP (sequence2);
+
+  overwriting = overwriting && starting2 <= starting1;
+
+  if (sequence1_listp && !ZEROP (start1))
+    {
+      sequence1 = Fnthcdr (start1, sequence1);
+
+      if (NILP (sequence1))
+        {
+          check_sequence_range (args[0], start1, end1, Flength (args[0]));
+          /* Give up early here. */
+          return result;
+        }
+
+      ending1 -= starting1;
+      starting1 = 0;
+    }
+
+  if (sequence2_listp && !ZEROP (start2))
+    {
+      sequence2 = Fnthcdr (start2, sequence2);
+
+      if (NILP (sequence2))
+        {
+          check_sequence_range (args[1], start1, end1, Flength (args[1]));
+          /* Nothing available to replace sequence1's contents. */
+          return result;
+        }
+
+      ending2 -= starting2;
+      starting2 = 0;
+    }
+
+  if (overwriting)
+    {
+      if (EQ (start1, start2))
+        {
+          return result;
+        }
+
+      /* Our ranges may overlap. Save the data that might be overwritten. */
+
+      if (CONSP (sequence2))
+        {
+          Elemcount len = XINT (Flength (sequence2));
+          Lisp_Object *subsequence
+            = alloca_array (Lisp_Object, min (ending2, len));
+          Elemcount ii = 0;
+
+          LIST_LOOP_2 (elt, sequence2)
+            {
+              if (counting == ending2)
+                {
+                  break;
+                }
+
+              subsequence[ii++] = elt;
+              counting++;
+            }
+
+          check_sequence_range (sequence1, start1, end1,
+                                /* The XINT (start2) is intentional here; we
+                                   called #'length after doing (nthcdr
+                                   start2 sequence2). */
+                                make_int (XINT (start2) + len));
+          check_sequence_range (sequence2, start2, end2,
+                                make_int (XINT (start2) + len));
+
+          while (starting1 < ending1
+                 && starting2 < ending2 && !NILP (sequence1))
+            {
+              XSETCAR (sequence1, subsequence[starting2]);
+              sequence1 = XCDR (sequence1);
+              starting1++;
+              starting2++;
+            }
+        }
+      else if (STRINGP (sequence2))
+        {
+          Ibyte *p = XSTRING_DATA (sequence2),
+            *pend = p + XSTRING_LENGTH (sequence2), *pcursor,
+            *staging;
+          Bytecount ii = 0;
+
+          while (ii < starting2 && p < pend)
+            {
+              INC_IBYTEPTR (p);
+              ii++;
+            }
+
+          pcursor = p;
+
+          while (ii < ending2 && starting1 < ending1 && pcursor < pend)
+            {
+              INC_IBYTEPTR (pcursor);
+              starting1++;
+              ii++;
+            }
+
+          if (pcursor == pend)
+            {
+              check_sequence_range (sequence1, start1, end1, make_int (ii));
+              check_sequence_range (sequence2, start2, end2, make_int (ii));
+            }
+          else
+            {
+              assert ((pcursor - p) > 0);
+              staging = alloca_ibytes (pcursor - p);
+              memcpy (staging, p, pcursor - p);
+              replace_string_range (result, start1,
+                                    make_int (starting1),
+                                    staging, staging + (pcursor - p));
+            }
+        }
+      else 
+        {
+          Elemcount seq_len = XINT (Flength (sequence2)), ii = 0,
+            subseq_len = min (min (ending1 - starting1, seq_len - starting1),
+                              min (ending2 - starting2, seq_len - starting2));
+          Lisp_Object *subsequence = alloca_array (Lisp_Object, subseq_len);
+
+          check_sequence_range (sequence1, start1, end1, make_int (seq_len));
+          check_sequence_range (sequence2, start2, end2, make_int (seq_len));
+
+          while (starting2 < ending2 && ii < seq_len)
+            {
+              subsequence[ii] = Faref (sequence2, make_int (starting2));
+              ii++, starting2++;
+            }
+
+          ii = 0;
+
+          while (starting1 < ending1 && ii < seq_len)
+            {
+              Faset (sequence1, make_int (starting1), subsequence[ii]);
+              ii++, starting1++;
+            }
+        }
+    }
+  else if (sequence1_listp && sequence2_listp)
+    {
+      Lisp_Object sequence1_tortoise = sequence1,
+        sequence2_tortoise = sequence2;
+      Elemcount shortest_len = 0;
+
+      counting = startcounting = min (ending1, ending2);
+
+      while (counting-- > 0 && !NILP (sequence1) && !NILP (sequence2))
+        {
+          XSETCAR (sequence1,
+                   CONSP (sequence2) ? XCAR (sequence2)
+                   : Fcar (sequence2));
+          sequence1 = CONSP (sequence1) ? XCDR (sequence1)
+            : Fcdr (sequence1);
+          sequence2 = CONSP (sequence2) ? XCDR (sequence2)
+            : Fcdr (sequence2);
+
+          shortest_len++;
+
+          if (startcounting - counting > CIRCULAR_LIST_SUSPICION_LENGTH)
+            {
+              if (counting & 1)
+                {
+                  sequence1_tortoise = XCDR (sequence1_tortoise);
+                  sequence2_tortoise = XCDR (sequence2_tortoise);
+                }
+
+              if (EQ (sequence1, sequence1_tortoise))
+                {
+                  signal_circular_list_error (sequence1);
+                }
+
+              if (EQ (sequence2, sequence2_tortoise))
+                {
+                  signal_circular_list_error (sequence2);
+                }
+            }
+        }
+
+      if (NILP (sequence1))
+        {
+          check_sequence_range (sequence1, start1, end1,
+                                make_int (XINT (start1) + shortest_len));
+        }
+      else if (NILP (sequence2))
+        {
+          check_sequence_range (sequence2, start2, end2,
+                                make_int (XINT (start2) + shortest_len));
+        }
+    }
+  else if (sequence1_listp)
+    {
+      if (STRINGP (sequence2))
+        {
+          Ibyte *s2_data = XSTRING_DATA (sequence2),
+            *s2_end = s2_data + XSTRING_LENGTH (sequence2);
+          Elemcount char_count = 0;
+          Lisp_Object character;
+
+          while (char_count < starting2 && s2_data < s2_end)
+            {
+              INC_IBYTEPTR (s2_data);
+              char_count++;
+            }
+
+          while (starting1 < ending1 && starting2 < ending2
+                 && s2_data < s2_end && !NILP (sequence1))
+            {
+              character = make_char (itext_ichar (s2_data));
+              CONSP (sequence1) ?
+                XSETCAR (sequence1, character)
+                : Fsetcar (sequence1, character);
+              sequence1 = XCDR (sequence1);
+              starting1++;
+              starting2++;
+              char_count++;
+              INC_IBYTEPTR (s2_data);
+            }
+
+          if (NILP (sequence1))
+            {
+              check_sequence_range (sequence1, start1, end1,
+                                    make_int (XINT (start1) + starting1));
+            }
+
+          if (s2_data == s2_end)
+            {
+              check_sequence_range (sequence2, start2, end2,
+                                    make_int (char_count));
+            }
+        }
+      else
+        {
+          Elemcount len2 = XINT (Flength (sequence2));
+          check_sequence_range (sequence2, start2, end2, make_int (len2));
+
+          ending2 = min (ending2, len2);
+          while (starting2 < ending2
+                 && starting1 < ending1 && !NILP (sequence1))
+            {
+              CHECK_CONS (sequence1);
+              XSETCAR (sequence1, Faref (sequence2, make_int (starting2)));
+              sequence1 = XCDR (sequence1);
+              starting1++;
+              starting2++;
+            }
+
+          if (NILP (sequence1))
+            {
+              check_sequence_range (sequence1, start1, end1,
+                                    make_int (XINT (start1) + starting1));
+            }
+        }
+    }
+  else if (sequence2_listp)
+    {
+      if (STRINGP (sequence1))
+        {
+          Elemcount ii = 0, count, len = string_char_length (sequence1);
+          Ibyte *staging, *cursor;
+          Lisp_Object obj;
+
+          check_sequence_range (sequence1, start1, end1, make_int (len));
+          ending1 = min (ending1, len);
+          count = ending1 - starting1;
+          staging = cursor = alloca_ibytes (count * MAX_ICHAR_LEN);
+
+          while (ii < count && !NILP (sequence2))
+            {
+              obj = CONSP (sequence2) ? XCAR (sequence2)
+                : Fcar (sequence2);
+
+              CHECK_CHAR_COERCE_INT (obj);
+              cursor += set_itext_ichar (cursor, XCHAR (obj));
+              ii++;
+              sequence2 = XCDR (sequence2);
+            }
+
+          if (NILP (sequence2))
+            {
+              check_sequence_range (sequence2, start2, end2,
+                                    make_int (XINT (start2) + ii));
+            }
+
+          replace_string_range (result, start1, make_int (XINT (start1) + ii),
+                                staging, cursor);
+        }
+      else
+        {
+          Elemcount len = XINT (Flength (sequence1));
+
+          check_sequence_range (sequence1, start2, end1, make_int (len));
+          ending1 = min (ending2, min (ending1, len));
+
+          while (starting1 < ending1 && !NILP (sequence2))
+            {
+              Faset (sequence1, make_int (starting1),
+                     CONSP (sequence2) ? XCAR (sequence2)
+                     : Fcar (sequence2));
+              sequence2 = XCDR (sequence2);
+              starting1++;
+              starting2++;
+            }
+
+          if (NILP (sequence2))
+            {
+              check_sequence_range (sequence2, start2, end2,
+                                    make_int (XINT (start2) + starting2));
+            }
+        }
+    }
+  else
+    {
+      if (STRINGP (sequence1) && STRINGP (sequence2))
+        {
+          Ibyte *p2 = XSTRING_DATA (sequence2),
+            *p2end = p2 + XSTRING_LENGTH (sequence2), *p2cursor;
+          Charcount ii = 0, len1 = string_char_length (sequence1);
+
+          while (ii < starting2 && p2 < p2end)
+            {
+              INC_IBYTEPTR (p2);
+              ii++;
+            }
+
+          p2cursor = p2;
+          ending1 = min (ending1, len1);
+
+          while (ii < ending2 && starting1 < ending1 && p2cursor < p2end)
+            {
+              INC_IBYTEPTR (p2cursor);
+              ii++;
+              starting1++;
+            }
+
+          if (p2cursor == p2end)
+            {
+              check_sequence_range (sequence2, start2, end2, make_int (ii));
+            }
+
+          /* This isn't great; any error message won't necessarily reflect
+             the END1 that was supplied to #'replace. */
+          replace_string_range (result, start1, make_int (starting1),
+                                p2, p2cursor);
+        }
+      else if (STRINGP (sequence1))
+        {
+          Ibyte *staging, *cursor;
+          Elemcount count, len1 = string_char_length (sequence1);
+          Elemcount len2 = XINT (Flength (sequence2)), ii = 0;
+          Lisp_Object obj;
+
+          check_sequence_range (sequence1, start1, end1, make_int (len1));
+          check_sequence_range (sequence2, start2, end2, make_int (len2));
+
+          ending1 = min (ending1, len1);
+          ending2 = min (ending2, len2);
+          count = min (ending1 - starting1, ending2 - starting2);
+          staging = cursor = alloca_ibytes (count * MAX_ICHAR_LEN);
+
+          ii = 0;
+          while (ii < count)
+            {
+              obj = Faref (sequence2, make_int (starting2));
+
+              CHECK_CHAR_COERCE_INT (obj);
+              cursor += set_itext_ichar (cursor, XCHAR (obj));
+              starting2++, ii++;
+            }
+
+          replace_string_range (result, start1,
+                                make_int (XINT (start1) + count),
+                                staging, cursor);
+        }
+      else if (STRINGP (sequence2))
+        {
+          Ibyte *p2 = XSTRING_DATA (sequence2),
+            *p2end = p2 + XSTRING_LENGTH (sequence2);
+          Elemcount len1 = XINT (Flength (sequence1)), ii = 0;
+
+          check_sequence_range (sequence1, start1, end1, make_int (len1));
+          ending1 = min (ending1, len1);
+
+          while (ii < starting2 && p2 < p2end)
+            {
+              INC_IBYTEPTR (p2);
+              ii++;
+            }
+
+          while (p2 < p2end && starting1 < ending1 && starting2 < ending2)
+            {
+              Faset (sequence1, make_int (starting1),
+                     make_char (itext_ichar (p2)));
+              INC_IBYTEPTR (p2);
+              starting1++;
+              starting2++;
+              ii++;
+            }
+
+          if (p2 == p2end)
+            {
+              check_sequence_range (sequence2, start2, end2, make_int (ii));
+            }
+        }
+      else
+        {
+          Elemcount len1 = XINT (Flength (sequence1)),
+            len2 = XINT (Flength (sequence2));
+
+          check_sequence_range (sequence1, start1, end1, make_int (len1));
+          check_sequence_range (sequence2, start2, end2, make_int (len2));
+
+          ending1 = min (ending1, len1);
+          ending2 = min (ending2, len2);
+          
+          while (starting1 < ending1 && starting2 < ending2)
+            {
+              Faset (sequence1, make_int (starting1),
+                     Faref (sequence2, make_int (starting2)));
+              starting1++;
+              starting2++;
+            }
+        }
+    }
+
+  return result;
+}
 
 Lisp_Object
 add_suffix_to_symbol (Lisp_Object symbol, const Ascbyte *ascii_string)
@@ -5877,9 +6696,27 @@
   DEFSYMBOL (Qbit_vector);
   defsymbol (&QsortX, "sort*");
   DEFSYMBOL (Qreduce);
+  DEFSYMBOL (Qreplace);
+
+  DEFSYMBOL (Qmapconcat);
+  defsymbol (&QmapcarX, "mapcar*");
+  DEFSYMBOL (Qmapvector);
+  DEFSYMBOL (Qmapcan);
+  DEFSYMBOL (Qmapc);
+  DEFSYMBOL (Qmap);
+  DEFSYMBOL (Qmap_into);
+  DEFSYMBOL (Qsome);
+  DEFSYMBOL (Qevery);
+  DEFSYMBOL (Qmaplist);
+  DEFSYMBOL (Qmapl);
+  DEFSYMBOL (Qmapcon);
 
   DEFKEYWORD (Q_from_end);
   DEFKEYWORD (Q_initial_value);
+  DEFKEYWORD (Q_start1);
+  DEFKEYWORD (Q_start2);
+  DEFKEYWORD (Q_end1);
+  DEFKEYWORD (Q_end2);
 
   DEFSYMBOL (Qyes_or_no_p);
 
@@ -5889,6 +6726,7 @@
   DEFSUBR (Frandom);
   DEFSUBR (Flength);
   DEFSUBR (Fsafe_length);
+  DEFSUBR (Flist_length);
   DEFSUBR (Fstring_equal);
   DEFSUBR (Fcompare_strings);
   DEFSUBR (Fstring_lessp);
@@ -5954,6 +6792,7 @@
   DEFSUBR (Fput);
   DEFSUBR (Fremprop);
   DEFSUBR (Fobject_plist);
+  DEFSUBR (Fobject_setplist);
   DEFSUBR (Fequal);
   DEFSUBR (Fequalp);
   DEFSUBR (Fold_equal);
@@ -5978,6 +6817,7 @@
 
   DEFSUBR (Freduce);
   DEFSUBR (Freplace_list);
+  DEFSUBR (Freplace);
   DEFSUBR (Fload_average);
   DEFSUBR (Ffeaturep);
   DEFSUBR (Frequire);
--- a/src/fontcolor-msw.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/fontcolor-msw.c	Mon Oct 18 23:21:23 2010 +0900
@@ -1022,10 +1022,10 @@
         }
       *c = '\0';
       
-      if ((res = bsearch (&key, mswindows_X_color_map,
-                          countof (mswindows_X_color_map),
-                          sizeof (mswindows_X_color_map[0]),
-                          colormap_t_compare)) != NULL)
+      if ((res = (colormap_t *) bsearch (&key, mswindows_X_color_map,
+                                         countof (mswindows_X_color_map),
+                                         sizeof (mswindows_X_color_map[0]),
+                                         colormap_t_compare)) != NULL)
         {
           return res->colorref;
         }
--- a/src/gc.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/gc.c	Mon Oct 18 23:21:23 2010 +0900
@@ -21,6 +21,318 @@
 
 /* Synched up with: Not in FSF. */
 
+/* 
+   Garbage Collectors in XEmacs
+
+   Currently, XEmacs comes with two garbage collectors:
+
+   - The "old garbage collector": a simple mark and sweep collector,
+     its implementation is mainly spread out over gc.c and alloc.c.
+     It is used by the default configuration or if you configure
+     `--with-newgc=no'.
+
+   - The "new garbage collector": an incremental mark and sweep collector,
+     its implementation is in gc.c.  It is used if you configure
+     `--with-newgc'.  It comes with a new allocator, see mc-alloc.c, and
+     with the KKCC mark algorith, see below.
+
+   Additionally, the old garbage collectors comes with two mark algorithms:
+
+   - The "recursive mark algorithm" marks live objects by recursively
+     calling mark_* functions on live objects.  It is the default mark 
+     algorithm of the old garbage collector.
+
+   - The "KKCC mark algorithm" uses an explicit stack that to keep
+     track of the current progress of traversal and uses memory layout
+     descriptions (that are also used by the portable dumper) instead
+     of the mark_* functions.  The old garbage collector uses it if
+     you configure `--with-kkcc'.  It is the default and only mark
+     algorithm of the new garbage collector.
+
+
+   The New Incremental Garbage Collector
+
+   An incremental garbage collector keeps garbage collection pause
+   times short by interleaving small amounts of collection work with
+   program execution, it does that by instrumenting write barrier
+   algorithms that essentially allow interrupting the mark phase.
+
+
+   Write Barrier
+
+   A write barrier is the most important prerequisite for fancy
+   garbage collection techniques.  We implement a "Virtual Dirty Bit
+   (short: vdb) Write Barrier" that makes uses of the operating
+   system's memory-protection mechanisms: The write barrier
+   write-protects memory pages containing heap objects.  If the
+   mutator tries to modify these objects by writing into the
+   write-protected page, the operating system generates a fault.  The
+   write barrier catches this fault, reads out the error-causing
+   address and can thus identify the updated object and page.
+
+   Not all environments and operating systems provide the mechanism to
+   write-protect memory, catch resulting write faults, and read out
+   the faulting address.  But luckily, most of today's operating
+   systems provide the features needed for the write-barrier
+   implementation.  Currently, XEmacs includes write-barrier
+   implementations for the following platforms:
+
+   - POSIX-compliant platforms like up-to-date UNIX, Linux, Solaris,
+     etc. use the system call `mprotect' for memory protection,
+     `sigaction' for signal handling and get the faulting address from
+     `struct siginfo'.  See file vdb-posix.c.
+
+  - Mach-based systems like Mac OS X use "Mach Exception Handlers".
+    See file vdb-mach.c.
+
+  - Windows systems like native Windows and Cygwin use Microsoft's
+    so-called "Structured Exception Handling".  See file vdb-win32.c.
+ 
+  The configure script determines which write barrier implementation
+  to use for a system.  If no write barrier implementation is working
+  on that system, a fall-back "fake" implementation is used: This
+  implementation simply turns of the incremental write barrier at
+  runtime and does not allow any incremental collection (see
+  vdb-fake.c).  The garbage collector then acts like a traditional
+  mark-and-sweep garbage collector.  Generally, the incremental
+  garbage collector can be turned of at runtime by the user or by
+  applications, see below.
+   
+   
+  Memory Protection and Object Layout
+
+  Implementations of a memory-protection mechanism may restrict the
+  size and the alignment of the memory region to be on page-size
+  boundaries.  All objects subject to be covered by the write barrier
+  have to be allocated on logical memory pages, so that they meet the
+  requirement to be write-protected.  The new allocator mc-alloc is
+  aware of a system page size---it allocates all Lisp objects on
+  logical memory pages and is therefore defaulted to on when the new
+  garbage collector is enabled.
+
+  Unfortunately, the Lisp object layout that works with the old
+  collector leads to holes in the write barrier: Not all data
+  structures containing pointers to Lisp objects are allocated on the
+  Lisp heap.  Some Lisp objects do not carry all their information in
+  the object itself.  External parts are kept in separately allocated
+  memory blocks that are not managed by the new Lisp allocator.
+  Examples for these objects are hash tables and dynamic arrays, two
+  objects that can dynamically grow and shrink.  The separate memory
+  blocks are not guaranteed to reside on page boundaries, and thus
+  cannot be watched by the write barrier.
+
+  Moreover, the separate parts can contain live pointers to other Lisp
+  objects.  These pointers are not covered by the write barrier and
+  modifications by the client during garbage collection do escape.  In
+  this case, the client changes the connectivity of the reachability
+  graph behind the collector's back, which eventually leads to
+  erroneous collection of live objects.  To solve this problem, I
+  transformed the separately allocated parts to fully qualified Lisp
+  objects that are managed by the allocator and thus are covered by
+  the write barrier.  This also removes a lot of special allocation
+  and removal code for the out-sourced parts.  Generally, allocating
+  all data structures that contain pointers to Lisp objects on one
+  heap makes the whole memory layout more consistent.
+
+
+  Debugging
+
+  The virtual-dirty-bit write barrier provokes signals on purpose,
+  namely SIGSEGV and SIGBUS.  When debugging XEmacs with this write
+  barrier running, the debugger always breaks whenever a signal
+  occurs.  This behavior is generally desired: A debugger has to break
+  on signals, to allow the user to examine the cause of the
+  signal---especially for illegal memory access, which is a common
+  programming error.  But the debugger should not break for signals
+  caused by the write barrier.  Therefore, most debuggers provide the
+  ability to turn of their fault handling for specific signals.  The
+  configure script generates the debugger's settings .gdbinit and
+  .dbxrc, adding code to turn of signal handling for SIGSEGV and
+  SIGBUS, if the new garbage collector is used.
+
+  But what happens if a bug in XEmacs causes an illegal memory access?
+  To maintain basic debugging abilities, we use another signal: First,
+  the write-barrier signal handler has to determine if the current
+  error situation is caused by the write-barrier memory protection or
+  not.  Therefore, the signal handler checks if the faulting address
+  has been write-protected before.  If it has not, the fault is caused
+  by a bug; the debugger has to break in this situation.  To achieve
+  this, the signal handler raises SIGABRT to abort the program.  Since
+  SIGABRT is not masked out by the debugger, XEmacs aborts and allows
+  the user to examine the problem.
+
+
+  Incremental Garbage Collection
+
+  The new garbage collector is still a mark-and-sweep collector, but
+  now the mark phase no longer runs in one atomic action, it is
+  interleaved with program execution.  The incremental garbage
+  collector needs an explicit mark stack to store the state of the
+  incremental traversal: the KKCC mark algorithm is a prerequisite and
+  is enabled by default when the new garbage collector is on.
+
+  Garbage collection is invoked as before: After `gc-cons-threshold'
+  bytes have been allocated since the last garbage collection (or
+  after `gc-cons-percentage' percentage of the total amount of memory
+  used for Lisp data has been allocated since the last garbage
+  collection) a collection starts.  After some initialization, the
+  marking begins.
+
+  The variable `gc-incremental-traversal-threshold' contains how many
+  steps of incremental work have to be executed in one incremental
+  traversal cycle.  After that many steps have been made, the mark
+  phase is interrupted and the client resumes.  Now, the Lisp memory
+  is write-protected and the write barrier records modified objects.
+  Incremental traversal is resumed after
+  `gc-cons-incremental-threshold' bytes have been allocated since the
+  interruption of garbage collection.  Then, the objects recorded by
+  the write-barrier have to be re-examined by the traversal, i.e. they
+  are re-pushed onto the mark stack and processed again.  Once the
+  mark stack is empty, the traversal is done.
+
+  A full incremental collection is slightly slower than a full garbage
+  collection before: There is an overhead for storing pointers into
+  objects when the write barrier is running, and an overhead for
+  repeated traversal of modified objects.  However, the new
+  incremental garbage collector reduces client pause times to
+  one-third, so even when a garbage collection is running, XEmacs
+  stays reactive.
+
+
+  Tricolor Marking: White, Black, and Grey Mark Bits
+
+  Garbage collection traverses the graph of reachable objects and
+  colors them. The objects subject to garbage collection are white at
+  the beginning. By the end of the collection, those that will be
+  retained are colored black. When there are no reachable objects left
+  to blacken, the traversal of live data structures is finished. In
+  traditional mark-and-sweep collectors, this black and white coloring
+  is sufficient.
+
+  In an incremental collector, the intermediate state of the traversal
+  is im- portant because of ongoing mutator activity: the mutator
+  cannot be allowed to change things in such way that the collector
+  will fail to find all reachable objects. To understand and prevent
+  such interactions between the mutator and the collector, it is
+  useful to introduce a third color, grey.
+
+  Grey objects have been reached by the traversal, but its descendants
+  may not have been. White objects are changed to grey when they are
+  reached by the traversal. Grey objects mark the current state of the
+  traversal: traversal pro- ceeds by processing the grey objects. The
+  KKCC mark stack holds all the currently grey-colored objects.
+  Processing a grey object means following its outgoing pointers, and
+  coloring it black afterwards.
+
+  Intuitively, the traversal proceeds in a wavefront of grey objects
+  that separates the unreached objects, which are colored white, from
+  the already processed black objects.
+
+  The allocator takes care of storing the mark bits: The mark bits are
+  kept in a tree like structure, for details see mc-alloc.c.
+
+
+  Internal States of the Incremental Garbage Collector
+
+  To keep track of its current state, the collector holds it's current
+  phase in the global `gc_state' variable.  A collector phase is one
+  of the following:
+
+  NONE  No incremental or full collection is currently running.
+
+  INIT_GC  The collector prepares for a new collection, e.g. sets some
+    global variables.
+
+  PUSH_ROOT_SET  The collector pushes the root set on the mark stack 
+    to start the traversal of live objects.
+
+  MARK   The traversal of live objects colors the reachable objects
+    white, grey, or black, according to their lifeness.  The mark
+    phase can be interrupted by the incremental collection algorithm:
+    Before the client (i.e. the non collector part of XEmacs) resumes,
+    the write barrier has to be installed so that the collector knows
+    what objects get modified during the collector's pause.
+    Installing a write barrier means protecting pages that only
+    contain black objects and recording write access to these objects.
+    Pages with white or grey objects do not need to be protected,
+    since these pages are due to marking anyways when the collector
+    resumes.  Once the collector resumes, it has to re-scan all
+    objects that have been modified during the collector pause and
+    have been caught by the write barrier.  The mark phase is done when
+    there are no more grey objects on the heap, i.e. the KKCC mark stack
+    is empty.
+
+  REPUSH_ROOT_SET  After the mark phase is done, the collector has to 
+    traverse the root set pointers again, since modifications to the
+    objects in the root set can not all be covered by the write barrier
+    (e.g. root set objects that are on the call stack).  Therefore, the
+    collector has to traverse the root set again without interruption.
+
+  FINISH_MARK  After the mark phase is finished, some objects with
+    special liveness semantics have to be treated separately, e.g.
+    ephemerons and the various flavors of weak objects.
+
+  FINALIZE  The collector registers all objects that have finalizers
+    for finalization.  Finalizations happens asynchronously sometimes
+    after the collection has finished.
+
+  SWEEP  The allocator scans the entire heap and frees all white marked
+    objects. The freed memory is recycled and can be re-used for future
+    allocations. The sweep phase is carried out atomically.
+
+  FINISH_GC  The collector cleans up after the garbage collection by
+    resetting some global variables.
+
+
+  Lisp Interface
+
+  The new garbage collector can be accessed directly from Emacs Lisp.
+  Basically, two functions invoke the garbage collector:
+
+  (gc-full) starts a full garbage collection.  If an incremental
+    garbage collection is already running, it is finished without
+    further interruption.  This function guarantees that unused
+    objects have been freed when it returns.
+
+  (gc-incremental) starts an incremental garbage collection.  If an
+    incremental garbage collection is already running, the next cycle
+    of incremental traversal is started.  The garbage collection is
+    finished if the traversal completes.  Note that this function does
+    not necessarily free any memory.  It only guarantees that the
+    traversal of the heap makes progress.
+
+  The old garbage collector uses the function (garbage-collect) to
+  invoke a garbage collection.  This function is still in use by some
+  applications that explicitly want to invoke a garbage collection.
+  Since these applications may expect that unused memory has really
+  been freed when (garbage-collect) returns, it maps to (gc-full).
+
+  The new garbage collector is highly customizable during runtime; it
+  can even be switched back to the traditional mark-and-sweep garbage
+  collector: The variable allow-incremental-gc controls whether
+  garbage collections may be interrupted or if they have to be carried
+  out in one atomic action.  Setting allow-incremental-gc to nil
+  prevents incremental garbage collection, and the garbage collector
+  then only does full collects, even if (gc-incremental) is called.
+  Non-nil allows incremental garbage collection.
+
+  This way applications can freely decide what garbage collection
+  algorithm is best for the upcoming memory usage.  How frequently a
+  garbage collection occurs and how much traversal work is done in one
+  incremental cycle can also be modified during runtime.  See
+
+    M-x customize RET alloc RET
+
+  for an overview of all settings.
+
+
+  More Information
+
+  More details can be found in
+  http://crestani.de/xemacs/pdf/thesis-newgc.pdf .
+
+*/
+
 #include <config.h>
 #include "lisp.h"
 
@@ -50,8 +362,14 @@
 #include "vdb.h"
 
 
+/* Number of bytes of consing since gc before a full gc should happen. */
 #define GC_CONS_THRESHOLD                  2000000
+
+/* Number of bytes of consing since gc before another cycle of the gc
+   should happen in incremental mode. */
 #define GC_CONS_INCREMENTAL_THRESHOLD       200000
+
+/* Number of elements marked in one cycle of incremental GC. */
 #define GC_INCREMENTAL_TRAVERSAL_THRESHOLD  100000
 
 /* Number of bytes of consing done since the last GC. */
--- a/src/glyphs-eimage.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/glyphs-eimage.c	Mon Oct 18 23:21:23 2010 +0900
@@ -694,7 +694,7 @@
 
   /* 3. Now create the EImage(s) */
   {
-    ColorMapObject *cmo = unwind.giffile->SColorMap;
+    ColorMapObject *cmo = (unwind.giffile->Image.ColorMap ? unwind.giffile->Image.ColorMap : unwind.giffile->SColorMap);
     int i, j, row, pass, interlace, slice;
     UINT_64_BIT pixels_sq;
     Binbyte *eip;
@@ -703,6 +703,9 @@
     static int InterlacedOffset[] = { 0, 4, 2, 1 };
     static int InterlacedJumps[] = { 8, 8, 4, 2 };
 
+    if (cmo == NULL)
+      signal_image_error ("GIF image has no color map", instantiator);
+
     height = unwind.giffile->SHeight;
     width = unwind.giffile->SWidth;
     pixels_sq = (UINT_64_BIT) width * (UINT_64_BIT) height;
--- a/src/lisp.h	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/lisp.h	Mon Oct 18 23:21:23 2010 +0900
@@ -3404,7 +3404,7 @@
   static struct Lisp_Subr *S##Fname;					  \
   DOESNT_RETURN_TYPE (Lisp_Object) Fname (DEFUN_##max_args arglist)
 #define GET_DEFUN_LISP_OBJECT(Fname) \
-  wrap_subr (S##Fname);
+  wrap_subr (&MC_ALLOC_S##Fname)
 #else /* not NEW_GC */
 #define DEFUN(lname, Fname, min_args, max_args, prompt, arglist)	\
   Lisp_Object Fname (EXFUN_##max_args);					\
@@ -3444,7 +3444,7 @@
   };									\
   DOESNT_RETURN_TYPE (Lisp_Object) Fname (DEFUN_##max_args arglist)
 #define GET_DEFUN_LISP_OBJECT(Fname) \
-  wrap_subr (&S##Fname);
+  wrap_subr (&S##Fname)
 #endif /* not NEW_GC */
 
 /* Heavy ANSI C preprocessor hackery to get DEFUN to declare a
@@ -3494,17 +3494,21 @@
 /************************************************************************/
 
 /* The C subr must have been declared with MANY as its max args, and this
-   PARSE_KEYWORDS call must come before any statements.
-
-   FUNCTION is the name of the current function, as a symbol.
+   PARSE_KEYWORDS call must come before any statements. Equivalently, it
+   can appear within braces.
+
+   FUNCTION is the C name of the current DEFUN.  If there is no current
+   DEFUN, use the PARSE_KEYWORDS_8 macro, not PARSE_KEYWORDS.  If the
+   current DEFUN has optional arguments that are not keywords, you also need
+   to use the PARSE_KEYWORDS_8 macro.  This is also the case if there are
+   optional arguments that come before the keywords, as Common Lisp
+   specifies for #'parse-integer.
 
    NARGS is the count of arguments supplied to FUNCTION.
 
    ARGS is a pointer to the argument vector (not a Lisp vector) supplied to
    FUNCTION.
 
-   KEYWORDS_OFFSET is the offset into ARGS where the keyword arguments start.
-
    KEYWORD_COUNT is the number of keywords FUNCTION is normally prepared to
    handle.
 
@@ -3516,11 +3520,6 @@
    by parentheses and separated by the comma operator. If you don't need
    this, supply NULL as KEYWORD_DEFAULTS.
 
-   ALLOW_OTHER_KEYS corresponds to the &allow-other-keys argument list
-   entry in defun*; it is 1 if other keys are normally allowed, 0
-   otherwise. This may be overridden in the caller by specifying
-   :allow-other-keys t in the argument list.
-
    For keywords which appear multiple times in the called argument list, the
    leftmost one overrides, as specified in section 7.1.1 of the CLHS.
 
@@ -3534,26 +3533,71 @@
    and an unrelated name for the local variable, as is possible with the
    ((:keyword unrelated-var)) syntax in defun* and in Common Lisp. That
    shouldn't matter in practice. */
- 
-#define PARSE_KEYWORDS(function, nargs, args, keywords_offset,          \
-                       keyword_count, keywords, keyword_defaults,       \
-                       allow_other_keys)                                \
+#if defined (DEBUG_XEMACS) && defined (__STDC_VERSION__) &&	\
+  __STDC_VERSION__ >= 199901L
+
+/* This version has the advantage that DEFUN without DEFSUBR still provokes
+   a defined but not used warning, and it provokes an assertion failure at
+   runtime if someone has copied and pasted the PARSE_KEYWORDS macro from
+   another function without changing FUNCTION; that would lead to an
+   incorrect determination of KEYWORDS_OFFSET. */
+
+#define PARSE_KEYWORDS(function, nargs, args, keyword_count, keywords,	\
+		       keyword_defaults)				\
+  PARSE_KEYWORDS_8 (intern_massaging_name (1 + #function), nargs, args, \
+                    keyword_count, keywords, keyword_defaults,          \
+                    /* Can't XSUBR (Fsymbol_function (...))->min_args,  \
+                       the function may be advised. */                  \
+                    XINT (Ffunction_min_args                            \
+                          (intern_massaging_name (1 + #function))),     \
+                    0);                                                 \
+  assert (0 == strcmp (__func__, #function))
+#else /* defined (DEBUG_XEMACS) && ... */
+#define PARSE_KEYWORDS(function, nargs, args, keyword_count, keywords,	\
+		       keyword_defaults)				\
+  PARSE_KEYWORDS_8 (intern (subr_name (XSUBR                            \
+                                       (GET_DEFUN_LISP_OBJECT (function)))), \
+                    nargs, args, keyword_count, keywords,               \
+                    keyword_defaults,                                   \
+                    XSUBR (GET_DEFUN_LISP_OBJECT (function))->min_args, \
+                    0)
+#endif /* defined (DEBUG_XEMACS) && defined (__STDC_VERSION__) ... */
+
+/* PARSE_KEYWORDS_8 is a more fine-grained version of PARSE_KEYWORDS. The
+   differences are as follows:
+
+   FUNC_SYM is a symbol reflecting the name of the function for which
+   keywords are being parsed.  In PARSE_KEYWORDS, it is the Lisp-visible
+   name of C_FUNC, interned as a symbol in obarray.
+
+   KEYWORDS_OFFSET is the offset into ARGS where the keyword arguments
+   start.  In PARSE_KEYWORDS, this is the index of the first optional
+   argument, determined from the information known about C_FUNC.
+
+   ALLOW_OTHER_KEYS corresponds to the &allow-other-keys argument list entry
+   in defun*; it is 1 if other keys are normally allowed, 0 otherwise. This
+   may be overridden in the caller by specifying :allow-other-keys t in the
+   argument list. In PARSE_KEYWORDS, ALLOW_OTHER_KEYS is always 0. */
+
+#define PARSE_KEYWORDS_8(func_sym, nargs, args,				\
+			 keyword_count, keywords, keyword_defaults,	\
+			 keywords_offset, allow_other_keys)		\
   DECLARE_N_KEYWORDS_##keyword_count keywords;                          \
                                                                         \
   do                                                                    \
     {                                                                   \
       Lisp_Object pk_key, pk_value;                                     \
-      Elemcount pk_i = nargs - 1;                                       \
+      Elemcount pk_i = nargs - 1, pk_offset = keywords_offset;		\
       Boolint pk_allow_other_keys = allow_other_keys;                   \
                                                                         \
-      if ((nargs - keywords_offset) & 1)                                \
+      if ((nargs - pk_offset) & 1)					\
         {                                                               \
           if (!allow_other_keys                                         \
               && !(pk_allow_other_keys                                  \
-                   = non_nil_allow_other_keys_p (keywords_offset,       \
+                   = non_nil_allow_other_keys_p (pk_offset,		\
                                                  nargs, args)))         \
             {                                                           \
-              signal_wrong_number_of_arguments_error (function, nargs); \
+              signal_wrong_number_of_arguments_error (func_sym, nargs); \
             }                                                           \
           else                                                          \
             {                                                           \
@@ -3566,7 +3610,7 @@
       (void)(keyword_defaults);                                         \
                                                                         \
       /* Start from the end, because the leftmost element overrides. */ \
-      while (pk_i > keywords_offset)                                    \
+      while (pk_i > pk_offset)						\
         {                                                               \
           pk_value = args[pk_i--];                                      \
           pk_key = args[pk_i--];                                        \
@@ -3577,11 +3621,20 @@
             {                                                           \
               continue;                                                 \
             }                                                           \
-          else if (!(pk_allow_other_keys                                \
-                     = non_nil_allow_other_keys_p (keywords_offset,     \
-                                                   nargs, args)))       \
+          else if ((pk_allow_other_keys                                 \
+                    = non_nil_allow_other_keys_p (pk_offset,		\
+                                                  nargs, args)))        \
             {                                                           \
-              invalid_keyword_argument (function, pk_key);              \
+              continue;                                                 \
+            }                                                           \
+          else if (EQ (pk_key, Q_allow_other_keys) &&                   \
+                   NILP (pk_value))                                     \
+            {                                                           \
+              continue;                                                 \
+            }                                                           \
+          else                                                          \
+            {                                                           \
+              invalid_keyword_argument (func_sym, pk_key);              \
             }                                                           \
         }                                                               \
     } while (0)
@@ -5346,9 +5399,7 @@
 int locate_file (Lisp_Object, Lisp_Object, Lisp_Object, Lisp_Object *, int);
 EXFUN (Flocate_file_clear_hashing, 1);
 int isfloat_string (const char *);
-#ifdef HAVE_RATIO
 int isratio_string (const char *);
-#endif
 
 /* Well, I've decided to enable this. -- ben */
 /* And I've decided to make it work right.  -- sb */
@@ -5642,7 +5693,7 @@
 unsigned int hash_string (const Ibyte *, Bytecount);
 Lisp_Object intern_istring (const Ibyte *str);
 MODULE_API Lisp_Object intern (const CIbyte *str);
-Lisp_Object intern_converting_underscores_to_dashes (const CIbyte *str);
+Lisp_Object intern_massaging_name (const CIbyte *str);
 Lisp_Object oblookup (Lisp_Object, const Ibyte *, Bytecount);
 void map_obarray (Lisp_Object, int (*) (Lisp_Object, void *), void *);
 Lisp_Object indirect_function (Lisp_Object, int);
--- a/src/lread.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/lread.c	Mon Oct 18 23:21:23 2010 +0900
@@ -1818,8 +1818,12 @@
 	      }
 	  }
 	if (i >= 0400)
-	  syntax_error ("Non-ISO-8859-1 character specified with octal escape",
-			make_int (i));
+	  {
+	    read_syntax_error ((Ascbyte *) emacs_sprintf_malloc
+			       (NULL,
+				"Non-ISO-8859-1 octal character escape, "
+				"?\\%.3o", i));
+	  }
 	return i;
       }
 
@@ -1827,13 +1831,23 @@
       /* A hex escape, as in ANSI C, except that we only allow latin-1
 	 characters to be read this way.  What is "\x4e03" supposed to
 	 mean, anyways, if the internal representation is hidden?
-         This is also consistent with the treatment of octal escapes. */
+         This is also consistent with the treatment of octal escapes.
+
+         Note that we don't accept ?\XAB as specifying the character with
+         numeric value 171; it must be ?\xAB. */
       {
+#define OVERLONG_INFO "Overlong hex character escape, ?\\x"
+
 	REGISTER Ichar i = 0;
 	REGISTER int count = 0;
+	Ascbyte seen[] = OVERLONG_INFO "\0\0\0\0\0";
+	REGISTER Ascbyte *seenp = seen + sizeof (OVERLONG_INFO) - 1;
+
+#undef OVERLONG_INFO
+
 	while (++count <= 2)
 	  {
-	    c = readchar (readcharfun);
+	    c = readchar (readcharfun), *seenp = c, ++seenp;
 	    /* Remember, can't use isdigit(), isalpha() etc. on Ichars */
 	    if      (c >= '0' && c <= '9')  i = (i << 4) + (c - '0');
 	    else if (c >= 'a' && c <= 'f')  i = (i << 4) + (c - 'a') + 10;
@@ -1847,21 +1861,12 @@
 
         if (count == 3)
           {
-            c = readchar (readcharfun);
+            c = readchar (readcharfun), *seenp = c, ++seenp;
             if ((c >= '0' && c <= '9') ||
                 (c >= 'a' && c <= 'f') ||
                 (c >= 'A' && c <= 'F'))
               {
-                Lisp_Object args[2];
-
-                if      (c >= '0' && c <= '9')  i = (i << 4) + (c - '0');
-                else if (c >= 'a' && c <= 'f')  i = (i << 4) + (c - 'a') + 10;
-                else if (c >= 'A' && c <= 'F')  i = (i << 4) + (c - 'A') + 10;
-
-                args[0] = build_ascstring ("?\\x%x");
-                args[1] = make_int (i);
-                syntax_error ("Overlong hex character escape",
-                              Fformat (2, args));
+		read_syntax_error (seen);
               }
             unreadchar (readcharfun, c);
           }
@@ -2876,7 +2881,6 @@
 	      || state == (DOT_CHAR|TRAIL_INT|E_CHAR|EXP_INT)));
 }
 
-#ifdef HAVE_RATIO
 int
 isratio_string (const char *cp)
 {
@@ -2907,7 +2911,7 @@
   return *cp == '\0' || *cp == ' ' || *cp =='\t' || *cp == '\n' ||
     *cp == '\r' || *cp == '\f';
 }
-#endif
+
 
 static void *
 sequence_reader (Lisp_Object readcharfun,
--- a/src/lrecord.h	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/lrecord.h	Mon Oct 18 23:21:23 2010 +0900
@@ -525,6 +525,7 @@
   int (*putprop) (Lisp_Object obj, Lisp_Object prop, Lisp_Object val);
   int (*remprop) (Lisp_Object obj, Lisp_Object prop);
   Lisp_Object (*plist) (Lisp_Object obj);
+  Lisp_Object (*setplist) (Lisp_Object obj, Lisp_Object newplist);
 
   /* `disksave' is called at dump time.  It is used for objects that
      contain pointers or handles to objects created in external libraries,
--- a/src/mc-alloc.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/mc-alloc.c	Mon Oct 18 23:21:23 2010 +0900
@@ -21,6 +21,227 @@
 
 /* Synched up with: Not in FSF. */
 
+/* 
+   The New Allocator
+
+   The ideas and algorithms are based on the allocator of the
+   Boehm-Demers-Weiser conservative garbage collector. See
+   http://www.hpl.hp.com/personal/Hans_ Boehm/gc/index.html.
+
+   The new allocator is enabled when the new garbage collector
+   is enabled (with `--with-newgc').  The implementation of
+   the new garbage collector is in gc.c.
+
+   The new allocator takes care of:
+   - allocating objects in a write-barrier-friendly way
+   - manage object's mark bits 
+
+   Three-Level Allocation
+
+   The new allocator efficiently manages the allocation of Lisp
+   objects by minimizing the number of times malloc() and free() are
+   called. The allocation process has three layers of abstraction:
+
+   1. It allocates memory in very large chunks called heap sections. 
+   
+   2. The heap sections are subdivided into pages. The page size is
+      determined by the constant PAGE_SIZE. It holds the size of a page
+      in bytes.
+
+   3. One page consists of one or more cells. Each cell represents
+      a memory location for an object. The cells on one page all have
+      the same size, thus every page only contains equal-sized
+      objects.
+
+   If an object is bigger than page size, it is allocated on a
+   multi-page. Then there is only one cell on a multi-page (the cell
+   covers the full multi-page). Is an object smaller than 1/2 PAGE_SIZE,
+   a page contains several objects and several cells. There
+   is only one cell on a page for object sizes from 1/2 PAGE_SIZE to
+   PAGE_SIZE (whereas multi-pages always contain 2 only one
+   cell). Only in layer one malloc() and free() are called.
+
+
+   Size Classes and Page Lists
+
+   Meta-information about every page and multi-page is kept in a page
+   header. The page header contains some bookkeeping information like
+   number of used and free cells, and pointers to other page
+   headers. The page headers are linked in a page list.
+
+   Every page list builds a size class. A size class contains all
+   pages (linked via page headers) for objects of the same size. The
+   new allocator does not group objects based on their type, it groups
+   objects based on their sizes.
+
+   Here is an example: A cons contains a lrecord_header, a car and cdr
+   field. Altogether it uses 12 bytes of memory (on 32 bits
+   machines). All conses are allocated on pages with a cell size of 12
+   bytes. All theses pages are kept together in a page list, which
+   represents the size class for 12 bytes objects. But this size class
+   is not exclusively for conses only. Other objects, which are also
+   12 bytes big (e.g. weak-boxes), are allocated in the same size
+   class and on the same pages.
+
+   The number of size classes is customizable, so is the size step
+   between successive size classes.
+
+
+   Used and Unused Heap
+
+   The memory which is managed by the allocator can be divided in two
+   logical parts:
+
+   The used heap contains pages, on which objects are allocated. These
+   pages are com- pletely or partially occupied. In the used heap, it
+   is important to quickly find a free spot for a new
+   object. Therefore the size classes of the used heap are defined by
+   the size of the cells on the pages. The size classes should match
+   common object sizes, to avoid wasting memory.
+
+   The unused heap only contains completely empty pages. They have
+   never been used or have been freed completely again. In the unused
+   heap, the size of consecutive memory tips the scales. A page is the
+   smallest entity which is asked for. Therefore, the size classes of
+   the unused heap are defined by the number of consecutive pages.
+
+   The parameters for the different size classes can be adjusted
+   independently, see `configurable values' below.
+
+
+   The Allocator's Data Structures
+
+   The struct `mc_allocator_globals holds' all the data structures
+   that the new allocator uses (lists of used and unused pages, mark
+   bits, etc.).
+
+
+   Mapping of Heap Pointers to Page Headers
+
+   For caching benefits, the page headers and mark bits are stored
+   separately from their associated page. During garbage collection
+   (i.e. for marking and freeing objects) it is important to identify
+   the page header which is responsible for a given Lisp object.
+
+   To do this task quickly, I added a two level search tree: the upper
+   10 bits of the heap pointer are the index of the first level. This
+   entry of the first level links to the second level, where the next
+   10 bits of the heap pointer are used to identify the page
+   header. The remaining bits point to the object relative to the
+   page.
+
+   On architectures with more than 32 bits pointers, a hash value of
+   the upper bits is used to index into the first level.
+
+   
+   Mark Bits
+
+   For caching purposes, the mark bits are no longer kept within the
+   objects, they are kept in a separate bit field.
+
+   Every page header has a field for the mark bits of the objects on
+   the page. If there are less cells on the page than there fit bits
+   in the integral data type EMACS_INT, the mark bits are stored
+   directly in this EMACS_INT.
+
+   Otherwise, the mark bits are written in a separate space, with the
+   page header pointing to this space. This happens to pages with
+   rather small objects: many cells fit on a page, thus many mark bits
+   are needed.
+
+
+   Allocate Memory
+
+   Use
+      void *mc_alloc (size_t size) 
+   to request memory from the allocator.  This returns a pointer to a
+   newly allocated block of memory of given size.
+
+   This is how the new allocator allocates memory: 
+   1. Determine the size class of the object. 
+   2. Is there already a page in this size class and is there a free
+      cell on this page?
+      * YES 
+        3. Unlink free cell from free list, return address of free cell. 
+        DONE.
+      * NO 
+        3. Is there a page in the unused heap?
+	* YES 
+          4. Move unused page to used heap. 
+          5. Initialize page header, free list, and mark bits. 
+          6. Unlink first cell from free list, return address of cell. 
+          DONE.
+	* NO 
+          4. Expand the heap, add new memory to unused heap 
+             [go back to 3. and proceed with the YES case].
+
+  The allocator puts partially filled pages to the front of the page
+  list, completely filled ones to the end. That guarantees a fast
+  terminating search for free cells. Are there two successive full
+  pages at the front of the page list, the complete size class is
+  full, a new page has to be added.
+
+
+  Expand Heap
+
+  To expand the heap, a big chunk of contiguous memory is allocated
+  using malloc(). These pieces are called heap sections. How big a new
+  heap section is (and thus the growth of the heap) is adjustable:  See
+  MIN_HEAP_INCREASE, MAX_HEAP_INCREASE, and HEAP_GROWTH_DIVISOR below.
+
+
+  Free Memory
+
+  One optimization in XEmacs is that locally used Lisp objects are
+  freed manually (the memory is not wasted till the next garbage
+  collection). Therefore the new allocator provides this function:
+    void mc_free (void *ptr) 
+  That frees the object pointed to by ptr.
+
+  This function is also used internally during sweep phase of the
+  garbage collection.  This is how it works in detail:
+
+  1. Use pointer to identify page header 
+     (use lookup mechanism described above).
+  2. Mark cell as free and hook it into free list. 
+  3. Is the page completely empty?
+     * YES 
+       4. Unlink page from page list. 
+       5. Remove page header, free list, and mark bits. 
+       6. Move page to unused heap.
+     * NO 
+       4. Move page to front of size class (to speed up allocation 
+          of objects).
+
+  If the last object of a page is freed, the empty page is returned to
+  the unused heap. The allocator tries to coalesce adjacent pages, to
+  gain a big piece of contiguous memory. The resulting chunk is hooked
+  into the according size class of the unused heap. If this created a
+  complete heap section, the heap section is returned to the operating
+  system by using free().
+
+
+  Allocator and Garbage Collector
+
+  The new allocator simplifies the interface to the Garbage Collector:
+  * mark live objects: MARK_[WHITE|GREY|BLACK] (ptr)
+  * sweep heap: EMACS_INT mc_sweep (void)
+  * run finalizers: EMACS_INT mc_finalize (void)
+
+
+  Allocator and Dumper
+
+  The new allocator provides special finalization for the portable
+  dumper (to save disk space): EMACS_INT mc_finalize_for_disksave (void)
+
+
+  More Information
+
+  More details can be found in
+  http://crestani.de/xemacs/pdf/mc-alloc.pdf .
+  
+*/
+
 #include <config.h>
 
 #include "lisp.h"
--- a/src/print.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/print.c	Mon Oct 18 23:21:23 2010 +0900
@@ -2027,7 +2027,7 @@
 
     for (; confusing < size; confusing++)
       {
-        if (!isdigit (data[confusing]))
+	if (!isdigit (data[confusing]) && '/' != data[confusing])
           {
             confusing = 0;
             break;
@@ -2039,7 +2039,8 @@
       /* #### Ugh, this is needlessly complex and slow for what we
          need here.  It might be a good idea to copy equivalent code
          from FSF.  --hniksic */
-      confusing = isfloat_string ((char *) data);
+      confusing = isfloat_string ((char *) data)
+	|| isratio_string ((char *) data);
     if (confusing)
       write_ascstring (printcharfun, "\\");
   }
--- a/src/process-slots.h	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/process-slots.h	Mon Oct 18 23:21:23 2010 +0900
@@ -68,4 +68,6 @@
      all of the Lisp objects, including in process-type-specific data. */
   MARKED_SLOT (tty_name)
 
+  MARKED_SLOT (plist)
+
 #undef MARKED_SLOT
--- a/src/process.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/process.c	Mon Oct 18 23:21:23 2010 +0900
@@ -170,6 +170,42 @@
       write_ascstring (printcharfun, ">");
     }
 }
+/* Process plists are directly accessible, so we need to protect against
+   invalid property list structure */
+
+static Lisp_Object
+process_getprop (Lisp_Object process, Lisp_Object property)
+{
+  return external_plist_get (&XPROCESS (process)->plist, property, 0,
+                             ERROR_ME);
+}
+
+static int
+process_putprop (Lisp_Object process, Lisp_Object property, Lisp_Object value)
+{
+  external_plist_put (&XPROCESS (process)->plist, property, value, 0,
+                      ERROR_ME);
+  return 1;
+}
+
+static int
+process_remprop (Lisp_Object process, Lisp_Object property)
+{
+  return external_remprop (&XPROCESS (process)->plist, property, 0, ERROR_ME);
+}
+
+static Lisp_Object
+process_plist (Lisp_Object process)
+{
+  return XPROCESS (process)->plist;
+}
+
+static Lisp_Object
+process_setplist (Lisp_Object process, Lisp_Object newplist)
+{
+  XPROCESS (process)->plist = newplist;
+  return newplist;
+}
 
 #ifdef HAVE_WINDOW_SYSTEM
 extern void debug_process_finalization (Lisp_Process *p);
@@ -2405,6 +2441,16 @@
 }
 
 
+void
+reinit_process_early (void)
+{
+  OBJECT_HAS_METHOD (process, getprop);
+  OBJECT_HAS_METHOD (process, putprop);
+  OBJECT_HAS_METHOD (process, remprop);
+  OBJECT_HAS_METHOD (process, plist);
+  OBJECT_HAS_METHOD (process, setplist);
+}
+
 /* This is not named init_process in order to avoid a conflict with NS 3.3 */
 void
 init_xemacs_process (void)
@@ -2481,6 +2527,8 @@
 
     Vshell_file_name = build_istring (shell);
   }
+
+  reinit_process_early ();
 }
 
 void
--- a/src/strftime.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/strftime.c	Mon Oct 18 23:21:23 2010 +0900
@@ -132,6 +132,16 @@
   "July", "August", "September", "October", "November", "December"
 };
 
+static char const * const roman_upper[] =
+{
+  "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII"
+};
+
+static char const * const roman_lower[] =
+{
+  "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix", "x", "xi", "xii"
+};
+
 /* Add character C to STRING and increment LENGTH,
    unless LENGTH would exceed MAX. */
 
@@ -601,6 +611,16 @@
 		add_num3 (&string[length],
 			  (1900 + tm->tm_year) % 1000, max - length, zero);
 	      break;
+	    case '\xe6':
+	      length +=
+		add_str (&string[length], roman_lower[tm->tm_mon],
+			 max - length);
+	      break;
+	    case '\xC6':
+	      length +=
+		add_str (&string[length], roman_upper[tm->tm_mon],
+			 max - length);
+	      break;
 	    }
 	}
     }
--- a/src/symbols.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/symbols.c	Mon Oct 18 23:21:23 2010 +0900
@@ -198,15 +198,23 @@
 }
 
 Lisp_Object
-intern_converting_underscores_to_dashes (const CIbyte *str)
+intern_massaging_name (const CIbyte *str)
 {
   Bytecount len = strlen (str);
   CIbyte *tmp = alloca_extbytes (len + 1);
   Bytecount i;
   strcpy (tmp, str);
   for (i = 0; i < len; i++)
-    if (tmp[i] == '_')
-      tmp[i] = '-';
+    {
+      if (tmp[i] == '_')
+	{
+	  tmp[i] = '-';
+	}
+      else if (tmp[i] == 'X')
+	{
+	  tmp[i] = '*';
+	}
+    }
   return intern_istring ((Ibyte *) tmp);
 }
 
@@ -3530,6 +3538,7 @@
   OBJECT_HAS_METHOD (symbol, putprop);
   OBJECT_HAS_METHOD (symbol, remprop);
   OBJECT_HAS_NAMED_METHOD (symbol, plist, Fsymbol_plist);
+  OBJECT_HAS_NAMED_METHOD (symbol, setplist, Fsetplist);
 }
 
 void
--- a/src/symeval.h	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/symeval.h	Mon Oct 18 23:21:23 2010 +0900
@@ -294,6 +294,9 @@
 
 #define DEFSUBR(Fname)				\
 do {						\
+  /* #### As far as I can see, this has no upside compared to the non-NEW_GC \
+     code. The MC_ALLOC_S##Fname structure is also in the dumped	\
+     XEmacs. Aidan Kehoe, Mon Sep 20 23:14:01 IST 2010 */		\
   DEFSUBR_MC_ALLOC (Fname);			\
   defsubr (S##Fname);				\
 } while (0)
--- a/src/symsinit.h	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/symsinit.h	Mon Oct 18 23:21:23 2010 +0900
@@ -54,6 +54,7 @@
 void init_errors_once_early (void);
 void reinit_opaque_early (void);
 void init_opaque_once_early (void);
+void reinit_process_early (void);
 void reinit_symbols_early (void);
 void init_symbols_once_early (void);
 
--- a/src/termcap.c	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/termcap.c	Mon Oct 18 23:21:23 2010 +0900
@@ -25,7 +25,10 @@
 #ifdef emacs
 #include <config.h>
 #include "lisp.h" /* For encapsulated open, close, read */
-#include "device.h" /* For DEVICE_BAUD_RATE */
+#include "device.h"
+#include "device-impl.h" /* For DEVICE_BAUD_RATE */
+#include "sysfile.h"
+#include "process.h"
 #else /* not emacs */
 
 #include <stdlib.h>
--- a/src/text.h	Mon Oct 18 23:03:27 2010 +0900
+++ b/src/text.h	Mon Oct 18 23:21:23 2010 +0900
@@ -3095,7 +3095,7 @@
 #endif
 #define Qunix_host_name_encoding Qnative
 #define Qunix_service_name_encoding Qnative
-#define Qtime_function_encoding Qnative
+#define Qtime_function_encoding Qbinary
 #define Qtime_zone_encoding Qtime_function_encoding
 #define Qmswindows_host_name_encoding Qmswindows_multibyte
 #define Qmswindows_service_name_encoding Qmswindows_multibyte
--- a/tests/ChangeLog	Mon Oct 18 23:03:27 2010 +0900
+++ b/tests/ChangeLog	Mon Oct 18 23:21:23 2010 +0900
@@ -18,6 +18,38 @@
 
 	* reproduce-crashes.el: Amend "this file" to "XEmacs is free...".
 
+2010-10-14  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* automated/lisp-tests.el (x):
+	Test #'nbutlast, #'butlast with dotted lists.
+	Check that #'ldiff and #'tailp don't hang on circular lists; check
+	that #'tailp returns t with circular lists when that is
+	appropriate.  Test them both with dotted lists.
+
+2010-10-12  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* automated/lisp-tests.el:
+	Make sure circularity checking with #'merge is sane.
+
+2010-08-15  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* automated/lisp-tests.el:
+	(not, not, invalid-argument, invalid-argument):
+	Check that error messages from the image specifier instantiator
+	code are clearer than they used to be.
+
+2010-08-15  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* automated/lisp-tests.el:
+	Test that symbols with names that look like ratios are printed
+	distinctly from the equivalent ratios.
+
+2010-07-24  Aidan Kehoe  <kehoea@parhasard.net>
+
+	* automated/lisp-tests.el:
+	Test a couple of things #'reduce was just made more careful
+	about.
+
 2010-06-13  Stephen J. Turnbull  <stephen@xemacs.org>
 
 	* gtk/event-stream-tests.el:
--- a/tests/automated/lisp-tests.el	Mon Oct 18 23:03:27 2010 +0900
+++ b/tests/automated/lisp-tests.el	Mon Oct 18 23:21:23 2010 +0900
@@ -200,6 +200,14 @@
   (Assert (equal y '(0 1 2 3)))
   (Assert (equal z y)))
 
+(let* ((x (list* 0 1 2 3 4 5 6.0 ?7 ?8 (vector 'a 'b 'c)))
+       (y (butlast x 0))
+       (z (nbutlast x 0)))
+  (Assert (eq z x))
+  (Assert (not (eq y x)))
+  (Assert (equal y '(0 1 2 3 4 5 6.0 ?7 ?8)))
+  (Assert (equal z y)))
+
 (Assert (eq (butlast  '(x)) nil))
 (Assert (eq (nbutlast '(x)) nil))
 (Assert (eq (butlast  '()) nil))
@@ -219,6 +227,58 @@
     (Assert (and (equal x y) (not (eq x y))))))
 
 ;;-----------------------------------------------------
+;; Test `ldiff'
+;;-----------------------------------------------------
+(Check-Error wrong-type-argument (ldiff 'foo pi))
+(Check-Error wrong-number-of-arguments (ldiff))
+(Check-Error wrong-number-of-arguments (ldiff '(1 2)))
+(Check-Error circular-list (ldiff (make-circular-list 1) nil))
+(Check-Error circular-list (ldiff (make-circular-list 2000) nil))
+(Assert (eq '() (ldiff '() pi)))
+(dolist (x '((1) (1 2) (1 2 3) (1 2 . 3)))
+  (let ((y (ldiff x nil)))
+    (Assert (and (equal x y) (not (eq x y))))))
+
+(let* ((vector (vector 'foo))
+       (dotted `(1 2 3 ,pi 40 50 . ,vector))
+       (dotted-pi `(1 2 3 . ,pi))
+       without-vector without-pi)
+  (Assert (equal dotted (ldiff dotted nil))
+	  "checking ldiff handles dotted lists properly")
+  (Assert (equal (butlast dotted 0) (ldiff dotted vector))
+	  "checking ldiff discards dotted elements correctly")
+  (Assert (equal (butlast dotted-pi 0) (ldiff dotted-pi (* 4 (atan 1))))
+	  "checking ldiff handles float equivalence correctly"))
+
+;;-----------------------------------------------------
+;; Test `tailp'
+;;-----------------------------------------------------
+(Check-Error wrong-type-argument (tailp pi 'foo))
+(Check-Error wrong-number-of-arguments (tailp))
+(Check-Error wrong-number-of-arguments (tailp '(1 2)))
+(Check-Error circular-list (tailp nil (make-circular-list 1)))
+(Check-Error circular-list (tailp nil (make-circular-list 2000)))
+(Assert (null (tailp pi '()))
+	"checking pi is not a tail of the list nil")
+(Assert (tailp 3 '(1 2 . 3))
+	"checking #'tailp works with a dotted integer.")
+(Assert (tailp pi `(1 2 . ,(* 4 (atan 1))))
+	"checking tailp works with non-eq dotted floats.")
+(let ((list (make-list 2048 nil)))
+  (Assert (tailp (nthcdr 2000 list) (nconc list list))
+	  "checking #'tailp succeeds with circular LIST containing SUBLIST"))
+
+;;-----------------------------------------------------
+;; Test `endp'
+;;-----------------------------------------------------
+(Check-Error wrong-type-argument (endp 'foo))
+(Check-Error wrong-number-of-arguments (endp))
+(Check-Error wrong-number-of-arguments (endp '(1 2) 'foo))
+(Assert (endp nil) "checking nil is recognized as the end of a list")
+(Assert (not (endp (list 200 200 4 0 9)))
+	"checking a cons is not recognised as the end of a list")
+
+;;-----------------------------------------------------
 ;; Arithmetic operations
 ;;-----------------------------------------------------
 
@@ -2341,4 +2401,78 @@
 	       (gethash hashed-bignum hashing))
 	      "checking hashing works correctly with #'eql tests and bignums"))))
 
+;; 
+(when (decode-char 'ucs #x0192)
+  (Check-Error
+   invalid-state
+   (let ((str "aaaaaaaaaaaaa")
+	 (called 0)
+	 modified)
+     (reduce #'+ str
+	     :key #'(lambda (object)
+		      (prog1
+			  object
+			(incf called) 
+			(or modified
+			    (and (> called 5)
+				 (setq modified
+				       (fill str (read #r"?\u0192")))))))))))
+
+(Assert
+ (eql 55
+      (let ((sequence '(1 2 3 4 5 6 7 8 9 10))
+	    (called 0)
+	    modified)
+	(reduce #'+
+		sequence
+		:key
+		#'(lambda (object) (prog1
+				       object
+				     (incf called)
+				     (and (eql called 5)
+					  (setcdr (nthcdr 3 sequence) nil))
+				     (garbage-collect))))))
+ "checking we can amputate lists without crashing #'reduce")
+
+(Assert (not (eq t (canonicalize-inst-list
+		    `(((mswindows) . [string :data ,(make-string 20 0)])
+		      ((tty) . [string :data " "])) 'image t)))
+	"checking mswindows is always available as a specifier tag")
+
+(Assert (not (eq t (canonicalize-inst-list
+		    `(((mswindows) . [nothing])
+		      ((tty) . [string :data " "]))
+		    'image t)))
+	"checking the correct syntax for a nothing image specifier works")
+
+(Check-Error-Message invalid-argument "^Invalid specifier tag set"
+		     (canonicalize-inst-list
+		      `(((,(gensym)) . [nothing])
+			((tty) . [string :data " "]))
+		      'image))
+
+(Check-Error-Message invalid-argument "^Unrecognized keyword"
+		     (canonicalize-inst-list
+		      `(((mswindows) . [nothing :data "hi there"])
+			((tty) . [string :data " "])) 'image))
+
+;; If we combine both the specifier inst list problems, we get the
+;; unrecognized keyword error first, not the invalid specifier tag set
+;; error. This is a little unintuitive; the specifier tag set thing is
+;; processed first, and would seem to be more important. But anyone writing
+;; code needs to solve both problems, it's reasonable to ask them to do it
+;; in series rather than in parallel.
+
+(when (featurep 'ratio)
+  (Assert (not (eql '1/2 (read (prin1-to-string (intern "1/2")))))
+	  "checking symbols with ratio-like names are printed distinctly")
+  (Assert (not (eql '1/5 (read (prin1-to-string (intern "2/10")))))
+	  "checking symbol named \"2/10\" not eql to ratio 1/5 on read"))
+
+(let* ((count 0)
+       (list (map-into (make-list 2048 nil) #'(lambda () (decf count))))
+       (expected (append list '(1))))
+  (Assert (equal expected (merge 'list list '(1) #'<))
+	  "checking merge's circularity checks are sane"))
+
 ;;; end of lisp-tests.el