Klammerset: the @@@klammerset construct, its search path, and const correctness
The @@@klammerset system command formally declares a klammerset — a named, logically related group of klammer definitions — with an operative, idempotent declaration (:requires and :files load in order at the declaration point, relative to the declaring file). A bare symbol given to ktext -k, kdesc --input, or :requires resolves to x/x.k on the search path: the document's directory, then KLAMMERTEXT_KLAMMERSETS, then KLAMMERTEXT_HOME; kdesc --klammerset lists the available sets. sks/sks.k is the first declared klammerset, so `-k sks` loads the SKS by name. The engine's lookup classes were renamed *_set → *_registry to keep the two concepts apart, and the whole C++ tree now follows standard const-correctness conventions. tst/ gains klammerset_test.sh (18 cases). (from dev 64b1abf23e56)
This commit is contained in:
@@ -8,9 +8,9 @@ include $(K)/env/makefile.env
|
||||
|
||||
# Source files
|
||||
BASENAMES := util error locator file argv character ktype katom katom_list \
|
||||
log show command argument argument_set argtype argtype_set \
|
||||
state eval eval_python eval_cpp klammer klammer_set deftype \
|
||||
target target_set machine font_store
|
||||
log show command argument argument_set argtype argtype_registry \
|
||||
state eval eval_python eval_cpp klammer klammer_registry klammerset klammerset_registry deftype \
|
||||
target target_registry machine font_store
|
||||
|
||||
SOURCES := $(addsuffix .cpp,$(BASENAMES))
|
||||
OBJECTS := $(addsuffix .o,$(BASENAMES))
|
||||
|
||||
@@ -6,9 +6,10 @@
|
||||
#include "error.h"
|
||||
#include "util.h"
|
||||
|
||||
Argtype::Argtype(std::string name, std::string desc, std::string symbolic_pattern, std::string pattern,
|
||||
std::string default_value, std::string alone_value,
|
||||
std::string python_cast, modify_string_f python_format,
|
||||
Argtype::Argtype(const std::string& name, const std::string& desc, const std::string& symbolic_pattern,
|
||||
const std::string& pattern,
|
||||
const std::string& default_value, const std::string& alone_value,
|
||||
const std::string& python_cast, const modify_string_f& python_format,
|
||||
const Locator& loc)
|
||||
: m_name(name)
|
||||
, m_desc(desc)
|
||||
|
||||
@@ -25,9 +25,10 @@ public:
|
||||
, m_loc()
|
||||
{};
|
||||
|
||||
Argtype(std::string name, std::string desc, std::string symbolic_pattern, std::string pattern,
|
||||
std::string default_value, std::string alone_value,
|
||||
std::string python_cast, modify_string_f python_format,
|
||||
Argtype(const std::string& name, const std::string& desc, const std::string& symbolic_pattern,
|
||||
const std::string& pattern,
|
||||
const std::string& default_value, const std::string& alone_value,
|
||||
const std::string& python_cast, const modify_string_f& python_format,
|
||||
const Locator& loc);
|
||||
|
||||
std::string python_value(const std::string& var_name, std::vector<std::string> value, size_t name_size);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
|
||||
#include "argtype_set.h"
|
||||
#include "argtype_registry.h"
|
||||
#include "error.h"
|
||||
#include "show.h"
|
||||
#include "log.h"
|
||||
@@ -11,13 +11,13 @@
|
||||
#include "character.h"
|
||||
#include "katom.h"
|
||||
|
||||
Parameter_set& Argtype_set::parameters()
|
||||
Parameter_set& Argtype_registry::parameters()
|
||||
{
|
||||
static Parameter_set instance("name | desc :pattern .* :python_cast str :default :alone");
|
||||
return instance;
|
||||
}
|
||||
|
||||
Argtype_set::Argtype_set()
|
||||
Argtype_registry::Argtype_registry()
|
||||
{
|
||||
(void)(void)K::log(2);
|
||||
Locator loc = current_locator();
|
||||
@@ -33,7 +33,7 @@ Argtype_set::Argtype_set()
|
||||
m_types["bool"].m_alone = "true";
|
||||
}
|
||||
|
||||
std::string Argtype_set::replace_symbols(const std::string& pattern, const Locator& loc)
|
||||
std::string Argtype_registry::replace_symbols(const std::string& pattern, const Locator& loc)
|
||||
{
|
||||
std::smatch match {};
|
||||
std::regex symbol_pat(R"('(\w+)')");
|
||||
@@ -54,7 +54,7 @@ std::string Argtype_set::replace_symbols(const std::string& pattern, const Locat
|
||||
return expanded;
|
||||
}
|
||||
|
||||
void Argtype_set::check_for_existing_definition(
|
||||
void Argtype_registry::check_for_existing_definition(
|
||||
const std::string& name, const Locator& loc)
|
||||
{
|
||||
if (count(m_names.begin(), m_names.end(), name) > 0) {
|
||||
@@ -65,7 +65,7 @@ void Argtype_set::check_for_existing_definition(
|
||||
}
|
||||
}
|
||||
|
||||
void Argtype_set::add(const std::string& name, const std::string& desc,
|
||||
void Argtype_registry::add(const std::string& name, const std::string& desc,
|
||||
const std::string& pattern, const std::string& default_value,
|
||||
const std::string& alone_value,
|
||||
const std::string& python_cast, modify_string_f python_format,
|
||||
@@ -130,15 +130,15 @@ void Argtype_set::add(const std::string& name, const std::string& desc,
|
||||
m_names.push_back(name);
|
||||
}
|
||||
|
||||
void Argtype_set::add(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, std::vector<Katom>& katoms)
|
||||
void Argtype_registry::add(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, std::vector<Katom>& katoms)
|
||||
{
|
||||
(void)K::log(3);
|
||||
auto [positional, optional, rest] =
|
||||
argument_split(begin + 1, end - 1); //, Argtype_set::parameters.m_positional.size());
|
||||
argument_split(begin + 1, end - 1); //, Argtype_registry::parameters.m_positional.size());
|
||||
|
||||
check_for_existing_definition(positional[0][0].m_text, begin->m_loc);
|
||||
|
||||
auto values = Argtype_set::parameters().value_map(positional, optional, rest, begin->m_loc);
|
||||
auto values = Argtype_registry::parameters().value_map(positional, optional, rest, begin->m_loc);
|
||||
|
||||
// std::for_each(begin, end+1, [](Katom& k) { k.m_type = katom_t::replaced; });
|
||||
|
||||
@@ -151,7 +151,7 @@ void Argtype_set::add(std::vector<Katom>::iterator begin, std::vector<Katom>::it
|
||||
ignore_whitespace(next_iter, katoms);
|
||||
}
|
||||
|
||||
Argtype Argtype_set::get(const std::string& name, const Locator& loc) const
|
||||
Argtype Argtype_registry::get(const std::string& name, const Locator& loc) const
|
||||
{
|
||||
if (is_not_in(name, m_names)) {
|
||||
std::stringstream msg {};
|
||||
@@ -162,7 +162,7 @@ Argtype Argtype_set::get(const std::string& name, const Locator& loc) const
|
||||
}
|
||||
|
||||
|
||||
std::string Argtype_set::eval(
|
||||
std::string Argtype_registry::eval(
|
||||
const std::string& value, const std::string& type_name, const Locator& loc)
|
||||
{
|
||||
std::regex re = m_types[type_name].m_regex;
|
||||
@@ -193,7 +193,7 @@ static std::string values_note(const Argtype& type)
|
||||
return note.str();
|
||||
}
|
||||
|
||||
std::string Argtype_set::describe(bool long_form, int indent_width) const
|
||||
std::string Argtype_registry::describe(bool long_form, int indent_width) const
|
||||
{
|
||||
std::string indent(' ', indent_width);
|
||||
std::size_t name_width = std::accumulate(
|
||||
@@ -8,12 +8,12 @@
|
||||
#include "katom.h"
|
||||
#include "argument_set.h"
|
||||
|
||||
class Argtype_set
|
||||
class Argtype_registry
|
||||
{
|
||||
public:
|
||||
static Parameter_set& parameters();
|
||||
|
||||
Argtype_set();
|
||||
Argtype_registry();
|
||||
|
||||
std::string replace_symbols(const std::string& pattern, const Locator& loc);
|
||||
void check_for_existing_definition(const std::string& name, const Locator& loc);
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
std::string eval(const std::string& value, const std::string& type_name, const Locator& loc);
|
||||
std::string describe(bool long_form=false, int indent_width=4) const;
|
||||
|
||||
inline bool is_defined(std::string name) {
|
||||
inline bool is_defined(const std::string& name) const {
|
||||
return count(m_names.begin(), m_names.end(), name) > 0;
|
||||
}
|
||||
std::vector<std::string> m_names {};
|
||||
@@ -1,8 +1,8 @@
|
||||
#include "argument.h"
|
||||
#include "argtype.h"
|
||||
|
||||
Parameter::Parameter(const std::string& name, Argtype argtype, const Locator& loc,
|
||||
bool optional, std::string default_value)
|
||||
Parameter::Parameter(const std::string& name, const Argtype& argtype, const Locator& loc,
|
||||
bool optional, const std::string& default_value)
|
||||
: m_name(name)
|
||||
, m_argtype(argtype)
|
||||
, m_optional(optional)
|
||||
|
||||
@@ -19,11 +19,10 @@ public:
|
||||
, m_target()
|
||||
{};
|
||||
|
||||
Parameter(const std::string& name, Argtype argtype, const Locator& loc,
|
||||
bool optional=false, std::string default_value = "");
|
||||
Parameter(const std::string& name, const Argtype& argtype, const Locator& loc,
|
||||
bool optional=false, const std::string& default_value = "");
|
||||
~Parameter() = default;
|
||||
|
||||
std::string python_value(std::string value);
|
||||
bool undefined() const { return m_name == "_default"; };
|
||||
|
||||
std::string m_name {};
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "show.h"
|
||||
#include "log.h"
|
||||
#include "katom.h"
|
||||
#include "argtype_set.h"
|
||||
#include "argtype_registry.h"
|
||||
#include "argument_set.h"
|
||||
#include "util.h"
|
||||
|
||||
@@ -36,7 +36,7 @@ std::regex parameter_regex(bool optional=false)
|
||||
// rest(2): the base type is copied, its type parameter set, and its
|
||||
// display name extended, so kdesc signatures show rows.rest(2).
|
||||
static Argtype resolve_argtype(
|
||||
const std::string& type_text, const Argtype_set& argtypes, const Locator& loc)
|
||||
const std::string& type_text, const Argtype_registry& argtypes, const Locator& loc)
|
||||
{
|
||||
static const std::regex parameterized(R"((\w+)\((\d+)\))");
|
||||
std::smatch match {};
|
||||
@@ -58,7 +58,7 @@ static bool is_rest(const Argtype& argtype)
|
||||
Parameter_set::Parameter_set(const std::string parameter_string)
|
||||
{
|
||||
(void)K::log(3);
|
||||
Argtype_set argtypes {};
|
||||
Argtype_registry argtypes {};
|
||||
parse_parameters(
|
||||
katomize(line_split(parameter_string), Locator().str()),
|
||||
argtypes);
|
||||
@@ -69,11 +69,11 @@ Parameter_set::Parameter_set(const std::vector<Katom>& katoms)
|
||||
: m_katoms(katoms)
|
||||
{
|
||||
(void)K::log(3);
|
||||
Argtype_set argtypes {};
|
||||
Argtype_registry argtypes {};
|
||||
parse_parameters(m_katoms, argtypes);
|
||||
}
|
||||
|
||||
Parameter_set::Parameter_set(const std::vector<Katom>& katoms, const Argtype_set& argtypes)
|
||||
Parameter_set::Parameter_set(const std::vector<Katom>& katoms, const Argtype_registry& argtypes)
|
||||
: m_katoms(katoms)
|
||||
{
|
||||
(void)K::log(3);
|
||||
@@ -82,7 +82,7 @@ Parameter_set::Parameter_set(const std::vector<Katom>& katoms, const Argtype_set
|
||||
|
||||
// Parameter parsing
|
||||
|
||||
Parameter parse_positional_parameter(const katom_list& katoms, const Argtype_set& argtypes)
|
||||
Parameter parse_positional_parameter(const katom_list& katoms, const Argtype_registry& argtypes)
|
||||
{
|
||||
// (void)K::log(3, katoms);
|
||||
if (katoms.size() > 1) {
|
||||
@@ -110,7 +110,7 @@ Parameter parse_positional_parameter(const katom_list& katoms, const Argtype_set
|
||||
}
|
||||
|
||||
|
||||
Parameter parse_optional_parameter(const katom_list& katoms, const Argtype_set& argtypes)
|
||||
Parameter parse_optional_parameter(const katom_list& katoms, const Argtype_registry& argtypes)
|
||||
{
|
||||
//(void)K::log(3);
|
||||
Katom k = katoms[0];
|
||||
@@ -242,7 +242,7 @@ parameter_split(katom_list::const_iterator kbegin, katom_list::const_iterator ke
|
||||
return {positional, optional};
|
||||
}
|
||||
|
||||
void Parameter_set::parse_parameters(const katom_list& katoms, const Argtype_set& argtypes)
|
||||
void Parameter_set::parse_parameters(const katom_list& katoms, const Argtype_registry& argtypes)
|
||||
{
|
||||
(void)K::log(3, trim(katoms));
|
||||
if (katoms.empty()) {
|
||||
@@ -274,10 +274,10 @@ void Parameter_set::parse_parameters(const katom_list& katoms, const Argtype_set
|
||||
}
|
||||
|
||||
void describe_arguments(
|
||||
std::string label,
|
||||
std::vector<std::vector<Katom>> positional,
|
||||
std::vector<std::vector<Katom>> optional,
|
||||
std::vector<Katom> rest)
|
||||
const std::string& label,
|
||||
const std::vector<std::vector<Katom>>& positional,
|
||||
const std::vector<std::vector<Katom>>& optional,
|
||||
const std::vector<Katom>& rest)
|
||||
{
|
||||
std::cout << label << ":\n"
|
||||
<< " positional: " << positional << "\n"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "argument.h"
|
||||
#include "locator.h"
|
||||
|
||||
class Argtype_set;
|
||||
class Argtype_registry;
|
||||
|
||||
std::tuple<std::vector<std::vector<Katom>>,std::vector<std::vector<Katom>>,std::vector<Katom>>
|
||||
argument_split(std::vector<Katom>::const_iterator kbegin, std::vector<Katom>::const_iterator kend,
|
||||
@@ -20,9 +20,9 @@ public:
|
||||
~Parameter_set() = default;
|
||||
Parameter_set(const std::string parameter_string);
|
||||
Parameter_set(const std::vector<Katom>& katoms);
|
||||
Parameter_set(const std::vector<Katom>& katoms, const Argtype_set& argtypes);
|
||||
Parameter_set(const std::vector<Katom>& katoms, const Argtype_registry& argtypes);
|
||||
|
||||
void parse_parameters(const std::vector<Katom>& katoms, const Argtype_set& argtypes);
|
||||
void parse_parameters(const std::vector<Katom>& katoms, const Argtype_registry& argtypes);
|
||||
void describe_parameters();
|
||||
|
||||
void check_positional(
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
bool empty() const { return m_katoms.size() == 0; };
|
||||
|
||||
std::vector<Katom> m_katoms {};
|
||||
//Argtype_set m_argtypes {};
|
||||
//Argtype_registry m_argtypes {};
|
||||
std::vector<Parameter> m_positional {};
|
||||
std::vector<Parameter> m_optional {};
|
||||
std::vector<std::string> m_optional_names {};
|
||||
@@ -56,10 +56,10 @@ bool operator==(Parameter_set lhs, Parameter_set rhs);
|
||||
using Argument_set = Parameter_set;
|
||||
|
||||
void describe_arguments(
|
||||
std::string label,
|
||||
std::vector<std::vector<Katom>> positional,
|
||||
std::vector<std::vector<Katom>> optional,
|
||||
std::vector<Katom> rest);
|
||||
const std::string& label,
|
||||
const std::vector<std::vector<Katom>>& positional,
|
||||
const std::vector<std::vector<Katom>>& optional,
|
||||
const std::vector<Katom>& rest);
|
||||
|
||||
std::string replace_arguments(
|
||||
const std::map<std::string, std::string>& values,
|
||||
|
||||
@@ -227,7 +227,7 @@ void Argv::usage(const std::string& command)
|
||||
}
|
||||
|
||||
|
||||
void Argv::check_flags_and_options(std::string command, strings_t& words)
|
||||
void Argv::check_flags_and_options(const std::string& command, strings_t& words)
|
||||
{
|
||||
std::vector<std::string> not_defined {};
|
||||
for (auto word : words) {
|
||||
@@ -334,10 +334,10 @@ void Argv::parse_optional(strings_t& words, string_map& named_args)
|
||||
// std::cout << "\n";
|
||||
}
|
||||
|
||||
void Argv::parse_positional(std::string command, //strings_t words,
|
||||
void Argv::parse_positional(const std::string& command, //strings_t words,
|
||||
std::string pos_args, string_map& named_args)
|
||||
{
|
||||
for (std::string req : m_req_names) {
|
||||
for (const std::string& req : m_req_names) {
|
||||
auto arg = m_args[req];
|
||||
auto [substring, rest, found] = regex_split_prefix(arg.m_rgx, pos_args);
|
||||
if (!found) {
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
|
||||
void update_width(Arg arg);
|
||||
|
||||
void check_flags_and_options(std::string command, std::vector<std::string>& words);
|
||||
void check_flags_and_options(const std::string& command, std::vector<std::string>& words);
|
||||
void parse_flags(std::vector<std::string>& words, std::map<std::string, std::string>& named_args);
|
||||
void parse_optional(std::vector<std::string>& words, std::map<std::string, std::string>& named_args);
|
||||
void parse_vars(std::vector<std::string>& words, std::map<std::string, std::string>& named_args);
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
bool given(const std::string& name) { return m_given.contains(name); };
|
||||
|
||||
void parse_positional(
|
||||
std::string command, // std::vector<std::string> words,
|
||||
const std::string& command, // std::vector<std::string> words,
|
||||
std::string pos_args, std::map<std::string, std::string>& named_args);
|
||||
|
||||
std::map<std::string, std::string> classify_arguments(int argc, char* argv[], bool full_parse=true);
|
||||
@@ -96,11 +96,11 @@ public:
|
||||
void describe();
|
||||
// void describe(Argv original);
|
||||
|
||||
bool is_flag(std::string name) {
|
||||
bool is_flag(const std::string& name) const {
|
||||
return std::ranges::count(m_flag_names, name) > 0;
|
||||
}
|
||||
|
||||
bool is_opt(std::string name) {
|
||||
bool is_opt(const std::string& name) const {
|
||||
return std::ranges::count(m_opt_names, name) > 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
BASENAMES := util error locator file argv character ktype katom katom_list log show command argument argument_set argtype argtype_set state eval eval_python eval_cpp klammer klammer_set target target_set machine
|
||||
BASENAMES := util error locator file argv character ktype katom katom_list log show command argument argument_set argtype argtype_registry state eval eval_python eval_cpp klammer klammer_registry klammerset klammerset_registry target target_registry machine
|
||||
|
||||
11
mac/error.h
11
mac/error.h
@@ -10,8 +10,8 @@ inline std::string command_pathname { "Pathname of command executed on the comma
|
||||
|
||||
class Error : std::exception {
|
||||
public:
|
||||
Error(std::string error_type, std::string description,
|
||||
Locator locator = Locator(), bool do_justify = true)
|
||||
Error(const std::string& error_type, const std::string& description,
|
||||
const Locator& locator = Locator(), bool do_justify = true)
|
||||
: m_type(error_type)
|
||||
, m_desc(description)
|
||||
, m_loc(locator)
|
||||
@@ -48,6 +48,13 @@ public:
|
||||
: Error("target", description, locator, do_justify) {};
|
||||
};
|
||||
|
||||
class Klammerset_error : public Error {
|
||||
public:
|
||||
explicit Klammerset_error(
|
||||
const std::string& description, const Locator& locator=Locator(), bool do_justify=true)
|
||||
: Error("klammerset", description, locator, do_justify) {};
|
||||
};
|
||||
|
||||
class Definition_error : public Error {
|
||||
public:
|
||||
explicit Definition_error(
|
||||
|
||||
@@ -14,7 +14,7 @@ enum class eval_t {
|
||||
class Eval
|
||||
{
|
||||
public:
|
||||
explicit Eval(Machine& machine, Locator loc)
|
||||
explicit Eval(Machine& machine, const Locator& loc)
|
||||
: m_machine(machine),
|
||||
m_loc(loc)
|
||||
{};
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
#include "file.h"
|
||||
#include "show.h"
|
||||
|
||||
Eval_cpp::Eval_cpp(Machine& machine, Locator loc)
|
||||
Eval_cpp::Eval_cpp(Machine& machine, const Locator& loc)
|
||||
: m_machine(machine)
|
||||
, m_loc(loc)
|
||||
{
|
||||
(void)K::log(3);
|
||||
}
|
||||
|
||||
std::string Eval_cpp::eval(fs::path library_path, std::string function_name)
|
||||
std::string Eval_cpp::eval(const fs::path& library_path, const std::string& function_name)
|
||||
{
|
||||
(void)K::log(3, library_path, function_name);
|
||||
// msg() << "library path: " << library_path.string().c_str() << "\n";
|
||||
|
||||
@@ -7,12 +7,12 @@
|
||||
class Eval_cpp
|
||||
{
|
||||
public:
|
||||
explicit Eval_cpp(Machine& machine, Locator loc);
|
||||
explicit Eval_cpp(Machine& machine, const Locator& loc);
|
||||
Eval_cpp(const Eval_cpp&) = delete;
|
||||
Eval_cpp& operator=(const Eval_cpp&) = delete;
|
||||
//~Eval_cpp();
|
||||
|
||||
std::string eval(fs::path library_path, std::string function_name);
|
||||
std::string eval(const fs::path& library_path, const std::string& function_name);
|
||||
|
||||
Machine m_machine {};
|
||||
Locator m_loc;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
std::regex Eval_python::statement_delimiter("\\s*;\\s*");
|
||||
|
||||
Eval_python::Eval_python(Machine& machine, Locator loc)
|
||||
Eval_python::Eval_python(Machine& machine, const Locator& loc)
|
||||
: m_machine(machine)
|
||||
, m_loc(loc)
|
||||
, m_globals(nullptr)
|
||||
@@ -93,7 +93,7 @@ strings_t Eval_python::parse_modules(std::string code)
|
||||
return modules;
|
||||
}
|
||||
|
||||
void Eval_python::import_module(std::string module_name, bool verify)
|
||||
void Eval_python::import_module(const std::string& module_name, bool verify)
|
||||
{
|
||||
(void)K::log(3, module_name);
|
||||
|
||||
@@ -176,12 +176,12 @@ std::string Eval_python::get_result(PyObject* result_object)
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string Eval_python::eval_expression(std::string expression, bool import_modules)
|
||||
std::string Eval_python::eval_expression(const std::string& expression, bool import_modules)
|
||||
{
|
||||
(void)K::log(3, expression);
|
||||
// msg() << "expression: " << expression << "\n";
|
||||
if (import_modules && expression.find('.') != std::string::npos) {
|
||||
for (auto m : parse_modules(expression)) {
|
||||
for (const auto& m : parse_modules(expression)) {
|
||||
import_module(m);
|
||||
}
|
||||
}
|
||||
@@ -191,7 +191,7 @@ std::string Eval_python::eval_expression(std::string expression, bool import_mod
|
||||
Py_eval_input, m_globals, m_locals));
|
||||
}
|
||||
|
||||
std::string Eval_python::eval_statements(std::string script)
|
||||
std::string Eval_python::eval_statements(const std::string& script)
|
||||
{
|
||||
(void)K::log(3);
|
||||
strings_t statements = regex_split(script, statement_delimiter);
|
||||
|
||||
@@ -9,16 +9,16 @@ class Eval_python
|
||||
{
|
||||
public:
|
||||
static std::regex statement_delimiter;
|
||||
explicit Eval_python(Machine& machine, Locator loc);
|
||||
explicit Eval_python(Machine& machine, const Locator& loc);
|
||||
Eval_python(const Eval_python&) = delete;
|
||||
Eval_python& operator=(const Eval_python&) = delete;
|
||||
~Eval_python();
|
||||
void add_module_path(const std::string& path);
|
||||
std::vector<std::string> parse_modules(std::string code);
|
||||
void import_module(std::string module_name, bool verify = true);
|
||||
void import_module(const std::string& module_name, bool verify = true);
|
||||
std::string get_result(PyObject* result_object);
|
||||
std::string eval_expression(std::string expression, bool import_modules = true);
|
||||
std::string eval_statements(std::string script);
|
||||
std::string eval_expression(const std::string& expression, bool import_modules = true);
|
||||
std::string eval_statements(const std::string& script);
|
||||
std::string eval(std::string code);
|
||||
//std::string eval_katom_list(const katom_iter& begin, const katom_iter& end);
|
||||
std::string eval_katom_list(
|
||||
|
||||
13
mac/file.cpp
13
mac/file.cpp
@@ -440,7 +440,7 @@ strings_t get_sks_directories(const std::string& s, bool include_argument)
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string cache_directory(std::string subdirectory, std::string parent_directory)
|
||||
std::string cache_directory(const std::string& subdirectory, std::string parent_directory)
|
||||
{
|
||||
if (parent_directory.empty()) {
|
||||
// /dev/shm is a fast RAM-backed tmpfs on Linux; it does not exist on
|
||||
@@ -475,7 +475,7 @@ bool in_modification_order(std::string filename1, std::string filename2)
|
||||
}
|
||||
}
|
||||
|
||||
void write_to_cache(std::string cache_dir, std::string basename, std::string text)
|
||||
void write_to_cache(const std::string& cache_dir, const std::string& basename, const std::string& text)
|
||||
{
|
||||
if (!file_exists(cache_dir)) {
|
||||
//std::cout << "Creating cache directory: " << cache_dir << "\n";
|
||||
@@ -486,14 +486,14 @@ void write_to_cache(std::string cache_dir, std::string basename, std::string tex
|
||||
string_to_file(output_filename, text);
|
||||
}
|
||||
|
||||
std::string read_from_cache(std::string cache_dir, std::string basename)
|
||||
std::string read_from_cache(const std::string& cache_dir, const std::string& basename)
|
||||
{
|
||||
std::string input_filename = cache_dir + "/" + basename;
|
||||
// msg() << "Reading file from cache: " << input_filename << "\n";
|
||||
return string_from_file(input_filename);
|
||||
}
|
||||
|
||||
bool cache_requires_update(std::string cache_dir, std::string file_to_cache, std::string basename)
|
||||
bool cache_requires_update(const std::string& cache_dir, const std::string& file_to_cache, const std::string& basename)
|
||||
{
|
||||
std::string cache_filename = cache_dir + "/" + basename;
|
||||
return !in_modification_order(file_to_cache, cache_filename);
|
||||
@@ -662,11 +662,12 @@ void copy_file_stream(const fs::path& src, const fs::path& dst)
|
||||
}
|
||||
|
||||
void copy_preserving_basename(
|
||||
strings_t filenames, std::string output_directory, std::string link_directory)
|
||||
const strings_t& filenames, const std::string& output_directory,
|
||||
const std::string& link_directory)
|
||||
{
|
||||
fs::path outdir(output_directory + "/" + link_directory);
|
||||
fs::create_directories(outdir);
|
||||
for (std::string filename : filenames) {
|
||||
for (const std::string& filename : filenames) {
|
||||
fs::path pname(filename);
|
||||
auto out_path = outdir / pname.filename();
|
||||
// Preserve the previous copy_options::update_existing behavior: skip
|
||||
|
||||
11
mac/file.h
11
mac/file.h
@@ -45,12 +45,12 @@ fs::path klammertext_filename(
|
||||
const std::string& basename, bool error_if_missing=true, bool make_directory_if_missing=false);
|
||||
std::vector<std::string> sks_dirs();
|
||||
std::vector<std::string> get_sks_directories(const std::string& s, bool include_argument=true);
|
||||
std::string cache_directory(std::string subdirectory, std::string parent_directory="");
|
||||
std::string cache_directory(const std::string& subdirectory, std::string parent_directory="");
|
||||
std::time_t to_time_t(const fs::file_time_type& ftime);
|
||||
bool in_modification_order(std::string filename1, std::string filename2);
|
||||
void write_to_cache(std::string cache_dir, std::string basename, std::string text);
|
||||
std::string read_from_cache(std::string cache_dir, std::string basename);
|
||||
bool cache_requires_update(std::string cache_dir, std::string file_to_cache, std::string basename);
|
||||
void write_to_cache(const std::string& cache_dir, const std::string& basename, const std::string& text);
|
||||
std::string read_from_cache(const std::string& cache_dir, const std::string& basename);
|
||||
bool cache_requires_update(const std::string& cache_dir, const std::string& file_to_cache, const std::string& basename);
|
||||
|
||||
std::vector<fs::path> pathnames_with_extension(
|
||||
const fs::path& dir, const std::string extension
|
||||
@@ -73,6 +73,7 @@ bool files_differ(const fs::path& p1,
|
||||
void copy_file_stream(const fs::path& src, const fs::path& dst);
|
||||
|
||||
void copy_preserving_basename(
|
||||
std::vector<std::string> filenames, std::string output_directory, std::string link_directory);
|
||||
const std::vector<std::string>& filenames, const std::string& output_directory,
|
||||
const std::string& link_directory);
|
||||
|
||||
fs::path resolve_relative_to(const fs::path& relative, const fs::path& base=std::filesystem::current_path());
|
||||
|
||||
@@ -36,7 +36,7 @@ static std::string lower_extension(const fs::path& path)
|
||||
}
|
||||
|
||||
|
||||
std::string name_to_dirname(std::string name)
|
||||
std::string name_to_dirname(const std::string& name)
|
||||
{
|
||||
std::string result {};
|
||||
for (char c : name) {
|
||||
@@ -206,7 +206,7 @@ static void extract_font_metrics(Resolved_font& font)
|
||||
}
|
||||
}
|
||||
|
||||
Resolved_font resolve_font(std::string family_name)
|
||||
Resolved_font resolve_font(const std::string& family_name)
|
||||
{
|
||||
if (family_name.empty())
|
||||
return {};
|
||||
|
||||
@@ -19,7 +19,7 @@ struct Resolved_font {
|
||||
float capheight_ratio = 0.0f; // cap-height / unitsPerEm from OS/2 table
|
||||
};
|
||||
|
||||
std::string name_to_dirname(std::string name);
|
||||
std::string name_to_dirname(const std::string& name);
|
||||
// Directories searched for installed fonts (KLAMMERTEXT_FONTS, default
|
||||
// ~/.klammertext/fonts); the default font set is searched after them.
|
||||
std::vector<std::string> installed_font_dirs();
|
||||
@@ -27,7 +27,7 @@ std::vector<std::string> installed_font_dirs();
|
||||
std::string default_font_dir();
|
||||
// Every installable font family found across those directories.
|
||||
std::vector<std::string> available_font_families();
|
||||
Resolved_font resolve_font(std::string family_name);
|
||||
Resolved_font resolve_font(const std::string& family_name);
|
||||
void install_resolved_font(const Resolved_font& font, std::string output_dir);
|
||||
|
||||
// One font file classified by its internal metadata (name table, OS/2).
|
||||
|
||||
@@ -281,7 +281,7 @@ katom_list trim(const katom_list& katoms, bool trim_inactive)
|
||||
return trim(result, trim_types);
|
||||
}
|
||||
|
||||
strings_t line_split(std::string s)
|
||||
strings_t line_split(const std::string& s)
|
||||
{
|
||||
std::istringstream is(s);
|
||||
strings_t result {};
|
||||
@@ -293,7 +293,7 @@ strings_t line_split(std::string s)
|
||||
return result;
|
||||
}
|
||||
|
||||
std::pair<std::string, strings_t> line_split(fs::path pathname)
|
||||
std::pair<std::string, strings_t> line_split(const fs::path& pathname)
|
||||
{
|
||||
std::string source {};
|
||||
strings_t lines {};
|
||||
|
||||
@@ -99,8 +99,8 @@ std::vector<Katom> trim(const std::vector<Katom>& katoms, bool trim_inactive = f
|
||||
|
||||
std::vector<std::vector<Katom>> bar_split(std::vector<Katom>::iterator kbegin, std::vector<Katom>::iterator kend);
|
||||
|
||||
std::vector<std::string> line_split(std::string s);
|
||||
std::pair<std::string, std::vector<std::string>> line_split(fs::path pathname);
|
||||
std::vector<std::string> line_split(const std::string& s);
|
||||
std::pair<std::string, std::vector<std::string>> line_split(const fs::path& pathname);
|
||||
std::vector<Katom> katomize(const std::vector<std::string>& lines, const std::string& source_desc);
|
||||
|
||||
void warn_unparsed_katoms(std::vector<Katom>& katoms, bool warn = true);
|
||||
|
||||
@@ -181,10 +181,10 @@ void check_named_katom_span(const Katom& begin, const Katom& end)
|
||||
|
||||
spans_t find_spans(
|
||||
katom_iter begin, katom_iter end,
|
||||
std::function<bool(const Katom&)> level_inc,
|
||||
std::function<bool(const Katom&)> level_dec,
|
||||
const std::function<bool(const Katom&)>& level_inc,
|
||||
const std::function<bool(const Katom&)>& level_dec,
|
||||
bool error_exit,
|
||||
std::string name)
|
||||
const std::string& name)
|
||||
{
|
||||
(void)K::log(4, name);
|
||||
bool _dbg = false;
|
||||
@@ -245,10 +245,10 @@ spans_t find_spans(
|
||||
|
||||
spans_t find_spans(
|
||||
katom_list& katoms,
|
||||
std::function<bool(const Katom&)> level_inc,
|
||||
std::function<bool(const Katom&)> level_dec,
|
||||
const std::function<bool(const Katom&)>& level_inc,
|
||||
const std::function<bool(const Katom&)>& level_dec,
|
||||
bool error_exit,
|
||||
std::string name)
|
||||
const std::string& name)
|
||||
{
|
||||
return find_spans(katoms.begin(), katoms.end(), level_inc, level_dec, error_exit, name);
|
||||
}
|
||||
|
||||
@@ -23,17 +23,17 @@ find_katom(const std::vector<Katom>::iterator begin, const std::vector<Katom>::i
|
||||
|
||||
std::vector<std::pair<Katom, Katom>>
|
||||
find_spans(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end,
|
||||
std::function<bool(const Katom&)> level_inc,
|
||||
std::function<bool(const Katom&)> level_dec,
|
||||
const std::function<bool(const Katom&)>& level_inc,
|
||||
const std::function<bool(const Katom&)>& level_dec,
|
||||
bool error_exit,
|
||||
std::string name);
|
||||
const std::string& name);
|
||||
|
||||
std::vector<std::pair<Katom, Katom>>
|
||||
find_spans(std::vector<Katom>& katoms,
|
||||
std::function<bool(const Katom&)> level_inc,
|
||||
std::function<bool(const Katom&)> level_dec,
|
||||
const std::function<bool(const Katom&)>& level_inc,
|
||||
const std::function<bool(const Katom&)>& level_dec,
|
||||
bool error_exit=true,
|
||||
std::string name="all");
|
||||
const std::string& name="all");
|
||||
|
||||
|
||||
void describe_spans(const std::vector<Katom>& katoms);
|
||||
|
||||
@@ -13,7 +13,7 @@ using namespace std::literals;
|
||||
std::regex Klammer::name_re = std::regex(R"((\w+)(?:\.(\w+))?)");
|
||||
|
||||
std::tuple<std::string, std::string>
|
||||
parse_name(Target_set targets, Katom name_katom)
|
||||
parse_name(const Target_registry& targets, const Katom& name_katom)
|
||||
{
|
||||
std::string name_with_target = trim_char(name_katom.m_text, '@');
|
||||
std::smatch match {};
|
||||
@@ -29,7 +29,7 @@ parse_name(Target_set targets, Katom name_katom)
|
||||
std::string klammer_name = match[1];
|
||||
std::string target_name = match[2];
|
||||
if (target_name.empty()) {
|
||||
target_name = Target_set::general_name;
|
||||
target_name = Target_registry::general_name;
|
||||
}
|
||||
if (!targets.has(target_name)) {
|
||||
throw Target_error(
|
||||
@@ -41,7 +41,7 @@ parse_name(Target_set targets, Katom name_katom)
|
||||
}
|
||||
|
||||
std::tuple<Katom, Parameter_set, katom_list, Locator>
|
||||
parse_definition_katoms(std::string klammer_name, Argtype_set argtypes, katom_iter& begin, katom_iter& end)
|
||||
parse_definition_katoms(const std::string& klammer_name, const Argtype_registry& argtypes, katom_iter& begin, katom_iter& end)
|
||||
{
|
||||
(void)K::log(3, *begin, *(end - 1));
|
||||
katom_iter deftype = std::find_if(
|
||||
@@ -84,7 +84,7 @@ parse_definition_katoms(std::string klammer_name, Argtype_set argtypes, katom_it
|
||||
}
|
||||
|
||||
void Klammer::add_target_definition(
|
||||
std::string target_name, Argtype_set argtypes, katom_iter begin, katom_iter end)
|
||||
const std::string& target_name, const Argtype_registry& argtypes, katom_iter begin, katom_iter end)
|
||||
{
|
||||
(void)K::log(3, *begin, *(end-1));
|
||||
auto [deftype, parameters, body, loc] =
|
||||
@@ -95,7 +95,7 @@ void Klammer::add_target_definition(
|
||||
std::regex variable_re(R"(\*(\w+)\*)");
|
||||
int i = 0;
|
||||
variable_map_t varmap {};
|
||||
for (auto k : body) {
|
||||
for (const auto& k : body) {
|
||||
std::smatch match {};
|
||||
std::string txt = k.m_text;
|
||||
while (std::regex_search(txt, match, variable_re) &&
|
||||
@@ -127,23 +127,23 @@ void Klammer::remove_target_definition(const std::string& target_name)
|
||||
|
||||
// Rationalize multiple definitions
|
||||
|
||||
std::string error_list(std::string label, auto components, std::string after="")
|
||||
std::string error_list(const std::string& label, const auto& components, const std::string& after="")
|
||||
{
|
||||
std::stringstream ss {};
|
||||
ss << label << ":\n";
|
||||
for (auto c : components) {
|
||||
for (const auto& c : components) {
|
||||
ss << " " << c.loc.desc() << "\n";
|
||||
}
|
||||
ss << after;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
auto Klammer::target_defs(std::vector<std::string> target_names)
|
||||
auto Klammer::target_defs(const std::vector<std::string>& target_names)
|
||||
{
|
||||
std::vector<Klammer::components> defs {};
|
||||
for (auto target : target_names) {
|
||||
for (const auto& target : target_names) {
|
||||
auto target_defs = collect_if(
|
||||
m_defs, [target](const auto& def) { return def.target == target; });
|
||||
m_defs, [&target](const auto& def) { return def.target == target; });
|
||||
defs.insert(defs.end(), target_defs.begin(), target_defs.end());
|
||||
}
|
||||
return defs;
|
||||
@@ -173,7 +173,7 @@ void Klammer::disallow_instances() //Klammer::components declaration)
|
||||
}
|
||||
}
|
||||
|
||||
bool Klammer::copy_to_instances(Target_set targets)
|
||||
bool Klammer::copy_to_instances(const Target_registry& targets)
|
||||
{
|
||||
auto instances = instance_defs();
|
||||
if (!instances.empty()) {
|
||||
@@ -202,19 +202,20 @@ bool Klammer::copy_to_instances(Target_set targets)
|
||||
}
|
||||
|
||||
void Klammer::copy_components(
|
||||
Parameter_set parameters, std::vector<Klammer::components> cs, Target_set targets)
|
||||
const Parameter_set& parameters, const std::vector<Klammer::components>& cs,
|
||||
const Target_registry& targets)
|
||||
{
|
||||
(void)K::log(4);
|
||||
for (auto target_name : targets.m_names) {
|
||||
if (target_name == Target_set::declare_name ||
|
||||
target_name == Target_set::general_name) {
|
||||
for (const auto& target_name : targets.m_names) {
|
||||
if (target_name == Target_registry::declare_name ||
|
||||
target_name == Target_registry::general_name) {
|
||||
continue;
|
||||
}
|
||||
m_parameters = parameters;
|
||||
}
|
||||
for (auto c : cs) {
|
||||
for (const auto& c : cs) {
|
||||
m_body[c.target] = c.body;
|
||||
m_body_generic[c.target] = (c.target == Target_set::general_name);
|
||||
m_body_generic[c.target] = (c.target == Target_registry::general_name);
|
||||
m_varmap[c.target] = c.varmap;
|
||||
}
|
||||
}
|
||||
@@ -223,7 +224,7 @@ void Klammer::copy_components(
|
||||
|
||||
void Klammer::check_for_multiple_general_klammers()
|
||||
{
|
||||
auto general_klammers = target_defs({Target_set::general_name});
|
||||
auto general_klammers = target_defs({Target_registry::general_name});
|
||||
if (general_klammers.size() > 1) {
|
||||
throw Definition_error(
|
||||
error_list(
|
||||
@@ -235,11 +236,11 @@ void Klammer::check_for_multiple_general_klammers()
|
||||
|
||||
void Klammer::check_for_declaration_and_definitions()
|
||||
{
|
||||
auto declares = target_defs({Target_set::declare_name});
|
||||
auto declares = target_defs({Target_registry::declare_name});
|
||||
if (!declares.empty()) {
|
||||
std::vector<Klammer::components> definitions {};
|
||||
for (auto def : m_defs) {
|
||||
if (def.target != Target_set::declare_name) {
|
||||
for (const auto& def : m_defs) {
|
||||
if (def.target != Target_registry::declare_name) {
|
||||
if (def.deftype == katom_t::klammer_definition ||
|
||||
def.deftype == katom_t::klammer_default) {
|
||||
msg() << def << "\n";
|
||||
@@ -261,11 +262,11 @@ void Klammer::check_for_declaration_and_definitions()
|
||||
|
||||
// If a general definition exists, use it for targets not defined, but check signatures
|
||||
|
||||
void Klammer::copy_general_klammer_to_undefined(Target_set targets)
|
||||
void Klammer::copy_general_klammer_to_undefined(const Target_registry& targets)
|
||||
{
|
||||
(void)K::log(4);
|
||||
auto general_klammers = target_defs({Target_set::general_name});
|
||||
auto declares = target_defs({Target_set::declare_name});
|
||||
auto general_klammers = target_defs({Target_registry::general_name});
|
||||
auto declares = target_defs({Target_registry::declare_name});
|
||||
|
||||
// Check matching signatures (though this case already handled)
|
||||
if (general_klammers.size() == 1) {
|
||||
@@ -279,13 +280,13 @@ void Klammer::copy_general_klammer_to_undefined(Target_set targets)
|
||||
m_parameters.m_katoms[0].m_loc, false);
|
||||
}
|
||||
}
|
||||
auto [target, deftype, parameters, body, varmap, loc] = general_klammers[0];
|
||||
const auto& [target, deftype, parameters, body, varmap, loc] = general_klammers[0];
|
||||
if (m_parameters.m_katoms.empty()) {
|
||||
m_parameters = parameters;
|
||||
}
|
||||
for (auto target_name : targets.m_names) {
|
||||
for (const auto& target_name : targets.m_names) {
|
||||
// std::cout << "General copy, considering " << target_name << "\n";
|
||||
if (m_body.count(target_name) == 0 && target_name != Target_set::declare_name) {
|
||||
if (m_body.count(target_name) == 0 && target_name != Target_registry::declare_name) {
|
||||
// std::cout << " Copying to " << target_name << "\n";
|
||||
m_body[target_name] = body;
|
||||
m_body_generic[target_name] = true; // general body -> writer content
|
||||
@@ -298,7 +299,7 @@ void Klammer::copy_general_klammer_to_undefined(Target_set targets)
|
||||
|
||||
// Three declaration cases: none, one, many
|
||||
|
||||
void Klammer::no_declarations(Target_set targets)
|
||||
void Klammer::no_declarations(const Target_registry& targets)
|
||||
{
|
||||
(void)K::log(4);
|
||||
// std::cout << boldblack << "No declarations\n" << black;
|
||||
@@ -308,7 +309,7 @@ void Klammer::no_declarations(Target_set targets)
|
||||
std::vector<std::string> target_names = targets.applicable();
|
||||
std::vector<Parameter_set> all_parameter_sets {};
|
||||
// Are all parameters the same?
|
||||
for (auto def : m_defs) {
|
||||
for (const auto& def : m_defs) {
|
||||
if (std::ranges::find(target_names, def.target) != target_names.end()) {
|
||||
// std::cout << " Found: " << def.target << "\n";
|
||||
all_parameter_sets.push_back(def.parameters);
|
||||
@@ -332,7 +333,7 @@ void Klammer::no_declarations(Target_set targets)
|
||||
copy_general_klammer_to_undefined(targets);
|
||||
}
|
||||
|
||||
void Klammer::one_declaration(Target_set targets, Klammer::components declare)
|
||||
void Klammer::one_declaration(const Target_registry& targets, const Klammer::components& declare)
|
||||
{
|
||||
(void)K::log(4);
|
||||
// std::cout << boldblack << "One declaration\n" << black;
|
||||
@@ -342,7 +343,7 @@ void Klammer::one_declaration(Target_set targets, Klammer::components declare)
|
||||
copy_general_klammer_to_undefined(targets);
|
||||
}
|
||||
|
||||
void Klammer::many_declarations(std::vector<Klammer::components> declares)
|
||||
void Klammer::many_declarations(const std::vector<Klammer::components>& declares)
|
||||
{
|
||||
(void)K::log(4);
|
||||
// std::cout << boldblack << "Many declarations\n" << black;
|
||||
@@ -353,10 +354,10 @@ void Klammer::many_declarations(std::vector<Klammer::components> declares)
|
||||
|
||||
|
||||
|
||||
void Klammer::rationalize(Target_set targets)
|
||||
void Klammer::rationalize(const Target_registry& targets)
|
||||
{
|
||||
(void)K::log(3, m_name);
|
||||
auto declares = target_defs({Target_set::declare_name});
|
||||
auto declares = target_defs({Target_registry::declare_name});
|
||||
auto declare_count = declares.size();
|
||||
if (declare_count == 0) {
|
||||
disallow_instances();
|
||||
@@ -371,7 +372,7 @@ void Klammer::rationalize(Target_set targets)
|
||||
}
|
||||
|
||||
|
||||
std::string klammer_name_from_katom(std::string s, Locator loc)
|
||||
std::string klammer_name_from_katom(const std::string& s, const Locator& loc)
|
||||
{
|
||||
std::regex rgx(R"(@(\w+).*)");
|
||||
std::smatch match {};
|
||||
@@ -389,11 +390,11 @@ void label(const std::string& s)
|
||||
std::cout << std::right << std::setw(w) << std::setfill(' ') << s << ": ";
|
||||
}
|
||||
|
||||
void show_args(const std::string& label_text, std::vector<Argument> arguments)
|
||||
void show_args(const std::string& label_text, const std::vector<Argument>& arguments)
|
||||
{
|
||||
if (!arguments.empty()) {
|
||||
label(label_text);
|
||||
for (auto a : arguments) {
|
||||
for (const auto& a : arguments) {
|
||||
std::cout << a << " ";
|
||||
}
|
||||
std::cout << '\n';
|
||||
@@ -403,7 +404,7 @@ void show_args(const std::string& label_text, std::vector<Argument> arguments)
|
||||
strings_t Klammer::get_target_names() const
|
||||
{
|
||||
strings_t names {};
|
||||
for (auto [target, body] : m_body) {
|
||||
for (const auto& [target, body] : m_body) {
|
||||
std::stringstream ss {};
|
||||
// ss << name << target.m_loc.m_line;
|
||||
ss << target;
|
||||
@@ -422,12 +423,12 @@ strings_t Klammer::get_locations()
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string Klammer::signature_text()
|
||||
std::string Klammer::signature_text() const
|
||||
{
|
||||
std::string result {};
|
||||
bool has_pos = false;
|
||||
bool has_opt = false;
|
||||
for (auto pos : m_parameters.m_positional) {
|
||||
for (const auto& pos : m_parameters.m_positional) {
|
||||
result += pos.m_name;
|
||||
std::string type = pos.m_argtype.m_name;
|
||||
if (type != default_argtype) {
|
||||
@@ -442,7 +443,7 @@ std::string Klammer::signature_text()
|
||||
if (opt_count <= 3 && !has_pos) {
|
||||
result += " ";
|
||||
}
|
||||
for (auto opt : m_parameters.m_optional) {
|
||||
for (const auto& opt : m_parameters.m_optional) {
|
||||
if (opt_count > 3) {
|
||||
result += "\n :" + opt.m_name;
|
||||
} else {
|
||||
@@ -473,18 +474,18 @@ std::string Klammer::signature_text()
|
||||
}
|
||||
|
||||
|
||||
std::string Klammer::description_text()
|
||||
std::string Klammer::description_text() const
|
||||
{
|
||||
std::string result = " [" + m_name + ": no description]";
|
||||
if (m_body.contains("k")) {
|
||||
result = to_string(m_body["k"], true);
|
||||
result = to_string(m_body.at("k"), true);
|
||||
result = justify(result, 80, 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
std::string Klammer::describe(int margin)
|
||||
std::string Klammer::describe(int margin) const
|
||||
{
|
||||
std::string result {};
|
||||
result += "@" + m_name + signature_text() + description_text();
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "deftype.h"
|
||||
#include "argument_set.h"
|
||||
#include "target_set.h"
|
||||
#include "target_registry.h"
|
||||
#include "locator.h"
|
||||
|
||||
class Klammer
|
||||
@@ -31,37 +31,38 @@ public:
|
||||
// target-name -> [variable -> index]
|
||||
|
||||
void add_target_definition(
|
||||
std::string target_name, Argtype_set argtypes,
|
||||
const std::string& target_name, const Argtype_registry& argtypes,
|
||||
std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end);
|
||||
void remove_target_definition(const std::string& target_name);
|
||||
|
||||
auto target_defs(std::vector<std::string> target_names);
|
||||
auto target_defs(const std::vector<std::string>& target_names);
|
||||
auto instance_defs();
|
||||
void disallow_instances(); //Klammer::components declaration);
|
||||
bool copy_to_instances(Target_set targets);
|
||||
bool copy_to_instances(const Target_registry& targets);
|
||||
void copy_components(
|
||||
Parameter_set parameters, std::vector<Klammer::components> cs, Target_set targets);
|
||||
const Parameter_set& parameters, const std::vector<Klammer::components>& cs,
|
||||
const Target_registry& targets);
|
||||
void check_for_multiple_general_klammers();
|
||||
void check_for_declaration_and_definitions();
|
||||
void copy_general_klammer_to_undefined(Target_set targets);
|
||||
void no_declarations(Target_set targets);
|
||||
void one_declaration(Target_set targets, Klammer::components declare);
|
||||
void many_declarations(std::vector<Klammer::components> declares);
|
||||
void rationalize(Target_set target);
|
||||
void copy_general_klammer_to_undefined(const Target_registry& targets);
|
||||
void no_declarations(const Target_registry& targets);
|
||||
void one_declaration(const Target_registry& targets, const Klammer::components& declare);
|
||||
void many_declarations(const std::vector<Klammer::components>& declares);
|
||||
void rationalize(const Target_registry& targets);
|
||||
/*
|
||||
void add_description(const std::string& desc, Katom definition_type);
|
||||
|
||||
auto user_defs();
|
||||
auto klammer_defines_parameters();
|
||||
auto klammer_uses_parameters();
|
||||
void check_for_target_errors(Target_set targets);
|
||||
void check_for_target_errors(Target_registry targets);
|
||||
bool explicit_parameters_match();
|
||||
void copy_components(Klammer::components cs, Target_set targets);
|
||||
void copy_components(Klammer::components cs, Target_registry targets);
|
||||
*/
|
||||
|
||||
std::string signature_text();
|
||||
std::string description_text();
|
||||
std::string describe(int margin=0);
|
||||
std::string signature_text() const;
|
||||
std::string description_text() const;
|
||||
std::string describe(int margin=0) const;
|
||||
|
||||
bool has_literal_param() const {
|
||||
for (const auto& p : m_parameters.m_positional)
|
||||
@@ -91,18 +92,18 @@ public:
|
||||
std::map<std::string, bool> m_body_generic {};
|
||||
};
|
||||
|
||||
std::string klammer_name_from_katom(std::string s, Locator loc);
|
||||
std::string klammer_name_from_katom(const std::string& s, const Locator& loc);
|
||||
|
||||
std::tuple<std::string,std::string>
|
||||
parse_name(Target_set targets, Katom name_katom);
|
||||
parse_name(const Target_registry& targets, const Katom& name_katom);
|
||||
|
||||
std::tuple<Katom, Parameter_set, std::vector<Katom>, Locator>
|
||||
parse_definition_katoms(Argtype_set argtypes, //Target_set targets,
|
||||
parse_definition_katoms(const std::string& klammer_name, const Argtype_registry& argtypes,
|
||||
std::vector<Katom>::iterator& begin, std::vector<Katom>::iterator& end);
|
||||
|
||||
/*
|
||||
klammer_definition_args parse_klammer_definition_katoms(
|
||||
katom_list& katoms, Argtype_set& argtypes);
|
||||
katom_list& katoms, Argtype_registry& argtypes);
|
||||
|
||||
void check_for_undefined_arguments(
|
||||
std::string name, Parameters parameters, katom_list body_katoms, Locator loc);
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
#include "klammer.h"
|
||||
#include "klammer_set.h"
|
||||
#include "klammer_registry.h"
|
||||
#include "show.h"
|
||||
#include "util.h"
|
||||
#include "log.h"
|
||||
#include "error.h"
|
||||
|
||||
/*
|
||||
bool Klammer_set::has(std::string name, std::string target)
|
||||
bool Klammer_registry::has(std::string name, std::string target)
|
||||
{
|
||||
return m_klammers.count(name) > 0;
|
||||
}
|
||||
*/
|
||||
|
||||
void Klammer_set::add(Argtype_set argtypes, Target_set& targets, katom_iter begin, katom_iter end, katom_list& katoms)
|
||||
void Klammer_registry::add(const Argtype_registry& argtypes, const Target_registry& targets, katom_iter begin, katom_iter end, katom_list& katoms)
|
||||
{
|
||||
(void)K::log(3, *begin, *(end - 1));
|
||||
restore_initial_type(begin, end);
|
||||
@@ -62,7 +62,7 @@ void Klammer_set::add(Argtype_set argtypes, Target_set& targets, katom_iter begi
|
||||
// This add's target:
|
||||
Target target = targets.get(target_name, begin->m_loc);
|
||||
if (!target.m_provides.empty()) {
|
||||
for (auto provide_name : target.m_provides) {
|
||||
for (const auto& provide_name : target.m_provides) {
|
||||
if (m_klammers[klammer_name].m_defloc.count(provide_name) > 0) {
|
||||
m_klammers[klammer_name].remove_target_definition(provide_name);
|
||||
}
|
||||
@@ -80,30 +80,30 @@ void Klammer_set::add(Argtype_set argtypes, Target_set& targets, katom_iter begi
|
||||
ignore_whitespace(next_iter, katoms);
|
||||
}
|
||||
|
||||
void Klammer_set::rationalize(Target_set targets)
|
||||
void Klammer_registry::rationalize(const Target_registry& targets)
|
||||
{
|
||||
(void)K::log(3);
|
||||
for (auto k : m_klammers) {
|
||||
m_klammers[k.first].rationalize(targets);
|
||||
for (auto& [name, klammer] : m_klammers) {
|
||||
klammer.rationalize(targets);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
bool Klammer_set::has(std::string name, std::string target)
|
||||
bool Klammer_registry::has(std::string name, std::string target)
|
||||
{
|
||||
return m_klammers.count(name) > 0;
|
||||
}
|
||||
*/
|
||||
|
||||
void Klammer_set::check_klammer(std::string name, std::string target, Locator loc)
|
||||
void Klammer_registry::check_klammer(const std::string& name, const std::string& target, const Locator& loc) const
|
||||
{
|
||||
if (m_klammers.count(name) == 0) {
|
||||
throw Definition_error("The klammer " + q_(name) + " is not defined for an unspecified target", loc);
|
||||
}
|
||||
Klammer k = m_klammers[name];
|
||||
const Klammer& k = m_klammers.at(name);
|
||||
if (k.m_defloc.count(target) == 0) {
|
||||
std::string desc;
|
||||
if (target == Target_set::general_name) {
|
||||
if (target == Target_registry::general_name) {
|
||||
desc = "an unspecified target";
|
||||
} else {
|
||||
desc = "target " + q_(target);
|
||||
@@ -113,7 +113,7 @@ void Klammer_set::check_klammer(std::string name, std::string target, Locator lo
|
||||
}
|
||||
|
||||
|
||||
const std::vector<Katom>* Klammer_set::constant_body(const std::string& name) const
|
||||
const std::vector<Katom>* Klammer_registry::constant_body(const std::string& name) const
|
||||
{
|
||||
auto it = m_klammers.find(name);
|
||||
if (it == m_klammers.end()) return nullptr;
|
||||
@@ -126,14 +126,14 @@ const std::vector<Katom>* Klammer_set::constant_body(const std::string& name) co
|
||||
if (!d.parameters.empty()) return nullptr;
|
||||
}
|
||||
for (const auto& d : k.m_defs) {
|
||||
if (d.target == Target_set::general_name && d.parameters.empty()) {
|
||||
if (d.target == Target_registry::general_name && d.parameters.empty()) {
|
||||
return &d.body;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int max_length(std::map<std::string, Klammer> ss)
|
||||
int max_length(const std::map<std::string, Klammer>& ss)
|
||||
{
|
||||
size_t result = 0;
|
||||
for_each(ss.begin(), ss.end(),
|
||||
@@ -141,19 +141,19 @@ int max_length(std::map<std::string, Klammer> ss)
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string Klammer_set::instance_list(int margin) const
|
||||
std::string Klammer_registry::instance_list(int margin) const
|
||||
{
|
||||
std::stringstream ss {};
|
||||
std::string tab(margin, ' ');
|
||||
auto name_width = max_length(m_klammers);
|
||||
for (auto [name, k] : m_klammers) {
|
||||
for (const auto& [name, k] : m_klammers) {
|
||||
ss << tab << std::setfill(' ') << std::setw(name_width) << name
|
||||
<< sp_arrow << k << "\n";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string Klammer_set::describe(int margin) const
|
||||
std::string Klammer_registry::describe(int margin) const
|
||||
{
|
||||
/*
|
||||
strings_t names {};
|
||||
@@ -161,7 +161,7 @@ std::string Klammer_set::describe(int margin) const
|
||||
strings_t locations {};
|
||||
*/
|
||||
std::string result;
|
||||
for (auto [name, k] : m_klammers) {
|
||||
for (const auto& [name, k] : m_klammers) {
|
||||
result += k.describe(margin) + "\n";
|
||||
/*
|
||||
names.push_back(name);
|
||||
@@ -1,16 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "klammer.h"
|
||||
#include "target_set.h"
|
||||
#include "target_registry.h"
|
||||
|
||||
class Klammer_set
|
||||
class Klammer_registry
|
||||
{
|
||||
public:
|
||||
Klammer_set() = default;
|
||||
void add(Argtype_set argtypes, Target_set& targets,
|
||||
Klammer_registry() = default;
|
||||
void add(const Argtype_registry& argtypes, const Target_registry& targets,
|
||||
std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, std::vector<Katom>& katoms);
|
||||
void rationalize(Target_set targets);
|
||||
void check_klammer(std::string name, std::string target, Locator loc);
|
||||
void rationalize(const Target_registry& targets);
|
||||
void check_klammer(const std::string& name, const std::string& target, const Locator& loc) const;
|
||||
const std::vector<Katom>* constant_body(const std::string& name) const;
|
||||
std::string instance_list(int margin) const;
|
||||
std::string describe(int margin=0) const;
|
||||
8
mac/klammerset.cpp
Normal file
8
mac/klammerset.cpp
Normal file
@@ -0,0 +1,8 @@
|
||||
#include "klammerset.h"
|
||||
|
||||
Klammerset::Klammerset(const std::string& symbol, const std::string& desc, const Locator& loc)
|
||||
: m_symbol(symbol)
|
||||
, m_desc(desc)
|
||||
, m_loc(loc)
|
||||
{
|
||||
}
|
||||
28
mac/klammerset.h
Normal file
28
mac/klammerset.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "locator.h"
|
||||
|
||||
// A Klammerset is the formal construct declared by the @@@klammerset system
|
||||
// command: a named, logically related group of klammer definitions loaded
|
||||
// together. The instance holds metadata and the file list only -- the
|
||||
// klammers themselves live in the Machine's Klammer_registry (one flat,
|
||||
// additive namespace; the definition modes govern collisions). Membership
|
||||
// is provenance, not containment.
|
||||
class Klammerset
|
||||
{
|
||||
public:
|
||||
Klammerset() = default;
|
||||
Klammerset(const std::string& symbol, const std::string& desc, const Locator& loc);
|
||||
|
||||
std::string m_symbol {}; // registry key and command-line name (e.g. "sks")
|
||||
std::string m_desc {}; // the logical relationship that makes this a set
|
||||
std::string m_name {}; // display name (e.g. "Standard Klammer Set")
|
||||
std::string m_author {};
|
||||
std::string m_date {}; // last update; a date serves as the version
|
||||
std::vector<std::string> m_requires {}; // klammerset declaration files, loaded first
|
||||
std::vector<std::string> m_files {}; // definition files, loaded in list order
|
||||
Locator m_loc {}; // the declaring file; relative names resolve against it
|
||||
};
|
||||
225
mac/klammerset_registry.cpp
Normal file
225
mac/klammerset_registry.cpp
Normal file
@@ -0,0 +1,225 @@
|
||||
#include <cctype>
|
||||
#include <cstdlib>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "klammerset_registry.h"
|
||||
#include "error.h"
|
||||
#include "file.h"
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
#include "show.h"
|
||||
#include "katom.h"
|
||||
|
||||
Klammerset_registry::Klammerset_registry()
|
||||
: m_parameters(Parameter_set("symbol | desc :name :author :date :requires :files"))
|
||||
{
|
||||
}
|
||||
|
||||
void Klammerset_registry::add(Klammerset klammerset)
|
||||
{
|
||||
(void)K::log(3, klammerset.m_symbol);
|
||||
m_klammersets[klammerset.m_symbol] = klammerset;
|
||||
m_symbols.push_back(klammerset.m_symbol);
|
||||
}
|
||||
|
||||
std::optional<Klammerset> Klammerset_registry::add(
|
||||
std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, std::vector<Katom>& katoms)
|
||||
{
|
||||
(void)K::log(3, *begin, *(end - 1));
|
||||
auto [positional, optional, rest] =
|
||||
argument_split(begin + 1, end - 1, m_parameters.m_positional.size());
|
||||
auto values = m_parameters.value_map(positional, optional, rest, begin->m_loc);
|
||||
|
||||
modify_type(katom_t::replaced, begin, end);
|
||||
auto next_iter = end;
|
||||
ignore_whitespace(next_iter, katoms);
|
||||
|
||||
std::string symbol = values["symbol"];
|
||||
check_symbol(symbol, begin->m_loc);
|
||||
if (has(symbol)) {
|
||||
(void)K::log(2, "Klammerset \"" + symbol + "\" is already loaded; declaration skipped");
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// The filename lists follow the standard conventions (spaces allowed,
|
||||
// standalone "/" separator). The existence rescue tests names against
|
||||
// the declaring file's directory, where relative names are later
|
||||
// resolved by Machine::load_klammerset_files.
|
||||
fs::path declaring(begin->m_loc.m_filename);
|
||||
std::string base_dir =
|
||||
fs::exists(declaring) ? declaring.parent_path().string() : "";
|
||||
|
||||
Klammerset klammerset(symbol, values["desc"], begin->m_loc);
|
||||
klammerset.m_name = values["name"];
|
||||
klammerset.m_author = values["author"];
|
||||
klammerset.m_date = values["date"];
|
||||
klammerset.m_requires = resolve_filename_list(values["requires"], base_dir);
|
||||
klammerset.m_files = resolve_filename_list(values["files"], base_dir);
|
||||
add(klammerset);
|
||||
return klammerset;
|
||||
}
|
||||
|
||||
void Klammerset_registry::check_symbol(const std::string& symbol, const Locator& loc) const
|
||||
{
|
||||
bool valid = !symbol.empty() && std::isalpha(static_cast<unsigned char>(symbol[0]));
|
||||
for (char c : symbol) {
|
||||
if (!std::isalnum(static_cast<unsigned char>(c)) && c != '_') {
|
||||
valid = false;
|
||||
}
|
||||
}
|
||||
if (!valid) {
|
||||
throw Klammerset_error(
|
||||
"The klammerset symbol \"" + symbol + "\" is not valid. A symbol begins "
|
||||
"with a letter and contains only letters, digits, and underscores.",
|
||||
loc);
|
||||
}
|
||||
}
|
||||
|
||||
bool Klammerset_registry::has(const std::string& symbol) const
|
||||
{
|
||||
return m_klammersets.count(symbol) > 0;
|
||||
}
|
||||
|
||||
Klammerset Klammerset_registry::get(const std::string& symbol, const Locator& loc) const
|
||||
{
|
||||
if (has(symbol)) {
|
||||
return m_klammersets.at(symbol);
|
||||
} else {
|
||||
throw Klammerset_error("Klammerset " + symbol + " does not exist", loc);
|
||||
}
|
||||
}
|
||||
|
||||
// --- The klammerset search path ---
|
||||
|
||||
bool is_klammerset_symbol(const std::string& name)
|
||||
{
|
||||
if (name.empty() || !std::isalpha(static_cast<unsigned char>(name[0]))) {
|
||||
return false;
|
||||
}
|
||||
for (char c : name) {
|
||||
if (!std::isalnum(static_cast<unsigned char>(c)) && c != '_') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> klammerset_search_dirs(const std::string& local_dir)
|
||||
{
|
||||
std::vector<std::string> result {};
|
||||
// A repeated directory (e.g. the local stage already IS
|
||||
// $KLAMMERTEXT_HOME) adds nothing and clutters error messages.
|
||||
auto push_unique = [&result](const std::string& dir) {
|
||||
std::string canonical = fs::weakly_canonical(dir).string();
|
||||
if (!is_in(canonical, result)) {
|
||||
result.push_back(canonical);
|
||||
}
|
||||
};
|
||||
if (!local_dir.empty()) {
|
||||
push_unique(local_dir);
|
||||
}
|
||||
std::string paths {};
|
||||
const char* env = std::getenv("KLAMMERTEXT_KLAMMERSETS");
|
||||
if (env && *env) {
|
||||
paths = env;
|
||||
} else if (const char* home = std::getenv("HOME"); home && *home) {
|
||||
paths = std::string(home) + "/.klammertext/klammersets";
|
||||
}
|
||||
std::stringstream ss(paths);
|
||||
std::string dir;
|
||||
while (std::getline(ss, dir, ':')) {
|
||||
if (!dir.empty()) {
|
||||
push_unique(dir);
|
||||
}
|
||||
}
|
||||
if (const char* kthome = std::getenv(klammertext_home_var.c_str()); kthome && *kthome) {
|
||||
push_unique(kthome);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
fs::path resolve_klammerset_symbol(
|
||||
const std::string& symbol, const std::string& local_dir, const Locator& loc)
|
||||
{
|
||||
std::vector<std::string> dirs = klammerset_search_dirs(local_dir);
|
||||
for (const std::string& dir : dirs) {
|
||||
fs::path candidate = fs::path(dir) / symbol / (symbol + ".k");
|
||||
if (fs::exists(candidate) && fs::is_regular_file(candidate)) {
|
||||
return fs::weakly_canonical(candidate);
|
||||
}
|
||||
}
|
||||
throw Klammerset_error(
|
||||
"The klammerset \"" + symbol + "\" was not found. A symbol x names the "
|
||||
"declaration file x/x.k in one of the search directories: "
|
||||
+ join(dirs, ", ")
|
||||
+ ". Enter \"kdesc --klammerset\" to list the available klammersets.",
|
||||
loc);
|
||||
}
|
||||
|
||||
std::string describe_klammerset_search(const std::string& local_dir, int margin)
|
||||
{
|
||||
std::string tab(margin, ' ');
|
||||
std::stringstream ss {};
|
||||
std::map<std::string, std::string> first_hit {};
|
||||
for (const std::string& dir : klammerset_search_dirs(local_dir)) {
|
||||
if (!fs::is_directory(dir)) {
|
||||
continue;
|
||||
}
|
||||
for (const auto& entry : fs::directory_iterator(dir)) {
|
||||
if (!entry.is_directory()) {
|
||||
continue;
|
||||
}
|
||||
std::string symbol = entry.path().filename().string();
|
||||
fs::path declaration = entry.path() / (symbol + ".k");
|
||||
if (!is_klammerset_symbol(symbol) || !fs::is_regular_file(declaration)) {
|
||||
continue;
|
||||
}
|
||||
ss << tab << symbol << sp_arrow << declaration.string();
|
||||
if (first_hit.count(symbol)) {
|
||||
ss << " (shadowed by " << first_hit[symbol] << ")";
|
||||
} else {
|
||||
first_hit[symbol] = declaration.string();
|
||||
}
|
||||
ss << "\n";
|
||||
}
|
||||
}
|
||||
if (first_hit.empty()) {
|
||||
ss << tab << "(no klammersets found)\n";
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string Klammerset_registry::describe(int margin, bool long_format) const
|
||||
{
|
||||
std::string tab(margin, ' ');
|
||||
std::stringstream ss {};
|
||||
std::vector<std::string> descs {};
|
||||
for (const std::string& symbol : m_symbols) {
|
||||
descs.push_back(m_klammersets.at(symbol).m_desc);
|
||||
}
|
||||
auto symbol_width = max_length(m_symbols);
|
||||
auto desc_width = max_length(descs);
|
||||
for (const std::string& symbol : m_symbols) {
|
||||
const Klammerset& ks = m_klammersets.at(symbol);
|
||||
if (long_format) {
|
||||
ss << tab << std::setfill(' ') << std::setw(symbol_width) << std::left << symbol << " "
|
||||
<< std::setw(desc_width) << std::left << ks.m_desc << " "
|
||||
<< ks.m_loc.str() << "\n";
|
||||
if (!ks.m_name.empty())
|
||||
ss << tab << std::string(symbol_width, ' ') << " name: " << ks.m_name << "\n";
|
||||
if (!ks.m_author.empty())
|
||||
ss << tab << std::string(symbol_width, ' ') << " author: " << ks.m_author << "\n";
|
||||
if (!ks.m_date.empty())
|
||||
ss << tab << std::string(symbol_width, ' ') << " date: " << ks.m_date << "\n";
|
||||
if (!ks.m_requires.empty())
|
||||
ss << tab << std::string(symbol_width, ' ') << " requires: " << join(ks.m_requires, " / ") << "\n";
|
||||
if (!ks.m_files.empty())
|
||||
ss << tab << std::string(symbol_width, ' ') << " files: " << join(ks.m_files, " / ") << "\n";
|
||||
} else {
|
||||
ss << tab << std::setfill(' ') << std::setw(symbol_width) << std::left << symbol
|
||||
<< sp_arrow << ks << "\n";
|
||||
}
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
63
mac/klammerset_registry.h
Normal file
63
mac/klammerset_registry.h
Normal file
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "klammerset.h"
|
||||
#include "argument_set.h"
|
||||
#include "katom.h"
|
||||
|
||||
class Klammerset_registry
|
||||
{
|
||||
public:
|
||||
Klammerset_registry();
|
||||
|
||||
void add(Klammerset klammerset);
|
||||
// Parse a @@@klammerset span. Returns the new Klammerset so the
|
||||
// Machine can load its files, or nullopt when the symbol is already
|
||||
// registered: a klammerset is loaded once, and a repeated declaration
|
||||
// (typically reached through :requires) is skipped, not an error.
|
||||
std::optional<Klammerset> add(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, std::vector<Katom>& katoms);
|
||||
void check_symbol(const std::string& symbol, const Locator& loc) const;
|
||||
|
||||
bool has(const std::string& symbol) const;
|
||||
Klammerset get(const std::string& symbol, const Locator& loc) const;
|
||||
|
||||
std::string describe(int margin=2, bool long_format=false) const;
|
||||
|
||||
std::map<std::string, Klammerset> m_klammersets {};
|
||||
std::vector<std::string> m_symbols {};
|
||||
Parameter_set m_parameters {};
|
||||
};
|
||||
|
||||
// --- The klammerset search path (symbol -> declaration file) ---
|
||||
|
||||
// A bare identifier (letters, digits, underscores; starts with a letter)
|
||||
// names a klammerset symbol; anything else -- a path component, an
|
||||
// extension, a space -- is a filename used as given.
|
||||
bool is_klammerset_symbol(const std::string& name);
|
||||
|
||||
// The directories searched for a klammerset symbol, most specific first:
|
||||
// 1. local_dir -- the directory of whatever names the symbol: the input
|
||||
// document's directory (ktext -k), the declaring file's directory
|
||||
// (:requires), or the cwd when there is no document
|
||||
// 2. the KLAMMERTEXT_KLAMMERSETS directories (colon-separated; default
|
||||
// ~/.klammertext/klammersets), in listed order
|
||||
// 3. $KLAMMERTEXT_HOME (the distribution's sets, e.g. sks/sks.k)
|
||||
// A symbol x resolves to the first <dir>/x/x.k found, so a document-local
|
||||
// set shadows an installed one, which shadows a distributed one. (This is
|
||||
// deliberately the OPPOSITE order from the @eval module path, which puts
|
||||
// the SKS directories first: a stray util.py next to a document shadowing
|
||||
// an SKS module is an everyday accident, while a directory named sks/
|
||||
// holding an sks.k next to a manuscript is not.)
|
||||
std::vector<std::string> klammerset_search_dirs(const std::string& local_dir);
|
||||
|
||||
// Resolve a symbol to its declaration file; first hit wins. Throws a
|
||||
// Klammerset_error naming the searched directories when nothing matches.
|
||||
fs::path resolve_klammerset_symbol(
|
||||
const std::string& symbol, const std::string& local_dir, const Locator& loc);
|
||||
|
||||
// The symbols available on the search path, with provenance; a symbol
|
||||
// found again in a later directory is marked as shadowed. For
|
||||
// kdesc --klammerset.
|
||||
std::string describe_klammerset_search(const std::string& local_dir, int margin=2);
|
||||
@@ -28,7 +28,7 @@ std::string abbreviate_location(
|
||||
}
|
||||
|
||||
|
||||
Locator::Locator(fs::path filename, int line, int chr)
|
||||
Locator::Locator(const fs::path& filename, int line, int chr)
|
||||
: m_filename(filename)
|
||||
, m_line(line)
|
||||
, m_chr(chr)
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
, m_line(int(location.line()))
|
||||
, m_chr(int(location.column()))
|
||||
{};
|
||||
Locator(fs::path filename, int line, int chr);
|
||||
Locator(const fs::path& filename, int line, int chr);
|
||||
std::string str(bool relative = false) const;
|
||||
std::string desc(bool relative = false) const;
|
||||
std::string abbrev(bool include_chr=true) const;
|
||||
|
||||
100
mac/machine.cpp
100
mac/machine.cpp
@@ -9,10 +9,10 @@
|
||||
#include "eval.h"
|
||||
|
||||
Machine::Machine()
|
||||
: m_argtypes(Argtype_set())
|
||||
: m_argtypes(Argtype_registry())
|
||||
, m_state(State())
|
||||
, m_targets(Target_set())
|
||||
, m_klammers(Klammer_set())
|
||||
, m_targets(Target_registry())
|
||||
, m_klammers(Klammer_registry())
|
||||
{
|
||||
(void)K::log(3);
|
||||
m_state.add_environment_frame();
|
||||
@@ -352,20 +352,80 @@ void Machine::extract_machine_definitions()
|
||||
if (m_katoms.empty()) {
|
||||
return;
|
||||
}
|
||||
for (const auto& [op, cl] : find_spans(m_katoms, begin_machine_def, end_machine_def, true, command_name)) {
|
||||
auto [begin, end] = find_span_katoms(m_katoms, op, cl);
|
||||
//std::string name = trim_char(begin->m_text, '@');
|
||||
std::string name = begin->m_text;
|
||||
if (name == "@@@target") {
|
||||
m_targets.add(begin, end, m_katoms);
|
||||
} else if (name == "@@@argtype") {
|
||||
m_argtypes.add(begin, end, m_katoms);
|
||||
} else if (name == "@@@state") {
|
||||
m_state.parse_state_katoms(begin, end, m_katoms);
|
||||
// A @@@klammerset declaration inserts its files' katoms into the stream
|
||||
// at the declaration point, invalidating the span list, so the scan
|
||||
// restarts. Processed spans are marked replaced and are never found
|
||||
// again, which also bounds the restarts.
|
||||
bool rescan = true;
|
||||
while (rescan) {
|
||||
rescan = false;
|
||||
for (const auto& [op, cl] : find_spans(m_katoms, begin_machine_def, end_machine_def, true, command_name)) {
|
||||
auto [begin, end] = find_span_katoms(m_katoms, op, cl);
|
||||
//std::string name = trim_char(begin->m_text, '@');
|
||||
std::string name = begin->m_text;
|
||||
if (name == "@@@target") {
|
||||
m_targets.add(begin, end, m_katoms);
|
||||
} else if (name == "@@@argtype") {
|
||||
m_argtypes.add(begin, end, m_katoms);
|
||||
} else if (name == "@@@state") {
|
||||
m_state.parse_state_katoms(begin, end, m_katoms);
|
||||
} else if (name == "@@@klammerset") {
|
||||
if (auto klammerset = m_klammersets.add(begin, end, m_katoms)) {
|
||||
load_klammerset_files(*klammerset, end);
|
||||
rescan = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Machine::load_klammerset_files(const Klammerset& klammerset, katom_iter insert_at)
|
||||
{
|
||||
(void)K::log(2, "Loading klammerset \"" + klammerset.m_symbol + "\"");
|
||||
// Relative names resolve against the declaring file's directory, never
|
||||
// the cwd. :requires files are read before the set's own files; each
|
||||
// holds its own @@@klammerset declaration, whose already-loaded guard
|
||||
// makes repeated requirements a no-op.
|
||||
fs::path declaring(klammerset.m_loc.m_filename);
|
||||
fs::path base = fs::exists(declaring) ? declaring : fs::current_path();
|
||||
std::string base_dir = (is_directory(base) ? base : base.parent_path()).string();
|
||||
|
||||
// A :requires entry may be a bare symbol, resolved on the klammerset
|
||||
// search path with the declaring directory as the local stage; :files
|
||||
// entries are always filenames (this set's own definition files).
|
||||
std::vector<std::string> filenames {};
|
||||
for (const auto& required : klammerset.m_requires) {
|
||||
if (is_klammerset_symbol(required)) {
|
||||
filenames.push_back(
|
||||
resolve_klammerset_symbol(required, base_dir, klammerset.m_loc).string());
|
||||
} else {
|
||||
filenames.push_back(required);
|
||||
}
|
||||
}
|
||||
filenames.insert(filenames.end(), klammerset.m_files.begin(), klammerset.m_files.end());
|
||||
|
||||
// Collect all files into one list and insert once: insert_at is
|
||||
// invalidated by the first insertion into m_katoms.
|
||||
katom_list loaded {};
|
||||
for (const auto& filename : filenames) {
|
||||
fs::path pathname = resolve_relative_to(filename, base);
|
||||
if (!fs::exists(pathname)) {
|
||||
throw Klammerset_error(
|
||||
"Klammerset \"" + klammerset.m_symbol + "\" lists the file \"" + filename
|
||||
+ "\", which does not exist (resolved to \"" + pathname.string() + "\")",
|
||||
klammerset.m_loc);
|
||||
}
|
||||
pathname = fs::canonical(pathname);
|
||||
m_state.add_search_dir(pathname.parent_path().string());
|
||||
std::string text = trim_right(string_from_file(pathname.string()));
|
||||
katom_list ks = katomize(line_split(text), pathname);
|
||||
process_katoms(ks, pathname);
|
||||
loaded.insert(loaded.end(), ks.begin(), ks.end());
|
||||
}
|
||||
m_katoms.insert(insert_at, loaded.begin(), loaded.end());
|
||||
}
|
||||
|
||||
void Machine::extract_klammer_definitions(katom_list katoms)
|
||||
{
|
||||
fmsg() << katoms << "\n";
|
||||
@@ -489,12 +549,12 @@ katom_list Machine::apply_klammer(
|
||||
return result;
|
||||
}
|
||||
|
||||
void Machine::apply_klammer_set(
|
||||
Klammer_set& klammer_set, katom_list& katoms, const std::string& target, katom_iter begin, katom_iter end)
|
||||
void Machine::apply_klammer_registry(
|
||||
Klammer_registry& klammer_registry, katom_list& katoms, const std::string& target, katom_iter begin, katom_iter end)
|
||||
{
|
||||
(void)K::log(3, "Klammer");
|
||||
std::string name = trim_char(begin->m_text, '@');
|
||||
katom_list applied_katoms = apply_klammer(klammer_set.m_klammers[name], target, begin, end);
|
||||
katom_list applied_katoms = apply_klammer(klammer_registry.m_klammers[name], target, begin, end);
|
||||
for (auto& k : applied_katoms) {
|
||||
if (k.m_type == katom_t::bar || k.m_type == katom_t::double_bar || k.m_type == katom_t::option_name) {
|
||||
k.m_type = katom_t::text;
|
||||
@@ -504,16 +564,16 @@ void Machine::apply_klammer_set(
|
||||
}
|
||||
|
||||
void Machine::apply(
|
||||
Klammer_set& klammer_set, katom_list& katoms, const std::string& target)
|
||||
Klammer_registry& klammer_registry, katom_list& katoms, const std::string& target)
|
||||
{
|
||||
(void)K::log(3, "Klammer_set");
|
||||
(void)K::log(3, "Klammer_registry");
|
||||
for (const auto& [op, cl] : find_spans(
|
||||
katoms, begin_klammer_apply, end_klammer_apply, true, command_name)) {
|
||||
auto [begin, end] = find_span_katoms(katoms, op, cl);
|
||||
klammer_set.check_klammer(
|
||||
klammer_registry.check_klammer(
|
||||
klammer_name_from_katom(begin->m_text, begin->m_loc),
|
||||
target, begin->m_loc);
|
||||
apply_klammer_set(klammer_set, katoms, target, begin, end);
|
||||
apply_klammer_registry(klammer_registry, katoms, target, begin, end);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
|
||||
// #include "source.h"
|
||||
#include "katom_list.h"
|
||||
#include "klammer_set.h"
|
||||
#include "target_set.h"
|
||||
#include "argtype_set.h"
|
||||
#include "klammer_registry.h"
|
||||
#include "klammerset_registry.h"
|
||||
#include "target_registry.h"
|
||||
#include "argtype_registry.h"
|
||||
#include "state.h"
|
||||
|
||||
#include "error.h"
|
||||
@@ -20,11 +21,12 @@ public:
|
||||
Machine();
|
||||
|
||||
// Copy constructor
|
||||
Machine(const Machine& other)
|
||||
Machine(const Machine& other)
|
||||
: m_argtypes(other.m_argtypes)
|
||||
, m_state(other.m_state)
|
||||
, m_targets(other.m_targets)
|
||||
, m_klammers(other.m_klammers)
|
||||
, m_klammersets(other.m_klammersets)
|
||||
, m_result(other.m_result)
|
||||
{}
|
||||
|
||||
@@ -35,6 +37,7 @@ public:
|
||||
m_state = other.m_state;
|
||||
m_targets = other.m_targets;
|
||||
m_klammers = other.m_klammers;
|
||||
m_klammersets = other.m_klammersets;
|
||||
m_result = other.m_result;
|
||||
}
|
||||
return *this;
|
||||
@@ -65,6 +68,7 @@ public:
|
||||
bool klammers=true, bool eval=true, bool cond=true, bool read=true);
|
||||
|
||||
void expand_constant_klammers(katom_list& katoms, const Katom& op, const Katom& cl);
|
||||
void load_klammerset_files(const Klammerset& klammerset, katom_iter insert_at);
|
||||
void extract_machine_definitions();
|
||||
void extract_klammer_definitions();
|
||||
void extract_klammer_definitions(katom_list katoms);
|
||||
@@ -72,18 +76,19 @@ public:
|
||||
|
||||
katom_list apply_klammer(Klammer& klammer, const std::string& target, katom_iter arguments_begin, katom_iter arguments_end);
|
||||
|
||||
void apply_klammer_set(Klammer_set& klammer_set,
|
||||
void apply_klammer_registry(Klammer_registry& klammer_registry,
|
||||
katom_list& katoms, const std::string& target, katom_iter begin, katom_iter end);
|
||||
|
||||
void apply(Klammer_set& klammer_set, katom_list& katoms, const std::string& target);
|
||||
void apply(Klammer_registry& klammer_registry, katom_list& katoms, const std::string& target);
|
||||
|
||||
std::string run_phase_functions();
|
||||
std::string apply(const std::string& target_name, bool final_processing=true, bool escape_characters=true);
|
||||
|
||||
Argtype_set m_argtypes {};
|
||||
Argtype_registry m_argtypes {};
|
||||
State m_state {};
|
||||
Target_set m_targets {};
|
||||
Klammer_set m_klammers {};
|
||||
Target_registry m_targets {};
|
||||
Klammer_registry m_klammers {};
|
||||
Klammerset_registry m_klammersets {};
|
||||
input_sources_t m_sources {};
|
||||
std::string m_result {};
|
||||
std::vector<Katom> m_katoms {};
|
||||
|
||||
58
mac/show.cpp
58
mac/show.cpp
@@ -461,12 +461,12 @@ std::ostream& operator<<(std::ostream& os, const Klammer::components& kc)
|
||||
}
|
||||
|
||||
|
||||
// Klammer_set
|
||||
// Klammer_registry
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Klammer_set& ks)
|
||||
std::ostream& operator<<(std::ostream& os, const Klammer_registry& ks)
|
||||
{
|
||||
for (auto klam : ks.m_klammers) {
|
||||
for (auto [k,v] : klam.second.m_defloc) {
|
||||
for (const auto& klam : ks.m_klammers) {
|
||||
for (const auto& [k,v] : klam.second.m_defloc) {
|
||||
os << " " << k << sp_arrow << v << "\n";
|
||||
}
|
||||
//klam.second.m_defloc.str() << "\n";
|
||||
@@ -485,30 +485,62 @@ void show_arrow_pair(std::ostream& os, std::pair<std::string,std::string> transf
|
||||
std::ostream& operator<<(std::ostream& os, const Target& t)
|
||||
{
|
||||
os << "<\U0001D517" << broken_bar << t.m_name << broken_bar << t.m_desc << broken_bar;
|
||||
for (auto i : t.m_includes) {
|
||||
for (const auto& i : t.m_includes) {
|
||||
os << i << right_arrow << t.m_name << broken_bar;
|
||||
}
|
||||
for (auto p : t.m_provides) {
|
||||
for (const auto& p : t.m_provides) {
|
||||
os << t.m_name << right_arrow << p << broken_bar;
|
||||
}
|
||||
os << ">";
|
||||
return os;
|
||||
}
|
||||
|
||||
// Target_set
|
||||
// Target_registry
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Target_set& ts)
|
||||
std::ostream& operator<<(std::ostream& os, const Target_registry& ts)
|
||||
{
|
||||
size_t width = 0;
|
||||
for (auto t : ts.m_targets) {
|
||||
for (const auto& t : ts.m_targets) {
|
||||
width = std::max(width, t.first.size());
|
||||
}
|
||||
for (auto [name, target] : ts.m_targets) {
|
||||
for (const auto& [name, target] : ts.m_targets) {
|
||||
os << std::setw(width) << name << sp_arrow << target << "\n";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
// Klammerset
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Klammerset& ks)
|
||||
{
|
||||
os << "<\U0001D516" << broken_bar << ks.m_symbol << broken_bar << ks.m_desc;
|
||||
if (!ks.m_date.empty()) {
|
||||
os << broken_bar << ks.m_date;
|
||||
}
|
||||
if (!ks.m_requires.empty()) {
|
||||
os << broken_bar << "requires " << join(ks.m_requires, " / ");
|
||||
}
|
||||
if (!ks.m_files.empty()) {
|
||||
os << broken_bar << join(ks.m_files, " / ");
|
||||
}
|
||||
os << ">";
|
||||
return os;
|
||||
}
|
||||
|
||||
// Klammerset_registry
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Klammerset_registry& kr)
|
||||
{
|
||||
size_t width = 0;
|
||||
for (const auto& k : kr.m_klammersets) {
|
||||
width = std::max(width, k.first.size());
|
||||
}
|
||||
for (const auto& [symbol, klammerset] : kr.m_klammersets) {
|
||||
os << std::setw(width) << symbol << sp_arrow << klammerset << "\n";
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
// Machine
|
||||
|
||||
|
||||
@@ -537,6 +569,7 @@ std::ostream& operator<<(std::ostream& os, const Machine& m)
|
||||
std::string argtypes_desc = m.m_argtypes.describe(false, 8);
|
||||
std::string state_desc = m.m_state.describe(false, 3);
|
||||
std::string targets_desc = m.m_targets.describe(4);
|
||||
std::string klammersets_desc = m.m_klammersets.describe(4);
|
||||
std::string klammer_desc = m.m_klammers.describe(2);
|
||||
std::string source_desc = describe_sources(m);
|
||||
|
||||
@@ -544,12 +577,13 @@ std::ostream& operator<<(std::ostream& os, const Machine& m)
|
||||
<< label("Sources", m.m_sources.size()) << source_desc << "\n"
|
||||
<< label("Argtypes", m.m_argtypes.m_names.size()) << argtypes_desc << "\n"
|
||||
<< label("Targets", m.m_targets.m_names.size()) << targets_desc << "\n"
|
||||
<< label("Klammersets", m.m_klammersets.m_symbols.size()) << klammersets_desc << "\n"
|
||||
<< label("Klammers", m.m_klammers.m_klammers.size()) << klammer_desc << "\n"
|
||||
<< label("State", m.m_state.m_frames.size()) << state_desc;
|
||||
<< label("State", m.m_state.m_frames.size()) << state_desc;
|
||||
return os;
|
||||
}
|
||||
|
||||
void modify_stream(std::string name)
|
||||
void modify_stream(const std::string& name)
|
||||
{
|
||||
if (name == "all") std::cout << kall;
|
||||
if (name == "type") std::cout << ktype;
|
||||
|
||||
21
mac/show.h
21
mac/show.h
@@ -8,9 +8,10 @@
|
||||
#include "argtype.h"
|
||||
#include "argument.h"
|
||||
#include "klammer.h"
|
||||
#include "klammer_set.h"
|
||||
#include "klammer_registry.h"
|
||||
#include "klammerset_registry.h"
|
||||
#include "state.h"
|
||||
#include "target_set.h"
|
||||
#include "target_registry.h"
|
||||
#include "machine.h"
|
||||
#include "file.h"
|
||||
|
||||
@@ -143,16 +144,22 @@ std::ostream& operator<<(std::ostream& os, const Klammer::variable_map_t& vm);
|
||||
// Klammer::components
|
||||
std::ostream& operator<<(std::ostream& os, const Klammer::components& kc);
|
||||
|
||||
// Klammer_set
|
||||
std::ostream& operator<<(std::ostream& os, const Klammer_set& ks);
|
||||
// Klammer_registry
|
||||
std::ostream& operator<<(std::ostream& os, const Klammer_registry& ks);
|
||||
|
||||
// Target
|
||||
std::ostream& operator<<(std::ostream& os, const Target& t);
|
||||
|
||||
// Target_set
|
||||
std::ostream& operator<<(std::ostream& os, const Target_set& ts);
|
||||
// Target_registry
|
||||
std::ostream& operator<<(std::ostream& os, const Target_registry& ts);
|
||||
|
||||
// Klammerset
|
||||
std::ostream& operator<<(std::ostream& os, const Klammerset& ks);
|
||||
|
||||
// Klammerset_registry
|
||||
std::ostream& operator<<(std::ostream& os, const Klammerset_registry& kr);
|
||||
|
||||
// Machine
|
||||
std::ostream& operator<<(std::ostream& os, const Machine& m);
|
||||
|
||||
void modify_stream(std::string name);
|
||||
void modify_stream(const std::string& name);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
int State::class_id = 0;
|
||||
|
||||
bool Var::defined()
|
||||
bool Var::defined() const
|
||||
{
|
||||
return !m_name.empty();
|
||||
}
|
||||
@@ -24,18 +24,19 @@ std::vector<std::string> Frame::names() const
|
||||
return result;
|
||||
}
|
||||
|
||||
void Frame::set(std::string name, std::string value,
|
||||
std::string delim, std::string desc, Locator loc, Argtype argtype)
|
||||
void Frame::set(const std::string& name, const std::string& value,
|
||||
const std::string& delim, const std::string& desc, const Locator& loc,
|
||||
const Argtype& argtype)
|
||||
{
|
||||
Var v(name, value, delim, desc, loc, argtype);
|
||||
m_vars[name] = v;
|
||||
}
|
||||
|
||||
std::pair<Var, bool> Frame::get(std::string name)
|
||||
std::pair<Var, bool> Frame::get(const std::string& name) const
|
||||
{
|
||||
std::pair<Var, bool> result {Var(), false};
|
||||
if (m_vars.contains(name)) {
|
||||
result = {m_vars[name], true};
|
||||
result = {m_vars.at(name), true};
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -43,7 +44,7 @@ std::pair<Var, bool> Frame::get(std::string name)
|
||||
// State
|
||||
|
||||
|
||||
void State::open_frame(std::string name)
|
||||
void State::open_frame(const std::string& name)
|
||||
{
|
||||
Frame f(name);
|
||||
// m_frames.push_back(f);
|
||||
@@ -58,19 +59,20 @@ void State::close_frame()
|
||||
}
|
||||
// Preserve altered machine state:
|
||||
string_map machine_state {};
|
||||
for (auto [name, var] : m_frames[0].m_vars) {
|
||||
for (const auto& [name, var] : m_frames[0].m_vars) {
|
||||
if (contains(name, "K_")) {
|
||||
machine_state[name] = var.m_value;
|
||||
}
|
||||
}
|
||||
m_frames.erase(m_frames.begin());
|
||||
for (auto [name, value] : machine_state) {
|
||||
for (const auto& [name, value] : machine_state) {
|
||||
set(name, value, true);
|
||||
}
|
||||
}
|
||||
|
||||
void State::set(std::string name, std::string value, bool update,
|
||||
std::string delim, std::string desc, Locator loc, Argtype argtype)
|
||||
void State::set(const std::string& name, const std::string& value, bool update,
|
||||
const std::string& delim, const std::string& desc, const Locator& loc,
|
||||
const Argtype& argtype)
|
||||
{
|
||||
if (m_frames.empty()) {
|
||||
std::stringstream ss {};
|
||||
@@ -89,9 +91,9 @@ void State::set(std::string name, std::string value, bool update,
|
||||
m_frames[0].set(name, value, delim, desc, loc, argtype);
|
||||
}
|
||||
|
||||
void State::set(std::map<std::string, std::string> varmap)
|
||||
void State::set(const std::map<std::string, std::string>& varmap)
|
||||
{
|
||||
for (auto [k, v] : varmap) {
|
||||
for (const auto& [k, v] : varmap) {
|
||||
set(k, v);
|
||||
}
|
||||
}
|
||||
@@ -107,7 +109,7 @@ void State::set(const std::map<std::string, std::string>& varmap,
|
||||
}
|
||||
|
||||
|
||||
void State::replace(std::string name, std::string value, bool error_if_not_defined)
|
||||
void State::replace(const std::string& name, const std::string& value, bool error_if_not_defined)
|
||||
{
|
||||
if (error_if_not_defined && !get(name).defined()) {
|
||||
std::stringstream ss {};
|
||||
@@ -120,14 +122,14 @@ void State::replace(std::string name, std::string value, bool error_if_not_defin
|
||||
void State::add_environment_frame()
|
||||
{
|
||||
open_frame(klammerstate::shell_environment_name);
|
||||
for (auto [name, value] : environment_variables()) {
|
||||
for (const auto& [name, value] : environment_variables()) {
|
||||
set(name, value);
|
||||
}
|
||||
}
|
||||
|
||||
Var State::get(std::string name, bool error_if_not_defined, Locator loc)
|
||||
Var State::get(const std::string& name, bool error_if_not_defined, const Locator& loc) const
|
||||
{
|
||||
for (auto f : m_frames) {
|
||||
for (const auto& f : m_frames) {
|
||||
auto [result, found] = f.get(name);
|
||||
if (found) {
|
||||
return result;
|
||||
@@ -141,12 +143,12 @@ Var State::get(std::string name, bool error_if_not_defined, Locator loc)
|
||||
}
|
||||
}
|
||||
|
||||
std::string State::value(std::string name, bool error_if_not_defined, Locator loc)
|
||||
std::string State::value(const std::string& name, bool error_if_not_defined, const Locator& loc) const
|
||||
{
|
||||
return get(name, error_if_not_defined, loc).m_value;
|
||||
}
|
||||
|
||||
std::string State::subst(std::string text, bool quote_values)
|
||||
std::string State::subst(const std::string& text, bool quote_values) const
|
||||
{
|
||||
(void)K::log(3);
|
||||
std::string result = text;
|
||||
@@ -198,7 +200,8 @@ void State::subst(katom_iter begin, katom_iter end)
|
||||
}
|
||||
|
||||
void prohibit_change_of_description(
|
||||
std::string name, bool defined, std::string old_desc, std::string new_desc, Locator old_loc, Locator loc)
|
||||
const std::string& name, bool defined, const std::string& old_desc,
|
||||
const std::string& new_desc, const Locator& old_loc, const Locator& loc)
|
||||
{
|
||||
if (defined && !old_desc.empty() && !new_desc.empty()) {
|
||||
std::stringstream ss {};
|
||||
@@ -216,7 +219,7 @@ void prohibit_change_of_description(
|
||||
|
||||
// Parameter_set m_parameters = Parameter_set("name :value :append :replace :delim :desc");
|
||||
|
||||
void State::parse_state_katoms(katom_iter begin, katom_iter end, katom_list katoms)
|
||||
void State::parse_state_katoms(katom_iter begin, katom_iter end, katom_list& katoms)
|
||||
{
|
||||
(void)K::log(3, *begin, *(end-1));
|
||||
// std::cout << "parse_katoms: " << std::pair(begin + 1, end - 1) << "\n";
|
||||
@@ -246,11 +249,11 @@ void State::parse_state_katoms(katom_iter begin, katom_iter end, katom_list kato
|
||||
ignore_whitespace(next_iter, katoms);
|
||||
}
|
||||
|
||||
std::vector<std::string> State::all_names()
|
||||
std::vector<std::string> State::all_names() const
|
||||
{
|
||||
std::vector<std::string> result {};
|
||||
for (Frame f : m_frames) {
|
||||
for (auto [name, var] : f.m_vars) {
|
||||
for (const Frame& f : m_frames) {
|
||||
for (const auto& [name, var] : f.m_vars) {
|
||||
// std::cout << "Name: " << name << "\n";
|
||||
result.push_back(name);
|
||||
}
|
||||
@@ -282,7 +285,7 @@ std::string State::python_code()
|
||||
// the file whose @eval names it is found regardless of the cwd.
|
||||
python_dirs.insert(python_dirs.end(),
|
||||
m_search_dirs.begin(), m_search_dirs.end());
|
||||
for (auto d : python_dirs) {
|
||||
for (const auto& d : python_dirs) {
|
||||
auto python_files = pathnames_with_extension(d, "py");
|
||||
if (!python_files.empty()) {
|
||||
ss << "sys.path.append('" << d << "')\n";
|
||||
@@ -308,12 +311,12 @@ std::string State::describe(bool show_environment, int margin_size) const
|
||||
std::string margin(margin_size, ' ');
|
||||
int i = m_frames.size() - 1;
|
||||
std::stringstream ss {};
|
||||
for (auto f : m_frames) {
|
||||
for (const auto& f : m_frames) {
|
||||
int width = max_key_length(f.m_vars);
|
||||
ss << margin << "Frame " << i-- << ": " << f.m_name << "\n";
|
||||
if ((f.m_name != klammerstate::shell_environment_name) ||
|
||||
(show_environment && f.m_name == klammerstate::shell_environment_name)) {
|
||||
for (auto [key, value] : f.m_vars) {
|
||||
for (const auto& [key, value] : f.m_vars) {
|
||||
std::string print_value = value.m_value;
|
||||
if (print_value == klammerstate::no_value) {
|
||||
print_value = "<no-value>";
|
||||
|
||||
40
mac/state.h
40
mac/state.h
@@ -14,9 +14,9 @@ class Var
|
||||
{
|
||||
public:
|
||||
Var() = default;
|
||||
Var(std::string name, std::string value=klammerstate::no_value,
|
||||
std::string delim=":", std::string desc="", Locator loc=Locator(),
|
||||
Argtype argtype=Argtype())
|
||||
Var(const std::string& name, const std::string& value=klammerstate::no_value,
|
||||
const std::string& delim=":", const std::string& desc="", const Locator& loc=Locator(),
|
||||
const Argtype& argtype=Argtype())
|
||||
: m_name(name)
|
||||
, m_value(value)
|
||||
, m_delim(delim)
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
, m_loc(loc)
|
||||
, m_argtype(argtype)
|
||||
{};
|
||||
bool defined();
|
||||
bool defined() const;
|
||||
|
||||
std::string m_name {};
|
||||
std::string m_value {};
|
||||
@@ -41,15 +41,15 @@ inline std::string shell_environment_name = "Shell environment";
|
||||
class Frame
|
||||
{
|
||||
public:
|
||||
Frame(std::string name)
|
||||
Frame(const std::string& name)
|
||||
: m_name(name)
|
||||
{};
|
||||
|
||||
std::vector<std::string> names() const;
|
||||
void set(std::string name, std::string value,
|
||||
std::string delim=":", std::string desc="", Locator loc=Locator(),
|
||||
Argtype argtype=Argtype());
|
||||
std::pair<Var, bool> get(std::string name);
|
||||
void set(const std::string& name, const std::string& value,
|
||||
const std::string& delim=":", const std::string& desc="", const Locator& loc=Locator(),
|
||||
const Argtype& argtype=Argtype());
|
||||
std::pair<Var, bool> get(const std::string& name) const;
|
||||
|
||||
std::string m_name {};
|
||||
std::map<std::string, Var> m_vars {};
|
||||
@@ -59,24 +59,24 @@ class State
|
||||
{
|
||||
public:
|
||||
static int class_id;
|
||||
void open_frame(std::string name);
|
||||
void open_frame(const std::string& name);
|
||||
void close_frame();
|
||||
void set(std::string name, std::string value, bool update=false,
|
||||
std::string delim=" ", std::string desc="", Locator loc=Locator(),
|
||||
Argtype argtype=Argtype());
|
||||
void set(std::map<std::string, std::string> varmap);
|
||||
void set(const std::string& name, const std::string& value, bool update=false,
|
||||
const std::string& delim=" ", const std::string& desc="", const Locator& loc=Locator(),
|
||||
const Argtype& argtype=Argtype());
|
||||
void set(const std::map<std::string, std::string>& varmap);
|
||||
void set(const std::map<std::string, std::string>& varmap,
|
||||
const Parameter_set& parameters);
|
||||
void replace(std::string name, std::string value, bool error_if_not_defined=true);
|
||||
void replace(const std::string& name, const std::string& value, bool error_if_not_defined=true);
|
||||
void add_environment_frame();
|
||||
Var get(std::string name, bool error_if_not_defined=false, Locator loc=Locator());
|
||||
std::string value(std::string name, bool error_if_not_defined=true, Locator loc=Locator());
|
||||
Var get(const std::string& name, bool error_if_not_defined=false, const Locator& loc=Locator()) const;
|
||||
std::string value(const std::string& name, bool error_if_not_defined=true, const Locator& loc=Locator()) const;
|
||||
|
||||
std::string subst(std::string text, bool quote_values=false);
|
||||
std::string subst(const std::string& text, bool quote_values=false) const;
|
||||
void subst(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end);
|
||||
|
||||
void parse_state_katoms(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, katom_list katoms);
|
||||
std::vector<std::string> all_names();
|
||||
void parse_state_katoms(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, katom_list& katoms);
|
||||
std::vector<std::string> all_names() const;
|
||||
void add_search_dir(const std::string& dir);
|
||||
std::string python_code();
|
||||
std::string describe(bool show_environment=false, int margin_size=2) const;
|
||||
|
||||
@@ -7,32 +7,32 @@
|
||||
//#include "text.h"
|
||||
#include "util.h"
|
||||
|
||||
void Target::add_transform(std::string original, std::string transformed)
|
||||
void Target::add_transform(const std::string& original, const std::string& transformed)
|
||||
{
|
||||
m_transforms.push_back({original, transformed});
|
||||
}
|
||||
|
||||
void Target::add_transforms(std::string transforms)
|
||||
void Target::add_transforms(const std::string& transforms)
|
||||
{
|
||||
add_transforms(parse_transforms(transforms));
|
||||
}
|
||||
|
||||
void Target::add_transforms(string_pairs transforms)
|
||||
void Target::add_transforms(const string_pairs& transforms)
|
||||
{
|
||||
for (auto [old_str, new_str] : transforms) {
|
||||
for (const auto& [old_str, new_str] : transforms) {
|
||||
add_transform(old_str, new_str);
|
||||
}
|
||||
}
|
||||
|
||||
void Target::transform(katom_list& katoms)
|
||||
void Target::transform(katom_list& katoms) const
|
||||
{
|
||||
(void)K::log(3);
|
||||
std::for_each(
|
||||
katoms.begin(), katoms.end(),
|
||||
[this] (Katom& k) {
|
||||
katoms.begin(), katoms.end(),
|
||||
[this] (Katom& k) {
|
||||
// std::cout << "transform: " << k << "\n";
|
||||
if (k.m_type != katom_t::literal) {
|
||||
for (auto [a, b] : this->m_transforms) {
|
||||
for (const auto& [a, b] : this->m_transforms) {
|
||||
// std::cout << " " << a << right_arrow << b << "\n";
|
||||
k.m_text = string_replace(k.m_text, a, b);
|
||||
}
|
||||
@@ -41,7 +41,7 @@ void Target::transform(katom_list& katoms)
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string, std::string>>
|
||||
parse_transforms(std::string transform_string)
|
||||
parse_transforms(const std::string& transform_string)
|
||||
{
|
||||
(void)K::log(3);
|
||||
if (trim(transform_string).empty()) return {};
|
||||
@@ -59,7 +59,7 @@ parse_transforms(std::string transform_string)
|
||||
return result;
|
||||
}
|
||||
|
||||
void Target::add_escapes(std::string escape_spec)
|
||||
void Target::add_escapes(const std::string& escape_spec)
|
||||
{
|
||||
auto words = word_split(escape_spec);
|
||||
for (size_t i = 0; i + 1 < words.size(); i += 2) {
|
||||
@@ -142,9 +142,9 @@ std::string hide_structural_characters(const std::string& s)
|
||||
return result;
|
||||
}
|
||||
|
||||
void Target::add_after_apply(std::string function_specs)
|
||||
void Target::add_after_apply(const std::string& function_specs)
|
||||
{
|
||||
for (auto f : regex_split(function_specs, std::regex(R"(\s+;\s+)"), true)) {
|
||||
for (const auto& f : regex_split(function_specs, std::regex(R"(\s+;\s+)"), true)) {
|
||||
// msg() << "Add " << m_name << " after-apply: " << f << "\n";
|
||||
m_after_apply.push_back(f);
|
||||
}
|
||||
|
||||
20
mac/target.h
20
mac/target.h
@@ -11,25 +11,25 @@ class Target
|
||||
{
|
||||
public:
|
||||
Target() = default;
|
||||
// Target(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, Argtype_set argtypes);
|
||||
Target(std::string name, std::string desc, Locator loc)
|
||||
// Target(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, Argtype_registry argtypes);
|
||||
Target(const std::string& name, const std::string& desc, const Locator& loc)
|
||||
: m_name(name)
|
||||
, m_desc(desc)
|
||||
, m_loc(loc)
|
||||
{};
|
||||
|
||||
void add_transform(std::string original, std::string transformed);
|
||||
void add_transforms(std::string transforms);
|
||||
void add_transforms(std::vector<std::pair<std::string, std::string>> transforms);
|
||||
void transform(std::vector<Katom>& katoms);
|
||||
void add_transform(const std::string& original, const std::string& transformed);
|
||||
void add_transforms(const std::string& transforms);
|
||||
void add_transforms(const std::vector<std::pair<std::string, std::string>>& transforms);
|
||||
void transform(std::vector<Katom>& katoms) const;
|
||||
|
||||
void add_escapes(std::string escape_spec);
|
||||
void add_escapes(const std::string& escape_spec);
|
||||
std::string escape_text(std::string text) const;
|
||||
std::string unescape_text(std::string text) const;
|
||||
std::string resolve_escapes(std::string text) const;
|
||||
static std::string escape_marker(const std::string& ch);
|
||||
|
||||
void add_after_apply(std::string function_specs);
|
||||
void add_after_apply(const std::string& function_specs);
|
||||
|
||||
std::string m_name {};
|
||||
std::string m_desc {};
|
||||
@@ -40,13 +40,13 @@ public:
|
||||
Locator m_loc {};
|
||||
std::vector<std::pair<std::string, std::string>> m_transforms {};
|
||||
std::vector<std::pair<std::string, std::string>> m_escapes {};
|
||||
// Argtype_set m_argtypes {};
|
||||
// Argtype_registry m_argtypes {};
|
||||
|
||||
|
||||
};
|
||||
|
||||
std::vector<std::pair<std::string, std::string>>
|
||||
parse_transforms(std::string transform_string);
|
||||
parse_transforms(const std::string& transform_string);
|
||||
|
||||
// Decode every KTESC<hex>KTESC marker in text back to its original
|
||||
// characters. Used for the final output (after target-declared escapes have
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#include <sstream>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
#include "target_set.h"
|
||||
#include "target_registry.h"
|
||||
#include "error.h"
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
@@ -10,10 +9,10 @@
|
||||
#include "log.h"
|
||||
#include "katom.h"
|
||||
|
||||
std::string Target_set::declare_name = "k";
|
||||
std::string Target_set::general_name = "*";
|
||||
std::string Target_registry::declare_name = "k";
|
||||
std::string Target_registry::general_name = "*";
|
||||
|
||||
Target_set::Target_set()
|
||||
Target_registry::Target_registry()
|
||||
: m_parameters(Parameter_set("name | desc :after_apply :after_write :includes :escape | transforms.rest"))
|
||||
{
|
||||
Target k(declare_name, "Description of parameters and klammer result", Locator());
|
||||
@@ -22,16 +21,15 @@ Target_set::Target_set()
|
||||
add(general);
|
||||
}
|
||||
|
||||
void Target_set::add(Target target)
|
||||
void Target_registry::add(Target target)
|
||||
{
|
||||
(void)K::log(3, target);
|
||||
check_for_previous_definition(target.m_name, target.m_loc);
|
||||
m_targets[target.m_name] = target;
|
||||
m_names.push_back(target.m_name);
|
||||
m_descs.push_back(target.m_desc);
|
||||
}
|
||||
|
||||
void Target_set::add(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, std::vector<Katom>& katoms)
|
||||
void Target_registry::add(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, std::vector<Katom>& katoms)
|
||||
{
|
||||
(void)K::log(3, *begin, *(end - 1));
|
||||
auto [positional, optional, rest] =
|
||||
@@ -40,14 +38,10 @@ void Target_set::add(std::vector<Katom>::iterator begin, std::vector<Katom>::ite
|
||||
|
||||
//std::cout << ktype << "Transformed: " << kreplaced << std::pair(begin, end) << "\n";
|
||||
//std::cout << values << "\n";
|
||||
check_for_previous_definition(values["name"], begin->m_loc);
|
||||
Target target(values["name"], values["desc"], begin->m_loc);
|
||||
target.add_transforms(values["transforms"]);
|
||||
target.add_escapes(values["escape"]);
|
||||
target.add_after_apply(values["after_apply"]);
|
||||
// for (auto included_target : word_split(values["includes"])) {
|
||||
// msg() << "Include: " << included_target << "\n";
|
||||
// }
|
||||
target.m_includes = word_split(values["includes"]);
|
||||
// Inherit escapes from included targets
|
||||
for (const auto& included : target.m_includes) {
|
||||
@@ -57,15 +51,13 @@ void Target_set::add(std::vector<Katom>::iterator begin, std::vector<Katom>::ite
|
||||
}
|
||||
}
|
||||
}
|
||||
m_targets[target.m_name] = target;
|
||||
m_names.push_back(target.m_name);
|
||||
// Registration (and the previous-definition check) goes through
|
||||
// add(Target) -- the single registration path.
|
||||
add(target);
|
||||
|
||||
for (auto [name, defined_target] : m_targets) {
|
||||
// msg() << name << sp_arrow << defined_target << "\n";
|
||||
for (auto& [name, defined_target] : m_targets) {
|
||||
if (is_in(name, target.m_includes)) {
|
||||
defined_target.m_provides.push_back(target.m_name);
|
||||
// msg() << " " << name << " provides " << target.m_name << "\n " << defined_target.m_provides << "\n";
|
||||
m_targets[name] = defined_target;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,56 +68,62 @@ void Target_set::add(std::vector<Katom>::iterator begin, std::vector<Katom>::ite
|
||||
}
|
||||
|
||||
|
||||
void Target_set::check_for_previous_definition(std::string name, Locator loc)
|
||||
void Target_registry::check_for_previous_definition(const std::string& name, const Locator& loc) const
|
||||
{
|
||||
if (has(name)) {
|
||||
Target current = m_targets[name];
|
||||
const Target& current = m_targets.at(name);
|
||||
throw Target_error("Target \"" + name + "\" is already defined:\n " + current.m_loc.desc(),
|
||||
loc, false);
|
||||
}
|
||||
}
|
||||
|
||||
bool Target_set::has(std::string target_name)
|
||||
bool Target_registry::has(const std::string& target_name) const
|
||||
{
|
||||
return std::ranges::find(m_names, target_name) != m_names.end();
|
||||
// Membership comes from the map; m_names exists only to preserve
|
||||
// definition order for describe().
|
||||
return m_targets.count(target_name) > 0;
|
||||
}
|
||||
|
||||
|
||||
Target Target_set::get(std::string target_name, Locator loc)
|
||||
Target Target_registry::get(const std::string& target_name, const Locator& loc) const
|
||||
{
|
||||
if (has(target_name) || target_name == Target_set::general_name) {
|
||||
if (has(target_name) || target_name == Target_registry::general_name) {
|
||||
return m_targets.at(target_name);
|
||||
} else {
|
||||
throw Target_error("Target " + target_name + " does not exist", loc);
|
||||
}
|
||||
}
|
||||
|
||||
void Target_set::transform(std::string target_name, katom_list& katoms)
|
||||
void Target_registry::transform(const std::string& target_name, katom_list& katoms) const
|
||||
{
|
||||
(void)K::log(3);
|
||||
m_targets[target_name].transform(katoms);
|
||||
m_targets.at(target_name).transform(katoms);
|
||||
}
|
||||
|
||||
std::vector<std::string> Target_set::user_defined()
|
||||
std::vector<std::string> Target_registry::user_defined() const
|
||||
{
|
||||
return collect_if(
|
||||
m_names, [](auto name) {
|
||||
return name != Target_set::declare_name && name != Target_set::general_name; });
|
||||
m_names, [](const auto& name) {
|
||||
return name != Target_registry::declare_name && name != Target_registry::general_name; });
|
||||
}
|
||||
|
||||
std::vector<std::string> Target_set::applicable()
|
||||
std::vector<std::string> Target_registry::applicable() const
|
||||
{
|
||||
return collect_if(
|
||||
m_names, [](auto name) {
|
||||
return name != Target_set::declare_name; });
|
||||
m_names, [](const auto& name) {
|
||||
return name != Target_registry::declare_name; });
|
||||
}
|
||||
|
||||
std::string Target_set::describe(int margin, bool long_format) const
|
||||
std::string Target_registry::describe(int margin, bool long_format) const
|
||||
{
|
||||
std::string tab(margin, ' ');
|
||||
std::stringstream ss {};
|
||||
std::vector<std::string> descs {};
|
||||
for (const std::string& name : m_names) {
|
||||
descs.push_back(m_targets.at(name).m_desc);
|
||||
}
|
||||
auto name_width = max_length(m_names);
|
||||
auto desc_width = max_length(m_descs);
|
||||
auto desc_width = max_length(descs);
|
||||
for (const std::string& name : m_names) {
|
||||
const Target& t = m_targets.at(name);
|
||||
if (long_format) {
|
||||
@@ -6,17 +6,17 @@
|
||||
#include "argument_set.h"
|
||||
#include "katom.h"
|
||||
|
||||
class Target_set
|
||||
class Target_registry
|
||||
{
|
||||
public:
|
||||
static std::string declare_name;
|
||||
static std::string general_name;
|
||||
|
||||
Target_set();
|
||||
Target_registry();
|
||||
|
||||
void add(Target target);
|
||||
void add(std::vector<Katom>::iterator begin, std::vector<Katom>::iterator end, std::vector<Katom>& katoms);
|
||||
void check_for_previous_definition(std::string name, Locator loc);
|
||||
void check_for_previous_definition(const std::string& name, const Locator& loc) const;
|
||||
|
||||
|
||||
/*
|
||||
@@ -27,19 +27,18 @@ public:
|
||||
*/
|
||||
|
||||
|
||||
bool has(std::string target_name);
|
||||
Target get(std::string target_name, Locator loc);
|
||||
void transform(std::string target_name, std::vector<Katom>& katoms);
|
||||
bool has(const std::string& target_name) const;
|
||||
Target get(const std::string& target_name, const Locator& loc) const;
|
||||
void transform(const std::string& target_name, std::vector<Katom>& katoms) const;
|
||||
|
||||
std::vector<std::string> user_defined();
|
||||
std::vector<std::string> applicable();
|
||||
std::vector<std::string> user_defined() const;
|
||||
std::vector<std::string> applicable() const;
|
||||
|
||||
std::string describe(int margin=2, bool long_format=false) const;
|
||||
|
||||
//Argtype_set m_argtypes {};
|
||||
//Argtype_registry m_argtypes {};
|
||||
std::map<std::string, Target> m_targets {};
|
||||
std::vector<std::string> m_names {};
|
||||
std::vector<std::string> m_descs {};
|
||||
Parameter_set m_parameters {};
|
||||
|
||||
|
||||
@@ -51,7 +50,7 @@ public:
|
||||
|
||||
|
||||
//Parameter_set m_parameters =
|
||||
// Parameter_set(katomize({"name :desc | transforms.rest"}, "target_set"));
|
||||
// Parameter_set(katomize({"name :desc | transforms.rest"}, "target_registry"));
|
||||
|
||||
/*
|
||||
// Targets(Statevar_set& statevars);
|
||||
25
mac/util.cpp
25
mac/util.cpp
@@ -111,7 +111,7 @@ std::string regex_escape(const std::string& s)
|
||||
return result;
|
||||
}
|
||||
|
||||
strings_t regex_split(std::string s, std::regex re, bool trim_parts)
|
||||
strings_t regex_split(const std::string& s, const std::regex& re, bool trim_parts)
|
||||
{
|
||||
strings_t result = {};
|
||||
if (s.size() == 0) {
|
||||
@@ -134,17 +134,17 @@ strings_t word_split(const std::string& s)
|
||||
return regex_split(s, std::regex("\\s+"));
|
||||
}
|
||||
|
||||
bool is_in(std::string s, strings_t v)
|
||||
bool is_in(const std::string& s, const strings_t& v)
|
||||
{
|
||||
return find(v.begin(), v.end(), s) != v.end();
|
||||
}
|
||||
|
||||
bool is_not_in(std::string s, strings_t v)
|
||||
bool is_not_in(const std::string& s, const strings_t& v)
|
||||
{
|
||||
return find(v.begin(), v.end(), s) == v.end();
|
||||
}
|
||||
|
||||
strings_t find_all(std::string str, std::regex pattern, int match_group)
|
||||
strings_t find_all(const std::string& str, const std::regex& pattern, int match_group)
|
||||
{
|
||||
std::sregex_iterator end {};
|
||||
strings_t result;
|
||||
@@ -153,7 +153,7 @@ strings_t find_all(std::string str, std::regex pattern, int match_group)
|
||||
return result;
|
||||
}
|
||||
|
||||
strings_t find_all(std::string str, std::string pattern, int match_group)
|
||||
strings_t find_all(const std::string& str, const std::string& pattern, int match_group)
|
||||
{
|
||||
return find_all(str, std::regex(pattern), match_group);
|
||||
}
|
||||
@@ -168,7 +168,7 @@ strings_t split_into_paragraphs(const std::string& s)
|
||||
|
||||
}
|
||||
|
||||
std::string add_margin(std::string s, unsigned int margin_size)
|
||||
std::string add_margin(const std::string& s, unsigned int margin_size)
|
||||
{
|
||||
auto margin = std::string(margin_size, ' ');
|
||||
return trim_right(
|
||||
@@ -297,7 +297,7 @@ std::string to_be(int count, bool present)
|
||||
return result;
|
||||
}
|
||||
|
||||
int max_length(strings_t ss)
|
||||
int max_length(const strings_t& ss)
|
||||
{
|
||||
size_t result = 0;
|
||||
for_each(ss.begin(), ss.end(),
|
||||
@@ -349,7 +349,7 @@ std::vector<std::pair<std::string, std::string>> environment_variables(bool allo
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string replace_environment_variables(std::string str)
|
||||
std::string replace_environment_variables(const std::string& str)
|
||||
{
|
||||
if (str.find('{') == std::string::npos || str.find('}') == std::string::npos) {
|
||||
return str;
|
||||
@@ -398,10 +398,10 @@ std::string abbrev(const std::string& s, unsigned int max_length, bool remove_ne
|
||||
return result;
|
||||
}
|
||||
|
||||
void remove_element(std::vector<std::string>& ss, std::string removed)
|
||||
void remove_element(std::vector<std::string>& ss, const std::string& removed)
|
||||
{
|
||||
ss.erase(std::remove_if(ss.begin(), ss.end(),
|
||||
[&removed](std::string s) { return s == removed; }),
|
||||
[&removed](const std::string& s) { return s == removed; }),
|
||||
ss.end());
|
||||
}
|
||||
|
||||
@@ -428,7 +428,7 @@ std::string display_string(const std::string& s, unsigned int width, bool replac
|
||||
return result;
|
||||
}
|
||||
|
||||
std::pair<std::string,std::string> extract_parameter_type(std::string parameter_name)
|
||||
std::pair<std::string,std::string> extract_parameter_type(const std::string& parameter_name)
|
||||
{
|
||||
std::regex name_pat { R"((\w+)\.(\w+))" };
|
||||
std::smatch match {};
|
||||
@@ -487,7 +487,8 @@ std::string get_env_var(const std::string& var) {
|
||||
return val ? std::string(val) : "";
|
||||
}
|
||||
|
||||
std::string freplace(const std::string src, std::regex pattern, std::function<std::string(std::smatch)> func)
|
||||
std::string freplace(const std::string& src, const std::regex& pattern,
|
||||
const std::function<std::string(std::smatch)>& func)
|
||||
{
|
||||
std::string result {};
|
||||
std::smatch match;
|
||||
|
||||
29
mac/util.h
29
mac/util.h
@@ -36,13 +36,13 @@ std::string string_replace(const std::string& source, const std::string& old_str
|
||||
std::string regex_escape(const std::string& s);
|
||||
bool contains(const std::string& str, const std::string& substr);
|
||||
bool contains(const std::vector<std::string>& strings, const std::string& element);
|
||||
std::vector<std::string> regex_split(std::string s, std::regex re, bool trim_parts=true);
|
||||
std::vector<std::string> regex_split(const std::string& s, const std::regex& re, bool trim_parts=true);
|
||||
std::vector<std::string> word_split(const std::string& s);
|
||||
bool is_in(std::string s, std::vector<std::string> v);
|
||||
bool is_not_in(std::string s, std::vector<std::string> v);
|
||||
std::vector<std::string> find_all(std::string str, std::regex pattern, int match_group=0);
|
||||
std::vector<std::string> find_all(std::string str, std::string pattern, int match_group=0);
|
||||
std::string add_margin(std::string s, unsigned int margin_size);
|
||||
bool is_in(const std::string& s, const std::vector<std::string>& v);
|
||||
bool is_not_in(const std::string& s, const std::vector<std::string>& v);
|
||||
std::vector<std::string> find_all(const std::string& str, const std::regex& pattern, int match_group=0);
|
||||
std::vector<std::string> find_all(const std::string& str, const std::string& pattern, int match_group=0);
|
||||
std::string add_margin(const std::string& s, unsigned int margin_size);
|
||||
std::string justify(const std::string& input_text, unsigned int text_width=80, unsigned int margin_width=0);
|
||||
std::string join(const std::vector<std::string>& ss, const std::string& separator = " ");
|
||||
std::string join(int argc, char* array[], const std::string& separator = " ");
|
||||
@@ -50,26 +50,27 @@ std::string argv_to_string(int argc, char* argv[]);
|
||||
std::string plural(const std::string& word, int count);
|
||||
std::string plural(const std::string& word, const std::vector<std::string>& things);
|
||||
std::string to_be(int count, bool present = true);
|
||||
int max_length(std::vector<std::string> ss);
|
||||
int max_length(const std::vector<std::string>& ss);
|
||||
std::vector<std::pair<std::string, std::string>> environment_variables(bool allow_empty_definitions=true);
|
||||
std::string replace_environment_variables(std::string str);
|
||||
std::string replace_environment_variables(const std::string& str);
|
||||
std::string abbrev(const std::string& s, unsigned int max_length=65, bool remove_newlines=true);
|
||||
void remove_element(std::vector<std::string>& ss, std::string removed);
|
||||
void remove_element(std::vector<std::string>& ss, const std::string& removed);
|
||||
void remove_duplicates(std::vector<std::string>& ss);
|
||||
std::string display_string(const std::string& s, unsigned int width=40, bool replace_newlines=true);
|
||||
std::pair<std::string,std::string> extract_parameter_type(std::string parameter_name);
|
||||
std::pair<std::string,std::string> extract_parameter_type(const std::string& parameter_name);
|
||||
std::tuple<std::string, std::string, bool> regex_split_prefix(const std::regex& pattern, const std::string& text);
|
||||
std::vector<std::string> dlist_split(const std::string& s);
|
||||
std::string get_env_var(const std::string& var);
|
||||
std::string freplace(const std::string src, std::regex pattern, std::function<std::string(std::smatch)> func);
|
||||
std::string freplace(const std::string& src, const std::regex& pattern,
|
||||
const std::function<std::string(std::smatch)>& func);
|
||||
std::string exec(const char* cmd);
|
||||
|
||||
inline std::string q_(std::string s)
|
||||
inline std::string q_(const std::string& s)
|
||||
{
|
||||
return "\"" + s + "\"";
|
||||
}
|
||||
|
||||
inline std::string qq_(std::string s)
|
||||
inline std::string qq_(const std::string& s)
|
||||
{
|
||||
if (s.find('\n') == std::string::npos) {
|
||||
return "\"" + s + "\"";
|
||||
@@ -97,7 +98,7 @@ bool all_equal(const std::vector<T>& v) {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int max_key_length(std::map<std::string, T> map)
|
||||
int max_key_length(const std::map<std::string, T>& map)
|
||||
{
|
||||
size_t result = 0;
|
||||
for_each(map.begin(), map.end(),
|
||||
|
||||
Reference in New Issue
Block a user