From f9ed75b8c4105a420bbef173e78c577cdc166829 Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Nov 10 2016 13:09:51 +0000 Subject: Support empty properties in INI files The ini file parser doesn't support parsing properties with no value. This patch adds that feature, as it turned out to be a pre-requisite for reading Linux Kernel ABI whitelist files. * include/abg-ini.h (simple_property::simple_property): Add a new constructor for empty values. (simple_property::has_empty_value): Declare new member function. * src/abg-ini.cc (simple_property::{simple_property, has_empty_value}): Define new member functions. (read_context::read_property): Support reading a property with no value. (write_property_value, write_property): Support writting a property with empty value. Signed-off-by: Dodji Seketeli --- diff --git a/include/abg-ini.h b/include/abg-ini.h index e8ecb91..bd4ed52 100644 --- a/include/abg-ini.h +++ b/include/abg-ini.h @@ -244,12 +244,17 @@ public: simple_property(const string& name, const string_property_value_sptr& value); + simple_property(const string& name); + const string_property_value_sptr& get_value() const; void set_value(const string_property_value_sptr& value); + bool + has_empty_value() const; + virtual ~simple_property(); }; // end class simple_property diff --git a/src/abg-ini.cc b/src/abg-ini.cc index 2cae789..b528d16 100644 --- a/src/abg-ini.cc +++ b/src/abg-ini.cc @@ -576,6 +576,16 @@ simple_property::simple_property(const string& name, priv_(new priv(value)) {} +/// Constructor for the @ref simple_property type. +/// +/// This one constructs a property with an empty value. +/// +/// @param name the name of the property. +simple_property::simple_property(const string& name) + : property(name), + priv_(new priv) +{} + /// Getter for the string value of the property. /// /// @return the string value of the property. @@ -590,6 +600,19 @@ void simple_property::set_value(const string_property_value_sptr& value) {priv_->value_ = value;} +/// Test if the property has an empty value. +/// +/// An empty value is either no value at all or an empty string value. +/// +/// @return true iff the property has an empty value. +bool +simple_property::has_empty_value() const +{ + if (!priv_->value_) + return true; + return priv_->value_->as_string().empty(); +} + /// Destructor of the @ref simple_property type. simple_property::~simple_property() {} @@ -1523,14 +1546,22 @@ public: return nil; skip_white_spaces(); - if (!good()) - return nil; - char c = 0; - if (!read_next_char(c) || c != '=') - return nil; + property_sptr result; + + char c = peek(); + if (c == '=') + { + assert(read_next_char(c)); + assert(c == '='); + skip_white_spaces(); + } + else + { + property_sptr empty_value_property(new simple_property(name)); + return empty_value_property; + } - skip_white_spaces(); if (!good()) return nil; @@ -1538,7 +1569,6 @@ public: if (!value) return nil; - property_sptr result; if (tuple_property_value_sptr tv = is_tuple_property_value(value)) result.reset(new tuple_property(name, tv)); else if (list_property_value_sptr lv = is_list_property_value(value)) @@ -1791,7 +1821,10 @@ write_property_value(const property_sptr& prop) { string result; if (simple_property_sptr simple_prop = is_simple_property(prop)) - result = simple_prop->get_value()->as_string(); + { + if (!simple_prop->has_empty_value()) + result = simple_prop->get_value()->as_string(); + } else if (list_property_sptr list_prop = is_list_property(prop)) result = list_prop->get_value()->as_string(); else if (tuple_property_sptr tuple_prop = is_tuple_property(prop)) @@ -1813,7 +1846,10 @@ static bool write_property(const property_sptr& prop, std::ostream& out) { - out << prop->get_name() << " = " << write_property_value(prop); + out << prop->get_name(); + string value = write_property_value(prop); + if (!value.empty()) + out << " = " << write_property_value(prop); return out.good(); }