This commit is contained in:
brad Arant 2024-11-20 08:51:29 -08:00
commit 64fd81d6ed
16 changed files with 176 additions and 63 deletions

View File

@ -7,7 +7,7 @@
namespace jet { namespace jet {
Global::Global() { Global::Global(char **envp) : envp(envp) {
} }
@ -108,7 +108,7 @@ namespace jet {
name << getVariable(variable, lvariables); name << getVariable(variable, lvariables);
else if(variable.ifNext("]")) else if(variable.ifNext("]"))
return; return;
else if(!variable.ifNextInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-")) else if(!variable.ifNextInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._-"))
throw coreutils::Exception("invalid variable name."); throw coreutils::Exception("invalid variable name.");
} }
return; return;

View File

@ -11,7 +11,7 @@ namespace jet {
class Global { class Global {
public: public:
Global(); Global(char **envp);
virtual ~Global(); virtual ~Global();
void dump(); void dump();
@ -30,7 +30,8 @@ namespace jet {
std::map<coreutils::MString, __mysql *> sessions; std::map<coreutils::MString, __mysql *> sessions;
std::map<coreutils::MString, coreutils::MString> headers; std::map<coreutils::MString, coreutils::MString> headers;
std::map<coreutils::MString, coreutils::MString> tags; std::map<coreutils::MString, coreutils::MString> tags;
coreutils::MString lastConverted; coreutils::MString lastConverted;
char **envp;
}; };

View File

@ -111,15 +111,22 @@ operators, as follows:
\section{Function Reference} \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. 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 Use the substring operation to extract a portion of a string and return
the value as a string. the value as a string.
@ -170,6 +177,8 @@ name
input input
error
\begin{verbatim} \begin{verbatim}
<call pgm="ls" arg1="-al" name="listing" /> <call pgm="ls" arg1="-al" name="listing" />
\end{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 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. used for making comments and is ignored by the jet reader.
The comments tag has no attributes.
\section{expr} \section{expr}
\section{for} \section{for}
Use the for tag to iterate a tag container for a logical number of Use the for tag to iterate a tag container for a logical number of
times. times.
The attributes are:
start
end
step
name
\section{header} \section{header}
Use the header tag to output a header prior to outputting the process Use the header tag to output a header prior to outputting the process
buffer to the requester. buffer to the requester.
The attributes are:
name
expr
value
container
\section{if/else} \section{if/else}
Use the if tag to perform a conditional output on the tag container. Use the if tag to perform a conditional output on the tag container.
An optional else container provides alternate output in the event the An optional else container provides alternate output in the event the
condition is not met. condition is not met.
The attributes are:
value1
value2
type
expr
\section{ifrow/else} \section{ifrow/else}
Use the ifrow tag to output the tag container if a row exists in the 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} \section{jet}
@ -217,19 +270,50 @@ to control the output options.
Use the mysql tag to specify parameters for connecting to a mysql 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 server. The container of the tag is where you can specify the sql
statement and method of processing the result output of the executed 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} \section{read}
Use the read tag to read the contents of a file contained on the local 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. file system into a variable for further output or processing.
The attributes are:
file
name
\section{set} \section{set}
Use the set tag to store initialize a variable to a value contained in 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 a value attribute, the result of an expression (expr) attribute or the
contents of the set tag container. contents of the set tag container.
The attributes are:
name
expr
value
container
scope
\section{sql} \section{sql}
Use the sql tag to specify an sql statement to run on the sql server 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 containing tag then the same mysql session is used for each sql
statement. statement.
The attributes are:
sessionid
container
\section{stream} \section{stream}
Use stream tag to output data from the server without waiting for the 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 useful for outputting images and streams for audio and video without
the server having to load the whole thing into RAM first. the server having to load the whole thing into RAM first.
The attributes are:
file
\section{system} \section{system}
Use the system tag to execute a bash shell command within the JET Use the system tag to execute a bash shell command within the JET

View File

@ -53,7 +53,16 @@ namespace jet {
} else } else
throw coreutils::Exception("Expecting ) at end of LEFT expression."); throw coreutils::Exception("Expecting ) at end of LEFT expression.");
} else if(in.ifNextIgnoreCase("EXPR")) { } 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("RIGHT")) {
} else if(in.ifNextIgnoreCase("TRIM")) { } else if(in.ifNextIgnoreCase("TRIM")) {
@ -90,7 +99,8 @@ namespace jet {
string = in.getTokenExclude("'"); string = in.getTokenExclude("'");
in.ifNext("'"); in.ifNext("'");
isNumber = false; isNumber = false;
} } else
throw coreutils::Exception("operand is not valid.");
in.skipWhitespace(); in.skipWhitespace();
@ -284,7 +294,6 @@ namespace jet {
throw coreutils::Exception("operand is not a number."); throw coreutils::Exception("operand is not a number.");
} else } else
return; return;
} }
} }

View File

