LCOV - code coverage report
Current view: top level - core - CLTool.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 24 34 70.6 %
Date: 2024-10-11 08:09:47 Functions: 11 14 78.6 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2012-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             : #ifndef __PLUMED_core_CLTool_h
      23             : #define __PLUMED_core_CLTool_h
      24             : #include <cstdio>
      25             : #include <vector>
      26             : #include <string>
      27             : #include <cstdio>
      28             : #include "tools/Tools.h"
      29             : #include "tools/Keywords.h"
      30             : 
      31             : namespace PLMD {
      32             : 
      33             : class Communicator;
      34             : 
      35        4690 : class CLToolOptions {
      36             :   friend class CLTool;
      37             :   friend class CLToolRegister;
      38             : private:
      39             :   std::vector<std::string> line;
      40             : /// The documentation for this command line tool
      41             :   const Keywords& keys;
      42             :   static Keywords emptyKeys;
      43             : public:
      44             :   explicit CLToolOptions(const std::string &name);
      45             :   CLToolOptions(const CLToolOptions& co, const Keywords& k);
      46             : };
      47             : 
      48             : /**
      49             : \ingroup INHERIT
      50             : This is the abstract base class to use for implementing new command line tool, within it there
      51             : is \ref AddingACLTool "information" as to how to go about implemneting a new tool.
      52             : */
      53             : 
      54             : class CLTool {
      55             : private:
      56             : /// The name of this command line tool
      57             :   const std::string name;
      58             : /// The list of keywords for this CLTool
      59             :   const Keywords& keywords;
      60             : /// The data read in from the command line stored in a map with the keywords
      61             :   std::map<std::string,std::string> inputData;
      62             : /// Read the arguments from the command line
      63             :   bool readCommandLineArgs( int argc, char**argv, FILE*out );
      64             : /// Read the arguments from an input file specified on the command line
      65             :   bool readInputFile( int argc, char**argv, FILE* in, FILE*out );
      66             : /// Set arguments from the default options provided to Keywords
      67             :   void setRemainingToDefault(FILE* out);
      68             : public:
      69             : /// Set the input data:
      70             :   void setInputData(const std::map<std::string,std::string>&inputData) {
      71             :     this->inputData=inputData;
      72           0 :   }
      73             :   const std::map<std::string,std::string>&getInputData() {
      74             :     return this->inputData;
      75             :   }
      76             : protected:
      77             : /// Get the value of one of the command line arguments
      78             :   template<class T>
      79             :   bool parse(const std::string&key,T&t);
      80             : /// Find out whether one of the command line flags is present or not
      81             :   void parseFlag(const std::string&key,bool&t);
      82             : /// Crash the command line tool with an error
      83             :   [[noreturn]] void error(const std::string& msg);
      84             :   template<class T>
      85             :   bool parseVector(const std::string&key,std::vector<T>&t);
      86             : public:
      87             : /// How is the input specified on the command line or in an input file
      88             :   enum {unset,commandline,ifile} inputdata;
      89             : /// Create the help keywords
      90             :   static void registerKeywords( Keywords& keys );
      91             :   explicit CLTool(const CLToolOptions& co );
      92             : /// Read the arguments from the command line
      93             :   bool readInput( int argc, char**argv, FILE* in, FILE*out );
      94             : /// virtual function mapping to the specific main for each tool
      95             :   virtual int main( FILE* in, FILE*out, Communicator&pc )=0;
      96             : /// virtual function returning a one-line descriptor for the tool
      97           0 :   virtual std::string description()const {return "(no description available)";}
      98             : /// virtual destructor to allow inheritance
      99        2345 :   virtual ~CLTool() {}
     100             : };
     101             : 
     102             : template<class T>
     103       23694 : bool CLTool::parse(const std::string&key,T&t) {
     104       23694 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
     105       47388 :   if(keywords.style(key,"compulsory") ) {
     106           0 :     if(inputData.count(key)==0) error("missing data for keyword " + key);
     107        3709 :     bool check=Tools::convertNoexcept(inputData[key],t);
     108        3709 :     if(!check) error("data input for keyword " + key + " has wrong type");
     109             :     return true;
     110             :   }
     111       18243 :   if( inputData.count(key)==0 ) return false;
     112        1742 :   Tools::convert(inputData[key],t);
     113        1742 :   return true;
     114             : }
     115             : // very limited support and check: take more from core/Action.h parseVector
     116             : template<class T>
     117         366 : bool CLTool::parseVector(const std::string&key,std::vector<T>&t) {
     118             : 
     119             :   // Check keyword has been registered
     120         366 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
     121             :   // initial size
     122         366 :   unsigned size=t.size();
     123             :   bool skipcheck=false;
     124         366 :   if(size==0) skipcheck=true; // if the vector in input has size zero, skip the check if size of input vector is the same of argument read
     125             : 
     126             :   // check if there is some value
     127             : 
     128         732 :   plumed_massert(inputData[key]!="false","compulsory keyword "+std::string(key)+"has no data");
     129         366 :   std::vector<std::string> words=Tools::getWords(inputData[key],"\t\n ,");
     130         366 :   t.resize(0);
     131         366 :   if(words.size()==0)return false;
     132             : 
     133         773 :   for(unsigned i=0; i<words.size(); ++i) {
     134             :     T v;
     135         487 :     Tools::convert(words[i],v);
     136         487 :     t.push_back(v);
     137             :   }
     138             :   // check the size
     139         286 :   if( !skipcheck && t.size()!=size ) {
     140           0 :     plumed_merror("vector read in for keyword  "+key+" has wrong size" );
     141             :   }
     142             :   std::string def;
     143             :   T val;
     144         572 :   if ( keywords.style(key,"compulsory") && t.size()==0 ) {
     145           0 :     if( keywords.getDefaultValue(key,def) ) {
     146           0 :       if( def.length()==0 || !Tools::convertNoexcept(def,val) ) {
     147           0 :         plumed_merror("ERROR in keyword "+key+ " has weird default value" );
     148             :       } else {
     149             :         // GB: before it was like this, but clearly if t.size()==0 this was not doing anything
     150             :         // for(unsigned i=0; i<t.size(); ++i) t[i]=val;
     151           0 :         t.resize(1);
     152           0 :         t[0]=val;
     153             :       }
     154             :     } else {
     155           0 :       plumed_merror("keyword " + key + " is compulsory for this action");
     156             :     }
     157             :   }
     158             :   return true;
     159         366 : }
     160             : 
     161             : 
     162             : 
     163             : }
     164             : 
     165             : #endif

Generated by: LCOV version 1.15