/***** Autogenerated from runfile.in; changes will be overwritten *****/

#line 1 "./runtimebase.in"
/*****
 * runtimebase.in
 * Andy Hammerlindl  2009/07/28
 *
 * Common declarations needed for all code-generating .in files.
 *
 *****/


#line 1 "./runfile.in"
/*****
 * runfile.in
 *
 * Runtime functions for file operations.
 *
 *****/

#line 23 "./runtimebase.in"
#include "stack.h"
#include "types.h"
#include "builtin.h"
#include "entry.h"
#include "errormsg.h"
#include "array.h"
#include "triple.h"
#include "callable.h"
#include "opsymbols.h"

using vm::stack;
using vm::error;
using vm::array;
using vm::read;
using vm::callable;
using types::formal;
using types::function;
using camp::triple;

#define PRIMITIVE(name,Name,asyName) using types::prim##Name;
#include <primitives.h>
#undef PRIMITIVE

void unused(void *);

namespace run {
typedef double real;

array *copyArray(array *a);
array *copyArray2(array *a);
array *copyArray3(array *a);

double *copyTripleArray2Components(array *a, size_t &N,
                                   GCPlacement placement=NoGC);
triple *copyTripleArray2C(array *a, size_t &N,
                          GCPlacement placement=NoGC);
}

function *realRealFunction();

#define CURRENTPEN processData().currentpen

#line 10 "runfile.in"
#include "fileio.h"
#include "callable.h"
#include "triple.h"
#include "array.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:



#ifndef NOSYM
#include "runfile.symbols.h"

#endif
namespace run {
#line 30 "./runfile.in"
// bool ==(file *a, file *b);
void gen_runfile0(stack *Stack)
{
  file * b=vm::pop<file *>(Stack);
  file * a=vm::pop<file *>(Stack);
#line 31 "./runfile.in"
  {Stack->push<bool>(a == b); return;}
}

#line 35 "./runfile.in"
// bool !=(file *a, file *b);
void gen_runfile1(stack *Stack)
{
  file * b=vm::pop<file *>(Stack);
  file * a=vm::pop<file *>(Stack);
#line 36 "./runfile.in"
  {Stack->push<bool>(a != b); return;}
}

#line 40 "./runfile.in"
void nullFile(stack *Stack)
{
#line 41 "./runfile.in"
  {Stack->push<file*>(&camp::nullfile); return;}
}

#line 45 "./runfile.in"
// file* input(string name=emptystring, bool check=true,            string comment=commentchar, string mode=emptystring);
void gen_runfile3(stack *Stack)
{
  string mode=vm::pop<string>(Stack,emptystring);
  string comment=vm::pop<string>(Stack,commentchar);
  bool check=vm::pop<bool>(Stack,true);
  string name=vm::pop<string>(Stack,emptystring);
#line 47 "./runfile.in"
  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();
  {Stack->push<file*>(f); return;}
}

#line 76 "./runfile.in"
// file* output(string name=emptystring, bool update=false,             string comment=commentchar, string mode=emptystring);
void gen_runfile4(stack *Stack)
{
  string mode=vm::pop<string>(Stack,emptystring);
  string comment=vm::pop<string>(Stack,commentchar);
  bool update=vm::pop<bool>(Stack,false);
  string name=vm::pop<string>(Stack,emptystring);
#line 78 "./runfile.in"
  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);

  {Stack->push<file*>(f); return;}
}

#line 113 "./runfile.in"
// bool eof(file *f);
void gen_runfile5(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 114 "./runfile.in"
  {Stack->push<bool>(f->eof()); return;}
}

#line 118 "./runfile.in"
// bool eol(file *f);
void gen_runfile6(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 119 "./runfile.in"
  {Stack->push<bool>(f->eol()); return;}
}

#line 123 "./runfile.in"
// bool error(file *f);
void gen_runfile7(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 124 "./runfile.in"
  {Stack->push<bool>(f->error()); return;}
}

#line 128 "./runfile.in"
// void clear(file *f);
void gen_runfile8(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 129 "./runfile.in"
  f->clear();
}

#line 133 "./runfile.in"
// void close(file *f);
void gen_runfile9(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 134 "./runfile.in"
  f->close();
}

#line 138 "./runfile.in"
// Int precision(file *f=NULL, Int digits=0);
void gen_runfile10(stack *Stack)
{
  Int digits=vm::pop<Int>(Stack,0);
  file * f=vm::pop<file *>(Stack,NULL);
#line 139 "./runfile.in"
  if(f == 0) f=&camp::Stdout;
  {Stack->push<Int>(f->precision(digits)); return;}
}

#line 144 "./runfile.in"
// void flush(file *f);
void gen_runfile11(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 145 "./runfile.in"
  f->flush();
}

