LCOV - code coverage report
Current view: top level - core - ActionRegister.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 52 76 68.4 %
Date: 2026-03-30 13:16:06 Functions: 10 11 90.9 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-2023 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #include "ActionRegister.h"
      23             : #include "tools/Tools.h"
      24             : #include "Action.h"
      25             : #include <algorithm>
      26             : #include <iostream>
      27             : 
      28             : namespace PLMD {
      29             : 
      30        4595 : ActionRegister::~ActionRegister() {
      31        4595 :   if(m.size()>0) {
      32           0 :     std::string names="";
      33           0 :     for(const auto & p : m) {
      34           0 :       names+=p.first+" ";
      35             :     }
      36           0 :     std::cerr<<"WARNING: Directive "+ names +" has not been properly unregistered. This might lead to memory leak!!\n";
      37             :   }
      38        4595 : }
      39             : 
      40     2699796 : ActionRegister& actionRegister() {
      41     2699796 :   static ActionRegister ans;
      42     2699796 :   return ans;
      43             : }
      44             : 
      45     1341741 : void ActionRegister::remove(creator_pointer f) {
      46   114323658 :   for(auto p=m.begin(); p!=m.end(); ++p) {
      47   114323658 :     if((*p).second==f) {
      48     1341741 :       m.erase(p);
      49             :       break;
      50             :     }
      51             :   }
      52     1341741 : }
      53             : 
      54     1341741 : void ActionRegister::add(std::string key,creator_pointer f,keywords_pointer k) {
      55             :   // this force each action to be registered as an uppercase string
      56     1341741 :   if ( std::any_of( std::begin( key ), std::end( key ), []( char c ) {
      57     5449673 :   return ( std::islower( c ) )
      58             :            ;
      59           0 :   } ) ) plumed_error() << "Action: " + key + " cannot be registered, use only UPPERCASE characters";
      60             :   if(m.count(key)) {
      61             :     m.erase(key);
      62           0 :     disabled.insert(key);
      63             :   } else {
      64     1341741 :     m.insert(std::pair<std::string,creator_pointer>(key,f));
      65             :     // Store a pointer to the function that creates keywords
      66             :     // A pointer is stored and not the keywords because all
      67             :     // Vessels must be dynamically loaded before the actions.
      68     1341741 :     mk.insert(std::pair<std::string,keywords_pointer>(key,k));
      69             :   };
      70     1341741 : }
      71             : 
      72       16308 : bool ActionRegister::check(const std::string & key) {
      73             :   if(m.count(key)>0 && mk.count(key)>0) {
      74       16303 :     return true;
      75             :   }
      76             :   return false;
      77             : }
      78             : 
      79       14552 : std::unique_ptr<Action> ActionRegister::create(const ActionOptions&ao) {
      80       14552 :   if(ao.line.size()<1) {
      81             :     return NULL;
      82             :   }
      83             :   // Create a copy of the manual locally. The manual is
      84             :   // then added to the ActionOptions. This allows us to
      85             :   // ensure during construction that all the keywords for
      86             :   // the action have been documented. In addition, we can
      87             :   // generate the documentation when the user makes an error
      88             :   // in the input.
      89       14552 :   std::unique_ptr<Action> action;
      90       14552 :   if( check(ao.line[0]) ) {
      91       14550 :     Keywords keys;
      92       14550 :     mk[ao.line[0]](keys);
      93       14550 :     ActionOptions nao( ao,keys );
      94       29062 :     action=m[ao.line[0]](nao);
      95       14550 :   }
      96             :   return action;
      97       14552 : }
      98             : 
      99        1168 : bool ActionRegister::getKeywords(const std::string& action, Keywords& keys) {
     100        1168 :   if ( check(action) ) {
     101        1168 :     mk[action](keys);
     102        1168 :     return true;
     103             :   }
     104             :   return false;
     105             : }
     106             : 
     107         586 : bool ActionRegister::printManual(const std::string& action, const bool& vimout, const bool& spellout) {
     108         586 :   if ( check(action) ) {
     109         584 :     Keywords keys;
     110         584 :     getKeywords( action, keys );
     111         584 :     if( vimout ) {
     112             :       printf("%s",action.c_str());
     113         584 :       keys.print_vim();
     114             :       printf("\n");
     115           0 :     } else if( spellout ) {
     116           0 :       keys.print_spelling();
     117             :     } else {
     118           0 :       keys.print_html();
     119             :     }
     120             :     return true;
     121         584 :   } else {
     122             :     return false;
     123             :   }
     124             : }
     125             : 
     126           0 : bool ActionRegister::printTemplate(const std::string& action, bool include_optional) {
     127           0 :   if( check(action) ) {
     128           0 :     Keywords keys;
     129           0 :     mk[action](keys);
     130           0 :     keys.print_template(action, include_optional);
     131             :     return true;
     132           0 :   } else {
     133             :     return false;
     134             :   }
     135             : }
     136             : 
     137         590 : std::vector<std::string> ActionRegister::getActionNames() const {
     138             :   std::vector<std::string> s;
     139      172871 :   for(const auto & it : m) {
     140      172281 :     s.push_back(it.first);
     141             :   }
     142         590 :   std::sort(s.begin(),s.end());
     143         590 :   return s;
     144           0 : }
     145             : 
     146         587 : std::ostream & operator<<(std::ostream &log,const ActionRegister&ar) {
     147         587 :   std::vector<std::string> s(ar.getActionNames());
     148      171992 :   for(unsigned i=0; i<s.size(); i++) {
     149      342810 :     log<<"  "<<s[i]<<"\n";
     150             :   }
     151         587 :   if(!ar.disabled.empty()) {
     152           0 :     s.assign(ar.disabled.size(),"");
     153           0 :     std::copy(ar.disabled.begin(),ar.disabled.end(),s.begin());
     154           0 :     std::sort(s.begin(),s.end());
     155           0 :     log<<"+++++++ WARNING +++++++\n";
     156           0 :     log<<"The following keywords have been registered more than once and will be disabled:\n";
     157           0 :     for(unsigned i=0; i<s.size(); i++) {
     158           0 :       log<<"  - "<<s[i]<<"\n";
     159             :     }
     160           0 :     log<<"+++++++ END WARNING +++++++\n";
     161             :   };
     162         587 :   return log;
     163         587 : }
     164             : 
     165             : 
     166             : }

Generated by: LCOV version 1.16