diff --git a/include/cproj.h b/include/cproj.h index a7eaee8..22f2081 100644 --- a/include/cproj.h +++ b/include/cproj.h @@ -24,6 +24,27 @@ struct check_table_column{ int pk; }; +struct setting_file_register{ + vector block_keys; +}; + +struct stn_register{ + vector stn_keys; +}; + +struct setting_file_read{ + string key; + string name; + string sentence; + bool if_blk; + vector childs; +}; + +struct stn_read{ + string key; + string value; +}; + //配置文件通用方法类 class setting_file{ protected: @@ -38,6 +59,13 @@ protected: if(isalnum(c) || c == '_') return true; else return false; } +// 检查名字是否合法 + bool if_name_illegal(string str){ + for(auto c:str){ + if(!if_illegal(c)) return false; + } + return true; + } // 寻找保留字 bool search_key(ifstream &ifsfile,string key){ string line; @@ -63,18 +91,133 @@ protected: return arg.substr(1,arg.size()-2); } - int read_file(string path, Byte *buff){ + int read_file(string path, Byte *buff, uint64_t size){ 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; + uint64_t idx_count = 0; + while (!ifsf.eof() && idx_count < size) { + if(size < 512){ + memset(tmp, 0, size); + ifsf.read(tmp, size); + memcpy(idx, tmp, size); + idx_count += size; + } + else if (size > 512){ + if(size - idx_count >= 512){ + memset(tmp, 0, 512); + ifsf.read(tmp, 512); + memcpy(idx, tmp, 512); + idx_count += 512; + idx += 512; + } + else{ + memset(tmp, 0, size-idx_count); + ifsf.read(tmp, size-idx_count); + memcpy(idx, tmp, size-idx_count); + idx_count += size-idx_count; + idx += size-idx_count; + } + } } ifsf.close(); return 0; } + +// 消去配置文件中的所有的空字符 + void read_settings(string path, string &tstr){ + struct stat tstat; + stat(path.data(), &tstat); + Byte *fbs = (Byte *)malloc(tstat.st_size); + read_file(path, fbs,tstat.st_size); + for(off_t i = 0; i < tstat.st_size; i++){ + if(isgraph(fbs[i])) tstr += fbs[i]; + } + free(fbs); + } +// 读取关键字及代码块 + void read_blocks(string str, setting_file_register &tsfr, vector *blocks){ + string tstr = str; + string::size_type curs_idx = 0; + while (tstr.size()) { +// 寻找语句或代码块 + string::size_type sem_idx = tstr.find(";",curs_idx); +// 如果没找到分号则读完 + if(sem_idx == string::npos) break; + string tmpstr = tstr.substr(curs_idx,sem_idx-curs_idx); + string::size_type blq_idx = tmpstr.find("{",curs_idx),brq_idx = string::npos; + bool if_blk = true; + string pcsstr; +// 如果是语句 + if(blq_idx == string::npos){ + brq_idx = tstr.find(";",curs_idx); + pcsstr = tstr.substr(curs_idx,brq_idx); + if_blk = false; + } + else{ + int blk_stack = 1; + for(auto c : tstr){ + pcsstr.push_back(c); + if(c == '{') blk_stack++; + else if(c == '}'){ + blk_stack--; + if(blk_stack == 1) break; + } + } + brq_idx = pcsstr.rfind('}') + 1; + } + + setting_file_read *ptsfbr = new setting_file_read(); +// 记录是语句还是信息块 + ptsfbr->if_blk = if_blk; +// 如果是信息块 + if(if_blk){ + string head = pcsstr.substr(0,blq_idx); + string keystr, namestr; + string::size_type key_idx; + +// 检查关键字 + for(auto key:tsfr.block_keys){ + if((key_idx = head.find(key)) != string::npos){ + keystr = pcsstr.substr(0,key.size()); + namestr = pcsstr.substr(key.size(),blq_idx-key.size()); + if(!if_name_illegal(namestr)){ + throw "block name is illegal"; + } + ptsfbr->key = keystr; + ptsfbr->name = namestr; + break; + } + } + if(ptsfbr->key.empty()) throw "unknown block key"; + blocks->push_back(ptsfbr); + string inblkstr = pcsstr.substr(blq_idx+1,brq_idx-blq_idx-2); + read_blocks(inblkstr, tsfr, &blocks->back()->childs); + } + else{ +// 记录语句 + ptsfbr->sentence = pcsstr; + blocks->push_back(ptsfbr); + } + + curs_idx = brq_idx+1; + tstr = tstr.substr(curs_idx,tstr.size()-curs_idx); + curs_idx = 0; + } + } + int read_stn(string stn_str, stn_register &tsr,stn_read *stn){ + string::size_type key_idx = string::npos; + stn->key.clear(); + stn->value.clear(); + for(auto key:tsr.stn_keys){ + if((key_idx = stn_str.find(key)) != string::npos){ + stn->key = key; + stn->value = stn_str.substr(key.size(),stn_str.size()-key.size()); + break; + } + } + if(stn->key.empty()) return -1; + return 0; + } }; @@ -102,9 +245,17 @@ class Cpt:public setting_file{ vector deal_args(string args); // 处理参数 cpt_func_args deal_arg(string arg); +// 配置文件文件解析结构 + vector blocks; +// 文件数据 + string content; +// 处理文件数据 + void deal_content(string data_content); public: // 构造函数 Cpt(string path, string proj_name); +// 数据库数据直接构造函数 + Cpt(string data_content, int if_db, string proj_name); }; //map文件管理类 @@ -123,6 +274,8 @@ class Proj:public setting_file{ string name; // 计算工程读入流 ifstream ifsproj; +// 工程文件内容 + string content; // 源文件所在的目录 vector src_paths; // 源文件搜索目录下的所有源文件 @@ -149,6 +302,8 @@ class Proj:public setting_file{ sqlite3 *psql; // 数据库文件路径 string db_path; +// 配置文件文件解析结构 + vector blocks; // 处理描述文件的命令 void deal_order(string tag, string arg); @@ -182,9 +337,13 @@ class Proj:public setting_file{ void check_database(void); // 检查数据库表 void check_table(int cnum, vector tctc,sqlite3_stmt *psqlsmt); +// 解析数据 + void deal_content(string data_content); public: // 读取Proj文件 Proj(string t_projpath, string t_projfile); +// 接受数据库数据 + Proj(string data_content); // 检查目录以及描述文件是否存在 void GeneralCheckInfo(void); // 搜寻源文件搜索目录并读取Cpt文件 @@ -203,6 +362,8 @@ public: string GetName(void); // 更新工程 void UpdateProcess(void); +// 获得数据库 + void AttachDatabases(void); }; #endif /* cproj_h */ diff --git a/include/type.h b/include/type.h index 3389f47..2395fda 100644 --- a/include/type.h +++ b/include/type.h @@ -47,6 +47,7 @@ using std::list; using std::ifstream; using std::cout; using std::endl; +using std::stringstream; typedef char Byte; diff --git a/src/cproj_cpt.cpp b/src/cproj_cpt.cpp index 2da09dd..87f9907 100644 --- a/src/cproj_cpt.cpp +++ b/src/cproj_cpt.cpp @@ -12,110 +12,89 @@ 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"; + string tifscpt; + read_settings(path, tifscpt); + name = proj_name; + deal_content(tifscpt); } +Cpt::Cpt(string data_content, int if_db, string proj_name){ +#ifdef DEBUG + printf("Receive Data To Build Class Cpt\n [*]%s\n",data_content.data()); +#endif + name = proj_name; + deal_content(data_content); +} + +void Cpt::deal_content(string data_content){ + setting_file_register tsfr = { + { + "cparts", + "srcfile", + } + }; + // 解析数据 + read_blocks(data_content, tsfr, &blocks); + content = data_content; + bool if_pblk = false; + int idx = 0; + // 寻找工程对应的块 + for(auto block :blocks){ + if(block->name == name){ + if_pblk = true; + break; + } + idx++; + } + if(!if_pblk) throw "proper blocks not found"; + if(blocks[idx]->if_blk){ + for(auto src : blocks[idx]->childs){ + if(src->key == "srcfile"){ + // 记录源文件名 + string tsrc_name = src->name+".cpp"; + src_files.push_back(tsrc_name); + for(auto func : src->childs){ + if(!func->if_blk){ + // 分离输出参数列表 + string::size_type dq_l = func->sentence.find("("); + string::size_type dq_r = func->sentence.find(")"); + if(dq_l == string::npos || dq_r == string::npos) throw "syntax error"; + string str_argout = func->sentence.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 = func->sentence.find("(",dq_r+1); + string::size_type yq_r = func->sentence.find(")",yq_l); + if(yq_l == string::npos || yq_r == string::npos) throw "syntax error"; + string str_argin = func->sentence.substr(yq_l+1,yq_r-yq_l-1); +#ifdef DEBUG + printf("Read Args (IN) Description %s\n",str_argin.data()); +#endif + vector cfgi = deal_args(str_argin); + + // 分离入口函数名 + string func_name = func->sentence.substr(dq_r+1,yq_l-dq_r-1); + if(!if_name_illegal(func_name)) throw "function name is illegal"; + +#ifdef DEBUG + printf("Read Function Name %s\n",func_name.data()); +#endif + // 记录入口函数名 + funcs_src.insert({func_name,tsrc_name}); + // 添加相关参数 + fargs_out.insert({func_name,cfgo}); + fargs_in.insert({func_name,cfgi}); + + } + } + } + } + } +} + + vector Cpt::deal_args(string args){ string::size_type lcma_dix = 0; string::size_type cma_idx = args.find(",",0); @@ -156,28 +135,34 @@ vector Cpt::deal_args(string args){ cpt_func_args Cpt::deal_arg(string arg){ cpt_func_args ncfa; std::stringstream ss,sr; - ss<>key; + stn_register tsr = { + { + "int", + "double" + } + }; // 读取数组标号 - string::size_type fq_l = key.find("["); - string::size_type fq_r = key.find("]"); + string::size_type fq_l = arg.find("["); + string::size_type fq_r = arg.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); + string size_str = arg.substr(fq_l+1,fq_r-fq_l-1); sr<>size; - type = key.substr(0,fq_l); - - + type = arg.substr(0,fq_l); + ncfa.size = size; + ncfa.type = type; + string key = arg.substr(fq_r+1,arg.size()-fq_r-1); + ncfa.key = key; } else if (fq_r == string::npos && fq_r == string::npos){ - type = key.substr(0,fq_l); + stn_read nstnr; + read_stn(arg, tsr, &nstnr); + ncfa.type = nstnr.key; + ncfa.key = nstnr.value; } 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 index 12375f6..3491265 100644 --- a/src/cproj_proj.cpp +++ b/src/cproj_proj.cpp @@ -463,7 +463,7 @@ void Proj::write_cpt_info(void){ throw "cpt file not exist"; }; char *buff = (char *)malloc(tstat.st_size); - read_file(treal_path, buff); + read_file(treal_path, buff, tstat.st_size); sqlite3_bind_int(psqlsmt, 1, idx++); string md5; ComputeFile(treal_path.data(), md5); @@ -504,7 +504,7 @@ void Proj::write_proj_info(void){ throw "project file not exist"; }; Byte *buff = (Byte *)malloc(tstat.st_size); - read_file(proj_path+"netc.proj", buff); + read_file(proj_path+"netc.proj", buff,tstat.st_size); sqlite3_bind_text(psqlsmt, 1, name.data(), -1, SQLITE_TRANSIENT); sqlite3_bind_blob(psqlsmt, 2, buff, (int)tstat.st_size, SQLITE_TRANSIENT); string md5; @@ -700,60 +700,123 @@ Proj::Proj(string t_projpath, string t_projfile){ 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"; + + string tifsproj; + read_settings(proj_path+proj_file, tifsproj); +// 处理文件数据 + deal_content(tifsproj); +} +Proj::Proj(string data_content){ + deal_content(data_content); +} + +//处理文件数据 +void Proj::deal_content(string data_content){ + setting_file_register tsfr = { + { + "proj", + "cpt", + "map", + "src_dir", + "lib_dir" + } + }; + stn_register tsr = stn_register{ + { + "path", + "name", + } + }; + // 解析配置文件 + read_blocks(data_content, tsfr, &blocks); + content = data_content; + stn_read tsread; + // 获得解析后的信息 + if (blocks[0]->key == "proj" && blocks[0]->if_blk) { + name = blocks[0]->name; + if(name.empty()) throw "a project must have a name"; + for(auto block : blocks[0]->childs){ + // 读取cpt描述 + if(block->key == "cpt"){ + string ncptp,tpath,tname; + for(auto stn : block->childs){ + if(!stn->if_blk){ + if(!~read_stn(stn->sentence, tsr, &tsread)) + throw "sentence illegal"; + + if(tsread.key == "path"){ + if(tpath.empty()){ + tpath = tsread.value; + } + else throw "only can a 'cpt' block have one 'path' tag"; + } + else if (tsread.key == "name"){ + tname = tsread.value + ".cpt"; + ncptp = tpath+"/"+tname; + cpt_paths.push_back(ncptp); + } + } + } + + } + else if (block->key == "map"){ + string nmapp,tpath,tname; + for(auto stn : block->childs){ + if(!stn->if_blk){ + if(!~read_stn(stn->sentence, tsr, &tsread)) + throw "sentence illegal"; + + if(tsread.key == "path"){ + if(tpath.empty()){ + tpath = tsread.value; + } + else throw "only can a 'map' block have one 'path' tag"; + } + else if (tsread.key == "name"){ + tname = tsread.value + ".map"; + nmapp = tpath + "/" + tname; + map_paths.push_back(nmapp); + } + } + } + + } + else if (block->key == "src_dir"){ + string tpath; + for(auto stn : block->childs){ + if(!stn->if_blk){ + if(!~read_stn(stn->sentence, tsr, &tsread)) + throw "sentence illegal"; + if(tsread.key == "path"){ + tpath = tsread.value; + src_paths.push_back(tpath); + } + } + } + } + else if (block->key == "lib_dir"){ + if(!lib_path.empty()) throw "only can a 'proj' block have one 'lib_dir' block"; + string tpath; + for(auto stn : block->childs){ + if(!stn->if_blk){ + if(!~read_stn(stn->sentence, tsr, &tsread)) + throw "sentence illegal"; + if(tsread.key == "path"){ + if(tpath.empty()){ + tpath = tsread.value; + lib_path = tpath; + } + else{ + throw "only can a 'lib_dir' block have one 'path' tag"; + } + } + } + } + } + } + } + else throw "project file illegal"; } //检查目录以及描述文件是否存在 @@ -908,8 +971,42 @@ string Proj::GetName(void){ return name; } + //更新工程 void Proj::UpdateProcess(void){ + AttachDatabases(); +// 检查工程描述文件的MD5 + string md5; + ComputeFile(proj_path+"netc.proj", md5); + sqlite3_stmt *psqlsmt; + const char *pzTail; + sqlite3_prepare(psql, "SELECT md5 FROM projfile;", -1, &psqlsmt, &pzTail); + sqlite3_step(psqlsmt); + string tmd5 = (char *) sqlite3_column_text(psqlsmt, 0); + sqlite3_finalize(psqlsmt); + if(tmd5 != md5){ +#ifdef DEBUG + printf("Curent Project File's MD5 Is Not Matched.\n"); +#endif +// 获取原工程描述文件的内容 + sqlite3_blob *psqlblb; + sqlite3_blob_open(psql, NULL, "projfile", "content", 1, 0, &psqlblb); + int size = sqlite3_blob_bytes(psqlblb); + char tempfile[] = "tempblob-XXXXXX"; + int fd = mkstemp(tempfile); + sqlite3_blob_close(psqlblb); + } + else{ +#ifdef DEBUG + printf("Curent Project File's MD5 Is Matched.\n"); +#endif + } + +} + +//获得数据库 +void Proj::AttachDatabases(void){ +// 合成数据库路径 db_path = proj_path +"dbs/"+ name+".db"; if(access(db_path.data(), F_OK) == -1){ #ifdef DEBUG @@ -918,6 +1015,7 @@ void Proj::UpdateProcess(void){ throw "database not exist"; } sqlite3_open(db_path.data(), &psql); -// 检查数据库的完成性 +// 检查数据库的完整性 check_database(); } +