diff --git a/Global.cpp b/Global.cpp index 05fbc56..9917c94 100644 --- a/Global.cpp +++ b/Global.cpp @@ -7,7 +7,7 @@ namespace jet { - Global::Global() { + Global::Global(char **envp) : envp(envp) { } @@ -108,7 +108,7 @@ namespace jet { name << getVariable(variable, lvariables); else if(variable.ifNext("]")) return; - else if(!variable.ifNextInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-")) + else if(!variable.ifNextInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-")) throw coreutils::Exception("invalid variable name."); } return; diff --git a/Global.h b/Global.h index 9a055e3..58a4ffe 100644 --- a/Global.h +++ b/Global.h @@ -11,7 +11,7 @@ namespace jet { class Global { public: - Global(); + Global(char **envp); virtual ~Global(); void dump(); @@ -30,7 +30,8 @@ namespace jet { std::map sessions; std::map headers; std::map tags; - coreutils::MString lastConverted; + coreutils::MString lastConverted; + char **envp; }; diff --git a/JetCore.txt b/JetCore.txt index a4ef490..e38db4e 100644 --- a/JetCore.txt +++ b/JetCore.txt @@ -111,15 +111,22 @@ operators, as follows: \section{Function Reference} -\subsection{left(string, number-of-characters)} +\subsection{concat} -\subsection{random()} +\subsection{integer} + +\subsection{left} + +\subsection{random} Use the random function to return a random number between 0 and 1. -\subsection{substring(string, start-position, number-of-characters} +\subsection{round} +Use the round function to round a numeric value to the specified +number of digits after the decimal point. +\subsection{substring} Use the substring operation to extract a portion of a string and return the value as a string. @@ -170,6 +177,8 @@ name input +error + \begin{verbatim} \end{verbatim} @@ -182,30 +191,74 @@ a variable named 'listing'. Use the comment tag to create a section in the jet script that can be used for making comments and is ignored by the jet reader. +The comments tag has no attributes. + \section{expr} - - \section{for} Use the for tag to iterate a tag container for a logical number of times. +The attributes are: + +start + +end + +step + +name + \section{header} Use the header tag to output a header prior to outputting the process buffer to the requester. +The attributes are: + +name + +expr + +value + +container + \section{if/else} Use the if tag to perform a conditional output on the tag container. An optional else container provides alternate output in the event the condition is not met. +The attributes are: + +value1 + +value2 + +type + +expr + \section{ifrow/else} Use the ifrow tag to output the tag container if a row exists in the -mysql tag. +mysql tag. An optional else container provides alternate output in the +event that there is no row for the sql result. + +The attributes are: + +sessionid + +\section{include} + +Use the include tag to include another content file at the location of +the include tag. + +The attributes are: + +file \section{jet} @@ -217,19 +270,50 @@ to control the output options. Use the mysql tag to specify parameters for connecting to a mysql server. The container of the tag is where you can specify the sql statement and method of processing the result output of the executed -sql statement. +sql statement. The mysql session created is valid only withon the +container of this tag. + +The attributes are: + +host + +database + +user + +password + +sessionid \section{read} Use the read tag to read the contents of a file contained on the local file system into a variable for further output or processing. +The attributes are: + +file + +name + \section{set} Use the set tag to store initialize a variable to a value contained in a value attribute, the result of an expression (expr) attribute or the contents of the set tag container. +The attributes are: + +name + +expr + +value + +container + +scope + \section{sql} Use the sql tag to specify an sql statement to run on the sql server @@ -239,6 +323,12 @@ As long as sql statements are executed within the same mysql containing tag then the same mysql session is used for each sql statement. +The attributes are: + +sessionid + +container + \section{stream} Use stream tag to output data from the server without waiting for the @@ -246,6 +336,10 @@ standard output buffering and processing of the JET script. This is useful for outputting images and streams for audio and video without the server having to load the whole thing into RAM first. +The attributes are: + +file + \section{system} Use the system tag to execute a bash shell command within the JET diff --git a/Operand.cpp b/Operand.cpp index aee75f0..2d9ff01 100644 --- a/Operand.cpp +++ b/Operand.cpp @@ -53,7 +53,16 @@ namespace jet { } else throw coreutils::Exception("Expecting ) at end of LEFT expression."); } else if(in.ifNextIgnoreCase("EXPR")) { - + if(!in.ifNext("(")) + throw coreutils::Exception("Expecting ( for EXPR parameters."); + Operand parm1(in, global, lvariables); + if(in.ifNext(")")) { + Operand op(parm1.string, global, lvariables); + string = op.string; + isNumber = op.isNumber; + boolean = op.boolean; + } else + throw coreutils::Exception("Expecting ) at end of EXPR expression."); } else if(in.ifNextIgnoreCase("RIGHT")) { } else if(in.ifNextIgnoreCase("TRIM")) { @@ -90,7 +99,8 @@ namespace jet { string = in.getTokenExclude("'"); in.ifNext("'"); isNumber = false; - } + } else + throw coreutils::Exception("operand is not valid."); in.skipWhitespace(); @@ -284,7 +294,6 @@ namespace jet { throw coreutils::Exception("operand is not a number."); } else return; - } } diff --git a/Tag.cpp b/Tag.cpp index 50012b0..69a2848 100644 --- a/Tag.cpp +++ b/Tag.cpp @@ -108,7 +108,7 @@ namespace jet { } void Tag::resolveKeyword(coreutils::ZString keyword) { - variables[keyword] = KeywordValue(variables[keyword], global, variables); + variables[keyword] = KeywordValue(variables[keyword], global, parent->variables); } void Tag::processContainer(coreutils::ZString &container, coreutils::ZString container2) { diff --git a/__call.cpp b/__call.cpp index f3e8b5d..5772756 100644 --- a/__call.cpp +++ b/__call.cpp @@ -33,7 +33,7 @@ namespace jet { dup2(fdo[1], 1); if(variableDefined("input")) { resolveKeyword("input"); - coreutils::ZString input(variables[variables["input"]]); + coreutils::ZString input(variables["input"]); pipe(fdi); if(fork() == 0) { close(fdi[0]); @@ -41,12 +41,12 @@ namespace jet { close(fdi[1]); exit(0); } - close(fdi[0]); + close(fdi[1]); dup2(fdi[0], 0); } - rc = execve(variables["pgm"].c_str(), argv, NULL); + rc = execvpe(variables["pgm"].c_str(), argv, global.envp); close(fdo[1]); - exit(rc); + exit(errno); } close(fdo[1]); if(variableDefined("name")) { @@ -63,9 +63,10 @@ namespace jet { } else out.read(fdo[0]); waitpid(pid, &status, 0); - if(variableDefined("status")) - resolveKeyword("status"); - global.variables[variables["status"]] = (status >> 8 & 255); + if(variableDefined("error")) { + resolveKeyword("error"); + global.variables[variables["error"]] = (status >> 8 & 255); + } } } diff --git a/__jet.cpp b/__jet.cpp index 275e515..5ad4385 100644 --- a/__jet.cpp +++ b/__jet.cpp @@ -19,26 +19,14 @@ namespace jet { coreutils::IMFRequest request(postdata); coreutils::IMFMessage message(postdata); - - - + if(contentType == "multipart/form-data") std::cout << "output multipart variables to global" << std::endl; else if(contentType == "application/x-www-form-urlencoded") std::cout << "output urlencoded variables to global" << std::endl; } } - - try { - processContainer(container); - } - catch(coreutils::Exception e) { - std::cout << container.parsed() << std::endl; - std::cout << "***** " << e.text << std::endl; - std::cout << container.unparsed() << std::endl; - throw e; - } - + processContainer(container); } } diff --git a/__system.cpp b/__system.cpp index 626d2e6..1f62b39 100644 --- a/__system.cpp +++ b/__system.cpp @@ -11,25 +11,16 @@ namespace jet { __system::__system(coreutils::ZString &in, coreutils::MString &parentOut, Global &global, Tag *parent) : Tag(in, parentOut, global, parent) { if(hasContainer) throw coreutils::Exception("system tag cannot have a container."); - if(!variableDefined(coreutils::ZString("pgm"))) - throw coreutils::Exception("pgm keyword must be specified."); - argv[0] = variables["pgm"].c_str(); // TODO: Need to peel off the program name only and pass as argv[0]. - for(ix = 1; ix <= 50; ++ix) { - coreutils::MString arg("arg"); - arg << ix; - if(variableDefined(arg)) - argv[ix] = variables[arg].c_str(); - else - break; - } - argv[ix] == NULL; + if(!variableDefined(coreutils::ZString("cmd"))) + throw coreutils::Exception("cmd keyword must be specified."); pipe(fdo); pid = fork(); if(pid == 0) { close(fdo[0]); dup2(fdo[1], 1); if(variableDefined("input")) { - coreutils::ZString input(variables[variables["input"]]); + resolveKeyword("input"); + coreutils::ZString input(variables["input"]); pipe(fdi); if(fork() == 0) { close(fdi[0]); @@ -37,13 +28,12 @@ namespace jet { close(fdi[1]); exit(0); } - close(fdi[0]); + close(fdi[1]); dup2(fdi[0], 0); } - rc = execve(variables["pgm"].c_str(), argv, NULL); + system(variables["cmd"].c_str()); close(fdo[1]); - std::cout << "rc: " << rc << std::endl; - exit(rc); + exit(errno); } close(fdo[1]); if(variableDefined("name")) @@ -51,7 +41,6 @@ namespace jet { else out.read(fdo[0]); waitpid(pid, &status, 0); - std::cout << "status: " << status << std::endl; } } diff --git a/compile b/compile index 197152f..2df9a61 100755 --- a/compile +++ b/compile @@ -29,5 +29,3 @@ fi rm *.o rm *~ - - diff --git a/jet-2.0.cpp b/jet-2.0.cpp index 2b14ce5..59191cb 100644 --- a/jet-2.0.cpp +++ b/jet-2.0.cpp @@ -5,14 +5,14 @@ #include "Exception.h" #include "__jet.h" -int main(int argc, char **argv) { +int main(int argc, char **argv, char **envp) { coreutils::File script(argv[1]); script.read(); coreutils::ZString data = script.asZString(); data.goeol(); - jet::Global global; + jet::Global global(envp); try { coreutils::MString out; @@ -22,6 +22,9 @@ int main(int argc, char **argv) { std::cout << out; } catch(coreutils::Exception e) { + std::cout << data.parsed() << std::endl; + std::cout << "******** Error caught: " << e.text << std::endl; + std::cout << data.unparsed() << std::endl; std::cout << "Error caught: " << e.text << std::endl; global.dump(); } diff --git a/tests/testcall.jet b/tests/testcall.jet new file mode 100755 index 0000000..be1f8bb --- /dev/null +++ b/tests/testcall.jet @@ -0,0 +1,8 @@ +#!../jet-2.0 + + + +test1=$[test1] +name1=#[localname] +error=$[error] + diff --git a/tests/testexpr.jet b/tests/testexpr.jet new file mode 100755 index 0000000..f159e5a --- /dev/null +++ b/tests/testexpr.jet @@ -0,0 +1,9 @@ +#!../jet-2.0 + + + +$[test2] +0123456789 + +$[lefty] + diff --git a/tests/testjet.jet b/tests/testjet.jet index 7bfba38..fa9822f 100755 --- a/tests/testjet.jet +++ b/tests/testjet.jet @@ -1,4 +1,4 @@ -#!../jet-2.0 +#!/home/barant/Development/JetCore/jet-2.0
This is a comment and should not show up in the output. @@ -21,9 +21,9 @@ - $[nested] + $[$nested] 0123456789 - + lefty=[$[lefty]] substring('abcdefg', 1, 3)=[$[theexpr]] 5+3=($[addition]) diff --git a/tests/testsystem.jet b/tests/testsystem.jet new file mode 100755 index 0000000..9b0e959 --- /dev/null +++ b/tests/testsystem.jet @@ -0,0 +1,8 @@ +#!../jet-2.0 + + + +test1=$[test1] +name1=#[localname] +error=$[error] + diff --git a/tests/testvar.jet b/tests/testvar.jet index 8527c75..3c79fed 100755 --- a/tests/testvar.jet +++ b/tests/testvar.jet @@ -1,10 +1,14 @@ #!../jet-2.0 + + +test1=[$[test1]] +name1=[#[name1]] $[$[ix]var$[ix];binary] $[var$[ix]] $[var$[ix]var] @@ -15,3 +19,4 @@ $[var$[i$[letterx]]$[i$[letterx]]] $[ix] $[ix] + diff --git a/tests/testwhile.jet b/tests/testwhile.jet index a3c3628..95b0e3a 100755 --- a/tests/testwhile.jet +++ b/tests/testwhile.jet @@ -1,8 +1,8 @@ #!../jet-2.0 - + -->$[ix]<-- - +