#line 149 "./runfile.in"
// string getc(file *f);
void gen_runfile12(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 150 "./runfile.in"
  char c=0;
  if(f->isOpen()) f->read(c);
  {Stack->push<string>(string(1,c)); return;}
}

#line 156 "./runfile.in"
// Int tell(file *f);
void gen_runfile13(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 157 "./runfile.in"
  {Stack->push<Int>(f->tell()); return;}
}

#line 161 "./runfile.in"
// void seek(file *f, Int pos);
void gen_runfile14(stack *Stack)
{
  Int pos=vm::pop<Int>(Stack);
  file * f=vm::pop<file *>(Stack);
#line 162 "./runfile.in"
  f->seek(pos,pos >= 0);
}

#line 166 "./runfile.in"
// void seekeof(file *f);
void gen_runfile15(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 167 "./runfile.in"
  f->seek(0,false);
}

#line 171 "./runfile.in"
void namePart(stack *Stack)
{
  file f=vm::pop<file>(Stack);
#line 172 "./runfile.in"
  {Stack->push<string>(f.filename()); return;}
}

#line 176 "./runfile.in"
void modePart(stack *Stack)
{
  file f=vm::pop<file>(Stack);
#line 177 "./runfile.in"
  {Stack->push<string>(f.FileMode()); return;}
}

// Set file dimensions
#line 182 "./runfile.in"
void dimensionSetHelper(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
  Int nz=vm::pop<Int>(Stack,-1);
  Int ny=vm::pop<Int>(Stack,-1);
  Int nx=vm::pop<Int>(Stack,-1);
#line 183 "./runfile.in"
  f->dimension(nx,ny,nz);
  {Stack->push<file*>(f); return;}
}

#line 188 "./runfile.in"
void dimensionSet(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 189 "./runfile.in"
  {Stack->push<callable*>(new thunk(new bfunc(dimensionSetHelper),f)); return;}
}

#line 193 "./runfile.in"
void dimensionPart(stack *Stack)
{
  file f=vm::pop<file>(Stack);
#line 194 "./runfile.in"
  array *a=new array(3);
  (*a)[0]=f.Nx();
  (*a)[1]=f.Ny();
  (*a)[2]=f.Nz();
  {Stack->push<array*>(a); return;}
}

// Set file f to read arrays in line-at-a-time mode
#line 203 "./runfile.in"
void lineSetHelper(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
  bool b=vm::pop<bool>(Stack,true);
#line 204 "./runfile.in"
  f->LineMode(b);
  {Stack->push<file*>(f); return;}
}

#line 209 "./runfile.in"
void lineSet(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 210 "./runfile.in"
  {Stack->push<callable*>(new thunk(new bfunc(lineSetHelper),f)); return;}
}

#line 214 "./runfile.in"
void linePart(stack *Stack)
{
  file f=vm::pop<file>(Stack);
#line 215 "./runfile.in"
  {Stack->push<bool>(f.LineMode()); return;}
}

// Set file to read comma-separated values
#line 220 "./runfile.in"
void csvSetHelper(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
  bool b=vm::pop<bool>(Stack,true);
#line 221 "./runfile.in"
  f->CSVMode(b);
  {Stack->push<file*>(f); return;}
}

#line 226 "./runfile.in"
void csvSet(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 227 "./runfile.in"
  {Stack->push<callable*>(new thunk(new bfunc(csvSetHelper),f)); return;}
}

#line 231 "./runfile.in"
void csvPart(stack *Stack)
{
  file f=vm::pop<file>(Stack);
#line 232 "./runfile.in"
  {Stack->push<bool>(f.CSVMode()); return;}
}

// Set file to read whitespace-separated values
#line 237 "./runfile.in"
void wordSetHelper(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
  bool b=vm::pop<bool>(Stack,true);
#line 238 "./runfile.in"
  f->WordMode(b);
  {Stack->push<file*>(f); return;}
}

#line 243 "./runfile.in"
void wordSet(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 244 "./runfile.in"
  {Stack->push<callable*>(new thunk(new bfunc(wordSetHelper),f)); return;}
}

#line 248 "./runfile.in"
void wordPart(stack *Stack)
{
  file f=vm::pop<file>(Stack);
#line 249 "./runfile.in"
  {Stack->push<bool>(f.WordMode()); return;}
}

// Set file to read/write single precision real XDR values.
#line 254 "./runfile.in"
void singlerealSetHelper(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
  bool b=vm::pop<bool>(Stack,true);
#line 255 "./runfile.in"
  f->SingleReal(b);
  {Stack->push<file*>(f); return;}
}

#line 260 "./runfile.in"
void singlerealSet(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 261 "./runfile.in"
  {Stack->push<callable*>(new thunk(new bfunc(singlerealSetHelper),f)); return;}
}

