Now on revision 110220. ------------------------------------------------------------ revno: 110220 fixes bug: http://debbugs.gnu.org/9781 committer: Glenn Morris branch nick: trunk timestamp: Wed 2012-09-26 23:59:21 -0700 message: Don't bother making files writable for commit with modern VCS * lisp/vc/vc.el (vc-next-action): Only gripe about committing read-only files for RCS and SCCS. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-09-27 03:31:58 +0000 +++ lisp/ChangeLog 2012-09-27 06:59:21 +0000 @@ -1,3 +1,8 @@ +2012-09-27 Glenn Morris + + * vc/vc.el (vc-next-action): Only gripe about committing read-only + files for RCS and SCCS. (Bug#9781) + 2012-09-27 Chong Yidong * progmodes/verilog-mode.el (verilog-mode-release-emacs): Fix last === modified file 'lisp/vc/vc.el' --- lisp/vc/vc.el 2012-09-25 04:13:02 +0000 +++ lisp/vc/vc.el 2012-09-27 06:59:21 +0000 @@ -1105,24 +1105,27 @@ ;; Files have local changes ((vc-compatible-state state 'edited) (let ((ready-for-commit files)) - ;; If files are edited but read-only, give user a chance to correct. - (dolist (file files) - ;; If committing a mix of removed and edited files, the - ;; fileset has state = 'edited. Rather than checking the - ;; state of each individual file in the fileset, it seems - ;; simplest to just check if the file exists. Bug#9781. - (when (and (file-exists-p file) (not (file-writable-p file))) - ;; Make the file+buffer read-write. - (unless (y-or-n-p (format "%s is edited but read-only; make it writable and continue? " file)) - (error "Aborted")) - ;; Maybe we somehow lost permissions on the directory. - (condition-case nil - (set-file-modes file (logior (file-modes file) 128)) - (error (error "Unable to make file writable"))) - (let ((visited (get-file-buffer file))) - (when visited - (with-current-buffer visited - (read-only-mode -1)))))) + ;; CVS, SVN and bzr don't care about read-only (bug#9781). + ;; RCS does, SCCS might (someone should check...). + (when (memq backend '(RCS SCCS)) + ;; If files are edited but read-only, give user a chance to correct. + (dolist (file files) + ;; If committing a mix of removed and edited files, the + ;; fileset has state = 'edited. Rather than checking the + ;; state of each individual file in the fileset, it seems + ;; simplest to just check if the file exists. Bug#9781. + (when (and (file-exists-p file) (not (file-writable-p file))) + ;; Make the file+buffer read-write. + (unless (y-or-n-p (format "%s is edited but read-only; make it writable and continue? " file)) + (error "Aborted")) + ;; Maybe we somehow lost permissions on the directory. + (condition-case nil + (set-file-modes file (logior (file-modes file) 128)) + (error (error "Unable to make file writable"))) + (let ((visited (get-file-buffer file))) + (when visited + (with-current-buffer visited + (read-only-mode -1))))))) ;; Allow user to revert files with no changes (save-excursion (dolist (file files) ------------------------------------------------------------ revno: 110219 committer: Glenn Morris branch nick: trunk timestamp: Wed 2012-09-26 23:51:35 -0700 message: Rename a section in doc/emacs/cal-xtra.texi * doc/emacs/cal-xtra.texi (Advanced Calendar/Diary Usage): Rename the section to be more general. * doc/emacs/emacs.texi: Update menu. diff: === modified file 'doc/emacs/ChangeLog' --- doc/emacs/ChangeLog 2012-09-23 10:46:50 +0000 +++ doc/emacs/ChangeLog 2012-09-27 06:51:35 +0000 @@ -1,3 +1,9 @@ +2012-09-27 Glenn Morris + + * cal-xtra.texi (Advanced Calendar/Diary Usage): + Rename the section to be more general. + * emacs.texi: Update menu. + 2012-09-23 Chong Yidong * buffers.texi (Misc Buffer): Replace toggle-read-only with === modified file 'doc/emacs/cal-xtra.texi' --- doc/emacs/cal-xtra.texi 2012-02-18 03:02:12 +0000 +++ doc/emacs/cal-xtra.texi 2012-09-27 06:51:35 +0000 @@ -7,10 +7,12 @@ @c Moved here from the Emacs Lisp Reference Manual, 2005-03-26. @node Advanced Calendar/Diary Usage -@section Customizing the Calendar and Diary +@section More advanced features of the Calendar and Diary - There are many ways in which you can customize the calendar and -diary to suit your personal tastes. + This section describes some of the more advanced/specialized +features of the calendar and diary. It starts with some of the +many ways in which you can customize the calendar and diary to suit +your personal tastes. @menu * Calendar Customizing:: Calendar layout and hooks. === modified file 'doc/emacs/emacs.texi' --- doc/emacs/emacs.texi 2012-09-04 18:29:04 +0000 +++ doc/emacs/emacs.texi 2012-09-27 06:51:35 +0000 @@ -953,7 +953,7 @@ * Special Diary Entries:: Anniversaries, blocks of dates, cyclic entries, etc. @ifnottex -Customizing the Calendar and Diary +More advanced features of the Calendar and Diary * Calendar Customizing:: Calendar layout and hooks. * Holiday Customizing:: Defining your own holidays. ------------------------------------------------------------ revno: 110218 committer: Glenn Morris branch nick: trunk timestamp: Wed 2012-09-26 23:47:12 -0700 message: Comment fix diff: === modified file 'lisp/calendar/cal-tex.el' --- lisp/calendar/cal-tex.el 2012-08-22 17:55:19 +0000 +++ lisp/calendar/cal-tex.el 2012-09-27 06:47:12 +0000 @@ -1097,7 +1097,7 @@ (cal-tex-longday "leftday" "2.75in")) (cal-tex-b-document) (cal-tex-cmd "\\pagestyle" "empty") - ;; Let's assume this is something to with twopage documents. + ;; Let's assume this is something to do with twopage documents. ;; It has the downside that we start with a blank page. ;; It doesn't make obvious sense when oddside and evenside margins ;; are the same (non-filofax), but consider the left and right ------------------------------------------------------------ revno: 110217 committer: Glenn Morris branch nick: trunk timestamp: Wed 2012-09-26 23:45:38 -0700 message: * admin/admin.el (set-version): Set msdos.c's Vwindow_system_version. diff: === modified file 'admin/ChangeLog' --- admin/ChangeLog 2012-09-27 01:06:23 +0000 +++ admin/ChangeLog 2012-09-27 06:45:38 +0000 @@ -1,3 +1,7 @@ +2012-09-27 Glenn Morris + + * admin.el (set-version): Set msdos.c's Vwindow_system_version. + 2012-09-27 Paul Eggert Check more robustly for timer_settime. === modified file 'admin/admin.el' --- admin/admin.el 2012-09-17 07:35:17 +0000 +++ admin/admin.el 2012-09-27 06:45:38 +0000 @@ -129,8 +129,12 @@ (rx (and "\"ProductVersion\"" (0+ space) ?, (0+ space) ?\" (submatch (1+ (in "0-9, "))) "\\0\""))) + ;; Major version only. (when (string-match "\\([0-9]\\{2,\\}\\)" version) (setq version (match-string 1 version)) + (set-version-in-file root "src/msdos.c" version + (rx (and "Vwindow_system_version" (1+ not-newline) + ?\( (submatch (1+ (in "0-9"))) ?\)))) (set-version-in-file root "etc/refcards/ru-refcard.tex" version "\\\\newcommand{\\\\versionemacs}\\[0\\]\ {\\([0-9]\\{2,\\}\\)}.+%.+version of Emacs") ------------------------------------------------------------ revno: 110216 committer: Chong Yidong branch nick: trunk timestamp: Thu 2012-09-27 11:31:58 +0800 message: Fix last commit. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-09-27 03:30:46 +0000 +++ lisp/ChangeLog 2012-09-27 03:31:58 +0000 @@ -3,11 +3,6 @@ * progmodes/verilog-mode.el (verilog-mode-release-emacs): Fix last change; value should be t. -2012-09-27 Ivan Andrus - - * emacs-lisp/package.el (package-delete): Don't signal an error if - the package directory is missing (Bug#12524). - 2012-09-27 Stefan Monnier * image-mode.el: Use lexical-binding. ------------------------------------------------------------ revno: 110215 committer: Chong Yidong branch nick: trunk timestamp: Thu 2012-09-27 11:30:46 +0800 message: Fix last change in verilog-mode.el. * progmodes/verilog-mode.el (verilog-mode-release-emacs): Fix last change; value should be t. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-09-27 03:16:35 +0000 +++ lisp/ChangeLog 2012-09-27 03:30:46 +0000 @@ -1,3 +1,13 @@ +2012-09-27 Chong Yidong + + * progmodes/verilog-mode.el (verilog-mode-release-emacs): Fix last + change; value should be t. + +2012-09-27 Ivan Andrus + + * emacs-lisp/package.el (package-delete): Don't signal an error if + the package directory is missing (Bug#12524). + 2012-09-27 Stefan Monnier * image-mode.el: Use lexical-binding. === modified file 'lisp/progmodes/verilog-mode.el' --- lisp/progmodes/verilog-mode.el 2012-09-26 03:32:51 +0000 +++ lisp/progmodes/verilog-mode.el 2012-09-27 03:30:46 +0000 @@ -127,7 +127,7 @@ "Version of this Verilog mode.") (defconst verilog-mode-release-date (substring "$$Date: 2012-09-17 20:43:10 -0400 (Mon, 17 Sep 2012) $$" 8 -3) "Release date of this Verilog mode.") -(defconst verilog-mode-release-emacs nil +(defconst verilog-mode-release-emacs t "If non-nil, this version of Verilog mode was released with Emacs itself.") (defun verilog-version () ------------------------------------------------------------ revno: 110214 committer: Stefan Monnier branch nick: trunk timestamp: Wed 2012-09-26 23:16:35 -0400 message: * lisp/image-mode.el: Use lexical-binding. (image-mode-winprops): Use t to stand for the window of a buffer that's not displayed. * lisp/doc-view.el (doc-view-new-window-function): Handle t in winprops. (doc-view-enlarge): Make it a real nop if the size is not changed. (doc-view-display): Handle the case where the buffer is not (yet?) displayed in any window. (doc-view-saved-settings): New var. (doc-view-mode): Use it. (doc-view-fallback-mode): Set it. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-09-27 02:10:54 +0000 +++ lisp/ChangeLog 2012-09-27 03:16:35 +0000 @@ -1,5 +1,17 @@ 2012-09-27 Stefan Monnier + * image-mode.el: Use lexical-binding. + (image-mode-winprops): Use t to stand for the window of + a buffer that's not displayed. + * doc-view.el (doc-view-new-window-function): Handle the new + t in winprops. + (doc-view-enlarge): Make it a real nop if the size is not changed. + (doc-view-display): Handle the case where the buffer is not (yet?) + displayed in any window. + (doc-view-saved-settings): New var. + (doc-view-mode): Use it. + (doc-view-fallback-mode): Set it. + * minibuf-eldef.el: Make it possible to replace (default ...) with [...]. Set lexical-binding. (minibuffer-eldef-shorten-default): New var. === modified file 'lisp/doc-view.el' --- lisp/doc-view.el 2012-09-20 19:53:40 +0000 +++ lisp/doc-view.el 2012-09-27 03:16:35 +0000 @@ -255,20 +255,23 @@ ;;;; Internal Variables (defun doc-view-new-window-function (winprops) + ;; (message "New window %s for buf %s" (car winprops) (current-buffer)) + (cl-assert (or (eq t (car winprops)) + (eq (window-buffer (car winprops)) (current-buffer)))) (let ((ol (image-mode-window-get 'overlay winprops))) - (when (and ol (not (overlay-buffer ol))) - ;; I've seen `ol' be a dead overlay. I do not yet know how this - ;; happened, so maybe the bug is elsewhere, but in the mean time, - ;; this seems like a safe approach. - (setq ol nil)) (if ol (progn - (cl-assert (eq (overlay-buffer ol) (current-buffer))) - (setq ol (copy-overlay ol))) - (cl-assert (not (get-char-property (point-min) 'display))) + (setq ol (copy-overlay ol)) + ;; `ol' might actually be dead. + (move-overlay ol (point-min) (point-max))) (setq ol (make-overlay (point-min) (point-max) nil t)) (overlay-put ol 'doc-view t)) (overlay-put ol 'window (car winprops)) + (unless (windowp (car winprops)) + ;; It's a pseudo entry. Let's make sure it's not displayed (the + ;; `window' property is only effective if its value is a window). + (cl-assert (eq t (car winprops))) + (delete-overlay ol)) (image-mode-window-put 'overlay ol winprops))) (defvar doc-view-current-files nil @@ -560,7 +563,8 @@ "Kill the current converter process(es)." (interactive) (while (consp doc-view-current-converter-processes) - (ignore-errors ;; Maybe it's dead already? + (ignore-errors ;; Some entries might not be processes, and maybe + ;; some are dead already? (kill-process (pop doc-view-current-converter-processes)))) (when doc-view-current-timer (cancel-timer doc-view-current-timer) @@ -663,19 +667,21 @@ (defvar doc-view-shrink-factor 1.125) (defun doc-view-enlarge (factor) - "Enlarge the document." + "Enlarge the document by FACTOR." (interactive (list doc-view-shrink-factor)) (if (eq (plist-get (cdr (doc-view-current-image)) :type) 'imagemagick) - ;; ImageMagick supports on-the-fly-rescaling - (progn - (set (make-local-variable 'doc-view-image-width) - (ceiling (* factor doc-view-image-width))) - (doc-view-insert-image (plist-get (cdr (doc-view-current-image)) :file) - :width doc-view-image-width)) - (set (make-local-variable 'doc-view-resolution) - (ceiling (* factor doc-view-resolution))) - (doc-view-reconvert-doc))) + ;; ImageMagick supports on-the-fly-rescaling. + (let ((new (ceiling (* factor doc-view-image-width)))) + (unless (equal new doc-view-image-width) + (set (make-local-variable 'doc-view-image-width) new) + (doc-view-insert-image + (plist-get (cdr (doc-view-current-image)) :file) + :width doc-view-image-width))) + (let ((new (ceiling (* factor doc-view-resolution)))) + (unless (equal new doc-view-resolution) + (set (make-local-variable 'doc-view-resolution) new) + (doc-view-reconvert-doc))))) (defun doc-view-shrink (factor) "Shrink the document." @@ -743,12 +749,14 @@ (img-height (cdr (image-display-size (image-get-display-property) t)))) (doc-view-enlarge (min (/ (float win-width) (float img-width)) - (/ (float (- win-height 1)) (float img-height))))) + (/ (float (- win-height 1)) + (float img-height))))) ;; If slice is set (let* ((slice-width (nth 2 slice)) (slice-height (nth 3 slice)) (scale-factor (min (/ (float win-width) (float slice-width)) - (/ (float (- win-height 1)) (float slice-height)))) + (/ (float (- win-height 1)) + (float slice-height)))) (new-slice (mapcar (lambda (x) (ceiling (* scale-factor x))) slice))) (doc-view-enlarge scale-factor) (setf (doc-view-current-slice) new-slice) @@ -762,6 +770,7 @@ ;; Clear the old cached files (when (file-exists-p (doc-view-current-cache-dir)) (delete-directory (doc-view-current-cache-dir) 'recursive)) + (kill-local-variable 'doc-view-last-page-number) (doc-view-initiate-display)) (defun doc-view-sentinel (proc event) @@ -1169,24 +1178,23 @@ If FORCE is non-nil, start viewing even if the document does not have the page we want to view." (with-current-buffer buffer - (let ((prev-pages doc-view-current-files) - (windows (get-buffer-window-list buffer nil t))) + (let ((prev-pages doc-view-current-files)) (setq doc-view-current-files (sort (directory-files (doc-view-current-cache-dir) t "page-[0-9]+\\.png" t) 'doc-view-sort)) - (unless windows - (switch-to-buffer buffer) - (setq windows (get-buffer-window-list buffer nil t))) - (dolist (win windows) + (dolist (win (or (get-buffer-window-list buffer nil t) + (list t))) (let* ((page (doc-view-current-page win)) (pagefile (expand-file-name (format "page-%d.png" page) (doc-view-current-cache-dir)))) (when (or force (and (not (member pagefile prev-pages)) (member pagefile doc-view-current-files))) - (with-selected-window win - (cl-assert (eq (current-buffer) buffer) t) + (if (windowp win) + (with-selected-window win + (cl-assert (eq (current-buffer) buffer) t) + (doc-view-goto-page page)) (doc-view-goto-page page)))))))) (defun doc-view-buffer-message () @@ -1231,6 +1239,10 @@ ;;;;; Toggle between editing and viewing +(defvar-local doc-view-saved-settings nil + "Doc-view settings saved while in some other mode.") +(put 'doc-view-saved-settings 'permanent-local t) + (defun doc-view-toggle-display () "Toggle between editing a document as text or viewing it." (interactive) @@ -1483,13 +1495,16 @@ ;; returns nil for tar members. (doc-view-fallback-mode) - (let* ((prev-major-mode (if (eq major-mode 'doc-view-mode) + (let* ((prev-major-mode (if (derived-mode-p 'doc-view-mode) doc-view-previous-major-mode - (when (not (memq major-mode - '(doc-view-mode fundamental-mode))) + (unless (eq major-mode 'fundamental-mode) major-mode)))) (kill-all-local-variables) - (set (make-local-variable 'doc-view-previous-major-mode) prev-major-mode)) + (set (make-local-variable 'doc-view-previous-major-mode) + prev-major-mode)) + + (dolist (var doc-view-saved-settings) + (set (make-local-variable (car var)) (cdr var))) ;; Figure out the document type. (unless doc-view-doc-type @@ -1563,13 +1578,20 @@ (defun doc-view-fallback-mode () "Fallback to the previous or next best major mode." - (if doc-view-previous-major-mode - (funcall doc-view-previous-major-mode) - (let ((auto-mode-alist (rassq-delete-all - 'doc-view-mode-maybe - (rassq-delete-all 'doc-view-mode - (copy-alist auto-mode-alist))))) - (normal-mode)))) + (let ((vars (if (derived-mode-p 'doc-view-mode) + (mapcar (lambda (var) (cons var (symbol-value var))) + '(doc-view-resolution + image-mode-winprops-alist))))) + (if doc-view-previous-major-mode + (funcall doc-view-previous-major-mode) + (let ((auto-mode-alist + (rassq-delete-all + 'doc-view-mode-maybe + (rassq-delete-all 'doc-view-mode + (copy-alist auto-mode-alist))))) + (normal-mode))) + (when vars + (setq-local doc-view-saved-settings vars)))) ;;;###autoload (defun doc-view-mode-maybe () === modified file 'lisp/image-mode.el' --- lisp/image-mode.el 2012-07-10 11:51:54 +0000 +++ lisp/image-mode.el 2012-09-27 03:16:35 +0000 @@ -1,4 +1,4 @@ -;;; image-mode.el --- support for visiting image files +;;; image-mode.el --- support for visiting image files -*- lexical-binding: t -*- ;; ;; Copyright (C) 2005-2012 Free Software Foundation, Inc. ;; @@ -31,6 +31,11 @@ ;; resulting buffer file is saved to another name it will correctly save ;; the image data to the new file. +;; Todo: + +;; Consolidate with doc-view to make them work on directories of images or on +;; image files containing various "pages". + ;;; Code: (require 'image) @@ -38,8 +43,7 @@ ;;; Image mode window-info management. -(defvar image-mode-winprops-alist t) -(make-variable-buffer-local 'image-mode-winprops-alist) +(defvar-local image-mode-winprops-alist t) (defvar image-mode-new-window-functions nil "Special hook run when image data is requested in a new window. @@ -47,9 +51,13 @@ (defun image-mode-winprops (&optional window cleanup) "Return winprops of WINDOW. -A winprops object has the shape (WINDOW . ALIST)." +A winprops object has the shape (WINDOW . ALIST). +WINDOW defaults to `selected-window' if it displays the current buffer, and +otherwise it defaults to t, used for times when the buffer is not displayed." (cond ((null window) - (setq window (selected-window))) + (setq window + (if (eq (current-buffer) (window-buffer)) (selected-window) t))) + ((eq window t)) ((not (windowp window)) (error "Not a window: %s" window))) (when cleanup ------------------------------------------------------------ revno: 110213 committer: Stefan Monnier branch nick: trunk timestamp: Wed 2012-09-26 22:10:54 -0400 message: * lisp/minibuf-eldef.el: Make it possible to replace (default ...) with [...]. Set lexical-binding. (minibuffer-eldef-shorten-default): New var. (minibuffer-default-in-prompt-regexps): Use it for new default. (minibuf-eldef-setup-minibuffer): Add replacement functionality. diff: === modified file 'etc/NEWS' --- etc/NEWS 2012-09-26 15:19:10 +0000 +++ etc/NEWS 2012-09-27 02:10:54 +0000 @@ -86,6 +86,9 @@ * Changes in Emacs 24.3 +** minibuffer-electric-default-mode can rewrite (default ...) to [...]. +Just set minibuffer-eldef-shorten-default to t before enabling the mode. + ** Most y-or-n prompts now allow you to scroll the selected window. Typing C-v or M-v at a y-or-n prompt scrolls forward or backward respectively, without exiting from the prompt. === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-09-26 22:42:54 +0000 +++ lisp/ChangeLog 2012-09-27 02:10:54 +0000 @@ -1,3 +1,11 @@ +2012-09-27 Stefan Monnier + + * minibuf-eldef.el: Make it possible to replace (default ...) with [...]. + Set lexical-binding. + (minibuffer-eldef-shorten-default): New var. + (minibuffer-default-in-prompt-regexps): Use it for new default. + (minibuf-eldef-setup-minibuffer): Add replacement functionality. + 2012-09-26 Juanma Barranquero * international/uni-bidi.el: === modified file 'lisp/minibuf-eldef.el' --- lisp/minibuf-eldef.el 2012-04-09 13:05:48 +0000 +++ lisp/minibuf-eldef.el 2012-09-27 02:10:54 +0000 @@ -1,4 +1,4 @@ -;;; minibuf-eldef.el --- Only show defaults in prompts when applicable +;;; minibuf-eldef.el --- Only show defaults in prompts when applicable -*- lexical-binding: t -*- ;; ;; Copyright (C) 2000-2012 Free Software Foundation, Inc. ;; @@ -33,16 +33,22 @@ ;;; Code: +(defvar minibuffer-eldef-shorten-default nil + "If non-nil, shorten \"(default ...)\" to \"[...]\" in minibuffer prompts.") + (defvar minibuffer-default-in-prompt-regexps - '(("\\( (default\\>.*)\\):? \\'" . 1) ("\\( \\[.*\\]\\):? *\\'" . 1)) + `(("\\( (default\\(?: is\\)? \\(.*\\))\\):? \\'" + 1 ,(if minibuffer-eldef-shorten-default " [\\2]")) + ("\\( \\[.*\\]\\):? *\\'" 1)) "A list of regexps matching the parts of minibuffer prompts showing defaults. When `minibuffer-electric-default-mode' is active, these regexps are used to identify the portions of prompts to elide. -Each entry is either a string, which should be a regexp matching the -default portion of the prompt, or a cons cell, who's car is a regexp -matching the default part of the prompt, and who's cdr indicates the -regexp subexpression that matched.") +Each entry is of the form (REGEXP MATCH-NUM &optional REWRITE), +where REGEXP should match the default part of the prompt, +MATCH-NUM is the subgroup that matched the actual default indicator, +and REWRITE, if present, is a string to pass to `replace-match' that +should be displayed in its place.") ;;; Internal variables @@ -79,21 +85,42 @@ (inhibit-point-motion-hooks t)) (save-excursion (save-restriction - ;; Narrow to only the prompt + ;; Narrow to only the prompt. (goto-char (point-min)) (narrow-to-region (point) (minibuffer-prompt-end)) - ;; See the prompt contains a default input indicator + ;; See if the prompt contains a default input indicator. (while regexps (setq match (pop regexps)) - (if (re-search-forward (if (stringp match) match (car match)) nil t) - (setq regexps nil) - (setq match nil))))) + (cond + ((not (re-search-forward (if (stringp match) match (car match)) + nil t)) + ;; No match yet, try the next rule. + (setq match nil)) + ((and (consp (cdr-safe match)) (nth 2 match)) + ;; Matched a replacement rule. + (let* ((inhibit-read-only t) + (buffer-undo-list t) + (submatch (nth 1 match)) + (replacement (nth 2 match)) + (props (text-properties-at (match-beginning submatch)))) + (replace-match replacement nil nil nil submatch) + (set-text-properties (match-beginning submatch) + (match-end submatch) + props) + ;; Replacement done, now keep trying with subsequent rules. + (setq match nil) + (goto-char (point-min)))) + ;; Matched a non-replacement (i.e. electric hide) rule, no need to + ;; keep trying. + (t (setq regexps nil)))))) (if (not match) - ;; Nope, so just make sure our post-command-hook isn't left around. + ;; No match for electric hiding, so just make sure our + ;; post-command-hook isn't left around. (remove-hook 'post-command-hook #'minibuf-eldef-update-minibuffer t) ;; Yup; set things up so we can frob the prompt as the state of ;; the input string changes. (setq match (if (consp match) (cdr match) 0)) + (setq match (if (consp match) (car match) match)) (setq minibuf-eldef-overlay (make-overlay (match-beginning match) (match-end match))) (setq minibuf-eldef-showing-default-in-prompt t) @@ -124,10 +151,6 @@ (overlay-put minibuf-eldef-overlay 'intangible t))))) -;;; Note this definition must be at the end of the file, because -;;; `define-minor-mode' actually calls the mode-function if the -;;; associated variable is non-nil, which requires that all needed -;;; functions be already defined. [This is arguably a bug in d-m-m] ;;;###autoload (define-minor-mode minibuffer-electric-default-mode "Toggle Minibuffer Electric Default mode. ------------------------------------------------------------ revno: 110212 committer: Paul Eggert branch nick: trunk timestamp: Wed 2012-09-26 18:06:23 -0700 message: Check more robustly for timer_settime. This should fix an OS X build problem reported by Ivan Andrus in . * admin/merge-gnulib (GNULIB_MODULES): Add timer-time. * configure.ac (gl_THREADLIB): Define to empty, since Emacs does threads its own way. * lib/gnulib.mk, m4/gnulib-comp.m4: Regenerate. * m4/timer_time.m4: New file, from gnulib. * src/atimer.c (alarm_timer, alarm_timer_ok, set_alarm, init_atimer): Use HAVE_TIMER_SETTIME, not SIGEV_SIGNAL, to decide whether to call timer_settime. diff: === modified file 'ChangeLog' --- ChangeLog 2012-09-26 15:19:10 +0000 +++ ChangeLog 2012-09-27 01:06:23 +0000 @@ -1,3 +1,11 @@ +2012-09-27 Paul Eggert + + Check more robustly for timer_settime. + This should fix an OS X build problem reported by Ivan Andrus in + . + * configure.ac (gl_THREADLIB): Define to empty, since Emacs + does threads its own way. + 2012-09-23 Paul Eggert * Makefile.in (bootstrap): Set MAKEFILE_NAME when building Makefile, === modified file 'admin/ChangeLog' --- admin/ChangeLog 2012-09-26 22:21:16 +0000 +++ admin/ChangeLog 2012-09-27 01:06:23 +0000 @@ -1,3 +1,8 @@ +2012-09-27 Paul Eggert + + Check more robustly for timer_settime. + * merge-gnulib (GNULIB_MODULES): Add timer-time. + 2012-09-26 Juanma Barranquero * unidata/BidiMirroring.txt: === modified file 'admin/merge-gnulib' --- admin/merge-gnulib 2012-08-25 04:04:08 +0000 +++ admin/merge-gnulib 2012-09-27 01:06:23 +0000 @@ -34,7 +34,7 @@ manywarnings mktime pselect pthread_sigmask readlink socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat - sys_time time timespec-add timespec-sub utimens + sys_time time timer-time timespec-add timespec-sub utimens warnings ' === modified file 'configure.ac' --- configure.ac 2012-09-18 18:13:01 +0000 +++ configure.ac 2012-09-27 01:06:23 +0000 @@ -571,6 +571,9 @@ test "x$NON_GCC_TEST_OPTIONS" != x && CC="$CC $NON_GCC_TEST_OPTIONS" fi +# Avoid gnulib's threadlib module, as we do threads our own way. +AC_DEFUN([gl_THREADLIB]) + # Initialize gnulib right after choosing the compiler. gl_EARLY === modified file 'lib/gnulib.mk' --- lib/gnulib.mk 2012-08-28 16:01:59 +0000 +++ lib/gnulib.mk 2012-09-27 01:06:23 +0000 @@ -21,7 +21,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=errno --avoid=fcntl --avoid=fcntl-h --avoid=fstat --avoid=msvc-inval --avoid=msvc-nothrow --avoid=raise --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timespec-add timespec-sub utimens warnings +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=build-aux --avoid=errno --avoid=fcntl --avoid=fcntl-h --avoid=fstat --avoid=msvc-inval --avoid=msvc-nothrow --avoid=raise --avoid=select --avoid=sigprocmask --avoid=sys_types --avoid=threadlib --makefile-name=gnulib.mk --conditional-dependencies --no-libtool --macro-prefix=gl --no-vc-files alloca-opt c-ctype c-strcase careadlinkat crypto/md5 crypto/sha1 crypto/sha256 crypto/sha512 dtoastr dtotimespec dup2 environ execinfo filemode getloadavg getopt-gnu gettime gettimeofday ignore-value intprops largefile lstat manywarnings mktime pselect pthread_sigmask readlink socklen stat-time stdalign stdarg stdbool stdio strftime strtoimax strtoumax symlink sys_stat sys_time time timer-time timespec-add timespec-sub utimens warnings MOSTLYCLEANFILES += core *.stackdump === modified file 'm4/gnulib-comp.m4' --- m4/gnulib-comp.m4 2012-08-25 04:04:08 +0000 +++ m4/gnulib-comp.m4 2012-09-27 01:06:23 +0000 @@ -111,6 +111,7 @@ # Code from module sys_time: # Code from module time: # Code from module time_r: + # Code from module timer-time: # Code from module timespec: # Code from module timespec-add: # Code from module timespec-sub: @@ -263,6 +264,7 @@ gl_PREREQ_TIME_R fi gl_TIME_MODULE_INDICATOR([time_r]) + gl_TIMER_TIME gl_TIMESPEC gl_UNISTD_H gl_UTIMENS @@ -661,6 +663,7 @@ m4/sys_time_h.m4 m4/time_h.m4 m4/time_r.m4 + m4/timer_time.m4 m4/timespec.m4 m4/tm_gmtoff.m4 m4/unistd_h.m4 === added file 'm4/timer_time.m4' --- m4/timer_time.m4 1970-01-01 00:00:00 +0000 +++ m4/timer_time.m4 2012-09-27 01:06:23 +0000 @@ -0,0 +1,39 @@ +# timer_time.m4 serial 2 +dnl Copyright (C) 2011-2012 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +# Check for timer_settime, and set LIB_TIMER_TIME. + +AC_DEFUN([gl_TIMER_TIME], +[ + dnl Based on clock_time.m4. See details there. + + AC_REQUIRE([gl_USE_SYSTEM_EXTENSIONS]) + AC_REQUIRE([gl_THREADLIB]) + + LIB_TIMER_TIME= + AC_SUBST([LIB_TIMER_TIME]) + gl_saved_libs=$LIBS + AC_SEARCH_LIBS([timer_settime], [rt posix4], + [test "$ac_cv_search_timer_settime" = "none required" || + LIB_TIMER_TIME=$ac_cv_search_timer_settime]) + dnl GLIBC uses threads to emulate posix timers when kernel support + dnl is not available (like Linux < 2.6 or when used with kFreeBSD) + dnl Now the pthread lib is linked automatically in the normal case, + dnl but when linking statically, it needs to be explicitly specified. + AC_EGREP_CPP([Thread], + [ +#include +#ifdef __GNU_LIBRARY__ + #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2) || (__GLIBC__ > 2)) \ + && !defined __UCLIBC__ + Thread emulation available + #endif +#endif + ], + [LIB_TIMER_TIME="$LIB_TIMER_TIME $LIBMULTITHREAD"]) + AC_CHECK_FUNCS([timer_settime]) + LIBS=$gl_saved_libs +]) === modified file 'src/ChangeLog' --- src/ChangeLog 2012-09-26 23:14:13 +0000 +++ src/ChangeLog 2012-09-27 01:06:23 +0000 @@ -1,3 +1,10 @@ +2012-09-27 Paul Eggert + + Check more robustly for timer_settime. + * atimer.c (alarm_timer, alarm_timer_ok, set_alarm, init_atimer): + Use HAVE_TIMER_SETTIME, not SIGEV_SIGNAL, to decide whether to + call timer_settime. + 2012-09-26 Tomohiro Matsuyama * profiler.c (Fprofiler_cpu_start): Remove unnecessary flag SA_SIGINFO. === modified file 'src/atimer.c' --- src/atimer.c 2012-09-25 19:18:05 +0000 +++ src/atimer.c 2012-09-27 01:06:23 +0000 @@ -42,7 +42,7 @@ /* The alarm timer and whether it was properly initialized, if POSIX timers are available. */ -#ifdef SIGEV_SIGNAL +#ifdef HAVE_TIMER_SETTIME static timer_t alarm_timer; static bool alarm_timer_ok; #endif @@ -296,7 +296,7 @@ #endif EMACS_TIME now, interval; -#ifdef SIGEV_SIGNAL +#ifdef HAVE_TIMER_SETTIME if (alarm_timer_ok) { struct itimerspec ispec; @@ -416,7 +416,7 @@ init_atimer (void) { struct sigaction action; -#ifdef SIGEV_SIGNAL +#ifdef HAVE_TIMER_SETTIME struct sigevent sigev; sigev.sigev_notify = SIGEV_SIGNAL; sigev.sigev_signo = SIGALRM; ------------------------------------------------------------ revno: 110211 committer: Tomohiro Matsuyama branch nick: trunk timestamp: Thu 2012-09-27 08:14:13 +0900 message: * profiler.c (Fprofiler_cpu_start): Remove unnecessary flag SA_SIGINFO. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2012-09-26 22:04:10 +0000 +++ src/ChangeLog 2012-09-26 23:14:13 +0000 @@ -1,3 +1,7 @@ +2012-09-26 Tomohiro Matsuyama + + * profiler.c (Fprofiler_cpu_start): Remove unnecessary flag SA_SIGINFO. + 2012-09-26 Juanma Barranquero * makefile.w32-in ($(BLD)/profiler.$(O)): Update dependencies. === modified file 'src/profiler.c' --- src/profiler.c 2012-09-26 15:19:10 +0000 +++ src/profiler.c 2012-09-26 23:14:13 +0000 @@ -214,7 +214,7 @@ /* Signal handler for sample profiler. */ static void -sigprof_handler (int signal, siginfo_t *info, void *ctx) +sigprof_handler (int signal) { eassert (HASH_TABLE_P (cpu_log)); if (backtrace_list && EQ (*backtrace_list->function, Qautomatic_gc)) @@ -251,8 +251,8 @@ current_sample_interval = XINT (sample_interval); - sa.sa_sigaction = sigprof_handler; - sa.sa_flags = SA_RESTART | SA_SIGINFO; + sa.sa_handler = sigprof_handler; + sa.sa_flags = SA_RESTART; sigemptyset (&sa.sa_mask); sigaction (SIGPROF, &sa, 0); ------------------------------------------------------------ revno: 110210 committer: Juanma Barranquero branch nick: trunk timestamp: Thu 2012-09-27 00:42:54 +0200 message: Fix ChangeLog typos. diff: === modified file 'lib-src/ChangeLog' --- lib-src/ChangeLog 2012-09-26 22:04:10 +0000 +++ lib-src/ChangeLog 2012-09-26 22:42:54 +0000 @@ -1042,7 +1042,7 @@ (Asm_help, default_C_suffixes, default_C_help, Cplusplus_suffixes) (Cplusplus_help, Cjava_suffixes, Cobol_suffixes, Cstar_suffixes) (Erlang_suffixes, Erlang_help, Forth_suffixes, Forth_help) - (Fortran_suffixes, Fortran_help, HTML_suffixes, HTML_help) + (Fortran_suffixes, Fortran_help, HTML_suffixes, HTML_help) (Lisp_suffixes, Lisp_help, Lua_suffixes, Lua_help) (Makefile_filenames, Makefile_help, Objc_suffixes, Objc_help) (Pascal_suffixes, Pascal_help, Perl_suffixes, Perl_interpreters) === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-09-26 22:21:16 +0000 +++ lisp/ChangeLog 2012-09-26 22:42:54 +0000 @@ -9752,7 +9752,7 @@ Declare as obsolete. (ns-get-pasteboard, ns-paste-secondary): Use ns-get-selection-internal. - (ns-set-pasteboard, ns-copy-including-secondary): + (ns-set-pasteboard, ns-copy-including-secondary): Use ns-store-selection-internal. 2011-12-17 Chong Yidong === modified file 'lisp/ChangeLog.8' --- lisp/ChangeLog.8 2012-07-29 08:18:29 +0000 +++ lisp/ChangeLog.8 2012-09-26 22:42:54 +0000 @@ -2372,7 +2372,7 @@ (sh-mode-map): Added new bindings. (sh-mode): Updated mode doc-string for new commands, added make-local-variable calls, initialize mode-specific variables. - (sh-indent-line): Renamed to sh-basic-indent-line; sh-indent-line + (sh-indent-line): Renamed to sh-basic-indent-line; sh-indent-line is now a different function. (sh-header-marker): Changed docstring. (sh-set-shell): Initialize mode-specific variables. === modified file 'lisp/ChangeLog.9' --- lisp/ChangeLog.9 2012-05-29 06:16:49 +0000 +++ lisp/ChangeLog.9 2012-09-26 22:42:54 +0000 @@ -569,7 +569,7 @@ Don't bind mouse events or tab/backtab. (help-function, help-variable, help-face, help-coding-system) (help-input-method, help-character-set, help-back, help-info) - (help-customize-variable, help-function-def, help-variable-def): + (help-customize-variable, help-function-def, help-variable-def): New button types. (help-button-action): New function. (describe-function-1): Pass help button-types to @@ -20671,7 +20671,7 @@ * term/tty-colors.el (tty-defined-color-alist): Renamed from tty-color-alist. (tty-color-alist, tty-modify-color-alist): New functions. - (tty-color-define, tty-color-clear, tty-color-approximate) + (tty-color-define, tty-color-clear, tty-color-approximate) (tty-color-translate, tty-color-by-index, tty-color-desc): Accept an optional parameter FRAME. === modified file 'lisp/gnus/ChangeLog.2' --- lisp/gnus/ChangeLog.2 2012-01-19 07:21:25 +0000 +++ lisp/gnus/ChangeLog.2 2012-09-26 22:42:54 +0000 @@ -11974,7 +11974,7 @@ 2001-12-18 01:00:00 ShengHuo ZHU - * ChangeLog, ChangeLog.1, nnwfm.el, gnus-smiley.el: + * ChangeLog, ChangeLog.1, nnwfm.el, gnus-smiley.el: * gnus-cite.el, gnus-delay.el, gnus-spec.el, message.el: * mml1991.el, nnultimate.el: Add `coding'. === modified file 'lisp/mh-e/ChangeLog.1' --- lisp/mh-e/ChangeLog.1 2012-07-29 08:18:29 +0000 +++ lisp/mh-e/ChangeLog.1 2012-09-26 22:42:54 +0000 @@ -10930,7 +10930,7 @@ * mh-utils.el (mh-prompt-for-folder): Exit with error if no folder specified, otherwise mh-refile-msg may try to create a folder with - empty name, and this creates problems; even mh-undo can't handle + empty name, and this creates problems; even mh-undo can't handle it (Closes SF #476824). * mh-comp.el (mh-letter-tool-bar-map): Info button needed to === modified file 'src/ChangeLog.11' --- src/ChangeLog.11 2012-07-29 08:18:29 +0000 +++ src/ChangeLog.11 2012-09-26 22:42:54 +0000 @@ -5532,7 +5532,7 @@ (update_frame_tool_bar): Remove old_req, new_req. Do not get tool bar height, call xg_update_tool_bar_sizes instead. (free_frame_tool_bar): Remove from hbox or vbox depending on - toolbar_in_hbox, Set all FRAME_TOOLBAR_*_(WIDTH|HEIGHT) to zero. + toolbar_in_hbox. Set all FRAME_TOOLBAR_*_(WIDTH|HEIGHT) to zero. (xg_change_toolbar_position): New function. * frame.h (struct frame): Add tool_bar_position. === modified file 'src/ChangeLog.2' --- src/ChangeLog.2 2012-01-19 07:21:25 +0000 +++ src/ChangeLog.2 2012-09-26 22:42:54 +0000 @@ -2680,7 +2680,7 @@ 1986-12-11 Richard Mlynarik (mly@prep) - * emacs.c, dispnew.c: + * emacs.c, dispnew.c: Rename inhibit_x_windows inhibit_window_system. Understand "-nw" command-line option. Reorganize init_display a little to make other window-system === modified file 'src/ChangeLog.3' --- src/ChangeLog.3 2012-01-19 07:21:25 +0000 +++ src/ChangeLog.3 2012-09-26 22:42:54 +0000 @@ -11154,7 +11154,7 @@ (classify_object): Removed code to look up a function key in the global and local function key keymaps, since this will be done more generally. - (Fexecute_mouse_event): Elided this function with a #if 0; I + (Fexecute_mouse_event): Elided this function with a #if 0; I think it will go away once the more general keymap stuff is implemented, but I'm not sure. (syms_of_keyboard): Removed defsubr for Sexecute_mouse_event. ------------------------------------------------------------ revno: 110209 committer: Juanma Barranquero branch nick: trunk timestamp: Thu 2012-09-27 00:21:16 +0200 message: Update to Unicode 6.2. * admin/unidata/BidiMirroring.txt: * admin/unidata/UnicodeData.txt: Update to Unicode 6.2. * lisp/international/uni-bidi.el: * lisp/international/uni-category.el: * lisp/international/uni-name.el: * lisp/international/uni-numeric.el: Regenerate. diff: === modified file 'admin/ChangeLog' --- admin/ChangeLog 2012-09-17 07:35:17 +0000 +++ admin/ChangeLog 2012-09-26 22:21:16 +0000 @@ -1,3 +1,8 @@ +2012-09-26 Juanma Barranquero + + * unidata/BidiMirroring.txt: + * unidata/UnicodeData.txt: Update to Unicode 6.2. + 2012-09-17 Glenn Morris * admin.el (add-log-time-format): Declare. === modified file 'admin/unidata/BidiMirroring.txt' --- admin/unidata/BidiMirroring.txt 2012-04-07 14:26:14 +0000 +++ admin/unidata/BidiMirroring.txt 2012-09-26 22:21:16 +0000 @@ -1,19 +1,19 @@ -# BidiMirroring-6.1.0.txt -# Date: 2011-12-20, 19:31:00 GMT [KW, LI] +# BidiMirroring-6.2.0.txt +# Date: 2012-05-15, 24:19:00 GMT [KW, LI] # # Bidi_Mirroring_Glyph Property # # This file is an informative contributory data file in the # Unicode Character Database. # -# Copyright (c) 1991-2011 Unicode, Inc. +# Copyright (c) 1991-2012 Unicode, Inc. # For terms of use, see http://www.unicode.org/terms_of_use.html # # This data file lists characters that have the Bidi_Mirrored=Yes property # value, for which there is another Unicode character that typically has a glyph # that is the mirror image of the original character's glyph. # -# The repertoire covered by the file is Unicode 6.1.0. +# The repertoire covered by the file is Unicode 6.2.0. # # The file contains a list of lines with mappings from one code point # to another one for character-based mirroring. @@ -30,16 +30,8 @@ # characters exist with mirrored glyphs, are # listed as comments at the end of the file. # -# Note: (2011-12-19) There is an inconsistency between the -# following statement about the default value -# of the Bidi_Mirroring_Glyph property and the -# value of the @missing line for Bidi_Mirroring_Glyph in -# PropertyValueAliases.txt. This inconsistency was discovered too -# late in the release process to be resolved by -# the UTC. The inconsistency will be resolved in a future revision. -# # Formally, the default value of the Bidi_Mirroring_Glyph property -# for each code point is the code point itself, unless a mapping to +# for each code point is , unless a mapping to # some other character is specified in this data file. When a code # point has the default value for the Bidi_Mirroring_Glyph property, # that means that no other character exists whose glyph is suitable @@ -50,12 +42,13 @@ # # This file was originally created by Markus Scherer. # Extended for Unicode 3.2, 4.0, 4.1, 5.0, 5.1, 5.2, and 6.0 by Ken Whistler, -# and for Unicode 6.1 by Ken Whistler and Laurentiu Iancu. +# and for Unicode 6.1 and 6.2 by Ken Whistler and Laurentiu Iancu. # # ############################################################ # # Property: Bidi_Mirroring_Glyph # +# @missing: 0000..10FFFF; 0028; 0029 # LEFT PARENTHESIS 0029; 0028 # RIGHT PARENTHESIS === modified file 'admin/unidata/UnicodeData.txt' --- admin/unidata/UnicodeData.txt 2012-04-07 14:26:14 +0000 +++ admin/unidata/UnicodeData.txt 2012-09-26 22:21:16 +0000 @@ -7190,6 +7190,7 @@ 20B7;SPESMILO SIGN;Sc;0;ET;;;;;N;;;;; 20B8;TENGE SIGN;Sc;0;ET;;;;;N;;;;; 20B9;INDIAN RUPEE SIGN;Sc;0;ET;;;;;N;;;;; +20BA;TURKISH LIRA SIGN;Sc;0;ET;;;;;N;;;;; 20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;; 20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;; 20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;; @@ -18703,8 +18704,8 @@ 1242F;CUNEIFORM NUMERIC SIGN THREE SHARU VARIANT FORM;Nl;0;L;;;;3;N;;;;; 12430;CUNEIFORM NUMERIC SIGN FOUR SHARU;Nl;0;L;;;;4;N;;;;; 12431;CUNEIFORM NUMERIC SIGN FIVE SHARU;Nl;0;L;;;;5;N;;;;; -12432;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS DISH;Nl;0;L;;;;;N;;;;; -12433;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS MIN;Nl;0;L;;;;;N;;;;; +12432;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS DISH;Nl;0;L;;;;216000;N;;;;; +12433;CUNEIFORM NUMERIC SIGN SHAR2 TIMES GAL PLUS MIN;Nl;0;L;;;;432000;N;;;;; 12434;CUNEIFORM NUMERIC SIGN ONE BURU;Nl;0;L;;;;1;N;;;;; 12435;CUNEIFORM NUMERIC SIGN TWO BURU;Nl;0;L;;;;2;N;;;;; 12436;CUNEIFORM NUMERIC SIGN THREE BURU;Nl;0;L;;;;3;N;;;;; @@ -18739,8 +18740,8 @@ 12453;CUNEIFORM NUMERIC SIGN FOUR BAN2 VARIANT FORM;Nl;0;L;;;;4;N;;;;; 12454;CUNEIFORM NUMERIC SIGN FIVE BAN2;Nl;0;L;;;;5;N;;;;; 12455;CUNEIFORM NUMERIC SIGN FIVE BAN2 VARIANT FORM;Nl;0;L;;;;5;N;;;;; -12456;CUNEIFORM NUMERIC SIGN NIGIDAMIN;Nl;0;L;;;;;N;;;;; -12457;CUNEIFORM NUMERIC SIGN NIGIDAESH;Nl;0;L;;;;;N;;;;; +12456;CUNEIFORM NUMERIC SIGN NIGIDAMIN;Nl;0;L;;;;-1;N;;;;; +12457;CUNEIFORM NUMERIC SIGN NIGIDAESH;Nl;0;L;;;;-1;N;;;;; 12458;CUNEIFORM NUMERIC SIGN ONE ESHE3;Nl;0;L;;;;1;N;;;;; 12459;CUNEIFORM NUMERIC SIGN TWO ESHE3;Nl;0;L;;;;2;N;;;;; 1245A;CUNEIFORM NUMERIC SIGN ONE THIRD DISH;Nl;0;L;;;;1/3;N;;;;; === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-09-26 15:19:10 +0000 +++ lisp/ChangeLog 2012-09-26 22:21:16 +0000 @@ -1,3 +1,10 @@ +2012-09-26 Juanma Barranquero + + * international/uni-bidi.el: + * international/uni-category.el: + * international/uni-name.el: + * international/uni-numeric.el: Regenerate. + 2012-09-26 Tomohiro Matsuyama Stefan Monnier === modified file 'lisp/international/uni-bidi.el' --- lisp/international/uni-bidi.el 2012-04-07 14:26:14 +0000 +++ lisp/international/uni-bidi.el 2012-09-26 22:21:16 +0000 @@ -5,7 +5,7 @@ (define-char-code-property 'bidi-class #^[1 nil char-code-property-table #^^[3 0 5 5 5 5 5 5 5 5 5 17 6 17 18 6 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 17 18 19 19 14 14 14 19 19 19 19 19 13 15 13 15 15 3 3 3 3 3 3 3 3 3 3 15 19 19 19 19 19 19 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 19 19 19 19 19 19 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 19 19 19 19 5] #^^[1 0 #^^[2 0 #^^[3 0 5 5 5 5 5 5 5 5 5 17 6 17 18 6 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 6 6 17 18 19 19 14 14 14 19 19 19 19 19 13 15 13 15 15 3 3 3 3 3 3 3 3 3 3 15 19 19 19 19 19 19 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 19 19 19 19 19 19 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 19 19 19 19 5] "…š„„ƒ…—Ÿˆ" 1 1 1 "¹‡ŽŽ…‰‘" "ð„ˆ" "„î‰" 1 "ƒ‡ö" 1 "Š„­¸" "…‹°•Šƒ" "Ö‡†„І" "Žž›³" "¦‹Ž«‰„†" "–„‰ƒ…«ƒ¤" " ‹·›" "ƒ·„ˆ„ƒ‡Šœ" "º„„ˆ”އ„" "¹„„ƒƒžƒŠ" "¹„…„”Ž" "º„ˆˆ‹œ" "½Œ¥†…" "¾ƒ…ƒ„‡‹”‡" "¼”œ" "Á„ˆ”œ" "ʇƒ©" "±‡„‡ˆ±" "±†‹†²" "˜›„³Ž" "……‹¤‰¹"] #^^[2 4096 "­„†™„ƒ„‹" "†â" 1 1 1 1 "݃ " "Šæ" "ÿ" 1 1 1 1 "šã" "’ƒƒžŒ" "´‡ˆ‹‡’І" "‹ƒñ" "©Ö" " ƒ„‰†ƒ„ƒº" "Þ¢" "—½‡ˆ†Š" 1 "„°……¨‰Œ" " „ºƒƒŽ" "¬ˆÈ" "Ѓ‡„†‹" 1 "À§•„" 1 1 1 "½ƒ‹ƒƒƒ"] #^^[2 8192 "‹ƒ˜ - …š……†ƒ† ƒ" "Š ƒ‘š–¡" "„Šƒ…†„‹„……„ " "‰†ð" "’ ì" 19 "¶Å…" "•ÞŒ" "§™‹• " "ˆ”Ζ" 19 19 19 "¬Ó" "ÿ" 19 1 1 19 19 19 19 "ÍƒŠ¦" 1 1 "冄ƒ‡‡" "ÿ" "à " "¼Ä" "šÙŒ" 19 "ÖšŒ„"] #^^[2 12288 "„ƒ™‰„……ƒÀ" "™ƒÚ„" 1 "À¤œ" "±œƒ" "±Œ„°" "÷„…" "ÞŸ" 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] #^^[2 16384 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 "ÀÀ" 1 1 1 1] 1 1 1 1 #^^[2 36864 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 + …š……†ƒ† ƒ" "Š ƒ‘›•¡" "„Šƒ…†„‹„……„ " "‰†ð" "’ ì" 19 "¶Å…" "•ÞŒ" "§™‹• " "ˆ”Ζ" 19 19 19 "¬Ó" "ÿ" 19 1 1 19 19 19 19 "ÍƒŠ¦" 1 1 "冄ƒ‡‡" "ÿ" "à " "¼Ä" "šÙŒ" 19 "ÖšŒ„"] #^^[2 12288 "„ƒ™‰„……ƒÀ" "™ƒÚ„" 1 "À¤œ" "±œƒ" "±Œ„°" "÷„…" "ÞŸ" 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] #^^[2 16384 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 "ÀÀ" 1 1 1 1] 1 1 1 1 #^^[2 36864 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 #^^[3 40832 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]] #^^[2 40960 1 1 1 1 1 1 1 1 1 "·¹" 1 1 "ƒß„Š" "ŸÐŽ" "¢Þ" "ˆ÷" "ƒ„™„Œº„ˆ" "Ä›’Ž" "¦ˆ™‹®" "ƒ°„Ã" "©†Œˆ³" "°ƒ…ªˆ‰" 1 "å„’" 1 1 1 1 1 1 1 1] 1 1 #^^[2 53248 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] 1 #^^[2 61440 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 "Š ¦°" 7 7 7 "¾À" "ý" "Š†‡‰ ‰ ƒ„" "ÿ" "ƒ…  Š†š†š‹š" "àƒ‡Š…"]] #^^[1 65536 #^^[2 65536 1 1 "¾À" "‹…Œá" 1 1 1 1 1 1 1 1 1 1 1 1 2 2 "Ÿà" 2 "ƒ…„¨ƒ„À" 2 "¹‡À" 2 2 2 2 2 "àŸ" 2 2 2] #^^[2 69632 "¶‹”š" "±„Å" "ƒ¤…ˆË" "´‰Á" 1 1 1 1 1 1 1 1 1 "«†È" 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] #^^[2 73728 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] #^^[2 77824 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] 1 1 #^^[2 90112 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 "„í"] 1 1 1 1 #^^[2 110592 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] 1 #^^[2 118784 1 1 "烉ˆ…" "ƒ‡ž„Ò" "ƒº" 1 "ש" 1 1 1 1 1 1 "Û¤" "•¹°" "‰¹Š²" 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] #^^[2 122880 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 "„›Š„†„ƒ„‡„„" "Š‘…ƒ…‘´Ž" 2 2] #^^[2 126976 "¬„Ð" "”ŒŽ " "‹ß”" 1 1 1 "¡†Æƒ" "”Œ¥…•‘" "¿¾" "ø„ƒ" "¾„Œ˜˜" "û…" "Á„‹°" "ƺ" "ôŒ" 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]] #^^[1 131072 1 1 1 1 1 1 1 1 1 1 #^^[2 172032 1 1 1 1 1 1 1 1 1 1 1 1 1 #^^[3 173696 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] #^^[2 176128 1 1 1 1 1 1 1 1 1 1 1 1 1 1 #^^[3 177920 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] 1 === modified file 'lisp/international/uni-category.el' --- lisp/international/uni-category.el 2012-04-07 14:26:14 +0000 +++ lisp/international/uni-category.el 2012-09-26 22:21:16 +0000 @@ -5,7 +5,7 @@ (define-char-code-property 'general-category #^[30 nil char-code-property-table #^^[3 0 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 23 18 18 18 20 18 18 18 14 15 18 19 18 13 18 18 9 9 9 9 9 9 9 9 9 9 18 18 19 19 19 18 18 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14 18 15 21 12 21 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 14 19 15 19 26] #^^[1 0 #^^[2 0 #^^[3 0 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 26 23 18 18 18 20 18 18 18 14 15 18 19 18 13 18 18 9 9 9 9 9 9 9 9 9 9 18 18 19 19 19 18 18 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 14 18 15 21 12 21 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 14 19 15 19 26] " „   ƒ—‡˜ˆ" "" "ƒ„ƒƒƒƒ„ƒ" "‡„±" "”›’„ŒŽ…‡‘" "ðƒ" "„ƒ‘‰£ƒƒ…ƒ" "°°" "…" "‰¦†Ÿ" "ˆ „­ ˆ›…ƒ‹" "…ƒ‹ Š• Š„" "Ô‡†„ Šƒ" "Žž›³" "¦‹Ž Š¡‰ƒ…" "–„‰ƒ…™ƒ¡" " ‹·›" "ƒ¶ƒˆ„‡Š І‡" "ˆ–‡ƒ„ƒ„ˆ„ƒ Š †„" "†„–‡ƒ„ƒƒ‡„‡ ŠƒŠ" "‰ƒ–‡…ƒ… ŠŽ" "ˆ–‡…„ˆ„ƒ Š †ˆ" "†ƒƒ„ƒƒƒƒƒŒ„ƒƒƒ†Ž Š ƒ†…" "ƒˆƒ—Š…ƒƒ„ƒ„‡† Šˆ ‡" "ˆƒ—Š……‡‡ Š" "ˆƒ©ƒ„ƒƒˆˆ Š †ƒ†" "’ƒ˜‰‡ƒ„ƒƒˆ’‹" "°‡„†ˆ Ф" "†„‡ƒ„†…† Š„ " "ƒƒ† Š Šˆ¤„Ž" "……‹¤ˆ†…„¥"] #^^[2 4096 "«„† І†„ƒƒ‡ƒ„‹" "† Šƒ¦…«ƒ" 5 5 "É„‡„ " "‰„¡„‡„¨" "‘„É ”ƒ" "Š†Õ‹" " ÿ" 5 5 5 "í‘" "šƒËƒ -ƒ" "„ƒ‹’ƒ‰’ŒƒŒ" "´‡ˆ‹ƒƒ І І" "† „ƒ І£´ˆ" "©…ÆŠ" "ƒƒ„ƒ„†ƒ„ƒ Šž…‹" "¬„‘‡† Š ƒ¢" "—ƒµ‡ˆ†Š" " І І‡†Ò" "„¯……‡„ ЇЉ‰ƒ" "ž„ Ьƒƒˆ„" "¤ˆˆƒ… Šƒƒ Šž†" "Àˆˆƒ‡„„‰" "¬¿‡" "›¥§•„" "" "‰" "ˆˆ††ˆˆˆˆ††ˆˆˆŽ" "ˆˆˆˆˆˆ…„ƒƒ„ƒ„„ƒˆ…ƒƒ„"] #^^[2 8192 "‹… †ˆ…‰„ ƒ‹ Š……†  †ƒ" " Šƒƒš–„ƒŒ" "„ƒƒ…†„„„…„  +ƒ" "„ƒ‹’ƒ‰’ŒƒŒ" "´‡ˆ‹ƒƒ І І" "† „ƒ І£´ˆ" "©…ÆŠ" "ƒƒ„ƒ„†ƒ„ƒ Šž…‹" "¬„‘‡† Š ƒ¢" "—ƒµ‡ˆ†Š" " І І‡†Ò" "„¯……‡„ ЇЉ‰ƒ" "ž„ Ьƒƒˆ„" "¤ˆˆƒ… Šƒƒ Šž†" "Àˆˆƒ‡„„‰" "¬¿‡" "›¥§•„" "" "‰" "ˆˆ††ˆˆˆˆ††ˆˆˆŽ" "ˆˆˆˆˆˆ…„ƒƒ„ƒ„„ƒˆ…ƒƒ„"] #^^[2 8192 "‹… †ˆ…‰„ ƒ‹ Š……†  †ƒ" " Šƒƒ›•„ƒŒ" "„ƒƒ…†„„„…„   " " ƒ „ †……„‡ŸŸŒ" 19 19 "ˆ„”‡Ñƒ" "›™¨†’Œ" "§™‹•  " " œÎ –" 22 "·‰¶ˆ" "ï" 22 "ç Š" " ”¬…Ÿ" 22 22 19 "ƒ¿ " 19 19 "°•†ƒŠ¦" 30 "¯¯ƒ„†" "†ƒ…„ " "¦…¸‡Ž" "—‰‡‡‡‡‡‡‡‡ " "ƒ‰  …Š Ä" "šÙŒ" 22 "ÖšŒ„"] #^^[2 12288 "ƒ === modified file 'lisp/international/uni-name.el' Binary files lisp/international/uni-name.el 2012-04-07 14:26:14 +0000 and lisp/international/uni-name.el 2012-09-26 22:21:16 +0000 differ === modified file 'lisp/international/uni-numeric.el' --- lisp/international/uni-numeric.el 2012-04-07 14:26:14 +0000 +++ lisp/international/uni-numeric.el 2012-09-26 22:21:16 +0000 @@ -69,8 +69,8 @@    -„ƒ -„-.4-. 3 " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 0 0 0 0 0 0 0 0 0 0 #^^[2 118784 0 0 0 0 0 0 "à +qr„ƒ +„ss-.4-. 3 " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 0 0 0 0 0 0 0 0 0 0 #^^[2 118784 0 0 0 0 0 0 "à  !\"#$%" 0 0 0 0 0 0 0 0 "Î   @@ -78,7 +78,7 @@  " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] 0 #^^[2 126976 0 0 " " 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]] #^^[1 131072 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 #^^[2 192512 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 " -" 0 0 0 0 0 0 0 0 0 0 0 0 0 0]] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 numeric-value 0 2 nil [nil 0 1 2 3 4 5 6 7 8 9 0.25 0.5 0.75 0.0625 0.125 0.1875 16 10 100 1000 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 -0.5 20 30 40 50 60 70 80 90 10000 17 18 19 0.14285714285714285 0.1111111111111111 0.1 0.3333333333333333 0.6666666666666666 0.2 0.4 0.6 0.8 0.16666666666666666 0.8333333333333334 0.375 0.625 0.875 11 12 500 5000 50000 100000 13 14 15 21 22 23 24 25 26 27 28 29 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46 47 48 49 200 300 400 600 700 800 900 2000 3000 4000 6000 7000 8000 9000 20000 30000 40000 60000 70000 80000 90000]] "Unicode numeric value (numeric). +" 0 0 0 0 0 0 0 0 0 0 0 0 0 0]] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 numeric-value 0 2 nil [nil 0 1 2 3 4 5 6 7 8 9 0.25 0.5 0.75 0.0625 0.125 0.1875 16 10 100 1000 1.5 2.5 3.5 4.5 5.5 6.5 7.5 8.5 -0.5 20 30 40 50 60 70 80 90 10000 17 18 19 0.14285714285714285 0.1111111111111111 0.1 0.3333333333333333 0.6666666666666666 0.2 0.4 0.6 0.8 0.16666666666666666 0.8333333333333334 0.375 0.625 0.875 11 12 500 5000 50000 100000 13 14 15 21 22 23 24 25 26 27 28 29 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46 47 48 49 200 300 400 600 700 800 900 2000 3000 4000 6000 7000 8000 9000 20000 30000 40000 60000 70000 80000 90000 216000 432000 -1]] "Unicode numeric value (numeric). Property value is an integer, a floating point, or nil. The value nil stands for NaN \"Numeric_Value\".") ;; Local Variables: ------------------------------------------------------------ revno: 110208 committer: Juanma Barranquero branch nick: trunk timestamp: Thu 2012-09-27 00:04:10 +0200 message: Fix some profiler stuff on Windows (follow-up to revno:11026). * lib-src/makefile.w32-in (obj): Add profiler.o. * src/makefile.w32-in ($(BLD)/profiler.$(O)): Update dependencies. diff: === modified file 'lib-src/ChangeLog' --- lib-src/ChangeLog 2012-09-17 00:56:08 +0000 +++ lib-src/ChangeLog 2012-09-26 22:04:10 +0000 @@ -1,3 +1,7 @@ +2012-09-26 Juanma Barranquero + + * makefile.w32-in (obj): Add profiler.o. + 2012-09-17 Glenn Morris * ebrowse.c (version): === modified file 'lib-src/makefile.w32-in' --- lib-src/makefile.w32-in 2012-08-17 01:53:29 +0000 +++ lib-src/makefile.w32-in 2012-09-26 22:04:10 +0000 @@ -140,7 +140,7 @@ process.o callproc.o unexw32.o \ region-cache.o sound.o atimer.o \ doprnt.o intervals.o textprop.o composite.o \ - gnutls.o xml.o + gnutls.o xml.o profiler.o # # These are the lisp files that are loaded up in loadup.el === modified file 'src/ChangeLog' --- src/ChangeLog 2012-09-26 20:00:29 +0000 +++ src/ChangeLog 2012-09-26 22:04:10 +0000 @@ -1,3 +1,7 @@ +2012-09-26 Juanma Barranquero + + * makefile.w32-in ($(BLD)/profiler.$(O)): Update dependencies. + 2012-09-26 Paul Eggert * character.h (MAYBE_UNIFY_CHAR): Remove. === modified file 'src/makefile.w32-in' --- src/makefile.w32-in 2012-09-26 15:19:10 +0000 +++ src/makefile.w32-in 2012-09-26 22:04:10 +0000 @@ -976,6 +976,7 @@ $(BLD)/profiler.$(O) : \ $(SRC)/profiler.c \ + $(NT_INC)/sys/time.h \ $(CONFIG_H) \ $(LISP_H) ------------------------------------------------------------ revno: 110207 committer: Paul Eggert branch nick: trunk timestamp: Wed 2012-09-26 13:00:29 -0700 message: * character.h (MAYBE_UNIFY_CHAR): Remove. * charset.c, charset.h (maybe_unify_char): Now static. * charset.c (decode_char): Use maybe_unify_char, not MAYBE_UNIFY_CHAR. Since this stuff is now private to charset.c, there's no need for a public macro and no need to inline by hand. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2012-09-26 15:19:10 +0000 +++ src/ChangeLog 2012-09-26 20:00:29 +0000 @@ -1,3 +1,11 @@ +2012-09-26 Paul Eggert + + * character.h (MAYBE_UNIFY_CHAR): Remove. + * charset.c, charset.h (maybe_unify_char): Now static. + * charset.c (decode_char): Use maybe_unify_char, not MAYBE_UNIFY_CHAR. + Since this stuff is now private to charset.c, there's no need for + a public macro and no need to inline by hand. + 2012-09-26 Tomohiro Matsuyama Stefan Monnier Juanma Barranquero === modified file 'src/character.h' --- src/character.h 2012-08-26 08:41:36 +0000 +++ src/character.h 2012-09-26 20:00:29 +0000 @@ -554,23 +554,6 @@ } while (0) -/* If C is a character to be unified with a Unicode character, return - the unified Unicode character. */ - -#define MAYBE_UNIFY_CHAR(c) \ - do { \ - if (c > MAX_UNICODE_CHAR && c <= MAX_5_BYTE_CHAR) \ - { \ - Lisp_Object val; \ - val = CHAR_TABLE_REF (Vchar_unify_table, c); \ - if (INTEGERP (val)) \ - c = XFASTINT (val); \ - else if (! NILP (val)) \ - c = maybe_unify_char (c, val); \ - } \ - } while (0) - - /* Return a non-outlandish value for the tab width. */ #define SANE_TAB_WIDTH(buf) \ === modified file 'src/charset.c' --- src/charset.c 2012-09-15 07:06:56 +0000 +++ src/charset.c 2012-09-26 20:00:29 +0000 @@ -1617,7 +1617,7 @@ /* Return a unified character code for C (>= 0x110000). VAL is a value of Vchar_unify_table for C; i.e. it is nil, an integer, or a charset symbol. */ -int +static int maybe_unify_char (int c, Lisp_Object val) { struct charset *charset; @@ -1723,8 +1723,12 @@ { c = char_index + CHARSET_CODE_OFFSET (charset); if (CHARSET_UNIFIED_P (charset) - && c > MAX_UNICODE_CHAR) - MAYBE_UNIFY_CHAR (c); + && MAX_UNICODE_CHAR < c && c <= MAX_5_BYTE_CHAR) + { + /* Unify C with a Unicode character if possible. */ + Lisp_Object val = CHAR_TABLE_REF (Vchar_unify_table, c); + c = maybe_unify_char (c, val); + } } } === modified file 'src/charset.h' --- src/charset.h 2012-08-27 16:19:34 +0000 +++ src/charset.h 2012-09-26 20:00:29 +0000 @@ -538,7 +538,6 @@ extern struct charset *char_charset (int, Lisp_Object, unsigned *); extern Lisp_Object charset_attributes (int); -extern int maybe_unify_char (int, Lisp_Object); extern int decode_char (struct charset *, unsigned); extern unsigned encode_char (struct charset *, int); extern int string_xstring_p (Lisp_Object); ------------------------------------------------------------ revno: 110206 [merge] committer: Stefan Monnier branch nick: trunk timestamp: Wed 2012-09-26 11:19:10 -0400 message: Merge profiler branch diff: === modified file 'etc/NEWS' --- etc/NEWS 2012-09-25 04:13:02 +0000 +++ etc/NEWS 2012-09-26 15:19:10 +0000 @@ -678,6 +678,11 @@ * Lisp changes in Emacs 24.3 +** New sampling-based Elisp profiler. +Try M-x profiler-start ... M-x profiler-stop; and then M-x profiler-report. +The sampling rate can be based on CPU time (only supported on some +systems), or based on memory allocations. + ** CL-style generalized variables are now in core Elisp. `setf' is autoloaded; `push' and `pop' accept generalized variables. === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-09-26 14:41:05 +0000 +++ lisp/ChangeLog 2012-09-26 15:19:10 +0000 @@ -1,3 +1,8 @@ +2012-09-26 Tomohiro Matsuyama + Stefan Monnier + + * profiler.el: New file. + 2012-09-26 Stefan Monnier * emacs-lisp/testcover.el (testcover-after): Add gv-expander. === added file 'lisp/profiler.el' --- lisp/profiler.el 1970-01-01 00:00:00 +0000 +++ lisp/profiler.el 2012-09-26 15:19:10 +0000 @@ -0,0 +1,665 @@ +;;; profiler.el --- UI and helper functions for Emacs's native profiler -*- lexical-binding: t -*- + +;; Copyright (C) 2012 Free Software Foundation, Inc. + +;; Author: Tomohiro Matsuyama +;; Keywords: lisp + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; + +;;; Code: + +(eval-when-compile + (require 'cl-lib)) + +(defgroup profiler nil + "Emacs profiler." + :group 'lisp + :prefix "profiler-") + +(defcustom profiler-sample-interval 1 + "Default sample interval in millisecond." + :type 'integer + :group 'profiler) + +;;; Utilities + +(defun profiler-ensure-string (object) + (cond ((stringp object) + object) + ((symbolp object) + (symbol-name object)) + ((numberp object) + (number-to-string object)) + (t + (format "%s" object)))) + +(defun profiler-format (fmt &rest args) + (cl-loop for (width align subfmt) in fmt + for arg in args + for str = (cond + ((consp subfmt) + (apply 'profiler-format subfmt arg)) + ((stringp subfmt) + (format subfmt arg)) + ((and (symbolp subfmt) + (fboundp subfmt)) + (funcall subfmt arg)) + (t + (profiler-ensure-string arg))) + for len = (length str) + if (< width len) + collect (substring str 0 width) into frags + else + collect + (let ((padding (make-string (- width len) ?\s))) + (cl-ecase align + (left (concat str padding)) + (right (concat padding str)))) + into frags + finally return (apply #'concat frags))) + +(defun profiler-format-percent (number divisor) + (concat (number-to-string (/ (* number 100) divisor)) "%")) + +(defun profiler-format-nbytes (nbytes) + "Format NBYTES in humarn readable string." + (if (and (integerp nbytes) (> nbytes 0)) + (cl-loop with i = (% (1+ (floor (log10 nbytes))) 3) + for c in (append (number-to-string nbytes) nil) + if (= i 0) + collect ?, into s + and do (setq i 3) + collect c into s + do (cl-decf i) + finally return + (apply 'string (if (eq (car s) ?,) (cdr s) s))) + (profiler-ensure-string nbytes))) + + +;;; Entries + +(defun profiler-entry-format (entry) + "Format ENTRY in human readable string. ENTRY would be a +function name of a function itself." + (cond ((memq (car-safe entry) '(closure lambda)) + (format "#" (sxhash entry))) + ((byte-code-function-p entry) + (format "#" (sxhash entry))) + ((or (subrp entry) (symbolp entry) (stringp entry)) + (format "%s" entry)) + (t + (format "#" (sxhash entry))))) + +;;; Log data structure + +;; The C code returns the log in the form of a hash-table where the keys are +;; vectors (of size profiler-max-stack-depth, holding truncated +;; backtraces, where the first element is the top of the stack) and +;; the values are integers (which count how many times this backtrace +;; has been seen, multiplied by a "weight factor" which is either the +;; sample-interval or the memory being allocated). +;; We extend it by adding a few other entries to the hash-table, most notably: +;; - Key `type' has a value indicating the kind of log (`memory' or `cpu'). +;; - Key `timestamp' has a value giving the time when the log was obtained. +;; - Key `diff-p' indicates if this log represents a diff between two logs. + +(defun profiler-log-timestamp (log) (gethash 'timestamp log)) +(defun profiler-log-type (log) (gethash 'type log)) +(defun profiler-log-diff-p (log) (gethash 'diff-p log)) + +(defun profiler-log-diff (log1 log2) + "Compare LOG1 with LOG2 and return a diff log. Both logs must +be same type." + (unless (eq (profiler-log-type log1) + (profiler-log-type log2)) + (error "Can't compare different type of logs")) + (let ((newlog (make-hash-table :test 'equal))) + ;; Make a copy of `log1' into `newlog'. + (maphash (lambda (backtrace count) (puthash backtrace count newlog)) + log1) + (puthash 'diff-p t newlog) + (maphash (lambda (backtrace count) + (when (vectorp backtrace) + (puthash backtrace (- (gethash backtrace log1 0) count) + newlog))) + log2) + newlog)) + +(defun profiler-log-fixup-entry (entry) + (if (symbolp entry) + entry + (profiler-entry-format entry))) + +(defun profiler-log-fixup-backtrace (backtrace) + (mapcar 'profiler-log-fixup-entry backtrace)) + +(defun profiler-log-fixup (log) + "Fixup LOG so that the log could be serialized into file." + (let ((newlog (make-hash-table :test 'equal))) + (maphash (lambda (backtrace count) + (puthash (if (not (vectorp backtrace)) + backtrace + (profiler-log-fixup-backtrace backtrace)) + count newlog)) + log) + newlog)) + +(defun profiler-log-write-file (log filename &optional confirm) + "Write LOG into FILENAME." + (with-temp-buffer + (let (print-level print-length) + (print (profiler-log-fixup log) (current-buffer))) + (write-file filename confirm))) + +(defun profiler-log-read-file (filename) + "Read log from FILENAME." + (with-temp-buffer + (insert-file-contents filename) + (goto-char (point-min)) + (read (current-buffer)))) + + +;;; Calltree data structure + +(cl-defstruct (profiler-calltree (:constructor profiler-make-calltree)) + entry + (count 0) (count-percent "") + parent children) + +(defun profiler-calltree-leaf-p (tree) + (null (profiler-calltree-children tree))) + +(defun profiler-calltree-count< (a b) + (cond ((eq (profiler-calltree-entry a) t) t) + ((eq (profiler-calltree-entry b) t) nil) + (t (< (profiler-calltree-count a) + (profiler-calltree-count b))))) + +(defun profiler-calltree-count> (a b) + (not (profiler-calltree-count< a b))) + +(defun profiler-calltree-depth (tree) + (let ((parent (profiler-calltree-parent tree))) + (if (null parent) + 0 + (1+ (profiler-calltree-depth parent))))) + +(defun profiler-calltree-find (tree entry) + "Return a child tree of ENTRY under TREE." + ;; OPTIMIZED + (let (result (children (profiler-calltree-children tree))) + ;; FIXME: Use `assoc'. + (while (and children (null result)) + (let ((child (car children))) + (when (equal (profiler-calltree-entry child) entry) + (setq result child)) + (setq children (cdr children)))) + result)) + +(defun profiler-calltree-walk (calltree function) + (funcall function calltree) + (dolist (child (profiler-calltree-children calltree)) + (profiler-calltree-walk child function))) + +(defun profiler-calltree-build-1 (tree log &optional reverse) + ;; FIXME: Do a better job of reconstructing a complete call-tree + ;; when the backtraces have been truncated. Ideally, we should be + ;; able to reduce profiler-max-stack-depth to 3 or 4 and still + ;; get a meaningful call-tree. + (maphash + (lambda (backtrace count) + (when (vectorp backtrace) + (let ((node tree) + (max (length backtrace))) + (dotimes (i max) + (let ((entry (aref backtrace (if reverse i (- max i 1))))) + (when entry + (let ((child (profiler-calltree-find node entry))) + (unless child + (setq child (profiler-make-calltree + :entry entry :parent node)) + (push child (profiler-calltree-children node))) + (cl-incf (profiler-calltree-count child) count) + (setq node child)))))))) + log)) + +(defun profiler-calltree-compute-percentages (tree) + (let ((total-count 0)) + ;; FIXME: the memory profiler's total wraps around all too easily! + (dolist (child (profiler-calltree-children tree)) + (cl-incf total-count (profiler-calltree-count child))) + (unless (zerop total-count) + (profiler-calltree-walk + tree (lambda (node) + (setf (profiler-calltree-count-percent node) + (profiler-format-percent (profiler-calltree-count node) + total-count))))))) + +(cl-defun profiler-calltree-build (log &key reverse) + (let ((tree (profiler-make-calltree))) + (profiler-calltree-build-1 tree log reverse) + (profiler-calltree-compute-percentages tree) + tree)) + +(defun profiler-calltree-sort (tree predicate) + (let ((children (profiler-calltree-children tree))) + (setf (profiler-calltree-children tree) (sort children predicate)) + (dolist (child (profiler-calltree-children tree)) + (profiler-calltree-sort child predicate)))) + + +;;; Report rendering + +(defcustom profiler-report-closed-mark "+" + "An indicator of closed calltrees." + :type 'string + :group 'profiler) + +(defcustom profiler-report-open-mark "-" + "An indicator of open calltrees." + :type 'string + :group 'profiler) + +(defcustom profiler-report-leaf-mark " " + "An indicator of calltree leaves." + :type 'string + :group 'profiler) + +(defvar profiler-report-sample-line-format + '((60 left) + (14 right ((9 right) + (5 right))))) + +(defvar profiler-report-memory-line-format + '((55 left) + (19 right ((14 right profiler-format-nbytes) + (5 right))))) + +(defvar-local profiler-report-log nil + "The current profiler log.") + +(defvar-local profiler-report-reversed nil + "True if calltree is rendered in bottom-up. Do not touch this +variable directly.") + +(defvar-local profiler-report-order nil + "The value can be `ascending' or `descending'. Do not touch +this variable directly.") + +(defun profiler-report-make-entry-part (entry) + (let ((string (cond + ((eq entry t) + "Others") + ((and (symbolp entry) + (fboundp entry)) + (propertize (symbol-name entry) + 'face 'link + 'mouse-face 'highlight + 'help-echo "mouse-2 or RET jumps to definition")) + (t + (profiler-entry-format entry))))) + (propertize string 'profiler-entry entry))) + +(defun profiler-report-make-name-part (tree) + (let* ((entry (profiler-calltree-entry tree)) + (depth (profiler-calltree-depth tree)) + (indent (make-string (* (1- depth) 2) ?\s)) + (mark (if (profiler-calltree-leaf-p tree) + profiler-report-leaf-mark + profiler-report-closed-mark)) + (entry (profiler-report-make-entry-part entry))) + (format "%s%s %s" indent mark entry))) + +(defun profiler-report-header-line-format (fmt &rest args) + (let* ((header (apply 'profiler-format fmt args)) + (escaped (replace-regexp-in-string "%" "%%" header))) + (concat " " escaped))) + +(defun profiler-report-line-format (tree) + (let ((diff-p (profiler-log-diff-p profiler-report-log)) + (name-part (profiler-report-make-name-part tree)) + (count (profiler-calltree-count tree)) + (count-percent (profiler-calltree-count-percent tree))) + (profiler-format (cl-ecase (profiler-log-type profiler-report-log) + (cpu profiler-report-sample-line-format) + (memory profiler-report-memory-line-format)) + name-part + (if diff-p + (list (if (> count 0) + (format "+%s" count) + count) + "") + (list count count-percent))))) + +(defun profiler-report-insert-calltree (tree) + (let ((line (profiler-report-line-format tree))) + (insert (propertize (concat line "\n") 'calltree tree)))) + +(defun profiler-report-insert-calltree-children (tree) + (mapc 'profiler-report-insert-calltree + (profiler-calltree-children tree))) + + +;;; Report mode + +(defvar profiler-report-mode-map + (let ((map (make-sparse-keymap))) + ;; FIXME: Add menu. + (define-key map "n" 'profiler-report-next-entry) + (define-key map "p" 'profiler-report-previous-entry) + ;; I find it annoying more than helpful to not be able to navigate + ;; normally with the cursor keys. --Stef + ;; (define-key map [down] 'profiler-report-next-entry) + ;; (define-key map [up] 'profiler-report-previous-entry) + (define-key map "\r" 'profiler-report-toggle-entry) + (define-key map "\t" 'profiler-report-toggle-entry) + (define-key map "i" 'profiler-report-toggle-entry) + (define-key map "f" 'profiler-report-find-entry) + (define-key map "j" 'profiler-report-find-entry) + (define-key map [mouse-2] 'profiler-report-find-entry) + (define-key map "d" 'profiler-report-describe-entry) + (define-key map "C" 'profiler-report-render-calltree) + (define-key map "B" 'profiler-report-render-reversed-calltree) + (define-key map "A" 'profiler-report-ascending-sort) + (define-key map "D" 'profiler-report-descending-sort) + (define-key map "=" 'profiler-report-compare-log) + (define-key map (kbd "C-x C-w") 'profiler-report-write-log) + (define-key map "q" 'quit-window) + map)) + +(defun profiler-report-make-buffer-name (log) + (format "*%s-Profiler-Report %s*" + (cl-ecase (profiler-log-type log) (cpu 'CPU) (memory 'Memory)) + (format-time-string "%Y-%m-%d %T" (profiler-log-timestamp log)))) + +(defun profiler-report-setup-buffer (log) + "Make a buffer for LOG and return it." + (let* ((buf-name (profiler-report-make-buffer-name log)) + (buffer (get-buffer-create buf-name))) + (with-current-buffer buffer + (profiler-report-mode) + (setq profiler-report-log log + profiler-report-reversed nil + profiler-report-order 'descending)) + buffer)) + +(define-derived-mode profiler-report-mode special-mode "Profiler-Report" + "Profiler Report Mode." + (setq buffer-read-only t + buffer-undo-list t + truncate-lines t)) + + +;;; Report commands + +(defun profiler-report-calltree-at-point () + (get-text-property (point) 'calltree)) + +(defun profiler-report-move-to-entry () + (let ((point (next-single-property-change (line-beginning-position) + 'profiler-entry))) + (if point + (goto-char point) + (back-to-indentation)))) + +(defun profiler-report-next-entry () + "Move cursor to next entry." + (interactive) + (forward-line) + (profiler-report-move-to-entry)) + +(defun profiler-report-previous-entry () + "Move cursor to previous entry." + (interactive) + (forward-line -1) + (profiler-report-move-to-entry)) + +(defun profiler-report-expand-entry () + "Expand entry at point." + (interactive) + (save-excursion + (beginning-of-line) + (when (search-forward (concat profiler-report-closed-mark " ") + (line-end-position) t) + (let ((tree (profiler-report-calltree-at-point))) + (when tree + (let ((inhibit-read-only t)) + (replace-match (concat profiler-report-open-mark " ")) + (forward-line) + (profiler-report-insert-calltree-children tree) + t)))))) + +(defun profiler-report-collapse-entry () + "Collpase entry at point." + (interactive) + (save-excursion + (beginning-of-line) + (when (search-forward (concat profiler-report-open-mark " ") + (line-end-position) t) + (let* ((tree (profiler-report-calltree-at-point)) + (depth (profiler-calltree-depth tree)) + (start (line-beginning-position 2)) + d) + (when tree + (let ((inhibit-read-only t)) + (replace-match (concat profiler-report-closed-mark " ")) + (while (and (eq (forward-line) 0) + (let ((child (get-text-property (point) 'calltree))) + (and child + (numberp (setq d (profiler-calltree-depth child))))) + (> d depth))) + (delete-region start (line-beginning-position))))) + t))) + +(defun profiler-report-toggle-entry () + "Expand entry at point if the tree is collapsed, +otherwise collapse." + (interactive) + (or (profiler-report-expand-entry) + (profiler-report-collapse-entry))) + +(defun profiler-report-find-entry (&optional event) + "Find entry at point." + (interactive (list last-nonmenu-event)) + (if event (posn-set-point (event-end event))) + (let ((tree (profiler-report-calltree-at-point))) + (when tree + (let ((entry (profiler-calltree-entry tree))) + (find-function entry))))) + +(defun profiler-report-describe-entry () + "Describe entry at point." + (interactive) + (let ((tree (profiler-report-calltree-at-point))) + (when tree + (let ((entry (profiler-calltree-entry tree))) + (require 'help-fns) + (describe-function entry))))) + +(cl-defun profiler-report-render-calltree-1 + (log &key reverse (order 'descending)) + (let ((calltree (profiler-calltree-build profiler-report-log + :reverse reverse))) + (setq header-line-format + (cl-ecase (profiler-log-type log) + (cpu + (profiler-report-header-line-format + profiler-report-sample-line-format + "Function" (list "Time (ms)" "%"))) + (memory + (profiler-report-header-line-format + profiler-report-memory-line-format + "Function" (list "Bytes" "%"))))) + (let ((predicate (cl-ecase order + (ascending #'profiler-calltree-count<) + (descending #'profiler-calltree-count>)))) + (profiler-calltree-sort calltree predicate)) + (let ((inhibit-read-only t)) + (erase-buffer) + (profiler-report-insert-calltree-children calltree) + (goto-char (point-min)) + (profiler-report-move-to-entry)))) + +(defun profiler-report-rerender-calltree () + (profiler-report-render-calltree-1 profiler-report-log + :reverse profiler-report-reversed + :order profiler-report-order)) + +(defun profiler-report-render-calltree () + "Render calltree view." + (interactive) + (setq profiler-report-reversed nil) + (profiler-report-rerender-calltree)) + +(defun profiler-report-render-reversed-calltree () + "Render reversed calltree view." + (interactive) + (setq profiler-report-reversed t) + (profiler-report-rerender-calltree)) + +(defun profiler-report-ascending-sort () + "Sort calltree view in ascending order." + (interactive) + (setq profiler-report-order 'ascending) + (profiler-report-rerender-calltree)) + +(defun profiler-report-descending-sort () + "Sort calltree view in descending order." + (interactive) + (setq profiler-report-order 'descending) + (profiler-report-rerender-calltree)) + +(defun profiler-report-log (log) + (let ((buffer (profiler-report-setup-buffer log))) + (with-current-buffer buffer + (profiler-report-render-calltree)) + (pop-to-buffer buffer))) + +(defun profiler-report-compare-log (buffer) + "Compare the current profiler log with another." + (interactive (list (read-buffer "Compare to: "))) + (let* ((log1 (with-current-buffer buffer profiler-report-log)) + (log2 profiler-report-log) + (diff-log (profiler-log-diff log1 log2))) + (profiler-report-log diff-log))) + +(defun profiler-report-write-log (filename &optional confirm) + "Write the current profiler log into FILENAME." + (interactive + (list (read-file-name "Write log: " default-directory) + (not current-prefix-arg))) + (profiler-log-write-file profiler-report-log + filename + confirm)) + + +;;; Profiler commands + +;;;###autoload +(defun profiler-start (mode) + "Start/restart profilers. +MODE can be one of `cpu', `mem', or `cpu+mem'. +If MODE is `cpu' or `cpu+mem', time-based profiler will be started. +Also, if MODE is `mem' or `cpu+mem', then memory profiler will be started." + (interactive + (list (if (not (fboundp 'profiler-cpu-start)) 'mem + (intern (completing-read "Mode (default cpu): " + '("cpu" "mem" "cpu+mem") + nil t nil nil "cpu"))))) + (cl-ecase mode + (cpu + (profiler-cpu-start profiler-sample-interval) + (message "CPU profiler started")) + (mem + (profiler-memory-start) + (message "Memory profiler started")) + (cpu+mem + (profiler-cpu-start profiler-sample-interval) + (profiler-memory-start) + (message "CPU and memory profiler started")))) + +(defun profiler-stop () + "Stop started profilers. Profiler logs will be kept." + (interactive) + (let ((cpu (if (fboundp 'profiler-cpu-stop) (profiler-cpu-stop))) + (mem (profiler-memory-stop))) + (message "%s profiler stopped" + (cond ((and mem cpu) "CPU and memory") + (mem "Memory") + (cpu "CPU") + (t "No"))))) + +(defun profiler-reset () + "Reset profiler log." + (interactive) + (when (fboundp 'profiler-cpu-log) + (ignore (profiler-cpu-log))) + (ignore (profiler-memory-log)) + t) + +(defun profiler--report-cpu () + (let ((log (if (fboundp 'profiler-cpu-log) (profiler-cpu-log)))) + (when log + (puthash 'type 'cpu log) + (puthash 'timestamp (current-time) log) + (profiler-report-log log)))) + +(defun profiler--report-memory () + (let ((log (profiler-memory-log))) + (when log + (puthash 'type 'memory log) + (puthash 'timestamp (current-time) log) + (profiler-report-log log)))) + +(defun profiler-report () + "Report profiling results." + (interactive) + (profiler--report-cpu) + (profiler--report-memory)) + +;;;###autoload +(defun profiler-find-log (filename) + "Read a profiler log from FILENAME and report it." + (interactive + (list (read-file-name "Find log: " default-directory))) + (profiler-report-log (profiler-log-read-file filename))) + + +;;; Profiling helpers + +;; (cl-defmacro with-sample-profiling ((&key interval) &rest body) +;; `(unwind-protect +;; (progn +;; (ignore (profiler-cpu-log)) +;; (profiler-cpu-start ,interval) +;; ,@body) +;; (profiler-cpu-stop) +;; (profiler--report-cpu))) + +;; (defmacro with-memory-profiling (&rest body) +;; `(unwind-protect +;; (progn +;; (ignore (profiler-memory-log)) +;; (profiler-memory-start) +;; ,@body) +;; (profiler-memory-stop) +;; (profiler--report-memory))) + +(provide 'profiler) +;;; profiler.el ends here === modified file 'src/ChangeLog' --- src/ChangeLog 2012-09-26 14:44:22 +0000 +++ src/ChangeLog 2012-09-26 15:19:10 +0000 @@ -1,3 +1,29 @@ +2012-09-26 Tomohiro Matsuyama + Stefan Monnier + Juanma Barranquero + + * profiler.c: New file. + * Makefile.in (base_obj): Add profiler.o. + * makefile.w32-in (OBJ2, GLOBAL_SOURCES): Add profiler.c. + ($(BLD)/profiler.$(O)): New target. + * emacs.c (main): Call syms_of_profiler. + * alloc.c (Qautomatic_gc): New constant. + (MALLOC_PROBE): New macro. + (xmalloc, xzalloc, xrealloc, lisp_malloc, lisp_align_malloc): Use it. + (total_bytes_of_live_objects): New function. + (Fgarbage_collect): Use it. Record itself in backtrace_list. + Call malloc_probe for the memory profiler. + (syms_of_alloc): Define Qautomatic_gc. + * eval.c (eval_sub, Ffuncall): Reorder assignments to avoid + race condition. + (struct backtrace): Move definition... + * lisp.h (struct backtrace): ..here. + (Qautomatic_gc, profiler_memory_running): Declare vars. + (malloc_probe, syms_of_profiler): Declare functions. + * xdisp.c (Qautomatic_redisplay): New constant. + (redisplay_internal): Record itself in backtrace_list. + (syms_of_xdisp): Define Qautomatic_redisplay. + 2012-09-25 Juanma Barranquero * makefile.w32-in ($(BLD)/callproc.$(O)): Update dependencies. @@ -291,8 +317,8 @@ (reinvoke_input_signal): Remove. All uses replaced by handle_async_input. (quit_count): Now volatile, since a signal handler uses it. - (handle_interrupt): Now takes bool IN_SIGNAL_HANDLER as arg. All - callers changed. Block SIGINT only if not already blocked. + (handle_interrupt): Now takes bool IN_SIGNAL_HANDLER as arg. + All callers changed. Block SIGINT only if not already blocked. Clear sigmask reliably, even if Fsignal returns, which it can. Omit unnecessary accesses to volatile var. (quit_throw_to_read_char): No need to restore sigmask. @@ -392,8 +418,8 @@ if it is defined. Arguments and return value changed. (valid_image_p, make_image): Callers changed. (xbm_type, xpm_type, pbm_type, png_type, jpeg_type, tiff_type) - (gif_type, imagemagick_type, svg_type, gs_type): Add - initialization functions. + (gif_type, imagemagick_type, svg_type, gs_type): + Add initialization functions. (Finit_image_library): Call lookup_image_type. (CHECK_LIB_AVAILABLE): Macro deleted. (lookup_image_type): Call define_image_type here, rather than via @@ -415,8 +441,8 @@ * window.c (Fsplit_window_internal): Handle only Qt value of Vwindow_combination_limit separately. (Qtemp_buffer_resize): New symbol. - (Vwindow_combination_limit): New default value. Rewrite - doc-string. + (Vwindow_combination_limit): New default value. + Rewrite doc-string. 2012-09-22 Eli Zaretskii @@ -515,7 +541,7 @@ (Fx_create_frame): Call x_set_offset to correctly interpret top_pos in geometry. - * frame.c (read_integer, XParseGeometry): Moved from w32xfns.c. + * frame.c (read_integer, XParseGeometry): Move from w32xfns.c. (Fx_parse_geometry): If there is a space in string, call Qns_parse_geometry, otherwise do as on other terms (Bug#12368). @@ -616,8 +642,8 @@ 2012-09-16 Martin Rudalics - * window.c (Fwindow_parameter, Fset_window_parameter): Accept - any window as argument (Bug#12452). + * window.c (Fwindow_parameter, Fset_window_parameter): + Accept any window as argument (Bug#12452). 2012-09-16 Jan Djärv @@ -692,8 +718,8 @@ 2012-09-14 Dmitry Antipov Avoid out-of-range marker position (Bug#12426). - * insdel.c (replace_range, replace_range_2): Adjust - markers before overlays, as suggested by comments. + * insdel.c (replace_range, replace_range_2): + Adjust markers before overlays, as suggested by comments. (insert_1_both, insert_from_buffer_1, adjust_after_replace): Remove redundant check before calling offset_intervals. @@ -992,8 +1018,8 @@ in the internal border. (x_set_window_size): Remove static variables and their usage. (ns_redraw_scroll_bars): Fix NSTRACE arg. - (ns_after_update_window_line, ns_draw_fringe_bitmap): Remove - fringe/internal border adjustment (Bug#11052). + (ns_after_update_window_line, ns_draw_fringe_bitmap): + Remove fringe/internal border adjustment (Bug#11052). (ns_draw_fringe_bitmap): Make code more like other terms (xterm.c). (ns_draw_window_cursor): Remove fringe/internal border adjustment. (ns_fix_rect_ibw): Remove. @@ -1210,8 +1236,8 @@ (init_signals) [FORWARD_SIGNAL_TO_MAIN_THREAD]: Initialize it; code moved here from emacs.c's main function. * sysdep.c, syssignal.h (handle_on_main_thread): New function, - replacing the old SIGNAL_THREAD_CHECK. All uses changed. This - lets callers save and restore errno properly. + replacing the old SIGNAL_THREAD_CHECK. All uses changed. + This lets callers save and restore errno properly. 2012-09-05 Dmitry Antipov @@ -1520,8 +1546,8 @@ * process.c: Include TERM_HEADER instead of listing all possible window-system headers. - * nsterm.h: Remove declarations now in frame.h. Define - FRAME_X_SCREEN, FRAME_X_VISUAL. + * nsterm.h: Remove declarations now in frame.h. + Define FRAME_X_SCREEN, FRAME_X_VISUAL. * menu.c: Include TERM_HEADER instead of listing all possible window-system headers. @@ -1717,8 +1743,8 @@ * nsterm.h (NSPanel): New class variable dialog_return. - * nsmenu.m (initWithContentRect:styleMask:backing:defer:): Initialize - dialog_return. + * nsmenu.m (initWithContentRect:styleMask:backing:defer:): + Initialize dialog_return. (windowShouldClose:): Use stop instead of stopModalWithCode. (clicked:): Ditto, and also set dialog_return (Bug#12258). (timeout_handler:): Use stop instead of abortModal. Send a dummy === modified file 'src/Makefile.in' --- src/Makefile.in 2012-09-16 19:17:20 +0000 +++ src/Makefile.in 2012-09-26 15:19:10 +0000 @@ -339,6 +339,7 @@ process.o gnutls.o callproc.o \ region-cache.o sound.o atimer.o \ doprnt.o intervals.o textprop.o composite.o xml.o \ + profiler.o \ $(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \ $(WINDOW_SYSTEM_OBJ) obj = $(base_obj) $(NS_OBJC_OBJ) === modified file 'src/alloc.c' --- src/alloc.c 2012-09-23 17:05:14 +0000 +++ src/alloc.c 2012-09-26 15:19:10 +0000 @@ -205,6 +205,7 @@ static Lisp_Object Qbuffers; static Lisp_Object Qstring_bytes, Qvector_slots, Qheap; static Lisp_Object Qgc_cons_threshold; +Lisp_Object Qautomatic_gc; Lisp_Object Qchar_table_extra_slots; /* Hook run after GC has finished. */ @@ -648,6 +649,13 @@ # define MALLOC_UNBLOCK_INPUT ((void) 0) #endif +#define MALLOC_PROBE(size) \ + do { \ + if (profiler_memory_running) \ + malloc_probe (size); \ + } while (0) + + /* Like malloc but check for no memory and block interrupt input.. */ void * @@ -661,6 +669,7 @@ if (!val && size) memory_full (size); + MALLOC_PROBE (size); return val; } @@ -678,6 +687,7 @@ if (!val && size) memory_full (size); memset (val, 0, size); + MALLOC_PROBE (size); return val; } @@ -699,6 +709,7 @@ if (!val && size) memory_full (size); + MALLOC_PROBE (size); return val; } @@ -888,6 +899,7 @@ MALLOC_UNBLOCK_INPUT; if (!val && nbytes) memory_full (nbytes); + MALLOC_PROBE (nbytes); return val; } @@ -1093,6 +1105,8 @@ MALLOC_UNBLOCK_INPUT; + MALLOC_PROBE (nbytes); + eassert (0 == ((uintptr_t) val) % BLOCK_ALIGN); return val; } @@ -5043,6 +5057,23 @@ return make_number (min (MOST_POSITIVE_FIXNUM, number)); } +/* Calculate total bytes of live objects. */ + +static size_t +total_bytes_of_live_objects (void) +{ + size_t tot = 0; + tot += total_conses * sizeof (struct Lisp_Cons); + tot += total_symbols * sizeof (struct Lisp_Symbol); + tot += total_markers * sizeof (union Lisp_Misc); + tot += total_string_bytes; + tot += total_vector_slots * word_size; + tot += total_floats * sizeof (struct Lisp_Float); + tot += total_intervals * sizeof (struct interval); + tot += total_strings * sizeof (struct Lisp_String); + return tot; +} + DEFUN ("garbage-collect", Fgarbage_collect, Sgarbage_collect, 0, 0, "", doc: /* Reclaim storage for Lisp objects no longer needed. Garbage collection happens automatically if you cons more than @@ -5068,6 +5099,8 @@ ptrdiff_t count = SPECPDL_INDEX (); EMACS_TIME start; Lisp_Object retval = Qnil; + size_t tot_before = 0; + struct backtrace backtrace; if (abort_on_gc) emacs_abort (); @@ -5077,6 +5110,14 @@ if (pure_bytes_used_before_overflow) return Qnil; + /* Record this function, so it appears on the profiler's backtraces. */ + backtrace.next = backtrace_list; + backtrace.function = &Qautomatic_gc; + backtrace.args = &Qautomatic_gc; + backtrace.nargs = 0; + backtrace.debug_on_exit = 0; + backtrace_list = &backtrace; + check_cons_list (); /* Don't keep undo information around forever. @@ -5084,6 +5125,9 @@ FOR_EACH_BUFFER (nextb) compact_buffer (nextb); + if (profiler_memory_running) + tot_before = total_bytes_of_live_objects (); + start = current_emacs_time (); /* In case user calls debug_print during GC, @@ -5255,16 +5299,7 @@ gc_relative_threshold = 0; if (FLOATP (Vgc_cons_percentage)) { /* Set gc_cons_combined_threshold. */ - double tot = 0; - - tot += total_conses * sizeof (struct Lisp_Cons); - tot += total_symbols * sizeof (struct Lisp_Symbol); - tot += total_markers * sizeof (union Lisp_Misc); - tot += total_string_bytes; - tot += total_vector_slots * word_size; - tot += total_floats * sizeof (struct Lisp_Float); - tot += total_intervals * sizeof (struct interval); - tot += total_strings * sizeof (struct Lisp_String); + double tot = total_bytes_of_live_objects (); tot *= XFLOAT_DATA (Vgc_cons_percentage); if (0 < tot) @@ -5367,6 +5402,17 @@ gcs_done++; + /* Collect profiling data. */ + if (profiler_memory_running) + { + size_t swept = 0; + size_t tot_after = total_bytes_of_live_objects (); + if (tot_before > tot_after) + swept = tot_before - tot_after; + malloc_probe (swept); + } + + backtrace_list = backtrace.next; return retval; } @@ -6527,6 +6573,7 @@ DEFSYM (Qstring_bytes, "string-bytes"); DEFSYM (Qvector_slots, "vector-slots"); DEFSYM (Qheap, "heap"); + DEFSYM (Qautomatic_gc, "Automatic GC"); DEFSYM (Qgc_cons_threshold, "gc-cons-threshold"); DEFSYM (Qchar_table_extra_slots, "char-table-extra-slots"); === modified file 'src/emacs.c' --- src/emacs.c 2012-09-25 11:57:30 +0000 +++ src/emacs.c 2012-09-26 15:19:10 +0000 @@ -1419,6 +1419,8 @@ syms_of_ntterm (); #endif /* WINDOWSNT */ + syms_of_profiler (); + keys_of_casefiddle (); keys_of_cmds (); keys_of_buffer (); === modified file 'src/eval.c' --- src/eval.c 2012-09-23 08:44:20 +0000 +++ src/eval.c 2012-09-26 15:19:10 +0000 @@ -31,17 +31,7 @@ #include "xterm.h" #endif -struct backtrace -{ - struct backtrace *next; - Lisp_Object *function; - Lisp_Object *args; /* Points to vector of args. */ - ptrdiff_t nargs; /* Length of vector. */ - /* Nonzero means call value of debugger when done with this operation. */ - unsigned int debug_on_exit : 1; -}; - -static struct backtrace *backtrace_list; +struct backtrace *backtrace_list; #if !BYTE_MARK_STACK static @@ -2055,11 +2045,11 @@ original_args = XCDR (form); backtrace.next = backtrace_list; - backtrace_list = &backtrace; backtrace.function = &original_fun; /* This also protects them from gc. */ backtrace.args = &original_args; backtrace.nargs = UNEVALLED; backtrace.debug_on_exit = 0; + backtrace_list = &backtrace; if (debug_on_next_call) do_debug_on_call (Qt); @@ -2730,11 +2720,11 @@ } backtrace.next = backtrace_list; - backtrace_list = &backtrace; backtrace.function = &args[0]; backtrace.args = &args[1]; /* This also GCPROs them. */ backtrace.nargs = nargs - 1; backtrace.debug_on_exit = 0; + backtrace_list = &backtrace; /* Call GC after setting up the backtrace, so the latter GCPROs the args. */ maybe_gc (); === modified file 'src/lisp.h' --- src/lisp.h 2012-09-25 11:57:30 +0000 +++ src/lisp.h 2012-09-26 15:19:10 +0000 @@ -2031,6 +2031,18 @@ #define SPECPDL_INDEX() (specpdl_ptr - specpdl) +struct backtrace +{ + struct backtrace *next; + Lisp_Object *function; + Lisp_Object *args; /* Points to vector of args. */ + ptrdiff_t nargs; /* Length of vector. */ + /* Nonzero means call value of debugger when done with this operation. */ + unsigned int debug_on_exit : 1; +}; + +extern struct backtrace *backtrace_list; + /* Everything needed to describe an active condition case. Members are volatile if their values need to survive _longjmp when @@ -2916,6 +2928,7 @@ extern Lisp_Object pure_cons (Lisp_Object, Lisp_Object); extern void make_byte_code (struct Lisp_Vector *); +extern Lisp_Object Qautomatic_gc; extern Lisp_Object Qchar_table_extra_slots; extern struct Lisp_Vector *allocate_vector (EMACS_INT); extern struct Lisp_Vector *allocate_pseudovector (int memlen, int lisplen, int tag); @@ -3534,6 +3547,13 @@ void syms_of_dbusbind (void); #endif + +/* Defined in profiler.c. */ +extern bool profiler_memory_running; +extern void malloc_probe (size_t); +extern void syms_of_profiler (void); + + #ifdef DOS_NT /* Defined in msdos.c, w32.c. */ extern char *emacs_root_dir (void); === modified file 'src/makefile.w32-in' --- src/makefile.w32-in 2012-09-25 22:07:22 +0000 +++ src/makefile.w32-in 2012-09-26 15:19:10 +0000 @@ -125,6 +125,7 @@ $(BLD)/terminal.$(O) \ $(BLD)/menu.$(O) \ $(BLD)/xml.$(O) \ + $(BLD)/profiler.$(O) \ $(BLD)/w32term.$(O) \ $(BLD)/w32xfns.$(O) \ $(BLD)/w32fns.$(O) \ @@ -222,7 +223,7 @@ process.c callproc.c unexw32.c \ region-cache.c sound.c atimer.c \ doprnt.c intervals.c textprop.c composite.c \ - gnutls.c xml.c + gnutls.c xml.c profiler.c SOME_MACHINE_OBJECTS = dosfns.o msdos.o \ xterm.o xfns.o xmenu.o xselect.o xrdb.o xsmfns.o dbusbind.o obj = $(GLOBAL_SOURCES:.c=.o) @@ -973,6 +974,11 @@ $(CONFIG_H) \ $(LISP_H) +$(BLD)/profiler.$(O) : \ + $(SRC)/profiler.c \ + $(CONFIG_H) \ + $(LISP_H) + $(BLD)/image.$(O) : \ $(SRC)/image.c \ $(SRC)/blockinput.h \ === added file 'src/profiler.c' --- src/profiler.c 1970-01-01 00:00:00 +0000 +++ src/profiler.c 2012-09-26 15:19:10 +0000 @@ -0,0 +1,426 @@ +/* Profiler implementation. + +Copyright (C) 2012 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs. If not, see . */ + +#include +#include +#include +#include +#include +#include +#include "lisp.h" + +/* Logs. */ + +typedef struct Lisp_Hash_Table log_t; + +static Lisp_Object +make_log (int heap_size, int max_stack_depth) +{ + /* We use a standard Elisp hash-table object, but we use it in + a special way. This is OK as long as the object is not exposed + to Elisp, i.e. until it is returned by *-profiler-log, after which + it can't be used any more. */ + Lisp_Object log = make_hash_table (Qequal, make_number (heap_size), + make_float (DEFAULT_REHASH_SIZE), + make_float (DEFAULT_REHASH_THRESHOLD), + Qnil, Qnil, Qnil); + struct Lisp_Hash_Table *h = XHASH_TABLE (log); + + /* What is special about our hash-tables is that the keys are pre-filled + with the vectors we'll put in them. */ + int i = ASIZE (h->key_and_value) / 2; + while (0 < i) + set_hash_key_slot (h, --i, + Fmake_vector (make_number (max_stack_depth), Qnil)); + return log; +} + +/* Evict the least used half of the hash_table. + + When the table is full, we have to evict someone. + The easiest and most efficient is to evict the value we're about to add + (i.e. once the table is full, stop sampling). + + We could also pick the element with the lowest count and evict it, + but finding it is O(N) and for that amount of work we get very + little in return: for the next sample, this latest sample will have + count==1 and will hence be a prime candidate for eviction :-( + + So instead, we take O(N) time to eliminate more or less half of the + entries (the half with the lowest counts). So we get an amortized + cost of O(1) and we get O(N) time for a new entry to grow larger + than the other least counts before a new round of eviction. */ + +static EMACS_INT approximate_median (log_t *log, + ptrdiff_t start, ptrdiff_t size) +{ + eassert (size > 0); + if (size < 2) + return XINT (HASH_VALUE (log, start)); + if (size < 3) + /* Not an actual median, but better for our application than + choosing either of the two numbers. */ + return ((XINT (HASH_VALUE (log, start)) + + XINT (HASH_VALUE (log, start + 1))) + / 2); + else + { + ptrdiff_t newsize = size / 3; + ptrdiff_t start2 = start + newsize; + EMACS_INT i1 = approximate_median (log, start, newsize); + EMACS_INT i2 = approximate_median (log, start2, newsize); + EMACS_INT i3 = approximate_median (log, start2 + newsize, + size - 2 * newsize); + return (i1 < i2 + ? (i2 < i3 ? i2 : (i1 < i3 ? i3 : i1)) + : (i1 < i3 ? i1 : (i2 < i3 ? i3 : i2))); + } +} + +static void evict_lower_half (log_t *log) +{ + ptrdiff_t size = ASIZE (log->key_and_value) / 2; + EMACS_INT median = approximate_median (log, 0, size); + ptrdiff_t i; + + for (i = 0; i < size; i++) + /* Evict not only values smaller but also values equal to the median, + so as to make sure we evict something no matter what. */ + if (XINT (HASH_VALUE (log, i)) <= median) + { + Lisp_Object key = HASH_KEY (log, i); + { /* FIXME: we could make this more efficient. */ + Lisp_Object tmp; + XSET_HASH_TABLE (tmp, log); /* FIXME: Use make_lisp_ptr. */ + Fremhash (key, tmp); + } + eassert (EQ (log->next_free, make_number (i))); + { + int j; + eassert (VECTORP (key)); + for (j = 0; j < ASIZE (key); j++) + ASET (key, j, Qnil); + } + set_hash_key_slot (log, i, key); + } +} + +/* Record the current backtrace in LOG. BASE is a special name for + describing which the backtrace come from. BASE can be nil. COUNT is + a number how many times the profiler sees the backtrace at the + time. ELAPSED is a elapsed time in millisecond that the backtrace + took. */ + +static void +record_backtrace (log_t *log, size_t count) +{ + struct backtrace *backlist = backtrace_list; + Lisp_Object backtrace; + ptrdiff_t index, i = 0; + ptrdiff_t asize; + + if (!INTEGERP (log->next_free)) + /* FIXME: transfer the evicted counts to a special entry rather + than dropping them on the floor. */ + evict_lower_half (log); + index = XINT (log->next_free); + + /* Get a "working memory" vector. */ + backtrace = HASH_KEY (log, index); + asize = ASIZE (backtrace); + + /* Copy the backtrace contents into working memory. */ + for (; i < asize && backlist; i++, backlist = backlist->next) + /* FIXME: For closures we should ignore the environment. */ + ASET (backtrace, i, *backlist->function); + + /* Make sure that unused space of working memory is filled with nil. */ + for (; i < asize; i++) + ASET (backtrace, i, Qnil); + + { /* We basically do a `gethash+puthash' here, except that we have to be + careful to avoid memory allocation since we're in a signal + handler, and we optimize the code to try and avoid computing the + hash+lookup twice. See fns.c:Fputhash for reference. */ + EMACS_UINT hash; + ptrdiff_t j = hash_lookup (log, backtrace, &hash); + if (j >= 0) + set_hash_value_slot (log, j, + make_number (count + XINT (HASH_VALUE (log, j)))); + else + { /* BEWARE! hash_put in general can allocate memory. + But currently it only does that if log->next_free is nil. */ + int j; + eassert (!NILP (log->next_free)); + j = hash_put (log, backtrace, make_number (count), hash); + /* Let's make sure we've put `backtrace' right where it + already was to start with. */ + eassert (index == j); + + /* FIXME: If the hash-table is almost full, we should set + some global flag so that some Elisp code can offload its + data elsewhere, so as to avoid the eviction code. + There are 2 ways to do that, AFAICT: + - Set a flag checked in QUIT, such that QUIT can then call + Fprofiler_cpu_log and stash the full log for later use. + - Set a flag check in post-gc-hook, so that Elisp code can call + profiler-cpu-log. That gives us more flexibility since that + Elisp code can then do all kinds of fun stuff like write + the log to disk. Or turn it right away into a call tree. + Of course, using Elisp is generally preferable, but it may + take longer until we get a chance to run the Elisp code, so + there's more risk that the table will get full before we + get there. */ + } + } +} + +/* Sample profiler. */ + +/* FIXME: Add support for the CPU profiler in W32. */ +/* FIXME: the sigprof_handler suffers from race-conditions if the signal + is delivered to a thread other than the main Emacs thread. */ + +#if defined SIGPROF && defined HAVE_SETITIMER +#define PROFILER_CPU_SUPPORT + +/* True if sampling profiler is running. */ +static bool profiler_cpu_running; + +static Lisp_Object cpu_log; +/* Separate counter for the time spent in the GC. */ +static EMACS_INT cpu_gc_count; + +/* The current sample interval in millisecond. */ + +static int current_sample_interval; + +/* Signal handler for sample profiler. */ + +static void +sigprof_handler (int signal, siginfo_t *info, void *ctx) +{ + eassert (HASH_TABLE_P (cpu_log)); + if (backtrace_list && EQ (*backtrace_list->function, Qautomatic_gc)) + /* Special case the time-count inside GC because the hash-table + code is not prepared to be used while the GC is running. + More specifically it uses ASIZE at many places where it does + not expect the ARRAY_MARK_FLAG to be set. We could try and + harden the hash-table code, but it doesn't seem worth the + effort. */ + cpu_gc_count += current_sample_interval; + else + record_backtrace (XHASH_TABLE (cpu_log), current_sample_interval); +} + +DEFUN ("profiler-cpu-start", Fprofiler_cpu_start, Sprofiler_cpu_start, + 1, 1, 0, + doc: /* Start or restart the cpu profiler. +The cpu profiler will take call-stack samples each SAMPLE-INTERVAL (expressed in milliseconds). +See also `profiler-log-size' and `profiler-max-stack-depth'. */) + (Lisp_Object sample_interval) +{ + struct sigaction sa; + struct itimerval timer; + + if (profiler_cpu_running) + error ("Sample profiler is already running"); + + if (NILP (cpu_log)) + { + cpu_gc_count = 0; + cpu_log = make_log (profiler_log_size, + profiler_max_stack_depth); + } + + current_sample_interval = XINT (sample_interval); + + sa.sa_sigaction = sigprof_handler; + sa.sa_flags = SA_RESTART | SA_SIGINFO; + sigemptyset (&sa.sa_mask); + sigaction (SIGPROF, &sa, 0); + + timer.it_interval.tv_sec = 0; + timer.it_interval.tv_usec = current_sample_interval * 1000; + timer.it_value = timer.it_interval; + setitimer (ITIMER_PROF, &timer, 0); + + profiler_cpu_running = true; + + return Qt; +} + +DEFUN ("profiler-cpu-stop", Fprofiler_cpu_stop, Sprofiler_cpu_stop, + 0, 0, 0, + doc: /* Stop the cpu profiler. The profiler log is not affected. +Return non-nil if the profiler was running. */) + (void) +{ + if (!profiler_cpu_running) + return Qnil; + profiler_cpu_running = false; + + setitimer (ITIMER_PROF, 0, 0); + + return Qt; +} + +DEFUN ("profiler-cpu-running-p", + Fprofiler_cpu_running_p, Sprofiler_cpu_running_p, + 0, 0, 0, + doc: /* Return non-nil iff cpu profiler is running. */) + (void) +{ + return profiler_cpu_running ? Qt : Qnil; +} + +DEFUN ("profiler-cpu-log", Fprofiler_cpu_log, Sprofiler_cpu_log, + 0, 0, 0, + doc: /* Return the current cpu profiler log. +The log is a hash-table mapping backtraces to counters which represent +the amount of time spent at those points. Every backtrace is a vector +of functions, where the last few elements may be nil. +Before returning, a new log is allocated for future samples. */) + (void) +{ + Lisp_Object result = cpu_log; + /* Here we're making the log visible to Elisp , so it's not safe any + more for our use afterwards since we can't rely on its special + pre-allocated keys anymore. So we have to allocate a new one. */ + cpu_log = (profiler_cpu_running + ? make_log (profiler_log_size, profiler_max_stack_depth) + : Qnil); + Fputhash (Fmake_vector (make_number (1), Qautomatic_gc), + make_number (cpu_gc_count), + result); + cpu_gc_count = 0; + return result; +} +#endif /* not defined PROFILER_CPU_SUPPORT */ + +/* Memory profiler. */ + +/* True if memory profiler is running. */ +bool profiler_memory_running; + +static Lisp_Object memory_log; + +DEFUN ("profiler-memory-start", Fprofiler_memory_start, Sprofiler_memory_start, + 0, 0, 0, + doc: /* Start/restart the memory profiler. +The memory profiler will take samples of the call-stack whenever a new +allocation takes place. Note that most small allocations only trigger +the profiler occasionally. +See also `profiler-log-size' and `profiler-max-stack-depth'. */) + (void) +{ + if (profiler_memory_running) + error ("Memory profiler is already running"); + + if (NILP (memory_log)) + memory_log = make_log (profiler_log_size, + profiler_max_stack_depth); + + profiler_memory_running = true; + + return Qt; +} + +DEFUN ("profiler-memory-stop", + Fprofiler_memory_stop, Sprofiler_memory_stop, + 0, 0, 0, + doc: /* Stop the memory profiler. The profiler log is not affected. +Return non-nil if the profiler was running. */) + (void) +{ + if (!profiler_memory_running) + return Qnil; + profiler_memory_running = false; + return Qt; +} + +DEFUN ("profiler-memory-running-p", + Fprofiler_memory_running_p, Sprofiler_memory_running_p, + 0, 0, 0, + doc: /* Return non-nil if memory profiler is running. */) + (void) +{ + return profiler_memory_running ? Qt : Qnil; +} + +DEFUN ("profiler-memory-log", + Fprofiler_memory_log, Sprofiler_memory_log, + 0, 0, 0, + doc: /* Return the current memory profiler log. +The log is a hash-table mapping backtraces to counters which represent +the amount of memory allocated at those points. Every backtrace is a vector +of functions, where the last few elements may be nil. +Before returning, a new log is allocated for future samples. */) + (void) +{ + Lisp_Object result = memory_log; + /* Here we're making the log visible to Elisp , so it's not safe any + more for our use afterwards since we can't rely on its special + pre-allocated keys anymore. So we have to allocate a new one. */ + memory_log = (profiler_memory_running + ? make_log (profiler_log_size, profiler_max_stack_depth) + : Qnil); + return result; +} + + +/* Signals and probes. */ + +/* Record that the current backtrace allocated SIZE bytes. */ +void +malloc_probe (size_t size) +{ + eassert (HASH_TABLE_P (memory_log)); + record_backtrace (XHASH_TABLE (memory_log), size); +} + +void +syms_of_profiler (void) +{ + DEFVAR_INT ("profiler-max-stack-depth", profiler_max_stack_depth, + doc: /* Number of elements from the call-stack recorded in the log. */); + profiler_max_stack_depth = 16; + DEFVAR_INT ("profiler-log-size", profiler_log_size, + doc: /* Number of distinct call-stacks that can be recorded in a profiler log. +If the log gets full, some of the least-seen call-stacks will be evicted +to make room for new entries. */); + profiler_log_size = 10000; + +#ifdef PROFILER_CPU_SUPPORT + profiler_cpu_running = false; + cpu_log = Qnil; + staticpro (&cpu_log); + defsubr (&Sprofiler_cpu_start); + defsubr (&Sprofiler_cpu_stop); + defsubr (&Sprofiler_cpu_running_p); + defsubr (&Sprofiler_cpu_log); +#endif + profiler_memory_running = false; + memory_log = Qnil; + staticpro (&memory_log); + defsubr (&Sprofiler_memory_start); + defsubr (&Sprofiler_memory_stop); + defsubr (&Sprofiler_memory_running_p); + defsubr (&Sprofiler_memory_log); +} === modified file 'src/xdisp.c' --- src/xdisp.c 2012-09-25 04:13:02 +0000 +++ src/xdisp.c 2012-09-26 15:19:10 +0000 @@ -333,10 +333,10 @@ static Lisp_Object Qbuffer_position, Qposition, Qobject; static Lisp_Object Qright_to_left, Qleft_to_right; -/* Cursor shapes */ +/* Cursor shapes. */ Lisp_Object Qbar, Qhbar, Qbox, Qhollow; -/* Pointer shapes */ +/* Pointer shapes. */ static Lisp_Object Qarrow, Qhand; Lisp_Object Qtext; @@ -347,6 +347,7 @@ static Lisp_Object Qwrap_prefix; static Lisp_Object Qline_prefix; +static Lisp_Object Qautomatic_redisplay; /* Non-nil means don't actually do any redisplay. */ @@ -12929,12 +12930,13 @@ struct frame *sf; int polling_stopped_here = 0; Lisp_Object old_frame = selected_frame; + struct backtrace backtrace; /* Non-zero means redisplay has to consider all windows on all frames. Zero means, only selected_window is considered. */ int consider_all_windows_p; - /* Non-zero means redisplay has to redisplay the miniwindow */ + /* Non-zero means redisplay has to redisplay the miniwindow. */ int update_miniwindow_p = 0; TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p)); @@ -12971,6 +12973,14 @@ redisplaying_p = 1; specbind (Qinhibit_free_realized_faces, Qnil); + /* Record this function, so it appears on the profiler's backtraces. */ + backtrace.next = backtrace_list; + backtrace.function = &Qautomatic_redisplay; + backtrace.args = &Qautomatic_redisplay; + backtrace.nargs = 0; + backtrace.debug_on_exit = 0; + backtrace_list = &backtrace; + { Lisp_Object tail, frame; @@ -13668,6 +13678,7 @@ #endif /* HAVE_WINDOW_SYSTEM */ end_of_redisplay: + backtrace_list = backtrace.next; unbind_to (count, Qnil); RESUME_POLLING; } @@ -28683,6 +28694,7 @@ staticpro (&Vmessage_stack); DEFSYM (Qinhibit_redisplay, "inhibit-redisplay"); + DEFSYM (Qautomatic_redisplay, "Automatic Redisplay"); message_dolog_marker1 = Fmake_marker (); staticpro (&message_dolog_marker1); @@ -29349,7 +29361,7 @@ the following three functions in w32fns.c. */ #ifndef WINDOWSNT -/* Platform-independent portion of hourglass implementation. */ +/* Platform-independent portion of hourglass implementation. */ /* Cancel a currently active hourglass timer, and start a new one. */ void ------------------------------------------------------------ revno: 110205 committer: Eli Zaretskii branch nick: trunk timestamp: Wed 2012-09-26 16:44:22 +0200 message: Fix a typo in a recent entry in src/ChangeLog. diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2012-09-26 07:07:32 +0000 +++ src/ChangeLog 2012-09-26 14:44:22 +0000 @@ -8,7 +8,7 @@ They avoid a race if the timer is too close to the current time. * atimer.c (alarm_timer, alarm_timer_ok) [SIGEV_SIGNAL]: New static vars. (set_alarm) [SIGEV_SIGNAL]: Use POSIX timers if available. - (init_atimer) [SIGEV_SIGAL]: Initialize them. + (init_atimer) [SIGEV_SIGNAL]: Initialize them. 2012-09-25 Eli Zaretskii ------------------------------------------------------------ revno: 110204 committer: Stefan Monnier branch nick: trunk timestamp: Wed 2012-09-26 10:41:05 -0400 message: * lisp/emacs-lisp/testcover.el (testcover-after): Add gv-expander. (testcover-reinstrument): Simplify with CSE. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-09-26 14:11:18 +0000 +++ lisp/ChangeLog 2012-09-26 14:41:05 +0000 @@ -1,3 +1,8 @@ +2012-09-26 Stefan Monnier + + * emacs-lisp/testcover.el (testcover-after): Add gv-expander. + (testcover-reinstrument): Simplify with CSE. + 2012-09-26 Juanma Barranquero * window.el (temp-buffer-window-setup): Fix typo in docstring. @@ -13,9 +18,9 @@ newline. Reported by Andrew Jones. (verilog-auto-inst) Support expanding $clog2 in AUTOINST. Reported by Brad Dobbie. - (verilog-batch-delete-trailing-whitespace): Create - verilog-batch-delete-trailing-whitespace. Reported by Brad - Dobbie. + (verilog-batch-delete-trailing-whitespace): + Create verilog-batch-delete-trailing-whitespace. + Reported by Brad Dobbie. (verilog-auto-inout-param): Support AUTOINOUTPARAM for copying parameters from another module. Reported by Dan Katz. (verilog-auto, verilog-auto-assign-modport) @@ -105,12 +110,12 @@ * ansi-color.el (ansi-color-unfontify-region): * international/latin1-disp.el (latin1-char-displayable-p): * progmodes/cwarn.el (turn-on-cwarn-mode): - * progmodes/which-func.el (which-func-update-1): Use - define-obsolete-function-alias. + * progmodes/which-func.el (which-func-update-1): + Use define-obsolete-function-alias. * net/newst-backend.el (newsticker-cache-filename): - * net/newst-treeview.el (newsticker-groups-filename): Fix - incorrect obsolescence declaration. + * net/newst-treeview.el (newsticker-groups-filename): + Fix incorrect obsolescence declaration. * allout.el (allout-passphrase-hint-string): Likewise. (allout-init): Use a declare form to mark obsolete. @@ -147,8 +152,8 @@ Enhancements for triple-quote string syntax. * progmodes/python.el (python-quote-syntax): Remove. (python-syntax-propertize-function): New value. - (python-syntax-count-quotes, python-syntax-stringify): New - functions. + (python-syntax-count-quotes, python-syntax-stringify): + New functions. 2012-09-24 Chong Yidong @@ -181,8 +186,8 @@ * vc/vc-hooks.el (vc-default-registered): Don't use vc-master-templates. - * font-lock.el (font-lock-reference-face): Use - define-obsolete-variable-alias. + * font-lock.el (font-lock-reference-face): + Use define-obsolete-variable-alias. * generic-x.el (rul-generic-mode): Use font-lock-constant-face. * calendar/calendar.el (calendar-font-lock-keywords): @@ -213,8 +218,8 @@ 2012-09-23 Roland Winkler - * textmodes/bibtex.el (bibtex-autokey-transcriptions): Transcribe - also LaTeX hyphenation. + * textmodes/bibtex.el (bibtex-autokey-transcriptions): + Transcribe also LaTeX hyphenation. (bibtex-reformat): Bug fix. Do not quote twice the elements of bibtex-reformat-previous-options. @@ -374,8 +379,8 @@ (rst-section-tree, rst-section-tree-rec) (rst-section-tree-point): Refactor and document properly. (rst-imenu-find-adornments-for-position) - (rst-imenu-convert-cell, rst-imenu-create-index): New - function. + (rst-imenu-convert-cell, rst-imenu-create-index): + New function. 2012-09-20 Stefan Monnier === modified file 'lisp/emacs-lisp/gv.el' --- lisp/emacs-lisp/gv.el 2012-09-24 12:31:24 +0000 +++ lisp/emacs-lisp/gv.el 2012-09-26 14:41:05 +0000 @@ -269,7 +269,7 @@ ;;;###autoload (put 'gv-place 'edebug-form-spec 'edebug-match-form) ;; CL did the equivalent of: -;;(gv-define-expand edebug-after (lambda (before index place) place)) +;;(gv-define-macroexpand edebug-after (lambda (before index place) place)) (put 'edebug-after 'gv-expander (lambda (do before index place) === modified file 'lisp/emacs-lisp/testcover.el' --- lisp/emacs-lisp/testcover.el 2012-01-19 07:21:25 +0000 +++ lisp/emacs-lisp/testcover.el 2012-09-26 14:41:05 +0000 @@ -270,9 +270,9 @@ (setq id (nth 2 form)) (setcdr form (nthcdr 2 form)) (setq val (testcover-reinstrument (nth 2 form))) - (if (eq val t) - (setcar form 'testcover-1value) - (setcar form 'testcover-after)) + (setcar form (if (eq val t) + 'testcover-1value + 'testcover-after)) (when val ;;1-valued or potentially 1-valued (aset testcover-vector id '1value)) @@ -359,9 +359,9 @@ ,(nth 3 (cadr form)))) t) (t - (if (eq (car (cadr form)) 'edebug-after) - (setq id (car (nth 3 (cadr form)))) - (setq id (car (cadr form)))) + (setq id (car (if (eq (car (cadr form)) 'edebug-after) + (nth 3 (cadr form)) + (cadr form)))) (let ((testcover-1value-functions (cons id testcover-1value-functions))) (testcover-reinstrument (cadr form)))))) @@ -379,9 +379,9 @@ ,(nth 3 (cadr form)))) 'maybe) (t - (if (eq (car (cadr form)) 'edebug-after) - (setq id (car (nth 3 (cadr form)))) - (setq id (car (cadr form)))) + (setq id (car (if (eq (car (cadr form)) 'edebug-after) + (nth 3 (cadr form)) + (cadr form)))) (let ((testcover-noreturn-functions (cons id testcover-noreturn-functions))) (testcover-reinstrument (cadr form)))))) @@ -447,6 +447,12 @@ (defun testcover-after (idx val) "Internal function for coverage testing. Returns VAL after installing it in `testcover-vector' at offset IDX." + (declare (gv-expander (lambda (do) + (gv-letplace (getter setter) val + (funcall do getter + (lambda (store) + `(progn (testcover-after ,idx ,getter) + ,(funcall setter store)))))))) (cond ((eq (aref testcover-vector idx) 'unknown) (aset testcover-vector idx val)) ------------------------------------------------------------ revno: 110203 committer: Juanma Barranquero branch nick: trunk timestamp: Wed 2012-09-26 16:11:18 +0200 message: lisp/window.el (temp-buffer-window-setup): Fix typo in docstring. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-09-26 03:32:51 +0000 +++ lisp/ChangeLog 2012-09-26 14:11:18 +0000 @@ -1,3 +1,7 @@ +2012-09-26 Juanma Barranquero + + * window.el (temp-buffer-window-setup): Fix typo in docstring. + 2012-09-25 Wilson Snyder * verilog-mode.el (verilog-auto-ascii-enum, verilog-auto-inout) === modified file 'lisp/window.el' --- lisp/window.el 2012-09-25 08:20:05 +0000 +++ lisp/window.el 2012-09-26 14:11:18 +0000 @@ -84,7 +84,7 @@ displayed and current and its window selected.") (defun temp-buffer-window-setup (buffer-or-name) - "Set up temporary buffer specified by BUFFER-OR-NAME + "Set up temporary buffer specified by BUFFER-OR-NAME. Return the buffer." (let ((old-dir default-directory) (buffer (get-buffer-create buffer-or-name))) @@ -903,7 +903,7 @@ (if right (throw 'reset t) (setq right t))) ((eq side 'bottom) (if bottom (throw 'reset t) (setq bottom t))) - (t + (t (throw 'reset t)))) frame t)) ;; If there's a side window, there must be at least one ------------------------------------------------------------ revno: 110202 committer: Glenn Morris branch nick: trunk timestamp: Wed 2012-09-26 00:07:32 -0700 message: Fix bug ref diff: === modified file 'src/ChangeLog' --- src/ChangeLog 2012-09-25 22:07:22 +0000 +++ src/ChangeLog 2012-09-26 07:07:32 +0000 @@ -359,7 +359,7 @@ 2012-09-23 Jan Djärv * nsterm.m (ns_dumpglyphs_image): dr is a new rect to draw image into, - background rect may be larger (Bug#12445). + background rect may be larger (Bug#12245). 2012-09-23 Chong Yidong ------------------------------------------------------------ revno: 110201 author: Wilson Snyder committer: Chong Yidong branch nick: trunk timestamp: Wed 2012-09-26 11:32:51 +0800 message: Synch verilog-mode.el to latest upstream version. * verilog-mode.el (verilog-auto-ascii-enum, verilog-auto-inout) (verilog-auto-input, verilog-auto-insert-lisp) (verilog-auto-output, verilog-auto-output-every, verilog-auto-reg) (verilog-auto-reg-input, verilog-auto-tieoff, verilog-auto-undef) (verilog-auto-unused, verilog-auto-wire) (verilog-forward-or-insert-line): Fix AUTOs with no trailing newline. Reported by Andrew Jones. (verilog-auto-inst) Support expanding $clog2 in AUTOINST. Reported by Brad Dobbie. (verilog-batch-delete-trailing-whitespace): Create verilog-batch-delete-trailing-whitespace. Reported by Brad Dobbie. (verilog-auto-inout-param): Support AUTOINOUTPARAM for copying parameters from another module. Reported by Dan Katz. (verilog-auto, verilog-auto-assign-modport) (verilog-auto-inout-modport): Add AUTOASSIGNMODPORT and AUTOINOUTMODPORT for UVM interface module shell generation. Reported by Brad Dobbie. (verilog-auto-inst-interfaced-ports): Make default nil, as more standard behavior. (verilog-auto): Fix AUTO parameters with parenthesis arguments. Reported by Matt Martin. diff: === modified file 'lisp/ChangeLog' --- lisp/ChangeLog 2012-09-25 08:20:05 +0000 +++ lisp/ChangeLog 2012-09-26 03:32:51 +0000 @@ -1,3 +1,28 @@ +2012-09-25 Wilson Snyder + + * verilog-mode.el (verilog-auto-ascii-enum, verilog-auto-inout) + (verilog-auto-input, verilog-auto-insert-lisp) + (verilog-auto-output, verilog-auto-output-every, verilog-auto-reg) + (verilog-auto-reg-input, verilog-auto-tieoff, verilog-auto-undef) + (verilog-auto-unused, verilog-auto-wire) + (verilog-forward-or-insert-line): Fix AUTOs with no trailing + newline. Reported by Andrew Jones. + (verilog-auto-inst) Support expanding $clog2 in AUTOINST. + Reported by Brad Dobbie. + (verilog-batch-delete-trailing-whitespace): Create + verilog-batch-delete-trailing-whitespace. Reported by Brad + Dobbie. + (verilog-auto-inout-param): Support AUTOINOUTPARAM for copying + parameters from another module. Reported by Dan Katz. + (verilog-auto, verilog-auto-assign-modport) + (verilog-auto-inout-modport): Add AUTOASSIGNMODPORT and + AUTOINOUTMODPORT for UVM interface module shell generation. + Reported by Brad Dobbie. + (verilog-auto-inst-interfaced-ports): Make default nil, as more + standard behavior. + (verilog-auto): Fix AUTO parameters with parenthesis arguments. + Reported by Matt Martin. + 2012-09-25 Martin Rudalics * window.el (window--resize-child-windows): When resizing child === modified file 'lisp/progmodes/verilog-mode.el' --- lisp/progmodes/verilog-mode.el 2012-09-17 05:41:04 +0000 +++ lisp/progmodes/verilog-mode.el 2012-09-26 03:32:51 +0000 @@ -123,11 +123,11 @@ ;;; Code: ;; This variable will always hold the version number of the mode -(defconst verilog-mode-version "800" +(defconst verilog-mode-version (substring "$$Revision: 820 $$" 12 -3) "Version of this Verilog mode.") -(defconst verilog-mode-release-date "2012-04-23-GNU" +(defconst verilog-mode-release-date (substring "$$Date: 2012-09-17 20:43:10 -0400 (Mon, 17 Sep 2012) $$" 8 -3) "Release date of this Verilog mode.") -(defconst verilog-mode-release-emacs t +(defconst verilog-mode-release-emacs nil "If non-nil, this version of Verilog mode was released with Emacs itself.") (defun verilog-version () @@ -1127,7 +1127,7 @@ :type 'integer) (put 'verilog-auto-inst-column 'safe-local-variable 'integerp) -(defcustom verilog-auto-inst-interfaced-ports t +(defcustom verilog-auto-inst-interfaced-ports nil "Non-nil means include interfaced ports in AUTOINST expansions." :group 'verilog-mode-auto :type 'boolean) @@ -1431,12 +1431,18 @@ :help "Help on AUTOARG - declaring module port list"] ["AUTOASCIIENUM" (describe-function 'verilog-auto-ascii-enum) :help "Help on AUTOASCIIENUM - creating ASCII for enumerations"] + ["AUTOASSIGNMODPORT" (describe-function 'verilog-auto-assign-modport) + :help "Help on AUTOASSIGNMODPORT - creating assignments to/from modports"] ["AUTOINOUTCOMP" (describe-function 'verilog-auto-inout-comp) :help "Help on AUTOINOUTCOMP - copying complemented i/o from another file"] ["AUTOINOUTIN" (describe-function 'verilog-auto-inout-in) - :help "Help on AUTOINOUTCOMP - copying i/o from another file as all inputs"] + :help "Help on AUTOINOUTIN - copying i/o from another file as all inputs"] + ["AUTOINOUTMODPORT" (describe-function 'verilog-auto-inout-modport) + :help "Help on AUTOINOUTMODPORT - copying i/o from an interface modport"] ["AUTOINOUTMODULE" (describe-function 'verilog-auto-inout-module) :help "Help on AUTOINOUTMODULE - copying i/o from another file"] + ["AUTOINOUTPARAM" (describe-function 'verilog-auto-inout-param) + :help "Help on AUTOINOUTPARAM - copying parameters from another file"] ["AUTOINSERTLISP" (describe-function 'verilog-auto-insert-lisp) :help "Help on AUTOINSERTLISP - insert text from a lisp function"] ["AUTOINOUT" (describe-function 'verilog-auto-inout) @@ -1706,12 +1712,19 @@ ;;(verilog-re-search-backward-substr "-end" "get-end-of" nil t) ;;-end (test bait) (defun verilog-delete-trailing-whitespace () - "Delete trailing spaces or tabs, but not newlines nor linefeeds." + "Delete trailing spaces or tabs, but not newlines nor linefeeds. +Also add missing final newline. + +To call this from the command line, see \\[verilog-batch-diff-auto]. + +To call on \\[verilog-auto], set `verilog-auto-delete-trailing-whitespace'." ;; Similar to `delete-trailing-whitespace' but that's not present in XEmacs (save-excursion (goto-char (point-min)) (while (re-search-forward "[ \t]+$" nil t) ;; Not syntactic WS as no formfeed - (replace-match "" nil nil)))) + (replace-match "" nil nil)) + (goto-char (point-max)) + (unless (bolp) (insert "\n")))) (defvar compile-command) @@ -5128,6 +5141,15 @@ (error "Use verilog-batch-delete-auto only with --batch")) ;; Otherwise we'd mess up buffer modes (verilog-batch-execute-func `verilog-delete-auto)) +(defun verilog-batch-delete-trailing-whitespace () + "For use with --batch, perform whitespace deletion as a stand-alone tool. +This sets up the appropriate Verilog mode environment, removes +whitespace with \\[verilog-delete-trailing-whitespace] on all +command-line files, and saves the buffers." + (unless noninteractive + (error "Use verilog-batch-delete-trailing-whitepace only with --batch")) ;; Otherwise we'd mess up buffer modes + (verilog-batch-execute-func `verilog-delete-trailing-whitespace)) + (defun verilog-batch-diff-auto () "For use with --batch, perform automatic differences as a stand-alone tool. This sets up the appropriate Verilog mode environment, expand automatics @@ -7479,6 +7501,19 @@ (defsubst verilog-alw-get-uses-delayed (sigs) (aref sigs 0)) +(defsubst verilog-modport-new (name clockings decls) + (list name clockings decls)) +(defsubst verilog-modport-name (sig) + (car sig)) +(defsubst verilog-modport-clockings (sig) + (nth 1 sig)) ;; Returns list of names +(defsubst verilog-modport-clockings-add (sig val) + (setcar (nthcdr 1 sig) (cons val (nth 1 sig)))) +(defsubst verilog-modport-decls (sig) + (nth 2 sig)) ;; Returns verilog-decls-* structure +(defsubst verilog-modport-decls-set (sig val) + (setcar (nthcdr 2 sig) val)) + (defsubst verilog-modi-new (name fob pt type) (vector name fob pt type)) (defsubst verilog-modi-name (modi) @@ -7496,8 +7531,15 @@ ;; Signal reading for given module ;; Note these all take modi's - as returned from verilog-modi-current -(defsubst verilog-decls-new (out inout in vars unuseds assigns consts gparams interfaces) - (vector out inout in vars unuseds assigns consts gparams interfaces)) +(defsubst verilog-decls-new (out inout in vars modports assigns consts gparams interfaces) + (vector out inout in vars modports assigns consts gparams interfaces)) +(defsubst verilog-decls-append (a b) + (cond ((not a) b) ((not b) a) + (t (vector (append (aref a 0) (aref b 0)) (append (aref a 1) (aref b 1)) + (append (aref a 2) (aref b 2)) (append (aref a 3) (aref b 3)) + (append (aref a 4) (aref b 4)) (append (aref a 5) (aref b 5)) + (append (aref a 6) (aref b 6)) (append (aref a 7) (aref b 7)) + (append (aref a 8) (aref b 8)))))) (defsubst verilog-decls-get-outputs (decls) (aref decls 0)) (defsubst verilog-decls-get-inouts (decls) @@ -7506,8 +7548,8 @@ (aref decls 2)) (defsubst verilog-decls-get-vars (decls) (aref decls 3)) -;;(defsubst verilog-decls-get-unused (decls) -;; (aref decls 4)) +(defsubst verilog-decls-get-modports (decls) ;; Also for clocking blocks; contains another verilog-decls struct + (aref decls 4)) ;; Returns verilog-modport* structure (defsubst verilog-decls-get-assigns (decls) (aref decls 5)) (defsubst verilog-decls-get-consts (decls) @@ -7517,6 +7559,7 @@ (defsubst verilog-decls-get-interfaces (decls) (aref decls 8)) + (defsubst verilog-subdecls-new (out inout in intf intfd) (vector out inout in intf intfd)) (defsubst verilog-subdecls-get-outputs (subdecls) @@ -7535,6 +7578,36 @@ (mapcar (lambda (name) (verilog-sig-new name nil nil nil nil nil nil nil nil)) signame-list)) +(defun verilog-signals-in (in-list not-list) + "Return list of signals in IN-LIST that are also in NOT-LIST. +Also remove any duplicates in IN-LIST. +Signals must be in standard (base vector) form." + ;; This function is hot, so implemented as O(1) + (cond ((eval-when-compile (fboundp 'make-hash-table)) + (let ((ht (make-hash-table :test 'equal :rehash-size 4.0)) + (ht-not (make-hash-table :test 'equal :rehash-size 4.0)) + out-list) + (while not-list + (puthash (car (car not-list)) t ht-not) + (setq not-list (cdr not-list))) + (while in-list + (when (and (gethash (verilog-sig-name (car in-list)) ht-not) + (not (gethash (verilog-sig-name (car in-list)) ht))) + (setq out-list (cons (car in-list) out-list)) + (puthash (verilog-sig-name (car in-list)) t ht)) + (setq in-list (cdr in-list))) + (nreverse out-list))) + ;; Slower Fallback if no hash tables (pre Emacs 21.1/XEmacs 21.4) + (t + (let (out-list) + (while in-list + (if (and (assoc (verilog-sig-name (car in-list)) not-list) + (not (assoc (verilog-sig-name (car in-list)) out-list))) + (setq out-list (cons (car in-list) out-list))) + (setq in-list (cdr in-list))) + (nreverse out-list))))) +;;(verilog-signals-in '(("A" "") ("B" "") ("DEL" "[2:3]")) '(("DEL" "") ("C" ""))) + (defun verilog-signals-not-in (in-list not-list) "Return list of signals in IN-LIST that aren't also in NOT-LIST. Also remove any duplicates in IN-LIST. @@ -7556,8 +7629,8 @@ (t (let (out-list) (while in-list - (if (not (or (assoc (verilog-sig-name (car in-list)) not-list) - (assoc (verilog-sig-name (car in-list)) out-list))) + (if (and (not (assoc (verilog-sig-name (car in-list)) not-list)) + (not (assoc (verilog-sig-name (car in-list)) out-list))) (setq out-list (cons (car in-list) out-list))) (setq in-list (cdr in-list))) (nreverse out-list))))) @@ -7702,30 +7775,35 @@ ;; Dumping ;; -(defun verilog-decls-princ (decls) +(defun verilog-decls-princ (decls &optional header prefix) "For debug, dump the `verilog-read-decls' structure DECLS." - (verilog-signals-princ (verilog-decls-get-outputs decls) - "Outputs:\n" " ") - (verilog-signals-princ (verilog-decls-get-inouts decls) - "Inout:\n" " ") - (verilog-signals-princ (verilog-decls-get-inputs decls) - "Inputs:\n" " ") - (verilog-signals-princ (verilog-decls-get-vars decls) - "Vars:\n" " ") - (verilog-signals-princ (verilog-decls-get-assigns decls) - "Assigns:\n" " ") - (verilog-signals-princ (verilog-decls-get-consts decls) - "Consts:\n" " ") - (verilog-signals-princ (verilog-decls-get-gparams decls) - "Gparams:\n" " ") - (verilog-signals-princ (verilog-decls-get-interfaces decls) - "Interfaces:\n" " ") - (princ "\n")) + (when decls + (if header (princ header)) + (setq prefix (or prefix "")) + (verilog-signals-princ (verilog-decls-get-outputs decls) + (concat prefix "Outputs:\n") (concat prefix " ")) + (verilog-signals-princ (verilog-decls-get-inouts decls) + (concat prefix "Inout:\n") (concat prefix " ")) + (verilog-signals-princ (verilog-decls-get-inputs decls) + (concat prefix "Inputs:\n") (concat prefix " ")) + (verilog-signals-princ (verilog-decls-get-vars decls) + (concat prefix "Vars:\n") (concat prefix " ")) + (verilog-signals-princ (verilog-decls-get-assigns decls) + (concat prefix "Assigns:\n") (concat prefix " ")) + (verilog-signals-princ (verilog-decls-get-consts decls) + (concat prefix "Consts:\n") (concat prefix " ")) + (verilog-signals-princ (verilog-decls-get-gparams decls) + (concat prefix "Gparams:\n") (concat prefix " ")) + (verilog-signals-princ (verilog-decls-get-interfaces decls) + (concat prefix "Interfaces:\n") (concat prefix " ")) + (verilog-modport-princ (verilog-decls-get-modports decls) + (concat prefix "Modports:\n") (concat prefix " ")) + (princ "\n"))) (defun verilog-signals-princ (signals &optional header prefix) "For debug, dump internal SIGNALS structures, with HEADER and PREFIX." (when signals - (princ header) + (if header (princ header)) (while signals (let ((sig (car signals))) (setq signals (cdr signals)) @@ -7741,6 +7819,21 @@ (princ " modp=") (princ (verilog-sig-modport sig)) (princ "\n"))))) +(defun verilog-modport-princ (modports &optional header prefix) + "For debug, dump internal MODPORT structures, with HEADER and PREFIX." + (when modports + (if header (princ header)) + (while modports + (let ((sig (car modports))) + (setq modports (cdr modports)) + (princ prefix) + (princ "\"") (princ (verilog-modport-name sig)) (princ "\"") + (princ " clockings=") (princ (verilog-modport-clockings sig)) + (princ "\n") + (verilog-decls-princ (verilog-modport-decls sig) + (concat prefix " syms:\n") + (concat prefix " ")))))) + ;; ;; Port/Wire/Etc Reading ;; @@ -7851,11 +7944,12 @@ Return an array of [outputs inouts inputs wire reg assign const]." (let ((end-mod-point (or (verilog-get-end-of-defun t) (point-max))) (functask 0) (paren 0) (sig-paren 0) (v2kargs-ok t) - in-modport ptype ign-prop + in-modport in-clocking ptype ign-prop sigs-in sigs-out sigs-inout sigs-var sigs-assign sigs-const - sigs-gparam sigs-intf + sigs-gparam sigs-intf sigs-modports vec expect-signal keywd newsig rvalue enum io signed typedefed multidim - modport) + modport + varstack tmp) (save-excursion (verilog-beg-of-defun-quick) (setq sigs-const (verilog-read-auto-constants (point) end-mod-point)) @@ -7881,6 +7975,17 @@ (or (re-search-forward "[^\\]\"" nil t) ;; don't forward-char first, since we look for a non backslash first (error "%s: Unmatched quotes, at char %d" (verilog-point-text) (point)))) ((eq ?\; (following-char)) + (when (and in-modport (not (eq in-modport t))) ;; end of a modport declaration + (verilog-modport-decls-set + in-modport + (verilog-decls-new sigs-out sigs-inout sigs-in + nil nil nil nil nil nil)) + ;; Pop from varstack to restore state to pre-clocking + (setq tmp (car varstack) + varstack (cdr varstack) + sigs-out (aref tmp 0) + sigs-inout (aref tmp 1) + sigs-in (aref tmp 2))) (setq vec nil io nil expect-signal nil newsig nil paren 0 rvalue nil v2kargs-ok nil in-modport nil ign-prop nil) (forward-char 1)) @@ -7974,15 +8079,17 @@ (setq signed keywd)) ((member keywd '("assert" "assume" "cover" "expect" "restrict")) (setq ign-prop t)) - ((member keywd '("class" "clocking" "covergroup" "function" + ((member keywd '("class" "covergroup" "function" "property" "randsequence" "sequence" "task")) (unless ign-prop (setq functask (1+ functask)))) - ((member keywd '("endclass" "endclocking" "endgroup" "endfunction" + ((member keywd '("endclass" "endgroup" "endfunction" "endproperty" "endsequence" "endtask")) (setq functask (1- functask))) ((equal keywd "modport") (setq in-modport t)) + ((equal keywd "clocking") + (setq in-clocking t)) ((equal keywd "type") (setq ptype t)) ;; Ifdef? Ignore name of define @@ -8008,11 +8115,47 @@ (goto-char (match-end 0)) (when (not rvalue) (setq expect-signal nil))) + ;; "modport " + ((and (eq in-modport t) + (not (member keywd verilog-keywords))) + (setq in-modport (verilog-modport-new keywd nil nil)) + (setq sigs-modports (cons in-modport sigs-modports)) + ;; Push old sig values to stack and point to new signal list + (setq varstack (cons (vector sigs-out sigs-inout sigs-in) + varstack)) + (setq sigs-in nil sigs-inout nil sigs-out nil)) + ;; "modport x (clocking )" + ((and in-modport in-clocking) + (verilog-modport-clockings-add in-modport keywd) + (setq in-clocking nil)) + ;; endclocking + ((and in-clocking + (equal keywd "endclocking")) + (unless (eq in-clocking t) + (verilog-modport-decls-set + in-clocking + (verilog-decls-new sigs-out sigs-inout sigs-in + nil nil nil nil nil nil)) + ;; Pop from varstack to restore state to pre-clocking + (setq tmp (car varstack) + varstack (cdr varstack) + sigs-out (aref tmp 0) + sigs-inout (aref tmp 1) + sigs-in (aref tmp 2))) + (setq in-clocking nil)) + ;; "clocking " + ((and (eq in-clocking t) + (not (member keywd verilog-keywords))) + (setq in-clocking (verilog-modport-new keywd nil nil)) + (setq sigs-modports (cons in-clocking sigs-modports)) + ;; Push old sig values to stack and point to new signal list + (setq varstack (cons (vector sigs-out sigs-inout sigs-in) + varstack)) + (setq sigs-in nil sigs-inout nil sigs-out nil)) ;; New signal, maybe? ((and expect-signal (not rvalue) (eq functask 0) - (not in-modport) (not (member keywd verilog-keywords))) ;; Add new signal to expect-signal's variable (setq newsig (verilog-sig-new keywd vec nil nil enum signed typedefed multidim modport)) @@ -8022,15 +8165,17 @@ (forward-char 1))) (skip-syntax-forward " ")) ;; Return arguments - (verilog-decls-new (nreverse sigs-out) - (nreverse sigs-inout) - (nreverse sigs-in) - (nreverse sigs-var) - nil - (nreverse sigs-assign) - (nreverse sigs-const) - (nreverse sigs-gparam) - (nreverse sigs-intf))))) + (setq tmp (verilog-decls-new (nreverse sigs-out) + (nreverse sigs-inout) + (nreverse sigs-in) + (nreverse sigs-var) + (nreverse sigs-modports) + (nreverse sigs-assign) + (nreverse sigs-const) + (nreverse sigs-gparam) + (nreverse sigs-intf))) + ;;(if dbg (verilog-decls-princ tmp)) + tmp))) (defvar verilog-read-sub-decls-in-interfaced nil "For `verilog-read-sub-decls', process next signal as under interfaced block.") @@ -9352,12 +9497,12 @@ ;;(message "verilog-modi-lookup: HIT %S" modi) modi) ;; Miss - (t (let* ((realmod (verilog-symbol-detick module t)) - (orig-filenames (verilog-module-filenames realmod current)) + (t (let* ((realname (verilog-symbol-detick module t)) + (orig-filenames (verilog-module-filenames realname current)) (filenames orig-filenames) mif) (while (and filenames (not mif)) - (if (not (setq mif (verilog-module-inside-filename-p realmod (car filenames)))) + (if (not (setq mif (verilog-module-inside-filename-p realname (car filenames)))) (setq filenames (cdr filenames)))) ;; mif has correct form to become later elements of modi (cond (mif (setq modi mif)) @@ -9365,8 +9510,8 @@ (or ignore-error (error (concat (verilog-point-text) ": Can't locate " module " module definition" - (if (not (equal module realmod)) - (concat " (Expanded macro to " realmod ")") + (if (not (equal module realname)) + (concat " (Expanded macro to " realname ")") "") "\n Check the verilog-library-directories variable." "\n I looked in (if not listed, doesn't exist):\n\t" @@ -9465,6 +9610,45 @@ (progn ,@body))) +(defun verilog-modi-modport-lookup-one (modi name &optional ignore-error) + "Given a MODI, return the declarations related to the given modport NAME." + ;; Recursive routine - see below + (let* ((realname (verilog-symbol-detick name t)) + (modport (assoc name (verilog-decls-get-modports (verilog-modi-get-decls modi))))) + (or modport ignore-error + (error (concat (verilog-point-text) + ": Can't locate " name " modport definition" + (if (not (equal name realname)) + (concat " (Expanded macro to " realname ")") + "")))) + (let* ((decls (verilog-modport-decls modport)) + (clks (verilog-modport-clockings modport))) + ;; Now expand any clocking's + (while clks + (setq decls (verilog-decls-append + decls + (verilog-modi-modport-lookup-one modi (car clks) ignore-error))) + (setq clks (cdr clks))) + decls))) + +(defun verilog-modi-modport-lookup (modi name-re &optional ignore-error) + "Given a MODI, return the declarations related to the given modport NAME-RE. +If the modport points to any clocking blocks, expand the signals to include +those clocking block's signals." + ;; Recursive routine - see below + (let* ((mod-decls (verilog-modi-get-decls modi)) + (clks (verilog-decls-get-modports mod-decls)) + (name-re (concat "^" name-re "$")) + (decls (verilog-decls-new nil nil nil nil nil nil nil nil nil))) + ;; Pull in all modports + (while clks + (when (string-match name-re (verilog-modport-name (car clks))) + (setq decls (verilog-decls-append + decls + (verilog-modi-modport-lookup-one modi (verilog-modport-name (car clks)) ignore-error)))) + (setq clks (cdr clks))) + decls)) + (defun verilog-signals-matching-enum (in-list enum) "Return all signals in IN-LIST matching the given ENUM." (let (out-list) @@ -9544,6 +9728,13 @@ (verilog-decls-get-inouts decls) (verilog-decls-get-inputs decls))) +(defun verilog-decls-get-iovars (decls) + (append + (verilog-decls-get-vars decls) + (verilog-decls-get-outputs decls) + (verilog-decls-get-inouts decls) + (verilog-decls-get-inputs decls))) + (defsubst verilog-modi-cache-add-outputs (modi sig-list) (verilog-modi-cache-add modi 'verilog-read-decls 0 sig-list)) (defsubst verilog-modi-cache-add-inouts (modi sig-list) @@ -9552,6 +9743,8 @@ (verilog-modi-cache-add modi 'verilog-read-decls 2 sig-list)) (defsubst verilog-modi-cache-add-vars (modi sig-list) (verilog-modi-cache-add modi 'verilog-read-decls 3 sig-list)) +(defsubst verilog-modi-cache-add-gparams (modi sig-list) + (verilog-modi-cache-add modi 'verilog-read-decls 7 sig-list)) ;; @@ -9608,6 +9801,8 @@ (when verilog-auto-declare-nettype (verilog-modi-cache-add-vars modi sigs))) ((equal direction "interface")) + ((equal direction "parameter") + (verilog-modi-cache-add-gparams modi sigs)) (t (error "Unsupported verilog-insert-definition direction: %s" direction)))) (or dont-sort @@ -9654,6 +9849,11 @@ stuff (cdr stuff))))) ;;(let ((indent-pt 10)) (verilog-insert-indent "hello\n" "addon" "there\n")) +(defun verilog-forward-or-insert-line () + "Move forward a line, unless at EOB, then insert a newline." + (if (eobp) (insert "\n") + (forward-line))) + (defun verilog-repair-open-comma () "Insert comma if previous argument is other than an open parenthesis or endif." ;; We can't just search backward for ) as it might be inside another expression. @@ -9741,6 +9941,17 @@ "\\([])}:*+-]\\)") out) (setq out (replace-match "\\1\\2\\3" nil nil out))) + (while (string-match + (concat "\\([[({:*+-]\\)" ; - must be last + "\\$clog2\\s *(\\<\\([0-9]+\\))" + "\\([])}:*+-]\\)") + out) + (setq out (replace-match + (concat + (match-string 1 out) + (int-to-string (verilog-clog2 (string-to-number (match-string 2 out)))) + (match-string 3 out)) + nil nil out))) ;; For precedence do * before +/- (while (string-match (concat "\\([[({:*+-]\\)" @@ -9777,6 +9988,7 @@ post) nil nil out)) ))) out))) + ;;(verilog-simplify-range-expression "[1:3]") ;; 1 ;;(verilog-simplify-range-expression "[(1):3]") ;; 1 ;;(verilog-simplify-range-expression "[(((16)+1)+1+(1+1))]") ;;20 @@ -9785,6 +9997,14 @@ ;;(verilog-simplify-range-expression "[(FOO*4+1-1)]") ;; FOO*4+0 ;;(verilog-simplify-range-expression "[(func(BAR))]") ;; func(BAR) ;;(verilog-simplify-range-expression "[FOO-1+1-1+1]") ;; FOO-0 +;;(verilog-simplify-range-expression "[$clog2(2)]") ;; 1 +;;(verilog-simplify-range-expression "[$clog2(7)]") ;; 3 + +(defun verilog-clog2 (value) + "Compute $clog2 - ceiling log2 of VALUE." + (if (< value 1) + 0 + (ceiling (/ (log value) (log 2))))) (defun verilog-typedef-name-p (variable-name) "Return true if the VARIABLE-NAME is a type definition." @@ -10348,6 +10568,86 @@ (insert "\n")) (indent-to verilog-indent-level-declaration)))) +(defun verilog-auto-assign-modport () + "Expand AUTOASSIGNMODPORT statements, as part of \\[verilog-auto]. +Take input/output/inout statements from the specified interface +and modport and use to build assignments into the modport, for +making verification modules that connect to UVM interfaces. + + The first parameter is the name of an interface. + + The second parameter is a regexp of modports to read from in + that interface. + + The third parameter is the instance name to use to dot reference into. + + The optional fourth parameter is a regular expression, and only + signals matching the regular expression will be included. + +Limitations: + + Interface names must be resolvable to filenames. See `verilog-auto-inst'. + + Inouts are not supported, as assignments must be unidirectional. + + If a signal is part of the interface header and in both a + modport and the interface itself, it will not be listed. (As + this would result in a syntax error when the connections are + made.) + +See the example in `verilog-auto-inout-modport'." + (save-excursion + (let* ((params (verilog-read-auto-params 3 4)) + (submod (nth 0 params)) + (modport-re (nth 1 params)) + (inst-name (nth 2 params)) + (regexp (nth 3 params)) + direction-re submodi) ;; direction argument not supported until requested + ;; Lookup position, etc of co-module + ;; Note this may raise an error + (when (setq submodi (verilog-modi-lookup submod t)) + (let* ((indent-pt (current-indentation)) + (modi (verilog-modi-current)) + (submoddecls (verilog-modi-get-decls submodi)) + (submodportdecls (verilog-modi-modport-lookup submodi modport-re)) + (sig-list-i (verilog-signals-in ;; Decls doesn't have data types, must resolve + (verilog-decls-get-vars submoddecls) + (verilog-signals-not-in + (verilog-decls-get-inputs submodportdecls) + (verilog-decls-get-ports submoddecls)))) + (sig-list-o (verilog-signals-in ;; Decls doesn't have data types, must resolve + (verilog-decls-get-vars submoddecls) + (verilog-signals-not-in + (verilog-decls-get-outputs submodportdecls) + (verilog-decls-get-ports submoddecls))))) + (forward-line 1) + (setq sig-list-i (verilog-signals-edit-wire-reg + (verilog-signals-matching-dir-re + (verilog-signals-matching-regexp sig-list-i regexp) + "input" direction-re)) + sig-list-o (verilog-signals-edit-wire-reg + (verilog-signals-matching-dir-re + (verilog-signals-matching-regexp sig-list-o regexp) + "output" direction-re))) + (setq sig-list-i (sort (copy-alist sig-list-i) `verilog-signals-sort-compare)) + (setq sig-list-o (sort (copy-alist sig-list-o) `verilog-signals-sort-compare)) + (when (or sig-list-i sig-list-o) + (verilog-insert-indent "// Beginning of automatic assignments from modport\n") + ;; Don't sort them so an upper AUTOINST will match the main module + (let ((sigs sig-list-o)) + (while sigs + (verilog-insert-indent "assign " (verilog-sig-name (car sigs)) + " = " inst-name + "." (verilog-sig-name (car sigs)) ";\n") + (setq sigs (cdr sigs)))) + (let ((sigs sig-list-i)) + (while sigs + (verilog-insert-indent "assign " inst-name + "." (verilog-sig-name (car sigs)) + " = " (verilog-sig-name (car sigs)) ";\n") + (setq sigs (cdr sigs)))) + (verilog-insert-indent "// End of automatics\n"))))))) + (defun verilog-auto-inst-port-map (port-st) nil) @@ -11067,8 +11367,8 @@ (verilog-subdecls-get-interfaced modsubdecls) (verilog-subdecls-get-outputs modsubdecls) (verilog-subdecls-get-inouts modsubdecls))))) - (forward-line 1) (when sig-list + (verilog-forward-or-insert-line) (verilog-insert-indent "// Beginning of automatic regs (for this module's undeclared outputs)\n") (verilog-insert-definition modi sig-list "reg" indent-pt nil) (verilog-insert-indent "// End of automatics\n"))))) @@ -11122,8 +11422,8 @@ (verilog-subdecls-get-inouts modsubdecls)) (append (verilog-decls-get-signals moddecls) (verilog-decls-get-assigns moddecls)))))) - (forward-line 1) (when sig-list + (verilog-forward-or-insert-line) (verilog-insert-indent "// Beginning of automatic reg inputs (for undeclared instantiated-module inputs)\n") (verilog-insert-definition modi sig-list "reg" indent-pt nil) (verilog-insert-indent "// End of automatics\n"))))) @@ -11210,8 +11510,8 @@ (append (verilog-subdecls-get-outputs modsubdecls) (verilog-subdecls-get-inouts modsubdecls)) (verilog-decls-get-signals moddecls))))) - (forward-line 1) (when sig-list + (verilog-forward-or-insert-line) (verilog-insert-indent "// Beginning of automatic wires (for undeclared instantiated-module outputs)\n") (verilog-insert-definition modi sig-list "wire" indent-pt nil) (verilog-insert-indent "// End of automatics\n") @@ -11221,7 +11521,7 @@ ;; syntax-ppss which is broken when change hooks are disabled. )))) -(defun verilog-auto-output (&optional with-params) +(defun verilog-auto-output () "Expand AUTOOUTPUT statements, as part of \\[verilog-auto]. Make output statements for any output signal from an /*AUTOINST*/ that isn't an input to another AUTOINST. This is useful for modules which @@ -11273,8 +11573,8 @@ (save-excursion ;; Point must be at insertion point. (let* ((indent-pt (current-indentation)) - (regexp (and with-params - (nth 0 (verilog-read-auto-params 1)))) + (params (verilog-read-auto-params 0 1)) + (regexp (nth 0 params)) (v2k (verilog-in-paren-quick)) (modi (verilog-modi-current)) (moddecls (verilog-modi-get-decls modi)) @@ -11290,7 +11590,7 @@ sig-list regexp))) (setq sig-list (verilog-signals-not-matching-regexp sig-list verilog-auto-output-ignore-regexp)) - (forward-line 1) + (verilog-forward-or-insert-line) (when v2k (verilog-repair-open-comma)) (when sig-list (verilog-insert-indent "// Beginning of automatic outputs (from unused autoinst outputs)\n") @@ -11340,7 +11640,7 @@ (verilog-signals-not-in (verilog-decls-get-signals moddecls) (verilog-decls-get-ports moddecls))))) - (forward-line 1) + (verilog-forward-or-insert-line) (when v2k (verilog-repair-open-comma)) (when sig-list (verilog-insert-indent "// Beginning of automatic outputs (every signal)\n") @@ -11348,7 +11648,7 @@ (verilog-insert-indent "// End of automatics\n")) (when v2k (verilog-repair-close-comma))))) -(defun verilog-auto-input (&optional with-params) +(defun verilog-auto-input () "Expand AUTOINPUT statements, as part of \\[verilog-auto]. Make input statements for any input signal into an /*AUTOINST*/ that isn't declared elsewhere inside the module. This is useful for modules which @@ -11399,8 +11699,8 @@ /*AUTOINPUT(\"^i\")*/" (save-excursion (let* ((indent-pt (current-indentation)) - (regexp (and with-params - (nth 0 (verilog-read-auto-params 1)))) + (params (verilog-read-auto-params 0 1)) + (regexp (nth 0 params)) (v2k (verilog-in-paren-quick)) (modi (verilog-modi-current)) (moddecls (verilog-modi-get-decls modi)) @@ -11420,7 +11720,7 @@ sig-list regexp))) (setq sig-list (verilog-signals-not-matching-regexp sig-list verilog-auto-input-ignore-regexp)) - (forward-line 1) + (verilog-forward-or-insert-line) (when v2k (verilog-repair-open-comma)) (when sig-list (verilog-insert-indent "// Beginning of automatic inputs (from unused autoinst inputs)\n") @@ -11428,7 +11728,7 @@ (verilog-insert-indent "// End of automatics\n")) (when v2k (verilog-repair-close-comma))))) -(defun verilog-auto-inout (&optional with-params) +(defun verilog-auto-inout () "Expand AUTOINOUT statements, as part of \\[verilog-auto]. Make inout statements for any inout signal in an /*AUTOINST*/ that isn't declared elsewhere inside the module. @@ -11479,8 +11779,8 @@ (save-excursion ;; Point must be at insertion point. (let* ((indent-pt (current-indentation)) - (regexp (and with-params - (nth 0 (verilog-read-auto-params 1)))) + (params (verilog-read-auto-params 0 1)) + (regexp (nth 0 params)) (v2k (verilog-in-paren-quick)) (modi (verilog-modi-current)) (moddecls (verilog-modi-get-decls modi)) @@ -11497,7 +11797,7 @@ sig-list regexp))) (setq sig-list (verilog-signals-not-matching-regexp sig-list verilog-auto-inout-ignore-regexp)) - (forward-line 1) + (verilog-forward-or-insert-line) (when v2k (verilog-repair-open-comma)) (when sig-list (verilog-insert-indent "// Beginning of automatic inouts (from unused autoinst inouts)\n") @@ -11739,6 +12039,225 @@ /*AUTOINOUTCOMP(\"ExampMain\",\"^i\")*/" (verilog-auto-inout-module nil t)) +(defun verilog-auto-inout-param () + "Expand AUTOINOUTPARAM statements, as part of \\[verilog-auto]. +Take input/output/inout statements from the specified module and insert +into the current module. This is useful for making null templates and +shell modules which need to have identical I/O with another module. +Any I/O which are already defined in this module will not be redefined. +For the complement of this function, see `verilog-auto-inout-comp', +and to make monitors with all inputs, see `verilog-auto-inout-in'. + +Limitations: + If placed inside the parenthesis of a module declaration, it creates + Verilog 2001 style, else uses Verilog 1995 style. + + Concatenation and outputting partial buses is not supported. + + Module names must be resolvable to filenames. See `verilog-auto-inst'. + + Signals are not inserted in the same order as in the original module, + though they will appear to be in the same order to an AUTOINST + instantiating either module. + + Signals declared as \"output reg\" or \"output wire\" etc will + lose the wire/reg declaration so that shell modules may + generate those outputs differently. However, \"output logic\" + is propagated. + +An example: + + module ExampShell (/*AUTOARG*/); + /*AUTOINOUTMODULE(\"ExampMain\")*/ + endmodule + + module ExampMain (i,o,io); + input i; + output o; + inout io; + endmodule + +Typing \\[verilog-auto] will make this into: + + module ExampShell (/*AUTOARG*/i,o,io); + /*AUTOINOUTMODULE(\"ExampMain\")*/ + // Beginning of automatic in/out/inouts (from specific module) + output o; + inout io; + input i; + // End of automatics + endmodule + +You may also provide an optional regular expression, in which case only +signals matching the regular expression will be included. For example the +same expansion will result from only extracting signals starting with i: + + /*AUTOINOUTMODULE(\"ExampMain\",\"^i\")*/ + +You may also provide an optional second regular expression, in +which case only signals which have that pin direction and data +type will be included. This matches against everything before +the signal name in the declaration, for example against +\"input\" (single bit), \"output logic\" (direction and type) or +\"output [1:0]\" (direction and implicit type). You also +probably want to skip spaces in your regexp. + +For example, the below will result in matching the output \"o\" +against the previous example's module: + + /*AUTOINOUTMODULE(\"ExampMain\",\"\",\"^output.*\")*/ + +You may also provide an optional third regular expression, in +which case any parameter names that match the given regexp will +be included. Including parameters is off by default. To include +all signals and parameters, use: + + /*AUTOINOUTMODULE(\"ExampMain\",\".*\",\".*\",\".*\")*/" + (save-excursion + (let* ((params (verilog-read-auto-params 1 2)) + (submod (nth 0 params)) + (regexp (nth 1 params)) + submodi) + ;; Lookup position, etc of co-module + ;; Note this may raise an error + (when (setq submodi (verilog-modi-lookup submod t)) + (let* ((indent-pt (current-indentation)) + (v2k (verilog-in-paren-quick)) + (modi (verilog-modi-current)) + (moddecls (verilog-modi-get-decls modi)) + (submoddecls (verilog-modi-get-decls submodi)) + (sig-list-p (verilog-signals-not-in + (verilog-decls-get-gparams submoddecls) + (append (verilog-decls-get-gparams moddecls))))) + (forward-line 1) + (setq sig-list-p (verilog-signals-matching-regexp sig-list-p regexp)) + (when v2k (verilog-repair-open-comma)) + (when sig-list-p + (verilog-insert-indent "// Beginning of automatic parameters (from specific module)\n") + ;; Don't sort them so an upper AUTOINST will match the main module + (verilog-insert-definition modi sig-list-p "parameter" indent-pt v2k t) + (verilog-insert-indent "// End of automatics\n")) + (when v2k (verilog-repair-close-comma))))))) + +(defun verilog-auto-inout-modport () + "Expand AUTOINOUTMODPORT statements, as part of \\[verilog-auto]. +Take input/output/inout statements from the specified interface +and modport and insert into the current module. This is useful +for making verification modules that connect to UVM interfaces. + + The first parameter is the name of an interface. + + The second parameter is a regexp of modports to read from in + that interface. + + The optional third parameter is a regular expression, and only + signals matching the regular expression will be included. + +Limitations: + If placed inside the parenthesis of a module declaration, it creates + Verilog 2001 style, else uses Verilog 1995 style. + + Interface names must be resolvable to filenames. See `verilog-auto-inst'. + +As with other autos, any inputs/outputs declared in the module +will suppress the AUTO from redeclarating an inputs/outputs by +the same name. + +An example: + + interface ExampIf + ( input logic clk ); + logic req_val; + logic [7:0] req_dat; + clocking mon_clkblk @(posedge clk); + input req_val; + input req_dat; + endclocking + modport mp(clocking mon_clkblk); + endinterface + + module ExampMain + ( input clk, + /*AUTOINOUTMODPORT(\"ExampIf\" \"mp\")*/ + // Beginning of automatic in/out/inouts (from modport) + input [7:0] req_dat, + input req_val + // End of automatics + ); + /*AUTOASSIGNMODPORT(\"ExampIf\" \"mp\")*/ + endmodule + +Typing \\[verilog-auto] will make this into: + + ... + module ExampMain + ( input clk, + /*AUTOINOUTMODPORT(\"ExampIf\" \"mp\")*/ + // Beginning of automatic in/out/inouts (from modport) + input req_dat, + input req_val + // End of automatics + ); + +If the modport is part of a UVM monitor/driver class, this +creates a wrapper module that may be used to instantiate the +driver/monitor using AUTOINST in the testbench." + (save-excursion + (let* ((params (verilog-read-auto-params 2 3)) + (submod (nth 0 params)) + (modport-re (nth 1 params)) + (regexp (nth 2 params)) + direction-re submodi) ;; direction argument not supported until requested + ;; Lookup position, etc of co-module + ;; Note this may raise an error + (when (setq submodi (verilog-modi-lookup submod t)) + (let* ((indent-pt (current-indentation)) + (v2k (verilog-in-paren-quick)) + (modi (verilog-modi-current)) + (moddecls (verilog-modi-get-decls modi)) + (submoddecls (verilog-modi-get-decls submodi)) + (submodportdecls (verilog-modi-modport-lookup submodi modport-re)) + (sig-list-i (verilog-signals-in ;; Decls doesn't have data types, must resolve + (verilog-decls-get-vars submoddecls) + (verilog-signals-not-in + (verilog-decls-get-inputs submodportdecls) + (append (verilog-decls-get-ports submoddecls) + (verilog-decls-get-ports moddecls))))) + (sig-list-o (verilog-signals-in ;; Decls doesn't have data types, must resolve + (verilog-decls-get-vars submoddecls) + (verilog-signals-not-in + (verilog-decls-get-outputs submodportdecls) + (append (verilog-decls-get-ports submoddecls) + (verilog-decls-get-ports moddecls))))) + (sig-list-io (verilog-signals-in ;; Decls doesn't have data types, must resolve + (verilog-decls-get-vars submoddecls) + (verilog-signals-not-in + (verilog-decls-get-inouts submodportdecls) + (append (verilog-decls-get-ports submoddecls) + (verilog-decls-get-ports moddecls)))))) + (forward-line 1) + (setq sig-list-i (verilog-signals-edit-wire-reg + (verilog-signals-matching-dir-re + (verilog-signals-matching-regexp sig-list-i regexp) + "input" direction-re)) + sig-list-o (verilog-signals-edit-wire-reg + (verilog-signals-matching-dir-re + (verilog-signals-matching-regexp sig-list-o regexp) + "output" direction-re)) + sig-list-io (verilog-signals-edit-wire-reg + (verilog-signals-matching-dir-re + (verilog-signals-matching-regexp sig-list-io regexp) + "inout" direction-re))) + (when v2k (verilog-repair-open-comma)) + (when (or sig-list-i sig-list-o sig-list-io) + (verilog-insert-indent "// Beginning of automatic in/out/inouts (from modport)\n") + ;; Don't sort them so an upper AUTOINST will match the main module + (verilog-insert-definition modi sig-list-o "output" indent-pt v2k t) + (verilog-insert-definition modi sig-list-io "inout" indent-pt v2k t) + (verilog-insert-definition modi sig-list-i "input" indent-pt v2k t) + (verilog-insert-indent "// End of automatics\n")) + (when v2k (verilog-repair-close-comma))))))) + (defun verilog-auto-insert-lisp () "Expand AUTOINSERTLISP statements, as part of \\[verilog-auto]. The Lisp code provided is called, and the Lisp code calls @@ -11789,7 +12308,7 @@ (backward-sexp 1) ;; Inside comment (point))) ;; Beginning paren (cmd (buffer-substring-no-properties cmd-beg-pt cmd-end-pt))) - (forward-line 1) + (verilog-forward-or-insert-line) ;; Some commands don't move point (like insert-file) so we always ;; add the begin/end comments, then delete it if not needed (verilog-insert-indent "// Beginning of automatic insert lisp\n") @@ -12042,6 +12561,7 @@ An example of making a stub for another module: module ExampStub (/*AUTOINST*/); + /*AUTOINOUTPARAM(\"Foo\")*/ /*AUTOINOUTMODULE(\"Foo\")*/ /*AUTOTIEOFF*/ // verilator lint_off UNUSED @@ -12054,6 +12574,7 @@ Typing \\[verilog-auto] will make this into: module ExampStub (/*AUTOINST*/...); + /*AUTOINOUTPARAM(\"Foo\")*/ /*AUTOINOUTMODULE(\"Foo\")*/ // Beginning of autotieoff output [2:0] foo; @@ -12084,7 +12605,7 @@ (setq sig-list (verilog-signals-not-matching-regexp sig-list verilog-auto-tieoff-ignore-regexp)) (when sig-list - (forward-line 1) + (verilog-forward-or-insert-line) (verilog-insert-indent "// Beginning of automatic tieoffs (for this module's unterminated outputs)\n") (setq sig-list (sort (copy-alist sig-list) `verilog-signals-sort-compare)) (verilog-modi-cache-add-vars modi sig-list) ; Before we trash list @@ -12161,7 +12682,7 @@ ;; Insert (setq defs (sort defs 'string<)) (when defs - (forward-line 1) + (verilog-forward-or-insert-line) (verilog-insert-indent "// Beginning of automatic undefs\n") (while defs (verilog-insert-indent "`undef " (car defs) "\n") @@ -12198,6 +12719,7 @@ An example of making a stub for another module: module ExampStub (/*AUTOINST*/); + /*AUTOINOUTPARAM(\"Examp\")*/ /*AUTOINOUTMODULE(\"Examp\")*/ /*AUTOTIEOFF*/ // verilator lint_off UNUSED @@ -12236,7 +12758,7 @@ (setq sig-list (verilog-signals-not-matching-regexp sig-list verilog-auto-unused-ignore-regexp)) (when sig-list - (forward-line 1) + (verilog-forward-or-insert-line) (verilog-insert-indent "// Beginning of automatic unused inputs\n") (setq sig-list (sort (copy-alist sig-list) `verilog-signals-sort-compare)) (while sig-list @@ -12335,10 +12857,7 @@ ;; (sig-list-consts (append (verilog-decls-get-consts moddecls) (verilog-decls-get-gparams moddecls))) - (sig-list-all (append (verilog-decls-get-vars moddecls) - (verilog-decls-get-outputs moddecls) - (verilog-decls-get-inouts moddecls) - (verilog-decls-get-inputs moddecls))) + (sig-list-all (verilog-decls-get-iovars moddecls)) ;; (undecode-sig (or (assoc undecode-name sig-list-all) (error "%s: Signal %s not found in design" (verilog-point-text) undecode-name))) @@ -12371,7 +12890,7 @@ elim-regexp))) tmp-sigs (cdr tmp-sigs)))) ;; - (forward-line 1) + (verilog-forward-or-insert-line) (verilog-insert-indent "// Beginning of automatic ASCII enum decoding\n") (let ((decode-sig-list (list (list ascii-name (format "[%d:0]" (- (* ascii-chars 8) 1)) (concat "Decode of " undecode-name) nil nil)))) @@ -12506,9 +13025,12 @@ Using \\[describe-function], see also: `verilog-auto-arg' for AUTOARG module instantiations `verilog-auto-ascii-enum' for AUTOASCIIENUM enumeration decoding + `verilog-auto-assign-modport' for AUTOASSIGNMODPORT assignment to/from modport `verilog-auto-inout-comp' for AUTOINOUTCOMP copy complemented i/o `verilog-auto-inout-in' for AUTOINOUTIN inputs for all i/o + `verilog-auto-inout-modport' for AUTOINOUTMODPORT i/o from an interface modport `verilog-auto-inout-module' for AUTOINOUTMODULE copying i/o from elsewhere + `verilog-auto-inout-param' for AUTOINOUTPARAM copying params from elsewhere `verilog-auto-inout' for AUTOINOUT making hierarchy inouts `verilog-auto-input' for AUTOINPUT making hierarchy inputs `verilog-auto-insert-lisp' for AUTOINSERTLISP insert code from lisp function @@ -12598,27 +13120,24 @@ (verilog-auto-re-search-do "/\\*\\(AUTOSENSE\\|AS\\)\\*/" 'verilog-auto-sense) (verilog-auto-re-search-do "/\\*AUTORESET\\*/" 'verilog-auto-reset) ;; Must be done before autoin/out as creates a reg - (verilog-auto-re-search-do "/\\*AUTOASCIIENUM([^)]*)\\*/" 'verilog-auto-ascii-enum) + (verilog-auto-re-search-do "/\\*AUTOASCIIENUM(.*?)\\*/" 'verilog-auto-ascii-enum) ;; ;; first in/outs from other files - (verilog-auto-re-search-do "/\\*AUTOINOUTMODULE([^)]*)\\*/" 'verilog-auto-inout-module) - (verilog-auto-re-search-do "/\\*AUTOINOUTCOMP([^)]*)\\*/" 'verilog-auto-inout-comp) - (verilog-auto-re-search-do "/\\*AUTOINOUTIN([^)]*)\\*/" 'verilog-auto-inout-in) + (verilog-auto-re-search-do "/\\*AUTOINOUTMODPORT(.*?)\\*/" 'verilog-auto-inout-modport) + (verilog-auto-re-search-do "/\\*AUTOINOUTMODULE(.*?)\\*/" 'verilog-auto-inout-module) + (verilog-auto-re-search-do "/\\*AUTOINOUTCOMP(.*?)\\*/" 'verilog-auto-inout-comp) + (verilog-auto-re-search-do "/\\*AUTOINOUTIN(.*?)\\*/" 'verilog-auto-inout-in) + (verilog-auto-re-search-do "/\\*AUTOINOUTPARAM(.*?)\\*/" 'verilog-auto-inout-param) ;; next in/outs which need previous sucked inputs first - (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\((\"[^\"]*\")\\)\\*/" - (lambda () (verilog-auto-output t))) - (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\*/" 'verilog-auto-output) - (verilog-auto-re-search-do "/\\*AUTOINPUT\\((\"[^\"]*\")\\)\\*/" - (lambda () (verilog-auto-input t))) - (verilog-auto-re-search-do "/\\*AUTOINPUT\\*/" 'verilog-auto-input) - (verilog-auto-re-search-do "/\\*AUTOINOUT\\((\"[^\"]*\")\\)\\*/" - (lambda () (verilog-auto-inout t))) - (verilog-auto-re-search-do "/\\*AUTOINOUT\\*/" 'verilog-auto-inout) + (verilog-auto-re-search-do "/\\*AUTOOUTPUT\\((.*?)\\)?\\*/" 'verilog-auto-output) + (verilog-auto-re-search-do "/\\*AUTOINPUT\\((.*?)\\)?\\*/" 'verilog-auto-input) + (verilog-auto-re-search-do "/\\*AUTOINOUT\\((.*?)\\)?\\*/" 'verilog-auto-inout) ;; Then tie off those in/outs (verilog-auto-re-search-do "/\\*AUTOTIEOFF\\*/" 'verilog-auto-tieoff) ;; These can be anywhere after AUTOINSERTLISP - (verilog-auto-re-search-do "/\\*AUTOUNDEF\\((\"[^\"]*\")\\)?\\*/" 'verilog-auto-undef) + (verilog-auto-re-search-do "/\\*AUTOUNDEF\\((.*?)\\)?\\*/" 'verilog-auto-undef) ;; Wires/regs must be after inputs/outputs + (verilog-auto-re-search-do "/\\*AUTOASSIGNMODPORT(.*?)\\*/" 'verilog-auto-assign-modport) (verilog-auto-re-search-do "/\\*AUTOLOGIC\\*/" 'verilog-auto-logic) (verilog-auto-re-search-do "/\\*AUTOWIRE\\*/" 'verilog-auto-wire) (verilog-auto-re-search-do "/\\*AUTOREG\\*/" 'verilog-auto-reg) @@ -12696,7 +13215,7 @@ ;; ;; Place the templates into Verilog Mode. They may be inserted under any key. ;; C-c C-t will be the default. If you use templates a lot, you -;; may want to consider moving the binding to another key in your .emacs +;; may want to consider moving the binding to another key in your init ;; file. ;; ;; Note \C-c and letter are reserved for users ------------------------------------------------------------ Use --include-merged or -n0 to see merged revisions.