Use o3tl::convert in Math
[LibreOffice.git] / unoidl / source / unoidl-read.cxx
bloba458d9b3286365880ef2255e525bbacc39f34b36
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/.
8 */
10 #include <sal/config.h>
12 #include <cassert>
13 #include <cstdlib>
14 #include <iostream>
15 #include <map>
16 #include <set>
17 #include <string_view>
18 #include <utility>
19 #include <vector>
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>
26 #include <sal/main.h>
27 #include <sal/types.h>
28 #include <unoidl/unoidl.hxx>
30 namespace {
32 void badUsage() {
33 std::cerr
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,"
38 " a single .idl")
39 << std::endl
40 << ("file, or a root directory of an .idl file tree. The complete"
41 " content of the")
42 << std::endl
43 << ("last <registry> is written to stdout; if --published is specified,"
44 " only the")
45 << std::endl
46 << ("published entities (plus any non-published entities referenced"
47 " from published")
48 << std::endl
49 << "via any unpublished optional bases) are written out." << std::endl;
50 std::exit(EXIT_FAILURE);
53 OUString getArgumentUri(sal_uInt32 argument) {
54 OUString arg;
55 rtl_getAppCommandArg(argument, &arg.pData);
56 OUString url;
57 osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
58 if (e1 != osl::FileBase::E_None) {
59 std::cerr
60 << "Cannot convert \"" << arg << "\" to file URL, error code "
61 << +e1 << std::endl;
62 std::exit(EXIT_FAILURE);
64 OUString cwd;
65 oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData);
66 if (e2 != osl_Process_E_None) {
67 std::cerr
68 << "Cannot obtain working directory, error code " << +e2
69 << std::endl;
70 std::exit(EXIT_FAILURE);
72 OUString abs;
73 e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
74 if (e1 != osl::FileBase::E_None) {
75 std::cerr
76 << "Cannot make \"" << url
77 << "\" into an absolute file URL, error code " << +e1 << std::endl;
78 std::exit(EXIT_FAILURE);
80 return abs;
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);
90 OUString nucl(type);
91 *rank = 0;
92 typeArguments->clear();
93 while (nucl.startsWith("[]", &nucl)) {
94 ++*rank;
96 sal_Int32 i = nucl.indexOf('<');
97 if (i != -1) {
98 OUString tmpl(nucl.copy(0, i));
99 do {
100 ++i; // skip '<' or ','
101 sal_Int32 j = i;
102 for (sal_Int32 level = 0; j != nucl.getLength(); ++j) {
103 sal_Unicode c = nucl[j];
104 if (c == ',') {
105 if (level == 0) {
106 break;
108 } else if (c == '<') {
109 ++level;
110 } else if (c == '>') {
111 if (level == 0) {
112 break;
114 --level;
117 if (j != nucl.getLength()) {
118 typeArguments->push_back(nucl.copy(i, j - i));
120 i = j;
121 } while (i != nucl.getLength() && nucl[i] != '>');
122 assert(i == nucl.getLength() - 1 && nucl[i] == '>');
123 assert(!typeArguments->empty());
124 nucl = tmpl;
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"
132 && nucl != "any";
133 assert(*entity || typeArguments->empty());
134 return nucl;
137 struct Entity {
138 enum class Sorted { NO, ACTIVE, YES };
139 enum class Written { NO, DECLARATION, DEFINITION };
141 explicit Entity(
142 rtl::Reference<unoidl::Entity> const & theEntity, bool theRelevant):
143 entity(theEntity), relevant(theRelevant), sorted(Sorted::NO),
144 written(Written::NO)
147 rtl::Reference<unoidl::Entity> const entity;
148 std::set<OUString> dependencies;
149 std::set<OUString> interfaceDependencies;
150 bool relevant;
151 Sorted sorted;
152 Written written;
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)
162 return;
164 bool ifc = false;
165 if (weakInterfaceDependency) {
166 rtl::Reference<unoidl::Entity> ent(manager->findEntity(name));
167 if (!ent.is()) {
168 std::cerr << "Unknown entity " << name << std::endl;
169 std::exit(EXIT_FAILURE);
171 ifc = ent->getSort() == unoidl::Entity::SORT_INTERFACE_TYPE;
173 (ifc
174 ? iterator->second.interfaceDependencies
175 : iterator->second.dependencies)
176 .insert(name);
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)
204 std::size_t rank;
205 std::vector<OUString> args;
206 bool entity;
207 OUString nucl(decomposeType(type, &rank, &args, &entity));
208 if (entity) {
209 insertEntityDependency(manager, iterator, nucl, true);
210 for (const auto & i: args) {
211 insertTypeDependency(manager, iterator, i);
216 void scanMap(
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)
221 assert(cursor.is());
222 for (;;) {
223 OUString id;
224 rtl::Reference<unoidl::Entity> ent(cursor->getNext(&id));
225 if (!ent.is()) {
226 break;
228 OUString name(prefix + id);
229 if (ent->getSort() == unoidl::Entity::SORT_MODULE) {
230 scanMap(
231 manager,
232 static_cast<unoidl::ModuleEntity *>(ent.get())->createCursor(),
233 published, OUStringConcatenation(name + "."), entities);
234 } else {
235 std::map<OUString, Entity>::iterator i(
236 entities.insert(
237 std::make_pair(
238 name,
239 Entity(
240 ent,
241 (!published
242 || (static_cast<unoidl::PublishableEntity *>(
243 ent.get())
244 ->isPublished())))))
245 .first);
246 switch (ent->getSort()) {
247 case unoidl::Entity::SORT_ENUM_TYPE:
248 case unoidl::Entity::SORT_CONSTANT_GROUP:
249 break;
250 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
252 rtl::Reference<unoidl::PlainStructTypeEntity> ent2(
253 static_cast<unoidl::PlainStructTypeEntity *>(
254 ent.get()));
255 if (!ent2->getDirectBase().isEmpty()) {
256 insertEntityDependency(
257 manager, i, ent2->getDirectBase());
259 for (auto & j: ent2->getDirectMembers()) {
260 insertTypeDependency(manager, i, j.type);
262 break;
264 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
266 rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
267 ent2(
268 static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
269 ent.get()));
270 for (auto & j: ent2->getMembers()) {
271 if (!j.parameterized) {
272 insertTypeDependency(manager, i, j.type);
275 break;
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);
288 break;
290 case unoidl::Entity::SORT_INTERFACE_TYPE:
292 rtl::Reference<unoidl::InterfaceTypeEntity> ent2(
293 static_cast<unoidl::InterfaceTypeEntity *>(
294 ent.get()));
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);
309 break;
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());
316 break;
318 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
320 rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
321 ent2(
322 static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
323 ent.get()));
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);
331 break;
333 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
335 rtl::Reference<unoidl::AccumulationBasedServiceEntity> ent2(
336 static_cast<unoidl::AccumulationBasedServiceEntity *>(
337 ent.get()));
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);
349 break;
351 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
353 rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2(
354 static_cast<unoidl::InterfaceBasedSingletonEntity *>(
355 ent.get()));
356 insertEntityDependency(manager, i, ent2->getBase());
357 break;
359 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
361 rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2(
362 static_cast<unoidl::ServiceBasedSingletonEntity *>(
363 ent.get()));
364 insertEntityDependency(manager, i, ent2->getBase());
365 break;
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);
388 void visit(
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);
407 break;
408 case Entity::Sorted::ACTIVE:
409 std::cerr
410 << "Entity " << iterator->first << " recursively depends on itself"
411 << std::endl;
412 std::exit(EXIT_FAILURE);
413 // fall-through avoids warnings
414 default:
415 break;
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);
424 return 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) {
429 std::cout << ' ';
431 for (unsigned int i = 0; i != extra; ++i) {
432 std::cout << ' ';
436 void closeModules(
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());
441 modules.pop_back();
442 indent(modules);
443 std::cout << "};\n";
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));
452 if (j == -1) {
453 closeModules(
454 modules,
455 static_cast< std::vector<OUString>::size_type >(
456 modules.end() - i));
457 indent(modules);
458 return id;
460 if (i != modules.end()) {
461 if (id == *i) {
462 ++i;
463 continue;
465 closeModules(
466 modules,
467 static_cast< std::vector<OUString>::size_type >(
468 modules.end() - i));
469 i = modules.end();
471 indent(modules);
472 std::cout << "module " << id << " {\n";
473 modules.push_back(id);
474 i = modules.end();
478 void writeName(OUString const & name) {
479 std::cout << "::" << name.replaceAll(".", "::");
482 void writeAnnotations(std::vector<OUString> const & annotations) {
483 if (!annotations.empty()) {
484 std::cout << "/**";
485 for (auto & i: annotations) {
486 //TODO: i.indexOf("*/") == -1
487 std::cout << " @" << i;
489 std::cout << " */ ";
493 void writePublished(rtl::Reference<unoidl::PublishableEntity> const & entity) {
494 assert(entity.is());
495 if (entity->isPublished()) {
496 std::cout << "published ";
500 void writeAnnotationsPublished(
501 rtl::Reference<unoidl::PublishableEntity> const & entity)
503 assert(entity.is());
504 writeAnnotations(entity->getAnnotations());
505 writePublished(entity);
508 void writeType(OUString const & type) {
509 std::size_t rank;
510 std::vector<OUString> args;
511 bool entity;
512 OUString nucl(decomposeType(type, &rank, &args, &entity));
513 for (std::size_t i = 0; i != rank; ++i) {
514 std::cout << "sequence< ";
516 if (entity) {
517 writeName(nucl);
518 } else {
519 std::cout << nucl;
521 if (!args.empty()) {
522 std::cout << "< ";
523 for (auto i(args.begin()); i != args.end(); ++i) {
524 if (i != args.begin()) {
525 std::cout << ", ";
527 writeType(*i);
529 std::cout << " >";
531 for (std::size_t i = 0; i != rank; ++i) {
532 std::cout << " >";
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()) {
541 std::cout << ", ";
543 writeName(*i);
545 std::cout << ')';
549 void writeEntity(
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)
555 return;
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)
567 std::cerr
568 << "Entity " << j << " should be an interface type"
569 << std::endl;
570 std::exit(EXIT_FAILURE);
572 writePublished(
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)
591 indent(modules, 1);
592 writeAnnotations(j->annotations);
593 std::cout << j->name << " = " << j->value;
594 if (j + 1 != ent2->getMembers().end()) {
595 std::cout << ',';
597 std::cout << '\n';
599 indent(modules);
600 std::cout << "};\n";
601 break;
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()) {
610 std::cout << ": ";
611 writeName(ent2->getDirectBase());
613 std::cout << " {\n";
614 for (auto & j: ent2->getDirectMembers()) {
615 indent(modules, 1);
616 writeAnnotations(j.annotations);
617 writeType(j.type);
618 std::cout << ' ' << j.name << ";\n";
620 indent(modules);
621 std::cout << "};\n";
622 break;
624 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
626 rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
627 ent2(
628 static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
629 ent.get()));
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()) {
636 std::cout << ", ";
638 std::cout << *j;
640 std::cout << "> {\n";
641 for (auto & j: ent2->getMembers()) {
642 indent(modules, 1);
643 writeAnnotations(j.annotations);
644 if (j.parameterized) {
645 std::cout << j.type;
646 } else {
647 writeType(j.type);
649 std::cout << ' ' << j.name << ";\n";
651 indent(modules);
652 std::cout << "};\n";
653 break;
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()) {
662 std::cout << ": ";
663 writeName(ent2->getDirectBase());
665 std::cout << " {\n";
666 for (auto & j: ent2->getDirectMembers()) {
667 indent(modules, 1);
668 writeAnnotations(j.annotations);
669 writeType(j.type);
670 std::cout << ' ' << j.name << ";\n";
672 indent(modules);
673 std::cout << "};\n";
674 break;
676 case unoidl::Entity::SORT_INTERFACE_TYPE:
678 rtl::Reference<unoidl::InterfaceTypeEntity> ent2(
679 static_cast<unoidl::InterfaceTypeEntity *>(
680 ent.get()));
681 writeAnnotationsPublished(ent);
682 std::cout << "interface " << id << " {\n";
683 for (auto & j: ent2->getDirectMandatoryBases()) {
684 indent(modules, 1);
685 writeAnnotations(j.annotations);
686 std::cout << "interface ";
687 writeName(j.name);
688 std::cout << ";\n";
690 for (auto & j: ent2->getDirectOptionalBases()) {
691 indent(modules, 1);
692 writeAnnotations(j.annotations);
693 std::cout << "[optional] interface ";
694 writeName(j.name);
695 std::cout << ";\n";
697 for (auto & j: ent2->getDirectAttributes()) {
698 indent(modules, 1);
699 writeAnnotations(j.annotations);
700 std::cout << "[attribute";
701 if (j.bound) {
702 std::cout << ", bound";
704 if (j.readOnly) {
705 std::cout << ", readonly";
707 std::cout << "] ";
708 writeType(j.type);
709 std::cout << ' ' << j.name;
710 if (!(j.getExceptions.empty() && j.setExceptions.empty())) {
711 std::cout << " {\n";
712 if (!j.getExceptions.empty()) {
713 indent(modules, 2);
714 std::cout << "get";
715 writeExceptionSpecification(j.getExceptions);
716 std::cout << ";\n";
718 if (!j.setExceptions.empty()) {
719 indent(modules, 2);
720 std::cout << "set";
721 writeExceptionSpecification(j.setExceptions);
722 std::cout << ";\n";
724 std::cout << " }";
726 std::cout << ";\n";
728 for (auto & j: ent2->getDirectMethods()) {
729 indent(modules, 1);
730 writeAnnotations(j.annotations);
731 writeType(j.returnType);
732 std::cout << ' ' << j.name << '(';
733 for (auto k(j.parameters.begin()); k != j.parameters.end();
734 ++k)
736 if (k != j.parameters.begin()) {
737 std::cout << ", ";
739 switch (k->direction) {
740 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN:
741 std::cout << "[in] ";
742 break;
743 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT:
744 std::cout << "[out] ";
745 break;
746 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT:
747 std::cout << "[inout] ";
748 break;
750 writeType(k->type);
751 std::cout << ' ' << k->name;
753 std::cout << ')';
754 writeExceptionSpecification(j.exceptions);
755 std::cout << ";\n";
757 indent(modules);
758 std::cout << "};\n";
759 break;
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";
769 break;
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()) {
778 indent(modules, 1);
779 writeAnnotations(j.annotations);
780 std::cout << "const ";
781 switch (j.value.type) {
782 case unoidl::ConstantValue::TYPE_BOOLEAN:
783 std::cout << "boolean";
784 break;
785 case unoidl::ConstantValue::TYPE_BYTE:
786 std::cout << "byte";
787 break;
788 case unoidl::ConstantValue::TYPE_SHORT:
789 std::cout << "short";
790 break;
791 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
792 std::cout << "unsigned short";
793 break;
794 case unoidl::ConstantValue::TYPE_LONG:
795 std::cout << "long";
796 break;
797 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
798 std::cout << "unsigned long";
799 break;
800 case unoidl::ConstantValue::TYPE_HYPER:
801 std::cout << "hyper";
802 break;
803 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
804 std::cout << "unsigned hyper";
805 break;
806 case unoidl::ConstantValue::TYPE_FLOAT:
807 std::cout << "float";
808 break;
809 case unoidl::ConstantValue::TYPE_DOUBLE:
810 std::cout << "double";
811 break;
813 std::cout << ' ' << j.name << " = ";
814 switch (j.value.type) {
815 case unoidl::ConstantValue::TYPE_BOOLEAN:
816 std::cout << (j.value.booleanValue ? "TRUE" : "FALSE");
817 break;
818 case unoidl::ConstantValue::TYPE_BYTE:
819 std::cout << int(j.value.byteValue);
820 break;
821 case unoidl::ConstantValue::TYPE_SHORT:
822 std::cout << j.value.shortValue;
823 break;
824 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
825 std::cout << j.value.unsignedShortValue;
826 break;
827 case unoidl::ConstantValue::TYPE_LONG:
828 std::cout << j.value.longValue;
829 break;
830 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
831 std::cout << j.value.unsignedLongValue;
832 break;
833 case unoidl::ConstantValue::TYPE_HYPER:
834 std::cout << j.value.hyperValue;
835 break;
836 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
837 std::cout << j.value.unsignedHyperValue;
838 break;
839 case unoidl::ConstantValue::TYPE_FLOAT:
840 std::cout << j.value.floatValue;
841 break;
842 case unoidl::ConstantValue::TYPE_DOUBLE:
843 std::cout << j.value.doubleValue;
844 break;
846 std::cout << ";\n";
848 indent(modules);
849 std::cout << "};\n";
850 break;
852 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
854 rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity> ent2(
855 static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
856 ent.get()));
857 writeAnnotationsPublished(ent);
858 std::cout << "service " << id << ": ";
859 writeName(ent2->getBase());
860 if (ent2->getConstructors().size() != 1
861 || !ent2->getConstructors().front().defaultConstructor)
863 std::cout << " {\n";
864 for (auto & j: ent2->getConstructors()) {
865 indent(modules, 1);
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()) {
872 std::cout << ", ";
874 std::cout << "[in] ";
875 writeType(k->type);
876 if (k->rest) {
877 std::cout << "...";
879 std::cout << ' ' << k->name;
881 std::cout << ')';
882 writeExceptionSpecification(j.exceptions);
883 std::cout << ";\n";
885 indent(modules);
886 std::cout << '}';
888 std::cout << ";\n";
889 break;
891 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
893 rtl::Reference<unoidl::AccumulationBasedServiceEntity> ent2(
894 static_cast<unoidl::AccumulationBasedServiceEntity *>(
895 ent.get()));
896 writeAnnotationsPublished(ent);
897 std::cout << "service " << id << " {\n";
898 for (auto & j: ent2->getDirectMandatoryBaseServices()) {
899 indent(modules, 1);
900 writeAnnotations(j.annotations);
901 std::cout << "service ";
902 writeName(j.name);
903 std::cout << ";\n";
905 for (auto & j: ent2->getDirectOptionalBaseServices()) {
906 indent(modules, 1);
907 writeAnnotations(j.annotations);
908 std::cout << "[optional] service ";
909 writeName(j.name);
910 std::cout << ";\n";
912 for (auto & j: ent2->getDirectMandatoryBaseInterfaces()) {
913 indent(modules, 1);
914 writeAnnotations(j.annotations);
915 std::cout << "interface ";
916 writeName(j.name);
917 std::cout << ";\n";
919 for (auto & j: ent2->getDirectOptionalBaseInterfaces()) {
920 indent(modules, 1);
921 writeAnnotations(j.annotations);
922 std::cout << "[optional] interface ";
923 writeName(j.name);
924 std::cout << ";\n";
926 for (auto & j: ent2->getDirectProperties()) {
927 indent(modules, 1);
928 writeAnnotations(j.annotations);
929 std::cout << "[property";
930 if ((j.attributes
931 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_BOUND)
932 != 0)
934 std::cout << ", bound";
936 if ((j.attributes
937 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED)
938 != 0)
940 std::cout << ", constrained";
942 if ((j.attributes
943 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_AMBIGUOUS)
944 != 0)
946 std::cout << ", maybeambiguous";
948 if ((j.attributes
949 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_DEFAULT)
950 != 0)
952 std::cout << ", maybedefault";
954 if ((j.attributes
955 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_VOID)
956 != 0)
958 std::cout << ", maybevoid";
960 if ((j.attributes
961 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL)
962 != 0)
964 std::cout << ", optional";
966 if ((j.attributes
967 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_READ_ONLY)
968 != 0)
970 std::cout << ", readonly";
972 if ((j.attributes
973 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_REMOVABLE)
974 != 0)
976 std::cout << ", removable";
978 if ((j.attributes
979 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_TRANSIENT)
980 != 0)
982 std::cout << ", transient";
984 std::cout << "] ";
985 writeType(j.type);
986 std::cout << ' ' << j.name << ";\n";
988 indent(modules);
989 std::cout << "};\n";
990 break;
992 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
994 rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2(
995 static_cast<unoidl::InterfaceBasedSingletonEntity *>(
996 ent.get()));
997 writeAnnotationsPublished(ent);
998 std::cout << "singleton " << id << ": ";
999 writeName(ent2->getBase());
1000 std::cout << ";\n";
1001 break;
1003 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
1005 rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2(
1006 static_cast<unoidl::ServiceBasedSingletonEntity *>(
1007 ent.get()));
1008 writeAnnotationsPublished(ent);
1009 std::cout << "singleton " << id << " { service ";
1010 writeName(ent2->getBase());
1011 std::cout << "; };";
1012 break;
1014 case unoidl::Entity::SORT_MODULE:
1015 assert(false && "this cannot happen");
1021 SAL_IMPLEMENT_MAIN() {
1022 try {
1023 sal_uInt32 args = rtl_getAppCommandArgCount();
1024 if (args == 0) {
1025 badUsage();
1027 OUString arg;
1028 rtl_getAppCommandArg(0, &arg.pData);
1029 bool published = arg == "--published";
1030 if (published && args == 1) {
1031 badUsage();
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));
1037 try {
1038 prov = mgr->addProvider(uri);
1039 } catch (unoidl::NoSuchFileException &) {
1040 std::cerr
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) {
1055 std::cerr
1056 << "Bad input <" << e1.getUri() << ">: " << e1.getDetail()
1057 << std::endl;
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: */