22 #include <fmt/format.h>
31 if ( !status )
return false;
41 if ( !status )
return false;
47 static std::unique_ptr<gp::PropertyName> GetPropertyName(
const gp::Node* node ) {
49 return std::make_unique<gp::PropertyName>( node->
children[0].value, node->
position );
53 for (
unsigned int i = 0; i < ( node->
children.size() - 1 ); ++i ) {
54 client += delim + node->
children[i].value;
57 return std::make_unique<gp::PropertyName>( client, node->
children[node->
children.size() - 1].value, node->
position );
59 static std::unique_ptr<gp::PropertyValue> GetPropertyValue(
const gp::Node* node,
gp::Catalog* catalog,
61 std::unique_ptr<gp::PropertyValue> value;
62 switch ( node->
type ) {
71 std::string unit_name = node->
children[0].value;
72 double unit_value = 0;
73 if ( units->
Find( unit_name, unit_value ) ) {
75 double val = std::stod( node->
value );
76 value = std::make_unique<gp::PropertyValue>( std::to_string( val * unit_value ) );
82 value = std::make_unique<gp::PropertyValue>( node->
value );
88 ss << std::quoted( node->
value );
89 value = std::make_unique<gp::PropertyValue>( ss.str() );
93 value = std::make_unique<gp::PropertyValue>( node->
value );
97 std::vector<std::string> result;
98 result.reserve( node->
children.size() );
100 [&](
const gp::Node& child ) { return GetPropertyValue( &child, catalog, units )->ToString(); } );
101 value = std::make_unique<gp::PropertyValue>( std::move( result ) );
106 for (
const auto& child : node->
children ) {
107 auto kvalue = GetPropertyValue( &child.children[0], catalog, units );
108 auto vvalue = GetPropertyValue( &child.children[1], catalog, units );
109 result.emplace( kvalue->ToString(), vvalue->ToString() );
112 # pragma GCC diagnostic push
114 # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
116 value = std::make_unique<gp::PropertyValue>( std::move( result ) );
118 # pragma GCC diagnostic pop
123 auto property = GetPropertyName( node );
124 gp::Property* exists = catalog->
Find( property->client(), property->property() );
126 value = std::make_unique<gp::PropertyValue>( exists->
property_value() );
133 auto property = GetPropertyName( node );
136 reference.push_back( property->client() );
137 reference.push_back( property->property() );
139 value = std::make_unique<gp::PropertyValue>( std::move(
reference ), property->position(),
true );
172 std::unique_ptr<gp::PropertyValue> value;
174 auto property = GetPropertyName( &node->
children[0] );
176 value = GetPropertyValue( &node->
children[2], catalog, units );
182 bool reassign =
false;
183 gp::Property* exists = catalog->
Find( property->client(), property->property() );
188 std::string
message =
fmt::format(
"Reassignment of option '{}'.", property->FullName() );
202 std::string
message = ex.what();
212 if ( !exists || reassign ) { result = catalog->
Add(
new gp::Property( *property, *value ) ); }
214 if ( result && is_print ) {
223 double left = std::stod( node->
children[0].value );
225 double right = std::stod( node->
children[2].value );
227 gp::Units::Container::mapped_type exists;
228 if ( units->
Find(
name, exists ) ) {
230 if ( exists.second.Exists() ) {
message +=
" at " + exists.second.ToString(); }
235 bool result = units->
Add(
name, right / left, node->
children[1].position );
236 if ( result && is_print ) {
244 auto property_name = GetPropertyName( &node->
children[0] );
246 bool is_defined = (
nullptr != catalog->
Find( property_name->client(), property_name->property() ) );
251 }
else if ( node->
children.size() > 2 ) {
262 bool local_result =
true;
263 bool skip_childs =
true;
266 switch ( node->
type ) {
273 local_result = IncludeNode( node, search_path, included, messages );
279 local_result = UnitsNode( node, search_path, included, messages );
285 local_result = AssignNode( node, messages, catalog, units, pragma->
is_print() );
290 local_result = UnitNode( node, messages, units, pragma->
is_print() );
295 local_result = ConditionNode( node, catalog, &next_root );
321 std::string file =
"";
334 if ( result ) result = local_result;
336 if ( !skip_childs && next_root ) {
337 for (
auto& child : next_root->
children ) {
338 local_result = Analyze( &child, search_path, included, messages, catalog, units, pragma );
339 if ( result ) result = local_result;
346 bool unreference_result =
true;
347 for (
auto& client : catalog ) {
348 for (
auto& current : client.second ) {
349 if ( current.IsReference() ) {
351 const std::vector<std::string>& names = value.
Vector();
352 gp::Property*
property = catalog.Find( names[0], names[1] );
354 messages->
AddError( value.
position(),
"Could not unreference " + current.ValueAsString() );
355 unreference_result =
false;
357 value =
property->property_value();
362 return unreference_result;
370 if ( !result )
return false;
372 bool result1 = Analyze(
root, search_path, &included, messages, catalog, units, pragma );
374 return result1 && result2;