From a7ed0531b30c0a1ed380598ca10ce9117666686a Mon Sep 17 00:00:00 2001
From: Giovanni Bussi <giovanni.bussi@gmail.com>
Date: Mon, 29 May 2017 15:36:26 +0200
Subject: [PATCH] Implemented ENDPLUMED action

Fixes #236
---
 src/core/PlumedMain.cpp    |  5 ++-
 src/core/PlumedMain.h      | 11 +++++
 src/generic/EndPlumed.cpp  | 82 ++++++++++++++++++++++++++++++++++++++
 user-doc/Miscelaneous.md   |  2 +-
 user-doc/plumed-syntax.awk |  6 +++
 5 files changed, 103 insertions(+), 3 deletions(-)
 create mode 100644 src/generic/EndPlumed.cpp

diff --git a/src/core/PlumedMain.cpp b/src/core/PlumedMain.cpp
index 0c5ee1415..c5066b457 100644
--- a/src/core/PlumedMain.cpp
+++ b/src/core/PlumedMain.cpp
@@ -73,6 +73,7 @@ PlumedMain::PlumedMain():
   citations(*new Citations),
   step(0),
   active(false),
+  endPlumed(false),
   atoms(*new Atoms(*this)),
   actionSet(*new ActionSet(*this)),
   bias(0.0),
