使用 python脚本获取函数调用关系

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013992766/article/details/50135127

        函数关系调用图可使用TestBed或者Source Insight软件生成。本文工具所提取的函数调用关系,是为了方便编写详细设计文档,自动将该函数所有调用的函数列举出来。

首先上传代码流程图:


代码的第一部分是变量定义,

  1. 定义了keyWordList列表,列表中的关键字可以根据实际的项目进行调整
  2. 定义了两个正则表达式,第一个正则表达式用来提取包含括号的语句中,括号前的字段,这个字段有可能是函数名,或者是判断条件,或者是强制转换
  3. 第二个正则表达式用于判断语句中是否包含控制语句和判断条件


__author__ = 'Z'
#coding:utf-8
import os
import re
 
keyWordList = [ 'break','continue', 'else', 'for','include', 'if', 'return', 'while','sizeof','int',
                'float','bool','char','switch']
specialCase = ["("]
commentCase =["/*","//"]
 
p =re.compile('(?P<name>\w+)\s*\(')
pControl =re.compile('\s*(for|if|else|switch|case|default|while|do)\s*\(')
 
methodExtractResult = []


第二部分主函数,执行流程如下:

扫描二维码关注公众号,回复: 4115767 查看本文章
  1. 判断输入的源代码文件是否存在,路径合法则逐行读取;
  2. 判断该行是否以“/”开头,是注释行则跳过该行;
  3. 如果该行包含关键字“(”,且排除控制语句,且不以分号结果,则表明该行为函数定义行,提取函数名;
  4. 如果该行包含关键字“(”,提取所用“(”前的字段,与预先定义的关键字列表取差集,剩余字段则为被调用函数;
  5. 去除存储在列表中重复的被调用函数,并写入日志中。

def main():
    funName = "Out Of the Function"
    #输入文件判断
    filePath = input("请输入源文件路径: \n")
    while False == os.path.isfile(filePath):
        print("文件不存在,请检查")
        filePath = input("请输入源文件路径: \n")

    fd = open(filePath)
    for line in fd:
        line = line.strip().strip('\n')
        if listInString(line[0:2],commentCase):
            #首先排除注释行
            pass
        elif listInString(line,specialCase) and (controlCaseInString(line) == False):
            #不含控制语句的关键字和和分号,且包含关键字“(”,判断为函数定义行,提取函数名
            mMethod = re.search(p,line)
            if mMethod:
                methodName = mMethod.groups("name")
                funName = methodName[0]
        else:
            #line中包含了关键字或者分号
            mLineList = re.findall(p,line)
            #list取差集,排除关键字
            methodList = list(set(mLineList).difference(set(keyWordList)))
            if methodList:
                for methodInList in methodList:
                    methodExtractResult.append(funName + ":"+ methodInList)
                    #print (funName + ":"+ methodInList)
    logfile = open(os.getcwd() + r'\\' + 'methodExtract.txt','w')
    try:
        #去除重复行
        methodExtractResultWithNoRepeat = []
        for elem in methodExtractResult:
            if elem not in methodExtractResultWithNoRepeat:
                methodExtractResultWithNoRepeat.append(elem)
                print (elem)
                logfile.write(elem + "\n")
    finally:
        logfile.close()
    fd.close()

第三部分为两个辅助功能函数:

  1. listInString函数实现了判断列表中的元素是否存在于string中;
  2. controlCaseInString函数实现利用正则判断sting中是否包含的关键字段。
def listInString(strLine, listJar):
    result = False
    if isinstance(listJar, list):
        for item in listJar:
            if item in strLine:
                result = True
                break
    else:
        result = False
    return  result

def controlCaseInString(strLine):
    if re.search(pControl,strLine) or ";" in strLine:
        return True
    else:return False

使用限制:

  1. 由于代码实现的是逐行读取处理,对于一条语句代码被分行书写的情况,可能会出现意外的错误;
  2. 由于注册函数的使用与变量使用类似,所以注册函数会被忽略。

猜你喜欢

转载自blog.csdn.net/u013992766/article/details/50135127