C 用于创建列表的脚本:<;方法名称>&书信电报;调用的次数>;对于特定的项目目录

C 用于创建列表的脚本:<;方法名称>&书信电报;调用的次数>;对于特定的项目目录,c,statistics,scripting,C,Statistics,Scripting,有谁知道一个脚本,可以得到一个列表,可以告诉我C项目中最常调用的函数 方法1391 方法2 23 方法3 12 更好的是,它可以自定义,要求在方法名“get”中使用关键字 我试着不去重新发明轮子,而是自己写一个简单的脚本。使用grep或awk可能是一种简单的方法。我可以编写一个正则表达式来匹配函数调用名。Eclipse插件将是理想的选择 我不是在找剖析器。我想要这种方法的原因是我需要为嵌入式项目优化程序空间。我倾向于用getter封装我的成员变量,但可能需要使用extern并直接访问最常用的成员

有谁知道一个脚本,可以得到一个列表,可以告诉我C项目中最常调用的函数

方法1391
方法2 23
方法3 12

更好的是,它可以自定义,要求在方法名“get”中使用关键字

我试着不去重新发明轮子,而是自己写一个简单的脚本。使用grep或awk可能是一种简单的方法。我可以编写一个正则表达式来匹配函数调用名。Eclipse插件将是理想的选择


我不是在找剖析器。我想要这种方法的原因是我需要为嵌入式项目优化程序空间。我倾向于用getter封装我的成员变量,但可能需要使用extern并直接访问最常用的成员以减少空间。

一种方法是运行源代码库。您需要将其配置为提取所有函数和类,除非您已经在使用Doxygen,因为默认情况下它会忽略未记录的实体

如果您还安装了AT&T,则可以为每个函数绘制漂亮的调用和调用图。但我不认为有一个表格可以通过电话数量来总结这一点

但是,可以选择几种非文档输出格式,包括Perl模块和XML。你可以解析其中一个来开发你想要的列表,而且解析这个信息几乎比把C++的前端凑到一起用蛮力得到正确答案更容易。
还有一个用于GCC的XML后端,它漂浮在某个地方,基本上将语法树转储到XML中。。。最近我被它绊倒了,但我不记得它具体在哪里。

如果“最频繁”是指某个程序运行中的实际调用数,则可能是您正在寻找的工具,假设您有一个Solaris、FreeBSD或OSX框用于开发工作。另请参阅,以获得对Doxygen和DTrace的详细描述。

这里是一个简单的java脚本,它提供了我想要的输出。 通过自定义文件顶部的两个正则表达式,它还可以用于生成其他模式出现的统计信息

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

public class MethodCallCount {
    // This is the regex which is applied to each line to test if there is a method call on it.
    private static String REGEX_METHODCALL = "(?:\\s*)([a-zA-Z0-9_]+)\\((.*)"; 
    // Only looks in files with .c extention
    private static String REGEX_FILEEXTS = ".*.c";
    private static boolean VERBOSE_OUTPUT = false;
    private static Map<String,Integer> patternMap = new HashMap<String,Integer>();

    // Process all files and directories under dir
    public static void visitAllDirsAndFiles(File dir) {

        if( !dir.isDirectory()) {
            if( dir.getName().matches(REGEX_FILEEXTS) ) {
                if( VERBOSE_OUTPUT ) { System.out.println("Processing File: " + dir.getName() ); }
                processFile(dir);
            }
        }
        else if( !dir.getName().equals(".svn") ) {
            String[] children = dir.list();
            for (int i=0; i<children.length; i++) {
                visitAllDirsAndFiles(new File(dir, children[i]));
            }
        }
    }

    // Process only directories under dir
    public static void visitAllDirs(File dir) {
        if (dir.isDirectory()) {
            processFile(dir);

            String[] children = dir.list();
            for (int i=0; i<children.length; i++) {
                visitAllDirs(new File(dir, children[i]));
            }
        }
    }

