Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-40
authorMiles Bader <miles@gnu.org>
Wed, 15 Sep 2004 09:00:10 +0000 (09:00 +0000)
committerMiles Bader <miles@gnu.org>
Wed, 15 Sep 2004 09:00:10 +0000 (09:00 +0000)
Merge from emacs--cvs-trunk--0

Patches applied:

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-535
   Update from CVS

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-536
   sync-tree with gnus--rel--5.10

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-537
 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-538
   Update from CVS

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-539
   Merge from gnus--rel--5.10

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-540
   Update from CVS

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-541
   Merge from gnus--rel--5.10

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-542
 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-545
   Update from CVS

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-546
   Merge from gnus--rel--5.10

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-547
 - miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-548
   Update from CVS

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-549
   Use symbol-matching for generic-mode keywords

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-550
   Update from CVS

 * miles@gnu.org--gnu-2004/gnus--devo--0--patch-2
   Add {arch}/=cvs-sync-make-log

 * miles@gnu.org--gnu-2004/gnus--rel--5.8--base-0
   Import from Gnus CVS branch V5-8

 * miles@gnu.org--gnu-2004/gnus--rel--5.8--patch-1
   {arch}/=tagging-method: Add CVS and autoconf grot to junk regexp

 * miles@gnu.org--gnu-2004/gnus--rel--5.8--patch-2
   Use explicit tags for autoconf input files

 * miles@gnu.org--gnu-2004/gnus--rel--5.8--patch-3
   Remove RCS keywords

 * miles@gnu.org--gnu-2004/gnus--rel--5.8--patch-4
   Fix copied explicit id-tags

 * miles@gnu.org--gnu-2004/gnus--rel--5.8--patch-5
   Add {arch}/=cvs-sync-make-log

 * miles@gnu.org--gnu-2004/gnus--rel--5.8--patch-6
   configure.in: Use ifelse instead of m4_if for arch-tag: comment

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--base-0
   tag of miles@gnu.org--gnu-2004/gnus--rel--5.8--base-0

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-1
   Gnus 5.10, from CVS branch v5-10

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-2
   Merge from gnus--rel--5.8

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-3
   Use explicit tags for autoconf input files

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-4
   sync-tree with gnus--rel--5.8

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-5
   Update from CVS

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-6
   Merge from gnus--rel--5.8

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-7
   Remove RCS keywords

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-8
   Merge from gnus--rel--5.8

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-9
   Update from CVS

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-10
   Add {arch}/=cvs-sync-make-log

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-11
   Merge from gnus--rel--5.8

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-12
   Update from CVS: make.bat: Fix line endings around arch-tag.

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-13
 - miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-17
   Update from CVS

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-21
   Merge from emacs--cvs-trunk--0

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-22
   Update from CVS: lisp/nndb.el (require): Remove tcp and duplicate cl.

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-23
   Update from CVS

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-24
   lisp/nnimap.el (nnimap-open-connection): Remove extraneous end-paren

 * miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-25
 - miles@gnu.org--gnu-2004/gnus--rel--5.10--patch-26
   Update from CVS

56 files changed:
admin/ChangeLog
admin/FOR-RELEASE
etc/ChangeLog
etc/ETAGS.EBNF
etc/MORE.STUFF
etc/NEWS
etc/etags.1
lib-src/ChangeLog
lib-src/etags.c
lisp/ChangeLog
lisp/ChangeLog.10
lisp/desktop.el
lisp/emacs-lisp/checkdoc.el
lisp/emulation/cua-rect.el
lisp/faces.el
lisp/files.el
lisp/generic.el
lisp/gnus/ChangeLog
lisp/gnus/ChangeLog.2
lisp/gnus/gnus-registry.el
lisp/gnus/gnus-sum.el
lisp/gnus/nndb.el
lisp/gnus/nnimap.el
lisp/ibuf-ext.el
lisp/ido.el
lisp/isearch.el
lisp/kmacro.el
lisp/novice.el
lisp/progmodes/compile.el
lisp/progmodes/grep.el
lisp/simple.el
lisp/textmodes/bibtex.el
lisp/textmodes/dns-mode.el [new file with mode: 0644]
lisp/vc-arch.el
lisp/vc-hooks.el
lisp/vc-mcvs.el
lisp/windmove.el
man/ChangeLog
man/Makefile.in
man/gnus.texi
man/kmacro.texi
man/maintaining.texi
man/makefile.w32-in
man/mini.texi
man/smtpmail.texi
src/ChangeLog
src/Makefile.in
src/alloc.c
src/bytecode.c
src/editfns.c
src/fileio.c
src/msdos.c
src/puresize.h
src/xdisp.c
src/xfaces.c
src/xselect.c

index dafae3c..4876e35 100644 (file)
@@ -1,3 +1,9 @@
+2004-09-11  Kim F. Storm  <storm@cua.dk>
+
+       * FOR-RELEASE (New features): Remove Gnus 5.10 entry (Done!).
+       (Documentation): Add NEWS entry.
+       Add section lists for proof-reading Emacs and Lisp manuals.
+
 2004-08-29  Kim F. Storm  <storm@cua.dk>
 
        * FOR-RELEASE (Documentation): Add man/ack.texi and AUTHORS.
index fbbacaf..05bbd0b 100644 (file)
@@ -1,32 +1,11 @@
 Tasks needed before the next release.
 
-* DOCUMENTATION
-
-** Finish updating the Emacs Lisp manual.
-
-** Finish checking the Emacs Lisp manual.
-
-** Update the Emacs manual.
-
-** Check the Emacs Manual.
-
-** Add missing years in copyright notices of all files.
-
-** Update man/info.texi.
-
-** Update man/ack.texi.
-
-** Update AUTHORS.
-
-
 * NEW FEATURES
 
 ** Test the mbox branch of Rmail.
 
 ** Install the mbox branch of Rmail.
 
-** Update Gnus.
-
 ** Face remapping.
 
 
@@ -44,6 +23,178 @@ isearch faces.
 
 ** Make GTK scrollbars behave like others w.r.t. overscrolling.
 
+
+* DOCUMENTATION
+
+** Finish updating the Emacs Lisp manual.
+
+*** New display properties (KFS to provide input).
+
+** Update the Emacs manual.
+
+*** Update man/info.texi.
+
+*** Update man/ack.texi.
+
+** Add missing years in copyright notices of all files.
+
+** Update AUTHORS.
+
+** Reorder NEWS entries.
+
+** Check the Emacs manual.
+
+Write you name/initials in the DONE column when you have
+proof-read the corresponding manual section.
+
+DONE   SECTION
+---------------------------------------------
+       man/abbrevs.texi
+       man/ack.texi
+       man/ada-mode.texi
+       man/anti.texi
+       man/autotype.texi
+       man/back.texi
+       man/basic.texi
+       man/buffers.texi
+       man/building.texi
+       man/calc.texi
+       man/calendar.texi
+       man/cc-mode.texi
+       man/cl.texi
+       man/cmdargs.texi
+       man/commands.texi
+       man/custom.texi
+       man/dired.texi
+       man/dired-x.texi
+       man/display.texi
+       man/doclicense.texi
+       man/ebrowse.texi
+       man/ediff.texi
+       man/emacs-mime.texi
+       man/emacs.texi
+       man/emacs-xtra.texi
+       man/entering.texi
+       man/eshell.texi
+       man/eudc.texi
+       man/faq.texi
+       man/files.texi
+       man/fixit.texi
+       man/flymake.texi
+       man/forms.texi
+       man/frames.texi
+       man/glossary.texi
+       man/gnus-faq.texi
+       man/gnus.texi
+       man/gnu.texi
+       man/help.texi
+       man/idlwave.texi
+       man/indent.texi
+       man/info.texi
+       man/killing.texi
+       man/kmacro.texi
+       man/macos.texi
+       man/maintaining.texi
+       man/major.texi
+       man/mark.texi
+       man/message.texi
+       man/mh-e.texi
+       man/mini.texi
+       man/misc.texi
+       man/msdog.texi
+       man/mule.texi
+       man/m-x.texi
+       man/pcl-cvs.texi
+       man/pgg.texi
+       man/picture.texi
+       man/programs.texi
+       man/reftex.texi
+       man/regs.texi
+       man/rmail.texi
+       man/screen.texi
+       man/sc.texi
+       man/search.texi
+       man/sending.texi
+       man/ses.texi
+       man/sieve.texi
+       man/smtpmail.texi
+       man/speedbar.texi
+       man/texinfo.tex
+       man/text.texi
+       man/tramp.texi
+       man/trampver.texi
+       man/trouble.texi
+       man/viper.texi
+       man/vip.texi
+       man/widget.texi
+       man/windows.texi
+       man/woman.texi
+       man/xresources.texi
+
+** Check the Emacs Lisp manual.
+
+Write you name/initials in the DONE column when you have
+proof-read the corresponding manual section.
+
+DONE   SECTION
+---------------------------------------------
+       lispref/abbrevs.texi
+       lispref/advice.texi
+       lispref/anti.texi
+       lispref/back.texi
+       lispref/backups.texi
+       lispref/buffers.texi
+       lispref/calendar.texi
+       lispref/commands.texi
+       lispref/compile.texi
+       lispref/control.texi
+       lispref/customize.texi
+       lispref/debugging.texi
+       lispref/display.texi
+       lispref/doclicense.texi
+       lispref/edebug.texi
+       lispref/elisp-covers.texi
+       lispref/elisp.texi
+       lispref/errors.texi
+       lispref/eval.texi
+       lispref/files.texi
+       lispref/frames.texi
+       lispref/front-cover-1.texi
+       lispref/functions.texi
+       lispref/gpl.texi
+       lispref/hash.texi
+       lispref/help.texi
+       lispref/hooks.texi
+       lispref/index.texi
+       lispref/internals.texi
+       lispref/intro.texi
+       lispref/keymaps.texi
+       lispref/lay-flat.texi
+       lispref/lists.texi
+       lispref/loading.texi
+       lispref/locals.texi
+       lispref/macros.texi
+       lispref/maps.texi
+       lispref/markers.texi
+       lispref/minibuf.texi
+       lispref/modes.texi
+       lispref/nonascii.texi
+       lispref/numbers.texi
+       lispref/objects.texi
+       lispref/os.texi
+       lispref/positions.texi
+       lispref/processes.texi
+       lispref/searching.texi
+       lispref/sequences.texi
+       lispref/streams.texi
+       lispref/strings.texi
+       lispref/symbols.texi
+       lispref/syntax.texi
+       lispref/text.texi
+       lispref/tips.texi
+       lispref/variables.texi
+       lispref/windows.texi
+
 \f
 Local variables:
 mode: outline
index e2d9457..5bc0ae4 100644 (file)
@@ -1,3 +1,7 @@
+2004-09-09  Thien-Thi Nguyen  <ttn@gnu.org>
+
+       * MORE.STUFF (EDB): Update entry.
+
 2004-09-07  Dan Nicolaescu  <dann@ics.uci.edu>
 
        * e/eterm.ti: Add `op' entry to enable colors in term.
index 55c90dc..4d09eaa 100644 (file)
@@ -2,7 +2,7 @@
 
 This file contains two sections:
 
-1) An EBNF (Extended Backus Normal Form) description of the format of
+1) An EBNF (Extended Backus-Naur Form) description of the format of
     the tags file created by etags.c and interpreted by etags.el;
 2) A discussion of tag names and implicit tag names.
 
@@ -81,7 +81,7 @@ substring of the tag pattern.  We define a set of rules to decide
 whether it is possible to deduce the tag name from the pattern, and make
 an unnamed tag in those cases.  The name deduced from the pattern of an
 unnamed tag is the implicit name of that tag.
-  When the user looks for a tag, and Emacs founds no explicit tag names
+  When the user looks for a tag, and Emacs finds no explicit tag names
 that match it, Emacs then looks for an tag whose implicit tag name
 matches the request.  etags.c uses implicit tag names when possible, in
 order to reduce the size of the tags file.
index 8a6ddd5..ad3f607 100644 (file)
@@ -140,9 +140,7 @@ Several are for Debian GNU/Linux in particular.
  * Dismal: spreadsheet:
    <URL:http://acs.ist.psu.edu/dismal/dismal.html>
 
- * EDB: database:
-   <URL:http://sdg.lcs.mit.edu/%7Emernst/software/edb-mrp.tar.gz>
-   Not maintained?
+ * EDB: database: <URL:http://www.glug.org/people/ttn/software/edb/>
 
  * Ee: categorizing information manager:
    <URL:http://www.jurta.org/emacs/ee/>
index 667e0f5..0c62333 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -692,6 +692,8 @@ version 4.7 or newer, compiles to Info pages with embedded images.
 'sql-sqlite'.
 
 ** BibTeX mode:
+*** The new command bibtex-url browses a URL for the BibTeX entry at
+point (bound to C-c C-l and mouse-2 on clickable fields).
 *** The new command bibtex-entry-update (bound to C-c C-u) updates
 an existing BibTeX entry.
 *** New `bibtex-entry-format' option `required-fields', enabled by default.
@@ -1247,9 +1249,9 @@ and to type `C-f' at the end of the search string in the minibuffer.
 search string used as the string to replace.
 
 +++
-** New user option `isearch-resume-enabled'.
-This option can be disabled, to avoid the normal behavior of isearch
-which puts calls to `isearch-resume' in the command history.
+** Isearch no longer adds `isearch-resume' commands to the command
+history by default.  To enable this feature, customize the new
+user option `isearch-resume-in-command-history'.
 
 +++
 ** New user option `history-delete-duplicates'.
@@ -1569,29 +1571,31 @@ per line.  Lines beginning with space or tab are ignored.
 **** The `::' qualifier triggers C++ parsing in C file.
 Previously, only the `template' and `class' keywords had this effect.
 
+**** New language HTML.
+Title and h1, h2, h3 are tagged.  Also, tags are generated when name= is
+used inside an anchor and whenever id= is used.
+
+**** In Makefiles, constants are tagged.
+If you want the old behavior instead, thus avoiding to increase the
+size of the tags file, use the --no-globals option.
+
+**** In Lua, all functions are tagged.
+
 **** In Perl, packages are tags.
 Subroutine tags are named from their package.  You can jump to sub tags
 as you did before, by the sub name, or additionally by looking for
 package::sub.
 
+**** In Prolog, etags creates tags for rules in addition to predicates.
+
 **** New language PHP.
 Tags are functions, classes and defines.
 If the --members option is specified to etags, tags are vars also.
 
-**** New language HTML.
-Title and h1, h2, h3 are tagged.  Also, tags are generated when name= is
-used inside an anchor and whenever id= is used.
-
 **** New default keywords for TeX.
 The new keywords are def, newcommand, renewcommand, newenvironment and
 renewenvironment.
 
-**** In Makefiles, constants are tagged.
-If you want the old behavior instead, thus avoiding to increase the
-size of the tags file, use the --no-globals option.
-
-**** In Prolog, etags creates tags for rules in addition to predicates.
-
 *** Honour #line directives.
 When Etags parses an input file that contains C preprocessor's #line
 directives, it creates tags using the file name and line number
@@ -1602,7 +1606,7 @@ writes tags pointing to the source file.
 *** New option --parse-stdin=FILE.
 This option is mostly useful when calling etags from programs.  It can
 be used (only once) in place of a file name on the command line.  Etags
-reads from standard input and mark the produced tags as belonging to
+reads from standard input and marks the produced tags as belonging to
 the file FILE.
 
 +++
@@ -2075,6 +2079,10 @@ anyone has committed to the repository since you last executed
 \f
 * New modes and packages in Emacs 21.4
 
