Implementing input from stdin (Fixes: #144)
authorChristopher L. Conway <christopherleeconway@gmail.com>
Thu, 3 Jun 2010 22:27:16 +0000 (22:27 +0000)
committerChristopher L. Conway <christopherleeconway@gmail.com>
Thu, 3 Jun 2010 22:27:16 +0000 (22:27 +0000)
src/main/main.cpp
src/parser/antlr_input.cpp
src/parser/antlr_input.h
src/parser/input.cpp
src/parser/input.h
src/parser/parser_builder.cpp
src/parser/parser_builder.h
src/parser/smt2/smt2.cpp
test/unit/Makefile.am
test/unit/parser/parser_black.h
test/unit/parser/parser_builder_black.h [new file with mode: 0644]

index 6be992479696ece5574268f7b1682a71ee0318f3..5150d32f917305414555a8e72a80c7da2af5cb61 100644 (file)
@@ -95,11 +95,6 @@ int runCvc4(int argc, char* argv[]) {
   cout << unitbuf;
 #endif
 
-  /* NOTE: ANTLR3 doesn't support input from stdin */
-  if(firstArgIndex >= argc) {
-    throw Exception("No input file specified.");
-  }
-
   // We only accept one input file
   if(argc > firstArgIndex + 1) {
     throw Exception("Too many input files specified.");
@@ -112,19 +107,26 @@ int runCvc4(int argc, char* argv[]) {
   SmtEngine smt(&exprMgr, &options);
 
   // If no file supplied we read from standard input
-  // bool inputFromStdin = firstArgIndex >= argc || !strcmp("-", argv[firstArgIndex]);
+  bool inputFromStdin = 
+    firstArgIndex >= argc || !strcmp("-", argv[firstArgIndex]);
 
   // Auto-detect input language by filename extension
-  if(/*!inputFromStdin && */options.lang == parser::LANG_AUTO) {
-    const char* filename = argv[firstArgIndex];
-    unsigned len = strlen(filename);
-    if(len >= 5 && !strcmp(".smt2", filename + len - 5)) {
-      options.lang = parser::LANG_SMTLIB_V2;
-    } else if(len >= 4 && !strcmp(".smt", filename + len - 4)) {
-      options.lang = parser::LANG_SMTLIB;
-    } else if(( len >= 4 && !strcmp(".cvc", filename + len - 4) )
-              || ( len >= 5 && !strcmp(".cvc4", filename + len - 5) )) {
+  const char* filename = inputFromStdin ? "<stdin>" : argv[firstArgIndex];
+
+  if(options.lang == parser::LANG_AUTO) {
+    if( inputFromStdin ) {
+      // We can't do any fancy detection on stdin
       options.lang = parser::LANG_CVC4;
+    } else {
+      unsigned len = strlen(filename);
+      if(len >= 5 && !strcmp(".smt2", filename + len - 5)) {
+        options.lang = parser::LANG_SMTLIB_V2;
+      } else if(len >= 4 && !strcmp(".smt", filename + len - 4)) {
+        options.lang = parser::LANG_SMTLIB;
+      } else if(( len >= 4 && !strcmp(".cvc", filename + len - 4) )
+                || ( len >= 5 && !strcmp(".cvc4", filename + len - 5) )) {
+        options.lang = parser::LANG_CVC4;
+      }
     }
   }
 
@@ -149,15 +151,19 @@ int runCvc4(int argc, char* argv[]) {
     }
   }
 
-  /* TODO: Hack ANTLR3 to support input from streams */
-  ParserBuilder parserBuilder(options.lang,  argv[firstArgIndex]);
-
-  Parser *parser =
-      parserBuilder.withExprManager(exprMgr)
+  ParserBuilder parserBuilder =
+      ParserBuilder(exprMgr, filename)
+        .withInputLanguage(options.lang)
         .withMmap(options.memoryMap)
-        .withChecks(options.semanticChecks && !Configuration::isMuzzledBuild() )
-        .withStrictMode( options.strictParsing )
-        .build();
+        .withChecks(options.semanticChecks && 
+                    !Configuration::isMuzzledBuild() )
+        .withStrictMode( options.strictParsing );
+
+  if( inputFromStdin ) {
+    parserBuilder.withStreamInput(cin);
+  }
+
+  Parser *parser = parserBuilder.build();
 
   // Parse and execute commands until we are done
   Command* cmd;
index 300b181a6ebb1bc890cb5733f063d6b60ae7abdd..9d75dd31f6353d92babbb21c65629fbeb32b65b8 100644 (file)
@@ -40,8 +40,10 @@ using namespace CVC4::kind;
 namespace CVC4 {
 namespace parser {
 
-AntlrInputStream::AntlrInputStream(std::string name, pANTLR3_INPUT_STREAM input) :
-  InputStream(name),
+AntlrInputStream::AntlrInputStream(std::string name, 
+                                   pANTLR3_INPUT_STREAM input,
+                                   bool fileIsTemporary) :
+  InputStream(name,fileIsTemporary),
   d_input(input) {
   AlwaysAssert( input != NULL );
 }
@@ -54,7 +56,9 @@ pANTLR3_INPUT_STREAM AntlrInputStream::getAntlr3InputStream() const {
   return d_input;
 }
 
-AntlrInputStream* AntlrInputStream::newFileInputStream(const std::string& name, bool useMmap)
+AntlrInputStream* 
+AntlrInputStream::newFileInputStream(const std::string& name, 
+                                     bool useMmap)
   throw (InputStreamException) {
   pANTLR3_INPUT_STREAM input = NULL;
   if( useMmap ) {
@@ -68,7 +72,53 @@ AntlrInputStream* AntlrInputStream::newFileInputStream(const std::string& name,
   return new AntlrInputStream( name, input );
 }
 
-AntlrInputStream* AntlrInputStream::newStringInputStream(const std::string& input, const std::string& name)
+AntlrInputStream* 
+AntlrInputStream::newStreamInputStream(std::istream& input, 
+                                       const std::string& name)
+  throw (InputStreamException) {
+  // // TODO: make this more portable
+  // char *filename = strdup("/tmp/streaminput.XXXXXX");
+  // int fd = mkstemp(filename);
+  // if( fd == -1 ) {
+  //   throw InputStreamException("Couldn't create temporary for stream input: " + name); 
+  // }
+  
+  // // We don't want to use the temp file directly, so first close it
+  // close(fd);
+
+  // // Make a FIFO with our reserved temporary name
+  // int fd = mkfifo(filename, s_IRUSR);
+
+  // // Just stuff everything from the istream into the FIFO
+  // char buf[4096];
+  // while( !input.eof() && !input.fail() ) {
+  //   input.read( buf, sizeof(buf) );
+  //   write( fd, buf, input.gcount() );
+  // }
+
+  // if( !input.eof() ) {
+  //   throw InputStreamException("Stream input failed: " + name);
+  // }
+
+  // // Now create the ANTLR stream
+  // pANTLR3_INPUT_STREAM input = antlr3AsciiFileStreamNew((pANTLR3_UINT8) filename);
+  
+  // if( input == NULL ) {
+  //   throw InputStreamException("Couldn't create stream input: " + name);
+  // }
+
+  // // Create the stream with fileIsTemporary = true
+  // return new AntlrInputStream( name, input, true );
+
+  stringstream ss( ios_base::out );
+  ss << input.rdbuf();
+  return newStringInputStream( ss.str(), name );
+}
+
+
+AntlrInputStream* 
+AntlrInputStream::newStringInputStream(const std::string& input, 
+                                       const std::string& name)
   throw (InputStreamException) {
   char* inputStr = strdup(input.c_str());
   char* nameStr = strdup(name.c_str());
index 27337c35f0399fdad09405bc33036c33aeb92531..642dc9654835f9ac49a5a049ecf9730f384c2b87 100644 (file)
@@ -47,7 +47,9 @@ namespace parser {
 class AntlrInputStream : public InputStream {
   pANTLR3_INPUT_STREAM d_input;
 
-  AntlrInputStream(std::string name,pANTLR3_INPUT_STREAM input);
+  AntlrInputStream(std::string name,
+                   pANTLR3_INPUT_STREAM input,
+                   bool fileIsTemporary = false);
 
   /* This is private and unimplemented, because you should never use it. */
   AntlrInputStream(const AntlrInputStream& inputStream);
@@ -67,18 +69,22 @@ public:
    * @param useMmap <code>true</code> if the input should use memory-mapped I/O; otherwise, the
    * input will use the standard ANTLR3 I/O implementation.
    */
-  static AntlrInputStream* newFileInputStream(const std::string& name, bool useMmap = false)
+  static AntlrInputStream* newFileInputStream(const std::string& name, 
+                                              bool useMmap = false)
     throw (InputStreamException);
 
   /** Create an input from an istream. */
-  // AntlrInputStream newInputStream(std::istream& input, const std::string& name);
+  static AntlrInputStream* newStreamInputStream(std::istream& input, 
+                                                const std::string& name)
+    throw (InputStreamException);
 
   /** Create a string input.
    *
    * @param input the string to read
    * @param name the "filename" to use when reporting errors
    */
-  static AntlrInputStream* newStringInputStream(const std::string& input, const std::string& name)
+  static AntlrInputStream* newStringInputStream(const std::string& input, 
+                                                const std::string& name)
     throw (InputStreamException);
 };
 
index 9ee167897c49c703965b5e6599a484c4961043e0..a900765b5b659b256c385b0f056e3eaa6096fa52 100644 (file)
@@ -55,7 +55,17 @@ Input* Input::newFileInput(InputLanguage lang,
                            const std::string& filename,
                            bool useMmap)
   throw (InputStreamException) {
-  AntlrInputStream *inputStream = AntlrInputStream::newFileInputStream(filename,useMmap);
+  AntlrInputStream *inputStream = 
+    AntlrInputStream::newFileInputStream(filename,useMmap);
+  return AntlrInput::newInput(lang,*inputStream);
+}
+
+Input* Input::newStreamInput(InputLanguage lang, 
+                             std::istream& input, 
+                             const std::string& name) 
+  throw (InputStreamException) {
+  AntlrInputStream *inputStream = 
+    AntlrInputStream::newStreamInputStream(input,name);
   return AntlrInput::newInput(lang,*inputStream);
 }
 
index ccae2d84bd4929f2c8ca4acaa3a4006c91a86622..926ebe156054556e0109add90a74abb4df8dc891 100644 (file)
@@ -20,6 +20,7 @@
 
 #include <iostream>
 #include <string>
+#include <stdio.h>
 #include <vector>
 
 #include "expr/expr.h"
@@ -49,17 +50,26 @@ class InputStream {
   /** The name of this input stream. */
   std::string d_name;
 
+  /** Indicates whether the input file is a temporary that we should
+    * delete on exit. */
+  bool d_fileIsTemporary;
+
 protected:
 
   /** Initialize the input stream with a name. */
-  InputStream(std::string name) :
-    d_name(name) {
+  InputStream(std::string name, bool isTemporary=false) :
+    d_name(name),
+    d_fileIsTemporary(isTemporary) {
   }
 
 public:
 
-  /** Do-nothing destructor. */
-  virtual ~InputStream() { }
+  /** Destructor. */
+  virtual ~InputStream() { 
+    if( d_fileIsTemporary ) {
+      remove(d_name.c_str());
+    }
+  }
 
   /** Get the name of this input stream. */
   const std::string getName() const;
@@ -92,7 +102,9 @@ class CVC4_PUBLIC Input {
     * @param filename the input filename
     * @param useMmap true if the parser should use memory-mapped I/O (default: false)
     */
-  static Input* newFileInput(InputLanguage lang, const std::string& filename, bool useMmap=false)
+  static Input* newFileInput(InputLanguage lang, 
+                             const std::string& filename, 
+                             bool useMmap=false)
       throw (InputStreamException);
 
   /** Create an input for the given stream.
@@ -101,7 +113,10 @@ class CVC4_PUBLIC Input {
    * @param input the input stream
    * @param name the name of the stream, for use in error messages
    */
-  //static Parser* newStreamInput(InputLanguage lang, std::istream& input, const std::string& name);
+  static Input* newStreamInput(InputLanguage lang, 
+                               std::istream& input, 
+                               const std::string& name) 
+    throw (InputStreamException);
 
   /** Create an input for the given string
    *
@@ -109,7 +124,9 @@ class CVC4_PUBLIC Input {
    * @param input the input string
    * @param name the name of the stream, for use in error messages
    */
-  static Input* newStringInput(InputLanguage lang, const std::string& input, const std::string& name)
+  static Input* newStringInput(InputLanguage lang, 
+                               const std::string& input, 
+                               const std::string& name)
     throw (InputStreamException);
 
 public:
index b2bb15a6a817484330ec378105c6873ccfe55ed8..a9b3c461d8ce381f271d6a33bdfa597e58b4ab6a 100644 (file)
@@ -52,31 +52,37 @@ public:
   }
 };*/
 
-ParserBuilder::ParserBuilder(InputLanguage lang, const std::string& filename) :
+ParserBuilder::ParserBuilder(ExprManager& exprManager, const std::string& filename) :
     d_inputType(FILE_INPUT),
-    d_lang(lang),
+    d_lang(LANG_AUTO),
     d_filename(filename),
-    d_exprManager(NULL),
+    d_streamInput(NULL),
+    d_exprManager(exprManager),
     d_checksEnabled(true),
     d_strictMode(false),
     d_mmap(false) {
 }
 
-Parser *ParserBuilder::build() throw (InputStreamException) {
+Parser *ParserBuilder::build() throw (InputStreamException,AssertionException) {
   Input *input;
   switch( d_inputType ) {
   case FILE_INPUT:
     input = Input::newFileInput(d_lang,d_filename,d_mmap);
     break;
+  case STREAM_INPUT:
+    AlwaysAssert( d_streamInput != NULL,
+                  "Uninitialized stream input in ParserBuilder::build()" );
+    input = Input::newStreamInput(d_lang,*d_streamInput,d_filename);
+    break;
   case STRING_INPUT:
     input = Input::newStringInput(d_lang,d_stringInput,d_filename);
     break;
   }
   switch(d_lang) {
   case LANG_SMTLIB_V2:
-    return new Smt2(d_exprManager, input, d_strictMode);
+    return new Smt2(&d_exprManager, input, d_strictMode);
   default:
-    return new Parser(d_exprManager, input, d_strictMode);
+    return new Parser(&d_exprManager, input, d_strictMode);
   }
 }
 
@@ -115,6 +121,27 @@ ParserBuilder& ParserBuilder::withChecks(bool flag) {
   return *this;
 }
 
+ParserBuilder& ParserBuilder::withExprManager(ExprManager& exprManager) {
+  d_exprManager = exprManager;
+  return *this;
+}
+
+ParserBuilder& ParserBuilder::withFileInput() {
+  d_inputType = FILE_INPUT;
+  return *this;
+}
+
+ParserBuilder& ParserBuilder::withFilename(const std::string& filename) {
+  d_filename = filename;
+  return *this;
+}
+
+ParserBuilder& ParserBuilder::withInputLanguage(InputLanguage lang) {
+  d_lang = lang;
+  return *this;
+}
+
+
 ParserBuilder& ParserBuilder::withMmap(bool flag) {
   d_mmap = flag;
   return *this;
@@ -125,8 +152,9 @@ ParserBuilder& ParserBuilder::withStrictMode(bool flag) {
   return *this;
 }
 
-ParserBuilder& ParserBuilder::withExprManager(ExprManager& exprManager) {
-  d_exprManager = &exprManager;
+ParserBuilder& ParserBuilder::withStreamInput(std::istream& input) {
+  d_inputType = STREAM_INPUT;
+  d_streamInput = &input;
   return *this;
 }
 
index d0b8b7bb2cb9f4225447d8a7a3d997a64604a6e9..92b44a82dbfd92419b4ceddc016c10ec860d67fd 100644 (file)
@@ -45,9 +45,15 @@ public:
 
 class Parser;
 
+/**
+ * A builder for input language parsers. <code>build()</code> can be
+ * called any number of times on an instance and will generate a fresh
+ * parser each time.
+ */
 class CVC4_PUBLIC ParserBuilder {
   enum InputType {
     FILE_INPUT,
+    STREAM_INPUT,
     STRING_INPUT
   };
 
@@ -63,8 +69,11 @@ class CVC4_PUBLIC ParserBuilder {
   /** The string input, if any. */
   std::string d_stringInput;
 
+  /** The stream input, if any. */
+  std::istream *d_streamInput;
+
   /** The expression manager */
-  ExprManager *d_exprManager;
+  ExprManagerd_exprManager;
 
   /** Should semantic checks be enabled during parsing? */
   bool d_checksEnabled;
@@ -76,12 +85,43 @@ class CVC4_PUBLIC ParserBuilder {
   bool d_mmap;
 
 public:
-  ParserBuilder(InputLanguage lang, const std::string& filename);
-  Parser *build() throw (InputStreamException);
+
+  /** Create a parser builder using the given ExprManager and filename. */
+  ParserBuilder(ExprManager& exprManager, const std::string& filename);
+
+  /** Build the parser, using the current settings. */
+  Parser *build() throw (InputStreamException,AssertionException);
+
+  /** Should semantic checks be enabled in the parser? (Default: yes) */
   ParserBuilder& withChecks(bool flag = true);
+
+  /** Set the ExprManager to use with the parser. */
+  ParserBuilder& withExprManager(ExprManager& exprManager);
+
+  /** Set the parser to read a file for its input. (Default) */
+  ParserBuilder& withFileInput();
+
+  /** Set the filename for use by the parser. If file input is used,
+   * this file will be opened and read by the parser. Otherwise, the
+   * filename string (possibly a non-existent path) will only be used
+   * in error messages. */
+  ParserBuilder& withFilename(const std::string& filename);
+
+  /** Set the input language to be used by the parser. (Default:
+      LANG_AUTO). */
+  ParserBuilder& withInputLanguage(InputLanguage lang);
+
+  /** Should the parser memory-map its input? This is only relevant if
+   * the parser will have a file input. (Default: no) */
   ParserBuilder& withMmap(bool flag = true);
+
+  /** Should the parser use strict mode? (Default: no) */
   ParserBuilder& withStrictMode(bool flag = true);
-  ParserBuilder& withExprManager(ExprManager& exprManager);
+
+  /** Set the parser to use the given stream for its input. */
+  ParserBuilder& withStreamInput(std::istream& input);
+
+  /** Set the parser to use the given string for its input. */
   ParserBuilder& withStringInput(const std::string& input);
 };
 
index d76d8ba387ee6f42e41f8279568008d1080ee27e..f6089382c2ac80151f29b093b71e0aa1e163d949 100644 (file)
@@ -145,6 +145,8 @@ void Smt2::setLogic(const std::string& name) {
   case AUFNIRA:
   case QF_AUFBV:
   case QF_AUFLIA:
+  case QF_AX:
+  case QF_BV:
     Unhandled(name);
   }
 }
index 1f283f4766af66c33e3b9dbb3981bb3a2101b297..0597de9313716153d70be6158aa7a486a65651ab 100644 (file)
@@ -12,6 +12,7 @@ UNIT_TESTS = \
        expr/attribute_black \
        expr/declaration_scope_black \
        parser/parser_black \
+       parser/parser_builder_black \
        prop/cnf_stream_black \
        context/context_black \
        context/context_white \
index 6f09820c50a56f448232a01712a6554813bf0f21..f6d822265933ecb5c09d331d474f89dd6d19cb85 100644 (file)
@@ -1,5 +1,5 @@
 /*********************                                                        */
-/** parser_white.h
+/** parser_black.h
  ** Original author: cconway
  ** Major contributors: none
  ** Minor contributors (to current version): dejan, mdeters
  ** See the file COPYING in the top-level source directory for licensing
  ** information.
  **
- ** White box testing of CVC4::parser::SmtParser.
+ ** Black box testing of CVC4::parser::Parser, including CVC, SMT and
+ ** SMT v2 inputs.
  **/
 
 #include <cxxtest/TestSuite.h>
-//#include <string>
 #include <sstream>
 
 #include "expr/expr.h"
 #include "expr/expr_manager.h"
 #include "parser/parser.h"
 #include "parser/parser_builder.h"
+#include "parser/parser_options.h"
 #include "parser/smt2/smt2.h"
 #include "expr/command.h"
 #include "util/output.h"
@@ -29,8 +30,6 @@ using namespace CVC4;
 using namespace CVC4::parser;
 using namespace std;
 
-
-
 class ParserBlack {
   InputLanguage d_lang;
   ExprManager *d_exprManager;
@@ -62,10 +61,10 @@ protected:
 //         Debug.on("parser-extra");
 //        cerr << "Testing good input: <<" << goodInput << ">>" << endl;
 //        istringstream stream(goodInputs[i]);
-        ParserBuilder parserBuilder(d_lang,"test");
         Parser *parser =
-          parserBuilder.withStringInput(goodInput)
-            .withExprManager(*d_exprManager)
+          ParserBuilder(*d_exprManager,"test")
+            .withStringInput(goodInput)
+            .withInputLanguage(d_lang)
             .build();
         TS_ASSERT( !parser->done() );
         Command* cmd;
@@ -88,10 +87,11 @@ protected:
   void tryBadInput(const string badInput, bool strictMode = false) {
 //      cerr << "Testing bad input: '" << badInput << "'\n";
 //      Debug.on("parser");
-    ParserBuilder parserBuilder(d_lang,"test");
+
     Parser *parser =
-      parserBuilder.withStringInput(badInput)
-        .withExprManager(*d_exprManager)
+      ParserBuilder(*d_exprManager,"test")
+        .withStringInput(badInput)
+        .withInputLanguage(d_lang)
         .withStrictMode(strictMode)
         .build();
       TS_ASSERT_THROWS
@@ -109,11 +109,13 @@ protected:
 //        cerr << "Testing good expr: '" << goodExpr << "'\n";
         // Debug.on("parser");
 //        istringstream stream(context + goodBooleanExprs[i]);
-        ParserBuilder parserBuilder(d_lang,"test");
+
         Parser *parser =
-          parserBuilder.withStringInput(goodExpr)
-            .withExprManager(*d_exprManager)
+          ParserBuilder(*d_exprManager,"test")
+            .withStringInput(goodExpr)
+            .withInputLanguage(d_lang)
             .build();
+
         TS_ASSERT( !parser->done() );
         setupContext(*parser);
         TS_ASSERT( !parser->done() );
@@ -142,10 +144,11 @@ protected:
 //    Debug.on("parser");
 //    Debug.on("parser-extra");
 //      cout << "Testing bad expr: '" << badExpr << "'\n";
-      ParserBuilder parserBuilder(d_lang,"test");
+      
       Parser *parser =
-        parserBuilder.withStringInput(badExpr)
-          .withExprManager(*d_exprManager)
+        ParserBuilder(*d_exprManager,"test")
+          .withStringInput(badExpr)
+          .withInputLanguage(d_lang)
           .withStrictMode(strictMode)
           .build();
       setupContext(*parser);
diff --git a/test/unit/parser/parser_builder_black.h b/test/unit/parser/parser_builder_black.h
new file mode 100644 (file)
index 0000000..f254580
--- /dev/null
@@ -0,0 +1,150 @@
+/*********************                                                        */
+/** parser_builder_black.h
+ ** Original author: cconway
+ ** Major contributors: none
+ ** Minor contributors (to current version): dejan, mdeters
+ ** This file is part of the CVC4 prototype.
+ ** Copyright (c) 2009, 2010  The Analysis of Computer Systems Group (ACSys)
+ ** Courant Institute of Mathematical Sciences
+ ** New York University
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.
+ **
+ ** Black box testing of CVC4::parser::ParserBuilder.
+ **/
+
+#include <cxxtest/TestSuite.h>
+#include <ext/stdio_filebuf.h>
+#include <fstream>
+#include <iostream>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "expr/command.h"
+#include "parser/parser.h"
+#include "parser/parser_builder.h"
+#include "parser/parser_options.h"
+
+typedef __gnu_cxx::stdio_filebuf<char> filebuf_gnu;
+
+using namespace CVC4;
+using namespace CVC4::parser;
+using namespace std;
+
+class ParserBuilderBlack : public CxxTest::TestSuite {
+
+  ExprManager *d_exprManager;
+
+  void checkEmptyInput(ParserBuilder& builder) {
+    Parser *parser = builder.build();
+    TS_ASSERT( parser != NULL );
+
+    Expr e = parser->nextExpression();
+    TS_ASSERT( e.isNull() );
+
+    delete parser;
+  }
+
+  void checkTrueInput(ParserBuilder& builder) {
+    Parser *parser = builder.build();
+    TS_ASSERT( parser != NULL );
+
+    Expr e = parser->nextExpression();
+    TS_ASSERT_EQUALS( e, d_exprManager->mkConst(true) );
+
+    e = parser->nextExpression();
+    TS_ASSERT( e.isNull() );
+    delete parser;
+  }
+
+  char* mkTemp() {
+    char *filename = strdup("/tmp/testinput.XXXXXX");
+    int fd = mkstemp(filename);
+    TS_ASSERT( fd != -1 );
+    close(fd);
+    return filename;
+  }
+
+public:
+
+  void setUp() {
+    d_exprManager = new ExprManager;
+  }
+
+  void tearDown() {
+    delete d_exprManager;
+  }
+
+  void testEmptyFileInput() {
+    char *filename = mkTemp();
+
+    /* FILE *fp = tmpfile(); */
+    /* filebuf_gnu fs( fd, ios_base::out ); */
+
+    /* ptr = tmpnam(filename); */
+    /* std::fstream fs( ptr, fstream::out ); */
+    /* fs.close(); */
+
+    checkEmptyInput(
+      ParserBuilder(*d_exprManager,filename)
+        .withInputLanguage(LANG_CVC4)
+                    );
+
+    remove(filename);
+    //    mkfifo(ptr, S_IWUSR | s_IRUSR);    
+  }
+
+  void testSimpleFileInput() {
+    char *filename = mkTemp();
+
+    std::fstream fs( filename, fstream::out );
+    fs << "TRUE" << std::endl;
+    fs.close();
+
+    checkTrueInput(
+      ParserBuilder(*d_exprManager,filename)
+        .withInputLanguage(LANG_CVC4)
+                   );
+
+    remove(filename);
+  }
+
+  void testEmptyStringInput() {
+    checkEmptyInput(
+      ParserBuilder(*d_exprManager,"foo")
+        .withInputLanguage(LANG_CVC4)
+        .withStringInput("")
+                    );
+  }
+
+  void testTrueStringInput() {
+    checkTrueInput(
+      ParserBuilder(*d_exprManager,"foo")
+        .withInputLanguage(LANG_CVC4)
+        .withStringInput("TRUE")
+                   );
+  }
+
+  void testEmptyStreamInput() {
+    stringstream ss( "", ios_base::in );
+    checkEmptyInput(
+      ParserBuilder(*d_exprManager,"foo")
+        .withInputLanguage(LANG_CVC4)
+        .withStreamInput(ss)
+                    );
+  }
+
+  void testTrueStreamInput() {
+    stringstream ss( "TRUE", ios_base::in );
+    checkTrueInput(
+      ParserBuilder(*d_exprManager,"foo")
+        .withInputLanguage(LANG_CVC4)
+        .withStreamInput(ss)
+                   );
+  }
+
+
+
+}; // class ParserBuilderBlack