aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/emacs/ChangeLog8
-rw-r--r--doc/emacs/custom.texi12
-rw-r--r--doc/emacs/maintaining.texi8
-rw-r--r--doc/lispref/ChangeLog17
-rw-r--r--doc/lispref/commands.texi4
-rw-r--r--doc/lispref/customize.texi4
-rw-r--r--doc/lispref/display.texi2
-rw-r--r--doc/lispref/elisp.texi17
-rw-r--r--doc/lispref/keymaps.texi10
-rw-r--r--doc/lispref/lists.texi140
-rw-r--r--doc/lispref/sequences.texi8
-rw-r--r--doc/lispref/symbols.texi300
-rw-r--r--doc/lispref/variables.texi1
-rw-r--r--doc/man/ChangeLog4
-rw-r--r--doc/man/etags.11
-rw-r--r--doc/misc/ChangeLog9
-rw-r--r--doc/misc/rcirc.texi2
-rw-r--r--doc/misc/tramp.texi27
-rw-r--r--etc/NEWS17
-rw-r--r--lib-src/ChangeLog7
-rw-r--r--lib-src/etags.c27
-rw-r--r--lisp/ChangeLog64
-rw-r--r--lisp/buff-menu.el59
-rw-r--r--lisp/calc/calc-forms.el146
-rw-r--r--lisp/calendar/diary-lib.el3
-rw-r--r--lisp/files.el17
-rw-r--r--lisp/gnus/ChangeLog9
-rw-r--r--lisp/gnus/gnus-sum.el4
-rw-r--r--lisp/gnus/gnus-sync.el17
-rw-r--r--lisp/info.el17
-rw-r--r--lisp/jka-cmpr-hook.el15
-rw-r--r--lisp/net/tramp-sh.el7
-rw-r--r--lisp/simple.el14
-rw-r--r--lisp/sort.el56
-rw-r--r--lisp/textmodes/ispell.el23
-rw-r--r--lisp/url/ChangeLog5
-rw-r--r--lisp/url/url-misc.el36
-rw-r--r--lisp/vc/vc.el17
-rw-r--r--msdos/ChangeLog5
-rw-r--r--msdos/sed1v2.inp6
-rw-r--r--src/ChangeLog134
-rw-r--r--src/alloc.c32
-rw-r--r--src/bytecode.c4
-rw-r--r--src/callproc.c255
-rw-r--r--src/casefiddle.c2
-rw-r--r--src/charset.c4
-rw-r--r--src/data.c8
-rw-r--r--src/doprnt.c5
-rw-r--r--src/editfns.c91
-rw-r--r--src/fileio.c2
-rw-r--r--src/gtkutil.c15
-rw-r--r--src/insdel.c21
-rw-r--r--src/lisp.h4
-rw-r--r--src/process.c151
-rw-r--r--src/process.h17
-rw-r--r--src/sysdep.c80
-rw-r--r--src/syswait.h7
-rw-r--r--src/textprop.c24
-rw-r--r--src/w32.c8
-rw-r--r--src/w32common.h2
-rw-r--r--src/w32fns.c5
-rw-r--r--src/w32proc.c28
-rw-r--r--src/xdisp.c29
-rw-r--r--src/xterm.c15
-rw-r--r--test/ChangeLog6
-rw-r--r--test/automated/ruby-mode-tests.el22
66 files changed, 1370 insertions, 746 deletions
diff --git a/doc/emacs/ChangeLog b/doc/emacs/ChangeLog
index fd543789751..ce56d3af1b0 100644
--- a/doc/emacs/ChangeLog
+++ b/doc/emacs/ChangeLog
@@ -1,3 +1,11 @@
12012-12-03 Chong Yidong <cyd@gnu.org>
2
3 * custom.texi (Init Rebinding): kbd is now a function (Bug#13052).
4
52012-12-02 Kevin Ryde <user42@zip.com.au>
6
7 * maintaining.texi (Tag Syntax): Mention (defvar foo) handling.
8
12012-12-01 Kevin Ryde <user42@zip.com.au> 92012-12-01 Kevin Ryde <user42@zip.com.au>
2 10
3 * maintaining.texi (Tag Syntax): Mention Perl's "use constant". 11 * maintaining.texi (Tag Syntax): Mention Perl's "use constant".
diff --git a/doc/emacs/custom.texi b/doc/emacs/custom.texi
index a614126dbc0..6ea1ad5535f 100644
--- a/doc/emacs/custom.texi
+++ b/doc/emacs/custom.texi
@@ -1648,7 +1648,7 @@ you can specify them in your initialization file by writing Lisp code.
1648 1648
1649@findex kbd 1649@findex kbd
1650 There are several ways to write a key binding using Lisp. The 1650 There are several ways to write a key binding using Lisp. The
1651simplest is to use the @code{kbd} macro, which converts a textual 1651simplest is to use the @code{kbd} function, which converts a textual
1652representation of a key sequence---similar to how we have written key 1652representation of a key sequence---similar to how we have written key
1653sequences in this manual---into a form that can be passed as an 1653sequences in this manual---into a form that can be passed as an
1654argument to @code{global-set-key}. For example, here's how to bind 1654argument to @code{global-set-key}. For example, here's how to bind
@@ -1676,11 +1676,11 @@ and mouse events:
1676(global-set-key (kbd "<mouse-2>") 'mouse-save-then-kill) 1676(global-set-key (kbd "<mouse-2>") 'mouse-save-then-kill)
1677@end example 1677@end example
1678 1678
1679 Instead of using the @code{kbd} macro, you can use a Lisp string or 1679 Instead of using @code{kbd}, you can use a Lisp string or vector to
1680vector to specify the key sequence. Using a string is simpler, but 1680specify the key sequence. Using a string is simpler, but only works
1681only works for @acronym{ASCII} characters and Meta-modified 1681for @acronym{ASCII} characters and Meta-modified @acronym{ASCII}
1682@acronym{ASCII} characters. For example, here's how to bind @kbd{C-x 1682characters. For example, here's how to bind @kbd{C-x M-l} to
1683M-l} to @code{make-symbolic-link} (@pxref{Misc File Ops}): 1683@code{make-symbolic-link} (@pxref{Misc File Ops}):
1684 1684
1685@example 1685@example
1686(global-set-key "\C-x\M-l" 'make-symbolic-link) 1686(global-set-key "\C-x\M-l" 'make-symbolic-link)
diff --git a/doc/emacs/maintaining.texi b/doc/emacs/maintaining.texi
index 06680a6b4e3..555409f6be6 100644
--- a/doc/emacs/maintaining.texi
+++ b/doc/emacs/maintaining.texi
@@ -1676,9 +1676,11 @@ specifies (using Bourne shell syntax) that the commands
1676 1676
1677@item 1677@item
1678In Lisp code, any function defined with @code{defun}, any variable 1678In Lisp code, any function defined with @code{defun}, any variable
1679defined with @code{defvar} or @code{defconst}, and in general the first 1679defined with @code{defvar} or @code{defconst}, and in general the
1680argument of any expression that starts with @samp{(def} in column zero is 1680first argument of any expression that starts with @samp{(def} in
1681a tag. 1681column zero is a tag. As an exception, expressions of the form
1682@code{(defvar @var{foo})} are treated as declarations, and are only
1683tagged if the @samp{--declarations} option is given.
1682 1684
1683@item 1685@item
1684In Scheme code, tags include anything defined with @code{def} or with a 1686In Scheme code, tags include anything defined with @code{def} or with a
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index a0710723ea2..d15a05fe777 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,20 @@
12012-12-03 Chong Yidong <cyd@gnu.org>
2
3 * symbols.texi (Symbol Properties): New node.
4 (Symbol Plists): Make it a subsection under Symbol Properties.
5 (Standard Properties): New node.
6
7 * lists.texi (Property Lists): Move here from symbols.texi.
8 (Plist Access): Rename from Other Plists.
9
10 * customize.texi (Variable Definitions):
11 * display.texi (Defining Faces):
12 * sequences.texi (Char-Tables): Fix xref.
13
14 * keymaps.texi (Key Sequences): kbd is now a function.
15
16 * commands.texi (Using Interactive): Fix index entry.
17
12012-11-24 Paul Eggert <eggert@cs.ucla.edu> 182012-11-24 Paul Eggert <eggert@cs.ucla.edu>
2 19
3 * doclicense.texi: Update to latest version from FSF. 20 * doclicense.texi: Update to latest version from FSF.
diff --git a/doc/lispref/commands.texi b/doc/lispref/commands.texi
index c42e4b3b6dc..8806c933bf3 100644
--- a/doc/lispref/commands.texi
+++ b/doc/lispref/commands.texi
@@ -141,10 +141,10 @@ A command may be called from Lisp programs like any other function, but
141then the caller supplies the arguments and @var{arg-descriptor} has no 141then the caller supplies the arguments and @var{arg-descriptor} has no
142effect. 142effect.
143 143
144@cindex @code{interactive-form}, function property 144@cindex @code{interactive-form}, symbol property
145The @code{interactive} form must be located at top-level in the 145The @code{interactive} form must be located at top-level in the
146function body, or in the function symbol's @code{interactive-form} 146function body, or in the function symbol's @code{interactive-form}
147property (@pxref{Symbol Plists}). It has its effect because the 147property (@pxref{Symbol Properties}). It has its effect because the
148command loop looks for it before calling the function 148command loop looks for it before calling the function
149(@pxref{Interactive Call}). Once the function is called, all its body 149(@pxref{Interactive Call}). Once the function is called, all its body
150forms are executed; at this time, if the @code{interactive} form 150forms are executed; at this time, if the @code{interactive} form
diff --git a/doc/lispref/customize.texi b/doc/lispref/customize.texi
index c9d22851ed2..d85361499ba 100644
--- a/doc/lispref/customize.texi
+++ b/doc/lispref/customize.texi
@@ -472,8 +472,8 @@ Internally, @code{defcustom} uses the symbol property
472@code{saved-value} to record the value saved by the user with the 472@code{saved-value} to record the value saved by the user with the
473customization buffer, and @code{customized-value} to record the value 473customization buffer, and @code{customized-value} to record the value
474set by the user with the customization buffer, but not saved. 474set by the user with the customization buffer, but not saved.
475@xref{Property Lists}. These properties are lists, the car of which 475@xref{Symbol Properties}. These properties are lists, the car of
476is an expression that evaluates to the value. 476which is an expression that evaluates to the value.
477 477
478@defun custom-reevaluate-setting symbol 478@defun custom-reevaluate-setting symbol
479This function re-evaluates the standard value of @var{symbol}, which 479This function re-evaluates the standard value of @var{symbol}, which
diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 5148c6ec22e..f1b2074f457 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -2287,7 +2287,7 @@ terminal must match one of the @var{value}s specified for it in
2287@end example 2287@end example
2288 2288
2289 Internally, Emacs stores the face's default specification in its 2289 Internally, Emacs stores the face's default specification in its
2290@code{face-defface-spec} symbol property (@pxref{Property Lists}). 2290@code{face-defface-spec} symbol property (@pxref{Symbol Properties}).
2291The @code{saved-face} property stores the face specification saved by 2291The @code{saved-face} property stores the face specification saved by
2292the user, using the customization buffer; the @code{customized-face} 2292the user, using the customization buffer; the @code{customized-face}
2293property stores the face specification customized for the current 2293property stores the face specification customized for the current
diff --git a/doc/lispref/elisp.texi b/doc/lispref/elisp.texi
index 371593f7203..3980f7ac868 100644
--- a/doc/lispref/elisp.texi
+++ b/doc/lispref/elisp.texi
@@ -378,6 +378,7 @@ Lists
378* Modifying Lists:: Storing new pieces into an existing list. 378* Modifying Lists:: Storing new pieces into an existing list.
379* Sets And Lists:: A list can represent a finite mathematical set. 379* Sets And Lists:: A list can represent a finite mathematical set.
380* Association Lists:: A list can represent a finite relation or mapping. 380* Association Lists:: A list can represent a finite relation or mapping.
381* Property Lists:: A list of paired elements.
381 382
382Modifying Existing List Structure 383Modifying Existing List Structure
383 384
@@ -386,6 +387,12 @@ Modifying Existing List Structure
386 This can be used to remove or add elements. 387 This can be used to remove or add elements.
387* Rearrangement:: Reordering the elements in a list; combining lists. 388* Rearrangement:: Reordering the elements in a list; combining lists.
388 389
390Property Lists
391
392* Plists and Alists:: Comparison of the advantages of property
393 lists and association lists.
394* Plist Access:: Accessing property lists stored elsewhere.
395
389Sequences, Arrays, and Vectors 396Sequences, Arrays, and Vectors
390 397
391* Sequence Functions:: Functions that accept any kind of sequence. 398* Sequence Functions:: Functions that accept any kind of sequence.
@@ -410,15 +417,13 @@ Symbols
410 and property lists. 417 and property lists.
411* Definitions:: A definition says how a symbol will be used. 418* Definitions:: A definition says how a symbol will be used.
412* Creating Symbols:: How symbols are kept unique. 419* Creating Symbols:: How symbols are kept unique.
413* Property Lists:: Each symbol has a property list 420* Symbol Properties:: Each symbol has a property list
414 for recording miscellaneous information. 421 for recording miscellaneous information.
415 422
416Property Lists 423Symbol Properties
417 424
418* Plists and Alists:: Comparison of the advantages of property 425* Symbol Plists:: Accessing symbol properties.
419 lists and association lists. 426* Standard Properties:: Standard meanings of symbol properties.
420* Symbol Plists:: Functions to access symbols' property lists.
421* Other Plists:: Accessing property lists stored elsewhere.
422 427
423Evaluation 428Evaluation
424 429
diff --git a/doc/lispref/keymaps.texi b/doc/lispref/keymaps.texi
index d01ecba4bed..d9eddcee669 100644
--- a/doc/lispref/keymaps.texi
+++ b/doc/lispref/keymaps.texi
@@ -75,8 +75,8 @@ the vector @code{[?\C-x ?l]} represents the key sequence @kbd{C-x l}.
75 For examples of key sequences written in string and vector 75 For examples of key sequences written in string and vector
76representations, @ref{Init Rebinding,,, emacs, The GNU Emacs Manual}. 76representations, @ref{Init Rebinding,,, emacs, The GNU Emacs Manual}.
77 77
78@defmac kbd keyseq-text 78@defun kbd keyseq-text
79This macro converts the text @var{keyseq-text} (a string constant) 79This function converts the text @var{keyseq-text} (a string constant)
80into a key sequence (a string or vector constant). The contents of 80into a key sequence (a string or vector constant). The contents of
81@var{keyseq-text} should use the same syntax as in the buffer invoked 81@var{keyseq-text} should use the same syntax as in the buffer invoked
82by the @kbd{C-x C-k @key{RET}} (@code{kmacro-edit-macro}) command; in 82by the @kbd{C-x C-k @key{RET}} (@code{kmacro-edit-macro}) command; in
@@ -97,7 +97,7 @@ Manual}.
97 97
98This macro is not meant for use with arguments that vary---only 98This macro is not meant for use with arguments that vary---only
99with string constants. 99with string constants.
100@end defmac 100@end defun
101 101
102@node Keymap Basics 102@node Keymap Basics
103@section Keymap Basics 103@section Keymap Basics
@@ -1294,8 +1294,8 @@ numeric codes for the modifier bits don't appear in compiled files.
1294 The functions below signal an error if @var{keymap} is not a keymap, 1294 The functions below signal an error if @var{keymap} is not a keymap,
1295or if @var{key} is not a string or vector representing a key sequence. 1295or if @var{key} is not a string or vector representing a key sequence.
1296You can use event types (symbols) as shorthand for events that are 1296You can use event types (symbols) as shorthand for events that are
1297lists. The @code{kbd} macro (@pxref{Key Sequences}) is a convenient 1297lists. The @code{kbd} function (@pxref{Key Sequences}) is a
1298way to specify the key sequence. 1298convenient way to specify the key sequence.
1299 1299
1300@defun define-key keymap key binding 1300@defun define-key keymap key binding
1301This function sets the binding for @var{key} in @var{keymap}. (If 1301This function sets the binding for @var{key} in @var{keymap}. (If
diff --git a/doc/lispref/lists.texi b/doc/lispref/lists.texi
index 40e8d08f72c..1a3d85b9b35 100644
--- a/doc/lispref/lists.texi
+++ b/doc/lispref/lists.texi
@@ -22,6 +22,7 @@ the whole list.
22* Modifying Lists:: Storing new pieces into an existing list. 22* Modifying Lists:: Storing new pieces into an existing list.
23* Sets And Lists:: A list can represent a finite mathematical set. 23* Sets And Lists:: A list can represent a finite mathematical set.
24* Association Lists:: A list can represent a finite relation or mapping. 24* Association Lists:: A list can represent a finite relation or mapping.
25* Property Lists:: A list of paired elements.
25@end menu 26@end menu
26 27
27@node Cons Cells 28@node Cons Cells
@@ -1821,3 +1822,142 @@ often modifies the original list structure of @var{alist}.
1821compares the @sc{cdr} of each @var{alist} association instead of the 1822compares the @sc{cdr} of each @var{alist} association instead of the
1822@sc{car}. 1823@sc{car}.
1823@end defun 1824@end defun
1825
1826@node Property Lists
1827@section Property Lists
1828@cindex property list
1829@cindex plist
1830
1831 A @dfn{property list} (@dfn{plist} for short) is a list of paired
1832elements. Each of the pairs associates a property name (usually a
1833symbol) with a property or value. Here is an example of a property
1834list:
1835
1836@example
1837(pine cones numbers (1 2 3) color "blue")
1838@end example
1839
1840@noindent
1841This property list associates @code{pine} with @code{cones},
1842@code{numbers} with @code{(1 2 3)}, and @code{color} with
1843@code{"blue"}. The property names and values can be any Lisp objects,
1844but the names are usually symbols (as they are in this example).
1845
1846 Property lists are used in several contexts. For instance, the
1847function @code{put-text-property} takes an argument which is a
1848property list, specifying text properties and associated values which
1849are to be applied to text in a string or buffer. @xref{Text
1850Properties}.
1851
1852 Another prominent use of property lists is for storing symbol
1853properties. Every symbol possesses a list of properties, used to
1854record miscellaneous information about the symbol; these properties
1855are stored in the form of a property list. @xref{Symbol Properties}.
1856
1857@menu
1858* Plists and Alists:: Comparison of the advantages of property
1859 lists and association lists.
1860* Plist Access:: Accessing property lists stored elsewhere.
1861@end menu
1862
1863@node Plists and Alists
1864@subsection Property Lists and Association Lists
1865@cindex plist vs. alist
1866@cindex alist vs. plist
1867
1868@cindex property lists vs association lists
1869 Association lists (@pxref{Association Lists}) are very similar to
1870property lists. In contrast to association lists, the order of the
1871pairs in the property list is not significant, since the property
1872names must be distinct.
1873
1874 Property lists are better than association lists for attaching
1875information to various Lisp function names or variables. If your
1876program keeps all such information in one association list, it will
1877typically need to search that entire list each time it checks for an
1878association for a particular Lisp function name or variable, which
1879could be slow. By contrast, if you keep the same information in the
1880property lists of the function names or variables themselves, each
1881search will scan only the length of one property list, which is
1882usually short. This is why the documentation for a variable is
1883recorded in a property named @code{variable-documentation}. The byte
1884compiler likewise uses properties to record those functions needing
1885special treatment.
1886
1887 However, association lists have their own advantages. Depending on
1888your application, it may be faster to add an association to the front of
1889an association list than to update a property. All properties for a
1890symbol are stored in the same property list, so there is a possibility
1891of a conflict between different uses of a property name. (For this
1892reason, it is a good idea to choose property names that are probably
1893unique, such as by beginning the property name with the program's usual
1894name-prefix for variables and functions.) An association list may be
1895used like a stack where associations are pushed on the front of the list
1896and later discarded; this is not possible with a property list.
1897
1898@node Plist Access
1899@subsection Property Lists Outside Symbols
1900
1901 The following functions can be used to manipulate property lists.
1902They all compare property names using @code{eq}.
1903
1904@defun plist-get plist property
1905This returns the value of the @var{property} property stored in the
1906property list @var{plist}. It accepts a malformed @var{plist}
1907argument. If @var{property} is not found in the @var{plist}, it
1908returns @code{nil}. For example,
1909
1910@example
1911(plist-get '(foo 4) 'foo)
1912 @result{} 4
1913(plist-get '(foo 4 bad) 'foo)
1914 @result{} 4
1915(plist-get '(foo 4 bad) 'bad)
1916 @result{} nil
1917(plist-get '(foo 4 bad) 'bar)
1918 @result{} nil
1919@end example
1920@end defun
1921
1922@defun plist-put plist property value
1923This stores @var{value} as the value of the @var{property} property in
1924the property list @var{plist}. It may modify @var{plist} destructively,
1925or it may construct a new list structure without altering the old. The
1926function returns the modified property list, so you can store that back
1927in the place where you got @var{plist}. For example,
1928
1929@example
1930(setq my-plist '(bar t foo 4))
1931 @result{} (bar t foo 4)
1932(setq my-plist (plist-put my-plist 'foo 69))
1933 @result{} (bar t foo 69)
1934(setq my-plist (plist-put my-plist 'quux '(a)))
1935 @result{} (bar t foo 69 quux (a))
1936@end example
1937@end defun
1938
1939 You could define @code{put} in terms of @code{plist-put} as follows:
1940
1941@example
1942(defun put (symbol prop value)
1943 (setplist symbol
1944 (plist-put (symbol-plist symbol) prop value)))
1945@end example
1946
1947@defun lax-plist-get plist property
1948Like @code{plist-get} except that it compares properties
1949using @code{equal} instead of @code{eq}.
1950@end defun
1951
1952@defun lax-plist-put plist property value
1953Like @code{plist-put} except that it compares properties
1954using @code{equal} instead of @code{eq}.
1955@end defun
1956
1957@defun plist-member plist property
1958This returns non-@code{nil} if @var{plist} contains the given
1959@var{property}. Unlike @code{plist-get}, this allows you to distinguish
1960between a missing property and a property with the value @code{nil}.
1961The value is actually the tail of @var{plist} whose @code{car} is
1962@var{property}.
1963@end defun
diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index e66f61d22d3..8bb1e9e5abf 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -542,10 +542,10 @@ the function @code{char-table-subtype}, described below.
542@item 542@item
543The subtype controls the number of @dfn{extra slots} in the 543The subtype controls the number of @dfn{extra slots} in the
544char-table. This number is specified by the subtype's 544char-table. This number is specified by the subtype's
545@code{char-table-extra-slots} symbol property, which should be an 545@code{char-table-extra-slots} symbol property (@pxref{Symbol
546integer between 0 and 10. If the subtype has no such symbol property, 546Properties}), whose value should be an integer between 0 and 10. If
547the char-table has no extra slots. @xref{Property Lists}, for 547the subtype has no such symbol property, the char-table has no extra
548information about symbol properties. 548slots.
549@end itemize 549@end itemize
550 550
551@cindex parent of char-table 551@cindex parent of char-table
diff --git a/doc/lispref/symbols.texi b/doc/lispref/symbols.texi
index 326c6cd4ab2..d3e5c1f1574 100644
--- a/doc/lispref/symbols.texi
+++ b/doc/lispref/symbols.texi
@@ -13,8 +13,8 @@ as variables and as function names; see @ref{Variables}, and
13@ref{Functions}. For the precise read syntax for symbols, see 13@ref{Functions}. For the precise read syntax for symbols, see
14@ref{Symbol Type}. 14@ref{Symbol Type}.
15 15
16 You can test whether an arbitrary Lisp object is a symbol 16 You can test whether an arbitrary Lisp object is a symbol with
17with @code{symbolp}: 17@code{symbolp}:
18 18
19@defun symbolp object 19@defun symbolp object
20This function returns @code{t} if @var{object} is a symbol, @code{nil} 20This function returns @code{t} if @var{object} is a symbol, @code{nil}
@@ -26,7 +26,7 @@ otherwise.
26 and property lists. 26 and property lists.
27* Definitions:: A definition says how a symbol will be used. 27* Definitions:: A definition says how a symbol will be used.
28* Creating Symbols:: How symbols are kept unique. 28* Creating Symbols:: How symbols are kept unique.
29* Property Lists:: Each symbol has a property list 29* Symbol Properties:: Each symbol has a property list
30 for recording miscellaneous information. 30 for recording miscellaneous information.
31@end menu 31@end menu
32 32
@@ -91,7 +91,7 @@ the contents of a symbol's function cell, use the function
91 91
92 The property list cell normally should hold a correctly formatted 92 The property list cell normally should hold a correctly formatted
93property list. To get a symbol's property list, use the function 93property list. To get a symbol's property list, use the function
94@code{symbol-plist}. @xref{Property Lists}. 94@code{symbol-plist}. @xref{Symbol Properties}.
95 95
96 The function cell or the value cell may be @dfn{void}, which means 96 The function cell or the value cell may be @dfn{void}, which means
97that the cell does not reference any object. (This is not the same 97that the cell does not reference any object. (This is not the same
@@ -376,109 +376,34 @@ If @code{unintern} does delete a symbol, it returns @code{t}. Otherwise
376it returns @code{nil}. 376it returns @code{nil}.
377@end defun 377@end defun
378 378
379@node Property Lists 379@node Symbol Properties
380@section Property Lists 380@section Symbol Properties
381@cindex property list 381@cindex symbol property
382@cindex plist
383 382
384 A @dfn{property list} (@dfn{plist} for short) is a list of paired 383 A symbol may possess any number of @dfn{symbol properties}, which
385elements. Each of the pairs associates a property name (usually a 384can be used to record miscellaneous information about the symbol. For
386symbol) with a property or value. 385example, when a symbol has a @code{risky-local-variable} property with
386a non-@code{nil} value, that means the variable which the symbol names
387is a risky file-local variable (@pxref{File Local Variables}).
387 388
388 Every symbol has a cell that stores a property list (@pxref{Symbol 389 Each symbol's properties and property values are stored in the
389Components}). This property list is used to record information about 390symbol's property list cell (@pxref{Symbol Components}), in the form
390the symbol, such as its variable documentation and the name of the 391of a property list (@pxref{Property Lists}).
391file where it was defined.
392
393 Property lists can also be used in other contexts. For instance,
394you can assign property lists to character positions in a string or
395buffer. @xref{Text Properties}.
396
397 The property names and values in a property list can be any Lisp
398objects, but the names are usually symbols. Property list functions
399compare the property names using @code{eq}. Here is an example of a
400property list, found on the symbol @code{progn} when the compiler is
401loaded:
402
403@example
404(lisp-indent-function 0 byte-compile byte-compile-progn)
405@end example
406
407@noindent
408Here @code{lisp-indent-function} and @code{byte-compile} are property
409names, and the other two elements are the corresponding values.
410 392
411@menu 393@menu
412* Plists and Alists:: Comparison of the advantages of property 394* Symbol Plists:: Accessing symbol properties.
413 lists and association lists. 395* Standard Properties:: Standard meanings of symbol properties.
414* Symbol Plists:: Functions to access symbols' property lists.
415* Other Plists:: Accessing property lists stored elsewhere.
416@end menu 396@end menu
417 397
418@node Plists and Alists
419@subsection Property Lists and Association Lists
420@cindex plist vs. alist
421@cindex alist vs. plist
422
423@cindex property lists vs association lists
424 Association lists (@pxref{Association Lists}) are very similar to
425property lists. In contrast to association lists, the order of the
426pairs in the property list is not significant since the property names
427must be distinct.
428
429 Property lists are better than association lists for attaching
430information to various Lisp function names or variables. If your
431program keeps all such information in one association list, it will
432typically need to search that entire list each time it checks for an
433association for a particular Lisp function name or variable, which
434could be slow. By contrast, if you keep the same information in the
435property lists of the function names or variables themselves, each
436search will scan only the length of one property list, which is
437usually short. This is why the documentation for a variable is
438recorded in a property named @code{variable-documentation}. The byte
439compiler likewise uses properties to record those functions needing
440special treatment.
441
442 However, association lists have their own advantages. Depending on
443your application, it may be faster to add an association to the front of
444an association list than to update a property. All properties for a
445symbol are stored in the same property list, so there is a possibility
446of a conflict between different uses of a property name. (For this
447reason, it is a good idea to choose property names that are probably
448unique, such as by beginning the property name with the program's usual
449name-prefix for variables and functions.) An association list may be
450used like a stack where associations are pushed on the front of the list
451and later discarded; this is not possible with a property list.
452
453@node Symbol Plists 398@node Symbol Plists
454@subsection Property List Functions for Symbols 399@subsection Accessing Symbol Properties
455
456@defun symbol-plist symbol
457This function returns the property list of @var{symbol}.
458@end defun
459
460@defun setplist symbol plist
461This function sets @var{symbol}'s property list to @var{plist}.
462Normally, @var{plist} should be a well-formed property list, but this is
463not enforced. The return value is @var{plist}.
464 400
465@example 401 The following functions can be used to access symbol properties.
466(setplist 'foo '(a 1 b (2 3) c nil))
467 @result{} (a 1 b (2 3) c nil)
468(symbol-plist 'foo)
469 @result{} (a 1 b (2 3) c nil)
470@end example
471
472For symbols in special obarrays, which are not used for ordinary
473purposes, it may make sense to use the property list cell in a
474nonstandard fashion; in fact, the abbrev mechanism does so
475(@pxref{Abbrevs}).
476@end defun
477 402
478@defun get symbol property 403@defun get symbol property
479This function finds the value of the property named @var{property} in 404This function returns the value of the property named @var{property}
480@var{symbol}'s property list. If there is no such property, @code{nil} 405in @var{symbol}'s property list. If there is no such property, it
481is returned. Thus, there is no distinction between a value of 406returns @code{nil}. Thus, there is no distinction between a value of
482@code{nil} and the absence of the property. 407@code{nil} and the absence of the property.
483 408
484The name @var{property} is compared with the existing property names 409The name @var{property} is compared with the existing property names
@@ -487,12 +412,6 @@ using @code{eq}, so any object is a legitimate property.
487See @code{put} for an example. 412See @code{put} for an example.
488@end defun 413@end defun
489 414
490@defun function-get symbol property
491This function is identical to @code{get}, except that if @var{symbol}
492is the name of a function alias, it looks in the property list of the
493symbol naming the actual function. @xref{Defining Functions}.
494@end defun
495
496@defun put symbol property value 415@defun put symbol property value
497This function puts @var{value} onto @var{symbol}'s property list under 416This function puts @var{value} onto @var{symbol}'s property list under
498the property name @var{property}, replacing any previous property value. 417the property name @var{property}, replacing any previous property value.
@@ -510,69 +429,132 @@ The @code{put} function returns @var{value}.
510@end example 429@end example
511@end defun 430@end defun
512 431
513@node Other Plists 432@defun symbol-plist symbol
514@subsection Property Lists Outside Symbols 433This function returns the property list of @var{symbol}.
515
516 These functions are useful for manipulating property lists
517not stored in symbols:
518
519@defun plist-get plist property
520This returns the value of the @var{property} property stored in the
521property list @var{plist}. It accepts a malformed @var{plist}
522argument. If @var{property} is not found in the @var{plist}, it
523returns @code{nil}. For example,
524
525@example
526(plist-get '(foo 4) 'foo)
527 @result{} 4
528(plist-get '(foo 4 bad) 'foo)
529 @result{} 4
530(plist-get '(foo 4 bad) 'bad)
531 @result{} nil
532(plist-get '(foo 4 bad) 'bar)
533 @result{} nil
534@end example
535@end defun
536
537@defun plist-put plist property value
538This stores @var{value} as the value of the @var{property} property in
539the property list @var{plist}. It may modify @var{plist} destructively,
540or it may construct a new list structure without altering the old. The
541function returns the modified property list, so you can store that back
542in the place where you got @var{plist}. For example,
543
544@example
545(setq my-plist '(bar t foo 4))
546 @result{} (bar t foo 4)
547(setq my-plist (plist-put my-plist 'foo 69))
548 @result{} (bar t foo 69)
549(setq my-plist (plist-put my-plist 'quux '(a)))
550 @result{} (bar t foo 69 quux (a))
551@end example
552@end defun 434@end defun
553 435
554 You could define @code{put} in terms of @code{plist-put} as follows: 436@defun setplist symbol plist
437This function sets @var{symbol}'s property list to @var{plist}.
438Normally, @var{plist} should be a well-formed property list, but this is
439not enforced. The return value is @var{plist}.
555 440
556@example 441@example
557(defun put (symbol prop value) 442(setplist 'foo '(a 1 b (2 3) c nil))
558 (setplist symbol 443 @result{} (a 1 b (2 3) c nil)
559 (plist-put (symbol-plist symbol) prop value))) 444(symbol-plist 'foo)
445 @result{} (a 1 b (2 3) c nil)
560@end example 446@end example
561 447
562@defun lax-plist-get plist property 448For symbols in special obarrays, which are not used for ordinary
563Like @code{plist-get} except that it compares properties 449purposes, it may make sense to use the property list cell in a
564using @code{equal} instead of @code{eq}. 450nonstandard fashion; in fact, the abbrev mechanism does so
451(@pxref{Abbrevs}).
565@end defun 452@end defun
566 453
567@defun lax-plist-put plist property value 454@defun function-get symbol property
568Like @code{plist-put} except that it compares properties 455This function is identical to @code{get}, except that if @var{symbol}
569using @code{equal} instead of @code{eq}. 456is the name of a function alias, it looks in the property list of the
457symbol naming the actual function. @xref{Defining Functions}.
570@end defun 458@end defun
571 459
572@defun plist-member plist property 460@node Standard Properties
573This returns non-@code{nil} if @var{plist} contains the given 461@subsection Standard Symbol Properties
574@var{property}. Unlike @code{plist-get}, this allows you to distinguish 462
575between a missing property and a property with the value @code{nil}. 463 Here, we list the symbol properties which are used for special
576The value is actually the tail of @var{plist} whose @code{car} is 464purposes in Emacs. In the following table, whenever we say ``the
577@var{property}. 465named function'', that means the function whose name is the relevant
578@end defun 466symbol; similarly for ``the named variable'' etc.
467
468@table @code
469@item :advertised-binding
470This property value specifies the preferred key binding, when showing
471documentation, for the named function. @xref{Keys in Documentation}.
472
473@item char-table-extra-slots
474The value, if non-@code{nil}, specifies the number of extra slots in
475the named char-table type. @xref{Char-Tables}.
476
477@itemx customized-face
478@item face-defface-spec
479@itemx saved-face
480@itemx theme-face
481These properties are used to record a face's standard, saved,
482customized, and themed face specs. Do not set them directly; they are
483managed by @code{defface} and related functions. @xref{Defining
484Faces}.
485
486@itemx customized-value
487@itemx saved-value
488@item standard-value
489@itemx theme-value
490These properties are used to record a customizable variable's standard
491value, saved value, customized-but-unsaved value, and themed values.
492Do not set them directly; they are managed by @code{defcustom} and
493related functions. @xref{Variable Definitions}.
494
495@item disabled
496If the value is non-@code{nil}, the named function is disabled as a
497command. @xref{Disabling Commands}.
498
499@item face-documentation
500The value stores the documentation string of the named face. This is
501normally set automatically by @code{defface}. @xref{Defining Faces}.
502
503@item history-length
504The value, if non-@code{nil}, specifies the maximum minibuffer history
505length for the named history list variable. @xref{Minibuffer
506History}.
507
508@item interactive-form
509The value is an interactive form for the named function. Normally,
510you should not set this directly; use the @code{interactive} special
511form instead. @xref{Interactive Call}.
512
513@item menu-enable
514The value is an expression for determining whether the named menu item
515should be enabled in menus. @xref{Simple Menu Items}.
516
517@item mode-class
518If the value is @code{special}, the named major mode is ``special''.
519@xref{Major Mode Conventions}.
520
521@item permanent-local
522If the value is non-@code{nil}, the named variable is a buffer-local
523variable whose value should not be reset when changing major modes.
524@xref{Creating Buffer-Local}.
525
526@item permanent-local-hook
527If the value is non-@code{nil}, the named function should not be
528deleted from the local value of a hook variable when changing major
529modes. @xref{Setting Hooks}.
530
531@item pure
532This property is used internally to mark certain named functions for
533byte compiler optimization. Do not set it.
534
535@item risky-local-variable
536If the value is non-@code{nil}, the named variable is considered risky
537as a file-local variable. @xref{File Local Variables}.
538
539@item safe-function
540If the value is non-@code{nil}, the named function is considered
541generally safe for evaluation. @xref{Function Safety}.
542
543@item safe-local-eval-function
544If the value is non-@code{nil}, the named function is safe to call in
545file-local evaluation forms. @xref{File Local Variables}.
546
547@item safe-local-variable
548The value specifies a function for determining safe file-local values
549for the named variable. @xref{File Local Variables}.
550
551@item side-effect-free
552A non-@code{nil} value indicates that the named function is free of
553side-effects, for determining function safety (@pxref{Function
554Safety}) as well as for byte compiler optimizations. Do not set it.
555
556@item variable-documentation
557If non-@code{nil}, this specifies the named vaariable's documentation
558string. This is normally set automatically by @code{defvar} and
559related functions. @xref{Defining Faces}.
560@end table
diff --git a/doc/lispref/variables.texi b/doc/lispref/variables.texi
index dfde3c45c04..2168bd5af05 100644
--- a/doc/lispref/variables.texi
+++ b/doc/lispref/variables.texi
@@ -1423,7 +1423,6 @@ disappear after doing its job and will not interfere with the
1423subsequent major mode. @xref{Hooks}. 1423subsequent major mode. @xref{Hooks}.
1424@end defvar 1424@end defvar
1425 1425
1426@c Emacs 19 feature
1427@cindex permanent local variable 1426@cindex permanent local variable
1428A buffer-local variable is @dfn{permanent} if the variable name (a 1427A buffer-local variable is @dfn{permanent} if the variable name (a
1429symbol) has a @code{permanent-local} property that is non-@code{nil}. 1428symbol) has a @code{permanent-local} property that is non-@code{nil}.
diff --git a/doc/man/ChangeLog b/doc/man/ChangeLog
index cc54cd254b5..afd6b7b6051 100644
--- a/doc/man/ChangeLog
+++ b/doc/man/ChangeLog
@@ -1,3 +1,7 @@
12012-12-02 Kevin Ryde <user42@zip.com.au>
2
3 * etags.1: Mention effect of --declarations in Lisp.
4
12012-06-03 Glenn Morris <rgm@gnu.org> 52012-06-03 Glenn Morris <rgm@gnu.org>
2 6
3 * rcs-checkin.1: Remove. 7 * rcs-checkin.1: Remove.
diff --git a/doc/man/etags.1 b/doc/man/etags.1
index a1291829665..3f22364a194 100644
--- a/doc/man/etags.1
+++ b/doc/man/etags.1
@@ -88,6 +88,7 @@ Only \fBctags\fP accepts this option.
88.B \-\-declarations 88.B \-\-declarations
89In C and derived languages, create tags for function declarations, 89In C and derived languages, create tags for function declarations,
90and create tags for extern variables unless \-\-no\-globals is used. 90and create tags for extern variables unless \-\-no\-globals is used.
91In Lisp, create tags for (defvar foo) declarations.
91.TP 92.TP
92.B \-D, \-\-no\-defines 93.B \-D, \-\-no\-defines
93Do not create tag entries for C preprocessor constant definitions 94Do not create tag entries for C preprocessor constant definitions
diff --git a/doc/misc/ChangeLog b/doc/misc/ChangeLog
index 8a067b5c100..f5e5007c58d 100644
--- a/doc/misc/ChangeLog
+++ b/doc/misc/ChangeLog
@@ -1,3 +1,12 @@
12012-12-03 Michael Albinus <michael.albinus@gmx.de>
2
3 * tramp.texi (Top, Obtaining Tramp): Replace CVS by Git.
4 (External methods): Fix typo.
5
62012-12-03 Glenn Morris <rgm@gnu.org>
7
8 * rcirc.texi (Notices): Fix typo.
9
12012-11-25 Bill Wohler <wohler@newt.com> 102012-11-25 Bill Wohler <wohler@newt.com>
2 11
3 Release MH-E manual version 8.4. 12 Release MH-E manual version 8.4.
diff --git a/doc/misc/rcirc.texi b/doc/misc/rcirc.texi
index 0174c3fa87f..ac97db414a4 100644
--- a/doc/misc/rcirc.texi
+++ b/doc/misc/rcirc.texi
@@ -764,7 +764,7 @@ You can control which notices get omitted via the
764omit away messages: 764omit away messages:
765 765
766@example 766@example
767(setq rcirc-omit-responses '("JOIN" "PART" "QUIT" "NICK" "AWAY)) 767(setq rcirc-omit-responses '("JOIN" "PART" "QUIT" "NICK" "AWAY"))
768@end example 768@end example
769 769
770@vindex rcirc-omit-threshold 770@vindex rcirc-omit-threshold
diff --git a/doc/misc/tramp.texi b/doc/misc/tramp.texi
index a983f76ffd3..020a6e55833 100644
--- a/doc/misc/tramp.texi
+++ b/doc/misc/tramp.texi
@@ -7,7 +7,7 @@
7@c This is *so* much nicer :) 7@c This is *so* much nicer :)
8@footnotestyle end 8@footnotestyle end
9 9
10@c In the Tramp CVS, the version number is auto-frobbed from 10@c In the Tramp repository, the version number is auto-frobbed from
11@c configure.ac, so you should edit that file and run 11@c configure.ac, so you should edit that file and run
12@c "autoconf && ./configure" to change the version number. 12@c "autoconf && ./configure" to change the version number.
13 13
@@ -106,7 +106,7 @@ If you're using the other Emacs flavor, you should read the
106@ifhtml 106@ifhtml
107The latest release of @value{tramp} is available for 107The latest release of @value{tramp} is available for
108@uref{ftp://ftp.gnu.org/gnu/tramp/, download}, or you may see 108@uref{ftp://ftp.gnu.org/gnu/tramp/, download}, or you may see
109@ref{Obtaining Tramp} for more details, including the CVS server 109@ref{Obtaining Tramp} for more details, including the Git server
110details. 110details.
111 111
112@value{tramp} also has a @uref{http://savannah.gnu.org/projects/tramp/, 112@value{tramp} also has a @uref{http://savannah.gnu.org/projects/tramp/,
@@ -377,13 +377,13 @@ includes @value{tramp} already, and there is a @value{tramp} package
377for XEmacs, as well. So maybe it is easier to just use those. But if 377for XEmacs, as well. So maybe it is easier to just use those. But if
378you want the bleeding edge, read on@dots{...} 378you want the bleeding edge, read on@dots{...}
379 379
380For the especially brave, @value{tramp} is available from CVS. The CVS 380For the especially brave, @value{tramp} is available from Git. The Git
381version is the latest version of the code and may contain incomplete 381version is the latest version of the code and may contain incomplete
382features or new issues. Use these versions at your own risk. 382features or new issues. Use these versions at your own risk.
383 383
384Instructions for obtaining the latest development version of @value{tramp} 384Instructions for obtaining the latest development version of @value{tramp}
385from CVS can be found by going to the Savannah project page at the 385from Git can be found by going to the Savannah project page at the
386following URL and then clicking on the CVS link in the navigation bar 386following URL and then clicking on the Git link in the navigation bar
387at the top. 387at the top.
388 388
389@noindent 389@noindent
@@ -394,8 +394,14 @@ Or follow the example session below:
394 394
395@example 395@example
396] @strong{cd ~/@value{emacsdir}} 396] @strong{cd ~/@value{emacsdir}}
397] @strong{export CVS_RSH="ssh"} 397] @strong{git clone git://git.savannah.gnu.org/tramp.git}
398] @strong{cvs -z3 -d:pserver:anonymous@@cvs.savannah.gnu.org:/sources/tramp co tramp} 398@end example
399
400@noindent
401Tramp developers use instead
402
403@example
404] @strong{git clone login@@git.sv.gnu.org:/srv/git/tramp.git}
399@end example 405@end example
400 406
401@noindent 407@noindent
@@ -405,12 +411,11 @@ updates from the repository by issuing the command:
405 411
406@example 412@example
407] @strong{cd ~/@value{emacsdir}/tramp} 413] @strong{cd ~/@value{emacsdir}/tramp}
408] @strong{export CVS_RSH="ssh"} 414] @strong{git pull}
409] @strong{cvs update -d}
410@end example 415@end example
411 416
412@noindent 417@noindent
413Once you've got updated files from the CVS repository, you need to run 418Once you've got updated files from the Git repository, you need to run
414@command{autoconf} in order to get an up-to-date @file{configure} 419@command{autoconf} in order to get an up-to-date @file{configure}
415script: 420script:
416 421
@@ -980,7 +985,7 @@ This works only for unified filenames, see @ref{Issues}.
980@cindex method smb 985@cindex method smb
981@cindex smb method 986@cindex smb method
982 987
983This is another not natural @value{tramp} method. It uses the 988This is another not native @value{tramp} method. It uses the
984@command{smbclient} command on different Unices in order to connect to 989@command{smbclient} command on different Unices in order to connect to
985an SMB server. An SMB server might be a Samba (or CIFS) server on 990an SMB server. An SMB server might be a Samba (or CIFS) server on
986another UNIX host or, more interesting, a host running MS Windows. So 991another UNIX host or, more interesting, a host running MS Windows. So
diff --git a/etc/NEWS b/etc/NEWS
index 05a57e9afe7..b175843828d 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -69,6 +69,11 @@ New features include:
69 name and arguments. Useful to trace the value of (current-buffer) or 69 name and arguments. Useful to trace the value of (current-buffer) or
70 (point) when the function is invoked. 70 (point) when the function is invoked.
71 71
72** New command `delete-duplicate-lines' has two types of operation:
73when its arg ADJACENT is non-nil (when called interactively with C-u C-u)
74it works like the utility `uniq'. Otherwise by default it deletes
75duplicate lines everywhere in the region without regard to adjacency.
76
72** Woman 77** Woman
73 78
74*** The commands `woman-default-faces' and `woman-monochrome-faces' 79*** The commands `woman-default-faces' and `woman-monochrome-faces'
@@ -812,9 +817,9 @@ The function `user-variable-p' is now an obsolete alias for
812 817
813+++ 818+++
814** The return values of `defalias', `defun' and `defmacro' have changed, 819** The return values of `defalias', `defun' and `defmacro' have changed,
815and are now undefined. For backwards compatibility, defun and 820and are now undefined. For backwards compatibility, `defun' and
816defmacro currently return the name of the newly defined function/macro 821`defmacro' currently return the name of the newly defined
817but this should not be relied upon. 822function/macro, but this should not be relied upon.
818 823
819--- 824---
820** `face-spec-set' no longer sets frame-specific attributes when the 825** `face-spec-set' no longer sets frame-specific attributes when the
@@ -1061,6 +1066,12 @@ takes precedence over most other maps for a short while (normally one key).
1061+++ 1066+++
1062** New macros `setq-local' and `defvar-local'. 1067** New macros `setq-local' and `defvar-local'.
1063 1068
1069** Changes to special forms and macros
1070+++
1071*** `defun' and `defmacro' are now macros rather than special forms
1072+++
1073*** `kbd' is now a function rather than a macro.
1074
1064+++ 1075+++
1065** New fringe bitmap `exclamation-mark'. 1076** New fringe bitmap `exclamation-mark'.
1066 1077
diff --git a/lib-src/ChangeLog b/lib-src/ChangeLog
index 294661a6cb3..480ddabd44a 100644
--- a/lib-src/ChangeLog
+++ b/lib-src/ChangeLog
@@ -1,3 +1,10 @@
12012-12-02 Kevin Ryde <user42@zip.com.au>
2
3 * etags.c (Lisp_functions): Skip (defvar foo) declarations unless
4 the --declarations flag is enabled (Bug#5600).
5 (Lisp_help): Update.
6 (skip_name): New function.
7
12012-12-01 Kevin Ryde <user42@zip.com.au> 82012-12-01 Kevin Ryde <user42@zip.com.au>
2 9
3 * etags.c (Perl_functions): Support "use constant" (Bug#5055). 10 * etags.c (Perl_functions): Support "use constant" (Bug#5055).
diff --git a/lib-src/etags.c b/lib-src/etags.c
index ec185c9819f..d393c4d2e4a 100644
--- a/lib-src/etags.c
+++ b/lib-src/etags.c
@@ -353,6 +353,7 @@ static void put_entries (node *);
353static char *concat (const char *, const char *, const char *); 353static char *concat (const char *, const char *, const char *);
354static char *skip_spaces (char *); 354static char *skip_spaces (char *);
355static char *skip_non_spaces (char *); 355static char *skip_non_spaces (char *);
356static char *skip_name (char *);
356static char *savenstr (const char *, int); 357static char *savenstr (const char *, int);
357static char *savestr (const char *); 358static char *savestr (const char *);
358static char *etags_strchr (const char *, int); 359static char *etags_strchr (const char *, int);
@@ -619,7 +620,8 @@ static const char Lisp_help [] =
619"In Lisp code, any function defined with `defun', any variable\n\ 620"In Lisp code, any function defined with `defun', any variable\n\
620defined with `defvar' or `defconst', and in general the first\n\ 621defined with `defvar' or `defconst', and in general the first\n\
621argument of any expression that starts with `(def' in column zero\n\ 622argument of any expression that starts with `(def' in column zero\n\
622is a tag."; 623is a tag.\n\
624The `--declarations' option tags \"(defvar foo)\" constructs too.";
623 625
624static const char *Lua_suffixes [] = 626static const char *Lua_suffixes [] =
625 { "lua", "LUA", NULL }; 627 { "lua", "LUA", NULL };
@@ -4747,6 +4749,19 @@ Lisp_functions (FILE *inf)
4747 if (dbp[0] != '(') 4749 if (dbp[0] != '(')
4748 continue; 4750 continue;
4749 4751
4752 /* "(defvar foo)" is a declaration rather than a definition. */
4753 if (! declarations)
4754 {
4755 char *p = dbp + 1;
4756 if (LOOKING_AT (p, "defvar"))
4757 {
4758 p = skip_name (p); /* past var name */
4759 p = skip_spaces (p);
4760 if (*p == ')')
4761 continue;
4762 }
4763 }
4764
4750 if (strneq (dbp+1, "def", 3) || strneq (dbp+1, "DEF", 3)) 4765 if (strneq (dbp+1, "def", 3) || strneq (dbp+1, "DEF", 3))
4751 { 4766 {
4752 dbp = skip_non_spaces (dbp); 4767 dbp = skip_non_spaces (dbp);
@@ -6307,6 +6322,16 @@ skip_non_spaces (char *cp)
6307 return cp; 6322 return cp;
6308} 6323}
6309 6324
6325/* Skip any chars in the "name" class.*/
6326static char *
6327skip_name (char *cp)
6328{
6329 /* '\0' is a notinname() so loop stops there too */
6330 while (! notinname (*cp))
6331 cp++;
6332 return cp;
6333}
6334
6310/* Print error message and exit. */ 6335/* Print error message and exit. */
6311void 6336void
6312fatal (const char *s1, const char *s2) 6337fatal (const char *s1, const char *s2)
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index ec7791597f0..f4963a07a92 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,67 @@
12012-12-03 Juri Linkov <juri@jurta.org>
2
3 * sort.el (delete-duplicate-lines): New command. (Bug#13032)
4
52012-12-03 Agustín Martín Domingo <agustin.martin@hispalinux.es>
6
7 * textmodes/ispell.el (ispell-init-process)
8 (ispell-start-process, ispell-internal-change-dictionary):
9 Make sure personal dictionary name is expanded after initial
10 `default-directory' value. Use expanded strings for
11 keep/restart checks and for value (Bug#13019).
12
132012-12-03 Jay Belanger <jay.p.belanger@gmail.com>
14
15 * calc/calc-forms.el (math-date-to-iso-dt): Fix weekday number.
16
172012-12-03 Leo Liu <sdl.web@gmail.com>
18
19 * files.el (dir-locals-read-from-file): Check file non-empty
20 before reading. (Bug#13038)
21
222012-12-03 Glenn Morris <rgm@gnu.org>
23
24 * jka-cmpr-hook.el (jka-compr-get-compression-info):
25 Remove any version extension before checking filename. (Bug#13006)
26 (jka-compr-compression-info-list): Belated :version bump.
27
282012-12-03 Chong Yidong <cyd@gnu.org>
29
30 * simple.el (transient-mark-mode): Doc fix (Bug#11523).
31
32 * buff-menu.el (Buffer-menu-delete-backwards, Buffer-menu-mode)
33 (buffer-menu): Doc fix (Bug#12294).
34
352012-12-03 Roland Winkler <winkler@gnu.org>
36
37 * calendar/diary-lib.el (diary-header-line-format): Use keybinding
38 of diary-show-all-entries in the diary buffer (Bug#12994).
39
402012-12-03 Michael Albinus <michael.albinus@gmx.de>
41
42 * net/tramp-sh.el (tramp-perl-encode): Use "read STDIN" instead of
43 "<STDIN>". This is binary safe.
44
452012-12-03 Jay Belanger <jay.p.belanger@gmail.com>
46
47 * calc/calc-forms.el (math-absolute-from-iso-dt)
48 (math-date-to-iso-dt, math-parse-iso-date-validate)
49 (math-iso-dt-to-date): New functions.
50 (math-fd-iso-dt, math-fd-isoyear, math-fd-isoweek)
51 (math-fd-isoweekday): New variables.
52 (calc-date-notation, math-parse-standard-date, math-format-date)
53 (math-format-date-part): Add support for more formatting codes.
54
552012-12-02 Dmitry Gutov <dgutov@yandex.ru>
56
57 * vc/vc.el (vc-delete-file, vc-rename-file): Default to the
58 current buffer's file name when called interactively (Bug#12488).
59
602012-12-02 Juri Linkov <juri@jurta.org>
61
62 * info.el (info-display-manual): Don't clobber an existing Info
63 buffer (Bug#10770). Add completion (Bug#10771).
64
12012-12-01 Yuya Nishihara <yuya@tcha.org> (tiny change) 652012-12-01 Yuya Nishihara <yuya@tcha.org> (tiny change)
2 66
3 * vc/vc-hooks.el (vc-find-file-hook): Expand buffer-file-truename 67 * vc/vc-hooks.el (vc-find-file-hook): Expand buffer-file-truename
diff --git a/lisp/buff-menu.el b/lisp/buff-menu.el
index 01035f8727d..3161973ba32 100644
--- a/lisp/buff-menu.el
+++ b/lisp/buff-menu.el
@@ -204,31 +204,11 @@ commands.")
204 204
205(define-derived-mode Buffer-menu-mode tabulated-list-mode "Buffer Menu" 205(define-derived-mode Buffer-menu-mode tabulated-list-mode "Buffer Menu"
206 "Major mode for Buffer Menu buffers. 206 "Major mode for Buffer Menu buffers.
207The Buffer Menu is invoked by the commands \\[list-buffers], \\[buffer-menu], and 207The Buffer Menu is invoked by the commands \\[list-buffers],
208\\[buffer-menu-other-window]. See `buffer-menu' for details." 208\\[buffer-menu], and \\[buffer-menu-other-window].
209 (set (make-local-variable 'buffer-stale-function) 209See `buffer-menu' for a description of its contents.
210 (lambda (&optional _noconfirm) 'fast))
211 (add-hook 'tabulated-list-revert-hook 'list-buffers--refresh nil t))
212
213(defun buffer-menu (&optional arg)
214 "Switch to the Buffer Menu.
215By default, all buffers are listed except those whose names start
216with a space (which are for internal use). With prefix argument
217ARG, show only buffers that are visiting files.
218
219The first column (denoted \"C\") shows \".\" for the buffer from
220which you came. It shows \">\" for buffers you mark to be
221displayed, and \"D\" for those you mark for deletion.
222
223The \"R\" column has a \"%\" if the buffer is read-only.
224The \"M\" column has a \"*\" if it is modified, or \"S\" if you
225have marked it for saving.
226
227After this come the buffer name, its size in characters, its
228major mode, and the visited file name (if any).
229
230 210
231In the Buffer Menu, the following commands are defined: 211In Buffer Menu mode, the following commands are defined:
232\\<Buffer-menu-mode-map> 212\\<Buffer-menu-mode-map>
233\\[quit-window] Remove the Buffer Menu from the display. 213\\[quit-window] Remove the Buffer Menu from the display.
234\\[Buffer-menu-this-window] Select current line's buffer in place of the buffer menu. 214\\[Buffer-menu-this-window] Select current line's buffer in place of the buffer menu.
@@ -244,7 +224,7 @@ In the Buffer Menu, the following commands are defined:
244\\[Buffer-menu-1-window] Select that buffer in full-frame window. 224\\[Buffer-menu-1-window] Select that buffer in full-frame window.
245\\[Buffer-menu-2-window] Select that buffer in one window, together with the 225\\[Buffer-menu-2-window] Select that buffer in one window, together with the
246 buffer selected before this one in another window. 226 buffer selected before this one in another window.
247\\[Buffer-menu-isearch-buffers] Incremental search in the marked buffers. 227\\[Buffer-menu-isearch-buffers] Incremental search in the marked buffers.
248\\[Buffer-menu-isearch-buffers-regexp] Isearch for regexp in the marked buffers. 228\\[Buffer-menu-isearch-buffers-regexp] Isearch for regexp in the marked buffers.
249\\[Buffer-menu-visit-tags-table] visit-tags-table this buffer. 229\\[Buffer-menu-visit-tags-table] visit-tags-table this buffer.
250\\[Buffer-menu-not-modified] Clear modified-flag on that buffer. 230\\[Buffer-menu-not-modified] Clear modified-flag on that buffer.
@@ -259,6 +239,29 @@ In the Buffer Menu, the following commands are defined:
259\\[revert-buffer] Update the list of buffers. 239\\[revert-buffer] Update the list of buffers.
260\\[Buffer-menu-toggle-files-only] Toggle whether the menu displays only file buffers. 240\\[Buffer-menu-toggle-files-only] Toggle whether the menu displays only file buffers.
261\\[Buffer-menu-bury] Bury the buffer listed on this line." 241\\[Buffer-menu-bury] Bury the buffer listed on this line."
242 (set (make-local-variable 'buffer-stale-function)
243 (lambda (&optional _noconfirm) 'fast))
244 (add-hook 'tabulated-list-revert-hook 'list-buffers--refresh nil t))
245
246(defun buffer-menu (&optional arg)
247 "Switch to the Buffer Menu.
248By default, the Buffer Menu lists all buffers except those whose
249names start with a space (which are for internal use). With
250prefix argument ARG, show only buffers that are visiting files.
251
252In the Buffer Menu, the first column (denoted \"C\") shows \".\"
253for the buffer from which you came, \">\" for buffers you mark to
254be displayed, and \"D\" for those you mark for deletion.
255
256The \"R\" column has a \"%\" if the buffer is read-only.
257The \"M\" column has a \"*\" if it is modified, or \"S\" if you
258have marked it for saving.
259
260The remaining columns show the buffer name, the buffer size in
261characters, its major mode, and the visited file name (if any).
262
263See `Buffer-menu-mode' for the keybindings available the Buffer
264Menu."
262 (interactive "P") 265 (interactive "P")
263 (switch-to-buffer (list-buffers-noselect arg)) 266 (switch-to-buffer (list-buffers-noselect arg))
264 (message 267 (message
@@ -280,7 +283,7 @@ ARG, show only buffers that are visiting files."
280(defun list-buffers (&optional arg) 283(defun list-buffers (&optional arg)
281 "Display a list of existing buffers. 284 "Display a list of existing buffers.
282The list is displayed in a buffer named \"*Buffer List*\". 285The list is displayed in a buffer named \"*Buffer List*\".
283See `buffer-menu' for details about the Buffer Menu buffer. 286See `buffer-menu' for a description of the Buffer Menu.
284 287
285By default, all buffers are listed except those whose names start 288By default, all buffers are listed except those whose names start
286with a space (which are for internal use). With prefix argument 289with a space (which are for internal use). With prefix argument
@@ -377,7 +380,9 @@ buffers to delete; a negative ARG means to delete backwards."
377 380
378(defun Buffer-menu-delete-backwards (&optional arg) 381(defun Buffer-menu-delete-backwards (&optional arg)
379 "Mark the buffer on this Buffer Menu line for deletion, and move up. 382 "Mark the buffer on this Buffer Menu line for deletion, and move up.
380Prefix ARG means move that many lines." 383A subsequent \\<Buffer-menu-mode-map>`\\[Buffer-menu-execute]'
384command will delete the marked buffer. Prefix ARG means move
385that many lines."
381 (interactive "p") 386 (interactive "p")
382 (Buffer-menu-delete (- (or arg 1)))) 387 (Buffer-menu-delete (- (or arg 1))))
383 388
diff --git a/lisp/calc/calc-forms.el b/lisp/calc/calc-forms.el
index 15a153059a8..5ce76b14d72 100644
--- a/lisp/calc/calc-forms.el
+++ b/lisp/calc/calc-forms.el
@@ -95,7 +95,7 @@
95 (let ((case-fold-search nil)) 95 (let ((case-fold-search nil))
96 (and (not (string-match "<.*>" fmt)) 96 (and (not (string-match "<.*>" fmt))
97 ;; Find time part to put in <...> 97 ;; Find time part to put in <...>
98 (string-match "\\`[^hHspP]*\\([^ac-gi-lnoqrt-zAC-GI-OQRT-Z]*\\(bs\\|bm\\|bh\\|BS\\|BH\\|[hHmpPsS]\\)+[^ac-gi-lnoqrt-zAC-GI-OQRT-Z]*\\)[^hHspP]*\\'" fmt) 98 (string-match "\\`[^hHspPT]*\\([^ac-gi-lnoqrt-zAC-GI-OQRU-Z]*\\(bs\\|bm\\|bh\\|BS\\|BH\\|[hHmpPsST]\\)+[^ac-gi-lnoqrt-zAC-GI-OQRU-Z]*\\)[^hHspPT]*\\'" fmt)
99 (string-match (concat "[^ac-gi-lnoqrt-zAC-GI-OQRT-Z]*" 99 (string-match (concat "[^ac-gi-lnoqrt-zAC-GI-OQRT-Z]*"
100 (regexp-quote (math-match-substring fmt 1)) 100 (regexp-quote (math-match-substring fmt 1))
101 "[^ac-gi-lnoqrt-zAC-GI-OQRT-Z]*") fmt) 101 "[^ac-gi-lnoqrt-zAC-GI-OQRT-Z]*") fmt)
@@ -126,7 +126,7 @@
126 lfmt nil)) 126 lfmt nil))
127 (setq time nil)) 127 (setq time nil))
128 (t 128 (t
129 (if (string-match "\\`[^a-zA-Z]*[bB][a-zA-Z]" fmt) 129 (if (string-match "\\`[^a-zA-Z]*[bBZI][a-zA-Z]" fmt)
130 (setq pos2 (1+ pos2))) 130 (setq pos2 (1+ pos2)))
131 (while (and (< pos2 (length fmt)) 131 (while (and (< pos2 (length fmt))
132 (= (upcase (aref fmt pos2)) 132 (= (upcase (aref fmt pos2))
@@ -134,6 +134,7 @@
134 (setq pos2 (1+ pos2))) 134 (setq pos2 (1+ pos2)))
135 (setq sym (intern (substring fmt pos pos2))) 135 (setq sym (intern (substring fmt pos pos2)))
136 (or (memq sym '(Y YY BY YYY YYYY 136 (or (memq sym '(Y YY BY YYY YYYY
137 ZYYY IYYY Iww w
137 aa AA aaa AAA aaaa AAAA 138 aa AA aaa AAA aaaa AAAA
138 bb BB bbb BBB bbbb BBBB 139 bb BB bbb BBB bbbb BBBB
139 M MM BM mmm Mmm Mmmm MMM MMMM 140 M MM BM mmm Mmm Mmmm MMM MMMM
@@ -142,7 +143,7 @@
142 h hh bh H HH BH 143 h hh bh H HH BH
143 p P pp PP pppp PPPP 144 p P pp PP pppp PPPP
144 m mm bm s ss bs SS BS C 145 m mm bm s ss bs SS BS C
145 N n J j U b)) 146 N n J j U b T))
146 (and (eq sym 'X) (not lfmt) (not fullfmt)) 147 (and (eq sym 'X) (not lfmt) (not fullfmt))
147 (error "Bad format code: %s" sym)) 148 (error "Bad format code: %s" sym))
148 (and (memq sym '(bb BB bbb BBB bbbb BBBB)) 149 (and (memq sym '(bb BB bbb BBB bbbb BBBB))
@@ -455,6 +456,27 @@ in the Gregorian calendar and the remaining part determines the time."
455 (% (/ time 60) 60) 456 (% (/ time 60) 60)
456 (math-add (% time 60) (nth 2 parts))))))) 457 (math-add (% time 60) (nth 2 parts)))))))
457 458
459(defun math-date-to-iso-dt (date)
460 "Return the ISO8601 date (year week day) of DATE."
461 (unless (Math-integerp date)
462 (setq date (math-floor date)))
463 (let* ((approx (nth 0 (math-date-to-gregorian-dt (math-sub date 3))))
464 (year (math-add approx
465 (let ((y approx)
466 (sum 0))
467 (while (>= (math-compare date
468 (math-absolute-from-iso-dt (setq y (math-add y 1)) 1 1)) 0)
469 (setq sum (+ sum 1)))
470 sum))))
471 (list
472 year
473 (math-add (car (math-idivmod
474 (math-sub date (math-absolute-from-iso-dt year 1 1))
475 7))
476 1)
477 (let ((day (calcFunc-mod date 7)))
478 (if (= day 0) 7 day)))))
479
458(defun math-dt-to-date (dt) 480(defun math-dt-to-date (dt)
459 (or (integerp (nth 1 dt)) 481 (or (integerp (nth 1 dt))
460 (math-reject-arg (nth 1 dt) 'fixnump)) 482 (math-reject-arg (nth 1 dt) 'fixnump))
@@ -473,6 +495,16 @@ in the Gregorian calendar and the remaining part determines the time."
473 '(float 864 2))) 495 '(float 864 2)))
474 date))) 496 date)))
475 497
498(defun math-iso-dt-to-date (dt)
499 (let ((date (math-absolute-from-iso-dt (car dt) (nth 1 dt) (nth 2 dt))))
500 (if (nth 3 dt)
501 (math-add (math-float date)
502 (math-div (math-add (+ (* (nth 3 dt) 3600)
503 (* (nth 4 dt) 60))
504 (nth 5 dt))
505 '(float 864 2)))
506 date)))
507
476(defun math-date-parts (value &optional offset) 508(defun math-date-parts (value &optional offset)
477 (let* ((date (math-floor value)) 509 (let* ((date (math-floor value))
478 (time (math-round (math-mul (math-sub value (or offset date)) 86400) 510 (time (math-round (math-mul (math-sub value (or offset date)) 86400)
@@ -594,6 +626,14 @@ in the Gregorian calendar."
594;; calc-gregorian-switch is a customizable variable defined in calc.el 626;; calc-gregorian-switch is a customizable variable defined in calc.el
595(defvar calc-gregorian-switch) 627(defvar calc-gregorian-switch)
596 628
629(defun math-absolute-from-iso-dt (year week day)
630 "Return the DATE of the day given by the iso8601 day YEAR WEEK DAY."
631 (let* ((janfour (math-absolute-from-gregorian-dt year 1 4))
632 (prevmon (math-sub janfour
633 (cdr (math-idivmod (math-sub janfour 1) 7)))))
634 (math-add
635 (math-add prevmon (* (1- week) 7))
636 (if (zerop day) 6 (1- day)))))
597 637
598(defun math-absolute-from-dt (year month day) 638(defun math-absolute-from-dt (year month day)
599 "Return the DATE of the day given by the day YEAR MONTH DAY. 639 "Return the DATE of the day given by the day YEAR MONTH DAY.
@@ -638,6 +678,10 @@ in the Gregorian calendar."
638(defvar math-fd-minute) 678(defvar math-fd-minute)
639(defvar math-fd-second) 679(defvar math-fd-second)
640(defvar math-fd-bc-flag) 680(defvar math-fd-bc-flag)
681(defvar math-fd-iso-dt)
682(defvar math-fd-isoyear)
683(defvar math-fd-isoweek)
684(defvar math-fd-isoweekday)
641 685
642(defun math-format-date (math-fd-date) 686(defun math-format-date (math-fd-date)
643 (if (eq (car-safe math-fd-date) 'date) 687 (if (eq (car-safe math-fd-date) 'date)
@@ -645,12 +689,14 @@ in the Gregorian calendar."
645 (let ((entry (list math-fd-date calc-internal-prec calc-date-format))) 689 (let ((entry (list math-fd-date calc-internal-prec calc-date-format)))
646 (or (cdr (assoc entry math-format-date-cache)) 690 (or (cdr (assoc entry math-format-date-cache))
647 (let* ((math-fd-dt nil) 691 (let* ((math-fd-dt nil)
692 (math-fd-iso-dt nil)
648 (calc-group-digits nil) 693 (calc-group-digits nil)
649 (calc-leading-zeros nil) 694 (calc-leading-zeros nil)
650 (calc-number-radix 10) 695 (calc-number-radix 10)
651 (calc-twos-complement-mode nil) 696 (calc-twos-complement-mode nil)
652 math-fd-year math-fd-month math-fd-day math-fd-weekday 697 math-fd-year math-fd-month math-fd-day math-fd-weekday
653 math-fd-hour math-fd-minute math-fd-second 698 math-fd-hour math-fd-minute math-fd-second
699 math-fd-isoyear math-fd-isoweek math-fd-isoweekday
654 (math-fd-bc-flag nil) 700 (math-fd-bc-flag nil)
655 (fmt (apply 'concat (mapcar 'math-format-date-part 701 (fmt (apply 'concat (mapcar 'math-format-date-part
656 calc-date-format)))) 702 calc-date-format))))
@@ -690,6 +736,23 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
690 math-julian-date-beginning-int))) 736 math-julian-date-beginning-int)))
691 ((eq x 'U) 737 ((eq x 'U)
692 (math-format-number (nth 1 (math-date-parts math-fd-date 719164)))) 738 (math-format-number (nth 1 (math-date-parts math-fd-date 719164))))
739 ((memq x '(IYYY Iww w))
740 (progn
741 (or math-fd-iso-dt
742 (setq math-fd-iso-dt (math-date-to-iso-dt math-fd-date)
743 math-fd-isoyear (car math-fd-iso-dt)
744 math-fd-isoweek (nth 1 math-fd-iso-dt)
745 math-fd-isoweekday (nth 2 math-fd-iso-dt)))
746 (cond ((eq x 'IYYY)
747 (let* ((neg (Math-negp math-fd-isoyear))
748 (pyear (calcFunc-abs math-fd-isoyear)))
749 (if (and (natnump pyear) (< pyear 10000))
750 (concat (if neg "-" "") (format "%04d" pyear))
751 (concat (if neg "-" "+") (math-format-number pyear)))))
752 ((eq x 'Iww)
753 (concat "W" (format "%02d" math-fd-isoweek)))
754 ((eq x 'w)
755 (format "%d" math-fd-isoweekday)))))
693 ((progn 756 ((progn
694 (or math-fd-dt 757 (or math-fd-dt
695 (progn 758 (progn
@@ -720,6 +783,15 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
720 (if (and (natnump math-fd-year) (< math-fd-year 100)) 783 (if (and (natnump math-fd-year) (< math-fd-year 100))
721 (format "+%d" math-fd-year) 784 (format "+%d" math-fd-year)
722 (math-format-number math-fd-year))) 785 (math-format-number math-fd-year)))
786 ((eq x 'ZYYY)
787 (let* ((year (if (Math-negp math-fd-year)
788 (math-add math-fd-year 1)
789 math-fd-year))
790 (neg (Math-negp year))
791 (pyear (calcFunc-abs year)))
792 (if (and (natnump pyear) (< pyear 10000))
793 (concat (if neg "-" "") (format "%04d" pyear))
794 (concat (if neg "-" "+") (math-format-number pyear)))))
723 ((eq x 'b) "") 795 ((eq x 'b) "")
724 ((eq x 'aa) 796 ((eq x 'aa)
725 (and (not math-fd-bc-flag) "ad")) 797 (and (not math-fd-bc-flag) "ad"))
@@ -745,6 +817,7 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
745 (and math-fd-bc-flag "b.c.")) 817 (and math-fd-bc-flag "b.c."))
746 ((eq x 'BBBB) 818 ((eq x 'BBBB)
747 (and math-fd-bc-flag "B.C.")) 819 (and math-fd-bc-flag "B.C."))
820 ((eq x 'T) "T")
748 ((eq x 'M) 821 ((eq x 'M)
749 (format "%d" math-fd-month)) 822 (format "%d" math-fd-month))
750 ((eq x 'MM) 823 ((eq x 'MM)
@@ -1009,6 +1082,20 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
1009 (list 'date (math-dt-to-date (append (list year month day) 1082 (list 'date (math-dt-to-date (append (list year month day)
1010 (and hour (list hour minute second)))))) 1083 (and hour (list hour minute second))))))
1011 1084
1085(defun math-parse-iso-date-validate (isoyear isoweek isoweekday hour minute second)
1086 (if (or (< isoweek 1) (> isoweek 53))
1087 (throw 'syntax "Week value is out of range"))
1088 (and hour
1089 (progn
1090 (if (or (< hour 0) (> hour 23))
1091 (throw 'syntax "Hour value is out of range"))
1092 (if (or (< minute 0) (> minute 59))
1093 (throw 'syntax "Minute value is out of range"))
1094 (if (or (math-negp second) (not (Math-lessp second 60)))
1095 (throw 'syntax "Seconds value is out of range"))))
1096 (list 'date (math-iso-dt-to-date (append (list isoyear isoweek isoweekday)
1097 (and hour (list hour minute second))))))
1098
1012(defun math-parse-date-word (names &optional front) 1099(defun math-parse-date-word (names &optional front)
1013 (let ((n 1)) 1100 (let ((n 1))
1014 (while (and names (not (string-match (if (equal (car names) "Sep") 1101 (while (and names (not (string-match (if (equal (car names) "Sep")
@@ -1029,6 +1116,7 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
1029 (let ((case-fold-search t) 1116 (let ((case-fold-search t)
1030 (okay t) num 1117 (okay t) num
1031 (fmt calc-date-format) this next (gnext nil) 1118 (fmt calc-date-format) this next (gnext nil)
1119 (isoyear nil) (isoweek nil) (isoweekday nil)
1032 (year nil) (month nil) (day nil) (bigyear nil) (yearday nil) 1120 (year nil) (month nil) (day nil) (bigyear nil) (yearday nil)
1033 (hour nil) (minute nil) (second nil) (bc-flag nil)) 1121 (hour nil) (minute nil) (second nil) (bc-flag nil))
1034 (while (and fmt okay) 1122 (while (and fmt okay)
@@ -1105,19 +1193,35 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
1105 (if (string-match "\\`pm\\|p\\.m\\." math-pd-str) 1193 (if (string-match "\\`pm\\|p\\.m\\." math-pd-str)
1106 (setq hour (if (= hour 12) 12 (% (+ hour 12) 24)) 1194 (setq hour (if (= hour 12) 12 (% (+ hour 12) 24))
1107 math-pd-str (substring math-pd-str (match-end 0)))))) 1195 math-pd-str (substring math-pd-str (match-end 0))))))
1108 ((memq this '(Y YY BY YYY YYYY)) 1196 ((memq this '(Y YY BY YYY YYYY ZYYY))
1109 (and (if (memq next '(MM DD ddd hh HH mm ss SS)) 1197 (and (if (memq next '(MM DD ddd hh HH mm ss SS))
1110 (if (memq this '(Y YY BYY)) 1198 (if (memq this '(Y YY BYY))
1111 (string-match "\\` *[0-9][0-9]" math-pd-str) 1199 (string-match "\\` *[0-9][0-9]" math-pd-str)
1112 (string-match "\\`[0-9][0-9][0-9][0-9]" math-pd-str)) 1200 (string-match "\\`[0-9][0-9][0-9][0-9]" math-pd-str))
1113 (string-match "\\`[-+]?[0-9]+" math-pd-str)) 1201 (string-match "\\`[-+]?[0-9]+" math-pd-str))
1114 (setq year (math-match-substring math-pd-str 0) 1202 (setq year (math-match-substring math-pd-str 0)
1115 bigyear (or (eq this 'YYY) 1203 bigyear (or (eq this 'YYY)
1116 (memq (aref math-pd-str 0) '(?\+ ?\-))) 1204 (memq (aref math-pd-str 0) '(?\+ ?\-)))
1117 math-pd-str (substring math-pd-str (match-end 0)) 1205 math-pd-str (substring math-pd-str (match-end 0))
1118 year (math-read-number year)))) 1206 year (math-read-number year))
1207 (if (and (eq this 'ZYYY) (eq year 0))
1208 (setq year (math-sub year 1)
1209 bigyear t)
1210 t)))
1211 ((eq this 'IYYY)
1212 (if (string-match "\\`[-+]?[0-9]+" math-pd-str)
1213 (setq isoyear (string-to-number (math-match-substring math-pd-str 0))
1214 math-pd-str (substring math-pd-str (match-end 0)))))
1215 ((eq this 'Iww)
1216 (if (string-match "W\\([0-9][0-9]\\)" math-pd-str)
1217 (setq isoweek (string-to-number (math-match-substring math-pd-str 1))
1218 math-pd-str (substring math-pd-str 3))))
1119 ((eq this 'b) 1219 ((eq this 'b)
1120 t) 1220 t)
1221 ((eq this 'T)
1222 (if (eq (aref math-pd-str 0) ?T)
1223 (setq math-pd-str (substring math-pd-str 1))
1224 t))
1121 ((memq this '(aa AA aaaa AAAA)) 1225 ((memq this '(aa AA aaaa AAAA))
1122 (if (string-match "\\` *\\(ad\\|a\\.d\\.\\)" math-pd-str) 1226 (if (string-match "\\` *\\(ad\\|a\\.d\\.\\)" math-pd-str)
1123 (setq math-pd-str (substring math-pd-str (match-end 0))))) 1227 (setq math-pd-str (substring math-pd-str (match-end 0)))))
@@ -1152,7 +1256,9 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
1152 nil)) 1256 nil))
1153 nil) 1257 nil)
1154 ((eq this 'W) 1258 ((eq this 'W)
1155 (and (>= num 0) (< num 7))) 1259 (and (>= num 0) (< num 7)))
1260 ((eq this 'w)
1261 (setq isoweekday num))
1156 ((memq this '(d ddd bdd)) 1262 ((memq this '(d ddd bdd))
1157 (setq yearday num)) 1263 (setq yearday num))
1158 ((memq this '(M MM BM)) 1264 ((memq this '(M MM BM))
@@ -1169,18 +1275,20 @@ as measured in the integer number of days before December 31, 1 BC (Gregorian)."
1169 (setq yearday nil) 1275 (setq yearday nil)
1170 (setq month 1 day 1))) 1276 (setq month 1 day 1)))
1171 (if (and okay (equal math-pd-str "")) 1277 (if (and okay (equal math-pd-str ""))
1172 (and month day (or (not (or hour minute second)) 1278 (if isoyear
1173 (and hour minute)) 1279 (math-parse-iso-date-validate isoyear isoweek isoweekday hour minute second)
1174 (progn 1280 (and month day (or (not (or hour minute second))
1175 (or year (setq year (math-this-year))) 1281 (and hour minute))
1176 (or second (setq second 0)) 1282 (progn
1177 (if bc-flag 1283 (or year (setq year (math-this-year)))
1178 (setq year (math-neg (math-abs year)))) 1284 (or second (setq second 0))
1179 (setq day (math-parse-date-validate year bigyear month day 1285 (if bc-flag
1180 hour minute second)) 1286 (setq year (math-neg (math-abs year))))
1181 (if yearday 1287 (setq day (math-parse-date-validate year bigyear month day
1182 (setq day (math-add day (1- yearday)))) 1288 hour minute second))
1183 day))))) 1289 (if yearday
1290 (setq day (math-add day (1- yearday))))
1291 day))))))
1184 1292
1185 1293
1186(defun calcFunc-now (&optional zone) 1294(defun calcFunc-now (&optional zone)
diff --git a/lisp/calendar/diary-lib.el b/lisp/calendar/diary-lib.el
index 27c6f76581c..46a7f703019 100644
--- a/lisp/calendar/diary-lib.el
+++ b/lisp/calendar/diary-lib.el
@@ -444,8 +444,7 @@ The format of the header is specified by `diary-header-line-format'."
444(defcustom diary-header-line-format 444(defcustom diary-header-line-format
445 '(:eval (calendar-string-spread 445 '(:eval (calendar-string-spread
446 (list (if diary-selective-display 446 (list (if diary-selective-display
447 "Some text is hidden - press \"s\" in calendar \ 447 "Some text is hidden - press \"C-c C-s\" before edit/copy"
448before edit/copy"
449 "Diary")) 448 "Diary"))
450 ?\s (window-width))) 449 ?\s (window-width)))
451 "Format of the header line displayed by `diary-simple-display'. 450 "Format of the header line displayed by `diary-simple-display'.
diff --git a/lisp/files.el b/lisp/files.el
index 1bb140c0562..c8a75f67820 100644
--- a/lisp/files.el
+++ b/lisp/files.el
@@ -3640,14 +3640,15 @@ is found. Returns the new class name."
3640 (condition-case err 3640 (condition-case err
3641 (progn 3641 (progn
3642 (insert-file-contents file) 3642 (insert-file-contents file)
3643 (let* ((dir-name (file-name-directory file)) 3643 (unless (zerop (buffer-size))
3644 (class-name (intern dir-name)) 3644 (let* ((dir-name (file-name-directory file))
3645 (variables (let ((read-circle nil)) 3645 (class-name (intern dir-name))
3646 (read (current-buffer))))) 3646 (variables (let ((read-circle nil))
3647 (dir-locals-set-class-variables class-name variables) 3647 (read (current-buffer)))))
3648 (dir-locals-set-directory-class dir-name class-name 3648 (dir-locals-set-class-variables class-name variables)
3649 (nth 5 (file-attributes file))) 3649 (dir-locals-set-directory-class dir-name class-name
3650 class-name)) 3650 (nth 5 (file-attributes file)))
3651 class-name)))
3651 (error (message "Error reading dir-locals: %S" err) nil))))) 3652 (error (message "Error reading dir-locals: %S" err) nil)))))
3652 3653
3653(defcustom enable-remote-dir-locals nil 3654(defcustom enable-remote-dir-locals nil
diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog
index d0dfd100f44..0aef3732ad5 100644
--- a/lisp/gnus/ChangeLog
+++ b/lisp/gnus/ChangeLog
@@ -1,3 +1,12 @@
12012-12-03 Andreas Schwab <schwab@linux-m68k.org>
2
3 * gnus-sum.el (gnus-summary-mode-map): Bind gnus-summary-widget-forward
4 to TAB, not [tab].
5 (gnus-summary-article-map): Likewise.
6
7 * gnus-sync.el (gnus-sync-newsrc-offsets): Restore definition.
8 (gnus-sync-save): Use correct format for gnus-sync-newsrc-loader.
9
12012-11-19 Katsumi Yamaoka <yamaoka@jpl.org> 102012-11-19 Katsumi Yamaoka <yamaoka@jpl.org>
2 11
3 * message.el (message-get-reply-headers): 12 * message.el (message-get-reply-headers):
diff --git a/lisp/gnus/gnus-sum.el b/lisp/gnus/gnus-sum.el
index b44b953bec6..1d4f470aea2 100644
--- a/lisp/gnus/gnus-sum.el
+++ b/lisp/gnus/gnus-sum.el
@@ -1911,7 +1911,7 @@ increase the score of each group you read."
1911 "a" gnus-summary-post-news 1911 "a" gnus-summary-post-news
1912 "x" gnus-summary-limit-to-unread 1912 "x" gnus-summary-limit-to-unread
1913 "s" gnus-summary-isearch-article 1913 "s" gnus-summary-isearch-article
1914 [tab] gnus-summary-widget-forward 1914 "\t" gnus-summary-widget-forward
1915 [backtab] gnus-summary-widget-backward 1915 [backtab] gnus-summary-widget-backward
1916 "t" gnus-summary-toggle-header 1916 "t" gnus-summary-toggle-header
1917 "g" gnus-summary-show-article 1917 "g" gnus-summary-show-article
@@ -2076,7 +2076,7 @@ increase the score of each group you read."
2076 "W" gnus-warp-to-article 2076 "W" gnus-warp-to-article
2077 "g" gnus-summary-show-article 2077 "g" gnus-summary-show-article
2078 "s" gnus-summary-isearch-article 2078 "s" gnus-summary-isearch-article
2079 [tab] gnus-summary-widget-forward 2079 "\t" gnus-summary-widget-forward
2080 [backtab] gnus-summary-widget-backward 2080 [backtab] gnus-summary-widget-backward
2081 "P" gnus-summary-print-article 2081 "P" gnus-summary-print-article
2082 "S" gnus-sticky-article 2082 "S" gnus-sticky-article
diff --git a/lisp/gnus/gnus-sync.el b/lisp/gnus/gnus-sync.el
index b5f8379e367..493025cbe1d 100644
--- a/lisp/gnus/gnus-sync.el
+++ b/lisp/gnus/gnus-sync.el
@@ -109,6 +109,13 @@ this setting is harmless until the user chooses a sync backend."
109 :group 'gnus-sync 109 :group 'gnus-sync
110 :type '(repeat regexp)) 110 :type '(repeat regexp))
111 111
112(defcustom gnus-sync-newsrc-offsets '(2 3)
113 "List of per-group data to be synchronized."
114 :group 'gnus-sync
115 :version "24.4"
116 :type '(set (const :tag "Read ranges" 2)
117 (const :tag "Marks" 3)))
118
112(defcustom gnus-sync-global-vars nil 119(defcustom gnus-sync-global-vars nil
113 "List of global variables to be synchronized. 120 "List of global variables to be synchronized.
114You may want to sync `gnus-newsrc-last-checked-date' but pretty 121You may want to sync `gnus-newsrc-last-checked-date' but pretty
@@ -743,7 +750,15 @@ With a prefix, FORCE is set and all groups will be saved."
743 ;; entry in gnus-newsrc-alist whose group matches any of the 750 ;; entry in gnus-newsrc-alist whose group matches any of the
744 ;; gnus-sync-newsrc-groups 751 ;; gnus-sync-newsrc-groups
745 ;; TODO: keep the old contents for groups we don't have! 752 ;; TODO: keep the old contents for groups we don't have!
746 (let ((gnus-sync-newsrc-loader (gnus-sync-newsrc-loader-builder))) 753 (let ((gnus-sync-newsrc-loader
754 (loop for entry in (cdr gnus-newsrc-alist)
755 when (gnus-grep-in-list
756 (car entry) ;the group name
757 gnus-sync-newsrc-groups)
758 collect (cons (car entry)
759 (mapcar (lambda (offset)
760 (cons offset (nth offset entry)))
761 gnus-sync-newsrc-offsets)))))
747 (with-temp-file gnus-sync-backend 762 (with-temp-file gnus-sync-backend
748 (progn 763 (progn
749 (let ((coding-system-for-write gnus-ding-file-coding-system) 764 (let ((coding-system-for-write gnus-ding-file-coding-system)
diff --git a/lisp/info.el b/lisp/info.el
index b0ef5c6bc4d..6149c3fcd80 100644
--- a/lisp/info.el
+++ b/lisp/info.el
@@ -5097,8 +5097,18 @@ type returned by `Info-bookmark-make-record', which see."
5097 5097
5098;;;###autoload 5098;;;###autoload
5099(defun info-display-manual (manual) 5099(defun info-display-manual (manual)
5100 "Go to Info buffer that displays MANUAL, creating it if none already exists." 5100 "Display an Info buffer displaying MANUAL.
5101 (interactive "sManual name: ") 5101If there is an existing Info buffer for MANUAL, display it.
5102Otherwise, visit the manual in a new Info buffer."
5103 (interactive
5104 (list
5105 (progn
5106 (info-initialize)
5107 (completing-read "Manual name: "
5108 (apply-partially 'Info-read-node-name-2
5109 Info-directory-list
5110 (mapcar 'car Info-suffix-list))
5111 nil t))))
5102 (let ((blist (buffer-list)) 5112 (let ((blist (buffer-list))
5103 (manual-re (concat "\\(/\\|\\`\\)" manual "\\(\\.\\|\\'\\)")) 5113 (manual-re (concat "\\(/\\|\\`\\)" manual "\\(\\.\\|\\'\\)"))
5104 (case-fold-search t) 5114 (case-fold-search t)
@@ -5113,7 +5123,8 @@ type returned by `Info-bookmark-make-record', which see."
5113 (if found 5123 (if found
5114 (switch-to-buffer found) 5124 (switch-to-buffer found)
5115 (info-initialize) 5125 (info-initialize)
5116 (info (Info-find-file manual))))) 5126 (info (Info-find-file manual)
5127 (generate-new-buffer-name "*info*")))))
5117 5128
5118(provide 'info) 5129(provide 'info)
5119 5130
diff --git a/lisp/jka-cmpr-hook.el b/lisp/jka-cmpr-hook.el
index e4743ada045..75d1bbbad6b 100644
--- a/lisp/jka-cmpr-hook.el
+++ b/lisp/jka-cmpr-hook.el
@@ -109,6 +109,7 @@ Otherwise, it is nil.")
109 "Return information about the compression scheme of FILENAME. 109 "Return information about the compression scheme of FILENAME.
110The determination as to which compression scheme, if any, to use is 110The determination as to which compression scheme, if any, to use is
111based on the filename itself and `jka-compr-compression-info-list'." 111based on the filename itself and `jka-compr-compression-info-list'."
112 (setq filename (file-name-sans-versions filename))
112 (catch 'compression-info 113 (catch 'compression-info
113 (let ((case-fold-search nil)) 114 (let ((case-fold-search nil))
114 (dolist (x jka-compr-compression-info-list) 115 (dolist (x jka-compr-compression-info-list)
@@ -191,19 +192,6 @@ options through Custom does this automatically."
191 192
192;; I have this defined so that .Z files are assumed to be in unix 193;; I have this defined so that .Z files are assumed to be in unix
193;; compress format; and .gz files, in gzip format, and .bz2 files in bzip fmt. 194;; compress format; and .gz files, in gzip format, and .bz2 files in bzip fmt.
194
195;; FIXME? It seems ugly that one has to add "\\(~\\|\\.~[0-9]+~\\)?" to
196;; all the regexps here, in order to match backup files etc.
197;; It's trivial to modify jka-compr-get-compression-info to match
198;; regexps against file-name-sans-versions, but this regexp is also
199;; used to build a file-name-handler-alist entry.
200;; find-file-name-handler does not use file-name-sans-versions.
201;; Perhaps it should,
202;; http://lists.gnu.org/archive/html/emacs-devel/2008-02/msg00812.html,
203;; but it's used all over the place and there are probably other ramifications.
204;; One could modify jka-compr-build-file-regexp to add the backup regexp,
205;; but jka-compr-compression-info-list is a defcustom to which
206;; anything could be added, so it's easiest to leave things as they are.
207(defcustom jka-compr-compression-info-list 195(defcustom jka-compr-compression-info-list
208 ;;[regexp 196 ;;[regexp
209 ;; compr-message compr-prog compr-args 197 ;; compr-message compr-prog compr-args
@@ -310,6 +298,7 @@ variables. Setting this through Custom does that automatically."
310 (boolean :tag "Strip Extension") 298 (boolean :tag "Strip Extension")
311 (string :tag "Magic Bytes"))) 299 (string :tag "Magic Bytes")))
312 :set 'jka-compr-set 300 :set 'jka-compr-set
301 :version "24.1" ; removed version extension piece
313 :group 'jka-compr) 302 :group 'jka-compr)
314 303
315(defcustom jka-compr-mode-alist-additions 304(defcustom jka-compr-mode-alist-additions
diff --git a/lisp/net/tramp-sh.el b/lisp/net/tramp-sh.el
index 07da0b3dc16..340b7ad353d 100644
--- a/lisp/net/tramp-sh.el
+++ b/lisp/net/tramp-sh.el
@@ -813,14 +813,11 @@ my %%trans = do {
813 map {(substr(unpack(q(B8), chr $i++), 2, 6), $_)} 813 map {(substr(unpack(q(B8), chr $i++), 2, 6), $_)}
814 split //, q(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/); 814 split //, q(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/);
815}; 815};
816 816my $data;
817binmode(\\*STDIN);
818 817
819# We read in chunks of 54 bytes, to generate output lines 818# We read in chunks of 54 bytes, to generate output lines
820# of 72 chars (plus end of line) 819# of 72 chars (plus end of line)
821$/ = \\54; 820while (read STDIN, $data, 54) {
822
823while (my $data = <STDIN>) {
824 my $pad = q(); 821 my $pad = q();
825 822
826 # Only for the last chunk, and only if did not fill the last three-byte packet 823 # Only for the last chunk, and only if did not fill the last three-byte packet
diff --git a/lisp/simple.el b/lisp/simple.el
index ecd02545b41..c86f367c8a8 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -4333,14 +4333,14 @@ else--for example, incremental search, \\[beginning-of-buffer], and \\[end-of-bu
4333You can also deactivate the mark by typing \\[keyboard-quit] or 4333You can also deactivate the mark by typing \\[keyboard-quit] or
4334\\[keyboard-escape-quit]. 4334\\[keyboard-escape-quit].
4335 4335
4336Many commands change their behavior when Transient Mark mode is in effect 4336Many commands change their behavior when Transient Mark mode is
4337and the mark is active, by acting on the region instead of their usual 4337in effect and the mark is active, by acting on the region instead
4338default part of the buffer's text. Examples of such commands include 4338of their usual default part of the buffer's text. Examples of
4339\\[comment-dwim], \\[flush-lines], \\[keep-lines], \ 4339such commands include \\[comment-dwim], \\[flush-lines], \\[keep-lines],
4340\\[query-replace], \\[query-replace-regexp], \\[ispell], and \\[undo]. 4340\\[query-replace], \\[query-replace-regexp], \\[ispell], and \\[undo].
4341Invoke \\[apropos-documentation] and type \"transient\" or 4341To see the documentation of commands which are sensitive to the
4342\"mark.*active\" at the prompt, to see the documentation of 4342Transient Mark mode, invoke \\[apropos-documentation] and type \"transient\"
4343commands which are sensitive to the Transient Mark mode." 4343or \"mark.*active\" at the prompt."
4344 :global t 4344 :global t
4345 ;; It's defined in C/cus-start, this stops the d-m-m macro defining it again. 4345 ;; It's defined in C/cus-start, this stops the d-m-m macro defining it again.
4346 :variable transient-mark-mode) 4346 :variable transient-mark-mode)
diff --git a/lisp/sort.el b/lisp/sort.el
index 44f90fff379..cd0b4433ab3 100644
--- a/lisp/sort.el
+++ b/lisp/sort.el
@@ -562,6 +562,62 @@ From a program takes two point or marker arguments, BEG and END."
562 (setq ll (cdr ll))) 562 (setq ll (cdr ll)))
563 (insert (car ll))))) 563 (insert (car ll)))))
564 564
565;;;###autoload
566(defun delete-duplicate-lines (beg end &optional reverse adjacent interactive)
567 "Delete duplicate lines in the region between BEG and END.
568
569If REVERSE is nil, search and delete duplicates forward keeping the first
570occurrence of duplicate lines. If REVERSE is non-nil (when called
571interactively with C-u prefix), search and delete duplicates backward
572keeping the last occurrence of duplicate lines.
573
574If ADJACENT is non-nil (when called interactively with two C-u prefixes),
575delete repeated lines only if they are adjacent. It works like the utility
576`uniq' and is useful when lines are already sorted in a large file since
577this is more efficient in performance and memory usage than when ADJACENT
578is nil that uses additional memory to remember previous lines.
579
580When called from Lisp and INTERACTIVE is omitted or nil, return the number
581of deleted duplicate lines, do not print it; if INTERACTIVE is t, the
582function behaves in all respects as if it had been called interactively."
583 (interactive
584 (progn
585 (barf-if-buffer-read-only)
586 (list (region-beginning) (region-end)
587 (equal current-prefix-arg '(4))
588 (equal current-prefix-arg '(16))
589 t)))
590 (let ((lines (unless adjacent (make-hash-table :weakness 'key :test 'equal)))
591 line prev-line
592 (count 0)
593 (beg (copy-marker beg))
594 (end (copy-marker end)))
595 (save-excursion
596 (goto-char (if reverse end beg))
597 (if (and reverse (bolp)) (forward-char -1))
598 (while (if reverse
599 (and (> (point) beg) (not (bobp)))
600 (and (< (point) end) (not (eobp))))
601 (setq line (buffer-substring-no-properties
602 (line-beginning-position) (line-end-position)))
603 (if (if adjacent (equal line prev-line) (gethash line lines))
604 (progn
605 (delete-region (progn (forward-line 0) (point))
606 (progn (forward-line 1) (point)))
607 (if reverse (forward-line -1))
608 (setq count (1+ count)))
609 (if adjacent (setq prev-line line) (puthash line t lines))
610 (forward-line (if reverse -1 1)))))
611 (set-marker beg nil)
612 (set-marker end nil)
613 (when interactive
614 (message "Deleted %d %sduplicate line%s%s"
615 count
616 (if adjacent "adjacent " "")
617 (if (= count 1) "" "s")
618 (if reverse " backward" "")))
619 count))
620
565(provide 'sort) 621(provide 'sort)
566 622
567;;; sort.el ends here 623;;; sort.el ends here
diff --git a/lisp/textmodes/ispell.el b/lisp/textmodes/ispell.el
index f667525397c..961fb1bad83 100644
--- a/lisp/textmodes/ispell.el
+++ b/lisp/textmodes/ispell.el
@@ -2649,11 +2649,8 @@ When asynchronous processes are not supported, `run' is always returned."
2649(defun ispell-start-process () 2649(defun ispell-start-process ()
2650 "Start the Ispell process, with support for no asynchronous processes. 2650 "Start the Ispell process, with support for no asynchronous processes.
2651Keeps argument list for future Ispell invocations for no async support." 2651Keeps argument list for future Ispell invocations for no async support."
2652 ;; Local dictionary becomes the global dictionary in use. 2652 ;; `ispell-current-dictionary' and `ispell-current-personal-dictionary'
2653 (setq ispell-current-dictionary 2653 ;; are properly set in `ispell-internal-change-dictionary'.
2654 (or ispell-local-dictionary ispell-dictionary))
2655 (setq ispell-current-personal-dictionary
2656 (or ispell-local-pdict ispell-personal-dictionary))
2657 (let* ((default-directory 2654 (let* ((default-directory
2658 (if (and (file-directory-p default-directory) 2655 (if (and (file-directory-p default-directory)
2659 (file-readable-p default-directory)) 2656 (file-readable-p default-directory))
@@ -2668,8 +2665,7 @@ Keeps argument list for future Ispell invocations for no async support."
2668 (list "-d" ispell-current-dictionary)) 2665 (list "-d" ispell-current-dictionary))
2669 orig-args 2666 orig-args
2670 (if ispell-current-personal-dictionary ; Use specified pers dict. 2667 (if ispell-current-personal-dictionary ; Use specified pers dict.
2671 (list "-p" 2668 (list "-p" ispell-current-personal-dictionary))
2672 (expand-file-name ispell-current-personal-dictionary)))
2673 ;; If we are using recent aspell or hunspell, make sure we use the 2669 ;; If we are using recent aspell or hunspell, make sure we use the
2674 ;; right encoding for communication. ispell or older aspell/hunspell 2670 ;; right encoding for communication. ispell or older aspell/hunspell
2675 ;; does not support this. 2671 ;; does not support this.
@@ -2706,6 +2702,9 @@ Keeps argument list for future Ispell invocations for no async support."
2706 (let* (;; Basename of dictionary used by the spell-checker 2702 (let* (;; Basename of dictionary used by the spell-checker
2707 (dict-bname (or (car (cdr (member "-d" (ispell-get-ispell-args)))) 2703 (dict-bname (or (car (cdr (member "-d" (ispell-get-ispell-args))))
2708 ispell-current-dictionary)) 2704 ispell-current-dictionary))
2705 ;; The directory where process was started.
2706 (current-ispell-directory default-directory)
2707 ;; The default directory for the process.
2709 ;; Use "~/" as default-directory unless using Ispell with per-dir 2708 ;; Use "~/" as default-directory unless using Ispell with per-dir
2710 ;; personal dictionaries and not in a minibuffer under XEmacs 2709 ;; personal dictionaries and not in a minibuffer under XEmacs
2711 (default-directory 2710 (default-directory
@@ -2896,13 +2895,15 @@ By just answering RET you can find out what the current dictionary is."
2896 "Update the dictionary and the personal dictionary used by Ispell. 2895 "Update the dictionary and the personal dictionary used by Ispell.
2897This may kill the Ispell process; if so, a new one will be started 2896This may kill the Ispell process; if so, a new one will be started
2898when needed." 2897when needed."
2899 (let ((dict (or ispell-local-dictionary ispell-dictionary)) 2898 (let* ((dict (or ispell-local-dictionary ispell-dictionary))
2900 (pdict (or ispell-local-pdict ispell-personal-dictionary))) 2899 (pdict (or ispell-local-pdict ispell-personal-dictionary))
2900 (expanded-pdict (if pdict (expand-file-name pdict))))
2901 (unless (and (equal ispell-current-dictionary dict) 2901 (unless (and (equal ispell-current-dictionary dict)
2902 (equal ispell-current-personal-dictionary pdict)) 2902 (equal ispell-current-personal-dictionary
2903 expanded-pdict))
2903 (ispell-kill-ispell t) 2904 (ispell-kill-ispell t)
2904 (setq ispell-current-dictionary dict 2905 (setq ispell-current-dictionary dict
2905 ispell-current-personal-dictionary pdict)))) 2906 ispell-current-personal-dictionary expanded-pdict))))
2906 2907
2907;; Avoid error messages when compiling for these dynamic variables. 2908;; Avoid error messages when compiling for these dynamic variables.
2908(defvar ispell-start) 2909(defvar ispell-start)
diff --git a/lisp/url/ChangeLog b/lisp/url/ChangeLog
index 59222bcc957..fb4839358b9 100644
--- a/lisp/url/ChangeLog
+++ b/lisp/url/ChangeLog
@@ -1,3 +1,8 @@
12012-12-03 Chong Yidong <cyd@gnu.org>
2
3 * url-misc.el (url-do-terminal-emulator): Use make-term instead of
4 terminal-emulator.
5
12012-10-13 Liam Stitt <stittl@cuug.ab.ca> (tiny change) 62012-10-13 Liam Stitt <stittl@cuug.ab.ca> (tiny change)
2 7
3 * url-vars.el (url-uncompressor-alist): 8 * url-vars.el (url-uncompressor-alist):
diff --git a/lisp/url/url-misc.el b/lisp/url/url-misc.el
index dd521ccd690..8cf9cffdf6b 100644
--- a/lisp/url/url-misc.el
+++ b/lisp/url/url-misc.el
@@ -44,27 +44,21 @@
44 nil)) 44 nil))
45 45
46(defun url-do-terminal-emulator (type server port user) 46(defun url-do-terminal-emulator (type server port user)
47 (terminal-emulator 47 (switch-to-buffer
48 (generate-new-buffer (format "%s%s" (if user (concat user "@") "") server)) 48 (apply
49 (pcase type 49 'make-term
50 (`rlogin "rlogin") 50 (format "%s%s" (if user (concat user "@") "") server)
51 (`telnet "telnet") 51 (cond ((eq type 'rlogin) "rlogin")
52 (`tn3270 "tn3270") 52 ((eq type 'telnet) "telnet")
53 (_ 53 ((eq type 'tn3270) "tn3270")
54 (error "Unknown terminal emulator required: %s" type))) 54 (t (error "Unknown terminal emulator required: %s" type)))
55 (pcase type 55 nil
56 (`rlogin 56 (cond ((eq type 'rlogin)
57 (if user 57 (if user (list server "-l" user) (list server)))
58 (list server "-l" user) 58 ((eq type 'telnet)
59 (list server))) 59 (if port (list server port) (list server)))
60 (`telnet 60 ((eq type 'tn3270)
61 (if user (message "Please log in as user: %s" user)) 61 (list server))))))
62 (if port
63 (list server port)
64 (list server)))
65 (`tn3270
66 (if user (message "Please log in as user: %s" user))
67 (list server)))))
68 62
69;;;###autoload 63;;;###autoload
70(defun url-generic-emulator-loader (url) 64(defun url-generic-emulator-loader (url)
diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el
index 0224211e6cf..d001df87d5c 100644
--- a/lisp/vc/vc.el
+++ b/lisp/vc/vc.el
@@ -2554,8 +2554,12 @@ backend to NEW-BACKEND, and unregister FILE from the current backend.
2554 2554
2555;;;###autoload 2555;;;###autoload
2556(defun vc-delete-file (file) 2556(defun vc-delete-file (file)
2557 "Delete file and mark it as such in the version control system." 2557 "Delete file and mark it as such in the version control system.
2558 (interactive "fVC delete file: ") 2558If called interactively, read FILE, defaulting to the current
2559buffer's file name if it's under version control."
2560 (interactive (list (read-file-name "VC delete file: " nil
2561 (when (vc-backend buffer-file-name)
2562 buffer-file-name) t)))
2559 (setq file (expand-file-name file)) 2563 (setq file (expand-file-name file))
2560 (let ((buf (get-file-buffer file)) 2564 (let ((buf (get-file-buffer file))
2561 (backend (vc-backend file))) 2565 (backend (vc-backend file)))
@@ -2593,8 +2597,13 @@ backend to NEW-BACKEND, and unregister FILE from the current backend.
2593 2597
2594;;;###autoload 2598;;;###autoload
2595(defun vc-rename-file (old new) 2599(defun vc-rename-file (old new)
2596 "Rename file OLD to NEW in both work area and repository." 2600 "Rename file OLD to NEW in both work area and repository.
2597 (interactive "fVC rename file: \nFRename to: ") 2601If called interactively, read OLD and NEW, defaulting OLD to the
2602current buffer's file name if it's under version control."
2603 (interactive (list (read-file-name "VC rename file: " nil
2604 (when (vc-backend buffer-file-name)
2605 buffer-file-name) t)
2606 (read-file-name "Rename to: ")))
2598 ;; in CL I would have said (setq new (merge-pathnames new old)) 2607 ;; in CL I would have said (setq new (merge-pathnames new old))
2599 (let ((old-base (file-name-nondirectory old))) 2608 (let ((old-base (file-name-nondirectory old)))
2600 (when (and (not (string= "" old-base)) 2609 (when (and (not (string= "" old-base))
diff --git a/msdos/ChangeLog b/msdos/ChangeLog
index 753931ae097..1fdd9316847 100644
--- a/msdos/ChangeLog
+++ b/msdos/ChangeLog
@@ -1,3 +1,8 @@
12012-12-03 Eli Zaretskii <eliz@gnu.org>
2
3 * sed1v2.inp: Dump emacs.exe and copy to b-emacs.exe before
4 generating leim-list.el.
5
12012-11-24 Ken Brown <kbrown@cornell.edu> 62012-11-24 Ken Brown <kbrown@cornell.edu>
2 7
3 * sed2v2.inp (HAVE_MOUSE): Remove. 8 * sed2v2.inp (HAVE_MOUSE): Remove.
diff --git a/msdos/sed1v2.inp b/msdos/sed1v2.inp
index 84f24bf2c1a..0ee7510bec1 100644
--- a/msdos/sed1v2.inp
+++ b/msdos/sed1v2.inp
@@ -157,6 +157,12 @@ s/^ [^ ]*move-if-change / update /
157/^ echo[ ][ ]*timestamp/s/echo /djecho / 157/^ echo[ ][ ]*timestamp/s/echo /djecho /
158/^ .*djecho timestamp/a\ 158/^ .*djecho timestamp/a\
159 @rm -f gl-tmp 159 @rm -f gl-tmp
160/^ cd \$(leimdir) && \$(MAKE)/i\
161 $(RUN_TEMACS) -batch -l loadup dump\
162 stubify emacs\
163 stubedit emacs.exe minstack=2048k\
164 rm -f b-emacs$(EXEEXT)\
165 cp emacs$(EXEEXT) b-emacs$(EXEEXT)
160/^ cd \$(leimdir) && \$(MAKE)/c\ 166/^ cd \$(leimdir) && \$(MAKE)/c\
161 $(MAKE) $(MFLAGS) -C $(leimdir) leim-list.el EMACS=$(bootstrap_exe) 167 $(MAKE) $(MFLAGS) -C $(leimdir) leim-list.el EMACS=$(bootstrap_exe)
162/^ cd \$(lib) && \$(MAKE)/c\ 168/^ cd \$(lib) && \$(MAKE)/c\
diff --git a/src/ChangeLog b/src/ChangeLog
index a6fabdccdea..1a91eb0f1a3 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,137 @@
12012-12-03 Paul Eggert <eggert@cs.ucla.edu>
2
3 Don't let call-process be a zombie factory (Bug#12980).
4 Fixing this bug required some cleanup of the signal-handling code.
5 As a side effect, this change also fixes a longstanding rare race
6 condition whereby Emacs could mistakenly kill unrelated processes,
7 and it fixes a bug where a second C-g does not kill a recalcitrant
8 synchronous process in GNU/Linux and similar platforms.
9 The patch should also fix the last vestiges of Bug#9488,
10 a bug which has mostly been fixed on the trunk by other changes.
11 * callproc.c, process.h (synch_process_alive, synch_process_death)
12 (synch_process_termsig, sync_process_retcode):
13 Remove. All uses removed, to simplify analysis and so that
14 less consing is done inside critical sections.
15 * callproc.c (call_process_exited): Remove. All uses replaced
16 with !synch_process_pid.
17 * callproc.c (synch_process_pid, synch_process_fd): New static vars.
18 These take the role of what used to be in unwind-protect arg.
19 All uses changed.
20 (block_child_signal, unblock_child_signal):
21 New functions, to avoid races that could kill innocent-victim processes.
22 (call_process_kill, call_process_cleanup, Fcall_process): Use them.
23 (call_process_kill): Record killed processes as deleted, so that
24 zombies do not clutter up the system. Do this inside a critical
25 section, to avoid a race that would allow the clutter.
26 (call_process_cleanup): Fix code so that the second C-g works again
27 on common platforms such as GNU/Linux.
28 (Fcall_process): Create the child process in a critical section,
29 to fix a race condition. If creating an asynchronous process,
30 record it as deleted so that zombies do not clutter up the system.
31 Do unwind-protect for WINDOWSNT too, as that's simpler in the
32 light of these changes. Omit unnecessary call to emacs_close
33 before failure, as the unwind-protect code does that.
34 * callproc.c (call_process_cleanup):
35 * w32proc.c (waitpid): Simplify now that synch_process_alive is gone.
36 * process.c (record_deleted_pid): New function, containing
37 code refactored out of Fdelete_process.
38 (Fdelete_process): Use it.
39 (process_status_retrieved): Remove. All callers changed to use
40 child_status_change.
41 (record_child_status_change): Remove, folding its contents into ...
42 (handle_child_signal): ... this signal handler. Now, this
43 function is purely a handler for SIGCHLD, and is not called after
44 a synchronous waitpid returns; the synchronous code is moved to
45 wait_for_termination. There is no need to worry about reaping
46 more than one child now.
47 * sysdep.c (get_child_status, child_status_changed): New functions.
48 (wait_for_termination): Now takes int * status and bool
49 interruptible arguments, too. Do not record child status change;
50 that's now the caller's responsibility. All callers changed.
51 Reimplement in terms of get_child_status.
52 (wait_for_termination_1, interruptible_wait_for_termination):
53 Remove. All callers changed to use wait_for_termination.
54 * syswait.h: Include <stdbool.h>, for bool.
55 (record_child_status_change, interruptible_wait_for_termination):
56 Remove decls.
57 (record_deleted_pid, child_status_changed): New decls.
58 (wait_for_termination): Adjust to API changes noted above.
59
60 * bytecode.c, lisp.h (Qbytecode): Remove.
61 No longer needed after 2012-11-20 interactive-p changes.
62
632012-12-03 Eli Zaretskii <eliz@gnu.org>
64
65 * xdisp.c (redisplay_window): If the cursor is visible, but inside
66 the scroll margin, move point outside the margin. (Bug#13055)
67
682012-12-03 Jan Djärv <jan.h.d@swipnet.se>
69
70 * gtkutil.c (my_log_handler): New function.
71 (xg_set_geometry): Set log handler to my_log_handler (Bug#11177).
72
732012-12-03 Dmitry Antipov <dmantipov@yandex.ru>
74
75 * lisp.h (modify_region): Rename to...
76 (modify_region_1): ...new prototype.
77 * textprop.c (modify_region): Now static. Adjust users.
78 * insdel.c (modify_region): Rename to...
79 (modify_region_1): ...new function to work with current buffer.
80 Adjust comment and users. Use true and false for booleans.
81
822012-12-03 Dmitry Antipov <dmantipov@yandex.ru>
83
84 * alloc.c (free_save_value): New function.
85 (safe_alloca_unwind): Use it.
86 * lisp.h (free_save_value): New prototype.
87 * editfns.c (save_excursion_save): Use Lisp_Misc_Save_Value.
88 Add comment.
89 (save_excursion_restore): Adjust to match saved data structure.
90 Use free_save_value to offload some work from GC. Drop obsolete
91 #if 0 code.
92
932012-12-03 Chong Yidong <cyd@gnu.org>
94
95 * fileio.c (Vauto_save_list_file_name): Doc fix.
96
972012-12-03 Fabrice Popineau <fabrice.popineau@gmail.com>
98
99 * w32fns.c: Remove prototype of atof.
100 (syspage_mask): Declared DWORD_PTR, for compatibility with 64-bit
101 builds.
102 (file_dialog_callback): Declared UINT_PTR.
103
104 * w32common.h (syspage_mask): Declare DWORD_PTR, for compatibility
105 with 64-bit builds.
106
107 * w32.c (FILE_DEVICE_FILE_SYSTEM, METHOD_BUFFERED)
108 (FILE_ANY_ACCESS, CTL_CODE) [_MSC_VER]: Define only if not already
109 defined.
110
1112012-12-03 Glenn Morris <rgm@gnu.org>
112
113 * data.c (Fboundp, Fsymbol_value): Doc fix re lexical-binding.
114
1152012-12-02 Paul Eggert <eggert@cs.ucla.edu>
116
117 Fix xpalloc confusion after memory is exhausted.
118 * alloc.c (xpalloc): Comment fix.
119 * charset.c (Fdefine_charset_internal): If xpalloc exhausts memory
120 and signals an error, do not clear charset_table_size, as
121 charset_table is still valid.
122 * doprnt.c (evxprintf): Clear *BUF after freeing it.
123
124 Use execve to avoid need to munge environ (Bug#13054).
125 * callproc.c (Fcall_process):
126 * process.c (create_process):
127 Don't save and restore environ; no longer needed.
128 * callproc.c (child_setup):
129 Use execve, not execvp, to preserve environ.
130
1312012-12-01 Paul Eggert <eggert@cs.ucla.edu>
132
133 * xterm.c (x_draw_image_relief): Remove unused locals (Bug#10500).
134
12012-12-01 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> 1352012-12-01 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp>
2 136
3 * xterm.c (x_draw_relief_rect, x_draw_image_relief): Fix relief 137 * xterm.c (x_draw_relief_rect, x_draw_image_relief): Fix relief
diff --git a/src/alloc.c b/src/alloc.c
index 28c9b51dab4..0f105f87207 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -761,13 +761,17 @@ xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size)
761 infinity. 761 infinity.
762 762
763 If PA is null, then allocate a new array instead of reallocating 763 If PA is null, then allocate a new array instead of reallocating
764 the old one. Thus, to grow an array A without saving its old 764 the old one.
765 contents, invoke xfree (A) immediately followed by xgrowalloc (0,
766 &NITEMS, ...).
767 765
768 Block interrupt input as needed. If memory exhaustion occurs, set 766 Block interrupt input as needed. If memory exhaustion occurs, set
769 *NITEMS to zero if PA is null, and signal an error (i.e., do not 767 *NITEMS to zero if PA is null, and signal an error (i.e., do not
770 return). */ 768 return).
769
770 Thus, to grow an array A without saving its old contents, do
771 { xfree (A); A = NULL; A = xpalloc (NULL, &AITEMS, ...); }.
772 The A = NULL avoids a dangling pointer if xpalloc exhausts memory
773 and signals an error, and later this code is reexecuted and
774 attempts to free A. */
771 775
772void * 776void *
773xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, 777xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min,
@@ -822,12 +826,7 @@ xstrdup (const char *s)
822Lisp_Object 826Lisp_Object
823safe_alloca_unwind (Lisp_Object arg) 827safe_alloca_unwind (Lisp_Object arg)
824{ 828{
825 register struct Lisp_Save_Value *p = XSAVE_VALUE (arg); 829 free_save_value (arg);
826
827 p->dogc = 0;
828 xfree (p->pointer);
829 p->pointer = 0;
830 free_misc (arg);
831 return Qnil; 830 return Qnil;
832} 831}
833 832
@@ -3361,6 +3360,19 @@ make_save_value (void *pointer, ptrdiff_t integer)
3361 return val; 3360 return val;
3362} 3361}
3363 3362
3363/* Free a Lisp_Misc_Save_Value object. */
3364
3365void
3366free_save_value (Lisp_Object save)
3367{
3368 register struct Lisp_Save_Value *p = XSAVE_VALUE (save);
3369
3370 p->dogc = 0;
3371 xfree (p->pointer);
3372 p->pointer = NULL;
3373 free_misc (save);
3374}
3375
3364/* Return a Lisp_Misc_Overlay object with specified START, END and PLIST. */ 3376/* Return a Lisp_Misc_Overlay object with specified START, END and PLIST. */
3365 3377
3366Lisp_Object 3378Lisp_Object
diff --git a/src/bytecode.c b/src/bytecode.c
index 3267c7c8c76..4c5ac151de1 100644
--- a/src/bytecode.c
+++ b/src/bytecode.c
@@ -87,8 +87,6 @@ Lisp_Object Qbyte_code_meter;
87#endif /* BYTE_CODE_METER */ 87#endif /* BYTE_CODE_METER */
88 88
89 89
90Lisp_Object Qbytecode;
91
92/* Byte codes: */ 90/* Byte codes: */
93 91
94#define BYTE_CODES \ 92#define BYTE_CODES \
@@ -1963,8 +1961,6 @@ exec_byte_code (Lisp_Object bytestr, Lisp_Object vector, Lisp_Object maxdepth,
1963void 1961void
1964syms_of_bytecode (void) 1962syms_of_bytecode (void)
1965{ 1963{
1966 DEFSYM (Qbytecode, "byte-code");
1967
1968 defsubr (&Sbyte_code); 1964 defsubr (&Sbyte_code);
1969 1965
1970#ifdef BYTE_CODE_METER 1966#ifdef BYTE_CODE_METER
diff --git a/src/callproc.c b/src/callproc.c
index 167663a45c6..21c52d09e6b 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -67,88 +67,110 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
67/* Pattern used by call-process-region to make temp files. */ 67/* Pattern used by call-process-region to make temp files. */
68static Lisp_Object Vtemp_file_name_pattern; 68static Lisp_Object Vtemp_file_name_pattern;
69 69
70/* True if we are about to fork off a synchronous process or if we 70/* The next two variables are valid only while record-unwind-protect
71 are waiting for it. */ 71 is in place during call-process for a synchronous subprocess. At
72bool synch_process_alive; 72 other times, their contents are irrelevant. Doing this via static
73 73 C variables is more convenient than putting them into the arguments
74/* Nonzero => this is a string explaining death of synchronous subprocess. */ 74 of record-unwind-protect, as they need to be updated at randomish
75const char *synch_process_death; 75 times in the code, and Lisp cannot always store these values as
76 Emacs integers. It's safe to use static variables here, as the
77 code is never invoked reentrantly. */
78
79/* If nonzero, a process-ID that has not been reaped. */
80static pid_t synch_process_pid;
81
82/* If nonnegative, a file descriptor that has not been closed. */
83static int synch_process_fd;
84
85/* Block SIGCHLD. */
76 86
77/* Nonzero => this is the signal number that terminated the subprocess. */ 87static void
78int synch_process_termsig; 88block_child_signal (void)
89{
90#ifdef SIGCHLD
91 sigset_t blocked;
92 sigemptyset (&blocked);
93 sigaddset (&blocked, SIGCHLD);
94 pthread_sigmask (SIG_BLOCK, &blocked, 0);
95#endif
96}
79 97
80/* If synch_process_death is zero, 98/* Unblock SIGCHLD. */
81 this is exit code of synchronous subprocess. */
82int synch_process_retcode;
83 99
84 100static void
85/* Clean up when exiting Fcall_process. 101unblock_child_signal (void)
86 On MSDOS, delete the temporary file on any kind of termination. 102{
87 On Unix, kill the process and any children on termination by signal. */ 103#ifdef SIGCHLD
104 pthread_sigmask (SIG_SETMASK, &empty_mask, 0);
105#endif
106}
88 107
89/* True if this is termination due to exit. */ 108/* Clean up when exiting call_process_cleanup. */
90static bool call_process_exited;
91 109
92static Lisp_Object 110static Lisp_Object
93call_process_kill (Lisp_Object fdpid) 111call_process_kill (Lisp_Object ignored)
94{ 112{
95 int fd; 113 if (0 <= synch_process_fd)
96 pid_t pid; 114 emacs_close (synch_process_fd);
97 CONS_TO_INTEGER (Fcar (fdpid), int, fd); 115
98 CONS_TO_INTEGER (Fcdr (fdpid), pid_t, pid); 116 /* If PID is reapable, kill it and record it as a deleted process.
99 emacs_close (fd); 117 Do this in a critical section. Unless PID is wedged it will be
100 EMACS_KILLPG (pid, SIGKILL); 118 reaped on receipt of the first SIGCHLD after the critical section. */
101 synch_process_alive = 0; 119 if (synch_process_pid)
120 {
121 block_child_signal ();
122 record_deleted_pid (synch_process_pid);
123 EMACS_KILLPG (synch_process_pid, SIGKILL);
124 unblock_child_signal ();
125 }
126
102 return Qnil; 127 return Qnil;
103} 128}
104 129
130/* Clean up when exiting Fcall_process.
131 On MSDOS, delete the temporary file on any kind of termination.
132 On Unix, kill the process and any children on termination by signal. */
133
105static Lisp_Object 134static Lisp_Object
106call_process_cleanup (Lisp_Object arg) 135call_process_cleanup (Lisp_Object arg)
107{ 136{
108 Lisp_Object fdpid = Fcdr (arg); 137#ifdef MSDOS
109 int fd; 138 Lisp_Object buffer = Fcar (arg);
110#if defined (MSDOS) 139 Lisp_Object file = Fcdr (arg);
111 Lisp_Object file;
112#else 140#else
113 pid_t pid; 141 Lisp_Object buffer = arg;
114#endif 142#endif
115 143
116 Fset_buffer (Fcar (arg)); 144 Fset_buffer (buffer);
117 CONS_TO_INTEGER (Fcar (fdpid), int, fd);
118
119#if defined (MSDOS)
120 /* for MSDOS fdpid is really (fd . tempfile) */
121 file = Fcdr (fdpid);
122 /* FD is -1 and FILE is "" when we didn't actually create a
123 temporary file in call-process. */
124 if (fd >= 0)
125 emacs_close (fd);
126 if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0'))
127 unlink (SDATA (file));
128#else /* not MSDOS */
129 CONS_TO_INTEGER (Fcdr (fdpid), pid_t, pid);
130
131 if (call_process_exited)
132 {
133 emacs_close (fd);
134 return Qnil;
135 }
136 145
137 if (EMACS_KILLPG (pid, SIGINT) == 0) 146#ifndef MSDOS
147 /* If the process still exists, kill its process group. */
148 if (synch_process_pid)
138 { 149 {
139 ptrdiff_t count = SPECPDL_INDEX (); 150 ptrdiff_t count = SPECPDL_INDEX ();
140 record_unwind_protect (call_process_kill, fdpid); 151 EMACS_KILLPG (synch_process_pid, SIGINT);
152 record_unwind_protect (call_process_kill, make_number (0));
141 message1 ("Waiting for process to die...(type C-g again to kill it instantly)"); 153 message1 ("Waiting for process to die...(type C-g again to kill it instantly)");
142 immediate_quit = 1; 154 immediate_quit = 1;
143 QUIT; 155 QUIT;
144 wait_for_termination (pid); 156 wait_for_termination (synch_process_pid, 0, 1);
157 synch_process_pid = 0;
145 immediate_quit = 0; 158 immediate_quit = 0;
146 specpdl_ptr = specpdl + count; /* Discard the unwind protect. */ 159 specpdl_ptr = specpdl + count; /* Discard the unwind protect. */
147 message1 ("Waiting for process to die...done"); 160 message1 ("Waiting for process to die...done");
148 } 161 }
149 synch_process_alive = 0; 162#endif
150 emacs_close (fd); 163
151#endif /* not MSDOS */ 164 if (0 <= synch_process_fd)
165 emacs_close (synch_process_fd);
166
167#ifdef MSDOS
168 /* FILE is "" when we didn't actually create a temporary file in
169 call-process. */
170 if (!(strcmp (SDATA (file), NULL_DEVICE) == 0 || SREF (file, 0) == '\0'))
171 unlink (SDATA (file));
172#endif
173
152 return Qnil; 174 return Qnil;
153} 175}
154 176
@@ -181,9 +203,10 @@ If you quit, the process is killed with SIGINT, or SIGKILL if you quit again.
181usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) 203usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
182 (ptrdiff_t nargs, Lisp_Object *args) 204 (ptrdiff_t nargs, Lisp_Object *args)
183{ 205{
184 Lisp_Object infile, buffer, current_dir, path, cleanup_info_tail; 206 Lisp_Object infile, buffer, current_dir, path;
185 bool display_p; 207 bool display_p;
186 int fd0, fd1, filefd; 208 int fd0, fd1, filefd;
209 int status;
187 ptrdiff_t count = SPECPDL_INDEX (); 210 ptrdiff_t count = SPECPDL_INDEX ();
188 USE_SAFE_ALLOCA; 211 USE_SAFE_ALLOCA;
189 212
@@ -199,7 +222,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
199#else 222#else
200 pid_t pid; 223 pid_t pid;
201#endif 224#endif
202 int vfork_errno; 225 int child_errno;
203 int fd_output = -1; 226 int fd_output = -1;
204 struct coding_system process_coding; /* coding-system of process output */ 227 struct coding_system process_coding; /* coding-system of process output */
205 struct coding_system argument_coding; /* coding-system of arguments */ 228 struct coding_system argument_coding; /* coding-system of arguments */
@@ -488,24 +511,11 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
488 } 511 }
489 512
490 { 513 {
491 /* child_setup must clobber environ in systems with true vfork.
492 Protect it from permanent change. */
493 char **save_environ = environ;
494 int fd_error = fd1; 514 int fd_error = fd1;
495 515
496 if (fd_output >= 0) 516 if (fd_output >= 0)
497 fd1 = fd_output; 517 fd1 = fd_output;
498 518
499 /* Record that we're about to create a synchronous process. */
500 synch_process_alive = 1;
501
502 /* These vars record information from process termination.
503 Clear them now before process can possibly terminate,
504 to avoid timing error if process terminates soon. */
505 synch_process_death = 0;
506 synch_process_retcode = 0;
507 synch_process_termsig = 0;
508
509 if (NILP (error_file)) 519 if (NILP (error_file))
510 fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0); 520 fd_error = emacs_open (NULL_DEVICE, O_WRONLY, 0);
511 else if (STRINGP (error_file)) 521 else if (STRINGP (error_file))
@@ -538,23 +548,21 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
538 548
539#ifdef MSDOS /* MW, July 1993 */ 549#ifdef MSDOS /* MW, July 1993 */
540 /* Note that on MSDOS `child_setup' actually returns the child process 550 /* Note that on MSDOS `child_setup' actually returns the child process
541 exit status, not its PID, so we assign it to `synch_process_retcode' 551 exit status, not its PID, so assign it to status below. */
542 below. */
543 pid = child_setup (filefd, outfilefd, fd_error, new_argv, 0, current_dir); 552 pid = child_setup (filefd, outfilefd, fd_error, new_argv, 0, current_dir);
544 553 child_errno = errno;
545 /* Record that the synchronous process exited and note its
546 termination status. */
547 synch_process_alive = 0;
548 synch_process_retcode = pid;
549 if (synch_process_retcode < 0) /* means it couldn't be exec'ed */
550 {
551 synchronize_system_messages_locale ();
552 synch_process_death = strerror (errno);
553 }
554 554
555 emacs_close (outfilefd); 555 emacs_close (outfilefd);
556 if (fd_error != outfilefd) 556 if (fd_error != outfilefd)
557 emacs_close (fd_error); 557 emacs_close (fd_error);
558 if (pid < 0)
559 {
560 synchronize_system_messages_locale ();
561 return
562 code_convert_string_norecord (build_string (strerror (child_errno)),
563 Vlocale_coding_system, 0);
564 }
565 status = pid;
558 fd1 = -1; /* No harm in closing that one! */ 566 fd1 = -1; /* No harm in closing that one! */
559 if (tempfile) 567 if (tempfile)
560 { 568 {
@@ -572,12 +580,21 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
572 else 580 else
573 fd0 = -1; /* We are not going to read from tempfile. */ 581 fd0 = -1; /* We are not going to read from tempfile. */
574#else /* not MSDOS */ 582#else /* not MSDOS */
583
584 /* Do the unwind-protect now, even though the pid is not known, so
585 that no storage allocation is done in the critical section.
586 The actual PID will be filled in during the critical section. */
587 synch_process_pid = 0;
588 synch_process_fd = fd0;
589 record_unwind_protect (call_process_cleanup, Fcurrent_buffer ());
590
591 block_input ();
592 block_child_signal ();
593
575#ifdef WINDOWSNT 594#ifdef WINDOWSNT
576 pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); 595 pid = child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir);
577#else /* not WINDOWSNT */ 596#else /* not WINDOWSNT */
578 597
579 block_input ();
580
581 /* vfork, and prevent local vars from being clobbered by the vfork. */ 598 /* vfork, and prevent local vars from being clobbered by the vfork. */
582 { 599 {
583 Lisp_Object volatile buffer_volatile = buffer; 600 Lisp_Object volatile buffer_volatile = buffer;
@@ -594,9 +611,9 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
594 ptrdiff_t volatile count_volatile = count; 611 ptrdiff_t volatile count_volatile = count;
595 ptrdiff_t volatile sa_count_volatile = sa_count; 612 ptrdiff_t volatile sa_count_volatile = sa_count;
596 char **volatile new_argv_volatile = new_argv; 613 char **volatile new_argv_volatile = new_argv;
597 char **volatile new_save_environ = save_environ;
598 614
599 pid = vfork (); 615 pid = vfork ();
616 child_errno = errno;
600 617
601 buffer = buffer_volatile; 618 buffer = buffer_volatile;
602 coding_systems = coding_systems_volatile; 619 coding_systems = coding_systems_volatile;
@@ -612,11 +629,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
612 count = count_volatile; 629 count = count_volatile;
613 sa_count = sa_count_volatile; 630 sa_count = sa_count_volatile;
614 new_argv = new_argv_volatile; 631 new_argv = new_argv_volatile;
615 save_environ = new_save_environ;
616 } 632 }
617 633
618 if (pid == 0) 634 if (pid == 0)
619 { 635 {
636 unblock_child_signal ();
637
620 if (fd0 >= 0) 638 if (fd0 >= 0)
621 emacs_close (fd0); 639 emacs_close (fd0);
622 640
@@ -628,18 +646,26 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
628 child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir); 646 child_setup (filefd, fd1, fd_error, new_argv, 0, current_dir);
629 } 647 }
630 648
631 vfork_errno = errno;
632 unblock_input ();
633
634#endif /* not WINDOWSNT */ 649#endif /* not WINDOWSNT */
635 650
651 child_errno = errno;
652
653 if (0 < pid)
654 {
655 if (INTEGERP (buffer))
656 record_deleted_pid (pid);
657 else
658 synch_process_pid = pid;
659 }
660
661 unblock_child_signal ();
662 unblock_input ();
663
636 /* The MSDOS case did this already. */ 664 /* The MSDOS case did this already. */
637 if (fd_error >= 0) 665 if (fd_error >= 0)
638 emacs_close (fd_error); 666 emacs_close (fd_error);
639#endif /* not MSDOS */ 667#endif /* not MSDOS */
640 668
641 environ = save_environ;
642
643 /* Close most of our file descriptors, but not fd0 669 /* Close most of our file descriptors, but not fd0
644 since we will use that to read input from. */ 670 since we will use that to read input from. */
645 emacs_close (filefd); 671 emacs_close (filefd);
@@ -651,9 +677,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
651 677
652 if (pid < 0) 678 if (pid < 0)
653 { 679 {
654 if (fd0 >= 0) 680 errno = child_errno;
655 emacs_close (fd0);
656 errno = vfork_errno;
657 report_file_error ("Doing vfork", Qnil); 681 report_file_error ("Doing vfork", Qnil);
658 } 682 }
659 683
@@ -664,19 +688,12 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
664 return Qnil; 688 return Qnil;
665 } 689 }
666 690
667 /* Enable sending signal if user quits below. */
668 call_process_exited = 0;
669
670#if defined (MSDOS) 691#if defined (MSDOS)
671 /* MSDOS needs different cleanup information. */ 692 /* MSDOS needs different cleanup information. */
672 cleanup_info_tail = build_string (tempfile ? tempfile : "");
673#else
674 cleanup_info_tail = INTEGER_TO_CONS (pid);
675#endif /* not MSDOS */
676 record_unwind_protect (call_process_cleanup, 693 record_unwind_protect (call_process_cleanup,
677 Fcons (Fcurrent_buffer (), 694 Fcons (Fcurrent_buffer (),
678 Fcons (INTEGER_TO_CONS (fd0), 695 build_string (tempfile ? tempfile : "")));
679 cleanup_info_tail))); 696#endif
680 697
681 if (BUFFERP (buffer)) 698 if (BUFFERP (buffer))
682 Fset_buffer (buffer); 699 Fset_buffer (buffer);
@@ -863,38 +880,34 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */)
863 880
864#ifndef MSDOS 881#ifndef MSDOS
865 /* Wait for it to terminate, unless it already has. */ 882 /* Wait for it to terminate, unless it already has. */
866 if (output_to_buffer) 883 wait_for_termination (pid, &status, !output_to_buffer);
867 wait_for_termination (pid);
868 else
869 interruptible_wait_for_termination (pid);
870#endif 884#endif
871 885
872 immediate_quit = 0; 886 immediate_quit = 0;
873 887
874 /* Don't kill any children that the subprocess may have left behind 888 /* Don't kill any children that the subprocess may have left behind
875 when exiting. */ 889 when exiting. */
876 call_process_exited = 1; 890 synch_process_pid = 0;
877 891
878 SAFE_FREE (); 892 SAFE_FREE ();
879 unbind_to (count, Qnil); 893 unbind_to (count, Qnil);
880 894
881 if (synch_process_termsig) 895 if (WIFSIGNALED (status))
882 { 896 {
883 const char *signame; 897 const char *signame;
884 898
885 synchronize_system_messages_locale (); 899 synchronize_system_messages_locale ();
886 signame = strsignal (synch_process_termsig); 900 signame = strsignal (WTERMSIG (status));
887 901
888 if (signame == 0) 902 if (signame == 0)
889 signame = "unknown"; 903 signame = "unknown";
890 904
891 synch_process_death = signame; 905 return code_convert_string_norecord (build_string (signame),
906 Vlocale_coding_system, 0);
892 } 907 }
893 908
894 if (synch_process_death) 909 eassert (WIFEXITED (status));
895 return code_convert_string_norecord (build_string (synch_process_death), 910 return make_number (WEXITSTATUS (status));
896 Vlocale_coding_system, 0);
897 return make_number (synch_process_retcode);
898} 911}
899 912
900static Lisp_Object 913static Lisp_Object
@@ -1092,10 +1105,6 @@ add_env (char **env, char **new_env, char *string)
1092 Initialize inferior's priority, pgrp, connected dir and environment. 1105 Initialize inferior's priority, pgrp, connected dir and environment.
1093 then exec another program based on new_argv. 1106 then exec another program based on new_argv.
1094 1107
1095 This function may change environ for the superior process.
1096 Therefore, the superior process must save and restore the value
1097 of environ around the vfork and the call to this function.
1098
1099 If SET_PGRP, put the subprocess into a separate process group. 1108 If SET_PGRP, put the subprocess into a separate process group.
1100 1109
1101 CURRENT_DIR is an elisp string giving the path of the current 1110 CURRENT_DIR is an elisp string giving the path of the current
@@ -1298,11 +1307,7 @@ child_setup (int in, int out, int err, char **new_argv, bool set_pgrp,
1298 setpgid (0, 0); 1307 setpgid (0, 0);
1299 tcsetpgrp (0, pid); 1308 tcsetpgrp (0, pid);
1300 1309
1301 /* execvp does not accept an environment arg so the only way 1310 execve (new_argv[0], new_argv, env);
1302 to pass this environment is to set environ. Our caller
1303 is responsible for restoring the ambient value of environ. */
1304 environ = env;
1305 execvp (new_argv[0], new_argv);
1306 1311
1307 emacs_write (1, "Can't exec program: ", 20); 1312 emacs_write (1, "Can't exec program: ", 20);
1308 emacs_write (1, new_argv[0], strlen (new_argv[0])); 1313 emacs_write (1, new_argv[0], strlen (new_argv[0]));
diff --git a/src/casefiddle.c b/src/casefiddle.c
index e3654627576..d9c6a078973 100644
--- a/src/casefiddle.c
+++ b/src/casefiddle.c
@@ -213,7 +213,7 @@ casify_region (enum case_action flag, Lisp_Object b, Lisp_Object e)
213 validate_region (&b, &e); 213 validate_region (&b, &e);
214 start = XFASTINT (b); 214 start = XFASTINT (b);
215 end = XFASTINT (e); 215 end = XFASTINT (e);
216 modify_region (current_buffer, start, end, 0); 216 modify_region_1 (start, end, false);
217 record_change (start, end - start); 217 record_change (start, end - start);
218 start_byte = CHAR_TO_BYTE (start); 218 start_byte = CHAR_TO_BYTE (start);
219 219
diff --git a/src/charset.c b/src/charset.c
index c9133c780e8..43be0e9c780 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -1142,12 +1142,14 @@ usage: (define-charset-internal ...) */)
1142 example, the IDs are stuffed into struct 1142 example, the IDs are stuffed into struct
1143 coding_system.charbuf[i] entries, which are 'int'. */ 1143 coding_system.charbuf[i] entries, which are 'int'. */
1144 int old_size = charset_table_size; 1144 int old_size = charset_table_size;
1145 ptrdiff_t new_size = old_size;
1145 struct charset *new_table = 1146 struct charset *new_table =
1146 xpalloc (0, &charset_table_size, 1, 1147 xpalloc (0, &new_size, 1,
1147 min (INT_MAX, MOST_POSITIVE_FIXNUM), 1148 min (INT_MAX, MOST_POSITIVE_FIXNUM),
1148 sizeof *charset_table); 1149 sizeof *charset_table);
1149 memcpy (new_table, charset_table, old_size * sizeof *new_table); 1150 memcpy (new_table, charset_table, old_size * sizeof *new_table);
1150 charset_table = new_table; 1151 charset_table = new_table;
1152 charset_table_size = new_size;
1151 /* FIXME: This leaks memory, as the old charset_table becomes 1153 /* FIXME: This leaks memory, as the old charset_table becomes
1152 unreachable. If the old charset table is charset_table_init 1154 unreachable. If the old charset table is charset_table_init
1153 then this leak is intentional; otherwise, it's unclear. 1155 then this leak is intentional; otherwise, it's unclear.
diff --git a/src/data.c b/src/data.c
index 5fc6afaaa03..a72fa3e2b5f 100644
--- a/src/data.c
+++ b/src/data.c
@@ -506,7 +506,9 @@ DEFUN ("setcdr", Fsetcdr, Ssetcdr, 2, 2, 0,
506/* Extract and set components of symbols. */ 506/* Extract and set components of symbols. */
507 507
508DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0, 508DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0,
509 doc: /* Return t if SYMBOL's value is not void. */) 509 doc: /* Return t if SYMBOL's value is not void.
510Note that if `lexical-binding' is in effect, this refers to the
511global value outside of any lexical scope. */)
510 (register Lisp_Object symbol) 512 (register Lisp_Object symbol)
511{ 513{
512 Lisp_Object valcontents; 514 Lisp_Object valcontents;
@@ -1047,7 +1049,9 @@ find_symbol_value (Lisp_Object symbol)
1047} 1049}
1048 1050
1049DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0, 1051DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0,
1050 doc: /* Return SYMBOL's value. Error if that is void. */) 1052 doc: /* Return SYMBOL's value. Error if that is void.
1053Note that if `lexical-binding' is in effect, this returns the
1054global value outside of any lexical scope. */)
1051 (Lisp_Object symbol) 1055 (Lisp_Object symbol)
1052{ 1056{
1053 Lisp_Object val; 1057 Lisp_Object val;
diff --git a/src/doprnt.c b/src/doprnt.c
index caa56d6ae88..8cab219aafa 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -521,7 +521,10 @@ evxprintf (char **buf, ptrdiff_t *bufsize,
521 if (nbytes < *bufsize - 1) 521 if (nbytes < *bufsize - 1)
522 return nbytes; 522 return nbytes;
523 if (*buf != nonheapbuf) 523 if (*buf != nonheapbuf)
524 xfree (*buf); 524 {
525 xfree (*buf);
526 *buf = NULL;
527 }
525 *buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1); 528 *buf = xpalloc (NULL, bufsize, 1, bufsize_max, 1);
526 } 529 }
527} 530}
diff --git a/src/editfns.c b/src/editfns.c
index 8122ffdd0d4..d60f417e561 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -813,38 +813,43 @@ This function does not move point. */)
813 Qnil, Qt, Qnil); 813 Qnil, Qt, Qnil);
814} 814}
815 815
816 816/* Save current buffer state for `save-excursion' special form.
817 We (ab)use Lisp_Misc_Save_Value to allow explicit free and so
818 offload some work from GC. */
819
817Lisp_Object 820Lisp_Object
818save_excursion_save (void) 821save_excursion_save (void)
819{ 822{
820 bool visible = (XBUFFER (XWINDOW (selected_window)->buffer) 823 Lisp_Object save, *data = xmalloc (word_size * 4);
821 == current_buffer); 824
825 data[0] = Fpoint_marker ();
822 /* Do not copy the mark if it points to nowhere. */ 826 /* Do not copy the mark if it points to nowhere. */
823 Lisp_Object mark = (XMARKER (BVAR (current_buffer, mark))->buffer 827 data[1] = (XMARKER (BVAR (current_buffer, mark))->buffer
824 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil) 828 ? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
825 : Qnil); 829 : Qnil);
826 830 /* Selected window if current buffer is shown in it, nil otherwise. */
827 return Fcons (Fpoint_marker (), 831 data[2] = ((XBUFFER (XWINDOW (selected_window)->buffer) == current_buffer)
828 Fcons (mark, 832 ? selected_window : Qnil);
829 Fcons (visible ? Qt : Qnil, 833 data[3] = BVAR (current_buffer, mark_active);
830 Fcons (BVAR (current_buffer, mark_active), 834
831 selected_window)))); 835 save = make_save_value (data, 4);
836 XSAVE_VALUE (save)->dogc = 1;
837 return save;
832} 838}
833 839
840/* Restore saved buffer before leaving `save-excursion' special form. */
841
834Lisp_Object 842Lisp_Object
835save_excursion_restore (Lisp_Object info) 843save_excursion_restore (Lisp_Object info)
836{ 844{
837 Lisp_Object tem, tem1, omark, nmark; 845 Lisp_Object tem, tem1, omark, nmark, *data = XSAVE_VALUE (info)->pointer;
838 struct gcpro gcpro1, gcpro2, gcpro3; 846 struct gcpro gcpro1, gcpro2, gcpro3;
839 bool visible_p;
840 847
841 tem = Fmarker_buffer (XCAR (info)); 848 tem = Fmarker_buffer (data[0]);
842 /* If buffer being returned to is now deleted, avoid error */ 849 /* If we're unwinding to top level, saved buffer may be deleted. This
843 /* Otherwise could get error here while unwinding to top level 850 means that all of its markers are unchained and so tem is nil. */
844 and crash */
845 /* In that case, Fmarker_buffer returns nil now. */
846 if (NILP (tem)) 851 if (NILP (tem))
847 return Qnil; 852 goto out;
848 853
849 omark = nmark = Qnil; 854 omark = nmark = Qnil;
850 GCPRO3 (info, omark, nmark); 855 GCPRO3 (info, omark, nmark);
@@ -852,13 +857,12 @@ save_excursion_restore (Lisp_Object info)
852 Fset_buffer (tem); 857 Fset_buffer (tem);
853 858
854 /* Point marker. */ 859 /* Point marker. */
855 tem = XCAR (info); 860 tem = data[0];
856 Fgoto_char (tem); 861 Fgoto_char (tem);
857 unchain_marker (XMARKER (tem)); 862 unchain_marker (XMARKER (tem));
858 863
859 /* Mark marker. */ 864 /* Mark marker. */
860 info = XCDR (info); 865 tem = data[1];
861 tem = XCAR (info);
862 omark = Fmarker_position (BVAR (current_buffer, mark)); 866 omark = Fmarker_position (BVAR (current_buffer, mark));
863 if (NILP (tem)) 867 if (NILP (tem))
864 unchain_marker (XMARKER (BVAR (current_buffer, mark))); 868 unchain_marker (XMARKER (BVAR (current_buffer, mark)));
@@ -869,23 +873,8 @@ save_excursion_restore (Lisp_Object info)
869 unchain_marker (XMARKER (tem)); 873 unchain_marker (XMARKER (tem));
870 } 874 }
871 875
872 /* visible */ 876 /* Mark active. */
873 info = XCDR (info); 877 tem = data[3];
874 visible_p = !NILP (XCAR (info));
875
876#if 0 /* We used to make the current buffer visible in the selected window
877 if that was true previously. That avoids some anomalies.
878 But it creates others, and it wasn't documented, and it is simpler
879 and cleaner never to alter the window/buffer connections. */
880 tem1 = Fcar (tem);
881 if (!NILP (tem1)
882 && current_buffer != XBUFFER (XWINDOW (selected_window)->buffer))
883 Fswitch_to_buffer (Fcurrent_buffer (), Qnil);
884#endif /* 0 */
885
886 /* Mark active */
887 info = XCDR (info);
888 tem = XCAR (info);
889 tem1 = BVAR (current_buffer, mark_active); 878 tem1 = BVAR (current_buffer, mark_active);
890 bset_mark_active (current_buffer, tem); 879 bset_mark_active (current_buffer, tem);
891 880
@@ -909,8 +898,8 @@ save_excursion_restore (Lisp_Object info)
909 /* If buffer was visible in a window, and a different window was 898 /* If buffer was visible in a window, and a different window was
910 selected, and the old selected window is still showing this 899 selected, and the old selected window is still showing this
911 buffer, restore point in that window. */ 900 buffer, restore point in that window. */
912 tem = XCDR (info); 901 tem = data[2];
913 if (visible_p 902 if (WINDOWP (tem)
914 && !EQ (tem, selected_window) 903 && !EQ (tem, selected_window)
915 && (tem1 = XWINDOW (tem)->buffer, 904 && (tem1 = XWINDOW (tem)->buffer,
916 (/* Window is live... */ 905 (/* Window is live... */
@@ -920,6 +909,10 @@ save_excursion_restore (Lisp_Object info)
920 Fset_window_point (tem, make_number (PT)); 909 Fset_window_point (tem, make_number (PT));
921 910
922 UNGCPRO; 911 UNGCPRO;
912
913 out:
914
915 free_save_value (info);
923 return Qnil; 916 return Qnil;
924} 917}
925 918
@@ -2929,7 +2922,7 @@ Both characters must have the same length of multi-byte form. */)
2929 else if (!changed) 2922 else if (!changed)
2930 { 2923 {
2931 changed = -1; 2924 changed = -1;
2932 modify_region (current_buffer, pos, XINT (end), 0); 2925 modify_region_1 (pos, XINT (end), false);
2933 2926
2934 if (! NILP (noundo)) 2927 if (! NILP (noundo))
2935 { 2928 {
@@ -3105,7 +3098,7 @@ It returns the number of characters changed. */)
3105 pos = XINT (start); 3098 pos = XINT (start);
3106 pos_byte = CHAR_TO_BYTE (pos); 3099 pos_byte = CHAR_TO_BYTE (pos);
3107 end_pos = XINT (end); 3100 end_pos = XINT (end);
3108 modify_region (current_buffer, pos, end_pos, 0); 3101 modify_region_1 (pos, end_pos, false);
3109 3102
3110 cnt = 0; 3103 cnt = 0;
3111 for (; pos < end_pos; ) 3104 for (; pos < end_pos; )
@@ -4629,7 +4622,7 @@ Transposing beyond buffer boundaries is an error. */)
4629 4622
4630 if (end1 == start2) /* adjacent regions */ 4623 if (end1 == start2) /* adjacent regions */
4631 { 4624 {
4632 modify_region (current_buffer, start1, end2, 0); 4625 modify_region_1 (start1, end2, false);
4633 record_change (start1, len1 + len2); 4626 record_change (start1, len1 + len2);
4634 4627
4635 tmp_interval1 = copy_intervals (cur_intv, start1, len1); 4628 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
@@ -4688,8 +4681,8 @@ Transposing beyond buffer boundaries is an error. */)
4688 { 4681 {
4689 USE_SAFE_ALLOCA; 4682 USE_SAFE_ALLOCA;
4690 4683
4691 modify_region (current_buffer, start1, end1, 0); 4684 modify_region_1 (start1, end1, false);
4692 modify_region (current_buffer, start2, end2, 0); 4685 modify_region_1 (start2, end2, false);
4693 record_change (start1, len1); 4686 record_change (start1, len1);
4694 record_change (start2, len2); 4687 record_change (start2, len2);
4695 tmp_interval1 = copy_intervals (cur_intv, start1, len1); 4688 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
@@ -4722,7 +4715,7 @@ Transposing beyond buffer boundaries is an error. */)
4722 { 4715 {
4723 USE_SAFE_ALLOCA; 4716 USE_SAFE_ALLOCA;
4724 4717
4725 modify_region (current_buffer, start1, end2, 0); 4718 modify_region_1 (start1, end2, false);
4726 record_change (start1, (end2 - start1)); 4719 record_change (start1, (end2 - start1));
4727 tmp_interval1 = copy_intervals (cur_intv, start1, len1); 4720 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
4728 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); 4721 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
@@ -4755,7 +4748,7 @@ Transposing beyond buffer boundaries is an error. */)
4755 USE_SAFE_ALLOCA; 4748 USE_SAFE_ALLOCA;
4756 4749
4757 record_change (start1, (end2 - start1)); 4750 record_change (start1, (end2 - start1));
4758 modify_region (current_buffer, start1, end2, 0); 4751 modify_region_1 (start1, end2, false);
4759 4752
4760 tmp_interval1 = copy_intervals (cur_intv, start1, len1); 4753 tmp_interval1 = copy_intervals (cur_intv, start1, len1);
4761 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid); 4754 tmp_interval_mid = copy_intervals (cur_intv, end1, len_mid);
diff --git a/src/fileio.c b/src/fileio.c
index 48dbf20b88f..9edd88ca64f 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -5771,7 +5771,7 @@ This applies only to the operation `inhibit-file-name-operation'. */);
5771 DEFVAR_LISP ("auto-save-list-file-name", Vauto_save_list_file_name, 5771 DEFVAR_LISP ("auto-save-list-file-name", Vauto_save_list_file_name,
5772 doc: /* File name in which we write a list of all auto save file names. 5772 doc: /* File name in which we write a list of all auto save file names.
5773This variable is initialized automatically from `auto-save-list-file-prefix' 5773This variable is initialized automatically from `auto-save-list-file-prefix'
5774shortly after Emacs reads your `.emacs' file, if you have not yet given it 5774shortly after Emacs reads your init file, if you have not yet given it
5775a non-nil value. */); 5775a non-nil value. */);
5776 Vauto_save_list_file_name = Qnil; 5776 Vauto_save_list_file_name = Qnil;
5777 5777
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 4367b534cb9..52a6c37b0d5 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -813,6 +813,14 @@ xg_hide_tooltip (FRAME_PTR f)
813 General functions for creating widgets, resizing, events, e.t.c. 813 General functions for creating widgets, resizing, events, e.t.c.
814 ***********************************************************************/ 814 ***********************************************************************/
815 815
816static void
817my_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
818 const gchar *msg, gpointer user_data)
819{
820 if (!strstr (msg, "visible children"))
821 fprintf (stderr, "XX %s-WARNING **: %s\n", log_domain, msg);
822}
823
816/* Make a geometry string and pass that to GTK. It seems this is the 824/* Make a geometry string and pass that to GTK. It seems this is the
817 only way to get geometry position right if the user explicitly 825 only way to get geometry position right if the user explicitly
818 asked for a position when starting Emacs. 826 asked for a position when starting Emacs.
@@ -828,6 +836,7 @@ xg_set_geometry (FRAME_PTR f)
828 int top = f->top_pos; 836 int top = f->top_pos;
829 int yneg = f->size_hint_flags & YNegative; 837 int yneg = f->size_hint_flags & YNegative;
830 char geom_str[sizeof "=x--" + 4 * INT_STRLEN_BOUND (int)]; 838 char geom_str[sizeof "=x--" + 4 * INT_STRLEN_BOUND (int)];
839 guint id;
831 840
832 if (xneg) 841 if (xneg)
833 left = -left; 842 left = -left;
@@ -840,9 +849,15 @@ xg_set_geometry (FRAME_PTR f)
840 (xneg ? '-' : '+'), left, 849 (xneg ? '-' : '+'), left,
841 (yneg ? '-' : '+'), top); 850 (yneg ? '-' : '+'), top);
842 851
852 /* Silence warning about visible children. */
853 id = g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING | G_LOG_FLAG_FATAL
854 | G_LOG_FLAG_RECURSION, my_log_handler, NULL);
855
843 if (!gtk_window_parse_geometry (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)), 856 if (!gtk_window_parse_geometry (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
844 geom_str)) 857 geom_str))
845 fprintf (stderr, "Failed to parse: '%s'\n", geom_str); 858 fprintf (stderr, "Failed to parse: '%s'\n", geom_str);
859
860 g_log_remove_handler ("Gtk", id);
846 } 861 }
847} 862}
848 863
diff --git a/src/insdel.c b/src/insdel.c
index 87010cd8251..892ca3d5216 100644
--- a/src/insdel.c
+++ b/src/insdel.c
@@ -1755,9 +1755,9 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte,
1755 1755
1756 return deletion; 1756 return deletion;
1757} 1757}
1758 1758
1759/* Call this if you're about to change the region of BUFFER from 1759/* Call this if you're about to change the region of current buffer
1760 character positions START to END. This checks the read-only 1760 from character positions START to END. This checks the read-only
1761 properties of the region, calls the necessary modification hooks, 1761 properties of the region, calls the necessary modification hooks,
1762 and warns the next redisplay that it should pay attention to that 1762 and warns the next redisplay that it should pay attention to that
1763 area. 1763 area.
@@ -1766,16 +1766,11 @@ del_range_2 (ptrdiff_t from, ptrdiff_t from_byte,
1766 Otherwise set CHARS_MODIFF to the new value of MODIFF. */ 1766 Otherwise set CHARS_MODIFF to the new value of MODIFF. */
1767 1767
1768void 1768void
1769modify_region (struct buffer *buffer, ptrdiff_t start, ptrdiff_t end, 1769modify_region_1 (ptrdiff_t start, ptrdiff_t end, bool preserve_chars_modiff)
1770 bool preserve_chars_modiff)
1771{ 1770{
1772 struct buffer *old_buffer = current_buffer;
1773
1774 set_buffer_internal (buffer);
1775
1776 prepare_to_modify_buffer (start, end, NULL); 1771 prepare_to_modify_buffer (start, end, NULL);
1777 1772
1778 BUF_COMPUTE_UNCHANGED (buffer, start - 1, end); 1773 BUF_COMPUTE_UNCHANGED (current_buffer, start - 1, end);
1779 1774
1780 if (MODIFF <= SAVE_MODIFF) 1775 if (MODIFF <= SAVE_MODIFF)
1781 record_first_change (); 1776 record_first_change ();
@@ -1783,11 +1778,9 @@ modify_region (struct buffer *buffer, ptrdiff_t start, ptrdiff_t end,
1783 if (! preserve_chars_modiff) 1778 if (! preserve_chars_modiff)
1784 CHARS_MODIFF = MODIFF; 1779 CHARS_MODIFF = MODIFF;
1785 1780
1786 bset_point_before_scroll (buffer, Qnil); 1781 bset_point_before_scroll (current_buffer, Qnil);
1787
1788 set_buffer_internal (old_buffer);
1789} 1782}
1790 1783
1791/* Check that it is okay to modify the buffer between START and END, 1784/* Check that it is okay to modify the buffer between START and END,
1792 which are char positions. 1785 which are char positions.
1793 1786
diff --git a/src/lisp.h b/src/lisp.h
index a5c4f862d37..ad249a2c66b 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -2801,7 +2801,7 @@ extern void del_range_byte (ptrdiff_t, ptrdiff_t, bool);
2801extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); 2801extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool);
2802extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, 2802extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t,
2803 ptrdiff_t, ptrdiff_t, bool); 2803 ptrdiff_t, ptrdiff_t, bool);
2804extern void modify_region (struct buffer *, ptrdiff_t, ptrdiff_t, bool); 2804extern void modify_region_1 (ptrdiff_t, ptrdiff_t, bool);
2805extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); 2805extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *);
2806extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); 2806extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t);
2807extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, 2807extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t,
@@ -2968,6 +2968,7 @@ extern Lisp_Object make_float (double);
2968extern void display_malloc_warning (void); 2968extern void display_malloc_warning (void);
2969extern ptrdiff_t inhibit_garbage_collection (void); 2969extern ptrdiff_t inhibit_garbage_collection (void);
2970extern Lisp_Object make_save_value (void *, ptrdiff_t); 2970extern Lisp_Object make_save_value (void *, ptrdiff_t);
2971extern void free_save_value (Lisp_Object);
2971extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); 2972extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object);
2972extern void free_marker (Lisp_Object); 2973extern void free_marker (Lisp_Object);
2973extern void free_cons (struct Lisp_Cons *); 2974extern void free_cons (struct Lisp_Cons *);
@@ -3398,7 +3399,6 @@ extern void syms_of_doc (void);
3398extern int read_bytecode_char (bool); 3399extern int read_bytecode_char (bool);
3399 3400
3400/* Defined in bytecode.c. */ 3401/* Defined in bytecode.c. */
3401extern Lisp_Object Qbytecode;
3402extern void syms_of_bytecode (void); 3402extern void syms_of_bytecode (void);
3403extern struct byte_stack *byte_stack_list; 3403extern struct byte_stack *byte_stack_list;
3404#if BYTE_MARK_STACK 3404#if BYTE_MARK_STACK
diff --git a/src/process.c b/src/process.c
index b23f06fd025..27009882c99 100644
--- a/src/process.c
+++ b/src/process.c
@@ -777,10 +777,23 @@ get_process (register Lisp_Object name)
777/* Fdelete_process promises to immediately forget about the process, but in 777/* Fdelete_process promises to immediately forget about the process, but in
778 reality, Emacs needs to remember those processes until they have been 778 reality, Emacs needs to remember those processes until they have been
779 treated by the SIGCHLD handler and waitpid has been invoked on them; 779 treated by the SIGCHLD handler and waitpid has been invoked on them;
780 otherwise they might fill up the kernel's process table. */ 780 otherwise they might fill up the kernel's process table.
781
782 Some processes created by call-process are also put onto this list. */
781static Lisp_Object deleted_pid_list; 783static Lisp_Object deleted_pid_list;
782#endif 784#endif
783 785
786void
787record_deleted_pid (pid_t pid)
788{
789#ifdef SIGCHLD
790 deleted_pid_list = Fcons (make_fixnum_or_float (pid),
791 /* GC treated elements set to nil. */
792 Fdelq (Qnil, deleted_pid_list));
793
794#endif
795}
796
784DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, 797DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0,
785 doc: /* Delete PROCESS: kill it and forget about it immediately. 798 doc: /* Delete PROCESS: kill it and forget about it immediately.
786PROCESS may be a process, a buffer, the name of a process or buffer, or 799PROCESS may be a process, a buffer, the name of a process or buffer, or
@@ -807,9 +820,7 @@ nil, indicating the current buffer's process. */)
807 pid_t pid = p->pid; 820 pid_t pid = p->pid;
808 821
809 /* No problem storing the pid here, as it is still in Vprocess_alist. */ 822 /* No problem storing the pid here, as it is still in Vprocess_alist. */
810 deleted_pid_list = Fcons (make_fixnum_or_float (pid), 823 record_deleted_pid (pid);
811 /* GC treated elements set to nil. */
812 Fdelq (Qnil, deleted_pid_list));
813 /* If the process has already signaled, remove it from the list. */ 824 /* If the process has already signaled, remove it from the list. */
814 if (p->raw_status_new) 825 if (p->raw_status_new)
815 update_status (p); 826 update_status (p);
@@ -1586,9 +1597,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1586 volatile int pty_flag = 0; 1597 volatile int pty_flag = 0;
1587 volatile Lisp_Object lisp_pty_name = Qnil; 1598 volatile Lisp_Object lisp_pty_name = Qnil;
1588 volatile Lisp_Object encoded_current_dir; 1599 volatile Lisp_Object encoded_current_dir;
1589#if HAVE_WORKING_VFORK
1590 char **volatile save_environ;
1591#endif
1592 1600
1593 inchannel = outchannel = -1; 1601 inchannel = outchannel = -1;
1594 1602
@@ -1688,12 +1696,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1688 pthread_sigmask (SIG_BLOCK, &blocked, 0); 1696 pthread_sigmask (SIG_BLOCK, &blocked, 0);
1689#endif 1697#endif
1690 1698
1691#if HAVE_WORKING_VFORK
1692 /* child_setup must clobber environ on systems with true vfork.
1693 Protect it from permanent change. */
1694 save_environ = environ;
1695#endif
1696
1697#ifndef WINDOWSNT 1699#ifndef WINDOWSNT
1698 pid = vfork (); 1700 pid = vfork ();
1699 if (pid == 0) 1701 if (pid == 0)
@@ -1819,10 +1821,6 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1819 1821
1820 /* Back in the parent process. */ 1822 /* Back in the parent process. */
1821 1823
1822#if HAVE_WORKING_VFORK
1823 environ = save_environ;
1824#endif
1825
1826 XPROCESS (process)->pid = pid; 1824 XPROCESS (process)->pid = pid;
1827 if (0 <= pid) 1825 if (0 <= pid)
1828 XPROCESS (process)->alive = 1; 1826 XPROCESS (process)->alive = 1;
@@ -1874,7 +1872,7 @@ create_process (Lisp_Object process, char **new_argv, Lisp_Object current_dir)
1874 /* Wait for child_setup to complete in case that vfork is 1872 /* Wait for child_setup to complete in case that vfork is
1875 actually defined as fork. The descriptor wait_child_setup[1] 1873 actually defined as fork. The descriptor wait_child_setup[1]
1876 of a pipe is closed at the child side either by close-on-exec 1874 of a pipe is closed at the child side either by close-on-exec
1877 on successful execvp or the _exit call in child_setup. */ 1875 on successful execve or the _exit call in child_setup. */
1878 { 1876 {
1879 char dummy; 1877 char dummy;
1880 1878
@@ -6160,35 +6158,37 @@ process has been transmitted to the serial port. */)
6160 return process; 6158 return process;
6161} 6159}
6162 6160
6163/* If the status of the process DESIRED has changed, return true and 6161#ifdef SIGCHLD
6164 set *STATUS to its exit status; otherwise, return false.
6165 If HAVE is nonnegative, assume that HAVE = waitpid (HAVE, STATUS, ...)
6166 has already been invoked, and do not invoke waitpid again. */
6167 6162
6168static bool 6163/* The main Emacs thread records child processes in three places:
6169process_status_retrieved (pid_t desired, pid_t have, int *status)
6170{
6171 if (have < 0)
6172 {
6173 /* Invoke waitpid only with a known process ID; do not invoke
6174 waitpid with a nonpositive argument. Otherwise, Emacs might
6175 reap an unwanted process by mistake. For example, invoking
6176 waitpid (-1, ...) can mess up glib by reaping glib's subprocesses,
6177 so that another thread running glib won't find them. */
6178 do
6179 have = waitpid (desired, status, WNOHANG | WUNTRACED);
6180 while (have < 0 && errno == EINTR);
6181 }
6182 6164
6183 return have == desired; 6165 - Vprocess_alist, for asynchronous subprocesses, which are child
6184} 6166 processes visible to Lisp.
6185 6167
6186/* If PID is nonnegative, the child process PID with wait status W has 6168 - deleted_pid_list, for child processes invisible to Lisp,
6187 changed its status; record this and return true. 6169 typically because of delete-process. These are recorded so that
6170 the processes can be reaped when they exit, so that the operating
6171 system's process table is not cluttered by zombies.
6188 6172
6189 If PID is negative, ignore W, and look for known child processes 6173 - the local variable PID in Fcall_process, call_process_cleanup and
6190 of Emacs whose status have changed. For each one found, record its new 6174 call_process_kill, for synchronous subprocesses.
6191 status. 6175 record_unwind_protect is used to make sure this process is not
6176 forgotten: if the user interrupts call-process and the child
6177 process refuses to exit immediately even with two C-g's,
6178 call_process_kill adds PID's contents to deleted_pid_list before
6179 returning.
6180
6181 The main Emacs thread invokes waitpid only on child processes that
6182 it creates and that have not been reaped. This avoid races on
6183 platforms such as GTK, where other threads create their own
6184 subprocesses which the main thread should not reap. For example,
6185 if the main thread attempted to reap an already-reaped child, it
6186 might inadvertently reap a GTK-created process that happened to
6187 have the same process ID. */
6188
6189/* Handle a SIGCHLD signal by looking for known child processes of
6190 Emacs whose status have changed. For each one found, record its
6191 new status.
6192 6192
6193 All we do is change the status; we do not run sentinels or print 6193 All we do is change the status; we do not run sentinels or print
6194 notifications. That is saved for the next time keyboard input is 6194 notifications. That is saved for the next time keyboard input is
@@ -6211,20 +6211,15 @@ process_status_retrieved (pid_t desired, pid_t have, int *status)
6211 ** Malloc WARNING: This should never call malloc either directly or 6211 ** Malloc WARNING: This should never call malloc either directly or
6212 indirectly; if it does, that is a bug */ 6212 indirectly; if it does, that is a bug */
6213 6213
6214void 6214static void
6215record_child_status_change (pid_t pid, int w) 6215handle_child_signal (int sig)
6216{ 6216{
6217#ifdef SIGCHLD
6218
6219 /* Record at most one child only if we already know one child that
6220 has exited. */
6221 bool record_at_most_one_child = 0 <= pid;
6222
6223 Lisp_Object tail; 6217 Lisp_Object tail;
6224 6218
6225 /* Find the process that signaled us, and record its status. */ 6219 /* Find the process that signaled us, and record its status. */
6226 6220
6227 /* The process can have been deleted by Fdelete_process. */ 6221 /* The process can have been deleted by Fdelete_process, or have
6222 been started asynchronously by Fcall_process. */
6228 for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail)) 6223 for (tail = deleted_pid_list; CONSP (tail); tail = XCDR (tail))
6229 { 6224 {
6230 bool all_pids_are_fixnums 6225 bool all_pids_are_fixnums
@@ -6238,12 +6233,8 @@ record_child_status_change (pid_t pid, int w)
6238 deleted_pid = XINT (xpid); 6233 deleted_pid = XINT (xpid);
6239 else 6234 else
6240 deleted_pid = XFLOAT_DATA (xpid); 6235 deleted_pid = XFLOAT_DATA (xpid);
6241 if (process_status_retrieved (deleted_pid, pid, &w)) 6236 if (child_status_changed (deleted_pid, 0, 0))
6242 { 6237 XSETCAR (tail, Qnil);
6243 XSETCAR (tail, Qnil);
6244 if (record_at_most_one_child)
6245 return;
6246 }
6247 } 6238 }
6248 } 6239 }
6249 6240
@@ -6252,15 +6243,17 @@ record_child_status_change (pid_t pid, int w)
6252 { 6243 {
6253 Lisp_Object proc = XCDR (XCAR (tail)); 6244 Lisp_Object proc = XCDR (XCAR (tail));
6254 struct Lisp_Process *p = XPROCESS (proc); 6245 struct Lisp_Process *p = XPROCESS (proc);
6255 if (p->alive && process_status_retrieved (p->pid, pid, &w)) 6246 int status;
6247
6248 if (p->alive && child_status_changed (p->pid, &status, WUNTRACED))
6256 { 6249 {
6257 /* Change the status of the process that was found. */ 6250 /* Change the status of the process that was found. */
6258 p->tick = ++process_tick; 6251 p->tick = ++process_tick;
6259 p->raw_status = w; 6252 p->raw_status = status;
6260 p->raw_status_new = 1; 6253 p->raw_status_new = 1;
6261 6254
6262 /* If process has terminated, stop waiting for its output. */ 6255 /* If process has terminated, stop waiting for its output. */
6263 if (WIFSIGNALED (w) || WIFEXITED (w)) 6256 if (WIFSIGNALED (status) || WIFEXITED (status))
6264 { 6257 {
6265 int clear_desc_flag = 0; 6258 int clear_desc_flag = 0;
6266 p->alive = 0; 6259 p->alive = 0;
@@ -6274,44 +6267,8 @@ record_child_status_change (pid_t pid, int w)
6274 FD_CLR (p->infd, &non_keyboard_wait_mask); 6267 FD_CLR (p->infd, &non_keyboard_wait_mask);
6275 } 6268 }
6276 } 6269 }
6277
6278 /* Tell wait_reading_process_output that it needs to wake up and
6279 look around. */
6280 if (input_available_clear_time)
6281 *input_available_clear_time = make_emacs_time (0, 0);
6282
6283 if (record_at_most_one_child)
6284 return;
6285 } 6270 }
6286 } 6271 }
6287
6288 if (0 <= pid)
6289 {
6290 /* The caller successfully waited for a pid but no asynchronous
6291 process was found for it, so this is a synchronous process. */
6292
6293 synch_process_alive = 0;
6294
6295 /* Report the status of the synchronous process. */
6296 if (WIFEXITED (w))
6297 synch_process_retcode = WEXITSTATUS (w);
6298 else if (WIFSIGNALED (w))
6299 synch_process_termsig = WTERMSIG (w);
6300
6301 /* Tell wait_reading_process_output that it needs to wake up and
6302 look around. */
6303 if (input_available_clear_time)
6304 *input_available_clear_time = make_emacs_time (0, 0);
6305 }
6306#endif
6307}
6308
6309#ifdef SIGCHLD
6310
6311static void
6312handle_child_signal (int sig)
6313{
6314 record_child_status_change (-1, 0);
6315} 6272}
6316 6273
6317static void 6274static void
diff --git a/src/process.h b/src/process.h
index 74d1a124060..4fa22747ca9 100644
--- a/src/process.h
+++ b/src/process.h
@@ -185,23 +185,6 @@ pset_gnutls_cred_type (struct Lisp_Process *p, Lisp_Object val)
185} 185}
186#endif 186#endif
187 187
188/* True if we are about to fork off a synchronous process or if we
189 are waiting for it. */
190extern bool synch_process_alive;
191
192/* Communicate exit status of sync process to from sigchld_handler
193 to Fcall_process. */
194
195/* Nonzero => this is a string explaining death of synchronous subprocess. */
196extern const char *synch_process_death;
197
198/* Nonzero => this is the signal number that terminated the subprocess. */
199extern int synch_process_termsig;
200
201/* If synch_process_death is zero,
202 this is exit code of synchronous subprocess. */
203extern int synch_process_retcode;
204
205/* Nonzero means don't run process sentinels. This is used 188/* Nonzero means don't run process sentinels. This is used
206 when exiting. */ 189 when exiting. */
207extern int inhibit_sentinels; 190extern int inhibit_sentinels;
diff --git a/src/sysdep.c b/src/sysdep.c
index 1a3834f0379..7068a4f0977 100644
--- a/src/sysdep.c
+++ b/src/sysdep.c
@@ -266,45 +266,71 @@ init_baud_rate (int fd)
266 266
267#ifndef MSDOS 267#ifndef MSDOS
268 268
269static void 269/* Wait for the subprocess with process id CHILD to terminate or change status.
270wait_for_termination_1 (pid_t pid, int interruptible) 270 CHILD must be a child process that has not been reaped.
271 If STATUS is non-null, store the waitpid-style exit status into *STATUS
272 and tell wait_reading_process_output that it needs to look around.
273 Use waitpid-style OPTIONS when waiting.
274 If INTERRUPTIBLE, this function is interruptible by a signal.
275
276 Return CHILD if successful, 0 if no status is available;
277 the latter is possible only when options & NOHANG. */
278static pid_t
279get_child_status (pid_t child, int *status, int options, bool interruptible)
271{ 280{
272 while (1) 281 pid_t pid;
282
283 /* Invoke waitpid only with a known process ID; do not invoke
284 waitpid with a nonpositive argument. Otherwise, Emacs might
285 reap an unwanted process by mistake. For example, invoking
286 waitpid (-1, ...) can mess up glib by reaping glib's subprocesses,
287 so that another thread running glib won't find them. */
288 eassert (0 < child);
289
290 while ((pid = waitpid (child, status, options)) < 0)
273 { 291 {
274 int status; 292 /* CHILD must be a child process that has not been reaped, and
275 int wait_result = waitpid (pid, &status, 0); 293 STATUS and OPTIONS must be valid. */
276 if (wait_result < 0) 294 eassert (errno == EINTR);
277 {
278 if (errno != EINTR)
279 break;
280 }
281 else
282 {
283 record_child_status_change (wait_result, status);
284 break;
285 }
286 295
287 /* Note: the MS-Windows emulation of waitpid calls QUIT 296 /* Note: the MS-Windows emulation of waitpid calls QUIT
288 internally. */ 297 internally. */
289 if (interruptible) 298 if (interruptible)
290 QUIT; 299 QUIT;
291 } 300 }
292}
293 301
294/* Wait for subprocess with process id `pid' to terminate and 302 /* If successful and status is requested, tell wait_reading_process_output
295 make sure it will get eliminated (not remain forever as a zombie) */ 303 that it needs to wake up and look around. */
304 if (pid && status && input_available_clear_time)
305 *input_available_clear_time = make_emacs_time (0, 0);
296 306
307 return pid;
308}
309
310/* Wait for the subprocess with process id CHILD to terminate.
311 CHILD must be a child process that has not been reaped.
312 If STATUS is non-null, store the waitpid-style exit status into *STATUS
313 and tell wait_reading_process_output that it needs to look around.
314 If INTERRUPTIBLE, this function is interruptible by a signal. */
297void 315void
298wait_for_termination (pid_t pid) 316wait_for_termination (pid_t child, int *status, bool interruptible)
299{ 317{
300 wait_for_termination_1 (pid, 0); 318 get_child_status (child, status, 0, interruptible);
301} 319}
302 320
303/* Like the above, but allow keyboard interruption. */ 321/* Report whether the subprocess with process id CHILD has changed status.
304void 322 Termination counts as a change of status.
305interruptible_wait_for_termination (pid_t pid) 323 CHILD must be a child process that has not been reaped.
324 If STATUS is non-null, store the waitpid-style exit status into *STATUS
325 and tell wait_reading_process_output that it needs to look around.
326 Use waitpid-style OPTIONS to check status, but do not wait.
327
328 Return CHILD if successful, 0 if no status is available because
329 the process's state has not changed. */
330pid_t
331child_status_changed (pid_t child, int *status, int options)
306{ 332{
307 wait_for_termination_1 (pid, 1); 333 return get_child_status (child, status, WNOHANG | options, 0);
308} 334}
309 335
310/* 336/*
@@ -454,6 +480,7 @@ sys_subshell (void)
454 char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */ 480 char oldwd[MAXPATHLEN+1]; /* Fixed length is safe on MSDOS. */
455#endif 481#endif
456 pid_t pid; 482 pid_t pid;
483 int status;
457 struct save_signal saved_handlers[5]; 484 struct save_signal saved_handlers[5];
458 Lisp_Object dir; 485 Lisp_Object dir;
459 unsigned char *volatile str_volatile = 0; 486 unsigned char *volatile str_volatile = 0;
@@ -491,7 +518,6 @@ sys_subshell (void)
491#ifdef DOS_NT 518#ifdef DOS_NT
492 pid = 0; 519 pid = 0;
493 save_signal_handlers (saved_handlers); 520 save_signal_handlers (saved_handlers);
494 synch_process_alive = 1;
495#else 521#else
496 pid = vfork (); 522 pid = vfork ();
497 if (pid == -1) 523 if (pid == -1)
@@ -560,14 +586,12 @@ sys_subshell (void)
560 /* Do this now if we did not do it before. */ 586 /* Do this now if we did not do it before. */
561#ifndef MSDOS 587#ifndef MSDOS
562 save_signal_handlers (saved_handlers); 588 save_signal_handlers (saved_handlers);
563 synch_process_alive = 1;
564#endif 589#endif
565 590
566#ifndef DOS_NT 591#ifndef DOS_NT
567 wait_for_termination (pid); 592 wait_for_termination (pid, &status, 0);
568#endif 593#endif
569 restore_signal_handlers (saved_handlers); 594 restore_signal_handlers (saved_handlers);
570 synch_process_alive = 0;
571} 595}
572 596
573static void 597static void
diff --git a/src/syswait.h b/src/syswait.h
index aa4c4bcf527..360407d558e 100644
--- a/src/syswait.h
+++ b/src/syswait.h
@@ -23,6 +23,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
23#ifndef EMACS_SYSWAIT_H 23#ifndef EMACS_SYSWAIT_H
24#define EMACS_SYSWAIT_H 24#define EMACS_SYSWAIT_H
25 25
26#include <stdbool.h>
26#include <sys/types.h> 27#include <sys/types.h>
27 28
28#ifdef HAVE_SYS_WAIT_H /* We have sys/wait.h with POSIXoid definitions. */ 29#ifdef HAVE_SYS_WAIT_H /* We have sys/wait.h with POSIXoid definitions. */
@@ -52,10 +53,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
52#endif 53#endif
53 54
54/* Defined in process.c. */ 55/* Defined in process.c. */
55extern void record_child_status_change (pid_t, int); 56extern void record_deleted_pid (pid_t);
56 57
57/* Defined in sysdep.c. */ 58/* Defined in sysdep.c. */
58extern void wait_for_termination (pid_t); 59extern void wait_for_termination (pid_t, int *, bool);
59extern void interruptible_wait_for_termination (pid_t); 60extern pid_t child_status_changed (pid_t, int *, int);
60 61
61#endif /* EMACS_SYSWAIT_H */ 62#endif /* EMACS_SYSWAIT_H */
diff --git a/src/textprop.c b/src/textprop.c
index 379eafb73f7..1ce44ad60ac 100644
--- a/src/textprop.c
+++ b/src/textprop.c
@@ -85,8 +85,18 @@ text_read_only (Lisp_Object propval)
85 xsignal0 (Qtext_read_only); 85 xsignal0 (Qtext_read_only);
86} 86}
87 87
88/* Prepare to modify the region of BUFFER from START to END. */
89
90static void
91modify_region (Lisp_Object buffer, Lisp_Object start, Lisp_Object end)
92{
93 struct buffer *buf = XBUFFER (buffer), *old = current_buffer;
94
95 set_buffer_internal (buf);
96 modify_region_1 (XINT (start), XINT (end), true);
97 set_buffer_internal (old);
98}
88 99
89
90/* Extract the interval at the position pointed to by BEGIN from 100/* Extract the interval at the position pointed to by BEGIN from
91 OBJECT, a string or buffer. Additionally, check that the positions 101 OBJECT, a string or buffer. Additionally, check that the positions
92 pointed to by BEGIN and END are within the bounds of OBJECT, and 102 pointed to by BEGIN and END are within the bounds of OBJECT, and
@@ -1164,7 +1174,7 @@ Return t if any property value actually changed, nil otherwise. */)
1164 } 1174 }
1165 1175
1166 if (BUFFERP (object)) 1176 if (BUFFERP (object))
1167 modify_region (XBUFFER (object), XINT (start), XINT (end), 1); 1177 modify_region (object, start, end);
1168 1178
1169 /* We are at the beginning of interval I, with LEN chars to scan. */ 1179 /* We are at the beginning of interval I, with LEN chars to scan. */
1170 for (;;) 1180 for (;;)
@@ -1302,7 +1312,7 @@ set_text_properties (Lisp_Object start, Lisp_Object end, Lisp_Object properties,
1302 } 1312 }
1303 1313
1304 if (BUFFERP (object) && !NILP (coherent_change_p)) 1314 if (BUFFERP (object) && !NILP (coherent_change_p))
1305 modify_region (XBUFFER (object), XINT (start), XINT (end), 1); 1315 modify_region (object, start, end);
1306 1316
1307 set_text_properties_1 (start, end, properties, object, i); 1317 set_text_properties_1 (start, end, properties, object, i);
1308 1318
@@ -1451,7 +1461,7 @@ Use `set-text-properties' if you want to remove all text properties. */)
1451 } 1461 }
1452 1462
1453 if (BUFFERP (object)) 1463 if (BUFFERP (object))
1454 modify_region (XBUFFER (object), XINT (start), XINT (end), 1); 1464 modify_region (object, start, end);
1455 1465
1456 /* We are at the beginning of an interval, with len to scan */ 1466 /* We are at the beginning of an interval, with len to scan */
1457 for (;;) 1467 for (;;)
@@ -1565,7 +1575,7 @@ Return t if any property was actually removed, nil otherwise. */)
1565 else if (LENGTH (i) == len) 1575 else if (LENGTH (i) == len)
1566 { 1576 {
1567 if (!modified && BUFFERP (object)) 1577 if (!modified && BUFFERP (object))
1568 modify_region (XBUFFER (object), XINT (start), XINT (end), 1); 1578 modify_region (object, start, end);
1569 remove_properties (Qnil, properties, i, object); 1579 remove_properties (Qnil, properties, i, object);
1570 if (BUFFERP (object)) 1580 if (BUFFERP (object))
1571 signal_after_change (XINT (start), XINT (end) - XINT (start), 1581 signal_after_change (XINT (start), XINT (end) - XINT (start),
@@ -1578,7 +1588,7 @@ Return t if any property was actually removed, nil otherwise. */)
1578 i = split_interval_left (i, len); 1588 i = split_interval_left (i, len);
1579 copy_properties (unchanged, i); 1589 copy_properties (unchanged, i);
1580 if (!modified && BUFFERP (object)) 1590 if (!modified && BUFFERP (object))
1581 modify_region (XBUFFER (object), XINT (start), XINT (end), 1); 1591 modify_region (object, start, end);
1582 remove_properties (Qnil, properties, i, object); 1592 remove_properties (Qnil, properties, i, object);
1583 if (BUFFERP (object)) 1593 if (BUFFERP (object))
1584 signal_after_change (XINT (start), XINT (end) - XINT (start), 1594 signal_after_change (XINT (start), XINT (end) - XINT (start),
@@ -1589,7 +1599,7 @@ Return t if any property was actually removed, nil otherwise. */)
1589 if (interval_has_some_properties_list (properties, i)) 1599 if (interval_has_some_properties_list (properties, i))
1590 { 1600 {
1591 if (!modified && BUFFERP (object)) 1601 if (!modified && BUFFERP (object))
1592 modify_region (XBUFFER (object), XINT (start), XINT (end), 1); 1602 modify_region (object, start, end);
1593 remove_properties (Qnil, properties, i, object); 1603 remove_properties (Qnil, properties, i, object);
1594 modified = 1; 1604 modified = 1;
1595 } 1605 }
diff --git a/src/w32.c b/src/w32.c
index c8e16dfaa94..e81fc7b4f3e 100644
--- a/src/w32.c
+++ b/src/w32.c
@@ -150,10 +150,18 @@ typedef struct _REPARSE_DATA_BUFFER {
150 } DUMMYUNIONNAME; 150 } DUMMYUNIONNAME;
151} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; 151} REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
152 152
153#ifndef FILE_DEVICE_FILE_SYSTEM
153#define FILE_DEVICE_FILE_SYSTEM 9 154#define FILE_DEVICE_FILE_SYSTEM 9
155#endif
156#ifndef METHOD_BUFFERED
154#define METHOD_BUFFERED 0 157#define METHOD_BUFFERED 0
158#endif
159#ifndef FILE_ANY_ACCESS
155#define FILE_ANY_ACCESS 0x00000000 160#define FILE_ANY_ACCESS 0x00000000
161#endif
162#ifndef CTL_CODE
156#define CTL_CODE(t,f,m,a) (((t)<<16)|((a)<<14)|((f)<<2)|(m)) 163#define CTL_CODE(t,f,m,a) (((t)<<16)|((a)<<14)|((f)<<2)|(m))
164#endif
157#define FSCTL_GET_REPARSE_POINT \ 165#define FSCTL_GET_REPARSE_POINT \
158 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) 166 CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS)
159#endif 167#endif
diff --git a/src/w32common.h b/src/w32common.h
index 50724e5553c..5e9b61824ae 100644
--- a/src/w32common.h
+++ b/src/w32common.h
@@ -34,7 +34,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
34 34
35extern SYSTEM_INFO sysinfo_cache; 35extern SYSTEM_INFO sysinfo_cache;
36extern OSVERSIONINFO osinfo_cache; 36extern OSVERSIONINFO osinfo_cache;
37extern unsigned long syspage_mask; 37extern DWORD_PTR syspage_mask;
38 38
39extern int w32_major_version; 39extern int w32_major_version;
40extern int w32_minor_version; 40extern int w32_minor_version;
diff --git a/src/w32fns.c b/src/w32fns.c
index 90f5b1695ea..044c377f496 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -82,7 +82,6 @@ void syms_of_w32fns (void);
82void globals_of_w32fns (void); 82void globals_of_w32fns (void);
83 83
84extern void free_frame_menubar (struct frame *); 84extern void free_frame_menubar (struct frame *);
85extern double atof (const char *);
86extern int w32_console_toggle_lock_key (int, Lisp_Object); 85extern int w32_console_toggle_lock_key (int, Lisp_Object);
87extern void w32_menu_display_help (HWND, HMENU, UINT, UINT); 86extern void w32_menu_display_help (HWND, HMENU, UINT, UINT);
88extern void w32_free_menu_strings (HWND); 87extern void w32_free_menu_strings (HWND);
@@ -223,7 +222,7 @@ SYSTEM_INFO sysinfo_cache;
223/* This gives us version, build, and platform identification. */ 222/* This gives us version, build, and platform identification. */
224OSVERSIONINFO osinfo_cache; 223OSVERSIONINFO osinfo_cache;
225 224
226unsigned long syspage_mask = 0; 225DWORD_PTR syspage_mask = 0;
227 226
228/* The major and minor versions of NT. */ 227/* The major and minor versions of NT. */
229int w32_major_version; 228int w32_major_version;
@@ -6035,7 +6034,7 @@ typedef char guichar_t;
6035 read-only when "Directories" is selected in the filter. This 6034 read-only when "Directories" is selected in the filter. This
6036 allows us to work around the fact that the standard Open File 6035 allows us to work around the fact that the standard Open File
6037 dialog does not support directories. */ 6036 dialog does not support directories. */
6038static UINT CALLBACK 6037static UINT_PTR CALLBACK
6039file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) 6038file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
6040{ 6039{
6041 if (msg == WM_NOTIFY) 6040 if (msg == WM_NOTIFY)
diff --git a/src/w32proc.c b/src/w32proc.c
index 9b111b40e36..87af8682390 100644
--- a/src/w32proc.c
+++ b/src/w32proc.c
@@ -1274,33 +1274,7 @@ waitpid (pid_t pid, int *status, int options)
1274#endif 1274#endif
1275 1275
1276 if (status) 1276 if (status)
1277 { 1277 *status = retval;
1278 *status = retval;
1279 }
1280 else if (synch_process_alive)
1281 {
1282 synch_process_alive = 0;
1283
1284 /* Report the status of the synchronous process. */
1285 if (WIFEXITED (retval))
1286 synch_process_retcode = WEXITSTATUS (retval);
1287 else if (WIFSIGNALED (retval))
1288 {
1289 int code = WTERMSIG (retval);
1290 const char *signame;
1291
1292 synchronize_system_messages_locale ();
1293 signame = strsignal (code);
1294
1295 if (signame == 0)
1296 signame = "unknown";
1297
1298 synch_process_death = signame;
1299 }
1300
1301 reap_subprocess (cp);
1302 }
1303
1304 reap_subprocess (cp); 1278 reap_subprocess (cp);
1305 1279
1306 return pid; 1280 return pid;
diff --git a/src/xdisp.c b/src/xdisp.c
index 2f7b0a21f3b..4bab2756e64 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -15778,6 +15778,35 @@ redisplay_window (Lisp_Object window, int just_this_one_p)
15778 Move it back to a fully-visible line. */ 15778 Move it back to a fully-visible line. */
15779 new_vpos = window_box_height (w); 15779 new_vpos = window_box_height (w);
15780 } 15780 }
15781 else if (w->cursor.vpos >=0)
15782 {
15783 /* Some people insist on not letting point enter the scroll
15784 margin, even though this part handles windows that didn't
15785 scroll at all. */
15786 struct frame *f = XFRAME (w->frame);
15787 int margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
15788 int pixel_margin = margin * FRAME_LINE_HEIGHT (f);
15789 bool header_line = WINDOW_WANTS_HEADER_LINE_P (w);
15790
15791 /* Note: We add an extra FRAME_LINE_HEIGHT, because the loop
15792 below, which finds the row to move point to, advances by
15793 the Y coordinate of the _next_ row, see the definition of
15794 MATRIX_ROW_BOTTOM_Y. */
15795 if (w->cursor.vpos < margin + header_line)
15796 new_vpos
15797 = pixel_margin + (header_line
15798 ? CURRENT_HEADER_LINE_HEIGHT (w)
15799 : 0) + FRAME_LINE_HEIGHT (f);
15800 else
15801 {
15802 int window_height = window_box_height (w);
15803
15804 if (header_line)
15805 window_height += CURRENT_HEADER_LINE_HEIGHT (w);
15806 if (w->cursor.y >= window_height - pixel_margin)
15807 new_vpos = window_height - pixel_margin;
15808 }
15809 }
15781 15810
15782 /* If we need to move point for either of the above reasons, 15811 /* If we need to move point for either of the above reasons,
15783 now actually do it. */ 15812 now actually do it. */
diff --git a/src/xterm.c b/src/xterm.c
index 8f7ed8ef561..68d2dd7c70d 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -2261,7 +2261,6 @@ static void
2261x_draw_image_relief (struct glyph_string *s) 2261x_draw_image_relief (struct glyph_string *s)
2262{ 2262{
2263 int x1, y1, thick, raised_p, top_p, bot_p, left_p, right_p; 2263 int x1, y1, thick, raised_p, top_p, bot_p, left_p, right_p;
2264 int extra_x, extra_y;
2265 XRectangle r; 2264 XRectangle r;
2266 int x = s->x; 2265 int x = s->x;
2267 int y = s->ybase - image_ascent (s->img, s->face, &s->slice); 2266 int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
@@ -2292,20 +2291,6 @@ x_draw_image_relief (struct glyph_string *s)
2292 raised_p = s->img->relief > 0; 2291 raised_p = s->img->relief > 0;
2293 } 2292 }
2294 2293
2295 extra_x = extra_y = 0;
2296 if (s->face->id == TOOL_BAR_FACE_ID)
2297 {
2298 if (CONSP (Vtool_bar_button_margin)
2299 && INTEGERP (XCAR (Vtool_bar_button_margin))
2300 && INTEGERP (XCDR (Vtool_bar_button_margin)))
2301 {
2302 extra_x = XINT (XCAR (Vtool_bar_button_margin));
2303 extra_y = XINT (XCDR (Vtool_bar_button_margin));
2304 }
2305 else if (INTEGERP (Vtool_bar_button_margin))
2306 extra_x = extra_y = XINT (Vtool_bar_button_margin);
2307 }
2308
2309 x1 = x + s->slice.width - 1; 2294 x1 = x + s->slice.width - 1;
2310 y1 = y + s->slice.height - 1; 2295 y1 = y + s->slice.height - 1;
2311 top_p = bot_p = left_p = right_p = 0; 2296 top_p = bot_p = left_p = right_p = 0;
diff --git a/test/ChangeLog b/test/ChangeLog
index b66c2925287..21f0f29b73b 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,9 @@
12012-12-02 Chong Yidong <cyd@gnu.org>
2
3 * automated/ruby-mode-tests.el
4 (ruby-add-log-current-method-examples): Don't use loop macro, to
5 allow automated testing to work.
6
12012-11-20 Stefan Monnier <monnier@iro.umontreal.ca> 72012-11-20 Stefan Monnier <monnier@iro.umontreal.ca>
2 8
3 * automated/advice-tests.el (advice-tests--data): Remove. 9 * automated/advice-tests.el (advice-tests--data): Remove.
diff --git a/test/automated/ruby-mode-tests.el b/test/automated/ruby-mode-tests.el
index ad48413b030..620fe72fb69 100644
--- a/test/automated/ruby-mode-tests.el
+++ b/test/automated/ruby-mode-tests.el
@@ -296,21 +296,23 @@ VALUES-PLIST is a list with alternating index and value elements."
296 (let ((pairs '(("foo" . "#foo") 296 (let ((pairs '(("foo" . "#foo")
297 ("C.foo" . ".foo") 297 ("C.foo" . ".foo")
298 ("self.foo" . ".foo")))) 298 ("self.foo" . ".foo"))))
299 (loop for (name . value) in pairs 299 (dolist (pair pairs)
300 do (with-temp-buffer 300 (let ((name (car pair))
301 (insert (ruby-test-string 301 (value (cdr pair)))
302 "module M 302 (with-temp-buffer
303 (insert (ruby-test-string
304 "module M
303 | class C 305 | class C
304 | def %s 306 | def %s
305 | end 307 | end
306 | end 308 | end
307 |end" 309 |end"
308 name)) 310 name))
309 (ruby-mode) 311 (ruby-mode)
310 (search-backward "def") 312 (search-backward "def")
311 (forward-line) 313 (forward-line)
312 (should (string= (ruby-add-log-current-method) 314 (should (string= (ruby-add-log-current-method)
313 (format "M::C%s" value))))))) 315 (format "M::C%s" value))))))))
314 316
315(defvar ruby-block-test-example 317(defvar ruby-block-test-example
316 (ruby-test-string 318 (ruby-test-string