+** The new package dns-mode.el add syntax highlight of DNS master files.
+The key binding C-c C-s (`dns-mode-soa-increment-serial') can be used
+to increment the SOA serial.
+
 ** The new package flymake.el does on-the-fly syntax checking of program
 source files.  See the Flymake's Info manual for more details.
 
index 8aa2fd5..2a84c62 100644 (file)
@@ -50,7 +50,7 @@ format understood by
 .BR vi ( 1 )\c
 \&.  Both forms of the program understand
 the syntax of C, Objective C, C++, Java, Fortran, Ada, Cobol, Erlang, HTML,
-LaTeX, Emacs Lisp/Common Lisp, makefiles, Pascal, Perl, PHP, Postscript,
+LaTeX, Emacs Lisp/Common Lisp, Lua, makefile, Pascal, Perl, PHP, Postscript,
 Python, Prolog, Scheme and
 most assembler\-like syntaxes.
 Both forms read the files specified on the command line, and write a tag
@@ -58,7 +58,9 @@ table (defaults: \fBTAGS\fP for \fBetags\fP, \fBtags\fP for
 \fBctags\fP) in the current working directory.
 Files specified with relative file names will be recorded in the tag
 table with file names relative to the directory where the tag table
-resides.  Files specified with absolute file names will be recorded
+resides.  If the tag table is in /dev, however, the file names are made
+relative to the working directory.  Files specified with absolute file
+names will be recorded
 with absolute file names.  Files generated from a source file\-\-like
 a C file generated from a source Cweb file\-\-will be recorded with
 the name of the source file.
index 909a571..c04bdf2 100644 (file)
@@ -1,3 +1,28 @@
+2004-09-13  Francesco Potort\e,Al\e(B  <pot@gnu.org>
+
+       * etags.c (main): When relative file names are given as argument,
+       make them relative to the current working dir, rather than
+       relative to the output tags file, if the latter is in /dev.
+
+2004-09-13  Francesco Potort\e,Al\e(B  <pot@gnu.org>
+
+       * etags.c [EXIT_SUCCESS, EXIT_FAILURE]: Define them when no
+       <stdlib.h> is available.
+       (enum sym_type): New st_C_attribute value for parsing
+       gcc's __attribute__.  Deleted st_C_typespec value.
+       (gperf, in_word_set): Use gperf 3, options changed.  Added the
+       __attribute__ keyword, removed all the st_C_typespec keywords,
+       changed attribute for Java to (C_JAVA & !C_PLPL).
+       (inattribute): New global bool, part of the C state machine.
+       (cblev): Identifier renamed to bracelev throughout.
+       (consider_token, C_entries): Numerous changes for making the
+       parser more robust and adding support for __attribute__.
+
+2004-09-13  David A. Capello  <dacap@users.sourceforge.net>  (tiny change)
+
+       * etags.c: (Lua_suffixes, Lua_help, lang_names, Lua_functions):
+       Support the Lua scripting language <http://www.lua.org>.
+
 2004-09-08  Francesco Potort\e,Al\e(B  <pot@gnu.org>
 
        * etags.c: [LONG_OPTIONS]: make it TRUE (ifdef) or FALSE (ifndef)
index 094c81e..a6004a0 100644 (file)
  * 2002 #line directives by Francesco Potortì.
  *
  * Francesco Potortì <pot@gnu.org> has maintained and improved it since 1993.
- *
  */
 
-char pot_etags_version[] = "@(#) pot revision number is 16.58";
+/*
+ * If you want to add support for a new language, start by looking at the LUA
+ * language, which is the simplest.  Alternatively, consider shipping a
+ * configuration file containing regexp definitions for etags.
+ */
+
+char pot_etags_version[] = "@(#) pot revision number is 17.5";
 
 #define        TRUE    1
 #define        FALSE   0
@@ -61,11 +66,11 @@ char pot_etags_version[] = "@(#) pot revision number is 16.58";
 # ifndef __P                   /* for Xemacs */
 #   define __P(args) args
 # endif
-#else
+#else  /* no config.h */
 # if defined(__STDC__) && (__STDC__ || defined(__SUNPRO_C))
 #   define __P(args) args      /* use prototypes */
 #   define PTR void *          /* for generic pointers */
-# else
+# else /* not standard C */
 #   define __P(args) ()                /* no prototypes */
 #   define const               /* remove const for old compilers' sake */
 #   define PTR long *          /* don't use void* */
@@ -118,12 +123,19 @@ char pot_etags_version[] = "@(#) pot revision number is 16.58";
 # ifndef HAVE_GETCWD
 #   define HAVE_GETCWD
 # endif /* undef HAVE_GETCWD */
-#else /* !WINDOWSNT */
+#else /* not WINDOWSNT */
 # ifdef STDC_HEADERS
 #  include <stdlib.h>
 #  include <string.h>
-# else
+# else /* no standard C headers */
     extern char *getenv ();
+#  ifdef VMS
+#   define EXIT_SUCCESS        1
+#   define EXIT_FAILURE        0
+#  else /* no VMS */
+#   define EXIT_SUCCESS        0
+#   define EXIT_FAILURE        1
+#  endif
 # endif
 #endif /* !WINDOWSNT */
 
@@ -333,6 +345,7 @@ static void Erlang_functions __P((FILE *));
 static void Fortran_functions __P((FILE *));
 static void HTML_labels __P((FILE *));
 static void Lisp_functions __P((FILE *));
+static void Lua_functions __P((FILE *));
 static void Makefile_targets __P((FILE *));
 static void Pascal_functions __P((FILE *));
 static void Perl_functions __P((FILE *));
@@ -637,6 +650,11 @@ defined with `defvar' or `defconst', and in general the first\n\
 argument of any expression that starts with `(def' in column zero\n\
 is a tag.";
 
+static char *Lua_suffixes [] =
+  { "lua", "LUA", NULL };
+static char Lua_help [] =
+"In Lua scripts, all functions are tags.";
+
 static char *Makefile_filenames [] =
   { "Makefile", "makefile", "GNUMakefile", "Makefile.in", "Makefile.am", NULL};
 static char Makefile_help [] =
@@ -763,6 +781,7 @@ static language lang_names [] =
   { "html",      HTML_help,      HTML_labels,       HTML_suffixes      },
   { "java",      Cjava_help,     Cjava_entries,     Cjava_suffixes     },
   { "lisp",      Lisp_help,      Lisp_functions,    Lisp_suffixes      },
+  { "lua",       Lua_help,       Lua_functions,     Lua_suffixes       },
   { "makefile",  Makefile_help,Makefile_targets,NULL,Makefile_filenames},
   { "objc",      Objc_help,      plain_C_entries,   Objc_suffixes      },
   { "pascal",    Pascal_help,    Pascal_functions,  Pascal_suffixes    },
@@ -1295,7 +1314,9 @@ main (argc, argv)
       cwd = concat (oldcwd, "/", "");
       free (oldcwd);
     }
-  if (streq (tagfile, "-"))
+  /* Relative file names are made relative to the current directory. */
+  if (streq (tagfile, "-")
+      || strneq (tagfile, "/dev/", 5))
     tagfiledir = cwd;
   else
     tagfiledir = absolute_dirname (tagfile, cwd);
@@ -2373,11 +2394,11 @@ enum sym_type
   st_none,
   st_C_objprot, st_C_objimpl, st_C_objend,
   st_C_gnumacro,
-  st_C_ignore,
+  st_C_ignore, st_C_attribute,
   st_C_javastruct,
   st_C_operator,
   st_C_class, st_C_template,
-  st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef, st_C_typespec
+  st_C_struct, st_C_extern, st_C_enum, st_C_define, st_C_typedef
 };
 
 static unsigned int hash __P((const char *, unsigned int));
@@ -2385,79 +2406,67 @@ static struct C_stab_entry * in_word_set __P((const char *, unsigned int));
 static enum sym_type C_symtype __P((char *, int, int));
 
 /* Feed stuff between (but not including) %[ and %] lines to:
-      gperf -c -k 1,3 -o -p -r -t
+     gperf -m 5
 %[
+%compare-strncmp
+%enum
+%struct-type
 struct C_stab_entry { char *name; int c_ext; enum sym_type type; }
 %%
-if,            0,      st_C_ignore
-for,           0,      st_C_ignore
-while,         0,      st_C_ignore
-switch,                0,      st_C_ignore
-return,                0,      st_C_ignore
-@interface,    0,      st_C_objprot
-@protocol,     0,      st_C_objprot
-@implementation,0,     st_C_objimpl
-@end,          0,      st_C_objend
-import,                C_JAVA, st_C_ignore
-package,       C_JAVA, st_C_ignore
-friend,                C_PLPL, st_C_ignore
-extends,       C_JAVA, st_C_javastruct
-implements,    C_JAVA, st_C_javastruct
-interface,     C_JAVA, st_C_struct
-class,         0,      st_C_class
-namespace,     C_PLPL, st_C_struct
-domain,        C_STAR, st_C_struct
-union,         0,      st_C_struct
-struct,        0,      st_C_struct
-extern,        0,      st_C_extern
-enum,          0,      st_C_enum
-typedef,       0,      st_C_typedef
-define,        0,      st_C_define
-operator,      C_PLPL, st_C_operator
-template,      0,      st_C_template
-bool,          C_PLPL, st_C_typespec
-long,          0,      st_C_typespec
-short,         0,      st_C_typespec
-int,           0,      st_C_typespec
-char,          0,      st_C_typespec
-float,         0,      st_C_typespec
-double,        0,      st_C_typespec
-signed,        0,      st_C_typespec
-unsigned,      0,      st_C_typespec
-auto,          0,      st_C_typespec
-void,          0,      st_C_typespec
-static,        0,      st_C_typespec
-const,         0,      st_C_typespec
-volatile,      0,      st_C_typespec
-explicit,      C_PLPL, st_C_typespec
-mutable,       C_PLPL, st_C_typespec
-typename,      C_PLPL, st_C_typespec
+if,            0,                      st_C_ignore
+for,           0,                      st_C_ignore
+while,         0,                      st_C_ignore
+switch,                0,                      st_C_ignore
+return,                0,                      st_C_ignore
+__attribute__, 0,                      st_C_attribute
+@interface,    0,                      st_C_objprot
+@protocol,     0,                      st_C_objprot
+@implementation,0,                     st_C_objimpl
+@end,          0,                      st_C_objend
+import,                (C_JAVA & !C_PLPL),     st_C_ignore
+package,       (C_JAVA & !C_PLPL),     st_C_ignore
+friend,                C_PLPL,                 st_C_ignore
+extends,       (C_JAVA & !C_PLPL),     st_C_javastruct
+implements,    (C_JAVA & !C_PLPL),     st_C_javastruct
+interface,     (C_JAVA & !C_PLPL),     st_C_struct
+class,         0,                      st_C_class
+namespace,     C_PLPL,                 st_C_struct
+domain,                C_STAR,                 st_C_struct
+union,         0,                      st_C_struct
+struct,                0,                      st_C_struct
+extern,                0,                      st_C_extern
+enum,          0,                      st_C_enum
+typedef,       0,                      st_C_typedef
+define,                0,                      st_C_define
+operator,      C_PLPL,                 st_C_operator
+template,      0,                      st_C_template
 # DEFUN used in emacs, the next three used in glibc (SYSCALL only for mach).
-DEFUN,         0,      st_C_gnumacro
-SYSCALL,       0,      st_C_gnumacro
-ENTRY,         0,      st_C_gnumacro
-PSEUDO,                0,      st_C_gnumacro
+DEFUN,         0,                      st_C_gnumacro
+SYSCALL,       0,                      st_C_gnumacro
+ENTRY,         0,                      st_C_gnumacro
+PSEUDO,                0,                      st_C_gnumacro
 # These are defined inside C functions, so currently they are not met.
 # EXFUN used in glibc, DEFVAR_* in emacs.
-#EXFUN,                0,      st_C_gnumacro
-#DEFVAR_,      0,      st_C_gnumacro
+#EXFUN,                0,                      st_C_gnumacro
+#DEFVAR_,      0,                      st_C_gnumacro
 %]
-and replace lines between %< and %> with its output,
-then make in_word_set and C_stab_entry static. */
+and replace lines between %< and %> with its output, then:
+ - remove the #if characterset check
+ - make in_word_set static and not inline. */
 /*%<*/
-/* C code produced by gperf version 2.7.1 (19981006 egcs) */
-/* Command-line: gperf -c -k 1,3 -o -p -r -t  */
-struct C_stab_entry { char *name; int c_ext; enum sym_type type; };
+/* C code produced by gperf version 3.0.1 */
+/* Command-line: gperf -m 5  */
+/* Computed positions: -k'1-2' */
 
-#define TOTAL_KEYWORDS 47
-#define MIN_WORD_LENGTH 2
-#define MAX_WORD_LENGTH 15
-#define MIN_HASH_VALUE 18
-#define MAX_HASH_VALUE 138
-/* maximum key range = 121, duplicates = 0 */
+struct C_stab_entry { char *name; int c_ext; enum sym_type type; };
+/* maximum key range = 31, duplicates = 0 */
 
 #ifdef __GNUC__
 __inline
+#else
+#ifdef __cplusplus
+inline
+#endif
 #endif
 static unsigned int
 hash (str, len)
@@ -2466,132 +2475,84 @@ hash (str, len)
 {
   static unsigned char asso_values[] =
     {
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139,  63, 139, 139, 139,  33,  44,
-       62, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-       42, 139, 139,  12,  32, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139,  34,  59,  37,
-       24,  58,  33,   3, 139,  16, 139, 139,  42,  60,
-       18,  11,  39, 139,  23,  57,   4,  63,   6,  20,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139, 139, 139, 139, 139,
-      139, 139, 139, 139, 139, 139
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34,  1, 34, 34, 34, 14, 14,
+      34, 34, 34, 34, 34, 34, 34, 34, 13, 34,
+      13, 34, 34, 12, 34, 34, 34, 34, 34, 11,
+      34, 34, 34, 34, 34,  8, 34, 11, 34, 12,
+      11,  0,  1, 34,  7,  0, 34, 34, 11,  9,
+       0,  4,  0, 34,  7,  4, 14, 21, 34, 15,
+       0,  2, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+      34, 34, 34, 34, 34, 34
     };
-  register int hval = len;
-
-  switch (hval)
-    {
-      default:
-      case 3:
-        hval += asso_values[(unsigned char)str[2]];
-      case 2:
-      case 1:
-        hval += asso_values[(unsigned char)str[0]];
-        break;
-    }
-  return hval;
+  return len + asso_values[(unsigned char)str[1]] + asso_values[(unsigned char)str[0]];
 }
 
-#ifdef __GNUC__
-__inline
-#endif
 static struct C_stab_entry *
 in_word_set (str, len)
      register const char *str;
      register unsigned int len;
 {
+  enum
+    {
+      TOTAL_KEYWORDS = 31,
+      MIN_WORD_LENGTH = 2,
+      MAX_WORD_LENGTH = 15,
+      MIN_HASH_VALUE = 3,
+      MAX_HASH_VALUE = 33
+    };
+
   static struct C_stab_entry wordlist[] =
     {
-      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
-      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
-      {"if",           0,      st_C_ignore},
-      {""}, {""}, {""}, {""},
-      {"int",          0,      st_C_typespec},
-      {""}, {""},
-      {"void",         0,      st_C_typespec},
-      {""}, {""},
-      {"interface",    C_JAVA, st_C_struct},
-      {""},
-      {"SYSCALL",      0,      st_C_gnumacro},
-      {""},
-      {"return",               0,      st_C_ignore},
-      {""}, {""}, {""}, {""}, {""}, {""}, {""},
-      {"while",                0,      st_C_ignore},
-      {"auto",         0,      st_C_typespec},
-      {""}, {""}, {""}, {""}, {""}, {""},
-      {"float",        0,      st_C_typespec},
-      {"typedef",      0,      st_C_typedef},
-      {"typename",     C_PLPL, st_C_typespec},
       {""}, {""}, {""},
-      {"friend",               C_PLPL, st_C_ignore},
-      {"volatile",     0,      st_C_typespec},
-      {""}, {""},
-      {"for",          0,      st_C_ignore},
-      {"const",        0,      st_C_typespec},
-      {"import",               C_JAVA, st_C_ignore},
-      {""},
-      {"define",       0,      st_C_define},
-      {"long",         0,      st_C_typespec},
-      {"implements",   C_JAVA, st_C_javastruct},
-      {"signed",       0,      st_C_typespec},
-      {""},
-      {"extern",       0,      st_C_extern},
-      {"extends",      C_JAVA, st_C_javastruct},
-      {""},
-      {"mutable",      C_PLPL, st_C_typespec},
-      {"template",     0,      st_C_template},
-      {"short",        0,      st_C_typespec},
-      {"bool",         C_PLPL, st_C_typespec},
-      {"char",         0,      st_C_typespec},
-      {"class",        0,      st_C_class},
-      {"operator",     C_PLPL, st_C_operator},
-      {""},
-      {"switch",               0,      st_C_ignore},
-      {""},
-      {"ENTRY",                0,      st_C_gnumacro},
-      {""},
-      {"package",      C_JAVA, st_C_ignore},
-      {"union",        0,      st_C_struct},
-      {"@end",         0,      st_C_objend},
-      {"struct",       0,      st_C_struct},
-      {"namespace",    C_PLPL, st_C_struct},
-      {""}, {""},
-      {"domain",       C_STAR, st_C_struct},
-      {"@interface",   0,      st_C_objprot},
-      {"PSEUDO",               0,      st_C_gnumacro},
-      {"double",       0,      st_C_typespec},
-      {""},
-      {"@protocol",    0,      st_C_objprot},
-      {""},
-      {"static",       0,      st_C_typespec},
-      {""}, {""},
-      {"DEFUN",                0,      st_C_gnumacro},
-      {""}, {""}, {""}, {""},
-      {"explicit",     C_PLPL, st_C_typespec},
-      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
-      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
-      {""},
-      {"enum",         0,      st_C_enum},
-      {""}, {""},
-      {"unsigned",     0,      st_C_typespec},
-      {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
-      {"@implementation",0,    st_C_objimpl}
+      {"if",           0,                      st_C_ignore},
+      {"enum",         0,                      st_C_enum},
+      {"@end",         0,                      st_C_objend},
+      {"extern",               0,                      st_C_extern},
+      {"extends",      (C_JAVA & !C_PLPL),     st_C_javastruct},
+      {"for",          0,                      st_C_ignore},
+      {"interface",    (C_JAVA & !C_PLPL),     st_C_struct},
+      {"@protocol",    0,                      st_C_objprot},
+      {"@interface",   0,                      st_C_objprot},
+      {"operator",     C_PLPL,                 st_C_operator},
+      {"return",               0,                      st_C_ignore},
+      {"friend",               C_PLPL,                 st_C_ignore},
+      {"import",               (C_JAVA & !C_PLPL),     st_C_ignore},
+      {"@implementation",0,                    st_C_objimpl},
+      {"define",               0,                      st_C_define},
+      {"package",      (C_JAVA & !C_PLPL),     st_C_ignore},
+      {"implements",   (C_JAVA & !C_PLPL),     st_C_javastruct},
+      {"namespace",    C_PLPL,                 st_C_struct},
+      {"domain",               C_STAR,                 st_C_struct},
+      {"template",     0,                      st_C_template},
+      {"typedef",      0,                      st_C_typedef},
+      {"struct",               0,                      st_C_struct},
+      {"switch",               0,                      st_C_ignore},
+      {"union",                0,                      st_C_struct},
+      {"while",                0,                      st_C_ignore},
+      {"class",                0,                      st_C_class},
+      {"__attribute__",        0,                      st_C_attribute},
+      {"SYSCALL",      0,                      st_C_gnumacro},
+      {"PSEUDO",               0,                      st_C_gnumacro},
+      {"ENTRY",                0,                      st_C_gnumacro},
+      {"DEFUN",                0,                      st_C_gnumacro}
     };
 
   if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
@@ -2602,7 +2563,7 @@ in_word_set (str, len)
         {
           register const char *s = wordlist[key].name;
 
-          if (*str == *s && !strncmp (str + 1, s + 1, len - 1))
+          if (*str == *s && !strncmp (str + 1, s + 1, len - 1) && s[len] == '\0')
             return &wordlist[key];
         }
     }
@@ -2624,6 +2585,11 @@ C_symtype (str, len, c_ext)
 }
 
 \f
+/*
+ * Ignoring __attribute__ ((list))
+ */
+static bool inattribute;       /* looking at an __attribute__ construct */
+
 /*
  * C functions and variables are recognized using a simple
  * finite automaton.  fvdef is its state variable.
@@ -2666,10 +2632,9 @@ static enum
 static enum
 {
   snone,                       /* nothing seen yet,
-                                  or in struct body if cblev > 0 */
+                                  or in struct body if bracelev > 0 */
   skeyseen,                    /* struct-like keyword seen */
   stagseen,                    /* struct-like tag seen */
-  sintemplate,                 /* inside template (ignore) */
   scolonseen                   /* colon seen after struct-like tag */
 } structdef;
 
@@ -2743,7 +2708,7 @@ static void write_classname __P((linebuffer *, char *qualifier));
 
 static struct {
   char **cname;                        /* nested class names */
-  int *cblev;                  /* nested class curly brace level */
+  int *bracelev;               /* nested class brace level */
   int nl;                      /* class nesting level (elements used) */
   int size;                    /* length of the array */
 } cstack;                      /* stack for nested declaration tags */
@@ -2751,38 +2716,38 @@ static struct {
 #define nestlev                (cstack.nl)
 /* After struct keyword or in struct body, not inside a nested function. */
 #define instruct       (structdef == snone && nestlev > 0                      \
-                        && cblev == cstack.cblev[nestlev-1] + 1)
+                        && bracelev == cstack.bracelev[nestlev-1] + 1)
 
 static void
-pushclass_above (cblev, str, len)
-     int cblev;
+pushclass_above (bracelev, str, len)
+     int bracelev;
      char *str;
      int len;
 {
   int nl;
 
-  popclass_above (cblev);
+  popclass_above (bracelev);
   nl = cstack.nl;
   if (nl >= cstack.size)
     {
       int size = cstack.size *= 2;
       xrnew (cstack.cname, size, char *);
-      xrnew (cstack.cblev, size, int);
+      xrnew (cstack.bracelev, size, int);
     }
-  assert (nl == 0 || cstack.cblev[nl-1] < cblev);
+  assert (nl == 0 || cstack.bracelev[nl-1] < bracelev);
   cstack.cname[nl] = (str == NULL) ? NULL : savenstr (str, len);
-  cstack.cblev[nl] = cblev;
+  cstack.bracelev[nl] = bracelev;
   cstack.nl = nl + 1;
 }
 
 static void
-popclass_above (cblev)
-     int cblev;
+popclass_above (bracelev)
+     int bracelev;
 {
   int nl;
 
   for (nl = cstack.nl - 1;
-       nl >= 0 && cstack.cblev[nl] >= cblev;
+       nl >= 0 && cstack.bracelev[nl] >= bracelev;
        nl--)
     {
       if (cstack.cname[nl] != NULL)
@@ -2849,269 +2814,286 @@ static void make_C_tag __P((bool));
  */
 
 static bool
-consider_token (str, len, c, c_extp, cblev, parlev, is_func_or_var)
+consider_token (str, len, c, c_extp, bracelev, parlev, is_func_or_var)
      register char *str;       /* IN: token pointer */
      register int len;         /* IN: token length */
      register int c;           /* IN: first char after the token */
      int *c_extp;              /* IN, OUT: C extensions mask */
-     int cblev;                        /* IN: curly brace level */
+     int bracelev;             /* IN: brace level */
      int parlev;               /* IN: parenthesis level */
      bool *is_func_or_var;     /* OUT: function or variable found */
 {
-  /* When structdef is stagseen, scolonseen, or snone with cblev > 0,
+  /* When structdef is stagseen, scolonseen, or snone with bracelev > 0,
      structtype is the type of the preceding struct-like keyword, and
-     structcblev is the curly brace level where it has been seen. */
+     structbracelev is the brace level where it has been seen. */
   static enum sym_type structtype;
-  static int structcblev;
+  static int structbracelev;
   static enum sym_type toktype;
 
 
   toktype = C_symtype (str, len, *c_extp);
 
   /*
-   * Advance the definedef state machine.
-   */
-  switch (definedef)
-    {
-    case dnone:
-      /* We're not on a preprocessor line. */
-      if (toktype == st_C_gnumacro)
-       {
-         fvdef = fdefunkey;
-         return FALSE;
-       }
-      break;
-    case dsharpseen:
-      if (toktype == st_C_define)
-       {
-         definedef = ddefineseen;
-       }
-      else
-       {
-         definedef = dignorerest;
-       }
-      return FALSE;
-    case ddefineseen:
-      /*
-       * Make a tag for any macro, unless it is a constant
-       * and constantypedefs is FALSE.
-       */
-      definedef = dignorerest;
-      *is_func_or_var = (c == '(');
-      if (!*is_func_or_var && !constantypedefs)
-       return FALSE;
-      else
-       return TRUE;
-    case dignorerest:
-      return FALSE;
-    default:
-      error ("internal error: definedef value.", (char *)NULL);
-    }
-
-  /*
-   * Now typedefs
-   */
-  switch (typdef)
-    {
-    case tnone:
-      if (toktype == st_C_typedef)
-       {
-         if (typedefs)
-           typdef = tkeyseen;
-         fvextern = FALSE;
-         fvdef = fvnone;
-         return FALSE;
-       }
-      break;
-    case tkeyseen:
-      switch (toktype)
-       {
-       case st_none:
-       case st_C_typespec:
-       case st_C_class:
-       case st_C_struct:
-       case st_C_enum:
-         typdef = ttypeseen;
-         break;
-       }
-      break;
-    case ttypeseen:
-      if (structdef == snone && fvdef == fvnone)
-       {
-         fvdef = fvnameseen;
-         return TRUE;
-       }
-      break;
-    case tend:
-      switch (toktype)
-       {
-       case st_C_typespec:
-       case st_C_class:
-       case st_C_struct:
-       case st_C_enum:
-         return FALSE;
-       }
-      return TRUE;
-    }
-
-  /*
-   * This structdef business is NOT invoked when we are ctags and the
-   * file is plain C.  This is because a struct tag may have the same
-   * name as another tag, and this loses with ctags.
+   * Skip __attribute__
    */
-  switch (toktype)
-    {
-    case st_C_javastruct:
-      if (structdef == stagseen)
-        structdef = scolonseen;
-      return FALSE;
-    case st_C_template:
-    case st_C_class:
-      if ((*c_extp & C_AUTO)   /* automatic detection of C++ language */
-         && cblev == 0
-         && definedef == dnone && structdef == snone
-         && typdef == tnone && fvdef == fvnone)
-       *c_extp = (*c_extp | C_PLPL) & ~C_AUTO;
-      if (toktype == st_C_template)
-       break;
-      /* FALLTHRU */
-    case st_C_struct:
-    case st_C_enum:
-      if (parlev == 0
-         && fvdef != vignore
-         && (typdef == tkeyseen
-             || (typedefs_or_cplusplus && structdef == snone)))
-       {
-         structdef = skeyseen;
-         structtype = toktype;
-         structcblev = cblev;
-       }
-      return FALSE;
-    }
-
-  if (structdef == skeyseen)
+  if (toktype == st_C_attribute)
     {
-      structdef = stagseen;
-      return TRUE;
-    }
-
-  if (typdef != tnone)
-    definedef = dnone;
-
-  /* Detect Objective C constructs. */
-  switch (objdef)
-    {
-    case onone:
-      switch (toktype)
-       {
-       case st_C_objprot:
-         objdef = oprotocol;
-         return FALSE;
-       case st_C_objimpl:
-         objdef = oimplementation;
-         return FALSE;
-       }
-      break;
-    case oimplementation:
-      /* Save the class tag for functions or variables defined inside. */
-      objtag = savenstr (str, len);
-      objdef = oinbody;
+      inattribute = TRUE;
       return FALSE;
-    case oprotocol:
-      /* Save the class tag for categories. */
-      objtag = savenstr (str, len);
-      objdef = otagseen;
-      *is_func_or_var = TRUE;
-      return TRUE;
-    case oparenseen:
-      objdef = ocatseen;
-      *is_func_or_var = TRUE;
-      return TRUE;
-    case oinbody:
-      break;
-    case omethodsign:
-      if (parlev == 0)
-       {
-         objdef = omethodtag;
-         linebuffer_setlen (&token_name, len);
-         strncpy (token_name.buffer, str, len);
-         token_name.buffer[len] = '\0';
-         return TRUE;
-       }
-      return FALSE;
-    case omethodcolon:
-      if (parlev == 0)
-       objdef = omethodparm;
-      return FALSE;
-    case omethodparm:
-      if (parlev == 0)
-       {
-         objdef = omethodtag;
-         linebuffer_setlen (&token_name, token_name.len + len);
-         strncat (token_name.buffer, str, len);
-         return TRUE;
-       }
-      return FALSE;
-    case oignore:
-      if (toktype == st_C_objend)
-       {
-         /* Memory leakage here: the string pointed by objtag is
-            never released, because many tests would be needed to
-            avoid breaking on incorrect input code.  The amount of
-            memory leaked here is the sum of the lengths of the
-            class tags.
-         free (objtag); */
-         objdef = onone;
-       }
-      return FALSE;
-    }
-
-  /* A function, variable or enum constant? */
-  switch (toktype)
-    {
-    case st_C_extern:
-      fvextern = TRUE;
-      /* FALLTHRU */
-    case st_C_typespec:
-      switch  (fvdef)
-       {
-       case finlist:
-       case flistseen:
-       case fignore:
-       case vignore:
-         break;
-       default:
-         fvdef = fvnone;
-       }
-      return FALSE;
-    case st_C_ignore:
-      fvextern = FALSE;
-      fvdef = vignore;
-      return FALSE;
-    case st_C_operator:
-      fvdef = foperator;
-      *is_func_or_var = TRUE;
-      return TRUE;
-    case st_none:
-      if (constantypedefs
-         && structdef == snone
-         && structtype == st_C_enum && cblev > structcblev)
-       return TRUE;            /* enum constant */
-      switch (fvdef)
-       {
-       case fdefunkey:
-         if (cblev > 0)
-           break;
-         fvdef = fdefunname;   /* GNU macro */
-         *is_func_or_var = TRUE;
-         return TRUE;
-       case fvnone:
-         if ((strneq (str, "asm", 3) && endtoken (str[3]))
-             || (strneq (str, "__asm__", 7) && endtoken (str[7])))
-           {
-             fvdef = vignore;
-             return FALSE;
-           }
+     }
+
+   /*
+    * Advance the definedef state machine.
+    */
+   switch (definedef)
+     {
+     case dnone:
+       /* We're not on a preprocessor line. */
+       if (toktype == st_C_gnumacro)
+        {
+          fvdef = fdefunkey;
+          return FALSE;
+        }
+       break;
+     case dsharpseen:
+       if (toktype == st_C_define)
+        {
+          definedef = ddefineseen;
+        }
+       else
+        {
+          definedef = dignorerest;
+        }
+       return FALSE;
+     case ddefineseen:
+       /*
+       * Make a tag for any macro, unless it is a constant
+       * and constantypedefs is FALSE.
+       */
+       definedef = dignorerest;
+       *is_func_or_var = (c == '(');
+       if (!*is_func_or_var && !constantypedefs)
+        return FALSE;
+       else
+        return TRUE;
+     case dignorerest:
+       return FALSE;
+     default:
+       error ("internal error: definedef value.", (char *)NULL);
+     }
+
+   /*
+    * Now typedefs
+    */
+   switch (typdef)
+     {
+     case tnone:
+       if (toktype == st_C_typedef)
+        {
+          if (typedefs)
+            typdef = tkeyseen;
+          fvextern = FALSE;
+          fvdef = fvnone;
+          return FALSE;
+        }
+       break;
+     case tkeyseen:
+       switch (toktype)
+        {
+        case st_none:
+        case st_C_class:
+        case st_C_struct:
+        case st_C_enum:
+          typdef = ttypeseen;
+        }
+       break;
+     case ttypeseen:
+       if (structdef == snone && fvdef == fvnone)
+        {
+          fvdef = fvnameseen;
+          return TRUE;
+        }
+       break;
+     case tend:
+       switch (toktype)
+        {
+        case st_C_class:
+        case st_C_struct:
+        case st_C_enum:
+          return FALSE;
+        }
+       return TRUE;
+     }
+
+   /*
+    * This structdef business is NOT invoked when we are ctags and the
+    * file is plain C.  This is because a struct tag may have the same
+    * name as another tag, and this loses with ctags.
+    */
+   switch (toktype)
+     {
+     case st_C_javastruct:
+       if (structdef == stagseen)
+        structdef = scolonseen;
+       return FALSE;
+     case st_C_template:
+     case st_C_class:
+       if ((*c_extp & C_AUTO)  /* automatic detection of C++ language */
+          && bracelev == 0
+          && definedef == dnone && structdef == snone
+          && typdef == tnone && fvdef == fvnone)
+        *c_extp = (*c_extp | C_PLPL) & ~C_AUTO;
+       if (toktype == st_C_template)
+        break;
+       /* FALLTHRU */
+     case st_C_struct:
+     case st_C_enum:
+       if (parlev == 0
+          && fvdef != vignore
+          && (typdef == tkeyseen
+              || (typedefs_or_cplusplus && structdef == snone)))
+        {
+          structdef = skeyseen;
+          structtype = toktype;
+          structbracelev = bracelev;
+          if (fvdef == fvnameseen)
+            fvdef = fvnone;
+        }
+       return FALSE;
+     }
+
+   if (structdef == skeyseen)
+     {
+       structdef = stagseen;
+       return TRUE;
+     }
+
+   if (typdef != tnone)
+     definedef = dnone;
+
+   /* Detect Objective C constructs. */
+   switch (objdef)
+     {
+     case onone:
+       switch (toktype)
+        {
+        case st_C_objprot:
+          objdef = oprotocol;
+          return FALSE;
+        case st_C_objimpl:
+          objdef = oimplementation;
+          return FALSE;
+        }
+       break;
+     case oimplementation:
+       /* Save the class tag for functions or variables defined inside. */
+       objtag = savenstr (str, len);
+       objdef = oinbody;
+       return FALSE;
+     case oprotocol:
+       /* Save the class tag for categories. */
+       objtag = savenstr (str, len);
+       objdef = otagseen;
+       *is_func_or_var = TRUE;
+       return TRUE;
+     case oparenseen:
+       objdef = ocatseen;
+       *is_func_or_var = TRUE;
+       return TRUE;
+     case oinbody:
+       break;
+     case omethodsign:
+       if (parlev == 0)
+        {
+          fvdef = fvnone;
+          objdef = omethodtag;
+          linebuffer_setlen (&token_name, len);
+          strncpy (token_name.buffer, str, len);
+          token_name.buffer[len] = '\0';
+          return TRUE;
+        }
+       return FALSE;
+     case omethodcolon:
+       if (parlev == 0)
+        objdef = omethodparm;
+       return FALSE;
+     case omethodparm:
+       if (parlev == 0)
+        {
+          fvdef = fvnone;
+          objdef = omethodtag;
+          linebuffer_setlen (&token_name, token_name.len + len);
+          strncat (token_name.buffer, str, len);
+          return TRUE;
+        }
+       return FALSE;
+     case oignore:
+       if (toktype == st_C_objend)
+        {
+          /* Memory leakage here: the string pointed by objtag is
+             never released, because many tests would be needed to
+             avoid breaking on incorrect input code.  The amount of
+             memory leaked here is the sum of the lengths of the
+             class tags.
+          free (objtag); */
+          objdef = onone;
+        }
+       return FALSE;
+     }
+
+   /* A function, variable or enum constant? */
+   switch (toktype)
+     {
+     case st_C_extern:
+       fvextern = TRUE;
+       switch  (fvdef)
+        {
+        case finlist:
+        case flistseen:
+        case fignore:
+        case vignore:
+          break;
+        default:
+          fvdef = fvnone;
+        }
+       return FALSE;
+     case st_C_ignore:
+       fvextern = FALSE;
+       fvdef = vignore;
+       return FALSE;
+     case st_C_operator:
+       fvdef = foperator;
+       *is_func_or_var = TRUE;
+       return TRUE;
+     case st_none:
+       if (constantypedefs
+          && structdef == snone
+          && structtype == st_C_enum && bracelev > structbracelev)
+        return TRUE;           /* enum constant */
+       switch (fvdef)
+        {
+        case fdefunkey:
+          if (bracelev > 0)
+            break;
+          fvdef = fdefunname;  /* GNU macro */
+          *is_func_or_var = TRUE;
+          return TRUE;
+        case fvnone:
+          switch (typdef)
+            {
+            case ttypeseen:
+              return FALSE;
+            case tnone:
+              if ((strneq (str, "asm", 3) && endtoken (str[3]))
+                  || (strneq (str, "__asm__", 7) && endtoken (str[7])))
+                {
+                  fvdef = vignore;
+                  return FALSE;
+                }
+              break;
+            }
+         /* FALLTHRU */
+         case fvnameseen:
          if (len >= 10 && strneq (str+len-10, "::operator", 10))
            {
              if (*c_extp & C_AUTO) /* automatic detection of C++ */
@@ -3120,7 +3102,7 @@ consider_token (str, len, c, c_extp, cblev, parlev, is_func_or_var)
              *is_func_or_var = TRUE;
              return TRUE;
            }
-         if (cblev > 0 && !instruct)
+         if (bracelev > 0 && !instruct)
            break;
          fvdef = fvnameseen;   /* function or variable */
          *is_func_or_var = TRUE;
@@ -3216,9 +3198,12 @@ C_entries (c_ext, inf)
   register int toklen;         /* length of current token */
   char *qualifier;             /* string used to qualify names */
   int qlen;                    /* length of qualifier */
-  int cblev;                   /* current curly brace level */
+  int bracelev;                        /* current brace level */
+  int bracketlev;              /* current bracket level */
   int parlev;                  /* current parenthesis level */
-  int typdefcblev;             /* cblev where a typedef struct body begun */
+  int attrparlev;              /* __attribute__ parenthesis level */
+  int templatelev;             /* current template level */
+  int typdefbracelev;          /* bracelev where a typedef struct body begun */
   bool incomm, inquote, inchar, quotednl, midtoken;
   bool yacc_rules;             /* in the rules part of a yacc file */
   struct tok savetoken;                /* token saved during preprocessor handling */
@@ -3231,10 +3216,10 @@ C_entries (c_ext, inf)
       cstack.size = (DEBUG) ? 1 : 4;
       cstack.nl = 0;
       cstack.cname = xnew (cstack.size, char *);
-      cstack.cblev = xnew (cstack.size, int);
+      cstack.bracelev = xnew (cstack.size, int);
     }
 
-  tokoff = toklen = typdefcblev = 0; /* keep compiler quiet */
+  tokoff = toklen = typdefbracelev = 0; /* keep compiler quiet */
   curndx = newndx = 0;
   lp = curlb.buffer;
   *lp = 0;
@@ -3244,8 +3229,7 @@ C_entries (c_ext, inf)
   yacc_rules = FALSE;
   midtoken = inquote = inchar = incomm = quotednl = FALSE;
   token.valid = savetoken.valid = FALSE;
-  cblev = 0;
-  parlev = 0;
+  bracelev = bracketlev = parlev = attrparlev = templatelev = 0;
   if (cjava)
     { qualifier = "."; qlen = 1; }
   else
@@ -3257,8 +3241,8 @@ C_entries (c_ext, inf)
       c = *lp++;
       if (c == '\\')
        {
-         /* If we're at the end of the line, the next character is a
-            '\0'; don't skip it, because it's the thing that tells us
+         /* If we are at the end of the line, the next character is a
+            '\0'; do not skip it, because it is what tells us
             to read the next line.  */
          if (*lp == '\0')
            {
@@ -3317,95 +3301,115 @@ C_entries (c_ext, inf)
            }
          continue;
        }
-      else
-       switch (c)
-         {
-         case '"':
-           inquote = TRUE;
-           switch (fvdef)
-             {
-             case fdefunkey:
-             case fstartlist:
-             case finlist:
-             case fignore:
-             case vignore:
-               break;
-             default:
-               fvextern = FALSE;
-               fvdef = fvnone;
-             }
-           continue;
-         case '\'':
-           inchar = TRUE;
-           if (fvdef != finlist && fvdef != fignore && fvdef !=vignore)
-             {
-               fvextern = FALSE;
-               fvdef = fvnone;
-             }
-           continue;
-         case '/':
-           if (*lp == '*')
-             {
-               lp++;
-               incomm = TRUE;
+      else if (bracketlev > 0)
+       {
+         switch (c)
+           {
+           case ']':
+             if (--bracketlev > 0)
                continue;
-             }
-           else if (/* cplpl && */ *lp == '/')
-             {
-               c = '\0';
-               break;
-             }
-           else
              break;
-         case '%':
-           if ((c_ext & YACC) && *lp == '%')
-             {
-               /* Entering or exiting rules section in yacc file. */
-               lp++;
-               definedef = dnone; fvdef = fvnone; fvextern = FALSE;
-               typdef = tnone; structdef = snone;
-               midtoken = inquote = inchar = incomm = quotednl = FALSE;
-               cblev = 0;
-               yacc_rules = !yacc_rules;
-               continue;
-             }
-           else
+           case '\0':
+             CNL_SAVE_DEFINEDEF ();
              break;
-         case '#':
-           if (definedef == dnone)
-             {
-               char *cp;
-               bool cpptoken = TRUE;
-
-               /* Look back on this line.  If all blanks, or nonblanks
-                  followed by an end of comment, this is a preprocessor
-                  token. */
-               for (cp = newlb.buffer; cp < lp-1; cp++)
-                 if (!iswhite (*cp))
-                   {
-                     if (*cp == '*' && *(cp+1) == '/')
-                       {
-                         cp++;
-                         cpptoken = TRUE;
-                       }
-                     else
-                       cpptoken = FALSE;
-                   }
-               if (cpptoken)
-                 definedef = dsharpseen;
-             } /* if (definedef == dnone) */
-
+           }
+         continue;
+       }
+      else switch (c)
+       {
+       case '"':
+         inquote = TRUE;
+         if (inattribute)
+           break;
+         switch (fvdef)
+           {
+           case fdefunkey:
+           case fstartlist:
+           case finlist:
+           case fignore:
+           case vignore:
+             break;
+           default:
+             fvextern = FALSE;
+             fvdef = fvnone;
+           }
+         continue;
+       case '\'':
+         inchar = TRUE;
+         if (inattribute)
+           break;
+         if (fvdef != finlist && fvdef != fignore && fvdef !=vignore)
+           {
+             fvextern = FALSE;
+             fvdef = fvnone;
+           }
+         continue;
+       case '/':
+         if (*lp == '*')
+           {
+             lp++;
+             incomm = TRUE;
+             continue;
+           }
+         else if (/* cplpl && */ *lp == '/')
+           {
+             c = '\0';
+             break;
+           }
+         else
+           break;
+       case '%':
+         if ((c_ext & YACC) && *lp == '%')
+           {
+             /* Entering or exiting rules section in yacc file. */
+             lp++;
+             definedef = dnone; fvdef = fvnone; fvextern = FALSE;
+             typdef = tnone; structdef = snone;
+             midtoken = inquote = inchar = incomm = quotednl = FALSE;
+             bracelev = 0;
+             yacc_rules = !yacc_rules;
+             continue;
+           }
+         else
+           break;
+       case '#':
+         if (definedef == dnone)
+           {
+             char *cp;
+             bool cpptoken = TRUE;
+
+             /* Look back on this line.  If all blanks, or nonblanks
+                followed by an end of comment, this is a preprocessor
+                token. */
+             for (cp = newlb.buffer; cp < lp-1; cp++)
+               if (!iswhite (*cp))
+                 {
+                   if (*cp == '*' && *(cp+1) == '/')
+                     {
+                       cp++;
+                       cpptoken = TRUE;
+                     }
+                   else
+                     cpptoken = FALSE;
+                 }
+             if (cpptoken)
+               definedef = dsharpseen;
+           } /* if (definedef == dnone) */
+         continue;
+       case '[':
+         bracketlev++;
            continue;
-         } /* switch (c) */
+       } /* switch (c) */
 
 
       /* Consider token only if some involved conditions are satisfied. */
       if (typdef != tignore
          && definedef != dignorerest
          && fvdef != finlist
-         && structdef != sintemplate
+         && templatelev == 0
          && (definedef != dnone
-             || structdef != scolonseen))
+             || structdef != scolonseen)
+         && !inattribute)
        {
          if (midtoken)
            {
@@ -3429,7 +3433,8 @@ C_entries (c_ext, inf)
 
                      if (yacc_rules
                          || consider_token (newlb.buffer + tokoff, toklen, c,
-                                            &c_ext, cblev, parlev, &funorvar))
+                                            &c_ext, bracelev, parlev,
+                                            &funorvar))
                        {
                          if (fvdef == foperator)
                            {
@@ -3514,7 +3519,7 @@ C_entries (c_ext, inf)
                                             || (funorvar
                                                 && definedef == dnone
                                                 && structdef == snone
-                                                && cblev > 0));
+                                                && bracelev > 0));
                            }
                          token.lineno = lineno;
                          token.offset = tokoff;
@@ -3539,6 +3544,16 @@ C_entries (c_ext, inf)
                                   || instruct)
                            make_C_tag (funorvar);
                        }
+                     else /* not yacc and consider_token failed */
+                       {
+                         if (inattribute && fvdef == fignore)
+                           {
+                             /* We have just met __attribute__ after a
+                                function parameter list: do not tag the
+                                function again. */
+                             fvdef = fvnone;
+                           }
+                       }
                      midtoken = FALSE;
                    }
                } /* if (endtoken (c)) */
@@ -3557,6 +3572,9 @@ C_entries (c_ext, inf)
                  switch (fvdef)
                    {
                    case fstartlist:
+                     /* This prevents tagging fb in
+                        void (__attribute__((noreturn)) *fb) (void);
+                        Fixing this is not easy and not very important. */
                      fvdef = finlist;
                      continue;
                    case flistseen:
@@ -3566,13 +3584,10 @@ C_entries (c_ext, inf)
                          fvdef = fignore;
                        }
                      break;
-                   case fvnameseen:
-                     fvdef = fvnone;
-                     break;
                    }
                  if (structdef == stagseen && !cjava)
                    {
-                     popclass_above (cblev);
+                     popclass_above (bracelev);
                      structdef = snone;
                    }
                  break;
@@ -3596,6 +3611,8 @@ C_entries (c_ext, inf)
       switch (c)
        {
        case ':':
+         if (inattribute)
+           break;
          if (yacc_rules && token.offset == 0 && token.valid)
            {
              make_C_tag (FALSE); /* a yacc function */
@@ -3630,7 +3647,7 @@ C_entries (c_ext, inf)
            }
          break;
        case ';':
-         if (definedef != dnone)
+         if (definedef != dnone || inattribute)
            break;
          switch (typdef)
            {
@@ -3650,7 +3667,7 @@ C_entries (c_ext, inf)
                    fvdef = fvnone;
                  break;
                case fvnameseen:
-                 if ((globals && cblev == 0 && (!fvextern || declarations))
+                 if ((globals && bracelev == 0 && (!fvextern || declarations))
                      || (members && instruct))
                    make_C_tag (FALSE); /* a variable */
                  fvextern = FALSE;
@@ -3658,9 +3675,12 @@ C_entries (c_ext, inf)
                  token.valid = FALSE;
                  break;
                case flistseen:
-                 if (declarations
-                     && (typdef == tnone || (typdef != tignore && instruct)))
-                   make_C_tag (TRUE);  /* a function declaration */
+                 if ((declarations
+                      && (cplpl || !instruct)
+                      && (typdef == tnone || (typdef != tignore && instruct)))
+                     || (members
+                         && plainc && instruct))
+                   make_C_tag (TRUE);  /* a function */
                  /* FALLTHRU */
                default:
                  fvextern = FALSE;
@@ -3680,7 +3700,7 @@ C_entries (c_ext, inf)
            structdef = snone;
          break;
        case ',':
-         if (definedef != dnone)
+         if (definedef != dnone || inattribute)
            break;
          switch (objdef)
            {
@@ -3702,16 +3722,20 @@ C_entries (c_ext, inf)
            case fdefunname:
              fvdef = fignore;
              break;
-           case fvnameseen:    /* a variable */
-             if ((globals && cblev == 0 && (!fvextern || declarations))
-                 || (members && instruct))
-               make_C_tag (FALSE);
+           case fvnameseen:
+             if (parlev == 0
+                 && ((globals
+                      && bracelev == 0
+                      && templatelev == 0
+                      && (!fvextern || declarations))
+                     || (members && instruct)))
+                 make_C_tag (FALSE); /* a variable */
              break;
-           case flistseen:     /* a function */
+           case flistseen:
              if ((declarations && typdef == tnone && !instruct)
                  || (members && typdef != tignore && instruct))
                {
-                 make_C_tag (TRUE); /* a function declaration */
+                 make_C_tag (TRUE); /* a function */
                  fvdef = fvnameseen;
                }
              else if (!declarations)
@@ -3724,8 +3748,8 @@ C_entries (c_ext, inf)
          if (structdef == stagseen)
            structdef = snone;
          break;
-       case '[':
-         if (definedef != dnone)
+       case ']':
+         if (definedef != dnone || inattribute)
            break;
          if (structdef == stagseen)
            structdef = snone;
@@ -3746,8 +3770,8 @@ C_entries (c_ext, inf)
                case vignore:
                  break;
                case fvnameseen:
-                 if ((members && cblev == 1)
-                     || (globals && cblev == 0
+                 if ((members && bracelev == 1)
+                     || (globals && bracelev == 0
                          && (!fvextern || declarations)))
                    make_C_tag (FALSE); /* a variable */
                  /* FALLTHRU */
@@ -3758,6 +3782,11 @@ C_entries (c_ext, inf)
            }
          break;
        case '(':
+         if (inattribute)
+           {
+             attrparlev++;
+             break;
+           }
          if (definedef != dnone)
            break;
          if (objdef == otagseen && parlev == 0)
@@ -3787,6 +3816,12 @@ C_entries (c_ext, inf)
          parlev++;
          break;
        case ')':
+         if (inattribute)
+           {
+             if (--attrparlev == 0)
+               inattribute = FALSE;
+             break;
+           }
          if (definedef != dnone)
            break;
          if (objdef == ocatseen && parlev == 1)
@@ -3820,9 +3855,9 @@ C_entries (c_ext, inf)
          if (typdef == ttypeseen)
            {
              /* Whenever typdef is set to tinbody (currently only
-                here), typdefcblev should be set to cblev. */
+                here), typdefbracelev should be set to bracelev. */
              typdef = tinbody;
-             typdefcblev = cblev;
+             typdefbracelev = bracelev;
            }
          switch (fvdef)
            {
@@ -3846,26 +3881,26 @@ C_entries (c_ext, inf)
                  break;
                default:
                  /* Neutralize `extern "C" {' grot. */
-                 if (cblev == 0 && structdef == snone && nestlev == 0
+                 if (bracelev == 0 && structdef == snone && nestlev == 0
                      && typdef == tnone)
-                   cblev = -1;
+                   bracelev = -1;
                }
              break;
            }
          switch (structdef)
            {
            case skeyseen:         /* unnamed struct */
-             pushclass_above (cblev, NULL, 0);
+             pushclass_above (bracelev, NULL, 0);
              structdef = snone;
              break;
            case stagseen:         /* named struct or enum */
            case scolonseen:       /* a class */
-             pushclass_above (cblev, token.line+token.offset, token.length);
+             pushclass_above (bracelev,token.line+token.offset, token.length);
              structdef = snone;
              make_C_tag (FALSE);  /* a struct or enum */
              break;
            }
-         cblev++;
+         bracelev++;
          break;
        case '*':
          if (definedef != dnone)
@@ -3881,21 +3916,21 @@ C_entries (c_ext, inf)
            break;
          if (!ignoreindent && lp == newlb.buffer + 1)
            {
-             if (cblev != 0)
+             if (bracelev != 0)
                token.valid = FALSE;
-             cblev = 0;        /* reset curly brace level if first column */
+             bracelev = 0;     /* reset brace level if first column */
              parlev = 0;       /* also reset paren level, just in case... */
            }
-         else if (cblev > 0)
-           cblev--;
+         else if (bracelev > 0)
+           bracelev--;
          else
            token.valid = FALSE; /* something gone amiss, token unreliable */
-         popclass_above (cblev);
+         popclass_above (bracelev);
          structdef = snone;
-         /* Only if typdef == tinbody is typdefcblev significant. */
-         if (typdef == tinbody && cblev <= typdefcblev)
+         /* Only if typdef == tinbody is typdefbracelev significant. */
+         if (typdef == tinbody && bracelev <= typdefbracelev)
            {
-             assert (cblev == typdefcblev);
+             assert (bracelev == typdefbracelev);
              typdef = tend;
            }
          break;
@@ -3910,8 +3945,8 @@ C_entries (c_ext, inf)
            case vignore:
              break;
            case fvnameseen:
-             if ((members && cblev == 1)
-                 || (globals && cblev == 0 && (!fvextern || declarations)))
+             if ((members && bracelev == 1)
+                 || (globals && bracelev == 0 && (!fvextern || declarations)))
                make_C_tag (FALSE); /* a variable */
              /* FALLTHRU */
            default:
@@ -3919,30 +3954,31 @@ C_entries (c_ext, inf)
            }
          break;
        case '<':
