/*****
* runfile.in
*
* Runtime functions for file operations.
*
*****/
file* => primFile()
#include "fileio.h"
#include "callable.h"
#include "triple.h"
#include "array.h"
#include "seconds.h"
#if defined(_WIN32)
#include <io.h>
#else
#include <unistd.h>
#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=renameOverwrite(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;
}