9 #include <boost/format.hpp>    26 static bool IncludeNode( gp::Node* node, 
const std::string& search_path, gp::IncludedFiles* included,
    27                          gp::Messages* messages ) {
    28   gp::Node include_root;
    29   bool     status = 
gp::Parse( node->position, node->value, search_path, included, messages, &include_root );
    30   if ( !status ) 
return false;
    31   node->value = include_root.value; 
    32   node->children.reserve( node->children.size() + include_root.children.size() );
    38 static bool UnitsNode( gp::Node* node, 
const std::string& search_path, gp::IncludedFiles* included,
    39                        gp::Messages* messages ) {
    41   bool     status = 
gp::ParseUnits( node->position, node->value, search_path, included, messages, &units_root );
    42   if ( !status ) 
return false;
    43   node->value = units_root.value; 
    44   node->children.reserve( node->children.size() + units_root.children.size() );
    50   if ( node->children.size() == 1 ) {
    51     return std::make_unique<gp::PropertyName>( node->children[0].value, node->position );
    55   for ( 
unsigned int i = 0; i < ( node->children.size() - 1 ); ++i ) {
    56     client += delim + node->children[i].value;
    59   return std::make_unique<gp::PropertyName>( client, node->children[node->children.size() - 1].value, node->position );
    65   switch ( node->type ) {
    67   case gp::Node::kReal: {
    73     if ( node->children.size() == 1 ) {
    76       double      unit_value = 0;
    77       if ( units->Find( unit_name, unit_value ) ) {
    80         value      = std::make_unique<gp::PropertyValue>( 
std::to_string( val * unit_value ) );
    83         throw gp::PositionalPropertyValueException::CouldNotFindUnit( node->children[0].position, unit_name );
    86       value = std::make_unique<gp::PropertyValue>( node->value );
    91   case gp::Node::kString: {
    93     value = std::make_unique<gp::PropertyValue>( 
'"' + node->value + 
'"' );
    97   case gp::Node::kBool: {
    98     value = std::make_unique<gp::PropertyValue>( node->value );
   102   case gp::Node::kVector: {
   104     result.
reserve( node->children.size() );
   106                     [&]( 
const gp::Node& child ) { return GetPropertyValue( &child, catalog, units )->ToString(); } );
   107     value = std::make_unique<gp::PropertyValue>( 
std::move( result ) );
   111   case gp::Node::kMap: {
   113     for ( 
const auto& child : node->children ) {
   114       auto kvalue = GetPropertyValue( &child.children[0], catalog, units );
   115       auto vvalue = GetPropertyValue( &child.children[1], catalog, units );
   116       result.
emplace( kvalue->ToString(), vvalue->ToString() );
   118     value = std::make_unique<gp::PropertyValue>( 
std::move( result ) );
   122   case gp::Node::kProperty: {
   123     auto          property = GetPropertyName( node );
   126       value = std::make_unique<gp::PropertyValue>( exists->property_value() );
   128       throw gp::PositionalPropertyValueException::CouldNotFindProperty( node->position, 
property->ToString() );
   132   case gp::Node::kPropertyRef: {
   133     auto property = GetPropertyName( node );
   139     value = std::make_unique<gp::PropertyValue>( 
std::move( reference ), 
property->position(), true );
   154   case gp::Node::kEqual: {
   158   case gp::Node::kPlusEqual: {
   162   case gp::Node::kMinusEqual: {
   173 static bool AssignNode( 
const gp::Node* node, gp::Messages* messages, gp::Catalog* catalog, gp::Units* units,
   178   auto property = GetPropertyName( &node->children[0] );
   180     value = GetPropertyValue( &node->children[2], catalog, units );
   181   } 
catch ( 
const gp::PositionalPropertyValueException& ex ) {
   182     messages->AddError( ex.position(), ex.what() );
   186   bool          reassign = 
false;
   194       if ( node->children[1].type == gp::Node::kEqual ) {
   196         if ( exists->HasDefinedPosition() ) {
   197           message += 
" Previously defined at " + exists->DefinedPosition().ToString() + 
".";
   202       } 
else if ( node->children[1].type == gp::Node::kPlusEqual ) {
   204       } 
else if ( node->children[1].type == gp::Node::kMinusEqual ) {
   207     } 
catch ( 
const gp::PropertyValueException& ex ) {
   209       if ( exists->HasDefinedPosition() ) {
   210         message += 
" Previously defined at " + exists->DefinedPosition().ToString() + 
".";
   212       messages->AddError( node->position, message );
   220   if ( result && is_print ) { 
   222                                SignString( node->children[1].type ) % value->ToString() );
   223     messages->AddInfo( node->position, message );
   228 static bool UnitNode( 
const gp::Node* node, gp::Messages* messages, gp::Units* units, 
bool is_print ) {
   234   gp::Units::Container::mapped_type exists;
   235   if ( units->Find( name, exists ) ) {
   237     if ( exists.second.Exists() ) { message += 
" at " + exists.second.ToString(); }
   238     messages->AddError( node->children[1].position, message );
   242   bool result = units->Add( name, right / left, node->children[1].position );
   243   if ( result && is_print ) {
   245     messages->AddInfo( node->position, message );
   250 static bool ConditionNode( gp::Node* node, gp::Catalog* catalog, gp::Node** next ) {
   252   auto property_name = GetPropertyName( &node->children[0] );
   254   bool is_defined = ( 
nullptr != catalog->Find( property_name->client(), property_name->property() ) );
   256   if ( ( is_defined && ( node->children[1].type == gp::Node::kIfdef ) ) ||
   257        ( !is_defined && ( node->children[1].type == gp::Node::kIfndef ) ) ) {
   258     *next = &node->children[1];
   259   } 
else if ( node->children.size() > 2 ) {
   260     *next = &node->children[2];
   267 static bool Analyze( gp::Node* node, 
const std::string& search_path, gp::IncludedFiles* included,
   268                      gp::Messages* messages, gp::Catalog* catalog, gp::Units* units, gp::PragmaOptions* pragma ) {
   271   bool      local_result = 
true;
   272   bool      skip_childs  = 
true;
   273   gp::Node* next_root    = node;
   275   switch ( node->type ) {
   277   case gp::Node::kRoot: {
   282   case gp::Node::kInclude: {
   283     local_result = IncludeNode( node, search_path, included, messages );
   288   case gp::Node::kUnits: {
   289     local_result = UnitsNode( node, search_path, included, messages );
   294   case gp::Node::kAssign: {
   295     local_result = AssignNode( node, messages, catalog, units, pragma->is_print() );
   299   case gp::Node::kUnit: {
   300     local_result = UnitNode( node, messages, units, pragma->is_print() );
   304   case gp::Node::kCondition: {
   305     local_result = ConditionNode( node, catalog, &next_root );
   310   case gp::Node::kPrintOptions: {
   311     pragma->setIsPrintOptions( 
true );
   315   case gp::Node::kPrintOn: {
   316     pragma->setIsPrint( 
true );
   320   case gp::Node::kPrintOff: {
   321     pragma->setIsPrint( 
false );
   325   case gp::Node::kPrintTree: {
   326     pragma->setIsPrintTree( 
true );
   330   case gp::Node::kDumpFile: {
   333       pragma->setDumpFile( file );
   335       pragma->setDumpFile( node->value );
   342   if ( result ) result = local_result;
   344   if ( !skip_childs && next_root ) {
   345     for ( 
auto& child : next_root->children ) {
   346       local_result = Analyze( &child, search_path, included, messages, catalog, units, pragma );
   347       if ( result ) result = local_result;
   353 bool Unreference( gp::Catalog& catalog, gp::Messages* messages ) {
   354   bool unreference_result = 
true;
   355   for ( 
auto& client : catalog ) {
   356     for ( 
auto& current : client.second ) {
   357       if ( current.IsReference() ) {
   358         gp::PropertyValue&              value    = current.property_value();
   360         gp::Property*                   
property = catalog.Find( names[0], names[1] );
   362           messages->AddError( value.position(), 
"Could not unreference " + current.ValueAsString() );
   363           unreference_result = 
false;
   365           value = 
property->property_value();
   370   return unreference_result;
   378   bool          result = 
Parse( filename, search_path, &included, messages, root );
   379   if ( !result ) 
return false;
   381   bool result1 = Analyze( root, search_path, &included, messages, catalog, units, pragma );
   383   return result1 && result2;
 
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)". 
GAUDI_API StatusCode resolveEnv(const std::string &var, std::string &res, int recusions=124)
bool ParseUnits(const Position &from, const std::string &filename, const std::string &search_path, IncludedFiles *included, Messages *messages, Node *root)
Gaudi::Details::PropertyBase * property(const std::string &name) const 
bool ReadOptions(const std::string &filename, const std::string &search_path, Messages *messages, Catalog *catalog, Units *units, PragmaOptions *pragma, Node *root)
Parse and analyze filename, save all messages and properties. 
Gaudi::Details::PropertyBase Property
backward compatibility hack for old Property base class 
bool Parse(const std::string &filename, const std::string &search_path, IncludedFiles *included, Messages *messages, Node *root)
T back_inserter(T...args)
bool Unreference(gp::Catalog &catalog, gp::Messages *messages)