-         if (cplpl && structdef == stagseen)
+         if (cplpl
+             && (structdef == stagseen || fvdef == fvnameseen))
            {
-             structdef = sintemplate;
+             templatelev++;
              break;
            }
          goto resetfvdef;
        case '>':
-         if (structdef == sintemplate)
+         if (templatelev > 0)
            {
-             structdef = stagseen;
+             templatelev--;
              break;
            }
          goto resetfvdef;
        case '+':
        case '-':
-         if (objdef == oinbody && cblev == 0)
+         if (objdef == oinbody && bracelev == 0)
            {
              objdef = omethodsign;
              break;
            }
          /* FALLTHRU */
        resetfvdef:
-       case '#': case '~': case '&': case '%': case '/': case '|':
-       case '^': case '!': case '.': case '?': case ']':
+       case '#': case '~': case '&': case '%': case '/':
+       case '|': case '^': case '!': case '.': case '?':
          if (definedef != dnone)
            break;
          /* These surely cannot follow a function tag in C. */
@@ -4893,6 +4929,31 @@ Lisp_functions (inf)
 }
 
 \f
+/*
+ * Lua script language parsing
+ * Original code by David A. Capello <dacap@users.sourceforge.net> (2004)
+ *
+ *  "function" and "local function" are tags if they start at column 1.
+ */
+static void
+Lua_functions (inf)
+     FILE *inf;
+{
+  register char *bp;
+
+  LOOP_ON_INPUT_LINES (inf, lb, bp)
+    {
+      if (bp[0] != 'f' && bp[0] != 'l')
+       continue;
+
+      LOOKING_AT (bp, "local");        /* skip possible "local" */
+
+      if (LOOKING_AT (bp, "function"))
+       get_tag (bp, NULL);
+    }
+}
+
+\f
 /*
  * Postscript tag functions
  * Just look for lines where the first character is '/'
index 0d9e7b4..6edfb46 100644 (file)
@@ -1,4 +1,154 @@
-2004-09-08  Stefan  <monnier@iro.umontreal.ca>
+2004-09-15  Miles Bader  <miles@gnu.org>
+
+       * generic.el (generic-make-keywords-list): Use symbol rather than
+       word anchors in regexp.
+
+2004-09-14  Sean O'Rourke  <sorourke@cs.ucsd.edu>
+
+       * ibuf-ext.el (define-ibuffer-filter filename): If buffer has
+       no file name consider `dired-directory'.
+
+2004-09-14  Kim F. Storm  <storm@cua.dk>
+
+       * faces.el (cursor): Add face-no-inherit property.  Doc fix.
+
+2004-09-14  Simon Josefsson  <jas@extundo.com>
+
+       * files.el (auto-mode-alist): Map .soa and .zone to dns-mode.
+
+       * textmodes/dns-mode.el: Add.
+
+2004-09-13  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * novice.el (disabled-command-hook): Use shorthand for obsolescence.
+       (disabled-command-function): Make the ?\  char more obvious.
+
+       * vc-arch.el (vc-arch-root, vc-arch-registered):
+       * vc-mcvs.el (vc-mcvs-root, vc-mcvs-registered): Use vc-find-root.
+
+2004-09-13  Hovav Shacham  <hovav@sha1.stanford.edu>
+
+       * windmove.el (windmove-frame-edges): Report coordinates of
+       outside edges of frame, not inside edges.
+       (windmove-coordinates-of-position): Convert into wrapper to new
+       function `windmove-coordinates-of-window-position';
+       `compute-motion' always applies to selected window.
+       (windmove-coordinates-of-position): Update documentation to refer
+       to Emacs 21 Lisp Reference Manual.
+       (windmove-find-other-window): Fix off-by-one errors for max x,y.
+
+2004-09-13  Kim F. Storm  <storm@cua.dk>
+
+       * isearch.el (isearch-resume-in-command-history): Rename from
+       isearch-resume-enabled and change default to nil.
+
+2004-09-12  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * vc-hooks.el (vc-ignore-dir-regexp): New var.
+       (vc-registered): Use it.
+       (vc-find-root): New fun.
+
+       * emacs-lisp/checkdoc.el (checkdoc-this-string-valid-engine):
+       Don't tell to use \\{...} when it's already done.
+
+       * textmodes/bibtex.el (bibtex-generate-url-list): Change format.
+       Provide a sample complex default.
+       (bibtex-url, bibtex-font-lock-url): Adapt to new format.
+       (bibtex-entry): Use mapc.
+
+2004-09-12  Kim F. Storm  <storm@cua.dk>
+
+       * kmacro.el (kmacro-step-edit-prompt): Add "%s" format to message.
+
+       * emulation/cua-rect.el (cua--rectangle-operation): Let bind
+       inhibit-field-text-motion to t so rectangles work in comint buffers.
+
+       * simple.el (choose-completion-string): Set buffer before running
+       choose-completion-string-functions hook so it can be buffer-local.
+
+2004-09-12  Daniel Pfeiffer  <occitan@esperanto.org>
+
+       * progmodes/compile.el (compilation-start): Parse command to see
+       if it starts with a cd, and if so perform it for the *compilation*
+       buffer.  Change the header to reflect this.
+
+2004-09-11  Kim F. Storm  <storm@cua.dk>
+
+       * ido.el (ido-enable-dot-prefix): Doc fix.
+       (ido-enable-dot-prefix): New defcustom.
+       (ido-set-matches1): Use it.
+
+2004-09-10  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * textmodes/bibtex.el (bibtex-mark-active)
+       (bibtex-run-with-idle-timer): Move the `if' inside the defun.
+
+2004-09-10  Roland Winkler  <Roland.Winkler@physik.uni-erlangen.de>
+
+       * textmodes/bibtex.el (bibtex-autokey-titleword-ignore): Regexp is
+       used in a case insensitive environment.
+       (bibtex-mode-map): Rearrange order of menus.
+       (bibtex-quoted-string-re): Obsolete.
+       (bibtex-complete-key-cleanup): Variable replaced by new function.
+       (bibtex-font-lock-keywords): Use backquotes.
+       (bibtex-font-lock-url-regexp): New internal variable.
+       (bibtex-name-in-field): New optional arg remove-opt-alt to remove
+       "OPT" and "ALT".
+       (bibtex-insert-current-kill, bibtex-make-field)
+       (bibtex-prepare-new-entry, bibtex-yank-pop, bibtex-String): Use unless.
+       (bibtex-parse-field-text): Simplify.
+       (bibtex-string=): New helper function.
+       (bibtex-member-of-regexp): Merge with bibtex-autokey-get-title.
+       (bibtex-map-entries): Use bibtex-string=.
+       (bibtex-search-entry): Use not.
+       (bibtex-enclosing-field): Fix docstring.
+       (bibtex-assoc-regexp): Obsolete.
+       (bibtex-format-entry): Use assoc-string and bibtex-string=.
+       (bibtex-autokey-get-names): Handle empty name field.
+       (bibtex-parse-strings): Use assoc-string and unless.
+       (bibtex-complete-string-cleanup): Expansion list is passed as an arg.
+       Use assoc-string.
+       (bibtex-pop): Simplify.
+       (bibtex-mode): Set font-lock-extra-managed-props.
+       (bibtex-entry-update): Use assoc-string.
+       (bibtex-parse-entry): Remove "OPT" and "ALT" from FIELD.
+       (bibtex-autofill-entry): Use bibtex-string=.
+       (bibtex-print-help-message): Simplify.
+       (bibtex-find-entry): New optional arg START.
+       (bibtex-validate): Use bibtex-string= and assoc-string.
+       Do not call obsolete function compilation-parse-errors.
+       (bibtex-remove-delimiters): Only remove delimiters if present.
+       (bibtex-copy-entry-as-kill): Add docstring.
+       (bibtex-clean-entry): Use bibtex-string=. Handle empty keys.
+       Detect duplicate keys if bibtex-maintain-sorted-entries is nil.
+       (bibtex-complete): Use bibtex-predefined-month-strings,
+       bibtex-string=, and new function bibtex-complete-key-cleanup.
+       (bibtex-generate-url-list): New variable.
+       (bibtex-url): New command bound to C-c C-l and mouse-2.
+       (bibtex-url-map): New local keymap for bibtex-url-mouse.
+       (bibtex-font-lock-url): New function.
+
+2004-09-09  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * progmodes/grep.el (grep-mode): Remove unnecessary autoload.
+
+2004-09-09  Kim F. Storm  <storm@cua.dk>
+
+       * kmacro.el (kmacro-bind-to-key): Associate dedicated macro
+       counter and format with binding.
+       (kmacro-name-last-macro): New defun.  Like name-last-kbd-macro, but
+       the declared macro uses own macro counter and format.  Give symbol
+       kmacro property.
+       (kmacro-keymap): Bind kmacro-name-last-macro to n.
+       (kmacro-start-macro, kmacro-end-macro, kmacro-call-macro)
+       (kmacro-end-and-call-macro): Doc fix.
+
+2004-09-09  Lars Hansen  <larsh@math.ku.dk>
+
+       * desktop.el (desktop-clear-preserve-buffers):
+       Remove make-obsolete-variable.
+
+2004-09-08  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * vc-arch.el (vc-arch-state): Fix parsing for `names' method.
 
        window system if overflow-newline-into-fringe is enabled.
        (term-mode): Don't disable overflow-newline-into-fringe.
 
-2004-09-07  Stefan  <monnier@iro.umontreal.ca>
+2004-09-07  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * term/xterm.el (function-key-map): Add bindings for C- and S- cursor
        motion as seen on my Mac OS X xterms.
 
 2004-08-29  Kim F. Storm  <storm@cua.dk>
 
-       * emulation/cua-base.el (cua-auto-expand-rectangles): Remove
-       automatic rectangle padding feature; replace by non-destructive
+       * emulation/cua-base.el (cua-auto-expand-rectangles):
+       Remove automatic rectangle padding feature; replace by non-destructive
        virtual rectangle edges feature.
        (cua-virtual-rectangle-edges): New defcustom.
        (cua-auto-tabify-rectangles): New defcustom.
        key-translation-map.
        (encoded-kbd-setup-keymap): Setup key-translation-map.
        (saved-key-translation-map): New variable.
-       (encoded-kbd-mode): Save/restore key-translation-map.  Adjusted
-       for the change of encoded-kbd-setup-keymap.
+       (encoded-kbd-mode): Save/restore key-translation-map.
+       Adjust for the change of encoded-kbd-setup-keymap.
 
 2004-08-02  Kim F. Storm  <storm@cua.dk>
 
 
        Sync with Tramp 2.0.43.
 
-       * net/tramp.el (tramp-handle-verify-visited-file-modtime): Remove
-       outdated comment.
+       * net/tramp.el (tramp-handle-verify-visited-file-modtime):
+       Remove outdated comment.
        (tramp-locked, tramp-locker): New variables for implementing a
        global lock.
-       (tramp-sh-file-name-handler): Use them to implement the global
-       lock.
+       (tramp-sh-file-name-handler): Use them to implement the global lock.
 
 2004-07-13  Michael Albinus  <michael.albinus@gmx.de>
 
        * emacs-lisp/testcover.el: New category "potentially-1valued" for
        functions that are not erroneous if either 1-valued or
        multi-valued.  Detect functions in this class.
-       (testcover-1value-functions, testcover-compose-functions,
-       testcover-progn-functions) Added some additional functions to lists.
+       (testcover-1value-functions, testcover-compose-functions)
+       (testcover-progn-functions) Added some additional functions to lists.
        (testcover-mark): Bugfix when marking up the definition for an
        empty function.
 
 2004-07-17  Richard M. Stallman  <rms@gnu.org>
 
-       * replace.el (occur-read-primary-args): Pass default to read-from-minibuffer.
+       * replace.el (occur-read-primary-args): Pass default to
+       read-from-minibuffer.
 
        * mail/footnote.el (footnote-section-tag): Use defcustom.
 
 
 2004-07-09  John Paul Wallington  <jpw@gnu.org>
 
-       * emacs-lisp/re-builder.el (reb-update-overlays): Distinguish
-       between one and several matches in message.
+       * emacs-lisp/re-builder.el (reb-update-overlays):
+       Distinguish between one and several matches in message.
 
 2004-07-09  Richard M. Stallman  <rms@gnu.org>
 
        Do not treat double clicks and triple clicks specially in the
        scroll bar (preventing strange repositioning problems)
 
-2004-07-06  Stefan  <monnier@iro.umontreal.ca>
+2004-07-06  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * replace.el (query-replace-regexp-eval): Fix last change.
 
-2004-07-05  Stefan  <monnier@iro.umontreal.ca>
+2004-07-05  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * replace.el (query-replace-descr): New fun.
        (query-replace-read-from, query-replace-read-args): Default to the
index cf1743c..486f0f3 100644 (file)
 2002-06-01  Kim F. Storm  <storm@cua.dk>
 
        * simple.el: Reworked previous change.
-       (choose-completion-string1): Merged back into choose-completion-string.
+       (choose-completion-string1): Merge back into choose-completion-string.
        (choose-completion-string): Run choose-completion-string-functions
        after checking for proper minibuffer window.  Added mini-p arg to
        the hook functions.  Insert choice if all hook functions return nil.
 2002-06-01  Kim F. Storm  <storm@cua.dk>
 
        * simple.el (choose-completion-string-functions): New special hook.
-       (choose-completion-string1): Renamed from choose-completion-string.
+       (choose-completion-string1): Rename from choose-completion-string.
        (choose-completion-string): Run choose-completion-string-functions
        until success, and only call choose-completion-string1 if it fails.
 
index a71fc6c..28521a0 100644 (file)
@@ -171,13 +171,13 @@ This is useful for truncating history lists, for example."
   :type 'hook
   :group 'desktop)
 
-(defcustom desktop-globals-to-save '(
-  desktop-missing-file-warning
-  tags-file-name
-  tags-table-list
-  search-ring
-  regexp-search-ring
-  register-alist)
+(defcustom desktop-globals-to-save
+  '(desktop-missing-file-warning
+    tags-file-name
+    tags-table-list
+    search-ring
+    regexp-search-ring
+    register-alist)
   "List of global variables saved by `desktop-save'.
 An element may be variable name (a symbol) or a cons cell of the form
 \(VAR . MAX-SIZE), which means to truncate VAR's value to at most
@@ -186,13 +186,13 @@ Feature: Saving `kill-ring' implies saving `kill-ring-yank-pointer'."
   :type '(repeat (restricted-sexp :match-alternatives (symbolp consp)))
   :group 'desktop)
 
-(defcustom desktop-globals-to-clear '(
-  kill-ring
-  kill-ring-yank-pointer
-  search-ring
-  search-ring-yank-pointer
-  regexp-search-ring
-  regexp-search-ring-yank-pointer)
+(defcustom desktop-globals-to-clear
+  '(kill-ring
+    kill-ring-yank-pointer
+    search-ring
+    search-ring-yank-pointer
+    regexp-search-ring
+    regexp-search-ring-yank-pointer)
   "List of global variables to clear by `desktop-clear'.
 An element may be variable name (a symbol) or a cons cell of the form
 \(VAR . FORM). Symbols are set to nil and for cons cells VAR is set
@@ -202,29 +202,27 @@ to the value obtained by evaluateing FORM."
 
 (defcustom desktop-clear-preserve-buffers-regexp
   "^\\(\\*scratch\\*\\|\\*Messages\\*\\|\\*tramp/.+\\*\\)$"
-  "Regexp identifying buffers that `desktop-clear' should not delete."
+  "Regexp identifying buffers that `desktop-clear' should not delete.
+See also `desktop-clear-preserve-buffers'."
   :type 'regexp
   :group 'desktop)
 
-;; Maintained for backward compatibility
 (defcustom desktop-clear-preserve-buffers nil
   "*List of buffer names that `desktop-clear' should not delete.
-This variable is maintained for backward compatibility only."
+See also `desktop-clear-preserve-buffers-regexp'."
   :type '(repeat string)
   :group 'desktop)
-(make-obsolete-variable 'desktop-clear-preserve-buffers
-                        'desktop-clear-preserve-buffers-regexp)
-
-(defcustom desktop-locals-to-save '(
-  desktop-locals-to-save  ; Itself!  Think it over.
-  truncate-lines
-  case-fold-search
-  case-replace
-  fill-column
-  overwrite-mode
-  change-log-default-name
-  line-number-mode
-  buffer-file-coding-system)
+
+(defcustom desktop-locals-to-save
+  '(desktop-locals-to-save  ; Itself!  Think it over.
+    truncate-lines
+    case-fold-search
+    case-replace
+    fill-column
+    overwrite-mode
+    change-log-default-name
+    line-number-mode
+    buffer-file-coding-system)
   "List of local variables to save for each buffer.
 The variables are saved only when they really are local."
   :type '(repeat symbol)
@@ -282,11 +280,11 @@ DESKTOP-BUFFER-MISC.")
 (make-obsolete-variable 'desktop-buffer-misc-functions
                         'desktop-save-buffer)
 
-(defcustom desktop-buffer-mode-handlers '(
-  (dired-mode . dired-restore-desktop-buffer)
-  (rmail-mode . rmail-restore-desktop-buffer)
-  (mh-folder-mode . mh-restore-desktop-buffer)
-  (Info-mode . Info-restore-desktop-buffer))
+(defcustom desktop-buffer-mode-handlers
+  '((dired-mode . dired-restore-desktop-buffer)
+    (rmail-mode . rmail-restore-desktop-buffer)
+    (mh-folder-mode . mh-restore-desktop-buffer)
+    (Info-mode . Info-restore-desktop-buffer))
   "Alist of major mode specific functions to restore a desktop buffer.
 Functions are called by `desktop-read'. List elements must have the form
 \(MAJOR-MODE . RESTORE-BUFFER-FUNCTION).
@@ -580,8 +578,7 @@ See also `desktop-base-file-name'."
     (let ((filename (expand-file-name desktop-base-file-name dirname))
           (info
             (mapcar
-              (function
-                (lambda (b)
+              #'(lambda (b)
                   (set-buffer b)
                   (list
                     (desktop-file-name (buffer-file-name) dirname)
@@ -618,7 +615,7 @@ See also `desktop-base-file-name'."
                             (when (member (car locals) loclist)
                               (setq ll (cons (car locals) ll)))))
                         (setq locals (cdr locals)))
-                      ll))))
+                      ll)))
               (buffer-list)))
           (buf (get-buffer-create "*desktop*")))
       (set-buffer buf)
@@ -639,19 +636,15 @@ See also `desktop-base-file-name'."
           " kill-ring))\n"))
 
       (insert "\n;; Buffer section -- buffers listed in same order as in buffer list:\n")
-      (mapcar
-        (function
-          (lambda (l)
-            (if (apply 'desktop-save-buffer-p l)
-              (progn
-                (insert "(desktop-create-buffer " desktop-file-version)
-                (mapcar
-                  (function
-                    (lambda (e)
-                      (insert "\n  " (desktop-value-to-string e))))
-                  l)
-                (insert ")\n\n")))))
-        info)
+      (mapcar #'(lambda (l)
+                  (if (apply 'desktop-save-buffer-p l)
+                      (progn
+                        (insert "(desktop-create-buffer " desktop-file-version)
+                        (mapcar #'(lambda (e)
+                                    (insert "\n  " (desktop-value-to-string e)))
+                                l)
+                        (insert ")\n\n"))))
+              info)
       (setq default-directory dirname)
       (when (file-exists-p filename) (delete-file filename))
       (let ((coding-system-for-write 'utf-8-emacs))
@@ -816,18 +809,18 @@ directory DIRNAME."
    (defvar desktop-first-buffer) ;; Dynamically bound in `desktop-read'
 )
 
-(defun desktop-create-buffer (
-  desktop-file-version
-  desktop-buffer-file-name
-  desktop-buffer-name
-  desktop-buffer-major-mode
-  desktop-buffer-minor-modes
-  desktop-buffer-point
-  desktop-buffer-mark
-  desktop-buffer-read-only
-  desktop-buffer-misc
-  &optional
-  desktop-buffer-locals)
+(defun desktop-create-buffer
+  (desktop-file-version
+   desktop-buffer-file-name
+   desktop-buffer-name
+   desktop-buffer-major-mode
+   desktop-buffer-minor-modes
+   desktop-buffer-point
+   desktop-buffer-mark
+   desktop-buffer-read-only
+   desktop-buffer-misc
+   &optional
+   desktop-buffer-locals)
   ;; Just to silence the byte compiler. Bound locally in `desktop-read'.
   (eval-when-compile
     (defvar desktop-buffer-ok-count)
@@ -835,21 +828,21 @@ directory DIRNAME."
   ;; To make desktop files with relative file names possible, we cannot
   ;; allow `default-directory' to change. Therefore we save current buffer.
   (save-current-buffer
-    (let (
-      (buffer-list (buffer-list))
-      (result
-         (condition-case err
-             (funcall (or (cdr (assq desktop-buffer-major-mode desktop-buffer-mode-handlers))
-                          'desktop-restore-file-buffer)
-                      desktop-buffer-file-name
-                      desktop-buffer-name
-                      desktop-buffer-misc)
-           (error
-             (message "Desktop: Can't load buffer %s: %s"
-                      desktop-buffer-name (error-message-string err))
-             (when desktop-missing-file-warning (sit-for 1))
-             nil)))
-    )
+    (let ((buffer-list (buffer-list))
+          (result
+           (condition-case err
+               (funcall (or (cdr (assq desktop-buffer-major-mode
+                                       desktop-buffer-mode-handlers))
+                            'desktop-restore-file-buffer)
+                        desktop-buffer-file-name
+                        desktop-buffer-name
+                        desktop-buffer-misc)
+             (error
+              (message "Desktop: Can't load buffer %s: %s"
+                       desktop-buffer-name
+                       (error-message-string err))
+              (when desktop-missing-file-warning (sit-for 1))
+              nil))))
       (if (bufferp result)
           (setq desktop-buffer-ok-count (1+ desktop-buffer-ok-count))
         (setq desktop-buffer-fail-count (1+ desktop-buffer-fail-count))
@@ -867,17 +860,14 @@ directory DIRNAME."
         (unless (equal (buffer-name) desktop-buffer-name)
           (rename-buffer desktop-buffer-name))
         ;; minor modes
-        (cond (
-          ;; backwards compatible
-          (equal '(t) desktop-buffer-minor-modes)
-          (auto-fill-mode 1))(
-          (equal '(nil) desktop-buffer-minor-modes)
-          (auto-fill-mode 0))(
-          t
-          (mapcar
-            #'(lambda (minor-mode)
-              (when (functionp minor-mode) (funcall minor-mode 1)))
-            desktop-buffer-minor-modes)))
+        (cond ((equal '(t) desktop-buffer-minor-modes) ; backwards compatible
+               (auto-fill-mode 1))
+              ((equal '(nil) desktop-buffer-minor-modes) ; backwards compatible
+               (auto-fill-mode 0))
+              (t
+               (mapcar #'(lambda (minor-mode)
+                           (when (functionp minor-mode) (funcall minor-mode 1)))
+                       desktop-buffer-minor-modes)))
         ;; Even though point and mark are non-nil when written by `desktop-save'
         ;; they may be modified by handlers wanting to set point or mark themselves.
         (when desktop-buffer-point
index 2aba3ea..cc2be89 100644 (file)
@@ -1561,8 +1561,9 @@ mouse-[0-3]\\)\\)\\>"))
      ;; to describe the most important commands in your major mode, and
      ;; then use `\\{...}' to display the rest of the mode's keymap.
      (save-excursion
-       (if (re-search-forward "\\\\\\\\\\[\\w+" e t
-                             (1+ checkdoc-max-keyref-before-warn))
+       (if (and (re-search-forward "\\\\\\\\\\[\\w+" e t
+                                  (1+ checkdoc-max-keyref-before-warn))
+               (not (re-search-forward "\\\\\\\\{\\w+}" e t)))
           (checkdoc-create-error
            "Too many occurrences of \\[function].  Use \\{keymap} instead"
            s (marker-position e))))
index 10d369f..742ae20 100644 (file)
@@ -559,7 +559,8 @@ If command is repeated at same position, delete the rectangle."
   ;; Rectangle is padded if PAD = t or numeric and (cua--rectangle-virtual-edges)
   ;; Perform auto-tabify after operation if TABIFY is non-nil.
   ;; Mark is kept if keep-clear is 'keep and cleared if keep-clear is 'clear.
-  (let* ((start (cua--rectangle-top))
+  (let* ((inhibit-field-text-motion t)
+        (start (cua--rectangle-top))
          (end   (cua--rectangle-bot))
          (l (cua--rectangle-left))
          (r (1+ (cua--rectangle-right)))
index 5ab91b5..8926bb2 100644 (file)
@@ -1925,11 +1925,13 @@ created."
 
 
 (defface cursor '()
-  "Basic face for the cursor color under X."
+  "Basic face for the cursor color under X.
+Note: Other faces cannot inherit from the cursor face."
   :version "21.1"
   :group 'cursor
   :group 'basic-faces)
 
+(put 'cursor 'face-no-inherit t)
 
 (defface mouse '()
   "Basic face for the mouse color under X."
index 30f318f..5571ede 100644 (file)
@@ -1771,6 +1771,7 @@ in that case, this function acts as if `enable-local-variables' were t."
      ("\\.g\\'" . antlr-mode)
      ("\\.ses\\'" . ses-mode)
      ("\\.orig\\'" nil t)              ; from patch
+     ("\\.\\(soa\\|zone\\)\\'" . dns-mode)
      ("\\.in\\'" nil t)))
   "Alist of filename patterns vs corresponding major mode functions.
 Each element looks like (REGEXP . FUNCTION) or (REGEXP FUNCTION NON-NIL).
index a951a0d..84cd4d0 100644 (file)
@@ -405,10 +405,10 @@ INI file.  This hook is NOT installed by default."
 The regexp is highlighted with FACE."
   (unless (listp keywords-list)
     (error "Keywords argument must be a list of strings"))
-  (list (concat prefix "\\<"
+  (list (concat prefix "\\_<"
                ;; Use an optimized regexp.
                (regexp-opt keywords-list t)
-               "\\>" suffix)
+               "\\_>" suffix)
        1
        face))
 
index 0f0f469..668607a 100644 (file)
@@ -1,3 +1,23 @@
+2004-09-13  Reiner Steib  <Reiner.Steib@gmx.de>
+
+       * gnus-sum.el (gnus-summary-copy-article): Fixed doc string.
+
+2004-09-10  Miles Bader  <miles@gnu.ai.mit.edu>
+
+       * nnimap.el (nnimap-open-connection): Remove extraneous end-paren.
+
+2004-09-10  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * nnimap.el (nnimap-open-connection): allow 'imaps' as a synonym
+       for the 'imap' port in netrc files
+
+       * gnus-registry.el (gnus-registry-trim): watch out for negatives
+       in gnus-registry-trim
+
+2004-09-10  Simon Josefsson  <jas@extundo.com>
+
+       * nndb.el (require): Remove tcp and duplicate cl.
+
 2004-09-08  Reiner Steib  <Reiner.Steib@gmx.de>
 
        * nntp.el (nntp): New customization group.
        * gnus-cus.el: Merged revisions 7.2 through 7.5 into branch to support
        gnus-agent.el update and incorporate bug fixes.
 
-;; Local Variables:
-;; coding: iso-2022-7bit
-;; End:
+See ChangeLog.2 for earlier changes.
 
-    Copyright (C) 2002 2004 Free Software Foundation, Inc.
+    Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
   Copying and distribution of this file, with or without modification,
   are permitted provided the copyright notice and this notice are preserved.
 
+;; Local Variables:
+;; coding: iso-2022-7bit
+;; End:
+
 ;;; arch-tag: 3f33a3e7-090d-492b-bedd-02a1417d32b4
index c36aad0..2dbd6d3 100644 (file)
        * smime.el: New file.
        * mml-smime.el: New file.
 
-;; Local Variables:
-;; coding: iso-2022-7bit
-;; End:
+2000-10-27 19:42:12  ShengHuo ZHU  <zsh@cs.rochester.edu>
+
+       * ChangeLog: Moved to ChangeLog.1.
+
+See ChangeLog.1 for earlier changes.
 
-    Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+    Copyright (C) 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
   Copying and distribution of this file, with or without modification,
   are permitted provided the copyright notice and this notice are preserved.
 
-;; arch-tag: 13460c90-d3bc-4be2-9e15-c7c271d0c1eb
+;; Local Variables:
+;; coding: iso-2022-7bit
+;; End:
+
+;; arch-tag: 956fd310-042f-4fca-8dca-a01dbe06acff
index 9a8d77d..33238ef 100644 (file)
@@ -266,25 +266,27 @@ way."
 (defun gnus-registry-trim (alist)
   "Trim alist to size, using gnus-registry-max-entries."
   (if (null gnus-registry-max-entries)
-      alist                            ; just return the alist
+      alist                             ; just return the alist
     ;; else, when given max-entries, trim the alist
-    (let ((timehash (make-hash-table                       
-                    :size 4096
-                    :test 'equal)))
+    (let* ((timehash (make-hash-table
+                     :size 4096
+                     :test 'equal))
+          (trim-length (- (length alist) gnus-registry-max-entries))
+          (trim-length (if (natnump trim-length) trim-length 0)))
       (maphash
        (lambda (key value)
-        (puthash key (gnus-registry-fetch-extra key 'mtime) timehash))
+         (puthash key (gnus-registry-fetch-extra key 'mtime) timehash))
        gnus-registry-hashtb)
 
       ;; we use the return value of this setq, which is the trimmed alist
       (setq alist
-           (nthcdr
-            (- (length alist) gnus-registry-max-entries)
-            (sort alist 
-                  (lambda (a b)
-                    (time-less-p 
-                     (cdr (gethash (car a) timehash))
-                     (cdr (gethash (car b) timehash))))))))))
+            (nthcdr
+             trim-length
+             (sort alist 
+                   (lambda (a b)
+                     (time-less-p 
+                      (cdr (gethash (car a) timehash))
+                      (cdr (gethash (car b) timehash))))))))))
 
 (defun alist-to-hashtable (alist)
   "Build a hashtable from the values in ALIST."
index 4a7bb5a..1d1e309 100644 (file)
@@ -9056,8 +9056,8 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
     (gnus-set-mode-line 'summary)))
 
 (defun gnus-summary-copy-article (&optional n to-newsgroup select-method)
-  "Move the current article to a different newsgroup.
-If TO-NEWSGROUP is string, do not prompt for a newsgroup to move to.
+  "Copy the current article to some other group.
+If TO-NEWSGROUP is string, do not prompt for a newsgroup to copy to.
 When called interactively, if TO-NEWSGROUP is nil, use the value of
 the variable `gnus-move-split-methods' for finding a default target
 newsgroup.
index d29d16f..bd8523f 100644 (file)
@@ -1,6 +1,6 @@
 ;;; nndb.el --- nndb access for Gnus
 
-;; Copyright (C) 1997, 1998, 2000, 2003 Free Software Foundation, Inc.
+;; Copyright (C) 1997, 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
 
 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
 ;;         Kai Grossjohann <grossjohann@ls6.informatik.uni-dortmund.de>
 (require 'nntp)
 (eval-when-compile (require 'cl))
 
-(eval-and-compile
-  (unless (fboundp 'open-network-stream)
-    (require 'tcp)))
-
-(eval-when-compile (require 'cl))
-
 (eval-and-compile
   (autoload 'news-setup "rnewspost")
   (autoload 'news-reply-mode "rnewspost")
index fc33b9a..08aa48a 100644 (file)
@@ -723,10 +723,15 @@ If EXAMINE is non-nil the group is selected read-only."
                     (int-to-string nnimap-server-port)
                   "imap"))
           (alist (or (gnus-netrc-machine list server port "imap")
+                     (gnus-netrc-machine list server port "imaps")
                      (gnus-netrc-machine list
                                          (or nnimap-server-address
                                              nnimap-address)
-                                         port "imap")))
+                                         port "imap")
+                     (gnus-netrc-machine list
+                                         (or nnimap-server-address
+                                             nnimap-address)
+                                         port "imaps")))
           (user (gnus-netrc-get alist "login"))
           (passwd (gnus-netrc-get alist "password")))
       (if (imap-authenticate user passwd nnimap-server-buffer)
index 96678d2..b7e6741 100644 (file)
@@ -1015,7 +1015,10 @@ currently used by buffers."
   "Toggle current view to buffers with filename matching QUALIFIER."
   (:description "filename"
    :reader (read-from-minibuffer "Filter by filename (regexp): "))
-  (ibuffer-awhen (buffer-file-name buf)
+  (ibuffer-awhen (with-current-buffer buf
+                  (or buffer-file-name
+                      (and (boundp 'dired-directory)
+                           dired-directory)))
     (string-match qualifier it)))
 
 ;;;###autoload (autoload 'ibuffer-filter-by-size-gt  "ibuf-ext.el")
index ae37674..b82338e 100644 (file)
@@ -482,14 +482,20 @@ Value can be toggled within `ido' using `ido-toggle-regexp'."
   :group 'ido)
 
 (defcustom ido-enable-prefix nil
-  "*Nil means that `ido' will match if the inserted text is an
-arbitrary substring (default). If non-nil `ido' will only match if the inserted
-text is a prefix \(this behavior is like the standard unix- or
-emacs-completion works).
+  "*Non-nil means only match if the entered text is a prefix of file name.
+This behavior is like the standard emacs-completion.
+Nil means to match if the entered text is an arbitrary substring.
 Value can be toggled within `ido' using `ido-toggle-prefix'."
   :type 'boolean
   :group 'ido)
 
+(defcustom ido-enable-dot-prefix nil
+  "*Non-nil means to match leading dot as prefix.
+I.e. hidden files and buffers will match only if you type a dot
+as first char even if `ido-enable-prefix' is nil."
+  :type 'boolean
+  :group 'ido)
+
 (defcustom ido-confirm-unique-completion nil
   "*Non-nil means that even a unique completion must be confirmed.
 This means that \\[ido-complete] must always be followed by \\[ido-exit-minibuffer]
@@ -2928,13 +2934,22 @@ for first matching file."
                       (concat "\\`" re "\\'")))
         (prefix-re (and full-re (not ido-enable-prefix)
                         (concat "\\`" rexq)))
+        (non-prefix-dot (or (not ido-enable-dot-prefix)
+                            (not ido-process-ignore-lists)
+                            ido-enable-prefix
+                            (= (length ido-text) 0)))
+
         full-matches
         prefix-matches
         matches)
     (mapcar
      (lambda (item)
        (let ((name (ido-name item)))
-        (if (string-match re name)
+        (if (and (or non-prefix-dot
+                     (if (= (aref ido-text 0) ?.)
+                         (= (aref name 0) ?.)
+                       (/= (aref name 0) ?.)))
+                 (string-match re name))
             (cond
              ((and full-re (string-match full-re name))
               (setq full-matches (cons item full-matches)))
index 12ac2ea..1e8e0f6 100644 (file)
@@ -146,8 +146,10 @@ Ordinarily the text becomes invisible again at the end of the search."
   :type 'boolean
   :group 'isearch)
 
-(defcustom isearch-resume-enabled t
-  "*If non-nil, `isearch-resume' commands are added to the command history."
+(defcustom isearch-resume-in-command-history nil
+  "*If non-nil, `isearch-resume' commands are added to the command history.
+This allows you to resume earlier isearch sessions through the
+command history."
   :type 'boolean
   :group 'isearch)
 
@@ -647,7 +649,7 @@ is treated as a regexp.  See \\[isearch-forward] for more info."
   (setq disable-point-adjustment t))
 
 (defun isearch-done (&optional nopush edit)
-  (if isearch-resume-enabled
+  (if isearch-resume-in-command-history
       (let ((command `(isearch-resume ,isearch-string ,isearch-regexp
                                      ,isearch-word ,isearch-forward
                                      ,isearch-message
index a129ab5..5aefe46 100644 (file)
@@ -204,7 +204,7 @@ macro to be executed before appending to it."
 
     ;; naming and binding
     (define-key map "b"    'kmacro-bind-to-key)
-    (define-key map "n"    'name-last-kbd-macro)
+    (define-key map "n"    'kmacro-name-last-macro)
     map)
   "Keymap for keyboard macro commands.")
 (defalias 'kmacro-keymap kmacro-keymap)
@@ -539,8 +539,8 @@ Displays the selected macro in the echo area."
 The commands are recorded even as they are executed.
 Use \\[kmacro-end-macro] to finish recording and make the macro available.
 Use \\[kmacro-end-and-call-macro] to execute the macro.
-Use \\[name-last-kbd-macro] to give it a permanent name.
-Non-nil arg (prefix arg) means append to last macro defined;
+
+Non-nil arg (prefix arg) means append to last macro defined.
 
 With \\[universal-argument] prefix, append to last keyboard macro
 defined.  Depending on `kmacro-execute-before-append', this may begin
@@ -551,7 +551,10 @@ defining the macro.
 
 Use \\[kmacro-insert-counter] to insert (and increment) the macro counter.
 The counter value can be set or modified via \\[kmacro-set-counter] and \\[kmacro-add-counter].
-The format of the counter can be modified via \\[kmacro-set-format]."
+The format of the counter can be modified via \\[kmacro-set-format].
+
+Use \\[kmacro-name-last-macro] to give it a permanent name.
+Use \\[kmacro-bind-to-key] to bind it to a key sequence."
   (interactive "P")
   (if (or defining-kbd-macro executing-kbd-macro)
       (message "Already defining keyboard macro.")
@@ -585,7 +588,7 @@ The format of the counter can be modified via \\[kmacro-set-format]."
   "Finish defining a keyboard macro.
 The definition was started by \\[kmacro-start-macro].
 The macro is now available for use via \\[kmacro-call-macro],
-or it can be given a name with \\[name-last-kbd-macro] and then invoked
+or it can be given a name with \\[kmacro-name-last-macro] and then invoked
 under that name.
 
 With numeric arg, repeat macro now that many times,
@@ -609,7 +612,7 @@ command.  See `kmacro-call-repeat-key' and `kmacro-call-repeat-with-arg'
 for details on how to adjust or disable this behaviour.
 
 To make a macro permanent so you can call it even after defining
-others, use \\[name-last-kbd-macro]."
+others, use \\[kmacro-name-last-macro]."
   (interactive "p")
   (let ((repeat-key (and (null no-repeat)
                         (> (length (this-single-command-keys)) 1)
@@ -707,7 +710,7 @@ With numeric prefix ARG, repeat macro that many times.
 Zero argument means repeat until there is an error.
 
 To give a macro a permanent name, so you can call it
-even after defining other macros, use \\[name-last-kbd-macro]."
+even after defining other macros, use \\[kmacro-name-last-macro]."
   (interactive "P")
   (if defining-kbd-macro
       (kmacro-end-macro nil))
@@ -771,10 +774,38 @@ may be shaded by a local key binding."
                     (yes-or-no-p (format "%s runs command %S.  Bind anyway? "
                                          (format-kbd-macro key-seq)
                                          cmd))))
-       (define-key global-map key-seq last-kbd-macro)
+       (define-key global-map key-seq
+         `(lambda (&optional arg)
+            "Keyboard macro."
+            (interactive "p")
+            (kmacro-exec-ring-item ',(kmacro-ring-head) arg)))
        (message "Keyboard macro bound to %s" (format-kbd-macro key-seq))))))
 
 
+(defun kmacro-name-last-macro (symbol)
+  "Assign a name to the last keyboard macro defined.
+Argument SYMBOL is the name to define.
+The symbol's function definition becomes the keyboard macro string.
+Such a \"function\" cannot be called from Lisp, but it is a valid editor command."
+  (interactive "SName for last kbd macro: ")
+  (or last-kbd-macro
+      (error "No keyboard macro defined"))
+  (and (fboundp symbol)
+       (not (get symbol 'kmacro))
+       (not (stringp (symbol-function symbol)))
+       (not (vectorp (symbol-function symbol)))
+       (error "Function %s is already defined and not a keyboard macro"
+             symbol))
+  (if (string-equal symbol "")
+      (error "No command name given"))
+  (fset symbol
+       `(lambda (&optional arg)
+          "Keyboard macro."
+          (interactive "p")
+          (kmacro-exec-ring-item ',(kmacro-ring-head) arg)))
+  (put symbol 'kmacro t))
+
+
 (defun kmacro-view-macro (&optional arg)
   "Display the last keyboard macro.
 If repeated, it shows previous elements in the macro ring."
@@ -897,7 +928,8 @@ following additional answers: `insert', `insert-1', `replace', `replace-1',
        (curmsg (current-message)))
 
     ;; TODO: Scroll macro if max-mini-window-height is too small.
-    (message (concat
+    (message "%s"
+            (concat
              (format "Macro: %s%s%s%s%s\n"
                      (format-kbd-macro kmacro-step-edit-new-macro 1)
                      (if (and kmacro-step-edit-new-macro (> (length kmacro-step-edit-new-macro) 0)) " " "")
index ca9a067..b2a0bec 100644 (file)
@@ -44,7 +44,7 @@ If nil, the feature is disabled, i.e., all commands work normally.")
 (defvaralias 'disabled-command-hook 'disabled-command-function)
 (make-obsolete-variable
  'disabled-command-hook
"use the variable `disabled-command-function' instead." "21.4")
'disabled-command-function "21.4")
 
 ;;;###autoload
 (defun disabled-command-function (&rest ignore)
@@ -93,7 +93,7 @@ SPC to try the command just this once, but leave it disabled.
      (message "Type y, n, ! or SPC (the space bar): ")
      (let ((cursor-in-echo-area t))
        (while (not (memq (setq char (downcase (read-char)))
-                        '(?! ?  ?y ?n)))
+                        '(?! ?y ?n ?\ )))
         (ding)
         (message "Please type y, n, ! or SPC (the space bar): "))))
     (if (= char ?!)
@@ -185,5 +185,5 @@ to future sessions."
 
 (provide 'novice)
 
-;;; arch-tag: f83c0f96-497e-4db6-a430-8703716c6dd9
+;; arch-tag: f83c0f96-497e-4db6-a430-8703716c6dd9
 ;;; novice.el ends here
index 8ae2a7a..2f91060 100644 (file)
@@ -849,6 +849,7 @@ Otherwise, construct a buffer name from MODE-NAME."
 
 (defun compilation-start (command &optional mode name-function highlight-regexp)
   "Run compilation command COMMAND (low level interface).
+If COMMAND starts with a cd command, that becomes the `default-directory'.
 The rest of the arguments are optional; for them, nil means use the default.
 
 MODE is the major mode to set in the compilation buffer.  Mode
@@ -861,26 +862,29 @@ global value of `compilation-highlight-regexp'.
 
 Returns the compilation buffer created."
   (or mode (setq mode 'compilation-mode))
-  (let ((name-of-mode
-        (if (eq mode t)
-            (prog1 "compilation" (require 'comint))
-          (replace-regexp-in-string "-mode$" "" (symbol-name mode))))
-       (process-environment
-        (append
-         compilation-environment
-         (if (if (boundp 'system-uses-terminfo) ; `if' for compiler warning
-                 system-uses-terminfo)
-             (list "TERM=dumb" "TERMCAP="
-                   (format "COLUMNS=%d" (window-width)))
-           (list "TERM=emacs"
-                 (format "TERMCAP=emacs:co#%d:tc=unknown:"
-                         (window-width))))
-         ;; Set the EMACS variable, but
-         ;; don't override users' setting of $EMACS.
-         (unless (getenv "EMACS") '("EMACS=t"))
-         (copy-sequence process-environment)))
-       (thisdir default-directory)
-       outwin outbuf)
+  (let* ((name-of-mode
+         (if (eq mode t)
+             (prog1 "compilation" (require 'comint))
+           (replace-regexp-in-string "-mode$" "" (symbol-name mode))))
+        (process-environment
+         (append
+          compilation-environment
+          (if (if (boundp 'system-uses-terminfo) ; `if' for compiler warning
+                  system-uses-terminfo)
+              (list "TERM=dumb" "TERMCAP="
+                    (format "COLUMNS=%d" (window-width)))
+            (list "TERM=emacs"
+                  (format "TERMCAP=emacs:co#%d:tc=unknown:"
+                          (window-width))))
+          ;; Set the EMACS variable, but
+          ;; don't override users' setting of $EMACS.
+          (unless (getenv "EMACS") '("EMACS=t"))
+          (copy-sequence process-environment)))
+        cd-path                 ; in case process-environment contains CDPATH
+        (thisdir (if (string-match "^\\s *cd\\s +\\(.+?\\)\\s *[;&\n]" command)
+                     (substitute-in-file-name (match-string 1 command))
+                   default-directory))
+        outwin outbuf)
     (with-current-buffer
        (setq outbuf
              (get-buffer-create
@@ -901,15 +905,16 @@ Returns the compilation buffer created."
                     (buffer-name)))))
       ;; Clear out the compilation buffer and make it writable.
       ;; Change its default-directory to the directory where the compilation
-      ;; will happen, and insert a `cd' command to indicate this.
+      ;; will happen, and insert a `default-directory' to indicate this.
       (setq buffer-read-only nil)
       (buffer-disable-undo (current-buffer))
       (erase-buffer)
       (buffer-enable-undo (current-buffer))
-      (setq default-directory thisdir)
+      (cd thisdir)
       ;; output a mode setter, for saving and later reloading this buffer
-      (insert "cd " thisdir "  # -*-" name-of-mode
-             "-*-\nEntering directory `" thisdir "'\n" command "\n")
+      (insert "-*- mode: " name-of-mode
+             "; default-directory: " (prin1-to-string default-directory)
+             " -*-\n" command "\n")
       (set-buffer-modified-p nil))
     ;; If we're already in the compilation buffer, go to the end
     ;; of the buffer, so point will track the compilation output.
index 083540c..4d9e051 100644 (file)
@@ -500,17 +500,6 @@ temporarily highlight in visited source lines."
                         command-args)
                       'grep-mode nil highlight-regexp)))
 
-;;; This doesn't work:
-;;;      ###autoload (autoload 'grep-mode "grep" nil t)
-;;; The ostensibly correct result is nonetheless opaque to the accounting
-;;; done in `generate-file-autoloads'; in loaddefs.el, the generated elisp is
-;;; correct but the generated header comment for grep.el lacks `grep-mode'.
-;;; This approach also doesn't help other users of `define-compilation-mode'
-;;; who wish to autoload.
-;;;
-;;; Better to extend autoload.el to grok `define-compilation-mode'.
-
-;;;###autoload
 (define-compilation-mode grep-mode "Grep"
   "Sets `grep-last-buffer' and `compilation-window-height'."
   (setq grep-last-buffer (current-buffer))
@@ -626,5 +615,5 @@ those sub directories of DIR."
 
 (provide 'grep)
 
-;;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d
+;; arch-tag: 5a5b9169-a79d-4f38-9c38-f69615f39c4d
 ;;; grep.el ends here
index 9bc8175..899534a 100644 (file)
@@ -4297,11 +4297,12 @@ to decide what to delete."
                 (not (equal buffer
                             (window-buffer (active-minibuffer-window))))))
        (error "Minibuffer is not active for completion")
+      ;; Set buffer so buffer-local choose-completion-string-functions works.
+      (set-buffer buffer)
       (unless (run-hook-with-args-until-success
               'choose-completion-string-functions
               choice buffer mini-p base-size)
        ;; Insert the completion into the buffer where it was requested.
-       (set-buffer buffer)
        (if base-size
            (delete-region (+ base-size (if mini-p
                                            (minibuffer-prompt-end)
index 1534820..ddc1d4e 100644 (file)
@@ -1,6 +1,6 @@
 ;;; bibtex.el --- BibTeX mode for GNU Emacs
 
-;; Copyright (C) 1992,94,95,96,97,98,1999,2003,2004
+;; Copyright (C) 1992, 1994, 1995, 1996, 1997, 1998, 1999, 2003, 2004
 ;;           Free Software Foundation, Inc.
 
 ;; Author: Stefan Schoef <schoef@offis.uni-oldenburg.de>
   :type 'hook)
 
 (defcustom bibtex-field-delimiters 'braces
-  "*Type of field delimiters. Allowed values are `braces' or `double-quotes'."
+  "*Type of field delimiters.  Allowed values are `braces' or `double-quotes'."
   :group 'bibtex
   :type '(choice (const braces)
                  (const double-quotes)))
 
 (defcustom bibtex-entry-delimiters 'braces
-  "*Type of entry delimiters. Allowed values are `braces' or `parentheses'."
+  "*Type of entry delimiters.  Allowed values are `braces' or `parentheses'."
   :group 'bibtex
   :type '(choice (const braces)
                  (const parentheses)))
@@ -154,10 +154,10 @@ narrowed to just the entry."
 Allowed non-nil values are:
 plain        All entries are sorted alphabetically.
 crossref     All entries are sorted alphabetically unless an entry has a
-             crossref field. These crossrefed entries are placed in
+             crossref field.  These crossrefed entries are placed in
              alphabetical order immediately preceding the main entry.
 entry-class  The entries are divided into classes according to their
-             entry name, see `bibtex-sort-entry-class'. Within each class
+             entry name, see `bibtex-sort-entry-class'.  Within each class
              the entries are sorted alphabetically.
 See also `bibtex-sort-ignore-string-entries'."
   :group 'bibtex
@@ -172,8 +172,8 @@ See also `bibtex-sort-ignore-string-entries'."
     ("Book" "Proceedings"))
   "*List of classes of BibTeX entry names, used for sorting entries.
 If value of `bibtex-maintain-sorted-entries' is `entry-class'
-entries are ordered according to the classes they belong to. Each
-class contains a list of entry names. An entry `catch-all' applies
+entries are ordered according to the classes they belong to.  Each
+class contains a list of entry names.  An entry `catch-all' applies
 to all entries not explicitely mentioned.")
 
 (defcustom bibtex-sort-ignore-string-entries t
@@ -640,7 +640,7 @@ See `bibtex-generate-autokey' for details."
 
 (defcustom bibtex-autokey-titleword-ignore
   '("A" "An" "On" "The" "Eine?" "Der" "Die" "Das"
-    "[^A-Z].*" ".*[^a-zA-Z0-9].*")
+    "[^A-Z].*" ".*[^A-Z0-9].*")
   "*Determines words from the title that are not to be used in the key.
 Each item of the list is a regexp.  If a word of the title matchs a
 regexp from that list, it is not included in the title part of the key.
@@ -762,11 +762,47 @@ If non-nil, the column for the equal sign is the value of
   "Automatically fill fields if possible for those BibTeX entry types."
   :type '(repeat string))
 
-(defcustom bibtex-complete-key-cleanup nil
-  "*Function called by `bibtex-complete' after insertion of a key fragment."
-  :group 'bibtex-autokey
-  :type '(choice (const :tag "None" nil)
-                 (function :tag "Cleanup function")))
+(defcustom bibtex-generate-url-list
+  '((("url" . ".*:.*"))
+    ;; Example of a complex setup.
+    (("journal" . "\\<\\(PR[ABCDEL]?\\|RMP\\)\\>")
+     "http://publish.aps.org/abstract/"
+     ("journal" ".*" downcase)
+     "/v"
+     ("volume" ".*" 0)
+     "/p"
+     ("pages" "\\`\\([0-9]+\\)" 1)))
+  "List of schemes for generating the URL of a BibTeX entry.
+These schemes are used by `bibtex-url'.
+
+Each scheme is of the form ((FIELD . REGEXP) STEP...).
+
+FIELD is a field name as returned by `bibtex-parse-entry'.
+REGEXP is matched against the text of FIELD.  If the match succeed, then
+this scheme will be used.  If no STEPS are specified the matched text is used
+as the URL, otherwise the URL is built by concatenating the STEPS.
+
+A STEP can be a string or a list (FIELD REGEXP REPLACE) in which case
+the text of FIELD is matched against REGEXP, and is replaced with REPLACE.
+REPLACE can be a string, or a number (which selects the corresponding submatch)
+or a function called with the field's text as argument and with the
+`match-data' properly set.
+
+Case is always ignored.  Always remove the field delimiters."
+  :group 'bibtex
+  :type '(repeat
+          (list :tag "Scheme"
+                (cons :tag "Matcher" :extra-offset 4
+                      (string :tag "BibTeX field")
+                     (regexp :tag "Regexp"))
+                (repeat :tag "Steps to generate URL" :inline t
+                        (choice
+                         (string :tag "Literal text")
+                         (list (string :tag "BibTeX field")
+                              (regexp :tag "Regexp")
+                               (choice (string :tag "Replacement")
+                                      (integer :tag "Sub-match")
+                                      (function :tag "Filter"))))))))
 
 ;; bibtex-font-lock-keywords is a user option as well, but since the
 ;; patterns used to define this variable are defined in a later
@@ -801,6 +837,7 @@ If non-nil, the column for the equal sign is the value of
     (define-key km "\C-c}" 'bibtex-remove-delimiters)
     (define-key km "\C-c\C-c" 'bibtex-clean-entry)
     (define-key km "\C-c\C-q" 'bibtex-fill-entry)
+    (define-key km "\C-c\C-s" 'bibtex-find-entry)
     (define-key km "\C-c?" 'bibtex-print-help-message)
     (define-key km "\C-c\C-p" 'bibtex-pop-previous)
     (define-key km "\C-c\C-n" 'bibtex-pop-next)
@@ -821,6 +858,7 @@ If non-nil, the column for the equal sign is the value of
     (define-key km "\C-c\C-b" 'bibtex-entry)
     (define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry)
     (define-key km "\C-c\C-rw" 'widen)
+    (define-key km "\C-c\C-l" 'bibtex-url)
     (define-key km "\C-c\C-o" 'bibtex-remove-OPT-or-ALT)
     (define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings)
     (define-key km "\C-c\C-ei" 'bibtex-InCollection)
@@ -854,21 +892,7 @@ If non-nil, the column for the equal sign is the value of
     ("Moving in BibTeX Buffer"
      ["Find Entry" bibtex-find-entry t]
      ["Find Crossref Entry" bibtex-find-crossref t])
-    ("Operating on Current Entry"
-     ["Fill Entry" bibtex-fill-entry t]
-     ["Clean Entry" bibtex-clean-entry t]
      "--"
-     ["Kill Entry" bibtex-kill-entry t]
-     ["Copy Entry to Kill Ring" bibtex-copy-entry-as-kill t]
-     ["Paste Most Recently Killed Entry" bibtex-yank t]
-     ["Paste Previously Killed Entry" bibtex-yank-pop t]
-     "--"
-     ["Ispell Entry" bibtex-ispell-entry t]
-     ["Ispell Entry Abstract" bibtex-ispell-abstract t]
-     ["Narrow to Entry" bibtex-narrow-to-entry t]
-     "--"
-     ["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex
-      (fboundp 'reftex-view-crossref-from-bibtex)])
     ("Operating on Current Field"
      ["Fill Field" fill-paragraph t]
      ["Remove Delimiters" bibtex-remove-delimiters t]
@@ -888,12 +912,28 @@ If non-nil, the column for the equal sign is the value of
      ["String or Key Complete" bibtex-complete t]
      "--"
      ["Help about Current Field" bibtex-print-help-message t])
+    ("Operating on Current Entry"
+     ["Fill Entry" bibtex-fill-entry t]
+     ["Clean Entry" bibtex-clean-entry t]
+     ["Update Entry" bibtex-entry-update t]
+     "--"
+     ["Kill Entry" bibtex-kill-entry t]
+     ["Copy Entry to Kill Ring" bibtex-copy-entry-as-kill t]
+     ["Paste Most Recently Killed Entry" bibtex-yank t]
+     ["Paste Previously Killed Entry" bibtex-yank-pop t]
+     "--"
+     ["Ispell Entry" bibtex-ispell-entry t]
+     ["Ispell Entry Abstract" bibtex-ispell-abstract t]
+     ["Narrow to Entry" bibtex-narrow-to-entry t]
+     "--"
+     ["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex
+      (fboundp 'reftex-view-crossref-from-bibtex)])
     ("Operating on Buffer or Region"
      ["Validate Entries" bibtex-validate t]
      ["Sort Entries" bibtex-sort-buffer t]
      ["Reformat Entries" bibtex-reformat t]
-     ["Count Entries" bibtex-count-entries t])
-    ("Miscellaneous"
+     ["Count Entries" bibtex-count-entries t]
+     "--"
      ["Convert Alien Buffer" bibtex-convert-alien t])))
 
 (easy-menu-define
@@ -915,6 +955,13 @@ If non-nil, the column for the equal sign is the value of
         ["String" bibtex-String t]
         ["Preamble" bibtex-Preamble t]))
 
+(defvar bibtex-url-map
+  (let ((km (make-sparse-keymap)))
+    (define-key km [(mouse-2)] 'bibtex-url)
+    km)
+  "Local keymap for clickable URLs.")
+(fset 'bibtex-url-map bibtex-url-map)
+    
 \f
 ;; Internal Variables
 
@@ -954,8 +1001,7 @@ Initialized from `bibtex-predefined-strings' and `bibtex-string-files'.")
 (make-variable-buffer-local 'bibtex-reference-keys)
 
 (defvar bibtex-buffer-last-parsed-tick nil
-  "Last value returned by `buffer-modified-tick' when buffer
-was parsed for keys the last time.")
+  "Value of `buffer-modified-tick' last time buffer was parsed for keys.")
 
 (defvar bibtex-parse-idle-timer nil
   "Stores if timer is already installed.")
@@ -1040,41 +1086,35 @@ was parsed for keys the last time.")
 (defconst bibtex-empty-field-re "\"\"\\|{}"
   "Regexp matching an empty field.")
 
-(defconst bibtex-quoted-string-re
-  (concat "\""
-          "\\("
-          "[^\"\\]"          ; anything but quote or backslash
-          "\\|"
-          "\\("
-          "\\\\\\(.\\|\n\\)" ; any backslash quoted character
-          "\\)"
-          "\\)*"
-          "\"")
-  "Regexp matching a field string enclosed by quotes.")
-
 (defconst bibtex-font-lock-syntactic-keywords
   `((,(concat "^[ \t]*\\(" (substring bibtex-comment-start 0 1) "\\)"
               (substring bibtex-comment-start 1) "\\>")
      1 '(11))))
 
 (defvar bibtex-font-lock-keywords
-  (list
-   ;; entry type and reference key
-   (list bibtex-entry-maybe-empty-head
-         (list bibtex-type-in-head 'font-lock-function-name-face)
-         (list bibtex-key-in-head 'font-lock-constant-face nil t))
-   ;; optional field names (treated as comments)
-   (list
-    (concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=")
-    1 'font-lock-comment-face)
-   ;; field names
-   (list (concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
-         1 'font-lock-variable-name-face))
+  ;; entry type and reference key
+  `((,bibtex-entry-maybe-empty-head
+     (,bibtex-type-in-head font-lock-function-name-face)
+     (,bibtex-key-in-head font-lock-constant-face nil t))
+    ;; optional field names (treated as comments)
+    (,(concat "^[ \t]*\\(OPT" bibtex-field-name "\\)[ \t]*=")
+     1 font-lock-comment-face)
+    ;; field names
+    (,(concat "^[ \t]*\\(" bibtex-field-name "\\)[ \t]*=")
+     1 font-lock-variable-name-face)
+    ;; url
+    (bibtex-font-lock-url 0 '(face nil mouse-face highlight
+                                   keymap bibtex-url-map)))
   "*Default expressions to highlight in BibTeX mode.")
 
+(defvar bibtex-font-lock-url-regexp
+  (concat "\\<" (regexp-opt (mapcar 'caar bibtex-generate-url-list) t)
+          "\\>[ \t]*=[ \t]*")
+  "Regexp for `bibtex-font-lock-url'.")
+
 (defvar bibtex-field-name-for-parsing nil
-  "Temporary variable storing the name string to be parsed by the callback
-function `bibtex-parse-field-name'.")
+  "Regexp of field name to be parsed by function `bibtex-parse-field-name'.
+Passed by dynamic scoping.")
 
 (defvar bibtex-sort-entry-class-alist
   (let ((i -1) alist)
@@ -1083,41 +1123,38 @@ function `bibtex-parse-field-name'.")
       (dolist (entry class)
         ;; all entry names should be downcase (for ease of comparison)
         (push (cons (if (stringp entry) (downcase entry) entry) i) alist))))
-  "Alist for the classes of the entry types if the value of
-`bibtex-maintain-sorted-entries' is `entry-class'.")
+  "Alist mapping entry types to their sorting index.
+Auto-generated from `bibtex-sort-entry-class'.
+Used when `bibtex-maintain-sorted-entries' is `entry-class'.")
 
 \f
 ;; Special support taking care of variants
 (defvar zmacs-regions)
-(if (boundp 'mark-active)
-    (defun bibtex-mark-active ()
+(defalias 'bibtex-mark-active
+  (if (boundp 'mark-active)
       ;; In Emacs mark-active indicates if mark is active.
-      mark-active)
-  (defun bibtex-mark-active ()
+      (lambda () mark-active)
     ;; In XEmacs (mark) returns nil when not active.
-    (if zmacs-regions (mark) (mark t))))
-
-(if (fboundp 'run-with-idle-timer)
-    ;; timer.el is distributed with Emacs
-    (fset 'bibtex-run-with-idle-timer 'run-with-idle-timer)
-  ;; timer.el is not distributed with XEmacs
-  ;; Notice that this does not (yet) pass the arguments, but they
-  ;; are not used (yet) in bibtex.el. Fix if needed.
-  (defun bibtex-run-with-idle-timer (secs repeat function &rest args)
-    (start-itimer "bibtex" function secs (if repeat secs nil) t)))
+    (lambda () (if zmacs-regions (mark) (mark t)))))
+
+(defalias 'bibtex-run-with-idle-timer
+  (if (fboundp 'run-with-idle-timer)
+      ;; timer.el is distributed with Emacs
+      'run-with-idle-timer
+    ;; timer.el is not distributed with XEmacs
+    ;; Notice that this does not (yet) pass the arguments, but they
+    ;; are not used (yet) in bibtex.el. Fix if needed.
+    (lambda (secs repeat function &rest args)
+      (start-itimer "bibtex" function secs (if repeat secs nil) t))))
 
 \f
 ;; Support for hideshow minor mode
 (defun bibtex-hs-forward-sexp (arg)
-  "Replacement for `forward-sexp' to be used by `hs-minor-mode'."
-  (if (< arg 0)
-      (backward-sexp 1)
-    (if (looking-at "@\\S(*\\s(")
-        (progn
-          (goto-char (match-end 0))
-          (forward-char -1)
-          (forward-sexp 1))
-      (forward-sexp 1))))
+  "Replacement for `forward-sexp' to be used by `hs-minor-mode'.
+ARG is ignored."
+  (if (looking-at "@\\S(*\\s(")
+    (goto-char (1- (match-end 0))))
+  (forward-sexp 1))
 
 (add-to-list
  'hs-special-modes-alist
@@ -1144,7 +1181,7 @@ values of the functions PARSE-LHS and PARSE-RHS is returned."
   "Parse the field name stored in `bibtex-field-name-for-parsing'.
 If the field name is found, return a triple consisting of the position of the
 very first character of the match, the actual starting position of the name
-part and end position of the match. Move point to end of field name.
+part and end position of the match.  Move point to end of field name.
 If `bibtex-autoadd-commas' is non-nil add missing comma at end of preceeding
 BibTeX field as necessary."
   (cond ((looking-at ",[ \t\n]*")
@@ -1206,7 +1243,7 @@ end position of the field string is returned, nil otherwise."
 The text part is either a string, or an empty string, or a constant followed
 by one or more <# (string|constant)> pairs.  If a syntactically correct text
 is found, a pair containing the start and end position of the text is
-returned, nil otherwise. Move point to end of field text."
+returned, nil otherwise.  Move point to end of field text."
   (let ((starting-point (point))
         end-point failure boundaries)
     (while (not (or end-point failure))
@@ -1215,9 +1252,9 @@ returned, nil otherwise. Move point to end of field text."
             ((setq boundaries (bibtex-parse-field-string))
              (goto-char (cdr boundaries)))
             ((setq failure t)))
-      (if (not (looking-at "[ \t\n]*#[ \t\n]*"))
-          (setq end-point (point))
-        (goto-char (match-end 0))))
+      (if (looking-at "[ \t\n]*#[ \t\n]*")
+          (goto-char (match-end 0))
+        (setq end-point (point))))
     (if (and (not failure)
              end-point)
         (cons starting-point end-point))))
@@ -1234,8 +1271,8 @@ the name and text parts of the field is returned."
   "Search forward to find a field of name NAME.
 If a syntactically correct field is found, a pair containing the boundaries of
 the name and text parts of the field is returned.  The search is limited by
-optional arg BOUND. If BOUND is t the search is limited by the end of the current
-entry. Do not move point."
+optional arg BOUND.  If BOUND is t the search is limited by the end of the
+current entry.  Do not move point."
   (save-match-data
     (save-excursion
       (unless (integer-or-marker-p bound)
@@ -1261,8 +1298,8 @@ entry. Do not move point."
   "Search backward to find a field of name NAME.
 If a syntactically correct field is found, a pair containing the boundaries of
 the name and text parts of the field is returned.  The search is limited by
-optional arg BOUND. If BOUND is t the search is limited by the beginning of the
-current entry. Do not move point."
+optional arg BOUND.  If BOUND is t the search is limited by the beginning of the
+current entry.  Do not move point."
   (save-match-data
     (save-excursion
       (unless (integer-or-marker-p bound)
@@ -1294,10 +1331,15 @@ current entry. Do not move point."
 (defsubst bibtex-end-of-text-in-field (bounds)
   (cddr bounds))
 
-(defun bibtex-name-in-field (bounds)
-  "Get content of name in BibTeX field defined via BOUNDS."
-  (buffer-substring-no-properties (nth 1 (car bounds))
-                                  (nth 2 (car bounds))))
+(defun bibtex-name-in-field (bounds &optional remove-opt-alt)
+  "Get content of name in BibTeX field defined via BOUNDS.
+If optional arg REMOVE-OPT-ALT is non-nil remove \"OPT\" and \"ALT\"."
+  (let ((name (buffer-substring-no-properties (nth 1 (car bounds))
+                                              (nth 2 (car bounds)))))
+    (if (and remove-opt-alt
+             (string-match "\\`\\(OPT\\|ALT\\)" name))
+        (substring name 3)
+      name)))
 
 (defun bibtex-text-in-field-bounds (bounds &optional remove-delim)
   "Get content of text in BibTeX field defined via BOUNDS.
@@ -1311,7 +1353,7 @@ if present."
       content)))
 
 (defun bibtex-text-in-field (field &optional follow-crossref)
-  "Get content of field FIELD of current BibTeX entry. Return nil if not found.
+  "Get content of field FIELD of current BibTeX entry.  Return nil if not found.
 If optional arg FOLLOW-CROSSREF is non-nil, follow crossref."
   (save-excursion
     (save-restriction
@@ -1351,7 +1393,7 @@ reference key and the end position of the match."
   "Parse the postfix part of a BibTeX string entry, including the text.
 If the string postfix is found, return a triple consisting of the position of
 the actual starting and ending position of the text and the very last
-character of the string entry. Move point past BibTeX string entry."
+character of the string entry.  Move point past BibTeX string entry."
   (let* ((case-fold-search t)
          (bounds (bibtex-parse-field-text)))
     (when bounds
@@ -1373,7 +1415,7 @@ Move point past BibTeX string entry."
 (defun bibtex-search-forward-string ()
   "Search forward to find a BibTeX string entry.
 If a syntactically correct entry is found, a pair containing the boundaries of
-the reference key and text parts of the string is returned. Do not move point."
+the reference key and text parts of the string is returned.  Do not move point."
   (save-excursion
     (save-match-data
       (let ((case-fold-search t)
@@ -1389,7 +1431,7 @@ the reference key and text parts of the string is returned. Do not move point."
 (defun bibtex-search-backward-string ()
   "Search backward to find a BibTeX string entry.
 If a syntactically correct entry is found, a pair containing the boundaries of
-the reference key and text parts of the field is returned. Do not move point."
+the reference key and text parts of the field is returned.  Do not move point."
   (save-excursion
     (save-match-data
       (let ((case-fold-search t)
@@ -1430,7 +1472,7 @@ delimiters if present."
                                   (match-end bibtex-type-in-head)))
 
 (defun bibtex-key-in-head (&optional empty)
-  "Extract BibTeX key in head. Return optional arg EMPTY if key is empty."
+  "Extract BibTeX key in head.  Return optional arg EMPTY if key is empty."
   (if (match-beginning bibtex-key-in-head)
       (buffer-substring-no-properties (match-beginning bibtex-key-in-head)
                                       (match-end bibtex-key-in-head))
@@ -1438,6 +1480,10 @@ delimiters if present."
 
 ;; Helper Functions
 
+(defsubst bibtex-string= (str1 str2)
+  "Return t if STR1 and STR2 are equal, ignoring case."
+  (eq t (compare-strings str1 0 nil str2 0 nil t)))
+
 (defun bibtex-delete-whitespace ()
   "Delete all whitespace starting at point."
   (if (looking-at "[ \t\n]+")
@@ -1448,22 +1494,14 @@ delimiters if present."
   (+ (count-lines 1 (point))
      (if (equal (current-column) 0) 1 0)))
 
-(defun bibtex-member-of-regexp (string list)
-  "Return non-nil if STRING is exactly matched by an element of LIST.
-The value is actually the tail of LIST whose car matches STRING."
-  (let (case-fold-search)
-    (while (and list
-                (not (string-match (concat "\\`\\(?:" (car list) "\\)\\'") string)))
-      (setq list (cdr list)))
-    list))
-
 (defun bibtex-skip-to-valid-entry (&optional backward)
-  "Unless at beginning of a valid BibTeX entry, move point to beginning of the
-next valid one. With optional argument BACKWARD non-nil, move backward to
-beginning of previous valid one. A valid entry is a syntactical correct one
+  "Move point to beginning of the next valid BibTeX entry.
+Do not move if we are already at beginning of a valid BibTeX entry.
+With optional argument BACKWARD non-nil, move backward to
+beginning of previous valid one.  A valid entry is a syntactical correct one
 with type contained in `bibtex-entry-field-alist' or, if
 `bibtex-sort-ignore-string-entries' is nil, a syntactical correct string
-entry. Return buffer position of beginning and ending of entry if a valid
+entry.  Return buffer position of beginning and ending of entry if a valid
 entry is found, nil otherwise."
   (interactive "P")
   (let ((case-fold-search t)
@@ -1488,9 +1526,9 @@ entry is found, nil otherwise."
 
 (defun bibtex-map-entries (fun)
   "Call FUN for each BibTeX entry starting with the current.
-Do this to the end of the file. FUN is called with three arguments, the key of
+Do this to the end of the file.  FUN is called with three arguments, the key of
 the entry and the buffer positions (marker) of beginning and end of entry.
-Point is inside the entry. If `bibtex-sort-ignore-string-entries' is non-nil,
+Point is inside the entry.  If `bibtex-sort-ignore-string-entries' is non-nil,
 FUN will not be called for @String entries."
   (let ((case-fold-search t))
     (bibtex-beginning-of-entry)
@@ -1501,7 +1539,7 @@ FUN will not be called for @String entries."
             (end (copy-marker (save-excursion (bibtex-end-of-entry)))))
         (save-excursion
           (if (or (and (not bibtex-sort-ignore-string-entries)
-                       (string-equal "string" (downcase entry-type)))
+                       (bibtex-string= entry-type "string"))
                   (assoc-string entry-type bibtex-entry-field-alist t))
               (funcall fun key beg end)))
         (goto-char end)))))
@@ -1556,8 +1594,8 @@ If FLAG is nil, a message is echoed if point was incremented at least
 
 (defun bibtex-search-entry (empty-head &optional bound noerror backward)
   "Search for a BibTeX entry (maybe without reference key if EMPTY-HEAD is t).
-BOUND and NOERROR are exactly as in `re-search-forward'. If BACKWARD
-is non-nil, search is done in reverse direction. Point is moved past the
+BOUND and NOERROR are exactly as in `re-search-forward'.  If BACKWARD
+is non-nil, search is done in reverse direction.  Point is moved past the
 closing delimiter (at the beginning of entry if BACKWARD is non-nil).
 Return a cons pair with buffer positions of beginning and end of entry.
 After call to this function MATCH-BEGINNING and MATCH-END functions
@@ -1575,7 +1613,7 @@ are defined, but only for the head part of the entry
           (if found
               (progn (goto-char (match-beginning 0))
                      found)
-            (cond ((equal noerror nil)
+            (cond ((not noerror)
                    ;; yell
                    (error "Backward search of BibTeX entry failed"))
                   ((equal noerror t)
@@ -1660,7 +1698,7 @@ are defined, but only for the head part of the entry
     (skip-chars-forward " \t\n")))
 
 (defun bibtex-beginning-of-first-entry ()
-  "Go to the beginning of the first BibTeX entry in buffer. Return point."
+  "Go to the beginning of the first BibTeX entry in buffer.  Return point."
   (goto-char (point-min))
   (if (re-search-forward "^[ \t]*@" nil 'move)
       (beginning-of-line))
@@ -1684,10 +1722,10 @@ are defined, but only for the head part of the entry
       (forward-char -1)))
 
 (defun bibtex-enclosing-field (&optional noerr)
-  "Search for BibTeX field enclosing point. Point moves to end of field.
-Use `match-beginning' and `match-end' to parse the field. If NOERR is non-nil,
-no error is signalled. In this case, bounds are returned on success,
-nil otherwise."
+  "Search for BibTeX field enclosing point.
+Use `match-beginning' and `match-end' to parse the field.  If NOERR is non-nil,
+no error is signalled.  In this case, bounds are returned on success,
+nil otherwise.  Does not move point."
   (let ((bounds (bibtex-search-backward-field bibtex-field-name t)))
     (if (and bounds
              (<= (bibtex-start-of-field bounds) (point))
@@ -1697,7 +1735,7 @@ nil otherwise."
         (error "Can't find enclosing BibTeX field")))))
 
 (defun bibtex-enclosing-entry-maybe-empty-head ()
-  "Search for BibTeX entry enclosing point. Move point to end of entry.
+  "Search for BibTeX entry enclosing point.  Move point to end of entry.
 Beginning (but not end) of entry is given by (`match-beginning' 0)."
   (let ((case-fold-search t)
         (old-point (point)))
@@ -1732,8 +1770,7 @@ Beginning (but not end) of entry is given by (`match-beginning' 0)."
         (message "Mark set")
         (bibtex-make-field (list (elt current 1) nil (elt current 2)) t))
        ((equal bibtex-last-kill-command 'entry)
-        (if (not (eobp))
-            (bibtex-beginning-of-entry))
+        (unless (eobp) (bibtex-beginning-of-entry))
         (set-mark (point))
         (message "Mark set")
         (insert (elt current 1)))
@@ -1741,15 +1778,6 @@ Beginning (but not end) of entry is given by (`match-beginning' 0)."
         (error "Unknown tag field: %s.  Please submit a bug report"
                bibtex-last-kill-command))))))
 
-(defun bibtex-assoc-regexp (regexp alist)
-  "Return non-nil if REGEXP matches the car of an element of ALIST.
-The value is actually the element of ALIST matched by REGEXP.
-Case is ignored if `case-fold-search' is non-nil in the current buffer."
-  (while (and alist
-              (not (string-match regexp (caar alist))))
-    (setq alist (cdr alist)))
-  (car alist))
-
 (defun bibtex-format-entry ()
   "Helper function for `bibtex-clean-entry'.
 Formats current entry according to variable `bibtex-entry-format'."
@@ -1764,7 +1792,7 @@ Formats current entry according to variable `bibtex-entry-format'."
                                   unify-case inherit-booktitle)
                       bibtex-entry-format))
             crossref-key bounds alternatives-there non-empty-alternative
-            entry-list req-field-list field-done field-list)
+            entry-list req-field-list field-list)
 
         ;; identify entry type
         (goto-char (point-min))
@@ -1792,9 +1820,7 @@ Formats current entry according to variable `bibtex-entry-format'."
         ;; one alternative is non-empty
         (goto-char (point-min))
         (let* ((fields-alist (bibtex-parse-entry))
-               (case-fold-search t)
-               (field (bibtex-assoc-regexp "\\`\\(OPT\\)?crossref\\'"
-                                           fields-alist)))
+               (field (assoc-string "crossref" fields-alist t)))
           (setq crossref-key (and field
                                   (not (string-match bibtex-empty-field-re
                                                      (cdr field)))
@@ -1806,9 +1832,7 @@ Formats current entry according to variable `bibtex-entry-format'."
           (dolist (rfield req-field-list)
             (when (nth 3 rfield) ; we should have an alternative
               (setq alternatives-there t
-                    field (bibtex-assoc-regexp
-                           (concat "\\`\\(ALT\\)?" (car rfield) "\\'")
-                           fields-alist))
+                    field (assoc-string (car rfield) fields-alist t))
               (if (and field
                        (not (string-match bibtex-empty-field-re
                                           (cdr field))))
@@ -1887,7 +1911,7 @@ Formats current entry according to variable `bibtex-entry-format'."
 
               ;; update page dashes
               (if (and (memq 'page-dashes format)
-                       (string-match "\\`\\(OPT\\)?pages\\'" field-name)
+                       (bibtex-string= field-name "pages")
                        (progn (goto-char beg-text)
                               (looking-at
                                "\\([\"{][0-9]+\\)[ \t\n]*--?[ \t\n]*\\([0-9]+[\"}]\\)")))
@@ -1896,7 +1920,7 @@ Formats current entry according to variable `bibtex-entry-format'."
               ;; use book title of crossref'd entry
               (if (and (memq 'inherit-booktitle format)
                        empty-field
-                       (equal (downcase field-name) "booktitle")
+                       (bibtex-string= field-name "booktitle")
                        crossref-key)
                   (let ((title (save-restriction
                                  (widen)
@@ -1909,7 +1933,7 @@ Formats current entry according to variable `bibtex-entry-format'."
 
              ;; Use booktitle to set a missing title.
              (if (and empty-field
-                      (equal (downcase field-name) "title"))
+                      (bibtex-string= field-name "title"))
                  (let ((booktitle (bibtex-text-in-field "booktitle")))
                    (when booktitle
                      (setq empty-field nil)
@@ -1990,8 +2014,8 @@ Formats current entry according to variable `bibtex-entry-format'."
 (defun bibtex-autokey-abbrev (string len)
   "Return an abbreviation of STRING with at least LEN characters.
 If LEN is positive the abbreviation is terminated only after a consonant
-or at the word end. If LEN is negative the abbreviation is strictly
-enforced using abs (LEN) characters. If LEN is not a number, STRING
+or at the word end.  If LEN is negative the abbreviation is strictly
+enforced using abs (LEN) characters.  If LEN is not a number, STRING
 is returned unchanged."
   (cond ((or (not (numberp len))
              (<= (length string) (abs len)))
@@ -2007,9 +2031,9 @@ is returned unchanged."
                string)))))
 
 (defun bibtex-autokey-get-field (field &optional change-list)
-  "Get content of BibTeX field FIELD. Return empty string if not found.
+  "Get content of BibTeX field FIELD.  Return empty string if not found.
 Optional arg CHANGE-LIST is a list of substitution patterns that is
-applied to the content of FIELD. It is an alist with pairs
+applied to the content of FIELD.  It is an alist with pairs
 \(OLD-REGEXP . NEW-STRING\)."
   (let ((content (bibtex-text-in-field field bibtex-autokey-use-crossref))
         case-fold-search)
@@ -2023,15 +2047,16 @@ applied to the content of FIELD. It is an alist with pairs
   "Get contents of the name field of the current entry.
 Do some modifications based on `bibtex-autokey-name-change-strings'
 and return results as a list."
-  (let ((case-fold-search t))
-    (mapcar 'bibtex-autokey-demangle-name
-            (split-string (bibtex-autokey-get-field
-                           "author\\|editor"
-                           bibtex-autokey-name-change-strings)
-                          "[ \t\n]+and[ \t\n]+"))))
+  (let ((case-fold-search t)
+        (names (bibtex-autokey-get-field "author\\|editor"
+                                         bibtex-autokey-name-change-strings)))
+    ;; Some entries do not have a name field.
+    (unless (string= "" names)
+      (mapcar 'bibtex-autokey-demangle-name
+              (split-string names "[ \t\n]+and[ \t\n]+")))))
 
 (defun bibtex-autokey-demangle-name (fullname)
-  "Get the last part from a well-formed name and perform abbreviations."
+  "Get the last part from a well-formed FULLNAME and perform abbreviations."
   (let* (case-fold-search
          (name (cond ((string-match "\\([A-Z][^, ]*\\)[^,]*," fullname)
                       ;; Name is of the form "von Last, First" or
@@ -2059,18 +2084,18 @@ and return results as a list."
 
 (defun bibtex-autokey-get-title ()
   "Get title field contents up to a terminator."
-  (let ((titlestring
+  (let ((case-fold-search t)
+        (titlestring
          (bibtex-autokey-get-field "title"
                                    bibtex-autokey-titleword-change-strings)))
     ;; ignore everything past a terminator
-    (let ((case-fold-search t))
-      (dolist (terminator bibtex-autokey-title-terminators)
-        (if (string-match terminator titlestring)
-            (setq titlestring (substring titlestring 0 (match-beginning 0))))))
+    (dolist (terminator bibtex-autokey-title-terminators)
+      (if (string-match terminator titlestring)
+          (setq titlestring (substring titlestring 0 (match-beginning 0)))))
     ;; gather words from titlestring into a list. Ignore
     ;; specific words and use only a specific amount of words.
     (let ((counter 0)
-          case-fold-search titlewords titlewords-extra titleword end-match)
+          titlewords titlewords-extra titleword end-match)
       (while (and (or (not (numberp bibtex-autokey-titlewords))
                       (< counter (+ bibtex-autokey-titlewords
                                     bibtex-autokey-titlewords-stretch)))
@@ -2078,8 +2103,12 @@ and return results as a list."
         (setq end-match (match-end 0)
               titleword (substring titlestring
                                    (match-beginning 0) end-match))
-        (unless (bibtex-member-of-regexp titleword
-                                         bibtex-autokey-titleword-ignore)
+        (unless (let ((lst bibtex-autokey-titleword-ignore))
+                  (while (and lst
+                              (not (string-match (concat "\\`\\(?:" (car lst)
+                                                         "\\)\\'") titleword)))
+                    (setq lst (cdr lst)))
+                  lst)
           (setq titleword
                 (funcall bibtex-autokey-titleword-case-convert titleword))
           (if (or (not (numberp bibtex-autokey-titlewords))
@@ -2097,7 +2126,7 @@ and return results as a list."
   "Do some abbreviations on TITLEWORD.
 The rules are defined in `bibtex-autokey-titleword-abbrevs'
 and `bibtex-autokey-titleword-length'."
-  (let ((case-folde-search t)
+  (let ((case-fold-search t)
         (alist bibtex-autokey-titleword-abbrevs))
     (while (and alist
                 (not (string-match (concat "\\`\\(?:" (caar alist) "\\)\\'")
@@ -2119,7 +2148,7 @@ The generation algorithm works as follows:
     `bibtex-autokey-name-change-strings' to the corresponding new
     one (see documentation of this variable for further detail).
  4. For every of at least first `bibtex-autokey-names' names in
-    the name field, determine the last name. If there are maximal
+    the name field, determine the last name.  If there are maximal
     `bibtex-autokey-names' + `bibtex-autokey-names-stretch'
     names, all names are used.
  5. From every last name, take at least `bibtex-autokey-name-length'
@@ -2128,12 +2157,12 @@ The generation algorithm works as follows:
     `bibtex-autokey-name-case-convert'.
  7. Build the name part of the key by concatenating all
     abbreviated last names with the string
-    `bibtex-autokey-name-separator' between any two. If there are
+    `bibtex-autokey-name-separator' between any two.  If there are
     more names than are used in the name part, prepend the string
     contained in `bibtex-autokey-additional-names'.
  8. Build the year part of the key by truncating the contents of
     the year field to the rightmost `bibtex-autokey-year-length'
-    digits (useful values are 2 and 4). If the year field (or any
+    digits (useful values are 2 and 4).  If the year field (or any
     other field required to generate the key) is absent, but the entry
     has a valid crossref field and the variable
     `bibtex-autokey-use-crossref' is non-nil, use the field of the
@@ -2149,7 +2178,7 @@ The generation algorithm works as follows:
     appear in `bibtex-autokey-titleword-ignore'.
     Build the title part of the key by using at least the first
     `bibtex-autokey-titlewords' words from this
-    abbreviated title. If the abbreviated title ends after
+    abbreviated title.  If the abbreviated title ends after
     maximal `bibtex-autokey-titlewords' +
     `bibtex-autokey-titlewords-stretch' words, all
     words from the abbreviated title are used.
@@ -2170,13 +2199,13 @@ The generation algorithm works as follows:
     and the title part with `bibtex-autokey-name-year-separator'
     between the name part and the year part if both are non-empty
     and `bibtex-autokey-year-title-separator' between the year
-    part and the title part if both are non-empty. If the year
+    part and the title part if both are non-empty.  If the year
     part is empty, but not the other two parts,
     `bibtex-autokey-year-title-separator' is used as well.
 16. If the value of `bibtex-autokey-before-presentation-function'
-    is non-nil, it must be a function taking one argument. This
+    is non-nil, it must be a function taking one argument.  This
     function is then called with the generated key as the
-    argument. The return value of this function (a string) is
+    argument.  The return value of this function (a string) is
     used as the key.
 17. If the value of `bibtex-autokey-edit-before-use' is non-nil,
     the key is then presented in the minibuffer to the user,
@@ -2230,9 +2259,9 @@ The generation algorithm works as follows:
 The buffer might possibly be restricted.
 Find both entry keys and crossref entries.
 If ADD is non-nil add the new keys to `bibtex-reference-keys' instead of
-simply resetting it. If ADD is an alist of keys, also add ADD to
-`bibtex-reference-keys'. If ABORTABLE is non-nil abort on user
-input. If VERBOSE is non-nil gives messages about progress.
+simply resetting it.  If ADD is an alist of keys, also add ADD to
+`bibtex-reference-keys'.  If ABORTABLE is non-nil abort on user
+input.  If VERBOSE is non-nil gives messages about progress.
 Return alist of keys if parsing was completed, `aborted' otherwise."
   (let ((reference-keys (if (and add
                                  (listp bibtex-reference-keys))
@@ -2296,8 +2325,8 @@ Return alist of keys if parsing was completed, `aborted' otherwise."
   "Set `bibtex-strings' to the string definitions in the whole buffer.
 The buffer might possibly be restricted.
 If ADD is non-nil add the new strings to `bibtex-strings' instead of
-simply resetting it. If ADD is an alist of strings, also add ADD to
-`bibtex-strings'. If ABORTABLE is non-nil abort on user input.
+simply resetting it.  If ADD is an alist of strings, also add ADD to
+`bibtex-strings'.  If ABORTABLE is non-nil abort on user input.
 Return alist of strings if parsing was completed, `aborted' otherwise."
   (save-excursion
     (save-match-data
@@ -2308,7 +2337,7 @@ Return alist of strings if parsing was completed, `aborted' otherwise."
             bounds key)
         (if (listp add)
             (dolist (string add)
-              (unless (assoc (car string) strings)
+              (unless (assoc-string (car string) strings t)
                 (push string strings))))
         (catch 'userkey
           (while (setq bounds (bibtex-search-forward-string))
@@ -2317,9 +2346,9 @@ Return alist of strings if parsing was completed, `aborted' otherwise."
                 ;; user has aborted by typing a key --> return `aborted'
                 (throw 'userkey 'aborted))
             (setq key (bibtex-reference-key-in-string bounds))
-            (if (not (assoc key strings))
-                (push (cons key (bibtex-text-in-string bounds t))
-                      strings))
+            (unless (assoc-string key strings t)
+              (push (cons key (bibtex-text-in-string bounds t))
+                    strings))
             (goto-char (bibtex-end-of-text-in-string bounds)))
           ;; successful operation --> return `bibtex-strings'
           (setq bibtex-strings strings))))))
@@ -2357,7 +2386,8 @@ Use `bibtex-predefined-strings' and bib files `bibtex-string-files'."
       (append bibtex-predefined-strings (nreverse compl)))))
 
 (defun bibtex-parse-buffers-stealthily ()
-  "Called by `bibtex-run-with-idle-timer'. Whenever emacs has been idle
+  "Parse buffer in the background during idle time.
+Called by `bibtex-run-with-idle-timer'.  Whenever Emacs has been idle
 for `bibtex-parse-keys-timeout' seconds, all BibTeX buffers (starting
 with the current) are parsed."
   (save-excursion
@@ -2381,9 +2411,9 @@ with the current) are parsed."
         (setq buffers (cdr buffers))))))
 
 (defun bibtex-complete-internal (completions)
-  "Complete word fragment before point to longest prefix of one
-string defined in list COMPLETIONS.  If point is not after the part
-of a word, all strings are listed. Return completion."
+  "Complete word fragment before point to longest prefix of COMPLETIONS.
+COMPLETIONS should be a list of strings.  If point is not after the part
+of a word, all strings are listed.  Return completion."
   (let* ((case-fold-search t)
          (beg (save-excursion
                 (re-search-backward "[ \t{\"]")
@@ -2409,11 +2439,12 @@ of a word, all strings are listed. Return completion."
            ;; return value is handled by choose-completion-string-functions
            nil))))
 
-(defun bibtex-complete-string-cleanup (str)
+(defun bibtex-complete-string-cleanup (str strings-alist)
   "Cleanup after inserting string STR.
-Remove enclosing field delimiters for string STR. Display message with
-expansion of STR."
-  (let ((pair (assoc str bibtex-strings)))
+Remove enclosing field delimiters for string STR.  Display message with
+expansion of STR using expansion list STRINGS-ALIST."
+  (let ((pair (if (stringp str)
+                  (assoc-string str strings-alist t))))
     (when pair
       (if (cdr pair)
           (message "Abbreviation for `%s'" (cdr pair)))
@@ -2427,6 +2458,38 @@ expansion of STR."
                             (bibtex-end-of-text-in-field bounds)))
                 (bibtex-remove-delimiters))))))))
 
+(defun bibtex-complete-key-cleanup (key)
+  "Display message on entry KEY after completion of a crossref key."
+  (save-excursion
+    ;; Don't do anything if we completed the key of an entry.
+    (let ((pnt (bibtex-beginning-of-entry)))
+      (if (and (stringp key)
+               (bibtex-find-entry key)
+               (/= pnt (point)))
+          (let* ((bibtex-autokey-name-case-convert 'identity)
+                 (bibtex-autokey-name-length 'infty)
+                 (nl (bibtex-autokey-get-names))
+                 (name (concat (nth 0 nl) (if (nth 1 nl) " etal")))
+                 (year (bibtex-autokey-get-field "year"))
+                 (bibtex-autokey-titlewords 5)
+                 (bibtex-autokey-titlewords-stretch 2)
+                 (bibtex-autokey-titleword-case-convert 'identity)
+                 (bibtex-autokey-titleword-length 5)
+                 (title (mapconcat 'identity
+                                   (bibtex-autokey-get-title) " "))
+                 (journal (bibtex-autokey-get-field
+                           "journal" bibtex-autokey-transcriptions))
+                 (volume (bibtex-autokey-get-field "volume"))
+                 (pages (bibtex-autokey-get-field "pages" '(("-.*\\'" . "")))))
+            (message "Ref:%s"
+                     (mapconcat (lambda (arg)
+                                  (if (not (string= "" (cdr arg)))
+                                      (concat (car arg) (cdr arg))))
+                                `((" " . ,name) (" " . ,year)
+                                  (": " . ,title) (", " . ,journal)
+                                  (" " . ,volume) (":" . ,pages))
+                                "")))))))
+
 (defun bibtex-choose-completion-string (choice buffer mini-p base-size)
   ;; Code borrowed from choose-completion-string:
   ;; We must duplicate the code from choose-completion-string
@@ -2450,7 +2513,8 @@ expansion of STR."
     (set-window-point window (point))))
 
 (defun bibtex-pop (arg direction)
-  "Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'."
+  "Fill current field from the ARG'th same field's text in DIRECTION.
+Generic function used by `bibtex-pop-previous' and `bibtex-pop-next'."
   (let (bibtex-help-message)
     (bibtex-find-text nil))
   (save-excursion
@@ -2460,17 +2524,7 @@ expansion of STR."
            (bounds (bibtex-enclosing-field))
            (start-old-text (bibtex-start-of-text-in-field bounds))
            (stop-old-text (bibtex-end-of-text-in-field bounds))
-           (start-name (bibtex-start-of-name-in-field bounds))
-           (stop-name (bibtex-end-of-name-in-field bounds))
-           ;; construct regexp for field with same name as this one,
-           ;; ignoring possible OPT's or ALT's
-           (field-name (progn
-                         (goto-char start-name)
-                         (buffer-substring-no-properties
-                          (if (looking-at "\\(OPT\\)\\|\\(ALT\\)")
-                              (match-end 0)
-                            (point))
-                          stop-name))))
+           (field-name (bibtex-name-in-field bounds t)))
       ;; if executed several times in a row, start each search where
       ;; the last one was finished
       (unless (eq last-command 'bibtex-pop)
@@ -2523,15 +2577,15 @@ expansion of STR."
 General information on working with BibTeX mode:
 
 You should use commands such as \\[bibtex-Book] to get a template for a
-specific entry. You should then fill in all desired fields using
-\\[bibtex-next-field] to jump from field to field. After having filled
+specific entry.  You should then fill in all desired fields using
+\\[bibtex-next-field] to jump from field to field.  After having filled
 in all desired fields in the entry, you should clean the new entry
 with the command \\[bibtex-clean-entry].
 
 Some features of BibTeX mode are available only by setting the variable
-`bibtex-maintain-sorted-entries' to non-nil. However, then BibTeX mode will
+`bibtex-maintain-sorted-entries' to non-nil.  However, then BibTeX mode will
 work only with buffers containing valid (syntactical correct) entries
-and with entries being sorted. This is usually the case, if you have
+and with entries being sorted.  This is usually the case, if you have
 created a buffer completely with BibTeX mode and finished every new
 entry with \\[bibtex-clean-entry].
 
@@ -2639,9 +2693,10 @@ non-nil.
                 )
          nil
          (font-lock-syntactic-keywords . bibtex-font-lock-syntactic-keywords)
+         (font-lock-extra-managed-props . (mouse-face keymap))
         (font-lock-mark-block-function
          . (lambda ()
-         (set-mark (bibtex-end-of-entry))
+              (set-mark (bibtex-end-of-entry))
              (bibtex-beginning-of-entry)))))
   (setq imenu-generic-expression
         (list (list nil bibtex-entry-head bibtex-key-in-head)))
@@ -2681,7 +2736,7 @@ names for ENTRY-TYPE according to `bibtex-entry-field-alist'."
     (cons required optional)))
 
 (defun bibtex-entry (entry-type)
-  "Insert a new BibTeX entry.
+  "Insert a new BibTeX entry of type ENTRY-TYPE.
 After insertion it calls the functions in `bibtex-add-entry-hook'."
   (interactive (let* ((completion-ignore-case t)
                       (e-t (completing-read
@@ -2698,8 +2753,8 @@ After insertion it calls the functions in `bibtex-add-entry-hook'."
     (insert "@" entry-type (bibtex-entry-left-delimiter))
     (if key (insert key))
     (save-excursion
-      (mapcar 'bibtex-make-field (car field-list))
-      (mapcar 'bibtex-make-optional-field (cdr field-list))
+      (mapc 'bibtex-make-field (car field-list))
+      (mapc 'bibtex-make-optional-field (cdr field-list))
       (if bibtex-comma-after-last-field
           (insert ","))
       (insert "\n")
@@ -2722,29 +2777,27 @@ according to `bibtex-entry-field-alist', but are not yet present."
     (let* ((fields-alist (bibtex-parse-entry))
            (field-list (bibtex-field-list
                         (substring (cdr (assoc "=type=" fields-alist))
-                                   1))) ; don't want @
-           (case-fold-search t))
+                                   1)))) ; don't want @
       (dolist (field (car field-list))
-        (unless (bibtex-assoc-regexp (concat "\\`\\(ALT\\)?" (car field) "\\'")
-                                     fields-alist)
+        (unless (assoc-string (car field) fields-alist t)
           (bibtex-make-field field)))
       (dolist (field (cdr field-list))
-        (unless (bibtex-assoc-regexp (concat "\\`\\(OPT\\)?" (car field) "\\'")
-                                     fields-alist)
+        (unless (assoc-string (car field) fields-alist t)
           (bibtex-make-optional-field field))))))
 
 (defun bibtex-parse-entry ()
   "Parse entry at point, return an alist.
 The alist elements have the form (FIELD . TEXT), where FIELD can also be
-the special strings \"=type=\" and \"=key=\". For the FIELD \"=key=\"
-TEXT may be nil. Move point to the end of the last field."
+the special strings \"=type=\" and \"=key=\".  For the FIELD \"=key=\"
+TEXT may be nil.  Remove \"OPT\" and \"ALT\" from FIELD.
+Move point to the end of the last field."
   (let (alist bounds)
     (when (looking-at bibtex-entry-maybe-empty-head)
       (push (cons "=type=" (match-string bibtex-type-in-head)) alist)
       (push (cons "=key=" (match-string bibtex-key-in-head)) alist)
       (goto-char (match-end 0))
       (while (setq bounds (bibtex-parse-field bibtex-field-name))
-       (push (cons (bibtex-name-in-field bounds)
+       (push (cons (bibtex-name-in-field bounds t)
                    (bibtex-text-in-field-bounds bounds))
              alist)
        (goto-char (bibtex-end-of-field bounds))))
@@ -2770,7 +2823,7 @@ TEXT may be nil. Move point to the end of the last field."
        (bibtex-beginning-of-entry)
        (when (and
               (looking-at bibtex-entry-head)
-              (equal type (match-string bibtex-type-in-head))
+              (bibtex-string= type (match-string bibtex-type-in-head))
               ;; In case we found ourselves :-(
               (not (equal key (setq tmp (match-string bibtex-key-in-head)))))
          (setq other-key tmp)
@@ -2780,7 +2833,7 @@ TEXT may be nil. Move point to the end of the last field."
        (bibtex-skip-to-valid-entry)
        (when (and
               (looking-at bibtex-entry-head)
-              (equal type (match-string bibtex-type-in-head))
+              (bibtex-string= type (match-string bibtex-type-in-head))
               ;; In case we found ourselves :-(
               (not (equal key (setq tmp (match-string bibtex-key-in-head))))
               (or (not other-key)
@@ -2794,11 +2847,8 @@ TEXT may be nil. Move point to the end of the last field."
        (setq other (save-excursion (goto-char other) (bibtex-parse-entry)))
        (setq key-end (point))      ;In case parse-entry changed the buffer.
        (while (setq bounds (bibtex-parse-field bibtex-field-name))
-         (goto-char (bibtex-start-of-name-in-field bounds))
-         (let* ((name (buffer-substring
-                       (if (looking-at "ALT\\|OPT") (match-end 0) (point))
-                       (bibtex-end-of-name-in-field bounds)))
-                (text (assoc-string name other t)))
+         (let ((text (assoc-string (bibtex-name-in-field bounds t)
+                                    other t)))
            (goto-char (bibtex-start-of-text-in-field bounds))
            (if (not (and (looking-at bibtex-empty-field-re) text))
                (goto-char (bibtex-end-of-field bounds))
@@ -2821,13 +2871,7 @@ TEXT may be nil. Move point to the end of the last field."
   (interactive)
   (save-excursion
     (let* ((case-fold-search t)
-           (bounds (bibtex-enclosing-field))
-           (mb (bibtex-start-of-name-in-field bounds))
-           (field-name (buffer-substring-no-properties
-                        (if (progn (goto-char mb)
-                                   (looking-at "OPT\\|ALT"))
-                            (match-end 0) mb)
-                        (bibtex-end-of-name-in-field bounds)))
+           (field-name (bibtex-name-in-field (bibtex-enclosing-field) t))
            (field-list (bibtex-field-list (progn (re-search-backward
                                                   bibtex-entry-maybe-empty-head nil t)
                                                  (bibtex-type-in-head))))
@@ -2843,7 +2887,8 @@ TEXT may be nil. Move point to the end of the last field."
   "Make a field named FIELD in current BibTeX entry.
 FIELD is either a string or a list of the form
 \(FIELD-NAME COMMENT-STRING INIT ALTERNATIVE-FLAG) as in
-`bibtex-entry-field-alist'."
+`bibtex-entry-field-alist'.
+If CALLED-BY-YANK is non-nil, don't insert delimiters."
   (interactive
    (list (let ((completion-ignore-case t)
                (field-list (bibtex-field-list
@@ -2868,16 +2913,16 @@ FIELD is either a string or a list of the form
       (indent-to-column (+ bibtex-entry-offset
                            (- bibtex-text-indentation 2))))
   (insert "= ")
-  (if (not bibtex-align-at-equal-sign)
-      (indent-to-column (+ bibtex-entry-offset
-                           bibtex-text-indentation)))
-  (if (not called-by-yank) (insert (bibtex-field-left-delimiter)))
+  (unless bibtex-align-at-equal-sign
+    (indent-to-column (+ bibtex-entry-offset
+                         bibtex-text-indentation)))
+  (unless called-by-yank (insert (bibtex-field-left-delimiter)))
   (let ((init (nth 2 field)))
     (cond ((stringp init)
            (insert init))
           ((fboundp init)
            (insert (funcall init)))))
-  (if (not called-by-yank) (insert (bibtex-field-right-delimiter)))
+  (unless called-by-yank (insert (bibtex-field-right-delimiter)))
   (when (interactive-p)
     (forward-char -1)
     (bibtex-print-help-message)))
@@ -2885,8 +2930,8 @@ FIELD is either a string or a list of the form
 (defun bibtex-beginning-of-entry ()
   "Move to beginning of BibTeX entry (beginning of line).
 If inside an entry, move to the beginning of it, otherwise move to the
-beginning of the previous entry. If point is ahead of all BibTeX entries
-move point to the beginning of buffer. Return the new location of point."
+beginning of the previous entry.  If point is ahead of all BibTeX entries
+move point to the beginning of buffer.  Return the new location of point."
   (interactive)
   (skip-chars-forward " \t")
   (if (looking-at "@")
@@ -2897,7 +2942,7 @@ move point to the beginning of buffer. Return the new location of point."
 (defun bibtex-end-of-entry ()
   "Move to end of BibTeX entry (past the closing brace).
 If inside an entry, move to the end of it, otherwise move to the end
-of the previous entry. Do not move if ahead of first entry.
+of the previous entry.  Do not move if ahead of first entry.
 Return the new location of point."
   (interactive)
   (let ((case-fold-search t)
@@ -2997,9 +3042,9 @@ If mark is active it counts entries in region, if not in whole buffer."
                       (bibtex-end-of-entry))))
 
 (defun bibtex-entry-index ()
-  "Return the index of the BibTeX entry at point. Move point.
+  "Return the index of the BibTeX entry at point.  Move point.
 The index is a list (KEY CROSSREF-KEY ENTRY-NAME) that is used for sorting
-the entries of the BibTeX buffer. Return nil if no entry found."
+the entries of the BibTeX buffer.  Return nil if no entry found."
   (let ((case-fold-search t))
     (if (re-search-forward bibtex-entry-maybe-empty-head nil t)
         (let ((key (bibtex-key-in-head))
@@ -3049,8 +3094,8 @@ If its value is nil use plain sorting."
 (defun bibtex-sort-buffer ()
   "Sort BibTeX buffer alphabetically by key.
 The predicate for sorting is defined via `bibtex-maintain-sorted-entries'.
-If its value is nil use plain sorting. Text outside of BibTeX entries is not
-affected. If `bibtex-sort-ignore-string-entries' is non-nil, @String entries
+If its value is nil use plain sorting.  Text outside of BibTeX entries is not
+affected.  If `bibtex-sort-ignore-string-entries' is non-nil, @String entries
 will be ignored."
   (interactive)
   (save-restriction
@@ -3084,13 +3129,17 @@ entry."
         (error "This entry must not follow the crossrefed entry!"))
     (goto-char pos)))
 
-(defun bibtex-find-entry (key)
+(defun bibtex-find-entry (key &optional start)
   "Move point to the beginning of BibTeX entry named KEY.
-Return position of entry if KEY is found or nil if not found."
-  (interactive (list (bibtex-read-key "Find key: ")))
+Return position of entry if KEY is found or nil if not found.
+Optional arg START is buffer position where the search starts.
+If it is nil, start search at beginning of buffer.
+With prefix arg, the value of START is position of point."
+  (interactive (list (bibtex-read-key "Find key: ")
+                     (if current-prefix-arg (point))))
   (let* (case-fold-search
          (pnt (save-excursion
-                (goto-char (point-min))
+                (goto-char (or start (point-min)))
                 (if (re-search-forward (concat "^[ \t]*\\("
                                                bibtex-entry-type
                                                "\\)[ \t]*[({][ \t\n]*\\("
@@ -3108,7 +3157,7 @@ Return position of entry if KEY is found or nil if not found."
 INDEX is a list (KEY CROSSREF-KEY ENTRY-NAME).
 Move point where the entry KEY should be placed.
 If `bibtex-maintain-sorted-entries' is non-nil, perform a binary
-search to look for place for KEY. This will fail if buffer is not in
+search to look for place for KEY.  This will fail if buffer is not in
 sorted order, see \\[bibtex-validate].)
 Return t if preparation was successful or nil if entry KEY already exists."
   (let ((key (nth 0 index))
@@ -3157,8 +3206,7 @@ Return t if preparation was successful or nil if entry KEY already exists."
                ;; buffer contains no valid entries or
                ;; greater than last entry --> append
                (bibtex-end-of-entry)
-               (if (not (bobp))
-                   (newline (forward-line 2)))
+               (unless (bobp) (newline (forward-line 2)))
                (beginning-of-line)))))
     (unless key-exist t)))
 
@@ -3233,9 +3281,7 @@ Returns t if test was successful, nil otherwise."
             (goto-char (point-min))
             (bibtex-progress-message
              "Checking required fields and month fields")
-            (let ((bibtex-sort-ignore-string-entries t)
-                  (questionable-month
-                   (regexp-opt (mapcar 'car bibtex-predefined-month-strings))))
+            (let ((bibtex-sort-ignore-string-entries t))
               (bibtex-map-entries
                (lambda (key beg end)
                  (bibtex-progress-message)
@@ -3251,17 +3297,16 @@ Returns t if test was successful, nil otherwise."
                    (while (setq bounds (bibtex-search-forward-field
                                         bibtex-field-name end))
                      (goto-char (bibtex-start-of-text-in-field bounds))
-                     (let ((field-name (downcase (bibtex-name-in-field bounds)))
-                           case-fold-search)
-                       (if (and (equal field-name "month")
-                                (not (string-match questionable-month
-                                                   (bibtex-text-in-field-bounds bounds))))
+                     (let ((field-name (bibtex-name-in-field bounds)))
+                       (if (and (bibtex-string= field-name "month")
+                                (not (assoc-string (bibtex-text-in-field-bounds bounds)
+                                                   bibtex-predefined-month-strings t)))
                            (push (list (bibtex-current-line)
                                        "Questionable month field")
                                  error-list))
                        (setq req (delete (assoc-string field-name req t) req)
                              creq (delete (assoc-string field-name creq t) creq))
-                       (if (equal field-name "crossref")
+                       (if (bibtex-string= field-name "crossref")
                            (setq crossref-there t))))
                    (if crossref-there
                        (setq req creq))
@@ -3305,10 +3350,6 @@ Returns t if test was successful, nil otherwise."
           (dolist (err error-list)
             (insert bufnam ":" (number-to-string (elt err 0))
                     ": " (elt err 1) "\n"))
-          (compilation-parse-errors nil nil)
-          (setq compilation-old-error-list compilation-error-list)
-          ;; this is necessary to avoid reparsing of buffer if you
-          ;; switch to compilation buffer and enter `compile-goto-error'
           (set-buffer-modified-p nil)
           (toggle-read-only 1)
           (goto-char (point-min))
@@ -3395,11 +3436,13 @@ Align text and go thereafter to end of text."
   (interactive)
   (save-excursion
     (bibtex-inside-field)
-    (let ((bounds (bibtex-enclosing-field)))
-      (goto-char (bibtex-start-of-text-in-field bounds))
-      (delete-char 1)
-      (goto-char (1- (bibtex-end-of-text-in-field bounds)))
-      (delete-backward-char 1))))
+    (let* ((bounds (bibtex-enclosing-field))
+          (end (bibtex-end-of-text-in-field bounds))
+          (start (bibtex-start-of-text-in-field bounds)))
+      (if (memq (char-before end) '(?\} ?\"))
+         (delete-region (1- end) end))
+      (if (memq (char-after start) '(?\{ ?\"))
+         (delete-region start (1+ start))))))
 
 (defun bibtex-kill-field (&optional copy-only)
   "Kill the entire enclosing BibTeX field.
@@ -3455,6 +3498,7 @@ With prefix arg COPY-ONLY the current entry to
   (setq bibtex-last-kill-command 'entry))
 
 (defun bibtex-copy-entry-as-kill ()
+  "Copy the entire enclosing BibTeX entry to `bibtex-entry-kill-ring'."
   (interactive)
   (bibtex-kill-entry t))
 
@@ -3482,8 +3526,8 @@ If N is negative, this is a more recent kill.
 The sequence of kills wraps around, so that after the oldest one
 comes the newest one."
   (interactive "*p")
-  (if (not (eq last-command 'bibtex-yank))
-      (error "Previous command was not a BibTeX yank"))
+  (unless (eq last-command 'bibtex-yank)
+    (error "Previous command was not a BibTeX yank"))
   (setq this-command 'bibtex-yank)
   (let ((inhibit-read-only t))
     (delete-region (point) (mark t))
@@ -3519,7 +3563,7 @@ intermixed with \\[bibtex-pop-previous] (bibtex-pop-previous)."
 Check that no required fields are empty and formats entry dependent
 on the value of `bibtex-entry-format'.
 If the reference key of the entry is empty or a prefix argument is given,
-calculate a new reference key. (Note: this will only work if fields in entry
+calculate a new reference key.  (Note: this will only work if fields in entry
 begin on separate lines prior to calling `bibtex-clean-entry' or if
 'realign is contained in `bibtex-entry-format'.)
 Don't call `bibtex-clean-entry' on @Preamble entries.
@@ -3533,19 +3577,20 @@ At end of the cleaning process, the functions in
     (bibtex-beginning-of-entry)
     (save-excursion
       (when (re-search-forward bibtex-entry-maybe-empty-head nil t)
-        (setq entry-type (downcase (bibtex-type-in-head)))
+        (setq entry-type (bibtex-type-in-head))
         (setq key (bibtex-key-in-head))))
     ;; formatting
-    (cond ((equal entry-type "preamble")
+    (cond ((bibtex-string= entry-type "preamble")
            ;; (bibtex-format-preamble)
            (error "No clean up of @Preamble entries"))
-          ((equal entry-type "string"))
+          ((bibtex-string= entry-type "string"))
            ;; (bibtex-format-string)
           (t (bibtex-format-entry)))
     ;; set key
     (when (or new-key (not key))
       (setq key (bibtex-generate-autokey))
-      (if bibtex-autokey-edit-before-use
+      ;; Sometimes bibtex-generate-autokey returns an empty string
+      (if (or bibtex-autokey-edit-before-use (string= "" key))
           (setq key (bibtex-read-key "Key to use: " key)))
       (re-search-forward bibtex-entry-maybe-empty-head)
       (if (match-beginning bibtex-key-in-head)
@@ -3563,19 +3608,21 @@ At end of the cleaning process, the functions in
              (entry (buffer-substring start end))
              (index (progn (goto-char start)
                            (bibtex-entry-index)))
-             no-error)
+             error)
         (if (and bibtex-maintain-sorted-entries
                  (not (and bibtex-sort-ignore-string-entries
-                           (equal entry-type "string"))))
+                           (bibtex-string= entry-type "string"))))
             (progn
               (delete-region start end)
-              (setq no-error (bibtex-prepare-new-entry index))
+              (setq error (not (bibtex-prepare-new-entry index)))
               (insert entry)
               (forward-char -1)
               (bibtex-beginning-of-entry) ; moves backward
               (re-search-forward bibtex-entry-head))
-          (setq no-error (bibtex-find-entry (car index))))
-        (unless no-error
+          (bibtex-find-entry key)
+          (setq error (or (/= (point) start)
+                          (bibtex-find-entry key end))))
+        (if error
           (error "New inserted entry yields duplicate key"))))
     ;; final clean up
     (unless called-by-reformat
@@ -3583,7 +3630,7 @@ At end of the cleaning process, the functions in
         (save-restriction
           (bibtex-narrow-to-entry)
           ;; Only update the list of keys if it has been built already.
-          (cond ((equal entry-type "string")
+          (cond ((bibtex-string= entry-type "string")
                  (if (listp bibtex-strings) (bibtex-parse-strings t)))
                 ((listp bibtex-reference-keys) (bibtex-parse-keys t)))
           (run-hooks 'bibtex-clean-entry-hook))))))
@@ -3752,28 +3799,29 @@ entries from minibuffer."
 (defun bibtex-complete ()
   "Complete word fragment before point according to context.
 If point is inside key or crossref field perform key completion based on
-`bibtex-reference-keys'. Inside any other field perform string
-completion based on `bibtex-strings'. An error is signaled if point
-is outside key or BibTeX field."
+`bibtex-reference-keys'.  Inside a month field perform key completion
+based on `bibtex-predefined-month-strings'.  Inside any other field
+perform string completion based on `bibtex-strings'.  An error is
+signaled if point is outside key or BibTeX field."
   (interactive)
-  (let* ((pnt (point))
-         (case-fold-search t)
-         bounds compl)
+  (let ((pnt (point))
+        (case-fold-search t)
+        bounds name compl)
     (save-excursion
       (if (and (setq bounds (bibtex-enclosing-field t))
                (>= pnt (bibtex-start-of-text-in-field bounds))
                (<= pnt (bibtex-end-of-text-in-field bounds)))
-          (progn
-            (goto-char (bibtex-start-of-name-in-field bounds))
-            (setq compl (if (string= "crossref"
-                                     (downcase
-                                      (buffer-substring-no-properties
-                                       (if (looking-at "\\(OPT\\)\\|\\(ALT\\)")
-                                           (match-end 0)
-                                         (point))
-                                       (bibtex-end-of-name-in-field bounds))))
-                            'key
-                          'str)))
+          (setq name (bibtex-name-in-field bounds t)
+                compl (cond ((bibtex-string= name "crossref")
+                             'key)
+                            ((bibtex-string= name "month")
+                             bibtex-predefined-month-strings)
+                            (t (if (listp bibtex-strings)
+                                   bibtex-strings
+                                 ;; so that bibtex-complete-string-cleanup
+                                 ;; can do its job
+                                 (bibtex-parse-strings
+                                  (bibtex-string-files-init))))))
         (bibtex-beginning-of-entry)
         (if (and (re-search-forward bibtex-entry-maybe-empty-head nil t)
                  ;; point is inside a key
@@ -3789,24 +3837,23 @@ is outside key or BibTeX field."
            ;; key completion
            (setq choose-completion-string-functions
                  (lambda (choice buffer mini-p base-size)
-                   (bibtex-choose-completion-string choice buffer mini-p base-size)
-                   (if bibtex-complete-key-cleanup
-                       (funcall bibtex-complete-key-cleanup choice))
+                    (bibtex-choose-completion-string choice buffer mini-p base-size)
+                   (bibtex-complete-key-cleanup choice)
                    ;; return t (required by choose-completion-string-functions)
                    t))
-           (let ((choice (bibtex-complete-internal bibtex-reference-keys)))
-             (if bibtex-complete-key-cleanup
-                 (funcall bibtex-complete-key-cleanup choice))))
+           (bibtex-complete-key-cleanup (bibtex-complete-internal 
+                                         bibtex-reference-keys)))
 
-          ((equal compl 'str)
+          (compl
            ;; string completion
            (setq choose-completion-string-functions
-                 (lambda (choice buffer mini-p base-size)
+                 `(lambda (choice buffer mini-p base-size)
                    (bibtex-choose-completion-string choice buffer mini-p base-size)
-                   (bibtex-complete-string-cleanup choice)
+                   (bibtex-complete-string-cleanup choice ',compl)
                    ;; return t (required by choose-completion-string-functions)
                    t))
-           (bibtex-complete-string-cleanup (bibtex-complete-internal bibtex-strings)))
+           (bibtex-complete-string-cleanup (bibtex-complete-internal compl)
+                                           compl))
 
           (t (error "Point outside key or BibTeX field")))))
 
@@ -3880,8 +3927,8 @@ is outside key or BibTeX field."
   (interactive (list (completing-read "String key: " bibtex-strings
                                       nil nil nil 'bibtex-key-history)))
   (let ((bibtex-maintain-sorted-entries
-         (if (not bibtex-sort-ignore-string-entries)
-             bibtex-maintain-sorted-entries))
+         (unless bibtex-sort-ignore-string-entries
+           bibtex-maintain-sorted-entries))
         endpos)
     (unless (bibtex-prepare-new-entry (list key nil "String"))
       (error "Entry with key `%s' already exists" key))
@@ -3913,6 +3960,81 @@ is outside key or BibTeX field."
             "\n")
     (goto-char endpos)))
 
+(defun bibtex-url (&optional event)
+  "Browse a URL for the BibTeX entry at position PNT.
+The URL is generated using the schemes defined in `bibtex-generate-url-list'
+\(see there\).  Then the URL is passed to `browse-url'."
+  (interactive (list last-input-event))
+  (save-excursion
+    (if event (posn-set-point (event-end event)))
+    (bibtex-beginning-of-entry)
+    (let ((fields-alist (bibtex-parse-entry))
+          (case-fold-search t)
+          (lst bibtex-generate-url-list)
+          field url scheme)
+      (while (setq scheme (car lst))
+        (when (and (setq field (cdr (assoc-string (caar scheme)
+                                                 fields-alist t)))
+                  (progn
+                    (if (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" field)
+                        (setq field (match-string 1 field)))
+                    (string-match (cdar scheme) field)))
+         (setq lst nil)
+         (if (null (cdr scheme))
+             (setq url (match-string 0 field)))
+          (dolist (step (cdr scheme))
+           (cond ((stringp step)
+                  (setq url (concat url step)))
+                 ((setq field (assoc-string (car step) fields-alist t))
+                  ;; always remove field delimiters
+                  (let* ((text (if (string-match "\\`[{\"]\\(.*\\)[}\"]\\'" 
+                                                 (cdr field))
+                                   (match-string 1 (cdr field))
+                                 (cdr field)))
+                         (str (if (string-match (nth 1 step) text)
+                                  (cond
+                                   ((functionp (nth 2 step))
+                                    (funcall (nth 2 step) text))
+                                   ((numberp (nth 2 step))
+                                    (match-string (nth 2 step) text))
+                                   (t
+                                    (replace-match (nth 2 step) nil nil text)))
+                                ;; If the scheme is set up correctly,
+                                ;; we should never reach this point
+                                (error "Match failed: %s" text))))
+                     (setq url (concat url str))))
+                 ;; If the scheme is set up correctly,
+                 ;; we should never reach this point
+                 (t (error "Step failed: %s" step))))
+         (message "%s" url)
+          (browse-url url))
+        (setq lst (cdr lst)))
+    (unless url (message "No URL known.")))))
+
+(defun bibtex-font-lock-url (bound)
+  "Font-lock for URLs."
+  (let ((case-fold-search t)
+        (bounds (bibtex-enclosing-field t))
+        (pnt (point))
+       found field)
+    ;; We use start-of-field as syntax-begin
+    (goto-char (if bounds (bibtex-start-of-field bounds) pnt))
+    (while (and (not found)
+               (prog1 (re-search-forward bibtex-font-lock-url-regexp bound t)
+                 (setq field (match-string-no-properties 1)))
+               (setq bounds (bibtex-parse-field-text))
+               (>= bound (car bounds))
+               (>= (car bounds) pnt))
+      (let ((lst bibtex-generate-url-list) url)
+       (goto-char (car bounds))
+       (while (and (not found)
+                   (setq url (caar lst)))
+         (when (bibtex-string= field (car url))
+           (setq found (re-search-forward (cdr url) (cdr bounds) t)))
+         (setq lst (cdr lst))))
+      (goto-char (cdr bounds)))
+    found))
+
 \f
 ;; Make BibTeX a Feature
 
diff --git a/lisp/textmodes/dns-mode.el b/lisp/textmodes/dns-mode.el
new file mode 100644 (file)
index 0000000..400f872
--- /dev/null
@@ -0,0 +1,198 @@
+;;; dns-mode.el --- a mode for viewing/editing Domain Name System master files
+;; Copyright (c) 2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+
+;; Author: Simon Josefsson <simon@josefsson.org>
+;; Keywords: DNS master zone file SOA
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; Use M-x dns-mode RET to invoke in master files.
+;;
+;; C-c C-s  Increment SOA serial.
+;;          Understands YYYYMMDDNN, Unix time, and serial number formats,
+;;          and complains if it fail to find SOA serial.
+;;
+;; Put something similar to the following in your ~/.emacs to use this file:
+;;
+;; (load "~/path/to/dns-mode.el")
+;; (setq auto-mode-alist (cons '("\\.soa\\'" . dns-mode) auto-mode-alist))
+
+;;; References:
+
+;; RFC 1034, "DOMAIN NAMES - CONCEPTS AND FACILITIES", P. Mockapetris.
+;; RFC 1035, "DOMAIN NAMES - IMPLEMENTATION AND SPECIFICATION", P. Mockapetris.
+
+;;; Release history:
+
+;; 2004-09-11  Posted on gnu.emacs.sources.
+;; 2004-09-13  Ported to XEmacs.
+;; 2004-09-14  Installed in Emacs CVS.
+
+;;; Code:
+
+(defgroup dns-mode nil
+  "DNS master file mode configuration.")
+
+(defconst dns-mode-classes '("IN" "CS" "CH" "HS")
+  "List of strings with known DNS classes.")
+
+(defconst dns-mode-types '("A" "NS" "MD" "MF" "CNAME" "SOA" "MB" "MG" "MR"
+                          "NULL" "WKS" "PTR" "HINFO" "MINFO" "MX" "TXT"
+                          "RP" "AFSDB" "X25" "ISDN" "RT" "NSAP" "NSAP"
+                          "SIG" "KEY" "PX" "GPOS" "AAAA" "LOC" "NXT"
+                          "EID" "NIMLOC" "SRV" "ATMA" "NAPTR" "KX" "CERT"
+                          "A6" "DNAME" "SINK" "OPT" "APL" "DS" "SSHFP"
+                          "RRSIG" "NSEC" "DNSKEY" "UINFO" "UID" "GID"
+                          "UNSPEC" "TKEY" "TSIG" "IXFR" "AXFR" "MAILB"
+                          "MAILA")
+  "List of strings with known DNS types.")
+
+;; Font lock.
+
+(defvar dns-mode-control-entity-face 'font-lock-keyword-face
+  "Name of face used for control entities, e.g. $ORIGIN.")
+
+(defvar dns-mode-bad-control-entity-face 'font-lock-warning-face
+  "Name of face used for non-standard control entities, e.g. $FOO.")
+
+(defvar dns-mode-type-face 'font-lock-type-face
+  "Name of face used for DNS types, e.g., SOA.")
+
+(defvar dns-mode-class-face 'font-lock-constant-face
+  "Name of face used for DNS classes, e.g., IN.")
+
+(defcustom dns-mode-font-lock-keywords
+  `(("^$ORIGIN" 0 ,dns-mode-control-entity-face)
+    ("^$INCLUDE" 0 ,dns-mode-control-entity-face)
+    ("^$[a-z0-9A-Z]+" 0 ,dns-mode-bad-control-entity-face)
+    (,(regexp-opt dns-mode-classes) 0 ,dns-mode-class-face)
+    (,(regexp-opt dns-mode-types) 0 ,dns-mode-type-face))
+  "Font lock keywords used to highlight text in DNS master file mode."
+  :type 'sexp
+  :group 'dns-mode)
+
+;; Syntax table.
+
+(defvar dns-mode-syntax-table
+  (let ((table (make-syntax-table)))
+    (modify-syntax-entry ?\; "<   " table)
+    (modify-syntax-entry ?\n ">   " table)
+    table)
+  "Syntax table in use in DNS master file buffers.")
+
+;; Keymap.
+
+(defvar dns-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "\C-c\C-s" 'dns-mode-soa-increment-serial)
+    map)
+  "Keymap for DNS master file mode.")
+
+;; Menu.
+
+(defvar dns-mode-menu nil
+  "Menubar used in DNS master file mode.")
+
+(easy-menu-define dns-mode-menu dns-mode-map
+  "DNS Menu."
+  '("DNS"
+    ["Increment SOA serial" dns-mode-soa-increment-serial t]))
+
+;; Mode.
+
+;;;###autoload
+(define-derived-mode dns-mode text-mode "DNS"
+  "Major mode for viewing and editing DNS master files.
+This mode is inherited from text mode.  It add syntax
+highlighting, and some commands for handling DNS master files.
+Its keymap inherits from `text-mode' and it has the same
+variables for customizing indentation.  It has its own abbrev
+table and its own syntax table.
+
+Turning on DNS mode runs `dns-mode-hook'."
+  (set (make-local-variable 'comment-start) ";")
+  (set (make-local-variable 'comment-end) "")
+  (set (make-local-variable 'comment-start-skip) ";+ *")
+  (unless (featurep 'xemacs)
+    (set (make-local-variable 'font-lock-defaults)
+        '(dns-mode-font-lock-keywords nil nil ((?_ . "w")))))
+  (easy-menu-add dns-mode-menu dns-mode-map))
+
+;; Tools.
+
+;;;###autoload
+(defun dns-mode-soa-increment-serial ()
+  "Locate SOA record and increment the serial field."
+  (interactive)
+  (save-excursion
+    (goto-char (point-min))
+    (unless (re-search-forward
+            (concat "^\\(\\(\\([^ \t]+[ \t]+\\)?[^ \t]+"
+                    "[ \t]+\\)?[^ \t]+[ \t]+\\)?SOA") nil t)
+      (error "Cannot locate SOA record"))
+    (if (re-search-forward (concat "\\<\\("
+                                  ;; year
+                                  "\\(198\\|199\\|20[0-9]\\)[0-9]"
+                                  ;; month
+                                  "\\(0[0-9]\\|10\\|11\\|12\\)"
+                                  ;; day
+                                  "\\([012][0-9]\\|30\\|31\\)"
+                                  ;; counter
+                                  "\\([0-9]\\{1,3\\}\\)"
+                                  "\\)\\>")
+                          nil t)
+       ;; YYYYMMDDIII format, one to three I's.
+       (let* ((serial (match-string 1))
+              (counterstr (match-string 5))
+              (counter (string-to-number counterstr))
+              (now (format-time-string "%Y%m%d"))
+              (nowandoldserial (concat now counterstr)))
+         (if (string< serial nowandoldserial)
+             (let ((new (format "%s00" now)))
+               (replace-match new nil nil nil 1)
+               (message "Replaced old serial %s with %s" serial new))
+           (if (string= serial nowandoldserial)
+               (let ((new (format (format "%%s%%0%dd" (length counterstr))
+                                  now (1+ counter))))
+                 (replace-match new nil nil nil 1)
+                 (message "Replaced old serial %s with %s" serial new))
+             (error "Current SOA serial is in the future"))))
+      (if (re-search-forward "\\<\\([0-9]\\{9,10\\}\\)\\>" nil t)
+         ;; Unix time
+         (let* ((serial (match-string 1))
+                (new (format-time-string "%s")))
+           (if (not (string< serial new))
+               (error "Current SOA serial is in the future")
+             (replace-match new nil nil nil 1)
+             (message "Replaced old serial %s with %s" serial new)))
+       (if (re-search-forward "\\<\\([0-9]+\\)\\>" nil t)
+           ;; Just any serial number.
+           (let* ((serial (match-string 1))
+                  (new (format "%d" (1+ (string-to-number serial)))))
+             (replace-match new nil nil nil 1)
+             (message "Replaced old serial %s with %s" serial new))
+         (error "Cannot locate serial number in SOA record"))))))
+
+;;;###autoload(add-to-list 'auto-mode-alist '("\\.soa\\'" . dns-mode))
+
+(provide 'dns-mode)
+
+;; arch-tag: 6a179f0a-072f-49db-8b01-37b8f23998c0
+;;; dns-mode.el ends here
index c4c484a..e32fc47 100644 (file)
 (put 'Arch 'vc-functions nil)
 
 ;;;###autoload (defun vc-arch-registered (file)
-;;;###autoload   (let ((dir file))
-;;;###autoload     (while (and (stringp dir)
-;;;###autoload                 (not (equal
-;;;###autoload                       dir (setq dir (file-name-directory dir))))
-;;;###autoload                 dir)
-;;;###autoload       (setq dir (if (file-directory-p
-;;;###autoload                      (expand-file-name "{arch}" dir))
-;;;###autoload                     t (directory-file-name dir))))
-;;;###autoload     (if (eq dir t)
-;;;###autoload          (progn
-;;;###autoload           (load "vc-arch")
-;;;###autoload           (vc-arch-registered file)))))
+;;;###autoload   (if (vc-find-root file "{arch}/=tagging-method")
+;;;###autoload       (progn
+;;;###autoload         (load "vc-arch")
+;;;###autoload         (vc-arch-registered file))))
 
 (defun vc-arch-add-tagline ()
   "Add an `arch-tag' to the end of the current file."
@@ -186,18 +178,10 @@ Only the value `maybe' can be trusted :-(."
 (defun vc-arch-root (file)
   "Return the root directory of a Arch project, if any."
   (or (vc-file-getprop file 'arch-root)
-      (vc-file-setprop
-       file 'arch-root
-       (let ((root nil))
-        (while (not (or root
-                        (equal file (setq file (file-name-directory file)))
-                        (null file)))
-          ;; Check the =tagging-method, in case someone naively manually
-          ;; creates a {arch} directory somewhere.
-          (if (file-exists-p (expand-file-name "{arch}/=tagging-method" file))
-              (setq root file)
-            (setq file (directory-file-name file))))
-        root))))
+      (vc-file-setprop 
+       ;; Check the =tagging-method, in case someone naively manually
+       ;; creates a {arch} directory somewhere.
+       file 'arch-root (vc-find-root file "{arch}/=tagging-method"))))
 
 (defun vc-arch-register (file &optional rev comment)
   (if rev (error "Explicit initial revision not supported for Arch"))
index 3f5a46c..fef1431 100644 (file)
@@ -1,6 +1,6 @@
 ;;; vc-hooks.el --- resident support for version-control
 
-;; Copyright (C) 1992,93,94,95,96,98,99,2000,03,2004
+;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2003, 2004
 ;;           Free Software Foundation, Inc.
 
 ;; Author:     FSF (see vc.el for full credits)
@@ -52,6 +52,12 @@ BACKEND, use `vc-handled-backends'.")
 (defvar vc-header-alist ())
 (make-obsolete-variable 'vc-header-alist 'vc-BACKEND-header)
 
+(defvar vc-ignore-dir-regexp "\\`\\([\\/][\\/]\\|/net/\\|/afs/\\)\\'"
+ "Regexp matching directory names that are not under VC's control.
+The default regexp prevents fruitless and time-consuming attempts
+to determine the VC status in directories in which filenames are
+interpreted as hostnames.")
+
 (defcustom vc-handled-backends '(RCS CVS SVN SCCS Arch MCVS)
   ;; Arch and MCVS come last because they are per-tree rather than per-dir.
   "*List of version control backends for which VC will be used.
@@ -298,6 +304,20 @@ non-nil if FILE exists and its contents were successfully inserted."
     (set-buffer-modified-p nil)
     t))
 
+(defun vc-find-root (file witness)
+  "Find the root of a checked out project.
+The function walks up the directory tree from FILE looking for WITNESS.
+If WITNESS if not found, return nil, otherwise return the root."
+  (let ((root nil))
+    (while (not (or root
+                   (equal file (setq file (file-name-directory file)))
+                   (null file)
+                   (string-match vc-ignore-dir-regexp file)))
+      (if (file-exists-p (expand-file-name witness file))
+         (setq root file)
+       (setq file (directory-file-name file))))
+    root))
+
 ;; Access functions to file properties
 ;; (Properties should be _set_ using vc-file-setprop, but
 ;; _retrieved_ only through these functions, which decide
@@ -315,11 +335,13 @@ on the result of a previous call, use `vc-backend' instead.  If the
 file was previously registered under a certain backend, then that
 backend is tried first."
   (let (handler)
-    (if (boundp 'file-name-handler-alist)
-       (setq handler (find-file-name-handler file 'vc-registered)))
-    (if handler
-        ;; handler should set vc-backend and return t if registered
-       (funcall handler 'vc-registered file)
+    (cond
+     ((string-match vc-ignore-dir-regexp (file-name-directory file)) nil)
+     ((and (boundp 'file-name-handler-alist)
+          (setq handler (find-file-name-handler file 'vc-registered)))
+      ;; handler should set vc-backend and return t if registered
+      (funcall handler 'vc-registered file))
+     (t
       ;; There is no file name handler.
       ;; Try vc-BACKEND-registered for each handled BACKEND.
       (catch 'found
@@ -334,7 +356,7 @@ backend is tried first."
             (cons backend vc-handled-backends))))
         ;; File is not registered.
         (vc-file-setprop file 'vc-backend 'none)
-        nil))))
+        nil)))))
 
 (defun vc-backend (file)
   "Return the version control type of FILE, nil if it is not registered."
@@ -869,5 +891,5 @@ Used in `find-file-not-found-functions'."
 
 (provide 'vc-hooks)
 
-;;; arch-tag: 2e5a6fa7-1d30-48e2-8bd0-e3d335f04f32
+;; arch-tag: 2e5a6fa7-1d30-48e2-8bd0-e3d335f04f32
 ;;; vc-hooks.el ends here
index 5c0bac4..d2ac776 100644 (file)
@@ -1,6 +1,7 @@
 ;;; vc-mcvs.el --- VC backend for the Meta-CVS version-control system
 
-;; Copyright (C) 1995,98,99,2000,01,02,03,2004  Free Software Foundation, Inc.
+;; Copyright (C) 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004
+;;           Free Software Foundation, Inc.
 
 ;; Author:      FSF (see vc.el for full credits)
 ;; Maintainer:  Stefan Monnier <monnier@gnu.org>
@@ -114,32 +115,15 @@ This is only meaningful if you don't use the implicit checkout model
 ;;;
 
 ;;;###autoload (defun vc-mcvs-registered (file)
-;;;###autoload   (let ((dir file))
-;;;###autoload     (while (and (stringp dir)
-;;;###autoload                 (not (equal
-;;;###autoload                       dir (setq dir (file-name-directory dir))))
-;;;###autoload                 dir)
-;;;###autoload       (setq dir (if (file-directory-p
-;;;###autoload                      (expand-file-name "MCVS/CVS" dir))
-;;;###autoload                     t (directory-file-name dir))))
-;;;###autoload     (if (eq dir t)
-;;;###autoload          (progn
-;;;###autoload           (load "vc-mcvs")
-;;;###autoload           (vc-mcvs-registered file)))))
+;;;###autoload   (if (vc-find-root file "MCVS/CVS")
+;;;###autoload       (progn
+;;;###autoload         (load "vc-mcvs")
+;;;###autoload         (vc-mcvs-registered file))))
 
 (defun vc-mcvs-root (file)
   "Return the root directory of a Meta-CVS project, if any."
   (or (vc-file-getprop file 'mcvs-root)
-      (vc-file-setprop
-       file 'mcvs-root
-       (let ((root nil))
-        (while (not (or root
-                        (equal file (setq file (file-name-directory file)))
-                        (null file)))
-          (if (file-directory-p (expand-file-name "MCVS/CVS" file))
-              (setq root file)
-            (setq file (directory-file-name file))))
-        root))))
+      (vc-file-setprop file 'mcvs-root (vc-find-root file "MCVS/CVS"))))
 
 (defun vc-mcvs-read (file)
   (if (file-readable-p file)
@@ -608,5 +592,5 @@ and that it passes `vc-mcvs-global-switches' to it before FLAGS."
 
 (provide 'vc-mcvs)
 
-;;; arch-tag: a39c7c1c-5247-429d-88df-dd7187d2e704
+;; arch-tag: a39c7c1c-5247-429d-88df-dd7187d2e704
 ;;; vc-mcvs.el ends here
index 642f04a..986280c 100644 (file)
@@ -324,11 +324,11 @@ from `windmove-frame-edges' will be the list (0 0 180 75)."
   (let* ((frame (if window
                    (window-frame window)
                  (selected-frame)))
-        (top-left (window-inside-edges (frame-first-window frame)))
+        (top-left (window-edges (frame-first-window frame)))
         (x-min (nth 0 top-left))
         (y-min (nth 1 top-left))
-        (x-max (+ x-min (frame-width frame) -1)) ; 1- for last row & col
-        (y-max (+ x-max (frame-height frame) -1)))
+        (x-max (1- (frame-width frame))) ; 1- for last row & col
+        (y-max (1- (frame-height frame))))
     (list x-min y-min x-max y-max)))
 
 ;; it turns out that constraining is always a good thing, even when
@@ -406,7 +406,7 @@ Returns the wrapped coordinate."
 
 
 ;; `windmove-coordinates-of-position' is stolen and modified from the
-;; Emacs Lisp Reference Manual, section 27.2.5.  It seems to work
+;; Emacs 20 Lisp Reference Manual, section 27.2.5.  It seems to work
 ;; okay, although I am bothered by the fact that tab-offset (the cdr
 ;; of the next-to- last argument) is set to 0.  On the other hand, I
 ;; can't find a single usage of `compute-motion' anywhere that doesn't
@@ -418,28 +418,43 @@ Returns the wrapped coordinate."
 ;; the number that `window-width' gives, or continuation lines aren't
 ;; counted correctly.  I haven't seen anyone doing this before,
 ;; though.
-(defun windmove-coordinates-of-position (pos &optional window)
-  "Return the coordinates of position POS in window WINDOW.
+;;
+;; Now updated for Emacs 21, based on the Emacs 21 Lisp Reference
+;; Manual, section 30.2.5.  It is no longer necessary to subtract
+;; 1 for the usable width of the window.
+;; TODO: also handle minibuffer case, w/ `minibuffer-prompt-width'.
+(defun windmove-coordinates-of-position (pos)
+  "Return the coordinates of position POS in the current window.
 Return the window-based coodinates in a cons pair: (HPOS . VPOS),
 where HPOS and VPOS are the zero-based x and y components of the
-screen location of POS.  If WINDOW is nil, return the coordinates in
-the currently selected window.
+screen location of POS.
 As an example, if point is in the top left corner of a window, then
 the return value from `windmove-coordinates-of-position' is (0 . 0)
 regardless of the where point is in the buffer and where the window
 is placed in the frame."
-  (let* ((wind (if (null window) (selected-window) window))
-         (big-hairy-result (compute-motion
-                            (window-start)
-                            '(0 . 0)
-                            pos
-                            nil ; (window-width window-height)
-                            nil ; window-width
-                            (cons (window-hscroll)
-                                  0)    ; why zero?
-                            wind)))
-    (cons (nth 1 big-hairy-result)      ; hpos, not vpos as documented
-          (nth 2 big-hairy-result))))   ; vpos, not hpos as documented
+  (let ((big-hairy-result (compute-motion
+                           (window-start)
+                           '(0 . 0)
+                           pos
+                           nil ; (window-width window-height)
+                           nil ; window-width
+                           (cons (window-hscroll)
+                                 0)  ; why zero?
+                           (selected-window))))
+  (cons (nth 1 big-hairy-result)        ; hpos, not vpos as documented
+        (nth 2 big-hairy-result))))     ; vpos, not hpos as documented
+
+(defun windmove-coordinates-of-window-position (pos &optional window)
+  "Return the coordinates of position POS in WINDOW.
+Return the window-based coodinates in a cons pair: (HPOS . VPOS),
+where HPOS and VPOS are the zero-based x and y components of the
+screen location of POS.  If WINDOW is nil, return the coordinates in
+the currently selected window."
+  (if (null window)
+      (windmove-coordinates-of-position pos)
+    (save-selected-window
+      (select-window window)
+      (windmove-coordinates-of-position pos))))
 
 ;; This calculates the reference location in the current window: the
 ;; frame-based (x . y) of either point, the top-left, or the
@@ -467,8 +482,9 @@ supplied, if ARG is greater or smaller than zero, respectively."
        ((= effective-arg 0)
           (windmove-coord-add
              top-left
-             (windmove-coordinates-of-position (window-point window)
-                                               window)))))))
+             (windmove-coordinates-of-window-position
+              (window-point window)
+              window)))))))
 
 ;; This uses the reference location in the current window (calculated
 ;; by `windmove-reference-loc' above) to find a reference location
@@ -491,13 +507,13 @@ movement is relative to."
             (- (nth 1 edges)
                windmove-window-distance-delta))) ; (x, y0-d)
      ((eq dir 'right)
-      (cons (+ (nth 2 edges)
+      (cons (+ (1- (nth 2 edges))      ; -1 to get actual max x
                windmove-window-distance-delta)
-            (cdr refpoint)))            ; (x1+d, y)
-     ((eq dir 'down)
+            (cdr refpoint)))            ; (x1+d-1, y)
+     ((eq dir 'down)                   ; -1 to get actual max y
       (cons (car refpoint)
-            (+ (nth 3 edges)
-               windmove-window-distance-delta))) ; (x, y1+d)
+            (+ (1- (nth 3 edges))
+               windmove-window-distance-delta))) ; (x, y1+d-1)
      (t (error "Invalid direction of movement: %s" dir)))))
 
 (defun windmove-find-other-window (dir &optional arg window)
index 09d273e..75e8d3d 100644 (file)
@@ -1,3 +1,46 @@
+2004-09-13  Kim F. Storm  <storm@cua.dk>
+
+       * mini.texi (Repetition): Rename isearch-resume-enabled to
+       isearch-resume-in-command-history and change default to disabled.
+
+2004-09-10  Simon Josefsson  <jas@extundo.com>
+
+       * gnus.texi (IMAP): Add example.  Suggested and partially written
+       by Steinar Bang <sb@dod.no>.
+
+2004-09-10  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * gnus.texi (IMAP): add comments about imaps synonym to imap in
+       netrc syntax
+
+2004-09-10  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * gnus.texi (Spam ELisp Package Sequence of Events): some clarifications
+       (Spam ELisp Package Global Variables)
+       (Spam ELisp Package Global Variables): more clarifications
+
+2004-09-10  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * gnus.texi (Spam ELisp Package Filtering of Incoming Mail):
+       mention spam-split does not modify incoming mail
+
+2004-09-10  Teodor Zlatanov  <tzz@lifelogs.com>
+
+       * gnus.texi (Spam ELisp Package Sequence of Events): fix typo
+
+2004-09-10  Eli Zaretskii  <eliz@gnu.org>
+
+       * Makefile.in (../info/gnus, gnus.dvi): Depend on gnus-faq.texi
+
+2004-09-09  Kim F. Storm  <storm@cua.dk>
+
+       * kmacro.texi (Save Keyboard Macro): Replace `name-last-kbd-macro'
+       with new `kmacro-name-last-macro'.
+
+2004-09-09  Reiner Steib  <Reiner.Steib@gmx.de>
+
+       * makefile.w32-in (sieve, pgg): Use $(infodir).
+
 2004-09-08  Juri Linkov  <juri@jurta.org>
 
        * mini.texi (Minibuffer History): Add `history-delete-duplicates'.
index 47530d4..20cbf76 100644 (file)
@@ -188,25 +188,29 @@ forms.dvi: forms.texi
        $(ENVADD) $(TEXI2DVI) ${srcdir}/forms.texi
 
 # gnus/message/emacs-mime/sieve/pgg are part of Gnus:
-../info/gnus: gnus.texi
+../info/gnus: gnus.texi gnus-faq.texi
        cd $(srcdir); $(MAKEINFO) gnus.texi
-gnus.dvi: gnus.texi
+gnus.dvi: gnus.texi gnus-faq.texi
        sed -e '/@iflatex/,/@end iflatex/d' ${srcdir}/gnus.texi > gnustmp.texi
        $(ENVADD) $(TEXI2DVI) gnustmp.texi
        cp gnustmp.dvi $*.dvi
        rm gnustmp.*
+
 ../info/message: message.texi
        cd $(srcdir); $(MAKEINFO) message.texi
 message.dvi: message.texi
        $(ENVADD) $(TEXI2DVI) ${srcdir}/message.texi
+
 ../info/sieve: sieve.texi
        cd $(srcdir); $(MAKEINFO) sieve.texi
 sieve.dvi: sieve.texi
        $(ENVADD) $(TEXI2DVI) ${srcdir}/sieve.texi
+
 ../info/emacs-mime: emacs-mime.texi
        cd $(srcdir); $(MAKEINFO) emacs-mime.texi
 emacs-mime.dvi: emacs-mime.texi
        $(ENVADD) $(TEXI2DVI) ${srcdir}/emacs-mime.texi
+
 ../info/pgg: pgg.texi
        cd $(srcdir); $(MAKEINFO) pgg.texi
 pgg.dvi: pgg.texi
index 763fe0c..b435a34 100644 (file)
@@ -14011,8 +14011,8 @@ is run.  That's why @code{(widen)} needs to be called after
 @code{save-excursion} and @code{save-restriction} in the example
 above.  Also note that with the nnimap backend, message bodies will
 not be downloaded by default.  You need to set
-@code{nnimap-split-download-body} to t to do that (@pxref{Splitting in
-IMAP}).
+@code{nnimap-split-download-body} to @code{t} to do that
+(@pxref{Splitting in IMAP}).
 
 @item (! @var{func} @var{split})
 If the split is a list, and the first element is @code{!}, then
@@ -16209,7 +16209,17 @@ RFC 2060 for more information on valid strings.
 A file containing credentials used to log in on servers.  The format is
 (almost) the same as the @code{ftp} @file{~/.netrc} file.  See the
 variable @code{nntp-authinfo-file} for exact syntax; also see
-@ref{NNTP}.
+@ref{NNTP}.  An example of an .authinfo line for an IMAP server, is: 
+
+@example
+machine students.uio.no login larsi password geheimnis port imap
+@end example
+
+Note that it should be @code{port imap}, or @code{port 143}, if you
+use a @code{nnimap-stream} of @code{tls} or @code{ssl}, even if the
+actual port number used is port 993 for secured IMAP.  For
+convenience, Gnus will accept @code{port imaps} as a synonym of
+@code{port imap}.
 
 @item nnimap-need-unselect-to-notice-new-mail
 @vindex nnimap-need-unselect-to-notice-new-mail
@@ -22249,16 +22259,18 @@ server or when you sort through incoming mail.  If you get 200 spam
 messages per day from @samp{random-address@@vmadmin.com}, you block
 @samp{vmadmin.com}.  If you get 200 messages about @samp{VIAGRA}, you
 discard all messages with @samp{VIAGRA} in the message.  If you get
-lots of spam from China, for example, you try to filter all mail from
-Chinese IPs.
+lots of spam from Bulgaria, for example, you try to filter all mail
+from Bulgarian IPs.  
+
+This, unfortunately, is a great way to discard legitimate e-mail.  The
+risks of blocking a whole country (Bulgaria, Norway, Nigeria, China,
+etc.) or even a continent (Asia, Africa, Europe, etc.) from contacting
+you should be obvious, so don't do it if you have the choice.
 
-This, unfortunately, is a great way to discard legitimate e-mail.  For
-instance, the very informative and useful RISKS digest has been
-blocked by overzealous mail filters because it @strong{contained}
-words that were common in spam messages.  The risks of blocking a
-whole country from contacting you should also be obvious, so don't do
-it if you have the choice.  Nevertheless, in isolated cases, with
-great care, direct filtering of mail can be useful.
+In another instance, the very informative and useful RISKS digest has
+been blocked by overzealous mail filters because it @strong{contained}
+words that were common in spam messages.  Nevertheless, in isolated
+cases, with great care, direct filtering of mail can be useful.
 
 Another approach to filtering e-mail is the distributed spam
 processing, for instance DCC implements such a system.  In essence,
@@ -22435,8 +22447,8 @@ call the external tools during splitting.  Example fancy split method:
 
 Note that with the nnimap backend, message bodies will not be
 downloaded by default.  You need to set
-@code{nnimap-split-download-body} to t to do that (@pxref{Splitting in
-IMAP}).
+@code{nnimap-split-download-body} to @code{t} to do that
+(@pxref{Splitting in IMAP}).
 
 That is about it.  As some spam is likely to get through anyway, you
 might want to have a nifty function to call when you happen to read
@@ -22672,8 +22684,8 @@ any are set, and the processed mail is moved to the
 @code{ham-process-destination} or the @code{spam-process-destination}
 depending on the article's classification.  If the
 @code{ham-process-destination} or the @code{spam-process-destination},
-whichever is appropriate, are nil, the article is left in the current
-group.
+whichever is appropriate, are @code{nil}, the article is left in the
+current group.
 
 If a spam is found in any group (this can be changed to only non-spam
 groups with @code{spam-move-spam-nonspam-groups-only}), it is
@@ -22685,11 +22697,11 @@ You have to load the @code{gnus-registry.el} package and enable the
 @code{spam-log-to-registry} variable if you want spam to be processed
 no more than once.  Thus, spam is detected and processed everywhere,
 which is what most people want.  If the
-@code{spam-process-destination} is nil, the spam is marked as
+@code{spam-process-destination} is @code{nil}, the spam is marked as
 expired, which is usually the right thing to do.
 
-If spam can not be moved - because of a read-only backend such as NNTP,
-for example, it will be copied.
+If spam can not be moved---because of a read-only backend such as
+@acronym{NNTP}, for example, it will be copied.
 
 If a ham mail is found in a ham group, as determined by the
 @code{ham-marks} parameter, it is processed as ham by the active ham
@@ -22703,11 +22715,11 @@ no more than once.  Thus, ham is detected and processed only when
 necessary, which is what most people want.  More on this in
 @xref{Spam ELisp Package Configuration Examples}.
 
-If ham can not be moved - because of a read-only backend such as NNTP,
-for example, it will be copied.
+If ham can not be moved---because of a read-only backend such as
+@acronym{NNTP}, for example, it will be copied.
 
 If all this seems confusing, don't worry.  Soon it will be as natural
-as typing Lisp one-liners on a neural interface... err, sorry, that's
+as typing Lisp one-liners on a neural interface@dots{} err, sorry, that's
 50 years in the future yet.  Just trust us, it's not so bad.
 
 @node Spam ELisp Package Filtering of Incoming Mail
@@ -22728,6 +22740,8 @@ Note that the fancy split may be called @code{nnmail-split-fancy} or
 @code{nnimap-split-fancy}, depending on whether you use the nnmail or
 nnimap back ends to retrieve your mail.
 
+Also, @code{spam-split} will not modify incoming mail in any way.
+
 The @code{spam-split} function will process incoming mail and send the
 mail considered to be spam into the group name given by the variable
 @code{spam-split-group}.  By default that group name is @samp{spam},
@@ -22741,7 +22755,7 @@ actually give you the group
 work depending on your server's tolerance for strange group names.
 
 You can also give @code{spam-split} a parameter,
-e.g. @samp{'spam-use-regex-headers} or @samp{"maybe-spam"}.  Why is
+e.g. @code{spam-use-regex-headers} or @code{"maybe-spam"}.  Why is
 this useful?
 
 Take these split rules (with @code{spam-use-regex-headers} and
@@ -22751,7 +22765,7 @@ Take these split rules (with @code{spam-use-regex-headers} and
  nnimap-split-fancy '(|
                       (any "ding" "ding")
                       (: spam-split)
-                      ;; default mailbox
+                      ;; @r{default mailbox}
                       "mail")
 @end example
 
@@ -22767,14 +22781,15 @@ You can let SpamAssassin headers supersede ding rules, but all other
 regex-headers check) will be after the ding rule:
 
 @example
- nnimap-split-fancy '(|
-;;; all spam detected by spam-use-regex-headers goes to "regex-spam"
-                      (: spam-split "regex-spam" 'spam-use-regex-headers)
-                      (any "ding" "ding")
-;;; all other spam detected by spam-split goes to spam-split-group
-                      (: spam-split)
-                      ;; default mailbox
-                      "mail")
+nnimap-split-fancy
+      '(|
+        ;; @r{all spam detected by @code{spam-use-regex-headers} goes to @samp{regex-spam}}
+        (: spam-split "regex-spam" 'spam-use-regex-headers)
+        (any "ding" "ding")
+        ;; @r{all other spam detected by spam-split goes to @code{spam-split-group}}
+        (: spam-split)
+        ;; @r{default mailbox}
+        "mail")
 @end example
 
 This lets you invoke specific @code{spam-split} checks depending on
@@ -22827,7 +22842,7 @@ processors take mail known to be spam and process it so similar spam
 will be detected later.
 
 The format of the spam or ham processor entry used to be a symbol,
-but now it is a cons cell.  See the individual spam processor entries
+but now it is a @sc{cons} cell.  See the individual spam processor entries
 for more information.
 
 @vindex gnus-spam-newsgroup-contents
@@ -22905,18 +22920,16 @@ not done for @emph{unclassified} or @emph{ham} groups.  Also, any
 determined by either the @code{ham-process-destination} group
 parameter or a match in the @code{gnus-ham-process-destinations}
 variable, which is a list of regular expressions matched with group
-names (it's easiest to customize this variable with
-@code{customize-variable gnus-ham-process-destinations}).  Each
-newsgroup specification has the format (REGEXP PROCESSOR) in a
-standard Lisp list, if you prefer to customize the variable manually.
-The ultimate location is a group name or names.  If the
-@code{ham-process-destination} parameter is not set, ham articles are
-left in place.  If the
+names (it's easiest to customize this variable with @kbd{M-x
+customize-variable @key{RET} gnus-ham-process-destinations}).  Each
+group name list is a standard Lisp list, if you prefer to customize
+the variable manually.  If the @code{ham-process-destination}
+parameter is not set, ham articles are left in place.  If the
 @code{spam-mark-ham-unread-before-move-from-spam-group} parameter is
-set, the ham articles are marked as unread before being moved.  
+set, the ham articles are marked as unread before being moved.
 
-If ham can not be moved - because of a read-only backend such as NNTP,
-for example, it will be copied.
+If ham can not be moved---because of a read-only backend such as
+@acronym{NNTP}, for example, it will be copied.
 
 Note that you can use multiples destinations per group or regular
 expression!  This enables you to send your ham to a regular mail
@@ -22944,18 +22957,16 @@ When you leave a @emph{ham} or @emph{unclassified} group, all
 the @code{spam-process-destination} group parameter or a match in the
 @code{gnus-spam-process-destinations} variable, which is a list of
 regular expressions matched with group names (it's easiest to
-customize this variable with @code{customize-variable
-gnus-spam-process-destinations}).  Each newsgroup specification has
-the repeated format (REGEXP GROUP) and they are all in a standard Lisp
-list, if you prefer to customize the variable manually.  The ultimate
-location is a group name or names.  If the
+customize this variable with @kbd{M-x customize-variable @key{RET}
+gnus-spam-process-destinations}).  Each group name list is a standard
+Lisp list, if you prefer to customize the variable manually.  If the
 @code{spam-process-destination} parameter is not set, the spam
 articles are only expired.  The group name is fully qualified, meaning
 that if you see @samp{nntp:servername} before the group name in the
-group buffer then you need it here as well.  
+group buffer then you need it here as well.
 
-If spam can not be moved - because of a read-only backend such as NNTP,
-for example, it will be copied.
+If spam can not be moved---because of a read-only backend such as
+@acronym{NNTP}, for example, it will be copied.
 
 Note that you can use multiples destinations per group or regular
 expression!  This enables you to send your spam to multiple @emph{spam
@@ -22971,15 +22982,15 @@ entries, this won't work as well as it does without a limit.
 
 @vindex spam-mark-only-unseen-as-spam
 Set this variable if you want only unseen articles in spam groups to
-be marked as spam.  By default, it is set.  If you set it to nil,
-unread articles will also be marked as spam.
+be marked as spam.  By default, it is set.  If you set it to
+@code{nil}, unread articles will also be marked as spam.
 
 @vindex spam-mark-ham-unread-before-move-from-spam-group
 Set this variable if you want ham to be unmarked before it is moved
 out of the spam group.  This is very useful when you use something
-like the tick mark @samp{!} to mark ham - the article will be placed
-in your ham-process-destination, unmarked as if it came fresh from
-the mail server.
+like the tick mark @samp{!} to mark ham---the article will be placed
+in your @code{ham-process-destination}, unmarked as if it came fresh
+from the mail server.
 
 @vindex spam-autodetect-recheck-messages
 When autodetecting spam, this variable tells @code{spam.el} whether
@@ -22997,87 +23008,86 @@ spam.  It is recommended that you leave it off.
 
 From Ted Zlatanov <tzz@@lifelogs.com>.
 @example
-
-;; for gnus-registry-split-fancy-with-parent and spam autodetection
-;; see gnus-registry.el for more information
+;; @r{for @code{gnus-registry-split-fancy-with-parent} and spam autodetection}
+;; @r{see @file{gnus-registry.el} for more information}
 (gnus-registry-initialize)
 (spam-initialize)
 
-;; I like control-S for marking spam
+;; @r{I like @kbd{C-s} for marking spam}
 (define-key gnus-summary-mode-map "\C-s" 'gnus-summary-mark-as-spam)
 
 (setq
- spam-log-to-registry t ;; for spam autodetection
+ spam-log-to-registry t     ; @r{for spam autodetection}
  spam-use-BBDB t
- spam-use-regex-headers t               ; catch X-Spam-Flag (SpamAssassin)
- ;; all groups with "spam" in the name contain spam
- gnus-spam-newsgroup-contents '(("spam" gnus-group-spam-classification-spam))
- ;; see documentation for these
+ spam-use-regex-headers t   ; @r{catch X-Spam-Flag (SpamAssassin)}
+ ;; @r{all groups with @samp{spam} in the name contain spam}
+ gnus-spam-newsgroup-contents
+  '(("spam" gnus-group-spam-classification-spam))
+ ;; @r{see documentation for these}
  spam-move-spam-nonspam-groups-only nil
  spam-mark-only-unseen-as-spam t
  spam-mark-ham-unread-before-move-from-spam-group t
  nnimap-split-rule 'nnimap-split-fancy
- ;; understand what this does before you copy it to your own setup!
+ ;; @r{understand what this does before you copy it to your own setup!}
  nnimap-split-fancy '(|
-                      ;; trace references to parents and put in their group
+                      ;; @r{trace references to parents and put in their group}
                       (: gnus-registry-split-fancy-with-parent)
-                      ;; this will catch server-side SpamAssassin tags
+                      ;; @r{this will catch server-side SpamAssassin tags}
                       (: spam-split 'spam-use-regex-headers)
                       (any "ding" "ding")
-                      ;; note that spam by default will go to "spam"
+                      ;; @r{note that spam by default will go to @samp{spam}}
                       (: spam-split)
-                      ;; default mailbox
+                      ;; @r{default mailbox}
                       "mail"))
 
-;; my parameters, set with `G p'
+;; @r{my parameters, set with @kbd{G p}}
 
-;; all nnml groups, and all nnimap groups except
-;; "nnimap+mail.lifelogs.com:train" and
-;; "nnimap+mail.lifelogs.com:spam": any spam goes to nnimap training,
-;; because it must have been detected manually
+;; @r{all nnml groups, and all nnimap groups except}
+;; @r{@samp{nnimap+mail.lifelogs.com:train} and}
+;; @r{@samp{nnimap+mail.lifelogs.com:spam}: any spam goes to nnimap training,}
+;; @r{because it must have been detected manually}
 
 ((spam-process-destination . "nnimap+mail.lifelogs.com:train"))
 
-;; all NNTP groups
-;; autodetect spam with the blacklist and ham with the BBDB
+;; @r{all @acronym{NNTP} groups}
+;; @r{autodetect spam with the blacklist and ham with the BBDB}
 ((spam-autodetect-methods spam-use-blacklist spam-use-BBDB)
-;; send all spam to the training group
+;; @r{send all spam to the training group}
  (spam-process-destination . "nnimap+mail.lifelogs.com:train"))
 
-;; only some NNTP groups, where I want to autodetect spam
+;; @r{only some @acronym{NNTP} groups, where I want to autodetect spam}
 ((spam-autodetect . t))
 
-;; my nnimap "nnimap+mail.lifelogs.com:spam" group
+;; @r{my nnimap @samp{nnimap+mail.lifelogs.com:spam} group}
 
-;; this is a spam group
+;; @r{this is a spam group}
 ((spam-contents gnus-group-spam-classification-spam)
 
- ;; any spam (which happens when I enter for all unseen messages,
- ;; because of the gnus-spam-newsgroup-contents setting above), goes to
- ;; "nnimap+mail.lifelogs.com:train" unless I mark it as ham
+ ;; @r{any spam (which happens when I enter for all unseen messages,}
+ ;; @r{because of the @code{gnus-spam-newsgroup-contents} setting above), goes to}
+ ;; @r{@samp{nnimap+mail.lifelogs.com:train} unless I mark it as ham}
 
  (spam-process-destination "nnimap+mail.lifelogs.com:train")
 
- ;; any ham goes to my "nnimap+mail.lifelogs.com:mail" folder, but
- ;; also to my "nnimap+mail.lifelogs.com:trainham" folder for training
+ ;; @r{any ham goes to my @samp{nnimap+mail.lifelogs.com:mail} folder, but}
+ ;; @r{also to my @samp{nnimap+mail.lifelogs.com:trainham} folder for training}
 
  (ham-process-destination "nnimap+mail.lifelogs.com:mail" 
                           "nnimap+mail.lifelogs.com:trainham")
- ;; in this group, only '!' marks are ham
+ ;; @r{in this group, only @samp{!} marks are ham}
  (ham-marks
   (gnus-ticked-mark))
- ;; remembers senders in the blacklist on the way out - this is
- ;; definitely not needed, it just makes me feel better
+ ;; @r{remembers senders in the blacklist on the way out---this is}
+ ;; @r{definitely not needed, it just makes me feel better}
  (spam-process (gnus-group-spam-exit-processor-blacklist)))
 
-;; Later, on the IMAP server I use the "train" group for training
-;; SpamAssassin to recognize spam, and the "trainham" group for
-;; recognizing ham - but Gnus has nothing to do with it.
+;; @r{Later, on the @acronym{IMAP} server I use the @samp{train} group for training}
+;; @r{SpamAssassin to recognize spam, and the @samp{trainham} group fora}
+;; @r{recognizing ham---but Gnus has nothing to do with it.}
 
 @end example
 
 @subsubheading Using @file{spam.el} on an IMAP server with a statistical filter on the server
-
 From Reiner Steib <reiner.steib@@gmx.de>.
 
 My provider has set up bogofilter (in combination with @acronym{DCC}) on
@@ -23115,7 +23125,7 @@ Because of the @code{gnus-group-spam-classification-spam} entry, all
 messages are marked as spam (with @code{$}).  When I find a false
 positive, I mark the message with some other ham mark (@code{ham-marks},
 @ref{Spam ELisp Package Global Variables}).  On group exit, those
-messages are copied to both groups, @samp{INBOX} (were I want to have
+messages are copied to both groups, @samp{INBOX} (where I want to have
 the article) and @samp{training.ham} (for training bogofilter) and
 deleted from the @samp{spam.detected} folder.
 
@@ -23147,7 +23157,7 @@ groups as spam and reports the to Gmane at group exit:
     (spam-process (gnus-group-spam-exit-processor-report-gmane)))
 @end lisp
 
-Additionally, I use `(setq spam-report-gmane-use-article-number nil)'
+Additionally, I use @code{(setq spam-report-gmane-use-article-number nil)}
 because I don't read the groups directly from news.gmane.org, but
 through my local news server (leafnode).  I.e. the article numbers are
 not the same as on news.gmane.org, thus @code{spam-report.el} has to check
@@ -23702,7 +23712,7 @@ the same way, we promise.
 Add this symbol to a group's @code{spam-process} parameter by
 customizing the group parameter or the
 @code{gnus-spam-process-newsgroups} variable.  When this symbol is added
-to a grup's @code{spam-process} parameter, the ham-marked articles in
+to a group's @code{spam-process} parameter, the ham-marked articles in
 @emph{ham} groups will be sent to the SpamOracle as samples of ham
 messages.  Note that this ham processor has no effect in @emph{spam} or
 @emph{unclassified} groups.
@@ -23742,7 +23752,7 @@ incoming mail, provide the following:
 @enumerate
 
 @item
-code
+Code
 
 @lisp
 (defvar spam-use-blackbox nil
@@ -23750,32 +23760,34 @@ code
 @end lisp
 
 Add
-@example
-    (spam-use-blackbox   . spam-check-blackbox)
-@end example
+@lisp
+(spam-use-blackbox   . spam-check-blackbox)
+@end lisp
 to @code{spam-list-of-checks}.
 
 Add
-@example
-    (gnus-group-ham-exit-processor-blackbox     ham spam-use-blackbox)
-    (gnus-group-spam-exit-processor-blackbox    spam spam-use-blackbox)
-@end example
+@lisp
+(gnus-group-ham-exit-processor-blackbox  ham spam-use-blackbox)
+(gnus-group-spam-exit-processor-blackbox spam spam-use-blackbox)
+@end lisp
+
 to @code{spam-list-of-processors}.
 
 Add
-@example
-    (spam-use-blackbox  spam-blackbox-register-routine
-                 nil
-                 spam-blackbox-unregister-routine
-                 nil)
-@end example
+@lisp
+(spam-use-blackbox spam-blackbox-register-routine
+                   nil
+                   spam-blackbox-unregister-routine
+                   nil)
+@end lisp
+
 to @code{spam-registration-functions}.  Write the register/unregister
 routines using the bogofilter register/unregister routines as a
 start, or other restister/unregister routines more appropriate to
 Blackbox.
 
 @item
-functionality
+Functionality
 
 Write the @code{spam-check-blackbox} function.  It should return
 @samp{nil} or @code{spam-split-group}, observing the other
@@ -23794,7 +23806,7 @@ For processing spam and ham messages, provide the following:
 @enumerate
 
 @item
-code
+Code
 
 Note you don't have to provide a spam or a ham processor.  Only
 provide them if Blackbox supports spam or ham processing.
@@ -23819,18 +23831,18 @@ Only applicable to non-spam (unclassified and ham) groups.")
 Gnus parameters
 
 Add
-@example
-                   (const :tag "Spam: Blackbox"   (spam spam-use-blackbox))
-                   (const :tag "Ham: Blackbox"    (ham spam-use-blackbox))
-@end example
+@lisp
+(const :tag "Spam: Blackbox" (spam spam-use-blackbox))
+(const :tag "Ham: Blackbox"  (ham spam-use-blackbox))
+@end lisp
 to the @code{spam-process} group parameter in @code{gnus.el}.  Make
 sure you do it twice, once for the parameter and once for the
 variable customization.
 
 Add
-@example
-          (variable-item spam-use-blackbox)
-@end example
+@lisp
+(variable-item spam-use-blackbox)
+@end lisp
 to the @code{spam-autodetect-methods} group parameter in
 @code{gnus.el}.
 
index bad186f..c07602b 100644 (file)
@@ -62,7 +62,7 @@ When this point is reached during macro execution, ask for confirmation
 (@code{kbd-macro-query}).
 @item C-x C-k n
 Give a command name (for the duration of the session) to the most
-recently defined keyboard macro (@code{name-last-kbd-macro}).
+recently defined keyboard macro (@code{kmacro-name-last-macro}).
 @item C-x C-k b
 Bind the most recently defined keyboard macro to a key sequence (for
 the duration of the session) (@code{kmacro-bind-to-key}).
@@ -361,10 +361,10 @@ register as a counter, incrementing it on each repetition of the macro.
 @section Naming and Saving Keyboard Macros
 
 @cindex saving keyboard macros
-@findex name-last-kbd-macro
+@findex kmacro-name-last-macro
 @kindex C-x C-k n
   If you wish to save a keyboard macro for later use, you can give it
-a name using @kbd{C-x C-k n} (@code{name-last-kbd-macro}).
+a name using @kbd{C-x C-k n} (@code{kmacro-name-last-macro}).
 This reads a name as an argument using the minibuffer and defines that
 name to execute the last keyboard macro, in its current form.  (If you
 later add to the definition of this macro, that does not alter the
index b5f13d5..e7d98e6 100644 (file)
@@ -342,6 +342,9 @@ In HTML input files, the tags are the @code{title} and the @code{h1},
 @code{h2}, @code{h3} headers.  Also, tags are @code{name=} in anchors
 and all occurrences of @code{id=}.
 
+@item
+In Lua input files, all functions are tags.
+
 @item
 In makefiles, targets are tags; additionally, variables are tags
 unless you specify @samp{--no-globals}.
@@ -442,7 +445,8 @@ well as the files it directly contains.
 directory where the tags file was initially written.  This way, you can
 move an entire directory tree containing both the tags file and the
 source files, and the tags file will still refer correctly to the source
-files.
+files.  If the tags file is in @file{/dev}, however, the file names are
+made relative to the current working directory.
 
   If you specify absolute file names as arguments to @code{etags}, then
 the tags file will contain absolute file names.  This way, the tags file
index 1041164..09f314d 100644 (file)
@@ -198,19 +198,23 @@ gnus.dvi: gnus.texi
        $(ENVADD) $(TEXI2DVI) gnustmp.texi
        cp gnustmp.dvi $*.dvi
        rm gnustmp.*
+#
 $(infodir)/message: message.texi
        $(MAKEINFO) message.texi
 message.dvi: message.texi
        $(ENVADD) $(TEXI2DVI) $(srcdir)/message.texi
+#
 $(infodir)/emacs-mime: emacs-mime.texi
        $(MAKEINFO) emacs-mime.texi
 emacs-mime.dvi: emacs-mime.texi
        $(ENVADD) $(TEXI2DVI) $(srcdir)/emacs-mime.texi
-../info/sieve: sieve.texi
+#
+$(infodir)/sieve: sieve.texi
        $(MAKEINFO) sieve.texi
 sieve.dvi: sieve.texi
        $(ENVADD) $(TEXI2DVI) $(srcdir)/sieve.texi
-../info/pgg: pgg.texi
+#
+$(infodir)/pgg: pgg.texi
        $(MAKEINFO) pgg.texi
 pgg.dvi: pgg.texi
        $(ENVADD) $(TEXI2DVI) $(srcdir)/pgg.texi
index ec82c6d..9d0a7d5 100644 (file)
@@ -564,12 +564,13 @@ of saved entire commands.  After finding the desired previous command,
 you can edit its expression as usual and then resubmit it by typing
 @key{RET} as usual.
 
-@vindex isearch-resume-enabled
+@vindex isearch-resume-in-command-history
   Incremental search does not, strictly speaking, use the minibuffer,
-but it does something similar, so normally it is treated as a complex
-command and it appears in the history list for @kbd{C-x @key{ESC}
-@key{ESC}}.  You can disable that by setting
-@code{isearch-resume-enabled} to @code{nil}.
+but it does something similar.  Although it behaves like a complex command,
+it normally does not appear in the history list for @kbd{C-x
+@key{ESC} @key{ESC}}.  You can make it appear in the history by
+setting @code{isearch-resume-in-command-history} to a non-@code{nil}
+value.
 
 @vindex command-history
   The list of previous minibuffer-using commands is stored as a Lisp
index 6efe6f7..26fd77e 100644 (file)
@@ -279,6 +279,13 @@ respectively.
 ;; Authenticate using this username and password against my server.
 (setq smtpmail-auth-credentials
       '(("@var{hostname}" "@var{port}" "@var{username}" "@var{password}")))
+
+;; Note that if @var{port} is an integer, you must not quote it as a
+;; string.  Normally @var{port} should be the integer 25, and the example
+;; become:
+(setq smtpmail-auth-credentials
+      '(("@var{hostname}" 25 "@var{username}" "@var{password}")))
+
 ;; Use STARTTLS without authentication against the server.
 (setq smtpmail-starttls-credentials
       '(("@var{hostname}" "@var{port}" nil nil)))
index 5242693..955c892 100644 (file)
@@ -1,3 +1,85 @@
+2004-09-14  Stefan  <monnier@iro.umontreal.ca>
+
+       * fileio.c (Finsert_file_contents): Fix case of replacement in a
+       narrowed buffer.
+
+2004-09-14  Kim F. Storm  <storm@cua.dk>
+
+       * puresize.h (PURESIZE_RATIO): Define based on BITS_PER_EMACS_INT.
+
+       * xfaces.c (Qface_no_inherit): New var.
+       (syms_of_xfaces): Intern and staticpro it.
+       (Finternal_make_lisp_face, Finternal_set_lisp_face_attribute)
+       (Finternal_copy_lisp_face, update_face_from_frame_parameter):
+       Don't increment face_change_count when face has non-nil
+       face-no-inherit property.
+
+2004-09-13  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+       * bytecode.c (BYTE_CODE_QUIT): Add missing AFTER_POTENTIAL_GC.
+       (Fbyte_code): Remove dead code after `wrong_type_argument'.
+
+       * alloc.c (Fgarbage_collect): Mark keyboards, gtk data, and specpdl
+       before doing the mark_stack_check_gcpros since they are not on the stack.
+
+2004-09-12  Kim F. Storm  <storm@cua.dk>
+
+       * editfns.c (Fformat): Handle format strings with multiple text
+       properties.  Reverse text property list from the format string,
+       so the positions are in increasing order.
+
+2004-09-10  Jan Dj\e,Ad\e(Brv  <jan.h.d@swipnet.se>
+
+       * xselect.c (x_reply_selection_request): XSync and UNBLOCK before
+       x_uncatch_errors so that possible protocol errors are delivered.
+
+2004-09-10  Eli Zaretskii  <eliz@gnu.org>
+
+       * Makefile.in (msdos.o): Depend on buffer.h, commands.h, and
+       blockinput.h.
+       (dosfns.o): Depend on blockinput.h, window.h, dispextern.h,
+       charset.h, and coding.h
+       (w16select.o): Depend on buffer.h, charset.h, coding.h, and
+       composite.h.
+       (term.o): Depend on window.h and keymap.h.
+       (abbrev.o): Depend on syntax.h.
+       (callint.o): Depend on keymap.h.
+       (casefiddle.o): Depend on charset.h and keymap.h.
+       (category.o): Depend on keymap.h.
+       (coding.o): Depend on dispextern.h.
+       (cmds.o): Depend on keyboard.h and keymap.h.
+       (dispnew.o): Depend on indent.h and intervals.h.
+       (doc.o): Depend on keymap.h.
+       (editfns.o): Depend on frame.h.
+       (emacs.o): Depend on dispextern.h.
+       (fileio.o): Don't depend on ccl.h.
+       (filelock.o): Depend on charset.h and coding.h.
+       (frame.o): Depend on w32term.h and macterm.h.
+       (insdel.o): Depend on region-cache.h.
+       (keyboard.o): Depend on keymap.h, w32term.h, and macterm.h.
+       (minibuf.o): Depend on $(INTERVALS_SRC) and keymap.h.
+       (search.o): Depend on $(INTERVALS_SRC).
+       (syntax.o): Depend on keymap.h, regex.h, and $(INTERVALS_SRC).
+       (window.o): Depend on keymap.h, blockinput.h, $(INTERVALS_SRC),
+       xterm.h, w32term.h, and macterm.h.
+       (xdisp.o): Depend on keyboard.h, $(INTERVALS_SRC), xterm.h,
+       w32term.h, and macterm.h.
+       (xfaces.o): Depend on keyboard.h, $(INTERVALS_SRC),
+       region-cache.h, xterm.h, w32term.h, and macterm.h.
+       (bytecode.o): Depend on dispextern.h, frame.h, and xterm.h.
+       (data.o): Depend on frame.h.
+       (fns.o): Depend on keymap.h, xterm.h, and blockinput.h.
+       (print.o): Depend on termchar.h and $(INTERVALS_SRC).
+       (lread.o): Depend on $(INTERVALS_SRC), termhooks.h, and coding.h.
+       (intervals.o): Depend on keymap.h.
+
+       * msdos.c (msdos_set_cursor_shape, IT_display_cursor): Add
+       debugging print-out to termscript.
+
+2004-09-09  Richard M. Stallman  <rms@gnu.org>
+
+       * xdisp.c (decode_mode_spec): Use current buffer for most purposes.
+
 2004-09-08  Richard M. Stallman  <rms@gnu.org>
 
        * window.c (Fset_window_buffer): Doc fix.
 
 2002-02-15  Andreas Schwab  <schwab@suse.de>
 
-       * puresize.h (BASE_PURESIZE): Increase to 9/5.
+       * puresize.h (PURESIZE_RATIO): Increase to 9/5.
 
        * alloc.c (NSTATICS): Increase to 1280.
 
index 14a4a64..007c058 100644 (file)
@@ -1024,29 +1024,32 @@ alloca.o: alloca.c blockinput.h atimer.h
    and so rarely changed in ways that do require any.  */
 
 abbrev.o: abbrev.c buffer.h window.h dispextern.h commands.h character.h \
