From b95f93789c8695365bc1741fe88fca9473a0d02c Mon Sep 17 00:00:00 2001 From: Tim King Date: Mon, 23 Nov 2015 16:30:24 -0800 Subject: [PATCH] Isolating the dependencies on CVC4_ANTLR3_OLD_INPUT_STREAM. Also freeing more memory for antlr input. --- src/parser/antlr_input.cpp | 149 ++++++++++++++++++++++++------------- src/parser/antlr_input.h | 25 +++++-- src/parser/input.cpp | 6 +- 3 files changed, 118 insertions(+), 62 deletions(-) diff --git a/src/parser/antlr_input.cpp b/src/parser/antlr_input.cpp index 4c779c46a..1d2dbd736 100644 --- a/src/parser/antlr_input.cpp +++ b/src/parser/antlr_input.cpp @@ -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::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::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. * diff --git a/src/parser/antlr_input.h b/src/parser/antlr_input.h index a869fa1e8..2086db714 100644 --- a/src/parser/antlr_input.h +++ b/src/parser/antlr_input.h @@ -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 true 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 diff --git a/src/parser/input.cpp b/src/parser/input.cpp index 53bf05064..09f71800b 100644 --- a/src/parser/input.cpp +++ b/src/parser/input.cpp @@ -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); } -- 2.30.2