@ -108,7 +108,7 @@ namespace jet {
} }
void Tag::resolveKeyword(coreutils::ZString keyword) { 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) { void Tag::processContainer(coreutils::ZString &container, coreutils::ZString container2) {

View File

@ -33,7 +33,7 @@ namespace jet {
dup2(fdo[1], 1); dup2(fdo[1], 1);
if(variableDefined("input")) { if(variableDefined("input")) {
resolveKeyword("input"); resolveKeyword("input");
coreutils::ZString input(variables[variables["input"]]); coreutils::ZString input(variables["input"]);
pipe(fdi); pipe(fdi);
if(fork() == 0) { if(fork() == 0) {
close(fdi[0]); close(fdi[0]);
@ -41,12 +41,12 @@ namespace jet {
close(fdi[1]); close(fdi[1]);
exit(0); exit(0);
} }
close(fdi[0]); close(fdi[1]);
dup2(fdi[0], 0); dup2(fdi[0], 0);
} }
rc = execve(variables["pgm"].c_str(), argv, NULL); rc = execvpe(variables["pgm"].c_str(), argv, global.envp);
close(fdo[1]); close(fdo[1]);
exit(rc); exit(errno);
} }
close(fdo[1]); close(fdo[1]);
if(variableDefined("name")) { if(variableDefined("name")) {
@ -63,9 +63,10 @@ namespace jet {
} else } else
out.read(fdo[0]); out.read(fdo[0]);
waitpid(pid, &status, 0); waitpid(pid, &status, 0);
if(variableDefined("status")) if(variableDefined("error")) {
resolveKeyword("status"); resolveKeyword("error");
global.variables[variables["status"]] = (status >> 8 & 255); global.variables[variables["error"]] = (status >> 8 & 255);
}
} }
} }

View File

@ -19,26 +19,14 @@ namespace jet {
coreutils::IMFRequest request(postdata); coreutils::IMFRequest request(postdata);
coreutils::IMFMessage message(postdata); coreutils::IMFMessage message(postdata);
if(contentType == "multipart/form-data") if(contentType == "multipart/form-data")
std::cout << "output multipart variables to global" << std::endl; std::cout << "output multipart variables to global" << std::endl;
else if(contentType == "application/x-www-form-urlencoded") else if(contentType == "application/x-www-form-urlencoded")
std::cout << "output urlencoded variables to global" << std::endl; std::cout << "output urlencoded variables to global" << std::endl;
} }
} }
processContainer(container);
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;
}
} }
} }

View File

