[代码实例][C++]分析C程序源文件(不完善)

    科技2026-06-06  8

    #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; }
    Processed: 0.010, SQL: 9