From xemacs-m  Tue Feb  4 14:21:40 1997
Received: from steadfast.teradyne.com (steadfast.teradyne.com [131.101.1.200])
	by xemacs.org (8.8.5/8.8.5) with ESMTP id OAA07827
	for <xemacs-beta@xemacs.org>; Tue, 4 Feb 1997 14:21:38 -0600 (CST)
Received: from engine.ecf.teradyne.com (engine.ecf.teradyne.com [131.101.192.6]) by steadfast.teradyne.com (8.7.1/8.7.1) with ESMTP id PAA25196; Tue, 4 Feb 1997 15:23:43 -0500 (EST)
Received: from midnight.eng.ecf.teradyne.com (midnight.ecf.teradyne.com [131.101.192.49]) by engine.ecf.teradyne.com (8.7.1/8.7.1) with SMTP id VAA18279; Tue, 4 Feb 1997 21:19:54 +0100 (MET)
Received: by midnight.eng.ecf.teradyne.com (SMI-8.6/SMI-SVR4)
	id VAA02924; Tue, 4 Feb 1997 21:19:54 +0100
To: Michael McNamara <mac@silicon-sorcery.com>
Cc: XEmacs Beta Mailing List <xemacs-beta@xemacs.org>,
        Jens Edelmann <edelmann@ecf.teradyne.com>
X-Face: 4[iHdXiTu\V3u[~\I)<f9HC);%~nG8`oUqv#uzvs6=\V{AjN6Sn
 c/qi;YLwRmEbt8Y*=j5n(urqY@chPh@J'D"QlqD!C8>*}#kYF[-tYl3VZga/HSOP|K,{L
 Rtu@f0y/=O&Cu}\:~d|P$JON?pn?j,&CnPb1z#/TL9bkAJwyol&a:SvYj-VYbM=Dtxhk9
 =w|R6U3_;SH&B<Mfy6Q%#
Subject: Update of verilog-mode.el<2.21> for XEmacs-20.0 (2/4)
Mime-Version: 1.0 (split by tm-edit 7.101)
Content-Type: message/partial; id="Tue_Feb__4_21:19:50_1997@midnight.ecf.teradyne.com"; number=2; total=4
From: Adrian Aichner <aichner@ecf.teradyne.com>
Date: 04 Feb 1997 21:19:51 +0100
Message-ID: <rxsvi88coig.fsf@midnight.ecf.teradyne.com>
Lines: 999
X-Mailer: Red Gnus v0.84/XEmacs 20.0

      (verilog-indent-comment t)
      (insert-string "* ")
      )
     ((eolp)
       ;; First, check if current line should be indented
       (if (save-excursion 
             (delete-horizontal-space)
	     (beginning-of-line)
	     (skip-chars-forward " \t")
	     (if (looking-at verilog-autoindent-lines-re)
		 (let ((indent-str (verilog-indent-line)))
		   ;; Maybe we should set some endcomments
		   (if verilog-auto-endcomments
		       (verilog-set-auto-endcomments indent-str arg))
		   (end-of-line)
		   (delete-horizontal-space)
		   (if arg
		       ()
		     (newline))
		   nil)
	       (progn
		 (end-of-line)
		 (delete-horizontal-space)
		 (newline))))
	   (newline)
	 (forward-line 1))
       ;; Indent next line
       (if verilog-auto-indent-on-newline
	   (verilog-indent-line))
       )
     (t
      (newline)
      )
     )
    )
  )
  
(defun electric-verilog-semi ()
  "Insert `;' character and reindent the line."
  (interactive)
  (insert last-command-char)
  (save-excursion
    (beginning-of-line)
    (verilog-indent-line))
  (if (and verilog-auto-newline
	   (= 0 (verilog-parenthesis-depth)))
      (electric-verilog-terminate-line)))

(defun electric-verilog-colon ()
  "Insert `:' and do all indentions except line indent on this line."
  (interactive)
  (insert last-command-char)
  ;; Do nothing if within string.
  (if (or
       (verilog-within-string)
       (not (verilog-in-case-region-p)))
      ()
    (save-excursion
      (let ((p (point))
	    (lim (progn (verilog-beg-of-statement) (point))))
	(goto-char p)
	(verilog-backward-case-item lim)
	(verilog-indent-line)))
;;    (let ((verilog-tab-always-indent nil))
;;      (verilog-indent-line))
    )
  )

