Skip to content

Commit 194e186

Browse files
committed
Fix slow verilog-auto expansion.
* verilog-mode.el (verilog-scan-cache-preserving, verilog-scan-cache-tick, verilog-scan-region, verilog-scan, verilog-inside-comment-p, verilog-insert) Fix slow verilog-auto expansion on very large files. (4th fix: inside-comment now preparses buffer using verilog-scan and properties; verilog-insert must be used inside AUTO expanders.) git-svn-id: file:///verilog-mode-svn/trunk@598 db5bb42b-8904-0410-88e9-aa7026cf2ec3
1 parent 09098c6 commit 194e186

File tree

1 file changed

+94
-41
lines changed

1 file changed

+94
-41
lines changed

verilog-mode.el

+94-41
Original file line numberDiff line numberDiff line change
@@ -2532,22 +2532,78 @@ See also `verilog-font-lock-extra-types'.")
25322532
(0 'verilog-font-lock-translate-off-face prepend))
25332533
)))))
25342534

2535+
;;
2536+
;; Comment detection and caching
25352537

2536-
(defun verilog-inside-comment-p ()
2537-
"Check if point inside a nested comment."
2538+
(defvar verilog-scan-cache-preserving nil
2539+
"If set, the specified buffer's comment properties are static.
2540+
Buffer changes will be ignored. See `verilog-inside-comment-p'
2541+
and `verilog-scan'.")
2542+
2543+
(defvar verilog-scan-cache-tick nil
2544+
"Modification tick at which `verilog-scan' was last completed.")
2545+
(make-variable-buffer-local 'verilog-scan-cache-tick)
2546+
2547+
(defun verilog-scan-region (beg end)
2548+
"Parse comments between BEG and END for `verilog-inside-comment-p'."
25382549
(save-excursion
2539-
(let ((st-point (point)) hitbeg)
2540-
(or (search-backward "//" (verilog-get-beg-of-line) t)
2541-
(if (progn
2542-
;; This is for tricky case //*, we keep searching if /*
2543-
;; is proceeded by // on same line.
2544-
(while
2545-
(and (setq hitbeg (search-backward "/*" nil t))
2546-
(progn
2547-
(forward-char 1)
2548-
(search-backward "//" (verilog-get-beg-of-line) t))))
2549-
hitbeg)
2550-
(not (search-forward "*/" st-point t)))))))
2550+
(let (pt)
2551+
(goto-char beg)
2552+
(while (< (point) end)
2553+
(cond ((looking-at "//")
2554+
(setq pt (point))
2555+
(or (search-forward "\n" end t)
2556+
(goto-char end))
2557+
;; "1+": The leading // or /* itself isn't considered as
2558+
;; being "inside" the comment, so that a (search-backward)
2559+
;; that lands at the start of the // won't mis-indicate
2560+
;; it's inside a comment
2561+
(put-text-property (1+ pt) (point) 'v-cmt t))
2562+
((looking-at "/\\*")
2563+
(setq pt (point))
2564+
(or (search-forward "*/" end t)
2565+
;; No error - let later code indicate it so we can
2566+
;; use inside functions on-the-fly
2567+
;;(error "%s: Unmatched /* */, at char %d"
2568+
;; (verilog-point-text) (point))
2569+
(goto-char end))
2570+
(put-text-property (1+ pt) (point) 'v-cmt t))
2571+
(t
2572+
(forward-char 1)
2573+
(if (search-forward "/" end t)
2574+
(backward-char 1)
2575+
(goto-char end))))))))
2576+
2577+
(defun verilog-scan ()
2578+
"Parse the buffer, marking all comments with properties.
2579+
Also assumes any text inserted since `verilog-scan-cache-tick'
2580+
either is ok to parse as a non-comment, or `verilog-insert' was used."
2581+
(unless (or (and verilog-scan-cache-preserving
2582+
(eq verilog-scan-cache-preserving (current-buffer)))
2583+
(equal verilog-scan-cache-tick (buffer-modified-tick)))
2584+
(setq verilog-scan-cache-tick (buffer-modified-tick))
2585+
(save-excursion
2586+
(let ((was-mod (buffer-modified-p)))
2587+
(remove-text-properties (point-min) (point-max) '(v-cmt nil))
2588+
(verilog-scan-region (point-min) (point-max))
2589+
(unless was-mod (set-buffer-modified-p nil))))))
2590+
2591+
(defun verilog-inside-comment-p ()
2592+
"Check if point inside a comment.
2593+
This may require a slow pre-parse of the buffer with `verilog-scan'
2594+
to establish comment properties on all text."
2595+
(verilog-scan)
2596+
(get-text-property (point) 'v-cmt))
2597+
2598+
(defun verilog-insert (&rest stuff)
2599+
"Insert arguments, tracking comments for `verilog-inside-comment-p'."
2600+
(let ((pt (point)))
2601+
(while stuff
2602+
(insert (car stuff))
2603+
(setq stuff (cdr stuff)))
2604+
(verilog-scan-region pt (point))))
2605+
2606+
;; More searching
25512607

25522608
(defun verilog-declaration-end ()
25532609
(search-forward ";"))
@@ -7908,7 +7964,7 @@ See `verilog-dir-exists-p' and `verilog-dir-files'.")
79087964
"Execute the BODY forms, allowing directory cache preservation within BODY.
79097965
This means that changes inside BODY made to the file system will not be
79107966
seen by the `verilog-dir-files' and related functions."
7911-
`(let ((verilog-dir-cache-preserving t)
7967+
`(let ((verilog-dir-cache-preserving (current-buffer))
79127968
verilog-dir-cache-list
79137969
verilog-dir-cache-lib-filenames)
79147970
(progn ,@body)))
@@ -8470,7 +8526,7 @@ format. Sort unless DONT-SORT. DIRECTION is normally wire/reg/output."
84708526
(equal "" (verilog-sig-comment sig)))
84718527
(insert "\n")
84728528
(indent-to (max 48 (+ indent-pt 40)))
8473-
(insert (concat "// " (verilog-sig-comment sig) "\n")))
8529+
(verilog-insert "// " (verilog-sig-comment sig) "\n"))
84748530
(setq sigs (cdr sigs)))))
84758531

84768532
(eval-when-compile
@@ -8484,7 +8540,7 @@ Presumes that any newlines end a list element."
84848540
(while stuff
84858541
(if need-indent (indent-to indent-pt))
84868542
(setq need-indent nil)
8487-
(insert (car stuff))
8543+
(verilog-insert (car stuff))
84888544
(setq need-indent (string-match "\n$" (car stuff))
84898545
stuff (cdr stuff)))))
84908546
;;(let ((indent-pt 10)) (verilog-insert-indent "hello\n" "addon" "there\n"))
@@ -8816,7 +8872,7 @@ Typing \\[verilog-inject-auto] will make this into:
88168872
(verilog-backward-syntactic-ws)
88178873
(backward-char 1) ; Moves to paren that closes argdecl's
88188874
(when (looking-at ")")
8819-
(insert "/*AUTOARG*/")))))))
8875+
(verilog-insert "/*AUTOARG*/")))))))
88208876

88218877
(defun verilog-inject-sense ()
88228878
"Inject AUTOSENSE into new code. See `verilog-inject-auto'."
@@ -8838,7 +8894,7 @@ Typing \\[verilog-inject-auto] will make this into:
88388894
(when (not (or (verilog-signals-not-in pre-sigs got-sigs) ; Both are equal?
88398895
(verilog-signals-not-in got-sigs pre-sigs)))
88408896
(delete-region start-pt (point))
8841-
(insert "/*AS*/")))))))
8897+
(verilog-insert "/*AS*/")))))))
88428898