    // Process only files under dir
    public static void visitAllFiles(File dir) {
        if (dir.isDirectory()) {
            String[] children = dir.list();
            for (int i=0; i<children.length; i++) {
                visitAllFiles(new File(dir, children[i]));
            }
        } else {
            processFile(dir);
        }
    }

    public static void processMethod( String pMethod ) {
        if( VERBOSE_OUTPUT ) { System.out.println("found: " + pMethod); }
        if( patternMap.containsKey( pMethod ) ) {
            Integer cnt = patternMap.get( pMethod );
            cnt = cnt + 1;
            patternMap.put(pMethod, cnt );
        }
        else {
            patternMap.put( pMethod.toString(), 1);
        }       
    }


    public static void processLine( String pLine ) {
        Pattern methodMatcher = Pattern.compile( REGEX_METHODCALL );
        java.util.regex.Matcher matcher = methodMatcher.matcher( pLine );

        if( matcher.matches() ) {
            if( VERBOSE_OUTPUT ) { System.out.println("processing " + matcher.group(1) ); }
            processMethod( matcher.group(1) );                  
            processLine( matcher.group(2) );
        }
    }

    public static void processFile( File pFile ) {
        BufferedReader fin;
        try {
            fin = new BufferedReader( new InputStreamReader( new FileInputStream(pFile) ) );
            String l = null;
            while( (l=fin.readLine()) != null ) {
                processLine( l );
            }
        } 
        catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       
    }

    /**
     * @param args[0] is the directory to run this on.  Otherwise current directory is used.
     */
    public static void main(String[] args) {

        String searchDirPath = System.getProperty("user.dir");
        if( args.length > 0 ) {
            searchDirPath = args[0];
        }
        else {
            System.out.println("No argument specified... searching for *.map in: " + searchDirPath );
        }

        File searchDir = new File( searchDirPath );
        visitAllDirsAndFiles(searchDir);

        // Print Stats.
        int callCnt = 0;
        Set<String> patternSet = patternMap.keySet();
        for( String p : patternSet ) {
            System.out.println( patternMap.get(p) + "\t" + p );
            callCnt += patternMap.get(p);
        }
        System.out.println("Unique Methods: " + patternMap.size());
        System.out.println("Calls Detected: " + callCnt );
        System.out.println("Copy and paste output above into excel and then sort columns");
        System.out.println("DONE.");
    }
}
导入java.io.BufferedReader;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.IOException;
导入java.io.InputStreamReader;
导入java.util.HashMap;
导入java.util.Map;
导入java.util.Set;
导入java.util.regex.Pattern;
公共类方法调用计数{
//这是应用于每一行的正则表达式,用于测试是否有方法调用。
私有静态字符串REGEX\u METHODCALL=“(?:\\s*)([a-zA-Z0-9\+)\(*”;
//仅在扩展名为.c的文件中查找
私有静态字符串REGEX_FILEEXTS=“.*.c”;
私有静态布尔详细输出=false;
私有静态映射patternMap=newhashmap();
//处理目录下的所有文件和目录
公共静态无效visitAllDirsAndFiles(文件目录){
如果(!dir.isDirectory()){
if(dir.getName().matches(REGEX_FILEEXTS)){
if(VERBOSE_输出){System.out.println(“处理文件:“+dir.getName());}
进程文件(dir);
}
}
如果(!dir.getName().equals(.svn)),则为else{
String[]children=dir.list();

对于(int i=0;i您使用的工具集是什么?许多工具集将生成调用图作为输出的一部分。我使用的是HiTech PICC-18 STD。您是对的,我可以得到调用图。我想这会稍微容易一些,因为现在我将所有信息都放在一个文件中……但我仍然会使用一个简单的脚本来创建摘要表。我感谢您的建议。我想获取Doxygen设置等将花费比编写一个小java应用程序花费15分钟更长的时间。别有用心的是,设置Doxygen通常对项目有长期的好处。。。