1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include <sal/config.h>
20 #include <osl/file.hxx>
21 #include <osl/process.h>
22 #include <rtl/process.h>
23 #include <rtl/ref.hxx>
24 #include <rtl/ustring.hxx>
26 #include <sal/types.h>
27 #include <unoidl/unoidl.hxx>
33 << "Usage:" << std::endl
<< std::endl
34 << " unoidl-read [--published] [<extra registries>] <registry>"
35 << std::endl
<< std::endl
36 << ("where each <registry> is either a new- or legacy-format .rdb file,"
39 << ("file, or a root directory of an .idl file tree. The complete"
42 << ("last <registry> is written to stdout; if --published is specified,"
45 << ("published entities (plus any non-published entities referenced"
48 << "via any unpublished optional bases) are written out." << std::endl
;
49 std::exit(EXIT_FAILURE
);
52 OUString
getArgumentUri(sal_uInt32 argument
) {
54 rtl_getAppCommandArg(argument
, &arg
.pData
);
56 osl::FileBase::RC e1
= osl::FileBase::getFileURLFromSystemPath(arg
, url
);
57 if (e1
!= osl::FileBase::E_None
) {
59 << "Cannot convert \"" << arg
<< "\" to file URL, error code "
61 std::exit(EXIT_FAILURE
);
64 oslProcessError e2
= osl_getProcessWorkingDir(&cwd
.pData
);
65 if (e2
!= osl_Process_E_None
) {
67 << "Cannot obtain working directory, error code " << +e2
69 std::exit(EXIT_FAILURE
);
72 e1
= osl::FileBase::getAbsoluteFileURL(cwd
, url
, abs
);
73 if (e1
!= osl::FileBase::E_None
) {
75 << "Cannot make \"" << url
76 << "\" into an absolute file URL, error code " << +e1
<< std::endl
;
77 std::exit(EXIT_FAILURE
);
82 OUString
decomposeType(
83 OUString
const & type
, std::size_t * rank
,
84 std::vector
<OUString
> * typeArguments
, bool * entity
)
86 assert(rank
!= nullptr);
87 assert(typeArguments
!= nullptr);
88 assert(entity
!= nullptr);
91 typeArguments
->clear();
92 while (nucl
.startsWith("[]", &nucl
)) {
95 sal_Int32 i
= nucl
.indexOf('<');
97 OUString
tmpl(nucl
.copy(0, i
));
99 ++i
; // skip '<' or ','
101 for (sal_Int32 level
= 0; j
!= nucl
.getLength(); ++j
) {
102 sal_Unicode c
= nucl
[j
];
107 } else if (c
== '<') {
109 } else if (c
== '>') {
116 if (j
!= nucl
.getLength()) {
117 typeArguments
->push_back(nucl
.copy(i
, j
- i
));
120 } while (i
!= nucl
.getLength() && nucl
[i
] != '>');
121 assert(i
== nucl
.getLength() - 1 && nucl
[i
] == '>');
122 assert(!typeArguments
->empty());
125 assert(!nucl
.isEmpty());
126 *entity
= nucl
!= "void" && nucl
!= "boolean" && nucl
!= "byte"
127 && nucl
!= "short" && nucl
!= "unsigned short" && nucl
!= "long"
128 && nucl
!= "unsigned long" && nucl
!= "hyper"
129 && nucl
!= "unsigned hyper" && nucl
!= "float" && nucl
!= "double"
130 && nucl
!= "char" && nucl
!= "string" && nucl
!= "type"
132 assert(*entity
|| typeArguments
->empty());
137 enum class Sorted
{ NO
, ACTIVE
, YES
};
138 enum class Written
{ NO
, DECLARATION
, DEFINITION
};
141 rtl::Reference
<unoidl::Entity
> const & theEntity
, bool theRelevant
):
142 entity(theEntity
), relevant(theRelevant
), sorted(Sorted::NO
),
146 rtl::Reference
<unoidl::Entity
> const entity
;
147 std::set
<OUString
> dependencies
;
148 std::set
<OUString
> interfaceDependencies
;
154 void insertEntityDependency(
155 rtl::Reference
<unoidl::Manager
> const & manager
,
156 std::map
<OUString
, Entity
>::iterator
const & iterator
,
157 OUString
const & name
, bool weakInterfaceDependency
= false)
159 assert(manager
.is());
160 if (name
!= iterator
->first
) {
162 if (weakInterfaceDependency
) {
163 rtl::Reference
<unoidl::Entity
> ent(manager
->findEntity(name
));
165 std::cerr
<< "Unknown entity " << name
<< std::endl
;
166 std::exit(EXIT_FAILURE
);
168 ifc
= ent
->getSort() == unoidl::Entity::SORT_INTERFACE_TYPE
;
171 ? iterator
->second
.interfaceDependencies
172 : iterator
->second
.dependencies
)
177 void insertEntityDependencies(
178 rtl::Reference
<unoidl::Manager
> const & manager
,
179 std::map
<OUString
, Entity
>::iterator
const & iterator
,
180 std::vector
<OUString
> const & names
)
182 for (auto & i
: names
) {
183 insertEntityDependency(manager
, iterator
, i
);
187 void insertEntityDependencies(
188 rtl::Reference
<unoidl::Manager
> const & manager
,
189 std::map
<OUString
, Entity
>::iterator
const & iterator
,
190 std::vector
<unoidl::AnnotatedReference
> const & references
)
192 for (auto & i
: references
) {
193 insertEntityDependency(manager
, iterator
, i
.name
);
197 void insertTypeDependency(
198 rtl::Reference
<unoidl::Manager
> const & manager
,
199 std::map
<OUString
, Entity
>::iterator
const & iterator
,
200 OUString
const & type
)
203 std::vector
<OUString
> args
;
205 OUString
nucl(decomposeType(type
, &rank
, &args
, &entity
));
207 insertEntityDependency(manager
, iterator
, nucl
, true);
208 for (const auto & i
: args
) {
209 insertTypeDependency(manager
, iterator
, i
);
215 rtl::Reference
<unoidl::Manager
> const & manager
,
216 rtl::Reference
<unoidl::MapCursor
> const & cursor
, bool published
,
217 OUString
const & prefix
, std::map
<OUString
, Entity
> & entities
)
222 rtl::Reference
<unoidl::Entity
> ent(cursor
->getNext(&id
));
226 OUString
name(prefix
+ id
);
227 if (ent
->getSort() == unoidl::Entity::SORT_MODULE
) {
230 static_cast<unoidl::ModuleEntity
*>(ent
.get())->createCursor(),
231 published
, name
+ ".", entities
);
233 std::map
<OUString
, Entity
>::iterator
i(
240 || (static_cast<unoidl::PublishableEntity
*>(
244 switch (ent
->getSort()) {
245 case unoidl::Entity::SORT_ENUM_TYPE
:
246 case unoidl::Entity::SORT_CONSTANT_GROUP
:
248 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE
:
250 rtl::Reference
<unoidl::PlainStructTypeEntity
> ent2(
251 static_cast<unoidl::PlainStructTypeEntity
*>(
253 if (!ent2
->getDirectBase().isEmpty()) {
254 insertEntityDependency(
255 manager
, i
, ent2
->getDirectBase());
257 for (auto & j
: ent2
->getDirectMembers()) {
258 insertTypeDependency(manager
, i
, j
.type
);
262 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE
:
264 rtl::Reference
<unoidl::PolymorphicStructTypeTemplateEntity
>
266 static_cast<unoidl::PolymorphicStructTypeTemplateEntity
*>(
268 for (auto & j
: ent2
->getMembers()) {
269 if (!j
.parameterized
) {
270 insertTypeDependency(manager
, i
, j
.type
);
275 case unoidl::Entity::SORT_EXCEPTION_TYPE
:
277 rtl::Reference
<unoidl::ExceptionTypeEntity
> ent2(
278 static_cast<unoidl::ExceptionTypeEntity
*>(ent
.get()));
279 if (!ent2
->getDirectBase().isEmpty()) {
280 insertEntityDependency(
281 manager
, i
, ent2
->getDirectBase());
283 for (auto & j
: ent2
->getDirectMembers()) {
284 insertTypeDependency(manager
, i
, j
.type
);
288 case unoidl::Entity::SORT_INTERFACE_TYPE
:
290 rtl::Reference
<unoidl::InterfaceTypeEntity
> ent2(
291 static_cast<unoidl::InterfaceTypeEntity
*>(
293 insertEntityDependencies(
294 manager
, i
, ent2
->getDirectMandatoryBases());
295 insertEntityDependencies(
296 manager
, i
, ent2
->getDirectOptionalBases());
297 for (auto & j
: ent2
->getDirectAttributes()) {
298 insertTypeDependency(manager
, i
, j
.type
);
300 for (auto & j
: ent2
->getDirectMethods()) {
301 insertTypeDependency(manager
, i
, j
.returnType
);
302 for (auto & k
: j
.parameters
) {
303 insertTypeDependency(manager
, i
, k
.type
);
305 insertEntityDependencies(manager
, i
, j
.exceptions
);
309 case unoidl::Entity::SORT_TYPEDEF
:
311 rtl::Reference
<unoidl::TypedefEntity
> ent2(
312 static_cast<unoidl::TypedefEntity
*>(ent
.get()));
313 insertTypeDependency(manager
, i
, ent2
->getType());
316 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE
:
318 rtl::Reference
<unoidl::SingleInterfaceBasedServiceEntity
>
320 static_cast<unoidl::SingleInterfaceBasedServiceEntity
*>(
322 insertEntityDependency(manager
, i
, ent2
->getBase());
323 for (auto & j
: ent2
->getConstructors()) {
324 for (auto & k
: j
.parameters
) {
325 insertTypeDependency(manager
, i
, k
.type
);
327 insertEntityDependencies(manager
, i
, j
.exceptions
);
331 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE
:
333 rtl::Reference
<unoidl::AccumulationBasedServiceEntity
> ent2(
334 static_cast<unoidl::AccumulationBasedServiceEntity
*>(
336 insertEntityDependencies(
337 manager
, i
, ent2
->getDirectMandatoryBaseServices());
338 insertEntityDependencies(
339 manager
, i
, ent2
->getDirectOptionalBaseServices());
340 insertEntityDependencies(
341 manager
, i
, ent2
->getDirectMandatoryBaseInterfaces());
342 insertEntityDependencies(
343 manager
, i
, ent2
->getDirectOptionalBaseInterfaces());
344 for (auto & j
: ent2
->getDirectProperties()) {
345 insertTypeDependency(manager
, i
, j
.type
);
349 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON
:
351 rtl::Reference
<unoidl::InterfaceBasedSingletonEntity
> ent2(
352 static_cast<unoidl::InterfaceBasedSingletonEntity
*>(
354 insertEntityDependency(manager
, i
, ent2
->getBase());
357 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON
:
359 rtl::Reference
<unoidl::ServiceBasedSingletonEntity
> ent2(
360 static_cast<unoidl::ServiceBasedSingletonEntity
*>(
362 insertEntityDependency(manager
, i
, ent2
->getBase());
365 case unoidl::Entity::SORT_MODULE
:
366 assert(false && "this cannot happen");
372 void propagateRelevant(std::map
<OUString
, Entity
> & entities
, Entity
& entity
) {
373 if (!entity
.relevant
) {
374 entity
.relevant
= true;
375 if (entity
.sorted
!= Entity::Sorted::YES
) {
376 for (auto & i
: entity
.dependencies
) {
377 std::map
<OUString
, Entity
>::iterator
j(entities
.find(i
));
378 if (j
!= entities
.end()) {
379 propagateRelevant(entities
, j
->second
);
387 std::map
<OUString
, Entity
> & entities
,
388 std::map
<OUString
, Entity
>::iterator
const & iterator
,
389 std::vector
<OUString
> & result
)
391 switch (iterator
->second
.sorted
) {
392 case Entity::Sorted::NO
:
393 iterator
->second
.sorted
= Entity::Sorted::ACTIVE
;
394 for (auto & i
: iterator
->second
.dependencies
) {
395 std::map
<OUString
, Entity
>::iterator
j(entities
.find(i
));
396 if (j
!= entities
.end()) {
397 if (iterator
->second
.relevant
) {
398 propagateRelevant(entities
, j
->second
);
400 visit(entities
, j
, result
);
403 iterator
->second
.sorted
= Entity::Sorted::YES
;
404 result
.push_back(iterator
->first
);
406 case Entity::Sorted::ACTIVE
:
408 << "Entity " << iterator
->first
<< " recursively depends on itself"
410 std::exit(EXIT_FAILURE
);
411 // fall-through avoids warnings
417 std::vector
<OUString
> sort(std::map
<OUString
, Entity
> & entities
) {
418 std::vector
<OUString
> res
;
419 for (auto i(entities
.begin()); i
!= entities
.end(); ++i
) {
420 visit(entities
, i
, res
);
425 void indent(std::vector
<OUString
> const & modules
, unsigned int extra
= 0) {
426 for (std::vector
<OUString
>::size_type i
= 0; i
!= modules
.size(); ++i
) {
429 for (unsigned int i
= 0; i
!= extra
; ++i
) {
435 std::vector
<OUString
> & modules
, std::vector
<OUString
>::size_type n
)
437 for (std::vector
<OUString
>::size_type i
= 0; i
!= n
; ++i
) {
438 assert(!modules
.empty());
445 OUString
openModulesFor(std::vector
<OUString
> & modules
, OUString
const & name
)
447 std::vector
<OUString
>::iterator
i(modules
.begin());
448 for (sal_Int32 j
= 0;;) {
449 OUString
id(name
.getToken(0, '.', j
));
453 static_cast< std::vector
<OUString
>::size_type
>(
458 if (i
!= modules
.end()) {
465 static_cast< std::vector
<OUString
>::size_type
>(
470 std::cout
<< "module " << id
<< " {\n";
471 modules
.push_back(id
);
476 void writeName(OUString
const & name
) {
477 std::cout
<< "::" << name
.replaceAll(".", "::");
480 void writeAnnotations(std::vector
<OUString
> const & annotations
) {
481 if (!annotations
.empty()) {
483 for (auto & i
: annotations
) {
484 //TODO: i.indexOf("*/") == -1
485 std::cout
<< " @" << i
;
491 void writePublished(rtl::Reference
<unoidl::PublishableEntity
> const & entity
) {
493 if (entity
->isPublished()) {
494 std::cout
<< "published ";
498 void writeAnnotationsPublished(
499 rtl::Reference
<unoidl::PublishableEntity
> const & entity
)
502 writeAnnotations(entity
->getAnnotations());
503 writePublished(entity
);
506 void writeType(OUString
const & type
) {
508 std::vector
<OUString
> args
;
510 OUString
nucl(decomposeType(type
, &rank
, &args
, &entity
));
511 for (std::size_t i
= 0; i
!= rank
; ++i
) {
512 std::cout
<< "sequence< ";
521 for (auto i(args
.begin()); i
!= args
.end(); ++i
) {
522 if (i
!= args
.begin()) {
529 for (std::size_t i
= 0; i
!= rank
; ++i
) {
534 void writeExceptionSpecification(std::vector
<OUString
> const & exceptions
) {
535 if (!exceptions
.empty()) {
536 std::cout
<< " raises (";
537 for (auto i(exceptions
.begin()); i
!= exceptions
.end(); ++i
) {
538 if (i
!= exceptions
.begin()) {
548 std::map
<OUString
, Entity
> & entities
, std::vector
<OUString
> & modules
,
549 OUString
const & name
)
551 std::map
<OUString
, Entity
>::iterator
i(entities
.find(name
));
552 if (i
!= entities
.end() && i
->second
.relevant
) {
553 assert(i
->second
.written
!= Entity::Written::DEFINITION
);
554 i
->second
.written
= Entity::Written::DEFINITION
;
555 for (auto & j
: i
->second
.interfaceDependencies
) {
556 std::map
<OUString
, Entity
>::iterator
k(entities
.find(j
));
557 if (k
!= entities
.end() && k
->second
.written
== Entity::Written::NO
) {
558 k
->second
.written
= Entity::Written::DECLARATION
;
559 OUString
id(openModulesFor(modules
, j
));
560 if (k
->second
.entity
->getSort()
561 != unoidl::Entity::SORT_INTERFACE_TYPE
)
564 << "Entity " << j
<< " should be an interface type"
566 std::exit(EXIT_FAILURE
);
569 static_cast<unoidl::PublishableEntity
*>(
570 k
->second
.entity
.get()));
571 std::cout
<< "interface " << id
<< ";\n";
574 OUString
id(openModulesFor(modules
, name
));
575 rtl::Reference
<unoidl::PublishableEntity
> ent(
576 static_cast<unoidl::PublishableEntity
*>(i
->second
.entity
.get()));
577 switch (ent
->getSort()) {
578 case unoidl::Entity::SORT_ENUM_TYPE
:
580 rtl::Reference
<unoidl::EnumTypeEntity
> ent2(
581 static_cast<unoidl::EnumTypeEntity
*>(ent
.get()));
582 writeAnnotationsPublished(ent
);
583 std::cout
<< "enum " << id
<< " {\n";
584 for (auto j(ent2
->getMembers().begin());
585 j
!= ent2
->getMembers().end(); ++j
)
588 writeAnnotations(j
->annotations
);
589 std::cout
<< j
->name
<< " = " << j
->value
;
590 if (j
+ 1 != ent2
->getMembers().end()) {
599 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE
:
601 rtl::Reference
<unoidl::PlainStructTypeEntity
> ent2(
602 static_cast<unoidl::PlainStructTypeEntity
*>(ent
.get()));
603 writeAnnotationsPublished(ent
);
604 std::cout
<< "struct " << id
;
605 if (!ent2
->getDirectBase().isEmpty()) {
607 writeName(ent2
->getDirectBase());
610 for (auto & j
: ent2
->getDirectMembers()) {
612 writeAnnotations(j
.annotations
);
614 std::cout
<< ' ' << j
.name
<< ";\n";
620 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE
:
622 rtl::Reference
<unoidl::PolymorphicStructTypeTemplateEntity
>
624 static_cast<unoidl::PolymorphicStructTypeTemplateEntity
*>(
626 writeAnnotationsPublished(ent
);
627 std::cout
<< "struct " << id
<< '<';
628 for (auto j(ent2
->getTypeParameters().begin());
629 j
!= ent2
->getTypeParameters().end(); ++j
)
631 if (j
!= ent2
->getTypeParameters().begin()) {
636 std::cout
<< "> {\n";
637 for (auto & j
: ent2
->getMembers()) {
639 writeAnnotations(j
.annotations
);
640 if (j
.parameterized
) {
645 std::cout
<< ' ' << j
.name
<< ";\n";
651 case unoidl::Entity::SORT_EXCEPTION_TYPE
:
653 rtl::Reference
<unoidl::ExceptionTypeEntity
> ent2(
654 static_cast<unoidl::ExceptionTypeEntity
*>(ent
.get()));
655 writeAnnotationsPublished(ent
);
656 std::cout
<< "exception " << id
;
657 if (!ent2
->getDirectBase().isEmpty()) {
659 writeName(ent2
->getDirectBase());
662 for (auto & j
: ent2
->getDirectMembers()) {
664 writeAnnotations(j
.annotations
);
666 std::cout
<< ' ' << j
.name
<< ";\n";
672 case unoidl::Entity::SORT_INTERFACE_TYPE
:
674 rtl::Reference
<unoidl::InterfaceTypeEntity
> ent2(
675 static_cast<unoidl::InterfaceTypeEntity
*>(
677 writeAnnotationsPublished(ent
);
678 std::cout
<< "interface " << id
<< " {\n";
679 for (auto & j
: ent2
->getDirectMandatoryBases()) {
681 writeAnnotations(j
.annotations
);
682 std::cout
<< "interface ";
686 for (auto & j
: ent2
->getDirectOptionalBases()) {
688 writeAnnotations(j
.annotations
);
689 std::cout
<< "[optional] interface ";
693 for (auto & j
: ent2
->getDirectAttributes()) {
695 writeAnnotations(j
.annotations
);
696 std::cout
<< "[attribute";
698 std::cout
<< ", bound";
701 std::cout
<< ", readonly";
705 std::cout
<< ' ' << j
.name
;
706 if (!(j
.getExceptions
.empty() && j
.setExceptions
.empty())) {
708 if (!j
.getExceptions
.empty()) {
711 writeExceptionSpecification(j
.getExceptions
);
714 if (!j
.setExceptions
.empty()) {
717 writeExceptionSpecification(j
.setExceptions
);
724 for (auto & j
: ent2
->getDirectMethods()) {
726 writeAnnotations(j
.annotations
);
727 writeType(j
.returnType
);
728 std::cout
<< ' ' << j
.name
<< '(';
729 for (auto k(j
.parameters
.begin()); k
!= j
.parameters
.end();
732 if (k
!= j
.parameters
.begin()) {
735 switch (k
->direction
) {
736 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
:
737 std::cout
<< "[in] ";
739 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT
:
740 std::cout
<< "[out] ";
742 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT
:
743 std::cout
<< "[inout] ";
747 std::cout
<< ' ' << k
->name
;
750 writeExceptionSpecification(j
.exceptions
);
757 case unoidl::Entity::SORT_TYPEDEF
:
759 rtl::Reference
<unoidl::TypedefEntity
> ent2(
760 static_cast<unoidl::TypedefEntity
*>(ent
.get()));
761 writeAnnotationsPublished(ent
);
762 std::cout
<< "typedef ";
763 writeType(ent2
->getType());
764 std::cout
<< ' ' << id
<< ";\n";
767 case unoidl::Entity::SORT_CONSTANT_GROUP
:
769 rtl::Reference
<unoidl::ConstantGroupEntity
> ent2(
770 static_cast<unoidl::ConstantGroupEntity
*>(ent
.get()));
771 writeAnnotationsPublished(ent
);
772 std::cout
<< "constants " << id
<< " {\n";
773 for (auto & j
: ent2
->getMembers()) {
775 writeAnnotations(j
.annotations
);
776 std::cout
<< "const ";
777 switch (j
.value
.type
) {
778 case unoidl::ConstantValue::TYPE_BOOLEAN
:
779 std::cout
<< "boolean";
781 case unoidl::ConstantValue::TYPE_BYTE
:
784 case unoidl::ConstantValue::TYPE_SHORT
:
785 std::cout
<< "short";
787 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT
:
788 std::cout
<< "unsigned short";
790 case unoidl::ConstantValue::TYPE_LONG
:
793 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG
:
794 std::cout
<< "unsigned long";
796 case unoidl::ConstantValue::TYPE_HYPER
:
797 std::cout
<< "hyper";
799 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER
:
800 std::cout
<< "unsigned hyper";
802 case unoidl::ConstantValue::TYPE_FLOAT
:
803 std::cout
<< "float";
805 case unoidl::ConstantValue::TYPE_DOUBLE
:
806 std::cout
<< "double";
809 std::cout
<< ' ' << j
.name
<< " = ";
810 switch (j
.value
.type
) {
811 case unoidl::ConstantValue::TYPE_BOOLEAN
:
812 std::cout
<< (j
.value
.booleanValue
? "TRUE" : "FALSE");
814 case unoidl::ConstantValue::TYPE_BYTE
:
815 std::cout
<< int(j
.value
.byteValue
);
817 case unoidl::ConstantValue::TYPE_SHORT
:
818 std::cout
<< j
.value
.shortValue
;
820 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT
:
821 std::cout
<< j
.value
.unsignedShortValue
;
823 case unoidl::ConstantValue::TYPE_LONG
:
824 std::cout
<< j
.value
.longValue
;
826 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG
:
827 std::cout
<< j
.value
.unsignedLongValue
;
829 case unoidl::ConstantValue::TYPE_HYPER
:
830 std::cout
<< j
.value
.hyperValue
;
832 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER
:
833 std::cout
<< j
.value
.unsignedHyperValue
;
835 case unoidl::ConstantValue::TYPE_FLOAT
:
836 std::cout
<< j
.value
.floatValue
;
838 case unoidl::ConstantValue::TYPE_DOUBLE
:
839 std::cout
<< j
.value
.doubleValue
;
848 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE
:
850 rtl::Reference
<unoidl::SingleInterfaceBasedServiceEntity
> ent2(
851 static_cast<unoidl::SingleInterfaceBasedServiceEntity
*>(
853 writeAnnotationsPublished(ent
);
854 std::cout
<< "service " << id
<< ": ";
855 writeName(ent2
->getBase());
856 if (ent2
->getConstructors().size() != 1
857 || !ent2
->getConstructors().front().defaultConstructor
)
860 for (auto & j
: ent2
->getConstructors()) {
862 writeAnnotations(j
.annotations
);
863 std::cout
<< j
.name
<< '(';
864 for (auto k(j
.parameters
.begin());
865 k
!= j
.parameters
.end(); ++k
)
867 if (k
!= j
.parameters
.begin()) {
870 std::cout
<< "[in] ";
875 std::cout
<< ' ' << k
->name
;
878 writeExceptionSpecification(j
.exceptions
);
887 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE
:
889 rtl::Reference
<unoidl::AccumulationBasedServiceEntity
> ent2(
890 static_cast<unoidl::AccumulationBasedServiceEntity
*>(
892 writeAnnotationsPublished(ent
);
893 std::cout
<< "service " << id
<< " {\n";
894 for (auto & j
: ent2
->getDirectMandatoryBaseServices()) {
896 writeAnnotations(j
.annotations
);
897 std::cout
<< "service ";
901 for (auto & j
: ent2
->getDirectOptionalBaseServices()) {
903 writeAnnotations(j
.annotations
);
904 std::cout
<< "[optional] service ";
908 for (auto & j
: ent2
->getDirectMandatoryBaseInterfaces()) {
910 writeAnnotations(j
.annotations
);
911 std::cout
<< "interface ";
915 for (auto & j
: ent2
->getDirectOptionalBaseInterfaces()) {
917 writeAnnotations(j
.annotations
);
918 std::cout
<< "[optional] interface ";
922 for (auto & j
: ent2
->getDirectProperties()) {
924 writeAnnotations(j
.annotations
);
925 std::cout
<< "[property";
927 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_BOUND
)
930 std::cout
<< ", bound";
933 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED
)
936 std::cout
<< ", constrained";
939 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_AMBIGUOUS
)
942 std::cout
<< ", maybeambiguous";
945 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_DEFAULT
)
948 std::cout
<< ", maybedefault";
951 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_VOID
)
954 std::cout
<< ", maybevoid";
957 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL
)
960 std::cout
<< ", optional";
963 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_READ_ONLY
)
966 std::cout
<< ", readonly";
969 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_REMOVABLE
)
972 std::cout
<< ", removable";
975 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_TRANSIENT
)
978 std::cout
<< ", transient";
982 std::cout
<< ' ' << j
.name
<< ";\n";
988 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON
:
990 rtl::Reference
<unoidl::InterfaceBasedSingletonEntity
> ent2(
991 static_cast<unoidl::InterfaceBasedSingletonEntity
*>(
993 writeAnnotationsPublished(ent
);
994 std::cout
<< "singleton " << id
<< ": ";
995 writeName(ent2
->getBase());
999 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON
:
1001 rtl::Reference
<unoidl::ServiceBasedSingletonEntity
> ent2(
1002 static_cast<unoidl::ServiceBasedSingletonEntity
*>(
1004 writeAnnotationsPublished(ent
);
1005 std::cout
<< "singleton " << id
<< " { service ";
1006 writeName(ent2
->getBase());
1007 std::cout
<< "; };";
1010 case unoidl::Entity::SORT_MODULE
:
1011 assert(false && "this cannot happen");
1018 SAL_IMPLEMENT_MAIN() {
1020 sal_uInt32 args
= rtl_getAppCommandArgCount();
1025 rtl_getAppCommandArg(0, &arg
.pData
);
1026 bool published
= arg
== "--published";
1027 if (published
&& args
== 1) {
1030 rtl::Reference
<unoidl::Manager
> mgr(new unoidl::Manager
);
1031 rtl::Reference
<unoidl::Provider
> prov
;
1032 for (sal_uInt32 i
= (published
? 1 : 0); i
!= args
; ++i
) {
1033 OUString
uri(getArgumentUri(i
));
1035 prov
= mgr
->addProvider(uri
);
1036 } catch (unoidl::NoSuchFileException
&) {
1038 << "Input <" << uri
<< "> does not exist" << std::endl
;
1039 std::exit(EXIT_FAILURE
);
1042 std::map
<OUString
, Entity
> ents
;
1043 scanMap(mgr
, prov
->createRootCursor(), published
, "", ents
);
1044 std::vector
<OUString
> sorted(sort(ents
));
1045 std::vector
<OUString
> mods
;
1046 for (const auto & i
: sorted
) {
1047 writeEntity(ents
, mods
, i
);
1049 closeModules(mods
, mods
.size());
1050 return EXIT_SUCCESS
;
1051 } catch (unoidl::FileFormatException
& e1
) {
1053 << "Bad input <" << e1
.getUri() << ">: " << e1
.getDetail()
1055 std::exit(EXIT_FAILURE
);
1056 } catch (std::exception
& e1
) {
1057 std::cerr
<< "Failure: " << e1
.what() << std::endl
;
1058 std::exit(EXIT_FAILURE
);
1062 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */