changeset 83116:6ae3d2810507

Merged in changes from CVS trunk. Patches applied: * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-262 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-263 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-264 Update from CVS: lispref/display.texi: emacs -> Emacs. * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-265 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-266 Update from CVS * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-267 Update from CVS git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-156
author Karoly Lorentey <lorentey@elte.hu>
date Sat, 01 May 2004 19:23:22 +0000
parents 141388e31bb7 (current diff) 0d08aa952288 (diff)
children 46882e012e30
files ChangeLog lisp/ChangeLog lisp/bindings.el lisp/simple.el lisp/smerge-mode.el src/buffer.c src/dispextern.h src/xdisp.c
diffstat 42 files changed, 1697 insertions(+), 698 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Thu Apr 29 20:45:02 2004 +0000
+++ b/ChangeLog	Sat May 01 19:23:22 2004 +0000
@@ -1,3 +1,7 @@
+2004-04-29  Dave Love  <fx@gnu.org>
+
+	* configure.in: Don't forget to quote args to `test'.
+
 2004-04-24  Thien-Thi Nguyen  <ttn@gnu.org>
 
 	* autogen.sh: Update filename in "please read" message.
--- a/configure.in	Thu Apr 29 20:45:02 2004 +0000
+++ b/configure.in	Sat May 01 19:23:22 2004 +0000
@@ -3,7 +3,7 @@
 dnl 	autoconf
 dnl in the directory containing this script.
 dnl
-dnl  Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2003
+dnl  Copyright (C) 1994, 95, 96, 1999, 2000, 01, 02, 03, 2004
 dnl  Free Software Foundation, Inc.
 dnl
 dnl  This file is part of GNU Emacs.
@@ -1280,7 +1280,7 @@
 dnl if not built to support GNU ld.
 
 late_LDFLAGS=$LDFLAGS
-if test $GCC = yes; then
+if test "$GCC" = yes; then
   LDFLAGS="$LDFLAGS -Wl,-znocombreloc"
 else
   LDFLAGS="$LDFLAGS -znocombreloc"
