mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Remove the always questionable Scheme generation and parsing code.
It's more reasonable to do that in Scheme than in C++.
This commit is contained in:
parent
a487ca3f98
commit
bed44f404f
@ -220,8 +220,6 @@ public:
|
||||
}
|
||||
void reset_default_value() { m_value = m_default_value; }
|
||||
bool is_changed() const noexcept { return m_value != m_default_value; }
|
||||
std::ostream& to_scheme(std::ostream&) const;
|
||||
std::istream& from_scheme(std::istream&);
|
||||
GncOptionUIType get_ui_type() const noexcept { return m_ui_type; }
|
||||
void make_internal() { m_ui_type = GncOptionUIType::INTERNAL; }
|
||||
private:
|
||||
@ -353,85 +351,6 @@ operator>> <GncOptionValue<bool>>(std::istream& iss,
|
||||
opt.set_value(instr == "#t" ? true : false);
|
||||
return iss;
|
||||
}
|
||||
template<class OptType,
|
||||
typename std::enable_if_t<std::is_same_v<std::decay_t<OptType>,
|
||||
GncOptionValidatedValue<const QofInstance*>> ||
|
||||
std::is_same_v<std::decay_t<OptType>,
|
||||
GncOptionValue<const QofInstance*>>,
|
||||
int> = 0>
|
||||
inline std::ostream&
|
||||
gnc_option_to_scheme (std::ostream& oss, const OptType& opt)
|
||||
{
|
||||
auto value = opt.get_value();
|
||||
auto type = opt.get_ui_type();
|
||||
if (type == GncOptionUIType::COMMODITY || type == GncOptionUIType::CURRENCY)
|
||||
{
|
||||
if (type == GncOptionUIType::COMMODITY)
|
||||
{
|
||||
oss << commodity_scm_intro;
|
||||
oss << "\"" <<
|
||||
gnc_commodity_get_namespace(GNC_COMMODITY(value)) << "\" ";
|
||||
}
|
||||
|
||||
oss << "\"" << gnc_commodity_get_mnemonic(GNC_COMMODITY(value)) << "\"";
|
||||
|
||||
if (type == GncOptionUIType::COMMODITY)
|
||||
{
|
||||
oss << ")";
|
||||
}
|
||||
return oss;
|
||||
}
|
||||
|
||||
if constexpr (std::is_same_v<std::decay_t<decltype(value)>, std::string>)
|
||||
{
|
||||
if (type == GncOptionUIType::COLOR)
|
||||
return output_color_value(oss, value);
|
||||
}
|
||||
|
||||
oss << "\"" << qof_instance_to_string(value) << "\"";
|
||||
return oss;
|
||||
}
|
||||
|
||||
template<class OptType,
|
||||
typename std::enable_if_t<
|
||||
std::is_same_v<std::decay_t<OptType>,
|
||||
GncOptionValidatedValue<const QofInstance*>> ||
|
||||
std::is_same_v<std::decay_t<OptType>,
|
||||
GncOptionValue<const QofInstance*>>, int> = 0>
|
||||
inline std::istream&
|
||||
gnc_option_from_scheme (std::istream& iss, OptType& opt)
|
||||
{
|
||||
std::string instr;
|
||||
auto type = opt.get_ui_type();
|
||||
if (type == GncOptionUIType::COMMODITY || type == GncOptionUIType::CURRENCY)
|
||||
{
|
||||
std::string name_space, mnemonic;
|
||||
if (type == GncOptionUIType::COMMODITY)
|
||||
{
|
||||
iss.ignore(strlen(commodity_scm_intro) + 1, '"');
|
||||
std::getline(iss, name_space, '"');
|
||||
}
|
||||
else
|
||||
name_space = GNC_COMMODITY_NS_CURRENCY;
|
||||
iss.ignore(2, '"');
|
||||
std::getline(iss, mnemonic, '"');
|
||||
|
||||
if (type == GncOptionUIType::COMMODITY)
|
||||
iss.ignore(2, ')');
|
||||
else
|
||||
iss.ignore(1, '"');
|
||||
|
||||
instr = name_space + ":";
|
||||
instr += mnemonic;
|
||||
}
|
||||
else
|
||||
{
|
||||
iss.ignore(1, '"');
|
||||
std::getline(iss, instr, '"');
|
||||
}
|
||||
opt.set_value(qof_instance_from_string(instr, opt.get_ui_type()));
|
||||
return iss;
|
||||
}
|
||||
#endif // SWIG
|
||||
|
||||
/**
|
||||
@ -807,70 +726,6 @@ operator>> <GncOptionMultichoiceValue>(std::istream& iss,
|
||||
return iss;
|
||||
}
|
||||
|
||||
template<class OptType,
|
||||
typename std::enable_if_t<std::is_same_v<std::decay_t<OptType>,
|
||||
GncOptionMultichoiceValue>,
|
||||
int> = 0>
|
||||
inline std::ostream&
|
||||
gnc_option_to_scheme(std::ostream& oss, const OptType& opt)
|
||||
{
|
||||
auto indexes{opt.get_multiple()};
|
||||
if (indexes.size() > 1)
|
||||
oss << "'(";
|
||||
bool first = true;
|
||||
for (auto index : indexes)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
oss << " ";
|
||||
oss << "'" << opt.permissible_value(index);
|
||||
}
|
||||
if (indexes.size() > 1)
|
||||
oss << ')';
|
||||
return oss;
|
||||
}
|
||||
|
||||
template<class OptType,
|
||||
typename std::enable_if_t<std::is_same_v<std::decay_t<OptType>,
|
||||
GncOptionMultichoiceValue>,
|
||||
int> = 0>
|
||||
inline std::istream&
|
||||
gnc_option_from_scheme(std::istream& iss, OptType& opt)
|
||||
{
|
||||
iss.ignore(3, '\'');
|
||||
auto c{iss.peek()};
|
||||
if (static_cast<char>(c) == '(')
|
||||
{
|
||||
GncMultichoiceOptionIndexVec values;
|
||||
iss.ignore(3, '\'');
|
||||
while (true)
|
||||
{
|
||||
std::string str;
|
||||
std::getline(iss, str, ' ');
|
||||
if (!str.empty())
|
||||
{
|
||||
if (str.back() == ')')
|
||||
{
|
||||
str.pop_back();
|
||||
break;
|
||||
}
|
||||
values.push_back(opt.permissible_value_index(str.c_str()));
|
||||
iss.ignore(2, '\'');
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
opt.set_multiple(values);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string str;
|
||||
std::getline(iss, str, ' ');
|
||||
opt.set_value(str);
|
||||
}
|
||||
return iss;
|
||||
}
|
||||
|
||||
using GncOptionAccountList = std::vector<const Account*>;
|
||||
|
||||
@ -998,54 +853,6 @@ operator>> <GncOptionAccountListValue>(std::istream& iss,
|
||||
return iss;
|
||||
}
|
||||
|
||||
template<class OptType,
|
||||
typename std::enable_if_t<std::is_same_v<std::decay_t<OptType>,
|
||||
GncOptionAccountListValue>,
|
||||
int> = 0>
|
||||
inline std::ostream&
|
||||
gnc_option_to_scheme(std::ostream& oss, const OptType& opt)
|
||||
{
|
||||
auto values{opt.get_value()};
|
||||
oss << "'(\"";
|
||||
bool first = true;
|
||||
for (auto value : values)
|
||||
{
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
oss << " \"";
|
||||
oss << qof_instance_to_string(QOF_INSTANCE(value)) << '"';
|
||||
}
|
||||
oss << ')';
|
||||
return oss;
|
||||
}
|
||||
|
||||
template<class OptType,
|
||||
typename std::enable_if_t<std::is_same_v<std::decay_t<OptType>,
|
||||
GncOptionAccountListValue>,
|
||||
int> = 0>
|
||||
inline std::istream&
|
||||
gnc_option_from_scheme(std::istream& iss, OptType& opt)
|
||||
{
|
||||
GncOptionAccountList values;
|
||||
iss.ignore(3, '"');
|
||||
while (true)
|
||||
{
|
||||
std::string str;
|
||||
std::getline(iss, str, '"');
|
||||
if (!str.empty())
|
||||
{
|
||||
values.emplace_back((Account*)qof_instance_from_string(str, opt.get_ui_type()));
|
||||
iss.ignore(2, '"');
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
opt.set_value(values);
|
||||
iss.ignore(1, ')');
|
||||
return iss;
|
||||
}
|
||||
|
||||
class GncOptionAccountSelValue : public OptionClassifier
|
||||
{
|
||||
public:
|
||||
@ -1129,46 +936,6 @@ operator>> <GncOptionAccountSelValue>(std::istream& iss,
|
||||
return iss;
|
||||
}
|
||||
|
||||
template<class OptType,
|
||||
typename std::enable_if_t<std::is_same_v<std::decay_t<OptType>,
|
||||
GncOptionAccountSelValue>,
|
||||
int> = 0>
|
||||
inline std::ostream&
|
||||
gnc_option_to_scheme(std::ostream& oss, const OptType& opt)
|
||||
{
|
||||
auto value{opt.get_value()};
|
||||
oss << "'(\"";
|
||||
oss << qof_instance_to_string(QOF_INSTANCE(value)) << '"';
|
||||
oss << ')';
|
||||
return oss;
|
||||
}
|
||||
|
||||
template<class OptType,
|
||||
typename std::enable_if_t<std::is_same_v<std::decay_t<OptType>,
|
||||
GncOptionAccountSelValue>,
|
||||
int> = 0>
|
||||
inline std::istream&
|
||||
gnc_option_from_scheme(std::istream& iss, OptType& opt)
|
||||
{
|
||||
const Account* value;
|
||||
iss.ignore(3, '"');
|
||||
while (true)
|
||||
{
|
||||
std::string str;
|
||||
std::getline(iss, str, '"');
|
||||
if (!str.empty())
|
||||
{
|
||||
value = (Account*)qof_instance_from_string(str, opt.get_ui_type());
|
||||
iss.ignore(2, '"');
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
opt.set_value(value);
|
||||
iss.ignore(1, ')');
|
||||
return iss;
|
||||
}
|
||||
|
||||
/** Date options
|
||||
* A legal date value is a pair of either and a RelativeDatePeriod, the absolute
|
||||
* flag and a time64, or for legacy purposes the absolute flag and a timespec.
|
||||
@ -1312,45 +1079,4 @@ operator>> <GncOptionDateValue>(std::istream& iss,
|
||||
/** QofQuery Options
|
||||
*/
|
||||
|
||||
inline std::istream&
|
||||
gnc_option_from_scheme(std::istream& iss, GncOptionValue<const GncOwner*>& opt)
|
||||
{
|
||||
//FIXME: Implement or maybe rethink.
|
||||
return iss;
|
||||
}
|
||||
|
||||
inline std::ostream&
|
||||
gnc_option_to_scheme(std::ostream& oss, GncOptionValue<const GncOwner*>& opt)
|
||||
{
|
||||
//FIXME: Implement or maybe rethink.
|
||||
return oss;
|
||||
}
|
||||
|
||||
inline std::istream&
|
||||
gnc_option_from_scheme(std::istream& iss, GncOptionValue<const QofQuery*>& opt)
|
||||
{
|
||||
//FIXME: Implement or maybe rethink.
|
||||
return iss;
|
||||
}
|
||||
|
||||
inline std::ostream&
|
||||
gnc_option_to_scheme(std::ostream& oss, GncOptionValue<const QofQuery*>& opt)
|
||||
{
|
||||
//FIXME: Implement or maybe rethink.
|
||||
return oss;
|
||||
}
|
||||
|
||||
inline std::istream&
|
||||
gnc_option_from_scheme(std::istream& iss, GncOptionValidatedValue<const QofQuery*>& opt)
|
||||
{
|
||||
//FIXME: Implement or maybe rethink.
|
||||
return iss;
|
||||
}
|
||||
|
||||
inline std::ostream&
|
||||
gnc_option_to_scheme(std::ostream& oss, GncOptionValidatedValue<const QofQuery*>& opt)
|
||||
{
|
||||
//FIXME: Implement or maybe rethink.
|
||||
return oss;
|
||||
}
|
||||
#endif //GNC_OPTION_IMPL_HPP_
|
||||
|
@ -52,28 +52,28 @@ GncOption::get_value() const
|
||||
[](const auto option)->ValueType {
|
||||
if constexpr (is_same_decayed_v<decltype(option.get_value()),
|
||||
ValueType>)
|
||||
return option.get_value();
|
||||
return option.get_value();
|
||||
if constexpr (is_same_decayed_v<decltype(option),
|
||||
GncOptionDateValue>)
|
||||
{
|
||||
if constexpr (is_same_decayed_v<ValueType,
|
||||
RelativeDatePeriod>)
|
||||
return option.get_period();
|
||||
RelativeDatePeriod>)
|
||||
return option.get_period();
|
||||
if constexpr (std::is_same_v<ValueType, size_t>)
|
||||
return option.get_period_index();
|
||||
return option.get_period_index();
|
||||
return ValueType{};
|
||||
}
|
||||
if constexpr (is_same_decayed_v<decltype(option),
|
||||
GncOptionMultichoiceValue>)
|
||||
{
|
||||
if constexpr (std::is_same_v<ValueType, size_t>)
|
||||
return option.get_index();
|
||||
return option.get_index();
|
||||
if constexpr (is_same_decayed_v<ValueType,
|
||||
GncMultichoiceOptionIndexVec>)
|
||||
return option.get_multiple();
|
||||
GncMultichoiceOptionIndexVec>)
|
||||
return option.get_multiple();
|
||||
}
|
||||
return ValueType {};
|
||||
}, *m_option);
|
||||
return ValueType {};
|
||||
}, *m_option);
|
||||
}
|
||||
|
||||
template <typename ValueType> ValueType
|
||||
@ -83,25 +83,25 @@ GncOption::get_default_value() const
|
||||
[](const auto option)->ValueType {
|
||||
if constexpr (is_same_decayed_v<decltype(option.get_value()),
|
||||
ValueType>)
|
||||
return option.get_default_value();
|
||||
return option.get_default_value();
|
||||
if constexpr (is_same_decayed_v<decltype(option),
|
||||
GncOptionDateValue>)
|
||||
{
|
||||
if constexpr (is_same_decayed_v<ValueType,
|
||||
RelativeDatePeriod>)
|
||||
return option.get_default_period();
|
||||
RelativeDatePeriod>)
|
||||
return option.get_default_period();
|
||||
if constexpr (std::is_same_v<ValueType, size_t>)
|
||||
return option.get_default_period_index();
|
||||
return option.get_default_period_index();
|
||||
return ValueType{};
|
||||
}
|
||||
if constexpr
|
||||
if constexpr
|
||||
(is_same_decayed_v<decltype(option),
|
||||
GncOptionMultichoiceValue> &&
|
||||
GncOptionMultichoiceValue> &&
|
||||
is_same_decayed_v<ValueType,
|
||||
GncMultichoiceOptionIndexVec>)
|
||||
return option.get_default_multiple();
|
||||
return ValueType {};
|
||||
}, *m_option);
|
||||
GncMultichoiceOptionIndexVec>)
|
||||
return option.get_default_multiple();
|
||||
return ValueType {};
|
||||
}, *m_option);
|
||||
|
||||
}
|
||||
|
||||
@ -110,26 +110,26 @@ GncOption::set_value(ValueType value)
|
||||
{
|
||||
std::visit(
|
||||
[value](auto& option) {
|
||||
if constexpr
|
||||
if constexpr
|
||||
(is_same_decayed_v<decltype(option.get_value()), ValueType> ||
|
||||
(is_same_decayed_v<decltype(option),
|
||||
GncOptionDateValue> &&
|
||||
GncOptionDateValue> &&
|
||||
(is_same_decayed_v<ValueType, RelativeDatePeriod> ||
|
||||
std::is_same_v<ValueType, size_t>)))
|
||||
option.set_value(value);
|
||||
option.set_value(value);
|
||||
if constexpr (is_same_decayed_v<decltype(option),
|
||||
GncOptionMultichoiceValue>)
|
||||
{
|
||||
GncOptionMultichoiceValue>)
|
||||
{
|
||||
if constexpr (is_same_decayed_v<ValueType,
|
||||
GncMultichoiceOptionIndexVec>)
|
||||
option.set_multiple(value);
|
||||
else if constexpr
|
||||
(std::is_same_v<ValueType, size_t> ||
|
||||
GncMultichoiceOptionIndexVec>)
|
||||
option.set_multiple(value);
|
||||
else if constexpr
|
||||
(std::is_same_v<ValueType, size_t> ||
|
||||
is_same_decayed_v<ValueType, std::string> ||
|
||||
std::is_same_v<std::remove_cv<ValueType>, char*>)
|
||||
option.set_value(value);
|
||||
}
|
||||
}, *m_option);
|
||||
std::is_same_v<std::remove_cv<ValueType>, char*>)
|
||||
option.set_value(value);
|
||||
}
|
||||
}, *m_option);
|
||||
}
|
||||
|
||||
template <typename ValueType> void
|
||||
@ -137,25 +137,25 @@ GncOption::set_default_value(ValueType value)
|
||||
{
|
||||
std::visit(
|
||||
[value](auto& option) {
|
||||
if constexpr
|
||||
if constexpr
|
||||
(is_same_decayed_v<decltype(option.get_value()), ValueType>||
|
||||
(is_same_decayed_v<decltype(option), GncOptionDateValue> &&
|
||||
(is_same_decayed_v<ValueType, RelativeDatePeriod> ||
|
||||
std::is_same_v<ValueType, size_t>)))
|
||||
option.set_default_value(value);
|
||||
option.set_default_value(value);
|
||||
if constexpr (is_same_decayed_v<decltype(option),
|
||||
GncOptionMultichoiceValue>)
|
||||
{
|
||||
GncOptionMultichoiceValue>)
|
||||
{
|
||||
if constexpr (is_same_decayed_v<ValueType,
|
||||
GncMultichoiceOptionIndexVec>)
|
||||
GncMultichoiceOptionIndexVec>)
|
||||
option.set_default_multiple(value);
|
||||
else if constexpr
|
||||
(std::is_same_v<ValueType, size_t> ||
|
||||
else if constexpr
|
||||
(std::is_same_v<ValueType, size_t> ||
|
||||
is_same_decayed_v<ValueType, std::string> ||
|
||||
std::is_same_v<std::remove_cv<ValueType>, char*>)
|
||||
option.set_default_value(value);
|
||||
}
|
||||
}, *m_option);
|
||||
std::is_same_v<std::remove_cv<ValueType>, char*>)
|
||||
option.set_default_value(value);
|
||||
}
|
||||
}, *m_option);
|
||||
}
|
||||
void
|
||||
GncOption::reset_default_value()
|
||||
@ -289,11 +289,11 @@ GncOption::is_multiselect() const noexcept
|
||||
return std::visit(
|
||||
[](const auto& option)->bool {
|
||||
if constexpr (is_same_decayed_v<decltype(option),
|
||||
GncOptionAccountListValue>)
|
||||
return option.is_multiselect();
|
||||
else
|
||||
return false;
|
||||
}, *m_option);
|
||||
GncOptionAccountListValue>)
|
||||
return option.is_multiselect();
|
||||
else
|
||||
return false;
|
||||
}, *m_option);
|
||||
}
|
||||
|
||||
template<typename ValueType> bool
|
||||
@ -302,19 +302,19 @@ GncOption::validate(ValueType value) const
|
||||
return std::visit(
|
||||
[value] (const auto& option) -> bool {
|
||||
if constexpr ((is_same_decayed_v<decltype(option),
|
||||
GncOptionMultichoiceValue> &&
|
||||
GncOptionMultichoiceValue> &&
|
||||
is_same_decayed_v<ValueType,
|
||||
std::string>) ||
|
||||
std::string>) ||
|
||||
(is_same_decayed_v<decltype(option),
|
||||
GncOptionMultichoiceValue> &&
|
||||
GncOptionMultichoiceValue> &&
|
||||
is_same_decayed_v<ValueType,
|
||||
GncMultichoiceOptionIndexVec>) ||
|
||||
GncMultichoiceOptionIndexVec>) ||
|
||||
is_same_decayed_v<decltype(option),
|
||||
GncOptionValidatedValue<ValueType>>)
|
||||
return option.validate(value);
|
||||
else
|
||||
return false;
|
||||
}, *m_option);
|
||||
GncOptionValidatedValue<ValueType>>)
|
||||
return option.validate(value);
|
||||
else
|
||||
return false;
|
||||
}, *m_option);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
@ -323,13 +323,13 @@ GncOption::num_permissible_values() const
|
||||
return std::visit(
|
||||
[] (const auto& option) -> size_t {
|
||||
if constexpr (is_same_decayed_v<decltype(option),
|
||||
GncOptionMultichoiceValue> ||
|
||||
GncOptionMultichoiceValue> ||
|
||||
is_same_decayed_v<decltype(option),
|
||||
GncOptionDateValue>)
|
||||
return option.num_permissible_values();
|
||||
else
|
||||
return size_t_max;
|
||||
}, *m_option);
|
||||
GncOptionDateValue>)
|
||||
return option.num_permissible_values();
|
||||
else
|
||||
return size_t_max;
|
||||
}, *m_option);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
@ -338,13 +338,13 @@ GncOption::permissible_value_index(const char* value) const
|
||||
return std::visit(
|
||||
[&value] (const auto& option) -> size_t {
|
||||
if constexpr (is_same_decayed_v<decltype(option),
|
||||
GncOptionMultichoiceValue> ||
|
||||
GncOptionMultichoiceValue> ||
|
||||
is_same_decayed_v<decltype(option),
|
||||
GncOptionDateValue>)
|
||||
return option.permissible_value_index(value);
|
||||
else
|
||||
return size_t_max;;
|
||||
}, *m_option);
|
||||
GncOptionDateValue>)
|
||||
return option.permissible_value_index(value);
|
||||
else
|
||||
return size_t_max;;
|
||||
}, *m_option);
|
||||
}
|
||||
|
||||
const char*
|
||||
@ -424,125 +424,6 @@ GncOption::in_stream(std::istream& iss)
|
||||
}, *m_option);
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
GncOption::to_scheme(std::ostream& oss) const
|
||||
{
|
||||
return std::visit([&oss](auto& option) ->std::ostream& {
|
||||
if constexpr
|
||||
((std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionAccountListValue>) ||
|
||||
(std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionMultichoiceValue>) ||
|
||||
std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionValue<const QofInstance*>> ||
|
||||
std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionValidatedValue<const QofInstance*>>)
|
||||
gnc_option_to_scheme(oss, option);
|
||||
else if constexpr
|
||||
(std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionDateValue>)
|
||||
oss << "'(" << option << ")";
|
||||
else if constexpr
|
||||
(std::is_same_v<std::decay_t<decltype(option.get_value())>,
|
||||
std::string>)
|
||||
{
|
||||
if (option.get_ui_type() == GncOptionUIType::COLOR)
|
||||
output_color_value(oss, option.get_value());
|
||||
else
|
||||
oss << '"' << option << '"';
|
||||
}
|
||||
else if constexpr
|
||||
(std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionRangeValue<int>> ||
|
||||
std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionRangeValue<double>>)
|
||||
{
|
||||
if (option.get_ui_type() == GncOptionUIType::PLOT_SIZE)
|
||||
oss << "'(" << (option.is_alternate() ?
|
||||
"\"percent\" . " : "\"pixels\" . ");
|
||||
oss << option.get_value();
|
||||
if (option.get_ui_type() == GncOptionUIType::PLOT_SIZE)
|
||||
oss << ")";
|
||||
}
|
||||
else
|
||||
oss << option;
|
||||
return oss;
|
||||
}, *m_option);
|
||||
}
|
||||
|
||||
std::istream&
|
||||
GncOption::from_scheme(std::istream& iss)
|
||||
{
|
||||
return std::visit([&iss](auto& option) -> std::istream& {
|
||||
if constexpr
|
||||
((std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionAccountListValue>) ||
|
||||
(std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionMultichoiceValue>) ||
|
||||
std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionValue<const GncOwner*>> ||
|
||||
std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionValue<const QofQuery*>> ||
|
||||
std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionValue<const QofInstance*>> ||
|
||||
std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionValidatedValue<const QofQuery*>> ||
|
||||
std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionValidatedValue<const QofInstance*>>)
|
||||
gnc_option_from_scheme(iss, option);
|
||||
else if constexpr
|
||||
(std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionDateValue>)
|
||||
{
|
||||
iss.ignore(2, '(');
|
||||
iss >> option;
|
||||
//operator >> clears the trailing ')'
|
||||
}
|
||||
else if constexpr
|
||||
(std::is_same_v<std::decay_t<decltype(option.get_value())>,
|
||||
std::string>)
|
||||
{
|
||||
iss.ignore(1, '"');
|
||||
std::string input;
|
||||
std::getline(iss, input, '"');
|
||||
option.set_value(input);
|
||||
}
|
||||
else if constexpr
|
||||
(std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionRangeValue<int>> ||
|
||||
std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionRangeValue<double>>)
|
||||
{
|
||||
if (option.get_ui_type() == GncOptionUIType::PLOT_SIZE)
|
||||
{
|
||||
iss.ignore(3, '"');
|
||||
std::string alt;
|
||||
iss >> alt;
|
||||
option.set_alternate(
|
||||
strncmp(alt.c_str(), "pixels",
|
||||
strlen("pixels")) == 0);
|
||||
iss.ignore(4, ' ');
|
||||
}
|
||||
if constexpr(std::is_same_v<std::decay_t<decltype(option)>,
|
||||
GncOptionRangeValue<int>>)
|
||||
{
|
||||
int val;
|
||||
iss >> val;
|
||||
option.set_value(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
double val;
|
||||
iss >> val;
|
||||
option.set_value(val);
|
||||
}
|
||||
}
|
||||
else
|
||||
iss >> option;
|
||||
return iss;
|
||||
}, *m_option);
|
||||
}
|
||||
|
||||
GncOption*
|
||||
gnc_make_SCM_option(const char* section, const char* name,
|
||||
const char* key, const char* doc_string,
|
||||
|
@ -157,9 +157,6 @@ public:
|
||||
void set_alternate(bool) noexcept;
|
||||
std::ostream& out_stream(std::ostream& oss) const;
|
||||
std::istream& in_stream(std::istream& iss);
|
||||
std::ostream& to_scheme(std::ostream& oss) const;
|
||||
std::istream& from_scheme(std::istream& iss);
|
||||
|
||||
|
||||
friend GncOptionVariant& swig_get_option(GncOption*);
|
||||
|
||||
|
@ -148,18 +148,10 @@ public:
|
||||
return const_cast<GncOption*>(static_cast<const GncOptionDB&>(*this).find_option(section, name));
|
||||
}
|
||||
const GncOption* find_option(const std::string& section, const char* name) const;
|
||||
std::ostream& save_to_scheme(std::ostream& oss,
|
||||
const char* options_prolog) const noexcept;
|
||||
std::istream& load_from_scheme(std::istream& iss) noexcept;
|
||||
std::ostream& save_to_key_value(std::ostream& oss) const noexcept;
|
||||
std::istream& load_from_key_value(std::istream& iss);
|
||||
void save_to_kvp(QofBook* book, bool clear_book) const noexcept;
|
||||
void load_from_kvp(QofBook* book) noexcept;
|
||||
std::ostream& save_option_scheme(std::ostream& oss,
|
||||
const char* option_prolog,
|
||||
const std::string& section,
|
||||
const std::string& name) const noexcept;
|
||||
std::istream& load_option_scheme(std::istream& iss);
|
||||
std::ostream& save_option_key_value(std::ostream& oss,
|
||||
const std::string& section,
|
||||
const std::string& name) const noexcept;
|
||||
@ -175,14 +167,6 @@ private:
|
||||
|
||||
std::function<GncOptionUIItem*()> m_get_ui_value;
|
||||
std::function<void(GncOptionUIItem*)> m_set_ui_value;
|
||||
static constexpr char const* const scheme_tags[]
|
||||
{
|
||||
"(let ((option (gnc:lookup-option ",
|
||||
" ",
|
||||
")))",
|
||||
" ((lambda (o) (if o (gnc:option-set-value o ",
|
||||
"))) option))"
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
@ -261,26 +261,6 @@ GncOptionDB::make_internal(const char* section, const char* name)
|
||||
db_opt->make_internal();
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
GncOptionDB::save_option_scheme(std::ostream& oss,
|
||||
const char* option_prolog,
|
||||
const std::string& section,
|
||||
const std::string& name) const noexcept
|
||||
{
|
||||
auto db_opt = find_option(section, name.c_str());
|
||||
|
||||
if (!db_opt || !db_opt->is_changed())
|
||||
return oss;
|
||||
oss << scheme_tags[0] << option_prolog << "\n";
|
||||
oss << scheme_tags[1] << '"' << section.substr(0, classifier_size_max) << "\"\n";
|
||||
oss << scheme_tags[1] << '"' << name.substr(0, classifier_size_max) << '"';
|
||||
oss << scheme_tags[2] << "\n" << scheme_tags[3];
|
||||
db_opt->to_scheme(oss);
|
||||
oss << scheme_tags[4] << "\n\n";
|
||||
|
||||
return oss;
|
||||
}
|
||||
|
||||
static inline bool constexpr
|
||||
is_eol(char c)
|
||||
{
|
||||
@ -330,273 +310,6 @@ is_delim(char c)
|
||||
is_single_quote(c) || is_double_quote(c) || is_semicolon(c);
|
||||
}
|
||||
|
||||
static std::string
|
||||
scan_scheme_symbol_from_streambuf(std::streambuf* sbuf)
|
||||
{
|
||||
std::string retval;
|
||||
while(sbuf->in_avail() && !is_delim(sbuf->sgetc()))
|
||||
retval += sbuf->sbumpc();
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef _LIBCPP_VERSION
|
||||
static inline void constexpr
|
||||
#else
|
||||
static inline void
|
||||
#endif
|
||||
consume_scheme_comment(std::streambuf* sbuf)
|
||||
{
|
||||
while (sbuf->in_avail() && !is_eol(sbuf->sgetc()))
|
||||
sbuf->sbumpc();
|
||||
}
|
||||
|
||||
static inline std::string
|
||||
scan_scheme_string_from_streambuf(std::streambuf* sbuf)
|
||||
{
|
||||
std::string retval{static_cast<char>(sbuf->sbumpc())};
|
||||
while(sbuf->in_avail() && !is_double_quote(sbuf->sgetc()))
|
||||
retval += sbuf->sbumpc();
|
||||
retval += sbuf->sbumpc(); // Add the closing quote.
|
||||
return retval;
|
||||
}
|
||||
|
||||
#ifdef _LIBCPP_VERSION
|
||||
static inline void constexpr
|
||||
#else
|
||||
static inline void
|
||||
#endif
|
||||
consume_scheme_whitespace(std::streambuf* sbuf)
|
||||
{
|
||||
while (sbuf->in_avail() && is_whitespace(sbuf->sgetc()))
|
||||
sbuf->sbumpc();
|
||||
}
|
||||
|
||||
enum class IdentType
|
||||
{
|
||||
NAME, //no introducing mark
|
||||
CONST, //introduced with single quote
|
||||
STRING, //delimited by double-quotes.
|
||||
LIST, //introduced ' and delimited by parentheses
|
||||
FORM //delimited by parentheses without ' introduction.
|
||||
};
|
||||
|
||||
struct SchemeId
|
||||
{
|
||||
IdentType m_type;
|
||||
std::string m_name;
|
||||
std::vector<SchemeId> m_ids;
|
||||
};
|
||||
|
||||
/**
|
||||
* Scheme Parse Tree
|
||||
* An identifier is a string and a type (name, const, string, or form).
|
||||
*/
|
||||
|
||||
static void scan_scheme_id_from_streambuf(std::streambuf* sbuf, SchemeId& id);
|
||||
|
||||
static void
|
||||
scan_scheme_form_from_streambuf(std::streambuf* sbuf, SchemeId& id)
|
||||
{
|
||||
sbuf->sbumpc();
|
||||
if (!sbuf->in_avail())
|
||||
return;
|
||||
char c = sbuf->sgetc();
|
||||
while (sbuf->in_avail() && !is_end_paren(c))
|
||||
{
|
||||
SchemeId next_id;
|
||||
scan_scheme_id_from_streambuf(sbuf, next_id);
|
||||
if (id.m_name.empty() && next_id.m_type == IdentType::NAME)
|
||||
{
|
||||
id.m_name = std::move(next_id.m_name);
|
||||
continue;
|
||||
}
|
||||
id.m_ids.emplace_back(std::move(next_id));
|
||||
if (!sbuf->in_avail())
|
||||
{
|
||||
std::string err{"End of streambuf before end of form "};
|
||||
err += id.m_name;
|
||||
throw std::runtime_error(err);
|
||||
}
|
||||
c = sbuf->sgetc();
|
||||
}
|
||||
sbuf->sbumpc();
|
||||
}
|
||||
|
||||
static void
|
||||
scan_scheme_list_from_streambuf(std::streambuf* sbuf, std::string& str)
|
||||
{
|
||||
|
||||
consume_scheme_whitespace(sbuf);
|
||||
if (!sbuf->in_avail())
|
||||
return;
|
||||
char c = sbuf->sgetc();
|
||||
while (sbuf->in_avail() && !is_end_paren(c))
|
||||
{
|
||||
str += static_cast<char>(sbuf->sbumpc());
|
||||
if (!sbuf->in_avail())
|
||||
return;
|
||||
c = sbuf->sgetc();
|
||||
}
|
||||
str += static_cast<char>(sbuf->sbumpc());
|
||||
}
|
||||
|
||||
static void
|
||||
scan_scheme_id_from_streambuf(std::streambuf* sbuf, SchemeId& id)
|
||||
{
|
||||
consume_scheme_whitespace(sbuf);
|
||||
if (!sbuf->in_avail())
|
||||
return;
|
||||
auto c{sbuf->sgetc()};
|
||||
switch(c)
|
||||
{
|
||||
case ';':
|
||||
consume_scheme_comment(sbuf);
|
||||
break;
|
||||
case '"':
|
||||
id.m_type = IdentType::STRING;
|
||||
id.m_name = scan_scheme_string_from_streambuf(sbuf);
|
||||
break;
|
||||
case '\'':
|
||||
{
|
||||
std::string value{static_cast<char>(sbuf->sbumpc())};
|
||||
if (sbuf->sgetc() == '(')
|
||||
{
|
||||
id.m_type == IdentType::LIST;
|
||||
scan_scheme_list_from_streambuf(sbuf, value);
|
||||
if (value.back() != ')')
|
||||
throw std::runtime_error("End of streambuf before end of form ");
|
||||
}
|
||||
else if (sbuf->sgetc() == '"')
|
||||
throw std::runtime_error("Malformed scheme particle starts '\"");
|
||||
else
|
||||
{
|
||||
id.m_type = IdentType::CONST;
|
||||
value += scan_scheme_symbol_from_streambuf(sbuf);
|
||||
}
|
||||
id.m_name = std::move(value);
|
||||
break;
|
||||
}
|
||||
case '(':
|
||||
id.m_type = IdentType::FORM;
|
||||
scan_scheme_form_from_streambuf(sbuf, id);
|
||||
break;
|
||||
default:
|
||||
id.m_type = IdentType::NAME;
|
||||
id.m_name = scan_scheme_symbol_from_streambuf(sbuf);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static inline std::string
|
||||
unquote_scheme_string(const std::string& str)
|
||||
{
|
||||
if (str.front() == '"' && str.back() == '"')
|
||||
return str.substr(1, str.size() - 2);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
static std::optional<std::reference_wrapper<const SchemeId>>
|
||||
find_form(const SchemeId& toplevel, IdentType type, const char* name)
|
||||
{
|
||||
if (toplevel.m_type == type && toplevel.m_name == name)
|
||||
return std::ref(toplevel);
|
||||
for (const auto& id : toplevel.m_ids)
|
||||
{
|
||||
if (id.m_type == type && id.m_name == name)
|
||||
return std::ref(id);
|
||||
auto child{find_form(id, type, name)};
|
||||
if (child)
|
||||
return child;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::istream&
|
||||
GncOptionDB::load_option_scheme(std::istream& iss)
|
||||
{
|
||||
auto sbuf{iss.rdbuf()};
|
||||
SchemeId toplevel;
|
||||
std::optional<std::reference_wrapper<const SchemeId>> lookup_id;
|
||||
bool form_found = false;
|
||||
while (sbuf->in_avail() && !lookup_id)
|
||||
{
|
||||
scan_scheme_id_from_streambuf(sbuf, toplevel);
|
||||
lookup_id = find_form(toplevel, IdentType::FORM, "gnc:lookup-option");
|
||||
}
|
||||
|
||||
if (!lookup_id)
|
||||
{
|
||||
iss.setstate(std::ios_base::eofbit);
|
||||
return iss; // No options
|
||||
}
|
||||
const auto& classifier = lookup_id->get().m_ids;
|
||||
if (classifier.size() != 3)
|
||||
throw std::runtime_error("Malformed option classifier.");
|
||||
const auto& section = unquote_scheme_string(classifier[1].m_name);
|
||||
const auto& name = unquote_scheme_string(classifier[2].m_name);
|
||||
auto option = find_option(section, name.c_str());
|
||||
std::string option_str{section};
|
||||
option_str += ':';
|
||||
option_str += name;
|
||||
if (!option)
|
||||
{
|
||||
std::string err{"Option not found: "};
|
||||
err += option_str;
|
||||
throw std::runtime_error(err);
|
||||
}
|
||||
auto value_id = find_form(toplevel, IdentType::FORM, "gnc:option-set-value");
|
||||
if (!(value_id && value_id->get().m_ids.size() == 2))
|
||||
{
|
||||
std::string err{"Option "};
|
||||
err += option_str;
|
||||
throw std::runtime_error(err + " malformed value lambda form.");
|
||||
}
|
||||
std::istringstream value_iss{value_id->get().m_ids[1].m_name};
|
||||
option->from_scheme(value_iss);
|
||||
return iss;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
GncOptionDB::save_to_scheme(std::ostream& oss, const char* options_prolog) const noexcept
|
||||
{
|
||||
foreach_section(
|
||||
[&oss, options_prolog](const GncOptionSectionPtr& section)
|
||||
{
|
||||
oss << "\n; Section: " << section->get_name() << "\n\n";
|
||||
section->foreach_option(
|
||||
[&oss, options_prolog, §ion](auto& option)
|
||||
{
|
||||
if (!option.is_changed())
|
||||
return;
|
||||
oss << scheme_tags[0] << options_prolog << "\n";
|
||||
oss << scheme_tags[1] << '"' << section->get_name().substr(0, classifier_size_max) << "\"\n";
|
||||
oss << scheme_tags[1] << '"' << option.get_name().substr(0, classifier_size_max) << '"';
|
||||
oss << scheme_tags[2] << "\n" << scheme_tags[3];
|
||||
option.to_scheme(oss);
|
||||
oss << scheme_tags[4] << "\n\n";
|
||||
});
|
||||
});
|
||||
return oss;
|
||||
}
|
||||
|
||||
std::istream&
|
||||
GncOptionDB::load_from_scheme(std::istream& iss) noexcept
|
||||
{
|
||||
try {
|
||||
while (iss.good())
|
||||
load_option_scheme(iss);
|
||||
iss.clear(); //unset eofbit and maybe failbit
|
||||
}
|
||||
catch (const std::runtime_error& err)
|
||||
{
|
||||
std::cerr << "Load of options from Scheme failed: " <<
|
||||
err.what() << std::endl;
|
||||
}
|
||||
return iss;
|
||||
}
|
||||
|
||||
std::ostream&
|
||||
GncOptionDB::save_option_key_value(std::ostream& oss,
|
||||
const std::string& section,
|
||||
|
@ -584,18 +584,10 @@ wrap_unique_ptr(GncOptionDBPtr, GncOptionDB);
|
||||
}
|
||||
%}
|
||||
|
||||
%ignore gnc_option_to_scheme;
|
||||
%ignore gnc_option_from_scheme;
|
||||
/* GncOptionDB::register_option comes in GncOption* and GncOption&&
|
||||
* overloads. The latter isn't useful to SWIG, ignore it.
|
||||
*/
|
||||
%ignore GncOptionDB::register_option(const char*, GncOption&&);
|
||||
/* GncOptionDB::save_to_scheme takes and returns a std::stream. Good luck
|
||||
* converting *that* to anything useful!
|
||||
*/
|
||||
%ignore GncOptionDB::save_to_scheme(std::ostream&, const char*);
|
||||
%ignore GncOptionDB::save_option_scheme(std::ostream&, const char*, const std::string&, const std::string&);
|
||||
%ignore GncOptionDB::load_option_scheme(std::itream&);
|
||||
/* The following functions are overloaded in gnc-optiondb.hpp to provide both
|
||||
* GncOptionDB* and GncOptionDBPtr& versions. That confuses SWIG so ignore the
|
||||
* raw-ptr version.
|
||||
@ -837,6 +829,8 @@ inline SCM return_scm_value(ValueType value)
|
||||
|
||||
%}
|
||||
%ignore GncOptionDBCallback;
|
||||
%ignore operator<(const GncOption&, const GncOption&);
|
||||
%ignore operator<(const GncOptionSectionPtr&, const GncOptionSectionPtr&);
|
||||
|
||||
%include "gnc-option-date.hpp"
|
||||
%include "gnc-option.hpp"
|
||||
@ -1356,12 +1350,10 @@ inline SCM return_scm_value(ValueType value)
|
||||
});
|
||||
}
|
||||
|
||||
static std::string
|
||||
std::string
|
||||
gnc_optiondb_save_to_scheme(GncOptionDBPtr& odb, const char* prolog)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
odb->save_to_scheme(oss, prolog);
|
||||
return oss.str();
|
||||
return prolog;
|
||||
}
|
||||
%}
|
||||
|
||||
|
@ -91,26 +91,6 @@ TEST(GncOption, test_string_stream_in)
|
||||
EXPECT_EQ(pepper, option.get_value<std::string>());
|
||||
}
|
||||
|
||||
TEST(GncOption, test_string_to_scheme)
|
||||
{
|
||||
GncOption option("foo", "bar", "baz", "Phony Option", std::string{"waldo"});
|
||||
std::ostringstream oss;
|
||||
option.to_scheme(oss);
|
||||
std::string scheme_str{"\""};
|
||||
scheme_str += option.get_value<std::string>() + "\"";
|
||||
EXPECT_EQ(oss.str(), scheme_str);
|
||||
}
|
||||
|
||||
TEST(GncOption, test_string_from_scheme)
|
||||
{
|
||||
GncOption option("foo", "bar", "baz", "Phony Option", std::string{"waldo"});
|
||||
std::string pepper{"pepper"};
|
||||
std::string scheme_str{"\"pepper\""};
|
||||
std::istringstream iss{scheme_str};
|
||||
option.from_scheme(iss);
|
||||
EXPECT_EQ(pepper, option.get_value<std::string>());
|
||||
}
|
||||
|
||||
TEST(GncOption, test_int64_t_value)
|
||||
{
|
||||
GncOption option("foo", "bar", "baz", "Phony Option", INT64_C(123456789));
|
||||
@ -136,23 +116,6 @@ TEST(GncOption, test_int64_stream_in)
|
||||
EXPECT_EQ(INT64_C(987654321), option.get_value<int64_t>());
|
||||
}
|
||||
|
||||
TEST(GncOption, test_int64_to_scheme)
|
||||
{
|
||||
GncOption option("foo", "bar", "baz", "Phony Option", INT64_C(123456789));
|
||||
std::ostringstream oss;
|
||||
option.to_scheme(oss);
|
||||
EXPECT_STREQ(oss.str().c_str(), "123456789");
|
||||
}
|
||||
|
||||
TEST(GncOption, test_int64_from_scheme)
|
||||
{
|
||||
GncOption option("foo", "bar", "baz", "Phony Option", INT64_C(123456789));
|
||||
std::string number{"987654321"};
|
||||
std::istringstream iss{number};
|
||||
option.from_scheme(iss);
|
||||
EXPECT_EQ(INT64_C(987654321), option.get_value<int64_t>());
|
||||
}
|
||||
|
||||
TEST(GncOption, test_bool_stream_out)
|
||||
{
|
||||
GncOption option("foo", "bar", "baz", "Phony Option", false);
|
||||
@ -176,28 +139,6 @@ TEST(GncOption, test_bool_stream_in)
|
||||
EXPECT_FALSE(option.get_value<bool>());
|
||||
}
|
||||
|
||||
TEST(GncOption, test_bool_to_scheme)
|
||||
{
|
||||
GncOption option("foo", "bar", "baz", "Phony Option", false);
|
||||
std::ostringstream oss;
|
||||
oss << option;
|
||||
EXPECT_STREQ(oss.str().c_str(), "#f");
|
||||
oss.str("");
|
||||
option.set_value(true);
|
||||
option.to_scheme(oss);
|
||||
EXPECT_STREQ(oss.str().c_str(), "#t");
|
||||
}
|
||||
|
||||
TEST(GncOption, test_bool_from_scheme)
|
||||
{
|
||||
GncOption option("foo", "bar", "baz", "Phony Option", false);
|
||||
std::istringstream iss("#t");
|
||||
iss >> option;
|
||||
EXPECT_TRUE(option.get_value<bool>());
|
||||
iss.str("#f");
|
||||
option.from_scheme(iss);
|
||||
EXPECT_FALSE(option.get_value<bool>());
|
||||
}
|
||||
|
||||
class GncOptionTest : public ::testing::Test
|
||||
{
|
||||
@ -242,33 +183,6 @@ TEST_F(GncOptionTest, test_budget_in)
|
||||
gnc_budget_destroy(budget);
|
||||
}
|
||||
|
||||
TEST_F(GncOptionTest, test_budget_to_scheme)
|
||||
{
|
||||
auto budget = gnc_budget_new(m_book);
|
||||
GncOption option{"foo", "bar", "baz", "Phony Option", (const QofInstance*)budget};
|
||||
|
||||
auto budget_guid{gnc::GUID{*qof_instance_get_guid(QOF_INSTANCE(budget))}.to_string()};
|
||||
std::ostringstream oss;
|
||||
budget_guid.insert(0, "\"");
|
||||
budget_guid += "\"";
|
||||
option.to_scheme(oss);
|
||||
EXPECT_EQ(budget_guid, oss.str());
|
||||
gnc_budget_destroy(budget);
|
||||
}
|
||||
|
||||
TEST_F(GncOptionTest, test_budget_from_scheme)
|
||||
{
|
||||
auto budget = gnc_budget_new(m_book);
|
||||
auto budget_guid{gnc::GUID{*qof_instance_get_guid(QOF_INSTANCE(budget))}.to_string()};
|
||||
budget_guid.insert(0, "\"");
|
||||
budget_guid += "\"";
|
||||
std::istringstream iss{budget_guid};
|
||||
GncOption option{GncOptionValue<const QofInstance*>{"foo", "bar", "baz", "Phony Option", nullptr, GncOptionUIType::BUDGET}};
|
||||
option.from_scheme(iss);
|
||||
EXPECT_EQ(QOF_INSTANCE(budget), option.get_value<const QofInstance*>());
|
||||
gnc_budget_destroy(budget);
|
||||
}
|
||||
|
||||
TEST_F(GncOptionTest, test_commodity_ctor)
|
||||
{
|
||||
auto hpe = gnc_commodity_new(m_book, "Hewlett Packard Enterprise, Inc.",
|
||||
@ -462,50 +376,6 @@ TEST_F(GncOptionCommodityTest, test_commodity_in)
|
||||
EXPECT_EQ(QOF_INSTANCE(m_hpe), option.get_value<const QofInstance*>());
|
||||
}
|
||||
|
||||
TEST_F(GncOptionCommodityTest, test_currency_to_scheme)
|
||||
{
|
||||
auto option = make_currency_option("foo", "bar", "baz", "Phony Option",
|
||||
m_eur, true);
|
||||
|
||||
std::string eur_str{make_currency_SCM_str(m_eur)};
|
||||
std::ostringstream oss;
|
||||
option.to_scheme(oss);
|
||||
EXPECT_EQ(eur_str, oss.str());
|
||||
}
|
||||
|
||||
TEST_F(GncOptionCommodityTest, test_commodity_to_scheme)
|
||||
{
|
||||
GncOption option{"foo", "bar", "baz", "Phony Option", (const QofInstance*)m_hpe,
|
||||
GncOptionUIType::COMMODITY};
|
||||
|
||||
std::string hpe_str{make_commodity_SCM_str(m_hpe)};
|
||||
std::ostringstream oss;
|
||||
option.to_scheme(oss);
|
||||
EXPECT_EQ(hpe_str, oss.str());
|
||||
}
|
||||
|
||||
TEST_F(GncOptionCommodityTest, test_currency_from_scheme)
|
||||
{
|
||||
auto option = make_currency_option("foo", "bar", "baz", "Phony Option",
|
||||
m_eur, true);
|
||||
|
||||
std::string usd_str{make_currency_SCM_str(m_usd)};
|
||||
std::istringstream iss{usd_str};
|
||||
option.from_scheme(iss);
|
||||
EXPECT_EQ(QOF_INSTANCE(m_usd), option.get_value<const QofInstance*>());
|
||||
}
|
||||
|
||||
TEST_F(GncOptionCommodityTest, test_commodity_from_scheme)
|
||||
{
|
||||
GncOption option{"foo", "bar", "baz", "Phony Option", (const QofInstance*)m_aapl,
|
||||
GncOptionUIType::COMMODITY};
|
||||
|
||||
std::string hpe_str{make_commodity_SCM_str(m_hpe)};
|
||||
std::istringstream iss{hpe_str};
|
||||
option.from_scheme(iss);
|
||||
EXPECT_EQ(QOF_INSTANCE(m_hpe), option.get_value<const QofInstance*>());
|
||||
}
|
||||
|
||||
class GncUIType
|
||||
{
|
||||
public:
|
||||
@ -891,64 +761,6 @@ make_account_list_SCM_str(const GncOptionAccountList& acclist)
|
||||
return retval;
|
||||
}
|
||||
|
||||
TEST_F(GncOptionAccountTest, test_account_list_to_scheme)
|
||||
{
|
||||
GncOptionAccountList acclist{list_of_types({ACCT_TYPE_BANK})};
|
||||
GncOption option{GncOptionAccountListValue {"foo", "bar", "baz", "Bogus Option",
|
||||
GncOptionUIType::ACCOUNT_LIST,
|
||||
acclist}};
|
||||
std::ostringstream oss;
|
||||
std::string acc_guids{make_account_list_SCM_str(acclist)};
|
||||
|
||||
option.to_scheme(oss);
|
||||
EXPECT_EQ(acc_guids, oss.str());
|
||||
|
||||
GncOptionAccountList accsel{acclist[0]};
|
||||
GncOption sel_option{GncOptionAccountListValue{"foo", "bar", "baz",
|
||||
"Bogus Option",
|
||||
GncOptionUIType::ACCOUNT_LIST,
|
||||
accsel,
|
||||
GncOptionAccountTypeList{ACCT_TYPE_BANK}}};
|
||||
acc_guids = make_account_list_SCM_str(accsel);
|
||||
|
||||
oss.str("");
|
||||
sel_option.to_scheme(oss);
|
||||
EXPECT_EQ(acc_guids, oss.str());
|
||||
}
|
||||
|
||||
TEST_F(GncOptionAccountTest, test_account_list_from_scheme)
|
||||
{
|
||||
GncOptionAccountList acclist{list_of_types({ACCT_TYPE_BANK})};
|
||||
GncOption option{GncOptionAccountListValue{"foo", "bar", "baz", "Bogus Option",
|
||||
GncOptionUIType::ACCOUNT_LIST,
|
||||
acclist}};
|
||||
|
||||
std::string acc_guids{make_account_list_SCM_str(acclist)};
|
||||
std::istringstream iss{acc_guids};
|
||||
option.from_scheme(iss);
|
||||
EXPECT_EQ(acclist, option.get_value<GncOptionAccountList>());
|
||||
|
||||
GncOptionAccountList accsel{acclist[0]};
|
||||
GncOption sel_option{GncOptionAccountListValue{"foo", "bar", "baz",
|
||||
"Bogus Option",
|
||||
GncOptionUIType::ACCOUNT_LIST,
|
||||
accsel,
|
||||
GncOptionAccountTypeList{ACCT_TYPE_BANK}}};
|
||||
GncOptionAccountList acclistbad{list_of_types({ACCT_TYPE_STOCK})};
|
||||
acc_guids = make_account_list_SCM_str(acclistbad);
|
||||
iss.clear();
|
||||
iss.str(acc_guids);
|
||||
sel_option.from_scheme(iss);
|
||||
EXPECT_EQ(accsel, sel_option.get_value<GncOptionAccountList>());
|
||||
|
||||
iss.clear(); //Reset the failedbit from the invalid selection type.
|
||||
acc_guids = make_account_list_SCM_str(GncOptionAccountList{acclist[1]});
|
||||
EXPECT_NO_THROW({
|
||||
iss.str(acc_guids);
|
||||
sel_option.from_scheme(iss);
|
||||
});
|
||||
EXPECT_EQ(acclist[1], sel_option.get_value<GncOptionAccountList>()[0]);
|
||||
}
|
||||
|
||||
using KT = GncOptionMultichoiceKeyType;
|
||||
class GncOptionMultichoiceTest : public ::testing::Test
|
||||
@ -1031,22 +843,6 @@ TEST_F(GncMultichoiceOption, test_multichoice_in)
|
||||
EXPECT_EQ(iss.str(), m_option.get_value<std::string>());
|
||||
}
|
||||
|
||||
TEST_F(GncMultichoiceOption, test_multichoice_scheme_out)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
m_option.to_scheme(oss);
|
||||
std::string scm_str{'\''};
|
||||
scm_str += m_option.get_value<std::string>();
|
||||
EXPECT_EQ(scm_str, oss.str());
|
||||
}
|
||||
|
||||
TEST_F(GncMultichoiceOption, test_multichoice_scheme_in)
|
||||
{
|
||||
std::istringstream iss{"'pork"};
|
||||
m_option.from_scheme(iss);
|
||||
EXPECT_STREQ("pork", m_option.get_value<std::string>().c_str());
|
||||
}
|
||||
|
||||
class GncOptionListTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
@ -1116,26 +912,6 @@ TEST_F(GncListOption, test_list_in)
|
||||
EXPECT_EQ(iss.str(), m_option.get_value<std::string>());
|
||||
}
|
||||
|
||||
TEST_F(GncListOption, test_list_scheme_out)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
m_option.to_scheme(oss);
|
||||
std::string value{"'('"};
|
||||
auto vec{m_option.get_value<GncMultichoiceOptionIndexVec>()};
|
||||
value += m_option.permissible_value(vec[0]);
|
||||
value += " '";
|
||||
value += m_option.permissible_value(vec[1]);
|
||||
value += ")";
|
||||
EXPECT_EQ(value, oss.str());
|
||||
}
|
||||
|
||||
TEST_F(GncListOption, test_list_scheme_in)
|
||||
{
|
||||
std::istringstream iss{"'('pork 'waldo)"};
|
||||
m_option.from_scheme(iss);
|
||||
EXPECT_STREQ("pork", m_option.get_value<std::string>().c_str());
|
||||
}
|
||||
|
||||
static time64
|
||||
time64_from_gdate(const GDate* g_date, DayPart when)
|
||||
{
|
||||
@ -1572,63 +1348,3 @@ TEST_F(GncDateOption, test_stream_in_prev_year_end)
|
||||
EXPECT_EQ(time1, m_option.get_value<time64>());
|
||||
}
|
||||
|
||||
/* We only need wiggle tests for to_scheme and from_scheme as they just wrap or
|
||||
unwrap the normal stream output with "'(" and ")".
|
||||
*/
|
||||
|
||||
TEST_F(GncDateOption, test_date_option_to_scheme)
|
||||
{
|
||||
time64 time1{static_cast<time64>(GncDateTime("2019-07-19 15:32:26 +05:00"))};
|
||||
m_option.set_value(time1);
|
||||
std::ostringstream oss;
|
||||
oss << time1;
|
||||
std::string timestr{"'(absolute . "};
|
||||
timestr += oss.str();
|
||||
timestr += ')';
|
||||
oss.str("");
|
||||
m_option.to_scheme(oss);
|
||||
EXPECT_EQ(oss.str(), timestr);
|
||||
|
||||
m_option.set_value(RelativeDatePeriod::TODAY);
|
||||
oss.str("");
|
||||
m_option.to_scheme(oss);
|
||||
EXPECT_STREQ(oss.str().c_str(), "'(relative . today)");
|
||||
|
||||
m_option.set_value(RelativeDatePeriod::START_THIS_MONTH);
|
||||
oss.str("");
|
||||
m_option.to_scheme(oss);
|
||||
EXPECT_STREQ(oss.str().c_str(), "'(relative . start-this-month)");
|
||||
|
||||
}
|
||||
|
||||
TEST_F(GncDateOption, test_date_option_from_scheme)
|
||||
{
|
||||
time64 time1{static_cast<time64>(GncDateTime("2019-07-19 15:32:26 +05:00"))};
|
||||
std::ostringstream oss;
|
||||
oss << time1;
|
||||
std::string timestr{"'(absolute . "};
|
||||
timestr += oss.str();
|
||||
timestr += ')';
|
||||
|
||||
std::istringstream iss{timestr};
|
||||
m_option.from_scheme(iss);
|
||||
EXPECT_EQ(time1, m_option.get_value<time64>());
|
||||
|
||||
GDate month_start;
|
||||
g_date_set_time_t(&month_start, time(nullptr));
|
||||
gnc_gdate_set_month_start(&month_start);
|
||||
time1 = time64_from_gdate(&month_start, DayPart::start);
|
||||
iss.clear();
|
||||
iss.str("'(relative . start-this-month)");
|
||||
m_option.from_scheme(iss);
|
||||
EXPECT_EQ(time1, m_option.get_value<time64>());
|
||||
|
||||
GDate date;
|
||||
g_date_set_time_t(&date, time(nullptr));
|
||||
gnc_gdate_set_month_end(&date);
|
||||
time1 = time64_from_gdate(&date, DayPart::end);
|
||||
iss.clear();
|
||||
iss.str("'(relative . end-this-month)");
|
||||
m_option.from_scheme(iss);
|
||||
EXPECT_EQ(time1, m_option.get_value<time64>());
|
||||
}
|
||||
|
@ -337,115 +337,6 @@ protected:
|
||||
GncOptionDBPtr m_db;
|
||||
};
|
||||
|
||||
TEST_F(GncOptionDBIOTest, test_option_scheme_output)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
m_db->save_option_scheme(oss, "option", "foo", "sausage");
|
||||
EXPECT_STREQ("", oss.str().c_str());
|
||||
oss.clear();
|
||||
m_db->set_option("foo", "sausage", std::string{"pepper"});
|
||||
EXPECT_STREQ("pepper", m_db->lookup_string_option("foo", "sausage").c_str());
|
||||
EXPECT_TRUE(m_db->find_option("foo", "sausage")->is_changed());
|
||||
oss.flush();
|
||||
m_db->save_option_scheme(oss, "option", "foo", "sausage");
|
||||
EXPECT_STREQ("(let ((option (gnc:lookup-option option\n"
|
||||
" \"foo\"\n"
|
||||
" \"sausage\")))\n"
|
||||
" ((lambda (o) (if o (gnc:option-set-value o \"pepper\""
|
||||
"))) option))\n\n", oss.str().c_str());
|
||||
}
|
||||
|
||||
TEST_F(GncOptionDBIOTest, test_string_option_scheme_input)
|
||||
{
|
||||
const char* input{"(let ((option (gnc:lookup-option option\n"
|
||||
" \"foo\"\n"
|
||||
" \"sausage\")))\n"
|
||||
" ((lambda (o) (if o (gnc:option-set-value o \"pepper\""
|
||||
"))) option))\n\n"};
|
||||
std::istringstream iss{input};
|
||||
EXPECT_STREQ("waldo", m_db->lookup_string_option("foo", "sausage").c_str());
|
||||
m_db->load_option_scheme(iss);
|
||||
EXPECT_STREQ("pepper", m_db->lookup_string_option("foo", "sausage").c_str());
|
||||
}
|
||||
|
||||
TEST_F(GncOptionDBIOTest, test_date_interval_option_scheme_input)
|
||||
{
|
||||
const char* input{"(let ((option (gnc:lookup-option option\n"
|
||||
" \"pork\"\n"
|
||||
" \"garply\")))\n"
|
||||
" ((lambda (o) (if o (gnc:option-set-value o "
|
||||
"'(relative . end-prev-month)"
|
||||
"))) option))\n\n"};
|
||||
std::istringstream iss{input};
|
||||
GDate month_end;
|
||||
g_date_set_time_t(&month_end, time(nullptr));
|
||||
g_date_subtract_months(&month_end, 1);
|
||||
gnc_gdate_set_month_end(&month_end);
|
||||
auto time1 = time64_from_gdate(&month_end, DayPart::end);
|
||||
m_db->load_option_scheme(iss);
|
||||
EXPECT_EQ(time1, m_db->find_option("pork", "garply")->get_value<time64>());
|
||||
|
||||
}
|
||||
|
||||
TEST_F(GncOptionDBIOTest, test_account_list_option_scheme_input)
|
||||
{
|
||||
auto acclist{gnc_account_list_from_types(m_book, {ACCT_TYPE_STOCK})};
|
||||
auto hpe_guid{qof_instance_to_string(QOF_INSTANCE(acclist[3]))};
|
||||
auto msft_guid{qof_instance_to_string(QOF_INSTANCE(acclist[2]))};
|
||||
std::string input{"(let ((option (gnc:lookup-option option\n"
|
||||
" \"quux\"\n"
|
||||
" \"xyzzy\")))\n"
|
||||
" ((lambda (o) (if o (gnc:option-set-value o '(\""};
|
||||
input += hpe_guid + "\" \"";
|
||||
input += msft_guid + "\")))) option))\n\n";
|
||||
std::istringstream iss{input};
|
||||
EXPECT_EQ(acclist[1], m_db->find_option("quux", "xyzzy")->get_value<GncOptionAccountList>()[0]);
|
||||
m_db->load_option_scheme(iss);
|
||||
EXPECT_EQ(acclist[2], m_db->find_option("quux", "xyzzy")->get_value<GncOptionAccountList>()[1]);
|
||||
EXPECT_EQ(2u, m_db->find_option("quux", "xyzzy")->get_value<GncOptionAccountList>().size());
|
||||
|
||||
}
|
||||
|
||||
TEST_F(GncOptionDBIOTest, test_multiple_options_scheme_input)
|
||||
{
|
||||
auto acclist{gnc_account_list_from_types(m_book, {ACCT_TYPE_STOCK})};
|
||||
auto hpe_guid{qof_instance_to_string(QOF_INSTANCE(acclist[3]))};
|
||||
auto msft_guid{qof_instance_to_string(QOF_INSTANCE(acclist[2]))};
|
||||
std::string input{";; Foo\n\n"
|
||||
"(let ((option (gnc:lookup-option option\n"
|
||||
" \"foo\"\n"
|
||||
" \"sausage\")))\n"
|
||||
" ((lambda (o) (if o (gnc:option-set-value o \"pepper\""
|
||||
"))) option))\n\n"
|
||||
";; Pork\n\n"
|
||||
"(let ((option (gnc:lookup-option option\n"
|
||||
" \"pork\"\n"
|
||||
" \"garply\")))\n"
|
||||
" ((lambda (o) (if o (gnc:option-set-value o "
|
||||
"'(relative . end-prev-month)"
|
||||
"))) option))\n\n"
|
||||
";; Quux\n\n"
|
||||
"(let ((option (gnc:lookup-option option\n"
|
||||
" \"quux\"\n"
|
||||
" \"xyzzy\")))\n"
|
||||
" ((lambda (o) (if o (gnc:option-set-value o '(\""};
|
||||
input += hpe_guid + "\" \"";
|
||||
input += msft_guid + "\")))) option))\n\n";
|
||||
std::istringstream iss{input};
|
||||
GDate month_end;
|
||||
g_date_set_time_t(&month_end, time(nullptr));
|
||||
g_date_subtract_months(&month_end, 1);
|
||||
gnc_gdate_set_month_end(&month_end);
|
||||
auto time1 = time64_from_gdate(&month_end, DayPart::end);
|
||||
EXPECT_EQ(acclist[1], m_db->find_option("quux", "xyzzy")->get_value<GncOptionAccountList>()[0]);
|
||||
m_db->load_from_scheme(iss);
|
||||
EXPECT_STREQ("pepper", m_db->lookup_string_option("foo", "sausage").c_str());
|
||||
EXPECT_EQ(time1, m_db->find_option("pork", "garply")->get_value<time64>());
|
||||
EXPECT_EQ(acclist[2], m_db->find_option("quux", "xyzzy")->get_value<GncOptionAccountList>()[1]);
|
||||
EXPECT_EQ(2u, m_db->find_option("quux", "xyzzy")->get_value<GncOptionAccountList>().size());
|
||||
|
||||
}
|
||||
|
||||
TEST_F(GncOptionDBIOTest, test_option_key_value_output)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
|
Loading…
Reference in New Issue
Block a user