diff options
| author | Joakim Verona | 2012-12-04 01:46:34 +0100 |
|---|---|---|
| committer | Joakim Verona | 2012-12-04 01:46:34 +0100 |
| commit | d28fde00abbbf26b7c80700b1c9bc18b5079a30e (patch) | |
| tree | 3bf606901b01f67d6b2eed3998ac6fae9f4518a8 | |
| parent | fa8510a9aabe34d367d935b960eab0abbf060e18 (diff) | |
| parent | c38a186c2e06e0a351d166c5ef06d7307e145f45 (diff) | |
| download | emacs-d28fde00abbbf26b7c80700b1c9bc18b5079a30e.tar.gz emacs-d28fde00abbbf26b7c80700b1c9bc18b5079a30e.zip | |
auto upstream
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 @@ | |||
| 1 | 2012-12-03 Chong Yidong <cyd@gnu.org> | ||
| 2 | |||
| 3 | * custom.texi (Init Rebinding): kbd is now a function (Bug#13052). | ||
| 4 | |||
| 5 | 2012-12-02 Kevin Ryde <user42@zip.com.au> | ||
| 6 | |||
| 7 | * maintaining.texi (Tag Syntax): Mention (defvar foo) handling. | ||
| 8 | |||
| 1 | 2012-12-01 Kevin Ryde <user42@zip.com.au> | 9 | 2012-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 |
| 1651 | simplest is to use the @code{kbd} macro, which converts a textual | 1651 | simplest is to use the @code{kbd} function, which converts a textual |
| 1652 | representation of a key sequence---similar to how we have written key | 1652 | representation of a key sequence---similar to how we have written key |
| 1653 | sequences in this manual---into a form that can be passed as an | 1653 | sequences in this manual---into a form that can be passed as an |
| 1654 | argument to @code{global-set-key}. For example, here's how to bind | 1654 | argument 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 |
| 1680 | vector to specify the key sequence. Using a string is simpler, but | 1680 | specify the key sequence. Using a string is simpler, but only works |
| 1681 | only works for @acronym{ASCII} characters and Meta-modified | 1681 | for @acronym{ASCII} characters and Meta-modified @acronym{ASCII} |
| 1682 | @acronym{ASCII} characters. For example, here's how to bind @kbd{C-x | 1682 | characters. For example, here's how to bind @kbd{C-x M-l} to |
| 1683 | M-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 |
| 1678 | In Lisp code, any function defined with @code{defun}, any variable | 1678 | In Lisp code, any function defined with @code{defun}, any variable |
| 1679 | defined with @code{defvar} or @code{defconst}, and in general the first | 1679 | defined with @code{defvar} or @code{defconst}, and in general the |
| 1680 | argument of any expression that starts with @samp{(def} in column zero is | 1680 | first argument of any expression that starts with @samp{(def} in |
| 1681 | a tag. | 1681 | column zero is a tag. As an exception, expressions of the form |
| 1682 | @code{(defvar @var{foo})} are treated as declarations, and are only | ||
| 1683 | tagged if the @samp{--declarations} option is given. | ||
| 1682 | 1684 | ||
| 1683 | @item | 1685 | @item |
| 1684 | In Scheme code, tags include anything defined with @code{def} or with a | 1686 | In 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 @@ | |||
| 1 | 2012-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 | |||
| 1 | 2012-11-24 Paul Eggert <eggert@cs.ucla.edu> | 18 | 2012-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 | |||
| 141 | then the caller supplies the arguments and @var{arg-descriptor} has no | 141 | then the caller supplies the arguments and @var{arg-descriptor} has no |
| 142 | effect. | 142 | effect. |
| 143 | 143 | ||
| 144 | @cindex @code{interactive-form}, function property | 144 | @cindex @code{interactive-form}, symbol property |
| 145 | The @code{interactive} form must be located at top-level in the | 145 | The @code{interactive} form must be located at top-level in the |
| 146 | function body, or in the function symbol's @code{interactive-form} | 146 | function body, or in the function symbol's @code{interactive-form} |
| 147 | property (@pxref{Symbol Plists}). It has its effect because the | 147 | property (@pxref{Symbol Properties}). It has its effect because the |
| 148 | command loop looks for it before calling the function | 148 | command 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 |
| 150 | forms are executed; at this time, if the @code{interactive} form | 150 | forms 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 |
| 473 | customization buffer, and @code{customized-value} to record the value | 473 | customization buffer, and @code{customized-value} to record the value |
| 474 | set by the user with the customization buffer, but not saved. | 474 | set 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 |
| 476 | is an expression that evaluates to the value. | 476 | which is an expression that evaluates to the value. |
| 477 | 477 | ||
| 478 | @defun custom-reevaluate-setting symbol | 478 | @defun custom-reevaluate-setting symbol |
| 479 | This function re-evaluates the standard value of @var{symbol}, which | 479 | This 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}). |
| 2291 | The @code{saved-face} property stores the face specification saved by | 2291 | The @code{saved-face} property stores the face specification saved by |
| 2292 | the user, using the customization buffer; the @code{customized-face} | 2292 | the user, using the customization buffer; the @code{customized-face} |
| 2293 | property stores the face specification customized for the current | 2293 | property 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 | ||
| 382 | Modifying Existing List Structure | 383 | Modifying 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 | ||
| 390 | Property 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 | |||
| 389 | Sequences, Arrays, and Vectors | 396 | Sequences, 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 | ||
| 416 | Property Lists | 423 | Symbol 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 | ||
| 423 | Evaluation | 428 | Evaluation |
| 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 |
| 76 | representations, @ref{Init Rebinding,,, emacs, The GNU Emacs Manual}. | 76 | representations, @ref{Init Rebinding,,, emacs, The GNU Emacs Manual}. |
| 77 | 77 | ||
| 78 | @defmac kbd keyseq-text | 78 | @defun kbd keyseq-text |
| 79 | This macro converts the text @var{keyseq-text} (a string constant) | 79 | This function converts the text @var{keyseq-text} (a string constant) |
| 80 | into a key sequence (a string or vector constant). The contents of | 80 | into 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 |
| 82 | by the @kbd{C-x C-k @key{RET}} (@code{kmacro-edit-macro}) command; in | 82 | by the @kbd{C-x C-k @key{RET}} (@code{kmacro-edit-macro}) command; in |
| @@ -97,7 +97,7 @@ Manual}. | |||
| 97 | 97 | ||
| 98 | This macro is not meant for use with arguments that vary---only | 98 | This macro is not meant for use with arguments that vary---only |
| 99 | with string constants. | 99 | with 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, |
| 1295 | or if @var{key} is not a string or vector representing a key sequence. | 1295 | or if @var{key} is not a string or vector representing a key sequence. |
| 1296 | You can use event types (symbols) as shorthand for events that are | 1296 | You can use event types (symbols) as shorthand for events that are |
| 1297 | lists. The @code{kbd} macro (@pxref{Key Sequences}) is a convenient | 1297 | lists. The @code{kbd} function (@pxref{Key Sequences}) is a |
| 1298 | way to specify the key sequence. | 1298 | convenient way to specify the key sequence. |
| 1299 | 1299 | ||
| 1300 | @defun define-key keymap key binding | 1300 | @defun define-key keymap key binding |
| 1301 | This function sets the binding for @var{key} in @var{keymap}. (If | 1301 | This 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}. | |||
| 1821 | compares the @sc{cdr} of each @var{alist} association instead of the | 1822 | compares 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 | ||
| 1832 | elements. Each of the pairs associates a property name (usually a | ||
| 1833 | symbol) with a property or value. Here is an example of a property | ||
| 1834 | list: | ||
| 1835 | |||
| 1836 | @example | ||
| 1837 | (pine cones numbers (1 2 3) color "blue") | ||
| 1838 | @end example | ||
| 1839 | |||
| 1840 | @noindent | ||
| 1841 | This 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, | ||
| 1844 | but the names are usually symbols (as they are in this example). | ||
| 1845 | |||
| 1846 | Property lists are used in several contexts. For instance, the | ||
| 1847 | function @code{put-text-property} takes an argument which is a | ||
| 1848 | property list, specifying text properties and associated values which | ||
| 1849 | are to be applied to text in a string or buffer. @xref{Text | ||
| 1850 | Properties}. | ||
| 1851 | |||
| 1852 | Another prominent use of property lists is for storing symbol | ||
| 1853 | properties. Every symbol possesses a list of properties, used to | ||
| 1854 | record miscellaneous information about the symbol; these properties | ||
| 1855 | are 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 | ||
| 1870 | property lists. In contrast to association lists, the order of the | ||
| 1871 | pairs in the property list is not significant, since the property | ||
| 1872 | names must be distinct. | ||
| 1873 | |||
| 1874 | Property lists are better than association lists for attaching | ||
| 1875 | information to various Lisp function names or variables. If your | ||
| 1876 | program keeps all such information in one association list, it will | ||
| 1877 | typically need to search that entire list each time it checks for an | ||
| 1878 | association for a particular Lisp function name or variable, which | ||
| 1879 | could be slow. By contrast, if you keep the same information in the | ||
| 1880 | property lists of the function names or variables themselves, each | ||
| 1881 | search will scan only the length of one property list, which is | ||
| 1882 | usually short. This is why the documentation for a variable is | ||
| 1883 | recorded in a property named @code{variable-documentation}. The byte | ||
| 1884 | compiler likewise uses properties to record those functions needing | ||
| 1885 | special treatment. | ||
| 1886 | |||
| 1887 | However, association lists have their own advantages. Depending on | ||
| 1888 | your application, it may be faster to add an association to the front of | ||
| 1889 | an association list than to update a property. All properties for a | ||
| 1890 | symbol are stored in the same property list, so there is a possibility | ||
| 1891 | of a conflict between different uses of a property name. (For this | ||
| 1892 | reason, it is a good idea to choose property names that are probably | ||
| 1893 | unique, such as by beginning the property name with the program's usual | ||
| 1894 | name-prefix for variables and functions.) An association list may be | ||
| 1895 | used like a stack where associations are pushed on the front of the list | ||
| 1896 | and 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. | ||
| 1902 | They all compare property names using @code{eq}. | ||
| 1903 | |||
| 1904 | @defun plist-get plist property | ||
| 1905 | This returns the value of the @var{property} property stored in the | ||
| 1906 | property list @var{plist}. It accepts a malformed @var{plist} | ||
| 1907 | argument. If @var{property} is not found in the @var{plist}, it | ||
| 1908 | returns @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 | ||
| 1923 | This stores @var{value} as the value of the @var{property} property in | ||
| 1924 | the property list @var{plist}. It may modify @var{plist} destructively, | ||
| 1925 | or it may construct a new list structure without altering the old. The | ||
| 1926 | function returns the modified property list, so you can store that back | ||
| 1927 | in 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 | ||
| 1948 | Like @code{plist-get} except that it compares properties | ||
| 1949 | using @code{equal} instead of @code{eq}. | ||
| 1950 | @end defun | ||
| 1951 | |||
| 1952 | @defun lax-plist-put plist property value | ||
| 1953 | Like @code{plist-put} except that it compares properties | ||
| 1954 | using @code{equal} instead of @code{eq}. | ||
| 1955 | @end defun | ||
| 1956 | |||
| 1957 | @defun plist-member plist property | ||
| 1958 | This returns non-@code{nil} if @var{plist} contains the given | ||
| 1959 | @var{property}. Unlike @code{plist-get}, this allows you to distinguish | ||
| 1960 | between a missing property and a property with the value @code{nil}. | ||
| 1961 | The 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 |
| 543 | The subtype controls the number of @dfn{extra slots} in the | 543 | The subtype controls the number of @dfn{extra slots} in the |
| 544 | char-table. This number is specified by the subtype's | 544 | char-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 |
| 546 | integer between 0 and 10. If the subtype has no such symbol property, | 546 | Properties}), whose value should be an integer between 0 and 10. If |
| 547 | the char-table has no extra slots. @xref{Property Lists}, for | 547 | the subtype has no such symbol property, the char-table has no extra |
| 548 | information about symbol properties. | 548 | slots. |
| 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 |
| 17 | with @code{symbolp}: | 17 | @code{symbolp}: |
| 18 | 18 | ||
| 19 | @defun symbolp object | 19 | @defun symbolp object |
| 20 | This function returns @code{t} if @var{object} is a symbol, @code{nil} | 20 | This 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 |
| 93 | property list. To get a symbol's property list, use the function | 93 | property 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 |
| 97 | that the cell does not reference any object. (This is not the same | 97 | that 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 | |||
| 376 | it returns @code{nil}. | 376 | it 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 |
| 385 | elements. Each of the pairs associates a property name (usually a | 384 | can be used to record miscellaneous information about the symbol. For |
| 386 | symbol) with a property or value. | 385 | example, when a symbol has a @code{risky-local-variable} property with |
| 386 | a non-@code{nil} value, that means the variable which the symbol names | ||
| 387 | is 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 |
| 389 | Components}). This property list is used to record information about | 390 | symbol's property list cell (@pxref{Symbol Components}), in the form |
| 390 | the symbol, such as its variable documentation and the name of the | 391 | of a property list (@pxref{Property Lists}). |
| 391 | file where it was defined. | ||
| 392 | |||
| 393 | Property lists can also be used in other contexts. For instance, | ||
| 394 | you can assign property lists to character positions in a string or | ||
| 395 | buffer. @xref{Text Properties}. | ||
| 396 | |||
| 397 | The property names and values in a property list can be any Lisp | ||
| 398 | objects, but the names are usually symbols. Property list functions | ||
| 399 | compare the property names using @code{eq}. Here is an example of a | ||
| 400 | property list, found on the symbol @code{progn} when the compiler is | ||
| 401 | loaded: | ||
| 402 | |||
| 403 | @example | ||
| 404 | (lisp-indent-function 0 byte-compile byte-compile-progn) | ||
| 405 | @end example | ||
| 406 | |||
| 407 | @noindent | ||
| 408 | Here @code{lisp-indent-function} and @code{byte-compile} are property | ||
| 409 | names, 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 | ||
| 425 | property lists. In contrast to association lists, the order of the | ||
| 426 | pairs in the property list is not significant since the property names | ||
| 427 | must be distinct. | ||
| 428 | |||
| 429 | Property lists are better than association lists for attaching | ||
| 430 | information to various Lisp function names or variables. If your | ||
| 431 | program keeps all such information in one association list, it will | ||
| 432 | typically need to search that entire list each time it checks for an | ||
| 433 | association for a particular Lisp function name or variable, which | ||
| 434 | could be slow. By contrast, if you keep the same information in the | ||
| 435 | property lists of the function names or variables themselves, each | ||
| 436 | search will scan only the length of one property list, which is | ||
| 437 | usually short. This is why the documentation for a variable is | ||
| 438 | recorded in a property named @code{variable-documentation}. The byte | ||
| 439 | compiler likewise uses properties to record those functions needing | ||
| 440 | special treatment. | ||
| 441 | |||
| 442 | However, association lists have their own advantages. Depending on | ||
| 443 | your application, it may be faster to add an association to the front of | ||
| 444 | an association list than to update a property. All properties for a | ||
| 445 | symbol are stored in the same property list, so there is a possibility | ||
| 446 | of a conflict between different uses of a property name. (For this | ||
| 447 | reason, it is a good idea to choose property names that are probably | ||
| 448 | unique, such as by beginning the property name with the program's usual | ||
| 449 | name-prefix for variables and functions.) An association list may be | ||
| 450 | used like a stack where associations are pushed on the front of the list | ||
| 451 | and 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 | ||
| 457 | This function returns the property list of @var{symbol}. | ||
| 458 | @end defun | ||
| 459 | |||
| 460 | @defun setplist symbol plist | ||
| 461 | This function sets @var{symbol}'s property list to @var{plist}. | ||
| 462 | Normally, @var{plist} should be a well-formed property list, but this is | ||
| 463 | not 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 | |||
| 472 | For symbols in special obarrays, which are not used for ordinary | ||
| 473 | purposes, it may make sense to use the property list cell in a | ||
| 474 | nonstandard 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 |
| 479 | This function finds the value of the property named @var{property} in | 404 | This function returns the value of the property named @var{property} |
| 480 | @var{symbol}'s property list. If there is no such property, @code{nil} | 405 | in @var{symbol}'s property list. If there is no such property, it |
| 481 | is returned. Thus, there is no distinction between a value of | 406 | returns @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 | ||
| 484 | The name @var{property} is compared with the existing property names | 409 | The name @var{property} is compared with the existing property names |
| @@ -487,12 +412,6 @@ using @code{eq}, so any object is a legitimate property. | |||
| 487 | See @code{put} for an example. | 412 | See @code{put} for an example. |
| 488 | @end defun | 413 | @end defun |
| 489 | 414 | ||
| 490 | @defun function-get symbol property | ||
| 491 | This function is identical to @code{get}, except that if @var{symbol} | ||
| 492 | is the name of a function alias, it looks in the property list of the | ||
| 493 | symbol naming the actual function. @xref{Defining Functions}. | ||
| 494 | @end defun | ||
| 495 | |||
| 496 | @defun put symbol property value | 415 | @defun put symbol property value |
| 497 | This function puts @var{value} onto @var{symbol}'s property list under | 416 | This function puts @var{value} onto @var{symbol}'s property list under |
| 498 | the property name @var{property}, replacing any previous property value. | 417 | the 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 | 433 | This function returns the property list of @var{symbol}. |
| 515 | |||
| 516 | These functions are useful for manipulating property lists | ||
| 517 | not stored in symbols: | ||
| 518 | |||
| 519 | @defun plist-get plist property | ||
| 520 | This returns the value of the @var{property} property stored in the | ||
| 521 | property list @var{plist}. It accepts a malformed @var{plist} | ||
| 522 | argument. If @var{property} is not found in the @var{plist}, it | ||
| 523 | returns @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 | ||
| 538 | This stores @var{value} as the value of the @var{property} property in | ||
| 539 | the property list @var{plist}. It may modify @var{plist} destructively, | ||
| 540 | or it may construct a new list structure without altering the old. The | ||
| 541 | function returns the modified property list, so you can store that back | ||
| 542 | in 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 |
| 437 | This function sets @var{symbol}'s property list to @var{plist}. | ||
| 438 | Normally, @var{plist} should be a well-formed property list, but this is | ||
| 439 | not 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 | 448 | For symbols in special obarrays, which are not used for ordinary |
| 563 | Like @code{plist-get} except that it compares properties | 449 | purposes, it may make sense to use the property list cell in a |
| 564 | using @code{equal} instead of @code{eq}. | 450 | nonstandard 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 |
| 568 | Like @code{plist-put} except that it compares properties | 455 | This function is identical to @code{get}, except that if @var{symbol} |
| 569 | using @code{equal} instead of @code{eq}. | 456 | is the name of a function alias, it looks in the property list of the |
| 457 | symbol 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 |
| 573 | This 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 | |
| 575 | between a missing property and a property with the value @code{nil}. | 463 | Here, we list the symbol properties which are used for special |
| 576 | The value is actually the tail of @var{plist} whose @code{car} is | 464 | purposes in Emacs. In the following table, whenever we say ``the |
| 577 | @var{property}. | 465 | named function'', that means the function whose name is the relevant |
| 578 | @end defun | 466 | symbol; similarly for ``the named variable'' etc. |
| 467 | |||
| 468 | @table @code | ||
| 469 | @item :advertised-binding | ||
| 470 | This property value specifies the preferred key binding, when showing | ||
| 471 | documentation, for the named function. @xref{Keys in Documentation}. | ||
| 472 | |||
| 473 | @item char-table-extra-slots | ||
| 474 | The value, if non-@code{nil}, specifies the number of extra slots in | ||
| 475 | the 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 | ||
| 481 | These properties are used to record a face's standard, saved, | ||
| 482 | customized, and themed face specs. Do not set them directly; they are | ||
| 483 | managed by @code{defface} and related functions. @xref{Defining | ||
| 484 | Faces}. | ||
| 485 | |||
| 486 | @itemx customized-value | ||
| 487 | @itemx saved-value | ||
| 488 | @item standard-value | ||
| 489 | @itemx theme-value | ||
| 490 | These properties are used to record a customizable variable's standard | ||
| 491 | value, saved value, customized-but-unsaved value, and themed values. | ||
| 492 | Do not set them directly; they are managed by @code{defcustom} and | ||
| 493 | related functions. @xref{Variable Definitions}. | ||
| 494 | |||
| 495 | @item disabled | ||
| 496 | If the value is non-@code{nil}, the named function is disabled as a | ||
| 497 | command. @xref{Disabling Commands}. | ||
| 498 | |||
| 499 | @item face-documentation | ||
| 500 | The value stores the documentation string of the named face. This is | ||
| 501 | normally set automatically by @code{defface}. @xref{Defining Faces}. | ||
| 502 | |||
| 503 | @item history-length | ||
| 504 | The value, if non-@code{nil}, specifies the maximum minibuffer history | ||
| 505 | length for the named history list variable. @xref{Minibuffer | ||
| 506 | History}. | ||
| 507 | |||
| 508 | @item interactive-form | ||
| 509 | The value is an interactive form for the named function. Normally, | ||
| 510 | you should not set this directly; use the @code{interactive} special | ||
| 511 | form instead. @xref{Interactive Call}. | ||
| 512 | |||
| 513 | @item menu-enable | ||
| 514 | The value is an expression for determining whether the named menu item | ||
| 515 | should be enabled in menus. @xref{Simple Menu Items}. | ||
| 516 | |||
| 517 | @item mode-class | ||
| 518 | If the value is @code{special}, the named major mode is ``special''. | ||
| 519 | @xref{Major Mode Conventions}. | ||
| 520 | |||
| 521 | @item permanent-local | ||
| 522 | If the value is non-@code{nil}, the named variable is a buffer-local | ||
| 523 | variable whose value should not be reset when changing major modes. | ||
| 524 | @xref{Creating Buffer-Local}. | ||
| 525 | |||
| 526 | @item permanent-local-hook | ||
| 527 | If the value is non-@code{nil}, the named function should not be | ||
| 528 | deleted from the local value of a hook variable when changing major | ||
| 529 | modes. @xref{Setting Hooks}. | ||
| 530 | |||
| 531 | @item pure | ||
| 532 | This property is used internally to mark certain named functions for | ||
| 533 | byte compiler optimization. Do not set it. | ||
| 534 | |||
| 535 | @item risky-local-variable | ||
| 536 | If the value is non-@code{nil}, the named variable is considered risky | ||
| 537 | as a file-local variable. @xref{File Local Variables}. | ||
| 538 | |||
| 539 | @item safe-function | ||
| 540 | If the value is non-@code{nil}, the named function is considered | ||
| 541 | generally safe for evaluation. @xref{Function Safety}. | ||
| 542 | |||
| 543 | @item safe-local-eval-function | ||
| 544 | If the value is non-@code{nil}, the named function is safe to call in | ||
| 545 | file-local evaluation forms. @xref{File Local Variables}. | ||
| 546 | |||
| 547 | @item safe-local-variable | ||
| 548 | The value specifies a function for determining safe file-local values | ||
| 549 | for the named variable. @xref{File Local Variables}. | ||
| 550 | |||
| 551 | @item side-effect-free | ||
| 552 | A non-@code{nil} value indicates that the named function is free of | ||
| 553 | side-effects, for determining function safety (@pxref{Function | ||
| 554 | Safety}) as well as for byte compiler optimizations. Do not set it. | ||
| 555 | |||
| 556 | @item variable-documentation | ||
| 557 | If non-@code{nil}, this specifies the named vaariable's documentation | ||
| 558 | string. This is normally set automatically by @code{defvar} and | ||
| 559 | related 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 | |||
| 1423 | subsequent major mode. @xref{Hooks}. | 1423 | subsequent 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 |
| 1428 | A buffer-local variable is @dfn{permanent} if the variable name (a | 1427 | A buffer-local variable is @dfn{permanent} if the variable name (a |
| 1429 | symbol) has a @code{permanent-local} property that is non-@code{nil}. | 1428 | symbol) 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 @@ | |||
| 1 | 2012-12-02 Kevin Ryde <user42@zip.com.au> | ||
| 2 | |||
| 3 | * etags.1: Mention effect of --declarations in Lisp. | ||
| 4 | |||
| 1 | 2012-06-03 Glenn Morris <rgm@gnu.org> | 5 | 2012-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 |
| 89 | In C and derived languages, create tags for function declarations, | 89 | In C and derived languages, create tags for function declarations, |
| 90 | and create tags for extern variables unless \-\-no\-globals is used. | 90 | and create tags for extern variables unless \-\-no\-globals is used. |
| 91 | In Lisp, create tags for (defvar foo) declarations. | ||
| 91 | .TP | 92 | .TP |
| 92 | .B \-D, \-\-no\-defines | 93 | .B \-D, \-\-no\-defines |
| 93 | Do not create tag entries for C preprocessor constant definitions | 94 | Do 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 @@ | |||
| 1 | 2012-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 | |||
| 6 | 2012-12-03 Glenn Morris <rgm@gnu.org> | ||
| 7 | |||
| 8 | * rcirc.texi (Notices): Fix typo. | ||
| 9 | |||
| 1 | 2012-11-25 Bill Wohler <wohler@newt.com> | 10 | 2012-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 | |||
| 764 | omit away messages: | 764 | omit 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 |
| 107 | The latest release of @value{tramp} is available for | 107 | The 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 |
| 110 | details. | 110 | details. |
| 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 | |||
| 377 | for XEmacs, as well. So maybe it is easier to just use those. But if | 377 | for XEmacs, as well. So maybe it is easier to just use those. But if |
| 378 | you want the bleeding edge, read on@dots{...} | 378 | you want the bleeding edge, read on@dots{...} |
| 379 | 379 | ||
| 380 | For the especially brave, @value{tramp} is available from CVS. The CVS | 380 | For the especially brave, @value{tramp} is available from Git. The Git |
| 381 | version is the latest version of the code and may contain incomplete | 381 | version is the latest version of the code and may contain incomplete |
| 382 | features or new issues. Use these versions at your own risk. | 382 | features or new issues. Use these versions at your own risk. |
| 383 | 383 | ||
| 384 | Instructions for obtaining the latest development version of @value{tramp} | 384 | Instructions for obtaining the latest development version of @value{tramp} |
| 385 | from CVS can be found by going to the Savannah project page at the | 385 | from Git can be found by going to the Savannah project page at the |
| 386 | following URL and then clicking on the CVS link in the navigation bar | 386 | following URL and then clicking on the Git link in the navigation bar |
| 387 | at the top. | 387 | at 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 | ||
| 401 | Tramp 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 |
| 413 | Once you've got updated files from the CVS repository, you need to run | 418 | Once 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} |
| 415 | script: | 420 | script: |
| 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 | ||
| 983 | This is another not natural @value{tramp} method. It uses the | 988 | This 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 |
| 985 | an SMB server. An SMB server might be a Samba (or CIFS) server on | 990 | an SMB server. An SMB server might be a Samba (or CIFS) server on |
| 986 | another UNIX host or, more interesting, a host running MS Windows. So | 991 | another UNIX host or, more interesting, a host running MS Windows. So |
| @@ -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: | ||
| 73 | when its arg ADJACENT is non-nil (when called interactively with C-u C-u) | ||
| 74 | it works like the utility `uniq'. Otherwise by default it deletes | ||
| 75 | duplicate 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, |
| 815 | and are now undefined. For backwards compatibility, defun and | 820 | and are now undefined. For backwards compatibility, `defun' and |
| 816 | defmacro currently return the name of the newly defined function/macro | 821 | `defmacro' currently return the name of the newly defined |
| 817 | but this should not be relied upon. | 822 | function/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 @@ | |||
| 1 | 2012-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 | |||
| 1 | 2012-12-01 Kevin Ryde <user42@zip.com.au> | 8 | 2012-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 *); | |||
| 353 | static char *concat (const char *, const char *, const char *); | 353 | static char *concat (const char *, const char *, const char *); |
| 354 | static char *skip_spaces (char *); | 354 | static char *skip_spaces (char *); |
| 355 | static char *skip_non_spaces (char *); | 355 | static char *skip_non_spaces (char *); |
| 356 | static char *skip_name (char *); | ||
| 356 | static char *savenstr (const char *, int); | 357 | static char *savenstr (const char *, int); |
| 357 | static char *savestr (const char *); | 358 | static char *savestr (const char *); |
| 358 | static char *etags_strchr (const char *, int); | 359 | static 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\ |
| 620 | defined with `defvar' or `defconst', and in general the first\n\ | 621 | defined with `defvar' or `defconst', and in general the first\n\ |
| 621 | argument of any expression that starts with `(def' in column zero\n\ | 622 | argument of any expression that starts with `(def' in column zero\n\ |
| 622 | is a tag."; | 623 | is a tag.\n\ |
| 624 | The `--declarations' option tags \"(defvar foo)\" constructs too."; | ||
| 623 | 625 | ||
| 624 | static const char *Lua_suffixes [] = | 626 | static 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.*/ | ||
| 6326 | static char * | ||
| 6327 | skip_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. */ |
| 6311 | void | 6336 | void |
| 6312 | fatal (const char *s1, const char *s2) | 6337 | fatal (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 @@ | |||
| 1 | 2012-12-03 Juri Linkov <juri@jurta.org> | ||
| 2 | |||
| 3 | * sort.el (delete-duplicate-lines): New command. (Bug#13032) | ||
| 4 | |||
| 5 | 2012-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 | |||
| 13 | 2012-12-03 Jay Belanger <jay.p.belanger@gmail.com> | ||
| 14 | |||
| 15 | * calc/calc-forms.el (math-date-to-iso-dt): Fix weekday number. | ||
| 16 | |||
| 17 | 2012-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 | |||
| 22 | 2012-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 | |||
| 28 | 2012-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 | |||
| 35 | 2012-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 | |||
| 40 | 2012-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 | |||
| 45 | 2012-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 | |||
| 55 | 2012-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 | |||
| 60 | 2012-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 | |||
| 1 | 2012-12-01 Yuya Nishihara <yuya@tcha.org> (tiny change) | 65 | 2012-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. |
| 207 | The Buffer Menu is invoked by the commands \\[list-buffers], \\[buffer-menu], and | 207 | The 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) | 209 | See `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. | ||
| 215 | By default, all buffers are listed except those whose names start | ||
| 216 | with a space (which are for internal use). With prefix argument | ||
| 217 | ARG, show only buffers that are visiting files. | ||
| 218 | |||
| 219 | The first column (denoted \"C\") shows \".\" for the buffer from | ||
| 220 | which you came. It shows \">\" for buffers you mark to be | ||
| 221 | displayed, and \"D\" for those you mark for deletion. | ||
| 222 | |||
| 223 | The \"R\" column has a \"%\" if the buffer is read-only. | ||
| 224 | The \"M\" column has a \"*\" if it is modified, or \"S\" if you | ||
| 225 | have marked it for saving. | ||
| 226 | |||
| 227 | After this come the buffer name, its size in characters, its | ||
| 228 | major mode, and the visited file name (if any). | ||
| 229 | |||
| 230 | 210 | ||
| 231 | In the Buffer Menu, the following commands are defined: | 211 | In 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. | ||
| 248 | By default, the Buffer Menu lists all buffers except those whose | ||
| 249 | names start with a space (which are for internal use). With | ||
| 250 | prefix argument ARG, show only buffers that are visiting files. | ||
| 251 | |||
| 252 | In the Buffer Menu, the first column (denoted \"C\") shows \".\" | ||
| 253 | for the buffer from which you came, \">\" for buffers you mark to | ||
| 254 | be displayed, and \"D\" for those you mark for deletion. | ||
| 255 | |||
| 256 | The \"R\" column has a \"%\" if the buffer is read-only. | ||
| 257 | The \"M\" column has a \"*\" if it is modified, or \"S\" if you | ||
| 258 | have marked it for saving. | ||
| 259 | |||
| 260 | The remaining columns show the buffer name, the buffer size in | ||
| 261 | characters, its major mode, and the visited file name (if any). | ||
| 262 | |||
| 263 | See `Buffer-menu-mode' for the keybindings available the Buffer | ||
| 264 | Menu." | ||
| 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. |
| 282 | The list is displayed in a buffer named \"*Buffer List*\". | 285 | The list is displayed in a buffer named \"*Buffer List*\". |
| 283 | See `buffer-menu' for details about the Buffer Menu buffer. | 286 | See `buffer-menu' for a description of the Buffer Menu. |
| 284 | 287 | ||
| 285 | By default, all buffers are listed except those whose names start | 288 | By default, all buffers are listed except those whose names start |
| 286 | with a space (which are for internal use). With prefix argument | 289 | with 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. |
| 380 | Prefix ARG means move that many lines." | 383 | A subsequent \\<Buffer-menu-mode-map>`\\[Buffer-menu-execute]' |
| 384 | command will delete the marked buffer. Prefix ARG means move | ||
| 385 | that 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" |
| 448 | before 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 @@ | |||
| 1 | 2012-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 | |||
| 1 | 2012-11-19 Katsumi Yamaoka <yamaoka@jpl.org> | 10 | 2012-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. |
| 114 | You may want to sync `gnus-newsrc-last-checked-date' but pretty | 121 | You 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: ") | 5101 | If there is an existing Info buffer for MANUAL, display it. |
| 5102 | Otherwise, 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. |
| 110 | The determination as to which compression scheme, if any, to use is | 110 | The determination as to which compression scheme, if any, to use is |
| 111 | based on the filename itself and `jka-compr-compression-info-list'." | 111 | based 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 | 816 | my $data; | |
| 817 | binmode(\\*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; | 820 | while (read STDIN, $data, 54) { |
| 822 | |||
| 823 | while (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 | |||
| 4333 | You can also deactivate the mark by typing \\[keyboard-quit] or | 4333 | You can also deactivate the mark by typing \\[keyboard-quit] or |
| 4334 | \\[keyboard-escape-quit]. | 4334 | \\[keyboard-escape-quit]. |
| 4335 | 4335 | ||
| 4336 | Many commands change their behavior when Transient Mark mode is in effect | 4336 | Many commands change their behavior when Transient Mark mode is |
| 4337 | and the mark is active, by acting on the region instead of their usual | 4337 | in effect and the mark is active, by acting on the region instead |
| 4338 | default part of the buffer's text. Examples of such commands include | 4338 | of their usual default part of the buffer's text. Examples of |
| 4339 | \\[comment-dwim], \\[flush-lines], \\[keep-lines], \ | 4339 | such 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]. |
| 4341 | Invoke \\[apropos-documentation] and type \"transient\" or | 4341 | To see the documentation of commands which are sensitive to the |
| 4342 | \"mark.*active\" at the prompt, to see the documentation of | 4342 | Transient Mark mode, invoke \\[apropos-documentation] and type \"transient\" |
| 4343 | commands which are sensitive to the Transient Mark mode." | 4343 | or \"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 | |||
| 569 | If REVERSE is nil, search and delete duplicates forward keeping the first | ||
| 570 | occurrence of duplicate lines. If REVERSE is non-nil (when called | ||
| 571 | interactively with C-u prefix), search and delete duplicates backward | ||
| 572 | keeping the last occurrence of duplicate lines. | ||
| 573 | |||
| 574 | If ADJACENT is non-nil (when called interactively with two C-u prefixes), | ||
| 575 | delete 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 | ||
| 577 | this is more efficient in performance and memory usage than when ADJACENT | ||
| 578 | is nil that uses additional memory to remember previous lines. | ||
| 579 | |||
| 580 | When called from Lisp and INTERACTIVE is omitted or nil, return the number | ||
| 581 | of deleted duplicate lines, do not print it; if INTERACTIVE is t, the | ||
| 582 | function 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. |
| 2651 | Keeps argument list for future Ispell invocations for no async support." | 2651 | Keeps 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. |
| 2897 | This may kill the Ispell process; if so, a new one will be started | 2896 | This may kill the Ispell process; if so, a new one will be started |
| 2898 | when needed." | 2897 | when 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 @@ | |||
| 1 | 2012-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 | |||
| 1 | 2012-10-13 Liam Stitt <stittl@cuug.ab.ca> (tiny change) | 6 | 2012-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: ") | 2558 | If called interactively, read FILE, defaulting to the current |
| 2559 | buffer'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: ") | 2601 | If called interactively, read OLD and NEW, defaulting OLD to the |
| 2602 | current 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 @@ | |||
| 1 | 2012-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 | |||
| 1 | 2012-11-24 Ken Brown <kbrown@cornell.edu> | 6 | 2012-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 @@ | |||
| 1 | 2012-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 | |||
| 63 | 2012-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 | |||
| 68 | 2012-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 | |||
| 73 | 2012-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 | |||
| 82 | 2012-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 | |||
| 93 | 2012-12-03 Chong Yidong <cyd@gnu.org> | ||
| 94 | |||
| 95 | * fileio.c (Vauto_save_list_file_name): Doc fix. | ||
| 96 | |||
| 97 | 2012-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 | |||
| 111 | 2012-12-03 Glenn Morris <rgm@gnu.org> | ||
| 112 | |||
| 113 | * data.c (Fboundp, Fsymbol_value): Doc fix re lexical-binding. | ||
| 114 | |||
| 115 | 2012-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 | |||
| 131 | 2012-12-01 Paul Eggert <eggert@cs.ucla.edu> | ||
| 132 | |||
| 133 | * xterm.c (x_draw_image_relief): Remove unused locals (Bug#10500). | ||
| 134 | |||
| 1 | 2012-12-01 YAMAMOTO Mitsuharu <mituharu@math.s.chiba-u.ac.jp> | 135 | 2012-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 | ||
| 772 | void * | 776 | void * |
| 773 | xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, | 777 | xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, |
| @@ -822,12 +826,7 @@ xstrdup (const char *s) | |||
| 822 | Lisp_Object | 826 | Lisp_Object |
| 823 | safe_alloca_unwind (Lisp_Object arg) | 827 | safe_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 | |||
| 3365 | void | ||
| 3366 | free_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 | ||
| 3366 | Lisp_Object | 3378 | Lisp_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 | ||
| 90 | Lisp_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, | |||
| 1963 | void | 1961 | void |
| 1964 | syms_of_bytecode (void) | 1962 | syms_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. */ |
| 68 | static Lisp_Object Vtemp_file_name_pattern; | 68 | static 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 |
| 72 | bool 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 |
| 75 | const 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. */ | ||
| 80 | static pid_t synch_process_pid; | ||
| 81 | |||
| 82 | /* If nonnegative, a file descriptor that has not been closed. */ | ||
| 83 | static int synch_process_fd; | ||
| 84 | |||
| 85 | /* Block SIGCHLD. */ | ||
| 76 | 86 | ||
| 77 | /* Nonzero => this is the signal number that terminated the subprocess. */ | 87 | static void |
| 78 | int synch_process_termsig; | 88 | block_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. */ | ||
| 82 | int synch_process_retcode; | ||
| 83 | 99 | ||
| 84 | 100 | static void | |
| 85 | /* Clean up when exiting Fcall_process. | 101 | unblock_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. */ |
| 90 | static bool call_process_exited; | ||
| 91 | 109 | ||
| 92 | static Lisp_Object | 110 | static Lisp_Object |
| 93 | call_process_kill (Lisp_Object fdpid) | 111 | call_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 | |||
| 105 | static Lisp_Object | 134 | static Lisp_Object |
| 106 | call_process_cleanup (Lisp_Object arg) | 135 | call_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. | |||
| 181 | usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS) */) | 203 | usage: (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 | ||
| 900 | static Lisp_Object | 913 | static 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 | ||
| 508 | DEFUN ("boundp", Fboundp, Sboundp, 1, 1, 0, | 508 | DEFUN ("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. |
| 510 | Note that if `lexical-binding' is in effect, this refers to the | ||
| 511 | global 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 | ||
| 1049 | DEFUN ("symbol-value", Fsymbol_value, Ssymbol_value, 1, 1, 0, | 1051 | DEFUN ("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. |
| 1053 | Note that if `lexical-binding' is in effect, this returns the | ||
| 1054 | global 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 | |||
| 817 | Lisp_Object | 820 | Lisp_Object |
| 818 | save_excursion_save (void) | 821 | save_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 | |||
| 834 | Lisp_Object | 842 | Lisp_Object |
| 835 | save_excursion_restore (Lisp_Object info) | 843 | save_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. |
| 5773 | This variable is initialized automatically from `auto-save-list-file-prefix' | 5773 | This variable is initialized automatically from `auto-save-list-file-prefix' |
| 5774 | shortly after Emacs reads your `.emacs' file, if you have not yet given it | 5774 | shortly after Emacs reads your init file, if you have not yet given it |
| 5775 | a non-nil value. */); | 5775 | a 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 | ||
| 816 | static void | ||
| 817 | my_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 | ||
| 1768 | void | 1768 | void |
| 1769 | modify_region (struct buffer *buffer, ptrdiff_t start, ptrdiff_t end, | 1769 | modify_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); | |||
| 2801 | extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); | 2801 | extern void del_range_both (ptrdiff_t, ptrdiff_t, ptrdiff_t, ptrdiff_t, bool); |
| 2802 | extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, | 2802 | extern Lisp_Object del_range_2 (ptrdiff_t, ptrdiff_t, |
| 2803 | ptrdiff_t, ptrdiff_t, bool); | 2803 | ptrdiff_t, ptrdiff_t, bool); |
| 2804 | extern void modify_region (struct buffer *, ptrdiff_t, ptrdiff_t, bool); | 2804 | extern void modify_region_1 (ptrdiff_t, ptrdiff_t, bool); |
| 2805 | extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); | 2805 | extern void prepare_to_modify_buffer (ptrdiff_t, ptrdiff_t, ptrdiff_t *); |
| 2806 | extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); | 2806 | extern void signal_after_change (ptrdiff_t, ptrdiff_t, ptrdiff_t); |
| 2807 | extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, | 2807 | extern void adjust_after_insert (ptrdiff_t, ptrdiff_t, ptrdiff_t, |
| @@ -2968,6 +2968,7 @@ extern Lisp_Object make_float (double); | |||
| 2968 | extern void display_malloc_warning (void); | 2968 | extern void display_malloc_warning (void); |
| 2969 | extern ptrdiff_t inhibit_garbage_collection (void); | 2969 | extern ptrdiff_t inhibit_garbage_collection (void); |
| 2970 | extern Lisp_Object make_save_value (void *, ptrdiff_t); | 2970 | extern Lisp_Object make_save_value (void *, ptrdiff_t); |
| 2971 | extern void free_save_value (Lisp_Object); | ||
| 2971 | extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); | 2972 | extern Lisp_Object build_overlay (Lisp_Object, Lisp_Object, Lisp_Object); |
| 2972 | extern void free_marker (Lisp_Object); | 2973 | extern void free_marker (Lisp_Object); |
| 2973 | extern void free_cons (struct Lisp_Cons *); | 2974 | extern void free_cons (struct Lisp_Cons *); |
| @@ -3398,7 +3399,6 @@ extern void syms_of_doc (void); | |||
| 3398 | extern int read_bytecode_char (bool); | 3399 | extern int read_bytecode_char (bool); |
| 3399 | 3400 | ||
| 3400 | /* Defined in bytecode.c. */ | 3401 | /* Defined in bytecode.c. */ |
| 3401 | extern Lisp_Object Qbytecode; | ||
| 3402 | extern void syms_of_bytecode (void); | 3402 | extern void syms_of_bytecode (void); |
| 3403 | extern struct byte_stack *byte_stack_list; | 3403 | extern 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. */ | ||
| 781 | static Lisp_Object deleted_pid_list; | 783 | static Lisp_Object deleted_pid_list; |
| 782 | #endif | 784 | #endif |
| 783 | 785 | ||
| 786 | void | ||
| 787 | record_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 | |||
| 784 | DEFUN ("delete-process", Fdelete_process, Sdelete_process, 1, 1, 0, | 797 | DEFUN ("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. |
| 786 | PROCESS may be a process, a buffer, the name of a process or buffer, or | 799 | PROCESS 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 | ||
| 6168 | static bool | 6163 | /* The main Emacs thread records child processes in three places: |
| 6169 | process_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 | ||
| 6214 | void | 6214 | static void |
| 6215 | record_child_status_change (pid_t pid, int w) | 6215 | handle_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 | |||
| 6311 | static void | ||
| 6312 | handle_child_signal (int sig) | ||
| 6313 | { | ||
| 6314 | record_child_status_change (-1, 0); | ||
| 6315 | } | 6272 | } |
| 6316 | 6273 | ||
| 6317 | static void | 6274 | static 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. */ | ||
| 190 | extern 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. */ | ||
| 196 | extern const char *synch_process_death; | ||
| 197 | |||
| 198 | /* Nonzero => this is the signal number that terminated the subprocess. */ | ||
| 199 | extern int synch_process_termsig; | ||
| 200 | |||
| 201 | /* If synch_process_death is zero, | ||
| 202 | this is exit code of synchronous subprocess. */ | ||
| 203 | extern 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. */ |
| 207 | extern int inhibit_sentinels; | 190 | extern 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 | ||
| 269 | static void | 269 | /* Wait for the subprocess with process id CHILD to terminate or change status. |
| 270 | wait_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. */ | ||
| 278 | static pid_t | ||
| 279 | get_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. */ | ||
| 297 | void | 315 | void |
| 298 | wait_for_termination (pid_t pid) | 316 | wait_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. |
| 304 | void | 322 | Termination counts as a change of status. |
| 305 | interruptible_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. */ | ||
| 330 | pid_t | ||
| 331 | child_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 | ||
| 573 | static void | 597 | static 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. */ |
| 55 | extern void record_child_status_change (pid_t, int); | 56 | extern void record_deleted_pid (pid_t); |
| 56 | 57 | ||
| 57 | /* Defined in sysdep.c. */ | 58 | /* Defined in sysdep.c. */ |
| 58 | extern void wait_for_termination (pid_t); | 59 | extern void wait_for_termination (pid_t, int *, bool); |
| 59 | extern void interruptible_wait_for_termination (pid_t); | 60 | extern 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 | |||
| 90 | static void | ||
| 91 | modify_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 | } |
| @@ -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 | ||
| 35 | extern SYSTEM_INFO sysinfo_cache; | 35 | extern SYSTEM_INFO sysinfo_cache; |
| 36 | extern OSVERSIONINFO osinfo_cache; | 36 | extern OSVERSIONINFO osinfo_cache; |
| 37 | extern unsigned long syspage_mask; | 37 | extern DWORD_PTR syspage_mask; |
| 38 | 38 | ||
| 39 | extern int w32_major_version; | 39 | extern int w32_major_version; |
| 40 | extern int w32_minor_version; | 40 | extern 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); | |||
| 82 | void globals_of_w32fns (void); | 82 | void globals_of_w32fns (void); |
| 83 | 83 | ||
| 84 | extern void free_frame_menubar (struct frame *); | 84 | extern void free_frame_menubar (struct frame *); |
| 85 | extern double atof (const char *); | ||
| 86 | extern int w32_console_toggle_lock_key (int, Lisp_Object); | 85 | extern int w32_console_toggle_lock_key (int, Lisp_Object); |
| 87 | extern void w32_menu_display_help (HWND, HMENU, UINT, UINT); | 86 | extern void w32_menu_display_help (HWND, HMENU, UINT, UINT); |
| 88 | extern void w32_free_menu_strings (HWND); | 87 | extern 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. */ |
| 224 | OSVERSIONINFO osinfo_cache; | 223 | OSVERSIONINFO osinfo_cache; |
| 225 | 224 | ||
| 226 | unsigned long syspage_mask = 0; | 225 | DWORD_PTR syspage_mask = 0; |
| 227 | 226 | ||
| 228 | /* The major and minor versions of NT. */ | 227 | /* The major and minor versions of NT. */ |
| 229 | int w32_major_version; | 228 | int 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. */ |
| 6038 | static UINT CALLBACK | 6037 | static UINT_PTR CALLBACK |
| 6039 | file_dialog_callback (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) | 6038 | file_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 | |||
| 2261 | x_draw_image_relief (struct glyph_string *s) | 2261 | x_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 @@ | |||
| 1 | 2012-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 | |||
| 1 | 2012-11-20 Stefan Monnier <monnier@iro.umontreal.ca> | 7 | 2012-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 |