Fix various verilog-mode.el issues.

* lisp/progmodes/verilog-mode.el (verilog-expand-dirnames): Fix expanding
"*/*", msg2284. Reported by Jonathan Ferguson.
(ignore-errors): Fix ignore-errors error on Emacs 22.3, bug1177. Reported
by Victor Lau.
(verilog-getopt, verilog-getopt-file) (verilog-library-flags,
verilog-substitute-file-name-path): Support -F in verilog getopt files,
bug1171. Reported by George Cuan.
(verilog-do-indent): Fix misindenting symbols starting with t,
bug1169. Reported by Hoai Tran.
(verilog-read-auto-template-middle): Fix slow template matching on
AUTOINST. Reported by Jeffrey Huynh.
(verilog-pretty-expr): The extra whitespace addition before "=" operators
is now done only if the whole assignment block contains the 2-character
"<=" operator.  Remove the unused argument _myre.  Use `unless',
`save-excursion' and `when' functions where possible.  Internal variables
refactored for clarity.  Follow elisp convention for closing parentheses.
By Kaushal Modi.
(verilog-get-lineup-indent-2): Update docstring.  Internal variables
refactored for clarity.  Earlier EDPOS argument was expected to be a
marker; it is now renamed to END and is now expected to be a position.
Use `when' instead of `if'.  By Kaushal Modi.
(electric-verilog-terminate-line): Remove the unused second argument from
`verilog-pretty-expr' call.  By Kaushal Modi.
(verilog-calc-1): Fix indentation of a virtual class definition after a
typedef class, bug1080.  By Kaushal Modi.
This commit is contained in:
Wilson Snyder 2017-09-07 23:24:28 -04:00
parent 9546e1eba5
commit 442fe11143

View file

@ -4,7 +4,6 @@
;; Author: Michael McNamara <mac@verilog.com>
;; Wilson Snyder <wsnyder@wsnyder.org>
;; X-URL: http://www.verilog.com
;; X-URL: http://www.veripool.org
;; Created: 3 Jan 1996
;; Keywords: languages
@ -70,7 +69,7 @@
;; default.
;; You can get step by step help in installing this file by going to
;; <http://www.verilog.com/emacs_install.html>
;; <http://www.veripool.com/verilog-mode>
;; The short list of installation instructions are: To set up
;; automatic Verilog mode, put this file in your load path, and put
@ -123,7 +122,7 @@
;;
;; This variable will always hold the version number of the mode
(defconst verilog-mode-version "2017-05-08-b240c8f-vpo-GNU"
(defconst verilog-mode-version "2017-08-07-c085e50-vpo-GNU"
"Version of this Verilog mode.")
(defconst verilog-mode-release-emacs t
"If non-nil, this version of Verilog mode was released with Emacs itself.")
@ -345,6 +344,12 @@ wherever possible, since it is slow."
(unless (fboundp 'buffer-chars-modified-tick) ; Emacs 22 added
(defmacro buffer-chars-modified-tick () (buffer-modified-tick)))
(error nil))
;; Added in Emacs 23.1
(condition-case nil
(unless (fboundp 'ignore-errors)
(defmacro ignore-errors (&rest body)
(declare (debug t) (indent 0))
`(condition-case nil (progn ,@body) (error nil)))))
;; Added in Emacs 24.1
(condition-case nil
(unless (fboundp 'prog-mode)
@ -961,7 +966,8 @@ Only used in XEmacs; GNU Emacs uses `verilog-error-regexp-emacs-alist'.")
These arguments are used to find files for `verilog-auto', and match
the flags accepted by a standard Verilog-XL simulator.
-f filename Reads more `verilog-library-flags' from the filename.
-f filename Reads absolute `verilog-library-flags' from the filename.
-F filename Reads relative `verilog-library-flags' from the filename.
+incdir+dir Adds the directory to `verilog-library-directories'.
-Idir Adds the directory to `verilog-library-directories'.
-y dir Adds the directory to `verilog-library-directories'.
@ -4034,7 +4040,7 @@ With optional ARG, remove existing end of line comments."
(progn
(if (or (eq 'all verilog-auto-lineup)
(eq 'assignments verilog-auto-lineup))
(verilog-pretty-expr t "\\(<\\|:\\)?=" ))
(verilog-pretty-expr :quiet))
(newline))
(forward-line 1))
;; Indent next line
@ -5790,11 +5796,9 @@ Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
(goto-char here) ; or is clocking, starts a new block
(throw 'nesting 'block)))))
;; need to consider typedef struct here...
((looking-at "\\<class\\|struct\\|function\\|task\\>")
;; *sigh* These words have an optional prefix:
;; extern {virtual|protected}? function a();
;; typedef class foo;
;; and we don't want to confuse this with
;; function a();
;; property
@ -5804,7 +5808,11 @@ Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
(cond
((looking-at verilog-dpi-import-export-re)
(throw 'continue 'foo))
((looking-at "\\<pure\\>\\s-+\\<virtual\\>\\s-+\\(?:\\<\\(local\\|protected\\|static\\)\\>\\s-+\\)?\\<\\(function\\|task\\)\\>\\s-+")
((or
(looking-at "\\<pure\\>\\s-+\\<virtual\\>\\s-+\\(?:\\<\\(local\\|protected\\|static\\)\\>\\s-+\\)?\\<\\(function\\|task\\)\\>\\s-+")
;; Do not throw 'defun for class typedefs like
;; typedef class foo;
(looking-at "\\<typedef\\>\\s-+\\(?:\\<virtual\\>\\s-+\\)?\\<class\\>\\s-+"))
(throw 'nesting 'statement))
((looking-at verilog-beg-block-re-ordered)
(throw 'nesting 'block))
@ -6660,7 +6668,7 @@ Only look at a few lines to determine indent level."
(let ((val))
(verilog-beg-of-statement-1)
(if (and (< (point) here)
(verilog-re-search-forward "=[ \\t]*" here 'move)
(verilog-re-search-forward "=[ \t]*" here 'move)
;; not at a |=>, #=#, or [=n] operator
(not (string-match "\\[=.\\|#=#\\||=>"
(or (buffer-substring (- (point) 2) (1+ (point)))
@ -6974,106 +6982,97 @@ Be verbose about progress unless optional QUIET set."
(forward-line 1))
(unless quiet (message "")))))))
(defun verilog-pretty-expr (&optional quiet _myre)
"Line up expressions around point, optionally QUIET with regexp _MYRE ignored."
(defun verilog-pretty-expr (&optional quiet)
"Line up expressions around point.
If QUIET is non-nil, do not print messages showing the progress of line-up."
(interactive)
(if (not (verilog-in-comment-or-string-p))
(save-excursion
(let ( (rexp (concat "^\\s-*" verilog-complete-reg))
(rexp1 (concat "^\\s-*" verilog-basic-complete-re)))
(beginning-of-line)
(if (and (not (looking-at rexp ))
(unless (verilog-in-comment-or-string-p)
(save-excursion
(let ((regexp (concat "^\\s-*" verilog-complete-reg))
(regexp1 (concat "^\\s-*" verilog-basic-complete-re)))
(beginning-of-line)
(when (and (not (looking-at regexp))
(looking-at verilog-assignment-operation-re)
(save-excursion
(goto-char (match-end 2))
(and (not (verilog-in-attribute-p))
(not (verilog-in-parameter-p))
(not (verilog-in-comment-or-string-p)))))
(let* ((here (point))
(e) (r)
(start
(progn
(beginning-of-line)
(setq e (point))
(verilog-backward-syntactic-ws)
(beginning-of-line)
(while (and (not (looking-at rexp1))
(looking-at verilog-assignment-operation-re)
(not (bobp))
)
(setq e (point))
(verilog-backward-syntactic-ws)
(let* ((start (save-excursion ; BOL of the first line of the assignment block
(beginning-of-line)
) ;Ack, need to grok `define
e))
(end
(progn
(goto-char here)
(let ((pt (point)))
(verilog-backward-syntactic-ws)
(beginning-of-line)
(while (and (not (looking-at regexp1))
(looking-at verilog-assignment-operation-re)
(not (bobp)))
(setq pt (point))
(verilog-backward-syntactic-ws)
(beginning-of-line)) ; Ack, need to grok `define
pt)))
(end (save-excursion ; EOL of the last line of the assignment block
(end-of-line)
(setq e (point)) ;Might be on last line
(verilog-forward-syntactic-ws)
(beginning-of-line)
(while (and
(not (looking-at rexp1 ))
(looking-at verilog-assignment-operation-re)
(progn
(end-of-line)
(not (eq e (point)))))
(setq e (point))
(let ((pt (point))) ; Might be on last line
(verilog-forward-syntactic-ws)
(beginning-of-line)
)
e))
(endpos (set-marker (make-marker) end))
(ind)
)
(goto-char start)
(verilog-do-indent (verilog-calculate-indent))
(if (and (not quiet)
(> (- end start) 100))
(message "Lining up expressions..(please stand by)"))
(while (and
(not (looking-at regexp1))
(looking-at verilog-assignment-operation-re)
(progn
(end-of-line)
(not (eq pt (point)))))
(setq pt (point))
(verilog-forward-syntactic-ws)
(beginning-of-line))
pt)))
(contains-2-char-operator (string-match "<=" (buffer-substring-no-properties start end)))
(endmark (set-marker (make-marker) end)))
(goto-char start)
(verilog-do-indent (verilog-calculate-indent))
(when (and (not quiet)
(> (- end start) 100))
(message "Lining up expressions.. (please stand by)"))
;; Set indent to minimum throughout region
(while (< (point) (marker-position endpos))
(beginning-of-line)
(verilog-just-one-space verilog-assignment-operation-re)
(beginning-of-line)
(verilog-do-indent (verilog-calculate-indent))
(end-of-line)
(verilog-forward-syntactic-ws)
)
;; Set indent to minimum throughout region
;; Rely on mark rather than on point as the indentation changes can
;; make the older point reference obsolete
(while (< (point) (marker-position endmark))
(beginning-of-line)
(save-excursion
(verilog-just-one-space verilog-assignment-operation-re))
(verilog-do-indent (verilog-calculate-indent))
(end-of-line)
(verilog-forward-syntactic-ws))
;; Now find biggest prefix
(setq ind (verilog-get-lineup-indent-2 verilog-assignment-operation-re start endpos))
;; Now indent each line.
(goto-char start)
(while (progn (setq e (marker-position endpos))
(setq r (- e (point)))
(> r 0))
(setq e (point))
(if (not quiet) (message "%d" r))
(cond
((looking-at verilog-assignment-operation-re)
(goto-char (match-beginning 2))
(if (not (or (verilog-in-parenthesis-p) ; leave attributes and comparisons alone
(verilog-in-coverage-p)))
(if (eq (char-after) ?=)
(indent-to (1+ ind)) ; line up the = of the <= with surrounding =
(indent-to ind)
))
)
((verilog-continued-line-1 start)
(goto-char e)
(indent-line-to ind))
(t ; Must be comment or white space
(goto-char e)
(verilog-forward-ws&directives)
(forward-line -1))
)
(forward-line 1))
(unless quiet (message ""))
))))))
(let ((ind (verilog-get-lineup-indent-2 verilog-assignment-operation-re start (marker-position endmark))) ; Find the biggest prefix
e)
;; Now indent each line.
(goto-char start)
(while (progn
(setq e (marker-position endmark))
(> e (point)))
(unless quiet
(message " verilog-pretty-expr: %d" (- e (point))))
(setq e (point))
(cond
((looking-at verilog-assignment-operation-re)
(goto-char (match-beginning 2))
(unless (or (verilog-in-parenthesis-p) ; Leave attributes and comparisons alone
(verilog-in-coverage-p))
(if (and contains-2-char-operator
(eq (char-after) ?=))
(indent-to (1+ ind)) ; Line up the = of the <= with surrounding =
(indent-to ind))))
((verilog-continued-line-1 start)
(goto-char e)
(indent-line-to ind))
(t ; Must be comment or white space
(goto-char e)
(verilog-forward-ws&directives)
(forward-line -1)))
(forward-line 1))
(unless quiet
(message "")))))))))
(defun verilog-just-one-space (myre)
"Remove extra spaces around regular expression MYRE."
@ -7180,30 +7179,30 @@ Region is defined by B and EDPOS."
;;(skip-chars-backward " \t")
(1+ (current-column))))))
(defun verilog-get-lineup-indent-2 (myre b edpos)
"Return the indent level that will line up several lines within the region."
(defun verilog-get-lineup-indent-2 (regexp beg end)
"Return the indent level that will line up several lines.
The lineup string is searched using REGEXP within the region between points
BEG and END."
(save-excursion
(let ((ind 0) e)
(goto-char b)
(let ((ind 0))
(goto-char beg)
;; Get rightmost position
(while (progn (setq e (marker-position edpos))
(< (point) e))
(if (and (verilog-re-search-forward myre e 'move)
(not (verilog-in-attribute-p))) ; skip attribute exprs
(progn
(goto-char (match-beginning 2))
(verilog-backward-syntactic-ws)
(if (> (current-column) ind)
(setq ind (current-column)))
(goto-char (match-end 0)))
))
(if (> ind 0)
(1+ ind)
;; No lineup-string found
(goto-char b)
(end-of-line)
(skip-chars-backward " \t")
(1+ (current-column))))))
(while (< (point) end)
(when (and (verilog-re-search-forward regexp end 'move)
(not (verilog-in-attribute-p))) ; skip attribute exprs
(goto-char (match-beginning 2))
(verilog-backward-syntactic-ws)
(if (> (current-column) ind)
(setq ind (current-column)))
(goto-char (match-end 0))))
(setq ind (if (> ind 0)
(1+ ind)
;; No lineup-string found
(goto-char beg)
(end-of-line)
(skip-chars-backward " \t")
(1+ (current-column))))
ind)))
(defun verilog-comment-depth (type val)
"A useful mode debugging aide. TYPE and VAL are comments for insertion."
@ -9344,7 +9343,7 @@ Returns REGEXP and list of ( (signal_name connection_name)... )."
;; Regexp form??
((looking-at
;; Regexp bug in XEmacs disallows ][ inside [], and wants + last
"\\s-*\\.\\(\\([a-zA-Z0-9`_$+@^.*?|---]+\\|[][]\\|\\\\[()|]\\)+\\)\\s-*(\\(.*\\))\\s-*\\(,\\|)\\s-*;\\)")
"\\s-*\\.\\(\\([a-zA-Z0-9`_$+@^.*?|---]\\|[][]\\|\\\\[()|]\\)+\\)\\s-*(\\(.*\\))\\s-*\\(,\\|)\\s-*;\\)")
(setq rep (match-string-no-properties 3))
(goto-char (match-end 0))
(setq tpl-wild-list
@ -9619,8 +9618,9 @@ Some macros and such are also found and included. For dinotrace.el."
;; Argument file parsing
;;
(defun verilog-getopt (arglist)
"Parse -f, -v etc arguments in ARGLIST list or string."
(defun verilog-getopt (arglist &optional default-dir)
"Parse -f, -v etc arguments in ARGLIST list or string.
Use DEFAULT-DIR to anchor paths if non-nil."
(unless (listp arglist) (setq arglist (list arglist)))
(let ((space-args '())
arg next-param)
@ -9638,6 +9638,8 @@ Some macros and such are also found and included. For dinotrace.el."
space-args (cdr space-args))
(cond
;; Need another arg
((equal arg "-F")
(setq next-param arg))
((equal arg "-f")
(setq next-param arg))
((equal arg "-v")
@ -9661,32 +9663,37 @@ Some macros and such are also found and included. For dinotrace.el."
((or (string-match "^\\+incdir\\+\\(.*\\)" arg) ; +incdir+dir
(string-match "^-I\\(.*\\)" arg)) ; -Idir
(verilog-add-list-unique `verilog-library-directories
(match-string 1 (substitute-in-file-name arg))))
(substitute-in-file-name (match-string 1 arg))))
;; Ignore
((equal "+librescan" arg))
((string-match "^-U\\(.*\\)" arg)) ; -Udefine
;; Second parameters
((equal next-param "-F")
(setq next-param nil)
(verilog-getopt-file (verilog-substitute-file-name-path arg default-dir)
(file-name-directory (verilog-substitute-file-name-path arg default-dir))))
((equal next-param "-f")
(setq next-param nil)
(verilog-getopt-file (substitute-in-file-name arg)))
(verilog-getopt-file (verilog-substitute-file-name-path arg default-dir) nil))
((equal next-param "-v")
(setq next-param nil)
(verilog-add-list-unique `verilog-library-files
(substitute-in-file-name arg)))
(verilog-substitute-file-name-path arg default-dir)))
((equal next-param "-y")
(setq next-param nil)
(verilog-add-list-unique `verilog-library-directories
(substitute-in-file-name arg)))
(verilog-substitute-file-name-path arg default-dir)))
;; Filename
((string-match "^[^-+]" arg)
(verilog-add-list-unique `verilog-library-files
(substitute-in-file-name arg)))
(verilog-substitute-file-name-path arg default-dir)))
;; Default - ignore; no warning
))))
;;(verilog-getopt (list "+libext+.a+.b" "+incdir+foodir" "+define+a+aval" "-f" "otherf" "-v" "library" "-y" "dir"))
(defun verilog-getopt-file (filename)
"Read Verilog options from the specified FILENAME."
(defun verilog-getopt-file (filename &optional default-dir)
"Read Verilog options from the specified FILENAME.
Use DEFAULT-DIR to anchor paths if non-nil."
(save-excursion
(let ((fns (verilog-library-filenames filename (buffer-file-name)))
(orig-buffer (current-buffer))
@ -9702,7 +9709,7 @@ Some macros and such are also found and included. For dinotrace.el."
(when (string-match "//" line)
(setq line (substring line 0 (match-beginning 0))))
(with-current-buffer orig-buffer ; Variables are buffer-local, so need right context.
(verilog-getopt line))))))
(verilog-getopt line default-dir))))))
(defun verilog-getopt-flags ()
"Convert `verilog-library-flags' into standard library variables."
@ -9719,6 +9726,13 @@ Some macros and such are also found and included. For dinotrace.el."
;; Allow user to customize
(verilog-run-hooks 'verilog-getopt-flags-hook))
(defun verilog-substitute-file-name-path (filename default-dir)
"Return FILENAME with environment variables substituted.
Use DEFAULT-DIR to anchor paths if non-nil."
(if default-dir
(expand-file-name (substitute-in-file-name filename) default-dir)
(substitute-in-file-name filename)))
(defun verilog-add-list-unique (varref object)
"Append to VARREF list the given OBJECT,
unless it is already a member of the variable's list."
@ -9898,42 +9912,44 @@ Or, just the existing dirnames themselves if there are no wildcards."
(interactive)
(unless dirnames
(error "`verilog-library-directories' should include at least `.'"))
(setq dirnames (reverse dirnames)) ; not nreverse
(let ((dirlist nil)
pattern dirfile dirfiles dirname root filename rest basefile)
(while dirnames
(setq dirname (substitute-in-file-name (car dirnames))
dirnames (cdr dirnames))
(cond ((string-match (concat "^\\(\\|[/\\]*[^*?]*[/\\]\\)" ; root
"\\([^/\\]*[*?][^/\\]*\\)" ; filename with *?
"\\(.*\\)") ; rest
dirname)
(setq root (match-string 1 dirname)
filename (match-string 2 dirname)
rest (match-string 3 dirname)
pattern filename)
;; now replace those * and ? with .+ and .
;; use ^ and /> to get only whole file names
(setq pattern (verilog-string-replace-matches "[*]" ".+" nil nil pattern)
pattern (verilog-string-replace-matches "[?]" "." nil nil pattern)
pattern (concat "^" pattern "$")
dirfiles (verilog-dir-files root))
(while dirfiles
(setq basefile (car dirfiles)
dirfile (expand-file-name (concat root basefile rest))
dirfiles (cdr dirfiles))
(if (and (string-match pattern basefile)
;; Don't allow abc/*/rtl to match abc/rtl via ..
(not (equal basefile "."))
(not (equal basefile ".."))
(file-directory-p dirfile))
(setq dirlist (cons dirfile dirlist)))))
;; Defaults
(t
(if (file-directory-p dirname)
(setq dirlist (cons dirname dirlist))))))
dirlist))
;;(verilog-expand-dirnames (list "." ".." "nonexist" "../*" "/home/wsnyder/*/v"))
(save-match-data
(setq dirnames (reverse dirnames)) ; not nreverse
(let ((dirlist nil)
pattern dirfile dirfiles dirname root filename rest basefile)
(setq dirnames (mapcar 'substitute-in-file-name dirnames))
(while dirnames
(setq dirname (car dirnames)
dirnames (cdr dirnames))
(cond ((string-match (concat "^\\(\\|[/\\]*[^*?]*[/\\]\\)" ; root
"\\([^/\\]*[*?][^/\\]*\\)" ; filename with *?
"\\(.*\\)") ; rest
dirname)
(setq root (match-string 1 dirname)
filename (match-string 2 dirname)
rest (match-string 3 dirname)
pattern filename)
;; now replace those * and ? with .+ and .
;; use ^ and /> to get only whole file names
(setq pattern (verilog-string-replace-matches "[*]" ".+" nil nil pattern)
pattern (verilog-string-replace-matches "[?]" "." nil nil pattern)
pattern (concat "^" pattern "$")
dirfiles (verilog-dir-files root))
(while dirfiles
(setq basefile (car dirfiles)
dirfile (expand-file-name (concat root basefile rest))
dirfiles (cdr dirfiles))
(when (and (string-match pattern basefile)
;; Don't allow abc/*/rtl to match abc/rtl via ..
(not (equal basefile "."))
(not (equal basefile "..")))
;; Might have more wildcards, so process again
(setq dirnames (cons dirfile dirnames)))))
;; Defaults
(t
(if (file-directory-p dirname)
(setq dirlist (cons dirname dirlist))))))
dirlist)))
;;(verilog-expand-dirnames (list "." ".." "nonexist" "../*" "/home/wsnyder/*/v" "../*/*"))
(defun verilog-library-filenames (filename &optional current check-ext)
"Return a search path to find the given FILENAME or module name.
@ -12074,7 +12090,7 @@ This is currently equivalent to:
with the below at the bottom of the file
// Local Variables:
// verilog-auto-logic-type:\"logic\"
// verilog-auto-wire-type:\"logic\"
// End:
In the future AUTOLOGIC may declare additional identifiers,
@ -13223,10 +13239,12 @@ Typing \\[verilog-auto] will make this into:
Replace the /*AUTOTIEOFF*/ comment with code to wire-tie all unused output
signals to deasserted.
/*AUTOTIEOFF*/ is used to make stub modules; modules that have the same
input/output list as another module, but no internals. Specifically, it
finds all outputs in the module, and if that input is not otherwise declared
as a register or wire, creates a tieoff.
/*AUTOTIEOFF*/ is used to make stub modules; modules that have
the same input/output list as another module, but no internals.
Specifically, it finds all outputs in the module, and if that
input is not otherwise declared as a register or wire, nor comes
from a AUTOINST submodule's output, creates a tieoff. AUTOTIEOFF
does not examine assignments to determine what is already driven.
AUTORESET ties signals to deasserted, which is presumed to be zero.
Signals that match `verilog-active-low-regexp' will be deasserted by tying
@ -14420,7 +14438,7 @@ Files are checked based on `verilog-library-flags'."
(with-output-to-temp-buffer "*verilog-mode help*"
(princ (format "You are using verilog-mode %s\n" verilog-mode-version))
(princ "\n")
(princ "For new releases, see http://www.verilog.com\n")
(princ "For new releases, see http://www.veripool.com/verilog-mode\n")
(princ "\n")
(princ "For frequently asked questions, see http://www.veripool.org/verilog-mode-faq.html\n")
(princ "\n")