-       $(config_h)
+       syntax.h $(config_h)
 buffer.o: buffer.c buffer.h region-cache.h commands.h window.h \
    dispextern.h $(INTERVAL_SRC) blockinput.h atimer.h systime.h character.h \
    $(config_h)
-callint.o: callint.c window.h commands.h buffer.h \
+callint.o: callint.c window.h commands.h buffer.h keymap.h \
    keyboard.h dispextern.h $(config_h)
 callproc.o: callproc.c epaths.h buffer.h commands.h $(config_h) \
        process.h systty.h syssignal.h character.h coding.h ccl.h msdos.h \
-        composite.h
+        composite.h w32.h
 casefiddle.o: casefiddle.c syntax.h commands.h buffer.h character.h \
-   composite.h $(config_h)
+   composite.h \
+       charset.h keymap.h $(config_h)
 casetab.o: casetab.c buffer.h $(config_h)
-category.o: category.c category.h buffer.h charset.h character.h $(config_h)
+category.o: category.c category.h buffer.h charset.h keymap.h  \
+       character.h $(config_h)
 ccl.o: ccl.c ccl.h charset.h character.h coding.h $(config_h)
 character.o: character.c character.h buffer.h charset.h composite.h disptab.h \
    $(config.h)
 charset.o: charset.c charset.h character.h buffer.h coding.h composite.h \
    disptab.h $(config_h)
 chartab.o: charset.h character.h $(config.h)