#line 265 "./runfile.in"
void singlerealPart(stack *Stack)
{
  file f=vm::pop<file>(Stack);
#line 266 "./runfile.in"
  {Stack->push<bool>(f.SingleReal()); return;}
}

// Set file to read/write single precision int XDR values.
#line 271 "./runfile.in"
void singleintSetHelper(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
  bool b=vm::pop<bool>(Stack,true);
#line 272 "./runfile.in"
  f->SingleInt(b);
  {Stack->push<file*>(f); return;}
}

#line 277 "./runfile.in"
void singleintSet(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 278 "./runfile.in"
  {Stack->push<callable*>(new thunk(new bfunc(singleintSetHelper),f)); return;}
}

#line 282 "./runfile.in"
void singleintPart(stack *Stack)
{
  file f=vm::pop<file>(Stack);
#line 283 "./runfile.in"
  {Stack->push<bool>(f.SingleInt()); return;}
}

// Set file to read/write signed int XDR values.
#line 288 "./runfile.in"
void signedintSetHelper(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
  bool b=vm::pop<bool>(Stack,true);
#line 289 "./runfile.in"
  f->SignedInt(b);
  {Stack->push<file*>(f); return;}
}

#line 294 "./runfile.in"
void signedintSet(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 295 "./runfile.in"
  {Stack->push<callable*>(new thunk(new bfunc(signedintSetHelper),f)); return;}
}

#line 299 "./runfile.in"
void signedintPart(stack *Stack)
{
  file f=vm::pop<file>(Stack);
#line 300 "./runfile.in"
  {Stack->push<bool>(f.SignedInt()); return;}
}

// Set file to read an arrayi (i int sizes followed by an i-dimensional array)
#line 305 "./runfile.in"
void readSetHelper(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
  Int i=vm::pop<Int>(Stack);
#line 306 "./runfile.in"
  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();
  }

  {Stack->push<file*>(f); return;}
}

#line 327 "./runfile.in"
void readSet(stack *Stack)
{
  file * f=vm::pop<file *>(Stack);
#line 328 "./runfile.in"
  {Stack->push<callable*>(new thunk(new bfunc(readSetHelper),f)); return;}
}

// Delete file named s.
#line 333 "./runfile.in"
// Int delete(string s);
void gen_runfile41(stack *Stack)
{
  string s=vm::pop<string>(Stack);
#line 334 "./runfile.in"
  s=outpath(s);
  Int rc=unlink(s.c_str());
  if(rc == 0 && verbose > 0)
    cout << "Deleted " << s << endl;
  {Stack->push<Int>(rc); return;}
}

// Rename file "from" to file "to".
#line 343 "./runfile.in"
// Int rename(string from, string to);
void gen_runfile42(stack *Stack)
{
  string to=vm::pop<string>(Stack);
  string from=vm::pop<string>(Stack);
#line 344 "./runfile.in"
  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;
  {Stack->push<Int>(rc); return;}
}

// Create a uniquely named temporary file.
#line 354 "./runfile.in"
// string mktemp(string s);
void gen_runfile43(stack *Stack)
{
  string s=vm::pop<string>(Stack);
#line 355 "./runfile.in"
  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);
  }
  {Stack->push<string>(T); return;}
}

} // namespace run

