Added and Struct modified.

This commit is contained in:
Saturneic 2019-01-29 23:06:31 +08:00
parent fd59440b48
commit fc386d83de
13 changed files with 1438 additions and 1084 deletions

View File

@ -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 = "<group>"; };
9277A14521FD7246009C5F11 /* cproj.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = cproj.hpp; path = include/cproj.hpp; sourceTree = "<group>"; };
9277A14621FD7246009C5F11 /* cmap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cmap.h; path = include/cmap.h; sourceTree = "<group>"; };
9277A14721FD7246009C5F11 /* server.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = server.h; path = include/server.h; sourceTree = "<group>"; };
9277A14821FD7246009C5F11 /* net.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = net.h; path = include/net.h; sourceTree = "<group>"; };
@ -47,7 +48,7 @@
9277A15221FD725F009C5F11 /* addr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = addr.cpp; path = src/addr.cpp; sourceTree = "<group>"; };
9277A15321FD725F009C5F11 /* socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = socket.cpp; path = src/socket.cpp; sourceTree = "<group>"; };
9277A15421FD725F009C5F11 /* md5.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = md5.cpp; path = src/md5.cpp; sourceTree = "<group>"; };
9277A15521FD725F009C5F11 /* cproj.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cproj.cpp; path = src/cproj.cpp; sourceTree = "<group>"; };
9277A15521FD725F009C5F11 /* cproj_cpt.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cproj_cpt.cpp; path = src/cproj_cpt.cpp; sourceTree = "<group>"; };
9277A15621FD725F009C5F11 /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = src/main.cpp; sourceTree = "<group>"; };
9277A15721FD725F009C5F11 /* cthread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = cthread.cpp; path = src/cthread.cpp; sourceTree = "<group>"; };
9277A15821FD725F009C5F11 /* server.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = server.cpp; path = src/server.cpp; sourceTree = "<group>"; };
@ -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 = "<group>"; };
9277A16C21FE0357009C5F11 /* da.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = da.cpp; path = build/Debug/PCS/srcs/da.cpp; sourceTree = "<group>"; };
9277A18821FEB21D009C5F11 /* libsqlite3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libsqlite3.dylib; path = build/Debug/Libraries/libsqlite3.dylib; sourceTree = "<group>"; };
9277A18A220076EE009C5F11 /* sql.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = sql.cpp; path = src/sql.cpp; sourceTree = "<group>"; };
9277A18D22007758009C5F11 /* sql.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = sql.h; path = include/sql.h; sourceTree = "<group>"; };
9277A18E220077CC009C5F11 /* cproj.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = cproj.h; path = include/cproj.h; sourceTree = "<group>"; };
9277A18F220079DB009C5F11 /* cproj_proj.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = cproj_proj.cpp; path = src/cproj_proj.cpp; sourceTree = "<group>"; };
/* 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 = "<group>";
@ -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 */,

View File

@ -10,5 +10,13 @@
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>9221D9EA21EA5142007310A7</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

View File

@ -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<string> 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<string> src_files;
// 入口函数对应的源文件
map<string,string> funcs_src;
// 入口函数的输入与输出参数格式
map<string,vector<cpt_func_args>> 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<cpt_func_args> 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<cpt_func_args> 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_func_args> deal_args(string args){
string::size_type lcma_dix = 0;
string::size_type cma_idx = args.find(",",0);
vector<cpt_func_args> 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<<arg;
string key;
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_str;
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<pair<string, string>> colnums;
};
struct SQLItem{
vector<string> colnum;
vector<string> argv;
};
struct SQLCallBack{
unsigned long size;
vector<SQLItem> 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<pair<string, string>> colnums);
int insert_info(sqlite3 *psql, sqlite3_stmt **psqlsmt, string table_name, vector<pair<string, string>>value);
string string_type(string str);
}
class Proj:public setting_file{
// 计算工程所在的目录
string proj_path;
// 计算工程描述文件名
string proj_file;
// 工程名
string name;
// 计算工程读入流
ifstream ifsproj;
// 源文件所在的目录
vector<string> src_paths;
// 源文件搜索目录下的所有源文件
map<string,int> src_files;
// 计算工程所涉及到的源文件
map<string,int> used_srcfiles;
// 计算工程所涉及到的源文件的MD5
map<string,string> src_md5;
// 关系描述文件所在的目录
vector<string> map_paths;
// 模块描述文件所在目录
vector<string> cpt_paths;
// 模块描述对象
vector<Cpt *> cpts;
// 关系描述对象
vector<Map> maps;
// 动态链接库存放的目录
string lib_path;
// 模块入口函数索引
map<string, Cpt *> func_index;
// 动态链接库对应的源文件索引
map<string, string> 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<<psqlcb->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<<psqlcb->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<cpt_func_args> *pfin = &func.second->fargs_in.find(func.first)->second;
vector<cpt_func_args> *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<block_info> *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<block_info> *) 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<block_info> *) 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:

