Add basic arithmetic parse
This commit is contained in:
parent
577a1aef94
commit
01244e6ab1
4 changed files with 52 additions and 4 deletions
|
|
@ -1,2 +1,4 @@
|
||||||
# lxsh
|
# lxsh
|
||||||
Extended shell linker
|
Extended shell linker
|
||||||
|
|
||||||
|
Work in progress
|
||||||
|
|
|
||||||
|
|
@ -168,7 +168,7 @@ class subarg
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// type
|
// type
|
||||||
enum argtype { string, subshell };
|
enum argtype { string, subshell, arithmetic };
|
||||||
argtype type;
|
argtype type;
|
||||||
|
|
||||||
// ctor
|
// ctor
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,6 @@ std::string generate_resolve(std::vector<std::string> args, int ind)
|
||||||
throw std::runtime_error("Cannot cd to '"+cddir+"'");
|
throw std::runtime_error("Cannot cd to '"+cddir+"'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// exec call
|
// exec call
|
||||||
auto p=ztd::shp("exec "+cmd);
|
auto p=ztd::shp("exec "+cmd);
|
||||||
|
|
||||||
|
|
@ -210,6 +209,8 @@ std::string generate_include(std::vector<std::string> args, int ind)
|
||||||
file=import_file(it);
|
file=import_file(it);
|
||||||
if(opts['d'])
|
if(opts['d'])
|
||||||
file = stringReplace(file, "\"", "\\\"");
|
file = stringReplace(file, "\"", "\\\"");
|
||||||
|
if(opts['s'])
|
||||||
|
file = stringReplace(file, "'", "'\\''");
|
||||||
if(opts['r'])
|
if(opts['r'])
|
||||||
ret += file;
|
ret += file;
|
||||||
else
|
else
|
||||||
|
|
@ -378,6 +379,10 @@ std::string subarg::generate(int ind)
|
||||||
{
|
{
|
||||||
ret += val;
|
ret += val;
|
||||||
}
|
}
|
||||||
|
else if(type == subarg::arithmetic)
|
||||||
|
{
|
||||||
|
ret += "$(("+val+"))";
|
||||||
|
}
|
||||||
else if(type == subarg::subshell)
|
else if(type == subarg::subshell)
|
||||||
{
|
{
|
||||||
// includes and resolves inside command substitutions
|
// includes and resolves inside command substitutions
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,25 @@ uint32_t skip_unread(const char* in, uint32_t size, uint32_t start)
|
||||||
|
|
||||||
std::pair<block, uint32_t> parse_subshell(const char* in, uint32_t size, uint32_t start);
|
std::pair<block, uint32_t> 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<subarg, uint32_t> 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
|
// parse one argument
|
||||||
// must start at a read char
|
// must start at a read char
|
||||||
// ends at either " \t|&;\n()"
|
// ends at either " \t|&;\n()"
|
||||||
|
|
@ -114,12 +133,22 @@ std::pair<arg, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t start
|
||||||
{
|
{
|
||||||
i+=2;
|
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
|
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)));
|
ret.sa.push_back(subarg(std::string(in+j, i-j)));
|
||||||
i+=2;
|
i+=2;
|
||||||
// add subshell subarg
|
// get subshell
|
||||||
auto r=parse_subshell(in, size, i);
|
auto r=parse_subshell(in, size, i);
|
||||||
ret.sa.push_back(subarg(r.first));
|
ret.sa.push_back(subarg(r.first));
|
||||||
j = i = r.second;
|
j = i = r.second;
|
||||||
|
|
@ -142,10 +171,22 @@ std::pair<arg, uint32_t> parse_arg(const char* in, uint32_t size, uint32_t start
|
||||||
throw ztd::format_error("Unterminated single quote", g_origin, in, q);
|
throw ztd::format_error("Unterminated single quote", g_origin, in, q);
|
||||||
i++;
|
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
|
else if( word_eq("$(", in, size, i) ) // substitution
|
||||||
{
|
{
|
||||||
|
// add previous subarg
|
||||||
ret.sa.push_back(subarg(std::string(in+j, i-j)));
|
ret.sa.push_back(subarg(std::string(in+j, i-j)));
|
||||||
i+=2;
|
i+=2;
|
||||||
|
// get subshell
|
||||||
auto r=parse_subshell(in, size, i);
|
auto r=parse_subshell(in, size, i);
|
||||||
ret.sa.push_back(subarg(r.first));
|
ret.sa.push_back(subarg(r.first));
|
||||||
j = i = r.second;
|
j = i = r.second;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue