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