diff --git a/README.md b/README.md index 3fbb47e..1f443a3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # lxsh Extended shell linker + +Work in progress diff --git a/include/struc.hpp b/include/struc.hpp index 46ac262..902d845 100644 --- a/include/struc.hpp +++ b/include/struc.hpp @@ -168,7 +168,7 @@ class subarg { public: // type - enum argtype { string, subshell }; + enum argtype { string, subshell, arithmetic }; argtype type; // ctor diff --git a/src/generate.cpp b/src/generate.cpp index e07e83d..1329db4 100644 --- a/src/generate.cpp +++ b/src/generate.cpp @@ -124,7 +124,6 @@ std::string generate_resolve(std::vector args, int ind) throw std::runtime_error("Cannot cd to '"+cddir+"'"); } - // exec call auto p=ztd::shp("exec "+cmd); @@ -210,6 +209,8 @@ std::string generate_include(std::vector args, int ind) file=import_file(it); if(opts['d']) file = stringReplace(file, "\"", "\\\""); + if(opts['s']) + file = stringReplace(file, "'", "'\\''"); if(opts['r']) ret += file; else @@ -378,6 +379,10 @@ std::string subarg::generate(int ind) { ret += val; } + else if(type == subarg::arithmetic) + { + ret += "$(("+val+"))"; + } else if(type == subarg::subshell) { // includes and resolves inside command substitutions diff --git a/src/parse.cpp b/src/parse.cpp index 9151784..fc8c7e1 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -79,6 +79,25 @@ uint32_t skip_unread(const char* in, uint32_t size, uint32_t start) std::pair parse_subshell(const char* in, uint32_t size, uint32_t start); +// parse an arithmetic +// ends at )) +// for now, uses subshell parsing then takes raw string value +// temporary, to improve +std::pair parse_arithmetic(const char* in, uint32_t size, uint32_t start) +{ + subarg ret(subarg::arithmetic); + uint32_t i=start; + + auto pp=parse_subshell(in, size, i); + i=pp.second; + if(i >= size || in[i]!=')') + throw ztd::format_error( "Unexpected token ')', expecting '))'", g_origin, in, i ); + ret.val = std::string(in+start, i-start-1); + i++; + + return std::make_pair(ret, i); +} + // parse one argument // must start at a read char // ends at either " \t|&;\n()" @@ -114,12 +133,22 @@ std::pair parse_arg(const char* in, uint32_t size, uint32_t start { i+=2; } + else if( word_eq("$((", in, size, i) ) // arithmetic operation + { + // add previous subarg + ret.sa.push_back(subarg(std::string(in+j, i-j))); + i+=3; + // get arithmetic + auto r=parse_arithmetic(in, size, i); + ret.sa.push_back(r.first); + j = i = r.second; + } else if( word_eq("$(", in, size, i) ) // substitution { - // add string subarg + // add previous subarg ret.sa.push_back(subarg(std::string(in+j, i-j))); i+=2; - // add subshell subarg + // get subshell auto r=parse_subshell(in, size, i); ret.sa.push_back(subarg(r.first)); j = i = r.second; @@ -142,10 +171,22 @@ std::pair parse_arg(const char* in, uint32_t size, uint32_t start throw ztd::format_error("Unterminated single quote", g_origin, in, q); i++; } + else if( word_eq("$((", in, size, i) ) // arithmetic operation + { + // add previous subarg + ret.sa.push_back(subarg(std::string(in+j, i-j))); + i+=3; + // get arithmetic + auto r=parse_arithmetic(in, size, i); + ret.sa.push_back(r.first); + j = i = r.second; + } else if( word_eq("$(", in, size, i) ) // substitution { + // add previous subarg ret.sa.push_back(subarg(std::string(in+j, i-j))); i+=2; + // get subshell auto r=parse_subshell(in, size, i); ret.sa.push_back(subarg(r.first)); j = i = r.second;