-coding.o: coding.c coding.h ccl.h buffer.h character.h charset.h intervals.h composite.h window.h $(config_h)
+coding.o: coding.c coding.h ccl.h buffer.h character.h charset.h intervals.h composite.h \
+       window.h dispextern.h $(config_h)
 cm.o: cm.c cm.h termhooks.h $(config_h)
 cmds.o: cmds.c syntax.h buffer.h character.h commands.h window.h $(config_h) \
-       msdos.h dispextern.h
+       msdos.h dispextern.h keyboard.h keymap.h
 pre-crt0.o: pre-crt0.c
 ecrt0.o: ecrt0.c $(config_h)
        CRT0_COMPILE ${srcdir}/ecrt0.c
@@ -1054,25 +1057,26 @@ dired.o: dired.c commands.h buffer.h $(config_h) character.h charset.h \
    coding.h regex.h systime.h
 dispnew.o: dispnew.c  systty.h systime.h commands.h process.h frame.h \
    window.h buffer.h dispextern.h termchar.h termopts.h termhooks.h cm.h \
-   disptab.h \
+   disptab.h indent.h intervals.h \
    xterm.h blockinput.h atimer.h character.h msdos.h composite.h keyboard.h \
    $(config_h)
-doc.o: doc.c $(config_h) epaths.h buffer.h keyboard.h character.h
+doc.o: doc.c $(config_h) epaths.h buffer.h keyboard.h keymap.h character.h
 doprnt.o: doprnt.c character.h $(config_h)
