zoukankan      html  css  js  c++  java
  • Updated version: Use emacs & Graphviz to plot data structure

    简介: 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-more  blank))
          "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))
          (insert  header-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."))


  • 相关阅读:
    Hibernate中session的产生的方式
    Hibernate 多对多关联Demo
    Hibernate 一对多双向关联Demo
    Beta(0/7)
    获得小黄衫感想(2)
    软工实践作业(十)
    成员交换情况
    Alpha事后诸葛亮
    Alpha冲刺总结
    Alpha(10/10)
  • 原文地址:https://www.cnblogs.com/yangyingchao/p/2178381.html
Copyright © 2011-2022 走看看