@@ -512,7 +513,8 @@ void PlumedMain::readInputFile(std::string str) {
   ifile.open(str);
   ifile.allowNoEOL();
   std::vector<std::string> words;
-  while(Tools::getParsedLine(ifile,words) && words[0]!="ENDPLUMED") readInputWords(words);
+  while(Tools::getParsedLine(ifile,words) && !endPlumed) readInputWords(words);
+  endPlumed=false;
   log.printf("END FILE: %s\n",str.c_str());
   log.flush();
 
@@ -535,7 +537,6 @@ void PlumedMain::readInputLine(const std::string & str) {
 void PlumedMain::readInputWords(const std::vector<std::string> & words) {
   plumed_assert(initialized);
   if(words.empty())return;
-  else if(words[0]=="ENDPLUMED") return;
   else if(words[0]=="_SET_SUFFIX") {
     plumed_assert(words.size()==2);
     setSuffix(words[1]);
diff --git a/src/core/PlumedMain.h b/src/core/PlumedMain.h
index ad2662844..64fda6f07 100644
--- a/src/core/PlumedMain.h
+++ b/src/core/PlumedMain.h
@@ -104,6 +104,10 @@ private:
 /// Name of the input file
   std::string plumedDat;
 
+/// End of input file.
+/// Set to true to terminate reading
+  bool endPlumed;
+
 /// Object containing information about atoms (such as positions,...).
   Atoms&    atoms;           // atomic coordinates
 
@@ -330,6 +334,8 @@ public:
   void updateFlagsPop();
 /// Get top of update flags
   bool updateFlagsTop();
+/// Set end of input file
+  void setEndPlumed();
 };
 
 /////
@@ -395,6 +401,11 @@ bool PlumedMain::updateFlagsTop() {
   return updateFlags.top();
 }
 
+inline
+void PlumedMain::setEndPlumed() {
+  endPlumed=true;
+}
+
 }
 
 #endif
diff --git a/src/generic/EndPlumed.cpp b/src/generic/EndPlumed.cpp
new file mode 100644
index 000000000..fd8c57ff5
--- /dev/null
+++ b/src/generic/EndPlumed.cpp
@@ -0,0 +1,82 @@
+/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+   Copyright (c) 2011-2017 The plumed team
+   (see the PEOPLE file at the root of the distribution for a list of names)
+
+   See http://www.plumed.org for more information.
+
+   This file is part of plumed, version 2.
+
+   plumed is free software: you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   plumed is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with plumed.  If not, see <http://www.gnu.org/licenses/>.
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+#include "core/ActionRegister.h"
+#include "core/ActionSet.h"
+#include "core/PlumedMain.h"
+
+using namespace std;
+
+namespace PLMD {
+namespace generic {
+
+//+PLUMEDOC GENERIC ENDPLUMED
+/*
+Terminate plumed input.
+
+Can be used to effectively comment out the rest of the input file.
+It can be useful to quickly ignore part of a long input file. However,
+one should keep in mind that when opening the file it might be difficult to
+find where the commented out part begins. Regular comments (with `#`) are
+usually easier to read. Notice that \ref VimSyntax "VIM syntax" should be able
+to detect this command and properly mark the rest of the file as a comment,
+although since vim doesn't parse the whole file it might fail in doing so for long
+input files.
+
+\par Examples
+
+\plumedfile
+d: DISTANCE ATOMS=1,10
+PRINT ARG=d FILE=COLVAR STRIDE=10
+ENDPLUMED
+commands here are ignored
+PRINT ARG=d FILE=COLVAR STRIDE=1
+\endplumedfile
+
+*/
+//+ENDPLUMEDOC
+class EndPlumed:
+  public Action
+{
+public:
+  explicit EndPlumed(const ActionOptions&ao);
+/// Register all the relevant keywords for the action
+  static void registerKeywords( Keywords& keys );
+  void calculate() {}
+  void apply() {}
+};
+
+PLUMED_REGISTER_ACTION(EndPlumed,"ENDPLUMED")
+
+void EndPlumed::registerKeywords( Keywords& keys ) {
+  Action::registerKeywords( keys );
+}
+
+EndPlumed::EndPlumed(const ActionOptions&ao):
+  Action(ao)
+{
+  checkRead();
+  plumed.setEndPlumed();
+}
+
+}
+}
+
diff --git a/user-doc/Miscelaneous.md b/user-doc/Miscelaneous.md
index dc706f0fa..dfc8e1bcb 100644
--- a/user-doc/Miscelaneous.md
+++ b/user-doc/Miscelaneous.md
@@ -25,7 +25,7 @@ UPPER_WALLS ARG=d1 AT=3.0 KAPPA=3.0 LABEL=Snout # In this same interlude it doth
 \endplumedfile
 (see \ref DISTANCE and \ref UPPER_WALLS)
 
-An alternative to including comments in this way is to use line starting ENDPLUMED.  Everything in the PLUMED input after this
+An alternative to including comments in this way is to use the command \subpage ENDPLUMED.  Everything in the PLUMED input after this
 keyword will be ignored.
 
 \page ContinuationLines Continuation lines
diff --git a/user-doc/plumed-syntax.awk b/user-doc/plumed-syntax.awk
index 7d261bca4..116b5e70d 100755
--- a/user-doc/plumed-syntax.awk
+++ b/user-doc/plumed-syntax.awk
@@ -1,6 +1,7 @@
 {
   if(match($0,"BEGIN_PLUMED_FILE")){
     inside=1;
+    endplumed=0;
     sub("BEGIN_PLUMED_FILE","");
     print;
     next;
@@ -18,6 +19,7 @@
 # DRAFT LINK TO DOC:
  copy=$0
  sub("#.*","",copy);
+ if(endplumed) copy="";
  nw=split(copy,words);
  if(match(words[1],".*:$")){
    action=words[2];
@@ -25,6 +27,9 @@
    action=words[1];
  }
  if(action=="__FILL__") action=""
+ if(action=="ENDPLUMED"){
+   endplumed=1;
+ }
  actionx="";
  for(i=1;i<=length(action);i++){
    letter=substr(action,i,1);
@@ -50,5 +55,6 @@
 #  sub("#","<span style=\"color:blue\">#");
 #  if(match($0,"span style=")) $0=$0 "</span>";
   sub("#.*$","<span style=\"color:blue\">&</span>");
+  if(endplumed) sub("^.*$","<span style=\"color:blue\">&</span>");
   print
 }
-- 
GitLab