22 #include <fmt/format.h>
32 if ( !status )
return false;
43 if ( !status )
return false;
50 static std::unique_ptr<gp::PropertyName> GetPropertyName(
const gp::Node* node ) {
52 return std::make_unique<gp::PropertyName>( node->
children[0].value, node->
position );
56 for (
unsigned int i = 0; i < ( node->
children.size() - 1 ); ++i ) {
57 client += delim + node->
children[i].value;
60 return std::make_unique<gp::PropertyName>( client, node->
children[node->
children.size() - 1].value, node->
position );
63 static std::unique_ptr<gp::PropertyValue> GetPropertyValue(
const gp::Node* node,
gp::Catalog* catalog,
65 std::unique_ptr<gp::PropertyValue> value;
66 switch ( node->
type ) {
76 std::string unit_name = node->
children[0].value;
77 double unit_value = 0;
78 if ( units->
Find( unit_name, unit_value ) ) {
80 double val = std::stod( node->
value );
81 value = std::make_unique<gp::PropertyValue>( std::to_string( val * unit_value ) );
87 value = std::make_unique<gp::PropertyValue>( node->
value );
94 ss << std::quoted( node->
value );
95 value = std::make_unique<gp::PropertyValue>( ss.str() );
100 value = std::make_unique<gp::PropertyValue>( node->
value );
105 std::vector<std::string> result;
106 result.reserve( node->
children.size() );
108 [&](
const gp::Node& child ) { return GetPropertyValue( &child, catalog, units )->ToString(); } );
109 value = std::make_unique<gp::PropertyValue>( std::move( result ) );
115 for (
const auto& child : node->
children ) {
116 auto kvalue = GetPropertyValue( &child.children[0], catalog, units );
117 auto vvalue = GetPropertyValue( &child.children[1], catalog, units );
118 result.emplace( kvalue->ToString(), vvalue->ToString() );
121 # pragma GCC diagnostic push
123 # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
125 value = std::make_unique<gp::PropertyValue>( std::move( result ) );
127 # pragma GCC diagnostic pop
133 auto property = GetPropertyName( node );
134 gp::Property* exists = catalog->
Find( property->client(), property->property() );
136 value = std::make_unique<gp::PropertyValue>( exists->
property_value() );
143 auto property = GetPropertyName( node );
146 reference.push_back( property->client() );
147 reference.push_back( property->property() );
149 value = std::make_unique<gp::PropertyValue>( std::move(
reference ), property->position(),
true );
186 std::unique_ptr<gp::PropertyValue> value;
188 auto property = GetPropertyName( &node->
children[0] );
190 value = GetPropertyValue( &node->
children[2], catalog, units );
196 bool reassign =
false;
197 gp::Property* exists = catalog->
Find( property->client(), property->property() );
205 std::string
message =
fmt::format(
"Reassignment of option '{}'.", property->FullName() );
219 std::string
message = ex.what();
229 if ( !exists || reassign ) { result = catalog->
Add(
new gp::Property( *property, *value ) ); }
231 if ( result && is_print ) {
241 double left = std::stod( node->
children[0].value );
243 double right = std::stod( node->
children[2].value );
245 gp::Units::Container::mapped_type exists;
246 if ( units->
Find(
name, exists ) ) {
248 if ( exists.second.Exists() ) {
message +=
" at " + exists.second.ToString(); }
253 bool result = units->
Add(
name, right / left, node->
children[1].position );
254 if ( result && is_print ) {
263 auto property_name = GetPropertyName( &node->
children[0] );
265 bool is_defined = (
nullptr != catalog->
Find( property_name->client(), property_name->property() ) );
270 }
else if ( node->
children.size() > 2 ) {
282 bool local_result =
true;
283 bool skip_childs =
true;
286 switch ( node->
type ) {
294 local_result = IncludeNode( node, search_path, included, messages );
300 local_result = UnitsNode( node, search_path, included, messages );
306 local_result = AssignNode( node, messages, catalog, units, pragma->
is_print() );
311 local_result = UnitNode( node, messages, units, pragma->
is_print() );
316 local_result = ConditionNode( node, catalog, &next_root );
342 std::string file =
"";
355 if ( result ) result = local_result;
357 if ( !skip_childs && next_root ) {
358 for (
auto& child : next_root->
children ) {
359 local_result = Analyze( &child, search_path, included, messages, catalog, units, pragma );
360 if ( result ) result = local_result;
367 bool unreference_result =
true;
368 for (
auto& client : catalog ) {
369 for (
auto& current : client.second ) {
370 if ( current.IsReference() ) {
372 const std::vector<std::string>& names = value.
Vector();
373 gp::Property*
property = catalog.Find( names[0], names[1] );
375 messages->
AddError( value.
position(),
"Could not unreference " + current.ValueAsString() );
376 unreference_result =
false;
378 value =
property->property_value();
383 return unreference_result;
392 if ( !result )
return false;
394 bool result1 = Analyze(
root, search_path, &included, messages, catalog, units, pragma );
396 return result1 && result2;