88438899
(defun verilog-inject-inst ()
88448900
"Inject AUTOINST into new code. See `verilog-inject-auto'."
@@ -8872,9 +8928,8 @@ Typing \\[verilog-inject-auto] will make this into:
88728928
;; Not verilog-re-search, as we don't want to strip comments
88738929
(while (re-search-backward "[ \t\n\f]+" (- (point) 1) t)
88748930
(delete-region (match-beginning 0) (match-end 0)))
8875-
(insert "\n")
8876-
(indent-to indent-pt)
8877-
(insert "/*AUTOINST*/")))))))))
8931+
(verilog-insert "\n")
8932+
(verilog-insert-indent "/*AUTOINST*/")))))))))
88788933

88798934
;;
88808935
;; Auto save
@@ -9113,14 +9168,15 @@ If PAR-VALUES replace final strings with these parameter values."
91139168
(cond (tpl-ass
91149169
(indent-to (+ (if (< verilog-auto-inst-column 48) 24 16)
91159170
verilog-auto-inst-column))
9116-
(insert " // Templated")
9117-
(when verilog-auto-inst-template-numbers
9118-
(insert " T" (int-to-string (nth 2 tpl-ass))
9119-
" L" (int-to-string (nth 3 tpl-ass)))))
9171+
(if verilog-auto-inst-template-numbers
9172+
(verilog-insert " // Templated"
9173+
" T" (int-to-string (nth 2 tpl-ass))
9174+
" L" (int-to-string (nth 3 tpl-ass)))
9175+
(verilog-insert " // Templated")))
91209176
(for-star
91219177
(indent-to (+ (if (< verilog-auto-inst-column 48) 24 16)
91229178
verilog-auto-inst-column))
9123-
(insert " // Implicit .\*"))) ;For some reason the . or * must be escaped...
9179+
(verilog-insert " // Implicit .\*"))) ;For some reason the . or * must be escaped...
91249180
(insert "\n")))
91259181
;;(verilog-auto-inst-port (list "foo" "[5:0]") 10 (list (list "foo" "a@\"(% (+ @ 1) 4)\"a")) "3")
91269182
;;(x "incom[@\"(+ (* 8 @) 7)\":@\"(* 8 @)\"]")
@@ -9471,9 +9527,8 @@ For more information see the \\[verilog-faq] and forums at URL
94719527
(vl-dir "interface"))
94729528
(when sig-list
94739529
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
9474-
(indent-to indent-pt)
94759530
;; Note these are searched for in verilog-read-sub-decls.
9476-
(insert "// Interfaces\n")
9531+
(verilog-insert-indent "// Interfaces\n")
94779532
(mapc (lambda (port)
94789533
(verilog-auto-inst-port port indent-pt
94799534
tpl-list tpl-num for-star par-values))
@@ -9484,8 +9539,7 @@ For more information see the \\[verilog-faq] and forums at URL
94849539
(vl-dir "output"))
94859540
(when sig-list
94869541
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
9487-
(indent-to indent-pt)
9488-
(insert "// Outputs\n")
9542+
(verilog-insert-indent "// Outputs\n")
94899543
(mapc (lambda (port)
94909544
(verilog-auto-inst-port port indent-pt
94919545
tpl-list tpl-num for-star par-values))
@@ -9496,8 +9550,7 @@ For more information see the \\[verilog-faq] and forums at URL
94969550
(vl-dir "inout"))
94979551
(when sig-list
94989552
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
9499-
(indent-to indent-pt)
9500-
(insert "// Inouts\n")
9553+
(verilog-insert-indent "// Inouts\n")
95019554
(mapc (lambda (port)
95029555
(verilog-auto-inst-port port indent-pt
95039556
tpl-list tpl-num for-star par-values))
@@ -9508,8 +9561,7 @@ For more information see the \\[verilog-faq] and forums at URL
95089561
(vl-dir "input"))
95099562
(when sig-list
95109563
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
9511-
(indent-to indent-pt)
9512-
(insert "// Inputs\n")
9564+
(verilog-insert-indent "// Inputs\n")
95139565
(mapc (lambda (port)
95149566
(verilog-auto-inst-port port indent-pt
95159567
tpl-list tpl-num for-star par-values))
@@ -9614,9 +9666,8 @@ Templates:
96149666
(vl-dir "parameter"))
96159667
(when sig-list
96169668
(when (not did-first) (verilog-auto-inst-first) (setq did-first t))
9617-
(indent-to indent-pt)
96189669
;; Note these are searched for in verilog-read-sub-decls.
9619-
(insert "// Parameters\n")
9670+
(verilog-insert-indent "// Parameters\n")
96209671
(mapc (lambda (port)
96219672
(verilog-auto-inst-port port indent-pt
96229673
tpl-list tpl-num nil nil))
@@ -10322,6 +10373,7 @@ text:
1032210373
(forward-line -1)
1032310374
(eval (read cmd))
1032410375
(forward-line -1)
10376+
(setq verilog-scan-cache-tick nil) ;; Clear cache; inserted unknown text
1032510377
(verilog-delete-empty-auto-pair))))
1032610378

1032710379
(defun verilog-auto-sense-sigs (moddecls presense-sigs)
@@ -10413,7 +10465,7 @@ operator. (This was added to the language in part due to AUTOSENSE!)
1041310465
(when sig-memories
1041410466
(let ((tlen (length sig-list)))
1041510467
(setq sig-list (verilog-signals-not-in sig-list sig-memories))
10416-
(if (not (eq tlen (length sig-list))) (insert " /*memory or*/ "))))
10468+
(if (not (eq tlen (length sig-list))) (verilog-insert " /*memory or*/ "))))
1041710469
(if (and presense-sigs ;; Add a "or" if not "(.... or /*AUTOSENSE*/"
1041810470
(save-excursion (goto-char (point))
1041910471
(verilog-re-search-backward "[a-zA-Z0-9$_.%`]+" start-pt t)
@@ -10517,8 +10569,7 @@ Typing \\[verilog-auto] will make this into:
1051710569
(setq sig-list (sort sig-list `verilog-signals-sort-compare))
1051810570
(when sig-list
1051910571
(insert "\n");
10520-
(indent-to indent-pt)
10521-
(insert "// Beginning of autoreset for uninitialized flops\n");
10572+
(verilog-insert-indent "// Beginning of autoreset for uninitialized flops\n");
1052210573
(indent-to indent-pt)
1052310574
(while sig-list
1052410575
(let ((sig (or (assoc (verilog-sig-name (car sig-list)) all-list) ;; As sig-list has no widths
@@ -10529,7 +10580,7 @@ Typing \\[verilog-auto] will make this into:
1052910580
";\n")
1053010581
(indent-to indent-pt)
1053110582
(setq sig-list (cdr sig-list))))
10532-
(insert "// End of automatics")))))
10583+
(verilog-insert "// End of automatics")))))
1053310584

1053410585
(defun verilog-auto-tieoff ()
1053510586
"Expand AUTOTIEOFF statements, as part of \\[verilog-auto].
@@ -10939,6 +10990,8 @@ Wilson Snyder ([email protected])."
1093910990
(after-change-functions nil)
1094010991
;; Cache directories; we don't write new files, so can't change
1094110992
(verilog-dir-cache-preserving t)
10993+
(verilog-scan-cache-preserving (current-buffer))
10994+
(verilog-scan-cache-tick nil)
1094210995
;; Cache current module
1094310996
(verilog-modi-cache-current-enable t)
1094410997
(verilog-modi-cache-current-max (point-min)) ; IE it's invalid

0 commit comments

Comments
 (0)