LCOV - code coverage report
Current view: top level - tools - TokenizedLine.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 56 71 78.9 %
Date: 2026-11-05 10:19:04 Functions: 10 15 66.7 %

          Line data    Source code
       1             : 
       2             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       3             :    Copyright (c) 2025 The plumed team
       4             :    (see the PEOPLE file at the root of the distribution for a list of names)
       5             : 
       6             :    See http://www.plumed.org for more information.
       7             : 
       8             :    This file is part of plumed, version 2.
       9             : 
      10             :    plumed is free software: you can redistribute it and/or modify
      11             :    it under the terms of the GNU Lesser General Public License as published by
      12             :    the Free Software Foundation, either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    plumed is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU Lesser General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU Lesser General Public License
      21             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      22             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      23             : #include "TokenizedLine.h"
      24             : 
      25             : #include <iterator>
      26             : #include <string>
      27             : #include <algorithm>
      28             : 
      29             : namespace PLMD {
      30     1008845 : TokenizedLine::line wholeLineReplicas(const std::string& myLine) {
      31             : //NOTE: as now (exactly like before this PR) a vector will not accept only the first element as replicas:
      32             : // - @replicas:{1,2,3},4,5 do not work (KEY={@replicas:{1,2,3},4,5})
      33             : // - @replicas:{1,4,5},{2,4,5},{3,4,5} works (KEY=@replicas:{{1,4,5},{2,4,5},{3,4,5}}), it should be equivalent to the line above
      34             : // - 1,@replicas:{2,3,4},5 works (KEY={1,@replicas{2,3,4},5})
      35             : // the problem will be solved by passing to TokenizedLine the line with the first parentheses not removed
      36             : //
      37     1008845 :   if(Tools::startWith(myLine,Tools::replicaToken)) {
      38             :     auto tr = Tools::getWords(
      39         136 :                 myLine.substr(Tools::replicaToken.length()),
      40          68 :                 "\t\n ,");
      41          68 :     tr.insert(tr.begin(),myLine);
      42             :     return tr;
      43          68 :   } else {
      44     2017554 :     return {myLine};
      45             :   }
      46     1008777 : }
      47             : 
      48             : inline auto render(const TokenizedLine::line& l) {
      49      316004 :   return l[0];
      50             : }
      51             : 
      52             : template <typename IT>
      53       66033 : auto mapCreator(IT k, IT const end) {
      54             :   TokenizedLine::mapType toret;
      55     1098847 :   for (; k!=end; ++k) {
      56     1032814 :     auto eqpos=k->find('=');
      57             :     // We do not want to modify the original line
      58     1032814 :     std::string key = k->substr(0,eqpos);
      59             :     std::transform(key.begin(),key.end(),key.begin(),::toupper);
      60     1032814 :     if(eqpos != std::string::npos) {
      61     3026535 :       toret[key]=wholeLineReplicas(k->substr(eqpos+1));
      62             :     } else {
      63             :       //is a flag
      64             :       //maybe giving it a special value to confirm that it is indeed a flag?
      65       23969 :       toret[key].emplace_back("");
      66             :     }
      67             :   }
      68       66033 :   return toret;
      69             : }
      70             : 
      71           0 : TokenizedLine::TokenizedLine(vectorIt begin, vectorIt end):
      72           0 :   tokens(mapCreator(begin, end)) {}
      73             : 
      74       66033 : TokenizedLine::TokenizedLine(const_vectorIt begin,
      75       66033 :                              const_vectorIt end):
      76       66033 :   tokens(mapCreator(begin, end)) {}
      77             : 
      78           0 : TokenizedLine::TokenizedLine(const std::vector<std::string>& dataline):
      79           0 :   PLMD::TokenizedLine(dataline.begin(),dataline.end()) {}
      80             : 
      81       16686 : std::string TokenizedLine::convertToString(bool alsoClear) {
      82             :   std::string output;
      83      332687 :   for(auto p=tokens.begin(); p!=tokens.end(); ++p) {
      84             :     auto tmp = render(p->second);
      85      316001 :     if( tmp.find(" " )!=std::string::npos ) {
      86        1692 :       output += " " + p->first+ "={" + tmp + "}";
      87             :     } else {
      88      946311 :       output += " "+ p->first+ "=" + tmp;
      89             :     }
      90             :   }
      91       16686 :   if(alsoClear) {
      92             :     tokens.clear();
      93             :   }
      94       16686 :   return output;
      95             : }
      96             : 
      97           2 : std::string TokenizedLine::keyList(std::string_view sep ) {
      98           2 :   std::string mylist="";
      99             :   int i=0;
     100           2 :   std::string separator = "";
     101           4 :   for(const auto & l:tokens) {
     102           2 :     mylist = mylist + separator + l.first;
     103           2 :     if(i==0) {
     104           2 :       separator = std::string(sep);
     105           2 :       ++i;
     106             :     }
     107             :   }
     108           2 :   return mylist;
     109           4 : }
     110             : 
     111           0 : std::size_t TokenizedLine::size() const {
     112           0 :   return tokens.size();
     113             : }
     114             : 
     115       84447 : bool TokenizedLine::empty() const {
     116       84447 :   return tokens.empty();
     117             : }
     118             : 
     119           3 : std::string TokenizedLine::getKeyword(std::string_view key) const {
     120             :   auto keyArg = tokens.find(key);
     121           3 :   if( keyArg != tokens.end()) {
     122           6 :     return std::string(key) +"="+ render(keyArg->second);
     123             :   }
     124           0 :   return "";
     125             : }
     126             : 
     127      158904 : bool TokenizedLine::readAndRemoveFlag(std::string_view key) {
     128             :   auto keytext = tokens.find(key);
     129      158904 :   if(keytext != tokens.end()) {
     130       23962 :     tokens.erase(keytext);
     131       23962 :     return true;
     132             :   }
     133             :   return false;
     134             : }
     135             : 
     136        4508 : bool TokenizedLine::renameKey(std::string_view key, std::string_view newkey) {
     137             :   auto keytext = tokens.find(key);
     138        4519 :   if(keytext == tokens.end() || tokens.find(newkey) != tokens.end()) {
     139        4497 :     return false;
     140             :   }
     141             :   auto value = std::move(keytext->second);
     142          11 :   tokens.erase(keytext);
     143          22 :   tokens.emplace(std::string(newkey),std::move(value));
     144             :   return true;
     145          11 : }
     146             : 
     147           0 : std::string TokenizedLine::getValue(std::string_view key, int rep) const {
     148             :   auto keyArg = tokens.find(key);
     149           0 :   rep = (rep<0) ? -1:rep;
     150           0 :   if( keyArg != tokens.end()) {
     151           0 :     if (keyArg->second.size() == 1) {
     152           0 :       return keyArg->second[0];
     153             :     } else {
     154           0 :       if (rep < static_cast<long long int>(keyArg->second.size())-1) {
     155           0 :         return keyArg->second[rep+1];
     156             :       }
     157             :     }
     158             :   }
     159           0 :   return "";
     160             : }
     161      692749 : std::string_view TokenizedLine::replica(const line& l,int rep) {
     162      692749 :   rep = (rep<0) ? -1:rep;
     163      692749 :   if (l.size() == 1) {
     164             :     return l[0];
     165             :   } else {
     166             :     //TODO: check that this does not go rep> l.size()
     167          50 :     return l[rep+1];
     168             : 
     169             :   }
     170             : }
     171             : } // namespace PLMD
     172             : 

Generated by: LCOV version 1.16