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>
29 #include <o3tl/string_view.hxx>
35 << "Usage:" << std::endl
<< std::endl
36 << " unoidl-read [--published] [--summary] [<extra registries>] <registry>"
37 << std::endl
<< std::endl
38 << ("where each <registry> is either a new- or legacy-format .rdb file,"
41 << ("file, or a root directory of an .idl file tree. The complete"
44 << ("last <registry> is written to stdout; if --published is specified,"
47 << ("published entities (plus any non-published entities referenced"
50 << "via any unpublished optional bases) are written out. If --summary is specified,"
52 << "only a short summary is written, with the type and name of one entity per line."
54 std::exit(EXIT_FAILURE
);
57 OUString
getArgumentUri(sal_uInt32 argument
) {
59 rtl_getAppCommandArg(argument
, &arg
.pData
);
61 osl::FileBase::RC e1
= osl::FileBase::getFileURLFromSystemPath(arg
, url
);
62 if (e1
!= osl::FileBase::E_None
) {
64 << "Cannot convert \"" << arg
<< "\" to file URL, error code "
66 std::exit(EXIT_FAILURE
);
69 oslProcessError e2
= osl_getProcessWorkingDir(&cwd
.pData
);
70 if (e2
!= osl_Process_E_None
) {
72 << "Cannot obtain working directory, error code " << +e2
74 std::exit(EXIT_FAILURE
);
77 e1
= osl::FileBase::getAbsoluteFileURL(cwd
, url
, abs
);
78 if (e1
!= osl::FileBase::E_None
) {
80 << "Cannot make \"" << url
81 << "\" into an absolute file URL, error code " << +e1
<< std::endl
;
82 std::exit(EXIT_FAILURE
);
87 std::u16string_view
decomposeType(
88 std::u16string_view type
, std::size_t * rank
,
89 std::vector
<OUString
> * typeArguments
, bool * entity
)
91 assert(rank
!= nullptr);
92 assert(typeArguments
!= nullptr);
93 assert(entity
!= nullptr);
94 std::u16string_view
nucl(type
);
96 typeArguments
->clear();
97 while (o3tl::starts_with(nucl
, u
"[]", &nucl
)) {
100 size_t i
= nucl
.find('<');
101 if (i
!= std::u16string_view::npos
) {
102 std::u16string_view
tmpl(nucl
.substr(0, i
));
104 ++i
; // skip '<' or ','
106 for (size_t level
= 0; j
!= nucl
.size(); ++j
) {
107 sal_Unicode c
= nucl
[j
];
112 } else if (c
== '<') {
114 } else if (c
== '>') {
121 if (j
!= nucl
.size()) {
122 typeArguments
->push_back(OUString(nucl
.substr(i
, j
- i
)));
125 } while (i
!= nucl
.size() && nucl
[i
] != '>');
126 assert(i
== nucl
.size() - 1 && nucl
[i
] == '>');
127 assert(!typeArguments
->empty());
130 assert(!nucl
.empty());
131 *entity
= nucl
!= u
"void" && nucl
!= u
"boolean" && nucl
!= u
"byte"
132 && nucl
!= u
"short" && nucl
!= u
"unsigned short" && nucl
!= u
"long"
133 && nucl
!= u
"unsigned long" && nucl
!= u
"hyper"
134 && nucl
!= u
"unsigned hyper" && nucl
!= u
"float" && nucl
!= u
"double"
135 && nucl
!= u
"char" && nucl
!= u
"string" && nucl
!= u
"type"
137 assert(*entity
|| typeArguments
->empty());
142 enum class Sorted
{ NO
, ACTIVE
, YES
};
143 enum class Written
{ NO
, DECLARATION
, DEFINITION
};
146 rtl::Reference
<unoidl::Entity
> theEntity
, bool theRelevant
, Entity
* theParent
):
147 entity(std::move(theEntity
)), relevant(theRelevant
), sorted(Sorted::NO
),
148 written(Written::NO
), parent(theParent
)
151 rtl::Reference
<unoidl::Entity
> const entity
;
152 std::set
<OUString
> dependencies
;
153 std::set
<OUString
> interfaceDependencies
;
160 void insertEntityDependency(
161 rtl::Reference
<unoidl::Manager
> const & manager
,
162 std::map
<OUString
, Entity
>::iterator
const & iterator
,
163 OUString
const & name
, bool weakInterfaceDependency
= false)
165 assert(manager
.is());
166 if (name
== iterator
->first
)
170 if (weakInterfaceDependency
) {
171 rtl::Reference
<unoidl::Entity
> ent(manager
->findEntity(name
));
173 std::cerr
<< "Unknown entity " << name
<< std::endl
;
174 std::exit(EXIT_FAILURE
);
176 ifc
= ent
->getSort() == unoidl::Entity::SORT_INTERFACE_TYPE
;
179 ? iterator
->second
.interfaceDependencies
180 : iterator
->second
.dependencies
)
184 void insertEntityDependencies(
185 rtl::Reference
<unoidl::Manager
> const & manager
,
186 std::map
<OUString
, Entity
>::iterator
const & iterator
,
187 std::vector
<OUString
> const & names
)
189 for (auto & i
: names
) {
190 insertEntityDependency(manager
, iterator
, i
);
194 void insertEntityDependencies(
195 rtl::Reference
<unoidl::Manager
> const & manager
,
196 std::map
<OUString
, Entity
>::iterator
const & iterator
,
197 std::vector
<unoidl::AnnotatedReference
> const & references
)
199 for (auto & i
: references
) {
200 insertEntityDependency(manager
, iterator
, i
.name
);
204 void insertTypeDependency(
205 rtl::Reference
<unoidl::Manager
> const & manager
,
206 std::map
<OUString
, Entity
>::iterator
const & iterator
,
207 std::u16string_view type
)
210 std::vector
<OUString
> args
;
212 OUString
nucl(decomposeType(type
, &rank
, &args
, &entity
));
214 insertEntityDependency(manager
, iterator
, nucl
, true);
215 for (const auto & i
: args
) {
216 insertTypeDependency(manager
, iterator
, i
);
222 rtl::Reference
<unoidl::Manager
> const & manager
,
223 rtl::Reference
<unoidl::MapCursor
> const & cursor
, bool modules
, bool published
,
224 std::u16string_view prefix
, Entity
* parent
, std::map
<OUString
, Entity
> & entities
)
229 rtl::Reference
<unoidl::Entity
> ent(cursor
->getNext(&id
));
233 OUString
name(prefix
+ id
);
234 if (ent
->getSort() == unoidl::Entity::SORT_MODULE
) {
235 Entity
* p
= nullptr;
237 p
= &entities
.insert(std::make_pair(name
, Entity(ent
, !published
, parent
))).first
242 static_cast<unoidl::ModuleEntity
*>(ent
.get())->createCursor(), modules
,
243 published
, Concat2View(name
+ "."), p
, entities
);
245 auto const pub
= static_cast<unoidl::PublishableEntity
*>(ent
.get())->isPublished();
246 std::map
<OUString
, Entity
>::iterator
i(
256 if (modules
&& published
&& pub
) {
257 for (auto j
= parent
; j
; j
= j
->parent
) {
261 switch (ent
->getSort()) {
262 case unoidl::Entity::SORT_ENUM_TYPE
:
263 case unoidl::Entity::SORT_CONSTANT_GROUP
:
265 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE
:
267 rtl::Reference
<unoidl::PlainStructTypeEntity
> ent2(
268 static_cast<unoidl::PlainStructTypeEntity
*>(
270 if (!ent2
->getDirectBase().isEmpty()) {
271 insertEntityDependency(
272 manager
, i
, ent2
->getDirectBase());
274 for (auto & j
: ent2
->getDirectMembers()) {
275 insertTypeDependency(manager
, i
, j
.type
);
279 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE
:
281 rtl::Reference
<unoidl::PolymorphicStructTypeTemplateEntity
>
283 static_cast<unoidl::PolymorphicStructTypeTemplateEntity
*>(
285 for (auto & j
: ent2
->getMembers()) {
286 if (!j
.parameterized
) {
287 insertTypeDependency(manager
, i
, j
.type
);
292 case unoidl::Entity::SORT_EXCEPTION_TYPE
:
294 rtl::Reference
<unoidl::ExceptionTypeEntity
> ent2(
295 static_cast<unoidl::ExceptionTypeEntity
*>(ent
.get()));
296 if (!ent2
->getDirectBase().isEmpty()) {
297 insertEntityDependency(
298 manager
, i
, ent2
->getDirectBase());
300 for (auto & j
: ent2
->getDirectMembers()) {
301 insertTypeDependency(manager
, i
, j
.type
);
305 case unoidl::Entity::SORT_INTERFACE_TYPE
:
307 rtl::Reference
<unoidl::InterfaceTypeEntity
> ent2(
308 static_cast<unoidl::InterfaceTypeEntity
*>(
310 insertEntityDependencies(
311 manager
, i
, ent2
->getDirectMandatoryBases());
312 insertEntityDependencies(
313 manager
, i
, ent2
->getDirectOptionalBases());
314 for (auto & j
: ent2
->getDirectAttributes()) {
315 insertTypeDependency(manager
, i
, j
.type
);
317 for (auto & j
: ent2
->getDirectMethods()) {
318 insertTypeDependency(manager
, i
, j
.returnType
);
319 for (auto & k
: j
.parameters
) {
320 insertTypeDependency(manager
, i
, k
.type
);
322 insertEntityDependencies(manager
, i
, j
.exceptions
);
326 case unoidl::Entity::SORT_TYPEDEF
:
328 rtl::Reference
<unoidl::TypedefEntity
> ent2(
329 static_cast<unoidl::TypedefEntity
*>(ent
.get()));
330 insertTypeDependency(manager
, i
, ent2
->getType());
333 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE
:
335 rtl::Reference
<unoidl::SingleInterfaceBasedServiceEntity
>
337 static_cast<unoidl::SingleInterfaceBasedServiceEntity
*>(
339 insertEntityDependency(manager
, i
, ent2
->getBase());
340 for (auto & j
: ent2
->getConstructors()) {
341 for (auto & k
: j
.parameters
) {
342 insertTypeDependency(manager
, i
, k
.type
);
344 insertEntityDependencies(manager
, i
, j
.exceptions
);
348 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE
:
350 rtl::Reference
<unoidl::AccumulationBasedServiceEntity
> ent2(
351 static_cast<unoidl::AccumulationBasedServiceEntity
*>(
353 insertEntityDependencies(
354 manager
, i
, ent2
->getDirectMandatoryBaseServices());
355 insertEntityDependencies(
356 manager
, i
, ent2
->getDirectOptionalBaseServices());
357 insertEntityDependencies(
358 manager
, i
, ent2
->getDirectMandatoryBaseInterfaces());
359 insertEntityDependencies(
360 manager
, i
, ent2
->getDirectOptionalBaseInterfaces());
361 for (auto & j
: ent2
->getDirectProperties()) {
362 insertTypeDependency(manager
, i
, j
.type
);
366 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON
:
368 rtl::Reference
<unoidl::InterfaceBasedSingletonEntity
> ent2(
369 static_cast<unoidl::InterfaceBasedSingletonEntity
*>(
371 insertEntityDependency(manager
, i
, ent2
->getBase());
374 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON
:
376 rtl::Reference
<unoidl::ServiceBasedSingletonEntity
> ent2(
377 static_cast<unoidl::ServiceBasedSingletonEntity
*>(
379 insertEntityDependency(manager
, i
, ent2
->getBase());
382 case unoidl::Entity::SORT_MODULE
:
383 assert(false && "this cannot happen");
389 void propagateRelevant(std::map
<OUString
, Entity
> & entities
, Entity
& entity
) {
390 if (!entity
.relevant
) {
391 entity
.relevant
= true;
392 if (entity
.sorted
!= Entity::Sorted::YES
) {
393 for (auto & i
: entity
.dependencies
) {
394 std::map
<OUString
, Entity
>::iterator
j(entities
.find(i
));
395 if (j
!= entities
.end()) {
396 propagateRelevant(entities
, j
->second
);
404 std::map
<OUString
, Entity
> & entities
,
405 std::map
<OUString
, Entity
>::iterator
const & iterator
,
406 std::vector
<OUString
> & result
)
408 switch (iterator
->second
.sorted
) {
409 case Entity::Sorted::NO
:
410 iterator
->second
.sorted
= Entity::Sorted::ACTIVE
;
411 for (auto & i
: iterator
->second
.dependencies
) {
412 std::map
<OUString
, Entity
>::iterator
j(entities
.find(i
));
413 if (j
!= entities
.end()) {
414 if (iterator
->second
.relevant
) {
415 propagateRelevant(entities
, j
->second
);
417 visit(entities
, j
, result
);
420 iterator
->second
.sorted
= Entity::Sorted::YES
;
421 result
.push_back(iterator
->first
);
423 case Entity::Sorted::ACTIVE
:
425 << "Entity " << iterator
->first
<< " recursively depends on itself"
427 std::exit(EXIT_FAILURE
);
428 // fall-through avoids warnings
434 std::vector
<OUString
> sort(std::map
<OUString
, Entity
> & entities
) {
435 std::vector
<OUString
> res
;
436 for (auto i(entities
.begin()); i
!= entities
.end(); ++i
) {
437 visit(entities
, i
, res
);
442 void indent(std::vector
<OUString
> const & modules
, unsigned int extra
= 0) {
443 for (std::vector
<OUString
>::size_type i
= 0; i
!= modules
.size(); ++i
) {
446 for (unsigned int i
= 0; i
!= extra
; ++i
) {
452 std::vector
<OUString
> & modules
, std::vector
<OUString
>::size_type n
)
454 for (std::vector
<OUString
>::size_type i
= 0; i
!= n
; ++i
) {
455 assert(!modules
.empty());
462 OUString
openModulesFor(std::vector
<OUString
> & modules
, std::u16string_view name
)
464 std::vector
<OUString
>::iterator
i(modules
.begin());
465 for (sal_Int32 j
= 0;;) {
466 OUString
id(o3tl::getToken(name
, 0, '.', j
));
470 static_cast< std::vector
<OUString
>::size_type
>(
475 if (i
!= modules
.end()) {
482 static_cast< std::vector
<OUString
>::size_type
>(
487 std::cout
<< "module " << id
<< " {\n";
488 modules
.push_back(id
);
493 void writeName(OUString
const & name
) {
494 std::cout
<< "::" << name
.replaceAll(".", "::");
497 void writeAnnotations(std::vector
<OUString
> const & annotations
) {
498 if (!annotations
.empty()) {
500 for (auto & i
: annotations
) {
501 //TODO: i.indexOf("*/") == -1
502 std::cout
<< " @" << i
;
508 void writePublished(rtl::Reference
<unoidl::PublishableEntity
> const & entity
) {
510 if (entity
->isPublished()) {
511 std::cout
<< "published ";
515 void writeAnnotationsPublished(
516 rtl::Reference
<unoidl::PublishableEntity
> const & entity
)
519 writeAnnotations(entity
->getAnnotations());
520 writePublished(entity
);
523 void writeType(std::u16string_view type
) {
525 std::vector
<OUString
> args
;
527 OUString
nucl(decomposeType(type
, &rank
, &args
, &entity
));
528 for (std::size_t i
= 0; i
!= rank
; ++i
) {
529 std::cout
<< "sequence< ";
538 for (auto i(args
.begin()); i
!= args
.end(); ++i
) {
539 if (i
!= args
.begin()) {
546 for (std::size_t i
= 0; i
!= rank
; ++i
) {
551 void writeExceptionSpecification(std::vector
<OUString
> const & exceptions
) {
552 if (!exceptions
.empty()) {
553 std::cout
<< " raises (";
554 for (auto i(exceptions
.begin()); i
!= exceptions
.end(); ++i
) {
555 if (i
!= exceptions
.begin()) {
565 std::map
<OUString
, Entity
> & entities
, std::vector
<OUString
> & modules
,
566 OUString
const & name
)
568 std::map
<OUString
, Entity
>::iterator
i(entities
.find(name
));
569 if (i
== entities
.end() || !i
->second
.relevant
)
572 assert(i
->second
.written
!= Entity::Written::DEFINITION
);
573 i
->second
.written
= Entity::Written::DEFINITION
;
574 for (auto & j
: i
->second
.interfaceDependencies
) {
575 std::map
<OUString
, Entity
>::iterator
k(entities
.find(j
));
576 if (k
!= entities
.end() && k
->second
.written
== Entity::Written::NO
) {
577 k
->second
.written
= Entity::Written::DECLARATION
;
578 OUString
id(openModulesFor(modules
, j
));
579 if (k
->second
.entity
->getSort()
580 != unoidl::Entity::SORT_INTERFACE_TYPE
)
583 << "Entity " << j
<< " should be an interface type"
585 std::exit(EXIT_FAILURE
);
588 static_cast<unoidl::PublishableEntity
*>(
589 k
->second
.entity
.get()));
590 std::cout
<< "interface " << id
<< ";\n";
593 OUString
id(openModulesFor(modules
, name
));
594 rtl::Reference
<unoidl::PublishableEntity
> ent(
595 static_cast<unoidl::PublishableEntity
*>(i
->second
.entity
.get()));
596 switch (ent
->getSort()) {
597 case unoidl::Entity::SORT_ENUM_TYPE
:
599 rtl::Reference
<unoidl::EnumTypeEntity
> ent2(
600 static_cast<unoidl::EnumTypeEntity
*>(ent
.get()));
601 writeAnnotationsPublished(ent
);
602 std::cout
<< "enum " << id
<< " {\n";
603 for (auto j(ent2
->getMembers().begin());
604 j
!= ent2
->getMembers().end(); ++j
)
607 writeAnnotations(j
->annotations
);
608 std::cout
<< j
->name
<< " = " << j
->value
;
609 if (j
+ 1 != ent2
->getMembers().end()) {
618 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE
:
620 rtl::Reference
<unoidl::PlainStructTypeEntity
> ent2(
621 static_cast<unoidl::PlainStructTypeEntity
*>(ent
.get()));
622 writeAnnotationsPublished(ent
);
623 std::cout
<< "struct " << id
;
624 if (!ent2
->getDirectBase().isEmpty()) {
626 writeName(ent2
->getDirectBase());
629 for (auto & j
: ent2
->getDirectMembers()) {
631 writeAnnotations(j
.annotations
);
633 std::cout
<< ' ' << j
.name
<< ";\n";
639 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE
:
641 rtl::Reference
<unoidl::PolymorphicStructTypeTemplateEntity
>
643 static_cast<unoidl::PolymorphicStructTypeTemplateEntity
*>(
645 writeAnnotationsPublished(ent
);
646 std::cout
<< "struct " << id
<< '<';
647 for (auto j(ent2
->getTypeParameters().begin());
648 j
!= ent2
->getTypeParameters().end(); ++j
)
650 if (j
!= ent2
->getTypeParameters().begin()) {
655 std::cout
<< "> {\n";
656 for (auto & j
: ent2
->getMembers()) {
658 writeAnnotations(j
.annotations
);
659 if (j
.parameterized
) {
664 std::cout
<< ' ' << j
.name
<< ";\n";
670 case unoidl::Entity::SORT_EXCEPTION_TYPE
:
672 rtl::Reference
<unoidl::ExceptionTypeEntity
> ent2(
673 static_cast<unoidl::ExceptionTypeEntity
*>(ent
.get()));
674 writeAnnotationsPublished(ent
);
675 std::cout
<< "exception " << id
;
676 if (!ent2
->getDirectBase().isEmpty()) {
678 writeName(ent2
->getDirectBase());
681 for (auto & j
: ent2
->getDirectMembers()) {
683 writeAnnotations(j
.annotations
);
685 std::cout
<< ' ' << j
.name
<< ";\n";
691 case unoidl::Entity::SORT_INTERFACE_TYPE
:
693 rtl::Reference
<unoidl::InterfaceTypeEntity
> ent2(
694 static_cast<unoidl::InterfaceTypeEntity
*>(
696 writeAnnotationsPublished(ent
);
697 std::cout
<< "interface " << id
<< " {\n";
698 for (auto & j
: ent2
->getDirectMandatoryBases()) {
700 writeAnnotations(j
.annotations
);
701 std::cout
<< "interface ";
705 for (auto & j
: ent2
->getDirectOptionalBases()) {
707 writeAnnotations(j
.annotations
);
708 std::cout
<< "[optional] interface ";
712 for (auto & j
: ent2
->getDirectAttributes()) {
714 writeAnnotations(j
.annotations
);
715 std::cout
<< "[attribute";
717 std::cout
<< ", bound";
720 std::cout
<< ", readonly";
724 std::cout
<< ' ' << j
.name
;
725 if (!(j
.getExceptions
.empty() && j
.setExceptions
.empty())) {
727 if (!j
.getExceptions
.empty()) {
730 writeExceptionSpecification(j
.getExceptions
);
733 if (!j
.setExceptions
.empty()) {
736 writeExceptionSpecification(j
.setExceptions
);
743 for (auto & j
: ent2
->getDirectMethods()) {
745 writeAnnotations(j
.annotations
);
746 writeType(j
.returnType
);
747 std::cout
<< ' ' << j
.name
<< '(';
748 for (auto k(j
.parameters
.begin()); k
!= j
.parameters
.end();
751 if (k
!= j
.parameters
.begin()) {
754 switch (k
->direction
) {
755 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
:
756 std::cout
<< "[in] ";
758 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT
:
759 std::cout
<< "[out] ";
761 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT
:
762 std::cout
<< "[inout] ";
766 std::cout
<< ' ' << k
->name
;
769 writeExceptionSpecification(j
.exceptions
);
776 case unoidl::Entity::SORT_TYPEDEF
:
778 rtl::Reference
<unoidl::TypedefEntity
> ent2(
779 static_cast<unoidl::TypedefEntity
*>(ent
.get()));
780 writeAnnotationsPublished(ent
);
781 std::cout
<< "typedef ";
782 writeType(ent2
->getType());
783 std::cout
<< ' ' << id
<< ";\n";
786 case unoidl::Entity::SORT_CONSTANT_GROUP
:
788 rtl::Reference
<unoidl::ConstantGroupEntity
> ent2(
789 static_cast<unoidl::ConstantGroupEntity
*>(ent
.get()));
790 writeAnnotationsPublished(ent
);
791 std::cout
<< "constants " << id
<< " {\n";
792 for (auto & j
: ent2
->getMembers()) {
794 writeAnnotations(j
.annotations
);
795 std::cout
<< "const ";
796 switch (j
.value
.type
) {
797 case unoidl::ConstantValue::TYPE_BOOLEAN
:
798 std::cout
<< "boolean";
800 case unoidl::ConstantValue::TYPE_BYTE
:
803 case unoidl::ConstantValue::TYPE_SHORT
:
804 std::cout
<< "short";
806 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT
:
807 std::cout
<< "unsigned short";
809 case unoidl::ConstantValue::TYPE_LONG
:
812 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG
:
813 std::cout
<< "unsigned long";
815 case unoidl::ConstantValue::TYPE_HYPER
:
816 std::cout
<< "hyper";
818 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER
:
819 std::cout
<< "unsigned hyper";
821 case unoidl::ConstantValue::TYPE_FLOAT
:
822 std::cout
<< "float";
824 case unoidl::ConstantValue::TYPE_DOUBLE
:
825 std::cout
<< "double";
828 std::cout
<< ' ' << j
.name
<< " = ";
829 switch (j
.value
.type
) {
830 case unoidl::ConstantValue::TYPE_BOOLEAN
:
831 std::cout
<< (j
.value
.booleanValue
? "TRUE" : "FALSE");
833 case unoidl::ConstantValue::TYPE_BYTE
:
834 std::cout
<< int(j
.value
.byteValue
);
836 case unoidl::ConstantValue::TYPE_SHORT
:
837 std::cout
<< j
.value
.shortValue
;
839 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT
:
840 std::cout
<< j
.value
.unsignedShortValue
;
842 case unoidl::ConstantValue::TYPE_LONG
:
843 std::cout
<< j
.value
.longValue
;
845 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG
:
846 std::cout
<< j
.value
.unsignedLongValue
;
848 case unoidl::ConstantValue::TYPE_HYPER
:
849 std::cout
<< j
.value
.hyperValue
;
851 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER
:
852 std::cout
<< j
.value
.unsignedHyperValue
;
854 case unoidl::ConstantValue::TYPE_FLOAT
:
855 std::cout
<< j
.value
.floatValue
;
857 case unoidl::ConstantValue::TYPE_DOUBLE
:
858 std::cout
<< j
.value
.doubleValue
;
867 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE
:
869 rtl::Reference
<unoidl::SingleInterfaceBasedServiceEntity
> ent2(
870 static_cast<unoidl::SingleInterfaceBasedServiceEntity
*>(
872 writeAnnotationsPublished(ent
);
873 std::cout
<< "service " << id
<< ": ";
874 writeName(ent2
->getBase());
875 if (ent2
->getConstructors().size() != 1
876 || !ent2
->getConstructors().front().defaultConstructor
)
879 for (auto & j
: ent2
->getConstructors()) {
881 writeAnnotations(j
.annotations
);
882 std::cout
<< j
.name
<< '(';
883 for (auto k(j
.parameters
.begin());
884 k
!= j
.parameters
.end(); ++k
)
886 if (k
!= j
.parameters
.begin()) {
889 std::cout
<< "[in] ";
894 std::cout
<< ' ' << k
->name
;
897 writeExceptionSpecification(j
.exceptions
);
906 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE
:
908 rtl::Reference
<unoidl::AccumulationBasedServiceEntity
> ent2(
909 static_cast<unoidl::AccumulationBasedServiceEntity
*>(
911 writeAnnotationsPublished(ent
);
912 std::cout
<< "service " << id
<< " {\n";
913 for (auto & j
: ent2
->getDirectMandatoryBaseServices()) {
915 writeAnnotations(j
.annotations
);
916 std::cout
<< "service ";
920 for (auto & j
: ent2
->getDirectOptionalBaseServices()) {
922 writeAnnotations(j
.annotations
);
923 std::cout
<< "[optional] service ";
927 for (auto & j
: ent2
->getDirectMandatoryBaseInterfaces()) {
929 writeAnnotations(j
.annotations
);
930 std::cout
<< "interface ";
934 for (auto & j
: ent2
->getDirectOptionalBaseInterfaces()) {
936 writeAnnotations(j
.annotations
);
937 std::cout
<< "[optional] interface ";
941 for (auto & j
: ent2
->getDirectProperties()) {
943 writeAnnotations(j
.annotations
);
944 std::cout
<< "[property";
946 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_BOUND
)
949 std::cout
<< ", bound";
952 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED
)
955 std::cout
<< ", constrained";
958 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_AMBIGUOUS
)
961 std::cout
<< ", maybeambiguous";
964 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_DEFAULT
)
967 std::cout
<< ", maybedefault";
970 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_VOID
)
973 std::cout
<< ", maybevoid";
976 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL
)
979 std::cout
<< ", optional";
982 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_READ_ONLY
)
985 std::cout
<< ", readonly";
988 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_REMOVABLE
)
991 std::cout
<< ", removable";
994 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_TRANSIENT
)
997 std::cout
<< ", transient";
1001 std::cout
<< ' ' << j
.name
<< ";\n";
1004 std::cout
<< "};\n";
1007 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON
:
1009 rtl::Reference
<unoidl::InterfaceBasedSingletonEntity
> ent2(
1010 static_cast<unoidl::InterfaceBasedSingletonEntity
*>(
1012 writeAnnotationsPublished(ent
);
1013 std::cout
<< "singleton " << id
<< ": ";
1014 writeName(ent2
->getBase());
1018 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON
:
1020 rtl::Reference
<unoidl::ServiceBasedSingletonEntity
> ent2(
1021 static_cast<unoidl::ServiceBasedSingletonEntity
*>(
1023 writeAnnotationsPublished(ent
);
1024 std::cout
<< "singleton " << id
<< " { service ";
1025 writeName(ent2
->getBase());
1026 std::cout
<< "; };";
1029 case unoidl::Entity::SORT_MODULE
:
1030 assert(false && "this cannot happen");
1034 void writeSummary(OUString
const & name
, Entity
const & entity
) {
1035 if (!entity
.relevant
) {
1038 switch (entity
.entity
->getSort()) {
1039 case unoidl::Entity::SORT_ENUM_TYPE
:
1040 std::cout
<< "enum";
1042 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE
:
1043 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE
:
1044 std::cout
<< "struct";
1046 case unoidl::Entity::SORT_EXCEPTION_TYPE
:
1047 std::cout
<< "exception";
1049 case unoidl::Entity::SORT_INTERFACE_TYPE
:
1050 std::cout
<< "interface";
1052 case unoidl::Entity::SORT_TYPEDEF
:
1053 std::cout
<< "typedef";
1055 case unoidl::Entity::SORT_CONSTANT_GROUP
:
1056 std::cout
<< "constants";
1058 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE
:
1059 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE
:
1060 std::cout
<< "service";
1062 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON
:
1063 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON
:
1064 std::cout
<< "singleton";
1066 case unoidl::Entity::SORT_MODULE
:
1067 std::cout
<< "module";
1070 std::cout
<< ' ' << name
<< '\n';
1075 SAL_IMPLEMENT_MAIN() {
1077 sal_uInt32 args
= rtl_getAppCommandArgCount();
1079 bool published
= false;
1080 bool summary
= false;
1086 rtl_getAppCommandArg(i
, &arg
.pData
);
1087 if (arg
== "--published") {
1092 } else if (arg
== "--summary") {
1101 rtl::Reference
<unoidl::Manager
> mgr(new unoidl::Manager
);
1102 rtl::Reference
<unoidl::Provider
> prov
;
1103 for (; i
!= args
; ++i
) {
1104 OUString
uri(getArgumentUri(i
));
1106 prov
= mgr
->addProvider(uri
);
1107 } catch (unoidl::NoSuchFileException
&) {
1109 << "Input <" << uri
<< "> does not exist" << std::endl
;
1110 std::exit(EXIT_FAILURE
);
1113 std::map
<OUString
, Entity
> ents
;
1114 scanMap(mgr
, prov
->createRootCursor(), summary
, published
, u
"", nullptr, ents
);
1116 for (auto const & j
: ents
) {
1117 writeSummary(j
.first
, j
.second
);
1120 std::vector
<OUString
> sorted(sort(ents
));
1121 std::vector
<OUString
> mods
;
1122 for (const auto & j
: sorted
) {
1123 writeEntity(ents
, mods
, j
);
1125 closeModules(mods
, mods
.size());
1127 return EXIT_SUCCESS
;
1128 } catch (unoidl::FileFormatException
& e1
) {
1130 << "Bad input <" << e1
.getUri() << ">: " << e1
.getDetail()
1132 std::exit(EXIT_FAILURE
);
1133 } catch (std::exception
& e1
) {
1134 std::cerr
<< "Failure: " << e1
.what() << std::endl
;
1135 std::exit(EXIT_FAILURE
);
1139 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */