/***** * runfile.in * * Runtime functions for file operations. * *****/ file* => primFile() #include "fileio.h" #include "callable.h" #include "triple.h" #include "array.h" #if defined(_WIN32) #include #else #include #endif using namespace camp; using namespace settings; using namespace vm; string commentchar="#"; // Autogenerated routines: bool ==(file *a, file *b) { return a == b; } bool !=(file *a, file *b) { return a != b; } file* :nullFile() { return &camp::nullfile; } file* input(string name=emptystring, bool check=true, string comment=commentchar, string mode=emptystring) { file *f=NULL; if(mode == "binary") f=new ibfile(name,check); else if(mode == "xdr" || mode == "xdrgz") { #ifdef HAVE_LIBTIRPC if(mode == "xdr") f=new ixfile(name,check); else if(mode == "xdrgz") f=new igzxfile(name,check); #else ostringstream buf; buf << name << ": XDR read support not enabled"; error(buf); #endif } else if(mode == "") { char c=comment.empty() ? (char) 0 : comment[0]; f=new camp::ifile(name,c,check); } else { f=NULL; ostringstream buf; buf << name << ": invalid file mode '" << mode << "'"; error(buf); } f->open(); return f; } file* output(string name=emptystring, bool update=false, string comment=commentchar, string mode=emptystring) { file *f=NULL; if(mode == "pipe") { f=new opipe(name); } else if(mode == "binary") { if(update) f=new iobfile(name); else f=new obfile(name); } else if(mode == "xdr") { #ifdef HAVE_LIBTIRPC if(update) f=new ioxfile(name); else f=new oxfile(name); #else ostringstream buf; buf << name << ": XDR write support not enabled"; error(buf); #endif } else if(mode == "") { if(update) { char c=comment.empty() ? (char) 0 : comment[0]; f=new iofile(name,c); } else f=new ofile(name); } else { f=NULL; ostringstream buf; buf << name << ": invalid file mode '" << mode << "'"; error(buf); } f->open(); if(update) f->seek(0,false); return f; } bool eof(file *f) { return f->eof(); } bool eol(file *f) { return f->eol(); } bool error(file *f) { return f->error(); } void clear(file *f) { f->clear(); } void close(file *f) { f->close(); } Int precision(file *f=NULL, Int digits=0) { if(f == 0) f=&camp::Stdout; return f->precision(digits); } void flush(file *f) { f->flush(); } string getc(file *f) { char c=0; if(f->isOpen()) f->read(c); return string(1,c); } Int tell(file *f) { return f->tell(); } void seek(file *f, Int pos) { f->seek(pos,pos >= 0); } void seekeof(file *f) { f->seek(0,false); } string :namePart(file f) { return f.filename(); } string :modePart(file f) { return f.FileMode(); } // Set file dimensions file* :dimensionSetHelper(Int nx=-1, Int ny=-1, Int nz=-1, file *f) { f->dimension(nx,ny,nz); return f; } callable* :dimensionSet(file *f) { return new thunk(new bfunc(dimensionSetHelper),f); } array * :dimensionPart(file f) { array *a=new array(3); (*a)[0]=f.Nx(); (*a)[1]=f.Ny(); (*a)[2]=f.Nz(); return a; } // Set file f to read arrays in line-at-a-time mode file* :lineSetHelper(bool b=true, file *f) { f->LineMode(b); return f; } callable* :lineSet(file *f) { return new thunk(new bfunc(lineSetHelper),f); } bool :linePart(file f) { return f.LineMode(); } // Set file to read comma-separated values file* :csvSetHelper(bool b=true, file *f) { f->CSVMode(b); return f; } callable* :csvSet(file *f) { return new thunk(new bfunc(csvSetHelper),f); } bool :csvPart(file f) { return f.CSVMode(); } // Set file to read whitespace-separated values file* :wordSetHelper(bool b=true, file *f) { f->WordMode(b); return f; } callable* :wordSet(file *f) { return new thunk(new bfunc(wordSetHelper),f); } bool :wordPart(file f) { return f.WordMode(); } // Set file to read/write single precision real XDR values. file* :singlerealSetHelper(bool b=true, file *f) { f->SingleReal(b); return f; } callable* :singlerealSet(file *f) { return new thunk(new bfunc(singlerealSetHelper),f); } bool :singlerealPart(file f) { return f.SingleReal(); } // Set file to read/write single precision int XDR values. file* :singleintSetHelper(bool b=true, file *f) { f->SingleInt(b); return f; } callable* :singleintSet(file *f) { return new thunk(new bfunc(singleintSetHelper),f); } bool :singleintPart(file f) { return f.SingleInt(); } // Set file to read/write signed int XDR values. file* :signedintSetHelper(bool b=true, file *f) { f->SignedInt(b); return f; } callable* :signedintSet(file *f) { return new thunk(new bfunc(signedintSetHelper),f); } bool :signedintPart(file f) { return f.SignedInt(); } // Set file to read an arrayi (i int sizes followed by an i-dimensional array) file* :readSetHelper(Int i, file *f) { switch(i) { case 1: f->dimension(-2); break; case 2: f->dimension(-2,-2); break; case 3: f->dimension(-2,-2,-2); break; default: f->dimension(); } return f; } callable* :readSet(file *f) { return new thunk(new bfunc(readSetHelper),f); } // Delete file named s. Int delete(string s) { s=outpath(s); Int rc=unlink(s.c_str()); if(rc == 0 && verbose > 0) cout << "Deleted " << s << endl; return rc; } // Rename file "from" to file "to". Int rename(string from, string to) { from=outpath(from); to=outpath(to); Int rc=rename(from.c_str(),to.c_str()); if(rc == 0 && verbose > 0) cout << "Renamed " << from << " to " << to << endl; return rc; } // Create a uniquely named temporary file. string mktemp(string s) { string baseTemplate=s+"XXXXXX"; char *S=StrdupMalloc(baseTemplate); bool success=true; #if defined(_WIN32) if (_mktemp_s(S,baseTemplate.length()+1) != 0) { success = false; } FILE* fp; if (success && (fopen_s(&fp,S,"w") != 0)) { success = false; } #else int fd=mkstemp(S); if (fd < 0) { success = false; } #endif if(!success) { ostringstream buf; buf << "Could not create unique temporary filename based on " << s; error(buf); } string T(S); free(S); #if defined(_WIN32) bool closeSuccess = fclose(fp) == 0; #else bool closeSuccess = close(fd) == 0; #endif if (!closeSuccess) { ostringstream buf; buf << "Could not finalize temporary file based on " << s; error(buf); } return T; }