@ -11,25 +11,16 @@ namespace jet {
__system::__system(coreutils::ZString &in, coreutils::MString &parentOut, Global &global, Tag *parent) : Tag(in, parentOut, global, parent) { __system::__system(coreutils::ZString &in, coreutils::MString &parentOut, Global &global, Tag *parent) : Tag(in, parentOut, global, parent) {
if(hasContainer) if(hasContainer)
throw coreutils::Exception("system tag cannot have a container."); throw coreutils::Exception("system tag cannot have a container.");
if(!variableDefined(coreutils::ZString("pgm"))) if(!variableDefined(coreutils::ZString("cmd")))
throw coreutils::Exception("pgm keyword must be specified."); throw coreutils::Exception("cmd 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;
pipe(fdo); pipe(fdo);
pid = fork(); pid = fork();
if(pid == 0) { if(pid == 0) {
close(fdo[0]); close(fdo[0]);
dup2(fdo[1], 1); dup2(fdo[1], 1);
if(variableDefined("input")) { if(variableDefined("input")) {
coreutils::ZString input(variables[variables["input"]]); resolveKeyword("input");
coreutils::ZString input(variables["input"]);
pipe(fdi); pipe(fdi);
if(fork() == 0) { if(fork() == 0) {
close(fdi[0]); close(fdi[0]);
@ -37,13 +28,12 @@ namespace jet {
close(fdi[1]); close(fdi[1]);
exit(0); exit(0);
} }
close(fdi[0]); close(fdi[1]);
dup2(fdi[0], 0); dup2(fdi[0], 0);
} }
rc = execve(variables["pgm"].c_str(), argv, NULL); system(variables["cmd"].c_str());
close(fdo[1]); close(fdo[1]);
std::cout << "rc: " << rc << std::endl; exit(errno);
exit(rc);
} }
close(fdo[1]); close(fdo[1]);
if(variableDefined("name")) if(variableDefined("name"))
@ -51,7 +41,6 @@ namespace jet {
else else
out.read(fdo[0]); out.read(fdo[0]);
waitpid(pid, &status, 0); waitpid(pid, &status, 0);
std::cout << "status: " << status << std::endl;
} }
} }

View File

@ -29,5 +29,3 @@ fi
rm *.o rm *.o
rm *~ rm *~

View File

@ -5,14 +5,14 @@
#include "Exception.h" #include "Exception.h"
#include "__jet.h" #include "__jet.h"
int main(int argc, char **argv) { int main(int argc, char **argv, char **envp) {
coreutils::File script(argv[1]); coreutils::File script(argv[1]);
script.read(); script.read();
coreutils::ZString data = script.asZString(); coreutils::ZString data = script.asZString();
data.goeol(); data.goeol();
jet::Global global; jet::Global global(envp);
try { try {
coreutils::MString out; coreutils::MString out;
@ -22,6 +22,9 @@ int main(int argc, char **argv) {
std::cout << out; std::cout << out;
} }
catch(coreutils::Exception e) { 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; std::cout << "Error caught: " << e.text << std::endl;
global.dump(); global.dump();
} }

8
tests/testcall.jet Executable file
View File

@ -0,0 +1,8 @@
#!../jet-2.0
<jet name1="localname" filterblanklines="true" trimlines="true">
<set name="abc" value="abcdefg" />
<call pgm="cat" error="error" input="$[abc]xyz" name="test1" />
test1=$[test1]
name1=#[localname]
error=$[error]
</jet>

9
tests/testexpr.jet Executable file
View File

@ -0,0 +1,9 @@
#!../jet-2.0
<jet name1="localname" filterblanklines="true" trimlines="true">
<set name="test1" value="5 + 5" />
<set name="test2" expr="expr($[test1])" />
$[test2]
<set name="numbers">0123456789</set>
<set name="lefty" expr="left($[numbers],5)" />
$[lefty]
</jet>

View File

@ -1,4 +1,4 @@
#!../jet-2.0 #!/home/barant/Development/JetCore/jet-2.0
<jet cgi="true" name1="localname" filterblanklines="true" trimlines="true"> <jet cgi="true" name1="localname" filterblanklines="true" trimlines="true">
<header name="Content-Type" value="text/html" /> <header name="Content-Type" value="text/html" />
<comment>This is a comment and should not show up in the output.</comment> <comment>This is a comment and should not show up in the output.</comment>
@ -21,9 +21,9 @@
<set name="division" expr="5/3" /> <set name="division" expr="5/3" />
<set name="divisor" value="8" /> <set name="divisor" value="8" />
<set name="nested" expr="(2*(4+4)/$[divisor])*32" /> <set name="nested" expr="(2*(4+4)/$[divisor])*32" />
$[nested] $[$nested]
<set name="numbers">0123456789</set> <set name="numbers">0123456789</set>
<set name="lefty" expr="LEFT('$[numbers]',5)" /> <set name="lefty" expr="LEFT($[numbers],5)" />
lefty=[$[lefty]] lefty=[$[lefty]]
substring('abcdefg', 1, 3)=[$[theexpr]] substring('abcdefg', 1, 3)=[$[theexpr]]
5+3=($[addition]) 5+3=($[addition])

8
tests/testsystem.jet Executable file
View File

@ -0,0 +1,8 @@
#!../jet-2.0
<jet name1="localname" filterblanklines="true" trimlines="true">
<set name="abc" value="abcdefg" />
<system cmd="cats" input="$[abc]xyz" name="test1" />
test1=$[test1]
name1=#[localname]
error=$[error]
</jet>

View File

@ -1,10 +1,14 @@
#!../jet-2.0 #!../jet-2.0
<jet name1="localhost" filterblanklines="true" trimlines="true">
<set name="test1" value="#[name1]" />
test1=[$[test1]]
<set name="ix" value="1" /> <set name="ix" value="1" />
<set name="letterx" value="x" /> <set name="letterx" value="x" />
<set name="var$[ix]" value="this is a test $[ix]" /> <set name="var$[ix]" value="this is a test $[ix]" />
<set name="1var1" value="This is another test" /> <set name="1var1" value="This is another test" />
<set name="var1var" value="Yet another test" /> <set name="var1var" value="Yet another test" />
<set name="var11" value="it seems to work." /> <set name="var11" value="it seems to work." />
name1=[#[name1]]
$[$[ix]var$[ix];binary] $[$[ix]var$[ix];binary]
$[var$[ix]] $[var$[ix]]
$[var$[ix]var] $[var$[ix]var]
@ -15,3 +19,4 @@ $[var$[i$[letterx]]$[i$[letterx]]]
$[ix] $[ix]
<set name="ix" expr="$[ix]+1" /> <set name="ix" expr="$[ix]+1" />
$[ix] $[ix]
</jet>

View File

@ -1,8 +1,8 @@
#!../jet-2.0 #!../jet-2.0
<jet cgi="false" name1="localname" filterblanklines="true" trimlines="true"> <jet cgi="false" name1="localname" filterblanklines="true" trimlines="true">
<set name="ix" value="1" /> <set name="ix" value="1" />
<while expr="$[ix]<=11"> <while expr="$[ix] <= 11">
-->$[ix]<-- -->$[ix]<--
<set name="ix" expr="$[ix]+1" /> <set name="ix" expr="$[ix] + 1" />
</while> </while>
</jet> </jet>