Daily update
This commit is contained in:
parent
c264e3802b
commit
5fab1131ca
@ -34,6 +34,7 @@ struct CAWebChat {
|
||||
BuildUnitsArray runlevel_2;
|
||||
|
||||
std::string build_type;
|
||||
bool build_tests = false;
|
||||
|
||||
std::vector<std::string> warning_flags = {"-Wall", "-Wno-unused-variable", "-Werror=return-type","-pedantic",
|
||||
"-Wno-unused-but-set-variable", "-Wno-reorder"};
|
||||
@ -57,8 +58,8 @@ struct CAWebChat {
|
||||
return my_flag_collection;
|
||||
}
|
||||
|
||||
CAWebChat(std::string _build_type, const NormalCBuildSystemCommandMeaning& cmd)
|
||||
: build_type(std::move(_build_type))
|
||||
CAWebChat(const std::string& _build_type, bool _build_tests, const NormalCBuildSystemCommandMeaning& cmd)
|
||||
: build_type(_build_type), build_tests(_build_tests)
|
||||
{
|
||||
ASSERT(build_type == "release" || build_type == "debug", "Unknown build type");
|
||||
|
||||
@ -162,7 +163,9 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
NormalCBuildSystemCommandMeaning cmd;
|
||||
regular_bs_cli_cmd_interpret(args, cmd);
|
||||
CAWebChat bs("debug", cmd);
|
||||
const char* BS_SCRIPT_TYPE = getenv("BS_SCRIPT_TYPE");
|
||||
const char* BS_SCRIPT_TESTS = getenv("BS_SCRIPT_TESTS");
|
||||
CAWebChat bs(BS_SCRIPT_TYPE ? BS_SCRIPT_TYPE : "release", (bool)BS_SCRIPT_TESTS, cmd);
|
||||
if (cmd.need_to_build)
|
||||
complete_tasks_of_build_units(bs.runlevel_1);
|
||||
umask(~0755);
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <algorithm>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
|
||||
namespace nytl {
|
||||
FUp::FUp(const std::string &err, const std::string &file, const std::string &func, int line){
|
||||
@ -45,7 +46,7 @@ namespace nytl {
|
||||
return ch == ' ' || ch == '\r' || ch == '\t' || ch == '\r';
|
||||
}
|
||||
|
||||
bool isUname(const std::string &str) noexcept {
|
||||
bool isUname(const std::string &str) {
|
||||
if (str.empty() || str == "_")
|
||||
return false;
|
||||
if (isNUM(str[0]))
|
||||
@ -55,4 +56,21 @@ namespace nytl {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_uname_dotted_sequence(const std::string& uinp) {
|
||||
if (uinp.empty())
|
||||
return false;
|
||||
std::vector<std::string> r = {""};
|
||||
for (char ch: uinp) {
|
||||
if (ch == '.') {
|
||||
r.emplace_back();
|
||||
} else {
|
||||
r.back() += ch;
|
||||
}
|
||||
}
|
||||
for (const std::string& c: r)
|
||||
if (!isUname(c))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -22,11 +22,9 @@ namespace nytl {
|
||||
std::string prettyprint_errno(const std::string& pref);
|
||||
#define THROW(err) throw FUp(err, __FILE__, __func__, __LINE__)
|
||||
#define THROW_on_errno(err) THROW(prettyprint_errno(err))
|
||||
#define THROW_on_errno_pl() THROW(prettyprint_errno(""))
|
||||
#define ASSERT(cond, err) do { if (!(cond)) { THROW(err); } } while (0);
|
||||
#define ASSERT_pl(cond) ASSERT(cond, "Failed assertion `" #cond "`")
|
||||
#define ASSERT_on_iret(iret, err) ASSERT((iret) >= 0, prettyprint_errno(err));
|
||||
#define ASSERT_on_iret_pl(iret) ASSERT(iret >= 0, prettyprint_errno(""));
|
||||
|
||||
bool endsIn(const std::string& a, const std::string& b);
|
||||
|
||||
@ -37,7 +35,8 @@ namespace nytl {
|
||||
bool isUNCHAR(char ch);
|
||||
bool isSPACE(char ch);
|
||||
|
||||
bool isUname(const std::string& str) noexcept;
|
||||
bool isUname(const std::string& str);
|
||||
bool is_uname_dotted_sequence(const std::string& uinp);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -18,11 +18,11 @@ namespace nytl {
|
||||
|
||||
/* No new JSON object will ever be created, I have one root json argument,
|
||||
* all the other json variables are subtrees of it */
|
||||
LocalVarValue rendering_core_execute_expression(global_elem_set_t& global_elems,
|
||||
const std::vector<LocalVarValue>& local_vars, json::JSON& expr);
|
||||
LocalVarValue rendering_core_execute_expression(const global_elem_set_t& global_elems,
|
||||
const std::vector<LocalVarValue>& local_vars, const json::JSON& expr);
|
||||
|
||||
std::string rendering_core(const std::string& entry_func, const std::vector<json::JSON>& entry_arguments,
|
||||
std::map<std::string, Element>& elem_ns, const std::function<std::string(std::string)>& escape);
|
||||
const global_elem_set_t& elem_ns, const std::function<std::string(std::string)>& escape);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -3,42 +3,88 @@
|
||||
#include <assert.h>
|
||||
|
||||
namespace nytl {
|
||||
struct Frame {
|
||||
json::JSON& expr;
|
||||
struct EEFrame {
|
||||
const json::JSON& expr;
|
||||
LocalVarValue& result;
|
||||
LocalVarValue temp_ret;
|
||||
size_t chain_el = 0;
|
||||
|
||||
Frame(json::JSON &expr, LocalVarValue &result)
|
||||
EEFrame(const json::JSON &expr, LocalVarValue &result)
|
||||
: expr(expr),
|
||||
result(result) {
|
||||
}
|
||||
|
||||
uptr<Frame> toMe(bool returned_from_bottom, global_elem_set_t& global_elems,
|
||||
void descend(const json::JSON& what) {
|
||||
if (result.is_json) {
|
||||
const json::JSON& P = *result.JSON_subval;
|
||||
if (P.isArray() && what.isInteger()) {
|
||||
const std::vector<json::JSON> arr_p = P.asArray();
|
||||
int64_t ind_w = what.asInteger().get_int();
|
||||
ASSERT(ind_w > 0 && ind_w < arr_p.size(), "Expression \"array[integer]\" caused out-of-bound situation");
|
||||
result = LocalVarValue{true, "", &arr_p[ind_w]};
|
||||
} else if (P.isDictionary() && what.isString()) {
|
||||
const std::map<std::string, json::JSON> dict_p = P.asDictionary();
|
||||
const std::string& key_w = what.asString();
|
||||
ASSERT(dict_p.count(key_w) == 1, "No such key exception");
|
||||
result = LocalVarValue{true, "", &dict_p.at(key_w)};
|
||||
} else
|
||||
THROW("Incorrect type of \"json[json]\" expression. Unallowed signature of [] operator");
|
||||
} else {
|
||||
ASSERT(what.isString(), "Expression \"element[X]\" allowed only if X is string (json object)");
|
||||
if (what.asString().empty())
|
||||
return;
|
||||
if (!is_uname_dotted_sequence(what.asString()))
|
||||
THROW("Incorrect X in \"element[X]\"");
|
||||
result.EL_name += ("." + what.asString());
|
||||
}
|
||||
}
|
||||
|
||||
uptr<EEFrame> toMe(bool returned, const global_elem_set_t& global_elems,
|
||||
const std::vector<LocalVarValue>& local_vars) {
|
||||
if (returned_from_bottom) {
|
||||
ASSERT(temp_ret.is_json, "Expression \"[ element ]\" is not allowed");
|
||||
if (returned) {
|
||||
ASSERT(temp_ret.is_json, "Expression \"X[ element ]\" is not allowed");
|
||||
assert(temp_ret.JSON_subval);
|
||||
// json::JSON
|
||||
// todo: make usable const JSON
|
||||
descend(*(temp_ret.JSON_subval));
|
||||
} else {
|
||||
assert(expr.isDictionary());
|
||||
if ((*expr["V"]).isInteger()) {
|
||||
size_t lv_ind = (*expr["V"]).asInteger().get_int();
|
||||
const json::JSON& val = expr["V"].g();
|
||||
if (val.isInteger()) {
|
||||
size_t lv_ind = val.asInteger().get_int();
|
||||
assert(lv_ind < local_vars.size());
|
||||
result = local_vars[lv_ind];
|
||||
} else if ((*expr["V"]).isString()) {
|
||||
std::string cur_el_name_str = (*expr["V"]).asString();
|
||||
} else if (val.isString()) {
|
||||
std::string cur_el_name_str = expr["V"].g().asString();
|
||||
result = LocalVarValue{false, cur_el_name_str, NULL};
|
||||
} else
|
||||
assert(false);
|
||||
}
|
||||
if (chain_el == (*expr["C"]).)
|
||||
while (true) {
|
||||
const std::vector<json::JSON>& chain = expr["C"].g().asArray();
|
||||
if (chain_el >= chain.size())
|
||||
return NULL;
|
||||
const json::JSON& t = chain[chain_el++];
|
||||
if (t.isDictionary())
|
||||
return std::make_unique<EEFrame>(t, temp_ret);
|
||||
descend(t);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
LocalVarValue rendering_core_execute_expression(global_elem_set_t& global_elems,
|
||||
const std::vector<LocalVarValue>& local_vars, json::JSON& expr) {
|
||||
|
||||
LocalVarValue rendering_core_execute_expression(const global_elem_set_t& global_elems,
|
||||
const std::vector<LocalVarValue>& local_vars, const json::JSON& expr) {
|
||||
bool returned = false;
|
||||
std::vector<uptr<EEFrame>> stack;
|
||||
LocalVarValue result;
|
||||
stack.push_back(std::make_unique<EEFrame>(expr, result));
|
||||
while (!stack.empty()) {
|
||||
EEFrame& cur = *stack.back();
|
||||
uptr<EEFrame> todo = cur.toMe(returned, global_elems, local_vars);
|
||||
returned = (bool)todo;
|
||||
if (todo)
|
||||
stack.push_back(todo);
|
||||
else
|
||||
stack.pop_back();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -1,47 +1,15 @@
|
||||
#include "core.h"
|
||||
#include "alotalot.h"
|
||||
#include <string.h>
|
||||
#include <libjsonincpp/string_representation.h>
|
||||
#include <jsonincpp/string_representation.h>
|
||||
#include <assert.h>
|
||||
|
||||
namespace nytl {
|
||||
std::string rendering_core(const std::string& entry_func, const std::vector<json::JSON>& entry_arguments,
|
||||
std::map<std::string, Element>& elem_ns, const std::function<std::string(std::string)>& escape)
|
||||
{
|
||||
size_t cur_line_width = 0;
|
||||
struct Ditch {
|
||||
std::string result;
|
||||
size_t cur_line_width = 0;
|
||||
|
||||
struct Frame {
|
||||
const Element* el = NULL;
|
||||
/* Use by base elements to distinguish them */
|
||||
std::string base_name;
|
||||
size_t part_to_do = 0;
|
||||
std::vector<LocalVarValue> passed_args;
|
||||
/* This parameter incapsulates `cur_line_width` at some point for multiline `put-parts` */
|
||||
size_t multiline_put_start = 0;
|
||||
};
|
||||
std::vector<uptr<Frame>> stack;
|
||||
|
||||
auto make_frame = [&](const std::string& name, std::vector<LocalVarValue> passed_args){
|
||||
const Element* el = &elem_ns[name];
|
||||
Frame* us = new Frame{el, el->base ? name : "", 0, std::move(passed_args), cur_line_width};
|
||||
stack.push_back(uptr<Frame>(us));
|
||||
};
|
||||
|
||||
ASSERT(elem_ns.count(entry_func) == 1, "No such element " + entry_func);
|
||||
const Element& el = elem_ns[entry_func];
|
||||
ASSERT(el.arguments.size() == entry_arguments.size(), "Signature mismatch " + entry_func);
|
||||
for (const json::JSON& sigtbj: el.arguments) {
|
||||
ASSERT(sigtbj.type == json::true_symbol, "Signature mismatch. Entry element can take only JSON arguments");
|
||||
}
|
||||
{
|
||||
size_t AN = entry_arguments.size();
|
||||
std::vector<LocalVarValue> entry_arguments_conv(AN);
|
||||
for (size_t i = 0; i < AN; i++)
|
||||
entry_arguments_conv[i] = {"", &entry_arguments[i]};
|
||||
make_frame(entry_func, entry_arguments_conv);
|
||||
}
|
||||
auto append2res = [&](const std::string& text) {
|
||||
void append(const std::string& text) {
|
||||
size_t n = result.size();
|
||||
result.resize(n + text.size());
|
||||
memcpy((void*)&result.c_str()[n], text.c_str(), text.size());
|
||||
@ -51,48 +19,116 @@ namespace nytl {
|
||||
else
|
||||
cur_line_width++;
|
||||
}
|
||||
};
|
||||
auto linefeed2res = [&]() {
|
||||
result += "\n";
|
||||
cur_line_width = 0;
|
||||
};
|
||||
while (!stack.empty()) {
|
||||
Frame& cur = *stack.back();
|
||||
if (cur.el->base) {
|
||||
assert(cur.passed_args.size() == 1);
|
||||
const json::JSON* X = cur.passed_args[0].JSON_subval;
|
||||
assert(X);
|
||||
if (cur.base_name == "jesc") {
|
||||
append2res(escape(json::generate_str(*X, json::print_pretty)));
|
||||
} else if (cur.base_name == "str2text") {
|
||||
ASSERT(X->isString(), "str2text takes json string");
|
||||
append2res(escape(X->asString()));
|
||||
} else if (cur.base_name == "str2code") {
|
||||
ASSERT(X->isString(), "str2code takes json string");
|
||||
append2res(X->asString());
|
||||
}
|
||||
};
|
||||
|
||||
#define RFrame_passed const global_elem_set_t& elem_ns, Ditch& result, const std::function<std::string(std::string)>& escape
|
||||
struct RFrame {
|
||||
virtual uptr<RFrame> toMe(bool returned, RFrame_passed) {assert(false);}
|
||||
|
||||
virtual ~RFrame() = default;
|
||||
};
|
||||
|
||||
struct RFrame_OverParts : public RFrame{
|
||||
std::string name;
|
||||
std::vector<LocalVarValue> passed_args;
|
||||
/* This parameter incapsulates `cur_line_width` at some point for multiline `put-parts` */
|
||||
size_t multiline_put_start = 0;
|
||||
/* main iterator of this frame. Persistent across control returns */
|
||||
size_t part_to_do = 0;
|
||||
|
||||
RFrame_OverParts(const std::string &name, const std::vector<LocalVarValue> &passed_args,
|
||||
size_t multiline_put_start)
|
||||
: name(name),
|
||||
passed_args(passed_args),
|
||||
multiline_put_start(multiline_put_start) {
|
||||
}
|
||||
|
||||
uptr<RFrame> toMe(bool returned, RFrame_passed) override {
|
||||
if (!returned)
|
||||
ASSERT(elem_ns.count(name) == 1, "No such element");
|
||||
const Element& el = elem_ns.at(name);
|
||||
if (!returned) {
|
||||
/* Continue to do checks */
|
||||
size_t n = el.arguments.size();
|
||||
ASSERT(n == passed_args.size(), "Argument count mismatch");
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (el.arguments[i].type == json::true_symbol) {
|
||||
ASSERT(passed_args[i].is_json, "Expected json element argument, got element");
|
||||
} else {
|
||||
// If not json is expected, element must be expected
|
||||
assert(el.arguments[i].isArray());
|
||||
ASSERT(!passed_args[i].is_json, "Expected element element arguemnt, got json");
|
||||
ASSERT(elem_ns.count(passed_args[i].EL_name), "No such element, can't compare signatures of argument value");
|
||||
const Element& arg_element = elem_ns.at(passed_args[i].EL_name);
|
||||
// ASSERT(passed_args);
|
||||
if(el.arguments[i].asArray() != arg_element.arguments)
|
||||
THROW("Signature of argument " + std::to_string(i) + " does not match");
|
||||
}
|
||||
}
|
||||
stack.pop_back();
|
||||
continue;
|
||||
}
|
||||
if (cur.part_to_do == cur.el->parts.size()) {
|
||||
stack.pop_back();
|
||||
continue;
|
||||
if (el.base) {
|
||||
assert(!returned);
|
||||
assert(passed_args.size() == 1);
|
||||
const json::JSON* X = passed_args[0].JSON_subval;
|
||||
assert(X);
|
||||
if (name == "jesc") {
|
||||
result.append(escape(json::generate_str(*X, json::print_pretty)));
|
||||
} else if (name == "str2text") {
|
||||
ASSERT(X->isString(), "str2text takes json string");
|
||||
result.append(escape(X->asString()));
|
||||
} else if (name == "str2code") {
|
||||
ASSERT(X->isString(), "str2code takes json string");
|
||||
result.append(X->asString());
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
const ElementPart& cur_part = cur.el->parts[cur.part_to_do++];
|
||||
if (cur_part.type == element_part_types::code) {
|
||||
const ElementPart::when_code_S& pt = cur_part.when_code;
|
||||
append2res(pt.lines);
|
||||
} else if (cur_part.type == element_part_types::put) {
|
||||
const ElementPart::when_put_S& pt = cur_part.when_put;
|
||||
// todo
|
||||
} else if (cur_part.type == element_part_types::for_put) {
|
||||
const ElementPart::when_for_put_S& pt = cur_part.when_for_put;
|
||||
// todo
|
||||
} else if (cur_part.type == element_part_types::ref_put) {
|
||||
const ElementPart::when_ref_put_S& pt = cur_part.when_ref_put;
|
||||
// todo
|
||||
while (true) {
|
||||
if (part_to_do == el.parts.size())
|
||||
return NULL;
|
||||
const ElementPart& cur_part = el.parts[part_to_do++];
|
||||
if (cur_part.type == element_part_types::code) {
|
||||
const ElementPart::when_code_S& pt = cur_part.when_code;
|
||||
result.append(pt.lines);
|
||||
} else if (cur_part.type == element_part_types::put) {
|
||||
const ElementPart::when_put_S& pt = cur_part.when_put;
|
||||
LocalVarValue called_element_expv = rendering_core_execute_expression(elem_ns, passed_args, pt.called_element);
|
||||
ASSERT(!called_element_expv.is_json, "Can't PUT json variable");
|
||||
size_t AN = pt.passed_arguments.size();
|
||||
std::vector<LocalVarValue> passed_arguments_expv(AN);
|
||||
for (size_t i = 0; i < AN; i++)
|
||||
passed_arguments_expv[i] = rendering_core_execute_expression(elem_ns, passed_args, pt.passed_arguments[i]);
|
||||
return uptr<RFrame>(new RFrame_OverParts(called_element_expv.EL_name, passed_arguments_expv, result.cur_line_width));
|
||||
} else if (cur_part.type == element_part_types::for_put) {
|
||||
const ElementPart::when_for_put_S& pt = cur_part.when_for_put;
|
||||
// todo
|
||||
} else if (cur_part.type == element_part_types::ref_put) {
|
||||
const ElementPart::when_ref_put_S& pt = cur_part.when_ref_put;
|
||||
// todo
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
std::string rendering_core(const std::string& entry_func, const std::vector<json::JSON>& entry_arguments,
|
||||
const global_elem_set_t& elem_ns, const std::function<std::string(std::string)>& escape)
|
||||
{
|
||||
Ditch result;
|
||||
|
||||
std::vector<uptr<RFrame>> stack;
|
||||
|
||||
{
|
||||
size_t AN = entry_arguments.size();
|
||||
std::vector<LocalVarValue> entry_arguments_conv(AN);
|
||||
for (size_t i = 0; i < AN; i++)
|
||||
entry_arguments_conv[i] = {true, "", &entry_arguments[i]};
|
||||
// stack.push_back(std::make_unique<>());
|
||||
// make_frame(entry_func, entry_arguments_conv);
|
||||
}
|
||||
while (!stack.empty()) {
|
||||
// Frame& cur = *stack.back();
|
||||
|
||||
}
|
||||
return result.result;
|
||||
}
|
||||
}
|
||||
|
@ -126,24 +126,9 @@ namespace nytl {
|
||||
}
|
||||
}
|
||||
|
||||
void check_uinp_element(const std::string& uinp) {
|
||||
if (uinp.empty())
|
||||
THROW("empty???");
|
||||
std::vector<std::string> r = {""};
|
||||
for (char ch: uinp) {
|
||||
if (ch == '.') {
|
||||
r.emplace_back();
|
||||
} else {
|
||||
r.back() += ch;
|
||||
}
|
||||
}
|
||||
for (const std::string& c: r)
|
||||
ASSERT(isUname(c), "Incorrect name component");
|
||||
}
|
||||
|
||||
/* Still can throw some stuff derived from std::exception (like bad alloc) */
|
||||
std::string Templater::render(const std::string& element, const std::vector<json::JSON> &arguments) const {
|
||||
check_uinp_element(element);
|
||||
return rendering_core(element, arguments, elements);
|
||||
ASSERT(is_uname_dotted_sequence(element), "Incorrect entry element name");
|
||||
return rendering_core(element, arguments, elements, settings.escape);
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <libjsonincpp/jsonobj.h>
|
||||
#include <jsonincpp/jsonobj.h>
|
||||
#include <functional>
|
||||
#include "html_case.h"
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include <engine_engine_number_9/connecting_assets/static_asset_manager.h>
|
||||
#include <assert.h>
|
||||
#include <sqlite3.h>
|
||||
#include <libjsonincpp/string_representation.h>
|
||||
#include <jsonincpp/string_representation.h>
|
||||
#include <libregexis024vm/vm_opcodes.h>
|
||||
#include <engine_engine_number_9/form_data_structure/urlencoded_query.h>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user