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>
17 #include <string_view>
21 #include <osl/file.hxx>
22 #include <osl/process.h>
23 #include <rtl/process.h>
24 #include <rtl/ref.hxx>
25 #include <rtl/ustring.hxx>
27 #include <sal/types.h>
28 #include <unoidl/unoidl.hxx>
34 << "Usage:" << std::endl
<< std::endl
35 << " unoidl-read [--published] [<extra registries>] <registry>"
36 << std::endl
<< std::endl
37 << ("where each <registry> is either a new- or legacy-format .rdb file,"
40 << ("file, or a root directory of an .idl file tree. The complete"
43 << ("last <registry> is written to stdout; if --published is specified,"
46 << ("published entities (plus any non-published entities referenced"
49 << "via any unpublished optional bases) are written out." << std::endl
;
50 std::exit(EXIT_FAILURE
);
53 OUString
getArgumentUri(sal_uInt32 argument
) {
55 rtl_getAppCommandArg(argument
, &arg
.pData
);
57 osl::FileBase::RC e1
= osl::FileBase::getFileURLFromSystemPath(arg
, url
);
58 if (e1
!= osl::FileBase::E_None
) {
60 << "Cannot convert \"" << arg
<< "\" to file URL, error code "
62 std::exit(EXIT_FAILURE
);
65 oslProcessError e2
= osl_getProcessWorkingDir(&cwd
.pData
);
66 if (e2
!= osl_Process_E_None
) {
68 << "Cannot obtain working directory, error code " << +e2
70 std::exit(EXIT_FAILURE
);
73 e1
= osl::FileBase::getAbsoluteFileURL(cwd
, url
, abs
);
74 if (e1
!= osl::FileBase::E_None
) {
76 << "Cannot make \"" << url
77 << "\" into an absolute file URL, error code " << +e1
<< std::endl
;
78 std::exit(EXIT_FAILURE
);
83 OUString
decomposeType(
84 OUString
const & type
, std::size_t * rank
,
85 std::vector
<OUString
> * typeArguments
, bool * entity
)
87 assert(rank
!= nullptr);
88 assert(typeArguments
!= nullptr);
89 assert(entity
!= nullptr);
92 typeArguments
->clear();
93 while (nucl
.startsWith("[]", &nucl
)) {
96 sal_Int32 i
= nucl
.indexOf('<');
98 OUString
tmpl(nucl
.copy(0, i
));
100 ++i
; // skip '<' or ','
102 for (sal_Int32 level
= 0; j
!= nucl
.getLength(); ++j
) {
103 sal_Unicode c
= nucl
[j
];
108 } else if (c
== '<') {
110 } else if (c
== '>') {
117 if (j
!= nucl
.getLength()) {
118 typeArguments
->push_back(nucl
.copy(i
, j
- i
));
121 } while (i
!= nucl
.getLength() && nucl
[i
] != '>');
122 assert(i
== nucl
.getLength() - 1 && nucl
[i
] == '>');
123 assert(!typeArguments
->empty());
126 assert(!nucl
.isEmpty());
127 *entity
= nucl
!= "void" && nucl
!= "boolean" && nucl
!= "byte"
128 && nucl
!= "short" && nucl
!= "unsigned short" && nucl
!= "long"
129 && nucl
!= "unsigned long" && nucl
!= "hyper"
130 && nucl
!= "unsigned hyper" && nucl
!= "float" && nucl
!= "double"
131 && nucl
!= "char" && nucl
!= "string" && nucl
!= "type"
133 assert(*entity
|| typeArguments
->empty());
138 enum class Sorted
{ NO
, ACTIVE
, YES
};
139 enum class Written
{ NO
, DECLARATION
, DEFINITION
};
142 rtl::Reference
<unoidl::Entity
> const & theEntity
, bool theRelevant
):
143 entity(theEntity
), relevant(theRelevant
), sorted(Sorted::NO
),
147 rtl::Reference
<unoidl::Entity
> const entity
;
148 std::set
<OUString
> dependencies
;
149 std::set
<OUString
> interfaceDependencies
;
155 void insertEntityDependency(
156 rtl::Reference
<unoidl::Manager
> const & manager
,
157 std::map
<OUString
, Entity
>::iterator
const & iterator
,
158 OUString
const & name
, bool weakInterfaceDependency
= false)
160 assert(manager
.is());
161 if (name
== iterator
->first
)
165 if (weakInterfaceDependency
) {
166 rtl::Reference
<unoidl::Entity
> ent(manager
->findEntity(name
));
168 std::cerr
<< "Unknown entity " << name
<< std::endl
;
169 std::exit(EXIT_FAILURE
);
171 ifc
= ent
->getSort() == unoidl::Entity::SORT_INTERFACE_TYPE
;
174 ? iterator
->second
.interfaceDependencies
175 : iterator
->second
.dependencies
)
179 void insertEntityDependencies(
180 rtl::Reference
<unoidl::Manager
> const & manager
,
181 std::map
<OUString
, Entity
>::iterator
const & iterator
,
182 std::vector
<OUString
> const & names
)
184 for (auto & i
: names
) {
185 insertEntityDependency(manager
, iterator
, i
);
189 void insertEntityDependencies(
190 rtl::Reference
<unoidl::Manager
> const & manager
,
191 std::map
<OUString
, Entity
>::iterator
const & iterator
,
192 std::vector
<unoidl::AnnotatedReference
> const & references
)
194 for (auto & i
: references
) {
195 insertEntityDependency(manager
, iterator
, i
.name
);
199 void insertTypeDependency(
200 rtl::Reference
<unoidl::Manager
> const & manager
,
201 std::map
<OUString
, Entity
>::iterator
const & iterator
,
202 OUString
const & type
)
205 std::vector
<OUString
> args
;
207 OUString
nucl(decomposeType(type
, &rank
, &args
, &entity
));
209 insertEntityDependency(manager
, iterator
, nucl
, true);
210 for (const auto & i
: args
) {
211 insertTypeDependency(manager
, iterator
, i
);
217 rtl::Reference
<unoidl::Manager
> const & manager
,
218 rtl::Reference
<unoidl::MapCursor
> const & cursor
, bool published
,
219 std::u16string_view prefix
, std::map
<OUString
, Entity
> & entities
)
224 rtl::Reference
<unoidl::Entity
> ent(cursor
->getNext(&id
));
228 OUString
name(prefix
+ id
);
229 if (ent
->getSort() == unoidl::Entity::SORT_MODULE
) {
232 static_cast<unoidl::ModuleEntity
*>(ent
.get())->createCursor(),
233 published
, OUStringConcatenation(name
+ "."), entities
);
235 std::map
<OUString
, Entity
>::iterator
i(
242 || (static_cast<unoidl::PublishableEntity
*>(
246 switch (ent
->getSort()) {
247 case unoidl::Entity::SORT_ENUM_TYPE
:
248 case unoidl::Entity::SORT_CONSTANT_GROUP
:
250 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE
:
252 rtl::Reference
<unoidl::PlainStructTypeEntity
> ent2(
253 static_cast<unoidl::PlainStructTypeEntity
*>(
255 if (!ent2
->getDirectBase().isEmpty()) {
256 insertEntityDependency(
257 manager
, i
, ent2
->getDirectBase());
259 for (auto & j
: ent2
->getDirectMembers()) {
260 insertTypeDependency(manager
, i
, j
.type
);
264 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE
:
266 rtl::Reference
<unoidl::PolymorphicStructTypeTemplateEntity
>
268 static_cast<unoidl::PolymorphicStructTypeTemplateEntity
*>(
270 for (auto & j
: ent2
->getMembers()) {
271 if (!j
.parameterized
) {
272 insertTypeDependency(manager
, i
, j
.type
);
277 case unoidl::Entity::SORT_EXCEPTION_TYPE
:
279 rtl::Reference
<unoidl::ExceptionTypeEntity
> ent2(
280 static_cast<unoidl::ExceptionTypeEntity
*>(ent
.get()));
281 if (!ent2
->getDirectBase().isEmpty()) {
282 insertEntityDependency(
283 manager
, i
, ent2
->getDirectBase());
285 for (auto & j
: ent2
->getDirectMembers()) {
286 insertTypeDependency(manager
, i
, j
.type
);
290 case unoidl::Entity::SORT_INTERFACE_TYPE
:
292 rtl::Reference
<unoidl::InterfaceTypeEntity
> ent2(
293 static_cast<unoidl::InterfaceTypeEntity
*>(
295 insertEntityDependencies(
296 manager
, i
, ent2
->getDirectMandatoryBases());
297 insertEntityDependencies(
298 manager
, i
, ent2
->getDirectOptionalBases());
299 for (auto & j
: ent2
->getDirectAttributes()) {
300 insertTypeDependency(manager
, i
, j
.type
);
302 for (auto & j
: ent2
->getDirectMethods()) {
303 insertTypeDependency(manager
, i
, j
.returnType
);
304 for (auto & k
: j
.parameters
) {
305 insertTypeDependency(manager
, i
, k
.type
);
307 insertEntityDependencies(manager
, i
, j
.exceptions
);
311 case unoidl::Entity::SORT_TYPEDEF
:
313 rtl::Reference
<unoidl::TypedefEntity
> ent2(
314 static_cast<unoidl::TypedefEntity
*>(ent
.get()));
315 insertTypeDependency(manager
, i
, ent2
->getType());
318 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE
:
320 rtl::Reference
<unoidl::SingleInterfaceBasedServiceEntity
>
322 static_cast<unoidl::SingleInterfaceBasedServiceEntity
*>(
324 insertEntityDependency(manager
, i
, ent2
->getBase());
325 for (auto & j
: ent2
->getConstructors()) {
326 for (auto & k
: j
.parameters
) {
327 insertTypeDependency(manager
, i
, k
.type
);
329 insertEntityDependencies(manager
, i
, j
.exceptions
);
333 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE
:
335 rtl::Reference
<unoidl::AccumulationBasedServiceEntity
> ent2(
336 static_cast<unoidl::AccumulationBasedServiceEntity
*>(
338 insertEntityDependencies(
339 manager
, i
, ent2
->getDirectMandatoryBaseServices());
340 insertEntityDependencies(
341 manager
, i
, ent2
->getDirectOptionalBaseServices());
342 insertEntityDependencies(
343 manager
, i
, ent2
->getDirectMandatoryBaseInterfaces());
344 insertEntityDependencies(
345 manager
, i
, ent2
->getDirectOptionalBaseInterfaces());
346 for (auto & j
: ent2
->getDirectProperties()) {
347 insertTypeDependency(manager
, i
, j
.type
);
351 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON
:
353 rtl::Reference
<unoidl::InterfaceBasedSingletonEntity
> ent2(
354 static_cast<unoidl::InterfaceBasedSingletonEntity
*>(
356 insertEntityDependency(manager
, i
, ent2
->getBase());
359 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON
:
361 rtl::Reference
<unoidl::ServiceBasedSingletonEntity
> ent2(
362 static_cast<unoidl::ServiceBasedSingletonEntity
*>(
364 insertEntityDependency(manager
, i
, ent2
->getBase());
367 case unoidl::Entity::SORT_MODULE
:
368 assert(false && "this cannot happen");
374 void propagateRelevant(std::map
<OUString
, Entity
> & entities
, Entity
& entity
) {
375 if (!entity
.relevant
) {
376 entity
.relevant
= true;
377 if (entity
.sorted
!= Entity::Sorted::YES
) {
378 for (auto & i
: entity
.dependencies
) {
379 std::map
<OUString
, Entity
>::iterator
j(entities
.find(i
));
380 if (j
!= entities
.end()) {
381 propagateRelevant(entities
, j
->second
);
389 std::map
<OUString
, Entity
> & entities
,
390 std::map
<OUString
, Entity
>::iterator
const & iterator
,
391 std::vector
<OUString
> & result
)
393 switch (iterator
->second
.sorted
) {
394 case Entity::Sorted::NO
:
395 iterator
->second
.sorted
= Entity::Sorted::ACTIVE
;
396 for (auto & i
: iterator
->second
.dependencies
) {
397 std::map
<OUString
, Entity
>::iterator
j(entities
.find(i
));
398 if (j
!= entities
.end()) {
399 if (iterator
->second
.relevant
) {
400 propagateRelevant(entities
, j
->second
);
402 visit(entities
, j
, result
);
405 iterator
->second
.sorted
= Entity::Sorted::YES
;
406 result
.push_back(iterator
->first
);
408 case Entity::Sorted::ACTIVE
:
410 << "Entity " << iterator
->first
<< " recursively depends on itself"
412 std::exit(EXIT_FAILURE
);
413 // fall-through avoids warnings
419 std::vector
<OUString
> sort(std::map
<OUString
, Entity
> & entities
) {
420 std::vector
<OUString
> res
;
421 for (auto i(entities
.begin()); i
!= entities
.end(); ++i
) {
422 visit(entities
, i
, res
);
427 void indent(std::vector
<OUString
> const & modules
, unsigned int extra
= 0) {
428 for (std::vector
<OUString
>::size_type i
= 0; i
!= modules
.size(); ++i
) {
431 for (unsigned int i
= 0; i
!= extra
; ++i
) {
437 std::vector
<OUString
> & modules
, std::vector
<OUString
>::size_type n
)
439 for (std::vector
<OUString
>::size_type i
= 0; i
!= n
; ++i
) {
440 assert(!modules
.empty());
447 OUString
openModulesFor(std::vector
<OUString
> & modules
, OUString
const & name
)
449 std::vector
<OUString
>::iterator
i(modules
.begin());
450 for (sal_Int32 j
= 0;;) {
451 OUString
id(name
.getToken(0, '.', j
));
455 static_cast< std::vector
<OUString
>::size_type
>(
460 if (i
!= modules
.end()) {
467 static_cast< std::vector
<OUString
>::size_type
>(
472 std::cout
<< "module " << id
<< " {\n";
473 modules
.push_back(id
);
478 void writeName(OUString
const & name
) {
479 std::cout
<< "::" << name
.replaceAll(".", "::");
482 void writeAnnotations(std::vector
<OUString
> const & annotations
) {
483 if (!annotations
.empty()) {
485 for (auto & i
: annotations
) {
486 //TODO: i.indexOf("*/") == -1
487 std::cout
<< " @" << i
;
493 void writePublished(rtl::Reference
<unoidl::PublishableEntity
> const & entity
) {
495 if (entity
->isPublished()) {
496 std::cout
<< "published ";
500 void writeAnnotationsPublished(
501 rtl::Reference
<unoidl::PublishableEntity
> const & entity
)
504 writeAnnotations(entity
->getAnnotations());
505 writePublished(entity
);
508 void writeType(OUString
const & type
) {
510 std::vector
<OUString
> args
;
512 OUString
nucl(decomposeType(type
, &rank
, &args
, &entity
));
513 for (std::size_t i
= 0; i
!= rank
; ++i
) {
514 std::cout
<< "sequence< ";
523 for (auto i(args
.begin()); i
!= args
.end(); ++i
) {
524 if (i
!= args
.begin()) {
531 for (std::size_t i
= 0; i
!= rank
; ++i
) {
536 void writeExceptionSpecification(std::vector
<OUString
> const & exceptions
) {
537 if (!exceptions
.empty()) {
538 std::cout
<< " raises (";
539 for (auto i(exceptions
.begin()); i
!= exceptions
.end(); ++i
) {
540 if (i
!= exceptions
.begin()) {
550 std::map
<OUString
, Entity
> & entities
, std::vector
<OUString
> & modules
,
551 OUString
const & name
)
553 std::map
<OUString
, Entity
>::iterator
i(entities
.find(name
));
554 if (i
== entities
.end() || !i
->second
.relevant
)
557 assert(i
->second
.written
!= Entity::Written::DEFINITION
);
558 i
->second
.written
= Entity::Written::DEFINITION
;
559 for (auto & j
: i
->second
.interfaceDependencies
) {
560 std::map
<OUString
, Entity
>::iterator
k(entities
.find(j
));
561 if (k
!= entities
.end() && k
->second
.written
== Entity::Written::NO
) {
562 k
->second
.written
= Entity::Written::DECLARATION
;
563 OUString
id(openModulesFor(modules
, j
));
564 if (k
->second
.entity
->getSort()
565 != unoidl::Entity::SORT_INTERFACE_TYPE
)
568 << "Entity " << j
<< " should be an interface type"
570 std::exit(EXIT_FAILURE
);
573 static_cast<unoidl::PublishableEntity
*>(
574 k
->second
.entity
.get()));
575 std::cout
<< "interface " << id
<< ";\n";
578 OUString
id(openModulesFor(modules
, name
));
579 rtl::Reference
<unoidl::PublishableEntity
> ent(
580 static_cast<unoidl::PublishableEntity
*>(i
->second
.entity
.get()));
581 switch (ent
->getSort()) {
582 case unoidl::Entity::SORT_ENUM_TYPE
:
584 rtl::Reference
<unoidl::EnumTypeEntity
> ent2(
585 static_cast<unoidl::EnumTypeEntity
*>(ent
.get()));
586 writeAnnotationsPublished(ent
);
587 std::cout
<< "enum " << id
<< " {\n";
588 for (auto j(ent2
->getMembers().begin());
589 j
!= ent2
->getMembers().end(); ++j
)
592 writeAnnotations(j
->annotations
);
593 std::cout
<< j
->name
<< " = " << j
->value
;
594 if (j
+ 1 != ent2
->getMembers().end()) {
603 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE
:
605 rtl::Reference
<unoidl::PlainStructTypeEntity
> ent2(
606 static_cast<unoidl::PlainStructTypeEntity
*>(ent
.get()));
607 writeAnnotationsPublished(ent
);
608 std::cout
<< "struct " << id
;
609 if (!ent2
->getDirectBase().isEmpty()) {
611 writeName(ent2
->getDirectBase());
614 for (auto & j
: ent2
->getDirectMembers()) {
616 writeAnnotations(j
.annotations
);
618 std::cout
<< ' ' << j
.name
<< ";\n";
624 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE
:
626 rtl::Reference
<unoidl::PolymorphicStructTypeTemplateEntity
>
628 static_cast<unoidl::PolymorphicStructTypeTemplateEntity
*>(
630 writeAnnotationsPublished(ent
);
631 std::cout
<< "struct " << id
<< '<';
632 for (auto j(ent2
->getTypeParameters().begin());
633 j
!= ent2
->getTypeParameters().end(); ++j
)
635 if (j
!= ent2
->getTypeParameters().begin()) {
640 std::cout
<< "> {\n";
641 for (auto & j
: ent2
->getMembers()) {
643 writeAnnotations(j
.annotations
);
644 if (j
.parameterized
) {
649 std::cout
<< ' ' << j
.name
<< ";\n";
655 case unoidl::Entity::SORT_EXCEPTION_TYPE
:
657 rtl::Reference
<unoidl::ExceptionTypeEntity
> ent2(
658 static_cast<unoidl::ExceptionTypeEntity
*>(ent
.get()));
659 writeAnnotationsPublished(ent
);
660 std::cout
<< "exception " << id
;
661 if (!ent2
->getDirectBase().isEmpty()) {
663 writeName(ent2
->getDirectBase());
666 for (auto & j
: ent2
->getDirectMembers()) {
668 writeAnnotations(j
.annotations
);
670 std::cout
<< ' ' << j
.name
<< ";\n";
676 case unoidl::Entity::SORT_INTERFACE_TYPE
:
678 rtl::Reference
<unoidl::InterfaceTypeEntity
> ent2(
679 static_cast<unoidl::InterfaceTypeEntity
*>(
681 writeAnnotationsPublished(ent
);
682 std::cout
<< "interface " << id
<< " {\n";
683 for (auto & j
: ent2
->getDirectMandatoryBases()) {
685 writeAnnotations(j
.annotations
);
686 std::cout
<< "interface ";
690 for (auto & j
: ent2
->getDirectOptionalBases()) {
692 writeAnnotations(j
.annotations
);
693 std::cout
<< "[optional] interface ";
697 for (auto & j
: ent2
->getDirectAttributes()) {
699 writeAnnotations(j
.annotations
);
700 std::cout
<< "[attribute";
702 std::cout
<< ", bound";
705 std::cout
<< ", readonly";
709 std::cout
<< ' ' << j
.name
;
710 if (!(j
.getExceptions
.empty() && j
.setExceptions
.empty())) {
712 if (!j
.getExceptions
.empty()) {
715 writeExceptionSpecification(j
.getExceptions
);
718 if (!j
.setExceptions
.empty()) {
721 writeExceptionSpecification(j
.setExceptions
);
728 for (auto & j
: ent2
->getDirectMethods()) {
730 writeAnnotations(j
.annotations
);
731 writeType(j
.returnType
);
732 std::cout
<< ' ' << j
.name
<< '(';
733 for (auto k(j
.parameters
.begin()); k
!= j
.parameters
.end();
736 if (k
!= j
.parameters
.begin()) {
739 switch (k
->direction
) {
740 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
:
741 std::cout
<< "[in] ";
743 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT
:
744 std::cout
<< "[out] ";
746 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT
:
747 std::cout
<< "[inout] ";
751 std::cout
<< ' ' << k
->name
;
754 writeExceptionSpecification(j
.exceptions
);
761 case unoidl::Entity::SORT_TYPEDEF
:
763 rtl::Reference
<unoidl::TypedefEntity
> ent2(
764 static_cast<unoidl::TypedefEntity
*>(ent
.get()));
765 writeAnnotationsPublished(ent
);
766 std::cout
<< "typedef ";
767 writeType(ent2
->getType());
768 std::cout
<< ' ' << id
<< ";\n";
771 case unoidl::Entity::SORT_CONSTANT_GROUP
:
773 rtl::Reference
<unoidl::ConstantGroupEntity
> ent2(
774 static_cast<unoidl::ConstantGroupEntity
*>(ent
.get()));
775 writeAnnotationsPublished(ent
);
776 std::cout
<< "constants " << id
<< " {\n";
777 for (auto & j
: ent2
->getMembers()) {
779 writeAnnotations(j
.annotations
);
780 std::cout
<< "const ";
781 switch (j
.value
.type
) {
782 case unoidl::ConstantValue::TYPE_BOOLEAN
:
783 std::cout
<< "boolean";
785 case unoidl::ConstantValue::TYPE_BYTE
:
788 case unoidl::ConstantValue::TYPE_SHORT
:
789 std::cout
<< "short";
791 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT
:
792 std::cout
<< "unsigned short";
794 case unoidl::ConstantValue::TYPE_LONG
:
797 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG
:
798 std::cout
<< "unsigned long";
800 case unoidl::ConstantValue::TYPE_HYPER
:
801 std::cout
<< "hyper";
803 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER
:
804 std::cout
<< "unsigned hyper";
806 case unoidl::ConstantValue::TYPE_FLOAT
:
807 std::cout
<< "float";
809 case unoidl::ConstantValue::TYPE_DOUBLE
:
810 std::cout
<< "double";
813 std::cout
<< ' ' << j
.name
<< " = ";
814 switch (j
.value
.type
) {
815 case unoidl::ConstantValue::TYPE_BOOLEAN
:
816 std::cout
<< (j
.value
.booleanValue
? "TRUE" : "FALSE");
818 case unoidl::ConstantValue::TYPE_BYTE
:
819 std::cout
<< int(j
.value
.byteValue
);
821 case unoidl::ConstantValue::TYPE_SHORT
:
822 std::cout
<< j
.value
.shortValue
;
824 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT
:
825 std::cout
<< j
.value
.unsignedShortValue
;
827 case unoidl::ConstantValue::TYPE_LONG
:
828 std::cout
<< j
.value
.longValue
;
830 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG
:
831 std::cout
<< j
.value
.unsignedLongValue
;
833 case unoidl::ConstantValue::TYPE_HYPER
:
834 std::cout
<< j
.value
.hyperValue
;
836 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER
:
837 std::cout
<< j
.value
.unsignedHyperValue
;
839 case unoidl::ConstantValue::TYPE_FLOAT
:
840 std::cout
<< j
.value
.floatValue
;
842 case unoidl::ConstantValue::TYPE_DOUBLE
:
843 std::cout
<< j
.value
.doubleValue
;
852 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE
:
854 rtl::Reference
<unoidl::SingleInterfaceBasedServiceEntity
> ent2(
855 static_cast<unoidl::SingleInterfaceBasedServiceEntity
*>(
857 writeAnnotationsPublished(ent
);
858 std::cout
<< "service " << id
<< ": ";
859 writeName(ent2
->getBase());
860 if (ent2
->getConstructors().size() != 1
861 || !ent2
->getConstructors().front().defaultConstructor
)
864 for (auto & j
: ent2
->getConstructors()) {
866 writeAnnotations(j
.annotations
);
867 std::cout
<< j
.name
<< '(';
868 for (auto k(j
.parameters
.begin());
869 k
!= j
.parameters
.end(); ++k
)
871 if (k
!= j
.parameters
.begin()) {
874 std::cout
<< "[in] ";
879 std::cout
<< ' ' << k
->name
;
882 writeExceptionSpecification(j
.exceptions
);
891 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE
:
893 rtl::Reference
<unoidl::AccumulationBasedServiceEntity
> ent2(
894 static_cast<unoidl::AccumulationBasedServiceEntity
*>(
896 writeAnnotationsPublished(ent
);
897 std::cout
<< "service " << id
<< " {\n";
898 for (auto & j
: ent2
->getDirectMandatoryBaseServices()) {
900 writeAnnotations(j
.annotations
);
901 std::cout
<< "service ";
905 for (auto & j
: ent2
->getDirectOptionalBaseServices()) {
907 writeAnnotations(j
.annotations
);
908 std::cout
<< "[optional] service ";
912 for (auto & j
: ent2
->getDirectMandatoryBaseInterfaces()) {
914 writeAnnotations(j
.annotations
);
915 std::cout
<< "interface ";
919 for (auto & j
: ent2
->getDirectOptionalBaseInterfaces()) {
921 writeAnnotations(j
.annotations
);
922 std::cout
<< "[optional] interface ";
926 for (auto & j
: ent2
->getDirectProperties()) {
928 writeAnnotations(j
.annotations
);
929 std::cout
<< "[property";
931 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_BOUND
)
934 std::cout
<< ", bound";
937 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED
)
940 std::cout
<< ", constrained";
943 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_AMBIGUOUS
)
946 std::cout
<< ", maybeambiguous";
949 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_DEFAULT
)
952 std::cout
<< ", maybedefault";
955 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_VOID
)
958 std::cout
<< ", maybevoid";
961 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL
)
964 std::cout
<< ", optional";
967 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_READ_ONLY
)
970 std::cout
<< ", readonly";
973 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_REMOVABLE
)
976 std::cout
<< ", removable";
979 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_TRANSIENT
)
982 std::cout
<< ", transient";
986 std::cout
<< ' ' << j
.name
<< ";\n";
992 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON
:
994 rtl::Reference
<unoidl::InterfaceBasedSingletonEntity
> ent2(
995 static_cast<unoidl::InterfaceBasedSingletonEntity
*>(
997 writeAnnotationsPublished(ent
);
998 std::cout
<< "singleton " << id
<< ": ";
999 writeName(ent2
->getBase());
1003 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON
:
1005 rtl::Reference
<unoidl::ServiceBasedSingletonEntity
> ent2(
1006 static_cast<unoidl::ServiceBasedSingletonEntity
*>(
1008 writeAnnotationsPublished(ent
);
1009 std::cout
<< "singleton " << id
<< " { service ";
1010 writeName(ent2
->getBase());
1011 std::cout
<< "; };";
1014 case unoidl::Entity::SORT_MODULE
:
1015 assert(false && "this cannot happen");
1021 SAL_IMPLEMENT_MAIN() {
1023 sal_uInt32 args
= rtl_getAppCommandArgCount();
1028 rtl_getAppCommandArg(0, &arg
.pData
);
1029 bool published
= arg
== "--published";
1030 if (published
&& args
== 1) {
1033 rtl::Reference
<unoidl::Manager
> mgr(new unoidl::Manager
);
1034 rtl::Reference
<unoidl::Provider
> prov
;
1035 for (sal_uInt32 i
= (published
? 1 : 0); i
!= args
; ++i
) {
1036 OUString
uri(getArgumentUri(i
));
1038 prov
= mgr
->addProvider(uri
);
1039 } catch (unoidl::NoSuchFileException
&) {
1041 << "Input <" << uri
<< "> does not exist" << std::endl
;
1042 std::exit(EXIT_FAILURE
);
1045 std::map
<OUString
, Entity
> ents
;
1046 scanMap(mgr
, prov
->createRootCursor(), published
, u
"", ents
);
1047 std::vector
<OUString
> sorted(sort(ents
));
1048 std::vector
<OUString
> mods
;
1049 for (const auto & i
: sorted
) {
1050 writeEntity(ents
, mods
, i
);
1052 closeModules(mods
, mods
.size());
1053 return EXIT_SUCCESS
;
1054 } catch (unoidl::FileFormatException
& e1
) {
1056 << "Bad input <" << e1
.getUri() << ">: " << e1
.getDetail()
1058 std::exit(EXIT_FAILURE
);
1059 } catch (std::exception
& e1
) {
1060 std::cerr
<< "Failure: " << e1
.what() << std::endl
;
1061 std::exit(EXIT_FAILURE
);
1065 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */