任何人都知道一个脚本来获取一个能够告诉我C项目最常被调用的函数的列表吗?
方法1 391
方法2 23
method3 12
更好的是,可以自定义方法名称“get”中的关键字。
我正在尝试不重新发明轮子并编写一个简单的脚本来自己完成。使用grep或awk可能是一种简单的方法。我可以编写一个正则表达式来匹配函数调用名称。 Eclipse插件是理想的。
我不是在寻找一个探查器。我想要这样一个方法的原因是我需要为嵌入式项目优化程序空间。我倾向于使用getter封装我的成员变量,但可能需要使用externs并直接访问最常用的成员以减少空间。
答案 0 :(得分:1)
一种方法是在源代码库上运行Doxygen。您需要将其配置为提取所有函数和类,除非您已经在使用Doxygen,因为默认情况下它会忽略未记录的实体。
如果你还安装了AT& T GraphViz,你可以获得为每个功能绘制的漂亮的呼叫和来电图。但我不认为有一个表格可以通过呼叫数量来概括。
但是,可以选择几种非文档输出格式,包括Perl模块和XML。应该可以解析其中一个来开发你想要的列表,解析这些信息几乎肯定比通过破解足够的C ++前端来蛮力得到正确的答案更容易。
还有一个GCC的XML后端漂浮在某处,基本上以XML格式转储语法树...我最近绊倒了它,但不记得具体在哪里。
答案 1 :(得分:1)
这是一个简单的java脚本,它提供了我正在寻找的输出。 通过自定义文件顶部的两个REGEX,它可以用于生成其他模式出现的统计数据。
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.");
}
}
答案 2 :(得分:0)
如果“最频繁”是指程序的某些运行中的实际调用次数,DTrace可能是您正在寻找的工具,假设您有用于开发工作的Solaris,FreeBSD或OSX框。另请参阅Code Spelunking redux以获取有关Doxygen和DTrace的详细说明。