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 {
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;

View File

@ -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<coreutils::MString, __mysql *> sessions;
std::map<coreutils::MString, coreutils::MString> headers;
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}
\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}
<call pgm="ls" arg1="-al" name="listing" />
\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

View File

@ -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;
}
}

View File

@ -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) {

View File

@ -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);
}
}
}

View File

@ -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);
}
}

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) {
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;
}
}

View File

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

View File

@ -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();
}

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">
<header name="Content-Type" value="text/html" />
<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="divisor" value="8" />
<set name="nested" expr="(2*(4+4)/$[divisor])*32" />
$[nested]
$[$nested]
<set name="numbers">0123456789</set>
<set name="lefty" expr="LEFT('$[numbers]',5)" />
<set name="lefty" expr="LEFT($[numbers],5)" />
lefty=[$[lefty]]
substring('abcdefg', 1, 3)=[$[theexpr]]
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 name1="localhost" filterblanklines="true" trimlines="true">
<set name="test1" value="#[name1]" />
test1=[$[test1]]
<set name="ix" value="1" />
<set name="letterx" value="x" />
<set name="var$[ix]" value="this is a test $[ix]" />
<set name="1var1" value="This is another test" />
<set name="var1var" value="Yet another test" />
<set name="var11" value="it seems to work." />
name1=[#[name1]]
$[$[ix]var$[ix];binary]
$[var$[ix]]
$[var$[ix]var]
@ -15,3 +19,4 @@ $[var$[i$[letterx]]$[i$[letterx]]]
$[ix]
<set name="ix" expr="$[ix]+1" />
$[ix]
</jet>

View File

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