(defun electric-verilog-equal ()
  "Insert `=', and do indention if within block."
  (interactive)
  (insert last-command-char)
;; Could auto line up expressions, but not yet
;;  (if (eq (car (verilog-calculate-indent)) 'block)
;;      (let ((verilog-tab-always-indent nil))
;;	(verilog-indent-command)))
)


(defun electric-verilog-tick ()
  "Insert back-tick, and indent to coulmn 0 if this is a CPP directive."
  (interactive)
  (insert last-command-char)
  (if (save-excursion (beginning-of-line) (looking-at "^[ \t]*\`\\(\\<ifdef\\>\\|\\\<else\\>\\|\\<endif\\>\\|\\<define\\>\\)"))
      (save-excursion (beginning-of-line)
		      (delete-horizontal-space))))

(defun electric-verilog-tab ()
  "Function called when TAB is pressed in Verilog mode."
  (interactive)
  ;; If verilog-tab-always-indent, indent the beginning of the line.
  (if verilog-tab-always-indent
      (let* ((boi-point (save-excursion
			  (beginning-of-line)
			  (skip-chars-forward " \t")
			  (let (type state )
			    (setq type (verilog-indent-line))
			    (setq state (car type))
			    (cond
			     ((eq state 'block)
			      (if (looking-at verilog-behavorial-block-beg-re )
				  (error (concat "The reserved word \""
					 (buffer-substring (match-beginning 0) (match-end 0))
					 "\" must be at the behavorial level!"))))
			     ))
			  (back-to-indentation)
			  (point))))
        (if (< (point) boi-point)
            (back-to-indentation)))
    (progn (insert "\t"))
    )
  )



;;;
;;; Interactive functions
;;;
(defun verilog-insert-block ()
  "Insert Verilog begin ... end; block in the code with right indentation."
  (interactive)
  (verilog-indent-line)
  (insert "begin")
  (electric-verilog-terminate-line)
  (save-excursion
    (electric-verilog-terminate-line)
    (insert "end")
    (beginning-of-line)
    (verilog-indent-line)))

(defun verilog-star-comment ()
  "Insert Verilog star comment at point."
  (interactive)
  (verilog-indent-line)
  (insert "/*")
  (save-excursion
    (newline)
    (insert " */"))
  (newline)
  (insert " * "))

(defun verilog-mark-defun ()
  "Mark the current verilog function (or procedure).
This puts the mark at the end, and point at the beginning."
  (interactive)
  (push-mark (point))
  (verilog-end-of-defun)
  (push-mark (point))
  (verilog-beg-of-defun)
  (if (fboundp 'zmacs-activate-region)
      (zmacs-activate-region)))

(defun verilog-comment-area (start end)
  "Put the region into a Verilog comment.
The comments that are in this area are \"deformed\":
`*)' becomes `!(*' and `}' becomes `!{'.
These deformed comments are returned to normal if you use
\\[verilog-uncomment-area] to undo the commenting.

The commented area starts with `verilog-exclude-str-start', and ends with
`verilog-include-str-end'.  But if you change these variables,
\\[verilog-uncomment-area] won't recognize the comments."
  (interactive "r")
  (save-excursion
    ;; Insert start and endcomments
    (goto-char end)
    (if (and (save-excursion (skip-chars-forward " \t") (eolp))
	     (not (save-excursion (skip-chars-backward " \t") (bolp))))
	(forward-line 1)
      (beginning-of-line))
    (insert verilog-exclude-str-end)
    (setq end (point))
    (newline)
    (goto-char start)
    (beginning-of-line)
    (insert verilog-exclude-str-start)
    (newline)
    ;; Replace end-comments within commented area
    (goto-char end)
    (save-excursion
      (while (re-search-backward "\\*/" start t)
	(replace-match "!/*" t t)))
    )
)

(defun verilog-uncomment-area ()
  "Uncomment a commented area; change deformed comments back to normal.
This command does nothing if the pointer is not in a commented
area.  See also `verilog-comment-area'."
  (interactive)
  (save-excursion
    (let ((start (point))
	  (end (point)))
      ;; Find the boundaries of the comment
      (save-excursion
	(setq start (progn (search-backward verilog-exclude-str-start nil t)
			   (point)))
	(setq end (progn (search-forward verilog-exclude-str-end nil t)
			 (point))))
      ;; Check if we're really inside a comment
      (if (or (equal start (point)) (<= end (point)))
	  (message "Not standing within commented area.")
	(progn
	  ;; Remove endcomment
	  (goto-char end)
	  (beginning-of-line)
	  (let ((pos (point)))
	    (end-of-line)
	    (delete-region pos (1+ (point))))
	  ;; Change comments back to normal
	  (save-excursion
	    (while (re-search-backward "!/\\*" start t)
	      (replace-match "*/" t t)))
	  ;; Remove startcomment
	  (goto-char start)
	  (beginning-of-line)
	  (let ((pos (point)))
	    (end-of-line)
	    (delete-region pos (1+ (point)))))))))

(defun verilog-beg-of-defun ()
  "Move backward to the beginning of the current function or procedure."
  (interactive)
  (verilog-re-search-backward verilog-defun-re nil 'move)
  )
(defun verilog-end-of-defun ()
  (interactive)
  (verilog-re-search-forward verilog-end-defun-re nil 'move)
  )

(defun verilog-label-be (&optional arg)
  "Label matching begin ... end, fork ... join and case ... endcase statements in this module;
With argument, first kill any existing labels."
  (interactive)
  (let ((cnt 0)
	(oldpos (point))
	(b (progn 
	     (verilog-beg-of-defun) 
	     (point-marker)))
	(e (progn 
	     (verilog-end-of-defun) 
	     (point-marker)))
	)
    (goto-char (marker-position b))
    (if (> (- e b) 200)
	(message  "Relabeling module..."))
    (while (and
	    (> (marker-position e) (point))
	    (verilog-re-search-forward 
	     (concat 
	      "\\<end\\(\\(function\\)\\|\\(task\\)\\|\\(module\\)\\|\\(primitive\\)\\|\\(case\\)\\)?\\>"
	      "\\|\\(`endif\\)\\|\\(`else\\)")
	     nil 'move))
      (goto-char (match-beginning 0))
      (let ((indent-str (verilog-indent-line)))
	(verilog-set-auto-endcomments indent-str 't)
	(end-of-line)
	(delete-horizontal-space)
	)
      (setq cnt (1+ cnt))
      (if (= 9 (% cnt 10))
	  (message "%d..." cnt))
      )
    (goto-char oldpos)
    (if (or
	 (> (- e b) 200)
	 (> cnt 20))
	(message  "%d lines autocommented" cnt))
    )
  )

(defun verilog-beg-of-statement ()
  "Move backward to beginning of statement"
  (interactive)
  (while (save-excursion 
	   (and
	    (not (looking-at verilog-complete-reg))
	    (skip-chars-backward " \t")
	    (not (or (bolp) (= (preceding-char) ?\;)))
	    )
	   )
    (skip-chars-backward " \t")
    (verilog-backward-token))
  (let ((last (point)))
    (while (progn
	     (setq last (point))
	     (and (not (looking-at verilog-complete-reg))
		  (verilog-continued-line))))
    (goto-char last)
    (verilog-forward-syntactic-ws)
    )
  )
(defun verilog-end-of-statement ()
  "Move forward to end of current statement."
  (interactive)
  (let ((nest 0) pos)
    (if (not (looking-at "[ \t\n]")) (forward-sexp -1))
    (or (looking-at verilog-beg-block-re)
	;; Skip to end of statement
	(setq pos (catch 'found
		    (while t
		      (forward-sexp 1)
		      (verilog-skip-forward-comment-or-string)
		      (cond ((looking-at "[ \t]*;")
			     (skip-chars-forward "^;")
			     (forward-char 1)
			     (throw 'found (point)))
			    ((save-excursion
			       (forward-sexp -1)
			       (looking-at verilog-beg-block-re))
			     (goto-char (match-beginning 0))
			     (throw 'found nil))
			    ((eobp)
			     (throw 'found (point))))))))
    (if (not pos)
	;; Skip a whole block
	(catch 'found
	  (while t
	    (verilog-re-search-forward verilog-end-statement-re nil 'move)
	    (setq nest (if (match-end 1) 
			   (1+ nest)
			 (1- nest)))
	    (cond ((eobp)
		   (throw 'found (point)))
		  ((= 0 nest)
		   (throw 'found (verilog-end-of-statement))))))
      pos)))
(defun verilog-in-case-region-p ()
  "Return TRUE if in a case region: more specifically, point @ in the line foo : @ begin"
  (interactive)
  (save-excursion
    (if (and 
	 (progn (verilog-forward-syntactic-ws)	
		(looking-at "\\<begin\\>"))
	 (progn (verilog-backward-syntactic-ws)	
		(= (preceding-char) ?\:)))
	(catch 'found
	  (let ((nest 1))
	    (while t
	      (verilog-re-search-backward "\\(\\<module\\>\\)\\|\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)\\>" nil 'move)
	      (cond
	       ((match-end 3)
		(setq nest (1+ nest)))
	       ((match-end 2)
		(if (= nest 1)
		(throw 'found 1))
		(setq nest (1- nest))
		)
	       ( t
		 (throw 'found (= nest 0)))
	       )
	      )
	    )
	  )
      nil)
    )
  )
(defun verilog-backward-case-item (lim)
  "Skip backward to nearest enclosing case item"
  (interactive)
  (let (
	(str 'nil)
	(lim1 (progn 
		(save-excursion (verilog-re-search-backward verilog-endcomment-reason-re lim 'move)
				(point)))))
    ;; Try to find the real :
    (if (save-excursion (search-backward ":" lim1 t))
	(let ((colon 0)
	      b e )
	  (while (and (< colon 1)
		      (verilog-re-search-backward "\\(\\[\\)\\|\\(\\]\\)\\|\\(:\\)" lim1 'move))
	    (cond 
	     ((match-end 1) ;; [
	      (setq colon (1+ colon))
	      (if (>= colon 0)
		  (error "unbalanced [")))
	     ((match-end 2) ;; ]
	      (setq colon (1- colon)))
	     
	     ((match-end 3) ;; :
	      (setq colon (1+ colon)))
	     
	     )
	    )
	  ;; Skip back to begining of case item
	  (skip-chars-backward "\t ")
	  (verilog-skip-backward-comment-or-string)
	  (setq e (point))
	  (setq b (progn
		    (if (verilog-re-search-backward "\\<\\(case[zx]?\\)\\>\\|;\\|\\<end\\>" nil 'move)
			(progn
			  (cond 
			   ((match-end 1)
			    (goto-char (match-end 1))
			    (verilog-forward-ws&directives)
			    (if (looking-at "(")
				(progn
				  (forward-sexp)
				  (verilog-forward-ws&directives)
				  ))
			    (point))
			   (t
			    (goto-char (match-end 0))
			    (verilog-forward-ws&directives)
			    (point))
			   ))
		      (error "Malformed case item")
		      )
		    )
		)
	  (setq str (buffer-substring b e))
	  (if (setq e (string-match "[ \t]*\\(\\(\n\\)\\|\\(//\\)\\|\\(/\\*\\)\\)" str))
	      (setq str (concat (substring str 0 e) "...")))
	  str)
      'nil)
    )
  )


;;;
;;; Other functions
;;;

(defun kill-existing-comment ()
  "kill autocomment on this line"
  (save-excursion 
    (let* (
	   (e (progn
		(end-of-line)
		(point)))
	   (b (progn 
		(beginning-of-line)
		(search-forward "//" e t))))
      (if b
	  (delete-region (- b 2) e))
      )
    )
  )

(defun verilog-set-auto-endcomments (indent-str kill-existing-comment)
  "Insert `// case: 7 ' or `// NAME ' on this line if appropriate.
Insert `// case expr ' if this line ends a case block.  
Insert `// ifdef FOO ' if this line ends code conditional on FOO.
Insert `// NAME ' if this line ends a module or primitive named NAME."
  (save-excursion
    (cond 
     (; Comment close preprocessor directives
      (and 
       (looking-at "\\(`endif\\)\\|\\(`else\\)")
       (or  kill-existing-comment	
	    (not (save-excursion
		   (end-of-line)
		   (search-backward "//" (verilog-get-beg-of-line) t)))))
      (let ( (reg "\\(`else\\)\\|\\(`ifdef\\)\\|\\(`endif\\)")
	     (nest 1)
	     b e 
	     (else (if (match-end 2)
		       1
		     0))
	     )
	(end-of-line)
	(if kill-existing-comment
	    (kill-existing-comment))
	(delete-horizontal-space)
	(save-excursion
	  (backward-sexp 1)
	  (while (and (/= nest 0)
		      (verilog-re-search-backward reg nil 'move))
	    (cond 
	     ((match-end 1) ; `else
	      (if (= nest 1)
		  (setq else 1)))
	     ((match-end 2) ; `ifdef
	      (setq nest (1- nest)))
	     ((match-end 3) ; `endif
	      (setq nest (1+ nest)))
	     ))
	  (if (match-end 0)
	      (setq b (progn 
			(skip-chars-forward "^ \t")
			(verilog-forward-syntactic-ws)
			(point))
		    e (progn
			(skip-chars-forward "a-zA-Z0-9_")
			(point)
			))))
	(if b
	    (if (> (- (point) b) verilog-minimum-comment-distance)
		(insert (concat (if 
				    (= else 0)
				    " // ifdef " 
				  " // !ifdef ")
				(buffer-substring b e))))
	  (progn
	    (insert " // unmatched `endif")
	    (ding 't))
	  )))
     
     (; Comment close case/function/task/module and named block
      (and (looking-at "\\<end")
	   (or kill-existing-comment
	       (not (save-excursion
		      (end-of-line)
		      (search-backward "//" (verilog-get-beg-of-line) t)))))
      (let ((type (car indent-str)))
	(if (eq type 'declaration)
	    ()
	  (if 
	      (looking-at "\\(\\<endcase\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<end\\(\\(function\\)\\|\\(task\\)\\|\\(module\\)\\|\\(primitive\\)\\)\\>\\)")
	      (cond
	       (;- This is a case block; search back for the start of this case
		(match-end 1)
		
		(let ((err 't)
		      (str "UNMATCHED!!"))
		  (save-excursion
		    (verilog-leap-to-head)
		    (if (match-end 0)
			(progn
			  (goto-char (match-end 1))
			  (setq str (concat (buffer-substring (match-beginning 1) (match-end 1))
					    (verilog-get-expr)))
			  (setq err nil))))
		  (end-of-line)
		  (if kill-existing-comment
		      (kill-existing-comment))
		  (delete-horizontal-space)
		  (insert (concat " // " str ))
		  (if err (ding 't))
		  ))
	       
	       (;- This is a begin..end block
		(match-end 2)
		(let ((str " // UNMATCHED !!")
		      (err 't)
		      (here (point))
		      there
		      cntx
		      )
		  (save-excursion
		    (verilog-leap-to-head)
		    (setq there (point))
		    (if (not (match-end 0))
			(progn
			  (goto-char here)
			  (end-of-line)
			  (if kill-existing-comment
			      (kill-existing-comment))
			  (delete-horizontal-space)
			  (insert str)
			  (ding 't)			  
			  )
		      (let ( sp 
			    (lim (save-excursion (verilog-beg-of-defun) (point)))
			    (here (point))
			    )
			(cond
			 (;-- handle named block differently
			  (looking-at verilog-named-block-re)
			  (search-forward ":")
			  (setq there (point))
			  (setq str (verilog-get-expr))
			  (setq err nil)
			  (setq str (concat " // block: " str )))
			 
			 ((verilog-in-case-region-p) ;-- handle case item differently
			  (goto-char here)
			  (setq str (verilog-backward-case-item lim))
			  (setq there (point))
			  (setq err nil)
			  (setq str (concat " // case: " str ))
			  )
			 (;- try to find "reason" for this begin
			  (cond 
			   (;
			    (eq here (progn (verilog-beg-of-statement) (point)))
			    (setq err nil)
			    (setq str ""))
			   ((looking-at verilog-endcomment-reason-re)
			    (setq there (match-end 0))
			    (setq cntx (concat 
					(buffer-substring (match-beginning 0) (match-end 0)) " "))
			    (cond
			     (;
			      (match-end 2)
			      (setq err nil)
			      (save-excursion
				(goto-char sp)
				(if (and (verilog-continued-line)
					 (looking-at "\\<repeat\\>\\|\\<wait\\>\\|\\<always\\>"))
				    (progn
				      (goto-char (match-end 0))
				      (setq there (point))
				      (setq str 
					    (concat " // "
						    (buffer-substring (match-beginning 0) (match-end 0)) " "
						    (verilog-get-expr))))
				  (setq str "")		  
				  )
				)
			      )
			     (;- else 
			      (match-end 4)
			      (let ((nest 0)
				    ( reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|\\(\\<if\\>\\)")
				    )
				(catch 'skip
				  (while (verilog-re-search-backward reg nil 'move)
				    (cond 
				     ((match-end 1) ; begin
				      (setq nest (1- nest)))
				     ((match-end 2)                       ; end
				      (setq nest (1+ nest)))
				     ((match-end 3)
				      (if (= 0 nest)
					  (progn
					    (goto-char (match-end 0))
					    (setq there (point))
					    (setq err nil)
					    (setq str (verilog-get-expr))
					    (setq str (concat " // else: !if" str ))
					    (throw 'skip 1))
					)))
				    )
				  )
				)
			      )
			     (;- task/function/initial et cetera
			      t
			      (match-end 0)
			      (goto-char (match-end 0))
			      (setq there (point))
			      (setq err nil)
			      (setq str (verilog-get-expr))
			      (setq str (concat " // " cntx str )))
			     
			     (;-- otherwise...
			      (setq str " // auto-endcomment confused ")
			      )
			     )
			    )
			   ((and
			     (verilog-in-case-region-p) ;-- handle case item differently
			     (progn
			       (setq there (point))			       
			       (goto-char here)
			       (setq str (verilog-backward-case-item lim))))
			    (setq err nil)
			    (setq str (concat " // case: " str ))
			    )
			   )
			  )
			 )
			)
		      (goto-char here)
		      (end-of-line)
		      (if kill-existing-comment
			  (kill-existing-comment))
		      (delete-horizontal-space)
		      (if (or err
			      (> (- here there) verilog-minimum-comment-distance))
			  (insert str))
		      (if err (ding 't))
		      )
		    )
		  )
		)


	       (;- this is end{function,task,module}
		t 
		(let (string reg (width nil))
		  (end-of-line)
		  (if kill-existing-comment
		      (kill-existing-comment))
		  (delete-horizontal-space)
		  (backward-sexp)
		  (cond 
		   ((match-end 5) 
		    (setq reg "\\(\\<function\\>\\)\\|\\(\\<\\(endfunction\\|task\\|\\(macro\\)?module\\|primitive\\)\\>\\)")
		    (setq width "\\([ \t]*\\[[^]]*\\]\\)?")
		    )
		   ((match-end 6) 
		    (setq reg "\\(\\<task\\>\\)\\|\\(\\<\\(endtask\\|function\\|\\(macro\\)?module\\|primitive\\)\\>\\)"))
		   ((match-end 7) 
		    (setq reg "\\(\\<\\(macro\\)?module\\>\\)\\|\\<endmodule\\>"))
		   ((match-end 8) 
		    (setq reg "\\(\\<primitive\\>\\)\\|\\(\\<\\(endprimitive\\|function\\|task\\|\\(macro\\)?module\\)\\>\\)"))
		   )
		  (let (b e)
		    (save-excursion
		      (verilog-re-search-backward reg nil 'move)
		      (cond 
		       ((match-end 1)
			(setq b (progn 
				  (skip-chars-forward "^ \t")
				  (verilog-forward-ws&directives)
				  (if (and width (looking-at width))
				      (progn
					(goto-char (match-end 0))
					(verilog-forward-ws&directives)
					))
				  (point))
			      e (progn 
				  (skip-chars-forward "a-zA-Z0-9_")
				  (point)))
			(setq string (buffer-substring b e)))
		       (t
			(ding 't)
			(setq string "unmactched end(function|task|module|primitive)")))))
		  (end-of-line)
		  (insert (concat " // " string )))
		)
	       )
	    )
	  )
	)
      )
     )
    )
  )

(defun verilog-get-expr()
  "Grab expression at point, e.g, case ( a | b & (c ^d))"
  (let* ((b (progn 
	      (verilog-forward-syntactic-ws)
	      (skip-chars-forward " \t")
	      (point)))
	 (e (let ((par 1)) 
	      (cond
	       ((looking-at "(")
		(forward-char 1)
		(while (and (/= par 0) 
			    (verilog-re-search-forward "\\((\\)\\|\\()\\)" nil 'move))
		  (cond
		   ((match-end 1)
		    (setq par (1+ par)))
		   ((match-end 2)
		    (setq par (1- par)))))
		(point))
	       ((looking-at "\\[")
		(forward-char 1)
		(while (and (/= par 0) 
			    (verilog-re-search-forward "\\(\\[\\)\\|\\(\\]\\)" nil 'move))
		  (cond
		   ((match-end 1)
		    (setq par (1+ par)))
		   ((match-end 2)
		    (setq par (1- par)))))
		(verilog-forward-syntactic-ws)
		(skip-chars-forward "^ \t\n")		
		(point))
	       ((looking-at "/[/\\*]")
		b)
	       ('t
		(skip-chars-forward "^: \t\n")
		(point)
		))))
	 (str (buffer-substring b e)))
    (if (setq e (string-match "[ \t]*\\(\\(\n\\)\\|\\(//\\)\\|\\(/\\*\\)\\)" str))
	(setq str (concat (substring str 0 e) "...")))
    str)
  )


;;;
;;; Indentation
;;;
(defconst verilog-indent-alist
  '((block       . (+ ind verilog-indent-level))
    (case        . (+ ind verilog-case-indent))
    (cparenexp   . (+ ind verilog-indent-level))
    (cexp        . (+ ind verilog-indent-level))
    (defun       . verilog-indent-level)
    (declaration . verilog-indent-level)
    (tf          . verilog-indent-level)
    (behavorial  . verilog-indent-level)
    (statement   . ind)
    (cpp         . 0)
    (comment     . (verilog-indent-comment))
    (unknown     . 3) 
    (string      . 0)))

(defun verilog-calculate-indent ()
  "Calculate the indent of the current Verilog line, through examination
of previous lines.  Once a line is found that is definitive as to the
type of the current line, return that lines' indent level and it's
type. Return a list of two elements: (INDENT-TYPE INDENT-LEVEL)."
  (save-excursion
    (let* ((starting_position (point))
	   (par 0) 
	   (begin (looking-at "[ \t]*begin\\>"))
	   (type (catch 'nesting
		   ;; Keep working backwards until we can figure out
		   ;; what type of statement this is.
		   ;; Basically we need to figure out 
		   ;; 1) if this is a continuation of the previous line;
		   ;; 2) are we in a block scope (begin..end)
		   
		   ;; if we are in a comment, done.
		   (if (verilog-in-star-comment-p)   (throw 'nesting 'comment))

		   ;; if we are in a parenthesized list, done.
		   (if (verilog-in-paren) (progn (setq par 1) (throw 'nesting 'block)))

		   ;; See if we are continuing a previous line
		   (while t
		     ;; trap out if we crawl off the top of the buffer
		     (if (bobp) (throw 'nesting 'cpp))

		     (if (verilog-continued-line)
			 (let ((sp (point)))
			   (if (and
				(not (looking-at verilog-complete-reg))
				(verilog-continued-line))
			       (progn (goto-char sp)
				      (throw 'nesting 'cexp))
			     (goto-char sp))
			   (if (and begin
				    (not verilog-indent-begin-after-if)
				    (looking-at verilog-no-indent-begin-re))
			       (throw 'nesting 'statement)
			     (throw 'nesting 'cexp)))

		       ;; not a continued line
		       (goto-char starting_position))

		     (if (looking-at "\\<else\\>")
			 ;; search back for governing if, striding across begin..end pairs
			 ;; appropriately
			 (let ((reg (concat
				     verilog-end-block-re
				     "\\|\\(\\<else\\>\\)"
				     "\\|\\(\\<if\\>\\)"
				     ))
			       (elsec 1)
			       )
			   (while (verilog-re-search-backward reg nil 'move)
			     (cond 
			      ((match-end 1) ; endblock
					; try to leap back to matching outward block by striding across
					; indent level changing tokens then immediately
					; previous line governs indentation.
			       (let ((reg)(nest 1))
				 (looking-at verilog-end-block-re-1);; end|join|endcase|endtable|endspecify
				 (cond 
				  ((match-end 1) ; end
				   ;; Search back for matching begin
				   (setq reg "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)" )
				   )
				  ((match-end 2) ; endcase
				   ;; Search back for matching case
				   (setq reg "\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" )
				   )
				  ((match-end 3) ; join
				   ;; Search back for matching fork
				   (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\>\\)" )
				   )
				  ((match-end 4) ; endtable
				   ;; Search back for matching table
				   (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" )
				   )
				  ((match-end 5) ; endspecify
				   ;; Search back for matching specify
				   (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" )
				   )
				  ((match-end 6) ; endfunction
				   ;; Search back for matching function
				   (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" )
				   )
				  ((match-end 7) ; endspecify
				   ;; Search back for matching task
				   (setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" )
				   )
				  )
				 (catch 'skip
				   (while (verilog-re-search-backward reg nil 'move)
				     (cond 
				      ((match-end 1) ; begin
				       (setq nest (1- nest))
				       (if (= 0 nest)
					   (throw 'skip 1)))
				      ((match-end 2) ; end
				       (setq nest (1+ nest)))))
				   )
				 )
			       )
			      ((match-end 2) ; else, we're in deep
			       (setq elsec (1+ elsec))				 
			       )
			      ((match-end 3) ; found it
			       (setq elsec (1- elsec))
			       (if (= 0 elsec)
				   ;; Now previous line describes syntax
				   (throw 'nesting 'statement)
				   )))
			     )
			   )
		       )
		     (while (verilog-re-search-backward verilog-indent-reg nil 'move)
		       (cond 
			((match-end 1)   ; beg-block
			 (looking-at verilog-beg-block-re-1)
			 (cond
			  ((match-end 2)  (throw 'nesting 'case))
			  (t              (throw 'nesting 'block))))

			((match-end 2) ;; end-block
			 (verilog-leap-to-head)
			 (if (verilog-in-case-region-p)
			     (progn
			       (verilog-leap-to-case-head)
			       (if (looking-at verilog-case-re)
				   (throw 'nesting 'case))
			       )))
			
			((or (match-end 3) ;; module.. primitive
			     (match-end 5)) ;; endtask..
			 (throw 'nesting 'defun)) 

			((match-end 4) ;; endmodule
			 (throw 'nesting 'cpp))

			((match-end 6) ;; function/task
			 (throw 'nesting 'behavorial))

			((bobp) 
			 (throw 'nesting 'cpp))
			)
		       )
		     )
		   )
		 )
	   )
      ;; Return type of block and indent level.
      (if (not type)
	  (setq type 'cpp))
      (if (> par 0)			; Unclosed Parenthesis 
	  (list 'cparenexp par)
	(if (eq type 'case)
	    (list type (verilog-case-indent-level))
	  (list type (verilog-indent-level)))))))
(defun verilog-leap-to-case-head () ""
  (let ((nest 1))
    (while (/= 0 nest)
      (verilog-re-search-backward "\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" nil 'move)
      (cond 
       ((match-end 1)
	(setq nest (1- nest)))
       ((match-end 2)
	(setq nest (1+ nest)))
       ((bobp)
	(ding 't)
	(setq nest 0))
       )
      )
    )
  )

(defun verilog-leap-to-head () "foo"
  (let (reg 
	snest
	(nest 1))
    (if (looking-at verilog-end-block-re-1);; end|join|endcase|endtable|endspecify
	(progn
	  (cond 
	   ((match-end 1) ; end
	    ;; Search back for matching begin
	    (setq reg (concat "\\(\\<begin\\>\\)\\|\\(\\<end\\>\\)\\|" 
			      "\\(\\<endcase\\>\\)\\|\\(\\<join\\>\\)" )))
	   
	   ((match-end 2) ; endcase
	    ;; Search back for matching case
	    (setq reg "\\(\\<case[xz]?\\>[^:]\\)\\|\\(\\<endcase\\>\\)" )
	    )
	   ((match-end 3) ; join
	    ;; Search back for matching fork
	    (setq reg "\\(\\<fork\\>\\)\\|\\(\\<join\\>\\)" )
	    )
	   ((match-end 4) ; endtable
	    ;; Search back for matching table
	    (setq reg "\\(\\<table\\>\\)\\|\\(\\<endtable\\>\\)" )
	    )
	   ((match-end 5) ; endspecify
	    ;; Search back for matching specify
	    (setq reg "\\(\\<specify\\>\\)\\|\\(\\<endspecify\\>\\)" )
	    )
	   ((match-end 6) ; endfunction
	    ;; Search back for matching function
	    (setq reg "\\(\\<function\\>\\)\\|\\(\\<endfunction\\>\\)" )
	    )
	   ((match-end 7) ; endspecify
	    ;; Search back for matching task
	    (setq reg "\\(\\<task\\>\\)\\|\\(\\<endtask\\>\\)" )
	    )
	   )
	  (catch 'skip
	    (let (sreg)
	      (while (verilog-re-search-backward reg nil 'move)

