diff --git a/ChangeLog b/ChangeLog index 8882deb6954..73b82e15624 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2004-06-21 Kenichi Handa + + * make-dist: Link leim-ext.el into tempdir. + 2004-06-15 Luc Teirlinck * info/dir (File): Add emacs-xtra. diff --git a/admin/ChangeLog b/admin/ChangeLog index d0cc63f1e97..b164f414a88 100644 --- a/admin/ChangeLog +++ b/admin/ChangeLog @@ -1,3 +1,11 @@ +2004-06-28 Jan Dj,Ad(Brv + + * FOR-RELEASE: Removed entry about GTK and monochrome displays (done). + +2002-06-26 Eli Zaretskii + + * FOR-RELEASE: Moved here from the etc directory. + 2004-05-08 Thien-Thi Nguyen * notes/BRANCH: New file, to be maintained per CVS branch. diff --git a/admin/FOR-RELEASE b/admin/FOR-RELEASE new file mode 100644 index 00000000000..2d5738a8683 --- /dev/null +++ b/admin/FOR-RELEASE @@ -0,0 +1,48 @@ +Tasks needed before the next release. + +* DOCUMENTATION + +** Finish updating the Emacs Lisp manual. + +** Finish checking the Emacs Lisp manual. + +** Update the Emacs manual. + +** Check the Emacs Manual. + +** Add missing years in copyright notices of all files. + +** Update man/info.texi. + + +* NEW FEATURES + +** Test the mbox branch of Rmail. + +** Install the mbox branch of Rmail. + +** Update Gnus. + +** Face remapping. + + +* FATAL ERRORS + +** Investigate face cache related crash. + +Indications: Face cache seems to have been cleared, but +redisplay uses an invalidated face_id with FACE_FROM_ID +which then returns a NULL pointer. Said to happen with +isearch faces. + + +* GTK RELATED BUGS + +** Make geometry specifications work correctly for GTK. + +** Make GTK scrollbars behave like others w.r.t. overscrolling. + + +Local variables: +mode: outline +end: diff --git a/etc/ChangeLog b/etc/ChangeLog index 05c4549bee3..356946001bd 100644 --- a/etc/ChangeLog +++ b/etc/ChangeLog @@ -1,3 +1,18 @@ +2002-06-26 Eli Zaretskii + + * FOR-RELEASE: Moved to the admin directory. + +2004-06-24 David Kastrup + + * NEWS: Move description from new paragraph-start and + indent-line-function defaults to general news instead of new + packages. Same for query-replace-skip-read-only. Add + description of new `\,' and `\?' replacement string features. + +2004-06-23 Luc Teirlinck + + * MORE.STUFF: Delete obsolete URL. + 2004-06-10 Lars Hansen * NEWS: Describe dired-omit-mode. Describe desktop package changes. diff --git a/etc/FOR-RELEASE b/etc/FOR-RELEASE deleted file mode 100644 index b36632b092b..00000000000 --- a/etc/FOR-RELEASE +++ /dev/null @@ -1,13 +0,0 @@ -Tasks needed before the next release. - -** Test the mbox branch of Rmail. - -** Install the mbox branch of Rmail. - -** Finish updating the Emacs Lisp manual. - -** Finish checking the Emacs Lisp manual. - -** Update the Emacs Manual. - -** Check the Emacs Lisp manual. diff --git a/etc/MORE.STUFF b/etc/MORE.STUFF index 2e1803ae8ba..b060e137e37 100644 --- a/etc/MORE.STUFF +++ b/etc/MORE.STUFF @@ -36,9 +36,6 @@ You might find bug-fixes or enhancements in these places. * Ada: - * Autorevert, CWarn and Follow: - - * Battery and Info Look: * BibTeX: diff --git a/etc/NEWS b/etc/NEWS index ef5a3921d38..a7691aed9de 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -988,6 +988,23 @@ search multiple buffers. There is also a new command buffers to search by their filename. Internally, Occur mode has been rewritten, and now uses font-lock, among other changes. +** The default values of paragraph-start and indent-line-function have +been changed to reflect those used in Text mode rather than those used +in Indented-Text mode. + +** New user option `query-replace-skip-read-only': when non-nil, +`query-replace' and related functions simply ignore +a match if part of it has a read-only property. + +** When used interactively, the commands `query-replace-regexp' and +`replace-regexp' allow \,expr to be used in a replacement string, +where expr is an arbitrary Lisp expression evaluated at replacement +time. In many cases, this will be more convenient than using +`query-replace-regexp-eval'. All regular expression replacement +commands now allow `\?' in the replacement string to specify a +position where the replacement string can be edited for each +replacement. + +++ ** Emacs normally highlights mouse sensitive text whenever the mouse is over the text. By setting the new variable `mouse-highlight', you @@ -2210,14 +2227,6 @@ mode-lines in inverse-video. ** New package benchmark.el contains simple support for convenient timing measurements of code (including the garbage collection component). -** The default values of paragraph-start and indent-line-function have -been changed to reflect those used in Text mode rather than those used -in Indented-Text mode. - -** If you set `query-replace-skip-read-only' non-nil, -`query-replace' and related functions simply ignore -a match if part of it has a read-only property. - ** The new Lisp library fringe.el controls the apperance of fringes. ** `cfengine-mode' is a major mode for editing GNU Cfengine diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 70f7255782a..effae29fc8f 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,112 @@ +2004-06-29 Kim F. Storm + + * progmodes/gdb-ui.el (breakpoint-enabled-bitmap-face) + (breakpoint-disabled-bitmap-face): Add :group 'gud. + + * progmodes/ada-xref.el (ada-tight-gvd-integration): + Add :group 'ada. + + * vc-arch.el (vc-arch-mode-line-rewrite): Add :group 'vc. + +2004-06-29 Juri Linkov + + * replace.el (query-replace-read-args): Swallow a space after + everything except )]" which in most cases means after a symbol. + + * emacs-lisp/pp.el (pp-buffer): Add autoload. + +2004-06-26 David Kastrup + + * replace.el (perform-replace): Highlight the match even in + non-query mode if there is potential replace string editing. + +2004-06-26 Kai Grossjohann + + * net/tramp.el (tramp-handle-file-remote-p): New implementation to + agree with new return value of `file-remote-p'. + This syncs with Tramp 2.0.42. + + * net/ange-ftp.el (ange-ftp-file-remote-p): New return value, + according to new documentation of `file-remote-p'. + + * files.el (file-remote-p): Fix doc to say that return value is + identification of remote system, if not nil. + (file-relative-name): Use new return value of `file-remote-p'. + +2004-06-26 Nick Roberts + + * progmodes/gdb-ui.el (gdb-toggle-breakpoint) + (gdb-goto-breakpoint): Fix breakage. + +2004-06-26 Eli Zaretskii + + * man.el (Man-getpage-in-background): Add windows-nt to the list + of systems where shell-file-name should be used instead of + literal "sh". + +2004-06-25 Sam Steingold + + * add-log.el (change-log-font-lock-keywords): Support Common Lisp + function names `(setf symbol)'. + +2004-06-24 Richard M. Stallman + + * replace.el (query-replace-read-args): Swallow space after \,SYMBOL. + + * font-lock.el (font-lock-keywords): Change format of compiled values. + Document it. + (font-lock-add-keywords): If font-lock-keywords is compiled, + extract the uncompiled version, modify, then recompile. + (font-lock-remove-keywords): Likewise. + (font-lock-fontify-keywords-region): Handle changed format. + (font-lock-compile-keywords): Handle changed format. + (font-lock-set-defaults): Compile the keywords explicitly here. + +2004-06-24 David Kastrup + + * replace.el (query-replace-read-args): Implement `\,' and `\#' + replacements here. + (query-replace-regexp): Doc string explaining this and the new + `\?' replacement. Remove `\,' and `\#' implementation here, as it + is better placed in `query-replace-read-args'. + (replace-regexp): Explain `\,', `\#' and `\?'. + (replace-match-data): New function for thorough reuse/destruction + of old match-data. + (replace-match-maybe-edit): Function for implementing `\?' + editing. + (perform-replace): Fix maintaining of the match stack including + already matched regions, implement `\?', fix various problems + with regions while editing and other stuff. + (replace-highlight): Simplified. + +2004-06-24 Daniel Pfeiffer + + * progmodes/grep.el (grep-error-screen-columns): New variable. + (grep-regexp-alist): Give it the full functionality of gnu style + compilation messages with line and column ranges. Ask me for the + perl script I'm working on, that uses these. + +2004-06-23 Nick Roberts + + * comint.el: (comint-insert-clicked-input, comint-copy-old-input): + Remove. + (comint-insert-input, comint-mouse-insert-input): New functions + based on comint-insert-clicked-input for two bindings but just + one functionality. + +2004-06-23 Luc Teirlinck + + * net/goto-addr.el (goto-address-fontify): Fix help-echo text. + +2004-06-23 Lars Hansen + + * files.el (write-contents-functions): Doc fix. + +2004-06-21 Juanma Barranquero + + * image.el (image-library-alist): Rewrite docstring in active + voice. + 2004-06-20 Richard M. Stallman * mouse.el (mouse-set-region-1): Set transient-mark-mode to `only'. diff --git a/lisp/add-log.el b/lisp/add-log.el index 3c29e8a465e..26faea2ddc3 100644 --- a/lisp/add-log.el +++ b/lisp/add-log.el @@ -230,13 +230,16 @@ Note: The search is conducted only within 10%, at the beginning of the file." ;; Possibly further names in a list: ("\\=, \\([^ ,:([\n]+\\)" nil nil (1 'change-log-file-face)) ;; Possibly a parenthesized list of names: - ("\\= (\\([^) ,\n]+\\)" nil nil (1 'change-log-list-face)) - ("\\=, *\\([^) ,\n]+\\)" nil nil (1 'change-log-list-face))) + ("\\= (\\([^() ,\n]+\\|(\\(setf\\|SETF\\) [^() ,\n]+)\\)" + nil nil (1 'change-log-list-face)) + ("\\=, *\\([^() ,\n]+\\|(\\(setf\\|SETF\\) [^() ,\n]+)\\)" + nil nil (1 'change-log-list-face))) ;; ;; Function or variable names. - ("^\t(\\([^) ,\n]+\\)" + ("^\t(\\([^() ,\n]+\\|(\\(setf\\|SETF\\) [^() ,\n]+)\\)" (1 'change-log-list-face) - ("\\=, *\\([^) ,\n]+\\)" nil nil (1 'change-log-list-face))) + ("\\=, *\\([^() ,\n]+\\|(\\(setf\\|SETF\\) [^() ,\n]+)\\)" nil nil + (1 'change-log-list-face))) ;; ;; Conditionals. ("\\[!?\\([^]\n]+\\)\\]\\(:\\| (\\)" (1 'change-log-conditionals-face)) diff --git a/lisp/comint.el b/lisp/comint.el index 12d8e1fcbb7..8b5a107c7d7 100644 --- a/lisp/comint.el +++ b/lisp/comint.el @@ -571,7 +571,7 @@ Entry to this mode runs the hooks on `comint-mode-hook'." (define-key comint-mode-map "\C-c\C-c" 'comint-interrupt-subjob) (define-key comint-mode-map "\C-c\C-z" 'comint-stop-subjob) (define-key comint-mode-map "\C-c\C-\\" 'comint-quit-subjob) - (define-key comint-mode-map "\C-c\C-m" 'comint-copy-old-input) + (define-key comint-mode-map "\C-c\C-m" 'comint-insert-input) (define-key comint-mode-map "\C-c\C-o" 'comint-delete-output) (define-key comint-mode-map "\C-c\C-r" 'comint-show-output) (define-key comint-mode-map "\C-c\C-e" 'comint-show-maximum-output) @@ -582,7 +582,7 @@ Entry to this mode runs the hooks on `comint-mode-hook'." (define-key comint-mode-map "\C-c\C-s" 'comint-write-output) (define-key comint-mode-map "\C-c." 'comint-insert-previous-argument) ;; Mouse Buttons: - (define-key comint-mode-map [mouse-2] 'comint-insert-clicked-input) + (define-key comint-mode-map [mouse-2] 'comint-mouse-insert-input) ;; Menu bars: ;; completion: (define-key comint-mode-map [menu-bar completion] @@ -615,7 +615,7 @@ Entry to this mode runs the hooks on `comint-mode-hook'." (define-key comint-mode-map [menu-bar inout kill-input] '("Kill Current Input" . comint-kill-input)) (define-key comint-mode-map [menu-bar inout copy-input] - '("Copy Old Input" . comint-copy-old-input)) + '("Copy Old Input" . comint-insert-input)) (define-key comint-mode-map [menu-bar inout forward-matching-history] '("Forward Matching Input..." . comint-forward-matching-input)) (define-key comint-mode-map [menu-bar inout backward-matching-history] @@ -798,11 +798,10 @@ buffer. The hook `comint-exec-hook' is run after each exec." (set-process-coding-system proc decoding encoding)) proc)) - -(defun comint-insert-clicked-input (event) - "In a Comint buffer, set the current input to the clicked-on previous input." - (interactive "e") - (let ((pos (posn-point (event-end event)))) +(defun comint-insert-input () + "In a Comint buffer, set the current input to the previous input at point." + (interactive) + (let ((pos (point))) (if (not (eq (get-char-property pos 'field) 'input)) ;; No input at POS, fall back to the global definition. (let* ((keys (this-command-keys)) @@ -816,11 +815,16 @@ buffer. The hook `comint-exec-hook' is run after each exec." (or (marker-position comint-accum-marker) (process-mark (get-buffer-process (current-buffer)))) (point)) - ;; Insert the clicked-upon input + ;; Insert the input at point (insert (buffer-substring-no-properties (previous-single-char-property-change (1+ pos) 'field) (next-single-char-property-change pos 'field)))))) +(defun comint-mouse-insert-input (event) + "In a Comint buffer, set the current input to the previous input you click on." + (interactive "e") + (mouse-set-point event) + (comint-insert-input)) ;; Input history processing in a buffer @@ -1858,17 +1862,6 @@ the current line with any initial string matching the regexp (comint-bol) (buffer-substring-no-properties (point) (line-end-position))))) -(defun comint-copy-old-input () - "Insert after prompt old input at point as new input to be edited. -Calls `comint-get-old-input' to get old input." - (interactive) - (let ((input (funcall comint-get-old-input)) - (process (get-buffer-process (current-buffer)))) - (if (not process) - (error "Current buffer has no process") - (goto-char (process-mark process)) - (insert input)))) - (defun comint-skip-prompt () "Skip past the text matching regexp `comint-prompt-regexp'. If this takes us past the end of the current line, don't skip at all." diff --git a/lisp/emacs-lisp/pp.el b/lisp/emacs-lisp/pp.el index 61d31921e57..93e30fb0f55 100644 --- a/lisp/emacs-lisp/pp.el +++ b/lisp/emacs-lisp/pp.el @@ -54,6 +54,7 @@ to make output that `read' can handle, whenever this is possible." (buffer-string)) (kill-buffer (current-buffer))))) +;;;###autoload (defun pp-buffer () "Prettify the current buffer with printed representation of a Lisp object." (goto-char (point-min)) diff --git a/lisp/files.el b/lisp/files.el index 1804432ee45..1d500379925 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -393,7 +393,8 @@ updates before the buffer is saved, use `before-save-hook' .") (defvar write-contents-functions nil "List of functions to be called before writing out a buffer to a file. If one of them returns non-nil, the file is considered already written -and the rest are not called. +and the rest are not called and neither are the functions in +`write-file-functions'. This variable is meant to be used for hooks that pertain to the buffer's contents, not to the particular visited file; thus, @@ -649,7 +650,13 @@ This is an interface to the function `load'." (load library)) (defun file-remote-p (file) - "Test whether FILE specifies a location on a remote system." + "Test whether FILE specifies a location on a remote system. +Return an identification of the system if the location is indeed +remote. The identification of the system may comprise a method +to access the system and its hostname, amongst other things. + +For example, the filename \"/user@host:/foo\" specifies a location +on the system \"/user@host:\"." (let ((handler (find-file-name-handler file 'file-remote-p))) (if handler (funcall handler 'file-remote-p file) @@ -2915,8 +2922,8 @@ on a DOS/Windows machine, it returns FILENAME on expanded form." (file-name-as-directory (expand-file-name (or directory default-directory)))) (setq filename (expand-file-name filename)) - (let ((hf (find-file-name-handler filename 'file-remote-p)) - (hd (find-file-name-handler directory 'file-remote-p))) + (let ((fremote (file-remote-p filename)) + (dremote (file-remote-p directory))) (if ;; Conditions for separate trees (or ;; Test for different drives on DOS/Windows @@ -2924,20 +2931,8 @@ on a DOS/Windows machine, it returns FILENAME on expanded form." ;; Should `cygwin' really be included here? --stef (memq system-type '(ms-dos cygwin windows-nt)) (not (eq t (compare-strings filename 0 2 directory 0 2)))) - ;; Test for different remote file handlers - (not (eq hf hd)) ;; Test for different remote file system identification - (and - hf - (let ((re (car (rassq hf file-name-handler-alist)))) - (not - (equal - (and - (string-match re filename) - (substring filename 0 (match-end 0))) - (and - (string-match re directory) - (substring directory 0 (match-end 0)))))))) + (not (equal fremote dremote))) filename (let ((ancestor ".") (filename-dir (file-name-as-directory filename))) diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 1f6127f3ea5..9d3fdd6de5f 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -340,7 +340,15 @@ If a number, only buffers greater than this size have fontification messages." (defvar font-lock-keywords nil "A list of the keywords to highlight. -Each element should have one of these forms: +There are two kinds of values: user-level, and compiled. + +A user-level keywords list is what a major mode or the user would +set up. Normally the list would come from `font-lock-defaults'. +through selection of a fontification level and evaluation of any +contained expressions. You can also alter it by calling +`font-lock-add-keywords' or `font-lock-remove-keywords' with MODE = nil. + +Each element in a user-level keywords list should have one of these forms: MATCHER (MATCHER . MATCH) @@ -438,7 +446,14 @@ support modes like jit-lock or lazy-lock. This variable is set by major modes via the variable `font-lock-defaults'. Be careful when composing regexps for this list; a poorly written pattern can -dramatically slow things down!") +dramatically slow things down! + +A compiled keywords list starts with t. It is produced internal +by `font-lock-compile-keywords' from a user-level keywords list. +Its second element is the user-level keywords list that was +compiled. The remaining elements have the same form as +user-level keywords, but normally their values have been +optimized.") (defvar font-lock-keywords-alist nil "*Alist of `font-lock-keywords' local to a `major-mode'. @@ -659,16 +674,26 @@ see the variables `c-font-lock-extra-types', `c++-font-lock-extra-types', (font-lock-update-removed-keyword-alist mode keywords append)) (t ;; Otherwise set or add the keywords now. + ;; This is a no-op if it has been done already in this buffer. (font-lock-set-defaults) - (if (eq append 'set) - (setq font-lock-keywords keywords) - (font-lock-remove-keywords nil keywords) ;to avoid duplicates - (let ((old (if (eq (car-safe font-lock-keywords) t) - (cdr font-lock-keywords) - font-lock-keywords))) - (setq font-lock-keywords (if append - (append old keywords) - (append keywords old)))))))) + (let ((was-compiled (eq (car font-lock-keywords) t))) + ;; Bring back the user-level (uncompiled) keywords. + (if was-compiled + (setq font-lock-keywords (cadr font-lock-keywords))) + ;; Now modify or replace them. + (if (eq append 'set) + (setq font-lock-keywords keywords) + (font-lock-remove-keywords nil keywords) ;to avoid duplicates + (let ((old (if (eq (car-safe font-lock-keywords) t) + (cdr font-lock-keywords) + font-lock-keywords))) + (setq font-lock-keywords (if append + (append old keywords) + (append keywords old))))) + ;; If the keywords were compiled before, compile them again. + (if was-compiled + (set (make-local-variable 'font-lock-keywords) + (font-lock-compile-keywords keywords t))))))) (defun font-lock-update-removed-keyword-alist (mode keywords append) ;; Update `font-lock-removed-keywords-alist' when adding new @@ -762,13 +787,21 @@ subtle problems due to details of the implementation." (t ;; Otherwise remove it immediately. (font-lock-set-defaults) - (setq font-lock-keywords (copy-sequence font-lock-keywords)) - (dolist (keyword keywords) - (setq font-lock-keywords - (delete keyword - ;; The keywords might be compiled. - (delete (font-lock-compile-keyword keyword) - font-lock-keywords))))))) + (let ((was-compiled (eq (car font-lock-keywords) t))) + ;; Bring back the user-level (uncompiled) keywords. + (if was-compiled + (setq font-lock-keywords (cadr font-lock-keywords))) + + ;; Edit them. + (setq font-lock-keywords (copy-sequence font-lock-keywords)) + (dolist (keyword keywords) + (setq font-lock-keywords + (delete keyword font-lock-keywords))) + + ;; If the keywords were compiled before, compile them again. + (if was-compiled + (set (make-local-variable 'font-lock-keywords) + (font-lock-compile-keywords keywords t))))))) ;;; Font Lock Support mode. @@ -1224,7 +1257,7 @@ START should be at the beginning of a line." font-lock-syntactic-keywords))) ;; Get down to business. (let ((case-fold-search font-lock-keywords-case-fold-search) - (keywords (cdr font-lock-syntactic-keywords)) + (keywords (cddr font-lock-syntactic-keywords)) keyword matcher highlights) (while keywords ;; Find an occurrence of `matcher' from `start' to `end'. @@ -1349,7 +1382,7 @@ LOUDLY, if non-nil, allows progress-meter bar." (setq font-lock-keywords (font-lock-compile-keywords font-lock-keywords t))) (let ((case-fold-search font-lock-keywords-case-fold-search) - (keywords (cdr font-lock-keywords)) + (keywords (cddr font-lock-keywords)) (bufname (buffer-name)) (count 0) keyword matcher highlights) ;; @@ -1394,14 +1427,16 @@ LOUDLY, if non-nil, allows progress-meter bar." ;; Various functions. (defun font-lock-compile-keywords (keywords &optional regexp) - "Compile KEYWORDS into the form (t KEYWORD ...). -Here KEYWORD is of the form (MATCHER HIGHLIGHT ...) as shown in the + "Compile KEYWORDS into the form (t KEYWORDS COMPILED...) +Here each COMPILED is of the form (MATCHER HIGHLIGHT ...) as shown in the `font-lock-keywords' doc string. If REGEXP is non-nil, it means these keywords are used for `font-lock-keywords' rather than for `font-lock-syntactic-keywords'." (if (eq (car-safe keywords) t) keywords - (setq keywords (cons t (mapcar 'font-lock-compile-keyword keywords))) + (setq keywords + (cons t (cons keywords + (mapcar 'font-lock-compile-keyword keywords)))) (if (and regexp (eq (or syntax-begin-function font-lock-beginning-of-syntax-function) @@ -1512,17 +1547,21 @@ Sets various variables using `font-lock-defaults' (or, if nil, using ;; Variable alist? (dolist (x (nthcdr 5 defaults)) (set (make-local-variable (car x)) (cdr x))) - ;; Setup `font-lock-keywords' last because its value might depend + ;; Set up `font-lock-keywords' last because its value might depend ;; on other settings (e.g. font-lock-compile-keywords uses ;; font-lock-beginning-of-syntax-function). (set (make-local-variable 'font-lock-keywords) - (font-lock-compile-keywords (font-lock-eval-keywords keywords) t)) + (font-lock-eval-keywords keywords)) ;; Local fontification? (while local (font-lock-add-keywords nil (car (car local)) (cdr (car local))) (setq local (cdr local))) (when removed-keywords - (font-lock-remove-keywords nil removed-keywords))))) + (font-lock-remove-keywords nil removed-keywords)) + ;; Now compile the keywords. + (unless (eq (car font-lock-keywords) t) + (set (make-local-variable 'font-lock-keywords) + (font-lock-compile-keywords font-lock-keywords t)))))) ;;; Colour etc. support. diff --git a/lisp/gnus/ChangeLog b/lisp/gnus/ChangeLog index 78c9f15f912..8169b014e16 100644 --- a/lisp/gnus/ChangeLog +++ b/lisp/gnus/ChangeLog @@ -1,3 +1,10 @@ +2004-06-29 Kim F. Storm + + * nntp.el (nntp-authinfo-file): Add :group 'nntp. + + * nnimap.el (nnimap-authinfo-file, nnimap-prune-cache): + Add :group 'nnimap. + 2004-05-18 Stefan Monnier * mm-view.el (mm-insert-inline): Make it work in read-only buffer. diff --git a/lisp/gnus/nnimap.el b/lisp/gnus/nnimap.el index a7cf82317b5..ec9d42ee042 100644 --- a/lisp/gnus/nnimap.el +++ b/lisp/gnus/nnimap.el @@ -271,11 +271,13 @@ use this to make replies go directly to the group.") (string :format "Login: %v")) (cons :format "%v" (const :format "" "password") - (string :format "Password: %v"))))))) + (string :format "Password: %v")))))) + :group 'nnimap) (defcustom nnimap-prune-cache t "If non-nil, nnimap check whether articles still exist on server before using data stored in NOV cache." - :type 'boolean) + :type 'boolean + :group 'nnimap) (defvar nnimap-request-list-method 'imap-mailbox-list "Method to use to request a list of all folders from the server. diff --git a/lisp/gnus/nntp.el b/lisp/gnus/nntp.el index 8791c652a45..5722ba8456a 100644 --- a/lisp/gnus/nntp.el +++ b/lisp/gnus/nntp.el @@ -174,7 +174,8 @@ server there that you can connect to. See also (string :format "Login: %v")) (cons :format "%v" (const :format "" "password") - (string :format "Password: %v"))))))) + (string :format "Password: %v")))))) + :group 'nntp) @@ -223,7 +224,7 @@ noticing asynchronous data.") (defvar nntp-async-timer nil) (defvar nntp-async-process-list nil) -(defvar nntp-ssl-program +(defvar nntp-ssl-program "openssl s_client -quiet -ssl3 -connect %s:%p" "A string containing commands for SSL connections. Within a string, %s is replaced with the server address and %p with @@ -928,10 +929,10 @@ password contained in '~/.nntp-authinfo'." (defun nntp-open-ssl-stream (buffer) (let* ((process-connection-type nil) - (proc (start-process "nntpd" buffer + (proc (start-process "nntpd" buffer shell-file-name shell-command-switch - (format-spec nntp-ssl-program + (format-spec nntp-ssl-program (format-spec-make ?s nntp-address ?p nntp-port-number))))) diff --git a/lisp/image.el b/lisp/image.el index 88e38186d7b..ad8fcafe8de 100644 --- a/lisp/image.el +++ b/lisp/image.el @@ -54,10 +54,12 @@ a non-nil value, TYPE is the image's type.") Each element is a list (IMAGE-TYPE LIBRARY...), where the car is a symbol representing a supported image type, and the rest are strings giving -alternate filenames for the corresponding external libraries to load. -They are tried in the order they appear on the list; if none of them can -be loaded, the running session of Emacs won't display the image type. -No entries are needed for pbm and xbm images; they're always supported.") +alternate filenames for the corresponding external libraries. + +Emacs tries to load the libraries in the order they appear on the +list; if none is loaded, the running session of Emacs won't +support the image type. Types 'pbm and 'xbm don't need to be +listed; they're always supported.") ;;;###autoload (put 'image-library-alist 'risky-local-variable t) (defun image-jpeg-p (data) diff --git a/lisp/man.el b/lisp/man.el index 5a07045dda9..cbfae21e44b 100644 --- a/lisp/man.el +++ b/lisp/man.el @@ -733,7 +733,9 @@ all sections related to a subject, put something appropriate into the (if (fboundp 'start-process) (set-process-sentinel (start-process manual-program buffer - (if (eq system-type 'cygwin) shell-file-name "sh") + (if (memq system-type '(cygwin windows-nt)) + shell-file-name + "sh") shell-command-switch (format (Man-build-man-command) man-args)) 'Man-bgproc-sentinel) diff --git a/lisp/net/ange-ftp.el b/lisp/net/ange-ftp.el index 09448e87329..8e9d0bda5af 100644 --- a/lisp/net/ange-ftp.el +++ b/lisp/net/ange-ftp.el @@ -4117,7 +4117,7 @@ directory, so that Emacs will know its current contents." tmp1)))) (defun ange-ftp-file-remote-p (file) - (when (ange-ftp-ftp-name file) t)) + (ange-ftp-replace-name-component file "")) (defun ange-ftp-load (file &optional noerror nomessage nosuffix) (if (ange-ftp-ftp-name file) diff --git a/lisp/net/goto-addr.el b/lisp/net/goto-addr.el index b77be84deb3..428da8cbe8a 100644 --- a/lisp/net/goto-addr.el +++ b/lisp/net/goto-addr.el @@ -168,7 +168,7 @@ and `goto-address-fontify-p'." (overlay-put this-overlay 'mouse-face goto-address-url-mouse-face) (overlay-put this-overlay - 'help-echo "mouse-2: follow URL") + 'help-echo "mouse-2, C-c RET: follow URL") (overlay-put this-overlay 'keymap goto-address-highlight-keymap) (overlay-put this-overlay 'goto-address t))) @@ -182,7 +182,7 @@ and `goto-address-fontify-p'." (overlay-put this-overlay 'mouse-face goto-address-mail-mouse-face) (overlay-put this-overlay - 'help-echo "mouse-2: mail this address") + 'help-echo "mouse-2, C-c RET: mail this address") (overlay-put this-overlay 'keymap goto-address-highlight-keymap) (overlay-put this-overlay 'goto-address t)))))))) diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 769ad3f51f6..0414859c7eb 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -3542,7 +3542,14 @@ This will break if COMMAND prints a newline, followed by the value of (defun tramp-handle-file-remote-p (filename) "Like `file-remote-p' for tramp files." - (when (tramp-tramp-file-p filename) t)) + (when (tramp-tramp-file-p filename) + (with-parsed-tramp-file-name filename nil + (make-tramp-file-name + :multi-method multi-method + :method method + :user user + :host host + :localname "")))) (defun tramp-handle-insert-file-contents (filename &optional visit beg end replace) diff --git a/lisp/progmodes/ada-xref.el b/lisp/progmodes/ada-xref.el index c7b5717a1bb..c9bfbd76c23 100644 --- a/lisp/progmodes/ada-xref.el +++ b/lisp/progmodes/ada-xref.el @@ -143,7 +143,8 @@ Otherwise, ask the user for the name of the project file to use." (defcustom ada-tight-gvd-integration nil "*If non-nil, a new Emacs frame will be swallowed in GVD when debugging. -If GVD is not the debugger used, nothing happens.") +If GVD is not the debugger used, nothing happens." + :type 'boolean :group 'ada) (defcustom ada-xref-search-with-egrep t "*If non-nil, use egrep to find the possible declarations for an entity. @@ -506,12 +507,12 @@ All the directories are returned as absolute directories." (equal ada-prj-default-project-file (car x)) )))) - + ;; Parses all the known project files, and insert at ;; least the default one (in case ;; ada-xref-project-files is nil) (or ada-xref-project-files '(nil)))))) - + (easy-menu-add-item ada-mode-menu '() submenu))) diff --git a/lisp/progmodes/gdb-ui.el b/lisp/progmodes/gdb-ui.el index 2f267787707..1e2ef00580e 100644 --- a/lisp/progmodes/gdb-ui.el +++ b/lisp/progmodes/gdb-ui.el @@ -29,10 +29,9 @@ ;; GDB through the GUD buffer in the usual way, but there are also further ;; buffers which control the execution and describe the state of your program. ;; It separates the input/output of your program from that of GDB, if -;; required, and displays expressions and their current values in their own -;; buffers. It also uses features of Emacs 21 such as the display margin for -;; breakpoints, and the toolbar (see the GDB Graphical Interface section in -;; the Emacs info manual). +;; required, and watches expressions in the speedbar. It also uses features of +;; Emacs 21 such as the fringe/display margin for breakpoints, and the toolbar +;; (see the GDB Graphical Interface section in the Emacs info manual). ;; Start the debugger with M-x gdba. @@ -40,7 +39,7 @@ ;; Kingdon and uses GDB's annotation interface. You don't need to know about ;; annotations to use this mode as a debugger, but if you are interested ;; developing the mode itself, then see the Annotations section in the GDB -;; info manual. +;; info manual. ;; ;; GDB developers plan to make the annotation interface obsolete. A new ;; interface called GDB/MI (machine interface) has been designed to replace @@ -71,7 +70,7 @@ (defvar gdb-variables '() "A list of variables that are local to the GUD buffer.") (defvar gdb-server-prefix nil) - + ;;;###autoload (defun gdba (command-line) "Run gdb on program FILE in buffer *gud-FILE*. @@ -228,7 +227,7 @@ speedbar." (if (string-equal expr (car var)) (throw 'already-watched nil))) (set-text-properties 0 (length expr) nil expr) (gdb-enqueue-input - (list + (list (if (eq gud-minor-mode 'gdba) (concat "server interpreter mi \"-var-create - * " expr "\"\n") (concat"-var-create - * " expr "\n")) @@ -327,7 +326,7 @@ speedbar." (if (not (member 'gdb-var-update gdb-pending-triggers)) (progn (gdb-enqueue-input - (list + (list (if (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba)) "server interpreter mi \"-var-update *\"\n" "-var-update *\n") @@ -363,7 +362,7 @@ speedbar." (varnum (cadr var))) (unless (string-match "\\." varnum) (gdb-enqueue-input - (list + (list (if (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba)) (concat "server interpreter mi \"-var-delete " varnum "\"\n") @@ -487,7 +486,7 @@ The key should be one of the cars in `gdb-buffer-rules-assoc'." (set (make-local-variable 'gdb-buffer-type) key) (if (cdr (cdr rules)) (funcall (car (cdr (cdr rules))))) - (set (make-local-variable 'gud-minor-mode) + (set (make-local-variable 'gud-minor-mode) (with-current-buffer gud-comint-buffer gud-minor-mode)) (set (make-local-variable 'tool-bar-map) gud-tool-bar-map) new)))) @@ -1077,13 +1076,15 @@ static char *magick[] = { '((t :inherit fringe :foreground "red")) - "Face for enabled breakpoint icon in fringe.") + "Face for enabled breakpoint icon in fringe." + :group 'gud) (defface breakpoint-disabled-bitmap-face '((t :inherit fringe :foreground "grey60")) - "Face for disabled breakpoint icon in fringe.") + "Face for disabled breakpoint icon in fringe." + :group 'gud) ;;-put breakpoint icons in relevant margins (even those set in the GUD buffer) @@ -1207,8 +1208,8 @@ static char *magick[] = { (list (concat (if (eq ?y (char-after (match-beginning 2))) - gdb-server-prefix "disable " - gdb-server-prefix "enable ") + (concat gdb-server-prefix "disable ") + (concat gdb-server-prefix "enable ")) (match-string 1) "\n") 'ignore))))) @@ -1226,10 +1227,12 @@ static char *magick[] = { (interactive) (save-excursion (beginning-of-line 1) - (if (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdbmi)) - (looking-at "[0-9]*\\s-*\\S-*\\s-*\\S-*\\s-*.\\s-*\\S-*\\s-*\\(\\S-*\\):\\([0-9]+\\)") - (re-search-forward "in\\s-+\\S-+\\s-+at\\s-+" nil t) - (looking-at "\\(\\S-*\\):\\([0-9]+\\)"))) + (if (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba)) + (progn + (re-search-forward "in\\s-+\\S-+\\s-+at\\s-+" nil t) + (looking-at "\\(\\S-*\\):\\([0-9]+\\)")) + (looking-at + "[0-9]*\\s-*\\S-*\\s-*\\S-*\\s-*.\\s-*\\S-*\\s-*\\(\\S-*\\):\\([0-9]+\\)"))) (if (match-string 2) (let ((line (match-string 2)) (file (match-string 1))) @@ -1836,7 +1839,7 @@ BUFFER nil or omitted means use the current buffer." (save-current-buffer (setq left-margin-width 2) (if (get-buffer-window (current-buffer) 'visible) - (set-window-margins + (set-window-margins (get-buffer-window (current-buffer) 'visible) left-margin-width right-margin-width)))) (put-image @@ -1863,7 +1866,7 @@ BUFFER nil or omitted means use the current buffer." (save-current-buffer (setq left-margin-width 2) (if (get-buffer-window (current-buffer) 'visible) - (set-window-margins + (set-window-margins (get-buffer-window (current-buffer) 'visible) left-margin-width right-margin-width)))) (gdb-put-string (if enabled "B" "b") (1+ start))))) @@ -1875,7 +1878,7 @@ BUFFER nil or omitted means use the current buffer." (when remove-margin (setq left-margin-width 0) (if (get-buffer-window (current-buffer) 'visible) - (set-window-margins + (set-window-margins (get-buffer-window (current-buffer) 'visible) left-margin-width right-margin-width)))) diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index aa9a50a2580..1916bde9ea1 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el @@ -146,6 +146,14 @@ The following place holders should be present in the string: :type 'boolean :group 'grep) +(defcustom grep-error-screen-columns nil + "*If non-nil, column numbers in grep hits are screen columns. +See `compilation-error-screen-columns'" + :type '(choice (const :tag "Default" nil) + integer) + :version "21.4" + :group 'grep) + ;;;###autoload (defcustom grep-setup-hook nil "List of hook functions run by `grep-process-setup' (see `run-hooks')." @@ -216,7 +224,9 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies `complation-last-buffer' rather than `grep-last-buffer'.") (defvar grep-regexp-alist - '(("^\\(.+?\\)[:( \t]+\\([0-9]+\\)\\([:) \t]\\)\\(?:\\([0-9]+\\)\\(?:-\\([0-9]+\\)\\)?\\3\\)?" 1 2 (4 . 5)) + '(("^\\(.+?\\)[:( \t]+\ +\\([0-9]+\\)\\([.:]?\\)\\([0-9]+\\)?\ +\\(?:-\\(?:\\([0-9]+\\)\\3\\)?\\.?\\([0-9]+\\)?\\)?[:) \t]" 1 (2 . 5) (4 . 6)) ("^Binary file \\(.+\\) matches$" 1 nil nil 1)) "Regexp used to match grep hits. See `compilation-error-regexp-alist'.") diff --git a/lisp/replace.el b/lisp/replace.el index 89f55c2829e..c2305cdecc6 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -95,6 +95,35 @@ strings or patterns." (setq to (read-from-minibuffer (format "%s %s with: " string from) nil nil nil query-replace-to-history-variable from t))) + (when (and regexp-flag + (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to)) + (let (pos list char) + (while + (progn + (setq pos (match-end 0)) + (push (substring to 0 (- pos 2)) list) + (setq char (aref to (1- pos)) + to (substring to pos)) + (cond ((eq char ?\#) + (push '(number-to-string replace-count) list)) + ((eq char ?\,) + (setq pos (read-from-string to)) + (push `(replace-quote ,(car pos)) list) + (setq to (substring + to (+ (cdr pos) + ;; Swallow a space after a symbol + ;; if there is a space. + (if (string-match + "^[^])\"] " + (substring to (1- (cdr pos)))) + 1 0)))))) + (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to))) + (setq to (nreverse (delete "" (cons to list))))) + (replace-match-string-symbols to) + (setq to (cons 'replace-eval-replacement + (if (> (length to) 1) + (cons 'concat to) + (car to))))) (list from to current-prefix-arg))) (defun query-replace (from-string to-string &optional delimited start end) @@ -163,59 +192,35 @@ Fourth and fifth arg START and END specify the region to operate on. In TO-STRING, `\\&' stands for whatever matched the whole of REGEXP, and `\\=\\N' (where N is a digit) stands for whatever what matched the Nth `\\(...\\)' in REGEXP. +`\\?' lets you edit the replacement text in the minibuffer +at the given position for each replacement. -When this function is called interactively, the replacement text -can also contain `\\,' followed by a Lisp expression. The escaped -shorthands for `query-replace-regexp-eval' are also valid -here: within the Lisp expression, you can use `\\&' for the whole -match string, `\\N' for partial matches, `\\#&' and `\\#N' for -the respective numeric values, and `\\#' for `replace-count'. +In interactive calls, the replacement text can contain `\\,' +followed by a Lisp expression. Each +replacement evaluates that expression to compute the replacement +string. Inside of that expression, `\\&' is a string denoting the +whole match as a sting, `\\N' for a partial match, `\\#&' and `\\#N' +for the whole or a partial match converted to a number with +`string-to-number', and `\\#' itself for the number of replacements +done so far (starting with zero). -If your Lisp expression is an identifier and the next -letter in the replacement string would be interpreted as part of it, -you can wrap it with an expression like `\\,(or \\#)'. Incidentally, -for this particular case you may also enter `\\#' in the replacement -text directly. +If the replacement expression is a symbol, write a space after it +to terminate it. One space there, if any, will be discarded. -When you use `\\,' or `\\#' in the replacement, TO-STRING actually -becomes a list with expanded shorthands. -Use \\[repeat-complex-command] after this command to see details." +When using those Lisp features interactively in the replacement +text, TO-STRING is actually made a list instead of a string. +Use \\[repeat-complex-command] after this command for details." (interactive (let ((common (query-replace-read-args "Query replace regexp" t))) - (list - (nth 0 common) - (if (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" - (nth 1 common)) - (let ((to-string (nth 1 common)) pos to-expr char prompt) - (while (string-match - "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" - to-string) - (setq pos (match-end 0)) - (push (substring to-string 0 (- pos 2)) to-expr) - (setq char (aref to-string (1- pos)) - to-string (substring to-string pos)) - (cond ((eq char ?\#) - (push '(number-to-string replace-count) to-expr)) - ((eq char ?\,) - (setq pos (read-from-string to-string)) - (push `(replace-quote ,(car pos)) to-expr) - (setq to-string (substring to-string (cdr pos)))))) - (setq to-expr (nreverse (delete "" (cons to-string to-expr)))) - (replace-match-string-symbols to-expr) - (cons 'replace-eval-replacement - (if (> (length to-expr) 1) - (cons 'concat to-expr) - (car to-expr)))) - (nth 1 common)) - (nth 2 common) - ;; These are done separately here - ;; so that command-history will record these expressions - ;; rather than the values they had this time. - (if (and transient-mark-mode mark-active) - (region-beginning)) - (if (and transient-mark-mode mark-active) - (region-end))))) + (list (nth 0 common) (nth 1 common) (nth 2 common) + ;; These are done separately here + ;; so that command-history will record these expressions + ;; rather than the values they had this time. + (if (and transient-mark-mode mark-active) + (region-beginning)) + (if (and transient-mark-mode mark-active) + (region-end))))) (perform-replace regexp to-string t t delimited nil nil start end)) (define-key esc-map [?\C-%] 'query-replace-regexp) @@ -374,7 +379,27 @@ Fourth and fifth arg START and END specify the region to operate on. In TO-STRING, `\\&' stands for whatever matched the whole of REGEXP, and `\\=\\N' (where N is a digit) stands for - whatever what matched the Nth `\\(...\\)' in REGEXP. +whatever what matched the Nth `\\(...\\)' in REGEXP. +`\\?' lets you edit the replacement text in the minibuffer +at the given position for each replacement. + +In interactive calls, the replacement text may contain `\\,' +followed by a Lisp expression used as part of the replacement +text. Inside of that expression, `\\&' is a string denoting the +whole match, `\\N' a partial matches, `\\#&' and `\\#N' the +respective numeric values from `string-to-number', and `\\#' +itself for `replace-count', the number of replacements occured so +far. + +If your Lisp expression is an identifier and the next letter in +the replacement string would be interpreted as part of it, you +can wrap it with an expression like `\\,(or \\#)'. Incidentally, +for this particular case you may also enter `\\#' in the +replacement text directly. + +When using those Lisp features interactively in the replacement +text, TO-STRING is actually made a list instead of a string. +Use \\[repeat-complex-command] after this command for details. If `query-replace-interactive' is non-nil, the last incremental search regexp is used as REGEXP--you don't have to specify it with the minibuffer. @@ -1115,6 +1140,49 @@ with the `noescape' argument set. (aset data 2 (if (consp next) next (aref data 3)))))) (car (aref data 2))) +(defun replace-match-data (integers reuse &optional new) + "Like `match-data', but markers in REUSE get invalidated. +If NEW is non-NIL, it is set and returned instead of fresh data, +but coerced to the correct value of INTEGERS." + (or (and new + (progn + (set-match-data new) + (and (eq new reuse) + (eq (null integers) (markerp (car reuse))) + new))) + (match-data integers + (prog1 reuse + (while reuse + (if (markerp (car reuse)) + (set-marker (car reuse) nil)) + (setq reuse (cdr reuse))))))) + +(defun replace-match-maybe-edit (newtext fixedcase literal noedit match-data) + "Make a replacement with `replace-match', editing `\\?'. +NEXTEXT, FIXEDCASE, LITERAL are just passed on. If NOEDIT is true, no +check for `\\?' is made to save time. MATCH-DATA is used for the +replacement. In case editing is done, it is changed to use markers. + +The return value is non-NIL if there has been no `\\?' or NOEDIT was +passed in. If LITERAL is set, no checking is done, anyway." + (unless (or literal noedit) + (setq noedit t) + (while (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\(\\\\\\?\\)" + newtext) + (setq newtext + (read-input "Edit replacement string: " + (prog1 + (cons + (replace-match "" t t newtext 3) + (1+ (match-beginning 3))) + (setq match-data + (replace-match-data + nil match-data match-data)))) + noedit nil))) + (set-match-data match-data) + (replace-match newtext fixedcase literal) + noedit) + (defun perform-replace (from-string replacements query-flag regexp-flag delimited-flag &optional repeat-count map start end) @@ -1145,6 +1213,7 @@ make, or the user didn't cancel the call." (search-string from-string) (real-match-data nil) ; the match data for the current match (next-replacement nil) + (noedit nil) (keep-going t) (stack nil) (replace-count 0) @@ -1201,7 +1270,9 @@ make, or the user didn't cancel the call." (setq real-match-data (if (consp match-again) (progn (goto-char (nth 1 match-again)) - match-again) + (replace-match-data t + real-match-data + match-again)) (and (or match-again ;; MATCH-AGAIN non-nil means we ;; accept an adjacent match. If @@ -1217,7 +1288,7 @@ make, or the user didn't cancel the call." (funcall search-function search-string limit t) ;; For speed, use only integers and ;; reuse the list used last time. - (match-data t real-match-data))))) + (replace-match-data t real-match-data))))) ;; Optionally ignore matches that have a read-only property. (unless (and query-replace-skip-read-only (text-property-not-all @@ -1249,16 +1320,27 @@ make, or the user didn't cancel the call." (set-match-data real-match-data) (setq next-replacement (funcall (car replacements) (cdr replacements) - replace-count))) + replace-count) + noedit nil)) (if (not query-flag) - (let ((inhibit-read-only query-replace-skip-read-only)) - (set-match-data real-match-data) - (replace-match next-replacement nocasify literal) - (setq replace-count (1+ replace-count))) + (let ((inhibit-read-only + query-replace-skip-read-only)) + (unless noedit + (replace-highlight (nth 0 real-match-data) + (nth 1 real-match-data))) + (setq noedit + (replace-match-maybe-edit + next-replacement nocasify literal + noedit real-match-data) + replace-count (1+ replace-count))) (undo-boundary) (let (done replaced key def) ;; Loop reading commands until one of them sets done, - ;; which means it has finished handling this occurrence. + ;; which means it has finished handling this + ;; occurrence. Any command that sets `done' should + ;; leave behind proper match data for the stack. + ;; Commands not setting `done' need to adjust + ;; `real-match-data'. (while (not done) (set-match-data real-match-data) (replace-highlight (match-beginning 0) (match-end 0)) @@ -1290,37 +1372,49 @@ make, or the user didn't cancel the call." ((eq def 'backup) (if stack (let ((elt (pop stack))) - (goto-char (car elt)) - (setq replaced (eq t (cdr elt))) - (or replaced - (set-match-data (cdr elt)))) + (goto-char (nth 0 elt)) + (setq replaced (nth 1 elt) + real-match-data + (replace-match-data + t real-match-data + (nth 2 elt)))) (message "No previous match") (ding 'no-terminate) (sit-for 1))) ((eq def 'act) (or replaced - (progn - (replace-match next-replacement nocasify literal) - (setq replace-count (1+ replace-count)))) + (setq noedit + (replace-match-maybe-edit + next-replacement nocasify literal + noedit real-match-data) + replace-count (1+ replace-count))) (setq done t replaced t)) ((eq def 'act-and-exit) (or replaced - (progn - (replace-match next-replacement nocasify literal) - (setq replace-count (1+ replace-count)))) + (setq noedit + (replace-match-maybe-edit + next-replacement nocasify literal + noedit real-match-data) + replace-count (1+ replace-count))) (setq keep-going nil) (setq done t replaced t)) ((eq def 'act-and-show) (if (not replaced) - (progn - (replace-match next-replacement nocasify literal) - (setq replace-count (1+ replace-count)) - (setq replaced t)))) + (setq noedit + (replace-match-maybe-edit + next-replacement nocasify literal + noedit real-match-data) + replace-count (1+ replace-count) + real-match-data (replace-match-data + t real-match-data) + replaced t))) ((eq def 'automatic) (or replaced - (progn - (replace-match next-replacement nocasify literal) - (setq replace-count (1+ replace-count)))) + (setq noedit + (replace-match-maybe-edit + next-replacement nocasify literal + noedit real-match-data) + replace-count (1+ replace-count))) (setq done t query-flag nil replaced t)) ((eq def 'skip) (setq done t)) @@ -1328,36 +1422,45 @@ make, or the user didn't cancel the call." (recenter nil)) ((eq def 'edit) (let ((opos (point-marker))) + (setq real-match-data (replace-match-data + nil real-match-data + real-match-data)) (goto-char (match-beginning 0)) - (save-excursion - (funcall search-function search-string limit t) - (setq real-match-data (match-data))) (save-excursion (save-window-excursion (recursive-edit))) - (goto-char opos)) - (set-match-data real-match-data) + (goto-char opos) + (set-marker opos nil)) ;; Before we make the replacement, ;; decide whether the search string ;; can match again just after this match. (if (and regexp-flag nonempty-match) (setq match-again (and (looking-at search-string) (match-data))))) - ;; Edit replacement. ((eq def 'edit-replacement) - (setq next-replacement + (setq real-match-data (replace-match-data + nil real-match-data + real-match-data) + next-replacement (read-input "Edit replacement string: " - next-replacement)) - (or replaced - (replace-match next-replacement nocasify literal)) + next-replacement) + noedit nil) + (if replaced + (set-match-data real-match-data) + (setq noedit + (replace-match-maybe-edit + next-replacement nocasify literal noedit + real-match-data) + replaced t)) (setq done t)) ((eq def 'delete-and-edit) - (delete-region (match-beginning 0) (match-end 0)) - (set-match-data - (prog1 (match-data) - (save-excursion (recursive-edit)))) + (replace-match "" t t) + (setq real-match-data (replace-match-data + nil real-match-data)) + (replace-dehighlight) + (save-excursion (recursive-edit)) (setq replaced t)) ;; Note: we do not need to treat `exit-prefix' ;; specially here, since we reread @@ -1372,10 +1475,23 @@ make, or the user didn't cancel the call." ;; Record previous position for ^ when we move on. ;; Change markers to numbers in the match data ;; since lots of markers slow down editing. - (setq stack - (cons (cons (point) - (or replaced (match-data t))) - stack)))))) + (push (list (point) replaced +;;; If the replacement has already happened, all we need is the +;;; current match start and end. We could get this with a trivial +;;; match like +;;; (save-excursion (goto-char (match-beginning 0)) +;;; (search-forward (match-string 0)) +;;; (match-data t)) +;;; if we really wanted to avoid manually constructing match data. +;;; Adding current-buffer is necessary so that match-data calls can +;;; return markers which are appropriate for editing. + (if replaced + (list + (match-beginning 0) + (match-end 0) + (current-buffer)) + (match-data t))) + stack))))) ;; The code preventing adjacent regexp matches in the condition ;; of the while-loop above will haven taken us one character @@ -1405,14 +1521,12 @@ make, or the user didn't cancel the call." (defun replace-highlight (start end) (and query-replace-highlight - (progn - (or replace-overlay - (progn - (setq replace-overlay (make-overlay start end)) - (overlay-put replace-overlay 'face - (if (facep 'query-replace) - 'query-replace 'region)))) - (move-overlay replace-overlay start end (current-buffer))))) + (if replace-overlay + (move-overlay replace-overlay start end (current-buffer)) + (setq replace-overlay (make-overlay start end)) + (overlay-put replace-overlay 'face + (if (facep 'query-replace) + 'query-replace 'region))))) ;;; arch-tag: 16b4cd61-fd40-497b-b86f-b667c4cf88e4 ;;; replace.el ends here diff --git a/lisp/vc-arch.el b/lisp/vc-arch.el index a439174556e..5f24599241c 100644 --- a/lisp/vc-arch.el +++ b/lisp/vc-arch.el @@ -309,7 +309,8 @@ Return non-nil if FILE is unchanged." (defcustom vc-arch-mode-line-rewrite '(("\\`.*--\\(.*--.*\\)--\\(v?\\).*-\\([0-9]+\\)\\'" . "\\2\\3[\\1]")) "Rewrite rules to shorten Arch's revision names on the mode-line." - :type '(repeat (cons regexp string))) + :type '(repeat (cons regexp string)) + :group 'vc) (defun vc-arch-mode-line-string (file) "Return string for placement in modeline by `vc-mode-line' for FILE." diff --git a/lisp/woman.el b/lisp/woman.el index ba511bca1ae..cea1c61bcc4 100644 --- a/lisp/woman.el +++ b/lisp/woman.el @@ -5,7 +5,7 @@ ;; Author: Francis J. Wright ;; Maintainer: Francis J. Wright ;; Keywords: help, unix -;; Adapted-By: Eli Zaretskii +;; Adapted-By: Eli Zaretskii ;; Version: see `woman-version' ;; URL: http://centaur.maths.qmul.ac.uk/Emacs/WoMan/ diff --git a/lispref/ChangeLog b/lispref/ChangeLog index c4c6b81e8ba..970ecc4d494 100644 --- a/lispref/ChangeLog +++ b/lispref/ChangeLog @@ -1,3 +1,50 @@ +2004-06-24 Richard M. Stallman + + * commands.texi (Misc Events): Describe usr1-signal, usr2-signal event. + + * customize.texi (Variable Definitions): Note about doc strings + and :set. + + * keymaps.texi (Keymap Terminology): Document `kbd'. + (Changing Key Bindings, Key Binding Commands): Use kbd in examples. + + * display.texi (Invisible Text): Setting buffer-invisibility-spec + makes it buffer-local. + + * files.texi (Saving Buffers): Correct previous change. + + * commands.texi (Accessing Events): + Clarify posn-col-row and posn-actual-col-row. + +2004-06-24 David Ponce + + * commands.texi (Accessing Events): New functions + posn-at-point and posn-at-x-y. Add example to posn-x-y. + +2004-06-23 Luc Teirlinck + + * lists.texi, files.texi, processes.texi, macros.texi, hash.texi: + * frames.texi, buffers.texi, backups.texi, variables.texi: + * loading.texi, eval.texi, functions.texi, control.texi: + * symbols.texi, minibuf.texi: Reposition @anchor's. + + * help.texi: Various small changes in addition to the following. + (Describing Characters): Describe PREFIX argument to + `key-description'. Correct and clarify definition of + `text-char-description'. Describe NEED-VECTOR argument to + `read-kbd-macro'. + (Help Functions): Clarify definition of `apropos'. + +2004-06-23 Lars Hansen + + * files.texi (Saving Buffers): Correct description of + `write-contents-functions'. + +2004-06-21 Juanma Barranquero + + * display.texi (Images): Remove redundant @vindex directives. + Rewrite `image-library-alist' doc in active voice. + 2004-06-14 Juanma Barranquero * display.texi (Images): Document new delayed library loading, diff --git a/lispref/backups.texi b/lispref/backups.texi index d4ef8032ad9..52cb86dea88 100644 --- a/lispref/backups.texi +++ b/lispref/backups.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1999 +@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1999, 2004 @c Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @setfilename ../info/backups @@ -712,8 +712,8 @@ reverts the file without asking the user for confirmation. Some major modes customize @code{revert-buffer} by making buffer-local bindings for these variables: -@anchor{Definition of revert-buffer-function} @defvar revert-buffer-function +@anchor{Definition of revert-buffer-function} The value of this variable is the function to use to revert this buffer. If non-@code{nil}, it should be a function with two optional arguments to do the work of reverting. The two optional arguments, diff --git a/lispref/buffers.texi b/lispref/buffers.texi index 723dae742ab..8391159c088 100644 --- a/lispref/buffers.texi +++ b/lispref/buffers.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999 +@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2004 @c Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @setfilename ../info/buffers @@ -227,8 +227,8 @@ An error is signaled if @var{buffer-or-name} does not identify an existing buffer. @end defmac -@anchor{Definition of with-temp-buffer} @defmac with-temp-buffer body... +@anchor{Definition of with-temp-buffer} The @code{with-temp-buffer} macro evaluates the @var{body} forms with a temporary buffer as the current buffer. It saves the identity of the current buffer, creates a temporary buffer and makes it current, diff --git a/lispref/commands.texi b/lispref/commands.texi index 5a38179996f..7a014080e89 100644 --- a/lispref/commands.texi +++ b/lispref/commands.texi @@ -872,7 +872,7 @@ the current Emacs session. If a symbol has not yet been so used, * Repeat Events:: Double and triple click (or drag, or down). * Motion Events:: Just moving the mouse, not pushing a button. * Focus Events:: Moving the mouse between frames. -* Misc Events:: Other events window systems can generate. +* Misc Events:: Other events the system can generate. * Event Examples:: Examples of the lists for mouse events. * Classifying Events:: Finding the modifier keys in an event symbol. Event types. @@ -1462,9 +1462,9 @@ so that the focus event comes either before or after the multi-event key sequence, and not within it. @node Misc Events -@subsection Miscellaneous Window System Events +@subsection Miscellaneous System Events -A few other event types represent occurrences within the window system. +A few other event types represent occurrences within the system. @table @code @cindex @code{delete-frame} event @@ -1517,6 +1517,14 @@ The usual way to handle this event is by visiting these files. This kind of event is generated, at present, only on some kinds of systems. + +@cindex @code{usr1-signal} event +@cindex @code{usr2-signal} event +@item usr1-signal +@itemx usr2-signal +These events are generated when the Emacs process receives the signals +@code{SIGUSR1} and @code{SIGUSR2}. They contain no additional data +because signals do not carry additional information. @end table If one of these events arrives in the middle of a key sequence---that @@ -1695,7 +1703,7 @@ position such events have. @end defun @cindex mouse position list, accessing - These seven functions take a position list as described above, and + These functions take a position list as described above, and return various parts of it. @defun posn-window position @@ -1716,23 +1724,37 @@ is undefined. @end defun @defun posn-x-y position -Return the pixel-based x and y coordinates in @var{position}, as a cons -cell @code{(@var{x} . @var{y})}. +Return the pixel-based x and y coordinates in @var{position}, as a +cons cell @code{(@var{x} . @var{y})}. These coordinates are relative +to the window given by @code{posn-window}. + +This example shows how to convert these window-relative coordinates +into frame-relative coordinates: + +@example +(defun frame-relative-coordinates (position) + "Return frame-relative coordinates from POSITION." + (let* ((x-y (posn-x-y position)) + (window (posn-window position)) + (edges (window-inside-pixel-edges window))) + (cons (+ (car x-y) (car edges)) + (+ (cdr x-y) (cadr edges))))) +@end example @end defun @defun posn-col-row position -Return the row and column (in units of frame default characters) of -@var{position}, as a cons cell @code{(@var{col} . @var{row})}. These -are computed from the @var{x} and @var{y} values actually found in -@var{position}. +Return the row and column (in units of the frame's default character +height and width) of @var{position}, as a cons cell @code{(@var{col} . +@var{row})}. These are computed from the @var{x} and @var{y} values +actually found in @var{position}. @end defun @defun posn-actual-col-row position Return the actual row and column in @var{position}, as a cons cell @code{(@var{col} . @var{row})}. The values are the actual row number -in the window, and the actual character number in that row. Return -@code{nil} if @var{position} does not include the actual positions; in that -case, @code{posn-col-row} can be used to get approximate values. +in the window, and the actual character number in that row. It returns +@code{nil} if @var{position} does not include actual positions values. +You can use @code{posn-col-row} to get approximate values. @end defun @defun posn-string position @@ -1769,6 +1791,27 @@ is a buffer position, return the size of the character at that position. @defun posn-timestamp Return the timestamp in @var{position}. This is the time at which the event occurred, in milliseconds. +@end defun + + These functions compute a position list given particular buffer +position or screen position. You can access the data in this position +list with the functions described above. + +@defun posn-at-point &optional pos window +This function returns a position list for position @var{pos} in +@var{window}. @var{pos} defaults to point in @var{window}; +@var{window} defaults to the selected window. + +@code{posn-at-point} returns @code{nil} if @var{pos} is not visible in +@var{window}. +@end defun + +@defun posn-at-x-y x y &optional frame-or-window +This function returns position information corresponding to pixel +coordinates @var{x} and @var{y} in a specified frame or window, +@var{frame-or-window}, which defaults to the selected window. +The coordinates @var{x} and @var{y} are relative to the +frame or window used. @end defun These functions are useful for decoding scroll bar events. diff --git a/lispref/control.texi b/lispref/control.texi index 9ab86697367..e2a1e26b170 100644 --- a/lispref/control.texi +++ b/lispref/control.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999 +@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2003 @c Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @setfilename ../info/control @@ -784,8 +784,8 @@ contains @samp{%}, it will be interpreted as a format specifier, with undesirable results. Instead, use @code{(error "%s" @var{string})}. @end defun -@anchor{Definition of signal} @defun signal error-symbol data +@anchor{Definition of signal} This function signals an error named by @var{error-symbol}. The argument @var{data} is a list of additional Lisp objects relevant to the circumstances of the error. diff --git a/lispref/customize.texi b/lispref/customize.texi index 5b95e911f85..c2e31462e0e 100644 --- a/lispref/customize.texi +++ b/lispref/customize.texi @@ -194,6 +194,11 @@ than one occasion. You should normally avoid using backquotes in @var{default} because they are not expanded when editing the value, causing list values to appear to have the wrong structure. +If you specify the @code{:set} option, to make the variable take other +special actions when set through the customization buffer, the +variable's documentation string should tell the user specifically how +to do the same job in hand-written Lisp code. + When you evaluate a @code{defcustom} form with @kbd{C-M-x} in Emacs Lisp mode (@code{eval-defun}), a special feature of @code{eval-defun} arranges to set the variable unconditionally, without testing whether diff --git a/lispref/display.texi b/lispref/display.texi index 1f8868981b7..b6fd015beba 100644 --- a/lispref/display.texi +++ b/lispref/display.texi @@ -562,7 +562,8 @@ the buffer looking for properties to change. @defvar buffer-invisibility-spec This variable specifies which kinds of @code{invisible} properties -actually make a character invisible. +actually make a character invisible. Setting this variable makes it +buffer-local. @table @asis @item @code{t} @@ -2892,7 +2893,6 @@ type symbols are @code{xbm}, @code{xpm}, @code{gif}, @code{postscript}, @code{pbm}, @code{jpeg}, @code{tiff}, and @code{png}. @defvar image-types -@vindex image-types This variable contains a list of those image type symbols that are potentially supported in the current configuration. @emph{Potentially} here means that Emacs knows about the image types, @@ -2904,7 +2904,6 @@ To know which image types are really available, use @end defvar @defvar image-library-alist -@vindex image-library-alist This in an alist of image types vs external libraries needed to display them. @@ -2913,9 +2912,9 @@ where the car is a supported image format from @code{image-types}, and the rest are strings giving alternate filenames for the corresponding external libraries to load. -They are tried in the order they appear on the list; if none of them -can be loaded, the running session of Emacs won't support the image -type. No entries are needed for @code{pbm} and @code{xbm} images; +Emacs tries to load the libraries in the order they appear on the +list; if none is loaded, the running session of Emacs won't support +the image type. @code{pbm} and @code{xbm} don't need to be listed; they're always supported. This variable is ignored if the image libraries are statically linked @@ -2925,9 +2924,9 @@ into Emacs. @defun image-type-available-p type @findex image-type-available-p -This function returns non-nil if image type TYPE is available, i.e., -if images of this type can be loaded and displayed in Emacs. TYPE -should be one of the types contained in @code{image-types}. +This function returns non-nil if image type @var{TYPE} is available, +i.e., if images of this type can be loaded and displayed in Emacs. +@var{TYPE} should be one of the types contained in @code{image-types}. For image types whose support libraries are statically linked, this function always returns @code{t}; for other image types, it returns diff --git a/lispref/eval.texi b/lispref/eval.texi index 3c8a7a5e8a3..6a43466af67 100644 --- a/lispref/eval.texi +++ b/lispref/eval.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1998 Free Software Foundation, Inc. +@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1998, 2003, 2004 Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @setfilename ../info/eval @node Evaluation, Control Structures, Symbols, Top @@ -313,8 +313,8 @@ symbol function indirection when calling @code{erste}. perform symbol function indirection explicitly. @c Emacs 19 feature -@anchor{Definition of indirect-function} @defun indirect-function function +@anchor{Definition of indirect-function} This function returns the meaning of @var{function} as a function. If @var{function} is a symbol, then it finds @var{function}'s function definition and starts over with that value. If @var{function} is not a @@ -630,8 +630,8 @@ The number of currently active calls to @code{eval} is limited to @code{max-lisp-eval-depth} (see below). @end defun -@anchor{Definition of eval-region} @deffn Command eval-region start end &optional stream read-function +@anchor{Definition of eval-region} This function evaluates the forms in the current buffer in the region defined by the positions @var{start} and @var{end}. It reads forms from the region and calls @code{eval} on them until the end of the region is @@ -674,8 +674,8 @@ output of the output functions is printed in the echo area. @code{eval-current-buffer} is an alias for this command. @end deffn -@anchor{Definition of max-lisp-eval-depth} @defvar max-lisp-eval-depth +@anchor{Definition of max-lisp-eval-depth} This variable defines the maximum depth allowed in calls to @code{eval}, @code{apply}, and @code{funcall} before an error is signaled (with error message @code{"Lisp nesting exceeds max-lisp-eval-depth"}). diff --git a/lispref/files.texi b/lispref/files.texi index aa5b0c397b1..10d6c808625 100644 --- a/lispref/files.texi +++ b/lispref/files.texi @@ -329,8 +329,8 @@ With an argument of 0, unconditionally do @emph{not} make any backup file. @end itemize @end deffn -@anchor{Definition of save-some-buffers} @deffn Command save-some-buffers &optional save-silently-p pred +@anchor{Definition of save-some-buffers} This command saves some modified file-visiting buffers. Normally it asks the user about each buffer. But if @var{save-silently-p} is non-@code{nil}, it saves all the file-visiting buffers without querying @@ -352,8 +352,8 @@ whether to offer to save that buffer. If it returns a non-@code{nil} value in a certain buffer, that means do offer to save that buffer. @end deffn -@anchor{Definition of write-file} @deffn Command write-file filename &optional confirm +@anchor{Definition of write-file} This function writes the current buffer into file @var{filename}, makes the buffer visit that file, and marks it not modified. Then it renames the buffer based on @var{filename}, appending a string like @samp{<2>} @@ -417,10 +417,11 @@ Even though this is not a normal hook, you can use @code{add-hook} and @defvar write-contents-functions This works just like @code{write-file-functions}, but it is intended for hooks that pertain to the contents of the file, as opposed to hooks that -pertain to where the file came from. Such hooks are usually set up by +pertain to the file's name or location. Such hooks are usually set up by major modes, as buffer-local bindings for this variable. If any of the -functions in this hook returns non-@code{nil}, @code{write-file-functions} -is not run. +functions in this hook returns non-@code{nil}, the file is considered +already written and the rest are not called and neither are the functions +in @code{write-file-functions}. This variable automatically becomes buffer-local whenever it is set; switching to a new major mode always resets this variable, but @@ -625,8 +626,8 @@ feature is useful for programs that use files for internal purposes, files that the user does not need to know about. @end deffn -@anchor{Definition of with-temp-file} @defmac with-temp-file file body... +@anchor{Definition of with-temp-file} The @code{with-temp-file} macro evaluates the @var{body} forms with a temporary buffer as the current buffer; then, at the end, it writes the buffer contents into file @var{file}. It kills the temporary buffer @@ -1124,8 +1125,8 @@ link to. @end example @end defun -@anchor{Definition of file-attributes} @defun file-attributes filename &optional id-format +@anchor{Definition of file-attributes} This function returns a list of attributes of file @var{filename}. If the specified file cannot be opened, it returns @code{nil}. The optional parameter @var{id-format} specifies the preferred format @@ -1823,8 +1824,8 @@ and so on. To convert a directory name to its abbreviation, use this function: -@anchor{Definition of abbreviate-file-name} @defun abbreviate-file-name filename +@anchor{Definition of abbreviate-file-name} This function applies abbreviations from @code{directory-abbrev-alist} to its argument, and substitutes @samp{~} for the user's home directory. You can use it for directory names and for file names, @@ -1951,8 +1952,8 @@ default-directory @end example @end defvar -@anchor{Definition of substitute-in-file-name} @defun substitute-in-file-name filename +@anchor{Definition of substitute-in-file-name} This function replaces environment variable references in @var{filename} with the environment variable values. Following standard Unix shell syntax, @samp{$} is the prefix to substitute an diff --git a/lispref/frames.texi b/lispref/frames.texi index 0be4c525822..fe3bca7c119 100644 --- a/lispref/frames.texi +++ b/lispref/frames.texi @@ -1503,8 +1503,8 @@ This function returns the contents of cut buffer number @var{n}. If omitted @var{n} defaults to 0. @end defun -@anchor{Definition of x-set-cut-buffer} @defun x-set-cut-buffer string &optional push +@anchor{Definition of x-set-cut-buffer} This function stores @var{string} into the first cut buffer (cut buffer 0). If @var{push} is @code{nil}, only the first cut buffer is changed. If @var{push} is non-@code{nil}, that says to move the values down @@ -1793,8 +1793,8 @@ This function returns @code{t} if the screen can display shades of gray. (All color displays can do this.) @end defun -@anchor{Display Face Attribute Testing} @defun display-supports-face-attributes-p attributes &optional display +@anchor{Display Face Attribute Testing} @tindex display-supports-face-attributes-p This function returns non-@code{nil} if all the face attributes in @var{attributes} are supported (@pxref{Face Attributes}). diff --git a/lispref/functions.texi b/lispref/functions.texi index 427389b4a68..5c7433507b0 100644 --- a/lispref/functions.texi +++ b/lispref/functions.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999 +@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2004 @c Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @setfilename ../info/functions @@ -577,8 +577,8 @@ defined is often done deliberately, and there is no way to distinguish deliberate redefinition from unintentional redefinition. @end defspec -@anchor{Definition of defalias} @defun defalias name definition &optional docstring +@anchor{Definition of defalias} This special form defines the symbol @var{name} as a function, with definition @var{definition} (which can be any valid Lisp function). It returns @var{definition}. @@ -752,8 +752,8 @@ is a sparse array whose nominal range of indices is very large. To map over a char-table in a way that deals properly with its sparse nature, use the function @code{map-char-table} (@pxref{Char-Tables}). -@anchor{Definition of mapcar} @defun mapcar function sequence +@anchor{Definition of mapcar} @code{mapcar} applies @var{function} to each element of @var{sequence} in turn, and returns a list of the results. diff --git a/lispref/hash.texi b/lispref/hash.texi index bf4555d3903..107935f1ba0 100644 --- a/lispref/hash.texi +++ b/lispref/hash.texi @@ -205,8 +205,8 @@ table. @end defun @tindex maphash -@anchor{Definition of maphash} @defun maphash function table +@anchor{Definition of maphash} This function calls @var{function} once for each of the associations in @var{table}. The function @var{function} should accept two arguments---a @var{key} listed in @var{table}, and its associated diff --git a/lispref/help.texi b/lispref/help.texi index 9a55ebf6724..ddc52253a80 100644 --- a/lispref/help.texi +++ b/lispref/help.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999 +@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2004 @c Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @setfilename ../info/help @@ -59,7 +59,7 @@ view the documentation string. @xref{Documentation Tips}. stand for key bindings to be looked up in the current keymaps when the documentation is displayed. This allows documentation strings to refer to the keys for related commands and be accurate even when a user -rearranges the key bindings. (@xref{Accessing Documentation}.) +rearranges the key bindings. (@xref{Keys in Documentation}.) In Emacs Lisp, a documentation string is accessible through the function or variable that it describes: @@ -260,8 +260,8 @@ as shown above for the @code{goal-column} variable, means that it is a user option; see the description of @code{defvar} in @ref{Defining Variables}. -@anchor{Definition of Snarf-documentation} @defun Snarf-documentation filename +@anchor{Definition of Snarf-documentation} This function is used only during Emacs initialization, just before the runnable Emacs is dumped. It finds the file offsets of the documentation strings stored in the file @var{filename}, and records @@ -282,8 +282,7 @@ built-in and preloaded functions and variables. In most cases, this is the same as @code{data-directory}. They may be different when you run Emacs from the directory where you built it, -without actually installing it. See @code{data-directory} in @ref{Help -Functions}. +without actually installing it. @xref{Definition of data-directory}. In older Emacs versions, @code{exec-directory} was used for this. @end defvar @@ -375,13 +374,27 @@ convert non-printing and whitespace characters to sequences of printing characters. The description of a non-whitespace printing character is the character itself. -@defun key-description sequence +@defun key-description sequence &optional prefix @cindex Emacs event standard notation This function returns a string containing the Emacs standard notation -for the input events in @var{sequence}. The argument @var{sequence} may -be a string, vector or list. @xref{Input Events}, for more information -about valid events. See also the examples for -@code{single-key-description}, below. +for the input events in @var{sequence}. If @var{prefix} is +non-@code{nil}, it is a sequence of input events leading up to +@var{sequence} and is included in the return value. Both arguments +may be strings, vectors or lists. @xref{Input Events}, for more +information about valid events. + +@smallexample +@group +(key-description [?\M-3 delete]) + @result{} "M-3 " +@end group +@group +(key-description [delete] "\M-3") + @result{} "M-3 " +@end group +@end smallexample + + See also the examples for @code{single-key-description}, below. @end defun @defun single-key-description event &optional no-angles @@ -432,8 +445,10 @@ This function returns a string describing @var{character} in the standard Emacs notation for characters that appear in text---like @code{single-key-description}, except that control characters are represented with a leading caret (which is how control characters in -Emacs buffers are usually displayed) and character codes 128 -and above are not treated as Meta characters. +Emacs buffers are usually displayed). Another difference is that +@code{text-char-description} recognizes the 2**7 bit as the Meta +character, whereas @code{single-key-description} uses the 2**27 bit +for Meta. @smallexample @group @@ -448,16 +463,25 @@ and above are not treated as Meta characters. (text-char-description ?\C-\M-m) @result{} "\x8d" @end group +@group +(text-char-description (+ 128 ?m)) + @result{} "M-m" +@end group +@group +(text-char-description (+ 128 ?\C-m)) + @result{} "M-^M" +@end group @end smallexample @end defun -@defun read-kbd-macro string +@defun read-kbd-macro string &optional need-vector This function is used mainly for operating on keyboard macros, but it can also be used as a rough inverse for @code{key-description}. You call it with a string containing key descriptions, separated by spaces; it returns a string or vector containing the corresponding events. (This may or may not be a single valid key sequence, depending on what -events you use; @pxref{Keymap Terminology}.) +events you use; @pxref{Keymap Terminology}.) If @var{need-vector} is +non-@code{nil}, the return value is always a vector. @end defun @node Help Functions @@ -469,29 +493,20 @@ about them, see @ref{Help, , Help, emacs, The GNU Emacs Manual}. Here we describe some program-level interfaces to the same information. @deffn Command apropos regexp &optional do-all -This function finds all symbols whose names contain a match for the -regular expression @var{regexp}, and returns a list of them -(@pxref{Regular Expressions}). It also displays the symbols in a buffer -named @samp{*Help*}, each with a one-line description taken from the -beginning of its documentation string. +This function finds all ``meaningful'' symbols whose names contain a +match for the regular expression @var{regexp}, and returns a list of +them, with associated documentation (@pxref{Regular Expressions}). It +also displays the symbols in a buffer named @samp{*Apropos*}, each +with a one-line description taken from the beginning of its +documentation string. A symbol is ``meaningful'' if it has a +definition as a function, variable, or face, or has properties. @c Emacs 19 feature -If @var{do-all} is non-@code{nil}, then @code{apropos} also shows key -bindings for the functions that are found; it also shows all symbols, -even those that are neither functions nor variables. - -In the first of the following examples, @code{apropos} finds all the -symbols with names containing @samp{exec}. (We don't show here the -output that results in the @samp{*Help*} buffer.) - -@smallexample -@group -(apropos "exec") - @result{} (Buffer-menu-execute command-execute exec-directory - exec-path execute-extended-command execute-kbd-macro - executing-kbd-macro executing-macro) -@end group -@end smallexample +If @var{do-all} is non-@code{nil}, or if the user option +@code{apropos-do-all} is non-@code{nil}, then @code{apropos} also +shows key bindings for the functions that are found; it also shows +@emph{all} interned symbols, not just meaningful ones (and it lists +them in the return value as well). @end deffn @defvar help-map @@ -506,7 +521,7 @@ follows: @smallexample @group -(define-key global-map "\C-h" 'help-command) +(define-key global-map (char-to-string help-char) 'help-command) (fset 'help-command help-map) @end group @end smallexample @@ -562,7 +577,7 @@ some other meaning.) Evaluating this expression should result in a string that explains what the input is for and how to enter it properly. Entry to the minibuffer binds this variable to the value of -@code{minibuffer-help-form} (@pxref{Minibuffer Misc}). +@code{minibuffer-help-form} (@pxref{Definition of minibuffer-help-form}). @end defvar @defvar prefix-help-command @@ -601,6 +616,7 @@ This can be customized by changing the map @code{Helper-help-map}. @c Emacs 19 feature @defvar data-directory +@anchor{Definition of data-directory} This variable holds the name of the directory in which Emacs finds certain documentation and text files that come with Emacs. In older Emacs versions, @code{exec-directory} was used for this. diff --git a/lispref/keymaps.texi b/lispref/keymaps.texi index ee50855bef3..12246f0b236 100644 --- a/lispref/keymaps.texi +++ b/lispref/keymaps.texi @@ -95,6 +95,27 @@ precedence over) the corresponding global bindings. The minor mode keymaps shadow both local and global keymaps. @xref{Active Keymaps}, for details. + The Emacs Lisp representation for a key sequence is a string or vector. +You can enter key sequence constants using the ordinary string or vector +representation; it is also convenient to use @code{kbd}: + +@defmac kbd keyseq-text +This macro converts the text @var{keyseq-text} (a string constant) +into a key sequence (a string or vector constant). The contents +of @var{keyseq-text} should describe the key sequence using the syntax +used in this manual: + +@example +(kbd "C-x") @result{} "\C-x" +(kbd "C-x C-f") @result{} "\C-x\C-f" +(kbd "C-c C-c") @result{} "\C-c\C-c" +(kbd "C-x 4 C-f") @result{} "\C-x4\C-f" +(kbd "X") @result{} "X" +(kbd "RET") @result{} "\^M" +(kbd "C-c 3") @result{} "\C-c3" +@end example +@end defmac + @node Format of Keymaps @section Format of Keymaps @cindex format of keymaps @@ -880,6 +901,10 @@ the other functions described in this chapter that look up keys use @result{} find-file @end group @group +(lookup-key (current-global-map) (kbd "C-x C-f")) + @result{} find-file +@end group +@group (lookup-key (current-global-map) "\C-x\C-f12345") @result{} 2 @end group @@ -1126,7 +1151,7 @@ map @group ;; @r{Build sparse submap for @kbd{C-x} and bind @kbd{f} in that.} -(define-key map "\C-xf" 'forward-word) +(define-key map (kbd "C-x f") 'forward-word) @result{} forward-word @end group @group @@ -1139,14 +1164,14 @@ map @group ;; @r{Bind @kbd{C-p} to the @code{ctl-x-map}.} -(define-key map "\C-p" ctl-x-map) +(define-key map (kbd "C-p") ctl-x-map) ;; @code{ctl-x-map} @result{} [nil @dots{} find-file @dots{} backward-kill-sentence] @end group @group ;; @r{Bind @kbd{C-f} to @code{foo} in the @code{ctl-x-map}.} -(define-key map "\C-p\C-f" 'foo) +(define-key map (kbd "C-p C-f") 'foo) @result{} 'foo @end group @group @@ -1333,7 +1358,7 @@ changing key bindings. They work by calling @code{define-key}. (@pxref{Init File}) for simple customization. For example, @smallexample -(global-set-key "\C-x\C-\\" 'next-line) +(global-set-key (kbd "C-x C-\\") 'next-line) @end smallexample @noindent diff --git a/lispref/lists.texi b/lispref/lists.texi index 2aa3c40b0e5..d30dcb0c270 100644 --- a/lispref/lists.texi +++ b/lispref/lists.texi @@ -1,6 +1,7 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999 +@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, +@c 2003, 2004 @c Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @setfilename ../info/lists @@ -348,8 +349,8 @@ x @end example @end defmac -@anchor{Definition of nth} @defun nth n list +@anchor{Definition of nth} This function returns the @var{n}th element of @var{list}. Elements are numbered starting with zero, so the @sc{car} of @var{list} is element number zero. If the length of @var{list} is @var{n} or less, @@ -413,8 +414,8 @@ this link is the list's last element. If @var{list} is null, if @var{n} is bigger than @var{list}'s length. @end defun -@anchor{Definition of safe-length} @defun safe-length list +@anchor{Definition of safe-length} This function returns the length of @var{list}, with no risk of either an error or an infinite loop. It generally returns the number of distinct cons cells in the list. However, for circular lists, diff --git a/lispref/loading.texi b/lispref/loading.texi index 4d13e48def5..1b90ef5f2dd 100644 --- a/lispref/loading.texi +++ b/lispref/loading.texi @@ -1,6 +1,7 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999 +@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, +@c 2003, 2004 @c Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @setfilename ../info/loading @@ -140,8 +141,8 @@ This variable is non-@code{nil} if Emacs is in the process of loading a file, and it is @code{nil} otherwise. @end defvar -@anchor{Definition of load-read-function} @defvar load-read-function +@anchor{Definition of load-read-function} This variable specifies an alternate expression-reading function for @code{load} and @code{eval-region} to use instead of @code{read}. The function should accept one argument, just as @code{read} does. diff --git a/lispref/macros.texi b/lispref/macros.texi index b940125cb87..e903a159c27 100644 --- a/lispref/macros.texi +++ b/lispref/macros.texi @@ -232,8 +232,8 @@ called interactively. which can specify how @key{TAB} should indent macro calls, and how to step through them for Edebug. -@anchor{Definition of declare} @defmac declare @var{specs}@dots{} +@anchor{Definition of declare} A @code{declare} form is used in a macro definition to specify various additional information about it. Two kinds of specification are currently supported: diff --git a/lispref/minibuf.texi b/lispref/minibuf.texi index a2695eab6b9..8e8329967f3 100644 --- a/lispref/minibuf.texi +++ b/lispref/minibuf.texi @@ -1,6 +1,7 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2001 +@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, +@c 2001, 2004 @c Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @setfilename ../info/minibuf @@ -214,8 +215,8 @@ functions that do minibuffer input with completion, discard text properties unconditionally, regardless of the value of this variable. @end defvar -@anchor{Definition of minibuffer-local-map} @defvar minibuffer-local-map +@anchor{Definition of minibuffer-local-map} This is the default local keymap for reading from the minibuffer. By default, it makes the following bindings: @@ -531,7 +532,7 @@ etc. Use of a cons cell as the value for @var{initial} arguments is deprecated in user code. - + @node Completion @section Completion @cindex completion @@ -726,8 +727,8 @@ example for @code{try-completion}: @end smallexample @end defun -@anchor{Definition of test-completion} @defun test-completion string collection &optional predicate +@anchor{Definition of test-completion} This function returns non-@code{nil} if @var{string} is a valid completion possibility specified by @var{collection} and @var{predicate}. The arguments are the same as in @@ -1755,6 +1756,7 @@ This is a normal hook that is run whenever the minibuffer is exited. @end defvar @defvar minibuffer-help-form +@anchor{Definition of minibuffer-help-form} The current value of this variable is used to rebind @code{help-form} locally inside the minibuffer (@pxref{Help Functions}). @end defvar diff --git a/lispref/processes.texi b/lispref/processes.texi index a4166ee29a0..f580a774ae7 100644 --- a/lispref/processes.texi +++ b/lispref/processes.texi @@ -676,8 +676,8 @@ instead of a terminal (see @code{process-connection-type} in @ref{Asynchronous Processes}). @end defun -@anchor{Coding systems for a subprocess} @defun process-coding-system process +@anchor{Coding systems for a subprocess} This function returns a cons cell describing the coding systems in use for decoding output from @var{process} and for encoding input to @var{process} (@pxref{Coding Systems}). The value has this form: diff --git a/lispref/symbols.texi b/lispref/symbols.texi index 632f2cc5174..d6743898d6f 100644 --- a/lispref/symbols.texi +++ b/lispref/symbols.texi @@ -1,6 +1,6 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999 +@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2003 @c Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @setfilename ../info/symbols @@ -360,8 +360,8 @@ This variable is the standard obarray for use by @code{intern} and @code{read}. @end defvar -@anchor{Definition of mapatoms} @defun mapatoms function &optional obarray +@anchor{Definition of mapatoms} This function calls @var{function} once with each symbol in the obarray @var{obarray}. Then it returns @code{nil}. If @var{obarray} is omitted, it defaults to the value of @code{obarray}, the standard diff --git a/lispref/variables.texi b/lispref/variables.texi index c395702a40a..1f793b8f03f 100644 --- a/lispref/variables.texi +++ b/lispref/variables.texi @@ -1,6 +1,7 @@ @c -*-texinfo-*- @c This is part of the GNU Emacs Lisp Reference Manual. -@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2000 +@c Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, +@c 2000, 2003, 2004 @c Free Software Foundation, Inc. @c See the file elisp.texi for copying conditions. @setfilename ../info/variables @@ -260,8 +261,8 @@ These kinds of bindings work somewhat like ordinary local bindings, but they are localized depending on ``where'' you are in Emacs, rather than localized in time. -@anchor{Definition of max-specpdl-size} @defvar max-specpdl-size +@anchor{Definition of max-specpdl-size} @cindex variable limit error @cindex evaluation error @cindex infinite recursion diff --git a/make-dist b/make-dist index 78ce196a3da..8cfc41ccd25 100755 --- a/make-dist +++ b/make-dist @@ -406,6 +406,7 @@ echo "Making links to \`leim' and its subdirectories" ln MISC-DIC/*.* ../${tempdir}/leim/MISC-DIC ln ja-dic/*.el ja-dic/*.elc ../${tempdir}/leim/ja-dic ln Makefile.in ../${tempdir}/leim/Makefile.in + ln leim-ext.el ../${tempdir}/leim/leim-ext.el ln quail/[a-z]*.el quail/[a-z]*.elc ../${tempdir}/leim/quail rm -f ../${tempdir}/leim/quail/quick-b5.* rm -f ../${tempdir}/leim/quail/quick-cns.* diff --git a/man/ChangeLog b/man/ChangeLog index 16044ff1114..288cd00386a 100644 --- a/man/ChangeLog +++ b/man/ChangeLog @@ -1,3 +1,36 @@ +2004-06-29 Jesper Harder + + * ses.texi, viper.texi, search.texi, flymake.texi, faq.texi: + * eshell.texi, ediff.texi, calendar.texi: Markup fixes. + +2004-06-25 Richard M. Stallman + + * search.texi (Regexp Replace): Rewrite description of \# \, and \?. + +2004-06-25 David Kastrup + + * search.texi (Regexp Replace): Some typo corrections and + rearrangement. + +2004-06-24 David Kastrup + + * search.texi (Unconditional Replace): Use replace-string instead + of query-replace in example. + (Regexp Replace): Add explanations for `\,', `\#' and `\?' + sequences. + (Query Replace): Correct explanation of `^' which does not use + the mark stack. + +2004-06-21 Nick Roberts + + * misc.texi (Shell History Copying): Document comint-insert-input. + (Shell Ring): Describe comint-dynamic-list-input-ring here. + +2004-06-21 Karl Berry + + * info.texi (Top): mention that only Emacs has mouse support. + (Getting Started): mention this in a few other places. + 2004-06-20 Jesper Harder * msdog.texi (Text and Binary, MS-DOS Printing): Use m-dash. diff --git a/man/calendar.texi b/man/calendar.texi index 3d3f84b4ba3..9e3d3cf9f41 100644 --- a/man/calendar.texi +++ b/man/calendar.texi @@ -1332,7 +1332,7 @@ begins with a recognizable time of day, Emacs can warn you several minutes beforehand that that appointment is pending. Emacs alerts you to the appointment by displaying a message in your chosen format, as specified by the variable @code{appt-display-format}. If the value -of @code{appt-audible} is non-nil, an audible reminder is also given. +of @code{appt-audible} is non-@code{nil}, an audible reminder is also given. @findex appt-activate To enable appointment notification, call the function diff --git a/man/ediff.texi b/man/ediff.texi index b1447386b0c..954efe4e027 100644 --- a/man/ediff.texi +++ b/man/ediff.texi @@ -1067,7 +1067,7 @@ the only such group-level operation is the creation of a multi-file patch. @vindex ediff-autostore-merges For group sessions created to merge files, Ediff can store all merges automatically in a directory. The user is asked to specify such directory -if the value of @code{ediff-autostore-merges} is non-nil. If the value is +if the value of @code{ediff-autostore-merges} is non-@code{nil}. If the value is @code{nil}, nothing is done to the merge buffers---it will be the user's responsibility to save them. If the value is @code{t}, the user will be asked where to save the merge buffers in all merge jobs, even those that do @@ -2338,11 +2338,11 @@ The second of the data buffers being compared. @item ediff-buffer-C In three-way comparisons, this is the third buffer being compared. In merging, this is the merge buffer. -In two-way comparison, this variable is nil. +In two-way comparison, this variable is @code{nil}. @item ediff-window-A The window displaying buffer A. If buffer A is not visible, this variable -is nil or it may be a dead window. +is @code{nil} or it may be a dead window. @item ediff-window-B The window displaying buffer B. @@ -2351,9 +2351,9 @@ The window displaying buffer B. The window displaying buffer C, if any. @item ediff-control-frame -A dedicated frame displaying the control buffer, if it exists. -It is non-nil only if Ediff uses the multiframe display, i.e., when the -control buffer is in its own frame. +A dedicated frame displaying the control buffer, if it exists. It is +non-@code{nil} only if Ediff uses the multiframe display, i.e., when +the control buffer is in its own frame. @end table @node Credits, Index, Customization, Top diff --git a/man/eshell.texi b/man/eshell.texi index c909b6ebb46..fafc60ed186 100644 --- a/man/eshell.texi +++ b/man/eshell.texi @@ -846,7 +846,7 @@ At the moment, this is not supported. @item Error if a glob doesn't expand due to a predicate An error should be generated only if @code{eshell-error-if-no-glob} is -non-nil. +non-@code{nil}. @item @samp{(+ RET SPC TAB} does not cause @code{indent-according-to-mode} to occur diff --git a/man/eudc.texi b/man/eudc.texi index aaf130eb489..b5ff83be14a 100644 --- a/man/eudc.texi +++ b/man/eudc.texi @@ -475,7 +475,7 @@ An alist specifying methods to display attribute values. Each member of the list is of the form @code{(@var{name} . @var{func})} where @var{name} is a lowercased string naming a directory attribute (translated according to @code{eudc-user-attribute-names-alist} if -@code{eudc-use-raw-directory-names} is non-nil) and @var{func} a +@code{eudc-use-raw-directory-names} is non-@code{nil}) and @var{func} a function that will be passed the corresponding attribute values for display. @end defvar diff --git a/man/faq.texi b/man/faq.texi index 7c13dc16e7b..fc0afd85620 100644 --- a/man/faq.texi +++ b/man/faq.texi @@ -2367,7 +2367,7 @@ file, will bind the sequence @kbd{C-x g} to @code{goto-line}: Each menu title (e.g., @samp{File}, @samp{Edit}, @samp{Buffers}) represents a local or global keymap. Selecting a menu title with the -mouse displays that keymap's non-nil contents in the form of a menu. +mouse displays that keymap's non-@code{nil} contents in the form of a menu. So to add a menu option to an existing menu, all you have to do is add a new definition to the appropriate keymap. Adding a @samp{Forward Word} @@ -3173,7 +3173,7 @@ Obviously, there is a potential for Trojan horses to exploit this feature. Emacs 18 allowed this feature by default; users could disable it by -setting the variable @code{inhibit-local-variables} to a non-nil value. +setting the variable @code{inhibit-local-variables} to a non-@code{nil} value. As of Emacs 19, Emacs has a list of local variables that create a security risk. If a file tries to set one of them, it asks the user to diff --git a/man/flymake.texi b/man/flymake.texi index e710b903361..c505be21b6e 100644 --- a/man/flymake.texi +++ b/man/flymake.texi @@ -542,7 +542,7 @@ lines in the buffer using the accumulated error information. Syntax check is considered possible if there's an entry in @code{flymake-allowed-file-name-masks} matching buffer's filename and -its @code{init-function} returns non-nil value. +its @code{init-function} returns non-@code{nil} value. Two syntax check modes are distinguished: diff --git a/man/info.texi b/man/info.texi index 1d62c530bd0..2e42a0b9edc 100644 --- a/man/info.texi +++ b/man/info.texi @@ -62,6 +62,11 @@ The GNU Project distributes most of its on-line manuals in the @dfn{Info format}, which you read using an @dfn{Info reader}. You are probably using an Info reader to read this now. +There are two primary Info readers: @code{info}, a stand-alone program +designed just to read Info files, and the @code{info} package in GNU +Emacs, a general-purpose editor. At present, only the Emacs reader +supports using a mouse. + @ifinfo If you are new to the Info reader and want to learn how to use it, type the command @kbd{h} now. It brings you to a programmed @@ -84,7 +89,7 @@ Started' chapter. @comment node-name, next, previous, up @chapter Getting Started -This first part of the Info manual describes how to get around inside +This first part of this Info manual describes how to get around inside of Info. The second part of the manual describes various advanced Info commands, and how to write an Info as distinct from a Texinfo file. The third part briefly explains how to generate Info files from @@ -111,7 +116,7 @@ stand-alone program designed just to read Info files. @item Type @code{emacs} at the command line; then type @kbd{C-h i} (@kbd{Control-h}, followed by @kbd{i}). This approach uses the Info -mode of the Emacs program, an editor with many other capabilities. +mode of the Emacs editor. @end enumerate In either case, then type @kbd{mInfo} (just the letters), followed by @@ -270,9 +275,10 @@ command. Another @kbd{n} command now would take you to the next node, @samp{Help-^L}. @format ->> But do not type @kbd{n} yet. First, try the @kbd{p} command, - or click the middle mouse button on the @samp{Prev} link. That - takes you to the @samp{Previous} node. Then use @kbd{n} to return here. +>> But do not type @kbd{n} yet. First, try the @kbd{p} command, or + (in Emacs) click the middle mouse button on the @samp{Prev} link. + That takes you to the @samp{Previous} node. Then use @kbd{n} to + return here. @end format If you read this in Emacs, you will see an @samp{Info} item in the @@ -288,8 +294,8 @@ to. You could make Info skip past an important warning that was coming up. @format ->> Now do an @kbd{n}, or click the middle mouse button on the @samp{Next} - link, to get to the node @samp{Help-^L} and learn more. +>> Now do an @kbd{n}, or (in Emacs) click the middle mouse button on + the @samp{Next} link, to get to the node @samp{Help-^L} and learn more. @end format @node Help-^L, Help-Inv, Help-P, Getting Started diff --git a/man/misc.texi b/man/misc.texi index 83c86a1867a..3c5909a9f56 100644 --- a/man/misc.texi +++ b/man/misc.texi @@ -624,12 +624,6 @@ specifies how to recognize the end of a command. Move backward across one shell command, but not beyond the current line (@code{shell-backward-command}). -@item C-c C-l -@kindex C-c C-l @r{(Shell mode)} -@findex comint-dynamic-list-input-ring -Display the buffer's history of shell commands in another window -(@code{comint-dynamic-list-input-ring}). - @item M-x dirs Ask the shell what its current directory is, so that Emacs can agree with the shell. @@ -740,13 +734,21 @@ Fetch the next later old shell command. @itemx M-s @var{regexp} @key{RET} Search backwards or forwards for old shell commands that match @var{regexp}. -@item C-c C-x @r{(Shell mode)} +@item C-c C-x +@kindex C-c C-x @r{(Shell mode)} @findex comint-get-next-from-history Fetch the next subsequent command from the history. -@item C-c . @r{(Shell mode)} +@item C-c . +@kindex C-c . @r{(Shell mode)} @findex comint-input-previous-argument Fetch one argument from an old shell command. + +@item C-c C-l +@kindex C-c C-l @r{(Shell mode)} +@findex comint-dynamic-list-input-ring +Display the buffer's history of shell commands in another window +(@code{comint-dynamic-list-input-ring}). @end table Shell buffers provide a history of previously entered shell commands. To @@ -815,21 +817,26 @@ Move point to the previous prompt (@code{comint-previous-prompt}). Move point to the following prompt (@code{comint-next-prompt}). @kindex C-c RET @r{(Shell mode)} -@findex comint-copy-old-input +@findex comint-insert-input @item C-c @key{RET} Copy the input command which point is in, inserting the copy at the end -of the buffer (@code{comint-copy-old-input}). This is useful if you +of the buffer (@code{comint-insert-input}). This is useful if you move point back to a previous command. After you copy the command, you can submit the copy as input with @key{RET}. If you wish, you can edit the copy before resubmitting it. + +@item Mouse-2 +Copy the input command that you click on, inserting the copy at the end +of the buffer. @end table Moving to a previous input and then copying it with @kbd{C-c -@key{RET}} produces the same results---the same buffer contents---that -you would get by using @kbd{M-p} enough times to fetch that previous -input from the history list. However, @kbd{C-c @key{RET}} copies the -text from the buffer, which can be different from what is in the history -list if you edit the input text in the buffer after it has been sent. +@key{RET}} or @kbd{Mouse-2} produces the same results---the same +buffer contents---that you would get by using @kbd{M-p} enough times +to fetch that previous input from the history list. However, @kbd{C-c +@key{RET}} copies the text from the buffer, which can be different +from what is in the history list if you edit the input text in the +buffer after it has been sent. @node History References @subsubsection Shell History References diff --git a/man/search.texi b/man/search.texi index fbc8d24bf23..43d6af70cf5 100644 --- a/man/search.texi +++ b/man/search.texi @@ -231,18 +231,18 @@ of bindings, look at the documentation of @code{isearch-mode} with Vertical scrolling during incremental search can be enabled by setting the customizable variable @code{isearch-allow-scroll} to a -non-nil value. +non-@code{nil} value. You can then use the vertical scroll-bar or certain keyboard commands such as @kbd{@key{PRIOR}} (@code{scroll-down}), @kbd{@key{NEXT}} (@code{scroll-up}) and @kbd{C-l} (@code{recenter}) within the search, thus letting you see more of the text near the current match. You must run these commands via their key sequences to -stay in the search - typing M-x @var{comand-name} will always +stay in the search---typing M-x @var{comand-name} will always terminate a search. You can give prefix arguments to these commands in the usual way. -The current match cannot be scrolled out of the window - this is +The current match cannot be scrolled out of the window---this is intentional. Several other commands, such as @kbd{C-x 2} @@ -847,7 +847,7 @@ history matching commands (@pxref{Minibuffer History}). @vindex isearch-allow-scroll Scrolling, etc., during incremental search is enabled by setting the -customizable variable @code{isearch-allow-scroll} to a non-nil value. +customizable variable @code{isearch-allow-scroll} to a non-@code{nil} value. @c See Subject: Info file: How do I get an itemized list without blank lines? @c Date: Sat, 12 Apr 2003 09:45:31 +0000 in gnu.emacs.help @@ -893,7 +893,7 @@ For example: You should only thus configure commands which are ``safe'': i.e., they won't leave emacs in an inconsistent state when executed within a -search - that is to say, the following things may be changed by a +search---that is to say, the following things may be changed by a command only temporarily, and must be restored before the command finishes: @@ -913,7 +913,7 @@ not itself attempt an incremental search. It may, however, change the window's size, or create or delete other windows and frames. Note that an attempt by a command to scroll the text -@emph{horizontally} won't work, although it will do no harm - any such +@emph{horizontally} won't work, although it will do no harm---any such scrolling will be overriden and nullified by the display code. @node Replace, Other Repeating Search, Configuring Scrolling, Search @@ -977,9 +977,9 @@ by word boundaries. The argument's value doesn't matter. What if you want to exchange @samp{x} and @samp{y}: replace every @samp{x} with a @samp{y} and vice versa? You can do it this way: @example -M-x query-replace @key{RET} x @key{RET} @@TEMP@@ @key{RET} -M-x query-replace @key{RET} y @key{RET} x @key{RET} -M-x query-replace @key{RET} @@TEMP@@ @key{RET} y @key{RET} +M-x replace-string @key{RET} x @key{RET} @@TEMP@@ @key{RET} +M-< M-x replace-string @key{RET} y @key{RET} x @key{RET} +M-< M-x replace-string @key{RET} @@TEMP@@ @key{RET} y @key{RET} @end example @noindent @@ -993,13 +993,15 @@ in your text. single string. The similar command @kbd{M-x replace-regexp} replaces any match for a specified pattern. - In @code{replace-regexp}, the @var{newstring} need not be constant: it -can refer to all or part of what is matched by the @var{regexp}. -@samp{\&} in @var{newstring} stands for the entire match being replaced. -@samp{\@var{d}} in @var{newstring}, where @var{d} is a digit, stands for -whatever matched the @var{d}th parenthesized grouping in @var{regexp}. -To include a @samp{\} in the text to replace with, you must enter -@samp{\\}. For example, + In @code{replace-regexp}, the @var{newstring} need not be constant: +it can refer to all or part of what is matched by the @var{regexp}. +@samp{\&} in @var{newstring} stands for the entire match being +replaced. @samp{\@var{d}} in @var{newstring}, where @var{d} is a +digit, stands for whatever matched the @var{d}th parenthesized +grouping in @var{regexp}. @samp{\#} refers to the count of +replacements already made in this command, as a decimal number. In +the first replacement, @samp{\#} stands for @samp{0}; in the second, +for @samp{1}; and so on. For example, @example M-x replace-regexp @key{RET} c[ad]+r @key{RET} \&-safe @key{RET} @@ -1014,7 +1016,61 @@ M-x replace-regexp @key{RET} \(c[ad]+r\)-safe @key{RET} \1 @key{RET} @end example @noindent -performs the inverse transformation. +performs the inverse transformation. To include a @samp{\} in the +text to replace with, you must enter @samp{\\}. + + You can also use Lisp expressions to calculate parts of the +replacement string. To do this, write @samp{\,} followed by the +expression in the replacement string. Each replacement calculates the +value of the expression, which ought to be a string, and uses it in +the replacement string in place of the expression itself. If the +expression is a symbol, one space in the replacement string after the +symbol name counts as part of the symbol name, so the value replaces +them both. + + Inside such an expression, @samp{\&} and @samp{\@var{n}} used as +subexpressions refer respectively to the entire match as a string, and +to a submatch as a string. @var{n} may exceed 9 here, and the value +of @samp{\@var{n}} is @code{nil} if subexpression @var{n} did not +match. You can also use @samp{\#&} and @samp{\#@var{n}} refer to +those matches converted to numbers (this is valid when the match or +submatch has the form of a number). @samp{\#} stands for the number +of already-completed replacements. + + Repeating our example to exchange @samp{x} and @samp{y}, we can thus +do it also this way: + +@example +M-x replace-regexp @key{RET} \(x\)\|y @key{RET} +\,(if \1 "y" "x") @key{RET} +@end example + + The @code{format} function (@pxref{Formatting Strings,,,elisp, GNU +Emacs Lisp Reference Manual}) comes in handy for computing replacement +strings for @samp{\,}. For example, to add consecutively numbered +strings like @samp{ABC00042} to columns 73 @w{to 80} (unless they are +already occupied), you can use + +@example +M-x replace-regexp @key{RET} ^.\@{0,72\@}$ @key{RET} +\,(format "%-72sABC%05d" \& \#) @key{RET} +@end example + + If you want to enter part of the replacement string by hand each +time, use @samp{\?} in the replacement string. Each replacement will +enter a recursive edit, with point at the position where the @samp{\?} +was. For example, + +@example +M-x replace-regexp @key{RET} \footnote@{ @key{RET} +\&\\label@{fn:\#\?@} @key{RET} +@end example + +@noindent +will add labels starting with @samp{\label@{fn:0@}} to occurences of +@samp{\footnote@{}, but letting you edit each replacement before +performing it. To number the labels starting at 1, use @samp{\,(1+ +\#)} instead of @samp{\#}. @node Replacement and Case, Query Replace, Regexp Replace, Replace @subsection Replace Commands and Case @@ -1126,9 +1182,8 @@ to replace all remaining occurrences without asking again. @item ^ to go back to the position of the previous occurrence (or what used to -be an occurrence), in case you changed it by mistake. This works by -popping the mark ring. Only one @kbd{^} in a row is meaningful, because -only one previous replacement position is kept during @code{query-replace}. +be an occurrence), in case you changed it by mistake or want to +reexamine it. @item C-r to enter a recursive editing level, in case the occurrence needs to be diff --git a/man/ses.texi b/man/ses.texi index 8e0086ac54b..b648f6eef9a 100644 --- a/man/ses.texi +++ b/man/ses.texi @@ -251,8 +251,8 @@ one-argument function (a symbol or a lambda), whose result is a string (right-aligned) or list of one string (left-aligned). While typing in a lambda, you can use @kbd{M-TAB} to complete the names of symbols. -Each cell has a printer. If nil, the column-printer for the cell's -column is used. If that is also nil, the default-printer for the +Each cell has a printer. If @code{nil}, the column-printer for the cell's +column is used. If that is also @code{nil}, the default-printer for the spreadsheet is used. @table @kbd @@ -273,7 +273,7 @@ spreadsheet, plus the standard printers. The standard printers are suitable only for cells, not columns or default, because they format the value using the column-printer (or -default-printer if nil) and then center the result: +default-printer if @code{nil}) and then center the result: @table @code @item ses-center @@ -296,7 +296,7 @@ Centering with tildes (~) and spill-over. @node Clearing cells, Copy/cut/paste, Printer functions, The Basics @section Clearing cells -These commands set both formula and printer to nil: +These commands set both formula and printer to @code{nil}: @table @kbd @item DEL @@ -331,7 +331,7 @@ Mark a region and copy it to kill ring and secondary clipboard @item C-w @itemx [cut] @itemx [S-delete] -The cut functions do not actually delete rows or columns - they copy +The cut functions do not actually delete rows or columns---they copy and then clear (@code{ses-kill-override}). @item C-y @@ -537,7 +537,7 @@ are some useful functions to call from your formulas: @table @code @item (ses-delete-blanks &rest @var{args}) -Returns a list from which all blank cells (value is either nil or +Returns a list from which all blank cells (value is either @code{nil} or '*skip*) have been deleted. @item (ses+ &rest @var{args}) @@ -561,10 +561,10 @@ producing a value: the print cell is filled with hash marks (#). @end itemize If the result from the printer function is too wide for the cell and -the following cell is nil, the result will spill over into the +the following cell is @code{nil}, the result will spill over into the following cell. Very wide results can spill over several cells. If the result is too wide for the available space (up to the end of the -row or the next non-nil cell), the result is truncated if the cell's +row or the next non-@code{nil} cell), the result is truncated if the cell's value is a string, or replaced with hash marks otherwise. SES could get confused by printer results that contain newlines or diff --git a/man/trampver.texi b/man/trampver.texi index 4ffc14a48c2..a62583fd6d4 100644 --- a/man/trampver.texi +++ b/man/trampver.texi @@ -4,7 +4,7 @@ @c In the Tramp CVS, the version number is auto-frobbed from @c configure.ac, so you should edit that file and run @c "autoconf && ./configure" to change the version number. -@set trampver 2.0.41 +@set trampver 2.0.42 @c Other flags from configuration @set prefix /usr/local diff --git a/man/viper.texi b/man/viper.texi index 5d4329730dc..654f6c9355f 100644 --- a/man/viper.texi +++ b/man/viper.texi @@ -1312,7 +1312,7 @@ These two keys invoke many important Emacs functions. For example, if you hit @kbd{C-x} followed by @kbd{2}, then the current window will be split into 2. Except for novice users, @kbd{C-c} is also set to execute an Emacs command from the current major mode. @key{ESC} will do the same, if you -configure @key{ESC} as Meta by setting @code{viper-no-multiple-ESC} to nil +configure @key{ESC} as Meta by setting @code{viper-no-multiple-ESC} to @code{nil} in @file{.viper}. @xref{Customization}. @kbd{C-\} in Insert, Replace, or Vi states will make Emacs think @kbd{Meta} has been hit.@refill @item \ @@ -1742,7 +1742,7 @@ executed. Otherwise, it is processed as an ordinary sequence of typed keys. Setting this variable too high may slow down your typing. Setting it too low may make it hard to type macros quickly enough. -@item viper-translate-all-ESC-keysequences t on tty, nil on windowing display +@item viper-translate-all-ESC-keysequences @code{t} on tty, @code{nil} on windowing display Normally, Viper lets Emacs translate only those ESC key sequences that are defined in the low-level key-translation-map or function-key-map, such as those emitted by the arrow and function keys. Other sequences, e.g., @kbd{\\e/}, are @@ -1753,7 +1753,7 @@ The default is to translate all sequences only when using a dumb terminal. This permits you to use @kbd{ESC} as a meta key in insert mode. For instance, hitting @kbd{ESC x} fast would have the effect of typing @kbd{M-x}. If your dumb terminal is not so dumb and understands the meta key, then you -probably will be better off setting this variable to nil. Try and see which +probably will be better off setting this variable to @code{nil}. Try and see which way suits you best. @item viper-ex-style-motion t Set this to @code{nil}, if you want @kbd{l,h} to cross @@ -1764,8 +1764,8 @@ Set this to @code{nil}, if you want at the beginning of a line in Insert state, @key{X} and @key{x} to delete characters across lines in Vi command state, etc. @item viper-ESC-moves-cursor-back t -It t, cursor moves back 1 character when switching from insert state to vi -state. If nil, the cursor stays where it was before the switch. +It @code{t}, cursor moves back 1 character when switching from insert state to vi +state. If @code{nil}, the cursor stays where it was before the switch. @item viper-always t @code{t} means: leave it to Viper to decide when a buffer must be brought up in Vi state, @@ -1873,17 +1873,17 @@ If set to a valid color, this will be the cursor color when Viper is in insert state. @item viper-replace-region-end-delimiter "$" A string used to mark the end of replacement regions. It is used only on -TTYs or if @code{viper-use-replace-region-delimiters} is non-nil. +TTYs or if @code{viper-use-replace-region-delimiters} is non-@code{nil}. @item viper-replace-region-start-delimiter "" A string used to mark the beginning of replacement regions. It is used -only on TTYs or if @code{viper-use-replace-region-delimiters} is non-nil. +only on TTYs or if @code{viper-use-replace-region-delimiters} is non-@code{nil}. @item viper-use-replace-region-delimiters -If non-nil, Viper will always use @code{viper-replace-region-end-delimiter} and +If non-@code{nil}, Viper will always use @code{viper-replace-region-end-delimiter} and @code{viper-replace-region-start-delimiter} to delimit replacement regions, even on color displays (where this is unnecessary). By default, this -variable is non-nil only on TTYs or monochrome displays. +variable is non-@code{nil} only on TTYs or monochrome displays. @item viper-allow-multiline-replace-regions t -If non-nil, multi-line text replacement regions, such as those produced by +If non-@code{nil}, multi-line text replacement regions, such as those produced by commands @kbd{c55w}, @kbd{3C}, etc., will stay around until the user exits the replacement mode. In this variable is set to @code{nil}, Viper will emulate the standard Vi behavior, which supports only intra-line @@ -2390,7 +2390,7 @@ can unbind `/' and `:' in @code{viper-dired-modifier-map} (for Dired) or in To unbind the macros `//' and `///' for a major mode where you feel they are undesirable, execute @code{viper-set-emacs-state-searchstyle-macros} with a -non-nil argument. This can be done either interactively, by supplying a +non-@code{nil} argument. This can be done either interactively, by supplying a prefix argument, or by placing @example (viper-set-emacs-state-searchstyle-macros 'undefine) @@ -3360,7 +3360,7 @@ this function. Find the next bracket/parenthesis/brace and go to its match. By default, Viper ignores brackets/parentheses/braces that occur inside parentheses. You can change this by setting -@code{viper-parse-sexp-ignore-comments} to nil in your @file{.viper} file. +@code{viper-parse-sexp-ignore-comments} to @code{nil} in your @file{.viper} file. This option can also be toggled interactively if you quickly hit @kbd{%%%}. This latter feature is implemented as a vi-style keyboard macro. If you diff --git a/src/ChangeLog b/src/ChangeLog index 00822d9d277..60b8d5da63d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,131 @@ +2004-06-29 YAMAMOTO Mitsuharu + + * macterm.c (do_window_activate, do_window_deactivate): Remove. + (XTread_socket): Send mouse button events to the toolbox + dispatcher even when the mouse is grabbed. Don't process window + activate events for non-Emacs windows. Replace function calls to + do_window_activate and do_window_deactivate with their contents. + Reset mouse grabbing status when a window is deactivated. + +2004-06-29 Steven Tamm + + * macterm.c (mac_get_emulated_btn) + (mac_event_to_emacs_modifiers): Fix emulated mouse button + support to correctly mask out modifiers. + +2004-06-29 David Kastrup + + * search.c (Fset_match_data): Allow buffer before end of list + which can happen if set-match-data is using a pre-consed list. + +2004-06-28 Steven Tamm + + * macterm.c (XTread_socket): Correctly set the frame position + after the window is moved. + +2004-06-28 Jan Dj,Ad(Brv + + * gtkutil.c (xg_get_image_for_pixmap): Call g_object_unref on + gpix and gmask just before return to avoid memory leak. + (xg_get_image_for_pixmap): Add workaround for monochrome displays + so insensitive and activated icons look ok. + +2004-06-27 Jason Rumney + + * w32fns.c (file_dialog_callback): Disable edit control if set + to directories only on CDN_INITDONE message. + (Fx_file_dialog): Default to directories only when prompt starts + with "Dired". + +2004-06-25 Kim F. Storm + + * alloc.c (allocate_misc): Update total_free_markers. + (free_misc): New function. + (safe_alloca_unwind, free_marker): Use it. + + * lisp.h (free_misc): Add prototype. + + * fns.c (Fmapconcat, Fmapcar): Remove superfluous GCPROs. + +2004-06-24 Richard M. Stallman + + * emacs.c (Vsignal_USR1_hook, Vsignal_USR2_hook): Definitions deleted. + (syms_of_emacs): Lisp variables deleted. + +2004-06-23 David Kastrup + + * search.c (Freplace_match): Adjust the match-data more thoroughly + when replacing strings in the buffer. + (Fmatch_data): When INTEGERS is non-nil and the last match was in + a buffer, add the buffer as last element to the match data. + (Fset_match_data): If an additional element of the match-data is a + buffer, restore it to last_thing_searched. + (save_search_regs): Save last_thing_searched as part of the match + data. + (restore_match_data): Restore it again. + +2004-06-23 Luc Teirlinck + + * keymap.c (Ftext_char_description): Doc fix. + * doc.c (Fsnarf_documentation): Doc fix. + +2004-06-22 Kim F. Storm + + * fns.c (Fmapcar, Fmapconcat): GCPRO the args array. + + * lisp.h (struct Lisp_Save_Value): New member dogc. + (SAFE_ALLOCA_LISP): Change second arg to number of elements. + Set dogc member in Lisp_Save_Value object so it will be GC'ed. + (SAFE_FREE_LISP): New macro. + + * alloc.c (safe_alloca_unwind): Clear dogc and pointer members. + (make_save_value): Init new dogc member. + (mark_object): Mark Lisp_Save_Value pointer array if dogc is set. + + * fns.c (Fmapconcat, Fmapcar): Use new SAFE_ALLOCA_LISP and + SAFE_FREE_LISP macros. + +2004-06-22 Kim F. Storm + + * lisp.h (SAFE_ALLOCA_LISP): New macro to allocate Lisp_Objects. + Temporarily inhibits GC if memory is xmalloc'ed, as the Lisp_Objects + in that memory area are unknown to GC. Add comments. + + * fns.c (Fmapconcat, Fmapcar): Use SAFE_ALLOCA_LISP. + +2004-06-21 Kim F. Storm + + * lisp.h (MAX_ALLOCA): Define here. + (safe_alloca_unwind): Add prototype. + (USE_SAFE_ALLOCA, SAFE_ALLOCA, SAFE_FREE): New macros. + + * alloc.c (safe_alloca_unwind): New function. + + * casefiddle.c (casify_object): Use SAFE_ALLOCA. + + * charset.c (Fstring): Use SAFE_ALLOCA. + + * coding.c (MAX_ALLOCA): Remove define. + + * data.c (MAX_ALLOCA): Remove define. + (Faset): Use SAFE_ALLOCA. + + * editfns.c (Fformat, Ftranspose_regions): Use SAFE_ALLOCA. + + * fns.c (string_make_multibyte, string_to_multibyte) + (string_make_unibyte, Fmapconcat, Fmapcar): Use SAFE_ALLOCA. + (MAX_ALLOCA): Remove define. + (Fbase64_encode_region, Fbase64_encode_string) + (Fbase64_decode_region, Fbase64_decode_string): Use SAFE_ALLOCA. + (Fbase64_encode_region, Fbase64_encode_string): Fix potential + memory leak if encoding fails. + + * xdisp.c (add_to_log): Use SAFE_ALLOCA. + +2004-06-21 Eli Zaretskii + + * print.c (Fwith_output_to_temp_buffer): Doc fix. + 2004-06-20 Richard M. Stallman * xfaces.c (Finternal_copy_lisp_face): Small cleanup; doc fix. diff --git a/src/alloc.c b/src/alloc.c index ea7886dd4dc..994dc21079f 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -579,6 +579,22 @@ xstrdup (s) } +/* Unwind for SAFE_ALLOCA */ + +Lisp_Object +safe_alloca_unwind (arg) + Lisp_Object arg; +{ + register struct Lisp_Save_Value *p = XSAVE_VALUE (arg); + + p->dogc = 0; + xfree (p->pointer); + p->pointer = 0; + free_misc (arg); + return Qnil; +} + + /* Like malloc but used for allocating Lisp data. NBYTES is the number of bytes to allocate, TYPE describes the intended use of the allcated memory block (for strings, for conses, ...). */ @@ -2863,17 +2879,32 @@ allocate_misc () marker_block = new; marker_block_index = 0; n_marker_blocks++; + total_free_markers += MARKER_BLOCK_SIZE; } XSETMISC (val, &marker_block->markers[marker_block_index]); marker_block_index++; } + --total_free_markers; consing_since_gc += sizeof (union Lisp_Misc); misc_objects_consed++; XMARKER (val)->gcmarkbit = 0; return val; } +/* Free a Lisp_Misc object */ + +void +free_misc (misc) + Lisp_Object misc; +{ + XMISC (misc)->u_marker.type = Lisp_Misc_Free; + XMISC (misc)->u_free.chain = marker_free_list; + marker_free_list = XMISC (misc); + + total_free_markers++; +} + /* Return a Lisp_Misc_Save_Value object containing POINTER and INTEGER. This is used to package C values to call record_unwind_protect. The unwind function can get the C values back using XSAVE_VALUE. */ @@ -2891,6 +2922,7 @@ make_save_value (pointer, integer) p = XSAVE_VALUE (val); p->pointer = pointer; p->integer = integer; + p->dogc = 0; return val; } @@ -2919,12 +2951,7 @@ free_marker (marker) Lisp_Object marker; { unchain_marker (XMARKER (marker)); - - XMISC (marker)->u_marker.type = Lisp_Misc_Free; - XMISC (marker)->u_free.chain = marker_free_list; - marker_free_list = XMISC (marker); - - total_free_markers++; + free_misc (marker); } @@ -4924,6 +4951,7 @@ mark_object (arg) if (XMARKER (obj)->gcmarkbit) break; XMARKER (obj)->gcmarkbit = 1; + switch (XMISCTYPE (obj)) { case Lisp_Misc_Buffer_Local_Value: @@ -4948,6 +4976,8 @@ mark_object (arg) /* DO NOT mark thru the marker's chain. The buffer's markers chain does not preserve markers from gc; instead, markers are removed from the chain when freed by gc. */ + break; + case Lisp_Misc_Intfwd: case Lisp_Misc_Boolfwd: case Lisp_Misc_Objfwd: @@ -4957,7 +4987,21 @@ mark_object (arg) since all markable slots in current buffer marked anyway. */ /* Don't need to do Lisp_Objfwd, since the places they point are protected with staticpro. */ + break; + case Lisp_Misc_Save_Value: + { + register struct Lisp_Save_Value *ptr = XSAVE_VALUE (obj); + /* If DOGC is set, POINTER is the address of a memory + area containing INTEGER potential Lisp_Objects. */ + if (ptr->dogc) + { + Lisp_Object *p = (Lisp_Object *) ptr->pointer; + int nelt; + for (nelt = ptr->integer; nelt > 0; nelt--, p++) + mark_maybe_object (*p); + } + } break; case Lisp_Misc_Overlay: diff --git a/src/data.c b/src/data.c index 935c4348bb7..1071107947c 100644 --- a/src/data.c +++ b/src/data.c @@ -1983,11 +1983,6 @@ or a byte-code object. IDX starts at 0. */) } } -/* Don't use alloca for relocating string data larger than this, lest - we overflow their stack. The value is the same as what used in - fns.c for base64 handling. */ -#define MAX_ALLOCA 16*1024 - DEFUN ("aset", Faset, Saset, 3, 3, 0, doc: /* Store into the element of ARRAY at index IDX the value NEWELT. Return NEWELT. ARRAY may be a vector, a string, a char-table or a @@ -2051,10 +2046,9 @@ bool-vector. IDX starts at 0. */) /* We must relocate the string data. */ int nchars = SCHARS (array); unsigned char *str; + USE_SAFE_ALLOCA; - str = (nbytes <= MAX_ALLOCA - ? (unsigned char *) alloca (nbytes) - : (unsigned char *) xmalloc (nbytes)); + SAFE_ALLOCA (str, unsigned char *, nbytes); bcopy (SDATA (array), str, nbytes); allocate_string_data (XSTRING (array), nchars, nbytes + new_bytes - prev_bytes); @@ -2062,8 +2056,7 @@ bool-vector. IDX starts at 0. */) p1 = SDATA (array) + idxval_byte; bcopy (str + idxval_byte + prev_bytes, p1 + new_bytes, nbytes - (idxval_byte + prev_bytes)); - if (nbytes > MAX_ALLOCA) - xfree (str); + SAFE_FREE (nbytes); clear_string_char_byte_cache (); } while (new_bytes--) @@ -2086,14 +2079,13 @@ bool-vector. IDX starts at 0. */) unsigned char workbuf[MAX_MULTIBYTE_LENGTH], *p0 = workbuf, *p1; unsigned char *origstr = SDATA (array), *str; int nchars, nbytes; + USE_SAFE_ALLOCA; nchars = SCHARS (array); nbytes = idxval_byte = count_size_as_multibyte (origstr, idxval); nbytes += count_size_as_multibyte (origstr + idxval, nchars - idxval); - str = (nbytes <= MAX_ALLOCA - ? (unsigned char *) alloca (nbytes) - : (unsigned char *) xmalloc (nbytes)); + SAFE_ALLOCA (str, unsigned char *, nbytes); copy_text (SDATA (array), str, nchars, 0, 1); PARSE_MULTIBYTE_SEQ (str + idxval_byte, nbytes - idxval_byte, prev_bytes); @@ -2106,8 +2098,7 @@ bool-vector. IDX starts at 0. */) *p1++ = *p0++; bcopy (str + idxval_byte + prev_bytes, p1, nbytes - (idxval_byte + prev_bytes)); - if (nbytes > MAX_ALLOCA) - xfree (str); + SAFE_FREE (nbytes); clear_string_char_byte_cache (); } } diff --git a/src/doc.c b/src/doc.c index 2e66c5cea46..8c116210cda 100644 --- a/src/doc.c +++ b/src/doc.c @@ -570,7 +570,7 @@ records them in function and variable definitions. The function takes one argument, FILENAME, a string; it specifies the file name (without a directory) of the DOC file. That file is found in `../etc' now; later, when the dumped Emacs is run, -the same file name is found in the `data-directory'. */) +the same file name is found in the `doc-directory'. */) (filename) Lisp_Object filename; { diff --git a/src/editfns.c b/src/editfns.c index 130dffa77de..9928beff678 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -3381,6 +3381,7 @@ usage: (format STRING &rest OBJECTS) */) int longest_format; Lisp_Object val; int arg_intervals = 0; + USE_SAFE_ALLOCA; /* discarded[I] is 1 if byte I of the format string was not copied into the output. @@ -3429,7 +3430,7 @@ usage: (format STRING &rest OBJECTS) */) longest_format = 0; /* Make room in result for all the non-%-codes in the control string. */ - total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]); + total = 5 + CONVERTED_BYTE_SIZE (multibyte, args[0]) + 1; /* Allocate the info and discarded tables. */ { @@ -3622,10 +3623,7 @@ usage: (format STRING &rest OBJECTS) */) /* Allocate the space for the result. Note that TOTAL is an overestimate. */ - if (total < 1000) - buf = (char *) alloca (total + 1); - else - buf = (char *) xmalloc (total + 1); + SAFE_ALLOCA (buf, char *, total); p = buf; nchars = 0; @@ -3758,7 +3756,7 @@ usage: (format STRING &rest OBJECTS) */) maybe_combine_byte = 1; this_nchars = strlen (p); if (multibyte) - p += str_to_multibyte (p, buf + total - p, this_nchars); + p += str_to_multibyte (p, buf + total - 1 - p, this_nchars); else p += this_nchars; nchars += this_nchars; @@ -3795,7 +3793,7 @@ usage: (format STRING &rest OBJECTS) */) *p++ = *format++, nchars++; } - if (p > buf + total + 1) + if (p > buf + total) abort (); if (maybe_combine_byte) @@ -3803,8 +3801,7 @@ usage: (format STRING &rest OBJECTS) */) val = make_specified_string (buf, nchars, p - buf, multibyte); /* If we allocated BUF with malloc, free it too. */ - if (total >= 1000) - xfree (buf); + SAFE_FREE (total); /* If the format string has text properties, or any of the string arguments has text properties, set up text properties of the @@ -4173,12 +4170,9 @@ Transposing beyond buffer boundaries is an error. */) /* First region smaller than second. */ if (len1_byte < len2_byte) { - /* We use alloca only if it is small, - because we want to avoid stack overflow. */ - if (len2_byte > 20000) - temp = (unsigned char *) xmalloc (len2_byte); - else - temp = (unsigned char *) alloca (len2_byte); + USE_SAFE_ALLOCA; + + SAFE_ALLOCA (temp, unsigned char *, len2_byte); /* Don't precompute these addresses. We have to compute them at the last minute, because the relocating allocator might @@ -4189,23 +4183,20 @@ Transposing beyond buffer boundaries is an error. */) bcopy (start2_addr, temp, len2_byte); bcopy (start1_addr, start1_addr + len2_byte, len1_byte); bcopy (temp, start1_addr, len2_byte); - if (len2_byte > 20000) - xfree (temp); + SAFE_FREE (len2_byte); } else /* First region not smaller than second. */ { - if (len1_byte > 20000) - temp = (unsigned char *) xmalloc (len1_byte); - else - temp = (unsigned char *) alloca (len1_byte); + USE_SAFE_ALLOCA; + + SAFE_ALLOCA (temp, unsigned char *, len1_byte); start1_addr = BYTE_POS_ADDR (start1_byte); start2_addr = BYTE_POS_ADDR (start2_byte); bcopy (start1_addr, temp, len1_byte); bcopy (start2_addr, start1_addr, len2_byte); bcopy (temp, start1_addr + len2_byte, len1_byte); - if (len1_byte > 20000) - xfree (temp); + SAFE_FREE (len1_byte); } graft_intervals_into_buffer (tmp_interval1, start1 + len2, len1, current_buffer, 0); @@ -4222,6 +4213,8 @@ Transposing beyond buffer boundaries is an error. */) if (len1_byte == len2_byte) /* Regions are same size, though, how nice. */ { + USE_SAFE_ALLOCA; + modify_region (current_buffer, start1, end1); modify_region (current_buffer, start2, end2); record_change (start1, len1); @@ -4233,17 +4226,14 @@ Transposing beyond buffer boundaries is an error. */) Fset_text_properties (make_number (start2), make_number (end2), Qnil, Qnil); - if (len1_byte > 20000) - temp = (unsigned char *) xmalloc (len1_byte); - else - temp = (unsigned char *) alloca (len1_byte); + SAFE_ALLOCA (temp, unsigned char *, len1_byte); start1_addr = BYTE_POS_ADDR (start1_byte); start2_addr = BYTE_POS_ADDR (start2_byte); bcopy (start1_addr, temp, len1_byte); bcopy (start2_addr, start1_addr, len2_byte); bcopy (temp, start2_addr, len1_byte); - if (len1_byte > 20000) - xfree (temp); + SAFE_FREE (len1_byte); + graft_intervals_into_buffer (tmp_interval1, start2, len1, current_buffer, 0); graft_intervals_into_buffer (tmp_interval2, start1, @@ -4253,6 +4243,8 @@ Transposing beyond buffer boundaries is an error. */) else if (len1_byte < len2_byte) /* Second region larger than first */ /* Non-adjacent & unequal size, area between must also be shifted. */ { + USE_SAFE_ALLOCA; + modify_region (current_buffer, start1, end2); record_change (start1, (end2 - start1)); tmp_interval1 = copy_intervals (cur_intv, start1, len1); @@ -4262,18 +4254,15 @@ Transposing beyond buffer boundaries is an error. */) Qnil, Qnil); /* holds region 2 */ - if (len2_byte > 20000) - temp = (unsigned char *) xmalloc (len2_byte); - else - temp = (unsigned char *) alloca (len2_byte); + SAFE_ALLOCA (temp, unsigned char *, len2_byte); start1_addr = BYTE_POS_ADDR (start1_byte); start2_addr = BYTE_POS_ADDR (start2_byte); bcopy (start2_addr, temp, len2_byte); bcopy (start1_addr, start1_addr + len_mid + len2_byte, len1_byte); safe_bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid); bcopy (temp, start1_addr, len2_byte); - if (len2_byte > 20000) - xfree (temp); + SAFE_FREE (len2_byte); + graft_intervals_into_buffer (tmp_interval1, end2 - len1, len1, current_buffer, 0); graft_intervals_into_buffer (tmp_interval_mid, start1 + len2, @@ -4284,6 +4273,8 @@ Transposing beyond buffer boundaries is an error. */) else /* Second region smaller than first. */ { + USE_SAFE_ALLOCA; + record_change (start1, (end2 - start1)); modify_region (current_buffer, start1, end2); @@ -4294,18 +4285,15 @@ Transposing beyond buffer boundaries is an error. */) Qnil, Qnil); /* holds region 1 */ - if (len1_byte > 20000) - temp = (unsigned char *) xmalloc (len1_byte); - else - temp = (unsigned char *) alloca (len1_byte); + SAFE_ALLOCA (temp, unsigned char *, len1_byte); start1_addr = BYTE_POS_ADDR (start1_byte); start2_addr = BYTE_POS_ADDR (start2_byte); bcopy (start1_addr, temp, len1_byte); bcopy (start2_addr, start1_addr, len2_byte); bcopy (start1_addr + len1_byte, start1_addr + len2_byte, len_mid); bcopy (temp, start1_addr + len2_byte + len_mid, len1_byte); - if (len1_byte > 20000) - xfree (temp); + SAFE_FREE (len1_byte); + graft_intervals_into_buffer (tmp_interval1, end2 - len1, len1, current_buffer, 0); graft_intervals_into_buffer (tmp_interval_mid, start1 + len2, diff --git a/src/emacs.c b/src/emacs.c index d348eb86d29..5b7394627ef 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -126,14 +126,6 @@ Lisp_Object Vkill_emacs_hook; /* An empty lisp string. To avoid having to build any other. */ Lisp_Object empty_string; -#ifdef SIGUSR1 -/* Hooks for signal USR1 and USR2 handling. */ -Lisp_Object Vsignal_USR1_hook; -#ifdef SIGUSR2 -Lisp_Object Vsignal_USR2_hook; -#endif -#endif - /* Search path separator. */ Lisp_Object Vpath_separator; @@ -2379,18 +2371,6 @@ The hook is not run in batch mode, i.e., if `noninteractive' is non-nil. */); empty_string = build_string (""); staticpro (&empty_string); -#ifdef SIGUSR1 - DEFVAR_LISP ("signal-USR1-hook", &Vsignal_USR1_hook, - doc: /* Hook to be run whenever emacs receives a USR1 signal. */); - Vsignal_USR1_hook = Qnil; -#ifdef SIGUSR2 - DEFVAR_LISP ("signal-USR2-hook", &Vsignal_USR2_hook, - doc: /* Hook to be run whenever emacs receives a USR2 signal. */); - Vsignal_USR2_hook = Qnil; -#endif -#endif - - DEFVAR_INT ("emacs-priority", &emacs_priority, doc: /* Priority for Emacs to run at. This value is effective only if set before Emacs is dumped, diff --git a/src/fns.c b/src/fns.c index 5e20687494c..2058fb63a4e 100644 --- a/src/fns.c +++ b/src/fns.c @@ -929,11 +929,14 @@ string_make_multibyte (string) if (nbytes == SBYTES (string)) return string; - buf = (unsigned char *) alloca (nbytes); + SAFE_ALLOCA (buf, unsigned char *, nbytes); copy_text (SDATA (string), buf, SBYTES (string), 0, 1); - return make_multibyte_string (buf, SCHARS (string), nbytes); + ret = make_multibyte_string (buf, SCHARS (string), nbytes); + SAFE_FREE (nbytes); + + return ret; } @@ -947,6 +950,8 @@ string_to_multibyte (string) { unsigned char *buf; int nbytes; + Lisp_Object ret; + USE_SAFE_ALLOCA; if (STRING_MULTIBYTE (string)) return string; @@ -957,11 +962,14 @@ string_to_multibyte (string) if (nbytes == SBYTES (string)) return make_multibyte_string (SDATA (string), nbytes, nbytes); - buf = (unsigned char *) alloca (nbytes); + SAFE_ALLOCA (buf, unsigned char *, nbytes); bcopy (SDATA (string), buf, SBYTES (string)); str_to_multibyte (buf, nbytes, SBYTES (string)); - return make_multibyte_string (buf, SCHARS (string), nbytes); + ret = make_multibyte_string (buf, SCHARS (string), nbytes); + SAFE_FREE (nbytes); + + return ret; } @@ -971,23 +979,22 @@ Lisp_Object string_make_unibyte (string) Lisp_Object string; { + int nchars; unsigned char *buf; Lisp_Object ret; + USE_SAFE_ALLOCA; if (! STRING_MULTIBYTE (string)) return string; - /* We can not use alloca here, because string might be very long. - For example when selecting megabytes of text and then pasting it to - another application. */ - buf = (unsigned char *) xmalloc (SCHARS (string)); + nchars = SCHARS (string); + SAFE_ALLOCA (buf, unsigned char *, nchars); copy_text (SDATA (string), buf, SBYTES (string), 1, 0); - ret = make_unibyte_string (buf, SCHARS (string)); - - xfree (buf); + ret = make_unibyte_string (buf, nchars); + SAFE_FREE (nchars); return ret; } @@ -2455,6 +2462,8 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string. */) register Lisp_Object *args; register int i; struct gcpro gcpro1; + Lisp_Object ret; + USE_SAFE_ALLOCA; len = Flength (sequence); if (CHAR_TABLE_P (sequence)) @@ -2463,7 +2472,7 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string. */) nargs = leni + leni - 1; if (nargs < 0) return build_string (""); - args = (Lisp_Object *) alloca (nargs * sizeof (Lisp_Object)); + SAFE_ALLOCA_LISP (args, nargs); GCPRO1 (separator); mapcar1 (leni, args, function, sequence); @@ -2475,7 +2484,10 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string. */) for (i = 1; i < nargs; i += 2) args[i] = separator; - return Fconcat (nargs, args); + ret = Fconcat (nargs, args); + SAFE_FREE_LISP (nargs); + + return ret; } DEFUN ("mapcar", Fmapcar, Smapcar, 2, 2, 0, @@ -2488,16 +2500,22 @@ SEQUENCE may be a list, a vector, a bool-vector, or a string. */) register Lisp_Object len; register int leni; register Lisp_Object *args; + Lisp_Object ret; + USE_SAFE_ALLOCA; len = Flength (sequence); if (CHAR_TABLE_P (sequence)) wrong_type_argument (Qlistp, sequence); leni = XFASTINT (len); - args = (Lisp_Object *) alloca (leni * sizeof (Lisp_Object)); + + SAFE_ALLOCA_LISP (args, leni); mapcar1 (leni, args, function, sequence); - return Flist (leni, args); + ret = Flist (leni, args); + SAFE_FREE_LISP (leni); + + return ret; } DEFUN ("mapc", Fmapc, Smapc, 2, 2, 0, @@ -3114,10 +3132,6 @@ The data read from the system are decoded using `locale-coding-system'. */) } \ while (IS_BASE64_IGNORABLE (c)) -/* Don't use alloca for regions larger than this, lest we overflow - their stack. */ -#define MAX_ALLOCA 16*1024 - /* Table of characters coding the 64 values. */ static char base64_value_to_char[64] = { @@ -3183,6 +3197,7 @@ into shorter lines. */) int allength, length; int ibeg, iend, encoded_length; int old_pos = PT; + USE_SAFE_ALLOCA; validate_region (&beg, &end); @@ -3197,10 +3212,7 @@ into shorter lines. */) allength = length + length/3 + 1; allength += allength / MIME_LINE_LENGTH + 1 + 6; - if (allength <= MAX_ALLOCA) - encoded = (char *) alloca (allength); - else - encoded = (char *) xmalloc (allength); + SAFE_ALLOCA (encoded, char *, allength); encoded_length = base64_encode_1 (BYTE_POS_ADDR (ibeg), encoded, length, NILP (no_line_break), !NILP (current_buffer->enable_multibyte_characters)); @@ -3210,8 +3222,7 @@ into shorter lines. */) if (encoded_length < 0) { /* The encoding wasn't possible. */ - if (length > MAX_ALLOCA) - xfree (encoded); + SAFE_FREE (allength); error ("Multibyte character in data for base64 encoding"); } @@ -3219,8 +3230,7 @@ into shorter lines. */) and delete the old. (Insert first in order to preserve markers.) */ SET_PT_BOTH (XFASTINT (beg), ibeg); insert (encoded, encoded_length); - if (allength > MAX_ALLOCA) - xfree (encoded); + SAFE_FREE (allength); del_range_byte (ibeg + encoded_length, iend + encoded_length, 1); /* If point was outside of the region, restore it exactly; else just @@ -3246,6 +3256,7 @@ into shorter lines. */) int allength, length, encoded_length; char *encoded; Lisp_Object encoded_string; + USE_SAFE_ALLOCA; CHECK_STRING (string); @@ -3257,10 +3268,7 @@ into shorter lines. */) allength += allength / MIME_LINE_LENGTH + 1 + 6; /* We need to allocate enough room for decoding the text. */ - if (allength <= MAX_ALLOCA) - encoded = (char *) alloca (allength); - else - encoded = (char *) xmalloc (allength); + SAFE_ALLOCA (encoded, char *, allength); encoded_length = base64_encode_1 (SDATA (string), encoded, length, NILP (no_line_break), @@ -3271,14 +3279,12 @@ into shorter lines. */) if (encoded_length < 0) { /* The encoding wasn't possible. */ - if (length > MAX_ALLOCA) - xfree (encoded); + SAFE_FREE (allength); error ("Multibyte character in data for base64 encoding"); } encoded_string = make_unibyte_string (encoded, encoded_length); - if (allength > MAX_ALLOCA) - xfree (encoded); + SAFE_FREE (allength); return encoded_string; } @@ -3397,6 +3403,7 @@ If the region can't be decoded, signal an error and don't modify the buffer. */ int decoded_length; int inserted_chars; int multibyte = !NILP (current_buffer->enable_multibyte_characters); + USE_SAFE_ALLOCA; validate_region (&beg, &end); @@ -3409,10 +3416,7 @@ If the region can't be decoded, signal an error and don't modify the buffer. */ working on a multibyte buffer, each decoded code may occupy at most two bytes. */ allength = multibyte ? length * 2 : length; - if (allength <= MAX_ALLOCA) - decoded = (char *) alloca (allength); - else - decoded = (char *) xmalloc (allength); + SAFE_ALLOCA (decoded, char *, allength); move_gap_both (XFASTINT (beg), ibeg); decoded_length = base64_decode_1 (BYTE_POS_ADDR (ibeg), decoded, length, @@ -3423,8 +3427,7 @@ If the region can't be decoded, signal an error and don't modify the buffer. */ if (decoded_length < 0) { /* The decoding wasn't possible. */ - if (allength > MAX_ALLOCA) - xfree (decoded); + SAFE_FREE (allength); error ("Invalid base64 data"); } @@ -3432,8 +3435,8 @@ If the region can't be decoded, signal an error and don't modify the buffer. */ and delete the old. (Insert first in order to preserve markers.) */ TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg); insert_1_both (decoded, inserted_chars, decoded_length, 0, 1, 0); - if (allength > MAX_ALLOCA) - xfree (decoded); + SAFE_FREE (allength); + /* Delete the original text. */ del_range_both (PT, PT_BYTE, XFASTINT (end) + inserted_chars, iend + decoded_length, 1); @@ -3458,15 +3461,13 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string, char *decoded; int length, decoded_length; Lisp_Object decoded_string; + USE_SAFE_ALLOCA; CHECK_STRING (string); length = SBYTES (string); /* We need to allocate enough room for decoding the text. */ - if (length <= MAX_ALLOCA) - decoded = (char *) alloca (length); - else - decoded = (char *) xmalloc (length); + SAFE_ALLOCA (decoded, char *, length); /* The decoded result should be unibyte. */ decoded_length = base64_decode_1 (SDATA (string), decoded, length, @@ -3478,8 +3479,7 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string, else decoded_string = Qnil; - if (length > MAX_ALLOCA) - xfree (decoded); + SAFE_FREE (length); if (!STRINGP (decoded_string)) error ("Invalid base64 data"); diff --git a/src/gtkutil.c b/src/gtkutil.c index 84aa9f46d4d..3ffba0ba745 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c @@ -248,8 +248,46 @@ xg_get_image_for_pixmap (f, img, widget, old_widget) { GdkPixmap *gpix; GdkPixmap *gmask; - GdkDisplay *gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); + GdkDisplay *gdpy; + /* If we are on a one bit display, let GTK do all the image handling. + This seems to be the only way to make insensitive and activated icons + look good. */ + if (x_screen_planes (f) == 1) + { + Lisp_Object specified_file = Qnil; + Lisp_Object tail; + extern Lisp_Object QCfile; + + for (tail = XCDR (img->spec); + NILP (specified_file) && CONSP (tail) && CONSP (XCDR (tail)); + tail = XCDR (XCDR (tail))) + if (EQ (XCAR (tail), QCfile)) + specified_file = XCAR (XCDR (tail)); + + if (STRINGP (specified_file)) + { + + Lisp_Object file = Qnil; + struct gcpro gcpro1; + GCPRO1 (file); + + file = x_find_image_file (specified_file); + /* We already loaded the image once before calling this + function, so this should not fail. */ + xassert (STRINGP (file) != 0); + + if (! old_widget) + old_widget = GTK_IMAGE (gtk_image_new_from_file (SDATA (file))); + else + gtk_image_set_from_file (old_widget, SDATA (file)); + + UNGCPRO; + return GTK_WIDGET (old_widget); + } + } + + gdpy = gdk_x11_lookup_xdisplay (FRAME_X_DISPLAY (f)); gpix = gdk_pixmap_foreign_new_for_display (gdpy, img->pixmap); gmask = img->mask ? gdk_pixmap_foreign_new_for_display (gdpy, img->mask) : 0; @@ -262,6 +300,12 @@ xg_get_image_for_pixmap (f, img, widget, old_widget) } else { + /* This is a workaround to make icons look good on pseudo color + displays. Apparently GTK expects the images to have an alpha + channel. If they don't, insensitive and activated icons will + look bad. This workaround does not work on monochrome displays, + and is not needed on true color/static color displays (i.e. + 16 bits and higher). */ int x, y, width, height, rowstride, mask_rowstride; GdkPixbuf *icon_buf, *tmp_buf; guchar *pixels; @@ -308,12 +352,9 @@ xg_get_image_for_pixmap (f, img, widget, old_widget) } } - g_object_unref (G_OBJECT (gmask)); g_object_unref (G_OBJECT (mask_buf)); } - g_object_unref (G_OBJECT (gpix)); - if (! old_widget) old_widget = GTK_IMAGE (gtk_image_new_from_pixbuf (icon_buf)); else @@ -322,6 +363,9 @@ xg_get_image_for_pixmap (f, img, widget, old_widget) g_object_unref (G_OBJECT (icon_buf)); } + g_object_unref (G_OBJECT (gpix)); + if (gmask) g_object_unref (G_OBJECT (gmask)); + return GTK_WIDGET (old_widget); } diff --git a/src/keymap.c b/src/keymap.c index fbf1263a71b..4c23977ef41 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -2273,7 +2273,11 @@ push_text_char_description (c, p) DEFUN ("text-char-description", Ftext_char_description, Stext_char_description, 1, 1, 0, doc: /* Return a pretty description of file-character CHARACTER. -Control characters turn into "^char", etc. */) +Control characters turn into "^char", etc. This differs from +`single-key-description' which turns them into "C-char". +Also, this function recognizes the 2**7 bit as the Meta character, +whereas `single-key-description' uses the 2**27 bit for Meta. +See Info node `(elisp)Describing Characters' for examples. */) (character) Lisp_Object character; { diff --git a/src/lisp.h b/src/lisp.h index 7e39313a7fc..aba3073dc68 100644 --- a/src/lisp.h +++ b/src/lisp.h @@ -1203,7 +1203,10 @@ struct Lisp_Save_Value { int type : 16; /* = Lisp_Misc_Save_Value */ unsigned gcmarkbit : 1; - int spacer : 15; + int spacer : 14; + /* If DOGC is set, POINTER is the address of a memory + area containing INTEGER potential Lisp_Objects. */ + unsigned int dogc : 1; void *pointer; int integer; }; @@ -2498,6 +2501,7 @@ extern Lisp_Object make_float P_ ((double)); extern void display_malloc_warning P_ ((void)); extern int inhibit_garbage_collection P_ ((void)); extern Lisp_Object make_save_value P_ ((void *, int)); +extern void free_misc P_ ((Lisp_Object)); extern void free_marker P_ ((Lisp_Object)); extern void free_cons P_ ((struct Lisp_Cons *)); extern void init_alloc_once P_ ((void)); @@ -3290,6 +3294,64 @@ extern Lisp_Object Vdirectory_sep_char; : Fcons ((el), (check))))) +/* SAFE_ALLOCA normally allocates memory on the stack, but if size is + larger than MAX_ALLOCA, use xmalloc to avoid overflowing the stack. */ + +#define MAX_ALLOCA 16*1024 + +extern Lisp_Object safe_alloca_unwind (Lisp_Object); + +#define USE_SAFE_ALLOCA \ + int sa_count = SPECPDL_INDEX () + +/* SAFE_ALLOCA allocates a simple buffer. */ + +#define SAFE_ALLOCA(buf, type, size) \ + do { \ + if ((size) < MAX_ALLOCA) \ + buf = (type) alloca (size); \ + else \ + { \ + buf = (type) xmalloc (size); \ + record_unwind_protect (safe_alloca_unwind, \ + make_save_value (buf, 0)); \ + } \ + } while (0) + +/* SAFE_FREE frees xmalloced memory and enables GC as needed. */ + +#define SAFE_FREE(size) \ + do { \ + if ((size) >= MAX_ALLOCA) \ + unbind_to (sa_count, Qnil); \ + } while (0) + + +/* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects. */ + +#define SAFE_ALLOCA_LISP(buf, nelt) \ + do { \ + int size_ = (nelt) * sizeof (Lisp_Object); \ + if (size_ < MAX_ALLOCA) \ + buf = (Lisp_Object *) alloca (size_); \ + else \ + { \ + Lisp_Object arg_; \ + buf = (Lisp_Object *) xmalloc (size_); \ + arg_ = make_save_value (buf, nelt); \ + XSAVE_VALUE (arg_)->dogc = 1; \ + record_unwind_protect (safe_alloca_unwind, arg_); \ + } \ + } while (0) + +#define SAFE_FREE_LISP(nelt) \ + do { \ + if (((nelt) * sizeof (Lisp_Object)) >= MAX_ALLOCA) \ + unbind_to (sa_count, Qnil); \ + } while (0) + + + #endif /* EMACS_LISP_H */ /* arch-tag: 9b2ed020-70eb-47ac-94ee-e1c2a5107d5e diff --git a/src/macterm.c b/src/macterm.c index 360dccd4f16..04d6ec3be64 100644 --- a/src/macterm.c +++ b/src/macterm.c @@ -7018,7 +7018,7 @@ mac_get_emulated_btn ( UInt32 modifiers ) int result = 0; if (!NILP (Vmac_emulate_three_button_mouse)) { int cmdIs3 = !EQ (Vmac_emulate_three_button_mouse, Qreverse); - if (modifiers & controlKey) + if (modifiers & cmdKey) result = cmdIs3 ? 2 : 1; else if (modifiers & optionKey) result = cmdIs3 ? 1 : 2; @@ -7038,7 +7038,7 @@ mac_event_to_emacs_modifiers (EventRef eventRef) if (!NILP (Vmac_emulate_three_button_mouse) && GetEventClass(eventRef) == kEventClassMouse) { - mods &= ~(optionKey & cmdKey); + mods &= ~(optionKey | cmdKey); } return mac_to_emacs_modifiers (mods); } @@ -7236,40 +7236,6 @@ is_emacs_window (WindowPtr win) return 0; } -static void -do_window_activate (WindowPtr win) -{ - struct frame *f; - - if (is_emacs_window (win)) - { - f = mac_window_to_frame (win); - - if (f) - { - x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f), f); - activate_scroll_bars (f); - } - } -} - -static void -do_window_deactivate (WindowPtr win) -{ - struct frame *f; - - if (is_emacs_window (win)) - { - f = mac_window_to_frame (win); - - if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame) - { - x_new_focus_frame (FRAME_MAC_DISPLAY_INFO (f), 0); - deactivate_scroll_bars (f); - } - } -} - static void do_app_resume () { @@ -8084,6 +8050,25 @@ XTread_socket (sd, expected, hold_quit) if (!mac_convert_event_ref (eventRef, &er)) switch (GetEventClass (eventRef)) { + case kEventClassWindow: + if (GetEventKind (eventRef) == kEventWindowBoundsChanged) + { + WindowPtr window_ptr; + GetEventParameter(eventRef, kEventParamDirectObject, + typeWindowRef, NULL, sizeof(WindowPtr), + NULL, &window_ptr); + f = mac_window_to_frame (window_ptr); + if (f && !f->async_iconified) + { + int x, y; + + x_real_positions (f, &x, &y); + f->left_pos = x; + f->top_pos = y; + } + SendEventToEventTarget (eventRef, toolbox_dispatcher); + } + break; case kEventClassMouse: if (GetEventKind (eventRef) == kEventMouseWheelMoved) { @@ -8135,6 +8120,14 @@ XTread_socket (sd, expected, hold_quit) SInt16 part_code; int tool_bar_p = 0; +#if USE_CARBON_EVENTS + /* This is needed to send mouse events like aqua window + buttons to the correct handler. */ + if (SendEventToEventTarget (eventRef, toolbox_dispatcher) + != eventNotHandledErr) + break; +#endif + if (dpyinfo->grabbed && last_mouse_frame && FRAME_LIVE_P (last_mouse_frame)) { @@ -8150,16 +8143,9 @@ XTread_socket (sd, expected, hold_quit) window_ptr = FrontWindow (); } -#if USE_CARBON_EVENTS - /* This is needed to send mouse events like aqua - window buttons to the correct handler. */ - if (SendEventToEventTarget (eventRef, toolbox_dispatcher) - != eventNotHandledErr) - break; - if (!is_emacs_window (window_ptr)) break; -#endif + part_code = FindWindow (er.where, &window_ptr); } @@ -8306,6 +8292,18 @@ XTread_socket (sd, expected, hold_quit) #else /* not TARGET_API_MAC_CARBON */ DragWindow (window_ptr, er.where, &qd.screenBits.bounds); #endif /* not TARGET_API_MAC_CARBON */ + /* Update the frame parameters. */ + { + struct frame *f = mac_window_to_frame (window_ptr); + if (f && !f->async_iconified) + { + int x, y; + + x_real_positions (f, &x, &y); + f->left_pos = x; + f->top_pos = y; + } + } break; case inGoAway: @@ -8393,24 +8391,38 @@ XTread_socket (sd, expected, hold_quit) break; } + if (!is_emacs_window (window_ptr)) + break; + + f = mac_window_to_frame (window_ptr); + if ((er.modifiers & activeFlag) != 0) { + /* A window has been activated */ Point mouse_loc = er.where; - do_window_activate (window_ptr); + x_new_focus_frame (dpyinfo, f); + activate_scroll_bars (f); SetPortWindowPort (window_ptr); GlobalToLocal (&mouse_loc); - /* activateEvt counts as mouse movement, + /* Window-activated event counts as mouse movement, so update things that depend on mouse position. */ note_mouse_movement (mac_window_to_frame (window_ptr), &mouse_loc); } else { - do_window_deactivate (window_ptr); + /* A window has been deactivated */ + dpyinfo->grabbed = 0; + + if (f == dpyinfo->x_focus_frame) + { + x_new_focus_frame (dpyinfo, 0); + deactivate_scroll_bars (f); + } + - f = mac_window_to_frame (window_ptr); if (f == dpyinfo->mouse_face_mouse_frame) { /* If we move outside the frame, then we're diff --git a/src/print.c b/src/print.c index 4b94d77e876..287e77edad1 100644 --- a/src/print.c +++ b/src/print.c @@ -658,7 +658,7 @@ If variable `temp-buffer-show-function' is non-nil, call it at the end to get the buffer displayed instead of just displaying the non-selected buffer and calling the hook. It gets one argument, the buffer to display. -usage: (with-output-to-temp-buffer BUFFNAME BODY ...) */) +usage: (with-output-to-temp-buffer BUFNAME BODY ...) */) (args) Lisp_Object args; { diff --git a/src/search.c b/src/search.c index eba74f418ce..bb3f222e2c1 100644 --- a/src/search.c +++ b/src/search.c @@ -2543,15 +2543,20 @@ since only regular expressions have distinguished subexpressions. */) /* Adjust search data for this change. */ { int oldend = search_regs.end[sub]; + int oldstart = search_regs.start[sub]; int change = newpoint - search_regs.end[sub]; int i; for (i = 0; i < search_regs.num_regs; i++) { - if (search_regs.start[i] > oldend) + if (search_regs.start[i] >= oldend) search_regs.start[i] += change; - if (search_regs.end[i] > oldend) + else if (search_regs.start[i] > oldstart) + search_regs.start[i] = oldstart; + if (search_regs.end[i] >= oldend) search_regs.end[i] += change; + else if (search_regs.end[i] > oldstart) + search_regs.end[i] = oldstart; } } @@ -2620,8 +2625,11 @@ All the elements are markers or nil (nil if the Nth pair didn't match) if the last match was on a buffer; integers or nil if a string was matched. Use `store-match-data' to reinstate the data in this list. -If INTEGERS (the optional first argument) is non-nil, always use integers -\(rather than markers) to represent buffer positions. +If INTEGERS (the optional first argument) is non-nil, always use +integers \(rather than markers) to represent buffer positions. In +this case, and if the last match was in a buffer, the buffer will get +stored as one additional element at the end of the list. + If REUSE is a list, reuse it as part of the value. If REUSE is long enough to hold all the values, and if INTEGERS is non-nil, no consing is done. @@ -2638,10 +2646,10 @@ Return value is undefined if the last search failed. */) prev = Qnil; - data = (Lisp_Object *) alloca ((2 * search_regs.num_regs) + data = (Lisp_Object *) alloca ((2 * search_regs.num_regs + 1) * sizeof (Lisp_Object)); - len = -1; + len = 0; for (i = 0; i < search_regs.num_regs; i++) { int start = search_regs.start[i]; @@ -2668,22 +2676,29 @@ Return value is undefined if the last search failed. */) /* last_thing_searched must always be Qt, a buffer, or Qnil. */ abort (); - len = i; + len = 2*(i+1); } else data[2 * i] = data [2 * i + 1] = Qnil; } + if (BUFFERP(last_thing_searched) + && ! NILP (integers)) + { + XSETBUFFER(data[len], last_thing_searched); + len++; + } + /* If REUSE is not usable, cons up the values and return them. */ if (! CONSP (reuse)) - return Flist (2 * len + 2, data); + return Flist (len, data); /* If REUSE is a list, store as many value elements as will fit into the elements of REUSE. */ for (i = 0, tail = reuse; CONSP (tail); i++, tail = XCDR (tail)) { - if (i < 2 * len + 2) + if (i < len) XSETCAR (tail, data[i]); else XSETCAR (tail, Qnil); @@ -2692,8 +2707,8 @@ Return value is undefined if the last search failed. */) /* If we couldn't fit all value elements into REUSE, cons up the rest of them and add them to the end of REUSE. */ - if (i < 2 * len + 2) - XSETCDR (prev, Flist (2 * len + 2 - i, data + i)); + if (i < len) + XSETCDR (prev, Flist (len - i, data + i)); return reuse; } @@ -2714,8 +2729,8 @@ LIST should have been created by calling `match-data' previously. */) if (!CONSP (list) && !NILP (list)) list = wrong_type_argument (Qconsp, list); - /* Unless we find a marker with a buffer in LIST, assume that this - match data came from a string. */ + /* Unless we find a marker with a buffer or an explicit buffer + in LIST, assume that this match data came from a string. */ last_thing_searched = Qt; /* Allocate registers if they don't already exist. */ @@ -2746,43 +2761,53 @@ LIST should have been created by calling `match-data' previously. */) search_regs.num_regs = length; } + + for (i = 0;; i++) + { + marker = Fcar (list); + if (BUFFERP(marker)) + { + XSETBUFFER(last_thing_searched, marker); + break; + } + if (i >= length) + break; + if (NILP (marker)) + { + search_regs.start[i] = -1; + list = Fcdr (list); + } + else + { + int from; + + if (MARKERP (marker)) + { + if (XMARKER (marker)->buffer == 0) + XSETFASTINT (marker, 0); + else + XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer); + } + + CHECK_NUMBER_COERCE_MARKER (marker); + from = XINT (marker); + list = Fcdr (list); + + marker = Fcar (list); + if (MARKERP (marker) && XMARKER (marker)->buffer == 0) + XSETFASTINT (marker, 0); + + CHECK_NUMBER_COERCE_MARKER (marker); + search_regs.start[i] = from; + search_regs.end[i] = XINT (marker); + } + list = Fcdr (list); + } + + for (; i < search_regs.num_regs; i++) + search_regs.start[i] = -1; } - for (i = 0; i < search_regs.num_regs; i++) - { - marker = Fcar (list); - if (NILP (marker)) - { - search_regs.start[i] = -1; - list = Fcdr (list); - } - else - { - int from; - - if (MARKERP (marker)) - { - if (XMARKER (marker)->buffer == 0) - XSETFASTINT (marker, 0); - else - XSETBUFFER (last_thing_searched, XMARKER (marker)->buffer); - } - - CHECK_NUMBER_COERCE_MARKER (marker); - from = XINT (marker); - list = Fcdr (list); - - marker = Fcar (list); - if (MARKERP (marker) && XMARKER (marker)->buffer == 0) - XSETFASTINT (marker, 0); - - CHECK_NUMBER_COERCE_MARKER (marker); - search_regs.start[i] = from; - search_regs.end[i] = XINT (marker); - } - list = Fcdr (list); - } - return Qnil; } @@ -2790,6 +2815,7 @@ LIST should have been created by calling `match-data' previously. */) during the execution of a sentinel or filter. */ static int search_regs_saved; static struct re_registers saved_search_regs; +static Lisp_Object saved_last_thing_searched; /* Called from Flooking_at, Fstring_match, search_buffer, Fstore_match_data if asynchronous code (filter or sentinel) is running. */ @@ -2801,6 +2827,8 @@ save_search_regs () saved_search_regs.num_regs = search_regs.num_regs; saved_search_regs.start = search_regs.start; saved_search_regs.end = search_regs.end; + saved_last_thing_searched = last_thing_searched; + last_thing_searched = Qnil; search_regs.num_regs = 0; search_regs.start = 0; search_regs.end = 0; @@ -2823,7 +2851,8 @@ restore_match_data () search_regs.num_regs = saved_search_regs.num_regs; search_regs.start = saved_search_regs.start; search_regs.end = saved_search_regs.end; - + last_thing_searched = saved_last_thing_searched; + saved_last_thing_searched = Qnil; search_regs_saved = 0; } } diff --git a/src/w32fns.c b/src/w32fns.c index a5f8c4b61f3..d3342f3ad6a 100644 --- a/src/w32fns.c +++ b/src/w32fns.c @@ -7749,7 +7749,8 @@ file_dialog_callback (hwnd, msg, wParam, lParam) { OFNOTIFY * notify = (OFNOTIFY *)lParam; /* Detect when the Filter dropdown is changed. */ - if (notify->hdr.code == CDN_TYPECHANGE) + if (notify->hdr.code == CDN_TYPECHANGE + || notify->hdr.code == CDN_INITDONE) { HWND dialog = GetParent (hwnd); HWND edit_control = GetDlgItem (dialog, FILE_NAME_TEXT_FIELD); @@ -7763,8 +7764,10 @@ file_dialog_callback (hwnd, msg, wParam, lParam) } else { - CommDlg_OpenSave_SetControlText (dialog, FILE_NAME_TEXT_FIELD, - ""); + /* Don't override default filename on init done. */ + if (notify->hdr.code == CDN_TYPECHANGE) + CommDlg_OpenSave_SetControlText (dialog, + FILE_NAME_TEXT_FIELD, ""); EnableWindow (edit_control, TRUE); } } @@ -7786,6 +7789,7 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */) struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; char filename[MAX_PATH + 1]; char init_dir[MAX_PATH + 1]; + int default_filter_index = 1; /* 1: All Files, 2: Directories only */ GCPRO5 (prompt, dir, default_filename, mustmatch, file); CHECK_STRING (prompt); @@ -7809,9 +7813,7 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */) if (!file_name_only) file_name_only = full_path_name; else - { - file_name_only++; - } + file_name_only++; strncpy (filename, file_name_only, MAX_PATH); filename[MAX_PATH] = '\0'; @@ -7836,6 +7838,15 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */) file_details.nMaxFile = sizeof (filename); file_details.lpstrInitialDir = init_dir; file_details.lpstrTitle = SDATA (prompt); + + /* If prompt starts with Dired, default to directories only. */ + /* A bit hacky, but there doesn't seem to be a better way to + DTRT for dired. */ + if (strncmp (file_details.lpstrTitle, "Dired", 5) == 0) + default_filter_index = 2; + + file_details.nFilterIndex = default_filter_index; + file_details.Flags = (OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_EXPLORER | OFN_ENABLEHOOK); if (!NILP (mustmatch)) @@ -7848,7 +7859,7 @@ specified. Ensure that file exists if MUSTMATCH is non-nil. */) dostounix_filename (filename); if (file_details.nFilterIndex == 2) { - /* "Folder Only" selected - strip dummy file name. */ + /* "Directories" selected - strip dummy file name. */ char * last = strrchr (filename, '/'); *last = '\0'; } diff --git a/src/xdisp.c b/src/xdisp.c index 41e00893c30..c95493d5aa3 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -6426,6 +6426,7 @@ add_to_log (format, arg1, arg2) char *buffer; int len; struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; + USE_SAFE_ALLOCA; /* Do nothing if called asynchronously. Inserting text into a buffer may call after-change-functions and alike and @@ -6442,10 +6443,12 @@ add_to_log (format, arg1, arg2) msg = Fformat (3, args); len = SBYTES (msg) + 1; - buffer = (char *) alloca (len); + SAFE_ALLOCA (buffer, char *, len); bcopy (SDATA (msg), buffer, len); message_dolog (buffer, len - 1, 1, 0); + SAFE_FREE (len); + UNGCPRO; }