--- a/etc/NEWS	Thu Apr 29 20:45:02 2004 +0000
+++ b/etc/NEWS	Sat May 01 19:23:22 2004 +0000
@@ -290,13 +290,15 @@
 your .emacs will no longer establish the default highlighting -- Use
 `sql-product' to accomplish this.
 
+ANSI keywords are always highlighted.
+
 *** The function `sql-add-product-keywords' can be used to add
 font-lock rules to the product specific rules.  For example, to have
 all identifiers ending in "_t" under MS SQLServer treated as a type,
 you would use the following line in your .emacs file:
 
   (sql-add-product-keywords 'ms
-             '("\\<\\w+_t\\>" . font-lock-type-face))
+             '(("\\<\\w+_t\\>" . font-lock-type-face)))
 
 *** Oracle support includes keyword highlighting for Oracle 9i.  Most
 SQL and PL/SQL keywords are implemented.  SQL*Plus commands are
@@ -313,6 +315,13 @@
 called with the -E command line argument to use the operating system
 credentials to authenticate the user.
 
+*** Postgres support is enhanced.
+Keyword highlighting of Postgres 7.3 is implemented.  Prompting for
+the username and the pgsql `-U' option is added.
+
+*** MySQL support is enhanced.
+Keyword higlighting of MySql 4.0 is implemented.
+
 *** Imenu support has been enhanced to locate tables, views, indexes,
 packages, procedures, functions, triggers, sequences, rules, and
 defaults.
@@ -1142,6 +1151,13 @@
 `appt-display-format' controls how reminders are displayed, replacing
 appt-issue-message, appt-visible, and appt-msg-window.
 
+** The new functions `diary-from-outlook', `diary-from-outlook-gnus',
+and `diary-from-outlook-rmail' can be used to import diary entries
+from Outlook-format appointments in mail messages.  The variable
+`diary-outlook-formats' can be customized to recognize additional
+formats.
+
+
 ** VC Changes
 
 *** The key C-x C-q no longer checks files in or out, it only changes
@@ -2013,20 +2029,27 @@
 height it increased by increasing the line's ascent.
 
 If the line-height property value is a float, the minimum line height
-is calculated by multiplying the height of the current face font by
-the given value.
-
-If the line-height property value is t, the minimum line height is
-the height of the default frame font.
-
-If the line-spacing property value is an integer, the value is used as
-additional space to put after the display line; this overrides the
-default frame line-spacing and any buffer local value of the
-line-spacing variable.
-
-If the line-spacing property value is a float, the value is multiplied
-by the current height of the display row to determine the additional
-space to put after the display line.
+is calculated by multiplying the default frame line height by the
+given value.
+
+If the line-height property value is a cons (RATIO . FACE), the
+minimum line height is calculated as RATIO * height of named FACE.
+RATIO is int or float.  If FACE is t, it specifies the current face.
+
+If the line-spacing property value is an positive integer, the value
+is used as additional pixels to insert after the display line; this
+overrides the default frame line-spacing and any buffer local value of
+the line-spacing variable.
+
+If the value is a negative integer, the absolute value is used as the
+total height of the line, i.e. a varying number of pixels are
+inserted after each line to make each line exactly that many pixels high.
+
+If the line-spacing property may be a float or cons, the line spacing
+is calculated as specified above for the line-height property.
+
+** The buffer local line-spacing variable may now have a float value,
+which is used as a height relative to the default frame line height.
 
 ** Enhancements to stretch display properties
 
@@ -3417,7 +3440,7 @@
 running under X.
 
 ** Arguments for remove-overlays are now optional, so that you can remove
-all overlays in the buffer by just calling (remove-overlay). 
+all overlays in the buffer by just calling (remove-overlay).
 
 ** New packages:
 
--- a/leim/Makefile.in	Thu Apr 29 20:45:02 2004 +0000
+++ b/leim/Makefile.in	Sat May 01 19:23:22 2004 +0000
@@ -117,13 +117,13 @@
 
 RUSSIAN=${srcdir}/quail/cyrillic.elc ${srcdir}/quail/cyril-jis.elc
 
-MISC= \
+OTHERS= \
 	${srcdir}/quail/ethiopic.elc \
 	${srcdir}/quail/ipa.elc \
 	${srcdir}/quail/hebrew.elc \
 	${srcdir}/quail/georgian.elc
 
-MISC-DIC=\
+MISC= \
 	quail/tsang-b5.elc	\
 	quail/quick-b5.elc	\
 	quail/tsang-cns.elc	\
@@ -137,17 +137,17 @@
 EASTASIA=${CHINESE} ${JAPANESE} ${KOREAN}
 ASIA=${EASTASIA} ${THAI} ${VIETNAMESE} ${LAO} ${INDIAN} ${TIBETAN}
 EUROPEAN=${LATIN} ${SLAVIC} ${GREEK} ${RUSSIAN}
-WORLD=${ASIA} ${EUROPEAN} ${MISC} ${MISC-DIC} ${UNICODE}
+WORLD=${ASIA} ${EUROPEAN} ${OTHERS} ${MISC} ${UNICODE}
 
-TIT=${CHINESE-TIT}
-NON-TIT=${CHINESE-NON-TIT} ${JAPANESE} ${KOREAN} ${EUROPEAN} ${MISC}
+TIT-MISC=${CHINESE-TIT} ${MISC}
+NON-TIT-MISC=${CHINESE-NON-TIT} ${JAPANESE} ${KOREAN} ${EUROPEAN} ${OTHERS}
 
 .SUFFIXES: .elc .el
 
 .el.elc:
 	${RUN-EMACS} -f batch-byte-compile $<
 
-all: ${BUILT-EMACS} ${SUBDIRS} ${WORLD} leim-list.el
+all: ${BUILT-EMACS} ${SUBDIRS} leim-list.el
 
 # To ensure that we can run Emacs.  This target is ignored (never
 # being hit) if a user changes default value of EMACS.
@@ -158,38 +158,48 @@
 	mkdir $@
 	touch stamp-subdir
 
-# The rules which generate ${TIT} and ${MISC-DIC} files create them all
-# in one go.  So we need to prevent parallel execution for that target,
-# otherwise Emacs complains about files being locked.  .NOTPARALLEL is
-# for GNU Make, .NO_PARALLEL is for other Make's.
-.NOTPARALLEL: ${TIT} ${MISC-DIC}
+TIT-SOURCES= \
+	CXTERM-DIC/4Corner.tit \
+	CXTERM-DIC/ARRAY30.tit \
+	CXTERM-DIC/CCDOSPY.tit \
+	CXTERM-DIC/ECDICT.tit \
+	CXTERM-DIC/ETZY.tit \
+	CXTERM-DIC/PY-b5.tit \
+	CXTERM-DIC/Punct-b5.tit \
+	CXTERM-DIC/Punct.tit \
+	CXTERM-DIC/QJ-b5.tit \
+	CXTERM-DIC/QJ.tit \
+	CXTERM-DIC/SW.tit \
+	CXTERM-DIC/TONEPY.tit \
+	CXTERM-DIC/ZOZY.tit
 
-.NO_PARALLEL: ${TIT} ${MISC-DIC}
+changed.tit: ${TIT-SOURCES}
+	echo "0" > $@
 
-# Rule to generate quail/*.el from CXTERM-DIC/*.tit.
-# The "if [ -f $@ ]; then true; " part prevents parallel Make's
-# which don't honor .NOTPARALLEL, such as SGI's Make, from running
-# this rule many times, one each for every file it creates.
-${TIT}:
-	if [ -d quail ]; then true; else make quail; fi
-	if [ -f $@ ]; then true; else \
-	 ${RUN-EMACS} -l ${buildlisppath}/international/titdic-cnv \
-	  --eval '(batch-titdic-convert t)' -dir quail ${srcdir}/CXTERM-DIC; fi
-	if [ -f $@ ]; then true; else \
-	 ${RUN-EMACS}  -l ${buildlisppath}/international/quail \
-	  -f batch-byte-compile ${TIT:.elc=.el}; fi
+MISC-SOURCES= \
+	MISC-DIC/CTLau-b5.html \
+	MISC-DIC/CTLau.html \
+	MISC-DIC/cangjie-table.b5 \
+	MISC-DIC/cangjie-table.cns \
+	MISC-DIC/pinyin.map \
+	MISC-DIC/ziranma.cin
+
+changed.misc: ${MISC-SOURCES}
+	echo "0" > $@
 
-# Rule to generate quail/*.el from MISC-DIC/*.
-${MISC-DIC}:
-	if [ -d quail ]; then true; else make quail; fi
-	if [ -f $@ ]; then true; else \
-	 ${RUN-EMACS} -l ${buildlisppath}/international/titdic-cnv \
-	    -f batch-miscdic-convert -dir quail ${srcdir}/MISC-DIC; fi
-	if [ -f $@ ]; then true; else \
-	 ${RUN-EMACS} -l ${buildlisppath}/international/quail \
-	  -f batch-byte-compile ${MISC-DIC:.elc=.el}; fi
-
-leim-list.el: ${SUBDIRS} ${WORLD}
+leim-list.el: ${SUBDIRS} ${NON-TIT-MISC} changed.tit changed.misc
+	if [ `(cat changed.tit)` = 0 ] ; then \
+	  ${RUN-EMACS} -l ${buildlisppath}/international/titdic-cnv \
+	    -f batch-titdic-convert -dir quail ${srcdir}/CXTERM-DIC; \
+	  echo "1" > changed.tit; \
+	else true; fi
+	if [ `(cat changed.misc)` = 0 ] ; then \
+	  ${RUN-EMACS} -l ${buildlisppath}/international/titdic-cnv \
+	    -f batch-miscdic-convert -dir quail ${srcdir}/MISC-DIC; \
+	  echo "1" > changed.misc; \
+	else true; fi
+	${RUN-EMACS}  -l ${buildlisppath}/international/quail \
+	  -f batch-byte-compile-if-not-done ${TIT-MISC:.elc=.el}
 	if [ x`(cd ${srcdir} && /bin/pwd)` = x`(/bin/pwd)` ] ; then \
 	  ${RUN-EMACS} -l ${buildlisppath}/international/quail \
 	    --eval "(update-leim-list-file \".\")" ; \
@@ -223,8 +233,8 @@
 	-chmod -R a+r ${INSTALLDIR}
 
 clean mostlyclean:
-	rm -f ${TIT} ${TIT:.elc=.el} ${MISC-DIC} ${MISC-DIC:.elc=.el} \
-		leim-list.el
+	rm -f ${TIT-MISC} ${TIT-MISC:.elc=.el} \
+		leim-list.el changed.tit changed.misc
 
 distclean: clean
 	if test -f stamp-subdir; then rm -rf ${SUBDIRS} stamp-subdir; fi
--- a/lisp/ChangeLog	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/ChangeLog	Sat May 01 19:23:22 2004 +0000
@@ -1,3 +1,187 @@
+2004-05-01  Kenichi Handa  <handa@m17n.org>
+
+	* international/titdic-cnv.el (miscdic-convert): Don't generate a
+	quail file if it is up to date.
+
+2004-04-30  Juri Linkov  <juri@jurta.org>
+
+	* cus-edit.el (custom-mode-map):
+	Add key binding `C-x C-s' to `Custom-save'.
+
+	* outline.el (outline-blank-line): New var.
+	(outline-next-preface, outline-show-heading)
+	(outline-end-of-subtree): Use it.
+
+	* dired-aux.el (dired-touch-initial): New fun.
+	(dired-do-chxxx): Call it for op-symbol `touch'.
+	(dired-diff): Use `dired-dwim-target-directory'
+	if current dired buffer has no buffer mark.
+
+	* bindings.el (propertized-buffer-identification):
+	Replace `(:weight bold)' by `Buffer-menu-buffer-face'.
+	Add C-M-arrow keys for consistency.
+
+	* files.el (confirm-kill-emacs):
+	Change group from top-level `emacs' to `convenience'.
+
+	* emacs-lisp/lisp.el (beginning-of-defun, end-of-defun):
+	Push mark on the first call of successive command calls.
+	(insert-pair): New fun created from `insert-parentheses' with
+	`open' and `close' arguments added.  Enclose active regions
+	in paired characters.  Compare adjacent characters syntax with
+	inserted characters syntax before inserting a space.
+	(insert-parentheses): Call `insert-pair' with ?\( ?\).
+
+	* delsel.el: Don't put `delete-selection' property
+	on `insert-parentheses' symbol to take advantage of
+	region handling in `insert-pair' function.
+	Suggested by Stephan Stahl <stahl@eos.franken.de>
+
+2004-04-30  Kim F. Storm  <storm@cua.dk>
+
+	* emulation/cua-base.el: Add support for changing cursor types;
+	based on patch from Michael Mauger.
+	(cua-normal-cursor-color, cua-read-only-cursor-color)
+	(cua-overwrite-cursor-color, cua-global-mark-cursor-color):
+	Customization cursor type and/or cursor color.
+	(cua--update-indications): Handle cursor type changes.
+	(cua-mode): Update cursor indications if enabled.
+
+	* menu-bar.el (menu-bar-options-menu): Change menu text for CUA.
+
+	* mouse.el (mouse-drag-copy-region): New defcustom.
+	(mouse-set-region, mouse-drag-region-1): Use it.
+
+	* simple.el (kill-ring-save): If region face background color is
+	unspecified (if no highlighting), show extent of fully visible
+	region even if transient-mark-mode is enabled.
+
+	* emulation/cua-base.el (cua--standard-movement-commands):
+	Add cua-scroll-up and cua-scroll-down.
+	(cua-scroll-up, cua-scroll-down): New commands.
+	(cua--init-keymaps): Remap scroll-up and scroll-down.
+
+	* emulation/cua-rect.el (cua--convert-rectangle-as):
+	New defmacro.
+	(cua-upcase-rectangle, cua-downcase-rectangle): Use it.
+	(cua-upcase-initials-rectangle, cua-capitalize-rectangle):
+	New commands (suggested by Jordan Breeding)..
+
+2004-04-30  Juanma Barranquero  <lektu@terra.es>
+
+	* smerge-mode.el (smerge-diff-switches): Fix typo in docstring.
+
+2004-04-30  Mario Lang  <mlang@delysid.org>
+
+	* diff.el (diff-switches): Fix typo in docstring.
+
+2004-04-30  Alex Schroeder  <alex@gnu.org>
+
+	* xml.el (xml-debug-print-internal): Don't add newline and
+	indentation to text nodes and write empty elements as empty tags
+	instead of opening and closing tags.
+	(xml-debug-print): Take optional indent-string argument.
+	(xml-print): Alias for xml-debug-print.
+
+2004-04-30  Glenn Morris  <gmorris@ast.cam.ac.uk>
+
+	* progmodes/fortran.el (fortran-fill): Use local var `bol' rather
+	than duplicate call to `line-beginning-position'.
+
+	* progmodes/f90.el (f90-get-present-comment-type): Return
+	whitespace, as well as comment chars, for consistent filling
+	of comment blocks.  Use `match-string-no-properties'.
+	(f90-break-line): Do not leave trailing whitespace when filling
+	comments.
+
+2004-04-30  Dave Love  <fx@gnu.org>
+
+	* calendar/diary-lib.el (diary-outlook-formats): New variable.
+	(diary-from-outlook-internal, diary-from-outlook)
+	(diary-from-outlook-gnus, diary-from-outlook-rmail): New
+	functions to import diary entries from Outlook-format
+	appointments in mail messages.
+
+2004-04-29  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* progmodes/python.el (python-send-command): New fun.
+	(python-send-region, python-load-file): Use it.
+
+	* progmodes/compile.el (compilation-last-buffer): Add var alias.
+
+	* help-fns.el (help-C-file-name): Use new subr-name.
+	Prepend `src/' to the file name.
+	(help-C-source-directory, help-subr-name, help-find-C-source): Remove.
+	(describe-function-1, describe-variable): Only find a C source file
+	name if DOC is already loaded.
+
+	* help-mode.el (help-function-def, help-variable-def):
+	Use the new find-function-search-for-symbol functionality.
+	Allow FILE to be `C-source'.
+
+	* emacs-lisp/find-func.el (find-function-C-source-directory): New var.
+	(find-function-C-source): New fun.
+	(find-function-search-for-symbol): Use it.
+
+2004-03-29  Michael Mauger  <mmaug@yahoo.com>
+
+	* progmodes/sql.el (sql-product-alist): Rename variable
+	`sql-product-support'.  Add Postgres login parameters.
+	(sql-set-product, sql-product-feature): Update with renamed
+	variable.
+	(sql-connect-postgres): Add username prompt.
+	(sql-imenu-generic-expression, sql-mode-font-lock-object-name):
+	Make patterns less product specific.
+	(sql-xemacs-p, sql-emacs19-p): Add flags for emacs variants.
+	(sql-mode-abbrev-table): Modify initialization.
+	(sql-builtin-face): Add variable.
+	(sql-keywords-re): Add macro.
+	(sql-mode-ansi-font-lock-keywords): Update for ANSI-92.
+	(sql-mode-oracle-font-lock-keywords): Update for Oracle 9i.
+	(sql-mode-postgres-font-lock-keywords): Update for Postgres 7.3.
+	(sql-mode-mysql-font-lock-keywords): Update for MySql 4.0.
+	(sql-mode-linter-font-lock-keywords)
+	(sql-mode-ms-font-lock-keywords): Use `sql-keywords-re' macro.
+	(sql-mode-sybase-font-lock-keywords)
+	(sql-mode-informix-font-lock-keywords)
+	(sql-mode-interbase-font-lock-keywords)
+	(sql-mode-ingres-font-lock-keywords)
+	(sql-mode-solid-font-lock-keywords)
+	(sql-mode-sqlite-font-lock-keywords)
+	(sql-mode-db2-font-lock-keywords): Default to nil.
+	(sql-product-font-lock): Always highlight ANSI keywords.
+	(sql-add-product-keywords): Made similar to
+	`font-lock-add-keywords'.
+	(sql-send-string): Add function.
+
+2004-04-29  Dave Love <fx@gnu.org>
+
+	* progmodes/cfengine.el (cfengine-beginning-of-defun)
+	(cfengine-end-of-defun): Ensure progress through buffer.
+
+	* info-look.el (cfengine-mode): Accept a terminal ().
+
+2004-04-29  Juri Linkov  <juri@jurta.org>
+
+	* isearch.el (isearch-mode-map): Bind \C-w to isearch-yank-word
+	instead of isearch-yank-word-or-char.  Add new key bindings for
+	isearch-yank-char to \C-f, and isearch-del-char to \C-b.
+	(isearch-del-char): New fun.
+	(isearch-forward, isearch-edit-string): Update docstring.
+	(isearch-yank-char): Doc fix.
+	(isearch-other-meta-char): Restore point after scrolling.
+
+	* progmodes/compile.el (compilation-context-lines): Add nil option
+	to disable compilation output window scrolling.
+	(compilation-set-window): Use it.
+
+	* outline.el (outline-next-preface, outline-show-heading):
+	Don't leave unhidden blank line before heading.
+	(outline-end-of-subtree): Include last newline into subtree.
+	(hide-entry): Leave point at beginning of heading instead of end.
+	(outline-up-heading): Push mark for the first call of successive
+	command calls.
+
 2004-04-28  Luc Teirlinck  <teirllm@auburn.edu>
 
 	* comint.el (comint-prompt-read-only): New variable.
@@ -22,10 +206,9 @@
 2004-04-28  Nick Roberts  <nickrob@gnu.org>
 
 	* progmodes/gdb-ui.el (gdb-frame-breakpoints-buffer)
-	(gdb-frame-stack-buffer, gdb-frame-threads-buffer)
+	(gdb-frame-assembler-buffer, gdb-frame-threads-buffer)
 	(gdb-frame-registers-buffer, gdb-frame-locals-buffer)
-	(gdb-frame-gdb-buffer, gdb-frame-assembler-buffer): Use
-	selected-window.
+	(gdb-frame-gdb-buffer, gdb-frame-stack-buffer): Use selected-window.
 
 	* progmodes/gud.el (gud-common-init): Throw an error if program is
 	already running under gdb.
--- a/lisp/bindings.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/bindings.el	Sat May 01 19:23:22 2004 +0000
@@ -460,7 +460,7 @@
 FMT is a format specifier such as \"%12b\".  This function adds
 text properties for face, help-echo, and local-map to it."
   (list (propertize fmt
-		    'face '(:weight bold)
+		    'face 'Buffer-menu-buffer-face
 		    'help-echo
 		    (purecopy "mouse-1: previous buffer, mouse-3: next buffer")
 		    'local-map mode-line-buffer-identification-keymap)))
@@ -945,6 +945,13 @@
 ;; This is "move to the clipboard", or as close as we come.
 (global-set-key [S-delete] 'kill-region)
 
+(global-set-key [C-M-left]  'backward-sexp)
+(global-set-key [C-M-right] 'forward-sexp)
+(global-set-key [C-M-up]    'backward-up-list)
+(global-set-key [C-M-down]  'down-list)
+(global-set-key [C-M-home]  'beginning-of-defun)
+(global-set-key [C-M-end]   'end-of-defun)
+
 (define-key esc-map "\C-f" 'forward-sexp)
 (define-key esc-map "\C-b" 'backward-sexp)
 (define-key esc-map "\C-u" 'backward-up-list)
--- a/lisp/calendar/diary-lib.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/calendar/diary-lib.el	Sat May 01 19:23:22 2004 +0000
@@ -1859,6 +1859,155 @@
       "Forms to highlight in diary-mode")
 
 
+;; Following code from Dave Love <fx@gnu.org>.
+;; Import Outlook-format appointments from mail messages in Gnus or
+;; Rmail using command `diary-from-outlook'.  This, or the specialized
+;; functions `diary-from-outlook-gnus' and `diary-from-outlook-rmail',
+;; could be run from hooks to notice appointments automatically (in
+;; which case they will prompt about adding to the diary).  The
+;; message formats recognized are customizable through
+;; `diary-outlook-formats'.
+
+(defcustom diary-outlook-formats
+  '(
+    ;; When: 11 October 2001 12:00-14:00 (GMT) Greenwich Mean Time : Dublin, ...
+    ;; [Current UK format?  The timezone is meaningless.  Sometimes the
+    ;; Where is missing.]
+    ("When: \\([0-9]+ [[:alpha:]]+ [0-9]+\\) \
+\\([^ ]+\\) [^\n]+
+\[^\n]+
+\\(?:Where: \\([^\n]+\\)\n+\\)?
+\\*~\\*~\\*~\\*~\\*~\\*~\\*~\\*~\\*~\\*"
+     . "\\1\n \\2 %s, \\3")
+    ;; When: Tuesday, April 30, 2002 03:00 PM-03:30 PM (GMT) Greenwich Mean ...
+    ;; [Old UK format?]
+    ("^When: [[:alpha:]]+, \\([[:alpha:]]+\\) \\([0-9][0-9]*\\), \\([0-9]\\{4\\}\\) \
+\\([^ ]+\\) [^\n]+
+\[^\n]+
+\\(?:Where: \\([^\n]+\\)\\)?\n+"
+     . "\\2 \\1 \\3\n \\4 %s, \\5")
+    (
+     ;; German format, apparently.
+     "^Zeit: [^ ]+, +\\([0-9]+\\)\. +\\([[:upper:]][[:lower:]][[:lower:]]\\)[^ ]* +\\([0-9]+\\) +\\([^ ]+\\).*$"
+     . "\\1 \\2 \\3\n \\4 %s"))
+  "Alist of regexps matching message text and replacement text.
+
+The regexp must match the start of the message text containing an
+appointment, but need not include a leading `^'.  If it matches the
+current message, a diary entry is made from the corresponding
+template.  If the template is a string, it should be suitable for
+passing to `replace-match', and so will have occurrences of `\\D' to
+substitute the match for the Dth subexpression.  It must also contain
+a single `%s' which will be replaced with the text of the message's
+Subject field.  Any other `%' characters must be doubled, so that the
+template can be passed to `format'.
+
+If the template is actually a function, it is called with the message
+body text as argument, and may use `match-string' etc. to make a
+template following the rules above."
+  :type '(alist :key-type (regexp :tag "Regexp matching time/place")
+		:value-type (choice
+			     (string :tag "Template for entry")
+			     (function :tag "Unary function providing template")))
+  :version "21.4"
+  :group 'diary)
+
+
+;; Dynamically bound.
+(defvar body)
+(defvar subject)
+
+(defun diary-from-outlook-internal (&optional test-only)
+  "Snarf a diary entry from a message assumed to be from MS Outlook.
+Assumes `body' is bound to a string comprising the body of the message and
+`subject' is bound to a string comprising its subject.
+Arg TEST-ONLY non-nil means return non-nil if and only if the
+message contains an appointment, don't make a diary entry."
+  (catch 'finished
+    (let (format-string)
+      (dotimes (i (length diary-outlook-formats))
+	(when (eq 0 (string-match (car (nth i diary-outlook-formats))
+				  body))
+	  (unless test-only
+	    (setq format-string (cdr (nth i diary-outlook-formats)))
+	    (save-excursion
+	      (save-window-excursion
+		;; Fixme: References to optional fields in the format
+		;; are treated literally, not replaced by the empty
+		;; string.  I think this is an Emacs bug.
+		(make-diary-entry
+		 (format (replace-match (if (functionp format-string)
+					    (funcall format-string body)
+					  format-string)
+					t nil (match-string 0 body))
+			 subject))
+		(save-buffer))))
+	  (throw 'finished t))))
+    nil))
+
+(defun diary-from-outlook ()
+  "Maybe snarf diary entry from current Outlook-generated message.
+Currently knows about Gnus and Rmail modes."
+  (interactive)
+  (let ((func (cond
+	       ((eq major-mode 'rmail-mode)
+		#'diary-from-outlook-rmail)
+	       ((memq major-mode '(gnus-summary-mode gnus-article-mode))
+		#'diary-from-outlook-gnus)
+	       (t (error "Don't know how to snarf in `%s'" major-mode)))))
+    (if (interactive-p)
+	(call-interactively func)
+      (funcall func))))
+
+
+(defvar gnus-article-mime-handles)
+(defvar gnus-article-buffer)
+
+(autoload 'gnus-fetch-field "gnus-util")
+(autoload 'gnus-narrow-to-body "gnus")
+(autoload 'mm-get-part "mm-decode")
+
+(defun diary-from-outlook-gnus ()
+  "Maybe snarf diary entry from Outlook-generated message in Gnus.
+Add this to `gnus-article-prepare-hook' to notice appointments
+automatically."
+  (interactive)
+  (with-current-buffer gnus-article-buffer
+    (let ((subject (gnus-fetch-field "subject"))
+	  (body (if gnus-article-mime-handles
+		    ;; We're multipart.  Don't get confused by part
+		    ;; buttons &c.  Assume info is in first part.
+		    (mm-get-part (nth 1 gnus-article-mime-handles))
+		  (save-restriction
+		    (gnus-narrow-to-body)
+		    (buffer-string)))))
+      (when (diary-from-outlook-internal t)
+	(when (or (interactive-p)
+                  (y-or-n-p "Snarf diary entry? "))
+	  (diary-from-outlook-internal)
+	  (message "Diary entry added"))))))
+
+(custom-add-option 'gnus-article-prepare-hook 'diary-from-outlook-gnus)
+
+
+(defvar rmail-buffer)
+
+(defun diary-from-outlook-rmail ()
+  "Maybe snarf diary entry from Outlook-generated message in Rmail."
+  (interactive)
+  (with-current-buffer rmail-buffer
+    (let ((subject (mail-fetch-field "subject"))
+	  (body (buffer-substring (save-excursion
+				    (rfc822-goto-eoh)
+				    (point))
+				  (point-max))))
+      (when (diary-from-outlook-internal t)
+	(when (or (interactive-p)
+                  (y-or-n-p "Snarf diary entry? "))
+	  (diary-from-outlook-internal)
+	  (message "Diary entry added"))))))
+
+
 (provide 'diary-lib)
 
 ;;; arch-tag: 22dd506e-2e33-410d-9ae1-095a0c1b2010
--- a/lisp/cus-edit.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/cus-edit.el	Sat May 01 19:23:22 2004 +0000
@@ -4023,6 +4023,7 @@
   (suppress-keymap custom-mode-map)
   (define-key custom-mode-map " " 'scroll-up)
   (define-key custom-mode-map "\177" 'scroll-down)
+  (define-key custom-mode-map "\C-x\C-s" 'Custom-save)
   (define-key custom-mode-map "q" 'Custom-buffer-done)
   (define-key custom-mode-map "u" 'Custom-goto-parent)
   (define-key custom-mode-map "n" 'widget-forward)
--- a/lisp/delsel.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/delsel.el	Sat May 01 19:23:22 2004 +0000
@@ -123,8 +123,6 @@
 (put 'newline 'delete-selection t)
 (put 'open-line 'delete-selection 'kill)
 
-(put 'insert-parentheses 'delete-selection t)
-
 ;; This is very useful for cancelling a selection in the minibuffer without
 ;; aborting the minibuffer.
 (defun minibuffer-keyboard-quit ()
--- a/lisp/diff.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/diff.el	Sat May 01 19:23:22 2004 +0000
@@ -36,7 +36,7 @@
 
 ;;;###autoload
 (defcustom diff-switches "-c"
-  "*A string or list of strings specifying switches to be be passed to diff."
+  "*A string or list of strings specifying switches to be passed to diff."
   :type '(choice string (repeat string))
   :group 'diff)
 
--- a/lisp/dired-aux.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/dired-aux.el	Sat May 01 19:23:22 2004 +0000
@@ -64,7 +64,10 @@
 				   (if default
 				       (concat "(default " default ") ")
 				     ""))
-			   (dired-current-directory) default t)
+			   (if default
+			       (dired-current-directory)
+			     (dired-dwim-target-directory))
+			   default t)
 	   (if current-prefix-arg
 	       (read-string "Options for diff: "
 			    (if (stringp diff-switches)
@@ -185,6 +188,18 @@
              (file-attributes full-file-name))))
    (directory-files dir)))
 
+
+(defun dired-touch-initial (files)
+  "Create initial input value for `touch' command."
+  (let (initial)
+    (while files
+      (let ((current (nth 5 (file-attributes (car files)))))
+        (if (and initial (not (equal initial current)))
+            (setq initial (current-time) files nil)
+          (setq initial current))
+        (setq files (cdr files))))
+    (format-time-string "%Y%m%d%H%M.%S" initial)))
+
 (defun dired-do-chxxx (attribute-name program op-symbol arg)
   ;; Change file attributes (mode, group, owner, timestamp) of marked files and
   ;; refresh their file lines.
@@ -196,7 +211,8 @@
 	 (new-attribute
 	  (dired-mark-read-string
 	   (concat "Change " attribute-name " of %s to: ")
-	   nil op-symbol arg files))
+	   (if (eq op-symbol 'touch) (dired-touch-initial files))
+	   op-symbol arg files))
 	 (operation (concat program " " new-attribute))
 	 failures)
     (setq failures
--- a/lisp/emacs-lisp/find-func.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/emacs-lisp/find-func.el	Sat May 01 19:23:22 2004 +0000
@@ -1,6 +1,6 @@
 ;;; find-func.el --- find the definition of the Emacs Lisp function near point
 
-;; Copyright (C) 1997, 1999, 2001 Free Software Foundation, Inc.
+;; Copyright (C) 1997, 1999, 2001, 2004  Free Software Foundation, Inc.
 
 ;; Author: Jens Petersen <petersen@kurims.kyoto-u.ac.jp>
 ;; Maintainer: petersen@kurims.kyoto-u.ac.jp
@@ -128,6 +128,40 @@
 		   (append (find-library-suffixes) '("")))
       (error "Can't find library %s" library)))
 
+(defvar find-function-C-source-directory
+  (let ((dir (expand-file-name "src" source-directory)))
+    (when (and (file-directory-p dir) (file-readable-p dir))
+      dir))
+  "Directory where the C source files of Emacs can be found.
+If nil, do not try to find the source code of functions and variables
+defined in C.")
+
+(defun find-function-C-source (fun-or-var file variable-p)
+  "Find the source location where SUBR-OR-VAR is defined in FILE.
+VARIABLE-P should be non-nil for a variable or nil for a subroutine."
+  (unless find-function-C-source-directory
+    (setq find-function-C-source-directory
+	  (read-directory-name "Emacs C source dir: " nil nil t)))
+  (setq file (expand-file-name file find-function-C-source-directory))
+  (unless (file-readable-p file)
+    (error "The C source file %s is not available"
+	   (file-name-nondirectory file)))
+  (unless variable-p
+    (setq fun-or-var (indirect-function fun-or-var)))
+  (with-current-buffer (find-file-noselect file)
+    (goto-char (point-min))
+    (unless (re-search-forward
+	     (if variable-p
+		 (concat "DEFVAR[A-Z_]*[ \t\n]*([ \t\n]*\""
+			 (regexp-quote (symbol-name fun-or-var))
+			 "\"")
+	       (concat "DEFUN[ \t\n]*([ \t\n]*\""
+		       (regexp-quote (subr-name fun-or-var))
+		       "\""))
+	     nil t)
+      (error "Can't find source for %s" fun-or-var))
+    (cons (current-buffer) (match-beginning 0))))
+
 ;;;###autoload
 (defun find-library (library)
   "Find the elisp source of LIBRARY."
@@ -149,9 +183,10 @@
       (error "Don't know where `%s' is defined" symbol))
   ;; Some functions are defined as part of the construct
   ;; that defines something else.
-  (while (get symbol 'definition-name)
+  (while (and (symbolp symbol) (get symbol 'definition-name))
     (setq symbol (get symbol 'definition-name)))
-  (save-match-data
+  (if (string-match "\\`src/\\(.*\\.c\\)\\'" library)
+      (find-function-C-source symbol (match-string 1 library) variable-p)
     (if (string-match "\\.el\\(c\\)\\'" library)
 	(setq library (substring library 0 (match-beginning 1))))
     (let* ((filename (find-library-name library)))
--- a/lisp/emacs-lisp/lisp.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/emacs-lisp/lisp.el	Sat May 01 19:23:22 2004 +0000
@@ -175,6 +175,8 @@
 If variable `beginning-of-defun-function' is non-nil, its value
 is called as a function to find the defun's beginning."
   (interactive "p")
+  (and (eq this-command 'beginning-of-defun)
+       (or (eq last-command 'beginning-of-defun) (push-mark)))
   (and (beginning-of-defun-raw arg)
        (progn (beginning-of-line) t)))
 
@@ -223,6 +225,8 @@
 If variable `end-of-defun-function' is non-nil, its value
 is called as a function to find the defun's end."
   (interactive "p")
+  (and (eq this-command 'end-of-defun)
+       (or (eq last-command 'end-of-defun) (push-mark)))
   (if (or (null arg) (= arg 0)) (setq arg 1))
   (if end-of-defun-function
       (if (> arg 0)
@@ -302,29 +306,48 @@
       (end-of-defun)
       (narrow-to-region beg (point)))))
 
+(defun insert-pair (arg &optional open close)
+  "Enclose following ARG sexps in a pair of OPEN and CLOSE characters.
+Leave point after the first character.
+A negative ARG encloses the preceding ARG sexps instead.
+No argument is equivalent to zero: just insert characters
+and leave point between.
+If `parens-require-spaces' is non-nil, this command also inserts a space
+before and after, depending on the surrounding characters.
+If region is active, insert enclosing characters at region boundaries."
+  (interactive "P")
+  (if arg (setq arg (prefix-numeric-value arg))
+    (setq arg 0))
+  (or open  (setq open  ?\())
+  (or close (setq close ?\)))
+  (if (and transient-mark-mode mark-active)
+      (progn
+        (save-excursion (goto-char (region-end))       (insert close))
+        (save-excursion (goto-char (region-beginning)) (insert open)))
+    (cond ((> arg 0) (skip-chars-forward " \t"))
+          ((< arg 0) (forward-sexp arg) (setq arg (- arg))))
+    (and parens-require-spaces
+         (not (bobp))
+         (memq (char-syntax (preceding-char)) (list ?w ?_ (char-syntax close)))
+         (insert " "))
+    (insert open)
+    (save-excursion
+      (or (eq arg 0) (forward-sexp arg))
+      (insert close)
+      (and parens-require-spaces
+           (not (eobp))
+           (memq (char-syntax (following-char)) (list ?w ?_ (char-syntax open)))
+           (insert " ")))))
+
 (defun insert-parentheses (arg)
   "Enclose following ARG sexps in parentheses.  Leave point after open-paren.
 A negative ARG encloses the preceding ARG sexps instead.
 No argument is equivalent to zero: just insert `()' and leave point between.
 If `parens-require-spaces' is non-nil, this command also inserts a space
-before and after, depending on the surrounding characters."
+before and after, depending on the surrounding characters.
+If region is active, insert enclosing characters at region boundaries."
   (interactive "P")
-  (if arg (setq arg (prefix-numeric-value arg))
-    (setq arg 0))
-  (cond ((> arg 0) (skip-chars-forward " \t"))
-	((< arg 0) (forward-sexp arg) (setq arg (- arg))))
-  (and parens-require-spaces
-       (not (bobp))
-       (memq (char-syntax (preceding-char)) '(?w ?_ ?\) ))
-       (insert " "))
-  (insert ?\()
-  (save-excursion
-    (or (eq arg 0) (forward-sexp arg))
-    (insert ?\))
-    (and parens-require-spaces
-	 (not (eobp))
-	 (memq (char-syntax (following-char)) '(?w ?_ ?\( ))
-	 (insert " "))))
+  (insert-pair arg ?\( ?\)))
 
 (defun move-past-close-and-reindent ()
   "Move past next `)', delete indentation before it, then indent after it."
--- a/lisp/emulation/cua-base.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/emulation/cua-base.el	Sat May 01 19:23:22 2004 +0000
@@ -1,6 +1,6 @@
 ;;; cua-base.el --- emulate CUA key bindings
 
-;; Copyright (C) 1997,98,99,200,01,02,03  Free Software Foundation, Inc.
+;; Copyright (C) 1997,98,99,200,01,02,03,04  Free Software Foundation, Inc.
 
 ;; Author: Kim F. Storm <storm@cua.dk>
 ;; Keywords: keyboard emulation convenience cua
@@ -413,29 +413,101 @@
 				       "red")
   "Normal (non-overwrite) cursor color.
 Also used to indicate that rectangle padding is not in effect.
-Default is to load cursor color from initial or default frame parameters."
+Default is to load cursor color from initial or default frame parameters.
+
+If the value is a COLOR name, then only the `cursor-color' attribute will be
+affected.  If the value is a cursor TYPE (one of: box, hollow, bar, or hbar),
+then only the `cursor-type' property will be affected.  If the value is
+a cons (TYPE . COLOR), then both properties are affected."
   :initialize 'custom-initialize-default
-  :type 'color
+  :type '(choice
+	  (color :tag "Color")
+	  (choice :tag "Type"
+		  (const :tag "Filled box" box)
+		  (const :tag "Vertical bar" bar)
+		  (const :tag "Horisontal bar" hbar)
+		  (const :tag "Hollow box" hollow))
+	  (cons :tag "Color and Type"
+		(choice :tag "Type"
+			(const :tag "Filled box" box)
+			(const :tag "Vertical bar" bar)
+			(const :tag "Horisontal bar" hbar)
+			(const :tag "Hollow box" hollow))
+		(color :tag "Color")))
   :group 'cua)
 
 (defcustom cua-read-only-cursor-color "darkgreen"
   "*Cursor color used in read-only buffers, if non-nil.
-Only used when `cua-enable-cursor-indications' is non-nil."
-  :type 'color
+Only used when `cua-enable-cursor-indications' is non-nil.
+
+If the value is a COLOR name, then only the `cursor-color' attribute will be
+affected.  If the value is a cursor TYPE (one of: box, hollow, bar, or hbar),
+then only the `cursor-type' property will be affected.  If the value is
+a cons (TYPE . COLOR), then both properties are affected."
+  :type '(choice
+	  (color :tag "Color")
+	  (choice :tag "Type"
+		  (const :tag "Filled box" box)
+		  (const :tag "Vertical bar" bar)
+		  (const :tag "Horisontal bar" hbar)
+		  (const :tag "Hollow box" hollow))
+	  (cons :tag "Color and Type"
+		(choice :tag "Type"
+			(const :tag "Filled box" box)
+			(const :tag "Vertical bar" bar)
+			(const :tag "Horisontal bar" hbar)
+			(const :tag "Hollow box" hollow))
+		(color :tag "Color")))
   :group 'cua)
 
 (defcustom cua-overwrite-cursor-color "yellow"
   "*Cursor color used when overwrite mode is set, if non-nil.
 Also used to indicate that rectangle padding is in effect.
-Only used when `cua-enable-cursor-indications' is non-nil."
-  :type 'color
+Only used when `cua-enable-cursor-indications' is non-nil.
+
+If the value is a COLOR name, then only the `cursor-color' attribute will be
+affected.  If the value is a cursor TYPE (one of: box, hollow, bar, or hbar),
+then only the `cursor-type' property will be affected.  If the value is
+a cons (TYPE . COLOR), then both properties are affected."
+  :type '(choice
+	  (color :tag "Color")
+	  (choice :tag "Type"
+		  (const :tag "Filled box" box)
+		  (const :tag "Vertical bar" bar)
+		  (const :tag "Horisontal bar" hbar)
+		  (const :tag "Hollow box" hollow))
+	  (cons :tag "Color and Type"
+		(choice :tag "Type"
+			(const :tag "Filled box" box)
+			(const :tag "Vertical bar" bar)
+			(const :tag "Horisontal bar" hbar)
+			(const :tag "Hollow box" hollow))
+		(color :tag "Color")))
   :group 'cua)
 
 (defcustom cua-global-mark-cursor-color "cyan"
   "*Indication for active global mark.
 Will change cursor color to specified color if string.
-Only used when `cua-enable-cursor-indications' is non-nil."
-  :type 'color
+Only used when `cua-enable-cursor-indications' is non-nil.
+
+If the value is a COLOR name, then only the `cursor-color' attribute will be
+affected.  If the value is a cursor TYPE (one of: box, hollow, bar, or hbar),
+then only the `cursor-type' property will be affected.  If the value is
+a cons (TYPE . COLOR), then both properties are affected."
+  :type '(choice
+	  (color :tag "Color")
+	  (choice :tag "Type"
+		  (const :tag "Filled box" box)
+		  (const :tag "Vertical bar" bar)
+		  (const :tag "Horisontal bar" hbar)
+		  (const :tag "Hollow box" hollow))
+	  (cons :tag "Color and Type"
+		(choice :tag "Type"
+			(const :tag "Filled box" box)
+			(const :tag "Vertical bar" bar)
+			(const :tag "Horisontal bar" hbar)
+			(const :tag "Hollow box" hollow))
+		(color :tag "Color")))
   :group 'cua)
 
 
@@ -893,7 +965,7 @@
     forward-word backward-word
     end-of-line beginning-of-line
     end-of-buffer beginning-of-buffer
-    scroll-up scroll-down
+    scroll-up scroll-down cua-scroll-up cua-scroll-down
     forward-sentence backward-sentence
     forward-paragraph backward-paragraph)
   "List of standard movement commands.
@@ -903,26 +975,72 @@
   "User may add additional movement commands to this list.")
 
 
+;;; Scrolling commands which does not signal errors at top/bottom
+;;; of buffer at first key-press (instead moves to top/bottom
+;;; of buffer).
+
+(defun cua-scroll-up (&optional arg)
+  "Scroll text of current window upward ARG lines; or near full screen if no ARG.
+If window cannot be scrolled further, move cursor to bottom line instead.
+A near full screen is `next-screen-context-lines' less than a full screen.
+Negative ARG means scroll downward.
+If ARG is the atom `-', scroll downward by nearly full screen."
+  (interactive "P")
+  (cond
+   ((eq arg '-) (cua-scroll-down nil))
+   ((< (prefix-numeric-value arg) 0)
+    (cua-scroll-down (- (prefix-numeric-value arg))))
+   ((eobp)
+    (scroll-up arg))  ; signal error
+   (t
+    (condition-case nil
+	(scroll-up arg)
+      (end-of-buffer (goto-char (point-max)))))))
+
+(defun cua-scroll-down (&optional arg)
+  "Scroll text of current window downward ARG lines; or near full screen if no ARG.
+If window cannot be scrolled further, move cursor to top line instead.
+A near full screen is `next-screen-context-lines' less than a full screen.
+Negative ARG means scroll upward.
+If ARG is the atom `-', scroll upward by nearly full screen."
+  (interactive "P")
+  (cond
+   ((eq arg '-) (cua-scroll-up nil))
+   ((< (prefix-numeric-value arg) 0)
+    (cua-scroll-up (- (prefix-numeric-value arg))))
+   ((bobp)
+    (scroll-down arg))  ; signal error
+   (t
+    (condition-case nil
+	(scroll-down arg)
+      (beginning-of-buffer (goto-char (point-min)))))))
+
 ;;; Cursor indications
 
 (defun cua--update-indications ()
-  (let ((cursor
-	 (cond
-	  ((and cua--global-mark-active
-		(stringp cua-global-mark-cursor-color))
-	   cua-global-mark-cursor-color)
-	  ((and buffer-read-only
-		(stringp cua-read-only-cursor-color))
-	   cua-read-only-cursor-color)
-	  ((and (stringp cua-overwrite-cursor-color)
-		(or overwrite-mode
-		    (and cua--rectangle (cua--rectangle-padding))))
-	   cua-overwrite-cursor-color)
-	  (t cua-normal-cursor-color))))
-    (if (and cursor
-	     (not (equal cursor (frame-parameter nil 'cursor-color))))
-	(set-cursor-color cursor))
-    cursor))
+  (let* ((cursor
+	  (cond
+	   ((and cua--global-mark-active
+		 cua-global-mark-cursor-color)
+	    cua-global-mark-cursor-color)
+	   ((and buffer-read-only
+		 cua-read-only-cursor-color)
+	    cua-read-only-cursor-color)
+	   ((and cua-overwrite-cursor-color
+		 (or overwrite-mode
+		     (and cua--rectangle (cua--rectangle-padding))))
+	    cua-overwrite-cursor-color)
+	   (t cua-normal-cursor-color)))
+	 (color (if (consp cursor) (cdr cursor) cursor))
+	 (type (if (consp cursor) (car cursor) cursor)))
+    (if (and color
+	     (stringp color)
+	     (not (equal color (frame-parameter nil 'cursor-color))))
+	(set-cursor-color color))
+    (if (and type
+	     (symbolp type)
+	     (not (eq type (frame-parameter nil 'cursor-type))))
+	(setq default-cursor-type type))))
 
 
 ;;; Pre-command hook
@@ -1108,6 +1226,10 @@
   (define-key cua-global-keymap [remap undo]		'cua-undo)
   (define-key cua-global-keymap [remap advertised-undo]	'cua-undo)
 
+  ;; scrolling
+  (define-key cua-global-keymap [remap scroll-up]	'cua-scroll-up)
+  (define-key cua-global-keymap [remap scroll-down]	'cua-scroll-down)
+
   (define-key cua--cua-keys-keymap [(control x) timeout] 'kill-region)
   (define-key cua--cua-keys-keymap [(control c) timeout] 'copy-region-as-kill)
   (define-key cua--cua-keys-keymap [(control z)] 'undo)
@@ -1189,7 +1311,9 @@
 	(add-hook 'post-command-hook 'cua--post-command-handler)
 	(if (and cua-enable-modeline-indications (not (assoc 'cua-mode minor-mode-alist)))
 	    (setq minor-mode-alist (cons '(cua-mode cua--status-string) minor-mode-alist)))
-	)
+	(if cua-enable-cursor-indications
+	    (cua--update-indications)))
+
     (remove-hook 'pre-command-hook 'cua--pre-command-handler)
     (remove-hook 'post-command-hook 'cua--post-command-handler))
 
--- a/lisp/emulation/cua-rect.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/emulation/cua-rect.el	Sat May 01 19:23:22 2004 +0000
@@ -1,6 +1,6 @@
 ;;; cua-rect.el --- CUA unified rectangle support
 
-;; Copyright (C) 1997-2002 Free Software Foundation, Inc.
+;; Copyright (C) 1997-2002, 2004 Free Software Foundation, Inc.
 
 ;; Author: Kim F. Storm <storm@cua.dk>
 ;; Keywords: keyboard emulations convenience CUA
@@ -1057,19 +1057,30 @@
          (insert (format fmt first))
          (setq first (+ first incr)))))
 
+(defmacro cua--convert-rectangle-as (command)
+  `(cua--rectangle-operation 'clear nil nil nil
+    '(lambda (s e l r)
+       (,command s e))))
+
 (defun cua-upcase-rectangle ()
   "Convert the rectangle to upper case."
   (interactive)
-  (cua--rectangle-operation 'clear nil nil nil
-     '(lambda (s e l r)
-        (upcase-region s e))))
+  (cua--convert-rectangle-as upcase-region))
 
 (defun cua-downcase-rectangle ()
   "Convert the rectangle to lower case."
   (interactive)
-  (cua--rectangle-operation 'clear nil nil nil
-     '(lambda (s e l r)
-        (downcase-region s e))))
+  (cua--convert-rectangle-as downcase-region))
+
+(defun cua-upcase-initials-rectangle ()
+  "Convert the rectangle initials to upper case."
+  (interactive)
+  (cua--convert-rectangle-as upcase-initials-region))
+
+(defun cua-capitalize-rectangle ()
+  "Convert the rectangle to proper case."
+  (interactive)
+  (cua--convert-rectangle-as capitalize-region))
 
 
 ;;; Replace/rearrange text in current rectangle
--- a/lisp/files.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/files.el	Sat May 01 19:23:22 2004 +0000
@@ -4423,7 +4423,7 @@
   :type '(choice (const :tag "Ask with yes-or-no-p" yes-or-no-p)
 		 (const :tag "Ask with y-or-n-p" y-or-n-p)
 		 (const :tag "Don't confirm" nil))
-  :group 'emacs
+  :group 'convenience
   :version "21.1")
 
 (defun save-buffers-kill-emacs (&optional arg)
--- a/lisp/follow.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/follow.el	Sat May 01 19:23:22 2004 +0000
@@ -1561,7 +1561,7 @@
 	      (or follow-internal-force-redisplay
 		  (progn
 		    (if (eq dest (point-max))
-			;; We're at the end, we have be be careful since
+			;; We're at the end, we have to be careful since
 			;; the display can be aligned while `dest' can
 			;; be visible in several windows.
 			(cond
--- a/lisp/help-fns.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/help-fns.el	Sat May 01 19:23:22 2004 +0000
@@ -216,27 +216,13 @@
 			(intern (upcase name))))))
 		arglist)))
 
-(defvar help-C-source-directory
-  (let ((dir (expand-file-name "src" source-directory)))
-    (when (and (file-directory-p dir) (file-readable-p dir))
-      dir))
-  "Directory where the C source files of Emacs can be found.
-If nil, do not try to find the source code of functions and variables
-defined in C.")
-
-(defun help-subr-name (subr)
-  (let ((name (prin1-to-string subr)))
-    (if (string-match "\\`#<subr \\(.*\\)>\\'" name)
-	(match-string 1 name)
-      (error "Unexpected subroutine print name: %s" name))))
-
 (defun help-C-file-name (subr-or-var kind)
   "Return the name of the C file where SUBR-OR-VAR is defined.
 KIND should be `var' for a variable or `subr' for a subroutine."
   (let ((docbuf (get-buffer-create " *DOC*"))
 	(name (if (eq 'var kind)
 		  (concat "V" (symbol-name subr-or-var))
-		(concat "F" (help-subr-name subr-or-var)))))
+		(concat "F" (subr-name subr-or-var)))))
     (with-current-buffer docbuf
       (goto-char (point-min))
       (if (eobp)
@@ -246,31 +232,11 @@
       (re-search-backward "S\\(.*\\)")
       (let ((file (match-string 1)))
 	(if (string-match "\\.\\(o\\|obj\\)\\'" file)
-	    (replace-match ".c" t t file)
+	    (setq file (replace-match ".c" t t file)))
+	(if (string-match "\\.c\\'" file)
+	    (concat "src/" file)
 	  file)))))
 
-(defun help-find-C-source (fun-or-var file kind)
-  "Find the source location where SUBR-OR-VAR is defined in FILE.
-KIND should be `var' for a variable or `subr' for a subroutine."
-  (setq file (expand-file-name file help-C-source-directory))
-  (unless (file-readable-p file)
-    (error "The C source file %s is not available"
-	   (file-name-nondirectory file)))
-  (if (eq 'fun kind)
-      (setq fun-or-var (indirect-function fun-or-var)))
-  (with-current-buffer (find-file-noselect file)
-    (goto-char (point-min))
-    (unless (re-search-forward
-	     (if (eq 'fun kind)
-		 (concat "DEFUN[ \t\n]*([ \t\n]*\""
-			 (regexp-quote (help-subr-name fun-or-var))
-			 "\"")
-	       (concat "DEFVAR[A-Z_]*[ \t\n]*([ \t\n]*\""
-		       (regexp-quote (symbol-name fun-or-var))))
-	     nil t)
-      (error "Can't find source for %s" fun))
-    (cons (current-buffer) (match-beginning 0))))
-
 ;;;###autoload
 (defun describe-function-1 (function)
   (let* ((def (if (symbolp function)
@@ -336,14 +302,16 @@
 	    (when (re-search-backward
 		   "^;;; Generated autoloads from \\(.*\\)" nil t)
 	      (setq file-name (match-string 1)))))))
-    (when (and (null file-name) (subrp def) help-C-source-directory)
+    (when (and (null file-name) (subrp def))
       ;; Find the C source file name.
-      (setq file-name (concat "src/" (help-C-file-name def 'subr))))
+      (setq file-name (if (get-buffer " *DOC*")
+			  (help-C-file-name def 'subr)
+			'C-source)))
     (when file-name
       (princ " in `")
       ;; We used to add .el to the file name,
       ;; but that's completely wrong when the user used load-file.
-      (princ file-name)
+      (princ (if (eq file-name 'C-source) "C source code" file-name))
       (princ "'")
       ;; Make a hyperlink to the library.
       (with-current-buffer standard-output
@@ -576,13 +544,13 @@
 	      (when (and (null file-name)
 			 (integerp (get variable 'variable-documentation)))
 		;; It's a variable not defined in Elisp but in C.
-		(if help-C-source-directory
-		    (setq file-name
-			  (concat "src/" (help-C-file-name variable 'var)))
-		  (princ "\n\nDefined in core C code.")))
+		(setq file-name
+		      (if (get-buffer " *DOC*")
+			  (help-C-file-name variable 'var)
+			'C-source)))
 	      (when file-name
 		(princ "\n\nDefined in `")
-		(princ file-name)
+		(princ (if (eq file-name 'C-source) "C source code" file-name))
 		(princ "'.")
 		(with-current-buffer standard-output
 		  (save-excursion
--- a/lisp/help-mode.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/help-mode.el	Sat May 01 19:23:22 2004 +0000
@@ -147,14 +147,13 @@
   :supertype 'help-xref
   'help-function (lambda (fun file)
 		   (require 'find-func)
+		   (when (eq file 'C-source)
+		     (setq file
+			   (help-C-file-name (indirect-function fun) 'fun)))
 		   ;; Don't use find-function-noselect because it follows
 		   ;; aliases (which fails for built-in functions).
 		   (let ((location
-			  (cond
-			   ((bufferp file) (cons file fun))
-			   ((string-match "\\`src/\\(.*\\.c\\)" file)
-			    (help-find-C-source fun (match-string 1 file) 'fun))
-			   (t (find-function-search-for-symbol fun nil file)))))
+			  (find-function-search-for-symbol fun nil file)))
 		     (pop-to-buffer (car location))
 		     (goto-char (cdr location))))
   'help-echo (purecopy "mouse-2, RET: find function's definition"))
@@ -162,11 +161,9 @@
 (define-button-type 'help-variable-def
   :supertype 'help-xref
   'help-function (lambda (var &optional file)
-		   (let ((location
-			  (cond
-			   ((string-match "\\`src/\\(.*\\.c\\)" file)
-			    (help-find-C-source var (match-string 1 file) 'var))
-			   (t (find-variable-noselect var file)))))
+		   (when (eq file 'C-source)
+		     (setq file (help-C-file-name var 'var)))
+		   (let ((location (find-variable-noselect var file)))
 		     (pop-to-buffer (car location))
 		     (goto-char (cdr location))))
   'help-echo (purecopy"mouse-2, RET: find variable's definition"))
--- a/lisp/info-look.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/info-look.el	Sat May 01 19:23:22 2004 +0000
@@ -887,11 +887,21 @@
                       ((string-equal item "gawk, versions of, information about, printing")
                        "gawk"))))))
 
+;; This misses some things which occur as node names but not in the
+;; index.  Unfortunately it also picks up the wrong one of multiple
+;; entries for the same term in some cases.  --fx
 (info-lookup-maybe-add-help
  :mode 'cfengine-mode
- :regexp "[[:alnum:]_]+"
- :doc-spec '(("(cfengine-Reference)Variable Index" nil
-	      "^ - [^:]+:[ ]+\\(\\[[^=]*=[ ]+\\)?" nil)))
+ :regexp "[[:alnum:]_]+\\(:?()\\)?"
+ :doc-spec '(("(cfengine-Reference)Variable Index"
+	      (lambda (item)
+		;; Index entries may be like `IsPlain()'
+		(if (string-match "\\([[:alnum:]_]+\\)()" item)
+		    (match-string 1 item)
+		  item))
+	      ;; This gets functions in evaluated classes.  Other
+	      ;; possible patterns don't seem to work too well.
+	      "`" "(")))
 
 (provide 'info-look)
 
--- a/lisp/international/titdic-cnv.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/international/titdic-cnv.el	Sat May 01 19:23:22 2004 +0000
@@ -1113,21 +1113,25 @@
 	name title dicfile coding quailfile converter copyright
 	dicbuf)
     (while tail
-      (when (or (string-match (nth 2 (car tail)) filename)
-		;; MS-DOS filesystem truncates file names to 8+3
-		;; limits, so "cangjie-table.cns" becomes
-		;; "cangjie-.cns", and the above string-match fails.
-		;; Give DOS users a chance...
-		(and (fboundp 'msdos-long-file-names)
-		     (not (msdos-long-file-names))
-		     (string-match (dos-8+3-filename (nth 2 (car tail)))
-				   filename)))
-	(setq slot (car tail)
-	      name (car slot)
+      (setq slot (car tail)
+	    dicfile (nth 2 slot)
+	    quailfile (nth 4 slot))
+      (when (and (or (string-match dicfile filename)
+		     ;; MS-DOS filesystem truncates file names to 8+3
+		     ;; limits, so "cangjie-table.cns" becomes
+		     ;; "cangjie-.cns", and the above string-match
+		     ;; fails.  Give DOS users a chance...
+		     (and (fboundp 'msdos-long-file-names)
+			  (not (msdos-long-file-names))
+			  (string-match (dos-8+3-filename dicfile) filename)))
+		 (if (file-newer-than-file-p
+		      filename (expand-file-name quailfile dirname))
+		     t
+		   (message "%s is up to date" quailfile)
+		   nil))
+	(setq name (car slot)
 	      title (nth 1 slot)
-	      dicfile (nth 2 slot)
 	      coding (nth 3 slot)
-	      quailfile (nth 4 slot)
 	      converter (nth 5 slot)
 	      copyright (nth 6 slot))
 	(message "Converting %s to %s..." dicfile quailfile)
--- a/lisp/isearch.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/isearch.el	Sat May 01 19:23:22 2004 +0000
@@ -294,7 +294,9 @@
     (define-key map " " 'isearch-whitespace-chars)
     (define-key map [?\S-\ ] 'isearch-whitespace-chars)
 
-    (define-key map "\C-w" 'isearch-yank-word-or-char)
+    (define-key map "\C-b" 'isearch-del-char)
+    (define-key map "\C-f" 'isearch-yank-char)
+    (define-key map "\C-w" 'isearch-yank-word)
     (define-key map "\C-y" 'isearch-yank-line)
 
     ;; Define keys for regexp chars * ? |.
@@ -448,12 +450,15 @@
 As you type characters, they add to the search string and are found.
 The following non-printing keys are bound in `isearch-mode-map'.
 
-Type \\[isearch-delete-char] to cancel characters from end of search string.
+Type \\[isearch-delete-char] to cancel last input item from end of search string.
+Type \\[isearch-del-char] to cancel last character from end of search string.
 Type \\[isearch-exit] to exit, leaving point at location found.
 Type LFD (C-j) to match end of line.
 Type \\[isearch-repeat-forward] to search again forward,\
  \\[isearch-repeat-backward] to search again backward.
-Type \\[isearch-yank-word-or-char] to yank word from buffer onto end of search\
+Type \\[isearch-yank-char] to yank character from buffer onto end of search\
+ string and search for it.
+Type \\[isearch-yank-word] to yank word from buffer onto end of search\
  string and search for it.
 Type \\[isearch-yank-line] to yank rest of line onto end of search string\
  and search for it.
@@ -486,7 +491,7 @@
 you want to use.
 
 The above keys, bound in `isearch-mode-map', are often controlled by
- options; do M-x apropos on search-.* to find them.
+ options; do \\[apropos] on search-.* to find them.
 Other control and meta characters terminate the search
  and are then executed normally (depending on `search-exit-option').
 Likewise for function keys and mouse button events.
@@ -789,7 +794,7 @@
 \\[isearch-ring-retreat-edit] to replace the search string with the previous item in the search ring.
 \\[isearch-complete-edit] to complete the search string using the search ring.
 \\<isearch-mode-map>
-If first char entered is \\[isearch-yank-word-or-char], then do word search instead."
+If first char entered is \\[isearch-yank-word], then do word search instead."
 
   ;; This code is very hairy for several reasons, explained in the code.
   ;; Mainly, isearch-mode must be terminated while editing and then restarted.
@@ -1053,6 +1058,16 @@
     (isearch-pop-state))
   (isearch-update))
 
+(defun isearch-del-char ()
+  "Discard last character and move point back.
+If there is no previous character, just beep."
+  (interactive)
+  (if (equal isearch-string "")
+      (ding)
+    (setq isearch-string (substring isearch-string 0 -1)
+          isearch-message (mapconcat 'isearch-text-char-description
+                                     isearch-string "")))
+  (isearch-search-and-update))
 
 (defun isearch-yank-string (string)
   "Pull STRING into search string."
@@ -1114,7 +1129,7 @@
      (buffer-substring-no-properties (point) (funcall jumpform)))))
 
 (defun isearch-yank-char ()
-  "Pull next letter from buffer into search string."
+  "Pull next character from buffer into search string."
   (interactive)
   (isearch-yank-internal (lambda () (forward-char 1) (point))))
 
@@ -1142,9 +1157,8 @@
 (defun isearch-search-and-update ()
   ;; Do the search and update the display.
   (when (or isearch-success
-	    ;; unsuccessful regexp search may become
-	    ;;  successful by addition of characters which
-	    ;;  make isearch-string valid
+	    ;; Unsuccessful regexp search may become successful by
+	    ;; addition of characters which make isearch-string valid
 	    isearch-regexp
 	    ;; If the string was found but was completely invisible,
 	    ;; it might now be partly visible, so try again.
@@ -1471,7 +1485,9 @@
            (command-execute scroll-command)
            (let ((ab-bel (isearch-string-out-of-window isearch-point)))
              (if ab-bel
-                 (isearch-back-into-window (eq ab-bel 'above) isearch-point)))
+                 (isearch-back-into-window (eq ab-bel 'above) isearch-point)
+               (or (eq (point) isearch-point)
+                   (goto-char isearch-point))))
            (isearch-update))
 	  (search-exit-option
 	   (let (window)
--- a/lisp/menu-bar.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/menu-bar.el	Sat May 01 19:23:22 2004 +0000
@@ -893,7 +893,7 @@
   '("--"))
 (define-key menu-bar-options-menu [cua-mode]
   (menu-bar-make-mm-toggle cua-mode
-			   "CUA-style cut and paste"
+			   "C-x/C-c/C-v cut and paste (CUA)"
 			   "Use C-z/C-x/C-c/C-v keys for undo/cut/copy/paste"))
 
 (define-key menu-bar-options-menu [case-fold-search]
--- a/lisp/mouse.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/mouse.el	Sat May 01 19:23:22 2004 +0000
@@ -42,6 +42,12 @@
   "*If non-nil, mouse yank commands yank at point instead of at click."
   :type 'boolean
   :group 'mouse)
+
+(defcustom mouse-drag-copy-region t
+  "*If non-nil, mouse drag copies region to kill-ring."
+  :type 'boolean
+  :group 'mouse)
+
 
 ;; Provide a mode-specific menu on a mouse button.
 
@@ -612,8 +618,9 @@
     ;; Don't set this-command to kill-region, so that a following
     ;; C-w will not double the text in the kill ring.
     ;; Ignore last-command so we don't append to a preceding kill.
-    (let (this-command last-command deactivate-mark)
-      (copy-region-as-kill (mark) (point)))
+    (when mouse-drag-copy-region
+      (let (this-command last-command deactivate-mark)
+	(copy-region-as-kill (mark) (point))))
     (mouse-set-region-1)))
 
 (defun mouse-set-region-1 ()
@@ -827,8 +834,9 @@
 		  (push-mark region-commencement t t)
 		  (goto-char region-termination)
 		  ;; Don't let copy-region-as-kill set deactivate-mark.
-		  (let (deactivate-mark)
-		    (copy-region-as-kill (point) (mark t)))
+		  (when mouse-drag-copy-region
+		    (let (deactivate-mark)
+		      (copy-region-as-kill (point) (mark t))))
 		  (let ((buffer (current-buffer)))
 		    (mouse-show-mark)
 		    ;; mouse-show-mark can call read-event,
--- a/lisp/outline.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/outline.el	Sat May 01 19:23:22 2004 +0000
@@ -216,6 +216,9 @@
 (defvar outline-mode-hook nil
   "*This hook is run when outline mode starts.")
 
+(defvar outline-blank-line nil
+  "*Non-nil means to leave unhidden blank line before heading.")
+
 ;;;###autoload
 (define-derived-mode outline-mode text-mode "Outline"
   "Set major mode for editing outlines with selective display.
@@ -349,7 +352,7 @@
   (if (re-search-forward (concat "\n\\(?:" outline-regexp "\\)")
 			 nil 'move)
       (goto-char (match-beginning 0)))
-  (if (and (bolp) (not (bobp)))
+  (if (and (bolp) (or outline-blank-line (eobp)) (not (bobp)))
       (forward-char -1)))
 
 (defun outline-next-heading ()
@@ -706,8 +709,8 @@
   "Hide the body directly following this heading."
   (interactive)
   (outline-back-to-heading)
-  (outline-end-of-heading)
   (save-excursion
+    (outline-end-of-heading)
     (outline-flag-region (point) (progn (outline-next-preface) (point)) t)))
 
 (defun show-entry ()
@@ -770,9 +773,10 @@
 (defun outline-show-heading ()
   "Show the current heading and move to its end."
   (outline-flag-region (- (point)
-			  (if (bobp) 0
-			    (if (eq (char-before (1- (point))) ?\n)
-				2 1)))
+ 			  (if (bobp) 0
+ 			    (if (and outline-blank-line
+                                     (eq (char-before (1- (point))) ?\n))
+ 				2 1)))
 		       (progn (outline-end-of-heading) (point))
 		       nil))
 
@@ -841,9 +845,9 @@
 	(progn
 	  ;; Go to end of line before heading
 	  (forward-char -1)
-	  (if (bolp)
-	      ;; leave blank line before heading
-	      (forward-char -1))))))
+          (if (and outline-blank-line (bolp))
+ 	      ;; leave blank line before heading
+ 	      (forward-char -1))))))
 
 (defun show-branches ()
   "Show all subheadings of this heading, but not their bodies."
@@ -884,6 +888,8 @@
 With argument, move up ARG levels.
 If INVISIBLE-OK is non-nil, also consider invisible lines."
   (interactive "p")
+  (and (eq this-command 'outline-up-heading)
+       (or (eq last-command 'outline-up-heading) (push-mark)))
   (outline-back-to-heading invisible-ok)
   (let ((start-level (funcall outline-level)))
     (if (eq start-level 1)
--- a/lisp/progmodes/cfengine.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/progmodes/cfengine.el	Sat May 01 19:23:22 2004 +0000
@@ -1,6 +1,6 @@
 ;;; cfengine.el --- mode for editing Cfengine files
 
-;; Copyright (C) 2003 Free Software Foundation, Inc.
+;; Copyright (C) 2003, 2004  Free Software Foundation, Inc.
 
 ;; Author: Dave Love <fx@gnu.org>
 ;; Keywords: languages
@@ -102,7 +102,8 @@
 (defun cfengine-beginning-of-defun ()
   "`beginning-of-defun' function for Cfengine mode.
 Treats actions as defuns."
-  (end-of-line)
+  (unless (<= (current-column) (current-indentation))
+    (end-of-line))
   (if (re-search-backward "^[[:alpha:]]+: *$" nil t)
       (beginning-of-line)
     (goto-char (point-min)))
@@ -113,7 +114,7 @@
 Treats actions as defuns."
   (end-of-line)
   (if (re-search-forward "^[[:alpha:]]+: *$" nil t)
-      (progn (forward-line -1) (end-of-line))
+      (beginning-of-line)
     (goto-char (point-max)))
   t)
 
--- a/lisp/progmodes/compile.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/progmodes/compile.el	Sat May 01 19:23:22 2004 +0000
@@ -492,6 +492,7 @@
 
 
 ;; Used for compatibility with the old compile.el.
+(defvaralias 'compilation-last-buffer 'next-error-last-buffer)
 (defvar compilation-parsing-end (make-marker))
 (defvar compilation-parse-errors-function nil)
 (defvar compilation-error-list nil)
@@ -1473,17 +1474,19 @@
     loc))
 
 (defcustom compilation-context-lines 0
-  "*Display this many lines of leading context before message."
-  :type 'integer
+  "*Display this many lines of leading context before message.
+If nil, don't scroll the compilation output window."
+  :type '(choice integer (const :tag "No window scrolling" nil))
   :group 'compilation
   :version "21.4")
 
 (defsubst compilation-set-window (w mk)
   "Align the compilation output window W with marker MK near top."
-  (set-window-start w (save-excursion
-			(goto-char mk)
-			(beginning-of-line (- 1 compilation-context-lines))
-			(point)))
+  (if (integerp compilation-context-lines)
+      (set-window-start w (save-excursion
+                            (goto-char mk)
+                            (beginning-of-line (- 1 compilation-context-lines))
+                            (point))))
   (set-window-point w mk))
 
 (defun compilation-goto-locus (msg mk end-mk)
--- a/lisp/progmodes/f90.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/progmodes/f90.el	Sat May 01 19:23:22 2004 +0000
@@ -850,14 +850,16 @@
 
 (defsubst f90-get-present-comment-type ()
   "If point lies within a comment, return the string starting the comment.
-For example, \"!\" or \"!!\"."
+For example, \"!\" or \"!!\", followed by the appropriate amount of
+whitespace, if any."
+  ;; Include the whitespace for consistent auto-filling of comment blocks.
   (save-excursion
     (when (f90-in-comment)
       (beginning-of-line)
-      (re-search-forward "!+" (line-end-position))
+      (re-search-forward "!+[ \t]*" (line-end-position))
       (while (f90-in-string)
-        (re-search-forward "!+" (line-end-position)))
-      (match-string 0))))
+        (re-search-forward "!+[ \t]*" (line-end-position)))
+      (match-string-no-properties 0))))
 
 (defsubst f90-equal-symbols (a b)
   "Compare strings A and B neglecting case and allowing for nil value."
@@ -1519,6 +1521,7 @@
   (cond ((f90-in-string)
          (insert "&\n&"))
         ((f90-in-comment)
+         (delete-horizontal-space 'backwards) ; remove trailing whitespace
          (insert "\n" (f90-get-present-comment-type)))
         (t (insert "&")
            (or no-update (f90-update-line))
--- a/lisp/progmodes/fortran.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/progmodes/fortran.el	Sat May 01 19:23:22 2004 +0000
@@ -1700,8 +1700,7 @@
                   (while repeat
                     (setq repeat nil)
                     ;; Adapted from f90-find-breakpoint.
-                    (re-search-backward fortran-break-delimiters-re
-                                        (line-beginning-position))
+                    (re-search-backward fortran-break-delimiters-re bol)
                     (if (not fortran-break-before-delimiters)
                         (if (looking-at fortran-no-break-re)
                             ;; Deal with cases such as "**" split over
--- a/lisp/progmodes/python.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/progmodes/python.el	Sat May 01 19:23:22 2004 +0000
@@ -1141,6 +1141,14 @@
 print '_emacs_ok'"))
   (unless noshow (pop-to-buffer (setq python-buffer "*Python*"))))
 
+(defun python-send-command (command)
+  "Like `python-send-string' but resets `compilation-minor-mode'."
+  (let ((end (marker-position (process-mark (python-proc)))))
+    (compilation-forget-errors)
+    (python-send-string command)
+    (set-marker compilation-parsing-end end)
+    (setq compilation-last-buffer (current-buffer))))
+
 (defun python-send-region (start end)
   "Send the region to the inferior Python process."
   ;; The region is evaluated from a temporary file.  This avoids
@@ -1170,14 +1178,11 @@
     (write-region start end f t 'nomsg)
     (when python-buffer
       (with-current-buffer python-buffer
-	(let ((end (marker-position (process-mark (python-proc)))))
-	  (set (make-local-variable 'python-orig-start) orig-start)
-	  (set (make-local-variable 'compilation-error-list) nil)
-	  (let ((comint-input-filter-functions
-		 (delete 'python-input-filter comint-input-filter-functions)))
-	    (python-send-string command))
-	  (set-marker compilation-parsing-end end)
-	  (setq compilation-last-buffer (current-buffer)))))))
+	(set (make-local-variable 'python-orig-start) orig-start)
+	(let ((comint-input-filter-functions
+	       ;; Don't reset python-orig-start.
+	       (remq 'python-input-filter comint-input-filter-functions)))
+	  (python-send-command command))))))
 
 (defun python-send-string (string)
   "Evaluate STRING in inferior Python process."
@@ -1242,25 +1247,17 @@
 				   (file-name-nondirectory file-name)))
   (when python-buffer
     (with-current-buffer python-buffer
-      (let ((end (marker-position (process-mark (python-proc)))))
-	(set (make-local-variable 'compilation-error-list) nil)
-	;; (set (make-local-variable 'compilation-old-error-list) nil)
-	(let ((comint-input-filter-functions
-	       (delete 'python-input-filter comint-input-filter-functions)))
-	  (set (make-local-variable 'python-orig-start) nil)
-	  ;; Fixme: I'm not convinced by this logic from python-mode.el.
-	  (python-send-string
-	   (if (string-match "\\.py\\'" file-name)
-	       ;; Fixme: make sure the directory is in the path list
-	       (let ((module (file-name-sans-extension
-			      (file-name-nondirectory file-name))))
-		 (format "\
+      ;; Fixme: I'm not convinced by this logic from python-mode.el.
+      (python-send-command
+       (if (string-match "\\.py\\'" file-name)
+	   ;; Fixme: make sure the directory is in the path list
+	   (let ((module (file-name-sans-extension
+			  (file-name-nondirectory file-name))))
+	     (format "\
 if globals().has_key(%S): reload(%s)
 else: import %s
 " module module module))
-	     (format "execfile('%s')" file-name))))
-	(set-marker compilation-parsing-end end)
-	(setq compilation-last-buffer (current-buffer))))))
+	 (format "execfile('%s')" file-name))))))
 
 ;; Fixme: Should this start a process if there isn't one?  (Unlike cmuscheme.)
 (defun python-proc ()
--- a/lisp/progmodes/sql.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/progmodes/sql.el	Sat May 01 19:23:22 2004 +0000
@@ -1,11 +1,12 @@
 ;;; sql.el --- specialized comint.el for SQL interpreters
 
-;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003  Free Software Foundation, Inc.
+;; Copyright (C) 1998,99,2000,01,02,03,04  Free Software Foundation, Inc.
 
 ;; Author: Alex Schroeder <alex@gnu.org>
 ;; Maintainer: Michael Mauger <mmaug@yahoo.com>
-;; Version: 1.8.0
+;; Version: 2.0.0
 ;; Keywords: comm languages processes
+;; URL: http://savannah.gnu.org/cgi-bin/viewcvs/emacs/emacs/lisp/progmodes/sql.el
 ;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode
 
 ;; This file is part of GNU Emacs.
@@ -101,7 +102,7 @@
 
 ;;     (const :tag "XyzDB" xyz)
 
-;; 2) Add an entry to the `sql-product-support' list.
+;; 2) Add an entry to the `sql-product-alist' list.
 
 ;;     (xyz
 ;;      :font-lock sql-mode-xyz-font-lock-keywords
@@ -136,7 +137,7 @@
 ;;    using ANSI keywords.  See sql-mode-oracle-font-lock-keywords for
 ;;    a more complex example.
 
-;;     (defvar sql-mode-xyz-font-lock-keywords sql-mode-ansi-font-lock-keywords
+;;     (defvar sql-mode-xyz-font-lock-keywords nil
 ;;       "XyzDB SQL keywords used by font-lock.")
 
 ;; 6) Add a product highlighting function.
@@ -192,6 +193,7 @@
 
 ;;; Thanks to all the people who helped me out:
 
+;; Alex Schroeder <alex@gnu.org>
 ;; Kai Blauberg <kai.blauberg@metla.fi>
 ;; <ibalaban@dalet.com>
 ;; Yair Friedman <yfriedma@JohnBryce.Co.Il>
@@ -199,6 +201,7 @@
 ;; nino <nino@inform.dk>
 ;; Berend de Boer <berend@pobox.com>
 ;; Michael Mauger <mmaug@yahoo.com>
+;; Adam Jenkins <adam@thejenkins.org>
 
 
 
@@ -209,6 +212,8 @@
 (eval-when-compile
   (require 'regexp-opt))
 (require 'custom)
+(eval-when-compile ;; needed in Emacs 19, 20
+  (setq max-specpdl-size 2000))
 
 ;;; Allow customization
 
@@ -264,7 +269,7 @@
 (defvar sql-interactive-product nil
   "Product under `sql-interactive-mode'.")
 
-(defvar sql-product-support
+(defvar sql-product-alist
   '((ansi
      :font-lock sql-mode-ansi-font-lock-keywords)
     (db2
@@ -319,9 +324,9 @@
      :syntax-alist ((?$ . "w") (?# . "w")))
     (postgres
      :font-lock sql-mode-postgres-font-lock-keywords
-     :sqli-login (database server)
+     :sqli-login (user database server)
      :sqli-connect sql-connect-postgres
-     :sqli-prompt-regexp "^.*> *"
+     :sqli-prompt-regexp "^.*[#>] *"
      :sqli-prompt-length 5)
     (solid
      :font-lock sql-mode-solid-font-lock-keywords
@@ -372,10 +377,12 @@
                         database.  Do product specific
                         configuration of comint in this function.
 
- :sqli-prompt-regexp    a regular expression string that matches the
-                        prompt issued by the product interpreter.
-
- :sqli-prompt-length    the length of the prompt on the line.
+ :sqli-prompt-regexp    a regular expression string that matches
+                        the prompt issued by the product
+                        interpreter.  (Not needed in 21.3+)
+
+ :sqli-prompt-length    the length of the prompt on the line.(Not
+                        needed in 21.3+)
 
  :syntax-alist          an alist of syntax table entries to enable
                         special character treatment by font-lock and
@@ -412,14 +419,14 @@
 
 (defvar sql-imenu-generic-expression
   ;; Items are in reverse order because they are rendered in reverse.
-  '(("Rules/Defaults" "^\\s-*create\\s-+\\(rule\\|default\\)\\s-+\\(\\w+\\)" 2)
-    ("Sequences" "^\\s-*create\\s-+sequence\\s-+\\(\\w+\\)" 1)
-    ("Triggers" "^\\s-*\\(create\\s-+\\(or\\s-+replace\\s-+\\)?\\)?trigger\\s-+\\(\\w+\\)" 3)
-    ("Functions" "^\\s-*\\(create\\s-+\\(or\\s-+replace\\s-+\\)?\\)?function\\s-+\\(\\w+\\)" 3)
-    ("Procedures" "^\\s-*\\(create\\s-+\\(or\\s-+replace\\s-+\\)?\\)?proc\\(edure\\)?\\s-+\\(\\w+\\)" 4)
-    ("Packages" "^\\s-*create\\s-+\\(or\\s-+replace\\s-+\\)?package\\s-+\\(body\\s-+\\)?\\(\\w+\\)" 3)
-    ("Indexes" "^\\s-*create\\s-+index\\s-+\\(\\w+\\)" 1)
-    ("Tables/Views" "^\\s-*create\\s-+\\(\\(global\\s-+\\)?\\(temporary\\s-+\\)?table\\|view\\)\\s-+\\(\\w+\\)" 4))
+  '(("Rules/Defaults" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*\\(rule\\|default\\)\\s-+\\(\\w+\\)" 3)
+    ("Sequences" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*sequence\\s-+\\(\\w+\\)" 2)
+    ("Triggers" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*trigger\\s-+\\(\\w+\\)" 2)
+    ("Functions" "^\\s-*\\(create\\s-+\\(\\w+\\s-+\\)*\\)?function\\s-+\\(\\w+\\)" 3)
+    ("Procedures" "^\\s-*\\(create\\s-+\\(\\w+\\s-+\\)*\\)?proc\\(edure\\)?\\s-+\\(\\w+\\)" 4)
+    ("Packages" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*package\\s-+\\(body\\s-+\\)?\\(\\w+\\)" 3)
+    ("Indexes" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*index\\s-+\\(\\w+\\)" 2)
+    ("Tables/Views" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*\\(table\\|view\\)\\s-+\\(\\w+\\)" 3))
   "Define interesting points in the SQL buffer for `imenu'.
 
 This is used to set `imenu-generic-expression' when SQL mode is
@@ -686,6 +693,18 @@
 
 ;;; Variables which do not need customization
 
+(defvar sql-xemacs-p
+  (string-match "XEmacs\\|Lucid" emacs-version)
+  "Is this a non-GNU Emacs?")
+
+(defvar sql-emacs19-p
+  (string-match "GNU Emacs 19" emacs-version)
+  "Is this a GNU Emacs 19?")
+
+(defvar sql-emacs20-p
+  (string-match "20" emacs-version)
+  "Is this a GNU Emacs 20?")
+
 (defvar sql-user-history nil
   "History of usernames used.")
 
@@ -745,6 +764,7 @@
   (let ((map (make-sparse-keymap)))
     (define-key map (kbd "C-c C-c") 'sql-send-paragraph)
     (define-key map (kbd "C-c C-r") 'sql-send-region)
+    (define-key map (kbd "C-c C-s") 'sql-send-string)
     (define-key map (kbd "C-c C-b") 'sql-send-buffer)
     map)
   "Mode map used for `sql-mode'.")
@@ -764,6 +784,7 @@
 				       (get-buffer-process sql-buffer))]
    ["Send Buffer" sql-send-buffer (and (buffer-live-p sql-buffer)
 				       (get-buffer-process sql-buffer))]
+   ["Send String" sql-send-string t]
    ["--" nil nil]
    ["Start SQLi session" sql-product-interactive (sql-product-feature :sqli-connect)]
    ["Show SQLi buffer" sql-show-sqli-buffer t]
@@ -792,7 +813,7 @@
     ["Linter" sql-highlight-linter-keywords
      :style radio
      :selected (eq sql-product 'linter)]
-    ["Microsoft" sql-highlight-ms-keywords
+    ["MS SQLServer" sql-highlight-ms-keywords
      :style radio
      :selected (eq sql-product 'ms)]
     ["MySQL" sql-highlight-mysql-keywords
@@ -828,24 +849,24 @@
 
 (defvar sql-mode-abbrev-table nil
   "Abbrev table used in `sql-mode' and `sql-interactive-mode'.")
-(if sql-mode-abbrev-table
-    ()
-  (let ((nargs (cdr (subr-arity (symbol-function 'define-abbrev))))
-	d-a)
+(unless sql-mode-abbrev-table
+  (define-abbrev-table 'sql-mode-abbrev-table nil)
+  (mapcar
     ;; In Emacs 21.3+, provide SYSTEM-FLAG to define-abbrev.
-    (setq d-a
-	  (if (>= nargs 6)
-	      '(lambda (name expansion) (define-abbrev sql-mode-abbrev-table name expansion nil 0 t))
-	    '(lambda (name expansion) (define-abbrev sql-mode-abbrev-table name expansion))))
-
-    (define-abbrev-table 'sql-mode-abbrev-table nil)
-    (funcall d-a "ins" "insert")
-    (funcall d-a "upd" "update")
-    (funcall d-a "del" "delete")
-    (funcall d-a "sel" "select")
-    (funcall d-a "proc" "procedure")
-    (funcall d-a "func" "function")
-    (funcall d-a "cr" "create")))
+   '(lambda (abbrev)
+      (let ((name (car abbrev))
+	    (expansion (cdr abbrev)))
+	(condition-case nil
+	    (define-abbrev sql-mode-abbrev-table name expansion nil 0 t)
+	  (error
+	   (define-abbrev sql-mode-abbrev-table name expansion)))))
+   '(("ins" "insert")
+    ("upd" "update")
+    ("del" "delete")
+    ("sel" "select")
+    ("proc" "procedure")
+    ("func" "function")
+    ("cr" "create"))))
 
 ;; Syntax Table
 
@@ -855,7 +876,7 @@
     (modify-syntax-entry ?/ ". 14" table)
     (modify-syntax-entry ?* ". 23" table)
     ;; double-dash starts comment
-    (if (string-match "XEmacs\\|Lucid" emacs-version)
+    (if sql-xemacs-p
 	(modify-syntax-entry ?- ". 56" table)
       (modify-syntax-entry ?- ". 12b" table))
     ;; newline and formfeed end coments
@@ -871,55 +892,136 @@
 ;; Font lock support
 
 (defvar sql-mode-font-lock-object-name
-  (list (concat "^\\s-*\\(create\\(\\s-+or\\s-+replace\\)?\\|drop\\|alter\\)?\\s-+"
-		"\\(\\(global\\s-+\\)?\\(temporary\\s-+\\)?table\\|view\\|package\\(\\s-+body\\)?\\|"
-		"proc\\(edure\\)?\\|function\\|trigger\\|sequence\\|rule\\|default\\)\\s-+\\(\\w+\\)")
-	8 'font-lock-function-name-face)
-
-  "Pattern to match the names of top-level objects in a CREATE,
-DROP or ALTER statement.
-
-The format of variable should be a valid `font-lock-keywords'
-entry.")
+  (list (concat "^\\s-*\\(create\\|drop\\|alter\\)\\s-+" ;; lead off with CREATE, DROP or ALTER
+		"\\(\\w+\\s-+\\)*"  ;; optional intervening keywords
+		"\\(table\\|view\\|package\\(\\s-+body\\)?\\|proc\\(edure\\)?"
+		"\\|function\\|trigger\\|sequence\\|rule\\|default\\)\\s-+"
+		"\\(\\w+\\)")
+	6 'font-lock-function-name-face)
+
+  "Pattern to match the names of top-level objects.
+
+The pattern matches the name in a CREATE, DROP or ALTER
+statement.  The format of variable should be a valid
+`font-lock-keywords' entry.")
+
+(defvar sql-builtin-face
+  (if sql-xemacs-p
+      ;; XEmacs doesn't have the builtin face
+      'font-lock-preprocessor-face
+    ;; GNU Emacs 19 doesn't either
+    (if sql-emacs19-p
+	'font-lock-keyword-face
+      ;; Emacs 2x
+      'font-lock-builtin-face))
+  "Builtin face for font-lock in SQL mode.")
+
+(defvar sql-doc-face
+  (if (or sql-xemacs-p
+	  sql-emacs19-p
+	  sql-emacs20-p)
+      'font-lock-string-face
+    'font-lock-doc-face)
+  "Documentation face for font-lock in SQL mode.")
+
+(defmacro sql-keywords-re (&rest keywords)
+  "Compile-time generation of regexp matching any one of KEYWORDS."
+  `(eval-when-compile
+     (concat "\\b"
+	     (regexp-opt ',keywords t)
+	     "\\b")))
 
 (defvar sql-mode-ansi-font-lock-keywords
-  (let ((ansi-keywords (eval-when-compile
-			 (concat "\\b"
-				 (regexp-opt '(
-
-"authorization" "avg" "begin" "close" "cobol" "commit"
-"continue" "count" "declare" "double" "end" "escape"
-"exec" "fetch" "foreign" "fortran" "found" "go" "goto" "indicator"
-"key" "language" "max" "min" "module" "numeric" "open" "pascal" "pli"
-"precision" "primary" "procedure" "references" "rollback"
-"schema" "section" "some" "sqlcode" "sqlerror" "sum" "work"
-
-) t) "\\b")))
-	(ansi-reserved-words (eval-when-compile
-			       (concat "\\b"
-				       (regexp-opt '(
-
-"all" "and" "any" "as" "asc" "between" "by" "check" "create"
-"current" "default" "delete" "desc" "distinct" "exists" "float" "for"
-"from" "grant" "group" "having" "in" "insert" "into" "is"
-"like" "not" "null" "of" "on" "option" "or" "order" "privileges"
-"public" "select" "set" "table" "to" "union" "unique"
-"update" "user" "values" "view" "where" "with"
-
-) t) "\\b")))
-	(ansi-types (eval-when-compile
-		      (concat "\\b"
-			      (regexp-opt '(
-
-;; ANSI Keywords that look like types
-"character" "cursor" "dec" "int" "real"
-;; ANSI Reserved Word that look like types
-"char" "integer" "smallint"
-
-) t) "\\b"))))
-    (list (cons ansi-keywords 'font-lock-keyword-face)
-		(cons ansi-reserved-words 'font-lock-keyword-face)
-	  (cons ansi-types 'font-lock-type-face)))
+  (let ((ansi-funcs (sql-keywords-re
+"abs" "avg" "bit_length" "cardinality" "cast" "char_length"
+"character_length" "coalesce" "convert" "count" "current_date"
+"current_path" "current_role" "current_time" "current_timestamp"
+"current_user" "extract" "localtime" "localtimestamp" "lower" "max"
+"min" "mod" "nullif" "octet_length" "overlay" "placing" "session_user"
+"substring" "sum" "system_user" "translate" "treat" "trim" "upper"
+"user"
+))
+
+	(ansi-non-reserved (sql-keywords-re
+"ada" "asensitive" "assignment" "asymmetric" "atomic" "between"
+"bitvar" "called" "catalog_name" "chain" "character_set_catalog"
+"character_set_name" "character_set_schema" "checked" "class_origin"
+"cobol" "collation_catalog" "collation_name" "collation_schema"
+"column_name" "command_function" "command_function_code" "committed"
+"condition_number" "connection_name" "constraint_catalog"
+"constraint_name" "constraint_schema" "contains" "cursor_name"
+"datetime_interval_code" "datetime_interval_precision" "defined"
+"definer" "dispatch" "dynamic_function" "dynamic_function_code"
+"existing" "exists" "final" "fortran" "generated" "granted"
+"hierarchy" "hold" "implementation" "infix" "insensitive" "instance"
+"instantiable" "invoker" "key_member" "key_type" "length" "m"
+"message_length" "message_octet_length" "message_text" "method" "more"
+"mumps" "name" "nullable" "number" "options" "overlaps" "overriding"
+"parameter_mode" "parameter_name" "parameter_ordinal_position"
+"parameter_specific_catalog" "parameter_specific_name"
+"parameter_specific_schema" "pascal" "pli" "position" "repeatable"
+"returned_length" "returned_octet_length" "returned_sqlstate"
+"routine_catalog" "routine_name" "routine_schema" "row_count" "scale"
+"schema_name" "security" "self" "sensitive" "serializable"
+"server_name" "similar" "simple" "source" "specific_name" "style"
+"subclass_origin" "sublist" "symmetric" "system" "table_name"
+"transaction_active" "transactions_committed"
+"transactions_rolled_back" "transform" "transforms" "trigger_catalog"
+"trigger_name" "trigger_schema" "type" "uncommitted" "unnamed"
+"user_defined_type_catalog" "user_defined_type_name"
+"user_defined_type_schema"
+))
+
+	(ansi-reserved (sql-keywords-re
+"absolute" "action" "add" "admin" "after" "aggregate" "alias" "all"
+"allocate" "alter" "and" "any" "are" "as" "asc" "assertion" "at"
+"authorization" "before" "begin" "both" "breadth" "by" "call"
+"cascade" "cascaded" "case" "catalog" "check" "class" "close"
+"collate" "collation" "column" "commit" "completion" "connect"
+"connection" "constraint" "constraints" "constructor" "continue"
+"corresponding" "create" "cross" "cube" "current" "cursor" "cycle"
+"data" "day" "deallocate" "declare" "default" "deferrable" "deferred"
+"delete" "depth" "deref" "desc" "describe" "descriptor" "destroy"
+"destructor" "deterministic" "diagnostics" "dictionary" "disconnect"
+"distinct" "domain" "drop" "dynamic" "each" "else" "end" "equals"
+"escape" "every" "except" "exception" "exec" "execute" "external"
+"false" "fetch" "first" "for" "foreign" "found" "free" "from" "full"
+"function" "general" "get" "global" "go" "goto" "grant" "group"
+"grouping" "having" "host" "hour" "identity" "ignore" "immediate" "in"
+"indicator" "initialize" "initially" "inner" "inout" "input" "insert"
+"intersect" "into" "is" "isolation" "iterate" "join" "key" "language"
+"last" "lateral" "leading" "left" "less" "level" "like" "limit"
+"local" "locator" "map" "match" "minute" "modifies" "modify" "module"
+"month" "names" "natural" "new" "next" "no" "none" "not" "null" "of"
+"off" "old" "on" "only" "open" "operation" "option" "or" "order"
+"ordinality" "out" "outer" "output" "pad" "parameter" "parameters"
+"partial" "path" "postfix" "prefix" "preorder" "prepare" "preserve"
+"primary" "prior" "privileges" "procedure" "public" "read" "reads"
+"recursive" "references" "referencing" "relative" "restrict" "result"
+"return" "returns" "revoke" "right" "role" "rollback" "rollup"
+"routine" "rows" "savepoint" "schema" "scroll" "search" "second"
+"section" "select" "sequence" "session" "set" "sets" "size" "some"
+"space" "specific" "specifictype" "sql" "sqlexception" "sqlstate"
+"sqlwarning" "start" "state" "statement" "static" "structure" "table"
+"temporary" "terminate" "than" "then" "timezone_hour"
+"timezone_minute" "to" "trailing" "transaction" "translation"
+"trigger" "true" "under" "union" "unique" "unknown" "unnest" "update"
+"usage" "using" "value" "values" "variable" "view" "when" "whenever"
+"where" "with" "without" "work" "write" "year"
+))
+
+	(ansi-types (sql-keywords-re
+"array" "binary" "bit" "blob" "boolean" "char" "character" "clob"
+"date" "dec" "decimal" "double" "float" "int" "integer" "interval"
+"large" "national" "nchar" "nclob" "numeric" "object" "precision"
+"real" "ref" "row" "scope" "smallint" "time" "timestamp" "varchar"
+"varying" "zone"
+)))
+
+    `((,ansi-non-reserved . font-lock-keyword-face)
+      (,ansi-reserved     . font-lock-keyword-face)
+      (,ansi-funcs        . ,sql-builtin-face)
+      (,ansi-types        . font-lock-type-face)))
 
   "ANSI SQL keywords used by font-lock.
 
@@ -930,66 +1032,156 @@
 add functions and PL/SQL keywords.")
 
 (defvar sql-mode-oracle-font-lock-keywords
-  (let ((oracle-keywords (eval-when-compile
-			   (concat "\\b"
-				   (regexp-opt '(
-;; Oracle (+ANSI) SQL keywords
-
-; ANSI keywords
-"authorization" "avg" "begin" "close" "cobol" "commit"
-"continue" "count" "declare" "double" "end" "escape"
-"exec" "fetch" "foreign" "fortran" "found" "go" "goto" "indicator"
-"key" "language" "max" "min" "module" "numeric" "open" "pascal" "pli"
-"precision" "primary" "procedure" "references" "rollback"
-"schema" "section" "some" "sqlcode" "sqlerror" "sum" "work"
-
-; ANSI reserved words
-"all" "and" "any" "as" "asc" "between" "by" "check" "create"
-"current" "default" "delete" "desc" "distinct" "exists" "float" "for"
-"from" "grant" "group" "having" "in" "insert" "into" "is"
-"like" "not" "null" "of" "on" "option" "or" "order" "privileges"
-"public" "select" "set" "table" "to" "union" "unique"
-"update" "user" "values" "view" "where" "with"
-
-"access" "add" "admin" "after" "allocate" "alter" "analyze" "archive"
-"archivelog" "audit" "authid" "backup" "become" "before" "block"
-"body" "cache" "cancel" "cascade" "change" "checkpoint" "cluster"
-"comment" "compile" "compress" "compute" "connect" "constraint"
-"constraints" "contents" "controlfile" "cross" "currval" "cycle"
-"database" "datafile" "dba" "deterministic" "disable" "dismount"
-"drop" "dump" "each" "else" "else" "elsif" "enable" "events" "except"
-"exceptions" "exclusive" "execute" "exit" "explain" "extent"
-"externally" "false" "file" "flush" "force" "freelist" "freelists"
-"full" "function" "global" "grant" "groups" "identified" "if"
-"immediate" "including" "increment" "index" "initial" "initrans"
-"inner" "instance" "intersect" "join" "layer" "left" "level" "link"
-"lists" "lock" "logfile" "long" "loop" "manage" "manual"
-"maxdatafiles" "maxextents" "maxinistances" "maxlogfiles"
-"maxloghistory" "maxlogmembers" "maxtrans" "maxvalue" "merge"
-"minextents" "minus" "minvalue" "mode" "modify" "mount" "natural"
-"new" "next" "nextval" "noarchivelog" "noaudit" "nocache" "nocompress"
-"nocycle" "nomaxvalue" "nominvalue" "none" "noorder" "noresetlogs"
-"normal" "nosort" "nowait" "off" "offline" "old" "online" "only"
-"optimal" "others" "out" "outer" "over" "own" "package" "parallel"
-"parallel_enable" "pctfree" "pctincrease" "pctused" "plan" "pragma"
-"preserve" "prior" "private" "profile" "quota" "raise" "raw" "read"
-"recover" "referencing" "rename" "replace" "resetlogs" "resource"
-"restrict_references" "restricted" "return" "returning" "reuse"
-"revoke" "right" "rnds" "rnps" "role" "roles" "row" "rowlabel"
-"rownum" "rows" "savepoint" "scn" "segment" "sequence" "session"
-"share" "shared" "size" "snapshot" "sort" "statement_id" "statistics"
-"stop" "storage" "subtype" "successful" "switch" "synonym" "sysdate"
-"system" "tables" "tablespace" "temporary" "then" "thread" "tracing"
-"transaction" "trigger" "triggers" "true" "truncate" "type" "uid"
-"under" "unlimited" "until" "use" "using" "validate" "when" "while"
-"wnds" "wnps" "write"
-
-) t) "\\b")))
-	(oracle-warning-words (eval-when-compile
-				 (concat "\\b"
-					 (regexp-opt '(
-;; PLSQL defined exceptions
-
+  (let ((oracle-functions (sql-keywords-re
+"abs" "acos" "add_months" "ascii" "asciistr" "asin" "atan" "atan2"
+"avg" "bfilename" "bin_to_num" "bitand" "cast" "ceil" "chartorowid"
+"chr" "coalesce" "compose" "concat" "convert" "corr" "cos" "cosh"
+"count" "covar_pop" "covar_samp" "cume_dist" "current_date"
+"current_timestamp" "current_user" "dbtimezone" "decode" "decompose"
+"dense_rank" "depth" "deref" "dump" "empty_clob" "existsnode" "exp"
+"extract" "extractvalue" "first" "first_value" "floor" "following"
+"from_tz" "greatest" "group_id" "grouping_id" "hextoraw" "initcap"
+"instr" "lag" "last" "last_day" "last_value" "lead" "least" "length"
+"ln" "localtimestamp" "lower" "lpad" "ltrim" "make_ref" "max" "min"
+"mod" "months_between" "new_time" "next_day" "nls_charset_decl_len"
+"nls_charset_id" "nls_charset_name" "nls_initcap" "nls_lower"
+"nls_upper" "nlssort" "ntile" "nullif" "numtodsinterval"
+"numtoyminterval" "nvl" "nvl2" "over" "path" "percent_rank"
+"percentile_cont" "percentile_disc" "power" "preceding" "rank"
+"ratio_to_report" "rawtohex" "rawtonhex" "reftohex" "regr_"
+"regr_avgx" "regr_avgy" "regr_count" "regr_intercept" "regr_r2"
+"regr_slope" "regr_sxx" "regr_sxy" "regr_syy" "replace" "round"
+"row_number" "rowidtochar" "rowidtonchar" "rpad" "rtrim"
+"sessiontimezone" "sign" "sin" "sinh" "soundex" "sqrt" "stddev"
+"stddev_pop" "stddev_samp" "substr" "sum" "sys_connect_by_path"
+"sys_context" "sys_dburigen" "sys_extract_utc" "sys_guid" "sys_typeid"
+"sys_xmlagg" "sys_xmlgen" "sysdate" "systimestamp" "tan" "tanh"
+"to_char" "to_clob" "to_date" "to_dsinterval" "to_lob" "to_multi_byte"
+"to_nchar" "to_nclob" "to_number" "to_single_byte" "to_timestamp"
+"to_timestamp_tz" "to_yminterval" "translate" "treat" "trim" "trunc"
+"tz_offset" "uid" "unbounded" "unistr" "updatexml" "upper" "user"
+"userenv" "var_pop" "var_samp" "variance" "vsize" "width_bucket" "xml"
+"xmlagg" "xmlattribute" "xmlcolattval" "xmlconcat" "xmlelement"
+"xmlforest" "xmlsequence" "xmltransform"
+))
+
+	(oracle-keywords (sql-keywords-re
+"abort" "access" "accessed" "account" "activate" "add" "admin"
+"advise" "after" "agent" "aggregate" "all" "allocate" "allow" "alter"
+"always" "analyze" "ancillary" "and" "any" "apply" "archive"
+"archivelog" "array" "as" "asc" "associate" "at" "attribute"
+"attributes" "audit" "authenticated" "authid" "authorization" "auto"
+"autoallocate" "automatic" "availability" "backup" "before" "begin"
+"behalf" "between" "binding" "bitmap" "block" "blocksize" "body"
+"both" "buffer_pool" "build" "by"  "cache" "call" "cancel"
+"cascade" "case" "category" "certificate" "chained" "change" "check"
+"checkpoint" "child" "chunk" "class" "clear" "clone" "close" "cluster"
+"column" "column_value" "columns" "comment" "commit" "committed"
+"compatibility" "compile" "complete" "composite_limit" "compress"
+"compute" "connect" "connect_time" "consider" "consistent"
+"constraint" "constraints" "constructor" "contents" "context"
+"continue" "controlfile" "corruption" "cost" "cpu_per_call"
+"cpu_per_session" "create" "cross" "cube" "current" "currval" "cycle"
+"dangling" "data" "database" "datafile" "datafiles" "day" "ddl"
+"deallocate" "debug" "default" "deferrable" "deferred" "definer"
+"delay" "delete" "demand" "desc" "determines" "deterministic"
+"dictionary" "dimension" "directory" "disable" "disassociate"
+"disconnect" "distinct" "distinguished" "distributed" "dml" "drop"
+"each" "element" "else" "enable" "end" "equals_path" "escape"
+"estimate" "except" "exceptions" "exchange" "excluding" "exists"
+"expire" "explain" "extent" "external" "externally"
+"failed_login_attempts" "fast" "file" "final" "finish" "flush" "for"
+"force" "foreign" "freelist" "freelists" "freepools" "fresh" "from"
+"full" "function" "functions" "generated" "global" "global_name"
+"globally" "grant" "group" "grouping" "groups" "guard" "hash"
+"hashkeys" "having" "heap" "hierarchy" "id" "identified" "identifier"
+"idle_time" "immediate" "in" "including" "increment" "index" "indexed"
+"indexes" "indextype" "indextypes" "indicator" "initial" "initialized"
+"initially" "initrans" "inner" "insert" "instance" "instantiable"
+"instead" "intersect" "into" "invalidate" "is" "isolation" "java"
+"join"  "keep" "key" "kill" "language" "left" "less" "level"
+"levels" "library" "like" "like2" "like4" "likec" "limit" "link"
+"list" "lob" "local" "location" "locator" "lock" "log" "logfile"
+"logging" "logical" "logical_reads_per_call"
+"logical_reads_per_session"  "managed" "management" "manual" "map"
+"mapping" "master" "matched" "materialized" "maxdatafiles"
+"maxextents" "maximize" "maxinstances" "maxlogfiles" "maxloghistory"
+"maxlogmembers" "maxsize" "maxtrans" "maxvalue" "member" "memory"
+"merge" "migrate" "minextents" "minimize" "minimum" "minus" "minvalue"
+"mode" "modify" "monitoring" "month" "mount" "move" "movement" "name"
+"named" "natural" "nested" "never" "new" "next" "nextval" "no"
+"noarchivelog" "noaudit" "nocache" "nocompress" "nocopy" "nocycle"
+"nodelay" "noforce" "nologging" "nomapping" "nomaxvalue" "nominimize"
+"nominvalue" "nomonitoring" "none" "noorder" "noparallel" "norely"
+"noresetlogs" "noreverse" "normal" "norowdependencies" "nosort"
+"noswitch" "not" "nothing" "notimeout" "novalidate" "nowait" "null"
+"nulls" "object" "of" "off" "offline" "oidindex" "old" "on" "online"
+"only" "open" "operator" "optimal" "option" "or" "order"
+"organization" "out" "outer" "outline" "overflow" "overriding"
+"package" "packages" "parallel" "parallel_enable" "parameters"
+"parent" "partition" "partitions" "password" "password_grace_time"
+"password_life_time" "password_lock_time" "password_reuse_max"
+"password_reuse_time" "password_verify_function" "pctfree"
+"pctincrease" "pctthreshold" "pctused" "pctversion" "percent"
+"performance" "permanent" "pfile" "physical" "pipelined" "plan"
+"post_transaction" "pragma" "prebuilt" "preserve" "primary" "private"
+"private_sga" "privileges" "procedure" "profile" "protection" "public"
+"purge" "query" "quiesce" "quota" "range" "read" "reads" "rebuild"
+"records_per_block" "recover" "recovery" "recycle" "reduced" "ref"
+"references" "referencing" "refresh" "register" "reject" "relational"
+"rely" "rename" "reset" "resetlogs" "resize" "resolve" "resolver"
+"resource" "restrict" "restrict_references" "restricted" "result"
+"resumable" "resume" "retention" "return" "returning" "reuse"
+"reverse" "revoke" "rewrite" "right" "rnds" "rnps" "role" "roles"
+"rollback" "rollup" "row" "rowdependencies" "rownum" "rows" "sample"
+"savepoint" "scan" "schema" "scn" "scope" "segment" "select"
+"selectivity" "self" "sequence" "serializable" "session"
+"sessions_per_user" "set" "sets" "settings" "shared" "shared_pool"
+"shrink" "shutdown" "siblings" "sid" "single" "size" "skip" "some"
+"sort" "source" "space" "specification" "spfile" "split" "standby"
+"start" "statement_id" "static" "statistics" "stop" "storage" "store"
+"structure" "subpartition" "subpartitions" "substitutable"
+"successful" "supplemental" "suspend" "switch" "switchover" "synonym"
+"sys" "system" "table" "tables" "tablespace" "tempfile" "template"
+"temporary" "test" "than" "then" "thread" "through" "time_zone"
+"timeout" "to" "trace" "transaction" "trigger" "triggers" "truncate"
+"trust" "type" "types" "unarchived" "under" "under_path" "undo"
+"uniform" "union" "unique" "unlimited" "unlock" "unquiesce"
+"unrecoverable" "until" "unusable" "unused" "update" "upgrade" "usage"
+"use" "using" "validate" "validation" "value" "values" "variable"
+"varray" "version" "view" "wait" "when" "whenever" "where" "with"
+"without" "wnds" "wnps" "work" "write" "xmldata" "xmlschema" "xmltype"
+))
+
+	(oracle-types (sql-keywords-re
+"bfile" "blob" "byte" "char" "character" "clob" "date" "dec" "decimal"
+"double" "float" "int" "integer" "interval" "long" "national" "nchar"
+"nclob" "number" "numeric" "nvarchar2" "precision" "raw" "real"
+"rowid" "second" "smallint" "time" "timestamp" "urowid" "varchar"
+"varchar2" "varying" "year" "zone"
+))
+
+	(plsql-functions (sql-keywords-re
+"%bulk_rowcount" "%found" "%isopen" "%notfound" "%rowcount" "%rowtype"
+"%type" "extend" "prior"
+))
+
+	(plsql-keywords (sql-keywords-re
+"autonomous_transaction" "bulk" "char_base" "collect" "constant"
+"cursor" "declare" "do" "elsif" "exception_init" "execute" "exit"
+"extends" "false" "fetch" "forall" "goto" "hour" "if" "interface"
+"loop" "minute" "number_base" "ocirowid" "opaque" "others" "rowtype"
+"separate" "serially_reusable" "sql" "sqlcode" "sqlerrm" "subtype"
+"the" "timezone_abbr" "timezone_hour" "timezone_minute"
+"timezone_region" "true" "varrying" "while"
+))
+
+	(plsql-type (sql-keywords-re
+"binary_integer" "boolean" "naturaln" "pls_integer" "positive"
+"positiven" "record" "signtype" "string"
+))
+
+	(plsql-warning (sql-keywords-re
 "access_into_null" "case_not_found" "collection_is_null"
 "cursor_already_open" "dup_val_on_index" "invalid_cursor"
 "invalid_number" "login_denied" "no_data_found" "not_logged_on"
@@ -997,15 +1189,11 @@
 "subscript_beyond_count" "subscript_outside_limit" "sys_invalid_rowid"
 "timeout_on_resource" "too_many_rows" "value_error" "zero_divide"
 "exception" "notfound"
-
-) t) "\\b")))
-
-	(oracle-sqlplus-commands
-	 (eval-when-compile
-	   (concat "^\\(\\("
-					 (regexp-opt '(
-;; SQL*Plus commands
-
+))
+
+	(sqlplus-commands
+	 (eval-when-compile (concat "^\\(\\("
+				    (regexp-opt '(
 "@" "@@" "accept" "append" "archive" "attribute" "break"
 "btitle" "change" "clear" "column" "connect" "copy" "define"
 "del" "describe" "disconnect" "edit" "execute" "exit" "get" "help"
@@ -1040,73 +1228,16 @@
    "timi\\(ng\\)?\\|trim\\(out\\)?\\|trims\\(pool\\)?\\|"
    "und\\(erline\\)?\\|ver\\(ify\\)?\\|wra\\(p\\)?\\)\\)\\)"
    "\\b.*$"
-   )))
-
-	(oracle-types
-	 (eval-when-compile
-			(concat "\\b"
-				(regexp-opt '(
-;; Oracle Keywords that look like types
-;; Oracle Reserved Words that look like types
-
-"bfile" "binary_integer" "blob" "boolean" "byte" "char" "character"
-"clob" "date" "day" "dec" "decimal" "double" "float" "int" "integer"
-"interval" "local" "long" "month" "natural" "naturaln" "nchar" "nclob"
-"number" "numeric" "nvarchar2" "pls_integer" "positive" "positiven"
-"precision" "raw" "real" "rowid" "second" "signtype" "smallint"
-"string" "time" "timestamp" "urowid" "varchar" "varchar2" "year"
-"zone"
-
-) t) "\\b")))
-	(oracle-builtin-functions (eval-when-compile
-			(concat "\\b"
-				(regexp-opt '(
-;; Misc Oracle builtin functions
-
-"abs" "acos" "add_months" "ascii" "asciistr" "asin" "atan" "atan2"
-"avg" "bfilename" "bin_to_num" "bitand" "case" "cast" "ceil"
-"chartorowid" "chr" "coalesce" "compose" "concat" "convert" "corr"
-"cos" "cosh" "count" "covar_pop" "covar_samp" "cume_dist"
-"current_date" "current_timestamp" "current_user" "dbtimezone"
-"decode" "decompose" "dense_rank" "depth" "deref" "dump" "empty_blob"
-"empty_clob" "existsnode" "exp" "extract" "extractvalue" "first"
-"first_value" "floor" "from_tz" "greatest" "group_id" "grouping"
-"grouping_id" "hextoraw" "initcap" "instr" "lag" "last" "last_day"
-"last_value" "lead" "least" "length" "ln" "localtimestamp" "log"
-"lower" "lpad" "ltrim" "make_ref" "max" "min" "mod" "months_between"
-"nchr" "new_time" "next_day" "nls_charset_decl_len" "nls_charset_id"
-"nls_charset_name" "nls_initcap" "nls_lower" "nlssort" "nls_upper"
-"ntile" "nullif" "numtodsinterval" "numtoyminterval" "nvl" "nvl2"
-"path" "percent_rank" "percentile_cont" "percentile_disc" "power"
-"rank" "ratio_to_report" "rawtohex" "rawtonhex" "ref" "reftohex"
-"regr_slope" "regr_intercept" "regr_count" "regr_r2" "regr_avgx"
-"regr_avgy" "regr_sxx" "regr_syy" "regr_sxy" "round"
-"row_number" "rowidtochar" "rowidtonchar" "rpad" "rtrim"
-"sessiontimezone" "sign" "sin" "sinh" "soundex" "sqrt" "stddev"
-"stddev_pop" "stddev_samp" "substr" "sum" "sys_connect_by_path"
-"sys_context" "sys_dburigen" "sys_extract_utc" "sys_guid" "sys_typeid"
-"sys_xmlagg" "sys_xmlgen" "sysdate" "systimestamp" "tan" "tanh"
-"to_char" "to_clob" "to_date" "to_dsinterval" "to_lob" "to_multi_byte"
-"to_nchar" "to_nclob" "to_number" "to_single_byte" "to_timestamp"
-"to_timestamp_tz" "to_yminterval" "translate" "treat" "trim" "trunc"
-"tz_offset" "uid" "unistr" "updatexml" "upper" "user" "userenv"
-"value" "var_pop" "var_samp" "variance" "vsize" "width_bucket"
-"xmlagg" "xmlcolattval" "xmlconcat" "xmlelement" "xmlforest"
-"xmlsequence" "xmltransform"
-
-) t) "\\b"))))
-    (list (cons oracle-sqlplus-commands 'font-lock-doc-face)
-	  (cons oracle-keywords 'font-lock-keyword-face)
-			(cons oracle-warning-words 'font-lock-warning-face)
-			;; XEmacs doesn't have font-lock-builtin-face
-			(if (string-match "XEmacs\\|Lucid" emacs-version)
-			    (cons oracle-builtin-functions 'font-lock-preprocessor-face)
-			  ;; GNU Emacs 19 doesn't have it either
-			  (if (string-match "GNU Emacs 19" emacs-version)
-		(cons oracle-builtin-functions 'font-lock-keyword-face)
-			    ;; Emacs
-			    (cons oracle-builtin-functions 'font-lock-builtin-face)))
-	  (cons oracle-types 'font-lock-type-face)))
+   ))))
+
+    `((,sqlplus-commands . ,sql-doc-face)
+      (,oracle-functions . ,sql-builtin-face)
+      (,oracle-keywords  . font-lock-keyword-face)
+      (,oracle-types     . font-lock-type-face)
+      (,plsql-functions  . ,sql-builtin-face)
+      (,plsql-keywords   . font-lock-keyword-face)
+      (,plsql-type       . font-lock-type-face)
+      (,plsql-warning    . font-lock-warning-face)))
 
   "Oracle SQL keywords used by font-lock.
 
@@ -1117,42 +1248,84 @@
 to add functions and PL/SQL keywords.")
 
 (defvar sql-mode-postgres-font-lock-keywords
-  (let ((postgres-reserved-words (eval-when-compile
-				 (concat "\\b"
-					 (regexp-opt '(
-"language"
-) t) "\\b")))
-	(postgres-types (eval-when-compile
-			  (concat "\\b"
-				  (regexp-opt '(
-
-"bool" "box" "circle" "char" "char2" "char4" "char8" "char16" "date"
-"float4" "float8" "int2" "int4" "int8" "line" "lseg" "money" "path"
-"point" "polygon" "serial" "text" "time" "timespan" "timestamp" "varchar"
-
-) t)"\\b")))
-	(postgres-builtin-functions (eval-when-compile
-			(concat "\\b"
-				(regexp-opt '(
-;; Misc Postgres builtin functions
-
-"abstime" "age" "area" "box" "center" "date_part" "date_trunc"
-"datetime" "dexp" "diameter" "dpow" "float" "float4" "height"
-"initcap" "integer" "isclosed" "isfinite" "isoldpath" "isopen"
-"length" "lower" "lpad" "ltrim" "pclose" "point" "points" "popen"
-"position" "radius" "reltime" "revertpoly" "rpad" "rtrim" "substr"
-"substring" "text" "timespan" "translate" "trim" "upgradepath"
-"upgradepoly" "upper" "varchar" "width"
-
-) t) "\\b"))))
-	  (append sql-mode-ansi-font-lock-keywords
-		  (list (cons postgres-reserved-words 'font-lock-keyword-face)
-			;; XEmacs doesn't have 'font-lock-builtin-face
-			(if (string-match "XEmacs\\|Lucid" emacs-version)
-			    (cons postgres-builtin-functions 'font-lock-preprocessor-face)
-			  ;; Emacs
-			  (cons postgres-builtin-functions 'font-lock-builtin-face))
-		  (cons postgres-types 'font-lock-type-face))))
+  (let ((pg-funcs (sql-keywords-re
+"abbrev" "abs" "acos" "age" "area" "ascii" "asin" "atab2" "atan"
+"atan2" "avg" "bit_length" "both" "broadcast" "btrim" "cbrt" "ceil"
+"center" "char_length" "chr" "coalesce" "col_description" "convert"
+"cos" "cot" "count" "current_database" "current_date" "current_schema"
+"current_schemas" "current_setting" "current_time" "current_timestamp"
+"current_user" "currval" "date_part" "date_trunc" "decode" "degrees"
+"diameter" "encode" "exp" "extract" "floor" "get_bit" "get_byte"
+"has_database_privilege" "has_function_privilege"
+"has_language_privilege" "has_schema_privilege" "has_table_privilege"
+"height" "host" "initcap" "isclosed" "isfinite" "isopen" "leading"
+"length" "ln" "localtime" "localtimestamp" "log" "lower" "lpad"
+"ltrim" "masklen" "max" "min" "mod" "netmask" "network" "nextval"
+"now" "npoints" "nullif" "obj_description" "octet_length" "overlay"
+"pclose" "pg_client_encoding" "pg_function_is_visible"
+"pg_get_constraintdef" "pg_get_indexdef" "pg_get_ruledef"
+"pg_get_userbyid" "pg_get_viewdef" "pg_opclass_is_visible"
+"pg_operator_is_visible" "pg_table_is_visible" "pg_type_is_visible"
+"pi" "popen" "position" "pow" "quote_ident" "quote_literal" "radians"
+"radius" "random" "repeat" "replace" "round" "rpad" "rtrim"
+"session_user" "set_bit" "set_byte" "set_config" "set_masklen"
+"setval" "sign" "sin" "split_part" "sqrt" "stddev" "strpos" "substr"
+"substring" "sum" "tan" "timeofday" "to_ascii" "to_char" "to_date"
+"to_hex" "to_number" "to_timestamp" "trailing" "translate" "trim"
+"trunc" "upper" "variance" "version" "width"
+))
+
+	(pg-reserved (sql-keywords-re
+"abort" "access" "add" "after" "aggregate" "alignment" "all" "alter"
+"analyze" "and" "any" "as" "asc" "assignment" "authorization"
+"backward" "basetype" "before" "begin" "between" "binary" "by" "cache"
+"called" "cascade" "case" "cast" "characteristics" "check"
+"checkpoint" "class" "close" "cluster" "column" "comment" "commit"
+"committed" "commutator" "constraint" "constraints" "conversion"
+"copy" "create" "createdb" "createuser" "cursor" "cycle" "database"
+"deallocate" "declare" "default" "deferrable" "deferred" "definer"
+"delete" "delimiter" "desc" "distinct" "do" "domain" "drop" "each"
+"element" "else" "encoding" "encrypted" "end" "escape" "except"
+"exclusive" "execute" "exists" "explain" "extended" "external" "false"
+"fetch" "finalfunc" "for" "force" "foreign" "forward" "freeze" "from"
+"full" "function" "grant" "group" "gtcmp" "handler" "hashes" "having"
+"immediate" "immutable" "implicit" "in" "increment" "index" "inherits"
+"initcond" "initially" "input" "insensitive" "insert" "instead"
+"internallength" "intersect" "into" "invoker" "is" "isnull"
+"isolation" "join" "key" "language" "leftarg" "level" "like" "limit"
+"listen" "load" "local" "location" "lock" "ltcmp" "main" "match"
+"maxvalue" "merges" "minvalue" "mode" "move" "natural" "negator"
+"next" "nocreatedb" "nocreateuser" "none" "not" "nothing" "notify"
+"notnull" "null" "of" "offset" "oids" "on" "only" "operator" "or"
+"order" "output" "owner" "partial" "passedbyvalue" "password" "plain"
+"prepare" "primary" "prior" "privileges" "procedural" "procedure"
+"public" "read" "recheck" "references" "reindex" "relative" "rename"
+"reset" "restrict" "returns" "revoke" "rightarg" "rollback" "row"
+"rule" "schema" "scroll" "security" "select" "sequence" "serializable"
+"session" "set" "sfunc" "share" "show" "similar" "some" "sort1"
+"sort2" "stable" "start" "statement" "statistics" "storage" "strict"
+"stype" "sysid" "table" "temp" "template" "temporary" "then" "to"
+"transaction" "trigger" "true" "truncate" "trusted" "type"
+"unencrypted" "union" "unique" "unknown" "unlisten" "until" "update"
+"usage" "user" "using" "vacuum" "valid" "validator" "values"
+"variable" "verbose" "view" "volatile" "when" "where" "with" "without"
+"work"
+))
+
+	(pg-types (sql-keywords-re
+"anyarray" "bigint" "bigserial" "bit" "boolean" "box" "bytea" "char"
+"character" "cidr" "circle" "cstring" "date" "decimal" "double"
+"float4" "float8" "inet" "int2" "int4" "int8" "integer" "internal"
+"interval" "language_handler" "line" "lseg" "macaddr" "money"
+"numeric" "oid" "opaque" "path" "point" "polygon" "precision" "real"
+"record" "regclass" "regoper" "regoperator" "regproc" "regprocedure"
+"regtype" "serial" "serial4" "serial8" "smallint" "text" "time"
+"timestamp" "varchar" "varying" "void" "zone"
+)))
+
+  `((,pg-funcs    . ,sql-builtin-face)
+    (,pg-reserved . font-lock-keyword-face)
+    (,pg-types    . font-lock-type-face)))
 
   "Postgres SQL keywords used by font-lock.
 
@@ -1162,10 +1335,7 @@
 you define your own sql-mode-postgres-font-lock-keywords.")
 
 (defvar sql-mode-linter-font-lock-keywords
-  (let ((linter-keywords (eval-when-compile
-			   (concat "\\b"
-				   (regexp-opt '(
-
+  (let ((linter-keywords (sql-keywords-re
 "autocommit" "autoinc" "autorowid" "cancel" "cascade" "channel"
 "committed" "count" "countblob" "cross" "current" "data" "database"
 "datafile" "datafiles" "datesplit" "dba" "dbname" "default" "deferred"
@@ -1190,12 +1360,9 @@
 "trigger_info_size" "true" "trunc" "uncommitted" "unicode" "unknown"
 "unlimited" "unlisted" "user" "utf8" "value" "varying" "volumes"
 "wait" "windows_code" "workspace" "write" "xml"
-
-) t) "\\b")))
-	(linter-reserved-words (eval-when-compile
-				 (concat "\\b"
-					 (regexp-opt '(
-
+))
+
+	(linter-reserved (sql-keywords-re
 "access" "action" "add" "address" "after" "all" "alter" "always" "and"
 "any" "append" "as" "asc" "ascic" "async" "at_begin" "at_end" "audit"
 "aud_obj_name_len" "backup" "base" "before" "between" "blobfile"
@@ -1213,22 +1380,16 @@
 "start" "stop" "sync" "synchronize" "synonym" "sysdate" "table" "then"
 "to" "union" "unique" "unlock" "until" "update" "using" "values"
 "view" "when" "where" "with" "without"
-
-) t) "\\b")))
-	(linter-types (eval-when-compile
-			(concat "\\b"
-				(regexp-opt '(
-
+))
+
+	(linter-types (sql-keywords-re
 "bigint" "bitmap" "blob" "boolean" "char" "character" "date"
 "datetime" "dec" "decimal" "double" "float" "int" "integer" "nchar"
 "number" "numeric" "real" "smallint" "varbyte" "varchar" "byte"
 "cursor" "long"
-
-) t) "\\b")))
-	(linter-builtin-functions (eval-when-compile
-			(concat "\\b"
-				(regexp-opt '(
-
+))
+
+	(linter-functions (sql-keywords-re
 "abs" "acos" "asin" "atan" "atan2" "avg" "ceil" "cos" "cosh" "divtime"
 "exp" "floor" "getbits" "getblob" "getbyte" "getlong" "getraw"
 "getstr" "gettext" "getword" "hextoraw" "lenblob" "length" "log"
@@ -1239,20 +1400,12 @@
 "to_gmtime" "to_localtime" "to_number" "trim" "upper" "decode"
 "substr" "substring" "chr" "dayname" "days" "greatest" "hex" "initcap"
 "instr" "least" "multime" "replace" "width"
-
-) t) "\\b"))))
-	  (append sql-mode-ansi-font-lock-keywords
-	    (list (cons linter-keywords 'font-lock-keywords-face)
-			(cons linter-reserved-words 'font-lock-keyword-face)
-			;; XEmacs doesn't have font-lock-builtin-face
-			(if (string-match "XEmacs\\|Lucid" emacs-version)
-			    (cons linter-builtin-functions 'font-lock-preprocessor-face)
-			  ;; GNU Emacs 19 doesn't have it either
-			  (if (string-match "GNU Emacs 19" emacs-version)
-			(cons linter-builtin-functions 'font-lock-keywords-face)
-			    ;; Emacs
-			    (cons linter-builtin-functions 'font-lock-builtin-face)))
-		  (cons linter-types 'font-lock-type-face))))
+)))
+
+    `((,linter-keywords  . font-lock-keyword-face)
+      (,linter-reserved  . font-lock-keyword-face)
+      (,linter-functions . ,sql-builtin-face)
+      (,linter-types     . font-lock-type-face)))
 
   "Linter SQL keywords used by font-lock.
 
@@ -1261,21 +1414,18 @@
 function `regexp-opt'.")
 
 (defvar sql-mode-ms-font-lock-keywords
-  (let ((ms-reserved-words (eval-when-compile
-			     (concat "\\b"
-				     (regexp-opt '(
-
+  (let ((ms-reserved (sql-keywords-re
 "absolute" "add" "all" "alter" "and" "any" "as" "asc" "authorization"
 "avg" "backup" "begin" "between" "break" "browse" "bulk" "by"
 "cascade" "case" "check" "checkpoint" "close" "clustered" "coalesce"
 "column" "commit" "committed" "compute" "confirm" "constraint"
 "contains" "containstable" "continue" "controlrow" "convert" "count"
 "create" "cross" "current" "current_date" "current_time"
-"current_timestamp" "current_user" "database" "deallocate"
-"declare" "default" "delete" "deny" "desc" "disk" "distinct"
-"distributed" "double" "drop" "dummy" "dump" "else" "end" "errlvl"
-"errorexit" "escape" "except" "exec" "execute" "exists" "exit" "fetch"
-"file" "fillfactor" "first" "floppy" "for" "foreign" "freetext"
+"current_timestamp" "current_user" "database" "deallocate" "declare"
+"default" "delete" "deny" "desc" "disk" "distinct" "distributed"
+"double" "drop" "dummy" "dump" "else" "end" "errlvl" "errorexit"
+"escape" "except" "exec" "execute" "exists" "exit" "fetch" "file"
+"fillfactor" "first" "floppy" "for" "foreign" "freetext"
 "freetexttable" "from" "full" "goto" "grant" "group" "having"
 "holdlock" "identity" "identity_insert" "identitycol" "if" "in"
 "index" "inner" "insert" "intersect" "into" "is" "isolation" "join"
@@ -1295,29 +1445,21 @@
 "textsize" "then" "to" "top" "tran" "transaction" "trigger" "truncate"
 "tsequal" "uncommitted" "union" "unique" "update" "updatetext"
 "updlock" "use" "user" "values" "view" "waitfor" "when" "where"
-"while" "with" "work" "writetext"
-"collate" "function" "openxml" "returns"
-
-) t) "\\b")))
-	(ms-types (eval-when-compile
-		    (concat "\\b"
-			    (regexp-opt '(
-
+"while" "with" "work" "writetext" "collate" "function" "openxml"
+"returns"
+))
+
+	(ms-types (sql-keywords-re
 "binary" "bit" "char" "character" "cursor" "datetime" "dec" "decimal"
 "double" "float" "image" "int" "integer" "money" "national" "nchar"
 "ntext" "numeric" "numeric" "nvarchar" "precision" "real"
 "smalldatetime" "smallint" "smallmoney" "text" "timestamp" "tinyint"
 "uniqueidentifier" "varbinary" "varchar" "varying"
-
-) t) "\\b")))
+))
 
 	(ms-vars "\\b@[a-zA-Z0-9_]*\\b")
 
-	(ms-builtin-functions (eval-when-compile
-				(concat "\\b"
-					(regexp-opt '(
-;; Misc MS builtin functions
-
+	(ms-functions (sql-keywords-re
 "@@connections" "@@cpu_busy" "@@cursor_rows" "@@datefirst" "@@dbts"
 "@@error" "@@fetch_status" "@@identity" "@@idle" "@@io_busy"
 "@@langid" "@@language" "@@lock_timeout" "@@max_connections"
@@ -1346,14 +1488,12 @@
 "suser_id" "suser_name" "suser_sid" "suser_sname" "system_user" "tan"
 "textptr" "textvalid" "typeproperty" "unicode" "upper" "user"
 "user_id" "user_name" "var" "varp" "year"
-
-) t) "\\b")))
-
-	(ms-config-commands
+))
+
+	(ms-commands
 	 (eval-when-compile
 	   (concat "^\\(\\(set\\s-+\\("
 		   (regexp-opt '(
-
 "datefirst" "dateformat" "deadlock_priority" "lock_timeout"
 "concat_null_yields_null" "cursor_close_on_commit"
 "disable_def_cnst_chk" "fips_flagger" "identity_insert" "language"
@@ -1364,19 +1504,14 @@
 "ansi_warnings" "forceplan" "showplan_all" "showplan_text"
 "statistics" "implicit_transactions" "remote_proc_transactions"
 "transaction" "xact_abort"
-
 ) t)
 		   "\\)\\)\\|go\\s-*\\|use\\s-+\\|setuser\\s-+\\|dbcc\\s-+\\).*$"))))
 
-    (list (cons ms-config-commands 'font-lock-doc-face)
-	  (cons ms-reserved-words 'font-lock-keyword-face)
-	  ;; XEmacs doesn't have 'font-lock-builtin-face
-	  (if (string-match "XEmacs\\|Lucid" emacs-version)
-	      (cons ms-builtin-functions 'font-lock-preprocessor-face)
-	    ;; Emacs
-	    (cons ms-builtin-functions 'font-lock-builtin-face))
-	  (cons ms-vars  'font-lock-variable-name-face)
-	  (cons ms-types 'font-lock-type-face)))
+    `((,ms-commands  . ,sql-doc-face)
+      (,ms-reserved  . font-lock-keyword-face)
+      (,ms-functions . ,sql-builtin-face)
+      (,ms-vars      . font-lock-variable-name-face)
+      (,ms-types     . font-lock-type-face)))
 
   "Microsoft SQLServer SQL keywords used by font-lock.
 
@@ -1385,7 +1520,7 @@
 function `regexp-opt'.  Therefore, take a look at the source before
 you define your own sql-mode-ms-font-lock-keywords.")
 
-(defvar sql-mode-sybase-font-lock-keywords sql-mode-ansi-font-lock-keywords
+(defvar sql-mode-sybase-font-lock-keywords nil
   "Sybase SQL keywords used by font-lock.
 
 This variable is used by `sql-mode' and `sql-interactive-mode'.  The
@@ -1393,7 +1528,7 @@
 function `regexp-opt'.  Therefore, take a look at the source before
 you define your own sql-mode-sybase-font-lock-keywords.")
 
-(defvar sql-mode-informix-font-lock-keywords sql-mode-ansi-font-lock-keywords
+(defvar sql-mode-informix-font-lock-keywords nil
   "Informix SQL keywords used by font-lock.
 
 This variable is used by `sql-mode' and `sql-interactive-mode'.  The
@@ -1401,7 +1536,7 @@
 function `regexp-opt'.  Therefore, take a look at the source before
 you define your own sql-mode-informix-font-lock-keywords.")
 
-(defvar sql-mode-interbase-font-lock-keywords sql-mode-ansi-font-lock-keywords
+(defvar sql-mode-interbase-font-lock-keywords nil
   "Interbase SQL keywords used by font-lock.
 
 This variable is used by `sql-mode' and `sql-interactive-mode'.  The
@@ -1409,7 +1544,7 @@
 function `regexp-opt'.  Therefore, take a look at the source before
 you define your own sql-mode-interbase-font-lock-keywords.")
 
-(defvar sql-mode-ingres-font-lock-keywords sql-mode-ansi-font-lock-keywords
+(defvar sql-mode-ingres-font-lock-keywords nil
   "Ingres SQL keywords used by font-lock.
 
 This variable is used by `sql-mode' and `sql-interactive-mode'.  The
@@ -1417,7 +1552,7 @@
 function `regexp-opt'.  Therefore, take a look at the source before
 you define your own sql-mode-interbase-font-lock-keywords.")
 
-(defvar sql-mode-solid-font-lock-keywords sql-mode-ansi-font-lock-keywords
+(defvar sql-mode-solid-font-lock-keywords nil
   "Solid SQL keywords used by font-lock.
 
 This variable is used by `sql-mode' and `sql-interactive-mode'.  The
@@ -1425,7 +1560,76 @@
 function `regexp-opt'.  Therefore, take a look at the source before
 you define your own sql-mode-solid-font-lock-keywords.")
 
-(defvar sql-mode-mysql-font-lock-keywords sql-mode-ansi-font-lock-keywords
+(defvar sql-mode-mysql-font-lock-keywords
+  (let ((mysql-funcs (sql-keywords-re
+"ascii" "avg" "bdmpolyfromtext" "bdmpolyfromwkb" "bdpolyfromtext"
+"bdpolyfromwkb" "benchmark" "bin" "bit_and" "bit_length" "bit_or"
+"bit_xor" "both" "cast" "char_length" "character_length" "coalesce"
+"concat" "concat_ws" "connection_id" "conv" "convert" "count"
+"curdate" "current_date" "current_time" "current_timestamp" "curtime"
+"elt" "encrypt" "export_set" "field" "find_in_set" "found_rows" "from"
+"geomcollfromtext" "geomcollfromwkb" "geometrycollectionfromtext"
+"geometrycollectionfromwkb" "geometryfromtext" "geometryfromwkb"
+"geomfromtext" "geomfromwkb" "get_lock" "group_concat" "hex" "ifnull"
+"instr" "interval" "isnull" "last_insert_id" "lcase" "leading"
+"length" "linefromtext" "linefromwkb" "linestringfromtext"
+"linestringfromwkb" "load_file" "locate" "lower" "lpad" "ltrim"
+"make_set" "master_pos_wait" "max" "mid" "min" "mlinefromtext"
+"mlinefromwkb" "mpointfromtext" "mpointfromwkb" "mpolyfromtext"
+"mpolyfromwkb" "multilinestringfromtext" "multilinestringfromwkb"
+"multipointfromtext" "multipointfromwkb" "multipolygonfromtext"
+"multipolygonfromwkb" "now" "nullif" "oct" "octet_length" "ord"
+"pointfromtext" "pointfromwkb" "polyfromtext" "polyfromwkb"
+"polygonfromtext" "polygonfromwkb" "position" "quote" "rand"
+"release_lock" "repeat" "replace" "reverse" "rpad" "rtrim" "soundex"
+"space" "std" "stddev" "substring" "substring_index" "sum" "sysdate"
+"trailing" "trim" "ucase" "unix_timestamp" "upper" "user" "variance"
+))
+
+	(mysql-keywords (sql-keywords-re
+"action" "add" "after" "against" "all" "alter" "and" "as" "asc"
+"auto_increment" "avg_row_length" "bdb" "between" "by" "cascade"
+"case" "change" "character" "check" "checksum" "close" "collate"
+"collation" "column" "columns" "comment" "committed" "concurrent"
+"constraint" "create" "cross" "data" "database" "default"
+"delay_key_write" "delayed" "delete" "desc" "directory" "disable"
+"distinct" "distinctrow" "do" "drop" "dumpfile" "duplicate" "else"
+"enable" "enclosed" "end" "escaped" "exists" "fields" "first" "for"
+"force" "foreign" "from" "full" "fulltext" "global" "group" "handler"
+"having" "heap" "high_priority" "if" "ignore" "in" "index" "infile"
+"inner" "insert" "insert_method" "into" "is" "isam" "isolation" "join"
+"key" "keys" "last" "left" "level" "like" "limit" "lines" "load"
+"local" "lock" "low_priority" "match" "max_rows" "merge" "min_rows"
+"mode" "modify" "mrg_myisam" "myisam" "natural" "next" "no" "not"
+"null" "offset" "oj" "on" "open" "optionally" "or" "order" "outer"
+"outfile" "pack_keys" "partial" "password" "prev" "primary"
+"procedure" "quick" "raid0" "raid_type" "read" "references" "rename"
+"repeatable" "restrict" "right" "rollback" "rollup" "row_format"
+"savepoint" "select" "separator" "serializable" "session" "set"
+"share" "show" "sql_big_result" "sql_buffer_result" "sql_cache"
+"sql_calc_found_rows" "sql_no_cache" "sql_small_result" "starting"
+"straight_join" "striped" "table" "tables" "temporary" "terminated"
+"then" "to" "transaction" "truncate" "type" "uncommitted" "union"
+"unique" "unlock" "update" "use" "using" "values" "when" "where"
+"with" "write" "xor"
+))
+
+	(mysql-types (sql-keywords-re
+"bigint" "binary" "bit" "blob" "bool" "boolean" "char" "curve" "date"
+"datetime" "dec" "decimal" "double" "enum" "fixed" "float" "geometry"
+"geometrycollection" "int" "integer" "line" "linearring" "linestring"
+"longblob" "longtext" "mediumblob" "mediumint" "mediumtext"
+"multicurve" "multilinestring" "multipoint" "multipolygon"
+"multisurface" "national" "numeric" "point" "polygon" "precision"
+"real" "smallint" "surface" "text" "time" "timestamp" "tinyblob"
+"tinyint" "tinytext" "unsigned" "varchar" "year" "year2" "year4"
+"zerofill"
+)))
+
+    `((,mysql-funcs    . ,sql-builtin-face)
+      (,mysql-keywords . font-lock-keyword-face)
+      (,mysql-types    . font-lock-type-face)))
+
   "MySQL SQL keywords used by font-lock.
 
 This variable is used by `sql-mode' and `sql-interactive-mode'.  The
@@ -1433,7 +1637,7 @@
 function `regexp-opt'.  Therefore, take a look at the source before
 you define your own sql-mode-mysql-font-lock-keywords.")
 
-(defvar sql-mode-sqlite-font-lock-keywords sql-mode-ansi-font-lock-keywords
+(defvar sql-mode-sqlite-font-lock-keywords nil
   "SQLite SQL keywords used by font-lock.
 
 This variable is used by `sql-mode' and `sql-interactive-mode'.  The
@@ -1441,7 +1645,7 @@
 function `regexp-opt'.  Therefore, take a look at the source before
 you define your own sql-mode-sqlite-font-lock-keywords.")
 
-(defvar sql-mode-db2-font-lock-keywords sql-mode-ansi-font-lock-keywords
+(defvar sql-mode-db2-font-lock-keywords nil
   "DB2 SQL keywords used by font-lock.
 
 This variable is used by `sql-mode' and `sql-interactive-mode'.  The
@@ -1463,16 +1667,16 @@
 (defun sql-product-feature (feature &optional product)
   "Lookup `feature' needed to support the current SQL product.
 
-See \[sql-product-support] for a list of products and supported features."
-  (cadr
-   (memq feature
-	 (assoc (or product sql-product)
-		sql-product-support))))
+See \[sql-product-alist] for a list of products and supported features."
+  (plist-get
+   (cdr (assoc (or product sql-product)
+	       sql-product-alist))
+   feature))
 
 (defun sql-product-font-lock (keywords-only imenu)
   "Sets `font-lock-defaults' and `font-lock-keywords' based on
 the product-specific keywords and syntax-alists defined in
-`sql-product-support'."
+`sql-product-alist'."
   (let
       ;; Get the product-specific syntax-alist.
       ((syntax-alist
@@ -1484,6 +1688,7 @@
     (setq sql-mode-font-lock-keywords
 	  (append
 	   (eval (sql-product-feature :font-lock))
+	   (eval (sql-product-feature :font-lock 'ansi))
 	   (list sql-mode-font-lock-object-name)))
 
     ;; Setup font-lock.  (What is the minimum we should have to do
@@ -1498,12 +1703,34 @@
 	(setq imenu-syntax-alist syntax-alist))))
 
 ;;;###autoload
-(defun sql-add-product-keywords (product keywords)
-  "Append a `font-lock-keywords' entry to the existing entries defined
-  for the specified `product'."
-
-  (let ((font-lock (sql-product-feature :font-lock product)))
-       (set font-lock (append (eval font-lock) (list keywords)))))
+(defun sql-add-product-keywords (product keywords &optional append)
+  "Add highlighting KEYWORDS for SQL PRODUCT.
+
+PRODUCT should be a symbol, the name of a sql product, such as
+`oracle'.  KEYWORDS should be a list; see the variable
+`font-lock-keywords'.  By default they are added at the beginning
+of the current highlighting list.  If optional argument APPEND is
+`set', they are used to replace the current highlighting list.
+If APPEND is any other non-nil value, they are added at the end
+of the current highlighting list.
+
+For example:
+
+ (sql-add-product-keywords 'ms
+  '((\"\\\\b\\\\w+_t\\\\b\" . font-lock-type-face)))
+
+adds a fontification pattern to fontify identifiers ending in
+`_t' as data types."
+
+  (let ((font-lock (sql-product-feature :font-lock product))
+	old)
+    (setq old (eval font-lock))
+    (set font-lock
+	 (if (eq append 'set)
+	     keywords
+	   (if append
+	       (append old keywords)
+	     (append keywords old))))))
 
 
 
@@ -1518,7 +1745,8 @@
     (sql-product-font-lock nil t)
 
     ;; Force fontification, if its enabled.
-    (if font-lock-mode
+    (if (and (boundp 'font-lock-mode)
+	     font-lock-mode)
 	(font-lock-fontify-buffer))
 
     ;; Set the mode name to include the product.
@@ -1528,7 +1756,7 @@
   "Set `sql-product' to product and enable appropriate
 highlighting."
   (interactive "SEnter SQL product: ")
-  (when (not (assoc product sql-product-support))
+  (when (not (assoc product sql-product-alist))
     (error "SQL product %s is not supported; treated as ANSI" product)
     (setq product 'ansi))
 
@@ -1952,6 +2180,19 @@
   (interactive)
   (sql-send-region (point-min) (point-max)))
 
+(defun sql-send-string (str)
+  "Send a string to the SQL process."
+  (interactive "sSQL Text: ")
+  (if (buffer-live-p sql-buffer)
+      (save-excursion
+        (comint-send-string sql-buffer str)
+        (comint-send-string sql-buffer "\n")
+        (message "Sent string to buffer %s." (buffer-name sql-buffer))
+        (if sql-pop-to-buffer-after-send-region
+            (pop-to-buffer sql-buffer)
+          (display-buffer sql-buffer)))
+    (message "No SQL process started.")))
+
 (defun sql-toggle-pop-to-buffer-after-send-region (&optional value)
   "Toggle `sql-pop-to-buffer-after-send-region'.
 
@@ -2611,6 +2852,8 @@
 	(setq params (append params (list sql-database))))
     (if (not (string= "" sql-server))
 	(setq params (append (list "-h" sql-server) params)))
+    (if (not (string= "" sql-user))
+	(setq params (append (list "-U" sql-user) params)))
     (set-buffer (apply 'make-comint "SQL" sql-postgres-program
 		       nil params))))
 
--- a/lisp/simple.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/simple.el	Sat May 01 19:23:22 2004 +0000
@@ -2148,7 +2148,8 @@
 	    ;; look like a C-g typed as a command.
 	    (inhibit-quit t))
 	(if (pos-visible-in-window-p other-end (selected-window))
-	    (unless transient-mark-mode
+	    (unless (and transient-mark-mode
+			 (face-background 'region))
 	      ;; Swap point and mark.
 	      (set-marker (mark-marker) (point) (current-buffer))
 	      (goto-char other-end)
--- a/lisp/smerge-mode.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/smerge-mode.el	Sat May 01 19:23:22 2004 +0000
@@ -65,7 +65,7 @@
 (defcustom smerge-diff-switches
   (append '("-d" "-b")
 	  (if (listp diff-switches) diff-switches (list diff-switches)))
-  "*A list of strings specifying switches to be be passed to diff.
+  "*A list of strings specifying switches to be passed to diff.
 Used in `smerge-diff-base-mine' and related functions."
   :group 'smerge
   :type '(repeat string))
@@ -324,7 +324,7 @@
 	      ;; Out of range
 	      (popup-menu smerge-mode-menu)
 	    ;; Install overlay.
-	    (setq o (make-overlay (match-beginning i) (match-end i)))  
+	    (setq o (make-overlay (match-beginning i) (match-end i)))
 	    (unwind-protect
 		(progn
 		  (overlay-put o 'face 'highlight)
@@ -512,7 +512,7 @@
 	    (unwind-protect
 		(add-text-properties start end smerge-text-properties)
 	      (restore-buffer-modified-p m)))
-              
+
 	  (store-match-data (list start end
 				  mine-start mine-end
 				  base-start base-end
--- a/lisp/subr.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/subr.el	Sat May 01 19:23:22 2004 +0000
@@ -1531,8 +1531,7 @@
 (defun remove-overlays (&optional beg end name val)
   "Clear BEG and END of overlays whose property NAME has value VAL.
 Overlays might be moved and or split.
-If BEG is nil, `(point-min)' is used. If END is nil, `(point-max)' 
-is used."
+BEG and END default to the beginning resp. end of buffer."
   (unless beg (setq beg (point-min)))
   (unless end (setq end (point-max)))
   (if (< end beg)
--- a/lisp/xml.el	Thu Apr 29 20:45:02 2004 +0000
+++ b/lisp/xml.el	Sat May 01 19:23:22 2004 +0000
@@ -622,9 +622,15 @@
 ;;**
 ;;*******************************************************************
 
-(defun xml-debug-print (xml)
+(defun xml-debug-print (xml &optional indent-string)
+  "Outputs the XML in the current buffer.
+XML can be a tree or a list of nodes.
+The first line is indented with the optional INDENT-STRING."
+  (setq indent-string (or indent-string ""))
   (dolist (node xml)
-    (xml-debug-print-internal node "")))
+    (xml-debug-print-internal node indent-string)))
+
+(defalias 'xml-print 'xml-debug-print)
 
 (defun xml-debug-print-internal (xml indent-string)
   "Outputs the XML tree in the current buffer.
@@ -639,22 +645,26 @@
       (insert ?\  (symbol-name (caar attlist)) "=\"" (cdar attlist) ?\")
       (setq attlist (cdr attlist)))
 
-    (insert ?>)
-
     (setq tree (xml-node-children tree))
 
-    ;;  output the children
-    (dolist (node tree)
-      (cond
-       ((listp node)
-	(insert ?\n)
-	(xml-debug-print-internal node (concat indent-string "  ")))
-       ((stringp node) (insert node))
-       (t
-	(error "Invalid XML tree"))))
+    (if (null tree)
+	(insert ?/ ?>)
+      (insert ?>)
 
-    (insert ?\n indent-string
-	    ?< ?/ (symbol-name (xml-node-name xml)) ?>)))
+      ;;  output the children
+      (dolist (node tree)
+	(cond
+	 ((listp node)
+	  (insert ?\n)
+	  (xml-debug-print-internal node (concat indent-string "  ")))
+	 ((stringp node) (insert node))
+	 (t
+	  (error "Invalid XML tree"))))
+
+      (when (not (and (null (cdr tree))
+		      (stringp (car tree))))
+	(insert ?\n indent-string))
+      (insert ?< ?/ (symbol-name (xml-node-name xml)) ?>))))
 
 (provide 'xml)
 
--- a/lispref/ChangeLog	Thu Apr 29 20:45:02 2004 +0000
+++ b/lispref/ChangeLog	Sat May 01 19:23:22 2004 +0000
@@ -1,3 +1,7 @@
+2004-04-30  Jesper Harder  <harder@ifa.au.dk>
+
+	* display.texi: emacs -> Emacs.
+
 2004-04-27  Matthew Mundell  <matt@mundell.ukfsn.org>
 
 	* files.texi (Changing Files): Document set-file-times.
--- a/lispref/display.texi	Thu Apr 29 20:45:02 2004 +0000
+++ b/lispref/display.texi	Sat May 01 19:23:22 2004 +0000
@@ -3433,7 +3433,7 @@
 etc.  Emacs uses buttons for the hyper-links in help text and the like.
 
 A button is essentially a set of properties attached (via text
-properties or overlays) to a region of text in an emacs buffer, which
+properties or overlays) to a region of text in an Emacs buffer, which
 are called its button properties.  @xref{Button Properties}.
 
 One of the these properties (@code{action}) is a function, which will
@@ -3441,7 +3441,7 @@
 The invoked function may then examine the button and use its other
 properties as desired.
 
-In some ways the emacs button package duplicates functionality offered
+In some ways the Emacs button package duplicates functionality offered
 by the widget package (@pxref{Top, , Introduction, widget, The Emacs
 Widget Library}), but the button package has the advantage that it is
 much faster, much smaller, and much simpler to use (for elisp
@@ -3454,7 +3454,7 @@
 @menu
 * Button Properties::      Button properties with special meanings.
 * Button Types::           Defining common properties for classes of buttons.
-* Making Buttons::         Adding buttons to emacs buffers.
+* Making Buttons::         Adding buttons to Emacs buffers.
 * Manipulating Buttons::   Getting and setting properties of buttons.
 * Button Buffer Commands:: Buffer-wide commands and bindings for buttons.
 * Manipulating Button Types:: 
@@ -3488,14 +3488,14 @@
 
 @item face
 @kindex face @r{(button property)}
-This is an emacs face controlling how buttons of this type are
+This is an Emacs face controlling how buttons of this type are
 displayed; by default this is the @code{button} face.
 
 @item mouse-face
 @kindex mouse-face @r{(button property)}
 This is an additional face which controls appearance during
 mouse-overs (merged with the usual button face); by default this is
-the usual emacs @code{highlight} face.
+the usual Emacs @code{highlight} face.
 
 @item keymap
 @kindex keymap @r{(button property)}
@@ -3512,7 +3512,7 @@
 
 @item help-echo
 @kindex help-index @r{(button property)}
-A string displayed by the emacs tool-tip help system; by default,
+A string displayed by the Emacs tool-tip help system; by default,
 @code{"mouse-2, RET: Push this button"}.
 
 @item button
@@ -3562,7 +3562,7 @@
   Buttons are associated with a region of text, using an overlay or
 text-properties to hold button-specific information, all of which are
 initialized from the button's type (which defaults to the built-in
-button type @code{button}).  Like all emacs text, the appearance of
+button type @code{button}).  Like all Emacs text, the appearance of
 the button is governed by the @code{face} property; by default (via
 the @code{face} property inherited from the @code{button} button-type)
 this is a simple underline, like a typical web-page link.
@@ -3594,7 +3594,7 @@
 Insert a button with the label @var{label}.
 @end defun
 
-The following functions are similar, but use emacs text-properties
+The following functions are similar, but use Emacs text-properties
 (@pxref{Text Properties}) to hold the button properties, making the
 button actually part of the text instead of being a property of the
 buffer (using text-properties is usually faster than using overlays,
@@ -3683,7 +3683,7 @@
 @cindex button buffer commands
 
 These are commands and functions for locating and operating on
-buttons in an emacs buffer.
+buttons in an Emacs buffer.
 
 @code{push-button} is the command that a user uses to actually `push'
 a button, and is bound by default in the button itself to @key{RET}
--- a/src/ChangeLog	Thu Apr 29 20:45:02 2004 +0000
+++ b/src/ChangeLog	Sat May 01 19:23:22 2004 +0000
@@ -1,3 +1,32 @@
+2004-04-30  Kim F. Storm  <storm@cua.dk>
+
+	* buffer.c (syms_of_buffer) <line-spacing>: Allow float value.
+	(syms_of_buffer) <cursor-type>: Doc fix.
+
+	* dispextern.h (struct it): Remove member use_default_face.
+	Add members override_ascent, override_descent, override_boff.
+
+	* xdisp.c (init_iterator): Handle line-spacing float value.
+	Initialize override_ascent member.
+	(append_space_for_newline): Reset override_ascent.
+	Remove use_default_face.
+	(calc_line_height_property): New function to calculate value of
+	line-height and line-spacing properties.  Look at overlays, too.
+	Set override_ascent, override_descent, override_boff members when
+	using another face than the current face.  Float values are now
+	relative to the frame default font, by default; accept a cons
+	of ratio and face name to specify value relative to a specific face.
+	(x_produce_glyphs): Use calc_line_height_property.
+	Use override_ascent etc. when set to handle different face heights.
+	A negative line-spacing property value is interpreted as a total
+	line height, rather than inter-line spacing.
+	(note_mouse_highlight): Allocate room for 40 overlays initially.
+
+2004-04-29  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* data.c (Fsubr_name): New fun.
+	(syms_of_data): Defsubr it.
+
 2004-04-29  Kim F. Storm  <storm@cua.dk>
 
 	* xdisp.c (null_glyph_slice): New var.
--- a/src/buffer.c	Thu Apr 29 20:45:02 2004 +0000
+++ b/src/buffer.c	Sat May 01 19:23:22 2004 +0000
@@ -2143,7 +2143,7 @@
       GPT = GPT_BYTE;
       TEMP_SET_PT_BOTH (PT_BYTE, PT_BYTE);
 
-      
+
       for (tail = BUF_MARKERS (current_buffer); tail; tail = tail->next)
 	tail->charpos = tail->bytepos;
 
@@ -3339,7 +3339,7 @@
 
       if (endpos < start)
 	break;
-      
+
       if (endpos < end
 	  || (startpos >= start && startpos < end))
 	{
@@ -3382,7 +3382,7 @@
 	{
 	  startpos = endpos;
 	  Fset_marker (OVERLAY_START (overlay), make_number (startpos),
-		       Qnil);	  
+		       Qnil);
 	}
 
       if (startpos >= end)
@@ -4193,7 +4193,7 @@
 		add_overlay_mod_hooklist (prop, overlay);
 	    }
 	}
-      
+
       for (tail = current_buffer->overlays_after; tail; tail = tail->next)
 	{
 	  int startpos, endpos;
@@ -5856,9 +5856,13 @@
 
   t 		 use the cursor specified for the frame
   nil		 don't display a cursor
-  bar		 display a bar cursor with default width
-  (bar . WIDTH)	 display a bar cursor with width WIDTH
-  ANYTHING ELSE	 display a box cursor.
+  box		 display a filled box cursor
+  hollow	 display a hollow box cursor
+  bar		 display a vertical bar cursor with default width
+  (bar . WIDTH)	 display a vertical bar cursor with width WIDTH
+  hbar		 display a horisontal bar cursor with default width
+  (hbar . WIDTH) display a horisontal bar cursor with width WIDTH
+  ANYTHING ELSE	 display a hollow box cursor.
 
 When the buffer is displayed in a nonselected window,
 this variable has no effect; the cursor appears as a hollow box.  */);
@@ -5866,7 +5870,9 @@
   DEFVAR_PER_BUFFER ("line-spacing",
 		     &current_buffer->extra_line_spacing, Qnil,
 		     doc: /* Additional space to put between lines when displaying a buffer.
-The space is measured in pixels, and put below lines on window systems.  */);
+The space is measured in pixels, and put below lines on window systems.
+If value is a floating point number, it specifies the spacing relative
+to the default frame line height.  */);
 
   DEFVAR_LISP ("kill-buffer-query-functions", &Vkill_buffer_query_functions,
 	       doc: /* List of functions called with no args to query before killing a buffer.  */);
--- a/src/data.c	Thu Apr 29 20:45:02 2004 +0000
+++ b/src/data.c	Sat May 01 19:23:22 2004 +0000
@@ -761,6 +761,19 @@
     return Fcons (make_number (minargs), make_number (maxargs));
 }
 
+DEFUN ("subr-name", Fsubr_name, Ssubr_name, 1, 1, 0,
+       doc: /* Return name of subroutine SUBR.
+SUBR must be a built-in function.  */)
+     (subr)
+     Lisp_Object subr;
+{
+  const char *name;
+  if (!SUBRP (subr))
+    wrong_type_argument (Qsubrp, subr);
+  name = XSUBR (subr)->symbol_name;
+  return make_string (name, strlen (name));
+}
+
 DEFUN ("interactive-form", Finteractive_form, Sinteractive_form, 1, 1, 0,
        doc: /* Return the interactive form of CMD or nil if none.
 CMD must be a command.  Value, if non-nil, is a list
@@ -3319,6 +3332,7 @@
   defsubr (&Slognot);
   defsubr (&Sbyteorder);
   defsubr (&Ssubr_arity);
+  defsubr (&Ssubr_name);
 
   XSYMBOL (Qwholenump)->function = XSYMBOL (Qnatnump)->function;
 
--- a/src/dispextern.h	Thu Apr 29 20:45:02 2004 +0000
+++ b/src/dispextern.h	Sat May 01 19:23:22 2004 +0000
@@ -1923,9 +1923,6 @@
      descent/ascent (line-height property).  Reset after this glyph.  */
   unsigned constrain_row_ascent_descent_p : 1;
 
-  /* If 1, show current glyph in default face.  Reset after this glyph.  */
-  unsigned use_default_face : 1;
-
   /* The ID of the default face to use.  One of DEFAULT_FACE_ID,
      MODE_LINE_FACE_ID, etc, depending on what we are displaying.  */
   int base_face_id;
@@ -1992,6 +1989,10 @@
      only.)  */
   int extra_line_spacing;
 
+  /* Override font height information for this glyph.
+     Used if override_ascent >= 0.  Cleared after this glyph.  */
+  int override_ascent, override_descent, override_boff;
+
   /* If non-null, glyphs are produced in glyph_row with each call to
      produce_glyphs.  */
   struct glyph_row *glyph_row;
--- a/src/xdisp.c	Thu Apr 29 20:45:02 2004 +0000
+++ b/src/xdisp.c	Sat May 01 19:23:22 2004 +0000
@@ -2069,6 +2069,9 @@
     {
       if (NATNUMP (current_buffer->extra_line_spacing))
 	it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
+      else if (FLOATP (current_buffer->extra_line_spacing))
+	it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
+				  * FRAME_LINE_HEIGHT (it->f));
       else if (it->f->extra_line_spacing > 0)
 	it->extra_line_spacing = it->f->extra_line_spacing;
     }
@@ -2086,6 +2089,7 @@
   it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
   it->space_width = Qnil;
   it->font_height = Qnil;
+  it->override_ascent = -1;
 
   /* Are control characters displayed as `^C'?  */
   it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
@@ -14201,7 +14205,7 @@
 
 	  PRODUCE_GLYPHS (it);
 
-	  it->use_default_face = 0;
+	  it->override_ascent = -1;
 	  it->constrain_row_ascent_descent_p = 0;
 	  it->current_x = saved_x;
 	  it->object = saved_object;
@@ -18509,6 +18513,97 @@
   take_vertical_position_into_account (it);
 }
 
+/* Calculate line-height and line-spacing properties.
+   An integer value specifies explicit pixel value.
+   A float value specifies relative value to current face height.
+   A cons (float . face-name) specifies relative value to
+   height of specified face font.
+
+   Returns height in pixels, or nil.  */
+
+static Lisp_Object
+calc_line_height_property (it, prop, font, boff)
+     struct it *it;
+     Lisp_Object prop;
+     XFontStruct *font;
+     int boff;
+{
+  Lisp_Object val;
+  Lisp_Object face_name = Qnil;
+  int ascent, descent, height, override;
+
+  val = Fget_char_property (make_number (IT_CHARPOS (*it)),
+			    prop, it->object);
+
+  if (NILP (val))
+    return val;
+
+  if (INTEGERP (val))
+    return val;
+
+  if (CONSP (val))
+    {
+      face_name = XCDR (val);
+      val = XCAR (val);
+    }
+  else if (SYMBOLP (val))
+    {
+      face_name = val;
+      val = Qnil;
+    }
+
+  override = EQ (prop, Qline_height);
+
+  if (NILP (face_name))
+    {
+      font = FRAME_FONT (it->f);
+      boff = FRAME_BASELINE_OFFSET (it->f);
+    }
+  else if (EQ (face_name, Qt))
+    {
+      override = 0;
+    }
+  else
+    {
+      int face_id;
+      struct face *face;
+      struct font_info *font_info;
+
+      face_id = lookup_named_face (it->f, face_name, ' ');
+      if (face_id < 0)
+	return -1;
+
+      face = FACE_FROM_ID (it->f, face_id);
+      font = face->font;
+      if (font == NULL)
+	return -1;
+
+      font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
+      boff = font_info->baseline_offset;
+      if (font_info->vertical_centering)
+	boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
+    }
+
+  ascent = FONT_BASE (font) + boff;
+  descent = FONT_DESCENT (font) - boff;
+
+  if (override)
+    {
+      it->override_ascent = ascent;
+      it->override_descent = descent;
+      it->override_boff = boff;
+    }
+
+  height = ascent + descent;
+  if (FLOATP (val))
+    height = (int)(XFLOAT_DATA (val) * height);
+  else if (INTEGERP (val))
+    height *= XINT (val);
+
+  return make_number (height);
+}
+
+
 /* RIF:
    Produce glyphs/get display metrics for the display element IT is
    loaded with.  See the description of struct display_iterator in
@@ -18595,17 +18690,20 @@
 
 	  it->nglyphs = 1;
 
- 	  if (it->use_default_face)
+          pcm = FRAME_RIF (it->f)->per_char_metric
+            (font, &char2b, FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
+
+ 	  if (it->override_ascent >= 0)
  	    {
- 	      font = FRAME_FONT (it->f);
- 	      boff = FRAME_BASELINE_OFFSET (it->f);
+ 	      it->ascent = it->override_ascent;
+ 	      it->descent = it->override_descent;
+ 	      boff = it->override_boff;
  	    }
- 
-	  pcm = FRAME_RIF (it->f)->per_char_metric
-            (font, &char2b, FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
-
-	  it->ascent = FONT_BASE (font) + boff;
-	  it->descent = FONT_DESCENT (font) - boff;
+ 	  else
+ 	    {
+ 	      it->ascent = FONT_BASE (font) + boff;
+ 	      it->descent = FONT_DESCENT (font) - boff;
+ 	    }
 
 	  if (pcm)
 	    {
@@ -18708,26 +18806,27 @@
 	     But if previous part of the line set a height, don't
 	     increase that height */
 
-	  Lisp_Object lsp, lh;
-
+	  Lisp_Object height, spacing;
+
+	  it->override_ascent = -1;
 	  it->pixel_width = 0;
 	  it->nglyphs = 0;
 
-	  lh = Fget_text_property (make_number (IT_CHARPOS (*it)),
-				   Qline_height, it->object);
-
-	  if (EQ (lh, Qt))
-	    {
-	      it->use_default_face = 1;
-	      font = FRAME_FONT (it->f);
-	      boff = FRAME_BASELINE_OFFSET (it->f);
-	      font_info = NULL;
-	    }
-
-	  it->ascent = FONT_BASE (font) + boff;
-	  it->descent = FONT_DESCENT (font) - boff;
-
-	  if (EQ (lh, make_number (0)))
+	  height = calc_line_height_property(it, Qline_height, font, boff);
+
+	  if (it->override_ascent >= 0)
+	    {
+	      it->ascent = it->override_ascent;
+	      it->descent = it->override_descent;
+	      boff = it->override_boff;
+	    }
+	  else
+	    {
+	      it->ascent = FONT_BASE (font) + boff;
+	      it->descent = FONT_DESCENT (font) - boff;
+	    }
+
+	  if (EQ (height, make_number(0)))
 	    {
 	      if (it->descent > it->max_descent)
 		{
@@ -18746,7 +18845,6 @@
 	    }
 	  else
 	    {
-	      int explicit_height = -1;
 	      it->phys_ascent = it->ascent;
 	      it->phys_descent = it->descent;
 
@@ -18757,23 +18855,20 @@
 		  it->ascent += face->box_line_width;
 		  it->descent += face->box_line_width;
 		}
-	      if (INTEGERP (lh))
-		explicit_height = XINT (lh);
-	      else if (FLOATP (lh))
-		explicit_height = (it->phys_ascent + it->phys_descent)
-		  * XFLOAT_DATA (lh);
-
-	      if (explicit_height > it->ascent + it->descent)
-		it->ascent = explicit_height - it->descent;
-	    }
-
-	  lsp = Fget_text_property (make_number (IT_CHARPOS (*it)),
-				    Qline_spacing, it->object);
-	  if (INTEGERP (lsp))
-	    extra_line_spacing = XINT (lsp);
-	  else if (FLOATP (lsp))
-	    extra_line_spacing = (it->phys_ascent + it->phys_descent)
-	      * XFLOAT_DATA (lsp);
+	      if (!NILP (height)
+		  && XINT (height) > it->ascent + it->descent)
+		it->ascent = XINT (height) - it->descent;
+	    }
+
+	  spacing = calc_line_height_property(it, Qline_spacing, font, boff);
+	  if (!NILP (spacing))
+	    {
+	      int sp = XINT (spacing);
+	      if (sp < 0)
+		extra_line_spacing = (-sp) - (it->phys_ascent + it->phys_descent);
+	      else
+		extra_line_spacing = sp;
+	    }
 	}
       else if (it->char_to_display == '\t')
 	{
@@ -19150,7 +19245,8 @@
   if (it->area == TEXT_AREA)
     it->current_x += it->pixel_width;
 
-  it->descent += extra_line_spacing;
+  if (extra_line_spacing > 0)
+    it->descent += extra_line_spacing;
 
   it->max_ascent = max (it->max_ascent, it->ascent);
   it->max_descent = max (it->max_descent, it->descent);
@@ -20813,9 +20909,9 @@
       if (BUFFERP (object))
 	{
 	  /* Put all the overlays we want in a vector in overlay_vec.
-	     Store the length in len.  If there are more than 10, make
+	     Store the length in len.  If there are more than 40, make
 	     enough space for all, and try again.  */
-	  len = 10;
+	  len = 40;
 	  overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
 	  noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
 	  if (noverlays > len)