diff --git a/README.md b/README.md index a2b7974..1fa724b 100644 --- a/README.md +++ b/README.md @@ -1,59 +1,3 @@ -# Tiny +# TINY SOFTWARE SUITE -A tiny command line interpreter for organizing, you can split huge single line commands into lines and even add comments and variables! - -## Features - -Multi-command: You can make multiple commands in same `.tmk` file by having a line that starts with `\n` - -Comments: You can use comments in the file to your peers or future you remember what you done, also useful to separate sections of a command - -Variables: If a line starts with `%` it will get all the name of it until hit the second `%` and to set variables the line has to start with `set` - -Ignore space: Add `\` at the start of the line so it will not add an space before it. - -(all written in this line after the `\n` and `%var%` will be ignored and be seen as comments) - -## example - -``` -;set variables -set flags=-Os -;compiler -g++ -%flags% - -;files -main.cpp - -;includes --lstdc++ - --I/usr/ -;to not add space between /usr/ and include, you add \ so it will be "/usr/include" and not "/usr/ include" -\include - -;output --o tiny.exe - -;end command -\n -;run tiny -tiny.exe -``` - -# WARNING, THIS PROGRAM HAS STRICT SYNTAX -## The line MUST to have `;`,`set` and `%` as first character to be detected as comment, setter and variable, so you can have it in the command (without being interpreted by Tiny) by adding a space before. - - -# Roadmap - -- Add variables when loading a Tiny script - -- Create functions - -- Stuff people ask for - -# Compatibility - -This is supposed to run anywhere, if it dont work in a platform please warn me (maybe exotic systems with uncommon headers like master system or whatever might not work out of the box... idk.. if it even has a CLI lol) +[visit the wiki](https://github.com/kin-fuyuki/tiny/wiki) \ No newline at end of file diff --git a/inc/tdf.h b/inc/tdf.h new file mode 100644 index 0000000..31f1fbe --- /dev/null +++ b/inc/tdf.h @@ -0,0 +1,744 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef TINYDATAFORMAT_H +#define TINYDATAFORMAT_H +#define TINYDEFINEHEADER "0000_TDF_HEADER_DEFINE" +#include "term.h" +namespace tiny { +enum TDF_ERROR{ + SET_MISMATCH=1, + GET_MISMATCH=2, + PATH_NOT_FOUND=3, + UNKNOWN_ERROR=-1, + FILE_NOT_FOUND=4, + FAILED_TO_PARSE=5, + NULL_POINTER=6, +}; +class TDF_ERR : public std::exception + { + public: + std::string message; + + explicit TDF_ERR(TDF_ERROR err,std::string file,std::vectorpath) _GLIBCXX_TXN_SAFE{ + message="TDF ERROR: "; + + switch(err){ + case SET_MISMATCH: + message+="SET TYPE MISMATCH "; + break; + case GET_MISMATCH: + message+="GET TYPE MISMATCH "; + break; + case PATH_NOT_FOUND: + message+="PATH NOT FOUND "; + break; + case FILE_NOT_FOUND: + message+="FILE NOT FOUND "+file; + return; + case FAILED_TO_PARSE: + message+="FAILED TO PARSE "+file+" AT LINE :"+path[0]; + return; + case NULL_POINTER: + message+="NULL POINTER of selector "+path[0]; + message+="FAILED TO PARSE "+file+" AT LINE :"+path[1]; + return; + default: + message+="UNKNOWN ERROR "; + break; + } + + message+=" ON FILE: "+file+" AT PATH: "; + for(size_t i=0;i + TDF_CLASS = 9, //class +}; +struct TDF_DATA { + TDF_Type type; + void* datapointer; +}; +struct TDF_FUNCS{ + boost::unordered_mapfuncs; + TDF_DATA(*FUNCS[])(std::string); +}; +struct TDF_FILE{ + boost::unordered_map* data=nullptr; + char*filepath; + TDF_FUNCS FUNCS; + std::vector todelete; + void close(){ + for(size_t i=0;i(); + todelete.push_back(data); + boost::unordered_map*current=data; + + std::vector*>stack={}; + std::vectorpathvec={}; + bool textblock=false; + std::string BLOCK; + std::string BLOCKKEY; + std::vector *defines=new std::vector(); + TDF_DATA defdat={TDF_DEFINES,defines}; + (*current)[TINYDEFINEHEADER]=defdat; + + std::string line; + while (std::getline(file, line)) { + ++INDEX; + if (line.length()==0){continue;} + if (textblock){ + std::string blockline = line; + size_t lead = blockline.find_first_not_of(' '); + if(lead != std::string::npos){ + blockline = blockline.substr(lead); + } + if (blockline=="\\"){ + textblock=false; + TDF_DATA DAT={TDF_BLOCK,new std::string(BLOCK)}; + todelete.push_back(DAT.datapointer); + (*current)[BLOCKKEY]=DAT; + }else{ + BLOCK+=line+"\n"; + } + } + else{ + std::string trimmed = line; + size_t lead = trimmed.find_first_not_of(' '); + if(lead != std::string::npos){ + trimmed = trimmed.substr(lead); + }else{ + continue; + } + if (trimmed.empty() || trimmed[0]=='#'){continue;} + if (trimmed.size() > 1 && trimmed[1]==' '){ + CCHAR=trimmed[0]; + switch (CCHAR) { + + case '"':{ + int LAST = trimmed.find(' ', 3); + if (LAST == std::string::npos) goto FAILTOPARSE; + std::string KEY = trimmed.substr(2, LAST - 2); + std::string VALUE; + VALUE=trimmed.substr(LAST + 1); + TDF_DATA DAT = { TDF_STR, new std::string(VALUE) }; + todelete.push_back(DAT.datapointer); + (*current)[KEY]=DAT; + break;} + + + case 'S':{ + int LAST = trimmed.find(' ', 2); + std::string KEY; + if (LAST != std::string::npos){ + KEY = trimmed.substr(2, LAST - 2); + }else{ + KEY = trimmed.substr(2); + } + BLOCKKEY=KEY; + BLOCK=""; + textblock=true; + break;} + + + case '\'':{ + int LAST = trimmed.find(' ', 3); + if (LAST == std::string::npos) goto FAILTOPARSE; + std::string KEY = trimmed.substr(2, LAST - 2); + if (LAST + 1 >= trimmed.size()) goto FAILTOPARSE; + char VALUE=trimmed.at(LAST + 1); + if (LAST + 2 < trimmed.size()) goto FAILTOPARSE; + TDF_DATA DAT = { TDF_CHAR, new char(VALUE) }; + todelete.push_back(DAT.datapointer); + (*current)[KEY]=DAT; + break;} + + + case 'i':{ + int LAST = trimmed.find(' ', 3); + if (LAST == std::string::npos) goto FAILTOPARSE; + std::string KEY = trimmed.substr(2, LAST - 2); + std::string sub = trimmed.substr(LAST + 1); + size_t idx; + int VALUE; + try{ + VALUE=stoi(sub, &idx, 0); + if (idx != sub.size()) goto FAILTOPARSE; + }catch(std::invalid_argument&){ + goto FAILTOPARSE; + } + TDF_DATA DAT= {TDF_INT, new int(VALUE)}; + todelete.push_back(DAT.datapointer); + (*current)[KEY]=DAT; + break;} + + + case 'h':{ + int LAST = trimmed.find(' ', 3); + if (LAST == std::string::npos) goto FAILTOPARSE; + std::string KEY = trimmed.substr(2, LAST - 2); + std::string sub = trimmed.substr(LAST + 1); + size_t idx; + int VALUE; + try{ + VALUE=stoi(sub, &idx, 16); + if (idx != sub.size()) goto FAILTOPARSE; + }catch(const std::invalid_argument&){ + goto FAILTOPARSE; + } + TDF_DATA DAT={TDF_HEX,new int(VALUE)}; + todelete.push_back(DAT.datapointer); + (*current)[KEY]=DAT; + break;} + + + case 'b':{ + int LAST = trimmed.find(' ', 3); + if (LAST == std::string::npos) goto FAILTOPARSE; + std::string KEY = trimmed.substr(2, LAST - 2); + std::string sub = trimmed.substr(LAST + 1); + size_t idx; + int VALUE; + try{ + VALUE=stoi(sub, &idx, 2); + if (idx != sub.size()) goto FAILTOPARSE; + }catch(const std::invalid_argument&){ + goto FAILTOPARSE; + } + TDF_DATA DAT={TDF_BINARY,new int(VALUE)}; + todelete.push_back(DAT.datapointer); + (*current)[KEY]=DAT; + break;} + + + case 'B':{ + int LAST = trimmed.find(' ', 3); + if (LAST == std::string::npos) goto FAILTOPARSE; + std::string KEY = trimmed.substr(2, LAST - 2); + if (LAST + 1 >= trimmed.size()) goto FAILTOPARSE; + char c=trimmed.at(LAST + 1); + bool VALUE = c=='T'; + if (LAST + 2 < trimmed.size()) goto FAILTOPARSE; + TDF_DATA DAT={TDF_BOOL,new bool(VALUE)}; + todelete.push_back(DAT.datapointer); + (*current)[KEY]=DAT; + break;} + + + case 'f':{ + int LAST = trimmed.find(' ', 3); + if (LAST == std::string::npos) goto FAILTOPARSE; + std::string KEY = trimmed.substr(2, LAST - 2); + std::string sub = trimmed.substr(LAST + 1); + size_t idx; + float VALUE; + try{ + VALUE=stof(sub, &idx); + if (idx != sub.size()) goto FAILTOPARSE; + }catch(std::invalid_argument&){ + goto FAILTOPARSE; + } + TDF_DATA DAT={TDF_FLOAT,new float(VALUE)}; + todelete.push_back(DAT.datapointer); + (*current)[KEY]=DAT; + break;} + + + case '@':{ + int LAST = trimmed.find(' ', 3); + if (LAST == std::string::npos) goto FAILTOPARSE; + std::string KEY = trimmed.substr(2, LAST - 2); + std::string VALUE=trimmed.substr(LAST + 1); + std::vector*ptr=new std::vector(); + size_t pos=0; + std::string token; + while((pos=VALUE.find('.'))!=std::string::npos){ + token=VALUE.substr(0,pos); + ptr->push_back(token); + VALUE.erase(0,pos+1); + } + ptr->push_back(VALUE); + TDF_DATA DAT={TDF_POINTER,ptr}; + todelete.push_back(DAT.datapointer); + (*current)[KEY]=DAT; + break;} + + + case '{':{ + int LAST = trimmed.find(' ', 3); + std::string KEY; + if (LAST != std::string::npos){ + KEY = trimmed.substr(2, LAST - 2); + }else{ + KEY = trimmed.substr(2); + } + boost::unordered_map*newmap=new boost::unordered_map(); + TDF_DATA DAT={TDF_CLASS,newmap}; + todelete.push_back(DAT.datapointer); + (*current)[KEY]=DAT; + std::vector *defines=new std::vector(); + TDF_DATA defdat={TDF_DEFINES,defines}; + (*newmap)[TINYDEFINEHEADER]=defdat; + stack.push_back(current); + pathvec.push_back(KEY); + current=newmap; + break;} + + + default:{ + try { + int PATH=FUNCS.funcs.at(trimmed[0]); + int LAST = trimmed.find(' ', 3); + if (LAST == std::string::npos)goto FAILTOPARSE; + std::string KEY = trimmed.substr(2, LAST - 2); + (*current)[KEY]=FUNCS.FUNCS[PATH](trimmed); + todelete.push_back((*current)[KEY].datapointer); + if ((*current)[KEY].datapointer==nullptr) goto FAILTOPARSE; + }catch(const std::out_of_range&){ + break; + } + break;} + } + }else if(trimmed == "}"){ + if(stack.empty())goto FAILTOPARSE; + current=stack.back(); + stack.pop_back(); + if(!pathvec.empty())pathvec.pop_back(); + }else{ + auto it = current->find(TINYDEFINEHEADER); + if (it == current->end() || it->second.type != TDF_DEFINES) goto FAILTOPARSE; + std::vector* defines = static_cast*>(it->second.datapointer); + defines->push_back(line); + } + } + } + return data; + }else{ + throw TDF_ERR(FILE_NOT_FOUND,filepath,{}); + } + NULLPOINTER: + //tiny::fatal("NULL POINTER of selector %c",CCHAR); + throw TDF_ERR(NULL_POINTER,filepath,{std::string(1,CCHAR),std::to_string(INDEX)}); + FAILTOPARSE: + //tiny::fatal("FAILED TO PARSE LINE %i OF FILE %s",INDEX,filepath); + throw TDF_ERR(FAILED_TO_PARSE,filepath,{std::to_string(INDEX)}); + delete data; + data=nullptr; + return nullptr; + } + //get + bool defined(std::vectorpath){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end())return false; + if(i==path.size()-1)return true; + if(it->second.type!=TDF_CLASS)return false; + current=(boost::unordered_map*)it->second.datapointer; + } + return false; + } + bool getbool(std::vectorpath){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end())throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + if(i==path.size()-1){ + if(it->second.type!=TDF_BOOL)throw TDF_ERR(GET_MISMATCH,filepath,path); + return *static_cast(it->second.datapointer); + } + if(it->second.type!=TDF_CLASS)throw TDF_ERR(GET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + } + int getint(std::vectorpath){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end())throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + if(i==path.size()-1){ + if((it->second.type!=TDF_INT)&&(it->second.type!=TDF_HEX)&&(it->second.type!=TDF_BINARY))throw TDF_ERR(GET_MISMATCH,filepath,path); + return *static_cast(it->second.datapointer); + } + if(it->second.type!=TDF_CLASS)throw TDF_ERR(GET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + } + std::string getstring(std::vectorpath){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end())throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + if(i==path.size()-1){ + if((it->second.type!=TDF_STR)&&(it->second.type!=TDF_BLOCK))throw TDF_ERR(GET_MISMATCH,filepath,path); + return *static_cast(it->second.datapointer); + } + if(it->second.type!=TDF_CLASS)throw TDF_ERR(GET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + } + std::vector getpointer(std::vectorpath){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end())throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + if(i==path.size()-1){ + if(it->second.type!=TDF_POINTER)throw TDF_ERR(GET_MISMATCH,filepath,path); + return *static_cast*>(it->second.datapointer); + } + if(it->second.type!=TDF_CLASS)throw TDF_ERR(GET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + } + char getchar(std::vectorpath){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end())throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + if(i==path.size()-1){ + if(it->second.type!=TDF_CHAR)throw TDF_ERR(GET_MISMATCH,filepath,path); + return *static_cast(it->second.datapointer); + } + if(it->second.type!=TDF_CLASS)throw TDF_ERR(GET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + } + float getfloat(std::vectorpath){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end())throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + if(i==path.size()-1){ + if(it->second.type!=TDF_FLOAT)throw TDF_ERR(GET_MISMATCH,filepath,path); + return *static_cast(it->second.datapointer); + } + if(it->second.type!=TDF_CLASS)throw TDF_ERR(GET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + } + boost::unordered_map* getclass(std::vectorpath){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end())throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + if(i==path.size()-1){ + if(it->second.type!=TDF_CLASS)throw TDF_ERR(GET_MISMATCH,filepath,path); + return (boost::unordered_map*)(it->second.datapointer); + } + if(it->second.type!=TDF_CLASS)throw TDF_ERR(GET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + throw TDF_ERR(PATH_NOT_FOUND,filepath,path); + } + + //set + void setbool(std::vectorpath,bool value){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end()){ + if(i==path.size()-1){ + TDF_DATA DAT={TDF_BOOL,new bool(value)}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + return; + }else{ + boost::unordered_map*newmap=new boost::unordered_map(); + TDF_DATA DAT={TDF_CLASS,newmap}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + current=newmap; + } + }else{ + if(i==path.size()-1){ + if(it->second.type!=TDF_BOOL)throw TDF_ERR(SET_MISMATCH,filepath,path); + *static_cast(it->second.datapointer)=value; + return;} + if(it->second.type!=TDF_CLASS)throw TDF_ERR(SET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + } + } + void setint(std::vectorpath,int value){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end()){ + if(i==path.size()-1){ + TDF_DATA DAT={TDF_INT,new int(value)}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + return; + }else{ + boost::unordered_map*newmap=new boost::unordered_map(); + TDF_DATA DAT={TDF_CLASS,newmap}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + current=newmap; + } + }else{ + if(i==path.size()-1){ + if(it->second.type!=TDF_INT)throw TDF_ERR(SET_MISMATCH,filepath,path); + *static_cast(it->second.datapointer)=value; + return;} + if(it->second.type!=TDF_CLASS)throw TDF_ERR(SET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + } + } + void setstring(std::vectorpath,std::string value){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end()){ + if(i==path.size()-1){ + TDF_DATA DAT={TDF_STR,new std::string(value)}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + return; + }else{ + boost::unordered_map*newmap=new boost::unordered_map(); + TDF_DATA DAT={TDF_CLASS,newmap}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + current=newmap; + } + }else{ + if(i==path.size()-1){ + if(it->second.type!=TDF_STR)throw TDF_ERR(SET_MISMATCH,filepath,path); + *static_cast(it->second.datapointer)=value; + return;} + if(it->second.type!=TDF_CLASS)throw TDF_ERR(SET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + } + } + void setblock(std::vectorpath,std::string value){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end()){ + if(i==path.size()-1){ + TDF_DATA DAT={TDF_BLOCK,new std::string(value)}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + return; + }else{ + boost::unordered_map*newmap=new boost::unordered_map(); + TDF_DATA DAT={TDF_CLASS,newmap}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + current=newmap; + } + }else{ + if(i==path.size()-1){ + if(it->second.type!=TDF_BLOCK)throw TDF_ERR(SET_MISMATCH,filepath,path); + *static_cast(it->second.datapointer)=value; + return;} + if(it->second.type!=TDF_CLASS)throw TDF_ERR(SET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + } + } + void setfloat(std::vectorpath,float value){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end()){ + if(i==path.size()-1){ + TDF_DATA DAT={TDF_FLOAT,new float(value)}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + return; + }else{ + boost::unordered_map*newmap=new boost::unordered_map(); + TDF_DATA DAT={TDF_CLASS,newmap}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + current=newmap; + } + }else{ + if(i==path.size()-1){ + if(it->second.type!=TDF_FLOAT)throw TDF_ERR(SET_MISMATCH,filepath,path); + *static_cast(it->second.datapointer)=value; + return;} + if(it->second.type!=TDF_CLASS)throw TDF_ERR(SET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + } + } + void setchar(std::vectorpath,char value){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end()){ + if(i==path.size()-1){ + TDF_DATA DAT={TDF_CHAR,new char(value)}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + return; + }else{ + boost::unordered_map*newmap=new boost::unordered_map(); + TDF_DATA DAT={TDF_CLASS,newmap}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + current=newmap; + } + }else{ + if(i==path.size()-1){ + if(it->second.type!=TDF_CHAR)throw TDF_ERR(SET_MISMATCH,filepath,path); + *static_cast(it->second.datapointer)=value; + return;} + if(it->second.type!=TDF_CLASS)throw TDF_ERR(SET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + } + } + void setpointer(std::vectorpath,std::vectorvalue){ + boost::unordered_map*current=data; + for(size_t i=0;ifind(path[i]); + if(it==current->end()){ + if(i==path.size()-1){ + TDF_DATA DAT={TDF_POINTER,new std::vector(value)}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + return; + }else{ + boost::unordered_map*newmap=new boost::unordered_map(); + TDF_DATA DAT={TDF_CLASS,newmap}; + todelete.push_back(DAT.datapointer); + (*current)[path[i]]=DAT; + current=newmap; + } + }else{ + if(i==path.size()-1){ + if(it->second.type!=TDF_POINTER)throw TDF_ERR(SET_MISMATCH,filepath,path); + *static_cast*>(it->second.datapointer)=value; + return;} + if(it->second.type!=TDF_CLASS)throw TDF_ERR(SET_MISMATCH,filepath,path); + current=(boost::unordered_map*)(it->second.datapointer); + } + } + } + void define(std::vectordefines,char* name){ + auto it = data->find(TINYDEFINEHEADER); + if (it == data->end() || it->second.type != TDF_DEFINES) { + std::vector* newdefines = new std::vector(); + TDF_DATA defdat = { TDF_DEFINES, newdefines }; + (*data)[TINYDEFINEHEADER] = defdat; + todelete.push_back(defdat.datapointer); + it = data->find(TINYDEFINEHEADER); + } + std::vector* currentdefines = static_cast*>(it->second.datapointer); + for (size_t i = 0; i < defines.size(); i++) { + currentdefines->push_back(defines[i]); + } + currentdefines->push_back(std::string("#define ") + name); + } + + void save(){ + std::ofstream file(filepath, std::ios::out | std::ios::trunc); + std::string DATA=""; + crawl(data,&DATA,""); + file<*map,std::string*STR,std::string indent){ + auto it = map->find(TINYDEFINEHEADER); + if (it != map->end() && it->second.type == TDF_DEFINES) { + std::vector* defines = static_cast*>(it->second.datapointer); + for (auto& def : *defines) { + *STR += def + "\n"; + } + } + for(auto&[key,val]:*map){ + if(key==TINYDEFINEHEADER)continue; + switch(val.type){ + case TDF_STR: + *STR+="\" "+key+" "+*static_cast(val.datapointer)+"\n"; + break; + case TDF_CHAR: + *STR+="' "+key+" "+*static_cast(val.datapointer)+"\n"; + break; + case TDF_BLOCK: + *STR+="S "+key+"\n"+*static_cast(val.datapointer)+"\\\n"; + break; + case TDF_BOOL: + *STR+="B "+key+" "+(*static_cast(val.datapointer)?"T":"F")+"\n"; + break; + case TDF_BINARY: + *STR+="b "+key+" "+std::to_string(*static_cast(val.datapointer))+"\n"; + break; + case TDF_INT: + *STR+="i "+key+" "+std::to_string(*static_cast(val.datapointer))+"\n"; + break; + case TDF_FLOAT: + *STR+="f "+key+" "+std::to_string(*static_cast(val.datapointer))+"\n"; + break; + case TDF_HEX: + *STR+="h "+key+" "+std::to_string(*static_cast(val.datapointer))+"\n"; + break; + case TDF_POINTER:{ + std::vector*ptr=static_cast*>(val.datapointer); + *STR+="@ "+key+" "; + for(size_t i=0;isize();i++){ + *STR+=(*ptr)[i]; + if(isize()-1)*STR+="."; + } + *STR+="\n"; + break;} + case TDF_CLASS: + *STR+="{ "+key+"\n"; + crawl((boost::unordered_map*)(val.datapointer),STR,""); + *STR+="}\n"; + break; + } + } + } +}; + +} +#endif \ No newline at end of file diff --git a/inc/term.h b/inc/term.h new file mode 100644 index 0000000..95405b9 --- /dev/null +++ b/inc/term.h @@ -0,0 +1,124 @@ +#pragma once +#ifndef TINYTERM_H +#define TINYTERM_H + + +#include +#include +#include +#include + +namespace tiny { + + + +struct ErrorLevel { + int value; + ErrorLevel(int var){ + + this->value=var; + } + void setvalue(int var){ + this->value=var; + } +}; + +/* +-1: none +0: error +1: success +2: warning +3: message +4: echo + +ex (i recommend using on main.cpp): +tiny::ErrorLevel tiny::level={1}; +*/ + +extern tiny::ErrorLevel level; + +#define WHITE "\033[0m" /* White */ +#define BLACK "\033[30m" /* Black */ +#define RED "\033[31m" /* Red */ +#define GREEN "\033[32m" /* Green */ +#define YELLOW "\033[33m" /* Yellow */ +#define BLUE "\033[34m" /* Blue */ +#define MAGENTA "\033[35m" /* Magenta */ +#define CYAN "\033[36m" /* Cyan */ +#define WHITE "\033[37m" /* White */ +#define BGRED "\033[41m" /* Red */ +#define BOLDBLACK "\033[1m\033[30m" /* Bold Black */ +#define BOLDRED "\033[1m\033[31m" /* Bold Red */ +#define BOLDGREEN "\033[1m\033[32m" /* Bold Green */ +#define BOLDYELLOW "\033[1m\033[33m" /* Bold Yellow */ +#define BOLDBLUE "\033[1m\033[34m" /* Bold Blue */ +#define BOLDMAGENTA "\033[1m\033[35m" /* Bold Magenta */ +#define BOLDCYAN "\033[1m\033[36m" /* Bold Cyan */ +#define BOLDWHITE "\033[1m\033[37m" /* Bold White */ +#define ending \ + mixer.append(info); mixer.append("\033[0m\n");\ + const char * finalinfo=mixer.c_str();\ + va_start (arg, finalinfo);\ + vfprintf (stdout, finalinfo, arg);\ + va_end (arg); + +inline void echo(char * info,...){ + if (level.value==4) + { + va_list arg; + std::string mixer=info; + mixer.append("\n"); + const char * finalinfo=mixer.c_str(); + va_start (arg, finalinfo); + vfprintf (stdout, finalinfo, arg); + va_end (arg);} +} +inline void warning( char * info,...){ + if (level.value>=1) + { + va_list arg; + std::string mixer=YELLOW;ending +} +} +inline void fatal( char * info,...){ + va_list arg; + std::string mixer=BOLDWHITE+std::string(BGRED);ending +} +inline void error( char * info,...){ + if (level.value>=0) + { + va_list arg; + std::string mixer=BOLDRED;ending +}} +inline void success(char * info , ...){ + if (level.value>=2) + { + va_list arg; + std::string mixer=GREEN;ending} +} +inline void message(char * info , ...){ + if (level.value>=3) + { + va_list arg; + std::string mixer=BOLDWHITE;ending} +} +inline void startup(char* game,char*version){ +int lv=level.value;level.value=6; + echo("%s %s",game,version); + warning("be warned that"); + error("ERRORS MIGHT OCCUR!!!"); + success("but dont worry"); + message("this is not an error"); + fatal("I SWEAR"); +level.value=lv; +} + + + + +} + +#endif + + + diff --git a/inc/tiny.h b/inc/tiny.h new file mode 100644 index 0000000..e69de29