summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/include/tome/squelch/automatizer.hpp11
-rw-r--r--src/include/tome/squelch/condition.hpp90
-rw-r--r--src/include/tome/squelch/rule.hpp10
-rw-r--r--src/squelch/automatizer.cc25
-rw-r--r--src/squelch/condition.cc323
-rw-r--r--src/squelch/rule.cc63
-rw-r--r--src/squeltch.cc87
7 files changed, 319 insertions, 290 deletions
diff --git a/src/include/tome/squelch/automatizer.hpp b/src/include/tome/squelch/automatizer.hpp
index 786ca1ae..4361941a 100644
--- a/src/include/tome/squelch/automatizer.hpp
+++ b/src/include/tome/squelch/automatizer.hpp
@@ -2,8 +2,8 @@
#include <boost/noncopyable.hpp>
#include <memory>
+#include <jsoncons/json.hpp>
#include <vector>
-#include <jansson.h>
#include "tome/squelch/rule_fwd.hpp"
#include "tome/squelch/cursor_fwd.hpp"
@@ -44,15 +44,14 @@ public:
bool apply_rules(object_type *o_ptr, int item_idx) const;
/**
- * Build a JSON data structure to represent
- * all the rules.
+ * Build a JSON document to represent all the rules.
*/
- std::shared_ptr<json_t> to_json() const;
+ jsoncons::json to_json() const;
/**
- * Load rules from a JSON data structure.
+ * Load rules from a JSON document.
*/
- void load_json(json_t *json);
+ void load_json(jsoncons::json const &);
/**
* Remove currently selected condition or rule.
diff --git a/src/include/tome/squelch/condition.hpp b/src/include/tome/squelch/condition.hpp
index 5d1240f5..584ecb0e 100644
--- a/src/include/tome/squelch/condition.hpp
+++ b/src/include/tome/squelch/condition.hpp
@@ -3,10 +3,10 @@
#include "tome/squelch/condition_fwd.hpp"
#include <boost/noncopyable.hpp>
+#include <cstdint>
#include <functional>
#include <memory>
-#include <cstdint>
-#include <jansson.h>
+#include <jsoncons/json.hpp>
#include "tome/squelch/cursor_fwd.hpp"
#include "tome/squelch/tree_printer_fwd.hpp"
@@ -60,7 +60,7 @@ public:
}
public:
- json_t *to_json() const;
+ jsoncons::json to_json() const;
virtual void add_child(ConditionFactory const &factory) {
// Default is to not support children.
@@ -88,16 +88,16 @@ public:
/**
* Parse condition from JSON
*/
- static std::shared_ptr<Condition> parse_condition(json_t *);
+ static std::shared_ptr<Condition> parse_condition(jsoncons::json const &);
/**
* Convert an (optional) condition to JSON.
*/
- static json_t *optional_to_json(std::shared_ptr<Condition> condition);
+ static jsoncons::json optional_to_json(std::shared_ptr<Condition> condition);
protected:
virtual void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const = 0;
- virtual void to_json(json_t *) const = 0;
+ virtual void to_json(jsoncons::json &) const = 0;
// What do we want to match?
match_type match;
@@ -116,12 +116,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
uint8_t m_tval;
@@ -140,12 +140,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
std::string m_name;
@@ -164,12 +164,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
std::string m_contain;
@@ -189,12 +189,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
uint8_t m_min;
@@ -228,10 +228,10 @@ public:
virtual std::shared_ptr<Condition> next_child(Condition *current) override;
// Parse a list of conditions from JSON property
- static std::vector< std::shared_ptr<Condition> > parse_conditions(json_t *);
+ static std::vector< std::shared_ptr<Condition> > parse_conditions(jsoncons::json const &);
protected:
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
protected:
std::vector< std::shared_ptr<Condition> > m_conditions;
@@ -248,7 +248,7 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
@@ -265,7 +265,7 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
@@ -285,12 +285,12 @@ public:
public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
status_type m_status;
@@ -309,12 +309,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
std::string m_race;
@@ -333,12 +333,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
std::string m_subrace;
@@ -357,12 +357,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
std::string m_class;
@@ -381,12 +381,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
std::string m_inscription;
@@ -406,12 +406,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
int m_min;
@@ -432,12 +432,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
int m_min;
@@ -459,12 +459,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
uint16_t m_skill_idx;
@@ -485,12 +485,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
identification_state m_state;
@@ -509,12 +509,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
char m_symbol;
@@ -533,12 +533,12 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
private:
uint16_t m_ability_idx;
@@ -563,10 +563,10 @@ public:
virtual std::shared_ptr<Condition> first_child() override;
protected:
- void to_json(json_t *) const override;
+ void to_json(jsoncons::json &) const override;
static std::shared_ptr<Condition> parse_single_subcondition(
- json_t *condition_json);
+ jsoncons::json const &condition_json);
protected:
std::shared_ptr<Condition> m_subcondition;
@@ -584,7 +584,7 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
@@ -603,7 +603,7 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
@@ -623,7 +623,7 @@ public:
bool is_match(object_type *) const override;
- static std::shared_ptr<Condition> from_json(json_t *);
+ static std::shared_ptr<Condition> from_json(jsoncons::json const &);
protected:
void write_tree(TreePrinter *, Cursor *, uint8_t, uint8_t) const override;
diff --git a/src/include/tome/squelch/rule.hpp b/src/include/tome/squelch/rule.hpp
index 63f1b6c0..752a0c2e 100644
--- a/src/include/tome/squelch/rule.hpp
+++ b/src/include/tome/squelch/rule.hpp
@@ -1,7 +1,7 @@
#pragma once
-#include <jansson.h>
#include <memory>
+#include <jsoncons/json.hpp>
#include "tome/squelch/condition_fwd.hpp"
#include "tome/squelch/cursor_fwd.hpp"
@@ -75,14 +75,14 @@ public:
bool apply_rule(object_type *o_ptr, int item_idx) const;
/**
- * Convert rule to JSON
+ * Convert rule to JSON.
*/
- virtual json_t *to_json() const;
+ virtual jsoncons::json to_json() const;
/**
* Parse rule from JSON
*/
- static std::shared_ptr<Rule> parse_rule(json_t *);
+ static std::shared_ptr<Rule> parse_rule(jsoncons::json const &);
protected:
virtual bool do_apply_rule(object_type *, int) const = 0;
@@ -148,7 +148,7 @@ public:
, m_inscription(inscription) {
}
- json_t *to_json() const override;
+ jsoncons::json to_json() const override;
protected:
virtual void do_write_tree(TreePrinter *p) const override;
diff --git a/src/squelch/automatizer.cc b/src/squelch/automatizer.cc
index c3c52b1b..2f177ef9 100644
--- a/src/squelch/automatizer.cc
+++ b/src/squelch/automatizer.cc
@@ -12,20 +12,21 @@ namespace squelch {
/**
* Parse rules from JSON array
*/
-static std::vector< std::shared_ptr < Rule > > parse_rules(json_t *rules_j)
+static std::vector< std::shared_ptr < Rule > > parse_rules(jsoncons::json const &rules_json)
{
std::vector< std::shared_ptr < Rule > > rules;
- if (!json_is_array(rules_j))
+ if (!rules_json.is_array())
{
msg_format("Error 'rules' is not an array");
return rules;
}
- for (size_t i = 0; i < json_array_size(rules_j); i++)
+ auto rules_array = rules_json.array_value();
+
+ for (auto const &rule_value : rules_array)
{
- json_t *rule_j = json_array_get(rules_j, i);
- auto rule = Rule::parse_rule(rule_j);
+ auto rule = Rule::parse_rule(rule_value);
if (rule)
{
rules.push_back(rule);
@@ -63,25 +64,25 @@ bool Automatizer::apply_rules(object_type *o_ptr, int item_idx) const
return false;
}
-std::shared_ptr<json_t> Automatizer::to_json() const
+jsoncons::json Automatizer::to_json() const
{
- auto rules_json = std::shared_ptr<json_t>(json_array(), &json_decref);
+ auto document = jsoncons::json::array();
for (auto rule : m_rules)
{
- json_array_append_new(rules_json.get(), rule->to_json());
+ document.push_back(rule->to_json());
}
- return rules_json;
+ return document;
}
-void Automatizer::load_json(json_t *json)
+void Automatizer::load_json(jsoncons::json const &document)
{
// Go through all the found rules
- auto rules = parse_rules(json);
+ auto rules = parse_rules(document);
// Load rule
- for (auto rule : rules)
+ for (auto rule: rules)
{
append_rule(rule);
}
diff --git a/src/squelch/condition.cc b/src/squelch/condition.cc
index 9e93016e..e7429cab 100644
--- a/src/squelch/condition.cc
+++ b/src/squelch/condition.cc
@@ -57,12 +57,15 @@ EnumStringMap<identification_state> &identification_state_mapping()
return *m;
}
-json_t *Condition::to_json() const
+jsoncons::json Condition::to_json() const
{
- json_t *j = json_object();
- json_object_set_new(j, "type",
- json_string(match_mapping().stringify(match)));
+ // Start with an object with only 'type' property
+ jsoncons::json j;
+ j["type"] = match_mapping().stringify(match);
+
+ // Add sub-class properties
to_json(j);
+ // Return the completed JSON
return j;
}
@@ -85,11 +88,11 @@ void Condition::display(TreePrinter *tree_printer, Cursor *cursor) const
tree_printer->dedent();
}
-std::shared_ptr<Condition> Condition::parse_condition(json_t *condition_json)
+std::shared_ptr<Condition> Condition::parse_condition(jsoncons::json const &condition_json)
{
// Parsers for concrete types of conditions.
static std::map< match_type,
- std::function< std::shared_ptr< Condition > ( json_t * ) > > parsers {
+ std::function<std::shared_ptr<Condition>(jsoncons::json const &)>> parsers {
{ match_type::AND, &AndCondition::from_json },
{ match_type::OR, &OrCondition::from_json },
{ match_type::NOT, &NotCondition::from_json },
@@ -111,15 +114,13 @@ std::shared_ptr<Condition> Condition::parse_condition(json_t *condition_json)
{ match_type::SKILL, &SkillCondition::from_json },
{ match_type::ABILITY, &AbilityCondition::from_json } };
- if ((condition_json == nullptr) || json_is_null(condition_json))
+ if (condition_json.is_null())
{
return nullptr;
}
- cptr type_s = nullptr;
- if (json_unpack(condition_json,
- "{s:s}",
- "type", &type_s) < 0)
+ cptr type_s = condition_json.get("type").as<cptr>();
+ if (!type_s)
{
msg_print("Missing/invalid 'type' in condition");
return nullptr;
@@ -143,11 +144,11 @@ std::shared_ptr<Condition> Condition::parse_condition(json_t *condition_json)
return nullptr;
}
-json_t *Condition::optional_to_json(std::shared_ptr<Condition> condition)
+jsoncons::json Condition::optional_to_json(std::shared_ptr<Condition> condition)
{
return condition
? condition->to_json()
- : json_null();
+ : jsoncons::json::null_type();
}
bool TvalCondition::is_match(object_type *o_ptr) const
@@ -155,22 +156,23 @@ bool TvalCondition::is_match(object_type *o_ptr) const
return (o_ptr->tval == m_tval);
}
-std::shared_ptr<Condition> TvalCondition::from_json(json_t *j)
+std::shared_ptr<Condition> TvalCondition::from_json(jsoncons::json const &j)
{
- int tval;
-
- if (json_unpack(j, "{s:i}", "tval", &tval) < 0)
+ auto tval_j = j.get("tval");
+ if (!tval_j.is_uinteger())
{
msg_print("Missing/invalid 'tval' property");
return nullptr;
}
+ int tval = tval_j.as_uint();
+
return std::make_shared<TvalCondition>(tval);
}
-void TvalCondition::to_json(json_t *j) const
+void TvalCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "tval", json_integer(m_tval));
+ j["tval"] = m_tval;
}
void TvalCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
@@ -192,14 +194,16 @@ bool NameCondition::is_match(object_type *o_ptr) const
return boost::algorithm::iequals(m_name, buf1);
}
-std::shared_ptr<Condition> NameCondition::from_json(json_t *j)
+std::shared_ptr<Condition> NameCondition::from_json(jsoncons::json const &j)
{
- cptr s = nullptr;
- if (json_unpack(j, "{s:s}", "name", &s) < 0)
+ cptr s = j.get("name").as<cptr>();
+
+ if (!s)
{
msg_print("Missing/invalid 'name' property");
return nullptr;
}
+
return std::make_shared<NameCondition>(s);
}
@@ -213,9 +217,9 @@ void NameCondition::write_tree(TreePrinter *p, Cursor *cursor, uint8_t ecol, uin
p->write(TERM_WHITE, "\n");
}
-void NameCondition::to_json(json_t *j) const
+void NameCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "name", json_string(m_name.c_str()));
+ j["name"] = m_name;
}
bool ContainCondition::is_match(object_type *o_ptr) const
@@ -225,14 +229,16 @@ bool ContainCondition::is_match(object_type *o_ptr) const
return boost::algorithm::icontains(buf1, m_contain);
}
-std::shared_ptr<Condition> ContainCondition::from_json(json_t *j)
+std::shared_ptr<Condition> ContainCondition::from_json(jsoncons::json const &j)
{
- cptr s = nullptr;
- if (json_unpack(j, "{s:s}", "contain", &s) < 0)
+ cptr s = j.get("contain").as<cptr>();
+
+ if (!s)
{
msg_print("Missing/invalid 'contain' property");
return nullptr;
}
+
return std::make_shared<ContainCondition>(s);
}
@@ -246,9 +252,9 @@ void ContainCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_
p->write(TERM_WHITE, "\n");
}
-void ContainCondition::to_json(json_t *j) const
+void ContainCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "contain", json_string(m_contain.c_str()));
+ j["contain"] = m_contain;
}
bool SvalCondition::is_match(object_type *o_ptr) const
@@ -258,19 +264,25 @@ bool SvalCondition::is_match(object_type *o_ptr) const
(o_ptr->sval <= m_max));
}
-std::shared_ptr<Condition> SvalCondition::from_json(json_t *j)
+std::shared_ptr<Condition> SvalCondition::from_json(jsoncons::json const &j)
{
- int min, max;
+ auto min_j = j.get("min");
+ if (!min_j.is_uinteger())
+ {
+ msg_print("Missing/invalid 'min' property");
+ return nullptr;
+ }
- if (json_unpack(j, "{s:i,s:i}",
- "min", &min,
- "max", &max) < 0)
+ auto max_j = j.get("max");
+ if (!max_j.is_uinteger())
{
- msg_print("Missing/invalid 'min'/'max' properties");
+ msg_print("Missing/invalid 'max' property");
return nullptr;
}
- return std::make_shared<SvalCondition>(min, max);
+ return std::make_shared<SvalCondition>(
+ min_j.as_uint(),
+ max_j.as_uint());
}
void SvalCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t bcol) const
@@ -284,10 +296,10 @@ void SvalCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t b
p->write(TERM_WHITE, "\n");
}
-void SvalCondition::to_json(json_t *j) const
+void SvalCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "min", json_integer(m_min));
- json_object_set_new(j, "max", json_integer(m_max));
+ j["min"] = m_min;
+ j["max"] = m_max;
}
void GroupingCondition::add_child(ConditionFactory const &factory)
@@ -369,16 +381,15 @@ std::shared_ptr<Condition> GroupingCondition::next_child(Condition *current)
return nullptr;
}
-std::vector< std::shared_ptr<Condition> > GroupingCondition::parse_conditions(json_t *j)
+std::vector< std::shared_ptr<Condition> > GroupingCondition::parse_conditions(jsoncons::json const &j)
{
- json_t *conditions_j = json_object_get(j, "conditions");
+ auto conditions_j = j.get("conditions");
- if ((conditions_j == nullptr) ||
- (json_is_null(conditions_j)))
+ if (conditions_j.is_null())
{
return std::vector< std::shared_ptr<Condition> >();
}
- else if (!json_is_array(conditions_j))
+ else if (!conditions_j.is_array())
{
msg_print("'conditions' property has invalid type");
return std::vector< std::shared_ptr<Condition> >();
@@ -386,11 +397,8 @@ std::vector< std::shared_ptr<Condition> > GroupingCondition::parse_conditions(js
else
{
std::vector< std::shared_ptr<Condition> > subconditions;
- for (size_t i = 0; i < json_array_size(conditions_j); i++)
+ for (auto const &subcondition_j: conditions_j.array_value())
{
- json_t *subcondition_j =
- json_array_get(conditions_j, i);
-
std::shared_ptr<Condition> subcondition =
parse_condition(subcondition_j);
@@ -403,14 +411,16 @@ std::vector< std::shared_ptr<Condition> > GroupingCondition::parse_conditions(js
}
}
-void GroupingCondition::to_json(json_t *j) const
+void GroupingCondition::to_json(jsoncons::json &j) const
{
- json_t *ja = json_array();
+ // Put all the sub-conditions into an array
+ jsoncons::json::array ja;
for (auto condition_p : m_conditions)
{
- json_array_append_new(ja, optional_to_json(condition_p));
+ ja.push_back(optional_to_json(condition_p));
}
- json_object_set_new(j, "conditions", ja);
+ // Add to JSON object
+ j["conditions"] = ja;
}
bool AndCondition::is_match(object_type *o_ptr) const
@@ -425,7 +435,7 @@ bool AndCondition::is_match(object_type *o_ptr) const
return true;
}
-std::shared_ptr<Condition> AndCondition::from_json(json_t *j)
+std::shared_ptr<Condition> AndCondition::from_json(jsoncons::json const &j)
{
auto condition = std::make_shared<AndCondition>();
for (auto subcondition : parse_conditions(j))
@@ -458,7 +468,7 @@ bool OrCondition::is_match(object_type *o_ptr) const
return false;
}
-std::shared_ptr<Condition> OrCondition::from_json(json_t *j)
+std::shared_ptr<Condition> OrCondition::from_json(jsoncons::json const &j)
{
std::shared_ptr<OrCondition> condition =
std::make_shared<OrCondition>();
@@ -487,10 +497,11 @@ bool StatusCondition::is_match(object_type *o_ptr) const
return m_status == object_status(o_ptr);
}
-std::shared_ptr<Condition> StatusCondition::from_json(json_t *j)
+std::shared_ptr<Condition> StatusCondition::from_json(jsoncons::json const &j)
{
- cptr s;
- if (json_unpack(j, "{s:s}", "status", &s) < 0)
+ cptr s = j.get("status").as<cptr>();
+
+ if (!s)
{
msg_print("Missing/invalid 'status' property");
return nullptr;
@@ -517,9 +528,9 @@ void StatusCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t
p->write(TERM_WHITE, "\n");
}
-void StatusCondition::to_json(json_t *j) const
+void StatusCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "status", json_string(status_mapping().stringify(m_status)));
+ j["status"] = status_mapping().stringify(m_status);
}
bool RaceCondition::is_match(object_type *o_ptr) const
@@ -527,11 +538,11 @@ bool RaceCondition::is_match(object_type *o_ptr) const
return boost::algorithm::iequals(m_race, rp_ptr->title);
}
-std::shared_ptr<Condition> RaceCondition::from_json(json_t *j)
+std::shared_ptr<Condition> RaceCondition::from_json(jsoncons::json const &j)
{
- cptr s;
+ cptr s = j.get("race").as<cptr>();
- if (json_unpack(j, "{s:s}", "race", &s) < 0)
+ if (!s)
{
msg_print("Missing/invalid 'race' property");
return nullptr;
@@ -551,9 +562,9 @@ void RaceCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t b
p->write(TERM_WHITE, "\n");
}
-void RaceCondition::to_json(json_t *j) const
+void RaceCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "race", json_string(m_race.c_str()));
+ j["race"] = m_race;
}
bool SubraceCondition::is_match(object_type *o_ptr) const
@@ -561,11 +572,11 @@ bool SubraceCondition::is_match(object_type *o_ptr) const
return boost::algorithm::iequals(m_subrace, rmp_ptr->title);
}
-std::shared_ptr<Condition> SubraceCondition::from_json(json_t *j)
+std::shared_ptr<Condition> SubraceCondition::from_json(jsoncons::json const &j)
{
- cptr s;
+ cptr s = j.get("subrace").as<cptr>();
- if (json_unpack(j, "{s:s}", "subrace", &s) < 0)
+ if (!s)
{
msg_print("Missing/invalid 'subrace' property");
return nullptr;
@@ -585,9 +596,9 @@ void SubraceCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_
p->write(TERM_WHITE, "\n");
}
-void SubraceCondition::to_json(json_t *j) const
+void SubraceCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "subrace", json_string(m_subrace.c_str()));
+ j["subrace"] = m_subrace;
}
bool ClassCondition::is_match(object_type *o_ptr) const
@@ -595,11 +606,11 @@ bool ClassCondition::is_match(object_type *o_ptr) const
return boost::algorithm::iequals(m_class, spp_ptr->title);
}
-std::shared_ptr<Condition> ClassCondition::from_json(json_t *j)
+std::shared_ptr<Condition> ClassCondition::from_json(jsoncons::json const &j)
{
- cptr s;
+ cptr s = j.get("class").as<cptr>();
- if (json_unpack(j, "{s:s}", "class", &s) < 0)
+ if (!s)
{
msg_print("Missing/invalid 'class' property");
return nullptr;
@@ -619,9 +630,9 @@ void ClassCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t
p->write(TERM_WHITE, "\n");
}
-void ClassCondition::to_json(json_t *j) const
+void ClassCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "class", json_string(m_class.c_str()));
+ j["class"] = m_class;
}
bool InscriptionCondition::is_match(object_type *o_ptr) const
@@ -631,14 +642,16 @@ bool InscriptionCondition::is_match(object_type *o_ptr) const
m_inscription);
}
-std::shared_ptr<Condition> InscriptionCondition::from_json(json_t *j)
+std::shared_ptr<Condition> InscriptionCondition::from_json(jsoncons::json const &j)
{
- cptr s = nullptr;
- if (json_unpack(j, "{s:s}", "inscription", &s) < 0)
+ cptr s = j.get("inscription").as<cptr>();
+
+ if (!s)
{
msg_print("Missing/invalid 'inscription' property");
return nullptr;
}
+
return std::make_shared<InscriptionCondition>(s);
}
@@ -653,9 +666,9 @@ void InscriptionCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, ui
p->write(TERM_WHITE, "\n");
}
-void InscriptionCondition::to_json(json_t *j) const
+void InscriptionCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "inscription", json_string(m_inscription.c_str()));
+ j["inscription"] = m_inscription;
}
bool DiscountCondition::is_match(object_type *o_ptr) const
@@ -665,17 +678,23 @@ bool DiscountCondition::is_match(object_type *o_ptr) const
(o_ptr->discount <= m_max));
}
-std::shared_ptr<Condition> DiscountCondition::from_json(json_t *j)
+std::shared_ptr<Condition> DiscountCondition::from_json(jsoncons::json const &j)
{
- int min, max;
+ auto min_j = j.get("min");
+ if (!min_j.is_integer())
+ {
+ msg_print("Missing/invalid 'min' property");
+ return nullptr;
+ }
+ int min = min_j.as_int();
- if (json_unpack(j, "{s:i,s:i}",
- "min", &min,
- "max", &max) < 0)
+ auto max_j = j.get("max");
+ if (!max_j.is_integer())
{
- msg_print("Missing/invalid 'min'/'max' properties");
+ msg_print("Missing/invalid 'max' property");
return nullptr;
}
+ int max = max_j.as_int();
return std::make_shared<DiscountCondition>(min, max);
}
@@ -691,10 +710,10 @@ void DiscountCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8
p->write(TERM_WHITE, "\n");
}
-void DiscountCondition::to_json(json_t *j) const
+void DiscountCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "min", json_integer(m_min));
- json_object_set_new(j, "max", json_integer(m_max));
+ j["min"] = m_min;
+ j["max"] = m_max;
}
bool LevelCondition::is_match(object_type *) const
@@ -703,16 +722,23 @@ bool LevelCondition::is_match(object_type *) const
(p_ptr->lev <= m_max));
}
-std::shared_ptr<Condition> LevelCondition::from_json(json_t *j)
+std::shared_ptr<Condition> LevelCondition::from_json(jsoncons::json const &j)
{
- int min, max;
- if (json_unpack(j, "{s:i,s:i}",
- "min", &min,
- "max", &max) < 0)
+ auto min_j = j.get("min");
+ if (!min_j.is_integer())
{
- msg_print("Missing/invalid 'min'/'max' properties");
+ msg_print("Missing/invalid 'min' property");
return nullptr;
}
+ int min = min_j.as_int();
+
+ auto max_j = j.get("max");
+ if (!max_j.is_integer())
+ {
+ msg_print("Missing/invalid 'max' property");
+ return nullptr;
+ }
+ int max = max_j.as_int();
return std::make_shared<LevelCondition>(min, max);
}
@@ -729,10 +755,10 @@ void LevelCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t
p->write(TERM_WHITE, "\n");
}
-void LevelCondition::to_json(json_t *j) const
+void LevelCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "min", json_integer(m_min));
- json_object_set_new(j, "max", json_integer(m_max));
+ j["min"] = m_min;
+ j["max"] = m_max;
}
bool SkillCondition::is_match(object_type *) const
@@ -742,16 +768,28 @@ bool SkillCondition::is_match(object_type *) const
(sk <= m_max));
}
-std::shared_ptr<Condition> SkillCondition::from_json(json_t *j)
+std::shared_ptr<Condition> SkillCondition::from_json(jsoncons::json const &j)
{
- cptr s;
- int min, max;
- if (json_unpack(j, "{s:i,s:i,s:s}",
- "min", &min,
- "max", &max,
- "name", &s) < 0)
+ auto min_j = j.get("min");
+ if (!min_j.is_integer())
+ {
+ msg_print("Missing/invalid 'min' property");
+ return nullptr;
+ }
+ int min = min_j.as_int();
+
+ auto max_j = j.get("max");
+ if (!max_j.is_integer())
{
- msg_print("Missing/invalid 'min'/'max'/'name' properties");
+ msg_print("Missing/invalid 'max' property");
+ return nullptr;
+ }
+ int max = max_j.as_int();
+
+ auto s = j.get("name").as<cptr>();
+ if (!s)
+ {
+ msg_print("Missing/invalid 'name' property");
return nullptr;
}
@@ -776,14 +814,11 @@ void SkillCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t
p->write(TERM_WHITE, "\n");
}
-void SkillCondition::to_json(json_t *j) const
+void SkillCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "name",
- json_string(s_descriptors[m_skill_idx].name));
- json_object_set_new(j, "min",
- json_integer(m_min));
- json_object_set_new(j, "max",
- json_integer(m_max));
+ j["name"] = s_descriptors[m_skill_idx].name;
+ j["min"] = m_min;
+ j["max"] = m_max;
}
bool StateCondition::is_match(object_type *o_ptr) const
@@ -800,10 +835,11 @@ bool StateCondition::is_match(object_type *o_ptr) const
return false;
}
-std::shared_ptr<Condition> StateCondition::from_json(json_t *j)
+std::shared_ptr<Condition> StateCondition::from_json(jsoncons::json const &j)
{
- cptr s;
- if (json_unpack(j, "{s:s}", "state", &s) < 0)
+ cptr s = j.get("state").as<cptr>();
+
+ if (!s)
{
msg_print("Missing/invalid 'state' property");
return nullptr;
@@ -830,11 +866,9 @@ void StateCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t
p->write(TERM_WHITE, "\n");
}
-void StateCondition::to_json(json_t *j) const
+void StateCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "state",
- json_string(identification_state_mapping().
- stringify(m_state)));
+ j["state"] = identification_state_mapping().stringify(m_state);
}
bool SymbolCondition::is_match(object_type *o_ptr) const
@@ -843,21 +877,16 @@ bool SymbolCondition::is_match(object_type *o_ptr) const
return k_ptr->d_char == m_symbol;
}
-std::shared_ptr<Condition> SymbolCondition::from_json(json_t *j)
+std::shared_ptr<Condition> SymbolCondition::from_json(jsoncons::json const &j)
{
- cptr s_ = nullptr;
- if (json_unpack(j, "{s:s}", "symbol", &s_) < 0)
- {
- msg_print("Missing/invalid 'symbol' property");
- return nullptr;
- }
+ auto s = j.get("symbol").as<std::string>();
- std::string s(s_);
if (s.empty())
{
- msg_print("Invalid 'symbol' property: Too short");
+ msg_print("Missing/invalid 'symbol' property");
return nullptr;
}
+
if (s.size() > 1)
{
msg_print("Invalid 'symbol' property: Too long");
@@ -878,10 +907,9 @@ void SymbolCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_t
p->write(TERM_WHITE, "\n");
}
-void SymbolCondition::to_json(json_t *j) const
+void SymbolCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "symbol",
- json_string(format("%c", m_symbol)));
+ j["symbol"] = format("%c", m_symbol);
}
bool AbilityCondition::is_match(object_type *) const
@@ -889,10 +917,11 @@ bool AbilityCondition::is_match(object_type *) const
return p_ptr->has_ability(m_ability_idx);
}
-std::shared_ptr<Condition> AbilityCondition::from_json(json_t *j)
+std::shared_ptr<Condition> AbilityCondition::from_json(jsoncons::json const &j)
{
- cptr a;
- if (json_unpack(j, "{s:s}", "ability", &a) < 0)
+ cptr a = j.get("ability").as<cptr>();
+
+ if (!a)
{
msg_print("Missing/invalid 'ability' property");
return nullptr;
@@ -918,10 +947,9 @@ void AbilityCondition::write_tree(TreePrinter *p, Cursor *, uint8_t ecol, uint8_
p->write(TERM_WHITE, "\n");
}
-void AbilityCondition::to_json(json_t *j) const
+void AbilityCondition::to_json(jsoncons::json &j) const
{
- cptr ability_s = ab_info[m_ability_idx].name;
- json_object_set_new(j, "ability", json_string(ability_s));
+ j["ability"] = ab_info[m_ability_idx].name;
}
void SingleSubconditionCondition::add_child(std::function< std::shared_ptr<Condition> () > const &factory)
@@ -946,23 +974,20 @@ std::shared_ptr<Condition> SingleSubconditionCondition::first_child()
return m_subcondition;
}
-void SingleSubconditionCondition::to_json(json_t *j) const
+void SingleSubconditionCondition::to_json(jsoncons::json &j) const
{
- json_object_set_new(j, "condition",
- optional_to_json(m_subcondition));
+ j["condition"] = optional_to_json(m_subcondition);
}
-std::shared_ptr<Condition> SingleSubconditionCondition::parse_single_subcondition(json_t *in_json)
+std::shared_ptr<Condition> SingleSubconditionCondition::parse_single_subcondition(jsoncons::json const &in_json)
{
- json_t *condition_j =
- json_object_get(in_json, "condition");
+ auto condition_j = in_json.get("condition");
- if ((condition_j == nullptr) ||
- (json_is_null(condition_j)))
+ if (condition_j.is_null())
{
return nullptr;
}
- else if (!json_is_object(condition_j))
+ else if (!condition_j.is_object())
{
msg_format("Invalid 'condition' property");
return nullptr;
@@ -983,7 +1008,7 @@ bool NotCondition::is_match(object_type *o_ptr) const
return !m_subcondition->is_match(o_ptr);
}
-std::shared_ptr<Condition> NotCondition::from_json(json_t *j)
+std::shared_ptr<Condition> NotCondition::from_json(jsoncons::json const &j)
{
return std::make_shared<NotCondition>(parse_single_subcondition(j));
}
@@ -1016,7 +1041,7 @@ bool InventoryCondition::is_match(object_type *) const
return false;
}
-std::shared_ptr<Condition> InventoryCondition::from_json(json_t *j)
+std::shared_ptr<Condition> InventoryCondition::from_json(jsoncons::json const &j)
{
return std::make_shared<InventoryCondition>(
parse_single_subcondition(j));
@@ -1052,7 +1077,7 @@ bool EquipmentCondition::is_match(object_type *) const
return false;
}
-std::shared_ptr<Condition> EquipmentCondition::from_json(json_t *j)
+std::shared_ptr<Condition> EquipmentCondition::from_json(jsoncons::json const &j)
{
return std::make_shared<EquipmentCondition>(
parse_single_subcondition(j));
diff --git a/src/squelch/rule.cc b/src/squelch/rule.cc
index 223cf6d3..50a771ae 100644
--- a/src/squelch/rule.cc
+++ b/src/squelch/rule.cc
@@ -41,22 +41,16 @@ std::shared_ptr<Condition> Rule::get_condition() const
return m_condition;
}
-json_t *Rule::to_json() const
+jsoncons::json Rule::to_json() const
{
- json_t *rule_json = json_object();
- json_object_set_new(rule_json,
- "name",
- json_string(m_name.c_str()));
- json_object_set_new(rule_json,
- "action",
- json_string(action_mapping().stringify(m_action)));
- json_object_set_new(rule_json,
- "module",
- json_string(modules[m_module_idx].meta.name));
- json_object_set_new(rule_json,
- "condition",
- Condition::optional_to_json(m_condition));
- return rule_json;
+ jsoncons::json j;
+
+ j["name"] = jsoncons::json::string_type(m_name);
+ j["action"] = action_mapping().stringify(m_action);
+ j["module"] = modules[m_module_idx].meta.name;
+ j["condition"] = Condition::optional_to_json(m_condition);
+
+ return j;
}
void Rule::add_new_condition(Cursor *cursor,
@@ -138,23 +132,19 @@ bool Rule::apply_rule(object_type *o_ptr, int item_idx) const
return false;
}
-std::shared_ptr<Rule> Rule::parse_rule(json_t *rule_json)
+std::shared_ptr<Rule> Rule::parse_rule(jsoncons::json const &rule_json)
{
- if (!json_is_object(rule_json))
+ if (!rule_json.is_object())
{
msg_print("Rule is not an object");
return nullptr;
}
// Retrieve the attributes
- char *rule_name_s = nullptr;
- char *rule_action_s = nullptr;
- char *rule_module_s = nullptr;
- if (json_unpack(rule_json,
- "{s:s,s:s,s:s}",
- "name", &rule_name_s,
- "action", &rule_action_s,
- "module", &rule_module_s) < 0)
+ char const *rule_name_s = rule_json.get("name").as<char const *>();
+ char const *rule_action_s = rule_json.get("action").as<char const *>();
+ char const *rule_module_s = rule_json.get("module").as<char const *>();
+ if ((!rule_name_s) || (!rule_action_s) || (!rule_module_s))
{
msg_print("Rule missing required field(s)");
return nullptr;
@@ -178,28 +168,29 @@ std::shared_ptr<Rule> Rule::parse_rule(json_t *rule_json)
// Parse condition
std::shared_ptr<Condition> condition =
- Condition::parse_condition(json_object_get(rule_json, "condition"));
+ Condition::parse_condition(rule_json.get("condition"));
// Parse rule
switch (action)
{
case action_type::AUTO_INSCRIBE:
{
- json_t *rule_inscription_j = json_object_get(rule_json, "inscription");
+ auto rule_inscription_j = rule_json.get("inscription");
- if (rule_inscription_j == nullptr)
+ if (rule_inscription_j.is_null())
{
msg_print("Inscription rule missing 'inscription' attribute");
return nullptr;
}
- if (!json_is_string(rule_inscription_j))
+
+ if (!rule_inscription_j.is_string())
{
msg_print("Inscription rule 'inscription' attribute wrong type");
return nullptr;
}
- std::string inscription =
- json_string_value(rule_inscription_j);
+ std::string inscription = rule_inscription_j.as<std::string>();
+
return std::make_shared<InscribeRule>(
rule_name_s, module_idx, condition, inscription);
}
@@ -290,14 +281,10 @@ bool PickUpRule::do_apply_rule(object_type *o_ptr, int item_idx) const
return true;
}
-json_t *InscribeRule::to_json() const
+jsoncons::json InscribeRule::to_json() const
{
- json_t *j = Rule::to_json();
-
- json_object_set_new(j,
- "inscription",
- json_string(m_inscription.c_str()));
-
+ jsoncons::json j;
+ j["inscription"] = m_inscription;
return j;
}
diff --git a/src/squeltch.cc b/src/squeltch.cc
index 69c25dfd..eed3bf1b 100644
--- a/src/squeltch.cc
+++ b/src/squeltch.cc
@@ -30,11 +30,10 @@
#include "variable.h"
#include "variable.hpp"
-#include <jansson.h>
#include <algorithm>
-#include <memory>
#include <deque>
#include <list>
+#include <memory>
#include <string>
#include <vector>
@@ -182,14 +181,28 @@ static void automatizer_save_rules()
return;
}
+ // Function for showing a message
+ auto show_message = [hgt, wid](std::string text) {
+ auto n = std::max<std::size_t>(text.size(), 28);
+ while (text.size() < n)
+ {
+ text += ' ';
+ }
+ c_put_str(TERM_WHITE, text.c_str(), hgt/2, wid/2 - 14);
+ };
+
+ // Function for showing an error message
+ auto error = [show_message]() {
+ show_message("Saving rules FAILED!");
+ inkey();
+ };
+
// Build the filename
path_build(buf, 1024, ANGBAND_DIR_USER, name);
if (file_exist(buf))
{
- c_put_str(TERM_WHITE, "File exists, continue?[y/n]",
- hgt / 2,
- wid / 2 - 14);
+ show_message("File exists, continue? [y/n]");
ch = inkey();
if ((ch != 'Y') && (ch != 'y'))
{
@@ -197,29 +210,32 @@ static void automatizer_save_rules()
}
}
- // Write to file
- {
- auto rules_json = automatizer->to_json();
+ // Pretty-printing options
+ jsoncons::output_format format;
+ format.indent(2);
- int status = json_dump_file(rules_json.get(), buf,
- JSON_INDENT(2) |
- JSON_SORT_KEYS);
- if (status == 0)
- {
- c_put_str(TERM_WHITE, "Saved rules in file ",
- hgt / 2,
- wid / 2 - 14);
- }
- else
- {
- c_put_str(TERM_WHITE, "Saving rules failed! ",
- hgt / 2,
- wid / 2 - 14);
- }
+ // Convert to a JSON document
+ auto rules_document = automatizer->to_json();
- // Wait for keypress
- inkey();
+ // Open output stream
+ std::ofstream of(buf, std::ios_base::out | std::ios_base::binary);
+ if (of.fail())
+ {
+ error();
+ return;
}
+
+ // Write JSON to output
+ of << jsoncons::pretty_print(rules_document, format);
+ if (of.fail())
+ {
+ error();
+ return;
+ }
+
+ // Success
+ show_message("Saved rules in file");
+ inkey();
}
static void rename_rule(Rule *rule)
@@ -574,20 +590,21 @@ bool automatizer_load(boost::filesystem::path const &path)
return false; // Not fatal; just skip
}
- // Parse file
- json_error_t error;
- std::shared_ptr<json_t> rules_json(
- json_load_file(path.c_str(), 0, &error),
- &json_decref);
- if (rules_json == nullptr)
+ // Parse into memory
+ jsoncons::json rules_json;
+ try
+ {
+ rules_json = jsoncons::json::parse_file(path.string());
+ }
+ catch (jsoncons::json_exception const &exc)
{
msg_format("Error parsing automatizer rules from '%s'.", path.c_str());
- msg_format("Line %d, Column %d", error.line, error.column);
- msg_print(nullptr);
+ msg_print(exc.what());
return false;
}
- // Load rules
- automatizer->load_json(rules_json.get());
+ // We didn't return directly via an exception, so let's extract
+ // the rules.
+ automatizer->load_json(rules_json);
return true;
}