1 ;;; CFLOW.EL --- C flow graph
3 ;; Copyright (C) 1997 Paul Barham
5 ;; Author: Paul Barham Paul.Barham@cl.cam.ac.uk
6 ;; Maintainer: Paul Barham Paul.Barham@cl.cam.ac.uk
7 ;; Created: 19 Mar 1997
9 ;; Keywords: C language cxref flow static call graph browser
12 ;; This program is free software; you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation; either version 1, or (at your option)
17 ;; This program is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
22 ;; A copy of the GNU General Public License can be obtained from this
23 ;; program's author (send electronic mail to Paul.Barham@cl.cam.ac.uk)
24 ;; or from the Free Software Foundation, Inc., 675 Mass Ave,
25 ;; Cambridge, MA 02139, USA.
28 ;; cflow|Paul Barham|Paul.Barham@cl.cam.ac.uk
30 ;; |$Date$|$Revision$|~/packages/cflow.el
34 ;; This package is intended to be used in conjunction with cxref
35 ;; packeage (http://www.gedanken.demon.co.uk/cxref/index.html)
37 ;; It parses the cxref.function file generated by cxref and fires up
38 ;; a sort of folding mode which allows the hierarchical flow graph
39 ;; to be recursively expanded.
41 ;; Simply find the file cxref.function in a buffer and type M-x cflow
45 ;; SPC or RETURN Expand the current line
46 ;; x Close up the flow graph under the current node
47 ;; . Find the function on the current line in another window
53 ;; Revision 1.2 2004/01/04 19:43:16 galaxy
54 ;; *** empty log message ***
59 (defvar cflow-filenames t
60 "Show filenames where each function is declared")
62 (defvar cflow-main
"main"
63 "The name of the function at the root of the flowgraph")
65 (defvar cflow-indent
"| "
66 "The indentation string added per-level of the flowgraph")
71 ;;; This reads in the output of cxref
73 (defun cxref-readline ()
75 (let (file fn scope refs
76 (eol (progn (end-of-line) (point))))
78 (re-search-forward "\\([^ \t]+\\)[ \t]*" eol t
)
79 (setq file
(buffer-substring-no-properties
80 (match-beginning 1) (match-end 1)))
81 (re-search-forward "\\([^ \t]+\\)[ \t]*" eol t
)
82 (setq fn
(buffer-substring-no-properties
83 (match-beginning 1) (match-end 1)))
84 (re-search-forward "\\([0-9]+\\)[ \t]*" eol t
)
85 (setq scope
(car (read-from-string
86 (buffer-substring-no-properties
87 (match-beginning 1) (match-end 1)))))
89 (while (re-search-forward "\\([^ \t]+\\)[ \t]*" eol t
)
90 (setq refs
(cons (buffer-substring-no-properties
91 (match-beginning 1) (match-end 1)) refs
)))
92 (list fn file scope
(nreverse refs
))
100 (while (< (point) (point-max))
101 (setq fns
(cons (cxref-readline) fns
))
107 (defun cflow-insert (indent fname
)
108 (string-match "[&%]*\\(.*\\)" fname
)
109 (let* ((basename (substring fname
(match-beginning 1)))
110 (fun (assoc basename cflow-fns
)))
112 (insert (concat indent
115 (concat " (" (nth 1 fun
) ")")
118 (insert (concat indent fname
"\n")))
121 (defun cflow-expand ()
122 "Expand this node in the flow graph"
124 (let (name indent fun
)
127 (re-search-forward "\\(^[| ]*\\)[&%]*\\([*a-zA-Z0-9_$]+\\)")
128 (setq indent
(concat (buffer-substring-no-properties
130 (match-end 1)) cflow-indent
))
131 (setq name
(buffer-substring-no-properties
134 (setq fun
(assoc name cflow-fns
))
137 (or (looking-at indent
)
138 (mapcar (lambda (fname)
139 (cflow-insert indent fname
))
144 (defun cflow-contract ()
145 "Close up this section of the flow graph"
147 (let (name indent fun
)
150 (re-search-forward "\\(^[| ]*\\)")
151 (setq indent
(concat (buffer-substring-no-properties
153 (match-end 1)) cflow-indent
))
156 (while (looking-at indent
)
162 "Find the function on the current line using TAGS"
164 (let (name indent fun
)
167 (re-search-forward "\\(^[| ]*\\)[&%]*\\([*a-zA-Z0-9_$]+\\)")
168 (setq indent
(concat (buffer-substring-no-properties
170 (match-end 1)) cflow-indent
))
171 (setq name
(buffer-substring-no-properties
174 (message "Finding %s" name
)
175 (find-tag-other-window name
)))
178 (define-derived-mode cflow-mode fundamental-mode
"CFlow"
180 ;; Linemenu simply highlights the current line
181 ; (linemenu-initialize)
184 (define-key cflow-mode-map
" " 'cflow-expand
)
185 (define-key cflow-mode-map
"" 'cflow-expand
)
186 (define-key cflow-mode-map
"x" 'cflow-contract
)
187 (define-key cflow-mode-map
"." 'cflow-tag
)
188 (define-key cflow-mode-map
"q" 'bury-buffer
)
192 (let ((buf (get-buffer-create "*cflow*")))
193 (setq cflow-fns
(cxref-parse))
194 (switch-to-buffer buf
)
197 ;; Don't understand this :-)
198 ; (make-local-variable 'cflow-fns)
199 (cflow-insert "" "$")
200 (cflow-insert "" cflow-main
))
203 ;;; CFLOW.EL ends here