#define TEMP 1 /*ABCDEFG*/
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <sstream>
using namespace std;
#if (TEMP==1)
// Macro definition
#define MACRO 0
#define MACROFUN 1
#define STRUCTURE 2
#define DATATYPE 3
#define VARIABLE 4
#define FUNCTION 5
#define STATICFUN 6
#define EXTERNFUN 7
#define TYPE_COUNT 8
// Macro function definition
#define MAX(x, y) (if((x) >= (y)) ? (x) : (y))
// Structure definition
typedef struct MyStruct
{
int field1;
int field2;
} MyType;
// Variable definition
int myInteger1 = 123;
extern int myInteger2;
void fun(void)
{
}
static void staticFun(void)
{
}
extern void externFun(void)
{
}
#endif // (TEMP==1)
map<int, string>* fileLineMap = nullptr;
// 判断字符串1是不是以字符串2开始
bool startWith(string str1, string str2)
{
return str1.compare(0, str2.length(), str2) == 0;
}
// 获取指定行序号(从0开始的)之前,并且紧临的注释
// 从后往前,逐行扫描“//”或被“/*”“*/”包含的行
string getComment(map<int, string>* codeLineMap, size_t index)
{
string comment;
size_t i = index - 1;
bool isCommentInner = false;
bool isCommentEnd = false;
size_t pos;
do
{
if ((*codeLineMap)[i].find_first_not_of(" \n") == string::npos)
{
break;
}
while (!isCommentInner && (pos = (*codeLineMap)[i].find("//")) != string::npos)
{
i--;
}
if ((*codeLineMap)[i].find_first_not_of(" \n") == string::npos)
{
break;
}
while ((*codeLineMap)[i].find("*/") != string::npos)
{
isCommentInner = true;
i--;
do
{
if ((*codeLineMap)[i].find("/*") != string::npos)
{
isCommentInner = false;
}
i--;
} while (isCommentInner);
}
} while ((!isCommentInner && (*codeLineMap)[i].find("//") != string::npos)
|| (*codeLineMap)[i].find("*/") != string::npos);
for (int j = i + 1; j < index; j++)
{
comment.append((*codeLineMap)[j]);
}
return comment;
}
// 获取宏定义
// 如果某一行以“#define ”开始,但并不包含“(”,则为宏定义
list<pair<string, string>>* getMacro(map<int, string>* codeLineMap)
{
list<pair<string, string>>* macroList = new list<pair<string, string>>();
for (map<int, string>::iterator itor = codeLineMap->begin(); itor != codeLineMap->end(); itor++)
{
if (startWith(itor->second, "#define ") && itor->second.find_first_of("(") == string::npos)
{
string name;
for (size_t i = 8; i < itor->second.length(); i++)
{
if (itor->second[i] == ' ' || itor->second[i] == '\n')
{
break;
}
else
{
name.push_back(itor->second[i]);
}
}
macroList->push_back(make_pair(name, getComment(fileLineMap, itor->first) + fileLineMap->at(itor->first)));
}
}
return macroList;
}
// 获取宏函数定义
// 如果某一行以“#define ”开始,但并包含“(”,则为宏函数定义
list<pair<string, string>>* getMacroFunc(map<int, string>* codeLineMap)
{
list<pair<string, string>>* macroFuncList = new list<pair<string, string>>();
for (map<int, string>::iterator itor = codeLineMap->begin(); itor != codeLineMap->end(); itor++)
{
if (startWith(itor->second, "#define ") && itor->second.find_first_of("(") != string::npos)
{
string name;
for (size_t i = 8; i < itor->second.length(); i++)
{
if (itor->second[i] == '(')
{
break;
}
else
{
name.push_back(itor->second[i]);
}
}
macroFuncList->push_back(make_pair(name, getComment(fileLineMap, itor->first) + fileLineMap->at(itor->first)));
}
}
return macroFuncList;
}
// 获取全局变量定义
// 对于某一行,需要排除宏(或宏函数)(以#define开始)、数据类型(以typedef struct开始)、函数(包含括号)
// 同时还要排除这一行在代码块中
// 排除这些情况,基本可认定这就是一个全局变量。
list<pair<string, string>>* getVariable(map<int, string>* codeLineMap)
{
list<pair<string, string>>* variableList = new list<pair<string, string>>();
int count = 0;
bool isStringInner = false;
for (map<int, string>::iterator itor = codeLineMap->begin(); itor != codeLineMap->end(); itor++)
{
if (itor->first == 325)
{
int kkk = 0;
kkk++;
}
string line = itor->second;
if (line.length() > 0)
{
line.erase(line.length() - 1, 1);
}
for (int i = 0; i < line.length(); i++)
{
if (line[i] == '\"' && !isStringInner)
{
isStringInner = true;
}
else if (line[i] == '\"' && isStringInner)
{
isStringInner = false;
}
if ((line[i] == '\'' && line[i + 1] == '{' && line[i + 2] == '\'')
|| (line[i] == '\'' && line[i + 1] == '}' && line[i + 2] == '\''))
{
i += 2;
}
else if (line[i] == '{' && !isStringInner)
{
count++;
}
else if (line[i] == '}' && !isStringInner)
{
count--;
}
}
if (!startWith(line, "#define ") && !startWith(line, "typedef struct")
&& line.find("using ") == string::npos
&& line.find_first_of(";") != string::npos && count == 0
&& line.find_first_of("(") == string::npos && line.find_first_of(")") == string::npos
&& line.find_first_of("{") == string::npos && line.find_first_of("}") == string::npos
&& line.find("extern ") == string::npos)
{
string name;
size_t pos;
pos = line.find_first_of("=");
if (pos != string::npos)
{
if (line[--pos] == ' ')
{
pos--;
}
}
else
{
pos = line.find_first_of(";");
pos--;
}
do
{
name.push_back(line[pos]);
} while (line[--pos] != ' ');
reverse(name.begin(), name.end());
variableList->push_back(make_pair(name, getComment(fileLineMap, itor->first) + fileLineMap->at(itor->first)));
}
}
return variableList;
}
// 获取全局变量定义
// 对于某一行,需要排除宏(或宏函数)(以#define开始)、数据类型(以typedef struct开始)
// 排除这些情况,同时满足包含括号,基本可认定这就是一个函数。
void getFunction(map<int, string>* codeLineMap, list<pair<string, string>>* functionList, list<pair<string, string>>* staticFunctionList, list<pair<string, string>>* externFunctionList)
{
int count = 0;
for (map<int, string>::iterator itor = codeLineMap->begin(); itor != codeLineMap->end();)
{
string line = itor->second;
if (!startWith(line, "#define ") && !startWith(line, "typedef struct")
&& line.find("using ") == string::npos && line.find("=") == string::npos && line.find(";") == string::npos
&& line.find_first_of("(") != string::npos
&& count == 0)
{
string name;
size_t pos;
pos = line.find_first_of("(");
if (line[--pos] == ' ')
{
pos--;
}
do
{
name.push_back(line[pos]);
} while (line[--pos] != ' ');
reverse(name.begin(), name.end());
bool hasBodyInner = false;
string code;
map<int, string>::iterator itor_temp;
for (itor_temp = itor; itor_temp != codeLineMap->end(); itor_temp++)
{
for (int i = 0; i < itor_temp->second.length(); i++)
{
if ((itor_temp->second[i] == '\'' && itor_temp->second[i + 1] == '{' && itor_temp->second[i + 2] == '\'')
|| (itor_temp->second[i] == '\'' && itor_temp->second[i + 1] == '}' && itor_temp->second[i + 2] == '\''))
{
i += 2;
}
else if (itor_temp->second[i] == '{')
{
count++;
hasBodyInner = true;
}
else if (itor_temp->second[i] == '}')
{
count--;
}
}
code.append(fileLineMap->at(itor_temp->first));
if (hasBodyInner && count == 0)
{
break;
}
}
if (line.find("extern ") == string::npos && line.find("static ") == string::npos)
{
functionList->push_back(make_pair(name, getComment(fileLineMap, itor->first) + code));
}
else if (line.find("static ") != string::npos)
{
staticFunctionList->push_back(make_pair(name, getComment(fileLineMap, itor->first) + code));
}
else if (line.find("extern ") != string::npos)
{
externFunctionList->push_back(make_pair(name, getComment(fileLineMap, itor->first) + code));
}
itor = itor_temp;
if (itor->second[itor->second.length() - 1] == '\n')
{
itor++;
}
}
itor++;
}
}
// 获取宏定义
// 如果某一行以“typedef struct”开始,则为数据类型
list<pair<string, string>>* getDatatype(map<int, string>* codeLineMap)
{
list<pair<string, string>>* datatypeList = new list<pair<string, string>>();
int count = 0;
for (map<int, string>::iterator itor = codeLineMap->begin(); itor != codeLineMap->end();)
{
string line = itor->second;
if (startWith(line, "typedef struct")
&& line.find("using ") == string::npos && line.find("=") == string::npos && line.find(";") == string::npos
&& count == 0)
{
string name;
bool hasBodyInner = false;
string code;
map<int, string>::iterator itor_temp;
for (itor_temp = itor; itor_temp != codeLineMap->end(); itor_temp++)
{
for (int i = 0; i < itor_temp->second.length(); i++)
{
if (itor_temp->second[i] == '{')
{
count++;
hasBodyInner = true;
}
else if (itor_temp->second[i] == '}')
{
count--;
}
}
code.append(fileLineMap->at(itor_temp->first));
if (hasBodyInner && count == 0)
{
size_t pos = itor_temp->second.find_last_of("}") + 1;
while (itor_temp->second[pos] == ' ')
{
pos++;
}
for (size_t i = pos; i < itor_temp->second.length(); i++)
{
if (itor_temp->second[i] == ';' || itor_temp->second[i] == ' ' || itor_temp->second[i] == '\n')
{
break;
}
name.push_back(itor_temp->second[i]);
}
break;
}
}
datatypeList->push_back(make_pair(name, getComment(fileLineMap, itor->first) + code));
itor = itor_temp;
if (itor->second[itor->second.length() - 1] == '\n')
{
itor++;
}
}
itor++;
}
return datatypeList;
}
// 去除空白
void eraseWhite(map<int, string>* codeLineMap)
{
for (map<int, string>::iterator itor = codeLineMap->begin(); itor != codeLineMap->end(); itor++)
{
size_t pos;
// 替换制表符为空格
while ((pos = itor->second.find_first_of("\t")) != string::npos)
{
itor->second.replace(pos, 1, " ");
}
// 合并两个连续的空格为一个空格
while ((pos = itor->second.find(" ")) != string::npos)
{
itor->second.replace(pos, 2, " ");
}
// 去除开始的空格
itor->second.erase(0, itor->second.find_first_not_of(" "));
// 去除结尾的空格
if (itor->second.length() >= 2 && itor->second[itor->second.length() - 2] == ' ')
{
itor->second.erase(itor->second.length() - 2, 1);
}
// 去除分号的空格
if (itor->second.find(" ;") != string::npos)
{
itor->second.erase(itor->second.find(" ;"), 1);
}
}
}
// 去除注释
void eraseComment(map<int, string>* codeLineMap)
{
bool isCommentInner = false;
bool isStringInner = false;
for (map<int, string>::iterator itor = codeLineMap->begin(); itor != codeLineMap->end(); itor++)
{
for (size_t i = 0; i < itor->second.length();)
{
if (itor->second[i] == '/' && i < itor->second.length() && itor->second[i + 1] == '*')
{
if (!isStringInner)
{
isCommentInner = true;
itor->second.erase(i, 2);
}
else
{
i += 2;
}
}
else if (itor->second[i] == '*' && i < itor->second.length() && itor->second[i + 1] == '/')
{
if (!isStringInner)
{
isCommentInner = false;
itor->second.erase(i, 2);
}
else
{
i += 2;
}
}
else if (isCommentInner)
{
itor->second.erase(i, 1);
}
else if (itor->second[i] == '\\' && i < itor->second.length() && itor->second[i + 1] == '\"')
{
i += 2;
}
else if (itor->second[i] == '\"')
{
isStringInner = !isStringInner;
i++;
}
else if (itor->second[i] == '/' && i < itor->second.length() && itor->second[i + 1] == '/')
{
if (!isStringInner)
{
itor->second.erase(i, itor->second.length() - 1);
}
else
{
i += 2;
}
}
else
{
i++;
}
}
}
}
map<int, string>* dealWithCodeLineList(map<int, string>* fileLineMap)
{
map<int, string>* codeLineMap = new map<int, string>();
for (map<int, string>::iterator itor = fileLineMap->begin(); itor != fileLineMap->end(); itor++)
{
codeLineMap->insert(make_pair(itor->first, itor->second));
}
eraseComment(codeLineMap);
eraseWhite(codeLineMap);
return codeLineMap;
}
map<int, string>* readFile(string srcFileName)
{
map<int, string>* fileLineMap = new map<int, string>();
ifstream ifstream(srcFileName);
ostringstream buf;
char ch;
int i = 0;
while (ifstream.get(ch))
{
// 首先得排除BOM(EF BB BF)三个字节的情况
if (ch == (char)0xEF || ch == (char)0xBB || ch == (char)0xBF)
continue;
if (ch != '\n')
{
buf.put(ch);
continue;
}
buf.put('\n');
fileLineMap->insert(make_pair(i++, buf.str()));
buf.str("");
}
if (buf.str().length() >= 0)
{
fileLineMap->insert(make_pair(i, buf.str()));
}
return fileLineMap;
}
int main()
{
try
{
#if (TEMP==1)
string srcFileName = "D:\\Project\\VisualStudio\\CPlusPlus\\SrcAnalysis\\SrcAnalysis\\SrcAnalysis.cpp";
//string srcFileName = "D:\\Project\\VisualStudio\\CPlusPlus\\SrcAnalysis\\SrcAnalysis\\test_code.c";
string outputFileName_1 = "D:\\Project\\VisualStudio\\CPlusPlus\\SrcAnalysis\\Debug\\output1.txt";
string outputFileName_2 = "D:\\Project\\VisualStudio\\CPlusPlus\\SrcAnalysis\\Debug\\output2.txt";
#else
string srcFileName;
cin >> srcFileName;
string outputFileName_1;
string outputFileName_2;
cin >> outputFileName_1;
cin >> outputFileName_2;
#endif // (TEMP==1)
fileLineMap = readFile(srcFileName);
ofstream ofstream1(outputFileName_1);
ofstream ofstream2(outputFileName_2);
map<int, string>* codeLineMap = dealWithCodeLineList(fileLineMap);
list<pair<string, string>>* macroList = getMacro(codeLineMap);
cout << "***** Macro *****" << endl;
ofstream1 << "***** Macro *****" << endl;
for (list<pair<string, string>>::iterator itor = macroList->begin(); itor != macroList->end(); itor++)
{
cout << "[" << itor->first << "] => " << endl << itor->second << endl;
ofstream1 << "[" << itor->first << "] => " << endl << itor->second << endl;
}
list<pair<string, string>>* macroFuncList = getMacroFunc(codeLineMap);
cout << "***** Macro Function *****" << endl;
ofstream1 << "***** Macro Function *****" << endl;
for (list<pair<string, string>>::iterator itor = macroFuncList->begin(); itor != macroFuncList->end(); itor++)
{
cout << "[" << itor->first << "] => " << endl << itor->second << endl;
ofstream1 << "[" << itor->first << "] => " << endl << itor->second << endl;
}
list<pair<string, string>>* variableList = getVariable(codeLineMap);
cout << "***** Variable *****" << endl;
ofstream1 << "***** Variable *****" << endl;
for (list<pair<string, string>>::iterator itor = variableList->begin(); itor != variableList->end(); itor++)
{
cout << "[" << itor->first << "] => " << endl << itor->second << endl;
ofstream1 << "[" << itor->first << "] => " << endl << itor->second << endl;
}
list<pair<string, string>>* datatypeList = getDatatype(codeLineMap);
cout << "***** Datatype *****" << endl;
ofstream1 << "***** Datatype *****" << endl;
for (list<pair<string, string>>::iterator itor = datatypeList->begin(); itor != datatypeList->end(); itor++)
{
cout << "[" << itor->first << "] => " << endl << itor->second << endl;
ofstream1 << "[" << itor->first << "] => " << endl << itor->second << endl;
}
list<pair<string, string>>* functionList = new list<pair<string, string>>();
list<pair<string, string>>* staticFunctionList = new list<pair<string, string>>();
list<pair<string, string>>* externFunctionList = new list<pair<string, string>>();
getFunction(codeLineMap, functionList, staticFunctionList, externFunctionList);
cout << "***** Static Function *****" << endl;
ofstream2 << "***** Static Function *****" << endl;
for (list<pair<string, string>>::reverse_iterator itor = staticFunctionList->rbegin(); itor != staticFunctionList->rend(); itor++)
{
cout << "[" << itor->first << "] => " << endl << itor->second << endl;
ofstream2 << "[" << itor->first << "] => " << endl << itor->second << endl;
}
cout << "***** Extern Function *****" << endl;
ofstream2 << "***** Extern Function *****" << endl;
for (list<pair<string, string>>::reverse_iterator itor = externFunctionList->rbegin(); itor != externFunctionList->rend(); itor++)
{
cout << "[" << itor->first << "] => " << endl << itor->second << endl;
ofstream2 << "[" << itor->first << "] => " << endl << itor->second << endl;
}
cout << "***** Function *****" << endl;
ofstream2 << "***** Function *****" << endl;
for (list<pair<string, string>>::reverse_iterator itor = functionList->rbegin(); itor != functionList->rend(); itor++)
{
cout << "[" << itor->first << "] => " << endl << itor->second << endl;
ofstream2 << "[" << itor->first << "] => " << endl << itor->second << endl;
}
}
catch (const std::exception& ex)
{
cerr << endl << "[ERROR] " << ex.what() << endl;
}
return EXIT_SUCCESS;
}
[代码实例][C++]分析C程序源文件(不完善)
最新推荐文章于 2023-02-10 15:03:43 发布