Compare commits

..

No commits in common. "35ce3aeca7ab216aaa67703809ab1c9d1e7a917d" and "b8adc5bd55a9886f7474b9cab1dbb3c491c61ed6" have entirely different histories.

17 changed files with 131 additions and 284 deletions

View File

@ -1,32 +1,31 @@
{% ELDEF main JSON pres %}
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% WRITE pres.phr.decl.list-of-chat-rooms %}</title>
<title>Список Чат-Комнат</title>
<link rel="stylesheet" href="/assets/css/list-rooms.css">
</head>
<body>
<div class="container">
<h1 style="color: white;">{% WRITE pres.phr.decl.select-chat-room %}</h1>
<h1 style="color: white;">Выберите Чат-Комнату</h1>
<ul class="room-list">
<!-- Здесь будет список комнат -->
</ul>
<button class="create-room-button" onclick="openCreateRoomModal()">{% WRITE pres.phr.act.create-room %}</button>
<button class="create-room-button" onclick="openCreateRoomModal()">Создать Комнату</button>
</div>
<div id="passwordModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<span class="close" onclick="closeModal()">&times;</span>
<h2>VVedite parol</h2> <!-- Nam ne nuzhen parol ot komnat -->
<h2>Введите Пароль</h2>
</div>
<div class="modal-body">
<input type="password" id="roomPassword" placeholder="Пароль">
</div>
<div class="modal-footer">
<button class="join-button" onclick="validatePassword()">{% WRITE pres.phr.act.confirm %}</button>
<button class="join-button" onclick="validatePassword()">Подтвердить</button>
</div>
</div>
</div>
@ -36,14 +35,14 @@
<div class="modal-content">
<div class="modal-header">
<span class="close" onclick="closeCreateRoomModal()">&times;</span>
<h2>{% WRITE pres.phr.decl.create-room %}</h2>
<h2>Создать Комнату</h2>
</div>
<div class="modal-body">
<input type="text" id="newRoomName" placeholder="{% WRITE pres.phr.decl.name-of-room %}">
<input type="password" id="newRoomPassword" placeholder="Пароль"> <!-- Fedya, nam ne nuzhen parol -->
<input type="text" id="newRoomName" placeholder="Название комнаты">
<input type="password" id="newRoomPassword" placeholder="Пароль">
</div>
<div class="modal-footer">
<button class="join-button" onclick="createRoom()">{% WRITE pres.phr.act.create %}</button>
<button class="join-button" onclick="createRoom()">Создать</button>
</div>
</div>
</div>
@ -51,4 +50,3 @@
<script src="/assets/js/list-rooms.js"></script>
</body>
</html>
{% ENDELDEF %}

View File

@ -1,7 +1,3 @@
{% ELDEF main %}
CCC
DDD
AAAAAAAA
{% ENDELDEF %}

View File

@ -1,32 +1,3 @@
{
"presentation": {
"instance-identity": {
"top-title": "Вэб чат ИУ9"
},
"phr": {
"decl": {
"list-of-chat-rooms": "Список Чат-Комнат",
"select-chat-room": "Выберете чат комнату",
"name-of-room": "Название комнаты",
"create-room": "Создать комнату"
},
"act": {
"create-room": "Создать комнату",
"confirm": "Подтвердить",
"create": "Создать"
}
}
},
"assets": "./assets",
"limits": {
"max-users": 100000,
"max-rooms": 100000,
"max-messages": 10000000000000,
"storage-size-limit": 100000000000
},
"server": {
"workers": 8,
"http-listen": ["127.0.0.1:1025"],
"command-listen": []
}
"name": "Web chat"
}

View File