-dosfns.o: buffer.h termchar.h termhooks.h frame.h msdos.h dosfns.h $(config_h)
+dosfns.o: buffer.h termchar.h termhooks.h frame.h blockinput.h window.h \
+   msdos.h dosfns.h dispextern.h charset.h coding.h $(config_h)
 editfns.o: editfns.c window.h buffer.h systime.h $(INTERVAL_SRC) character.h \
-   coding.h dispextern.h $(config_h)
+   coding.h dispextern.h frame.h $(config_h)
 emacs.o: emacs.c commands.h systty.h syssignal.h blockinput.h process.h \
    termhooks.h buffer.h atimer.h systime.h $(INTERVAL_SRC) $(config_h) \
-   window.h keyboard.h keymap.h
+   window.h dispextern.h keyboard.h keymap.h
 fileio.o: fileio.c window.h buffer.h systime.h $(INTERVAL_SRC) character.h \
-   coding.h ccl.h msdos.h dispextern.h $(config_h)
+   coding.h msdos.h dispextern.h $(config_h)
 filelock.o: filelock.c buffer.h character.h charset.h coding.h systime.h \
    epaths.h $(config_h)
 filemode.o: filemode.c  $(config_h)
 frame.o: frame.c xterm.h window.h frame.h termhooks.h commands.h keyboard.h \
    blockinput.h atimer.h systime.h buffer.h character.h fontset.h \