197
include/cproj.h Normal file
View File

@ -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<string> 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<string> src_files;
// 入口函数对应的源文件(入口函数名,源文件名)
map<string,string> funcs_src;
// 入口函数的输入与输出参数格式(入口函数名,参数列表)
map<string,vector<cpt_func_args>> fargs_in,fargs_out;
// Cpt文件路径
string path;
ifstream ifscpt;
// 工程名
string name;
// 处理参数列表
vector<cpt_func_args> 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<string> src_paths;
// 源文件搜索目录下的所有源文件
map<string,int> src_files;
// 计算工程所涉及到的源文件
map<string,int> used_srcfiles;
// 计算工程所涉及到的源文件的MD5
map<string,string> src_md5;
// 关系描述文件所在的目录
vector<string> map_paths;
// 模块描述文件所在目录
vector<string> cpt_paths;
// 模块描述对象
vector<Cpt *> cpts;
// 关系描述对象
vector<Map> maps;
// 动态链接库存放的目录
string lib_path;
// 模块入口函数索引
map<string, Cpt *> func_index;
// 动态链接库对应的源文件索引
map<string, string> 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 */

View File

@ -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 */

42
include/sql.h Normal file
View File

@ -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<pair<string, string>> colnums;
};
//回调项目封装结构
struct SQLItem{
vector<string> colnum;
vector<string> argv;
};
//回调结果封装结构
struct SQLCallBack{
unsigned long size;
vector<SQLItem> 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<pair<string, string>> colnums);
// 编译插入命令
int insert_info(sqlite3 *psql, sqlite3_stmt **psqlsmt, string table_name, vector<pair<string, string>>value);
// 生成字符串格式的数据
string string_type(string str);
}
#endif /* sql_h */

View File

@ -48,4 +48,6 @@ using std::ifstream;
using std::cout;
using std::endl;
typedef char Byte;
#endif /* type_h */

View File

@ -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<pair<string, string>> 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<pair<string, string>>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+"\'";
}
}

View File

@ -1,9 +0,0 @@
//
// CProj.cpp
// Net
//
// Created by 胡一兵 on 2019/1/22.
// Copyright © 2019年 Bakantu. All rights reserved.
//
#include "cproj.hpp"

183
src/cproj_cpt.cpp Normal file
View File

@ -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<cpt_func_args> 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<cpt_func_args> 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_func_args> Cpt::deal_args(string args){
string::size_type lcma_dix = 0;
string::size_type cma_idx = args.find(",",0);
vector<cpt_func_args> 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<<arg;
string key;
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_str;
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;
}

743
src/cproj_proj.cpp Normal file
View File

@ -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<<psqlcb->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<<psqlcb->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<cpt_func_args> *pfin = &func.second->fargs_in.find(func.first)->second;
vector<cpt_func_args> *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<block_info> *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<block_info> *) 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<block_info> *) 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;
}

View File

@ -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<string> &configs, vector<string> &lconfigs, vector<string> &targets);
int construct(string instruct,vector<string> &config, vector<string> &lconfig, vector<string> &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<string> &, vector<string> &, vector<string> &) = NULL;
int (*construct)(string instruct,vector<string> &, vector<string> &, vector<string> &) = NULL;
int (*update)(string instruct,vector<string> &, vector<string> &, vector<string> &) = NULL;
};
int main(int argc, const char *argv[]){
// 命令
string instruct;
// 设置
vector<string> config;
// 长设置
vector<string> long_config;
// 目标
vector<string> 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<string> &configs,string tfg){
for(auto config : configs){
if(config == tfg) return true;
}
return false;
}
int update(string instruct, vector<string> &configs, vector<string> &lconfigs, vector<string> &targets){
return 0;
}
int construct(string instruct, vector<string> &configs, vector<string> &lconfigs, vector<string> &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<double>(2.0);

130
src/sql.cpp Normal file
View File

@ -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<pair<string, string>> 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<pair<string, string>>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+"\'";
}
}