Performance optimizations

- Replaced some exec() calls with functions
- Removed resolved code being resolved again
- Removed empty string subargs inserted upon parsing
This commit is contained in:
zawz 2020-11-13 15:18:30 +01:00
parent 5a7c2e0bf0
commit a0155991e3
10 changed files with 157 additions and 89 deletions

View file

@ -7,13 +7,14 @@
// boolean value of fct: if true, recurse on this object, if false, skip this object // boolean value of fct: if true, recurse on this object, if false, skip this object
template<class... Args> template<class... Args>
void recurse(void (&fct)(_obj*, Args...), _obj* o, Args... args) void recurse(bool (&fct)(_obj*, Args...), _obj* o, Args... args)
{ {
if(o == nullptr) if(o == nullptr)
return; return;
// execution // execution
fct(o, args...); if(!fct(o, args...))
return; // skip recurse if false
// recursive calls // recursive calls
switch(o->type) switch(o->type)

View file

@ -3,6 +3,11 @@
#include "struc.hpp" #include "struc.hpp"
extern std::vector<std::string> included;
bool add_include(std::string const& file);
void resolve(_obj* sh, shmain* parent);
void resolve(shmain* sh); void resolve(shmain* sh);
#endif //RESOLVE_HPP #endif //RESOLVE_HPP

View file

@ -76,8 +76,6 @@ extern std::string g_origin;
cmd* make_cmd(std::vector<std::string> args); cmd* make_cmd(std::vector<std::string> args);
bool add_include(std::string const& file);
class _obj class _obj
{ {
public: public:

View file

@ -18,6 +18,9 @@
extern std::string indenting_string; extern std::string indenting_string;
std::string basename(std::string const& in);
std::string dirname(std::string const& in);
std::string indent(int n); std::string indent(int n);
std::vector<std::string> split(std::string const& in, const char* splitters); std::vector<std::string> split(std::string const& in, const char* splitters);

View file

@ -6,8 +6,6 @@
#include "options.hpp" #include "options.hpp"
#include "parse.hpp" #include "parse.hpp"
std::vector<std::string> included;
bool is_sub_special_cmd(std::string in) bool is_sub_special_cmd(std::string in)
{ {
return in == "%include_sub" || in == "%resolve_sub"; return in == "%include_sub" || in == "%resolve_sub";
@ -111,18 +109,6 @@ std::string list::generate(int ind, bool first_indent)
return ret; return ret;
} }
bool add_include(std::string const& file)
{
std::string truepath=ztd::exec("readlink", "-f", file).first;
for(auto it: included)
{
if(it == truepath)
return false;
}
included.push_back(truepath);
return true;
}
// BLOCK // BLOCK
std::string block::generate_redirs(int ind) std::string block::generate_redirs(int ind)

View file

@ -86,7 +86,7 @@ int main(int argc, char* argv[])
// do parsing // do parsing
for(uint32_t i=0 ; i<args.size() ; i++) for(uint32_t i=0 ; i<args.size() ; i++)
{ {
std::string& file = args[i]; std::string file = args[i];
std::string filecontents=import_file(file); std::string filecontents=import_file(file);
// parse // parse
g_origin=file; g_origin=file;
@ -98,7 +98,7 @@ int main(int argc, char* argv[])
{ {
first_run=false; first_run=false;
// resolve shebang // resolve shebang
bool shebang_is_bin = ztd::exec("basename", argv[0]).first == ztd::exec("basename", tsh->shebang).first; bool shebang_is_bin = basename(argv[0]) == basename(tsh->shebang);
if(shebang_is_bin) if(shebang_is_bin)
tsh->shebang="#!/bin/sh"; tsh->shebang="#!/bin/sh";
@ -112,7 +112,6 @@ int main(int argc, char* argv[])
if(!is_exec && args.size() > 1) // not exec: parse options on args if(!is_exec && args.size() > 1) // not exec: parse options on args
{ {
std::string t=args[0];
args=options.process(args); args=options.process(args);
} }
@ -123,7 +122,9 @@ int main(int argc, char* argv[])
/* mid processing */ /* mid processing */
// resolve/include // resolve/include
if(g_include || g_resolve) if(g_include || g_resolve)
{
resolve(tsh); resolve(tsh);
}
// concatenate to main // concatenate to main
sh->concat(tsh); sh->concat(tsh);
@ -180,7 +181,7 @@ int main(int argc, char* argv[])
printFormatError(e); printFormatError(e);
return 100; return 100;
} }
catch(std::exception& e) catch(std::runtime_error& e)
{ {
if(tsh != nullptr) if(tsh != nullptr)
delete tsh; delete tsh;

View file

@ -87,10 +87,10 @@ std::string get_varname(subarg* in)
/** VAR RECURSE **/ /** VAR RECURSE **/
void get_map_varname(_obj* in, std::map<std::string,uint32_t>* variable_map) bool get_map_varname(_obj* in, std::map<std::string,uint32_t>* variable_map)
{ {
if(variable_map == nullptr) if(variable_map == nullptr)
return; return false;
switch(in->type) switch(in->type)
{ {
case _obj::subarg_variable: { case _obj::subarg_variable: {
@ -122,9 +122,10 @@ void get_map_varname(_obj* in, std::map<std::string,uint32_t>* variable_map)
}; break; }; break;
default: break; default: break;
} }
return true;
} }
void replace_varname(_obj* in, std::map<std::string,std::string>* varmap) bool replace_varname(_obj* in, std::map<std::string,std::string>* varmap)
{ {
switch(in->type) switch(in->type)
{ {
@ -170,15 +171,13 @@ void replace_varname(_obj* in, std::map<std::string,std::string>* varmap)
}; break; }; break;
default: break; default: break;
} }
return true;
} }
/** FCT RECURSE **/ /** FCT RECURSE **/
void get_map_cmd(_obj* in, std::map<std::string,uint32_t>* all_cmds) bool get_map_cmd(_obj* in, std::map<std::string,uint32_t>* all_cmds)
{ {
if(all_cmds == nullptr)
return;
switch(in->type) switch(in->type)
{ {
case _obj::block_cmd: { case _obj::block_cmd: {
@ -189,12 +188,11 @@ void get_map_cmd(_obj* in, std::map<std::string,uint32_t>* all_cmds)
}; break; }; break;
default: break; default: break;
} }
return true;
} }
void get_map_fctname(_obj* in, std::map<std::string,uint32_t>* fct_map) bool get_map_fctname(_obj* in, std::map<std::string,uint32_t>* fct_map)
{ {
if(fct_map == nullptr)
return;
switch(in->type) switch(in->type)
{ {
case _obj::block_function: { case _obj::block_function: {
@ -204,9 +202,10 @@ void get_map_fctname(_obj* in, std::map<std::string,uint32_t>* fct_map)
}; break; }; break;
default: break; default: break;
} }
return true;
} }
void replace_fctname(_obj* in, std::map<std::string,std::string>* fctmap) bool replace_fctname(_obj* in, std::map<std::string,std::string>* fctmap)
{ {
switch(in->type) switch(in->type)
{ {
@ -228,9 +227,10 @@ void replace_fctname(_obj* in, std::map<std::string,std::string>* fctmap)
}; break; }; break;
default: break; default: break;
} }
return true;
} }
void delete_fcts(_obj* in, std::set<std::string>* fcts) bool delete_fcts(_obj* in, std::set<std::string>* fcts)
{ {
switch(in->type) switch(in->type)
{ {
@ -253,6 +253,7 @@ void delete_fcts(_obj* in, std::set<std::string>* fcts)
} }
default: break; default: break;
} }
return true;
} }
/** name things **/ /** name things **/
@ -366,7 +367,7 @@ void delete_unused_fct(_obj* in, std::regex exclude)
recurse(delete_fcts, in, &unused); recurse(delete_fcts, in, &unused);
} }
void list_stuff(_obj* in, std::regex exclude, void (&fct)(_obj*,std::map<std::string,uint32_t>*) ) void list_stuff(_obj* in, std::regex exclude, bool (&fct)(_obj*,std::map<std::string,uint32_t>*) )
{ {
std::map<std::string,uint32_t> map; std::map<std::string,uint32_t> map;
recurse(fct, in, &map); recurse(fct, in, &map);

View file

@ -243,7 +243,9 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
else if( word_eq("$((", in, size, i) ) // arithmetic operation else if( word_eq("$((", in, size, i) ) // arithmetic operation
{ {
// add previous subarg // add previous subarg
ret->sa.push_back(new string_subarg(std::string(in+j, i-j))); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
// get arithmetic // get arithmetic
auto r=parse_arithmetic(in, size, i+3); auto r=parse_arithmetic(in, size, i+3);
ret->sa.push_back(r.first); ret->sa.push_back(r.first);
@ -252,7 +254,9 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
else if( word_eq("$(", in, size, i) ) // substitution else if( word_eq("$(", in, size, i) ) // substitution
{ {
// add previous subarg // add previous subarg
ret->sa.push_back(new string_subarg(std::string(in+j, i-j))); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
// get subshell // get subshell
auto r=parse_subshell(in, size, i+2); auto r=parse_subshell(in, size, i+2);
ret->sa.push_back(new subshell_subarg(r.first, true)); ret->sa.push_back(new subshell_subarg(r.first, true));
@ -261,7 +265,9 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
else if( word_eq("${", in, size, i) ) // variable manipulation else if( word_eq("${", in, size, i) ) // variable manipulation
{ {
// add previous subarg // add previous subarg
ret->sa.push_back(new string_subarg(std::string(in+j, i-j))); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
// get manipulation // get manipulation
auto r=parse_manipulation(in, size, i+2); auto r=parse_manipulation(in, size, i+2);
ret->sa.push_back(r.first); ret->sa.push_back(r.first);
@ -273,7 +279,9 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
if(r.second > i+1) if(r.second > i+1)
{ {
// add previous subarg // add previous subarg
ret->sa.push_back(new string_subarg(std::string(in+j, i-j))); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
// add varname // add varname
ret->sa.push_back(new variable_subarg(r.first)); ret->sa.push_back(new variable_subarg(r.first));
j = i = r.second; j = i = r.second;
@ -302,7 +310,9 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
else if( word_eq("$((", in, size, i) ) // arithmetic operation else if( word_eq("$((", in, size, i) ) // arithmetic operation
{ {
// add previous subarg // add previous subarg
ret->sa.push_back(new string_subarg(std::string(in+j, i-j))); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
// get arithmetic // get arithmetic
auto r=parse_arithmetic(in, size, i+3); auto r=parse_arithmetic(in, size, i+3);
ret->sa.push_back(r.first); ret->sa.push_back(r.first);
@ -311,7 +321,9 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
else if( word_eq("$(", in, size, i) ) // substitution else if( word_eq("$(", in, size, i) ) // substitution
{ {
// add previous subarg // add previous subarg
ret->sa.push_back(new string_subarg(std::string(in+j, i-j))); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
// get subshell // get subshell
auto r=parse_subshell(in, size, i+2); auto r=parse_subshell(in, size, i+2);
ret->sa.push_back(new subshell_subarg(r.first, false)); ret->sa.push_back(new subshell_subarg(r.first, false));
@ -320,7 +332,9 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
else if( word_eq("${", in, size, i) ) // variable manipulation else if( word_eq("${", in, size, i) ) // variable manipulation
{ {
// add previous subarg // add previous subarg
ret->sa.push_back(new string_subarg(std::string(in+j, i-j))); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
// get manipulation // get manipulation
auto r=parse_manipulation(in, size, i+2); auto r=parse_manipulation(in, size, i+2);
ret->sa.push_back(r.first); ret->sa.push_back(r.first);
@ -332,7 +346,9 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
if(r.second > i+1) if(r.second > i+1)
{ {
// add previous subarg // add previous subarg
ret->sa.push_back(new string_subarg(std::string(in+j, i-j))); std::string tmpstr=std::string(in+j, i-j);
if(tmpstr!="")
ret->sa.push_back(new string_subarg(tmpstr));
// add varname // add varname
ret->sa.push_back(new variable_subarg(r.first)); ret->sa.push_back(new variable_subarg(r.first));
j = i = r.second; j = i = r.second;
@ -346,7 +362,8 @@ std::pair<arg*, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t star
// add string subarg // add string subarg
std::string val=std::string(in+j, i-j); std::string val=std::string(in+j, i-j);
ret->sa.push_back(new string_subarg(val)); if(val != "")
ret->sa.push_back(new string_subarg(val));
} }
catch(ztd::format_error& e) catch(ztd::format_error& e)

View file

@ -7,29 +7,45 @@
#include "options.hpp" #include "options.hpp"
#include "util.hpp" #include "util.hpp"
#include "parse.hpp" #include "parse.hpp"
#include "timer.hpp"
std::vector<std::string> included;
// -- CD STUFF -- // -- CD STUFF --
std::string pwd() std::string pwd()
{ {
char buf[2048]; char buf[2048];
if(getcwd(buf, 2048) != NULL) if(getcwd(buf, 2048) == NULL)
{ {
std::string ret=ztd::exec("pwd").first; // getcwd failed: call pwd throw std::runtime_error("getcwd failed with errno "+std::to_string(errno));
ret.pop_back();
return ret;
} }
return std::string(buf); return std::string(buf);
} }
bool add_include(std::string const& file)
{
std::string truepath;
if(file[0] == '/')
truepath = file;
else
truepath=pwd() + '/' + file;
for(auto it: included)
{
if(it == truepath)
return false;
}
included.push_back(truepath);
return true;
}
// returns path to old dir // returns path to old dir
std::string _pre_cd(shmain* parent) std::string _pre_cd(shmain* parent)
{ {
if(parent->is_dev_file() || parent->filename == "") if(parent->is_dev_file() || parent->filename == "")
return ""; return "";
std::string dir=pwd(); std::string dir=pwd();
std::string cddir=ztd::exec("dirname", parent->filename).first; std::string cddir=dirname(parent->filename);
cddir.pop_back();
if(chdir(cddir.c_str()) != 0) if(chdir(cddir.c_str()) != 0)
throw std::runtime_error("Cannot cd to '"+cddir+"'"); throw std::runtime_error("Cannot cd to '"+cddir+"'");
return dir; return dir;
@ -47,8 +63,6 @@ void _cd(std::string const& dir)
std::vector<std::pair<std::string, std::string>> do_include_raw(condlist* cmd, shmain* parent, std::string* ex_dir=nullptr) std::vector<std::pair<std::string, std::string>> do_include_raw(condlist* cmd, shmain* parent, std::string* ex_dir=nullptr)
{ {
std::vector<std::pair<std::string, std::string>> ret; std::vector<std::pair<std::string, std::string>> ret;
if(!g_include)
return ret;
ztd::option_set opts = create_include_opts(); ztd::option_set opts = create_include_opts();
std::vector<std::string> rargs; std::vector<std::string> rargs;
@ -73,14 +87,16 @@ std::vector<std::pair<std::string, std::string>> do_include_raw(condlist* cmd, s
for(auto it: rargs) for(auto it: rargs)
command += it + ' '; command += it + ' ';
command += "; do echo $I ; done"; command += "; do echo $I ; done";
std::string inc=ztd::sh(command); std::string inc=ztd::sh(command); /* takes 1ms */
auto v = split(inc, '\n'); auto v = split(inc, '\n');
for(auto it: v) for(auto it: v)
{ {
if(opts['f'] || add_include(it)) if(opts['f'] || add_include(it))
{
ret.push_back(std::make_pair(it, import_file(it))); ret.push_back(std::make_pair(it, import_file(it)));
}
} }
if(ex_dir==nullptr) if(ex_dir==nullptr)
@ -92,13 +108,10 @@ std::vector<std::pair<std::string, std::string>> do_include_raw(condlist* cmd, s
std::vector<condlist*> do_include_parse(condlist* cmd, shmain* parent) std::vector<condlist*> do_include_parse(condlist* cmd, shmain* parent)
{ {
std::vector<condlist*> ret; std::vector<condlist*> ret;
if(!g_include)
return ret;
std::string dir; std::string dir;
auto incs=do_include_raw(cmd, parent, &dir); auto incs=do_include_raw(cmd, parent, &dir);
for(auto it: incs) for(auto it: incs)
{ {
shmain* sh=parse_text(it.second, it.first); shmain* sh=parse_text(it.second, it.first);
@ -119,8 +132,6 @@ std::vector<condlist*> do_include_parse(condlist* cmd, shmain* parent)
std::pair<std::string, std::string> do_resolve_raw(condlist* cmd, shmain* parent, std::string* ex_dir=nullptr) std::pair<std::string, std::string> do_resolve_raw(condlist* cmd, shmain* parent, std::string* ex_dir=nullptr)
{ {
std::pair<std::string, std::string> ret; std::pair<std::string, std::string> ret;
if(!g_resolve)
return ret;
ztd::option_set opts = create_resolve_opts(); ztd::option_set opts = create_resolve_opts();
std::vector<std::string> rargs; std::vector<std::string> rargs;
@ -169,8 +180,6 @@ std::pair<std::string, std::string> do_resolve_raw(condlist* cmd, shmain* parent
std::vector<condlist*> do_resolve_parse(condlist* cmd, shmain* parent) std::vector<condlist*> do_resolve_parse(condlist* cmd, shmain* parent)
{ {
std::vector<condlist*> ret; std::vector<condlist*> ret;
if(!g_resolve)
return ret;
std::pair<std::string,std::string> p; std::pair<std::string,std::string> p;
try try
@ -199,26 +208,27 @@ std::vector<condlist*> do_resolve_parse(condlist* cmd, shmain* parent)
// -- OBJECT CALLS -- // -- OBJECT CALLS --
std::vector<condlist*> resolve_condlist(condlist* in, shmain* parent) std::pair< std::vector<condlist*> , bool > resolve_condlist(condlist* in, shmain* parent)
{ {
cmd* tc = in->first_cmd(); cmd* tc = in->first_cmd();
if(tc == nullptr) if(tc == nullptr)
return std::vector<condlist*>(); return std::make_pair(std::vector<condlist*>(), false);
std::string const& strcmd=tc->firstarg_string(); std::string const& strcmd=tc->firstarg_string();
if(strcmd == "%include") if(g_include && strcmd == "%include")
return do_include_parse(in, parent); return std::make_pair(do_include_parse(in, parent), true);
else if(strcmd == "%resolve") else if(g_resolve && strcmd == "%resolve")
return do_resolve_parse(in, parent); return std::make_pair(do_resolve_parse(in, parent), true);
else else
return std::vector<condlist*>(); return std::make_pair(std::vector<condlist*>(), false);
} }
std::vector<arg*> resolve_arg(arg* in, shmain* parent, bool forcequote=false) std::pair< std::vector<arg*> , bool > resolve_arg(arg* in, shmain* parent, bool forcequote=false)
{ {
std::vector<arg*> ret; std::vector<arg*> ret;
arg* ta=nullptr; arg* ta=nullptr;
bool has_resolved=false;
uint32_t j=0; uint32_t j=0;
for(uint32_t i=0 ; i<in->sa.size() ; i++) for(uint32_t i=0 ; i<in->sa.size() ; i++)
{ {
@ -234,18 +244,21 @@ std::vector<arg*> resolve_arg(arg* in, shmain* parent, bool forcequote=false)
continue; continue;
std::string strcmd=c->firstarg_string(); std::string strcmd=c->firstarg_string();
std::string fulltext; std::string fulltext;
if(strcmd == "%include") if(g_include && strcmd == "%include")
{ {
for(auto it: do_include_raw(tc, parent) ) for(auto it: do_include_raw(tc, parent) )
fulltext += it.second; fulltext += it.second;
} }
else if(strcmd == "%resolve") else if(g_resolve && strcmd == "%resolve")
{ {
fulltext = do_resolve_raw(tc, parent).second; fulltext = do_resolve_raw(tc, parent).second;
} }
else // skip else // skip
continue; continue;
// start of resolve
has_resolved = true;
if(tsh->quoted || forcequote) if(tsh->quoted || forcequote)
{ {
stringReplace(fulltext, "\"", "\\\""); stringReplace(fulltext, "\"", "\\\"");
@ -301,34 +314,42 @@ std::vector<arg*> resolve_arg(arg* in, shmain* parent, bool forcequote=false)
delete ta; delete ta;
in->sa.resize(0); in->sa.resize(0);
} }
return ret; return std::make_pair(ret, has_resolved);
} }
// -- RECURSIVE CALL -- // -- RECURSIVE CALL --
void resolve_recurse(_obj* o, shmain* parent) bool resolve_recurse(_obj* o, shmain* parent)
{ {
switch(o->type) switch(o->type)
{ {
// in case of applicable object:
// check every sub-object
// execute resolve manually
// instruct parent resolve to not resolve
case _obj::_list : case _obj::_list :
{ {
auto t = dynamic_cast<list*>(o); auto t = dynamic_cast<list*>(o);
for(uint32_t i=0 ; i<t->cls.size() ; i++) for(uint32_t i=0 ; i<t->cls.size() ; i++)
{ {
std::vector<condlist*> r=resolve_condlist(t->cls[i], parent); auto r=resolve_condlist(t->cls[i], parent);
if(r.size()>0) if(r.second)
{ {
// add new cls after current // add new cls after current
t->cls.insert(t->cls.begin()+i+1, r.begin(), r.end()); t->cls.insert(t->cls.begin()+i+1, r.first.begin(), r.first.end());
// delete current // delete current
delete t->cls[i]; delete t->cls[i];
t->cls.erase(t->cls.begin()+i); t->cls.erase(t->cls.begin()+i);
// back to previous object // skip to after inserted cls
i--; i += r.first.size()-1;
}
else
{
resolve(t->cls[i], parent);
} }
} }
// list return false;
} break; } break;
case _obj::_arglist : case _obj::_arglist :
{ {
@ -336,24 +357,33 @@ void resolve_recurse(_obj* o, shmain* parent)
for(uint32_t i=0 ; i<t->args.size() ; i++) for(uint32_t i=0 ; i<t->args.size() ; i++)
{ {
auto r=resolve_arg(t->args[i], parent); auto r=resolve_arg(t->args[i], parent);
if(r.size()>0) if(r.first.size()>0)
{ {
// add new args // add new args
t->args.insert(t->args.begin()+i+1, r.begin(), r.end()); t->args.insert(t->args.begin()+i+1, r.first.begin(), r.first.end());
// delete current // delete current
delete t->args[i]; delete t->args[i];
t->args.erase(t->args.begin()+i); t->args.erase(t->args.begin()+i);
i += r.size()-1; i += r.first.size()-1;
}
else
{
resolve(t->args[i], parent);
} }
} }
// arglist return false;
return;
} break; } break;
case _obj::block_cmd : case _obj::block_cmd :
{ {
auto t = dynamic_cast<cmd*>(o); auto t = dynamic_cast<cmd*>(o);
for(auto it: t->var_assigns) for(auto it: t->var_assigns) // var assigns
{
resolve_arg(it.second, parent, true); // force quoted resolve_arg(it.second, parent, true); // force quoted
resolve(it.second, parent);
}
resolve(t->redirs, parent);
resolve(t->args, parent);
return false;
}; break; }; break;
case _obj::block_case : case _obj::block_case :
{ {
@ -361,18 +391,27 @@ void resolve_recurse(_obj* o, shmain* parent)
for(auto sc: t->cases) for(auto sc: t->cases)
{ {
resolve_arg(t->carg, parent, true); // force quoted resolve_arg(t->carg, parent, true); // force quoted
resolve(t->carg, parent);
for(auto it: sc.first)
{ {
for(auto it: sc.first) resolve_arg(it, parent, true); // force quoted
resolve_arg(it, parent, true); // force quoted resolve(it, parent);
} }
resolve(sc.second, parent);
} }
}; break; }; break;
default: break; default: break;
} }
return; return true;
} }
// recursive call of resolve // recursive call of resolve
void resolve(_obj* in, shmain* parent)
{
recurse(resolve_recurse, in, parent);
}
void resolve(shmain* sh) void resolve(shmain* sh)
{ {
recurse(resolve_recurse, sh, sh); recurse(resolve_recurse, sh, sh);

View file

@ -20,6 +20,24 @@ std::string indent(int n)
return ret; return ret;
} }
std::string basename(std::string const& in)
{
size_t slr=in.rfind('/');
if(slr != std::string::npos)
return in.substr(slr);
else
return in;
}
std::string dirname(std::string const& in)
{
size_t slr=in.rfind('/');
if(slr != std::string::npos)
return in.substr(0,slr);
else
return ".";
}
std::vector<std::string> split(std::string const& in, const char* splitters) std::vector<std::string> split(std::string const& in, const char* splitters)
{ {
uint32_t i=0,j=0; uint32_t i=0,j=0;
@ -229,8 +247,7 @@ int execute(shmain* sh, std::vector<std::string>& args)
{ {
std::string data=sh->generate(); std::string data=sh->generate();
std::string filename=ztd::exec("basename", args[0]).first; std::string filename = basename(args[0]);
filename.pop_back();
// generate path // generate path
std::string tmpdir = (getenv("TMPDIR") != NULL) ? getenv("TMPDIR") : "/tmp" ; std::string tmpdir = (getenv("TMPDIR") != NULL) ? getenv("TMPDIR") : "/tmp" ;