1/***** 2 * runfile.in 3 * 4 * Runtime functions for file operations. 5 * 6 *****/ 7 8file* => primFile() 9 10#include "fileio.h" 11#include "callable.h" 12#include "triple.h" 13#include "array.h" 14 15#ifdef __CYGWIN__ 16extern "C" int mkstemp(char *c); 17#endif 18 19using namespace camp; 20using namespace settings; 21using namespace vm; 22 23string commentchar="#"; 24 25// Autogenerated routines: 26 27 28bool ==(file *a, file *b) 29{ 30 return a == b; 31} 32 33bool !=(file *a, file *b) 34{ 35 return a != b; 36} 37 38file* :nullFile() 39{ 40 return &camp::nullfile; 41} 42 43file* input(string name=emptystring, bool check=true, 44 string comment=commentchar, string mode=emptystring) 45{ 46 file *f=NULL; 47 if(mode == "binary") { 48 f=new ibfile(name,check); 49 } else if(mode == "xdr") { 50#ifdef HAVE_RPC_RPC_H 51 f=new ixfile(name,check); 52#else 53 ostringstream buf; 54 buf << name << ": XDR read support not enabled"; 55 error(buf); 56#endif 57 } else if(mode == "") { 58 char c=comment.empty() ? (char) 0 : comment[0]; 59 f=new ifile(name,c,check); 60 } else { 61 f=NULL; 62 ostringstream buf; 63 buf << name << ": invalid file mode '" << mode << "'"; 64 error(buf); 65 } 66 67 f->open(); 68 return f; 69} 70 71file* output(string name=emptystring, bool update=false, 72 string comment=commentchar, string mode=emptystring) 73{ 74 file *f=NULL; 75 if(mode == "pipe") { 76 f=new opipe(name); 77 } else if(mode == "binary") { 78 if(update) f=new iobfile(name); 79 else f=new obfile(name); 80 } else if(mode == "xdr") { 81#ifdef HAVE_RPC_RPC_H 82 if(update) 83 f=new ioxfile(name); 84 else f=new oxfile(name); 85#else 86 ostringstream buf; 87 buf << name << ": XDR write support not enabled"; 88 error(buf); 89#endif 90 } else if(mode == "") { 91 if(update) { 92 char c=comment.empty() ? (char) 0 : comment[0]; 93 f=new iofile(name,c); 94 } else f=new ofile(name); 95 } else { 96 f=NULL; 97 ostringstream buf; 98 buf << name << ": invalid file mode '" << mode << "'"; 99 error(buf); 100 } 101 102 f->open(); 103 if(update) f->seek(0,false); 104 105 return f; 106} 107 108bool eof(file *f) 109{ 110 return f->eof(); 111} 112 113bool eol(file *f) 114{ 115 return f->eol(); 116} 117 118bool error(file *f) 119{ 120 return f->error(); 121} 122 123void clear(file *f) 124{ 125 f->clear(); 126} 127 128void close(file *f) 129{ 130 f->close(); 131} 132 133Int precision(file *f=NULL, Int digits=0) 134{ 135 if(f == 0) f=&camp::Stdout; 136 return f->precision(digits); 137} 138 139void flush(file *f) 140{ 141 f->flush(); 142} 143 144string getc(file *f) 145{ 146 char c=0; 147 if(f->isOpen()) f->read(c); 148 static char str[1]; 149 str[0]=c; 150 return string(str); 151} 152 153Int tell(file *f) 154{ 155 return f->tell(); 156} 157 158void seek(file *f, Int pos) 159{ 160 f->seek(pos,pos >= 0); 161} 162 163void seekeof(file *f) 164{ 165 f->seek(0,false); 166} 167 168string :namePart(file f) 169{ 170 return f.filename(); 171} 172 173string :modePart(file f) 174{ 175 return f.FileMode(); 176} 177 178// Set file dimensions 179file* :dimensionSetHelper(Int nx=-1, Int ny=-1, Int nz=-1, file *f) 180{ 181 f->dimension(nx,ny,nz); 182 return f; 183} 184 185callable* :dimensionSet(file *f) 186{ 187 return new thunk(new bfunc(dimensionSetHelper),f); 188} 189 190array * :dimensionPart(file f) 191{ 192 array *a=new array(3); 193 (*a)[0]=f.Nx(); 194 (*a)[1]=f.Ny(); 195 (*a)[2]=f.Nz(); 196 return a; 197} 198 199// Set file f to read arrays in line-at-a-time mode 200file* :lineSetHelper(bool b=true, file *f) 201{ 202 f->LineMode(b); 203 return f; 204} 205 206callable* :lineSet(file *f) 207{ 208 return new thunk(new bfunc(lineSetHelper),f); 209} 210 211bool :linePart(file f) 212{ 213 return f.LineMode(); 214} 215 216// Set file to read comma-separated values 217file* :csvSetHelper(bool b=true, file *f) 218{ 219 f->CSVMode(b); 220 return f; 221} 222 223callable* :csvSet(file *f) 224{ 225 return new thunk(new bfunc(csvSetHelper),f); 226} 227 228bool :csvPart(file f) 229{ 230 return f.CSVMode(); 231} 232 233// Set file to read whitespace-separated values 234file* :wordSetHelper(bool b=true, file *f) 235{ 236 f->WordMode(b); 237 return f; 238} 239 240callable* :wordSet(file *f) 241{ 242 return new thunk(new bfunc(wordSetHelper),f); 243} 244 245bool :wordPart(file f) 246{ 247 return f.WordMode(); 248} 249 250// Set file to read/write single precision real XDR values. 251file* :singlerealSetHelper(bool b=true, file *f) 252{ 253 f->SingleReal(b); 254 return f; 255} 256 257callable* :singlerealSet(file *f) 258{ 259 return new thunk(new bfunc(singlerealSetHelper),f); 260} 261 262bool :singlerealPart(file f) 263{ 264 return f.SingleReal(); 265} 266 267// Set file to read/write single precision int XDR values. 268file* :singleintSetHelper(bool b=true, file *f) 269{ 270 f->SingleInt(b); 271 return f; 272} 273 274callable* :singleintSet(file *f) 275{ 276 return new thunk(new bfunc(singleintSetHelper),f); 277} 278 279bool :singleintPart(file f) 280{ 281 return f.SingleInt(); 282} 283 284// Set file to read/write signed int XDR values. 285file* :signedintSetHelper(bool b=true, file *f) 286{ 287 f->SignedInt(b); 288 return f; 289} 290 291callable* :signedintSet(file *f) 292{ 293 return new thunk(new bfunc(signedintSetHelper),f); 294} 295 296bool :signedintPart(file f) 297{ 298 return f.SignedInt(); 299} 300 301// Set file to read an arrayi (i int sizes followed by an i-dimensional array) 302file* :readSetHelper(Int i, file *f) 303{ 304 switch(i) { 305 case 1: 306 f->dimension(-2); 307 break; 308 309 case 2: 310 f->dimension(-2,-2); 311 break; 312 313 case 3: 314 f->dimension(-2,-2,-2); 315 break; 316 317 default: 318 f->dimension(); 319 } 320 321 return f; 322} 323 324callable* :readSet(file *f) 325{ 326 return new thunk(new bfunc(readSetHelper),f); 327} 328 329// Delete file named s. 330Int delete(string s) 331{ 332 s=outpath(s); 333 Int rc=unlink(s.c_str()); 334 if(rc == 0 && verbose > 0) 335 cout << "Deleted " << s << endl; 336 return rc; 337} 338 339// Rename file "from" to file "to". 340Int rename(string from, string to) 341{ 342 from=outpath(from); 343 to=outpath(to); 344 Int rc=rename(from.c_str(),to.c_str()); 345 if(rc == 0 && verbose > 0) 346 cout << "Renamed " << from << " to " << to << endl; 347 return rc; 348} 349 350// Create a unique temporary file name. 351string mktemp(string s) 352{ 353 char *S=Strdup(s+"XXXXXX"); 354 int fd=mkstemp(S); 355 if(fd < 0) { 356 ostringstream buf; 357 buf << "Could not create unique temporary filename based on " << s; 358 error(buf); 359 } 360 return S; 361} 362