Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2011-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 "ActionRegister.h"
23 : #include "tools/Tools.h"
24 : #include "Action.h"
25 : #include <algorithm>
26 : #include <iostream>
27 :
28 :
29 : using namespace std;
30 : namespace PLMD {
31 :
32 1682 : ActionRegister::~ActionRegister() {
33 841 : if(m.size()>0) {
34 0 : string names="";
35 0 : for(mIterator p=m.begin(); p!=m.end(); ++p)names+=p->first+" ";
36 0 : std::cerr<<"WARNING: Directive "+ names +" has not been properly unregistered. This might lead to memory leak!!\n";
37 : }
38 841 : }
39 :
40 271790 : ActionRegister& actionRegister() {
41 271790 : static ActionRegister ans;
42 271790 : return ans;
43 : }
44 :
45 134561 : void ActionRegister::remove(creator_pointer f) {
46 6220917 : for(mIterator p=m.begin(); p!=m.end(); ++p) {
47 6220917 : if((*p).second==f) {
48 134561 : m.erase(p); break;
49 : }
50 : }
51 134561 : }
52 :
53 134561 : void ActionRegister::add(string key,creator_pointer f,keywords_pointer k) {
54 134561 : if(m.count(key)) {
55 0 : m.erase(key);
56 0 : disabled.insert(key);
57 : } else {
58 134561 : m.insert(pair<string,creator_pointer>(key,f));
59 : // Store a pointer to the function that creates keywords
60 : // A pointer is stored and not the keywords because all
61 : // Vessels must be dynamically loaded before the actions.
62 134561 : mk.insert(pair<string,keywords_pointer>(key,k));
63 : };
64 134561 : }
65 :
66 2507 : bool ActionRegister::check(string key) {
67 2507 : if(m.count(key)>0 && mk.count(key)>0) return true;
68 0 : return false;
69 : }
70 :
71 2347 : Action* ActionRegister::create(const ActionOptions&ao) {
72 2347 : if(ao.line.size()<1)return NULL;
73 : // Create a copy of the manual locally. The manual is
74 : // then added to the ActionOptions. This allows us to
75 : // ensure during construction that all the keywords for
76 : // the action have been documented. In addition, we can
77 : // generate the documentation when the user makes an error
78 : // in the input.
79 : Action* action;
80 2347 : if( check(ao.line[0]) ) {
81 2347 : Keywords keys; mk[ao.line[0]](keys);
82 4694 : ActionOptions nao( ao,keys );
83 2347 : action=m[ao.line[0]](nao);
84 4694 : keys.destroyData();
85 0 : } else action=NULL;
86 2347 : return action;
87 : }
88 :
89 160 : bool ActionRegister::printManual( const std::string& action, const bool& vimout ) {
90 160 : if ( check(action) ) {
91 160 : Keywords keys; mk[action](keys);
92 160 : if( vimout ) {
93 160 : printf("%s",action.c_str()); keys.print_vim(); printf("\n");
94 : } else {
95 0 : keys.print_html();
96 : }
97 160 : keys.destroyData();
98 160 : return true;
99 : } else {
100 0 : return false;
101 : }
102 : }
103 :
104 0 : bool ActionRegister::printTemplate( const std::string& action, bool include_optional ) {
105 0 : if( check(action) ) {
106 0 : Keywords keys; mk[action](keys);
107 0 : keys.print_template(action, include_optional); keys.destroyData();
108 0 : return true;
109 : } else {
110 0 : return false;
111 : }
112 : }
113 :
114 161 : std::ostream & operator<<(std::ostream &log,const ActionRegister&ar) {
115 161 : vector<string> s;
116 25922 : for(ActionRegister::const_mIterator it=ar.m.begin(); it!=ar.m.end(); ++it)
117 25761 : s.push_back((*it).first);
118 161 : sort(s.begin(),s.end());
119 161 : for(unsigned i=0; i<s.size(); i++) log<<" "<<s[i]<<"\n";
120 161 : if(!ar.disabled.empty()) {
121 0 : s.assign(ar.disabled.size(),"");
122 0 : copy(ar.disabled.begin(),ar.disabled.end(),s.begin());
123 0 : sort(s.begin(),s.end());
124 0 : log<<"+++++++ WARNING +++++++\n";
125 0 : log<<"The following keywords have been registered more than once and will be disabled:\n";
126 0 : for(unsigned i=0; i<s.size(); i++) log<<" - "<<s[i]<<"\n";
127 0 : log<<"+++++++ END WARNING +++++++\n";
128 : };
129 161 : return log;
130 : }
131 :
132 :
133 2523 : }
|