commit fce97e04ff363f21ec48b30252a7d290cd205870 Author: Brad Arant Date: Thu May 19 11:43:15 2022 -0700 Initial repository commit. diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..1211532 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,17 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu17", + "cppStandard": "gnu++14", + "intelliSenseMode": "linux-gcc-x64", + "configurationProvider": "ms-vscode.cmake-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..82cfcc9 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.configureOnOpen": false +} \ No newline at end of file diff --git a/Tag.cpp b/Tag.cpp new file mode 100644 index 0000000..1837d0c --- /dev/null +++ b/Tag.cpp @@ -0,0 +1,220 @@ +#include "Tag.h" +#include "Exception.h" +#include "Log.h" +#include "__mysql.h" +#include "__for.h" +#include "__if.h" +#include "__read.h" +#include "__set.h" +#include "__jet.h" +#include "__while.h" +#include + +namespace jet { + + Tag::Tag(coreutils::ZString &in, coreutils::MString &parent) + : ZString(in), parent(parent) { + if(in.ifNext("<")) { + name = in.getTokenInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_!"); + if(in.startsWith(" ") || in.startsWith("/") || in.startsWith(">")) { + coreutils::Log(coreutils::LOG_DEBUG_1) << "Processing tag: " << name; + bool finished = false; + while(!finished) { + in.skipWhitespace(); + if(in.ifNext(">")) { + hasContainer = true; + finished = true; + break; + } else if(in.ifNext("/>")) { + hasContainer = false; + finished = true; + break; + } + if(!finished) { + coreutils::ZString keywordName = in.getTokenInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"); + if(in.ifNext("=\"")) { + keywords[keywordName] = in.getTokenExclude("\""); + } + if(!in.ifNext("\"")) {} + } + } + if(hasContainer) { + coreutils::Log(coreutils::LOG_DEBUG_2) << "has Container: " << hasContainer; + char *start = in.getCursor(); + while(!in.eod()) { + char *end = in.getCursor(); + if(ifEndTagName(in)) { + container = coreutils::ZString(start, end - start); + coreutils::Log(coreutils::LOG_DEBUG_2) << "Container: [" << container << "]"; + break; + } else if(ifNested(in)) {} + else + in.nextChar(); + } + } + setZString(in.parsed()); + if(hasContainer && evaluate) + parseContainer(container); + } + } else + throw coreutils::Exception("First character of (in) must be a <."); + } + + Tag::~Tag() { + if(evaluate) { + copyContainer(out, parent); + } else { + copyContainer(container, parent); + } + } + + void Tag::parseContainer(coreutils::ZString &in) { + char *start = in.getCursor(); + while(!in.eod()) { + if(in.startsWith("<")) { + if(ifTagName(in, "mysql")) { + __mysql _mysql(in, out); + continue; + } else if(ifTagName(in, "for")) { + __for _for(in, out); + continue; + } else if(ifTagName(in, "if")) { + __if _if(in, out); + continue; + } else if(ifTagName(in, "jet")) { + __jet _jet(in, out); + continue; + } else if(ifTagName(in, "read")) { + __read _read(in, out); + continue; + } else if(ifTagName(in, "set")) { + __set _set(in, out); + continue; + } else if(ifTagName(in, "while")) { + __while _while(in, out); + continue; + } + } + out.write(in.charAt(0)); + in.nextChar(); + } + } + + void Tag::scanContainer(coreutils::ZString &in) { + while(!in.eod()) { + if(ifEndTagName(in)) + return; + else if(ifNested(in)) {} + else in.nextChar(); + } + } + + bool Tag::ifTagName(coreutils::ZString &in, const char *tag) { + in.push(); + if(in.ifNext("<")) + if(in.getTokenInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_").equals(tag)) { + if(in.ifNext(" ")) { + in.pop(); + return true; + } else if(in.ifNext("/>")) { + in.pop(); + return true; + } else if(in.ifNext(">")) { + in.pop(); + return true; + } + } + in.pop(); + return false; + } + + bool Tag::ifTagName(coreutils::ZString &in) { + in.push(); + if(in.ifNext("<")) + if(in.getTokenInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_").equals(name)) { + in.push(); + if(in.ifNext(" ")) { + in.pop(); + return true; + } else if(in.ifNext("/>")) { + in.pop(); + return true; + } else if(in.ifNext(">")) { + in.pop(); + return true; + } + in.pop(); + } + in.pop(); + return false; + } + + bool Tag::ifEndTagName(coreutils::ZString &in) { + in.push(); + if(in.ifNext("")) + return true; + } + in.pop(); + return false; + } + + int Tag::skipBlankLine(coreutils::ZString in) { + ZString temp = in.getTokenInclude(" \t"); + if(ifNext("\n")) + return temp.getLength() + 1; + return 0; + } + + void Tag::copyContainer(coreutils::ZString &in, coreutils::MString &out) { + while(!in.eod()) { + if(filterBlankLines) { + in.push(); + if(!in.eod()) { + in.getTokenInclude(" \t"); + if(!in.ifNext("\n")) { + in.pop(); + // TODO: shouod be safe to output line here. + } + } + } + else { + out.write(in.charAt(0)); + in.nextChar(); + } + } + } + + bool Tag::keywordExists(coreutils::ZString keyword) { + return keywords.find(keyword) != keywords.end(); + } + + bool Tag::ifNested(coreutils::ZString &in) { + bool hasContainer = false; + if(ifTagName(in)) { + while(!in.eod()) { + in.skipWhitespace(); + if(in.ifNext(">")) { + hasContainer = true; + break; + } else if(in.ifNext("/>")) { + hasContainer = false; + return true; + } else if(in.getTokenExclude("=").getLength() != 0) { + if(in.ifNext("=\"")) { + while(1) { + if(in.ifNext("\"")) { + break; + } + in.nextChar(); + } + } + } + } + if(hasContainer) + scanContainer(in); + } + return false; + } +} diff --git a/Tag.h b/Tag.h new file mode 100644 index 0000000..4500f72 --- /dev/null +++ b/Tag.h @@ -0,0 +1,46 @@ +#ifndef __Tag_h__ +#define __Tag_h__ + +#include "ZString.h" +#include "MString.h" +#include + +namespace jet { + + class Tag : public coreutils::ZString { + + public: + Tag(coreutils::ZString &in, coreutils::MString &parent); + ~Tag(); + coreutils::ZString name; + coreutils::ZString container; + + protected: + bool hasContainer; + std::map keywords; + bool keywordExists(coreutils::ZString keyword); + void parseContainer(coreutils::ZString &in); + void copyContainer(coreutils::ZString &in, coreutils::MString &out); + + private: + coreutils::MString &parent; + coreutils::MString out; + + bool evaluate = true; + bool filterBlankLines = false; + bool trim = false; + bool cleanWhitespace = false; + + int skipBlankLine(coreutils::ZString in); + + void scanContainer(coreutils::ZString &in); + bool ifNested(coreutils::ZString &in); + bool ifTagName(coreutils::ZString &in, const char *tag); + bool ifTagName(coreutils::ZString &in); + bool ifEndTagName(coreutils::ZString &in); + + }; + +} + +#endif diff --git a/__for.cpp b/__for.cpp new file mode 100644 index 0000000..19b9a8f --- /dev/null +++ b/__for.cpp @@ -0,0 +1,19 @@ +#include "__for.h" +#include "Exception.h" +#include + +namespace jet { + + __for::__for(coreutils::ZString &in, coreutils::MString &out) : Tag(in, out) { + if(!keywordExists(coreutils::ZString("begin"))) + throw coreutils::Exception("begin keyword must be specified."); + if(!keywordExists(coreutils::ZString("end"))) + throw coreutils::Exception("end keyword must be specified."); + + for(;;) { + parseContainer(container); + } + + } + +} diff --git a/__for.h b/__for.h new file mode 100644 index 0000000..fee99d3 --- /dev/null +++ b/__for.h @@ -0,0 +1,18 @@ +#ifndef ____for_h__ +#define ____for_h__ + +#include "Tag.h" +#include + +namespace jet { + + class __for : public Tag { + + public: + __for(coreutils::ZString &in, coreutils::MString &out); + + }; + +} + +#endif diff --git a/__if.cpp b/__if.cpp new file mode 100644 index 0000000..024db5e --- /dev/null +++ b/__if.cpp @@ -0,0 +1,33 @@ +#include "__if.h" +#include "Exception.h" +#include + +namespace jet { + + __if::__if(coreutils::ZString &in, coreutils::MString &out) : Tag(in, out) { + + if(keywordExists(coreutils::ZString("value1"))) { + if(keywordExists(coreutils::ZString("expr"))) + throw coreutils::Exception("Either value1 or expr can be specified but not both."); + if(keywordExists(coreutils::ZString("value2"))) { + if(keywordExists(coreutils::ZString("type"))) { + // process here + } else + throw coreutils::Exception("type expected if value1 and value2 specified."); + } else + throw coreutils::Exception("value2 required if value1 specified."); + } else if(keywordExists(coreutils::ZString("expr"))) { + if(keywordExists(coreutils::ZString("value2"))) + throw coreutils::Exception("value2 should not be specified with expr."); + if(keywordExists(coreutils::ZString("type"))) + throw coreutils::Exception("type should not be specified with expr."); + // process here + } + + if(true) { + parseContainer(container); + } + + } + +} diff --git a/__if.h b/__if.h new file mode 100644 index 0000000..bd7fdc4 --- /dev/null +++ b/__if.h @@ -0,0 +1,20 @@ +#ifndef __if_h__ +#define __if_h__ + +#include "Tag.h" +#include "ZString.h" +#include "MString.h" +#include + +namespace jet { + + class __if : public Tag { + + public: + __if(coreutils::ZString &in, coreutils::MString &out); + + }; + +} + +#endif diff --git a/__jet.cpp b/__jet.cpp new file mode 100644 index 0000000..c830cca --- /dev/null +++ b/__jet.cpp @@ -0,0 +1,10 @@ +#include "__jet.h" +#include + +namespace jet { + + __jet::__jet(coreutils::ZString &in, coreutils::MString &out) : Tag(in, out) { + parseContainer(container); + } + +} diff --git a/__jet.h b/__jet.h new file mode 100644 index 0000000..922b193 --- /dev/null +++ b/__jet.h @@ -0,0 +1,19 @@ +#ifndef ____jet_h__ +#define ____jet_h__ + +#include "Tag.h" +#include "ZString.h" +#include + +namespace jet { + + class __jet : public Tag { + + public: + __jet(coreutils::ZString &in, coreutils::MString &out); + + }; + +} + +#endif diff --git a/__mysql.cpp b/__mysql.cpp new file mode 100644 index 0000000..6033991 --- /dev/null +++ b/__mysql.cpp @@ -0,0 +1,10 @@ +#include "__mysql.h" +#include + +namespace jet { + + __mysql::__mysql(coreutils::ZString &in, coreutils::MString &out) : Tag(in, out) { + parseContainer(container); + } + +} diff --git a/__mysql.h b/__mysql.h new file mode 100644 index 0000000..176a7f0 --- /dev/null +++ b/__mysql.h @@ -0,0 +1,20 @@ +#ifndef __mysql_h__ +#define __mysql_h__ + +#include "Tag.h" +#include "ZString.h" +#include "MString.h" +#include + +namespace jet { + + class __mysql : public Tag { + + public: + __mysql(coreutils::ZString &in, coreutils::MString &out); + + }; + +} + +#endif diff --git a/__read.cpp b/__read.cpp new file mode 100644 index 0000000..bdb1f3d --- /dev/null +++ b/__read.cpp @@ -0,0 +1,17 @@ +#include "__read.h" +#include "Exception.h" + +namespace jet { + + __read::__read(coreutils::ZString &in, coreutils::MString &out) : Tag(in, out) { + if(!keywordExists(coreutils::ZString("file"))) + throw coreutils::Exception("file keyword must be specified."); + + if(hasContainer) + throw coreutils::Exception("missing / at end of tag definition."); + + // process file request here. + + } + +} diff --git a/__read.h b/__read.h new file mode 100644 index 0000000..23b06d6 --- /dev/null +++ b/__read.h @@ -0,0 +1,17 @@ +#ifndef ____read_h__ +#define ____read_h__ + +#include "Tag.h" + +namespace jet { + + class __read : public Tag { + + public: + __read(coreutils::ZString &in, coreutils::MString &out); + + }; + +} + +#endif diff --git a/__set.cpp b/__set.cpp new file mode 100644 index 0000000..c84acfc --- /dev/null +++ b/__set.cpp @@ -0,0 +1,11 @@ +#include "__set.h" +#include "Exception.h" +#include + +namespace jet { + + __set::__set(coreutils::ZString &in, coreutils::MString &out) : Tag(in, out) { + + } + +} diff --git a/__set.h b/__set.h new file mode 100644 index 0000000..41623c4 --- /dev/null +++ b/__set.h @@ -0,0 +1,20 @@ +#ifndef __set_h__ +#define __set_h__ + +#include "Tag.h" +#include "ZString.h" +#include "MString.h" +#include + +namespace jet { + + class __set : public Tag { + + public: + __set(coreutils::ZString &in, coreutils::MString &out); + + }; + +} + +#endif diff --git a/__while.cpp b/__while.cpp new file mode 100644 index 0000000..d502524 --- /dev/null +++ b/__while.cpp @@ -0,0 +1,33 @@ +#include "__while.h" +#include "Exception.h" +#include + +namespace jet { + + __while::__while(coreutils::ZString &in, coreutils::MString &out) : Tag(in, out) { + + if(keywordExists(coreutils::ZString("value1"))) { + if(keywordExists(coreutils::ZString("expr"))) + throw coreutils::Exception("Either value1 or expr can be specified but not both."); + if(keywordExists(coreutils::ZString("value2"))) { + if(keywordExists(coreutils::ZString("type"))) { + // process here + } else + throw coreutils::Exception("type expected if value1 and value2 specified."); + } else + throw coreutils::Exception("value2 required if value1 specified."); + } else if(keywordExists(coreutils::ZString("expr"))) { + if(keywordExists(coreutils::ZString("value2"))) + throw coreutils::Exception("value2 should not be specified with expr."); + if(keywordExists(coreutils::ZString("type"))) + throw coreutils::Exception("type should not be specified with expr."); + // process here + } + + while(true) { + parseContainer(container); + } + + } + +} diff --git a/__while.h b/__while.h new file mode 100644 index 0000000..7230cf8 --- /dev/null +++ b/__while.h @@ -0,0 +1,18 @@ +#ifndef ____while_h__ +#define ____while_h__ + +#include "Tag.h" +#include + +namespace jet { + + class __while : public Tag { + + public: + __while(coreutils::ZString &in, coreutils::MString &out); + + }; + +} + +#endif diff --git a/compile b/compile new file mode 100755 index 0000000..f62edee --- /dev/null +++ b/compile @@ -0,0 +1,33 @@ +#!/bin/bash + +for file in *.cpp +do + filename="${file%.*}" + list="$list $filename.o" + echo -n "Compiling $filename..." + g++ -g -c -std=c++17 -I../CoreUtils $file & + if [ $? = '0' ] + then + echo "OK" + else + echo "ERROR" + exit -1 + fi + +done + +wait +echo -n "Building executable testjet..." +g++ -g -o testjet $list -std=c++17 -L../CoreUtils -lCoreUtils +if [ $? = '0' ] +then + echo "OK" +else + echo "ERROR" + exit -1 +fi + +rm *.o +rm *~ + + diff --git a/testjet b/testjet new file mode 100755 index 0000000..9fdfb41 Binary files /dev/null and b/testjet differ diff --git a/testjet.cpp b/testjet.cpp new file mode 100644 index 0000000..9fd1245 --- /dev/null +++ b/testjet.cpp @@ -0,0 +1,29 @@ +#include +#include +#include "__jet.h" + +int main(int argc, char **argv) { + + coreutils::ZString data("\n" + " \n" + " this is the value\n" + " \n" + " \n" + " 789\n" + " \n" + " 123\n" + " \n" + " \n" + " \n" + "\n"); + +// coreutils::ZString data("ABCHIJXYZ\n"); + + std::cout << "---------\n" << data << "----------\n" << std::endl; + + coreutils::MString out; + jet::__jet *jet = new jet::__jet(data, out); + delete jet; + std::cout << ">>-------" << std::endl << out << std::endl << "<<------"; + +}