您的位置:首页 > 其它

Updated version: Use emacs & Graphviz to plot data structure

2011-08-19 13:12 531 查看
简介:Updated version to translate a C struct into corresponding dot file.
转载请注明出处

Refer to

http://emacser.com/emacs_graphviz_ds.htm or

http://blog.163.com/vic_kk/blog/static/494705242011526292895/

for orignal infomation.

;; Function used to add fields of struct into a dot file (for Graphviz).
;;;;; Dot templates
(defconst yyc/dot-head "subgraph cluster_%s {
node [shape=record fontsize=12 fontname=Courier style=filled]
;
color = lightgray
;
style=filled
;
label = \"Struct %s\"
;
edge[color=\
"brown\"];"
"Header part of dot file."
)
(defconst yyc/dot-tail "
}"
"Tail part of dot"
)
(defconst yyc/dot-node-head
"
node_%s[shape=record
label=\
"<f0>*** STRUCT %s ***|\\"
"Format of node."
)
(defconst yyc/dot-node-tail "
\
"];"
"Format of node."
)
(defconst attr_str "
<
f%d
>
+%s : %s\\l|\\
" "
nil
")
(defconst attr_func "
<
f%d
>
-%s() : %s\\l|\\
" "
nil
")
;;;;; Regular expressions to match a field of a struct.
(defconst r_attr_str
"[ \t]+\\(.*+\\)[ \t]+\\(.*?\\);\\([ \t]*/[/\\*].]*\\)?$"
"Regular expression for matching struct fields."
)
(defconst r_name
"\\_<\\(typedef[ \t]+\\)?struct[ \t]+\\(.*\\)?[ \t]*"
"Regular expression for mating struct name"
)
(defconst r_func_l
"\(.*"
"Regular expression to match a function"
)
(defconst r_func_r
".*\)"
"Regular expression to match a function"
)
(defconst r_comments
"^[ \t/\\*][/\\*]+"
"Regular expression to match a commentted field."
)
(defconst r_struct_func
"^[ \
t
]*\\(.+?\\)[ \
t
]*\(\\*\\(.*?\\)\)[ \
t
]*(\\(?:.\\|
\\)*?)
;"
"Regular expression to match a function decleration in a struct."
)
(defconst r_match_semicol
(rx (+? anything)
";"
))
(defconst r_match_attr
(rx (+? (
not
(any
"("
")"
"{"
"}"
)))
";"
))
(defconst r_match_func
(rx (+? (or alnum
"_"
blank))
"(*"
(+? (or alnum
"_"
))
")"
(zero-or-more blank)
"("
(*? anything)
");"
))
(defconst r_match_tag
(rx (zero-or-more blank)(zero-or-one 
"typedef"
(one-or-moreblank))
"struct"
(zero-or-more (or alnum
"_"
blank))
(zero-or-one "
") (zero-or-more blank)"
{"))
(
defun
get_struct_tag (decleration)
"Abstract decleration from a string"
(
if
(string-match r_name decleration 0)
(car (split-string (match-string 2 decleration) "{"))
nil
))
(
defun
skip(msg x)
(
if
x
(message(
format
"Skip invalid syntax for function: %s."
msg))
(message(
format
"Skip invalid syntax for struct field: %s."
msg))
)
)
(
defun
yyc/datastruct-to-dot (start end)
"Translate a C struct into dot file which can be turned into images using graphviz."
(interactive
"rp"
)
(
let
* ((tmp_str
""
)
 
(var-name
""
)
 
(var-type
""
)
 
(counter 0)
 
(next-begin 0)
 
(pos-cur 0)
 
(struct-name
""
)
 
(header-str
""
)
 
(pos-end 0)
 
(var-defination (buffer-substring-no-properties start end))
 
(item_str
""
)
 
)
(
defun
iter (pos)
(
if
(string-match r_match_tag var-defination pos)
;; Declerad a struct
(
progn
(setq pos-end (match-end 0))
(setq item_str (substring var-defination pos pos-end))
(setq struct-name (get_struct_tag item_str))
(setq header-str
(
format
yyc/dot-head struct-name struct-name))
(setq tmp_str
(
format
yyc/dot-node-head struct-name struct-name))
(setq pos-cur (1+ pos-end))
(iter pos-cur))
(
progn
(
if
(string-match r_match_semicol var-defination pos)
(
progn
(setq pos-end (match-end 0))
(setq item_str (substring var-defination pos pos-end))
(
if
(string-match r_match_func item_str 0)
;; Function
(
progn
(
if
(string-match r_struct_func item_str 0)
(
progn
(setq var-type
(match-string 1 item_str))
(setq var-name
(match-string 2 item_str))
(setq next-begin (match-end 0))
(
if
(string-match r_comments var-type 0)
;Comments
nil
(
progn
(setq counter (+ counter 1))
(setq tmp_str
(concat tmp_str
(
format
attr_func
counter var-name var-type))))))
(skip item_str
t
)
)
)
(
progn
(
if
(
equal
(string-match r_match_attr item_str 0) 0)
(
progn
(
if
(string-match r_attr_str item_str 0)
(
progn
(setq var-type
(match-string 1 item_str))
(setq var-name
(match-string 2 item_str))
(
if
(string-match r_comments var-type 0)
nil
(
progn
(setq counter (+ counter 1))
(setq tmp_str
(concat tmp_str
(
format
attr_str
counter var-name
var-type))))))
(skip item_str
nil
)))
(skip item_str
nil
))))
(iter pos-end))))))
(save-excursion
(iter 0)
(set-buffer (get-buffer-create
"tmp.dot"
))
(graphviz-dot-mode)
(goto-char (point-max))
(insertheader-str tmp_str )
(goto-char (point-max))
(delete-char -1)
(insert
"<f999>\\"
yyc/dot-node-tail yyc/dot-tail)
)
(
if
(one-window-p)
(split-window-vertically))
(switch-to-buffer-other-window
"tmp.dot"
)
(goto-char (point-min))
)
(message
"Finished, please refer to *tmp.dot* buffer."
))

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: