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 "FileBase.h"
23 : // this is required to compile test
24 : #include "File.h"
25 : #include "Exception.h"
26 : #include "core/Action.h"
27 : #include "core/PlumedMain.h"
28 : #include "core/Value.h"
29 : #include "Communicator.h"
30 : #include "Tools.h"
31 : #include <cstdarg>
32 : #include <cstring>
33 : #include <cstdlib>
34 :
35 : #include <iostream>
36 : #include <string>
37 :
38 : #ifdef __PLUMED_HAS_ZLIB
39 : #include <zlib.h>
40 : #endif
41 :
42 : namespace PLMD {
43 :
44 0 : void FileBase::test() {
45 0 : PLMD::OFile pof;
46 0 : pof.open("ciao");
47 0 : pof.printf("%s\n","test1");
48 0 : pof.setLinePrefix("plumed: ");
49 0 : pof.printf("%s\n","test2");
50 0 : pof.setLinePrefix("");
51 0 : pof.addConstantField("x2").printField("x2",67.0);
52 0 : pof.printField("x1",10.0).printField("x3",20.12345678901234567890).printField();
53 0 : pof.printField("x1",10.0).printField("x3",-1e70*20.12345678901234567890).printField();
54 0 : pof.printField("x3",10.0).printField("x2",777.0).printField("x1",-1e70*20.12345678901234567890).printField();
55 0 : pof.printField("x3",67.0).printField("x1",18.0).printField();
56 0 : pof.close();
57 :
58 0 : PLMD::IFile pif;
59 0 : std::string s;
60 0 : pif.open("ciao");
61 0 : pif.getline(s); std::printf("%s\n",s.c_str());
62 0 : pif.getline(s); std::printf("%s\n",s.c_str());
63 :
64 : int x1,x2,x3;
65 0 : while(pif.scanField("x1",x1).scanField("x3",x2).scanField("x2",x3).scanField()) {
66 0 : std::cout<<"CHECK "<<x1<<" "<<x2<<" "<<x3<<"\n";
67 : }
68 0 : pif.close();
69 0 : }
70 :
71 327 : FileBase& FileBase::link(FILE*fp) {
72 327 : plumed_massert(!this->fp,"cannot link an already open file");
73 327 : this->fp=fp;
74 327 : cloned=true;
75 327 : return *this;
76 : }
77 :
78 2290 : FileBase& FileBase::flush() {
79 2290 : if(fp) fflush(fp);
80 2290 : return *this;
81 : }
82 :
83 2373 : FileBase& FileBase::link(Communicator&comm) {
84 2373 : plumed_massert(!fp,"cannot link an already open file");
85 2373 : this->comm=&comm;
86 2373 : return *this;
87 : }
88 :
89 1214 : FileBase& FileBase::link(PlumedMain&plumed) {
90 1214 : plumed_massert(!fp,"cannot link an already open file");
91 1214 : this->plumed=&plumed;
92 1214 : link(plumed.comm);
93 1214 : return *this;
94 : }
95 :
96 918 : FileBase& FileBase::link(Action&action) {
97 918 : plumed_massert(!fp,"cannot link an already open file");
98 918 : this->action=&action;
99 918 : link(action.plumed);
100 918 : return *this;
101 : }
102 :
103 539 : bool FileBase::FileExist(const std::string& path) {
104 539 : bool do_exist=false;
105 539 : this->path=appendSuffix(path,getSuffix());
106 539 : mode="r";
107 539 : FILE *ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
108 539 : if(!ff) {
109 199 : this->path=path;
110 199 : ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
111 199 : mode="r";
112 : }
113 539 : if(ff) {do_exist=true; fclose(ff);}
114 539 : if(comm) comm->Barrier();
115 539 : return do_exist;
116 : }
117 :
118 6461 : bool FileBase::isOpen() {
119 6461 : bool isopen=false;
120 6461 : if(fp) isopen=true;
121 6461 : return isopen;
122 : }
123 :
124 279 : void FileBase::close() {
125 279 : plumed_assert(!cloned);
126 279 : eof=false;
127 279 : err=false;
128 279 : if(fp) std::fclose(fp);
129 : #ifdef __PLUMED_HAS_ZLIB
130 279 : if(gzfp) gzclose(gzFile(gzfp));
131 : #endif
132 279 : fp=NULL;
133 279 : gzfp=NULL;
134 279 : }
135 :
136 2764 : FileBase::FileBase():
137 : fp(NULL),
138 : gzfp(NULL),
139 : comm(NULL),
140 : plumed(NULL),
141 : action(NULL),
142 : cloned(false),
143 : eof(false),
144 : err(false),
145 : heavyFlush(false),
146 2764 : enforcedSuffix_(false)
147 : {
148 2764 : }
149 :
150 5504 : FileBase::~FileBase()
151 : {
152 2752 : if(plumed) plumed->eraseFile(*this);
153 2752 : if(!cloned && fp) fclose(fp);
154 : #ifdef __PLUMED_HAS_ZLIB
155 2752 : if(!cloned && gzfp) gzclose(gzFile(gzfp));
156 : #endif
157 2752 : }
158 :
159 1364824 : FileBase::operator bool()const {
160 1364824 : return !eof;
161 : }
162 :
163 1385 : std::string FileBase::appendSuffix(const std::string&path,const std::string&suffix) {
164 1385 : if(path=="/dev/null") return path; // do not append a suffix to /dev/null
165 1369 : std::string ret=path;
166 2738 : std::string ext=Tools::extension(path);
167 :
168 : // These are the recognized extensions so far:
169 : // gz xtc trr
170 : // If a file name ends with one of these extensions, the suffix is added *before*
171 : // the extension. This is useful when extensions are conventionally used
172 : // to detect file type, so as to allow easier file manipulation.
173 : // Removing this line, any extension recognized by Tools::extension() would be considered
174 : // if(ext!="gz" && ext!="xtc" && ext!="trr") ext="";
175 :
176 1369 : if(ext.length()>0) {
177 566 : int l=path.length()-(ext.length()+1);
178 566 : plumed_assert(l>=0);
179 566 : ret=ret.substr(0,l);
180 : }
181 1369 : ret+=suffix;
182 1369 : if(ext.length()>0)ret+="."+ext;
183 2738 : return ret;
184 : }
185 :
186 32 : FileBase& FileBase::enforceSuffix(const std::string&suffix) {
187 32 : enforcedSuffix_=true;
188 32 : enforcedSuffix=suffix;
189 32 : return *this;
190 : }
191 :
192 1322 : std::string FileBase::getSuffix()const {
193 1322 : if(enforcedSuffix_) return enforcedSuffix;
194 1290 : if(plumed) return plumed->getSuffix();
195 39 : return "";
196 : }
197 :
198 2523 : }
|