-   msdos.h dosfns.h dispextern.h $(config_h)
+   msdos.h dosfns.h dispextern.h w32term.h macterm.h $(config_h)
 fringe.o: fringe.c dispextern.h frame.h window.h buffer.h $(config_h)
 fontset.o: dispextern.h fontset.h fontset.c ccl.h buffer.h character.h \
    charset.h frame.h keyboard.h $(config_h)
@@ -1083,11 +1087,11 @@ indent.o: indent.c frame.h window.h indent.h buffer.h $(config_h) termchar.h \
    termopts.h disptab.h region-cache.h character.h category.h composite.h \
    dispextern.h keyboard.h
 insdel.o: insdel.c window.h buffer.h $(INTERVAL_SRC) blockinput.h character.h \
-   dispextern.h atimer.h systime.h $(config_h)
+   dispextern.h atimer.h systime.h region-cache.h $(config_h)
 keyboard.o: keyboard.c termchar.h termhooks.h termopts.h buffer.h character.h \
    commands.h frame.h window.h macros.h disptab.h keyboard.h syssignal.h \
    systty.h systime.h dispextern.h syntax.h $(INTERVAL_SRC) blockinput.h \
-   atimer.h xterm.h puresize.h msdos.h $(config_h)
+   atimer.h xterm.h puresize.h msdos.h keymap.h w32term.h macterm.h $(config_h)
 keymap.o: keymap.c buffer.h commands.h keyboard.h termhooks.h blockinput.h \
    atimer.h systime.h puresize.h character.h intervals.h $(config_h)
 lastfile.o: lastfile.c  $(config_h)
