All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Tools.cpp
Go to the documentation of this file.
1 /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2  Copyright (c) 2013 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-code.org for more information.
6 
7  This file is part of plumed, version 2.0.
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 <iostream>
23 #include "Tools.h"
24 #include "AtomNumber.h"
25 #include "Exception.h"
26 #include "IFile.h"
27 #include <cstring>
28 #include <dirent.h>
29 
30 using namespace std;
31 namespace PLMD{
32 
33 bool Tools::convert(const string & str,int & t){
34  istringstream istr(str.c_str());
35  bool ok=istr>>t;
36  if(!ok) return false;
37  string remaining;
38  istr>>remaining;
39  return remaining.length()==0;
40 }
41 
42 bool Tools::convert(const string & str,long int & t){
43  istringstream istr(str.c_str());
44  bool ok=istr>>t;
45  if(!ok) return false;
46  string remaining;
47  istr>>remaining;
48  return remaining.length()==0;
49 }
50 
51 bool Tools::convert(const string & str,unsigned & t){
52  istringstream istr(str.c_str());
53  bool ok=istr>>t;
54  if(!ok) return false;
55  string remaining;
56  istr>>remaining;
57  return remaining.length()==0;
58 }
59 
60 bool Tools::convert(const string & str,AtomNumber &a){
61  int i;
62  bool r=convert(str,i);
63  if(r) a.setSerial(i);
64  return r;
65 }
66 
67 bool Tools::convert(const string & str,float & t){
68  double tt;
69  bool r=convert(str,tt);
70  t=double(tt);
71  return r;
72 }
73 
74 bool Tools::convert(const string & str,double & t){
75  if(str=="PI" || str=="+PI" || str=="+pi" || str=="pi"){
76  t=pi; return true;
77  } else if(str=="-PI" || str=="-pi"){
78  t=-pi; return true;
79  } else if( str.find("PI")!=std::string::npos ){
80  std::size_t pi_start=str.find_first_of("PI");
81  if(str.substr(pi_start)!="PI") return false;
82  istringstream nstr(str.substr(0,pi_start));
83  double ff=0.0; bool ok=nstr>>ff;
84  if(!ok) return false;
85  t=ff*pi;
86  std::string remains; nstr>>remains;
87  return remains.length()==0;
88  } else if( str.find("pi")!=std::string::npos ){
89  std::size_t pi_start=str.find_first_of("pi");
90  if(str.substr(pi_start)!="pi") return false;
91  istringstream nstr(str.substr(0,pi_start));
92  double ff=0.0; bool ok=nstr>>ff;
93  if(!ok) return false;
94  t=ff*pi;
95  std::string remains; nstr>>remains;
96  return remains.length()==0;
97  }
98  istringstream istr(str.c_str());
99  bool ok=istr>>t;
100  if(!ok) return false;
101  string remaining;
102  istr>>remaining;
103  return remaining.length()==0;
104 }
105 
106 
107 bool Tools::convert(const string & str,string & t){
108  t=str;
109  return true;
110 }
111 
112 vector<string> Tools::getWords(const string & line,const char* separators,int * parlevel,const char* parenthesis){
113  plumed_massert(strlen(parenthesis)==1,"multiple parenthesis type not available");
114  plumed_massert(parenthesis[0]=='(' || parenthesis[0]=='[' || parenthesis[0]=='{',
115  "only ( [ { allowed as parenthesis");
116  if(!separators) separators=" \t\n";
117  const string sep(separators);
118  char openpar=parenthesis[0];
119  char closepar;
120  if(openpar=='(') closepar=')';
121  if(openpar=='[') closepar=']';
122  if(openpar=='{') closepar='}';
123  vector<string> words;
124  string word;
125  int parenthesisLevel=0;
126  if(parlevel) parenthesisLevel=*parlevel;
127  for(unsigned i=0;i<line.length();i++){
128  bool found=false;
129  bool onParenthesis=false;
130  if(line[i]==openpar || line[i]==closepar) onParenthesis=true;
131  if(line[i]==closepar){
132  parenthesisLevel--;
133  plumed_massert(parenthesisLevel>=0,"Extra closed parenthesis in '" + line + "'");
134  }
135  if(parenthesisLevel==0) for(unsigned j=0;j<sep.length();j++) if(line[i]==sep[j]) found=true;
136 // If at parenthesis level zero (outer)
137  if(!(parenthesisLevel==0 && (found||onParenthesis))) word.push_back(line[i]);
138  if(line[i]==openpar) parenthesisLevel++;
139  if(found && word.length()>0){
140  if(!parlevel) plumed_massert(parenthesisLevel==0,"Unmatching parenthesis in '" + line + "'");
141  words.push_back(word);
142  word.clear();
143  }
144  }
145  if(word.length()>0){
146  if(!parlevel) plumed_massert(parenthesisLevel==0,"Unmatching parenthesis in '" + line + "'");
147  words.push_back(word);
148  }
149  if(parlevel) *parlevel=parenthesisLevel;
150  return words;
151 }
152 
153 bool Tools::getParsedLine(IFile& ifile,vector<string> & words){
154  string line("");
155  words.clear();
156  bool stat;
157  bool inside=false;
158  int parlevel=0;
159  bool mergenext=false;
160  while((stat=ifile.getline(line))){
161  trimComments(line);
162  trim(line);
163  if(line.length()==0) continue;
164  vector<string> w=getWords(line,NULL,&parlevel);
165  if(w.empty()) continue;
166  if(inside && *(w.begin())=="..."){
167  inside=false;
168  if(w.size()==2) plumed_massert(w[1]==words[0],"second word in terminating \"...\" lines, if present, should be equal to first word of directive");
169  plumed_massert(w.size()<=2,"terminating \"...\" lines cannot consist of more than two words");
170  w.clear();
171  }else if(*(w.end()-1)=="..."){
172  inside=true;
173  w.erase(w.end()-1);
174  };
175  int i0=0;
176  if(mergenext && words.size()>0 && w.size()>0){
177  words[words.size()-1]+=" "+w[0];
178  i0=1;
179  }
180  for(unsigned i=i0;i<w.size();++i) words.push_back(w[i]);
181  mergenext=(parlevel>0);
182  if(!inside)break;
183  }
184  plumed_massert(parlevel==0,"non matching parenthesis");
185  if(words.size()>0) return true;
186  return stat;
187 }
188 
189 
190 bool Tools::getline(FILE* fp,string & line){
191  line="";
192  const int bufferlength=1024;
193  char buffer[bufferlength];
194  bool ret;
195  for(int i=0;i<bufferlength;i++) buffer[i]='\0';
196  while((ret=fgets(buffer,bufferlength,fp))){
197  line.append(buffer);
198  unsigned ss=strlen(buffer);
199  if(ss>0) if(buffer[ss-1]=='\n') break;
200  };
201  if(line.length()>0) if(*(line.end()-1)=='\n') line.erase(line.end()-1);
202  return ret;
203 }
204 
205 void Tools::trim(string & s){
206  size_t n=s.find_last_not_of(" \t");
207  s=s.substr(0,n+1);
208 }
209 
210 void Tools::trimComments(string & s){
211  size_t n=s.find_first_of("#");
212  s=s.substr(0,n);
213 }
214 
215 bool Tools::getKey(vector<string>& line,const string & key,string & s){
216  s.clear();
217  for(vector<string>::iterator p=line.begin();p!=line.end();++p){
218  if((*p).length()==0) continue;
219  string x=(*p).substr(0,key.length());
220  if(x==key){
221  if((*p).length()==key.length())return false;
222  string tmp=(*p).substr(key.length(),(*p).length());
223  line.erase(p);
224  s=tmp;
225  return true;
226  }
227  };
228  return false;
229 }
230 
231 void Tools::interpretRanges(std::vector<std::string>&s){
232  vector<string> news;
233  for(vector<string>::iterator p=s.begin();p!=s.end();++p){
234  vector<string> words;
235  words=getWords(*p,"-");
236  int a;
237  bool found=false;
238  if(words.size()==2 && convert(words[0],a)){
239  int b,c=1;
240  vector<string> bwords=getWords(words[1],":");
241  if(bwords.size()==2 && convert(bwords[0],b) && convert(bwords[1],c)) found=true;
242  else if(convert(words[1],b)){
243  c=1;
244  found=true;
245  }
246  if(found){
247  plumed_massert(b>=a,"interpreting ranges "+ *p + ", second number should be larger than first number");
248  plumed_massert(c>0,"interpreting ranges "+ *p + ", stride should be positive");
249  for(int i=a;i<=b;i+=c){
250  string ss;
251  convert(i,ss);
252  news.push_back(ss);
253  }
254  }
255  }
256  if(!found) news.push_back(*p);
257  }
258  s=news;
259 }
260 
261 void Tools::interpretLabel(vector<string>&s){
262  if(s.size()<2)return;
263  string s0=s[0];
264  unsigned l=s0.length();
265  if(l<1) return;
266  if(s0[l-1]==':'){
267  s[0]=s[1];
268  s[1]="LABEL="+s0.substr(0,l-1);
269  }
270 }
271 
272 vector<string> Tools::ls(const string&d){
273  DIR*dir;
274  vector<string> result;
275  if ((dir=opendir(d.c_str()))){
276  struct dirent *ent;
277  while ((ent = readdir (dir))) if(string(ent->d_name)!="." && string(ent->d_name)!="..") result.push_back(ent->d_name);
278  closedir (dir);
279  }
280  return result;
281 }
282 
283 void Tools::stripLeadingAndTrailingBlanks( std::string& str ){
284  std::size_t first=str.find_first_not_of(' ');
285  std::size_t last=str.find_last_not_of(' ');
286  if( first<=last && first!=std::string::npos) str=str.substr(first,last+1);
287 }
288 
289 std::string Tools::extension(const std::string&s){
290  size_t n=s.find_last_of(".");
291  std::string ext;
292  if(n!=std::string::npos && n+1<s.length() && n+5>=s.length()){
293  ext=s.substr(n+1);
294  if(ext.find("/")!=std::string::npos) ext="";
295  string base=s.substr(0,n);
296  if(base.length()==0) ext="";
297  if(base.length()>0 && base[base.length()-1]=='/') ext="";
298  }
299  return ext;
300 }
301 
302 }
Simple class to store the index of an atom.
Definition: AtomNumber.h:39
IFile & getline(std::string &)
Get a full line as a string.
Definition: IFile.cpp:169
STL namespace.
void const char const char int * n
Definition: Matrix.h:42
static bool convert(const std::string &str, float &t)
Convert a string to a float, reading it.
Definition: Tools.cpp:67
Class for input files.
Definition: IFile.h:40
void const char const char int double int double double int int double int double * w
Definition: Matrix.h:42
const double pi(3.141592653589793238462643383279502884197169399375105820974944592307)
PI.
void const char const char int double * a
Definition: Matrix.h:42
AtomNumber & setSerial(unsigned)
Sets the atom number by serial, returning a reference to the AtomNumber itself.
Definition: AtomNumber.h:94