namespace trans {

void gen_runfile_venv(venv &ve)
{
#line 30 "./runfile.in"
  addFunc(ve, run::gen_runfile0, primBoolean(), SYM_EQ, formal(primFile(), SYM(a), false, false), formal(primFile(), SYM(b), false, false));
#line 35 "./runfile.in"
  addFunc(ve, run::gen_runfile1, primBoolean(), SYM_NEQ, formal(primFile(), SYM(a), false, false), formal(primFile(), SYM(b), false, false));
#line 40 "./runfile.in"
  REGISTER_BLTIN(run::nullFile,"nullFile");
#line 45 "./runfile.in"
  addFunc(ve, run::gen_runfile3, primFile(), SYM(input), formal(primString(), SYM(name), true, false), formal(primBoolean(), SYM(check), true, false), formal(primString(), SYM(comment), true, false), formal(primString(), SYM(mode), true, false));
#line 76 "./runfile.in"
  addFunc(ve, run::gen_runfile4, primFile(), SYM(output), formal(primString(), SYM(name), true, false), formal(primBoolean(), SYM(update), true, false), formal(primString(), SYM(comment), true, false), formal(primString(), SYM(mode), true, false));
#line 113 "./runfile.in"
  addFunc(ve, run::gen_runfile5, primBoolean(), SYM(eof), formal(primFile(), SYM(f), false, false));
#line 118 "./runfile.in"
  addFunc(ve, run::gen_runfile6, primBoolean(), SYM(eol), formal(primFile(), SYM(f), false, false));
#line 123 "./runfile.in"
  addFunc(ve, run::gen_runfile7, primBoolean(), SYM(error), formal(primFile(), SYM(f), false, false));
#line 128 "./runfile.in"
  addFunc(ve, run::gen_runfile8, primVoid(), SYM(clear), formal(primFile(), SYM(f), false, false));
#line 133 "./runfile.in"
  addFunc(ve, run::gen_runfile9, primVoid(), SYM(close), formal(primFile(), SYM(f), false, false));
#line 138 "./runfile.in"
  addFunc(ve, run::gen_runfile10, primInt(), SYM(precision), formal(primFile(), SYM(f), true, false), formal(primInt(), SYM(digits), true, false));
#line 144 "./runfile.in"
  addFunc(ve, run::gen_runfile11, primVoid(), SYM(flush), formal(primFile(), SYM(f), false, false));
#line 149 "./runfile.in"
  addFunc(ve, run::gen_runfile12, primString(), SYM(getc), formal(primFile(), SYM(f), false, false));
#line 156 "./runfile.in"
  addFunc(ve, run::gen_runfile13, primInt(), SYM(tell), formal(primFile(), SYM(f), false, false));
#line 161 "./runfile.in"
  addFunc(ve, run::gen_runfile14, primVoid(), SYM(seek), formal(primFile(), SYM(f), false, false), formal(primInt(), SYM(pos), false, false));
#line 166 "./runfile.in"
  addFunc(ve, run::gen_runfile15, primVoid(), SYM(seekeof), formal(primFile(), SYM(f), false, false));
#line 171 "./runfile.in"
  REGISTER_BLTIN(run::namePart,"namePart");
#line 176 "./runfile.in"
  REGISTER_BLTIN(run::modePart,"modePart");
#line 181 "./runfile.in"
  REGISTER_BLTIN(run::dimensionSetHelper,"dimensionSetHelper");
#line 188 "./runfile.in"
  REGISTER_BLTIN(run::dimensionSet,"dimensionSet");
#line 193 "./runfile.in"
  REGISTER_BLTIN(run::dimensionPart,"dimensionPart");
#line 202 "./runfile.in"
  REGISTER_BLTIN(run::lineSetHelper,"lineSetHelper");
#line 209 "./runfile.in"
  REGISTER_BLTIN(run::lineSet,"lineSet");
#line 214 "./runfile.in"
  REGISTER_BLTIN(run::linePart,"linePart");
#line 219 "./runfile.in"
  REGISTER_BLTIN(run::csvSetHelper,"csvSetHelper");
#line 226 "./runfile.in"
  REGISTER_BLTIN(run::csvSet,"csvSet");
#line 231 "./runfile.in"
  REGISTER_BLTIN(run::csvPart,"csvPart");
#line 236 "./runfile.in"
  REGISTER_BLTIN(run::wordSetHelper,"wordSetHelper");
#line 243 "./runfile.in"
  REGISTER_BLTIN(run::wordSet,"wordSet");
#line 248 "./runfile.in"
  REGISTER_BLTIN(run::wordPart,"wordPart");
#line 253 "./runfile.in"
  REGISTER_BLTIN(run::singlerealSetHelper,"singlerealSetHelper");
#line 260 "./runfile.in"
  REGISTER_BLTIN(run::singlerealSet,"singlerealSet");
#line 265 "./runfile.in"
  REGISTER_BLTIN(run::singlerealPart,"singlerealPart");
#line 270 "./runfile.in"
  REGISTER_BLTIN(run::singleintSetHelper,"singleintSetHelper");
#line 277 "./runfile.in"
  REGISTER_BLTIN(run::singleintSet,"singleintSet");
#line 282 "./runfile.in"
  REGISTER_BLTIN(run::singleintPart,"singleintPart");
#line 287 "./runfile.in"
  REGISTER_BLTIN(run::signedintSetHelper,"signedintSetHelper");
#line 294 "./runfile.in"
  REGISTER_BLTIN(run::signedintSet,"signedintSet");
#line 299 "./runfile.in"
  REGISTER_BLTIN(run::signedintPart,"signedintPart");
#line 304 "./runfile.in"
  REGISTER_BLTIN(run::readSetHelper,"readSetHelper");
#line 327 "./runfile.in"
  REGISTER_BLTIN(run::readSet,"readSet");
#line 332 "./runfile.in"
  addFunc(ve, run::gen_runfile41, primInt(), SYM(delete), formal(primString(), SYM(s), false, false));
#line 342 "./runfile.in"
  addFunc(ve, run::gen_runfile42, primInt(), SYM(rename), formal(primString(), SYM(from), false, false), formal(primString(), SYM(to), false, false));
#line 353 "./runfile.in"
  addFunc(ve, run::gen_runfile43, primString(), SYM(mktemp), formal(primString(), SYM(s), false, false));
}

} // namespace trans
