LCOV - code coverage report
Current view: top level - core - CLTool.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 94 130 72.3 %
Date: 2018-12-19 07:49:13 Functions: 11 12 91.7 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2012-2018 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 "CLTool.h"
      23             : 
      24             : namespace PLMD {
      25             : 
      26         841 : Keywords CLToolOptions::emptyKeys;
      27             : 
      28         724 : CLToolOptions::CLToolOptions(const std::string &name):
      29             :   line(1,name),
      30         724 :   keys(emptyKeys)
      31             : {
      32         724 : }
      33             : 
      34         724 : CLToolOptions::CLToolOptions(const CLToolOptions& co, const Keywords& k):
      35             :   line(co.line),
      36         724 :   keys(k)
      37             : {
      38         724 : }
      39             : 
      40        5887 : void CLTool::registerKeywords( Keywords& keys ) {
      41        5887 :   keys.addFlag("--help/-h",false,"print this help");
      42        5887 : }
      43             : 
      44         724 : CLTool::CLTool(const CLToolOptions& co ):
      45         724 :   name(co.line[0]),
      46             :   keywords(co.keys),
      47        1448 :   inputdata(unset)
      48             : {
      49         724 : }
      50             : 
      51        2789 : void CLTool::parseFlag( const std::string&key, bool&t ) {
      52        2789 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
      53        2789 :   plumed_massert(keywords.style(key,"flag"),"keyword " + key + " has not been registered as a flag");
      54        2789 :   plumed_assert(inputData.count(key)>0);
      55        2789 :   if( inputData[key]=="true") t=true;
      56        2349 :   else if( inputData[key]=="false") t=false;
      57           0 :   else plumed_error();
      58        2789 : }
      59             : 
      60         724 : bool CLTool::readInput( int argc, char**argv, FILE* in, FILE*out ) {
      61         724 :   plumed_massert( inputdata!=unset,"You have not specified where your tool reads its input. "
      62             :                   "If it is from the command line (like driver) add inputdata=commandline to the "
      63             :                   "tools constructor. If it reads everything from an input file (like simplemd) "
      64           0 :                   "add inputdata=ifile to the tools constructor");
      65         724 :   if(inputdata==commandline) return readCommandLineArgs( argc, argv, out );
      66           4 :   if(inputdata==ifile) return readInputFile( argc, argv, in, out );
      67           0 :   return true;
      68             : }
      69             : 
      70         720 : bool CLTool::readCommandLineArgs( int argc, char**argv, FILE*out ) {
      71         720 :   plumed_assert(inputdata==commandline);
      72        1440 :   std::string prefix(""), a(""), thiskey;
      73             : 
      74             :   // Set all flags to default false
      75       13814 :   for(unsigned k=0; k<keywords.size(); ++k) {
      76       13094 :     thiskey=keywords.get(k);
      77       13094 :     if( keywords.style(thiskey,"flag") ) inputData.insert(std::pair<std::string,std::string>(thiskey,"false"));
      78             :   }
      79             : 
      80             :   // Read command line arguments
      81         720 :   bool printhelp=false;
      82        4172 :   for(int i=1; i<argc; i++) {
      83        3452 :     a=prefix+argv[i];
      84        3452 :     if(a.length()==0) continue;
      85        3452 :     if(a=="-h" || a=="--help") {
      86           0 :       printhelp=true;
      87             :     } else {
      88        3452 :       bool found=false;
      89      103330 :       for(unsigned k=0; k<keywords.size(); ++k) {
      90       99878 :         thiskey=keywords.get(k);
      91       99878 :         if( keywords.style(thiskey,"flag") ) {
      92       13971 :           if( a==thiskey ) { found=true; inputData[thiskey]="true"; }
      93             :         } else {
      94       85907 :           if( a==thiskey ) {
      95        1387 :             prefix=thiskey+"="; found=true;
      96        1387 :             inputData.insert(std::pair<std::string,std::string>(thiskey,""));
      97       84520 :           } else if(Tools::startWith(a,thiskey+"=")) {
      98        1625 :             a.erase(0,a.find("=")+1); prefix=""; found=true;
      99        1625 :             if(inputData.count(thiskey)==0) {
     100         238 :               inputData.insert(std::pair<std::string,std::string>(thiskey,a));
     101             :             } else {
     102        1387 :               inputData[thiskey]=a;
     103             :             }
     104             :           }
     105             :         }
     106             :       }
     107        3452 :       if(!found) {
     108           0 :         fprintf(stderr,"ERROR in input for command line tool %s : %s option is unknown \n\n", name.c_str(), a.c_str() );
     109           0 :         fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
     110           0 :         fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
     111           0 :         keywords.print( out );
     112           0 :         printhelp=true;
     113             :       }
     114             :     }
     115        3452 :     if(printhelp) break;
     116             :   }
     117             : 
     118         720 :   if(!printhelp) setRemainingToDefault(out);
     119             : 
     120         720 :   if(printhelp) {
     121           0 :     fprintf(out,"Usage: %s [options] \n\n", name.c_str() );
     122           0 :     keywords.print( out );
     123             :   }
     124             : 
     125        1440 :   return !printhelp;
     126             : }
     127             : 
     128         724 : void CLTool::setRemainingToDefault(FILE* out) {
     129        1448 :   std::string def, thiskey;
     130       13874 :   for(unsigned k=0; k<keywords.size(); ++k) {
     131       13150 :     thiskey=keywords.get(k);
     132       13150 :     if( keywords.style(thiskey,"compulsory") ) {
     133        1368 :       if( inputData.count(thiskey)==0 ) {
     134         461 :         if( keywords.getDefaultValue(thiskey,def) ) {
     135         461 :           plumed_assert( def.length()>0 );
     136         461 :           inputData.insert(std::pair<std::string,std::string>(thiskey,def));
     137             :         } else {
     138           0 :           fprintf(out,"ERROR : argument %s is compulsory. Use --help option for help\n",thiskey.c_str() );
     139           0 :           plumed_error();
     140             :         }
     141             :       }
     142             :     }
     143         724 :   }
     144         724 : }
     145             : 
     146           4 : bool CLTool::readInputFile( int argc, char**argv, FILE* in, FILE*out ) {
     147           4 :   plumed_assert(inputdata==ifile);
     148             : 
     149             :   // Check if use is just asking for help
     150           4 :   std::string a;
     151           4 :   for(int i=1; i<argc; i++) {
     152           0 :     a=argv[i];
     153           0 :     if(a.length()==0) continue;
     154           0 :     if(a=="-h" || a=="--help") {
     155           0 :       fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
     156           0 :       fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
     157           0 :       keywords.print( out );
     158           0 :       return false;
     159             :     }
     160             :   }
     161             : 
     162           4 :   FILE* mystdin=in;
     163           4 :   if(argc==2) {
     164           0 :     mystdin=fopen(argv[1],"r");
     165           0 :     if(!mystdin) {
     166           0 :       fprintf(stderr,"ERROR: cannot open file %s\n\n",argv[1]);
     167           0 :       fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
     168           0 :       fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
     169           0 :       keywords.print( out );
     170           0 :       return false;
     171             :     }
     172             :   }
     173             : 
     174           4 :   plumed_assert(mystdin);
     175             : 
     176           8 :   char buffer[256]; std::string line; line.resize(256);
     177          50 :   while(fgets(buffer,256,mystdin)) {
     178          42 :     line=buffer;
     179          42 :     for(unsigned i=0; i<line.length(); ++i) if(line[i]=='#' || line[i]=='\n') line.erase(i);
     180          42 :     Tools::stripLeadingAndTrailingBlanks( line );
     181          42 :     if(line.length()==0) continue;
     182          42 :     sscanf(line.c_str(),"%255s",buffer);
     183          42 :     std::string keyword=buffer; bool found=false;
     184         630 :     for(unsigned i=0; i<keywords.size(); ++i) {
     185         588 :       std::string thiskey=keywords.get(i);
     186         588 :       if(thiskey==keyword) {
     187          42 :         found=true;
     188          42 :         std::size_t keypos=line.find_first_of(keyword)+keyword.length();
     189          42 :         inputData.insert(std::pair<std::string,std::string>(thiskey,line.substr(keypos)));
     190          42 :         Tools::stripLeadingAndTrailingBlanks( inputData[thiskey] );
     191             :       }
     192         588 :     }
     193          42 :     if(!found) {
     194           0 :       fprintf(stderr,"ERROR in input for command line tool %s : unknown keyword %s found in input file\n\n",name.c_str(),keyword.c_str());
     195           0 :       fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
     196           0 :       fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
     197           0 :       keywords.print( out );
     198           0 :       fclose(mystdin);
     199           0 :       return false;
     200             :     }
     201          42 :   }
     202             : 
     203           4 :   if(argc==2) fclose(mystdin);
     204           4 :   setRemainingToDefault(out);
     205           8 :   return true;
     206             : }
     207             : 
     208           0 : void CLTool::error( const std::string& msg ) {
     209           0 :   fprintf(stderr,"ERROR : in input for command line tool %s : %s\n",name.c_str(),msg.c_str());
     210           0 :   plumed_error();
     211             : }
     212             : 
     213        2523 : }

Generated by: LCOV version 1.13