调整与添加

调整了配置文件的读取方式,为数据库的加入铺平道路。
This commit is contained in:
Saturneic 2019-01-31 22:09:41 +08:00
parent dbaa0fc064
commit 1265216866
4 changed files with 422 additions and 177 deletions

View File

@ -24,6 +24,27 @@ struct check_table_column{
int pk;
};
struct setting_file_register{
vector<string> block_keys;
};
struct stn_register{
vector<string> stn_keys;
};
struct setting_file_read{
string key;
string name;
string sentence;
bool if_blk;
vector<setting_file_read *> 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<setting_file_read *> *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<cpt_func_args> deal_args(string args);
// 处理参数
cpt_func_args deal_arg(string arg);
// 配置文件文件解析结构
vector<setting_file_read *> 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<string> src_paths;
// 源文件搜索目录下的所有源文件
@ -149,6 +302,8 @@ class Proj:public setting_file{
sqlite3 *psql;
// 数据库文件路径
string db_path;
// 配置文件文件解析结构
vector<setting_file_read *> 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<check_table_column> 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 */

View File

@ -47,6 +47,7 @@ using std::list;
using std::ifstream;
using std::cout;
using std::endl;
using std::stringstream;
typedef char Byte;

View File

@ -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<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";
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<cpt_func_args> 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<cpt_func_args> 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_func_args> 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_func_args> Cpt::deal_args(string args){
cpt_func_args Cpt::deal_arg(string arg){
cpt_func_args ncfa;
std::stringstream ss,sr;
ss<<arg;
string key;
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_str;
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;
}

View File

@ -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();
}