summaryrefslogtreecommitdiff
path: root/unoidl
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2013-09-16 22:25:30 +0200
committerStephan Bergmann <sbergman@redhat.com>2013-09-17 06:55:42 +0200
commitd11592ad8e21970e80f6a87a9ae43d380f1c3eef (patch)
treec9d52c17dd100e9edfe12c8acad1d1a4ddbbf8c4 /unoidl
parent65a1f81a70e4268801a09106df54fcb2497c6d7d (diff)
Move full file parsing logic to sourceprovider-parser.y
...in preparation of SourceFile- vs. -TreeProvider. Change-Id: I4c8f37ade1ba26cb7b38f63211711613d1b98a73
Diffstat (limited to 'unoidl')
-rw-r--r--unoidl/source/sourceprovider-parser-requires.hxx2
-rw-r--r--unoidl/source/sourceprovider-parser.y87
-rw-r--r--unoidl/source/sourceprovider-scanner.hxx16
-rwxr-xr-xunoidl/source/sourceprovider.cxx105
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));