@ -82,10 +82,10 @@ namespace een9 {
struct WorkersEnv {
WorkersEnvCommon& wtec;
worker_id_t id;
int id;
ClientRequestParser_WorkerBuffers personal_parser_buffer;
explicit WorkersEnv(WorkersEnvCommon& wtec, worker_id_t id): wtec(wtec), id(id), personal_parser_buffer(wtec.parser_programs){}
explicit WorkersEnv(WorkersEnvCommon& wtec, int id): wtec(wtec), id(id), personal_parser_buffer(wtec.parser_programs){}
};
// todo: add timeout for multiple bytes, add more settings
@ -125,7 +125,7 @@ namespace een9 {
void process_connection(const SlaveTask& task, WorkersEnv& wte) {
ClientRequest client_request = process_connection_input(task.fd(), task.s_tips, wte);
std::string server_response = wte.wtec.guest_core(task, client_request, wte.id);
std::string server_response = wte.wtec.guest_core(task, client_request);
process_connection_output(task.fd(), server_response);
}
@ -149,7 +149,6 @@ namespace een9 {
} catch (const std::exception& e) {
printf("Client request procession failure in worker\n");
printf("%s\n", e.what());
/* Under mysterious some circumstances, in this place destructor of string in SystemError causes segfault. I can't fix that */
}
}
printf("Worker finished\n");
@ -167,7 +166,7 @@ namespace een9 {
std::vector<pthread_t> workers(params.slave_number);
std::vector<uptr<WorkersEnv>> wtes(params.slave_number);
for (size_t i = 0; i < params.slave_number; i++) {
wtes[i] = std::make_unique<WorkersEnv>(wtec, (worker_id_t)i);
wtes[i] = std::make_unique<WorkersEnv>(wtec, i);
}
for (size_t i = 0; i < params.slave_number; i++) {
pthread_create(&workers[i], NULL, worker_func, wtes[i].get());

View File

@ -29,10 +29,8 @@ namespace een9 {
EEN9_ServerTips s_tips;
};
typedef int worker_id_t;
/* guest_core function must not throw anything that is not derived from std::exception */
typedef std::function<std::string(const SlaveTask&, const ClientRequest&, worker_id_t worker_id)> guest_core_t;
typedef std::function<std::string(const SlaveTask&, const ClientRequest&)> guest_core_t;
struct ServersConfiguration {
size_t critical_load_1 = 90;

View File

@ -87,9 +87,4 @@ namespace nytl {
}
return result;
}
void rstrip(std::string &str) {
while (!str.empty() && isSPACE(str.back()))
str.resize(str.size() - 1);
}
}

View File

@ -1,12 +1,12 @@
#ifndef NEW_YORK_TRANSIT_LINE_ALOTALOT_H
#define NEW_YORK_TRANSIT_LINE_ALOTALOT_H
#include <stdexcept>
#include <memory>
/* A little of this, a little of that
* DO NOT EXPORT THIS FILE */
#include <stdexcept>
#include <memory>
namespace nytl {
template<typename T>
using uptr = std::unique_ptr<T>;
@ -46,8 +46,6 @@ namespace nytl {
bool is_uname_dotted_sequence(const std::string& uinp);
std::string make_uppercase(const std::string& source);
void rstrip(std::string& str);
}
#endif

View File

@ -4,11 +4,7 @@
#include "templater.h"
#include <functional>
/* Do not export this header */
namespace nytl {
void debug_print_templater(const Templater& T);
/* ============== For parsing =============================*/
void parse_bare_file(const std::string& filename, const std::string& content,
global_elem_set_t& result);
@ -28,7 +24,7 @@ namespace nytl {
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<const json::JSON*>& entry_arguments,
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);
}

View File

@ -1,49 +0,0 @@
#include "templater.h"
#include "alotalot.h"
#include "jsonincpp/string_representation.h"
#include <assert.h>
namespace nytl {
void debug_print_templater(const Templater& T) {
printf("===== TEMPLATER INTERNAL RESOURCES =====\n");
for (auto& p: T.elements) {
printf("=== %s element =====\n", p.first.c_str());
const Element& el = p.second;
printf("%s, %s\n", el.base ? "BASE" : "NOT BASE", el.is_hidden ? "HIDDEN" : "NOT HIDDEN");
if (!el.is_hidden) {
std::string signature;
for (const json::JSON& arg_type: el.arguments) {
if (!signature.empty())
signature += " ";
signature += json::generate_str(arg_type, json::print_compact);
}
printf("Signature: %s\n", signature.c_str());
}
for (const ElementPart& part: el.parts) {
if (part.type == ElementPart::p_code) {
printf("code: <b><e><f><o><r><e><><l><f>\n%s\n<a><f><t><e><r><><l><f>\n", part.when_code.lines.c_str());
} else if (part.type == ElementPart::p_for_put) {
const ElementPart::when_for_put_S& P = part.when_for_put;
printf("dor cycle call:\ninternal_element: %s,\nref_over:%s,\nwhere_key_var: %ld, where_value_var: %ld, %s\n",
P.internal_element.c_str(), json::generate_str(P.ref_over, json::print_pretty).c_str(),
P.where_key_var, P.where_value_var, P.line_feed ? "LF" : "NOLF");
} else if (part.type == ElementPart::p_ref_put) {
const ElementPart::when_ref_put_S& P = part.when_ref_put;
printf("ref block call:\ninternal_element: %s\nref_over:%s\n",
P.internal_element.c_str(), json::generate_str(P.ref_over, json::print_pretty).c_str());
} else {
assert(part.type == ElementPart::p_put);
const ElementPart::when_put_S& P = part.when_put;
printf("PUT:\ncalled_element: %s\n",
json::generate_str(P.called_element, json::print_pretty).c_str());
for (size_t i = 0; i < P.passed_arguments.size(); i++) {
printf("passed_arguments[%lu] = %s\n", i,
json::generate_str(P.passed_arguments[i], json::print_pretty).c_str());
}
}
}
printf("=== That was element %s ====\n", p.first.c_str());
}
printf("===== DEBUG IS OVER =====\n");
}
}

View File

@ -3,7 +3,6 @@
#include <assert.h>
namespace nytl {
/* Expression Execution Frame */
struct EEFrame {
const json::JSON& expr;
LocalVarValue& result;
@ -15,15 +14,6 @@ namespace nytl {
result(result) {
}
// todo: remove this debug function
// void print_result() {
// if (result.is_json) {
// printf("print_result %%p: %p\n", result.JSON_subval);
// printf("%s\n", json::generate_str(*result.JSON_subval, json::print_compact).c_str());
// } else
// printf("element %s\n", result.EL_name.c_str());
// }
void descend(const json::JSON& what) {
if (result.is_json) {
const json::JSON& P = *result.JSON_subval;
@ -33,7 +23,7 @@ namespace nytl {
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::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)};

View File

@ -16,6 +16,11 @@ namespace nytl {
return first_nw_char(str) == str.size();
}
void rstrip(std::string& str) {
while (!str.empty() && isSPACE(str.back()))
str.resize(str.size() - 1);
}
std::string clement_lstrip(const std::string& str) {
size_t gone = 0;
size_t n = str.size();
@ -23,11 +28,11 @@ namespace nytl {
if (str[i] == '\n') {
gone = i + 1;
} else if (!isSPACE(str[i])) {
break;
}
}
return str.substr(gone);
}
}
return "";
}
struct ParsingContext {
std::string text;
@ -120,29 +125,22 @@ namespace nytl {
return result;
}
bool is_relevant_in_tab_cut(size_t PN, size_t I, size_t LN, size_t j, const std::string& line) {
if (j == 0 && I != 0)
return false;
if (!is_space_only(line))
return true;
return j + 1 == LN && I + 1 < PN;
}
void one_part_update_min_start_wsp_non_empty(const std::string& str, size_t I, size_t PN, size_t& min) {
void one_part_update_min_start_wsp_non_empty(const std::string& str, bool is_first, size_t& min) {
std::vector<std::string> lines = splitIntoLines(str);
size_t LN = lines.size();
for (size_t j = 0; j < LN; j++) {
if (is_relevant_in_tab_cut(PN, I, LN, j, lines[j]))
min = std::min(min, first_nw_char(lines[j]));
size_t L = lines.size();
for (size_t i = is_first ? 0 : 1; i < L; i++) {
size_t first_nw = first_nw_char(lines[i]);
if (first_nw < lines[i].size())
min = std::min(min, first_nw);
}
}
std::string one_part_cut_excess_tab(const std::string& str, size_t I, size_t PN, size_t cut) {
std::string one_part_cut_excess_tab(const std::string& str, bool is_first, size_t cut) {
std::vector<std::string> lines = splitIntoLines(str);
size_t LN = lines.size();
for (size_t j = 0; j < LN; j++) {
if (is_relevant_in_tab_cut(PN, I, LN, j, lines[j]))
lines[j] = lines[j].substr(cut);
size_t L = lines.size();
for (size_t i = is_first ? 0 : 1; i < L; i++) {
if (!is_space_only(lines[i]))
lines[i] = lines[i].substr(cut);
}
return concatenateLines(lines);
}
@ -151,17 +149,17 @@ namespace nytl {
global_elem_set_t& result)
{
ASSERT(result.count(filename) == 0, "Repeated element " + filename);
std::string txt = clement_lstrip(content);
rstrip(txt);
std::string P = clement_lstrip(content);
rstrip(P);
size_t cut = 9999999999999;
one_part_update_min_start_wsp_non_empty(txt, 0, 1, cut);
txt = one_part_cut_excess_tab(txt, 0, 1, cut);
one_part_update_min_start_wsp_non_empty(P, true, cut);
P = one_part_cut_excess_tab(P, true, cut);
Element& el = result[filename];
el.parts = {ElementPart{}};
el.parts[0].when_code.lines = mv(txt);
el.parts = {ElementPart{element_part_types::code}};
el.parts[0].when_code.lines = mv(P);
}
/* Type parsing frame */
/* This function parses variable type */
struct TPFrame {
json::JSON& result;
@ -208,7 +206,6 @@ namespace nytl {
/* From arg name to arg ID */
typedef std::map<std::string, size_t> arg_name_list_t;
/* Expression parsing frame */
struct EPFrame {
json::JSON& result;
@ -298,7 +295,6 @@ namespace nytl {
return peep(ctx) == syntax.magic_block_end[0];
}
/* Element content parsing frame */
struct ECPFrame {
enum block_type{
gone_for_nothing,
@ -326,7 +322,7 @@ namespace nytl {
uptr<ECPFrame> toMe(bool returned, ParsingContext& ctx, const TemplaterSettings& syntax, global_elem_set_t& elem_ns) {
if (returned) {
if (stopped_for == gone_for_for) {
assert(result.parts.back().type == ElementPart::p_for_put);
assert(result.parts.back().type == element_part_type_t::for_put);
if (ret_data_int == 1)
result.parts.back().when_for_put.line_feed = false;
else if (ret_data_int == 2)
@ -348,7 +344,7 @@ namespace nytl {
std::string op = make_uppercase(readName(ctx));
if (op == "FOR") {
result.parts.emplace_back();
result.parts.back().type = ElementPart::p_for_put;
result.parts.back().type = element_part_type_t::for_put;
ElementPart::when_for_put_S& P = result.parts.back().when_for_put;
skipWhitespace(ctx);
std::string V1 = readName(ctx);
@ -391,7 +387,7 @@ namespace nytl {
}
if (op == "REF") {
result.parts.emplace_back();
result.parts.back().type = ElementPart::p_ref_put;
result.parts.back().type = element_part_type_t::ref_put;
ElementPart::when_ref_put_S& P = result.parts.back().when_ref_put;
skipWhitespace(ctx);
std::string Vn = readName(ctx);
@ -415,7 +411,7 @@ namespace nytl {
}
if (op == "PUT") {
result.parts.emplace_back();
result.parts.back().type = ElementPart::p_put;
result.parts.back().type = element_part_type_t::put;
ElementPart::when_put_S& P = result.parts.back().when_put;
skipWhitespace(ctx);
P.called_element = parse_expression(ctx, local_var_names);
@ -431,13 +427,12 @@ namespace nytl {
}
auto mediocre_operator = [&](const std::string& base_el) -> void {
result.parts.emplace_back();
result.parts.back().type = ElementPart::p_put;
result.parts.back().type = element_part_type_t::put;
ElementPart::when_put_S& P = result.parts.back().when_put;
P.called_element["V"] = json::JSON(base_el);
P.called_element["C"] = json::JSON(json::array);
skipWhitespace(ctx);
P.passed_arguments = {parse_expression(ctx, local_var_names)};
skip_magic_block_end(ctx, syntax);
};
if (op == "WRITE") {
mediocre_operator("str2text");
@ -447,29 +442,27 @@ namespace nytl {
mediocre_operator("str2code");
goto ya_e_ya_h_i_ya_g_d_o;;
}
auto prepare_to_depart_parts = [&]() {
assert(!result.parts.empty());
if (result.parts[0].type == ElementPart::p_code)
if (op == "ENDELDEF") {
ASSERT(myself == gone_for_nothing, "Unexpected end of element");
skip_magic_block_end(ctx, syntax);
if (!result.parts.empty()) {
if (result.parts[0].type == element_part_type_t::code)
result.parts[0].when_code.lines = clement_lstrip(result.parts[0].when_code.lines);
if (result.parts.back().type == ElementPart::p_code)
if (result.parts.back().type == element_part_type_t::code)
rstrip(result.parts.back().when_code.lines);
size_t cut = 999999999999;
size_t N = result.parts.size();
for (size_t i = 0; i < N; i++) {
if (result.parts[i].type == ElementPart::p_code) {
one_part_update_min_start_wsp_non_empty(result.parts[i].when_code.lines, i, N, cut);
if (result.parts[i].type == element_part_type_t::code) {
one_part_update_min_start_wsp_non_empty(result.parts[i].when_code.lines, i == 0, cut);
}
}
for (size_t i = 0; i < N; i++) {
if (result.parts[i].type == ElementPart::p_code) {
result.parts[i].when_code.lines = one_part_cut_excess_tab(result.parts[i].when_code.lines, i, N, cut);
if (result.parts[i].type == element_part_type_t::code) {
result.parts[i].when_code.lines = one_part_cut_excess_tab(result.parts[i].when_code.lines, i == 0, cut);
}
}
}
};
if (op == "ENDELDEF") {
ASSERT(myself == gone_for_nothing, "Unexpected end of element");
skip_magic_block_end(ctx, syntax);
prepare_to_depart_parts();
return NULL;
}
if (op == "ENDFOR") {
@ -487,13 +480,10 @@ namespace nytl {
THROW("Expected LF, NOLF or end of magic block");
}
skip_magic_block_end(ctx, syntax);
prepare_to_depart_parts();
return NULL;
}
if (op == "ENDREF") {
assert(myself == gone_for_ref);
skip_magic_block_end(ctx, syntax);
prepare_to_depart_parts();
return NULL;
}
THROW("Unknown operator. Expected FOR, REF, PUT, WRITE, ROUGHINSERT, ENDELDEF, ENDFOR, ENDREF");

View File

@ -9,25 +9,22 @@ namespace nytl {
std::string result;
size_t cur_line_width = 0;
/* Fix idea: get rid of newlined_somewhere */
void append(const std::string& text, size_t wsp_before_newlines, bool& newlined_somewhere) {
size_t n = result.size();
size_t m = text.size();
result.reserve(n + m);
for (size_t i = 0; i < m; i++) {
result += text[i];
if (text[i] == '\n') {
// newlined_somewhere = true;
newlined_somewhere = true;
cur_line_width = 0;
} else {
if (cur_line_width == 0 && newlined_somewhere) {
result.resize(result.size() + wsp_before_newlines, ' ');
cur_line_width = wsp_before_newlines;
} else {
// if (cur_line_width == 0 && newlined_somewhere) {
// result.resize(result.size() + wsp_before_newlines, ' ');
// cur_line_width = wsp_before_newlines;
// }
}
cur_line_width++;
}
result += text[i];
}
}
};
@ -91,7 +88,7 @@ namespace nytl {
RFrame_OverArray(const ElementPart::when_for_put_S& part, size_t multiline_put_start, const std::vector<LocalVarValue> &saved_args,
const std::vector<json::JSON> &arr): RFrame_OverJSON(part, multiline_put_start, saved_args),
arr(arr) {
if (part.where_key_var >= 0)
if (part.where_key_var < 0)
additional_json_wrapper = json::JSON(json::Integer(0l));
}
@ -109,7 +106,7 @@ namespace nytl {
const std::map<std::string, json::JSON> &dict): RFrame_OverJSON(part, multiline_put_start, saved_args_plus_iter),
dict(dict) {
it = dict.begin();
if (part.where_key_var >= 0)
if (part.where_key_var < 0)
addition_json_wrapper = json::JSON("");
}
@ -117,7 +114,6 @@ namespace nytl {
const std::function<std::string(std::string)> &escape) override;
};
/* Rendering Frame */
uptr<RFrame> RFrame_OverParts::toMe(bool returned, const global_elem_set_t &elem_ns, Ditch &result,
const std::function<std::string(std::string)> &escape) {
if (!returned)
@ -151,11 +147,7 @@ namespace nytl {
const json::JSON* X = passed_args[0].JSON_subval;
assert(X);
if (name == "jesc") {
std::string escaped_json = escape(json::generate_str(*X, json::print_pretty));
rstrip(escaped_json);
append(escaped_json, result);
} else if (name == "jesccomp") {
append(escape(json::generate_str(*X, json::print_compact)), result);
append(escape(json::generate_str(*X, json::print_pretty)), result);
} else if (name == "str2text") {
ASSERT(X->isString(), "str2text takes json string");
append(escape(X->asString()), result);
@ -169,10 +161,10 @@ namespace nytl {
if (part_to_do == el.parts.size())
return NULL;
const ElementPart& cur_part = el.parts[part_to_do++];
if (cur_part.type == ElementPart::p_code) {
if (cur_part.type == element_part_types::code) {
const ElementPart::when_code_S& pt = cur_part.when_code;
append(pt.lines, result);
} else if (cur_part.type == ElementPart::p_put) {
} 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");
@ -182,7 +174,7 @@ namespace nytl {
passed_arguments_expv[i] = rendering_core_execute_expression(elem_ns, passed_args, pt.passed_arguments[i]);
return std::make_unique<RFrame_OverParts>(called_element_expv.EL_name, passed_arguments_expv,
result.cur_line_width);
} else if (cur_part.type == ElementPart::p_for_put) {
} else if (cur_part.type == element_part_types::for_put) {
const ElementPart::when_for_put_S& pt = cur_part.when_for_put;
LocalVarValue iting_over = rendering_core_execute_expression(elem_ns, passed_args, pt.ref_over);
ASSERT(iting_over.is_json, "Can't iterate over element");
@ -193,7 +185,7 @@ namespace nytl {
return std::make_unique<RFrame_OverDictionary>(pt, result.cur_line_width, passed_args, container.asDictionary());
} else
THROW("Can't iterate over non-natalistic jsobject");
} else if (cur_part.type == ElementPart::p_ref_put) {
} else if (cur_part.type == element_part_types::ref_put) {
const ElementPart::when_ref_put_S& pt = cur_part.when_ref_put;
std::vector<LocalVarValue> more_variables(passed_args.size() + 1);
std::copy(passed_args.begin(), passed_args.end(), more_variables.begin());
@ -220,10 +212,10 @@ namespace nytl {
}
uptr<RFrame> RFrame_OverDictionary::toMe(bool returned, RFrame_passed) {
if (it == dict.end())
return NULL;
if (returned && part.line_feed)
append("\n", result);
if (it == dict.end())
return NULL;
if (part.where_key_var > -1) {
addition_json_wrapper.asString() = it->first;
saved_args_plus_iter[part.where_key_var] = {true, "", &addition_json_wrapper};
@ -235,17 +227,18 @@ namespace nytl {
return std::make_unique<RFrame_OverParts>(part.internal_element, saved_args_plus_iter, wsp_before_newlines);
}
std::string rendering_core(const std::string& entry_func, const std::vector<const json::JSON*>& entry_arguments,
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]};
entry_arguments_conv[i] = {true, "", &entry_arguments[i]};
stack.push_back(std::make_unique<RFrame_OverParts>(entry_func, entry_arguments_conv, 0));
}
bool returned = false;

View File

@ -112,10 +112,7 @@ namespace nytl {
void Templater::update() {
elements = {
{"jesc", Element{{json::JSON(true)}, true}},
{"jesccomp", Element{{json::JSON(true)}, true}},
/* str2text base element has a dedicated operator - WRITE */
{"str2text", Element{{json::JSON(true)}, true}},
/* str2code base element has a dedicated operator - ROUGHINSERT */
{"str2code", Element{{json::JSON(true)}, true}},
};
std::vector<InterestingFile> intersting_files = indexing_detour(settings.det);
@ -130,7 +127,7 @@ namespace nytl {
}
/* Still can throw some stuff derived from std::exception (like bad alloc) */
std::string Templater::render(const std::string& element, const std::vector<const json::JSON*> &arguments) const {
std::string Templater::render(const std::string& element, const std::vector<json::JSON> &arguments) const {
ASSERT(is_uname_dotted_sequence(element), "Incorrect entry element name");
return rendering_core(element, arguments, elements, settings.escape);
}

View File

@ -10,15 +10,21 @@
namespace nytl {
typedef json::JSON expression_t;
namespace element_part_types {
enum element_part_type_E {
code,
/* write statements really mean PUT str2text X */
put,
for_put,
ref_put
};
}
typedef element_part_types::element_part_type_E element_part_type_t;
struct ElementPart {
/* Used with all types */
enum element_part_type_E {
p_code,
/* write statements really mean PUT str2text X */
p_put,
p_for_put,
p_ref_put
} type = p_code;
element_part_type_t type = element_part_types::code;
struct when_code_S {
std::string lines;
} when_code;
@ -74,7 +80,7 @@ namespace nytl {
void update();
/* Throws exception, derived from std::exception */
std::string render(const std::string& element, const std::vector<const json::JSON*>& arguments) const;
std::string render(const std::string& element, const std::vector<json::JSON>& arguments) const;
};
}

View File

@ -1,9 +0,0 @@
{% ELDEF main JSON cba %}
AAA
{% FOR _:val IN cba %}
TUTUTUTUTUTUTUTUN {% PUT jesccomp val %}
{% ENDFOR %}
{% ENDELDEF %}

View File

@ -1,6 +1,6 @@
#include <jsonincpp/string_representation.h>
#include <new_york_transit_line/templater.h>
#include <new_york_transit_line/core.h>
/* Yep, tests for nytl depend on assets for website. Yep, I see no problem with that */
int main(int argc, char** argv) {
if (argc < 2) {
@ -11,17 +11,10 @@ int main(int argc, char** argv) {
std::string dir_path = argv[1];
nytl::Templater templater(nytl::TemplaterSettings{nytl::TemplaterDetourRules{dir_path}});
templater.update();
nytl::debug_print_templater(templater);
json::JSON cba;
cba["boba"] = json::JSON("<>");
cba["arr"][0] = json::JSON("zero");
cba["arr"][1] = json::JSON("one");
cba["arr"][2] = json::JSON("two");
// printf("DEBUG WAS: %p\n", &cba["boba"].g());
// printf("%s\n", json::generate_str(cba["boba"].g(), json::print_compact).c_str());
// return 0;
std::string answer2 = templater.render("test", {&cba});
printf("%s\n<a><f><t><e><r><><l><f>\n", answer2.c_str());
std::string answer = templater.render("list-rooms", {});
printf("%s\n<a><f><t><e><r><><l><f>\n", answer.c_str());
std::string answer2 = templater.render("test", {});
printf("%s\n<a><f><t><e><r><><l><f>\n", answer.c_str());
return 0;
}

View File

@ -10,8 +10,6 @@
#include <engine_engine_number_9/form_data_structure/urlencoded_query.h>
#include <new_york_transit_line/templater.h>
#include "../http_server/engine_engine_number_9/running_mainloop.h"
bool termination = false;
void sigterm_action(int) {
@ -19,7 +17,7 @@ void sigterm_action(int) {
}
void usage(char** argv) {
printf("Usage: %s <file with settings>\n", argv[0]);
printf("Usage: %s <file with settings> <assets folder>\n", argv[0]);
exit(1);
}
@ -34,26 +32,30 @@ std::string unsafe_client_request_stringification(const een9::ClientRequest& req
}
int main(int argc, char** argv){
printf("%s\n", regexis024::opcode_to_str(regexis024::opcode_t::DIE));
try {
een9_ASSERT_pl(argc > 0);
if (argc < 1 + 1)
if (argc < 1 + 2)
usage(argv);
if (!een9::isRegularFile(argv[1]) || !een9::endsIn(argv[1], ".json")) {
printf("\"%s\" is not a json file\n", argv[1]);
usage(argv);
}
std::string config_file = argv[1];
if (!een9::isDirectory(argv[2])) {
printf("\"%s\" is not a directory\n", argv[2]);
usage(argv);
}
std::string assets_dir = argv[2];
std::string config_text;
een9::readFile(config_file, config_text);
json::JSON config = json::parse_str_flawless(config_text);
een9_ASSERT(config.isDictionary(), "config root is not dictionary");
een9_ASSERT(config["assets"].g().isString(), "config[\"\assets\"] is not string");
std::string assets_dir = config["assets"].g().asString();
een9_ASSERT(een9::isDirectory(assets_dir), "\"" + assets_dir + "\" is not a directory");
een9::StaticAssetManagerSlaveModule samI;
samI.update({
een9::StaticAssetManagerRule{assets_dir + "/HypertextPages", "/assets/html", {{".html", "text/html"}} },
een9::StaticAssetManagerRule{assets_dir + "/css", "/assets/css", {{".css", "text/css"}} },
een9::StaticAssetManagerRule{assets_dir + "/js", "/assets/js", {{".js", "text/js"}} },
een9::StaticAssetManagerRule{assets_dir + "/img", "/assets/img", {
@ -61,47 +63,31 @@ int main(int argc, char** argv){
} },
});
json::JSON& config_presentation = config["presentation"].g();
/* Because templaters use libjsonincpp, they can't be READ by two thread simultaneously */
std::vector<std::unique_ptr<nytl::Templater>> templaters_copies(8);
for (int i = 0; i < 8; i++) {
templaters_copies[i] = std::make_unique<nytl::Templater>(
nytl::TemplaterSettings{nytl::TemplaterDetourRules{assets_dir + "/HypertextPages"}});
templaters_copies[i]->update();
}
// printf("%s\n", templaters_copies[0]->render("list-rooms", {&config_presentation}).c_str());
// return 0;
een9::MainloopParameters params;
params.guest_core = [&samI, &templaters_copies, config_presentation]
(const een9::SlaveTask& task, const een9::ClientRequest& req, een9::worker_id_t worker_id) -> std::string {
een9_ASSERT_pl(0 <= worker_id && worker_id < templaters_copies.size());
nytl::Templater& templater = *templaters_copies[worker_id];
params.guest_core = [&samI](const een9::SlaveTask& task, const een9::ClientRequest& req) -> std::string {
een9::StaticAsset sa;
int ret;
// printf("%s", unsafe_client_request_stringification(req).c_str());
// if (req.uri_path == "/output") {
// std::string text = unsafe_client_request_stringification(req);
// return een9::form_http_server_response_200("text/plain", text);
// }
auto rteee = [&](const std::string& el_name, bool pass_phr) -> std::string {
std::string page = templater.render(el_name,
pass_phr ? std::vector<const json::JSON*>{&config_presentation} : std::vector<const json::JSON*>{});
return een9::form_http_server_response_200("text/html", page);
if (req.uri_path == "/output") {
std::string text = unsafe_client_request_stringification(req);
return een9::form_http_server_response_200("text/plain", text);
}
auto rteee = [&](const std::string& asset_path) -> std::string {
ret = samI.get_asset(asset_path, sa);
een9_ASSERT_pl(ret == 0);
return een9::form_http_server_response_200(sa.type, sa.content);
};
if (req.uri_path == "/" || req.uri_path == "/list-rooms") {
return rteee("list-rooms", true);
return rteee("/assets/html/list-rooms.html");
}
if (req.uri_path == "/chat") {
return rteee("chat", false);
return rteee("/assets/html/chat.html");
}
if (req.uri_path == "/profile") {
return rteee("profile", false);
return rteee("/assets/html/profile.html");
}
if (req.uri_path == "/registration") {
return rteee("registration", false);
return rteee("/assets/html/registration.html");
}
/* Trying to interpret request as asset lookup */
ret = samI.get_asset(req.uri_path, sa);
@ -110,7 +96,6 @@ int main(int argc, char** argv){
}
return een9::form_http_server_response_404("text/html", "<h1> Not found! </h1>");
};
params.ports_to_listen = {1025};
params.slave_number = 8;
params.open_admin_listener = false;