Isolating the dependencies on CVC4_ANTLR3_OLD_INPUT_STREAM. Also freeing more memory...
authorTim King <taking@google.com>
Tue, 24 Nov 2015 00:30:24 +0000 (16:30 -0800)
committerTim King <taking@google.com>
Tue, 24 Nov 2015 04:40:00 +0000 (20:40 -0800)
src/parser/antlr_input.cpp
src/parser/antlr_input.h
src/parser/input.cpp

index 4c779c46ad452befdafd5eb8db310501bcb4b12a..1d2dbd736947d9ec69eb42f7ba2bba26ee19aa3a 100644 (file)
@@ -44,23 +44,91 @@ using namespace CVC4::kind;
 namespace CVC4 {
 namespace parser {
 
-AntlrInputStream::AntlrInputStream(std::string name, 
+// These functions exactly wrap the antlr3 source inconsistencies.
+// These are the only location CVC4_ANTLR3_OLD_INPUT_STREAM ifdefs appear.
+// No other sanity checking happens;
+pANTLR3_INPUT_STREAM newAntlr3BufferedStream(std::istream& input, const std::string& name);
+pANTLR3_INPUT_STREAM newAntlr3FileStream(const std::string& name);
+pANTLR3_INPUT_STREAM newAntrl3InPlaceStream(pANTLR3_UINT8 basep,
+                                            uint32_t size,
+                                            const std::string& name);
+
+pANTLR3_INPUT_STREAM
+newAntlr3BufferedStream(std::istream& input, const std::string& name){
+  pANTLR3_INPUT_STREAM inputStream = NULL;
+  pANTLR3_UINT8 name_duplicate = (pANTLR3_UINT8) strdup(name.c_str());
+
+#ifdef CVC4_ANTLR3_OLD_INPUT_STREAM
+  inputStream =
+    antlr3LineBufferedStreamNew(input, 0, name_duplicate);
+#else /* CVC4_ANTLR3_OLD_INPUT_STREAM */
+  inputStream =
+    antlr3LineBufferedStreamNew(input, ANTLR3_ENC_8BIT, name_duplicate);
+#endif /* CVC4_ANTLR3_OLD_INPUT_STREAM */
+
+  free(name_duplicate);
+  return inputStream;
+}
+
+pANTLR3_INPUT_STREAM newAntlr3FileStream(const std::string& name){
+  pANTLR3_INPUT_STREAM input = NULL;
+  pANTLR3_UINT8 name_duplicate = (pANTLR3_UINT8) strdup(name.c_str());
+
+  // libantlr3c v3.2 isn't source-compatible with v3.4
+#ifdef CVC4_ANTLR3_OLD_INPUT_STREAM
+  input = antlr3AsciiFileStreamNew(name_duplicate);
+#else /* CVC4_ANTLR3_OLD_INPUT_STREAM */
+  input = antlr3FileStreamNew(name_duplicate, ANTLR3_ENC_8BIT);
+#endif /* CVC4_ANTLR3_OLD_INPUT_STREAM */
+
+  free(name_duplicate);
+  return input;
+}
+
+
+pANTLR3_INPUT_STREAM newAntrl3InPlaceStream(pANTLR3_UINT8 basep,
+                                            uint32_t size,
+                                            const std::string& name){
+  pANTLR3_UINT8 name_duplicate = (pANTLR3_UINT8) strdup(name.c_str());
+  pANTLR3_INPUT_STREAM inputStream = NULL;
+  /* Create an ANTLR input backed by the buffer. */
+#ifdef CVC4_ANTLR3_OLD_INPUT_STREAM
+  inputStream =
+    antlr3NewAsciiStringInPlaceStream(basep, size, name_duplicate);
+#else /* CVC4_ANTLR3_OLD_INPUT_STREAM */
+  inputStream =
+    antlr3StringStreamNew(basep, ANTLR3_ENC_8BIT, size,
+                          name_duplicate);
+#endif /* CVC4_ANTLR3_OLD_INPUT_STREAM */
+  free(name_duplicate);
+  return inputStream;
+}
+
+AntlrInputStream::AntlrInputStream(std::string name,
                                    pANTLR3_INPUT_STREAM input,
-                                   bool fileIsTemporary) :
+                                   bool fileIsTemporary,
+                                   pANTLR3_UINT8 inputString) :
   InputStream(name, fileIsTemporary),
-  d_input(input) {
+  d_input(input),
+  d_inputString(inputString)
+{
   assert( input != NULL );
   input->fileName = input->strFactory->newStr8(input->strFactory, (pANTLR3_UINT8)name.c_str());
 }
 
 AntlrInputStream::~AntlrInputStream() {
   d_input->free(d_input);
+  if(d_inputString != NULL){
+    free(d_inputString);
+  }
 }
 
 pANTLR3_INPUT_STREAM AntlrInputStream::getAntlr3InputStream() const {
   return d_input;
 }
 
+
+
 AntlrInputStream*
 AntlrInputStream::newFileInputStream(const std::string& name,
                                      bool useMmap)
@@ -74,19 +142,15 @@ AntlrInputStream::newFileInputStream(const std::string& name,
   if(useMmap) {
     input = MemoryMappedInputBufferNew(name);
   } else {
-    // libantlr3c v3.2 isn't source-compatible with v3.4
-#ifdef CVC4_ANTLR3_OLD_INPUT_STREAM
-    input = antlr3AsciiFileStreamNew((pANTLR3_UINT8) name.c_str());
-#else /* CVC4_ANTLR3_OLD_INPUT_STREAM */
-    input = antlr3FileStreamNew((pANTLR3_UINT8) name.c_str(), ANTLR3_ENC_8BIT);
-#endif /* CVC4_ANTLR3_OLD_INPUT_STREAM */
+    input = newAntlr3FileStream(name);
   }
   if(input == NULL) {
     throw InputStreamException("Couldn't open file: " + name);
   }
-  return new AntlrInputStream( name, input );
+  return new AntlrInputStream( name, input, false, NULL );
 }
 
+
 AntlrInputStream*
 AntlrInputStream::newStreamInputStream(std::istream& input,
                                        const std::string& name,
@@ -94,19 +158,10 @@ AntlrInputStream::newStreamInputStream(std::istream& input,
   throw (InputStreamException) {
 
   pANTLR3_INPUT_STREAM inputStream = NULL;
+  pANTLR3_UINT8 inputStringCopy = NULL;
 
   if(lineBuffered) {
-#ifdef CVC4_ANTLR3_OLD_INPUT_STREAM
-    inputStream =
-      antlr3LineBufferedStreamNew(input,
-                                  0,
-                                  (pANTLR3_UINT8) strdup(name.c_str()));
-#else /* CVC4_ANTLR3_OLD_INPUT_STREAM */
-    inputStream =
-      antlr3LineBufferedStreamNew(input,
-                                  ANTLR3_ENC_8BIT,
-                                  (pANTLR3_UINT8) strdup(name.c_str()));
-#endif /* CVC4_ANTLR3_OLD_INPUT_STREAM */
+    inputStream = newAntlr3BufferedStream(input, name);
   } else {
 
     // Since these are all NULL on entry, realloc will be called
@@ -138,28 +193,18 @@ AntlrInputStream::newStreamInputStream(std::istream& input,
     if( !input.eof() ) {
       throw InputStreamException("Stream input failed: " + name);
     }
-
-    /* Create an ANTLR input backed by the buffer. */
-#ifdef CVC4_ANTLR3_OLD_INPUT_STREAM
-    inputStream =
-      antlr3NewAsciiStringInPlaceStream((pANTLR3_UINT8) basep,
-                                        cp - basep,
-                                        (pANTLR3_UINT8) strdup(name.c_str()));
-#else /* CVC4_ANTLR3_OLD_INPUT_STREAM */
-    inputStream =
-      antlr3StringStreamNew((pANTLR3_UINT8) basep,
-                            ANTLR3_ENC_8BIT,
-                            cp - basep,
-                            (pANTLR3_UINT8) strdup(name.c_str()));
-#endif /* CVC4_ANTLR3_OLD_INPUT_STREAM */
-
+    ptrdiff_t offset = cp - basep;
+    assert(offset >= 0);
+    assert(offset <= std::numeric_limits<uint32_t>::max());
+    inputStringCopy = (pANTLR3_UINT8)basep;
+    inputStream = newAntrl3InPlaceStream(inputStringCopy, (uint32_t) offset, name);
   }
 
   if( inputStream == NULL ) {
     throw InputStreamException("Couldn't initialize input: " + name);
   }
 
-  return new AntlrInputStream( name, inputStream );
+  return new AntlrInputStream( name, inputStream, false, inputStringCopy );
 }
 
 
@@ -167,25 +212,22 @@ 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());
-  assert( inputStr!=NULL && nameStr!=NULL );
-#ifdef CVC4_ANTLR3_OLD_INPUT_STREAM
-  pANTLR3_INPUT_STREAM inputStream =
-      antlr3NewAsciiStringInPlaceStream((pANTLR3_UINT8) inputStr,
-                                        input.size(),
-                                        (pANTLR3_UINT8) nameStr);
-#else /* CVC4_ANTLR3_OLD_INPUT_STREAM */
-  pANTLR3_INPUT_STREAM inputStream =
-      antlr3StringStreamNew((pANTLR3_UINT8) inputStr,
-                            ANTLR3_ENC_8BIT,
-                            input.size(),
-                            (pANTLR3_UINT8) nameStr);
-#endif /* CVC4_ANTLR3_OLD_INPUT_STREAM */
+
+  size_t input_size = input.size();
+  assert(input_size <= std::numeric_limits<uint32_t>::max());
+
+  // Ownership of input_duplicate  is transferred to the AntlrInputStream.
+  pANTLR3_UINT8 input_duplicate = (pANTLR3_UINT8) strdup(input.c_str());
+
+  if( input_duplicate == NULL ) {
+    throw InputStreamException("Couldn't initialize string input: '" + input + "'");
+  }
+
+  pANTLR3_INPUT_STREAM inputStream = newAntrl3InPlaceStream(input_duplicate, (uint32_t)input_size, name);
   if( inputStream==NULL ) {
     throw InputStreamException("Couldn't initialize string input: '" + input + "'");
   }
-  return new AntlrInputStream( name, inputStream );
+  return new AntlrInputStream( name, inputStream, false, input_duplicate );
 }
 
 AntlrInput* AntlrInput::newInput(InputLanguage lang, AntlrInputStream& inputStream) {
@@ -291,6 +333,7 @@ void AntlrInput::warning(const std::string& message) {
 }
 
 
+
 /**
  * characters considered part of a simple symbol in SMTLIB.
  *
index a869fa1e8f93c82a5a22be0f446743457525749b..2086db714577e784e29c90329410b7262cb51b44 100644 (file)
@@ -55,11 +55,21 @@ namespace parser {
 
 /** Wrapper around an ANTLR3 input stream. */
 class AntlrInputStream : public InputStream {
+private:
   pANTLR3_INPUT_STREAM d_input;
 
+  /**
+   * If the AntlrInputStream corresponds to reading from a string,
+   * this is the string literal. The memory is owned by the Antlr3Input. It is
+   * assumed to be copied from malloc, and can be free'd at destruction time.
+   * It is otherwise NULL.
+   */
+  pANTLR3_UINT8 d_inputString;
+
   AntlrInputStream(std::string name,
                    pANTLR3_INPUT_STREAM input,
-                   bool fileIsTemporary = false);
+                   bool fileIsTemporary,
+                   pANTLR3_UINT8 inputString);
 
   /* This is private and unimplemented, because you should never use it. */
   AntlrInputStream(const AntlrInputStream& inputStream) CVC4_UNUSED;
@@ -79,22 +89,24 @@ 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, 
+  static AntlrInputStream* newFileInputStream(const std::string& name,
                                               bool useMmap = false)
     throw (InputStreamException);
 
   /** Create an input from an istream. */
-  static AntlrInputStream* newStreamInputStream(std::istream& input, 
+  static AntlrInputStream* newStreamInputStream(std::istream& input,
                                                 const std::string& name,
                                                 bool lineBuffered = false)
     throw (InputStreamException);
 
   /** Create a string input.
+   * NOTE: the new AntlrInputStream will take ownership of input over
+   * and free it at destruction time.
    *
    * @param input the string to read
    * @param name the "filename" to use when reporting errors
    */
-  static AntlrInputStream* newStringInputStream(const std::string& input, 
+  static AntlrInputStream* newStringInputStream(const std::string& input,
                                                 const std::string& name)
     throw (InputStreamException);
 };/* class AntlrInputStream */
@@ -156,8 +168,9 @@ public:
   /** Destructor. Frees the token stream and closes the input. */
   virtual ~AntlrInput();
 
-  /** Create an input for the given AntlrInputStream. NOTE: the new Input
-   * will take ownership of the input stream and delete it at destruction time.
+  /** Create an input for the given AntlrInputStream.
+   * NOTE: the new Input will take ownership of the input stream and delete it
+   * at destruction time.
    *
    * @param lang the input language
    * @param inputStream the input stream
index 53bf0506454d265efd0c41b25a727b26d755c3ea..09f71800b814834dab522bf601cf2b0aa1b7f36c 100644 (file)
@@ -60,12 +60,12 @@ Input* Input::newFileInput(InputLanguage lang,
   return AntlrInput::newInput(lang, *inputStream);
 }
 
-Input* Input::newStreamInput(InputLanguage lang, 
-                             std::istream& input, 
+Input* Input::newStreamInput(InputLanguage lang,
+                             std::istream& input,
                              const std::string& name,
                              bool lineBuffered)
   throw (InputStreamException) {
-  AntlrInputStream *inputStream = 
+  AntlrInputStream *inputStream =
     AntlrInputStream::newStreamInputStream(input, name, lineBuffered);
   return AntlrInput::newInput(lang, *inputStream);
 }