diff --git a/Net.xcodeproj/project.pbxproj b/Net.xcodeproj/project.pbxproj index bd5ffbf..500707d 100644 --- a/Net.xcodeproj/project.pbxproj +++ b/Net.xcodeproj/project.pbxproj @@ -8,13 +8,15 @@ /* Begin PBXBuildFile section */ 9277A16021FD725F009C5F11 /* md5.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9277A15421FD725F009C5F11 /* md5.cpp */; }; - 9277A16121FD725F009C5F11 /* cproj.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9277A15521FD725F009C5F11 /* cproj.cpp */; }; + 9277A16121FD725F009C5F11 /* cproj_cpt.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9277A15521FD725F009C5F11 /* cproj_cpt.cpp */; }; 9277A16221FD725F009C5F11 /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9277A15621FD725F009C5F11 /* main.cpp */; }; 9277A16521FD725F009C5F11 /* cmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9277A15921FD725F009C5F11 /* cmap.cpp */; }; 9277A16621FD725F009C5F11 /* cpart.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9277A15A21FD725F009C5F11 /* cpart.cpp */; }; 9277A16721FD725F009C5F11 /* memory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9277A15B21FD725F009C5F11 /* memory.cpp */; }; 9277A16821FD725F009C5F11 /* clock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9277A15C21FD725F009C5F11 /* clock.cpp */; }; 9277A18921FEB21D009C5F11 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 9277A18821FEB21D009C5F11 /* libsqlite3.dylib */; }; + 9277A18C220076EE009C5F11 /* sql.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9277A18A220076EE009C5F11 /* sql.cpp */; }; + 9277A190220079DB009C5F11 /* cproj_proj.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9277A18F220079DB009C5F11 /* cproj_proj.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -32,7 +34,6 @@ /* Begin PBXFileReference section */ 9221D9EB21EA5142007310A7 /* Net */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Net; sourceTree = BUILT_PRODUCTS_DIR; }; 9221DA1621EB8C02007310A7 /* pcs.map */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; name = pcs.map; path = build/Debug/PCS/pcs.map; sourceTree = ""; }; - 9277A14521FD7246009C5F11 /* cproj.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = cproj.hpp; path = include/cproj.hpp; sourceTree = ""; }; 9277A14621FD7246009C5F11 /* cmap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cmap.h; path = include/cmap.h; sourceTree = ""; }; 9277A14721FD7246009C5F11 /* server.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = server.h; path = include/server.h; sourceTree = ""; }; 9277A14821FD7246009C5F11 /* net.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = net.h; path = include/net.h; sourceTree = ""; }; @@ -47,7 +48,7 @@ 9277A15221FD725F009C5F11 /* addr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = addr.cpp; path = src/addr.cpp; sourceTree = ""; }; 9277A15321FD725F009C5F11 /* socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = socket.cpp; path = src/socket.cpp; sourceTree = ""; }; 9277A15421FD725F009C5F11 /* md5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = md5.cpp; path = src/md5.cpp; sourceTree = ""; }; - 9277A15521FD725F009C5F11 /* cproj.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cproj.cpp; path = src/cproj.cpp; sourceTree = ""; }; + 9277A15521FD725F009C5F11 /* cproj_cpt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cproj_cpt.cpp; path = src/cproj_cpt.cpp; sourceTree = ""; }; 9277A15621FD725F009C5F11 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = src/main.cpp; sourceTree = ""; }; 9277A15721FD725F009C5F11 /* cthread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cthread.cpp; path = src/cthread.cpp; sourceTree = ""; }; 9277A15821FD725F009C5F11 /* server.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = server.cpp; path = src/server.cpp; sourceTree = ""; }; @@ -58,6 +59,10 @@ 9277A16A21FE034F009C5F11 /* a.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = a.cpp; path = build/Debug/PCS/srcs/a.cpp; sourceTree = ""; }; 9277A16C21FE0357009C5F11 /* da.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = da.cpp; path = build/Debug/PCS/srcs/da.cpp; sourceTree = ""; }; 9277A18821FEB21D009C5F11 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = build/Debug/Libraries/libsqlite3.dylib; sourceTree = ""; }; + 9277A18A220076EE009C5F11 /* sql.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = sql.cpp; path = src/sql.cpp; sourceTree = ""; }; + 9277A18D22007758009C5F11 /* sql.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = sql.h; path = include/sql.h; sourceTree = ""; }; + 9277A18E220077CC009C5F11 /* cproj.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cproj.h; path = include/cproj.h; sourceTree = ""; }; + 9277A18F220079DB009C5F11 /* cproj_proj.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = cproj_proj.cpp; path = src/cproj_proj.cpp; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -104,11 +109,12 @@ 925A13AA21EC989500CBD427 /* include */ = { isa = PBXGroup; children = ( + 9277A18E220077CC009C5F11 /* cproj.h */, + 9277A18D22007758009C5F11 /* sql.h */, 9277A14C21FD7246009C5F11 /* clock.h */, 9277A14621FD7246009C5F11 /* cmap.h */, 9277A14921FD7246009C5F11 /* compute.h */, 9277A14B21FD7246009C5F11 /* cpart.h */, - 9277A14521FD7246009C5F11 /* cproj.hpp */, 9277A14A21FD7246009C5F11 /* cthread.h */, 9277A14D21FD7246009C5F11 /* md5.h */, 9277A14F21FD7246009C5F11 /* memory_type.h */, @@ -127,13 +133,15 @@ 9277A15C21FD725F009C5F11 /* clock.cpp */, 9277A15921FD725F009C5F11 /* cmap.cpp */, 9277A15A21FD725F009C5F11 /* cpart.cpp */, - 9277A15521FD725F009C5F11 /* cproj.cpp */, + 9277A15521FD725F009C5F11 /* cproj_cpt.cpp */, 9277A15721FD725F009C5F11 /* cthread.cpp */, 9277A15621FD725F009C5F11 /* main.cpp */, 9277A15421FD725F009C5F11 /* md5.cpp */, 9277A15B21FD725F009C5F11 /* memory.cpp */, 9277A15821FD725F009C5F11 /* server.cpp */, 9277A15321FD725F009C5F11 /* socket.cpp */, + 9277A18A220076EE009C5F11 /* sql.cpp */, + 9277A18F220079DB009C5F11 /* cproj_proj.cpp */, ); name = src; sourceTree = ""; @@ -202,10 +210,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9277A18C220076EE009C5F11 /* sql.cpp in Sources */, 9277A16721FD725F009C5F11 /* memory.cpp in Sources */, 9277A16821FD725F009C5F11 /* clock.cpp in Sources */, 9277A16621FD725F009C5F11 /* cpart.cpp in Sources */, - 9277A16121FD725F009C5F11 /* cproj.cpp in Sources */, + 9277A16121FD725F009C5F11 /* cproj_cpt.cpp in Sources */, + 9277A190220079DB009C5F11 /* cproj_proj.cpp in Sources */, 9277A16021FD725F009C5F11 /* md5.cpp in Sources */, 9277A16521FD725F009C5F11 /* cmap.cpp in Sources */, 9277A16221FD725F009C5F11 /* main.cpp in Sources */, diff --git a/Net.xcodeproj/xcuserdata/huyibing.xcuserdatad/xcschemes/xcschememanagement.plist b/Net.xcodeproj/xcuserdata/huyibing.xcuserdatad/xcschemes/xcschememanagement.plist index 3d8084a..ebb3c90 100644 --- a/Net.xcodeproj/xcuserdata/huyibing.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Net.xcodeproj/xcuserdata/huyibing.xcuserdatad/xcschemes/xcschememanagement.plist @@ -10,5 +10,13 @@ 0 + SuppressBuildableAutocreation + + 9221D9EA21EA5142007310A7 + + primary + + + diff --git a/include/cmap.h b/include/cmap.h index 65b1f53..be85255 100644 --- a/include/cmap.h +++ b/include/cmap.h @@ -12,8 +12,7 @@ #include "type.h" #include "cpart.h" #include "md5.h" - -class Proj; +#include "sql.h" //计算模块管理对象间的依赖关系管理结构 class cp_depend{ @@ -27,929 +26,8 @@ public: }; -class setting_file{ -protected: - // 检查路径或文件 - void check_paths(string main_path, vector paths){ - for(auto path : paths){ - if(!~access((main_path+path).data(),F_OK)) throw path+" is abnormal"; - } - } - // 检查字符是否合法 - bool if_illegal(char c){ - if(isalnum(c) || c == '_') return true; - else return false; - } - // 寻找保留字 - bool search_key(ifstream &ifsfile,string key){ - string line; - do{ - ifsfile>>line; - }while(line.find(key) == string::npos && ifsfile.eof() == false); - - if(ifsfile.eof() == true) return false; - return true; - } -}; -struct cpt_func_args{ - string type; - int size; - string key; -}; - -class Cpt:public setting_file{ - friend Proj; - vector src_files; -// 入口函数对应的源文件 - map funcs_src; -// 入口函数的输入与输出参数格式 - map> fargs_in,fargs_out; - string path; - ifstream ifscpt; - string name; -public: - - Cpt(string path, string proj_name){ -#ifdef DEBUG - printf("Reading Cpt File %s\n[*]Require Project Name %s\n",path.data(),proj_name.data()); -#endif - ifscpt.open(path); - string line; - if(search_key(ifscpt, "cparts")){ -// 读取下一段信息 - ifscpt>>line; -// 大括号位置 - string::size_type qb_idx = line.find("{"); -// 寻找任务工程名 - string t_name; - if(qb_idx == string::npos) t_name = line; - else t_name = line.substr(0,qb_idx); -// 检查工程名是否含有非法字符 - for(auto c:t_name){ - if(if_illegal(c)); - else throw "project's name has illegal char"; - } -#ifdef DEBUG - printf("Read Project Name %s\n",t_name.data()); -#endif -// 检查工程名 - if(t_name == proj_name) name = t_name; - else throw "project's name confilct"; -// 寻找左大括号 - if(qb_idx == string::npos){ - ifscpt>>line; - if((qb_idx = line.find("{")) == string::npos) throw "syntax error"; - } -// 源文件描述遍历 - while(search_key(ifscpt, "srcfile")){ - ifscpt>>line; -// 大括号位置 - string::size_type qb_idx = line.find("{"); -// 寻找源文件名 - string tsrc_name; - if(qb_idx == string::npos) tsrc_name = line; - else tsrc_name = line.substr(0,qb_idx); - tsrc_name = tsrc_name.substr(1,tsrc_name.size()-2); -#ifdef DEBUG - printf("Read Source File Name %s\n",tsrc_name.data()); -#endif -// 记录源文件名 - src_files.push_back(tsrc_name); -// 寻找左大括号 - if(qb_idx == string::npos){ - ifscpt>>line; - if((qb_idx = line.find("{")) == string::npos) throw "syntax error"; - } -// 入口函数描述遍历 - while(getline(ifscpt,line)){ - string real_line; - for(auto c:line){ - if(isgraph(c) || c == ' ') real_line.push_back(c); - } - if(real_line.empty()) continue; - if(real_line != "};"){ -#ifdef DEBUG - printf("Read Function Description %s\n",real_line.data()); -#endif -// 分离输出参数列表 - string::size_type dq_l = real_line.find("{"); - string::size_type dq_r = real_line.find("}"); - if(dq_l == string::npos || dq_r == string::npos) throw "syntax error"; - string str_argout = real_line.substr(dq_l+1,dq_r-dq_l-1); -#ifdef DEBUG - printf("Read Args (OUT) Description %s\n",str_argout.data()); -#endif - vector cfgo = deal_args(str_argout); -// 分离输入参数列表 - string::size_type yq_l = real_line.find("("); - string::size_type yq_r = real_line.find(")"); - if(yq_l == string::npos || yq_r == string::npos) throw "syntax error"; - string str_argin = real_line.substr(yq_l+1,yq_r-yq_l-1); - vector cfgi = deal_args(str_argin); -#ifdef DEBUG - printf("Read Args (IN) Description %s\n",str_argin.data()); -#endif -// 分离入口函数名 - string func = real_line.substr(dq_r+1,yq_l-dq_r-1); - string real_func; - for(auto c : func){ - if(isgraph(c)){ - real_func.push_back(c); - if(!if_illegal(c)) throw "func name has illegal char"; - } - } -#ifdef DEBUG - printf("Read Function Name %s\n",real_func.data()); -#endif -// 记录入口函数名 - funcs_src.insert({real_func,tsrc_name}); -// 添加相关参数 - fargs_out.insert({real_func,cfgo}); - fargs_in.insert({real_func,cfgi}); - - } - else break; - } - - } - - } - else throw "fail to find key word"; - } - - vector deal_args(string args){ - string::size_type lcma_dix = 0; - string::size_type cma_idx = args.find(",",0); - vector cfgs; - - if(cma_idx == string::npos){ - string real_args; - for(auto c : args){ - if(isgraph(c)){ - real_args.push_back(c); - if(!if_illegal(c)) throw "func name has illegal char"; - } - } - if(real_args.size() > 3){ - cpt_func_args ncfg = deal_arg(args); - cfgs.push_back(ncfg); - } - } - else{ -// 分割逗号 - while(cma_idx != string::npos){ - string arg = args.substr(lcma_dix,cma_idx-lcma_dix); - cpt_func_args ncfg; - ncfg = deal_arg(arg); - cfgs.push_back(ncfg); - lcma_dix = cma_idx+1; - cma_idx = args.find(",",lcma_dix); - if(cma_idx == string::npos && lcma_dix != string::npos){ - arg = args.substr(lcma_dix,args.size()-lcma_dix); - ncfg = deal_arg(arg); - cfgs.push_back(ncfg); - } - } - } - return cfgs; - } - - cpt_func_args deal_arg(string arg){ - cpt_func_args ncfa; - std::stringstream ss,sr; - ss<>key; -// 读取数组标号 - string::size_type fq_l = key.find("["); - string::size_type fq_r = key.find("]"); - int size = 1; - string type; - if(fq_l != string::npos && fq_r != string::npos){ - string size_str = key.substr(fq_l+1,fq_r-fq_l-1); - sr<>size; - type = key.substr(0,fq_l); - - - } - else if (fq_r == string::npos && fq_r == string::npos){ - type = key.substr(0,fq_l); - } - else throw "syntax error"; - ncfa.size = size; - ncfa.type = type; - ss>>ncfa.key; - return ncfa; - } - -}; - -class Map: public Cpt{ - -}; - - -struct SQLTable{ - string name; - vector> colnums; -}; - -struct SQLItem{ - vector colnum; - vector argv; -}; - -struct SQLCallBack{ - unsigned long size; - vector items; - string errmsg; - int sql_rtn; -}; - -namespace sql { - int SQLCallBackFunc(void *data, int argc, char **argv, char **azColName); - SQLCallBack *sql_exec(sqlite3 *psql, string sql); - int table_create(sqlite3 *psql, string name, vector> colnums); - int insert_info(sqlite3 *psql, sqlite3_stmt **psqlsmt, string table_name, vector>value); - string string_type(string str); -} - - -class Proj:public setting_file{ -// 计算工程所在的目录 - string proj_path; -// 计算工程描述文件名 - string proj_file; -// 工程名 - string name; -// 计算工程读入流 - ifstream ifsproj; -// 源文件所在的目录 - vector src_paths; -// 源文件搜索目录下的所有源文件 - map src_files; -// 计算工程所涉及到的源文件 - map used_srcfiles; -// 计算工程所涉及到的源文件的MD5 - map src_md5; -// 关系描述文件所在的目录 - vector map_paths; -// 模块描述文件所在目录 - vector cpt_paths; -// 模块描述对象 - vector cpts; -// 关系描述对象 - vector maps; -// 动态链接库存放的目录 - string lib_path; -// 模块入口函数索引 - map func_index; -// 动态链接库对应的源文件索引 - map lib_index; -// 工程对应数据库 - sqlite3 *psql; -// 数据库文件路径 - string db_path; -// 判断参数是否为字符串 - bool if_string(string &arg){ - if(arg[0] == '\"' && arg[arg.size()-1] == '\"') return true; - else return false; - } -// 判断下一条命令的有无 - bool if_continue(string &arg){ - if(arg.find(",") != string::npos && arg[arg.size()-1] == ',') return true; - else return false; - } -// 消去字符串的双引号 - string cut_string(string &arg){ - return arg.substr(1,arg.size()-2); - } -// 处理描述文件的命令 - void deal_order(string tag, string arg){ - if(tag == "cpt"){ - cpt_paths.push_back(arg); - } - else if (tag == "map"){ - map_paths.push_back(arg); - } - else if(tag == "src_dir"){ - src_paths.push_back(arg); - } - else if(tag == "lib_dir"){ - this->lib_path = arg; - } - else throw "syntax error"; - } -protected: - -// 读取所有涉及的Cpt文件 - void build_cpts(void){ - for(auto cptp : cpt_paths){ - Cpt *ncpt = new Cpt(proj_path + cptp, name); - cpts.push_back(ncpt); - } - } - -// 检查Cpt文件中描述的源文件是否存在对应实体 - void check_cpt(void){ - for(auto cpt:cpts){ -#ifdef DEBUG - printf("Checking Cpt File %p.\n",cpt); -#endif - for(auto file:cpt->src_files){ - auto src_file = src_files.find(file); -// 如果在索引中没有找到对应的源文件 - if(src_file == src_files.end()){ -#ifdef DEBUG - printf("[Error]Fail To Find Soruce File Related %s\n",file.data()); -#endif - throw "source file not exist"; - } - else{ -#ifdef DEBUG - printf("Succeed In Finding Source File %s\n",file.data()); -#endif - used_srcfiles.insert({src_file->first,src_file->second}); -// 计算源文件的MD5 - string md5; - string tsrc_path = src_paths[src_file->second]; - string t_path = proj_path+tsrc_path+"/"+file; - ComputeFile(t_path, md5); - src_md5.insert({file,md5}); -#ifdef DEBUG - printf("Computed Source File's MD5 %s\n[*]Source File Path %s\n",md5.data(),t_path.data()); -#endif - } - } - } - } - -// 搜寻源文件目录 - void search_src(int idx,string path){ - DIR *pdir = opendir(path.data()); - struct dirent *ptr; - if(pdir != NULL){ - while ((ptr = readdir(pdir)) != NULL) { -// 如果是文件 - if(ptr->d_type == 8){ - string file = ptr->d_name; -// 含有.cpp的文件 - if(file.find(".cpp") != string::npos){ - src_files.insert({file,idx}); - } - } - } - } - else throw "path is abnormal"; - } - -// 将现有信息储存到一个新的数据库中 - void update_db(void); - -// 检查涉及到的源文件的MD5与数据库中的是否一致 - void check_src_md5(string db_path); - -// 编译目标源文件生成动态链接库 - void build_src(string lib_name,string srcfile_path, string libs_path){ - string build_command = "g++ -fPIC -shared -std=c++11 -o "+libs_path+"/"+lib_name+" "+srcfile_path+" >gcc_build.log 2>&1"; -#ifdef DEBUG - printf("Build Command %s\n",build_command.data()); -#endif - int rtn = system(build_command.data()); -// 检测命令执行情况 - if(rtn != -1 && rtn != 127){ - struct stat statbuff; - stat("gcc_build.log", &statbuff); - unsigned long file_size = statbuff.st_size; -// 检测命令重定向输出文件的大小,判断编译是否出现了错误 - if(file_size == 0){ -#ifdef DEBUG - printf("Succeed In Compiling File %s\n",srcfile_path.data()); -#endif - } - else{ -#ifdef DEBUG - printf("[Error]Caught Errors or Warrnings In Compiling File %s\n",srcfile_path.data()); -#endif - throw "compile error"; - } - } - else throw "fail to build lib file"; - } - - void build_new_db(void){ - string db_dir = proj_path+"dbs"; - if(mkdir(db_dir.data(), S_IRWXU | S_IRWXG | S_IRWXO) == -1){ - if(!~access(db_dir.data(), X_OK)){ -#ifdef DEBUG - printf("[Error]Caught Error In Creating Directory dbs\n"); -#endif - throw "fail to make dir dbs"; - } - } - db_path = proj_path+"dbs/"+name+".db"; - int sqlrtn = sqlite3_open(db_path.data(), &psql); - if(!sqlrtn){ -// 创建数据库表 -// 记录源文件信息 - sql::table_create(psql, "srcfiles", { -// ID - {"id","INT PRIMARY KEY NOT NULL"}, -// 文件名 - {"name","TEXT NOT NULL"}, -// 文件路径 - {"path","TEXT NOT NULL"}, -// 文件内容 - {"content","NONE"}, -// 文件MD5 - {"md5","TEXT NOT NULL"} - }); -// 记录入口函数信息 - sql::table_create(psql, "functions", { -// ID - {"id","INT PRIMARY KEY NOT NULL"}, -// 入口函数名 - {"name","TEXT NOT NULL"}, -// 入口函数所在的源文件在数据库中对应的ID - {"srcfile_id","INT NOT NULL"}, -// 入口函数所在的动态链接库在数据库中对应的ID - {"libfile_id","INT NOT NULL"} - }); -// 记录cpt文件信息 - sql::table_create(psql, "cptfiles", { -// ID - {"id","INT PRIMARY KEY NOT NULL"}, -// cpt文件名及其路径 - {"pname","TEXT NOT NULL"}, -// cpt文件内容 - {"content","NONE"}, -// cpt文件MD5 - {"md5","TEXT NOT NULL"} - }); -// 记录动态链接库信息 - sql::table_create(psql, "libfiles", { -// ID - {"id","INT PRIMARY KEY NOT NULL"}, -// 动态链接库文件名 - {"name","TEXT NOT NULL"}, -// 动态链接库文件内容 - {"content","NONE"}, - }); - } - else{ -#ifdef DEBUG - printf("[Error] Fail To Create DB File %s\n",db_path.data()); -#endif - throw "fail to create db file"; - } - - } - -// 写入项目涉及的源文件信息到数据库中 - void write_src_info(void){ - int idx = 0; - sqlite3_stmt *psqlsmt; -// 编译SQL语句 - sql::insert_info(psql, &psqlsmt, "srcfiles", { - {"id","?1"}, - {"name","?2"}, - {"path","?3"}, - {"md5","?4"} - }); -#ifdef DEBUG - printf("Writing Srcfiles Information Into Database.\n"); -#endif - for(auto src:used_srcfiles){ -// 获取源文件的MD5 - string md5 = src_md5.find(src.first)->second; -// 链接数据 - sqlite3_bind_int(psqlsmt, 1, idx++); - sqlite3_bind_text(psqlsmt, 2, src.first.data(), -1, SQLITE_STATIC); - sqlite3_bind_text(psqlsmt, 3, src_paths[src.second].data(), -1, SQLITE_STATIC); - sqlite3_bind_text(psqlsmt, 4, md5.data(), -1, SQLITE_STATIC); -// 执行SQL语句 - int rtn = sqlite3_step(psqlsmt); - if(rtn == SQLITE_OK || rtn == SQLITE_DONE){ -#ifdef DEBUG - printf("[*]Succeed In Writing Srcfiles Information %s\n",src.first.data()); -#endif - } - else{ -#ifdef DEBUG - printf("[*]Failed to Write Srcfiles Information %s\n",src.first.data()); -#endif - } - sqlite3_reset(psqlsmt); - } - } - -// 写入动态链接库信息到数据库中 - void write_lib_info(void){ - int idx = 0; - sqlite3_stmt *psqlsmt; - sql::insert_info(psql, &psqlsmt, "libfiles", { - {"id","?1"}, - {"name","?2"} - }); -#ifdef DEBUG - printf("Writing Libfiles Information Into Database.\n"); -#endif - for(auto lib : lib_index){ -// 链接数据 - sqlite3_bind_int(psqlsmt, 1, idx++); - sqlite3_bind_text(psqlsmt, 2, lib.second.data(), -1, SQLITE_STATIC); -// 执行SQL语句 - int rtn = sqlite3_step(psqlsmt); - if(rtn == SQLITE_OK || rtn == SQLITE_DONE){ -#ifdef DEBUG - printf("[*]Succeed In Writing Libfile Information %s\n",lib.second.data()); -#endif - } - else{ -#ifdef DEBUG - printf("[*]Failed to Write Libfile Information %s\n",lib.second.data()); -#endif - } - sqlite3_reset(psqlsmt); - } - } - -// 写入入口函数信息到数据库中 - void write_func_info(void){ - int idx = 0; - sqlite3_stmt *psqlsmt; - sql::insert_info(psql, &psqlsmt, "functions", { - {"id","?1"}, - {"name","?2"}, - {"srcfile_id","?3"}, - {"libfile_id","?4"} - }); -#ifdef DEBUG - printf("Writing Functions Information Into Database.\n"); -#endif - for(auto func : func_index){ - string src_file = func.second->funcs_src.find(func.first)->second; - string lib_file = lib_index.find(src_file)->second; - string sql_quote = "SELECT id FROM srcfiles WHERE name = "+sql::string_type(src_file)+";"; -// 查找源文件信息在数据库中的ID - SQLCallBack *psqlcb = sql::sql_exec(psql, sql_quote); - if(psqlcb->size != 1){ -#ifdef DEBUG - printf("[Error]Database Data Is Abnormal.\n"); -#endif - throw "database abnormal"; - } - std::stringstream ss; - ss<items[0].argv[0]; - int srcfile_id = -1; - ss>>srcfile_id; - if(psqlcb->items[0].colnum[0] != "id" || srcfile_id == -1){ -#ifdef DEBUG - printf("[Error]Database Data Is Abnormal In Table srcfiles\n"); -#endif - throw "database abnormal"; - } - delete psqlcb; -// 查找动态链接库信息在数据库中的ID - sql_quote = "SELECT id FROM libfiles WHERE name = "+sql::string_type(lib_file)+";"; - psqlcb = sql::sql_exec(psql, sql_quote); - if(psqlcb->size != 1){ -#ifdef DEBUG - printf("[Error]Database Data Is Abnormal In Table libfiles\n"); -#endif - throw "database abnormal"; - } - std::stringstream ssl; - ssl<items[0].argv[0]; - int libfile_id = -1; - ssl>>libfile_id; - if(psqlcb->items[0].colnum[0] != "id" || libfile_id == -1){ -#ifdef DEBUG - printf("[Error]Database Data Is Abnormal In Table libfiles\n"); -#endif - throw "database abnormal"; - } - delete psqlcb; -// 链接数据 - sqlite3_bind_int(psqlsmt, 1, idx++); - sqlite3_bind_text(psqlsmt, 2, func.first.data(), -1, SQLITE_STATIC); - sqlite3_bind_int(psqlsmt, 3, srcfile_id); - sqlite3_bind_int(psqlsmt, 4, libfile_id); - -// 执行SQL语句 - int rtn = sqlite3_step(psqlsmt); - if(rtn == SQLITE_OK || rtn == SQLITE_DONE){ -#ifdef DEBUG - printf("[*]Succeed In Writing Function Information %s\n",func.first.data()); -#endif - } - else{ -#ifdef DEBUG - printf("[*]Failed to Write Function Information %s\n",func.first.data()); -#endif - } - sqlite3_reset(psqlsmt); - } - } - -// 写入口函数入输入输出参数信息到数据库中 - void write_args_info(void){ -#ifdef DEBUG - printf("Start to Write Function Parameter Information Into Database.\n"); -#endif - for(auto func : func_index){ - vector *pfin = &func.second->fargs_in.find(func.first)->second; - vector *pfout = &func.second->fargs_out.find(func.first)->second; -// 创建对应的储存表 - sql::table_create(psql, func.first, { -// ID - {"id","INT PRIMARY KEY NOT NULL"}, -// 数据类型 - {"type","TEXT NOT NULL"}, -// 顺序序号 - {"idx","INT NOT NULL"}, -// 输入或输出标识(0输入,1输出) - {"io","INT NOT NULL"}, -// 标签名 - {"key","TEXT"}, -// 数据单元个数 - {"size","INT NOT NULL"} - }); - - sqlite3_stmt *psqlsmt; - -// 生成并编译SQL语句 - sql::insert_info(psql, &psqlsmt, func.first, { - {"id","?6"}, - {"type","?1"}, - {"idx","?2"}, - {"io","?3"}, - {"key","?4"}, - {"size","?5"} - }); - - int idx = 0, sidx = 0; -#ifdef DEBUG - printf("Writing Function Parameter (IN) Information Into Database (%s)\n",func.first.data()); -#endif -// 写入输入参数 - for(auto arg : *pfin){ -// 连接数据 - sqlite3_bind_text(psqlsmt, 1, arg.type.data(), -1, SQLITE_STATIC); - sqlite3_bind_int(psqlsmt, 2, idx++); - sqlite3_bind_int(psqlsmt, 3, 0); - sqlite3_bind_text(psqlsmt,4, arg.key.data(), -1, SQLITE_STATIC); - sqlite3_bind_int(psqlsmt, 5, arg.size); - sqlite3_bind_int(psqlsmt, 6, sidx++); -// 执行SQL语句 - int rtn = sqlite3_step(psqlsmt); - if(rtn == SQLITE_OK || rtn == SQLITE_DONE){ -#ifdef DEBUG - printf("[*]Succeed In Writing Function Parameter Information %s\n",func.first.data()); -#endif - } - else{ -#ifdef DEBUG - printf("[*]Failed to Write Function Parameter Information %s\n",func.first.data()); -#endif - } - sqlite3_reset(psqlsmt); - } - -#ifdef DEBUG - printf("Writing Function Parameter (OUT) Information Into Database (%s)\n",func.first.data()); -#endif - idx = 0; -// 写入输入参数 - for(auto arg : *pfout){ -// 连接数据 - sqlite3_bind_text(psqlsmt, 1, arg.type.data(), -1, SQLITE_STATIC); - sqlite3_bind_int(psqlsmt, 2, idx++); - sqlite3_bind_int(psqlsmt, 3, 1); - sqlite3_bind_text(psqlsmt,4, arg.key.data(), -1, SQLITE_STATIC); - sqlite3_bind_int(psqlsmt, 5, arg.size); - sqlite3_bind_int(psqlsmt, 6, sidx++); - -// 执行SQL语句 - int rtn = sqlite3_step(psqlsmt); - if(rtn == SQLITE_OK || rtn == SQLITE_DONE){ -#ifdef DEBUG - printf("[*]Succeed In Writing Function Parameter Information %s\n",func.first.data()); -#endif - } - else{ -#ifdef DEBUG - printf("[*]Failed to Write Function Parameter Information %s\n",func.first.data()); -#endif - } - sqlite3_reset(psqlsmt); - } - } - } - -public: - Proj(string t_projpath, string t_projfile){ -// 检查工程描述文件是否可读 - if(!~access(t_projpath.data(), R_OK)) throw "project directory state is abnormal"; - if(proj_path[proj_path.find_last_not_of(" ")] != '/') - t_projpath += "/"; - proj_path = t_projpath; - if(!~access((t_projpath+t_projfile).data(), R_OK)) throw "project file state is abnormal"; - - - proj_file = t_projfile; - ifsproj.open(proj_path+proj_file); - if(ifsproj.good()){ - string line; -// 寻找保留字 - if(!search_key(ifsproj,"proj")) throw "project struct not found"; -// 读取下一段信息 - ifsproj>>line; -// 大括号位置 - string::size_type qb_idx = line.find("{"); -// 寻找任务工程名 - string t_name; - if(qb_idx == string::npos) t_name = line; - else t_name = line.substr(0,qb_idx); -// 检查工程名是否含有非法字符 - for(auto c:t_name){ - if(if_illegal(c)); - else throw "project's name has illegal char"; - } - name = t_name; -// 寻找左大括号 - if(qb_idx == string::npos){ - ifsproj>>line; - if((qb_idx = line.find("{")) == string::npos) throw "syntax error"; - } -// 逐行分析语句 - string tag,cma,arg; - bool if_ctn = false; - do{ -// 读取命令标签 - ifsproj>>tag; -// 读取冒号 - ifsproj>>cma; -// 读取命令变量 - ifsproj>>arg; -// 检查参数是否含有非法字符 - for(auto c:t_name){ - if(if_illegal(c)); - else throw " arg has illegal char"; - } - if(cma != ":") throw "syntax error"; - if((if_ctn = if_continue(arg)) == true){ -// 消掉逗号 - arg = arg.substr(0,arg.size()-1); - } - if(if_string(arg)){ - deal_order(tag, cut_string(arg)); - } - else throw "syntax error"; - }while(if_ctn); - ifsproj>>line; - if(line != "};") throw "syntax error"; - } - else throw "fail to open project file"; -// 检查目录以及描述文件是否存在 - if(!~access((proj_path+lib_path).data(),W_OK)) throw "lib path is abnormal"; - check_paths(proj_path,src_paths); - check_paths(proj_path,map_paths); - check_paths(proj_path,cpt_paths); - } - -// 搜寻源文件搜索目录并读取Cpt文件 - void SearchInfo(void){ - int idx = 0; -// 遍历源文件储存目录 - for(auto path : src_paths) search_src(idx++, proj_path+path); -// 读取cpt文件 - build_cpts(); - - } -// 检查Cpt文件内所描述的源文件是否有对应的实体 - void CheckCptInfo(void){ - check_cpt(); - } - -// 建立计算模块入口函数索引 - void BuildFuncIndex(void){ -// 对应cpt文件 - for(auto pcpt : cpts){ -// 对应源文件 - for(auto func: pcpt->funcs_src){ -// 对应的计算模块入口函数 - func_index.insert({func.first,pcpt}); -#ifdef DEBUG - printf("Building Func Index %s (%p).\n",func.first.data(),pcpt); -#endif - } - } - } - -// 编译涉及到的源文件 - void CompileUsedSrcFiles(void){ - for(auto src : used_srcfiles){ - string tsrc_path = src_paths[src.second]; - string tlib_name = "lib_"+src.first+".so"; - string t_path = proj_path+tsrc_path+"/"+src.first; - string tlib_path = proj_path+lib_path; -#ifdef DEBUG - printf("Compling Used Source File %s\n[*]Libname %s\n[*]Source File Path %s\n[*]Lib Path %s\n",src.first.data(),tlib_name.data(),t_path.data(),tlib_path.data()); -#endif - build_src(tlib_name,t_path,tlib_path); - lib_index.insert({src.first,tlib_name}); - } - } - -// 检查入口函数是否在对应的动态链接库中可被按要求正确解析 - void CheckFuncInfo(void){ - for(auto func : func_index){ -// 找到入口函数所在的源文件 - string src_file = func.second->funcs_src.find(func.first)->second; -// 找到入口函数所在的动态链接库 - string tlib_name = lib_index.find(src_file)->second; - string tlib_path = proj_path+lib_path+"/"+tlib_name; -#ifdef DEBUG - printf("Checking Func %s\n[*]Lib File %s\n[*]Source File %s\n",func.first.data(),tlib_path.data(),src_file.data()); - -#endif -// 动态链接库操作柄 - void *lib_handle; -// 入口函数操作柄 - PCSFUNC func_handle; -// 传入传出参数列表操作柄 - vector *args_handle; - // 获得动态链接库的操作柄 - lib_handle = dlopen(tlib_path.data(), RTLD_NOW | RTLD_LOCAL); - if(lib_handle == nullptr){ -#ifdef DEBUG - printf("Fail To Get Lib File Handle\n"); - -#endif - throw "can not open library"; - } -#ifdef DEBUG - printf("Succeed In Getting Lib File Handle %p\n",lib_handle); - -#endif - // 获得该模块的入口 - func_handle = (PCSFUNC) dlsym(lib_handle, func.first.data()); - if(func_handle == nullptr){ -#ifdef DEBUG - printf("Fail To Get Func Handle\n"); - -#endif - throw "can not get func "+func.first; - } -#ifdef DEBUG - printf("Succeed In Getting Func Handle %p\n",func_handle); - -#endif - // 获得向该模块传入参数的操作柄 - args_handle = (vector *) dlsym(lib_handle, ("__"+func.first+"_args_in").data()); - if(args_handle == nullptr){ -#ifdef DEBUG - printf("Fail To Get Args (IN) Handle\n"); - -#endif - throw "can not get the HANDLE to PUSH args"; - } -#ifdef DEBUG - printf("Succeed In Getting Args (IN) Handle %p\n",args_handle); - -#endif - // 获得获取该模块传出参数的操作柄 - args_handle = (vector *) dlsym(lib_handle, ("__"+func.first+"_args_out").data()); - if(args_handle == nullptr){ -#ifdef DEBUG - printf("Fail To Get Args (OUT) Handle\n"); - -#endif - throw "can not get the HANDLE to GET args"; - } -#ifdef DEBUG - printf("Succeed In Getting Args (OUT) Handle %p\n",args_handle); - -#endif - dlclose(lib_handle); - } - } - - void DBProcess(void){ - build_new_db(); - write_src_info(); - write_lib_info(); - write_func_info(); - write_args_info(); - } - - -}; - //计算任务图类 class CMap{ public: diff --git a/include/cproj.h b/include/cproj.h new file mode 100644 index 0000000..8b17543 --- /dev/null +++ b/include/cproj.h @@ -0,0 +1,197 @@ +// +// cproj.h +// Net +// +// Created by 胡一兵 on 2019/1/22. +// Copyright © 2019年 Bakantu. All rights reserved. +// + +#ifndef cproj_h +#define cproj_h + +#include "type.h" +#include "cpart.h" +#include "md5.h" +#include "sql.h" + +class Proj; + +//配置文件通用方法类 +class setting_file{ +protected: +// 检查路径或文件 + void check_paths(string main_path, vector paths){ + for(auto path : paths){ + if(!~access((main_path+path).data(),F_OK)) throw path+" is abnormal"; + } + } +// 检查字符是否合法 + bool if_illegal(char c){ + if(isalnum(c) || c == '_') return true; + else return false; + } +// 寻找保留字 + bool search_key(ifstream &ifsfile,string key){ + string line; + do{ + ifsfile>>line; + }while(line.find(key) == string::npos && ifsfile.eof() == false); + + if(ifsfile.eof() == true) return false; + return true; + } +// 判断参数是否为字符串 + bool if_string(string &arg){ + if(arg[0] == '\"' && arg[arg.size()-1] == '\"') return true; + else return false; + } +// 判断下一条命令的有无 + bool if_continue(string &arg){ + if(arg.find(",") != string::npos && arg[arg.size()-1] == ',') return true; + else return false; + } +// 消去字符串的双引号 + string cut_string(string &arg){ + return arg.substr(1,arg.size()-2); + } + + int read_file(string path, Byte *buff){ + ifstream ifsf(path.data(),std::ios::binary); + char tmp[512] = {0}, *idx = buff; + while (!ifsf.eof()) { + memset(tmp, 0, 512); + ifsf.read(tmp, 512); + memcpy(idx, tmp, 512); + idx += 512; + } + ifsf.close(); + return 0; + } +}; + + +struct cpt_func_args{ + string type; + int size; + string key; +}; + +//cpt文件管理类 +class Cpt:public setting_file{ + friend Proj; +// Cpt文件中所提到的源文件 + vector src_files; +// 入口函数对应的源文件(入口函数名,源文件名) + map funcs_src; +// 入口函数的输入与输出参数格式(入口函数名,参数列表) + map> fargs_in,fargs_out; +// Cpt文件路径 + string path; + ifstream ifscpt; +// 工程名 + string name; +// 处理参数列表 + vector deal_args(string args); +// 处理参数 + cpt_func_args deal_arg(string arg); +public: +// 构造函数 + Cpt(string path, string proj_name); +}; + +//map文件管理类 +class Map: public Cpt{ + +}; + + +//proj文件管理类 +class Proj:public setting_file{ +// 计算工程所在的目录 + string proj_path; +// 计算工程描述文件名 + string proj_file; +// 工程名 + string name; +// 计算工程读入流 + ifstream ifsproj; +// 源文件所在的目录 + vector src_paths; +// 源文件搜索目录下的所有源文件 + map src_files; +// 计算工程所涉及到的源文件 + map used_srcfiles; +// 计算工程所涉及到的源文件的MD5 + map src_md5; +// 关系描述文件所在的目录 + vector map_paths; +// 模块描述文件所在目录 + vector cpt_paths; +// 模块描述对象 + vector cpts; +// 关系描述对象 + vector maps; +// 动态链接库存放的目录 + string lib_path; +// 模块入口函数索引 + map func_index; +// 动态链接库对应的源文件索引 + map lib_index; +// 工程对应数据库 + sqlite3 *psql; +// 数据库文件路径 + string db_path; + +// 处理描述文件的命令 + void deal_order(string tag, string arg); +// 读取所有涉及的Cpt文件 + void build_cpts(void); +// 检查Cpt文件中描述的源文件是否存在对应实体 + void check_cpt(void); +// 搜寻源文件目录 + void search_src(int idx,string path); +// 将现有信息储存到一个新的数据库中 + void update_db(void); +// 检查涉及到的源文件的MD5与数据库中的是否一致 + void check_src_md5(string db_path); +// 编译目标源文件生成动态链接库 + void build_src(string lib_name,string srcfile_path, string libs_path); +// 创建数据库 + void build_new_db(void); +// 写入项目涉及的源文件信息到数据库中 + void write_src_info(void); +// 写入动态链接库信息到数据库中 + void write_lib_info(void); +// 写入入口函数信息到数据库中 + void write_func_info(void); +// 写入口函数入输入输出参数信息到数据库中 + void write_args_info(void); +// 写入cpt文件信息到数据库中 + void write_cpt_info(void); +// 写入工程描述文件信息到数据库中 + void write_proj_info(void); +// 检查数据库是否正确 + void check_database(void); +public: +// 读取Proj文件 + Proj(string t_projpath, string t_projfile); +// 检查目录以及描述文件是否存在 + void GeneralCheckInfo(void); +// 搜寻源文件搜索目录并读取Cpt文件 + void SearchInfo(void); +// 检查Cpt文件内所描述的源文件是否有对应的实体 + void CheckCptInfo(void); +// 建立计算模块入口函数索引 + void BuildFuncIndex(void); +// 编译涉及到的源文件 + void CompileUsedSrcFiles(void); +// 检查入口函数是否在对应的动态链接库中可被按要求正确解析 + void CheckFuncInfo(void); +// 建立数据库 + void DBProcess(void); +// 获得工程名 + string GetName(void); + void UpdateProcess(void); +}; + +#endif /* cproj_h */ diff --git a/include/cproj.hpp b/include/cproj.hpp deleted file mode 100644 index 2ddb6e5..0000000 --- a/include/cproj.hpp +++ /dev/null @@ -1,14 +0,0 @@ -// -// cproj.h -// Net -// -// Created by 胡一兵 on 2019/1/22. -// Copyright © 2019年 Bakantu. All rights reserved. -// - -#ifndef cproj_h -#define cproj_h - - - -#endif /* cproj_h */ diff --git a/include/sql.h b/include/sql.h new file mode 100644 index 0000000..d26394e --- /dev/null +++ b/include/sql.h @@ -0,0 +1,42 @@ +// +// sql.h +// Net +// +// Created by 胡一兵 on 2019/1/29. +// Copyright © 2019年 Bakantu. All rights reserved. +// + +#ifndef sql_h +#define sql_h + +struct SQLTable{ + string name; + vector> colnums; +}; +//回调项目封装结构 +struct SQLItem{ + vector colnum; + vector argv; +}; +//回调结果封装结构 +struct SQLCallBack{ + unsigned long size; + vector items; + string errmsg; + int sql_rtn; +}; + +namespace sql { +// 基本回调函数 + int SQLCallBackFunc(void *data, int argc, char **argv, char **azColName); +// 执行SQL命令 + SQLCallBack *sql_exec(sqlite3 *psql, string sql); +// 创建新数据表 + int table_create(sqlite3 *psql, string name, vector> colnums); +// 编译插入命令 + int insert_info(sqlite3 *psql, sqlite3_stmt **psqlsmt, string table_name, vector>value); +// 生成字符串格式的数据 + string string_type(string str); +} + +#endif /* sql_h */ diff --git a/include/type.h b/include/type.h index f8e2ee5..3389f47 100644 --- a/include/type.h +++ b/include/type.h @@ -48,4 +48,6 @@ using std::ifstream; using std::cout; using std::endl; +typedef char Byte; + #endif /* type_h */ diff --git a/src/cmap.cpp b/src/cmap.cpp index 7e41a0d..786fdbc 100644 --- a/src/cmap.cpp +++ b/src/cmap.cpp @@ -9,124 +9,6 @@ #include "memory.h" #include "cmap.h" -namespace sql { -// 数据库回调函数 - int SQLCallBackFunc(void *data, int argc, char **argv, char **azColName){ - SQLCallBack *pscb = (SQLCallBack *)data; - if(pscb == NULL){ -#ifdef DEBUG - printf("Illegal Function Calling SQLCallBackFunc\n"); -#endif - throw "illegal calling"; - } - if(pscb != nullptr){ - pscb->size = argc; - for(int i = 0; i < argc; i++){ - SQLItem nsi; - nsi.colnum.push_back(azColName[i]); - nsi.argv.push_back(argv[i] ? argv[i] : "nil"); - pscb->items.push_back(nsi); - } - } - return 0; - } - -// SQL语句执行 - SQLCallBack *sql_exec(sqlite3 *psql, string sql){ - SQLCallBack *pscb = new SQLCallBack; - if(pscb == NULL){ -#ifdef DEBUG - printf("Error In Creating Struct SQLCallBack\n"); -#endif - } -#ifdef DEBUG - printf("[*]SQL Request %s\n[*]SQL %p\n",sql.data(),psql); -#endif - char *errmsg; - pscb->sql_rtn = sqlite3_exec(psql, sql.data(), SQLCallBackFunc, (void *)pscb, &errmsg); - if(errmsg != NULL) pscb->errmsg = errmsg; - return pscb; - } - - - /** - 创建数据库表 - - @param psql 数据库操作柄 - @param name 数据库表名 - @param colnums 数据库表描述 - @return 执行成功返回0 - */ - int table_create(sqlite3 *psql, string name, vector> colnums){ -#ifdef DEBUG - printf("Create SQL Table %s\n",name.data()); -#endif -// SQL语句 - string sql_quote = "CREATE TABLE "+name; - sql_quote += "("; - int idx = 0; - for(auto colnum : colnums){ - if(idx++) sql_quote += ","; - sql_quote += colnum.first + " " + colnum.second; - } - sql_quote += ");"; -// 执行SQL语句 - SQLCallBack *pscb = sql_exec(psql, sql_quote); - if(pscb->sql_rtn != SQLITE_OK){ -#ifdef DEBUG - printf("[Error]Fail To Create Table %s\n",name.data()); -#endif - throw "fail to create table"; - } -#ifdef DEBUG - printf("Succeed In Creating Table %s\n",name.data()); -#endif - delete pscb; - return 0; - } - - int insert_info(sqlite3 *psql, sqlite3_stmt **psqlsmt, string table_name,vector>items){ - - string sql_quote = "INSERT INTO "+table_name; -// 处理表项名 - sql_quote +="("; - int idx = 0; - for(auto item : items){ - if(idx++) sql_quote +=","; - sql_quote+= item.first; - } - sql_quote +=") VALUES("; -// 处理数据 - idx = 0; - for(auto item : items){ - if(idx++) sql_quote +=","; - sql_quote+= item.second; - } - sql_quote += ");"; -#ifdef DEBUG - printf("SQL Insert Statment %s\n",sql_quote.data()); -#endif - const char *pzTail; - int rtn; - rtn = sqlite3_prepare(psql, sql_quote.data(), -1, psqlsmt, &pzTail); - if(rtn == SQLITE_OK){ -#ifdef DEBUG - printf("[*]Succeed In Compiling SQL Statment\n"); -#endif - return 0; - } - else{ -#ifdef DEBUG - printf("[*]Fail to Compile SQL Statment\n"); -#endif - return -1; - } - - } - string string_type(string str){ - return "\'"+str+"\'"; - } - -} + diff --git a/src/cproj.cpp b/src/cproj.cpp deleted file mode 100644 index bb735e3..0000000 --- a/src/cproj.cpp +++ /dev/null @@ -1,9 +0,0 @@ -// -// CProj.cpp -// Net -// -// Created by 胡一兵 on 2019/1/22. -// Copyright © 2019年 Bakantu. All rights reserved. -// - -#include "cproj.hpp" diff --git a/src/cproj_cpt.cpp b/src/cproj_cpt.cpp new file mode 100644 index 0000000..2da09dd --- /dev/null +++ b/src/cproj_cpt.cpp @@ -0,0 +1,183 @@ +// +// CProj.cpp +// Net +// +// Created by 胡一兵 on 2019/1/22. +// Copyright © 2019年 Bakantu. All rights reserved. +// + +#include "cproj.h" + +Cpt::Cpt(string path, string proj_name){ +#ifdef DEBUG + printf("Reading Cpt File %s\n[*]Require Project Name %s\n",path.data(),proj_name.data()); +#endif + ifscpt.open(path); + string line; + if(search_key(ifscpt, "cparts")){ + // 读取下一段信息 + ifscpt>>line; + // 大括号位置 + string::size_type qb_idx = line.find("{"); + // 寻找任务工程名 + string t_name; + if(qb_idx == string::npos) t_name = line; + else t_name = line.substr(0,qb_idx); + // 检查工程名是否含有非法字符 + for(auto c:t_name){ + if(if_illegal(c)); + else throw "project's name has illegal char"; + } +#ifdef DEBUG + printf("Read Project Name %s\n",t_name.data()); +#endif + // 检查工程名 + if(t_name == proj_name) name = t_name; + else throw "project's name confilct"; + // 寻找左大括号 + if(qb_idx == string::npos){ + ifscpt>>line; + if((qb_idx = line.find("{")) == string::npos) throw "syntax error"; + } + // 源文件描述遍历 + while(search_key(ifscpt, "srcfile")){ + ifscpt>>line; + // 大括号位置 + string::size_type qb_idx = line.find("{"); + // 寻找源文件名 + string tsrc_name; + if(qb_idx == string::npos) tsrc_name = line; + else tsrc_name = line.substr(0,qb_idx); + tsrc_name = tsrc_name.substr(1,tsrc_name.size()-2); +#ifdef DEBUG + printf("Read Source File Name %s\n",tsrc_name.data()); +#endif + // 记录源文件名 + src_files.push_back(tsrc_name); + // 寻找左大括号 + if(qb_idx == string::npos){ + ifscpt>>line; + if((qb_idx = line.find("{")) == string::npos) throw "syntax error"; + } + // 入口函数描述遍历 + while(getline(ifscpt,line)){ + string real_line; + for(auto c:line){ + if(isgraph(c) || c == ' ') real_line.push_back(c); + } + if(real_line.empty()) continue; + if(real_line != "};"){ +#ifdef DEBUG + printf("Read Function Description %s\n",real_line.data()); +#endif + // 分离输出参数列表 + string::size_type dq_l = real_line.find("{"); + string::size_type dq_r = real_line.find("}"); + if(dq_l == string::npos || dq_r == string::npos) throw "syntax error"; + string str_argout = real_line.substr(dq_l+1,dq_r-dq_l-1); +#ifdef DEBUG + printf("Read Args (OUT) Description %s\n",str_argout.data()); +#endif + vector cfgo = deal_args(str_argout); + // 分离输入参数列表 + string::size_type yq_l = real_line.find("("); + string::size_type yq_r = real_line.find(")"); + if(yq_l == string::npos || yq_r == string::npos) throw "syntax error"; + string str_argin = real_line.substr(yq_l+1,yq_r-yq_l-1); + vector cfgi = deal_args(str_argin); +#ifdef DEBUG + printf("Read Args (IN) Description %s\n",str_argin.data()); +#endif + // 分离入口函数名 + string func = real_line.substr(dq_r+1,yq_l-dq_r-1); + string real_func; + for(auto c : func){ + if(isgraph(c)){ + real_func.push_back(c); + if(!if_illegal(c)) throw "func name has illegal char"; + } + } +#ifdef DEBUG + printf("Read Function Name %s\n",real_func.data()); +#endif + // 记录入口函数名 + funcs_src.insert({real_func,tsrc_name}); + // 添加相关参数 + fargs_out.insert({real_func,cfgo}); + fargs_in.insert({real_func,cfgi}); + + } + else break; + } + + } + + } + else throw "fail to find key word"; +} + +vector Cpt::deal_args(string args){ + string::size_type lcma_dix = 0; + string::size_type cma_idx = args.find(",",0); + vector cfgs; + + if(cma_idx == string::npos){ + string real_args; + for(auto c : args){ + if(isgraph(c)){ + real_args.push_back(c); + if(!if_illegal(c)) throw "func name has illegal char"; + } + } + if(real_args.size() > 3){ + cpt_func_args ncfg = deal_arg(args); + cfgs.push_back(ncfg); + } + } + else{ + // 分割逗号 + while(cma_idx != string::npos){ + string arg = args.substr(lcma_dix,cma_idx-lcma_dix); + cpt_func_args ncfg; + ncfg = deal_arg(arg); + cfgs.push_back(ncfg); + lcma_dix = cma_idx+1; + cma_idx = args.find(",",lcma_dix); + if(cma_idx == string::npos && lcma_dix != string::npos){ + arg = args.substr(lcma_dix,args.size()-lcma_dix); + ncfg = deal_arg(arg); + cfgs.push_back(ncfg); + } + } + } + return cfgs; +} + +cpt_func_args Cpt::deal_arg(string arg){ + cpt_func_args ncfa; + std::stringstream ss,sr; + ss<>key; + // 读取数组标号 + string::size_type fq_l = key.find("["); + string::size_type fq_r = key.find("]"); + int size = 1; + string type; + if(fq_l != string::npos && fq_r != string::npos){ + string size_str = key.substr(fq_l+1,fq_r-fq_l-1); + sr<>size; + type = key.substr(0,fq_l); + + + } + else if (fq_r == string::npos && fq_r == string::npos){ + type = key.substr(0,fq_l); + } + else throw "syntax error"; + ncfa.size = size; + ncfa.type = type; + ss>>ncfa.key; + return ncfa; +} diff --git a/src/cproj_proj.cpp b/src/cproj_proj.cpp new file mode 100644 index 0000000..7debe09 --- /dev/null +++ b/src/cproj_proj.cpp @@ -0,0 +1,743 @@ +// +// cproj_proj.cpp +// Net +// +// Created by 胡一兵 on 2019/1/29. +// Copyright © 2019年 Bakantu. All rights reserved. +// + +#include "cproj.h" + +//处理描述文件的命令 +void Proj::deal_order(string tag, string arg){ + if(tag == "cpt"){ + cpt_paths.push_back(arg); + } + else if (tag == "map"){ + map_paths.push_back(arg); + } + else if(tag == "src_dir"){ + src_paths.push_back(arg); + } + else if(tag == "lib_dir"){ + this->lib_path = arg; + } + else throw "syntax error"; +} + +// 检查Cpt文件中描述的源文件是否存在对应实体 +void Proj::check_cpt(void){ + for(auto cpt:cpts){ +#ifdef DEBUG + printf("Checking Cpt File %p.\n",cpt); +#endif + for(auto file:cpt->src_files){ + auto src_file = src_files.find(file); +// 如果在索引中没有找到对应的源文件 + if(src_file == src_files.end()){ +#ifdef DEBUG + printf("[Error]Fail To Find Soruce File Related %s\n",file.data()); +#endif + throw "source file not exist"; + } + else{ +#ifdef DEBUG + printf("Succeed In Finding Source File %s\n",file.data()); +#endif + used_srcfiles.insert({src_file->first,src_file->second}); +// 计算源文件的MD5 + string md5; + string tsrc_path = src_paths[src_file->second]; + string t_path = proj_path+tsrc_path+"/"+file; + ComputeFile(t_path, md5); + src_md5.insert({file,md5}); +#ifdef DEBUG + printf("Computed Source File's MD5 %s\n[*]Source File Path %s\n",md5.data(),t_path.data()); +#endif + } + } + } +} + +// 读取所有涉及的Cpt文件 +void Proj::build_cpts(void){ + for(auto cptp : cpt_paths){ + Cpt *ncpt = new Cpt(proj_path + cptp, name); + cpts.push_back(ncpt); + } +} + +// 搜寻源文件搜索目录 +void Proj::search_src(int idx,string path){ + DIR *pdir = opendir(path.data()); + struct dirent *ptr; + if(pdir != NULL){ + while ((ptr = readdir(pdir)) != NULL) { +// 如果是文件 + if(ptr->d_type == 8){ + string file = ptr->d_name; +// 含有.cpp的文件 + if(file.find(".cpp") != string::npos){ + src_files.insert({file,idx}); + } + } + } + } + else throw "path is abnormal"; +} + +// 编译目标源文件生成动态链接库 +void Proj::build_src(string lib_name,string srcfile_path, string libs_path){ + string build_command = "g++ -fPIC -shared -std=c++11 -o "+libs_path+"/"+lib_name+" "+srcfile_path+" >gcc_build.log 2>&1"; +#ifdef DEBUG + printf("Build Command %s\n",build_command.data()); +#endif + int rtn = system(build_command.data()); +// 检测命令执行情况 + if(rtn != -1 && rtn != 127){ + struct stat statbuff; + stat("gcc_build.log", &statbuff); + unsigned long file_size = statbuff.st_size; +// 检测命令重定向输出文件的大小,判断编译是否出现了错误 + if(file_size == 0){ +#ifdef DEBUG + printf("Succeed In Compiling File %s\n",srcfile_path.data()); +#endif + } + else{ +#ifdef DEBUG + printf("[Error]Caught Errors or Warrnings In Compiling File %s\n",srcfile_path.data()); +#endif + throw "compile error"; + } + } + else throw "fail to build lib file"; +} + +// 创建数据库 +void Proj::build_new_db(void){ + string db_dir = proj_path+"dbs"; + if(mkdir(db_dir.data(), S_IRWXU | S_IRWXG | S_IRWXO) == -1){ + if(!~access(db_dir.data(), X_OK)){ +#ifdef DEBUG + printf("[Error]Caught Error In Creating Directory dbs\n"); +#endif + throw "fail to make dir dbs"; + } + } + db_path = proj_path+"dbs/"+name+".db"; + int sqlrtn = sqlite3_open(db_path.data(), &psql); + if(!sqlrtn){ +// 创建数据库表 +// 记录源文件信息 + sql::table_create(psql, "srcfiles", { +// ID + {"id","INT PRIMARY KEY NOT NULL"}, +// 文件名 + {"name","TEXT NOT NULL"}, +// 文件路径 + {"path","TEXT NOT NULL"}, +// 文件内容 + {"content","NONE"}, +// 文件MD5 + {"md5","TEXT NOT NULL"} + }); +// 记录入口函数信息 + sql::table_create(psql, "functions", { +// ID + {"id","INT PRIMARY KEY NOT NULL"}, +// 入口函数名 + {"name","TEXT NOT NULL"}, +// 入口函数所在的源文件在数据库中对应的ID + {"srcfile_id","INT NOT NULL"}, +// 入口函数所在的动态链接库在数据库中对应的ID + {"libfile_id","INT NOT NULL"} + }); +// 记录cpt文件信息 + sql::table_create(psql, "cptfiles", { +// ID + {"id","INT PRIMARY KEY NOT NULL"}, +// cpt文件完整路径 + {"path","TEXT NOT NULL"}, +// cpt文件内容 + {"content","NONE"}, +// cpt文件MD5 + {"md5","TEXT NOT NULL"} + }); +// 记录cpt文件信息 + sql::table_create(psql, "projfile", { +// 工程名 + {"project_name","TEXT NOT NULL"}, +// cpt文件内容 + {"content","NONE"}, +// cpt文件MD5 + {"md5","TEXT NOT NULL"} + }); + +// 记录动态链接库信息 + sql::table_create(psql, "libfiles", { +// ID + {"id","INT PRIMARY KEY NOT NULL"}, +// 动态链接库文件名 + {"name","TEXT NOT NULL"}, +// 动态链接库文件内容 + {"content","NONE"}, + }); + } + else{ +#ifdef DEBUG + printf("[Error] Fail To Create DB File %s\n",db_path.data()); +#endif + throw "fail to create db file"; + } + +} + +//写入项目涉及的源文件信息到数据库中 +void Proj::write_src_info(void){ + int idx = 0; + sqlite3_stmt *psqlsmt; +// 编译SQL语句 + sql::insert_info(psql, &psqlsmt, "srcfiles", { + {"id","?1"}, + {"name","?2"}, + {"path","?3"}, + {"md5","?4"} + }); +#ifdef DEBUG + printf("Writing Srcfiles Information Into Database.\n"); +#endif + for(auto src:used_srcfiles){ +// 获取源文件的MD5 + string md5 = src_md5.find(src.first)->second; +// 链接数据 + sqlite3_bind_int(psqlsmt, 1, idx++); + sqlite3_bind_text(psqlsmt, 2, src.first.data(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(psqlsmt, 3, src_paths[src.second].data(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(psqlsmt, 4, md5.data(), -1, SQLITE_TRANSIENT); +// 执行SQL语句 + int rtn = sqlite3_step(psqlsmt); + if(rtn == SQLITE_OK || rtn == SQLITE_DONE){ +#ifdef DEBUG + printf("[*]Succeed In Writing Srcfiles Information %s\n",src.first.data()); +#endif + } + else{ +#ifdef DEBUG + printf("[*]Failed to Write Srcfiles Information %s\n",src.first.data()); +#endif + } + sqlite3_reset(psqlsmt); + sqlite3_clear_bindings(psqlsmt); + } +} + +//写入动态链接库信息到数据库中 +void Proj::write_lib_info(void){ + int idx = 0; + sqlite3_stmt *psqlsmt; + sql::insert_info(psql, &psqlsmt, "libfiles", { + {"id","?1"}, + {"name","?2"} + }); +#ifdef DEBUG + printf("Writing Libfiles Information Into Database.\n"); +#endif + for(auto lib : lib_index){ +// 链接数据 + sqlite3_bind_int(psqlsmt, 1, idx++); + sqlite3_bind_text(psqlsmt, 2, lib.second.data(), -1, SQLITE_TRANSIENT); +// 执行SQL语句 + int rtn = sqlite3_step(psqlsmt); + if(rtn == SQLITE_OK || rtn == SQLITE_DONE){ +#ifdef DEBUG + printf("[*]Succeed In Writing Libfile Information %s\n",lib.second.data()); +#endif + } + else{ +#ifdef DEBUG + printf("[*]Failed to Write Libfile Information %s\n",lib.second.data()); +#endif + } + sqlite3_reset(psqlsmt); + sqlite3_clear_bindings(psqlsmt); + } +} + +// 写入入口函数信息到数据库中 +void Proj::write_func_info(void){ + int idx = 0; + sqlite3_stmt *psqlsmt; + sql::insert_info(psql, &psqlsmt, "functions", { + {"id","?1"}, + {"name","?2"}, + {"srcfile_id","?3"}, + {"libfile_id","?4"} + }); +#ifdef DEBUG + printf("Writing Functions Information Into Database.\n"); +#endif + for(auto func : func_index){ + string src_file = func.second->funcs_src.find(func.first)->second; + string lib_file = lib_index.find(src_file)->second; + string sql_quote = "SELECT id FROM srcfiles WHERE name = "+sql::string_type(src_file)+";"; +// 查找源文件信息在数据库中的ID + SQLCallBack *psqlcb = sql::sql_exec(psql, sql_quote); + if(psqlcb->size != 1){ +#ifdef DEBUG + printf("[Error]Database Data Is Abnormal.\n"); +#endif + throw "database abnormal"; + } + std::stringstream ss; + ss<items[0].argv[0]; + int srcfile_id = -1; + ss>>srcfile_id; + if(psqlcb->items[0].colnum[0] != "id" || srcfile_id == -1){ +#ifdef DEBUG + printf("[Error]Database Data Is Abnormal In Table srcfiles\n"); +#endif + throw "database abnormal"; + } + delete psqlcb; +// 查找动态链接库信息在数据库中的ID + sql_quote = "SELECT id FROM libfiles WHERE name = "+sql::string_type(lib_file)+";"; + psqlcb = sql::sql_exec(psql, sql_quote); + if(psqlcb->size != 1){ +#ifdef DEBUG + printf("[Error]Database Data Is Abnormal In Table libfiles\n"); +#endif + throw "database abnormal"; + } + std::stringstream ssl; + ssl<items[0].argv[0]; + int libfile_id = -1; + ssl>>libfile_id; + if(psqlcb->items[0].colnum[0] != "id" || libfile_id == -1){ +#ifdef DEBUG + printf("[Error]Database Data Is Abnormal In Table libfiles\n"); +#endif + throw "database abnormal"; + } + delete psqlcb; +// 链接数据 + sqlite3_bind_int(psqlsmt, 1, idx++); + sqlite3_bind_text(psqlsmt, 2, func.first.data(), -1, SQLITE_TRANSIENT); + sqlite3_bind_int(psqlsmt, 3, srcfile_id); + sqlite3_bind_int(psqlsmt, 4, libfile_id); + +// 执行SQL语句 + int rtn = sqlite3_step(psqlsmt); + if(rtn == SQLITE_OK || rtn == SQLITE_DONE){ +#ifdef DEBUG + printf("[*]Succeed In Writing Function Information %s\n",func.first.data()); +#endif + } + else{ +#ifdef DEBUG + printf("[*]Failed to Write Function Information %s\n",func.first.data()); +#endif + } + sqlite3_reset(psqlsmt); + sqlite3_clear_bindings(psqlsmt); + } +} + +//写入口函数入输入输出参数信息到数据库中 +void Proj::write_args_info(void){ +#ifdef DEBUG + printf("Start to Write Function Parameter Information Into Database.\n"); +#endif + for(auto func : func_index){ + vector *pfin = &func.second->fargs_in.find(func.first)->second; + vector *pfout = &func.second->fargs_out.find(func.first)->second; +// 创建对应的储存表 + sql::table_create(psql, func.first, { +// ID + {"id","INT PRIMARY KEY NOT NULL"}, +// 数据类型 + {"type","TEXT NOT NULL"}, +// 顺序序号 + {"idx","INT NOT NULL"}, +// 输入或输出标识(0输入,1输出) + {"io","INT NOT NULL"}, +// 标签名 + {"key","TEXT"}, +// 数据单元个数 + {"size","INT NOT NULL"} + }); + + sqlite3_stmt *psqlsmt; + +// 生成并编译SQL语句 + sql::insert_info(psql, &psqlsmt, func.first, { + {"id","?6"}, + {"type","?1"}, + {"idx","?2"}, + {"io","?3"}, + {"key","?4"}, + {"size","?5"} + }); + + int idx = 0, sidx = 0; +#ifdef DEBUG + printf("Writing Function Parameter (IN) Information Into Database (%s)\n",func.first.data()); +#endif +// 写入输入参数 + for(auto arg : *pfin){ +// 连接数据 + sqlite3_bind_text(psqlsmt, 1, arg.type.data(), -1, SQLITE_TRANSIENT); + sqlite3_bind_int(psqlsmt, 2, idx++); + sqlite3_bind_int(psqlsmt, 3, 0); + sqlite3_bind_text(psqlsmt,4, arg.key.data(), -1, SQLITE_TRANSIENT); + sqlite3_bind_int(psqlsmt, 5, arg.size); + sqlite3_bind_int(psqlsmt, 6, sidx++); +// 执行SQL语句 + int rtn = sqlite3_step(psqlsmt); + if(rtn == SQLITE_OK || rtn == SQLITE_DONE){ +#ifdef DEBUG + printf("[*]Succeed In Writing Function Parameter Information %s\n",func.first.data()); +#endif + } + else{ +#ifdef DEBUG + printf("[*]Failed to Write Function Parameter Information %s\n",func.first.data()); +#endif + } + sqlite3_reset(psqlsmt); + sqlite3_clear_bindings(psqlsmt); + } + +#ifdef DEBUG + printf("Writing Function Parameter (OUT) Information Into Database (%s)\n",func.first.data()); +#endif + idx = 0; +// 写入输入参数 + for(auto arg : *pfout){ +// 连接数据 + sqlite3_bind_text(psqlsmt, 1, arg.type.data(), -1, SQLITE_TRANSIENT); + sqlite3_bind_int(psqlsmt, 2, idx++); + sqlite3_bind_int(psqlsmt, 3, 1); + sqlite3_bind_text(psqlsmt,4, arg.key.data(), -1, SQLITE_TRANSIENT); + sqlite3_bind_int(psqlsmt, 5, arg.size); + sqlite3_bind_int(psqlsmt, 6, sidx++); + +// 执行SQL语句 + int rtn = sqlite3_step(psqlsmt); + if(rtn == SQLITE_OK || rtn == SQLITE_DONE){ +#ifdef DEBUG + printf("[*]Succeed In Writing Function Parameter Information %s\n",func.first.data()); +#endif + } + else{ +#ifdef DEBUG + printf("[*]Failed to Write Function Parameter Information %s\n",func.first.data()); +#endif + } + sqlite3_reset(psqlsmt); + sqlite3_clear_bindings(psqlsmt); + } + } +} + +void Proj::write_cpt_info(void){ + struct stat tstat; + sqlite3_stmt *psqlsmt; + sql::insert_info(psql, &psqlsmt, "cptfiles", { + {"id","?1"}, + {"path","?2"}, + {"md5","?3"}, + {"content","?4"} + }); + int idx = 0; + for(auto cpt : cpt_paths){ + string treal_path = proj_path+cpt; + if(!~stat(treal_path.data(), &tstat)){ +#ifdef DEBUG + printf("Error: Error In Getting Cpt File %s\n",treal_path.data()); +#endif + throw "cpt file not exist"; + }; + char *buff = (char *)malloc(tstat.st_size); + read_file(treal_path, buff); + sqlite3_bind_int(psqlsmt, 1, idx++); + string md5; + ComputeFile(treal_path.data(), md5); + sqlite3_bind_text(psqlsmt, 2, cpt.data(), -1, SQLITE_TRANSIENT); + sqlite3_bind_text(psqlsmt, 3, md5.data(), -1, SQLITE_TRANSIENT); + sqlite3_bind_blob(psqlsmt, 4, buff, (int)tstat.st_size, SQLITE_TRANSIENT); + free(buff); +// 执行SQL语句 + int rtn = sqlite3_step(psqlsmt); + if(rtn == SQLITE_OK || rtn == SQLITE_DONE){ +#ifdef DEBUG + printf("[*]Succeed In Writing Cpt File Information %s\n",treal_path.data()); +#endif + } + else{ +#ifdef DEBUG + printf("[*]Failed to Write Cpt File Information %s\n",treal_path.data()); +#endif + } + sqlite3_reset(psqlsmt); + sqlite3_clear_bindings(psqlsmt); + } +} +//写入工程描述文件信息到数据库中 +void Proj::write_proj_info(void){ + struct stat tstat; + sqlite3_stmt *psqlsmt; + sql::insert_info(psql, &psqlsmt, "projfile", { + {"project_name","?1"}, + {"content","?2"}, + {"md5","?3"} + }); + if(!~stat((proj_path+"netc.proj").data(), &tstat)){ +#ifdef DEBUG + printf("Error: Error In Getting Project File netc.proj\n"); +#endif + throw "project file not exist"; + }; + Byte *buff = (Byte *)malloc(tstat.st_size); + read_file(proj_path+"netc.proj", buff); + sqlite3_bind_text(psqlsmt, 1, name.data(), -1, SQLITE_TRANSIENT); + sqlite3_bind_blob(psqlsmt, 2, buff, (int)tstat.st_size, SQLITE_TRANSIENT); + string md5; + ComputeFile(proj_path+"netc.proj", md5); + sqlite3_bind_text(psqlsmt, 3, md5.data(), -1, SQLITE_TRANSIENT); + free(buff); +// 执行SQL语句 + int rtn = sqlite3_step(psqlsmt); + if(rtn == SQLITE_OK || rtn == SQLITE_DONE){ +#ifdef DEBUG + printf("[*]Succeed In Writing Project File Information netc.proj\n"); +#endif + } + else{ +#ifdef DEBUG + printf("[*]Failed to Write Project File Information netc.proj\n"); +#endif + } + sqlite3_reset(psqlsmt); + sqlite3_clear_bindings(psqlsmt); + +} + + +Proj::Proj(string t_projpath, string t_projfile){ +// 检查工程描述文件是否可读 + if(!~access(t_projpath.data(), R_OK)) throw "project directory state is abnormal"; + if(proj_path[proj_path.find_last_not_of(" ")] != '/') + t_projpath += "/"; + proj_path = t_projpath; + if(!~access((t_projpath+t_projfile).data(), R_OK)) throw "project file state is abnormal"; + + + proj_file = t_projfile; + ifsproj.open(proj_path+proj_file); + if(ifsproj.good()){ + string line; +// 寻找保留字 + if(!search_key(ifsproj,"proj")) throw "project struct not found"; +// 读取下一段信息 + ifsproj>>line; +// 大括号位置 + string::size_type qb_idx = line.find("{"); +// 寻找任务工程名 + string t_name; + if(qb_idx == string::npos) t_name = line; + else t_name = line.substr(0,qb_idx); +// 检查工程名是否含有非法字符 + for(auto c:t_name){ + if(if_illegal(c)); + else throw "project's name has illegal char"; + } + name = t_name; +// 寻找左大括号 + if(qb_idx == string::npos){ + ifsproj>>line; + if((qb_idx = line.find("{")) == string::npos) throw "syntax error"; + } +// 逐行分析语句 + string tag,cma,arg; + bool if_ctn = false; + do{ +// 读取命令标签 + ifsproj>>tag; +// 读取冒号 + ifsproj>>cma; +// 读取命令变量 + ifsproj>>arg; +// 检查参数是否含有非法字符 + for(auto c:t_name){ + if(if_illegal(c)); + else throw " arg has illegal char"; + } + if(cma != ":") throw "syntax error"; + if((if_ctn = if_continue(arg)) == true){ +// 消掉逗号 + arg = arg.substr(0,arg.size()-1); + } + if(if_string(arg)){ + deal_order(tag, cut_string(arg)); + } + else throw "syntax error"; + }while(if_ctn); + ifsproj>>line; + if(line != "};") throw "syntax error"; + } + else throw "fail to open project file"; + +} + +//检查目录以及描述文件是否存在 +void Proj::GeneralCheckInfo(void){ + + if(!~access((proj_path+lib_path).data(),W_OK)) throw "lib path is abnormal"; + check_paths(proj_path,src_paths); + check_paths(proj_path,map_paths); + check_paths(proj_path,cpt_paths); +} + +//搜寻源文件搜索目录并读取Cpt文件 +void Proj::SearchInfo(void){ + int idx = 0; + // 遍历源文件储存目录 + for(auto path : src_paths) search_src(idx++, proj_path+path); + // 读取cpt文件 + build_cpts(); + +} + +//检查Cpt文件内所描述的源文件是否有对应的实体 +void Proj::CheckCptInfo(void){ + check_cpt(); +} + +//建立计算模块入口函数索引 +void Proj::BuildFuncIndex(void){ +// 对应cpt文件 + for(auto pcpt : cpts){ +// 对应源文件 + for(auto func: pcpt->funcs_src){ +// 对应的计算模块入口函数 + func_index.insert({func.first,pcpt}); +#ifdef DEBUG + printf("Building Func Index %s (%p).\n",func.first.data(),pcpt); +#endif + } + } +} + +//编译涉及到的源文件 +void Proj::CompileUsedSrcFiles(void){ + for(auto src : used_srcfiles){ + string tsrc_path = src_paths[src.second]; + string tlib_name = "lib_"+src.first+".so"; + string t_path = proj_path+tsrc_path+"/"+src.first; + string tlib_path = proj_path+lib_path; +#ifdef DEBUG + printf("Compling Used Source File %s\n[*]Libname %s\n[*]Source File Path %s\n[*]Lib Path %s\n",src.first.data(),tlib_name.data(),t_path.data(),tlib_path.data()); +#endif + build_src(tlib_name,t_path,tlib_path); + lib_index.insert({src.first,tlib_name}); + } +} + +//检查入口函数是否在对应的动态链接库中可被按要求正确解析 +void Proj::CheckFuncInfo(void){ + for(auto func : func_index){ +// 找到入口函数所在的源文件 + string src_file = func.second->funcs_src.find(func.first)->second; +// 找到入口函数所在的动态链接库 + string tlib_name = lib_index.find(src_file)->second; + string tlib_path = proj_path+lib_path+"/"+tlib_name; +#ifdef DEBUG + printf("Checking Func %s\n[*]Lib File %s\n[*]Source File %s\n",func.first.data(),tlib_path.data(),src_file.data()); + +#endif +// 动态链接库操作柄 + void *lib_handle; +// 入口函数操作柄 + PCSFUNC func_handle; +// 传入传出参数列表操作柄 + vector *args_handle; +// 获得动态链接库的操作柄 + lib_handle = dlopen(tlib_path.data(), RTLD_NOW | RTLD_LOCAL); + if(lib_handle == nullptr){ +#ifdef DEBUG + printf("Fail To Get Lib File Handle\n"); + +#endif + throw "can not open library"; + } +#ifdef DEBUG + printf("Succeed In Getting Lib File Handle %p\n",lib_handle); + +#endif +// 获得该模块的入口 + func_handle = (PCSFUNC) dlsym(lib_handle, func.first.data()); + if(func_handle == nullptr){ +#ifdef DEBUG + printf("Fail To Get Func Handle\n"); + +#endif + throw "can not get func "+func.first; + } +#ifdef DEBUG + printf("Succeed In Getting Func Handle %p\n",func_handle); + +#endif +// 获得向该模块传入参数的操作柄 + args_handle = (vector *) dlsym(lib_handle, ("__"+func.first+"_args_in").data()); + if(args_handle == nullptr){ +#ifdef DEBUG + printf("Fail To Get Args (IN) Handle\n"); + +#endif + throw "can not get the HANDLE to PUSH args"; + } +#ifdef DEBUG + printf("Succeed In Getting Args (IN) Handle %p\n",args_handle); + +#endif +// 获得获取该模块传出参数的操作柄 + args_handle = (vector *) dlsym(lib_handle, ("__"+func.first+"_args_out").data()); + if(args_handle == nullptr){ +#ifdef DEBUG + printf("Fail To Get Args (OUT) Handle\n"); + +#endif + throw "can not get the HANDLE to GET args"; + } +#ifdef DEBUG + printf("Succeed In Getting Args (OUT) Handle %p\n",args_handle); + +#endif + dlclose(lib_handle); + } +} + +//建立数据库 +void Proj::DBProcess(void){ +// 建立新的数据库 + build_new_db(); +// 写入源文件信息 + write_src_info(); +// 写入动态链接库信息 + write_lib_info(); +// 写入入口函数信息 + write_func_info(); +// 写入参数信息 + write_args_info(); +// 写入cpt文件信息 + write_cpt_info(); +// 写入工程文件信息 + write_proj_info(); +} + + +//获得工程名 +string Proj::GetName(void){ + return name; +} diff --git a/src/main.cpp b/src/main.cpp index f15e2cc..9b7d8da 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,30 +10,132 @@ #include "memory.h" #include "clock.h" #include "net.h" +#include "cproj.h" #include "cpart.h" #include "cmap.h" #include "cthread.h" +int update(string instruct, vector &configs, vector &lconfigs, vector &targets); +int construct(string instruct,vector &config, vector &lconfig, vector &target); -int main(int argc, char *argv[]){ - try{ - Proj nproj("./PCS","pcs.proj"); - nproj.SearchInfo(); - nproj.BuildFuncIndex(); - nproj.CheckCptInfo(); - nproj.CompileUsedSrcFiles(); - nproj.CheckFuncInfo(); - nproj.DBProcess(); - //Cpt ncpt("./PCS/pcs.cpt","CPTest"); - +struct instructions{ + int (*unpack)(string instruct,vector &, vector &, vector &) = NULL; + int (*construct)(string instruct,vector &, vector &, vector &) = NULL; + int (*update)(string instruct,vector &, vector &, vector &) = NULL; +}; + +int main(int argc, const char *argv[]){ +// 命令 + string instruct; +// 设置 + vector config; +// 长设置 + vector long_config; +// 目标 + vector target; +// 设置函数 + struct instructions istns; + istns.construct = construct; + istns.update = update; + +// 解析命令 + int if_instruct = 1; + for(int i = 1; i < argc; i++){ + string sargv = argv[i]; + if(sargv[0] == '-'){ + config.push_back(sargv); + } + else if(sargv[0] == '-' && sargv[1] == '-'){ + long_config.push_back(sargv); + } + else{ + if(if_instruct){ + instruct = sargv; + if_instruct = 0; + } + else{ + target.push_back(sargv); + } + } } - catch(char const *error_info){ - printf("%s\n",error_info); +// 处理命令 + if(instruct == "construct"){ + if(istns.construct != nullptr) istns.construct(instruct,config,long_config,target); + else printf("Function not found.\n"); + } + else if (instruct == "update"){ + if(istns.update != nullptr) istns.update(instruct,config,long_config,target); + else printf("Function not found.\n"); + } + else{ + printf("Instruction \"%s\" doesn't make sense.\n",instruct.data()); } return 0; } +bool config_search(vector &configs,string tfg){ + for(auto config : configs){ + if(config == tfg) return true; + } + return false; +} + +int update(string instruct, vector &configs, vector &lconfigs, vector &targets){ + + return 0; +} + +int construct(string instruct, vector &configs, vector &lconfigs, vector &targets){ + try{ +// 读取工程文件 + Proj nproj(targets[0],"netc.proj"); +// 检查数据库文件是否存在 + string tdb_path = targets[0] + "/dbs/" + nproj.GetName() +".db"; +#ifdef DEBUG + printf("Search Database %s\n",tdb_path.data()); +#endif + if(!access(tdb_path.data(), R_OK)){ +// 设置为强制执行 + if(config_search(configs, "-f")){ + if(remove(tdb_path.data()) == -1){ + printf("\033[31m"); + printf("Error: Process meet unknown error.\n"); + printf("\033[0m"); + return -1; + } + } + else{ + printf("\033[33m"); + printf("Warning:Database has already existed. Use -f to continue process.\n"); + printf("\033[0m"); + return 0; + } + } +// 总体信息检查 + nproj.GeneralCheckInfo(); +// 收集信息 + nproj.SearchInfo(); +// 构建入口函数索引 + nproj.BuildFuncIndex(); +// 检查cpt文件信息 + nproj.CheckCptInfo(); +// 编译涉及源文件 + nproj.CompileUsedSrcFiles(); +// 检查入口函数信息 + nproj.CheckFuncInfo(); +// 建立数据库 + nproj.DBProcess(); + } + catch(char const *error_info){ + printf("\033[31mError:"); + printf("%s\033[0m\n",error_info); + return -1; + } + printf("\033[32mSucceed.\n\033[0m"); + return 0; +} + void wiki_cpart(void){ CPart ncp("./PCS","./Libs","a.cpp","A"); void *a = main_pool.bv_malloc(2.0); diff --git a/src/sql.cpp b/src/sql.cpp new file mode 100644 index 0000000..4ca706a --- /dev/null +++ b/src/sql.cpp @@ -0,0 +1,130 @@ +// +// sql.cpp +// Net +// +// Created by 胡一兵 on 2019/1/29. +// Copyright © 2019年 Bakantu. All rights reserved. +// + +#include "type.h" +#include "sql.h" + +namespace sql { + // 数据库回调函数 + int SQLCallBackFunc(void *data, int argc, char **argv, char **azColName){ + SQLCallBack *pscb = (SQLCallBack *)data; + if(pscb == NULL){ +#ifdef DEBUG + printf("Illegal Function Calling SQLCallBackFunc\n"); +#endif + throw "illegal calling"; + } + if(pscb != nullptr){ + pscb->size = argc; + for(int i = 0; i < argc; i++){ + SQLItem nsi; + nsi.colnum.push_back(azColName[i]); + nsi.argv.push_back(argv[i] ? argv[i] : "nil"); + pscb->items.push_back(nsi); + } + } + return 0; + } + + // SQL语句执行 + SQLCallBack *sql_exec(sqlite3 *psql, string sql){ + SQLCallBack *pscb = new SQLCallBack; + if(pscb == NULL){ +#ifdef DEBUG + printf("Error In Creating Struct SQLCallBack\n"); +#endif + } +#ifdef DEBUG + printf("[*]SQL Request %s\n[*]SQL %p\n",sql.data(),psql); +#endif + char *errmsg; + pscb->sql_rtn = sqlite3_exec(psql, sql.data(), SQLCallBackFunc, (void *)pscb, &errmsg); + if(errmsg != NULL) pscb->errmsg = errmsg; + return pscb; + } + + + /** + 创建数据库表 + + @param psql 数据库操作柄 + @param name 数据库表名 + @param colnums 数据库表描述 + @return 执行成功返回0 + */ + int table_create(sqlite3 *psql, string name, vector> colnums){ +#ifdef DEBUG + printf("Create SQL Table %s\n",name.data()); +#endif + // SQL语句 + string sql_quote = "CREATE TABLE "+name; + sql_quote += "("; + int idx = 0; + for(auto colnum : colnums){ + if(idx++) sql_quote += ","; + sql_quote += colnum.first + " " + colnum.second; + } + sql_quote += ");"; + // 执行SQL语句 + SQLCallBack *pscb = sql_exec(psql, sql_quote); + if(pscb->sql_rtn != SQLITE_OK){ +#ifdef DEBUG + printf("[Error]Fail To Create Table %s\n",name.data()); +#endif + throw "fail to create table"; + } +#ifdef DEBUG + printf("Succeed In Creating Table %s\n",name.data()); +#endif + delete pscb; + return 0; + } + + int insert_info(sqlite3 *psql, sqlite3_stmt **psqlsmt, string table_name,vector>items){ + + string sql_quote = "INSERT INTO "+table_name; + // 处理表项名 + sql_quote +="("; + int idx = 0; + for(auto item : items){ + if(idx++) sql_quote +=","; + sql_quote+= item.first; + } + sql_quote +=") VALUES("; + // 处理数据 + idx = 0; + for(auto item : items){ + if(idx++) sql_quote +=","; + sql_quote+= item.second; + } + sql_quote += ");"; +#ifdef DEBUG + printf("SQL Insert Statment %s\n",sql_quote.data()); +#endif + const char *pzTail; + int rtn; + rtn = sqlite3_prepare(psql, sql_quote.data(), -1, psqlsmt, &pzTail); + if(rtn == SQLITE_OK){ +#ifdef DEBUG + printf("[*]Succeed In Compiling SQL Statment\n"); +#endif + return 0; + } + else{ +#ifdef DEBUG + printf("[*]Fail to Compile SQL Statment\n"); +#endif + return -1; + } + + } + string string_type(string str){ + return "\'"+str+"\'"; + } + +}