Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ if(NOT CMAKE_C_COMPILER AND NOT CMAKE_CXX_COMPILER)
endif()

project(zelph VERSION 0.9.6 LANGUAGES C CXX)
set(ZELPH_VERSION_SUFFIX "-dev")
set(ZELPH_VERSION_SUFFIX "-dev" CACHE STRING "Version suffix appended to the reported project version")

include(GNUInstallDirs)

Expand Down
76 changes: 72 additions & 4 deletions src/lib/command_executor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ along with zelph. If not, see <https://www.gnu.org/licenses/>.
#include <filesystem>
#include <fstream>
#include <iomanip>
#include <limits>
#include <map>
#include <sstream>

Expand Down Expand Up @@ -416,6 +417,55 @@ class console::CommandExecutor::Impl
throw std::runtime_error("Command .index-file: Failed to open output file '" + output_filename + "'");
}

auto escape_json_string = [](const std::string& value)
{
std::ostringstream escaped;
for (unsigned char ch : value)
{
switch (ch)
{
case '\"':
escaped << "\\\"";
break;
case '\\':
escaped << "\\\\";
break;
case '\b':
escaped << "\\b";
break;
case '\f':
escaped << "\\f";
break;
case '\n':
escaped << "\\n";
break;
case '\r':
escaped << "\\r";
break;
case '\t':
escaped << "\\t";
break;
default:
if (ch < 0x20)
{
escaped << "\\u"
<< std::hex
<< std::setw(4)
<< std::setfill('0')
<< static_cast<int>(ch)
<< std::dec
<< std::setfill(' ');
}
else
{
escaped << static_cast<char>(ch);
}
break;
}
}
return escaped.str();
};

auto write_chunk_array = [&](const char* key, const std::vector<BinChunkRef>& refs)
{
out << " \"" << key << "\": [\n";
Expand All @@ -427,11 +477,11 @@ class console::CommandExecutor::Impl
<< ",\"length\":" << ref.length;
if (!ref.which.empty())
{
out << ",\"which\":\"" << ref.which << "\"";
out << ",\"which\":\"" << escape_json_string(ref.which) << "\"";
}
if (!ref.lang.empty())
{
out << ",\"lang\":\"" << ref.lang << "\"";
out << ",\"lang\":\"" << escape_json_string(ref.lang) << "\"";
}
out << "}";
if (i + 1 < refs.size())
Expand All @@ -444,7 +494,7 @@ class console::CommandExecutor::Impl
};

out << "{\n";
out << " \"file\":\"" << data.filename << "\",\n";
out << " \"file\":\"" << escape_json_string(data.filename) << "\",\n";
out << " \"header\":{\"offset\":0,\"length\":" << data.header_length_bytes << "},\n";
write_chunk_array("left", data.left_chunks);
out << ",\n";
Expand Down Expand Up @@ -490,11 +540,20 @@ class console::CommandExecutor::Impl
try
{
size_t pos = 0;
uint32_t index = static_cast<uint32_t>(std::stoul(token, &pos, 10));
if (token[0] == '-')
{
throw std::runtime_error("");
}
uint64_t parsed = std::stoull(token, &pos, 10);
if (pos != token.size())
{
throw std::runtime_error("");
}
if (parsed > std::numeric_limits<uint32_t>::max())
{
throw std::runtime_error("");
}
uint32_t index = static_cast<uint32_t>(parsed);
indices.push_back(index);
}
catch (...)
Expand Down Expand Up @@ -540,6 +599,10 @@ class console::CommandExecutor::Impl
try
{
size_t pos = 0;
if (token[0] == '-')
{
throw std::runtime_error("");
}
uint64_t id = std::stoull(token, &pos, 10);
if (pos != token.size())
{
Expand Down Expand Up @@ -1846,6 +1909,11 @@ class console::CommandExecutor::Impl
}
}

if (use_manifest && source_bin_override.empty() && first_arg.ends_with(".bin"))
{
source_bin_override = first_arg;
}

if ((selection.route_nodes_explicit || selection.route_name_explicit) && !use_manifest)
{
throw std::runtime_error("Command .load-partial: route selectors require manifest mode");
Expand Down
4 changes: 2 additions & 2 deletions src/lib/command_executor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ namespace zelph::console
*
* @param reasoning Pointer to the reasoning network (must remain valid).
* @param script_engine Pointer to the script engine (must remain valid).
* @param data_manager Reference to the shared_ptr holding the data manager (allows replacement).
* @param repl_state Shared REPL state used for mode flags and buffers.
* @param line_processor Callback to process a raw line (used for .import recursion).
*/
CommandExecutor(zelph::network::Reasoning* reasoning,
zelph::ScriptEngine* script_engine,
zelph::ScriptEngine* script_engine,
std::shared_ptr<ReplState> repl_state,
LineProcessor line_processor);

Expand Down
29 changes: 19 additions & 10 deletions src/lib/interactive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,25 @@ class console::Interactive::Impl
{ _interactive->process(line); });
}

void reset_reasoning()
{
_command_executor.reset(); // destroy first (depends on both)
_script_engine.reset(); // destroy second (depends on _n)
auto output = _n->get_output_handler(); // save what's needed
_n.reset(); // destroy last

init(output);
_n->out("Cleared network and re-initialized core nodes.");
}
void reset_reasoning()
{
_command_executor.reset(); // destroy first (depends on both)
_script_engine.reset(); // destroy second (depends on _n)
auto output = _n->get_output_handler(); // save what's needed
_n.reset(); // destroy last

_repl_state->partial_load_mode = false;
_repl_state->partial_load_source.clear();
_repl_state->janet_buffer.clear();
_repl_state->zelph_buffer.clear();
_repl_state->accumulating_inline_janet = false;
_repl_state->accumulating_zelph = false;
_repl_state->script_mode = ScriptMode::Zelph;
_repl_state->reset_requested = false;

init(output);
_n->out("Cleared network and re-initialized core nodes.");
}

// Member function to delegate to CommandExecutor
void process_command(const std::vector<std::string>& cmd);
Expand Down
2 changes: 1 addition & 1 deletion src/test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

include(FetchContent)

# doctest v2.4.11 declares cmake_minimum_required(VERSION 3.1),
# doctest v2.4.12 declares cmake_minimum_required(VERSION 3.1),
# which newer CMake rejects. Allow it to configure anyway.
set(CMAKE_POLICY_VERSION_MINIMUM 3.5 CACHE STRING "")

Expand Down
Loading