@@ -1100,11 +1104,11 @@ vm-limit.o: vm-limit.c mem-limits.h $(config_h)
 marker.o: marker.c buffer.h character.h $(config_h)
 md5.o: md5.c md5.h $(config_h)
 minibuf.o: minibuf.c syntax.h dispextern.h frame.h window.h keyboard.h \
-   buffer.h commands.h character.h msdos.h $(config_h)
+   buffer.h commands.h character.h msdos.h $(INTERVAL_SRC) keymap.h $(config_h)
 mktime.o: mktime.c $(config_h)
 msdos.o: msdos.c msdos.h dosfns.h systime.h termhooks.h dispextern.h frame.h \
    termopts.h termchar.h character.h coding.h ccl.h disptab.h window.h \
-   keyboard.h intervals.h $(config_h)
+   keyboard.h intervals.h buffer.h commands.h blockinput.h $(config_h)
 process.o: process.c process.h buffer.h window.h termhooks.h termopts.h \
    commands.h syssignal.h systime.h systty.h syswait.h frame.h dispextern.h \
    blockinput.h atimer.h charset.h coding.h ccl.h msdos.h composite.h \
@@ -1116,16 +1120,17 @@ scroll.o: scroll.c termchar.h dispextern.h frame.h msdos.h keyboard.h \
    $(config_h)
 search.o: search.c regex.h commands.h buffer.h region-cache.h syntax.h \
    blockinput.h atimer.h systime.h category.h character.h composite.h \
+   $(INTERVAL_SRC) \
    $(config_h)
 strftime.o: strftime.c $(config_h)
 syntax.o: syntax.c syntax.h buffer.h commands.h category.h character.h \
-   composite.h $(config_h)
+   composite.h keymap.h regex.h $(INTERVAL_SRC) $(config_h)
 sysdep.o: sysdep.c syssignal.h systty.h systime.h syswait.h blockinput.h \
    process.h dispextern.h termhooks.h termchar.h termopts.h \
    frame.h atimer.h window.h msdos.h dosfns.h keyboard.h  $(config_h)
 term.o: term.c termchar.h termhooks.h termopts.h $(config_h) cm.h frame.h \
    disptab.h dispextern.h keyboard.h character.h charset.h coding.h ccl.h \
-   msdos.h keymap.h
+   msdos.h window.h keymap.h
 termcap.o: termcap.c $(config_h)
 terminfo.o: terminfo.c $(config_h)
 tparam.o: tparam.c $(config_h)
@@ -1135,19 +1140,21 @@ undo.o: undo.c buffer.h commands.h $(config_h)
 UNEXEC_ALIAS=UNEXEC
 $(UNEXEC_ALIAS): UNEXEC_SRC $(config_h)
 w16select.o: w16select.c dispextern.h frame.h blockinput.h atimer.h systime.h \
-   msdos.h $(config_h)
+   msdos.h buffer.h charset.h coding.h composite.h $(config_h)
 widget.o: widget.c xterm.h frame.h dispextern.h widgetprv.h \
    $(srcdir)/../lwlib/lwlib.h $(config_h)
 window.o: window.c indent.h commands.h frame.h window.h buffer.h termchar.h \
    termhooks.h disptab.h keyboard.h dispextern.h msdos.h composite.h \
+   keymap.h blockinput.h $(INTERVAL_SRC) xterm.h w32term.h macterm.h $(config_h)
+xdisp.o: xdisp.c macros.h commands.h process.h indent.h buffer.h dispextern.h \
+   coding.h termchar.h frame.h window.h disptab.h termhooks.h character.h     \
+   charset.h keyboard.h $(INTERVAL_SRC) region-cache.h xterm.h w32term.h      \
+   macterm.h $(config_h) msdos.h composite.h fontset.h blockinput.h atimer.h  \
+   systime.h keymap.h
+xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h  \
+   window.h character.h charset.h msdos.h dosfns.h composite.h atimer.h        \
+   systime.h keyboard.h fontset.h w32term.h macterm.h $(INTERVAL_SRC)  \
    $(config_h)
-xdisp.o: xdisp.c macros.h commands.h process.h indent.h buffer.h dispextern.h coding.h \
-   termchar.h frame.h window.h disptab.h termhooks.h character.h charset.h \
-   $(config_h) msdos.h composite.h fontset.h blockinput.h atimer.h systime.h \
-   keymap.h region-cache.h
-xfaces.o: xfaces.c dispextern.h frame.h xterm.h buffer.h blockinput.h \
-   window.h character.h charset.h msdos.h dosfns.h composite.h atimer.h \
-   systime.h fontset.h $(config_h) $(INTERVAL_SRC)
 xfns.o: xfns.c buffer.h frame.h window.h keyboard.h xterm.h dispextern.h \
    $(srcdir)/../lwlib/lwlib.h blockinput.h atimer.h systime.h epaths.h \
    character.h charset.h coding.h gtkutil.h $(config_h) termhooks.h
@@ -1175,23 +1182,26 @@ atimer.o: atimer.c atimer.h systime.h $(config_h)
 alloc.o: alloc.c process.h frame.h window.h buffer.h  puresize.h syssignal.h keyboard.h \
  blockinput.h atimer.h systime.h character.h dispextern.h $(config_h) \
  $(INTERVAL_SRC)
-bytecode.o: bytecode.c buffer.h syntax.h character.h window.h $(config_h)
-data.o: data.c buffer.h puresize.h character.h syssignal.h keyboard.h \
+bytecode.o: bytecode.c buffer.h syntax.h character.h window.h dispextern.h \
+  frame.h xterm.h $(config_h)
+data.o: data.c buffer.h puresize.h character.h syssignal.h keyboard.h frame.h \
  $(config_h)
 eval.o: eval.c commands.h keyboard.h blockinput.h atimer.h systime.h \
   dispextern.h $(config_h)
 floatfns.o: floatfns.c $(config_h)
 fns.o: fns.c commands.h $(config_h) frame.h buffer.h character.h keyboard.h \
- frame.h window.h dispextern.h $(INTERVAL_SRC) coding.h md5.h
+ keymap.h frame.h window.h dispextern.h $(INTERVAL_SRC) coding.h md5.h \
+ blockinput.h xterm.h
 print.o: print.c process.h frame.h window.h buffer.h keyboard.h character.h \
-   $(config_h) dispextern.h msdos.h composite.h
+   $(config_h) dispextern.h termchar.h $(INTERVAL_SRC) msdos.h composite.h
 lread.o: lread.c commands.h keyboard.h buffer.h epaths.h character.h \
- charset.h $(config_h) termhooks.h coding.h msdos.h
+ charset.h $(config_h) $(INTERVAL_SRC) termhooks.h coding.h msdos.h
 
 /* Text properties support */
 textprop.o: textprop.c buffer.h window.h dispextern.h $(INTERVAL_SRC) \
        $(config_h)
-intervals.o: intervals.c buffer.h $(INTERVAL_SRC) keyboard.h puresize.h $(config_h)
+intervals.o: intervals.c buffer.h $(INTERVAL_SRC) keyboard.h puresize.h \
+       keymap.h $(config_h)
 composite.o: composite.c buffer.h  character.h $(INTERVAL_SRC) $(config_h)
 
 /* System-specific programs to be made.
index 567b8c7..4b31ec7 100644 (file)
@@ -1,6 +1,6 @@
 /* Storage allocation and gc for GNU Emacs Lisp interpreter.
-   Copyright (C) 1985,86,88,93,94,95,97,98,1999,2000,01,02,03,2004
-      Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1988, 1993, 1994, 1995, 1997, 1998, 1999,
+      2000, 2001, 2002, 2003, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -4411,6 +4411,20 @@ returns nil, because real GC can't be done.  */)
   for (i = 0; i < staticidx; i++)
     mark_object (*staticvec[i]);
 
+  for (bind = specpdl; bind != specpdl_ptr; bind++)
+    {
+      mark_object (bind->symbol);
+      mark_object (bind->old_value);
+    }
+  mark_kboards ();
+
+#ifdef USE_GTK
+  {
+    extern void xg_mark_data ();
+    xg_mark_data ();
+  }
+#endif
+
 #if (GC_MARK_STACK == GC_MAKE_GCPROS_NOOPS \
      || GC_MARK_STACK == GC_MARK_STACK_CHECK_GCPROS)
   mark_stack ();
@@ -4424,11 +4438,6 @@ returns nil, because real GC can't be done.  */)
 #endif
 
   mark_byte_stack ();
-  for (bind = specpdl; bind != specpdl_ptr; bind++)
-    {
-      mark_object (bind->symbol);
-      mark_object (bind->old_value);
-    }
   for (catch = catchlist; catch; catch = catch->next)
     {
       mark_object (catch->tag);
@@ -4440,19 +4449,11 @@ returns nil, because real GC can't be done.  */)
       mark_object (handler->var);
     }
   mark_backtrace ();
-  mark_kboards ();
 
 #if GC_MARK_STACK == GC_USE_GCPROS_CHECK_ZOMBIES
   mark_stack ();
 #endif
 
-#ifdef USE_GTK
-  {
-    extern void xg_mark_data ();
-    xg_mark_data ();
-  }
-#endif
-
   /* Everything is now marked, except for the things that require special
      finalization, i.e. the undo_list.
      Look thru every buffer's undo list
index b30a410..d130b3b 100644 (file)
@@ -1,5 +1,5 @@
 /* Execution of byte code produced by bytecomp.el.
-   Copyright (C) 1985, 1986, 1987, 1988, 1993, 2000, 2001, 2002, 2003
+   Copyright (C) 1985, 1986, 1987, 1988, 1993, 2000, 2001, 2002, 2003, 2004
    Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
@@ -387,6 +387,7 @@ unmark_byte_stack ()
        Vquit_flag = Qnil;                              \
         BEFORE_POTENTIAL_GC ();                                \
        Fsignal (Qquit, Qnil);                          \
+       AFTER_POTENTIAL_GC ();                          \
       }                                                        \
   } while (0)
 
@@ -539,9 +540,7 @@ If the third argument is incorrect, Emacs may crash.  */)
              TOP = Qnil;
            else
              {
-               BEFORE_POTENTIAL_GC ();
-               Fcar (wrong_type_argument (Qlistp, v1));
-               AFTER_POTENTIAL_GC ();
+               wrong_type_argument (Qlistp, v1);
              }
            break;
          }
@@ -574,9 +573,7 @@ If the third argument is incorrect, Emacs may crash.  */)
              TOP = Qnil;
            else
              {
-               BEFORE_POTENTIAL_GC ();
-               Fcdr (wrong_type_argument (Qlistp, v1));
-               AFTER_POTENTIAL_GC ();
+               wrong_type_argument (Qlistp, v1);
              }
            break;
          }
@@ -907,11 +904,7 @@ If the third argument is incorrect, Emacs may crash.  */)
                else if (!NILP (v1))
                  {
                    immediate_quit = 0;
-                   BEFORE_POTENTIAL_GC ();
-                   v1 = wrong_type_argument (Qlistp, v1);
-                   AFTER_POTENTIAL_GC ();
-                   immediate_quit = 1;
-                   op++;
+                   wrong_type_argument (Qlistp, v1);
                  }
              }
            immediate_quit = 0;
@@ -920,11 +913,7 @@ If the third argument is incorrect, Emacs may crash.  */)
            else if (NILP (v1))
              TOP = Qnil;
            else
-             {
-               BEFORE_POTENTIAL_GC ();
-               Fcar (wrong_type_argument (Qlistp, v1));
-               AFTER_POTENTIAL_GC ();
-             }
+             wrong_type_argument (Qlistp, v1);
            break;
          }
 
@@ -1561,11 +1550,7 @@ If the third argument is incorrect, Emacs may crash.  */)
                    else if (!NILP (v1))
                      {
                        immediate_quit = 0;
-                       BEFORE_POTENTIAL_GC ();
-                       v1 = wrong_type_argument (Qlistp, v1);
-                       AFTER_POTENTIAL_GC ();
-                       immediate_quit = 1;
-                       op++;
+                       wrong_type_argument (Qlistp, v1);
                      }
                  }
                immediate_quit = 0;
@@ -1574,11 +1559,7 @@ If the third argument is incorrect, Emacs may crash.  */)
                else if (NILP (v1))
                  TOP = Qnil;
                else
-                 {
-                   BEFORE_POTENTIAL_GC ();
-                   Fcar (wrong_type_argument (Qlistp, v1));
-                   AFTER_POTENTIAL_GC ();
-                 }
+                 wrong_type_argument (Qlistp, v1);
              }
            else
              {
index 7fdd559..49617f7 100644 (file)
@@ -3824,11 +3824,13 @@ usage: (format STRING &rest OBJECTS)  */)
 
          /* Adjust the bounds of each text property
             to the proper start and end in the output string.  */
-         /* We take advantage of the fact that the positions in PROPS
-            are in increasing order, so that we can do (effectively)
-            one scan through the position space of the format string.
 
-            BYTEPOS is the byte position in the format string,
+         /* Put the positions in PROPS in increasing order, so that
+            we can do (effectively) one scan through the position
+            space of the format string.  */
+         props = Fnreverse (props);
+
+         /* BYTEPOS is the byte position in the format string,
             POSITION is the untranslated char position in it,
             TRANSLATED is the translated char position in BUF,
             and ARGN is the number of the next arg we will come to.  */
index f3678ca..7c0490e 100644 (file)
@@ -1,6 +1,6 @@
 /* File IO for GNU Emacs.
-   Copyright (C) 1985,86,87,88,93,94,95,96,97,98,99,2000,01,03,2004
-     Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1996, 1997, 1998,
+     1999, 2000, 2001, 2003, 2004  Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -4304,7 +4304,7 @@ actually used.  */)
       /* Replace the chars that we need to replace,
         and update INSERTED to equal the number of bytes
         we are taking from the decoded string.  */
-      inserted -= (Z_BYTE - same_at_end) + (same_at_start - BEG_BYTE);
+      inserted -= (ZV_BYTE - same_at_end) + (same_at_start - BEGV_BYTE);
 
       if (same_at_end != same_at_start)
        {
index daa4199..0020be3 100644 (file)
@@ -752,6 +752,9 @@ msdos_set_cursor_shape (struct frame *f, int start_line, int width)
   if (f && f != SELECTED_FRAME())
     return;
 
+  if (termscript)
+    fprintf (termscript, "\nCURSOR SHAPE=(%d,%d)", start_line, width);
+
   /* The character cell size in scan lines is stored at 40:85 in the
      BIOS data area.  */
   max_line = _farpeekw (_dos_ds, 0x485) - 1;
@@ -851,10 +854,12 @@ IT_set_cursor_type (struct frame *f, Lisp_Object cursor_type)
        }
     }
   else
-    /* Treat anything unknown as "box cursor".  This includes nil, so
-       that a frame which doesn't specify a cursor type gets a box,
-       which is the default in Emacs.  */
-    msdos_set_cursor_shape (f, 0, BOX_CURSOR_WIDTH);
+    {
+      /* Treat anything unknown as "box cursor".  This includes nil, so
+        that a frame which doesn't specify a cursor type gets a box,
+        which is the default in Emacs.  */
+      msdos_set_cursor_shape (f, 0, BOX_CURSOR_WIDTH);
+    }
 }
 
 static void
@@ -1826,6 +1831,8 @@ static int cursor_cleared;
 static void
 IT_display_cursor (int on)
 {
+  if (termscript)
+    fprintf (termscript, "\nCURSOR %s", on ? "ON" : "OFF");
   if (on && cursor_cleared)
     {
       ScreenSetCursor (current_pos_Y, current_pos_X);
index 8088a37..054b2bc 100644 (file)
@@ -47,7 +47,7 @@ Boston, MA 02111-1307, USA.  */
 
 /* Increase BASE_PURESIZE by a ratio depending on the machine's word size.  */
 #ifndef PURESIZE_RATIO
-#if VALBITS + GCTYPEBITS + 1 > 32
+#if BITS_PER_EMACS_INT > 32
 #define PURESIZE_RATIO 9/5     /* Don't surround with `()'. */
 #else
 #define PURESIZE_RATIO 1
index 6f88827..a756b99 100644 (file)
@@ -16228,7 +16228,10 @@ decode_mode_spec_coding (coding_system, buf, eol_flag)
    generated by character C.  PRECISION >= 0 means don't return a
    string longer than that value.  FIELD_WIDTH > 0 means pad the
    string returned with spaces to that value.  Return 1 in *MULTIBYTE
-   if the result is multibyte text.  */
+   if the result is multibyte text.
+
+   Note we operate on the current buffer for most purposes,
+   the exception being w->base_line_pos.  */
 
 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
 
@@ -16242,7 +16245,7 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
   Lisp_Object obj;
   struct frame *f = XFRAME (WINDOW_FRAME (w));
   char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
-  struct buffer *b = XBUFFER (w->buffer);
+  struct buffer *b = current_buffer;
 
   obj = Qnil;
   *multibyte = 0;
@@ -16544,7 +16547,7 @@ decode_mode_spec (w, c, field_width, precision, multibyte)
 
     case 's':
       /* status of process */
-      obj = Fget_buffer_process (w->buffer);
+      obj = Fget_buffer_process (Fcurrent_buffer ());
       if (NILP (obj))
        return "no process";
 #ifdef subprocesses
index 6e8a64e..1936935 100644 (file)
@@ -389,6 +389,10 @@ Lisp_Object Qforeground_color, Qbackground_color;
 Lisp_Object Qface;
 extern Lisp_Object Qmouse_face;
 
+/* Property for basic faces which other faces cannot inherit.  */
+
+Lisp_Object Qface_no_inherit;
+
 /* Error symbol for wrong_type_argument in load_pixmap.  */
 
 Lisp_Object Qbitmap_spec_p;
@@ -3944,8 +3948,11 @@ Value is a vector of face attributes.  */)
      depend on the face, make sure they are all removed.  This is done
      by incrementing face_change_count.  The next call to
      init_iterator will then free realized faces.  */
-  ++face_change_count;
-  ++windows_or_buffers_changed;
+  if (NILP (Fget (face, Qface_no_inherit)))
+    {
+      ++face_change_count;
+      ++windows_or_buffers_changed;
+    }
 
   xassert (LFACEP (lface));
   check_lface (lface);
@@ -4020,8 +4027,11 @@ The value is TO.  */)
      depend on the face, make sure they are all removed.  This is done
      by incrementing face_change_count.  The next call to
      init_iterator will then free realized faces.  */
-  ++face_change_count;
-  ++windows_or_buffers_changed;
+  if (NILP (Fget (to, Qface_no_inherit)))
+    {
+      ++face_change_count;
+      ++windows_or_buffers_changed;
+    }
 
   return to;
 }
@@ -4385,6 +4395,7 @@ FRAME 0 means change the face on all frames, and change the default
      by incrementing face_change_count.  The next call to
      init_iterator will then free realized faces.  */
   if (!EQ (frame, Qt)
+      && NILP (Fget (face, Qface_no_inherit))
       && (EQ (attr, QCfont)
          || EQ (attr, QCfontset)
          || NILP (Fequal (old_value, value))))
@@ -4538,6 +4549,7 @@ update_face_from_frame_parameter (f, param, new_value)
      struct frame *f;
      Lisp_Object param, new_value;
 {
+  Lisp_Object face = Qnil;
   Lisp_Object lface;
 
   /* If there are no faces yet, give up.  This is the case when called
@@ -4546,17 +4558,10 @@ update_face_from_frame_parameter (f, param, new_value)
   if (NILP (f->face_alist))
     return;
 
-  /* Changing a named face means that all realized faces depending on
-     that face are invalid.  Since we cannot tell which realized faces
-     depend on the face, make sure they are all removed.  This is done
-     by incrementing face_change_count.  The next call to
-     init_iterator will then free realized faces.  */
-  ++face_change_count;
-  ++windows_or_buffers_changed;
-
   if (EQ (param, Qforeground_color))
     {
-      lface = lface_from_face_name (f, Qdefault, 1);
+      face = Qdefault;
+      lface = lface_from_face_name (f, face, 1);
       LFACE_FOREGROUND (lface) = (STRINGP (new_value)
                                  ? new_value : Qunspecified);
       realize_basic_faces (f);
@@ -4571,29 +4576,45 @@ update_face_from_frame_parameter (f, param, new_value)
       XSETFRAME (frame, f);
       call1 (Qframe_update_face_colors, frame);
 
-      lface = lface_from_face_name (f, Qdefault, 1);
+      face = Qdefault;
+      lface = lface_from_face_name (f, face, 1);
       LFACE_BACKGROUND (lface) = (STRINGP (new_value)
                                  ? new_value : Qunspecified);
       realize_basic_faces (f);
     }
-  if (EQ (param, Qborder_color))
+  else if (EQ (param, Qborder_color))
     {
-      lface = lface_from_face_name (f, Qborder, 1);
+      face = Qborder;
+      lface = lface_from_face_name (f, face, 1);
       LFACE_BACKGROUND (lface) = (STRINGP (new_value)
                                  ? new_value : Qunspecified);
     }
   else if (EQ (param, Qcursor_color))
     {
-      lface = lface_from_face_name (f, Qcursor, 1);
+      face = Qcursor;
+      lface = lface_from_face_name (f, face, 1);
       LFACE_BACKGROUND (lface) = (STRINGP (new_value)
                                  ? new_value : Qunspecified);
     }
   else if (EQ (param, Qmouse_color))
     {
-      lface = lface_from_face_name (f, Qmouse, 1);
+      face = Qmouse;
+      lface = lface_from_face_name (f, face, 1);
       LFACE_BACKGROUND (lface) = (STRINGP (new_value)
                                  ? new_value : Qunspecified);
     }
+
+  /* Changing a named face means that all realized faces depending on
+     that face are invalid.  Since we cannot tell which realized faces
+     depend on the face, make sure they are all removed.  This is done
+     by incrementing face_change_count.  The next call to
+     init_iterator will then free realized faces.  */
+  if (!NILP (face)
+      && NILP (Fget (face, Qface_no_inherit)))
+    {
+      ++face_change_count;
+      ++windows_or_buffers_changed;
+    }
 }
 
 
@@ -7951,6 +7972,8 @@ syms_of_xfaces ()
 {
   Qface = intern ("face");
   staticpro (&Qface);
+  Qface_no_inherit = intern ("face-no-inherit");
+  staticpro (&Qface_no_inherit);
   Qbitmap_spec_p = intern ("bitmap-spec-p");
   staticpro (&Qbitmap_spec_p);
   Qframe_update_face_colors = intern ("frame-update-face-colors");
index 5de1beb..1e3efd2 100644 (file)
@@ -744,7 +744,15 @@ x_reply_selection_request (event, format, data, size, type)
      refering to the deleted window, and we'll get a BadWindow error
      in XTread_socket when processing the events.  I don't have
      an idea how to fix that.  gerd, 2001-01-98.   */
-  XFlush (display);
+  /* 2004-09-10: XSync and UNBLOCK so that possible protocol errors are
+     delivered before uncatch errors.  */
+  XSync (display, False);
+  UNBLOCK_INPUT;
+
+  /* GTK queues events in addition to the queue in Xlib.  So we
+     UNBLOCK to enter the event loop and get possible errors delivered,
+     and then BLOCK again because x_uncatch_errors requires it.  */
+  BLOCK_INPUT;
   x_uncatch_errors (display, count);
   UNBLOCK_INPUT;
 }