refactor: rename DTree to DValue

This commit is contained in:
udo
2026-06-12 11:05:52 +00:00
parent 941f5aea08
commit 7066da3cde
157 changed files with 1203 additions and 1074 deletions
+5 -5
View File
@@ -1,8 +1,8 @@
#include "cli.h"
DTree cli_input(Request& context)
DValue cli_input(Request& context)
{
DTree input;
DValue input;
for(auto& item : context.get)
input[item.first] = item.second;
@@ -16,7 +16,7 @@ DTree cli_input(Request& context)
String body = trim(context.in);
if(body != "")
{
DTree parsed = json_decode(body);
DValue parsed = json_decode(body);
if(parsed.type == 'M')
{
for(auto& item : parsed._map)
@@ -34,8 +34,8 @@ DTree cli_input(Request& context)
String cli_arg(Request& context, String key, String default_value)
{
DTree input = cli_input(context);
DTree* value = input.key(key);
DValue input = cli_input(context);
DValue* value = input.key(key);
if(!value)
return(default_value);
String result = value->to_string();
+1 -1
View File
@@ -1,4 +1,4 @@
#pragma once
DTree cli_input(Request& context);
DValue cli_input(Request& context);
String cli_arg(Request& context, String key, String default_value = "");
+24 -24
View File
@@ -18,7 +18,7 @@ const char* UCE_CLI_SYMBOL = "__uce_cli";
const char* UCE_SERVE_HTTP_SYMBOL = "__uce_serve_http";
const char* UCE_ONCE_SYMBOL = "__uce_once";
const char* UCE_INIT_SYMBOL = "__uce_init";
const u64 UCE_UNIT_ABI_VERSION = 5;
const u64 UCE_UNIT_ABI_VERSION = 6;
struct SharedUnitFilesystemState
{
@@ -575,21 +575,21 @@ String compiler_unit_exports_text(SharedUnit* su)
return(trim(file_get_contents(su->api_file_name)));
}
void compiler_tree_push_string(DTree& tree, String value)
void compiler_tree_push_string(DValue& tree, String value)
{
DTree item;
DValue item;
item = value;
tree.push(item);
}
void compiler_tree_push_strings(DTree& tree, StringList values)
void compiler_tree_push_strings(DValue& tree, StringList values)
{
tree.set_array();
for(auto& value : values)
compiler_tree_push_string(tree, value);
}
void compiler_tree_set_bool(DTree& tree, String key, bool value)
void compiler_tree_set_bool(DValue& tree, String key, bool value)
{
tree[key].set_bool(value);
}
@@ -995,7 +995,7 @@ SharedUnit* compiler_load_shared_unit(Request* context, String file_name, String
printf("%s\n", display_messages.c_str());
if(compiler_can_write_response(context) && context->stats.invoke_count == 1)
{
DTree error_info;
DValue error_info;
error_info["type"] = "compiler_error";
error_info["status"] = su->compile_status;
error_info["source"] = su->file_name;
@@ -1124,9 +1124,9 @@ bool compiler_unit_needs_recompile(Request* context, String file_name, bool* sou
return(compile_check.needs_compile);
}
DTree unit_info(String path)
DValue unit_info(String path)
{
DTree info;
DValue info;
if(!context)
return(info);
@@ -1303,9 +1303,9 @@ struct UnitCallMacroTarget
struct RequestPropsScope
{
Request* context = 0;
DTree previous_props;
DValue previous_props;
RequestPropsScope(Request* context, const DTree& props)
RequestPropsScope(Request* context, const DValue& props)
{
this->context = context;
if(this->context)
@@ -1766,7 +1766,7 @@ String compiler_error_page_unit(Request* context, String config_key)
return(resolved);
}
bool compiler_render_error_page(Request* context, String config_key, s32 status_code, String status_reason, DTree error_info)
bool compiler_render_error_page(Request* context, String config_key, s32 status_code, String status_reason, DValue error_info)
{
if(!compiler_can_write_response(context))
return(false);
@@ -1840,7 +1840,7 @@ void compiler_invoke(Request* context, String file_name)
if(resolved != "" && compiler_unit_compile_pending(context, resolved))
{
compiler_track_known_unit(context, resolved);
DTree error_info;
DValue error_info;
error_info["type"] = "compiling";
error_info["source"] = resolved;
if(compiler_render_error_page(context, "page_compiling", 503, "UCE Unit Compiling", error_info))
@@ -1963,22 +1963,22 @@ String component_error_banner(String message)
void component_render(String name)
{
DTree props;
DValue props;
component_render(name, props, *context);
}
void component_render(String name, Request& context)
{
DTree props;
DValue props;
component_render(name, props, context);
}
void component_render(String name, DTree props)
void component_render(String name, DValue props)
{
component_render(name, props, *context);
}
void component_render(String name, DTree props, Request& context)
void component_render(String name, DValue props, Request& context)
{
String file_name;
String render_name;
@@ -2000,22 +2000,22 @@ void component_render(String name, DTree props, Request& context)
String component(String name)
{
DTree props;
DValue props;
return(component(name, props, *context));
}
String component(String name, Request& context)
{
DTree props;
DValue props;
return(component(name, props, context));
}
String component(String name, DTree props)
String component(String name, DValue props)
{
return(component(name, props, *context));
}
String component(String name, DTree props, Request& context)
String component(String name, DValue props, Request& context)
{
ob_start();
component_render(name, props, context);
@@ -2035,9 +2035,9 @@ SharedUnit* unit_load(String file_name)
}
}
DTree* unit_call(String file_name, String function_name, DTree* call_param)
DValue* unit_call(String file_name, String function_name, DValue* call_param)
{
DTree* result = 0;
DValue* result = 0;
auto su = compiler_load_shared_unit(context, file_name, "", false);
if(su && su->so_handle)
{
@@ -2050,7 +2050,7 @@ DTree* unit_call(String file_name, String function_name, DTree* call_param)
auto macro_target = unit_call_macro_target(function_name);
if(macro_target.kind != UnitCallMacroKind::none)
{
RequestPropsScope props_scope(context, (call_param ? *call_param : DTree()));
RequestPropsScope props_scope(context, (call_param ? *call_param : DValue()));
String error_message = "";
if(macro_target.kind == UnitCallMacroKind::render)
@@ -2094,7 +2094,7 @@ DTree* unit_call(String file_name, String function_name, DTree* call_param)
}
else
{
auto f = (dtree_call_handler)dlsym(su->so_handle, function_name.c_str());
auto f = (dv_call_handler)dlsym(su->so_handle, function_name.c_str());
if(!f)
{
print("Error: unit_call() function '", function_name, "' not found");
+7 -7
View File
@@ -22,7 +22,7 @@ void compiler_invoke_cli(Request* context, String file_name);
void compiler_invoke_serve_http(Request* context, String file_name, String handler_name = "");
SharedUnit* compiler_load_shared_unit(Request* context, String file_name, String current_path = "", bool opt_so_optional = false);
String compiler_error_page_unit(Request* context, String config_key);
bool compiler_render_error_page(Request* context, String config_key, s32 status_code, String status_reason, DTree error_info);
bool compiler_render_error_page(Request* context, String config_key, s32 status_code, String status_reason, DValue error_info);
bool compiler_unit_compile_pending(Request* context, String file_name);
String compiler_site_directory(Request* context);
StringList compiler_scan_site_units(Request* context);
@@ -31,21 +31,21 @@ void compiler_set_known_units(Request* context, StringList files);
void compiler_track_known_unit(Request* context, String file_name);
void compiler_untrack_known_unit(Request* context, String file_name);
bool compiler_unit_needs_recompile(Request* context, String file_name, bool* source_missing = 0);
DTree unit_info(String path = "");
DValue unit_info(String path = "");
StringList units_list();
bool unit_compile(String path = "");
SharedUnit* unit_load(String file_name);
void unit_render(String file_name);
void unit_render(String file_name, Request& context);
DTree* unit_call(String file_name, String function_name, DTree* call_param = 0);
DValue* unit_call(String file_name, String function_name, DValue* call_param = 0);
String component_resolve(String name);
bool component_exists(String name);
void component_render(String name);
void component_render(String name, Request& context);
void component_render(String name, DTree props);
void component_render(String name, DTree props, Request& context);
void component_render(String name, DValue props);
void component_render(String name, DValue props, Request& context);
String component(String name);
String component(String name, Request& context);
String component(String name, DTree props);
String component(String name, DTree props, Request& context);
String component(String name, DValue props);
String component(String name, DValue props, Request& context);
+111 -111
View File
@@ -6,7 +6,7 @@
namespace {
template <typename TreePtr>
TreePtr dtree_resolve_reference(TreePtr tree)
TreePtr dv_resolve_reference(TreePtr tree)
{
u32 depth = 0;
while(tree && tree->type == 'R' && depth < 16)
@@ -20,7 +20,7 @@ TreePtr dtree_resolve_reference(TreePtr tree)
return(tree);
}
bool dtree_key_is_index(String key)
bool dv_key_is_index(String key)
{
if(key == "")
return(false);
@@ -36,7 +36,7 @@ bool dtree_key_is_index(String key)
return(true);
}
String dtree_trim(String raw)
String dv_trim(String raw)
{
if(raw == "")
return(raw);
@@ -52,16 +52,16 @@ String dtree_trim(String raw)
return(raw.substr(start, end - start));
}
String dtree_lower(String raw)
String dv_lower(String raw)
{
for(auto& c : raw)
c = (char)tolower(c);
return(raw);
}
bool dtree_string_to_bool_value(String raw, bool& value_out)
bool dv_string_to_bool_value(String raw, bool& value_out)
{
raw = dtree_lower(dtree_trim(raw));
raw = dv_lower(dv_trim(raw));
if(raw == "")
return(false);
if(raw == "1" || raw == "true" || raw == "(true)" || raw == "yes" || raw == "on")
@@ -77,14 +77,14 @@ bool dtree_string_to_bool_value(String raw, bool& value_out)
return(false);
}
bool dtree_string_to_f64_value(String raw, f64& value_out)
bool dv_string_to_f64_value(String raw, f64& value_out)
{
raw = dtree_trim(raw);
raw = dv_trim(raw);
if(raw == "")
return(false);
bool bool_value = false;
if(dtree_string_to_bool_value(raw, bool_value))
if(dv_string_to_bool_value(raw, bool_value))
{
value_out = (bool_value ? 1.0 : 0.0);
return(true);
@@ -103,7 +103,7 @@ bool dtree_string_to_f64_value(String raw, f64& value_out)
return(std::isfinite(value_out));
}
const DTree* dtree_scalar_map_value(const DTree& tree)
const DValue* dv_scalar_map_value(const DValue& tree)
{
if(tree.type != 'M' || tree._map.size() != 1)
return(0);
@@ -113,7 +113,7 @@ const DTree* dtree_scalar_map_value(const DTree& tree)
return(&it->second.deref());
}
f64 dtree_clamp_to_f64_range(long double value)
f64 dv_clamp_to_f64_range(long double value)
{
if(value > std::numeric_limits<f64>::max())
return(std::numeric_limits<f64>::max());
@@ -122,7 +122,7 @@ f64 dtree_clamp_to_f64_range(long double value)
return((f64)value);
}
s64 dtree_clamp_to_s64_range(long double value)
s64 dv_clamp_to_s64_range(long double value)
{
if(value > (long double)std::numeric_limits<s64>::max())
return(std::numeric_limits<s64>::max());
@@ -131,7 +131,7 @@ s64 dtree_clamp_to_s64_range(long double value)
return((s64)value);
}
u64 dtree_clamp_to_u64_range(long double value)
u64 dv_clamp_to_u64_range(long double value)
{
if(value <= 0)
return(0);
@@ -142,9 +142,9 @@ u64 dtree_clamp_to_u64_range(long double value)
}
void DTree::each(std::function <void (const DTree& t, String key)> f) const
void DValue::each(std::function <void (const DValue& t, String key)> f) const
{
const DTree& target = deref();
const DValue& target = deref();
switch(target.type)
{
case('M'):
@@ -172,14 +172,14 @@ void DTree::each(std::function <void (const DTree& t, String key)> f) const
}
}
bool DTree::is_array() const
bool DValue::is_array() const
{
return(deref().type == 'M');
}
bool DTree::is_list() const
bool DValue::is_list() const
{
const DTree& target = deref();
const DValue& target = deref();
if(target.type != 'M')
return(false);
if(target._map.size() == 0)
@@ -190,7 +190,7 @@ bool DTree::is_list() const
s64 max_index = -1;
for(const auto& entry : target._map)
{
if(!dtree_key_is_index(entry.first))
if(!dv_key_is_index(entry.first))
return(false);
s64 index = strtoll(entry.first.c_str(), 0, 10);
if(index > max_index)
@@ -199,9 +199,9 @@ bool DTree::is_list() const
return(max_index == (s64)target._map.size() - 1);
}
String DTree::to_string(String default_value) const
String DValue::to_string(String default_value) const
{
const DTree& target = deref();
const DValue& target = deref();
switch(target.type)
{
case('S'):
@@ -222,56 +222,56 @@ String DTree::to_string(String default_value) const
return(default_value);
}
s64 DTree::to_s64(s64 default_value) const
s64 DValue::to_s64(s64 default_value) const
{
const DTree& target = deref();
const DValue& target = deref();
switch(target.type)
{
case('S'):
{
f64 value = 0;
if(!dtree_string_to_f64_value(target._String, value))
if(!dv_string_to_f64_value(target._String, value))
return(default_value);
return(dtree_clamp_to_s64_range((long double)value));
return(dv_clamp_to_s64_range((long double)value));
}
case('F'):
return(dtree_clamp_to_s64_range((long double)target._float));
return(dv_clamp_to_s64_range((long double)target._float));
case('B'):
return(target._bool ? 1 : 0);
case('M'):
{
const DTree* item = dtree_scalar_map_value(target);
const DValue* item = dv_scalar_map_value(target);
if(item)
return(item->to_s64(default_value));
return(default_value);
}
case('P'):
return(dtree_clamp_to_s64_range((long double)(u64)target._ptr));
return(dv_clamp_to_s64_range((long double)(u64)target._ptr));
case('R'):
return(default_value);
}
return(default_value);
}
u64 DTree::to_u64(u64 default_value) const
u64 DValue::to_u64(u64 default_value) const
{
const DTree& target = deref();
const DValue& target = deref();
switch(target.type)
{
case('S'):
{
f64 value = 0;
if(!dtree_string_to_f64_value(target._String, value))
if(!dv_string_to_f64_value(target._String, value))
return(default_value);
return(dtree_clamp_to_u64_range((long double)value));
return(dv_clamp_to_u64_range((long double)value));
}
case('F'):
return(dtree_clamp_to_u64_range((long double)target._float));
return(dv_clamp_to_u64_range((long double)target._float));
case('B'):
return(target._bool ? 1 : 0);
case('M'):
{
const DTree* item = dtree_scalar_map_value(target);
const DValue* item = dv_scalar_map_value(target);
if(item)
return(item->to_u64(default_value));
return(default_value);
@@ -284,15 +284,15 @@ u64 DTree::to_u64(u64 default_value) const
return(default_value);
}
f64 DTree::to_f64(f64 default_value) const
f64 DValue::to_f64(f64 default_value) const
{
const DTree& target = deref();
const DValue& target = deref();
switch(target.type)
{
case('S'):
{
f64 value = 0;
if(!dtree_string_to_f64_value(target._String, value))
if(!dv_string_to_f64_value(target._String, value))
return(default_value);
return(value);
}
@@ -302,35 +302,35 @@ f64 DTree::to_f64(f64 default_value) const
return(target._bool ? 1.0 : 0.0);
case('M'):
{
const DTree* item = dtree_scalar_map_value(target);
const DValue* item = dv_scalar_map_value(target);
if(item)
return(item->to_f64(default_value));
return(default_value);
}
case('P'):
return(dtree_clamp_to_f64_range((long double)(u64)target._ptr));
return(dv_clamp_to_f64_range((long double)(u64)target._ptr));
case('R'):
return(default_value);
}
return(default_value);
}
bool DTree::to_bool(bool default_value) const
bool DValue::to_bool(bool default_value) const
{
const DTree& target = deref();
const DValue& target = deref();
switch(target.type)
{
case('S'):
{
bool value = false;
if(dtree_string_to_bool_value(target._String, value))
if(dv_string_to_bool_value(target._String, value))
return(value);
f64 numeric_value = 0;
if(dtree_string_to_f64_value(target._String, numeric_value))
if(dv_string_to_f64_value(target._String, numeric_value))
return(numeric_value != 0);
// Non-empty unparseable strings stay truthy; only a missing/empty
// value falls back to the default.
if(dtree_trim(target._String) != "")
if(dv_trim(target._String) != "")
return(true);
return(default_value);
}
@@ -340,7 +340,7 @@ bool DTree::to_bool(bool default_value) const
return(target._bool);
case('M'):
{
const DTree* item = dtree_scalar_map_value(target);
const DValue* item = dv_scalar_map_value(target);
if(item)
return(item->to_bool(default_value));
return(target._map.size() > 0);
@@ -353,9 +353,9 @@ bool DTree::to_bool(bool default_value) const
return(default_value);
}
StringMap DTree::to_stringmap() const
StringMap DValue::to_stringmap() const
{
const DTree& target = deref();
const DValue& target = deref();
StringMap result;
switch(target.type)
{
@@ -364,7 +364,7 @@ StringMap DTree::to_stringmap() const
result[entry.first] = entry.second.deref().to_string();
break;
case('S'):
if(dtree_trim(target._String) != "")
if(dv_trim(target._String) != "")
result["value"] = target._String;
break;
case('F'):
@@ -378,9 +378,9 @@ StringMap DTree::to_stringmap() const
return(result);
}
String DTree::to_json(char quote_char) const
String DValue::to_json(char quote_char) const
{
const DTree& target = deref();
const DValue& target = deref();
switch(target.type)
{
case('S'):
@@ -405,9 +405,9 @@ String DTree::to_json(char quote_char) const
return("\"(unknown)\"");
}
String DTree::get_type_name() const
String DValue::get_type_name() const
{
const DTree& target = deref();
const DValue& target = deref();
switch(target.type)
{
case('S'):
@@ -432,9 +432,9 @@ String DTree::get_type_name() const
return("unknown");
}
DTree DTree::get_by_path(String path, String delim) const
DValue DValue::get_by_path(String path, String delim) const
{
const DTree* current = &deref();
const DValue* current = &deref();
if(path == "")
return(*current);
size_t start = 0;
@@ -455,10 +455,10 @@ DTree DTree::get_by_path(String path, String delim) const
}
current = &current->deref();
if(current->type != 'M')
return(DTree());
return(DValue());
auto it = current->_map.find(segment);
if(it == current->_map.end())
return(DTree());
return(DValue());
current = &it->second;
if(end == String::npos)
break;
@@ -467,50 +467,50 @@ DTree DTree::get_by_path(String path, String delim) const
return(current->deref());
}
bool DTree::is_reference() const
bool DValue::is_reference() const
{
return(type == 'R');
}
DTree* DTree::reference_target()
DValue* DValue::reference_target()
{
if(type != 'R')
return(0);
DTree* target = dtree_resolve_reference(this);
DValue* target = dv_resolve_reference(this);
if(target == 0 || target == this || target->type == 'R')
return(0);
return(target);
}
const DTree* DTree::reference_target() const
const DValue* DValue::reference_target() const
{
if(type != 'R')
return(0);
const DTree* target = dtree_resolve_reference(this);
const DValue* target = dv_resolve_reference(this);
if(target == 0 || target == this || target->type == 'R')
return(0);
return(target);
}
DTree& DTree::deref()
DValue& DValue::deref()
{
DTree* target = dtree_resolve_reference(this);
DValue* target = dv_resolve_reference(this);
if(target == 0)
return(*this);
return(*target);
}
const DTree& DTree::deref() const
const DValue& DValue::deref() const
{
const DTree* target = dtree_resolve_reference(this);
const DValue* target = dv_resolve_reference(this);
if(target == 0)
return(*this);
return(*target);
}
void DTree::set_type(char t)
void DValue::set_type(char t)
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
{
target->set_type(t);
@@ -530,9 +530,9 @@ void DTree::set_type(char t)
}
}
void DTree::set(String s)
void DValue::set(String s)
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
{
target->set(s);
@@ -543,9 +543,9 @@ void DTree::set(String s)
_list_mode = false;
}
void DTree::set(void* p)
void DValue::set(void* p)
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
{
target->set(p);
@@ -556,9 +556,9 @@ void DTree::set(void* p)
_list_mode = false;
}
void DTree::set(f64 f)
void DValue::set(f64 f)
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
{
target->set(f);
@@ -569,9 +569,9 @@ void DTree::set(f64 f)
_list_mode = false;
}
void DTree::set_bool(bool b)
void DValue::set_bool(bool b)
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
{
target->set_bool(b);
@@ -582,9 +582,9 @@ void DTree::set_bool(bool b)
_list_mode = false;
}
void DTree::set(DTree source)
void DValue::set(DValue source)
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
{
target->set(source);
@@ -621,9 +621,9 @@ void DTree::set(DTree source)
}
}
void DTree::set(StringMap source)
void DValue::set(StringMap source)
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
{
target->set(source);
@@ -639,9 +639,9 @@ void DTree::set(StringMap source)
}
}
void DTree::set_array()
void DValue::set_array()
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
{
target->set_array();
@@ -653,23 +653,23 @@ void DTree::set_array()
_list_mode = true;
}
void DTree::set_reference(DTree* target)
void DValue::set_reference(DValue* target)
{
type = 'R';
_ptr = target;
}
bool DTree::has(String s) const
bool DValue::has(String s) const
{
const DTree& target = deref();
const DValue& target = deref();
if(target.type != 'M')
return(false);
return(target._map.find(s) != target._map.end());
}
DTree* DTree::key(String s)
DValue* DValue::key(String s)
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
return(target->key(s));
if(type != 'M')
@@ -680,9 +680,9 @@ DTree* DTree::key(String s)
return(&it->second);
}
const DTree* DTree::key(String s) const
const DValue* DValue::key(String s) const
{
const DTree& target = deref();
const DValue& target = deref();
if(target.type != 'M')
return(0);
auto it = target._map.find(s);
@@ -691,33 +691,33 @@ const DTree* DTree::key(String s) const
return(&it->second);
}
DTree* DTree::get_or_create(String s)
DValue* DValue::get_or_create(String s)
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
return(target->get_or_create(s));
set_type('M');
if(_list_mode && !dtree_key_is_index(s))
if(_list_mode && !dv_key_is_index(s))
_list_mode = false;
return(&_map[s]);
}
DTree& DTree::operator [] (String s) {
DTree* target = reference_target();
DValue& DValue::operator [] (String s) {
DValue* target = reference_target();
if(target)
return((*target)[s]);
return(*get_or_create(s));
}
void DTree::operator = (String v) { set(v); }
void DTree::operator = (f64 v) { set(v); }
void DTree::operator = (void* v) { set(v); }
void DTree::operator = (DTree v) { set(v); }
void DTree::operator = (StringMap v) { set(v); }
void DValue::operator = (String v) { set(v); }
void DValue::operator = (f64 v) { set(v); }
void DValue::operator = (void* v) { set(v); }
void DValue::operator = (DValue v) { set(v); }
void DValue::operator = (StringMap v) { set(v); }
void DTree::push(const DTree& child)
void DValue::push(const DValue& child)
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
{
target->push(child);
@@ -747,28 +747,28 @@ void DTree::push(const DTree& child)
_array_index += 1;
}
DTree DTree::pop()
DValue DValue::pop()
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
return(target->pop());
set_type('M');
if(_map.empty())
{
_array_index = 0;
return(DTree());
return(DValue());
}
auto last = _map.rbegin();
DTree result = last->second;
DValue result = last->second;
_map.erase(last->first);
if(_list_mode)
_array_index = _map.size();
return(result);
}
void DTree::remove(String s)
void DValue::remove(String s)
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
{
target->remove(s);
@@ -780,9 +780,9 @@ void DTree::remove(String s)
_array_index = 0;
}
void DTree::clear()
void DValue::clear()
{
DTree* target = reference_target();
DValue* target = reference_target();
if(target)
{
target->clear();
@@ -793,17 +793,17 @@ void DTree::clear()
_array_index = 0;
}
String to_String(DTree t)
String to_String(DValue t)
{
return(t.to_string());
}
String var_dump(const DTree& map, String prefix, String postfix)
String var_dump(const DValue& map, String prefix, String postfix)
{
String result = "";
if(!map.is_array())
return(map.to_string());
map.each([&] (const DTree& item, String key) {
map.each([&] (const DValue& item, String key) {
result += prefix + key + ": " + item.to_string() + postfix;
if(item.is_array())
result += var_dump(item, prefix + "\t");
+20 -20
View File
@@ -2,12 +2,12 @@
String json_escape(String s, char quote_char = '"');
// DTree is UCE's general-purpose structured value container.
// DValue is UCE's general-purpose structured value container.
// It stores scalar values, nested map/list-like values, and internal references.
// Numeric and boolean reads are intentionally permissive so request data,
// JSON-decoded values, and metadata trees can be consumed without repetitive
// manual parsing at each call site.
struct DTree {
struct DValue {
char type = 'S';
@@ -17,12 +17,12 @@ struct DTree {
bool _bool;
bool _list_mode = false;
void* _ptr;
std::map<String, DTree> _map;
std::map<String, DValue> _map;
// Read accessors are const and never create or modify nodes. The to_*
// conversions take an optional default that is returned when the value is
// missing (empty) or cannot be converted to the requested type.
void each(std::function <void (const DTree& t, String key)> f) const;
void each(std::function <void (const DValue& t, String key)> f) const;
bool is_array() const;
bool is_list() const;
String to_string(String default_value = "") const;
@@ -33,37 +33,37 @@ struct DTree {
StringMap to_stringmap() const;
String to_json(char quote_char = '"') const;
String get_type_name() const;
DTree get_by_path(String path, String delim = "/") const;
DValue get_by_path(String path, String delim = "/") const;
bool is_reference() const;
DTree* reference_target();
const DTree* reference_target() const;
DTree& deref();
const DTree& deref() const;
DValue* reference_target();
const DValue* reference_target() const;
DValue& deref();
const DValue& deref() const;
void set_type(char t);
void set(String s);
void set(void* p);
void set(f64 f);
void set_bool(bool b);
void set(DTree source);
void set(DValue source);
void set(StringMap source);
void set_array();
void set_reference(DTree* target);
void set_reference(DValue* target);
bool has(String s) const;
DTree* key(String s);
const DTree* key(String s) const;
DTree* get_or_create(String s);
DTree& operator [] (String s);
DValue* key(String s);
const DValue* key(String s) const;
DValue* get_or_create(String s);
DValue& operator [] (String s);
void operator = (String v);
void operator = (f64 v);
void operator = (void* v);
void operator = (DTree v);
void operator = (DValue v);
void operator = (StringMap v);
void push(const DTree& child);
DTree pop();
void push(const DValue& child);
DValue pop();
void remove(String s);
void clear();
};
String to_String(DTree t);
String var_dump(const DTree& map, String prefix = "", String postfix = "\n");
String to_String(DValue t);
String var_dump(const DValue& map, String prefix = "", String postfix = "\n");
+97 -97
View File
@@ -110,57 +110,57 @@ String list_find(StringList items, std::function<bool (String)> f, String fallba
return(fallback);
}
StringList dtree_keys(DTree tree)
StringList dv_keys(DValue tree)
{
StringList result;
tree.each([&](const DTree& item, String key) {
tree.each([&](const DValue& item, String key) {
if(key != "")
result.push_back(key);
});
return(result);
}
DTree dtree_values(DTree tree)
DValue dv_values(DValue tree)
{
DTree result;
DValue result;
result.set_array();
tree.each([&](const DTree& item, String key) {
tree.each([&](const DValue& item, String key) {
result.push(item);
});
return(result);
}
DTree dtree_pick(DTree tree, StringList keys)
DValue dv_pick(DValue tree, StringList keys)
{
DTree result;
DValue result;
for(auto key : keys)
{
DTree* item = tree.key(key);
DValue* item = tree.key(key);
if(item)
result[key] = *item;
}
return(result);
}
DTree dtree_omit(DTree tree, StringList keys)
DValue dv_omit(DValue tree, StringList keys)
{
DTree result;
DValue result;
std::set<String> omitted(keys.begin(), keys.end());
tree.each([&](const DTree& item, String key) {
tree.each([&](const DValue& item, String key) {
if(key != "" && omitted.find(key) == omitted.end())
result[key] = item;
});
return(result);
}
DTree dtree_map(DTree tree, std::function<DTree (const DTree&, String)> f)
DValue dv_map(DValue tree, std::function<DValue (const DValue&, String)> f)
{
DTree result;
DValue result;
bool input_is_list = tree.is_list();
if(input_is_list)
result.set_array();
tree.each([&](const DTree& item, String key) {
DTree mapped = f(item, key);
tree.each([&](const DValue& item, String key) {
DValue mapped = f(item, key);
if(key != "" && !input_is_list)
result[key] = mapped;
else
@@ -169,13 +169,13 @@ DTree dtree_map(DTree tree, std::function<DTree (const DTree&, String)> f)
return(result);
}
DTree dtree_filter(DTree tree, std::function<bool (const DTree&, String)> f)
DValue dv_filter(DValue tree, std::function<bool (const DValue&, String)> f)
{
DTree result;
DValue result;
bool input_is_list = tree.is_list();
if(input_is_list)
result.set_array();
tree.each([&](const DTree& item, String key) {
tree.each([&](const DValue& item, String key) {
if(!f(item, key))
return;
if(key != "" && !input_is_list)
@@ -186,12 +186,12 @@ DTree dtree_filter(DTree tree, std::function<bool (const DTree&, String)> f)
return(result);
}
DTree dtree_group_by(DTree tree, std::function<String (const DTree&, String)> f)
DValue dv_group_by(DValue tree, std::function<String (const DValue&, String)> f)
{
DTree result;
tree.each([&](const DTree& item, String key) {
DValue result;
tree.each([&](const DValue& item, String key) {
String group = f(item, key);
DTree* group_items = result.get_or_create(group);
DValue* group_items = result.get_or_create(group);
if(!group_items->is_array())
group_items->set_array();
group_items->push(item);
@@ -423,7 +423,7 @@ size_t regex_next_utf8_offset(String subject, size_t offset)
return(offset + step);
}
void regex_add_named_captures(DTree& result, pcre2_code* code, String subject, PCRE2_SIZE* ovector, int rc)
void regex_add_named_captures(DValue& result, pcre2_code* code, String subject, PCRE2_SIZE* ovector, int rc)
{
uint32_t name_count = 0;
uint32_t entry_size = 0;
@@ -456,9 +456,9 @@ void regex_add_named_captures(DTree& result, pcre2_code* code, String subject, P
}
}
DTree regex_build_match_tree(String pattern, String flags, String subject, pcre2_code* code, pcre2_match_data* match_data, int rc)
DValue regex_build_match_tree(String pattern, String flags, String subject, pcre2_code* code, pcre2_match_data* match_data, int rc)
{
DTree result;
DValue result;
result["matched"].set_bool(rc >= 0);
result["pattern"] = pattern;
result["flags"] = regex_flags_label(flags);
@@ -473,7 +473,7 @@ DTree regex_build_match_tree(String pattern, String flags, String subject, pcre2
for(int i = 0; i < rc; i += 1)
{
DTree capture;
DValue capture;
PCRE2_SIZE start = ovector[i * 2];
PCRE2_SIZE end = ovector[i * 2 + 1];
capture["index"] = (f64)i;
@@ -520,7 +520,7 @@ bool regex_match(String pattern, String subject, String flags)
return(rc >= 0);
}
DTree regex_search(String pattern, String subject, String flags)
DValue regex_search(String pattern, String subject, String flags)
{
RegexCode regex(pattern, flags, "regex_search");
RegexMatchData match_data(regex.code);
@@ -528,11 +528,11 @@ DTree regex_search(String pattern, String subject, String flags)
return(regex_build_match_tree(pattern, flags, subject, regex.code, match_data.data, rc));
}
DTree regex_search_all(String pattern, String subject, String flags)
DValue regex_search_all(String pattern, String subject, String flags)
{
RegexCode regex(pattern, flags, "regex_search_all");
RegexMatchData match_data(regex.code);
DTree result;
DValue result;
result["matched"].set_bool(false);
result["pattern"] = pattern;
result["flags"] = regex_flags_label(flags);
@@ -544,7 +544,7 @@ DTree regex_search_all(String pattern, String subject, String flags)
if(rc == PCRE2_ERROR_NOMATCH)
break;
DTree match = regex_build_match_tree(pattern, flags, subject, regex.code, match_data.data, rc);
DValue match = regex_build_match_tree(pattern, flags, subject, regex.code, match_data.data, rc);
result["matches"].push(match);
result["matched"].set_bool(true);
@@ -827,14 +827,14 @@ StringMap array_merge(StringMap a, StringMap b)
return(result);
}
DTree array_merge(DTree a, DTree b)
DValue array_merge(DValue a, DValue b)
{
const DTree& left = a.deref();
const DTree& right = b.deref();
const DValue& left = a.deref();
const DValue& right = b.deref();
if(left.type != 'M')
return(b);
DTree result;
DValue result;
result.set(a);
if(right.type != 'M')
return(result);
@@ -844,7 +844,7 @@ DTree array_merge(DTree a, DTree b)
{
if(append_numeric_keys && array_merge_key_is_index(entry.first))
{
DTree child = entry.second;
DValue child = entry.second;
result.push(child);
}
else
@@ -1008,7 +1008,7 @@ String nibble(String& haystack, String delim)
}
}
String json_encode(DTree t, char quote_char)
String json_encode(DValue t, char quote_char)
{
String result = "";
if(t.is_array())
@@ -1036,7 +1036,7 @@ String json_encode(DTree t, char quote_char)
{
result += "{";
u32 count = 0;
t.each([&] (DTree item, String key) {
t.each([&] (DValue item, String key) {
if(count > 0)
result += ", ";
count += 1;
@@ -1138,35 +1138,35 @@ String xml_safe_name(String raw, String fallback = "item")
return(result);
}
String xml_tree_scalar_text(DTree t)
String xml_tree_scalar_text(DValue t)
{
const DTree& target = t.deref();
const DValue& target = t.deref();
if(target.type == 'B')
return(target._bool ? "true" : "false");
return(t.to_string());
}
const DTree* xml_tree_key(const DTree& t, String key)
const DValue* xml_tree_key(const DValue& t, String key)
{
return(t.deref().key(key));
}
bool xml_tree_has_element_shape(const DTree& t)
bool xml_tree_has_element_shape(const DValue& t)
{
const DTree& target = t.deref();
const DValue& target = t.deref();
return(target.type == 'M' && target.key("name"));
}
String xml_encode_element(DTree tree, String name_hint)
String xml_encode_element(DValue tree, String name_hint)
{
const DTree& target = tree.deref();
const DValue& target = tree.deref();
bool shaped = xml_tree_has_element_shape(target);
String name = xml_safe_name(name_hint, "root");
if(shaped)
{
const DTree* name_node = xml_tree_key(target, "name");
DTree name_copy = *name_node;
const DValue* name_node = xml_tree_key(target, "name");
DValue name_copy = *name_node;
name = xml_safe_name(name_copy.to_string(), name);
}
@@ -1174,12 +1174,12 @@ String xml_encode_element(DTree tree, String name_hint)
if(shaped)
{
const DTree* attrs = xml_tree_key(target, "attrs");
const DValue* attrs = xml_tree_key(target, "attrs");
if(attrs && attrs->deref().type == 'M')
{
for(const auto& entry : attrs->deref()._map)
{
DTree attr_value = entry.second;
DValue attr_value = entry.second;
result += " " + xml_safe_name(entry.first, "attr") + "=\"" + xml_escape_attr(xml_tree_scalar_text(attr_value)) + "\"";
}
}
@@ -1188,17 +1188,17 @@ String xml_encode_element(DTree tree, String name_hint)
String content;
if(shaped)
{
const DTree* text = xml_tree_key(target, "text");
const DValue* text = xml_tree_key(target, "text");
if(text)
{
DTree text_copy = *text;
DValue text_copy = *text;
content += xml_escape_text(xml_tree_scalar_text(text_copy));
}
const DTree* children = xml_tree_key(target, "children");
const DValue* children = xml_tree_key(target, "children");
if(children && children->deref().type == 'M')
{
const DTree& child_map = children->deref();
const DValue& child_map = children->deref();
if(child_map.is_list())
{
for(u32 i = 0; i < child_map._map.size(); i += 1)
@@ -1419,13 +1419,13 @@ struct XmlParser
return(xml_decode_text(src.substr(start, i - start)));
}
DTree parse_element()
DValue parse_element()
{
if(i >= src.length() || src[i] != '<')
xml_throw("expected element at byte " + std::to_string((u64)i));
i += 1;
DTree node;
DValue node;
String name = read_name();
node["name"] = name;
@@ -1494,7 +1494,7 @@ struct XmlParser
if(src[i] == '<')
{
DTree child = parse_element();
DValue child = parse_element();
node["children"].push(child);
continue;
}
@@ -1508,12 +1508,12 @@ struct XmlParser
return(node);
}
DTree parse_document()
DValue parse_document()
{
skip_misc();
if(i >= src.length())
xml_throw("empty document");
DTree result = parse_element();
DValue result = parse_element();
skip_misc();
if(i < src.length())
xml_throw("unexpected content after root element at byte " + std::to_string((u64)i));
@@ -1523,12 +1523,12 @@ struct XmlParser
}
String xml_encode(DTree t, String root_name)
String xml_encode(DValue t, String root_name)
{
return(xml_encode_element(t, root_name));
}
DTree xml_decode(String s)
DValue xml_decode(String s)
{
XmlParser parser(s);
return(parser.parse_document());
@@ -1665,9 +1665,9 @@ String yaml_quote_key(String key)
return(yaml_double_quote(key));
}
String yaml_scalar_to_string(DTree t)
String yaml_scalar_to_string(DValue t)
{
const DTree& target = t.deref();
const DValue& target = t.deref();
switch(target.type)
{
case('B'):
@@ -1693,10 +1693,10 @@ String yaml_scalar_to_string(DTree t)
}
}
String yaml_encode_scalar(DTree t, u32 indent)
String yaml_encode_scalar(DValue t, u32 indent)
{
String raw = yaml_scalar_to_string(t);
const DTree& target = t.deref();
const DValue& target = t.deref();
if(target.type == 'B' || target.type == 'F')
return(raw);
if(raw.find("\n") != String::npos)
@@ -1719,9 +1719,9 @@ String yaml_encode_scalar(DTree t, u32 indent)
return(yaml_double_quote(raw));
}
String yaml_encode_node(DTree t, u32 indent)
String yaml_encode_node(DValue t, u32 indent)
{
const DTree& target = t.deref();
const DValue& target = t.deref();
String result;
if(target.type == 'M')
{
@@ -1732,7 +1732,7 @@ String yaml_encode_node(DTree t, u32 indent)
auto it = target._map.find(std::to_string(i));
if(it == target._map.end())
continue;
const DTree& child = it->second.deref();
const DValue& child = it->second.deref();
if(child.type == 'M')
{
result += yaml_indent(indent) + "-\n";
@@ -1748,7 +1748,7 @@ String yaml_encode_node(DTree t, u32 indent)
for(const auto& entry : target._map)
{
const DTree& child = entry.second.deref();
const DValue& child = entry.second.deref();
result += yaml_indent(indent) + yaml_quote_key(entry.first) + ":";
if(child.type == 'M')
{
@@ -1929,9 +1929,9 @@ struct YamlParser
return(false);
}
DTree parse_scalar(String value)
DValue parse_scalar(String value)
{
DTree result;
DValue result;
value = trim(value);
if(value == "")
{
@@ -2019,11 +2019,11 @@ struct YamlParser
return(literal);
}
DTree parse_value_after_line(String value, u32 parent_indent)
DValue parse_value_after_line(String value, u32 parent_indent)
{
if(value == "|" || value == ">")
{
DTree result;
DValue result;
result = parse_block_scalar(parent_indent, value);
return(result);
}
@@ -2032,14 +2032,14 @@ struct YamlParser
skip_empty();
if(i < lines.size() && lines[i].indent > parent_indent)
return(parse_block(lines[i].indent));
DTree result;
DValue result;
result = "";
return(result);
}
return(parse_scalar(value));
}
void merge_map(DTree& target, DTree source)
void merge_map(DValue& target, DValue source)
{
if(source.deref().type != 'M' || source.deref().is_list())
return;
@@ -2047,9 +2047,9 @@ struct YamlParser
target[entry.first] = entry.second;
}
DTree parse_list(u32 indent)
DValue parse_list(u32 indent)
{
DTree result;
DValue result;
result.set_array();
while(i < lines.size())
{
@@ -2063,7 +2063,7 @@ struct YamlParser
u32 line_indent = lines[i].indent;
i += 1;
DTree item;
DValue item;
if(after == "")
{
skip_empty();
@@ -2093,9 +2093,9 @@ struct YamlParser
return(result);
}
DTree parse_map(u32 indent)
DValue parse_map(u32 indent)
{
DTree result;
DValue result;
result.set_type('M');
while(i < lines.size())
{
@@ -2111,7 +2111,7 @@ struct YamlParser
{
if(result.deref()._map.size() == 0)
{
DTree scalar = parse_scalar(lines[i].content);
DValue scalar = parse_scalar(lines[i].content);
i += 1;
return(scalar);
}
@@ -2124,18 +2124,18 @@ struct YamlParser
return(result);
}
DTree parse_block(u32 indent)
DValue parse_block(u32 indent)
{
skip_empty();
if(i >= lines.size())
{
DTree empty;
DValue empty;
empty.set_type('M');
return(empty);
}
if(lines[i].indent < indent)
{
DTree empty;
DValue empty;
empty.set_type('M');
return(empty);
}
@@ -2144,12 +2144,12 @@ struct YamlParser
return(parse_map(lines[i].indent));
}
DTree parse_document()
DValue parse_document()
{
skip_empty();
if(i < lines.size() && lines[i].content == "---")
i += 1;
DTree result = parse_block(i < lines.size() ? lines[i].indent : 0);
DValue result = parse_block(i < lines.size() ? lines[i].indent : 0);
skip_empty();
if(i < lines.size() && lines[i].content == "...")
i += 1;
@@ -2162,12 +2162,12 @@ struct YamlParser
}
String yaml_encode(DTree t)
String yaml_encode(DValue t)
{
return(yaml_encode_node(t, 0));
}
DTree yaml_decode(String s)
DValue yaml_decode(String s)
{
YamlParser parser(s);
return(parser.parse_document());
@@ -2228,8 +2228,8 @@ String json_decode_String(String s, u32& i, char termination_char)
return(result);
}
DTree json_decode_map(String s, u32& i);
DTree json_decode_array(String s, u32& i);
DValue json_decode_map(String s, u32& i);
DValue json_decode_array(String s, u32& i);
void json_consume_space(String s, u32& i)
{
@@ -2277,9 +2277,9 @@ String json_decode_number(String s, u32& i)
return(result);
}
DTree json_decode_value(String s, u32& i)
DValue json_decode_value(String s, u32& i)
{
DTree result;
DValue result;
String value = "";
json_consume_space(s, i);
char c = s[i];
@@ -2322,9 +2322,9 @@ DTree json_decode_value(String s, u32& i)
return(result);
}
DTree json_decode_map(String s, u32& i)
DValue json_decode_map(String s, u32& i)
{
DTree result;
DValue result;
result.type = 'M';
String key = "";
json_consume_space(s, i);
@@ -2349,7 +2349,7 @@ DTree json_decode_map(String s, u32& i)
if(s[i] != ':')
return(result); // malformed
i += 1;
DTree v = json_decode_value(s, i);
DValue v = json_decode_value(s, i);
//result._map[key] = json_decode_value(s, i);
//print("KV " + key + " = " + to_String(v) + "\n");
//printf("map add %s (%c) \n", key.c_str(), s[i]);
@@ -2365,9 +2365,9 @@ DTree json_decode_map(String s, u32& i)
return(result);
}
DTree json_decode_array(String s, u32& i)
DValue json_decode_array(String s, u32& i)
{
DTree result;
DValue result;
result.set_array();
json_consume_space(s, i);
while(i < s.length())
@@ -2384,7 +2384,7 @@ DTree json_decode_array(String s, u32& i)
}
else
{
DTree v = json_decode_value(s, i);
DValue v = json_decode_value(s, i);
result.push(v);
}
json_consume_space(s, i);
@@ -2392,7 +2392,7 @@ DTree json_decode_array(String s, u32& i)
return(result);
}
DTree json_decode(String s)
DValue json_decode(String s)
{
u32 i = 0;
return(json_decode_value(s, i));
+16 -16
View File
@@ -15,8 +15,8 @@ bool str_ends_with(String haystack, String needle);
bool contains(String haystack, String needle);
String replace(String s, String search, String replace_with);
bool regex_match(String pattern, String subject, String flags = "");
DTree regex_search(String pattern, String subject, String flags = "");
DTree regex_search_all(String pattern, String subject, String flags = "");
DValue regex_search(String pattern, String subject, String flags = "");
DValue regex_search_all(String pattern, String subject, String flags = "");
String regex_replace(String pattern, String replacement, String subject, String flags = "");
StringList regex_split(String pattern, String subject, String flags = "");
@@ -92,13 +92,13 @@ StringList list_sort(StringList items);
bool list_some(StringList items, std::function<bool (String)> f);
bool list_every(StringList items, std::function<bool (String)> f);
String list_find(StringList items, std::function<bool (String)> f, String fallback = "");
StringList dtree_keys(DTree tree);
DTree dtree_values(DTree tree);
DTree dtree_pick(DTree tree, StringList keys);
DTree dtree_omit(DTree tree, StringList keys);
DTree dtree_map(DTree tree, std::function<DTree (const DTree&, String)> f);
DTree dtree_filter(DTree tree, std::function<bool (const DTree&, String)> f);
DTree dtree_group_by(DTree tree, std::function<String (const DTree&, String)> f);
StringList dv_keys(DValue tree);
DValue dv_values(DValue tree);
DValue dv_pick(DValue tree, StringList keys);
DValue dv_omit(DValue tree, StringList keys);
DValue dv_map(DValue tree, std::function<DValue (const DValue&, String)> f);
DValue dv_filter(DValue tree, std::function<bool (const DValue&, String)> f);
DValue dv_group_by(DValue tree, std::function<String (const DValue&, String)> f);
template <class ...Args>
String first(Args... args)
@@ -115,17 +115,17 @@ String html_escape(u64 a);
String html_escape(f64 a);
String json_encode(String s, char quote_char = '"');
String json_encode(DTree t, char quote_char = '"');
DTree json_decode(String s);
String xml_encode(DTree t, String root_name = "root");
DTree xml_decode(String s);
String yaml_encode(DTree t);
DTree yaml_decode(String s);
String json_encode(DValue t, char quote_char = '"');
DValue json_decode(String s);
String xml_encode(DValue t, String root_name = "root");
DValue xml_decode(String s);
String yaml_encode(DValue t);
DValue yaml_decode(String s);
String var_dump(StringMap map, String prefix = "", String postfix = "\n");
String var_dump(StringList slist, String prefix = "", String postfix = "\n");
StringMap array_merge(StringMap a, StringMap b);
DTree array_merge(DTree a, DTree b);
DValue array_merge(DValue a, DValue b);
void ob_start();
void ob_close();
+87 -87
View File
@@ -1,26 +1,26 @@
DTree markdown_to_ast(String src, DTree options);
String markdown_to_html(String src, DTree options);
DValue markdown_to_ast(String src, DValue options);
String markdown_to_html(String src, DValue options);
bool markdown_has_key(DTree& tree, String key)
bool markdown_has_key(DValue& tree, String key)
{
return(tree.type == 'M' && tree._map.count(key) > 0);
}
DTree markdown_get_value(DTree& tree, String key)
DValue markdown_get_value(DValue& tree, String key)
{
if(markdown_has_key(tree, key))
return(tree._map[key]);
return(DTree());
return(DValue());
}
String markdown_get_string(DTree& tree, String key, String default_value = "")
String markdown_get_string(DValue& tree, String key, String default_value = "")
{
if(markdown_has_key(tree, key))
return(tree._map[key].to_string());
return(default_value);
}
bool markdown_truthy(DTree value, bool default_value = false)
bool markdown_truthy(DValue value, bool default_value = false)
{
switch(value.type)
{
@@ -44,41 +44,41 @@ bool markdown_truthy(DTree value, bool default_value = false)
}
}
bool markdown_get_bool(DTree& tree, String key, bool default_value = false)
bool markdown_get_bool(DValue& tree, String key, bool default_value = false)
{
if(markdown_has_key(tree, key))
return(markdown_truthy(tree._map[key], default_value));
return(default_value);
}
bool markdown_gfm_enabled(DTree& options)
bool markdown_gfm_enabled(DValue& options)
{
return(markdown_get_bool(options, "gfm", true));
}
bool markdown_allow_html(DTree& options)
bool markdown_allow_html(DValue& options)
{
return(markdown_get_bool(options, "allow_html", false));
}
String markdown_get_component_target(DTree& options, String hook)
String markdown_get_component_target(DValue& options, String hook)
{
if(!markdown_has_key(options, "components"))
return("");
DTree components = options._map["components"];
DValue components = options._map["components"];
if(!markdown_has_key(components, hook))
return("");
return(trim(components._map[hook].to_string()));
}
DTree markdown_make_node(String type)
DValue markdown_make_node(String type)
{
DTree node;
DValue node;
node["type"] = type;
return(node);
}
void markdown_push(DTree& parent, DTree child)
void markdown_push(DValue& parent, DValue child)
{
parent.push(child);
}
@@ -167,9 +167,9 @@ String markdown_read_quoted(String raw, s64& i)
return(result);
}
DTree markdown_parse_attrs(String raw, String& argument_out)
DValue markdown_parse_attrs(String raw, String& argument_out)
{
DTree attrs;
DValue attrs;
argument_out = "";
s64 i = 0;
while(i < (s64)raw.length())
@@ -223,7 +223,7 @@ DTree markdown_parse_attrs(String raw, String& argument_out)
return(attrs);
}
StringList markdown_sorted_keys(DTree tree)
StringList markdown_sorted_keys(DValue tree)
{
StringList keys;
if(tree.type != 'M')
@@ -447,7 +447,7 @@ bool markdown_parse_setext_heading(String current, String next, s64& level, Stri
return(true);
}
bool markdown_parse_directive_open(String raw, String& name, String& argument, DTree& attrs)
bool markdown_parse_directive_open(String raw, String& name, String& argument, DValue& attrs)
{
String trimmed = trim(raw);
if(trimmed.rfind(":::", 0) != 0 || trimmed == ":::")
@@ -516,21 +516,21 @@ bool markdown_parse_link_target(String raw, String& url, String& title)
return(url != "");
}
DTree markdown_parse_inline(String raw, DTree options);
DValue markdown_parse_inline(String raw, DValue options);
void markdown_flush_text(String& buffer, DTree& children)
void markdown_flush_text(String& buffer, DValue& children)
{
if(buffer == "")
return;
DTree node = markdown_make_node("text");
DValue node = markdown_make_node("text");
node["text"] = buffer;
markdown_push(children, node);
buffer = "";
}
DTree markdown_parse_inline(String raw, DTree options)
DValue markdown_parse_inline(String raw, DValue options)
{
DTree children;
DValue children;
String buffer = "";
bool gfm = markdown_gfm_enabled(options);
bool allow_html = markdown_allow_html(options);
@@ -557,7 +557,7 @@ DTree markdown_parse_inline(String raw, DTree options)
if(close_pos != String::npos)
{
markdown_flush_text(buffer, children);
DTree node = markdown_make_node("code");
DValue node = markdown_make_node("code");
node["text"] = raw.substr(i + tick_count, close_pos - (i + tick_count));
markdown_push(children, node);
i = close_pos + tick_count - 1;
@@ -578,7 +578,7 @@ DTree markdown_parse_inline(String raw, DTree options)
if(markdown_parse_link_target(raw.substr(label_end + 2, target_end - (label_end + 2)), url, title))
{
markdown_flush_text(buffer, children);
DTree node = markdown_make_node("image");
DValue node = markdown_make_node("image");
node["alt"] = raw.substr(i + 2, label_end - (i + 2));
node["src"] = url;
node["title"] = title;
@@ -603,7 +603,7 @@ DTree markdown_parse_inline(String raw, DTree options)
if(markdown_parse_link_target(raw.substr(label_end + 2, target_end - (label_end + 2)), url, title))
{
markdown_flush_text(buffer, children);
DTree node = markdown_make_node("link");
DValue node = markdown_make_node("link");
node["href"] = url;
node["title"] = title;
node["children"] = markdown_parse_inline(raw.substr(i + 1, label_end - (i + 1)), options);
@@ -621,7 +621,7 @@ DTree markdown_parse_inline(String raw, DTree options)
if(close_pos != String::npos)
{
markdown_flush_text(buffer, children);
DTree node = markdown_make_node("strike");
DValue node = markdown_make_node("strike");
node["children"] = markdown_parse_inline(raw.substr(i + 2, close_pos - (i + 2)), options);
markdown_push(children, node);
i = close_pos + 1;
@@ -636,7 +636,7 @@ DTree markdown_parse_inline(String raw, DTree options)
if(close_pos != String::npos)
{
markdown_flush_text(buffer, children);
DTree node = markdown_make_node("strong");
DValue node = markdown_make_node("strong");
node["children"] = markdown_parse_inline(raw.substr(i + 2, close_pos - (i + 2)), options);
markdown_push(children, node);
i = close_pos + 1;
@@ -651,7 +651,7 @@ DTree markdown_parse_inline(String raw, DTree options)
if(close_pos != String::npos)
{
markdown_flush_text(buffer, children);
DTree node = markdown_make_node("em");
DValue node = markdown_make_node("em");
node["children"] = markdown_parse_inline(raw.substr(i + 1, close_pos - (i + 1)), options);
markdown_push(children, node);
i = close_pos;
@@ -667,11 +667,11 @@ DTree markdown_parse_inline(String raw, DTree options)
if(markdown_parse_autolink(raw, i, end, href, text))
{
markdown_flush_text(buffer, children);
DTree node = markdown_make_node("link");
DValue node = markdown_make_node("link");
node["href"] = href;
node["title"] = "";
DTree link_children;
DTree text_node = markdown_make_node("text");
DValue link_children;
DValue text_node = markdown_make_node("text");
text_node["text"] = text;
markdown_push(link_children, text_node);
node["children"] = link_children;
@@ -690,7 +690,7 @@ DTree markdown_parse_inline(String raw, DTree options)
if(html.length() >= 3)
{
markdown_flush_text(buffer, children);
DTree node = markdown_make_node("raw_html");
DValue node = markdown_make_node("raw_html");
node["html"] = html;
markdown_push(children, node);
i = close_pos;
@@ -706,9 +706,9 @@ DTree markdown_parse_inline(String raw, DTree options)
return(children);
}
DTree markdown_parse_blocks(StringList lines, DTree options);
DValue markdown_parse_blocks(StringList lines, DValue options);
DTree markdown_parse_paragraph(StringList& lines, s64& idx, s64 base_indent, DTree& options)
DValue markdown_parse_paragraph(StringList& lines, s64& idx, s64 base_indent, DValue& options)
{
StringList paragraph_lines;
while(idx < (s64)lines.size())
@@ -731,7 +731,7 @@ DTree markdown_parse_paragraph(StringList& lines, s64& idx, s64 base_indent, DTr
String list_content = "";
String directive_name = "";
String directive_argument = "";
DTree directive_attrs;
DValue directive_attrs;
if(markdown_parse_atx_heading(current, heading_level, heading_content) ||
markdown_parse_fence(current, fence_char, fence_length, fence_info) ||
markdown_is_hr(current) ||
@@ -751,14 +751,14 @@ DTree markdown_parse_paragraph(StringList& lines, s64& idx, s64 base_indent, DTr
idx += 1;
}
DTree node = markdown_make_node("paragraph");
DValue node = markdown_make_node("paragraph");
String text = join(paragraph_lines, "\n");
node["text"] = text;
node["children"] = markdown_parse_inline(text, options);
return(node);
}
DTree markdown_parse_list(StringList& lines, s64& idx, s64 base_indent, DTree& options)
DValue markdown_parse_list(StringList& lines, s64& idx, s64 base_indent, DValue& options)
{
bool ordered = false;
s64 marker_length = 0;
@@ -767,7 +767,7 @@ DTree markdown_parse_list(StringList& lines, s64& idx, s64 base_indent, DTree& o
String raw = lines[idx].substr(base_indent);
markdown_parse_list_marker(raw, ordered, marker_length, start_number, content);
DTree node = markdown_make_node("list");
DValue node = markdown_make_node("list");
node["ordered"].set_bool(ordered);
node["start"] = (f64)start_number;
@@ -786,7 +786,7 @@ DTree markdown_parse_list(StringList& lines, s64& idx, s64 base_indent, DTree& o
if(!markdown_parse_list_marker(line_raw, item_ordered, item_marker_length, item_start_number, item_content) || item_ordered != ordered)
break;
DTree item = markdown_make_node("list_item");
DValue item = markdown_make_node("list_item");
if(markdown_gfm_enabled(options))
{
bool checked = false;
@@ -830,7 +830,7 @@ DTree markdown_parse_list(StringList& lines, s64& idx, s64 base_indent, DTree& o
idx += 1;
}
DTree child_doc = markdown_parse_blocks(child_lines, options);
DValue child_doc = markdown_parse_blocks(child_lines, options);
item["children"] = markdown_get_value(child_doc, "children");
markdown_push(node["children"], item);
}
@@ -838,7 +838,7 @@ DTree markdown_parse_list(StringList& lines, s64& idx, s64 base_indent, DTree& o
return(node);
}
DTree markdown_parse_blockquote(StringList& lines, s64& idx, s64 base_indent, DTree& options)
DValue markdown_parse_blockquote(StringList& lines, s64& idx, s64 base_indent, DValue& options)
{
StringList quote_lines;
while(idx < (s64)lines.size())
@@ -863,13 +863,13 @@ DTree markdown_parse_blockquote(StringList& lines, s64& idx, s64 base_indent, DT
idx += 1;
}
DTree node = markdown_make_node("blockquote");
DTree child_doc = markdown_parse_blocks(quote_lines, options);
DValue node = markdown_make_node("blockquote");
DValue child_doc = markdown_parse_blocks(quote_lines, options);
node["children"] = markdown_get_value(child_doc, "children");
return(node);
}
DTree markdown_parse_code_block(StringList& lines, s64& idx, s64 base_indent)
DValue markdown_parse_code_block(StringList& lines, s64& idx, s64 base_indent)
{
char fence_char = '\0';
s64 fence_length = 0;
@@ -900,16 +900,16 @@ DTree markdown_parse_code_block(StringList& lines, s64& idx, s64 base_indent)
idx += 1;
}
DTree node = markdown_make_node("code_block");
DValue node = markdown_make_node("code_block");
node["text"] = join(body, "\n");
node["lang"] = lang;
node["meta"] = meta;
return(node);
}
DTree markdown_parse_table(StringList& lines, s64& idx, s64 base_indent, DTree& options)
DValue markdown_parse_table(StringList& lines, s64& idx, s64 base_indent, DValue& options)
{
DTree node = markdown_make_node("table");
DValue node = markdown_make_node("table");
String header_line = lines[idx].substr(base_indent);
String separator_line = lines[idx + 1].substr(base_indent);
StringList alignments;
@@ -918,7 +918,7 @@ DTree markdown_parse_table(StringList& lines, s64& idx, s64 base_indent, DTree&
StringList header_cells = markdown_split_pipe_row(header_line);
for(auto cell_text : header_cells)
{
DTree cell = markdown_make_node("table_cell");
DValue cell = markdown_make_node("table_cell");
cell["text"] = cell_text;
cell["children"] = markdown_parse_inline(cell_text, options);
markdown_push(node["header"], cell);
@@ -926,7 +926,7 @@ DTree markdown_parse_table(StringList& lines, s64& idx, s64 base_indent, DTree&
for(auto align : alignments)
{
DTree cell_align;
DValue cell_align;
cell_align = align;
markdown_push(node["align"], cell_align);
}
@@ -944,10 +944,10 @@ DTree markdown_parse_table(StringList& lines, s64& idx, s64 base_indent, DTree&
StringList cells = markdown_split_pipe_row(raw);
if(cells.size() == 0)
break;
DTree row;
DValue row;
for(auto cell_text : cells)
{
DTree cell = markdown_make_node("table_cell");
DValue cell = markdown_make_node("table_cell");
cell["text"] = cell_text;
cell["children"] = markdown_parse_inline(cell_text, options);
markdown_push(row, cell);
@@ -959,11 +959,11 @@ DTree markdown_parse_table(StringList& lines, s64& idx, s64 base_indent, DTree&
return(node);
}
DTree markdown_parse_directive(StringList& lines, s64& idx, s64 base_indent, DTree& options)
DValue markdown_parse_directive(StringList& lines, s64& idx, s64 base_indent, DValue& options)
{
String name = "";
String argument = "";
DTree attrs;
DValue attrs;
markdown_parse_directive_open(lines[idx].substr(base_indent), name, argument, attrs);
StringList body_lines;
@@ -992,7 +992,7 @@ DTree markdown_parse_directive(StringList& lines, s64& idx, s64 base_indent, DTr
}
String nested_name = "";
String nested_argument = "";
DTree nested_attrs;
DValue nested_attrs;
if(markdown_parse_directive_open(raw, nested_name, nested_argument, nested_attrs))
depth += 1;
}
@@ -1000,17 +1000,17 @@ DTree markdown_parse_directive(StringList& lines, s64& idx, s64 base_indent, DTr
idx += 1;
}
DTree node = markdown_make_node("directive");
DValue node = markdown_make_node("directive");
node["name"] = name;
node["argument"] = argument;
node["attrs"] = attrs;
node["body_source"] = join(body_lines, "\n");
DTree child_doc = markdown_parse_blocks(body_lines, options);
DValue child_doc = markdown_parse_blocks(body_lines, options);
node["children"] = markdown_get_value(child_doc, "children");
return(node);
}
DTree markdown_parse_raw_html_block(StringList& lines, s64& idx, s64 base_indent)
DValue markdown_parse_raw_html_block(StringList& lines, s64& idx, s64 base_indent)
{
StringList html_lines;
while(idx < (s64)lines.size())
@@ -1025,14 +1025,14 @@ DTree markdown_parse_raw_html_block(StringList& lines, s64& idx, s64 base_indent
html_lines.push_back(raw);
idx += 1;
}
DTree node = markdown_make_node("raw_html");
DValue node = markdown_make_node("raw_html");
node["html"] = join(html_lines, "\n");
return(node);
}
DTree markdown_parse_blocks(StringList lines, DTree options)
DValue markdown_parse_blocks(StringList lines, DValue options)
{
DTree document = markdown_make_node("document");
DValue document = markdown_make_node("document");
document["source"] = join(lines, "\n");
s64 idx = 0;
@@ -1052,7 +1052,7 @@ DTree markdown_parse_blocks(StringList lines, DTree options)
String heading_content = "";
if(markdown_parse_atx_heading(raw, atx_level, heading_content))
{
DTree node = markdown_make_node("heading");
DValue node = markdown_make_node("heading");
node["level"] = (f64)atx_level;
node["text"] = heading_content;
node["children"] = markdown_parse_inline(heading_content, options);
@@ -1067,7 +1067,7 @@ DTree markdown_parse_blocks(StringList lines, DTree options)
String setext_content = "";
if(markdown_parse_setext_heading(raw, lines[idx + 1].substr(base_indent), setext_level, setext_content))
{
DTree node = markdown_make_node("heading");
DValue node = markdown_make_node("heading");
node["level"] = (f64)setext_level;
node["text"] = setext_content;
node["children"] = markdown_parse_inline(setext_content, options);
@@ -1082,14 +1082,14 @@ DTree markdown_parse_blocks(StringList lines, DTree options)
String fence_info = "";
if(markdown_parse_fence(raw, fence_char, fence_length, fence_info))
{
DTree node = markdown_parse_code_block(lines, idx, base_indent);
DValue node = markdown_parse_code_block(lines, idx, base_indent);
markdown_push(document["children"], node);
continue;
}
if(markdown_is_hr(raw))
{
DTree node = markdown_make_node("hr");
DValue node = markdown_make_node("hr");
markdown_push(document["children"], node);
idx += 1;
continue;
@@ -1097,17 +1097,17 @@ DTree markdown_parse_blocks(StringList lines, DTree options)
String directive_name = "";
String directive_argument = "";
DTree directive_attrs;
DValue directive_attrs;
if(markdown_parse_directive_open(raw, directive_name, directive_argument, directive_attrs))
{
DTree node = markdown_parse_directive(lines, idx, base_indent, options);
DValue node = markdown_parse_directive(lines, idx, base_indent, options);
markdown_push(document["children"], node);
continue;
}
if(trimmed.rfind(">", 0) == 0)
{
DTree node = markdown_parse_blockquote(lines, idx, base_indent, options);
DValue node = markdown_parse_blockquote(lines, idx, base_indent, options);
markdown_push(document["children"], node);
continue;
}
@@ -1118,7 +1118,7 @@ DTree markdown_parse_blocks(StringList lines, DTree options)
String list_content = "";
if(markdown_parse_list_marker(raw, ordered, marker_length, start_number, list_content))
{
DTree node = markdown_parse_list(lines, idx, base_indent, options);
DValue node = markdown_parse_list(lines, idx, base_indent, options);
markdown_push(document["children"], node);
continue;
}
@@ -1129,7 +1129,7 @@ DTree markdown_parse_blocks(StringList lines, DTree options)
StringList alignments;
if(markdown_parse_table_separator(lines[idx + 1].substr(base_indent), alignments))
{
DTree node = markdown_parse_table(lines, idx, base_indent, options);
DValue node = markdown_parse_table(lines, idx, base_indent, options);
markdown_push(document["children"], node);
continue;
}
@@ -1137,27 +1137,27 @@ DTree markdown_parse_blocks(StringList lines, DTree options)
if(markdown_allow_html(options) && trimmed.rfind("<", 0) == 0)
{
DTree node = markdown_parse_raw_html_block(lines, idx, base_indent);
DValue node = markdown_parse_raw_html_block(lines, idx, base_indent);
markdown_push(document["children"], node);
continue;
}
DTree node = markdown_parse_paragraph(lines, idx, base_indent, options);
DValue node = markdown_parse_paragraph(lines, idx, base_indent, options);
markdown_push(document["children"], node);
}
return(document);
}
String markdown_render_children(DTree children, DTree& options);
String markdown_render_node(DTree node, DTree& options);
String markdown_render_children(DValue children, DValue& options);
String markdown_render_node(DValue node, DValue& options);
String markdown_render_cell_children(DTree cell, DTree& options)
String markdown_render_cell_children(DValue cell, DValue& options)
{
return(markdown_render_children(markdown_get_value(cell, "children"), options));
}
String markdown_render_with_component_hook(DTree node, DTree& options, String hook, String children_html, String default_html)
String markdown_render_with_component_hook(DValue node, DValue& options, String hook, String children_html, String default_html)
{
String type = markdown_get_string(node, "type");
String target = "";
@@ -1174,7 +1174,7 @@ String markdown_render_with_component_hook(DTree node, DTree& options, String ho
if(target != "" && exact_hook != "")
hook = exact_hook;
DTree props;
DValue props;
props["hook"] = hook;
props["target"] = target;
props["default_html"] = default_html;
@@ -1192,7 +1192,7 @@ String markdown_render_with_component_hook(DTree node, DTree& options, String ho
return(component(target, props, *context));
}
String markdown_render_children(DTree children, DTree& options)
String markdown_render_children(DValue children, DValue& options)
{
String result = "";
for(auto key : markdown_sorted_keys(children))
@@ -1200,7 +1200,7 @@ String markdown_render_children(DTree children, DTree& options)
return(result);
}
String markdown_render_node(DTree node, DTree& options)
String markdown_render_node(DValue node, DValue& options)
{
String type = markdown_get_string(node, "type");
String hook = "node." + type;
@@ -1322,7 +1322,7 @@ String markdown_render_node(DTree node, DTree& options)
String body_html = "";
for(auto row_key : markdown_sorted_keys(markdown_get_value(node, "rows")))
{
DTree row = node["rows"]._map[row_key];
DValue row = node["rows"]._map[row_key];
String row_html = "";
StringList row_keys = markdown_sorted_keys(row);
for(s64 i = 0; i < (s64)row_keys.size(); i++)
@@ -1353,13 +1353,13 @@ String markdown_render_node(DTree node, DTree& options)
return(markdown_render_with_component_hook(node, options, hook, children_html, html));
}
DTree markdown_to_ast(String src)
DValue markdown_to_ast(String src)
{
DTree options;
DValue options;
return(markdown_to_ast(src, options));
}
DTree markdown_to_ast(String src, DTree options)
DValue markdown_to_ast(String src, DValue options)
{
src = markdown_strip_newlines(src);
return(markdown_parse_blocks(split(src, "\n"), options));
@@ -1367,12 +1367,12 @@ DTree markdown_to_ast(String src, DTree options)
String markdown_to_html(String src)
{
DTree options;
DValue options;
return(markdown_to_html(src, options));
}
String markdown_to_html(String src, DTree options)
String markdown_to_html(String src, DValue options)
{
DTree ast = markdown_to_ast(src, options);
DValue ast = markdown_to_ast(src, options);
return(markdown_render_node(ast, options));
}
+3 -3
View File
@@ -1,6 +1,6 @@
#pragma once
DTree markdown_to_ast(String src);
DTree markdown_to_ast(String src, DTree options);
DValue markdown_to_ast(String src);
DValue markdown_to_ast(String src, DValue options);
String markdown_to_html(String src);
String markdown_to_html(String src, DTree options);
String markdown_to_html(String src, DValue options);
+11 -11
View File
@@ -96,9 +96,9 @@ String mysql_escape(String raw, char quote_char)
return(result);
}
DTree field_to_dtree_node(char* data_ptr, MySQLFieldInfo field_info, u32 len)
DValue field_to_dv_node(char* data_ptr, MySQLFieldInfo field_info, u32 len)
{
DTree result;
DValue result;
switch(field_info.type)
{
case(MYSQL_TYPE_TINY):
@@ -133,9 +133,9 @@ DTree field_to_dtree_node(char* data_ptr, MySQLFieldInfo field_info, u32 len)
return(result);
}
DTree MySQL::get_pending_result()
DValue MySQL::get_pending_result()
{
DTree result_data;
DValue result_data;
// based on: https://dev.mysql.com/doc/c-api/5.7/en/mysql-field-count.html
MYSQL_RES *result;
result = mysql_store_result((MYSQL*)connection);
@@ -167,11 +167,11 @@ DTree MySQL::get_pending_result()
MYSQL_ROW row;
while ((row = mysql_fetch_row(result)))
{
DTree row_data;
DValue row_data;
auto lengths = mysql_fetch_lengths(result);
for(i = 0; i < field_count; i++)
{
row_data[field_info[i].name] = field_to_dtree_node(row[i], field_info[i], lengths[i]);
row_data[field_info[i].name] = field_to_dv_node(row[i], field_info[i], lengths[i]);
}
result_data.push(row_data);
}
@@ -196,22 +196,22 @@ DTree MySQL::get_pending_result()
static bool mysql_has_unquoted_positional_placeholder(String query);
DTree MySQL::query(String q)
DValue MySQL::query(String q)
{
if(mysql_has_unquoted_positional_placeholder(q))
{
_preload_next_error_code = CR_UNKNOWN_ERROR;
statement_info = "mysql positional ? placeholders are not supported; use named :name placeholders";
return(DTree());
return(DValue());
}
if(!connection)
{
_preload_next_error_code = CR_UNKNOWN_ERROR;
statement_info = "mysql connection is not open";
return(DTree());
return(DValue());
}
_preload_next_error_code = mysql_query((MYSQL*)connection, q.c_str());
DTree result;
DValue result;
if(_preload_next_error_code == 0)
result = get_pending_result();
return(result);
@@ -253,7 +253,7 @@ static bool mysql_has_unquoted_positional_placeholder(String query)
return(false);
}
DTree MySQL::query(String q, StringMap params)
DValue MySQL::query(String q, StringMap params)
{
// Positional ? placeholders survive named substitution (values are always
// quoted by escape()), so the check in query(String) covers this path too.
+5 -5
View File
@@ -29,9 +29,9 @@ struct MySQL {
String error();
String escape(String raw, char quote_char = '\'');
String parse_query_parameters(String query, StringMap m);
DTree query(String q);
DTree query(String q, StringMap params);
DTree get_pending_result();
DValue query(String q);
DValue query(String q, StringMap params);
DValue get_pending_result();
// Unregisters from the request's connection tracking, so stack-allocated
// instances cannot leave dangling pointers behind for request cleanup.
@@ -62,12 +62,12 @@ String mysql_error(MySQL* m)
String mysql_escape(String raw, char quote_char);
DTree mysql_query(MySQL* m, String q)
DValue mysql_query(MySQL* m, String q)
{
return(m->query(q));
}
DTree mysql_query(MySQL* m, String q, StringMap params)
DValue mysql_query(MySQL* m, String q, StringMap params)
{
return(m->query(q, params));
}
+11 -11
View File
@@ -147,10 +147,10 @@ bool SQLite::bind_params(void* statement, const StringMap& params)
return(true);
}
DTree SQLite::collect_rows(void* statement)
DValue SQLite::collect_rows(void* statement)
{
sqlite3_stmt* stmt = (sqlite3_stmt*)statement;
DTree result;
DValue result;
s32 column_count = sqlite3_column_count(stmt);
std::vector<String> column_names;
column_names.reserve(column_count);
@@ -161,7 +161,7 @@ DTree SQLite::collect_rows(void* statement)
s32 rc = sqlite3_step(stmt);
if(rc == SQLITE_ROW)
{
DTree row;
DValue row;
for(s32 i = 0; i < column_count; i++)
{
const String& name = column_names[i];
@@ -201,19 +201,19 @@ DTree SQLite::collect_rows(void* statement)
return(result);
}
set_error(rc, "sqlite step failed");
return(DTree());
return(DValue());
}
}
DTree SQLite::query(String q)
DValue SQLite::query(String q)
{
StringMap params;
return(query(q, params));
}
DTree SQLite::query(String q, const StringMap& params)
DValue SQLite::query(String q, const StringMap& params)
{
DTree result;
DValue result;
affected_rows = 0;
insert_id = 0;
error_code = SQLITE_OK;
@@ -309,17 +309,17 @@ String sqlite_error(SQLite* db)
return(db->error());
}
DTree sqlite_query(SQLite* db, String q)
DValue sqlite_query(SQLite* db, String q)
{
if(!db)
return(DTree());
return(DValue());
return(db->query(q));
}
DTree sqlite_query(SQLite* db, String q, const StringMap& params)
DValue sqlite_query(SQLite* db, String q, const StringMap& params)
{
if(!db)
return(DTree());
return(DValue());
return(db->query(q, params));
}
+5 -5
View File
@@ -14,8 +14,8 @@ struct SQLite {
bool connect(String path);
void disconnect();
String error();
DTree query(String q);
DTree query(String q, const StringMap& params);
DValue query(String q);
DValue query(String q, const StringMap& params);
// Unregisters from the request's connection tracking, so stack-allocated
// instances cannot leave dangling pointers behind for request cleanup.
@@ -25,14 +25,14 @@ private:
void set_error(s32 code, String info = "");
bool apply_default_pragmas();
bool bind_params(void* statement, const StringMap& params);
DTree collect_rows(void* statement);
DValue collect_rows(void* statement);
};
SQLite* sqlite_connect(String path);
void sqlite_disconnect(SQLite* db);
String sqlite_error(SQLite* db);
DTree sqlite_query(SQLite* db, String q);
DTree sqlite_query(SQLite* db, String q, const StringMap& params);
DValue sqlite_query(SQLite* db, String q);
DValue sqlite_query(SQLite* db, String q, const StringMap& params);
u64 sqlite_insert_id(SQLite* db);
u32 sqlite_affected_rows(SQLite* db);
void cleanup_sqlite_connections();
+9 -9
View File
@@ -53,10 +53,10 @@ typedef std::vector<String> StringList;
typedef std::ostringstream ByteStream;
struct Request;
struct DTree;
struct DValue;
typedef void (*request_ref_handler)(Request& request);
typedef DTree* (*dtree_call_handler)(DTree* call_param);
typedef DValue* (*dv_call_handler)(DValue* call_param);
typedef void (*request_handler)(Request* request);
String to_string(s64 v) { return(std::to_string(v)); }
@@ -146,7 +146,7 @@ struct URI {
String nibble(String div, String& haystack);
#include "dtree.h"
#include "dvalue.h"
void compiler_invoke(Request* context, String file_name);
@@ -162,10 +162,10 @@ struct Request {
String session_loaded_hash = "";
std::set<String> once_units;
DTree call;
DTree cfg;
DTree props;
DTree connection;
DValue call;
DValue cfg;
DValue props;
DValue connection;
String session_id = "";
String session_name = "";
@@ -215,9 +215,9 @@ struct Request {
bool is_cli = false;
String websocket_connection_id = "";
String websocket_scope = "";
DTree* websocket_connection_state = 0;
DValue* websocket_connection_state = 0;
StringList websocket_scope_connection_ids;
DTree websocket_dispatch_commands;
DValue websocket_dispatch_commands;
bool websocket_dispatch_capture = false;
u8 websocket_opcode = 0;
bool websocket_is_binary = false;
+1 -1
View File
@@ -5,7 +5,7 @@
// unless the build/compiler model is deliberately changed.
#include "types.cpp"
#include "dtree.cpp"
#include "dvalue.cpp"
#include "functionlib.cpp"
#include "hash.cpp"
#include "sys.cpp"
+4 -4
View File
@@ -341,16 +341,16 @@ String request_query_path(Request& context, String default_path)
return(request_query_route(context, default_path)["l_path"].to_string());
}
DTree request_query_route(Request& context, String default_path)
DValue request_query_route(Request& context, String default_path)
{
String raw_path = "";
parse_query(context.params["QUERY_STRING"], &raw_path);
return(request_route_from_raw_path(raw_path, default_path));
}
DTree request_route_from_raw_path(String raw_path, String default_path)
DValue request_route_from_raw_path(String raw_path, String default_path)
{
DTree route;
DValue route;
String normalized_path = route_path_normalize(raw_path);
String route_path = route_path_sanitize_normalized(normalized_path, default_path);
bool valid = route_path != "";
@@ -373,7 +373,7 @@ void request_populate_context_params(Request& context, String default_path)
void request_populate_context_params_from_route(Request& context, String raw_path, String default_path)
{
DTree route = request_route_from_raw_path(raw_path, default_path);
DValue route = request_route_from_raw_path(raw_path, default_path);
String script_url = request_script_url(context);
context.params["SCRIPT_URL"] = script_url;
context.params["BASE_URL"] = request_base_url_from_script_url(script_url);
+2 -2
View File
@@ -16,8 +16,8 @@ String route_path_sanitize(String path, String default_path = "index");
String request_script_url(Request& context);
String request_base_url(Request& context);
String request_query_path(Request& context, String default_path = "index");
DTree request_query_route(Request& context, String default_path = "index");
DTree request_route_from_raw_path(String raw_path, String default_path = "index");
DValue request_query_route(Request& context, String default_path = "index");
DValue request_route_from_raw_path(String raw_path, String default_path = "index");
void request_populate_context_params(Request& context, String default_path = "index");
void request_populate_context_params_from_route(Request& context, String raw_path, String default_path = "index");
void redirect(String url, s32 code = 302);
+11 -11
View File
@@ -63,14 +63,14 @@ bool zip_ensure_parent_directory(String path)
return(mkdir(parent));
}
void zip_add_file_info(DTree& files, mz_zip_archive* archive, mz_uint index)
void zip_add_file_info(DValue& files, mz_zip_archive* archive, mz_uint index)
{
mz_zip_archive_file_stat stat;
std::memset(&stat, 0, sizeof(stat));
if(!mz_zip_reader_file_stat(archive, index, &stat))
throw std::runtime_error(zip_error("zip_list", "could not read file metadata at index " + std::to_string((u64)index)));
DTree item;
DValue item;
item["name"] = String(stat.m_filename);
item["index"] = (f64)index;
item["size"] = (f64)stat.m_uncomp_size;
@@ -80,14 +80,14 @@ void zip_add_file_info(DTree& files, mz_zip_archive* archive, mz_uint index)
files.push(item);
}
DTree zip_list(String zip_file_name)
DValue zip_list(String zip_file_name)
{
mz_zip_archive archive;
std::memset(&archive, 0, sizeof(archive));
if(!mz_zip_reader_init_file(&archive, zip_file_name.c_str(), 0))
throw std::runtime_error(zip_error("zip_list", "could not open " + zip_file_name));
DTree result;
DValue result;
try
{
mz_uint count = mz_zip_reader_get_num_files(&archive);
@@ -146,20 +146,20 @@ String zip_read(String zip_file_name, String entry_name)
return(result);
}
String zip_entry_content(DTree item)
String zip_entry_content(DValue item)
{
DTree* content = item.key("content");
DValue* content = item.key("content");
if(content)
return(content->to_string());
DTree* file_name = item.key("file");
DValue* file_name = item.key("file");
if(file_name)
return(file_get_contents(file_name->to_string()));
return(item.to_string());
}
String zip_entry_name(String key, DTree item)
String zip_entry_name(String key, DValue item)
{
DTree* name = item.key("name");
DValue* name = item.key("name");
if(name)
return(name->to_string());
return(key);
@@ -175,7 +175,7 @@ void zip_add_entry(mz_zip_archive* archive, String name, String content)
throw std::runtime_error(zip_error("zip_create", "could not add entry " + name));
}
bool zip_create(String zip_file_name, DTree entries)
bool zip_create(String zip_file_name, DValue entries)
{
if(!zip_ensure_parent_directory(zip_file_name))
throw std::runtime_error(zip_error("zip_create", "could not create parent directory for " + zip_file_name));
@@ -188,7 +188,7 @@ bool zip_create(String zip_file_name, DTree entries)
try
{
u64 entry_count = 0;
entries.each([&](DTree item, String key)
entries.each([&](DValue item, String key)
{
entry_count++;
archive_check_size("zip_create", "entry count", entry_count, "ARCHIVE_MAX_ZIP_ENTRIES", 4096);
+2 -2
View File
@@ -1,8 +1,8 @@
#pragma once
DTree zip_list(String zip_file_name);
DValue zip_list(String zip_file_name);
String zip_read(String zip_file_name, String entry_name);
bool zip_create(String zip_file_name, DTree entries);
bool zip_create(String zip_file_name, DValue entries);
bool zip_extract(String zip_file_name, String destination_directory);
String gz_compress(String src);
String gz_uncompress(String compressed);