Chinaunix首页 | 论坛 | 博客
  • 博客访问: 960150
  • 博文数量: 134
  • 博客积分: 7443
  • 博客等级: 少将
  • 技术积分: 1411
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-10 20:18
文章分类

全部博文(134)

文章存档

2012年(7)

2011年(29)

2010年(16)

2009年(6)

2008年(18)

2007年(58)

分类: C/C++

2008-01-27 19:36:13

引言


c/c++支持独立编译,其源代码有多个头文件(.h)和执行文件(.c或.cpp)组成。在查看这样的源代码时,搞清楚所有这些文件之间的依赖或使用关系,就能系统地,全面地了解整个系统的层次结构。根据大多编码的习惯,有下面的事实:
1.每一个头文件往往对应一个同名执行文件(文件扩展名不同)。比如,在c++中,往往在"filename.h"中声明一个或多个类;在"filename.cpp"定义这个类的所有函数。这样的组合一般习惯上构成一个“模块”。
2.模块的实现文件包含(#include语句)模块的使用文件.
3.一个模块如果要调用其他模块,需要直接或间接包含被调用模块的头文件.

基于上面的情况,可以考虑:利用源代码中的#include语句,可以找出所有模块的直接依赖关系。利用这些依赖关系,结合Graphviz就可以生成一个简略的模块结构图。本文章以hp snmp ++的源代码为例,进行一次尝试.

试验环境

OS: debian linux , 2.6.21-2

SHELL : bash

使用到的工具:grep, awk, graphviz, sort

试验步骤


1. 下载源代码并解压缩
wget
tar -xzvf snmp++v3.2.23.tar.gz
2. 在src子目录下,搜索所有的cpp文件,得到'#include "'语句,保存到临时文件
cd snmp++/src
grep "^\#include \+\"" *.cpp >/tmp/xx.dep
注意:不要以'<'号括起来的系统的库文件
3. 在include子目录下,搜索所有的h文件,得到'#include "'语句,保存到临时文件
cd ../include/snmp_pp
grep "^\#include \+\"" *.h >>/tmp/xx.dep
4. 查d 看临时文件中的内容
cd /tmp
emacs -nw xx.dep


5. 精简临时文件中的内容
#去掉':#include',去掉引号
sed s/\:\#include// xx.dep | sed s/\"//g >xx2.dep
#去掉文件的路径和扩展名
sed s/snmp_pp\\/// xx2.dep | sed s/\\.h//g | sed s/\\.cpp//g >xx3.dep

现在生成的文件,每一行第一列为调用者,第二列为使用者
image file xx_2.gif



6. 生成Graphivz的源代码
echo "digraph snmp_pp_struct {" > xx.dot
awk '{ print $1 " -> " $2 ";" }' xx3.dep | sort -u >>xx.dot
echo "}" >>xx.dot
注意 sort -u 可以去掉重复的依赖关系

7. 使用Graphivz生成图形
编辑xx.dot, 补充一下绘制属性
graph [fontsize = 6,
label = "by cuichaox@gmail.com"]

node [ shape = box,
style = filled,
color = lightblue ];
生成图形
dot -Tgif xx.dot -o test.gif
见文档最后的图形.

试验结论

试验情况不是太理想,生成的线太多,图形太复杂

 (1)文件见的包含关系,有许多互相包含的情况.

 (2)间接包含加上直接包含,有重复包含的情况.


下一步要做的

(1)如果要让图形更好,需要手工编辑xx.dot文件,太麻烦。

(2)编写一个脚本或程序,使用更智能的源文件分析(不只使用include语句,而是分析到函数或类的定义和实现)。自动完成源代码的分析,和graphivz源代码策生成。有希望取得成功。


附件:最终生成的图


阅读(3220) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~