WIP: additional unoidl::Provider that directly reads from .idl files
Change-Id: I30fa6400724f4ca6f0e1986c741500f05710b840
This commit is contained in:
parent
3ea6e49f58
commit
5c2ba4aad6
7 changed files with 4535 additions and 0 deletions
48
include/unoidl/sourceprovider.hxx
Normal file
48
include/unoidl/sourceprovider.hxx
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_UNOIDL_SOURCEPROVIDER_HXX
|
||||
#define INCLUDED_UNOIDL_SOURCEPROVIDER_HXX
|
||||
|
||||
#include "sal/config.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "rtl/ref.hxx"
|
||||
#include "sal/types.h"
|
||||
#include "unoidl/detail/dllapi.hxx"
|
||||
#include "unoidl/unoidl.hxx"
|
||||
|
||||
namespace unoidl {
|
||||
|
||||
class LO_DLLPUBLIC_UNOIDL SourceProvider: public Provider {
|
||||
public:
|
||||
// throws FileFormatException, NoSuchFileException:
|
||||
SourceProvider(
|
||||
rtl::Reference<Manager> const & manager, OUString const & uri);
|
||||
|
||||
// throws FileFormatException:
|
||||
virtual rtl::Reference<MapCursor> createRootCursor() const;
|
||||
|
||||
// throws FileFormatException:
|
||||
virtual rtl::Reference<Entity> findEntity(OUString const & name) const;
|
||||
|
||||
private:
|
||||
virtual SAL_DLLPRIVATE ~SourceProvider() throw ();
|
||||
|
||||
rtl::Reference<Manager> manager_;
|
||||
OUString uri_;
|
||||
mutable std::map< OUString, rtl::Reference<Entity> > cache_; //TODO: at manager
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
|
@ -13,10 +13,24 @@ $(eval $(call gb_Library_add_defs,unoidl,-DLO_DLLIMPLEMENTATION_UNOIDL))
|
|||
|
||||
$(eval $(call gb_Library_add_exception_objects,unoidl, \
|
||||
unoidl/source/legacyprovider \
|
||||
unoidl/source/sourceprovider \
|
||||
unoidl/source/unoidl \
|
||||
unoidl/source/unoidlprovider \
|
||||
))
|
||||
|
||||
$(eval $(call gb_Library_add_grammars,unoidl, \
|
||||
unoidl/source/sourceprovider-parser \
|
||||
))
|
||||
|
||||
$(eval $(call gb_Library_add_scanners,unoidl, \
|
||||
unoidl/source/sourceprovider-scanner \
|
||||
))
|
||||
|
||||
$(eval $(call gb_Library_set_include,unoidl, \
|
||||
$$(INCLUDE) \
|
||||
-I$(SRCDIR)/unoidl/source \
|
||||
))
|
||||
|
||||
$(eval $(call gb_Library_use_libraries,unoidl, \
|
||||
reg \
|
||||
sal \
|
||||
|
|
136
unoidl/source/sourceprovider-parser-requires.hxx
Normal file
136
unoidl/source/sourceprovider-parser-requires.hxx
Normal file
|
@ -0,0 +1,136 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_UNOIDL_SOURCE_SOURCEPROVIDER_PARSER_REQUIRES_HXX
|
||||
#define INCLUDED_UNOIDL_SOURCE_SOURCEPROVIDER_PARSER_REQUIRES_HXX
|
||||
|
||||
#include "sal/config.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "rtl/string.hxx"
|
||||
#include "rtl/ustring.hxx"
|
||||
#include "sal/types.h"
|
||||
#include "unoidl/unoidl.hxx"
|
||||
|
||||
#define YYLTYPE int
|
||||
|
||||
typedef void * yyscan_t;
|
||||
|
||||
int yyparse(yyscan_t yyscanner);
|
||||
|
||||
namespace unoidl { namespace detail {
|
||||
|
||||
struct SourceProviderEntity;
|
||||
|
||||
enum SourceProviderAccessDecls { ACCESS_DECL_GET = 0x1, ACCESS_DECL_SET = 0x2 };
|
||||
|
||||
enum SourceProviderFlags {
|
||||
FLAG_ATTRIBUTE = 0x001, FLAG_BOUND = 0x002, FLAG_CONSTRAINED = 0x004,
|
||||
FLAG_MAYBEAMBIGUOUS = 0x008, FLAG_MAYBEDEFAULT = 0x010,
|
||||
FLAG_MAYBEVOID = 0x020, FLAG_OPTIONAL = 0x040, FLAG_PROPERTY = 0x080,
|
||||
FLAG_READONLY = 0x100, FLAG_REMOVABLE = 0x200, FLAG_TRANSIENT = 0x400
|
||||
};
|
||||
|
||||
struct SourceProviderExpr {
|
||||
static SourceProviderExpr Bool(bool v) {
|
||||
SourceProviderExpr e;
|
||||
e.type = TYPE_BOOL;
|
||||
e.bval = v;
|
||||
return e;
|
||||
}
|
||||
|
||||
static SourceProviderExpr Int(sal_Int64 v) {
|
||||
SourceProviderExpr e;
|
||||
e.type = TYPE_INT;
|
||||
e.ival = v;
|
||||
return e;
|
||||
}
|
||||
|
||||
static SourceProviderExpr Uint(sal_uInt64 v) {
|
||||
SourceProviderExpr e;
|
||||
e.type = TYPE_UINT;
|
||||
e.uval = v;
|
||||
return e;
|
||||
}
|
||||
|
||||
static SourceProviderExpr Float(double v) {
|
||||
SourceProviderExpr e;
|
||||
e.type = TYPE_FLOAT;
|
||||
e.fval = v;
|
||||
return e;
|
||||
}
|
||||
|
||||
enum Type { TYPE_BOOL, TYPE_INT, TYPE_UINT, TYPE_FLOAT };
|
||||
|
||||
Type type;
|
||||
union {
|
||||
bool bval;
|
||||
sal_Int64 ival;
|
||||
sal_uInt64 uval;
|
||||
double fval;
|
||||
};
|
||||
};
|
||||
|
||||
struct SourceProviderType {
|
||||
enum Type {
|
||||
TYPE_VOID, TYPE_BOOLEAN, TYPE_BYTE, TYPE_SHORT, TYPE_UNSIGNED_SHORT,
|
||||
TYPE_LONG, TYPE_UNSIGNED_LONG, TYPE_HYPER, TYPE_UNSIGNED_HYPER,
|
||||
TYPE_FLOAT, TYPE_DOUBLE, TYPE_CHAR, TYPE_STRING, TYPE_TYPE, TYPE_ANY,
|
||||
TYPE_SEQUENCE, TYPE_ENUM, TYPE_PLAIN_STRUCT, TYPE_EXCEPTION,
|
||||
TYPE_INTERFACE, TYPE_INSTANTIATED_POLYMORPHIC_STRUCT, TYPE_PARAMETER
|
||||
};
|
||||
|
||||
SourceProviderType() {}
|
||||
|
||||
explicit SourceProviderType(Type theType): type(theType)
|
||||
{ assert(theType <= TYPE_ANY); }
|
||||
|
||||
explicit SourceProviderType(SourceProviderType const * componentType):
|
||||
type(TYPE_SEQUENCE)
|
||||
{ assert(componentType != 0); subtypes.push_back(*componentType); }
|
||||
|
||||
SourceProviderType(
|
||||
Type theType, OUString const & theName,
|
||||
SourceProviderEntity const * theEntity):
|
||||
type(theType), name(theName), entity(theEntity)
|
||||
{
|
||||
assert(theType >= TYPE_ENUM && theType <= TYPE_INTERFACE);
|
||||
assert(theEntity != 0);
|
||||
}
|
||||
|
||||
SourceProviderType(
|
||||
OUString const & polymorphicStructTypeTemplateName,
|
||||
SourceProviderEntity const * theEntity,
|
||||
std::vector<SourceProviderType> const & typeArguments):
|
||||
type(TYPE_INSTANTIATED_POLYMORPHIC_STRUCT),
|
||||
name(polymorphicStructTypeTemplateName), entity(theEntity),
|
||||
subtypes(typeArguments)
|
||||
{ assert(theEntity != 0); }
|
||||
|
||||
explicit SourceProviderType(OUString const & identifier):
|
||||
type(TYPE_PARAMETER), name(identifier)
|
||||
{}
|
||||
|
||||
OUString getName() const;
|
||||
|
||||
Type type;
|
||||
OUString name; // TYPE_ENUM ... TYPE_PARAMETER
|
||||
SourceProviderEntity const * entity;
|
||||
// TYPE_ENUM ... TYPE_INSTANTIATED_POLYMOPRHIC_STRUCT
|
||||
std::vector<SourceProviderType> subtypes;
|
||||
// TYPE_SEQUENCE, TYPE_INSTANTIATED_POLYMOPRHIC_STRUCT
|
||||
OUString typedefName;
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
#endif
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
3631
unoidl/source/sourceprovider-parser.y
Normal file
3631
unoidl/source/sourceprovider-parser.y
Normal file
File diff suppressed because it is too large
Load diff
247
unoidl/source/sourceprovider-scanner.hxx
Normal file
247
unoidl/source/sourceprovider-scanner.hxx
Normal file
|
@ -0,0 +1,247 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_UNOIDL_SOURCE_SOURCEPROVIDER_SCANNER_HXX
|
||||
#define INCLUDED_UNOIDL_SOURCE_SOURCEPROVIDER_SCANNER_HXX
|
||||
|
||||
#include "sal/config.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "rtl/ref.hxx"
|
||||
#include "rtl/ustring.hxx"
|
||||
#include "sal/types.h"
|
||||
#include "salhelper/simplereferenceobject.hxx"
|
||||
#include "unoidl/unoidl.hxx"
|
||||
|
||||
#include "sourceprovider-parser-requires.hxx"
|
||||
#include "sourceprovider-parser.hxx"
|
||||
|
||||
namespace unoidl { namespace detail {
|
||||
|
||||
class SourceProviderEntityPad: public salhelper::SimpleReferenceObject {
|
||||
public:
|
||||
bool isPublished() const { return published_; }
|
||||
|
||||
protected:
|
||||
explicit SourceProviderEntityPad(bool published): published_(published) {}
|
||||
|
||||
virtual ~SourceProviderEntityPad() {}
|
||||
|
||||
private:
|
||||
bool const published_;
|
||||
};
|
||||
|
||||
class SourceProviderEnumTypeEntityPad: public SourceProviderEntityPad {
|
||||
public:
|
||||
explicit SourceProviderEnumTypeEntityPad(bool published):
|
||||
SourceProviderEntityPad(published)
|
||||
{}
|
||||
|
||||
std::vector<unoidl::EnumTypeEntity::Member> members;
|
||||
|
||||
private:
|
||||
virtual ~SourceProviderEnumTypeEntityPad() throw () {}
|
||||
};
|
||||
|
||||
class SourceProviderPlainStructTypeEntityPad: public SourceProviderEntityPad {
|
||||
public:
|
||||
SourceProviderPlainStructTypeEntityPad(
|
||||
bool published, OUString theBaseName,
|
||||
rtl::Reference<unoidl::PlainStructTypeEntity> const & theBaseEntity):
|
||||
SourceProviderEntityPad(published), baseName(theBaseName),
|
||||
baseEntity(theBaseEntity)
|
||||
{ assert(theBaseName.isEmpty() != theBaseEntity.is()); }
|
||||
|
||||
OUString const baseName;
|
||||
rtl::Reference<unoidl::PlainStructTypeEntity> const baseEntity;
|
||||
std::vector<unoidl::PlainStructTypeEntity::Member> members;
|
||||
|
||||
private:
|
||||
virtual ~SourceProviderPlainStructTypeEntityPad() throw () {}
|
||||
};
|
||||
|
||||
class SourceProviderPolymorphicStructTypeTemplateEntityPad:
|
||||
public SourceProviderEntityPad
|
||||
{
|
||||
public:
|
||||
SourceProviderPolymorphicStructTypeTemplateEntityPad(bool published):
|
||||
SourceProviderEntityPad(published)
|
||||
{}
|
||||
|
||||
std::vector<OUString> typeParameters;
|
||||
std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member> members;
|
||||
|
||||
private:
|
||||
virtual ~SourceProviderPolymorphicStructTypeTemplateEntityPad() throw () {}
|
||||
};
|
||||
|
||||
class SourceProviderExceptionTypeEntityPad: public SourceProviderEntityPad {
|
||||
public:
|
||||
SourceProviderExceptionTypeEntityPad(
|
||||
bool published, OUString theBaseName,
|
||||
rtl::Reference<unoidl::ExceptionTypeEntity> const & theBaseEntity):
|
||||
SourceProviderEntityPad(published), baseName(theBaseName),
|
||||
baseEntity(theBaseEntity)
|
||||
{ assert(theBaseName.isEmpty() != theBaseEntity.is()); }
|
||||
|
||||
OUString const baseName;
|
||||
rtl::Reference<unoidl::ExceptionTypeEntity> const baseEntity;
|
||||
std::vector<unoidl::ExceptionTypeEntity::Member> members;
|
||||
|
||||
private:
|
||||
virtual ~SourceProviderExceptionTypeEntityPad() throw () {}
|
||||
};
|
||||
|
||||
class SourceProviderInterfaceTypeEntityPad: public SourceProviderEntityPad {
|
||||
public:
|
||||
struct Base {
|
||||
Base(
|
||||
OUString const & theName,
|
||||
rtl::Reference<unoidl::InterfaceTypeEntity> const & theEntity,
|
||||
std::vector<OUString> const & theAnnotations):
|
||||
name(theName), entity(theEntity), annotations(theAnnotations)
|
||||
{}
|
||||
|
||||
OUString name;
|
||||
rtl::Reference<unoidl::InterfaceTypeEntity> entity;
|
||||
std::vector<OUString> annotations;
|
||||
};
|
||||
|
||||
SourceProviderInterfaceTypeEntityPad(
|
||||
bool published, OUString singleBaseName,
|
||||
rtl::Reference<unoidl::InterfaceTypeEntity> const & singleBaseEntity):
|
||||
SourceProviderEntityPad(published),
|
||||
singleBase(!singleBaseName.isEmpty())
|
||||
{
|
||||
assert(singleBaseName.isEmpty() != singleBaseEntity.is());
|
||||
if (singleBase) {
|
||||
mandatoryBases.push_back(
|
||||
Base(
|
||||
singleBaseName, singleBaseEntity, std::vector<OUString>()));
|
||||
}
|
||||
}
|
||||
|
||||
bool singleBase;
|
||||
std::vector<Base> mandatoryBases;
|
||||
std::vector<Base> optionalBases;
|
||||
std::vector<unoidl::InterfaceTypeEntity::Attribute> attributes;
|
||||
std::vector<unoidl::InterfaceTypeEntity::Method> methods;
|
||||
|
||||
private:
|
||||
virtual ~SourceProviderInterfaceTypeEntityPad() throw () {}
|
||||
};
|
||||
|
||||
class SourceProviderConstantGroupEntityPad: public SourceProviderEntityPad {
|
||||
public:
|
||||
explicit SourceProviderConstantGroupEntityPad(bool published):
|
||||
SourceProviderEntityPad(published)
|
||||
{}
|
||||
|
||||
std::vector<unoidl::ConstantGroupEntity::Member> members;
|
||||
|
||||
private:
|
||||
virtual ~SourceProviderConstantGroupEntityPad() throw () {}
|
||||
};
|
||||
|
||||
class SourceProviderSingleInterfaceBasedServiceEntityPad:
|
||||
public SourceProviderEntityPad
|
||||
{
|
||||
public:
|
||||
explicit SourceProviderSingleInterfaceBasedServiceEntityPad(
|
||||
bool published, OUString const & theBase):
|
||||
SourceProviderEntityPad(published), base(theBase)
|
||||
{}
|
||||
|
||||
OUString const base;
|
||||
std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>
|
||||
constructors;
|
||||
|
||||
private:
|
||||
virtual ~SourceProviderSingleInterfaceBasedServiceEntityPad() throw () {}
|
||||
};
|
||||
|
||||
class SourceProviderAccumulationBasedServiceEntityPad:
|
||||
public SourceProviderEntityPad
|
||||
{
|
||||
public:
|
||||
explicit SourceProviderAccumulationBasedServiceEntityPad(bool published):
|
||||
SourceProviderEntityPad(published)
|
||||
{}
|
||||
|
||||
std::vector<unoidl::AnnotatedReference> directMandatoryBaseServices;
|
||||
std::vector<unoidl::AnnotatedReference> directOptionalBaseServices;
|
||||
std::vector<unoidl::AnnotatedReference> directMandatoryBaseInterfaces;
|
||||
std::vector<unoidl::AnnotatedReference> directOptionalBaseInterfaces;
|
||||
std::vector<unoidl::AccumulationBasedServiceEntity::Property>
|
||||
directProperties;
|
||||
|
||||
private:
|
||||
virtual ~SourceProviderAccumulationBasedServiceEntityPad() throw () {}
|
||||
};
|
||||
|
||||
struct SourceProviderEntity {
|
||||
enum Kind { KIND_EXTERNAL, KIND_LOCAL, KIND_INTERFACE_DECL };
|
||||
|
||||
explicit SourceProviderEntity(
|
||||
Kind theKind, rtl::Reference<unoidl::Entity> const & externalEntity):
|
||||
kind(theKind), entity(externalEntity)
|
||||
{ assert(theKind != KIND_INTERFACE_DECL); assert(externalEntity.is()); }
|
||||
|
||||
explicit SourceProviderEntity(
|
||||
rtl::Reference<SourceProviderEntityPad> const & localPad):
|
||||
kind(KIND_LOCAL), pad(localPad)
|
||||
{ assert(localPad.is()); }
|
||||
|
||||
SourceProviderEntity(): kind(KIND_INTERFACE_DECL) {}
|
||||
|
||||
Kind kind;
|
||||
rtl::Reference<unoidl::Entity> entity;
|
||||
rtl::Reference<SourceProviderEntityPad> pad;
|
||||
};
|
||||
|
||||
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)
|
||||
{ assert(manager.is()); }
|
||||
|
||||
rtl::Reference<unoidl::Manager> manager;
|
||||
|
||||
char const * sourcePosition;
|
||||
char const * const sourceEnd;
|
||||
YYLTYPE errorLine;
|
||||
OString parserError;
|
||||
OUString errorMessage;
|
||||
|
||||
std::map<OUString, SourceProviderEntity> entities;
|
||||
std::vector<OUString> modules;
|
||||
OUString currentName;
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
int yylex_init_extra(
|
||||
unoidl::detail::SourceProviderScannerData * user_defined,
|
||||
yyscan_t * yyscanner);
|
||||
|
||||
int yylex_destroy(yyscan_t yyscanner);
|
||||
|
||||
int yylex(YYSTYPE * yylval_param, YYLTYPE * yylloc_param, yyscan_t yyscanner);
|
||||
|
||||
unoidl::detail::SourceProviderScannerData * yyget_extra(yyscan_t yyscanner);
|
||||
|
||||
#endif
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
253
unoidl/source/sourceprovider-scanner.l
Executable file
253
unoidl/source/sourceprovider-scanner.l
Executable file
|
@ -0,0 +1,253 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
%option bison-bridge
|
||||
%option bison-locations
|
||||
%option extra-type="unoidl::detail::SourceProviderScannerData *"
|
||||
%option never-interactive
|
||||
%option nounistd
|
||||
%option noyywrap
|
||||
%option reentrant
|
||||
%option warn
|
||||
%option yylineno
|
||||
|
||||
%top {
|
||||
|
||||
#include "sal/config.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
}
|
||||
|
||||
%{
|
||||
|
||||
#include "rtl/math.h"
|
||||
#include "rtl/string.hxx"
|
||||
#include "rtl/ustring.hxx"
|
||||
#include "rtl/textenc.h"
|
||||
#include "sal/types.h"
|
||||
|
||||
#include "sourceprovider-parser-requires.hxx"
|
||||
#include "sourceprovider-parser.hxx"
|
||||
#include "sourceprovider-scanner.hxx"
|
||||
|
||||
namespace unoidl { namespace detail {
|
||||
|
||||
static std::size_t sourceProviderScannerInput(
|
||||
SourceProviderScannerData * data, char * buffer, std::size_t size)
|
||||
{
|
||||
assert(data != 0);
|
||||
if (data->sourcePosition == data->sourceEnd) {
|
||||
return YY_NULL;
|
||||
}
|
||||
assert(data->sourcePosition < data->sourceEnd);
|
||||
size = std::min<std::size_t>(size, data->sourceEnd - data->sourcePosition);
|
||||
std::memcpy(buffer, data->sourcePosition, size);
|
||||
data->sourcePosition += size;
|
||||
return size;
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
#define YY_INPUT(buf, result, max_size) ((result) = \
|
||||
::unoidl::detail::sourceProviderScannerInput(yyextra, (buf), (max_size)))
|
||||
|
||||
namespace {
|
||||
|
||||
int nonZeroIntegerLiteral(
|
||||
char const * text, std::size_t length, sal_Int16 radix, sal_uInt64 * value,
|
||||
unoidl::detail::SourceProviderScannerData * data)
|
||||
{
|
||||
assert(text != 0);
|
||||
assert(length != 0);
|
||||
assert(value != 0);
|
||||
assert(data != 0);
|
||||
std::size_t n = length;
|
||||
switch (text[length - 1]) {
|
||||
case 'L':
|
||||
case 'U':
|
||||
case 'l':
|
||||
case 'u':
|
||||
--n;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*value = OString(text, n).toUInt64(radix);
|
||||
if (*value == 0) {
|
||||
data->errorMessage = "out-of-range integer literal "
|
||||
+ OUString(text, length, RTL_TEXTENCODING_ASCII_US);
|
||||
return TOK_ERROR;
|
||||
}
|
||||
return TOK_INTEGER;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%x comment1 comment2 doc docdepr
|
||||
|
||||
DIGIT [0-9]
|
||||
UPPER [A-Z]
|
||||
LOWER [a-z]
|
||||
ALPHA {UPPER}|{LOWER}
|
||||
ALNUM {DIGIT}|{ALPHA}
|
||||
|
||||
%%
|
||||
|
||||
[ \t\r]
|
||||
\n *yylloc = yylineno;
|
||||
|
||||
"//" BEGIN comment1;
|
||||
"#" BEGIN comment1; //TODO: only at start of line
|
||||
<comment1>.
|
||||
<comment1>\n *yylloc = yylineno; BEGIN INITIAL;
|
||||
|
||||
"/*" BEGIN comment2;
|
||||
"/**" BEGIN doc;
|
||||
"/***" BEGIN comment2;
|
||||
|
||||
<comment2,doc>"*/" BEGIN INITIAL;
|
||||
<docdepr>"*/" BEGIN INITIAL; return TOK_DEPRECATED;
|
||||
|
||||
<comment2,docdepr>.
|
||||
<comment2,doc,docdepr>\n *yylloc = yylineno;
|
||||
<comment2,doc,docdepr><<EOF>> {
|
||||
yyextra->errorMessage = "unterminated comment";
|
||||
return TOK_ERROR;
|
||||
}
|
||||
|
||||
<doc>[ \t\r]
|
||||
<doc>"@deprecated" BEGIN docdepr;
|
||||
<doc>"*"
|
||||
<doc>[^ \t\r\n*]+
|
||||
|
||||
[%&()*+,\-/:;<=>[\]^{|}~] return yytext[0];
|
||||
|
||||
"..." return TOK_ELLIPSIS;
|
||||
"::" return TOK_COLONS;
|
||||
"<<" return TOK_LEFTSHIFT;
|
||||
">>" return TOK_RIGHTSHIFT;
|
||||
|
||||
"FALSE" return TOK_FALSE;
|
||||
"False" return TOK_FALSE;
|
||||
"TRUE" return TOK_TRUE;
|
||||
"True" return TOK_TRUE;
|
||||
"any" return TOK_ANY;
|
||||
"attribute" return TOK_ATTRIBUTE;
|
||||
"boolean" return TOK_BOOLEAN;
|
||||
"bound" return TOK_BOUND;
|
||||
"byte" return TOK_BYTE;
|
||||
"char" return TOK_CHAR;
|
||||
"const" return TOK_CONST;
|
||||
"constants" return TOK_CONSTANTS;
|
||||
"constrained" return TOK_CONSTRAINED;
|
||||
"double" return TOK_DOUBLE;
|
||||
"enum" return TOK_ENUM;
|
||||
"exception" return TOK_EXCEPTION;
|
||||
"float" return TOK_FLOAT;
|
||||
"get" return TOK_GET;
|
||||
"hyper" return TOK_HYPER;
|
||||
"in" return TOK_IN;
|
||||
"inout" return TOK_INOUT;
|
||||
"interface" return TOK_INTERFACE;
|
||||
"long" return TOK_LONG;
|
||||
"maybeambiguous" return TOK_MAYBEAMBIGUOUS;
|
||||
"maybedefault" return TOK_MAYBEDEFAULT;
|
||||
"maybevoid" return TOK_MAYBEVOID;
|
||||
"module" return TOK_MODULE;
|
||||
"optional" return TOK_OPTIONAL;
|
||||
"out" return TOK_OUT;
|
||||
"property" return TOK_PROPERTY;
|
||||
"published" return TOK_PUBLISHED;
|
||||
"raises" return TOK_RAISES;
|
||||
"readonly" return TOK_READONLY;
|
||||
"removable" return TOK_REMOVABLE;
|
||||
"sequence" return TOK_SEQUENCE;
|
||||
"service" return TOK_SERVICE;
|
||||
"set" return TOK_SET;
|
||||
"short" return TOK_SHORT;
|
||||
"singleton" return TOK_SINGLETON;
|
||||
"string" return TOK_STRING;
|
||||
"struct" return TOK_STRUCT;
|
||||
"transient" return TOK_TRANSIENT;
|
||||
"type" return TOK_TYPE;
|
||||
"typedef" return TOK_TYPEDEF;
|
||||
"unsigned" return TOK_UNSIGNED;
|
||||
"void" return TOK_VOID;
|
||||
|
||||
{UPPER}("_"?{ALNUM})*|{LOWER}{ALNUM}* {
|
||||
yylval->sval = new OString(yytext);
|
||||
return TOK_IDENTIFIER;
|
||||
}
|
||||
|
||||
({ALPHA}|"_")({ALNUM}|"_")* {
|
||||
#if 1 //TODO
|
||||
yylval->sval=new OString(yytext);return TOK_IDENTIFIER;
|
||||
#else
|
||||
yyextra->errorMessage = "illegal identifier "
|
||||
+ OUString(yytext, yyleng, RTL_TEXTENCODING_ASCII_US);
|
||||
return TOK_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
0+[LUlu]? |
|
||||
0[Xx]0+[LUlu]? {
|
||||
yylval->ival = 0;
|
||||
return TOK_INTEGER;
|
||||
}
|
||||
|
||||
0[0-7]+[LUlu]? {
|
||||
return nonZeroIntegerLiteral(yytext, yyleng, 8, &yylval->ival, yyextra);
|
||||
}
|
||||
|
||||
[1-9]{DIGIT}*[LUlu]? {
|
||||
return nonZeroIntegerLiteral(yytext, yyleng, 10, &yylval->ival, yyextra);
|
||||
}
|
||||
|
||||
0[Xx][0-9A-Fa-f]+[LUlu]? {
|
||||
return nonZeroIntegerLiteral(
|
||||
yytext + 2, yyleng - 2, 16, &yylval->ival, yyextra);
|
||||
}
|
||||
|
||||
{DIGIT}+[Ee][+\-]?{DIGIT}+[Ff]? |
|
||||
{DIGIT}*"."{DIGIT}+([Ee][+\-]?{DIGIT}+)?[Ff]? {
|
||||
rtl_math_ConversionStatus s;
|
||||
yylval->fval = rtl_math_stringToDouble(
|
||||
yytext, yytext + yyleng, '.', 0, &s, 0);
|
||||
if (s == rtl_math_ConversionStatus_OutOfRange) {
|
||||
yyextra->errorMessage = "out-of-range floating-point literal "
|
||||
+ OUString(yytext, yyleng, RTL_TEXTENCODING_ASCII_US);
|
||||
return TOK_ERROR;
|
||||
}
|
||||
return TOK_FLOATING;
|
||||
}
|
||||
|
||||
{DIGIT}({ALNUM}|"_")* {
|
||||
yyextra->errorMessage = "illegal numeric literal "
|
||||
+ OUString(yytext, yyleng, RTL_TEXTENCODING_ASCII_US);
|
||||
return TOK_ERROR;
|
||||
}
|
||||
|
||||
. {
|
||||
unsigned char c = yytext[0];
|
||||
yyextra->errorMessage = c >= ' ' && c <= '~'
|
||||
? OUString("invalid character \"" + OUString(sal_Unicode(c)) + "\"")
|
||||
: OUString(
|
||||
"invalid byte x" + OUString::number(c, 16).toAsciiUpperCase());
|
||||
return TOK_ERROR;
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
206
unoidl/source/sourceprovider.cxx
Executable file
206
unoidl/source/sourceprovider.cxx
Executable file
|
@ -0,0 +1,206 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* This file is part of the LibreOffice project.
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#include "sal/config.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <map>
|
||||
#include <new>
|
||||
|
||||
#include "osl/file.h"
|
||||
#include "osl/thread.h"
|
||||
#include "rtl/character.hxx"
|
||||
#include "rtl/ref.hxx"
|
||||
#include "rtl/ustrbuf.hxx"
|
||||
#include "rtl/ustring.hxx"
|
||||
#include "unoidl/sourceprovider.hxx"
|
||||
#include "unoidl/unoidl.hxx"
|
||||
|
||||
#include "sourceprovider-parser-requires.hxx"
|
||||
#include "sourceprovider-parser.hxx"
|
||||
#include "sourceprovider-scanner.hxx"
|
||||
|
||||
namespace unoidl {
|
||||
|
||||
namespace {
|
||||
|
||||
rtl::Reference<Entity> parse(
|
||||
rtl::Reference<Manager> const & manager, OUString const & name,
|
||||
OUString const & uri, void const * address, sal_uInt64 size)
|
||||
{
|
||||
detail::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, detail::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() {}
|
||||
|
||||
private:
|
||||
virtual ~Cursor() throw () {}
|
||||
|
||||
virtual rtl::Reference<Entity> getNext(OUString *)
|
||||
{ return rtl::Reference<Entity>(); } //TODO
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
SourceProvider::SourceProvider(
|
||||
rtl::Reference<Manager> const & manager, OUString const & uri):
|
||||
manager_(manager), uri_(uri.endsWith("/") ? uri : uri + "/")
|
||||
{}
|
||||
|
||||
rtl::Reference<MapCursor> SourceProvider::createRootCursor() const {
|
||||
return new Cursor;
|
||||
}
|
||||
|
||||
rtl::Reference<Entity> SourceProvider::findEntity(OUString const & name) const {
|
||||
std::map< OUString, rtl::Reference<Entity> >::iterator ci(
|
||||
cache_.find(name));
|
||||
if (ci != cache_.end()) {
|
||||
return ci->second;
|
||||
}
|
||||
// Match name against
|
||||
// name ::= identifier ("." identifier)*
|
||||
// identifier ::= upper-blocks | lower-block
|
||||
// upper-blocks ::= upper ("_"? alnum)*
|
||||
// lower-block :== lower alnum*
|
||||
// alnum ::= digit | upper | lower
|
||||
// digit ::= "0"--"9"
|
||||
// upper ::= "A"--"Z"
|
||||
// lower ::= "a"--"z"
|
||||
OUStringBuffer buf(name);
|
||||
sal_Int32 start = 0;
|
||||
sal_Int32 i = 0;
|
||||
for (; i != name.getLength(); ++i) {
|
||||
sal_Unicode c = name[i];
|
||||
if (c == '.') {
|
||||
assert(i == start || i != 0);
|
||||
if (i == start || name[i - 1] == '_') {
|
||||
throw FileFormatException( //TODO
|
||||
"", "Illegal UNOIDL identifier \"" + name + "\"");
|
||||
}
|
||||
buf[i] = '/';
|
||||
start = i + 1;
|
||||
} else if (c == '_') {
|
||||
assert(i == start || i != 0);
|
||||
if (i == start || name[i - 1] == '_'
|
||||
|| !rtl::isAsciiUpperCase(name[start]))
|
||||
{
|
||||
throw FileFormatException( //TODO
|
||||
"", "Illegal UNOIDL identifier \"" + name + "\"");
|
||||
}
|
||||
} else if (rtl::isAsciiDigit(c)) {
|
||||
if (i == start) {
|
||||
throw FileFormatException( //TODO
|
||||
"", "Illegal UNOIDL identifier \"" + name + "\"");
|
||||
}
|
||||
} else if (!rtl::isAsciiAlpha(c)) {
|
||||
throw FileFormatException( //TODO
|
||||
"", "Illegal UNOIDL identifier \"" + name + "\"");
|
||||
}
|
||||
}
|
||||
if (i == start) {
|
||||
throw FileFormatException( //TODO
|
||||
"", "Illegal UNOIDL identifier \"" + name + "\"");
|
||||
}
|
||||
OUString uri(uri_ + buf.makeStringAndClear() + ".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);
|
||||
SAL_WARN_IF(
|
||||
e2 != osl_File_E_None, "unoidl",
|
||||
"cannot close " << uri << ": " << +e2);
|
||||
throw FileFormatException(uri, "cannot mmap: " + OUString::number(e));
|
||||
}
|
||||
rtl::Reference<Entity> ent;
|
||||
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;
|
||||
}
|
||||
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));
|
||||
return ent;
|
||||
}
|
||||
|
||||
SourceProvider::~SourceProvider() throw () {}
|
||||
|
||||
}
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
Loading…
Reference in a new issue