diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2013-09-16 22:25:30 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2013-09-17 06:55:42 +0200 |
commit | d11592ad8e21970e80f6a87a9ae43d380f1c3eef (patch) | |
tree | c9d52c17dd100e9edfe12c8acad1d1a4ddbbf8c4 | |
parent | 65a1f81a70e4268801a09106df54fcb2497c6d7d (diff) |
Move full file parsing logic to sourceprovider-parser.y
...in preparation of SourceFile- vs. -TreeProvider.
Change-Id: I4c8f37ade1ba26cb7b38f63211711613d1b98a73
-rw-r--r-- | unoidl/source/sourceprovider-parser-requires.hxx | 2 | ||||
-rw-r--r-- | unoidl/source/sourceprovider-parser.y | 87 | ||||
-rw-r--r-- | unoidl/source/sourceprovider-scanner.hxx | 16 | ||||
-rwxr-xr-x | unoidl/source/sourceprovider.cxx | 105 |
4 files changed, 107 insertions, 103 deletions
diff --git a/unoidl/source/sourceprovider-parser-requires.hxx b/unoidl/source/sourceprovider-parser-requires.hxx index 0c52b3db802d..fc84c5d41e02 100644 --- a/unoidl/source/sourceprovider-parser-requires.hxx +++ b/unoidl/source/sourceprovider-parser-requires.hxx @@ -23,8 +23,6 @@ typedef void * yyscan_t; -int yyparse(yyscan_t yyscanner); - namespace unoidl { namespace detail { struct SourceProviderEntity; diff --git a/unoidl/source/sourceprovider-parser.y b/unoidl/source/sourceprovider-parser.y index cc18854b1245..92deb23d96e4 100644 --- a/unoidl/source/sourceprovider-parser.y +++ b/unoidl/source/sourceprovider-parser.y @@ -19,10 +19,13 @@ #include <algorithm> #include <cassert> +#include <cerrno> #include <cstddef> #include <cstdlib> #include <limits> +#include <new> #include <utility> +#include <vector> #include <sourceprovider-parser-requires.hxx> @@ -50,6 +53,9 @@ %{ +#include "osl/file.h" +#include "osl/thread.h" + #include "sourceprovider-scanner.hxx" #define YYLLOC_DEFAULT(Current, Rhs, N) \ @@ -3657,6 +3663,87 @@ OUString SourceProviderType::getName() const { } } +bool parse(OUString const & uri, SourceProviderScannerData * data) { + assert(data != 0); + oslFileHandle handle; + oslFileError e = osl_openFile(uri.pData, &handle, osl_File_OpenFlag_Read); + switch (e) { + case osl_File_E_None: + break; + case osl_File_E_NOENT: + return false; + default: + throw FileFormatException(uri, "cannot open: " + OUString::number(e)); + } + sal_uInt64 size; + e = osl_getFileSize(handle, &size); + if (e != osl_File_E_None) { + oslFileError e2 = osl_closeFile(handle); + SAL_WARN_IF( + e2 != osl_File_E_None, "unoidl", + "cannot close " << uri << ": " << +e2); + throw FileFormatException( + uri, "cannot get size: " + OUString::number(e)); + } + void * address; + e = osl_mapFile(handle, &address, size, 0, osl_File_MapFlag_RandomAccess); + if (e != osl_File_E_None) { + oslFileError e2 = osl_closeFile(handle); + SAL_WARN_IF( + e2 != osl_File_E_None, "unoidl", + "cannot close " << uri << ": " << +e2); + throw FileFormatException(uri, "cannot mmap: " + OUString::number(e)); + } + try { + data->setSource(address, size); + yyscan_t yyscanner; + if (yylex_init_extra(data, &yyscanner) != 0) { + // Checking errno for the specific EINVAL, ENOMEM documented for + // yylex_init_extra would not work as those values are not defined + // by the C++ Standard: + int e = errno; + throw FileFormatException( + uri, + "yylex_init_extra failed with errno " + OUString::number(e)); + } + int e2 = yyparse(yyscanner); + yylex_destroy(yyscanner); + switch (e2) { + case 0: + break; + default: + assert(false); + // fall through + case 1: + throw FileFormatException( + uri, + ("cannot parse" + + (data->errorLine == 0 + ? OUString() : " line " + OUString::number(data->errorLine)) + + (data->parserError.isEmpty() + ? OUString() + : (", " + + OStringToOUString( + data->parserError, osl_getThreadTextEncoding()))) + + (data->errorMessage.isEmpty() + ? OUString() : ": \"" + data->errorMessage + "\""))); + case 2: + throw std::bad_alloc(); + } + } catch (...) { + e = osl_unmapMappedFile(handle, address, size); + SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e); + e = osl_closeFile(handle); + SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e); + throw; + } + e = osl_unmapMappedFile(handle, address, size); + SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e); + e = osl_closeFile(handle); + SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e); + return true; +} + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unoidl/source/sourceprovider-scanner.hxx b/unoidl/source/sourceprovider-scanner.hxx index 51900580e987..8a79d3172d6d 100644 --- a/unoidl/source/sourceprovider-scanner.hxx +++ b/unoidl/source/sourceprovider-scanner.hxx @@ -213,17 +213,19 @@ struct SourceProviderEntity { struct SourceProviderScannerData { SourceProviderScannerData( - rtl::Reference<unoidl::Manager> const & theManager, - void const * sourceAddress, sal_uInt64 sourceSize): - manager(theManager), - sourcePosition(static_cast<char const *>(sourceAddress)), - sourceEnd(sourcePosition + sourceSize), errorLine(0) + rtl::Reference<unoidl::Manager> const & theManager): + manager(theManager), errorLine(0) { assert(manager.is()); } + void setSource(void const * address, sal_uInt64 size) { + sourcePosition = static_cast<char const *>(address); + sourceEnd = sourcePosition + size; + } + rtl::Reference<unoidl::Manager> manager; char const * sourcePosition; - char const * const sourceEnd; + char const * sourceEnd; YYLTYPE errorLine; OString parserError; OUString errorMessage; @@ -233,6 +235,8 @@ struct SourceProviderScannerData { OUString currentName; }; +bool parse(OUString const & uri, SourceProviderScannerData * data); + } } int yylex_init_extra( diff --git a/unoidl/source/sourceprovider.cxx b/unoidl/source/sourceprovider.cxx index 429f68f41898..64428eb72839 100755 --- a/unoidl/source/sourceprovider.cxx +++ b/unoidl/source/sourceprovider.cxx @@ -9,13 +9,11 @@ #include "sal/config.h" -#include <cerrno> #include <map> -#include <new> +#include <vector> #include "osl/file.h" #include "osl/file.hxx" -#include "osl/thread.h" #include "rtl/character.hxx" #include "rtl/ref.hxx" #include "rtl/ustrbuf.hxx" @@ -31,51 +29,6 @@ namespace unoidl { namespace detail { namespace { -rtl::Reference<Entity> parse( - rtl::Reference<Manager> const & manager, OUString const & name, - OUString const & uri, void const * address, sal_uInt64 size) -{ - SourceProviderScannerData data(manager, address, size); - yyscan_t yyscanner; - if (yylex_init_extra(&data, &yyscanner) != 0) { - // Checking errno for the specific EINVAL, ENOMEM documented for - // yylex_init_extra would not work as those values are not defined by - // the C++ Standard: - int e = errno; - throw FileFormatException( - uri, "yylex_init_extra failed with errno " + OUString::number(e)); - } - int e = yyparse(yyscanner); - yylex_destroy(yyscanner); - switch (e) { - case 0: - { - std::map<OUString, SourceProviderEntity>::const_iterator i( - data.entities.find(name)); - return i == data.entities.end() - ? rtl::Reference<Entity>() : i->second.entity; - } - default: - assert(false); - // fall through - case 1: - throw FileFormatException( - uri, - ("cannot parse" - + (data.errorLine == 0 - ? OUString() : " line " + OUString::number(data.errorLine)) - + (data.parserError.isEmpty() - ? OUString() - : (", " - + OStringToOUString( - data.parserError, osl_getThreadTextEncoding()))) - + (data.errorMessage.isEmpty() - ? OUString() : ": \"" + data.errorMessage + "\""))); - case 2: - throw std::bad_alloc(); - } -} - class Cursor: public MapCursor { public: Cursor() {} @@ -173,55 +126,17 @@ rtl::Reference<Entity> SourceProvider::findEntity(OUString const & name) const { ent = new SourceModuleEntity; } else { uri += ".idl"; - oslFileHandle handle; - oslFileError e = osl_openFile( - uri.pData, &handle, osl_File_OpenFlag_Read); - switch (e) { - case osl_File_E_None: - break; - case osl_File_E_NOENT: - cache_.insert( - std::map< OUString, rtl::Reference<Entity> >::value_type( - name, rtl::Reference<Entity>())); - return rtl::Reference<Entity>(); - default: - throw FileFormatException( - uri, "cannot open: " + OUString::number(e)); - } - sal_uInt64 size; - e = osl_getFileSize(handle, &size); - if (e != osl_File_E_None) { - oslFileError e2 = osl_closeFile(handle); - SAL_WARN_IF( - e2 != osl_File_E_None, "unoidl", - "cannot close " << uri << ": " << +e2); - throw FileFormatException( - uri, "cannot get size: " + OUString::number(e)); - } - void * address; - e = osl_mapFile( - handle, &address, size, 0, osl_File_MapFlag_RandomAccess); - if (e != osl_File_E_None) { - oslFileError e2 = osl_closeFile(handle); + SourceProviderScannerData data(manager_); + if (parse(uri, &data)) { + std::map<OUString, SourceProviderEntity>::const_iterator i( + data.entities.find(name)); + if (i != data.entities.end()) { + ent = i->second.entity; + } SAL_WARN_IF( - e2 != osl_File_E_None, "unoidl", - "cannot close " << uri << ": " << +e2); - throw FileFormatException( - uri, "cannot mmap: " + OUString::number(e)); - } - try { - ent = parse(manager_, name, uri, address, size); - } catch (...) { - e = osl_unmapMappedFile(handle, address, size); - SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e); - e = osl_closeFile(handle); - SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e); - throw; + !ent.is(), "unoidl", + "<" << uri << "> does not define entity " << name); } - e = osl_unmapMappedFile(handle, address, size); - SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e); - e = osl_closeFile(handle); - SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e); } cache_.insert( std::map< OUString, rtl::Reference<Entity> >::value_type(name, ent)); |