nss: upgrade to release 3.73
[LibreOffice.git] / unoidl / source / unoidl-read.cxx
blob2b733c0f6f3115c7cd511eb7da753787992d0adb
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 <utility>
18 #include <vector>
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>
25 #include <sal/main.h>
26 #include <sal/types.h>
27 #include <unoidl/unoidl.hxx>
29 namespace {
31 void badUsage() {
32 std::cerr
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,"
37 " a single .idl")
38 << std::endl
39 << ("file, or a root directory of an .idl file tree. The complete"
40 " content of the")
41 << std::endl
42 << ("last <registry> is written to stdout; if --published is specified,"
43 " only the")
44 << std::endl
45 << ("published entities (plus any non-published entities referenced"
46 " from published")
47 << std::endl
48 << "via any unpublished optional bases) are written out." << std::endl;
49 std::exit(EXIT_FAILURE);
52 OUString getArgumentUri(sal_uInt32 argument) {
53 OUString arg;
54 rtl_getAppCommandArg(argument, &arg.pData);
55 OUString url;
56 osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
57 if (e1 != osl::FileBase::E_None) {
58 std::cerr
59 << "Cannot convert \"" << arg << "\" to file URL, error code "
60 << +e1 << std::endl;
61 std::exit(EXIT_FAILURE);
63 OUString cwd;
64 oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData);
65 if (e2 != osl_Process_E_None) {
66 std::cerr
67 << "Cannot obtain working directory, error code " << +e2
68 << std::endl;
69 std::exit(EXIT_FAILURE);
71 OUString abs;
72 e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
73 if (e1 != osl::FileBase::E_None) {
74 std::cerr
75 << "Cannot make \"" << url
76 << "\" into an absolute file URL, error code " << +e1 << std::endl;
77 std::exit(EXIT_FAILURE);
79 return abs;
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);
89 OUString nucl(type);
90 *rank = 0;
91 typeArguments->clear();
92 while (nucl.startsWith("[]", &nucl)) {
93 ++*rank;
95 sal_Int32 i = nucl.indexOf('<');
96 if (i != -1) {
97 OUString tmpl(nucl.copy(0, i));
98 do {
99 ++i; // skip '<' or ','
100 sal_Int32 j = i;
101 for (sal_Int32 level = 0; j != nucl.getLength(); ++j) {
102 sal_Unicode c = nucl[j];
103 if (c == ',') {
104 if (level == 0) {
105 break;
107 } else if (c == '<') {
108 ++level;
109 } else if (c == '>') {
110 if (level == 0) {
111 break;
113 --level;
116 if (j != nucl.getLength()) {
117 typeArguments->push_back(nucl.copy(i, j - i));
119 i = j;
120 } while (i != nucl.getLength() && nucl[i] != '>');
121 assert(i == nucl.getLength() - 1 && nucl[i] == '>');
122 assert(!typeArguments->empty());
123 nucl = tmpl;
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"
131 && nucl != "any";
132 assert(*entity || typeArguments->empty());
133 return nucl;
136 struct Entity {
137 enum class Sorted { NO, ACTIVE, YES };
138 enum class Written { NO, DECLARATION, DEFINITION };
140 explicit Entity(
141 rtl::Reference<unoidl::Entity> const & theEntity, bool theRelevant):
142 entity(theEntity), relevant(theRelevant), sorted(Sorted::NO),
143 written(Written::NO)
146 rtl::Reference<unoidl::Entity> const entity;
147 std::set<OUString> dependencies;
148 std::set<OUString> interfaceDependencies;
149 bool relevant;
150 Sorted sorted;
151 Written written;
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) {
161 bool ifc = false;
162 if (weakInterfaceDependency) {
163 rtl::Reference<unoidl::Entity> ent(manager->findEntity(name));
164 if (!ent.is()) {
165 std::cerr << "Unknown entity " << name << std::endl;
166 std::exit(EXIT_FAILURE);
168 ifc = ent->getSort() == unoidl::Entity::SORT_INTERFACE_TYPE;
170 (ifc
171 ? iterator->second.interfaceDependencies
172 : iterator->second.dependencies)
173 .insert(name);
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)
202 std::size_t rank;
203 std::vector<OUString> args;
204 bool entity;
205 OUString nucl(decomposeType(type, &rank, &args, &entity));
206 if (entity) {
207 insertEntityDependency(manager, iterator, nucl, true);
208 for (const auto & i: args) {
209 insertTypeDependency(manager, iterator, i);
214 void scanMap(
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)
219 assert(cursor.is());
220 for (;;) {
221 OUString id;
222 rtl::Reference<unoidl::Entity> ent(cursor->getNext(&id));
223 if (!ent.is()) {
224 break;
226 OUString name(prefix + id);
227 if (ent->getSort() == unoidl::Entity::SORT_MODULE) {
228 scanMap(
229 manager,
230 static_cast<unoidl::ModuleEntity *>(ent.get())->createCursor(),
231 published, name + ".", entities);
232 } else {
233 std::map<OUString, Entity>::iterator i(
234 entities.insert(
235 std::make_pair(
236 name,
237 Entity(
238 ent,
239 (!published
240 || (static_cast<unoidl::PublishableEntity *>(
241 ent.get())
242 ->isPublished())))))
243 .first);
244 switch (ent->getSort()) {
245 case unoidl::Entity::SORT_ENUM_TYPE:
246 case unoidl::Entity::SORT_CONSTANT_GROUP:
247 break;
248 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
250 rtl::Reference<unoidl::PlainStructTypeEntity> ent2(
251 static_cast<unoidl::PlainStructTypeEntity *>(
252 ent.get()));
253 if (!ent2->getDirectBase().isEmpty()) {
254 insertEntityDependency(
255 manager, i, ent2->getDirectBase());
257 for (auto & j: ent2->getDirectMembers()) {
258 insertTypeDependency(manager, i, j.type);
260 break;
262 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
264 rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
265 ent2(
266 static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
267 ent.get()));
268 for (auto & j: ent2->getMembers()) {
269 if (!j.parameterized) {
270 insertTypeDependency(manager, i, j.type);
273 break;
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);
286 break;
288 case unoidl::Entity::SORT_INTERFACE_TYPE:
290 rtl::Reference<unoidl::InterfaceTypeEntity> ent2(
291 static_cast<unoidl::InterfaceTypeEntity *>(
292 ent.get()));
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);
307 break;
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());
314 break;
316 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
318 rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
319 ent2(
320 static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
321 ent.get()));
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);
329 break;
331 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
333 rtl::Reference<unoidl::AccumulationBasedServiceEntity> ent2(
334 static_cast<unoidl::AccumulationBasedServiceEntity *>(
335 ent.get()));
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);
347 break;
349 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
351 rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2(
352 static_cast<unoidl::InterfaceBasedSingletonEntity *>(
353 ent.get()));
354 insertEntityDependency(manager, i, ent2->getBase());
355 break;
357 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
359 rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2(
360 static_cast<unoidl::ServiceBasedSingletonEntity *>(
361 ent.get()));
362 insertEntityDependency(manager, i, ent2->getBase());
363 break;
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);
386 void visit(
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);
405 break;
406 case Entity::Sorted::ACTIVE:
407 std::cerr
408 << "Entity " << iterator->first << " recursively depends on itself"
409 << std::endl;
410 std::exit(EXIT_FAILURE);
411 // fall-through avoids warnings
412 default:
413 break;
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);
422 return 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) {
427 std::cout << ' ';
429 for (unsigned int i = 0; i != extra; ++i) {
430 std::cout << ' ';
434 void closeModules(
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());
439 modules.pop_back();
440 indent(modules);
441 std::cout << "};\n";
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));
450 if (j == -1) {
451 closeModules(
452 modules,
453 static_cast< std::vector<OUString>::size_type >(
454 modules.end() - i));
455 indent(modules);
456 return id;
458 if (i != modules.end()) {
459 if (id == *i) {
460 ++i;
461 continue;
463 closeModules(
464 modules,
465 static_cast< std::vector<OUString>::size_type >(
466 modules.end() - i));
467 i = modules.end();
469 indent(modules);
470 std::cout << "module " << id << " {\n";
471 modules.push_back(id);
472 i = modules.end();
476 void writeName(OUString const & name) {
477 std::cout << "::" << name.replaceAll(".", "::");
480 void writeAnnotations(std::vector<OUString> const & annotations) {
481 if (!annotations.empty()) {
482 std::cout << "/**";
483 for (auto & i: annotations) {
484 //TODO: i.indexOf("*/") == -1
485 std::cout << " @" << i;
487 std::cout << " */ ";
491 void writePublished(rtl::Reference<unoidl::PublishableEntity> const & entity) {
492 assert(entity.is());
493 if (entity->isPublished()) {
494 std::cout << "published ";
498 void writeAnnotationsPublished(
499 rtl::Reference<unoidl::PublishableEntity> const & entity)
501 assert(entity.is());
502 writeAnnotations(entity->getAnnotations());
503 writePublished(entity);
506 void writeType(OUString const & type) {
507 std::size_t rank;
508 std::vector<OUString> args;
509 bool entity;
510 OUString nucl(decomposeType(type, &rank, &args, &entity));
511 for (std::size_t i = 0; i != rank; ++i) {
512 std::cout << "sequence< ";
514 if (entity) {
515 writeName(nucl);
516 } else {
517 std::cout << nucl;
519 if (!args.empty()) {
520 std::cout << "< ";
521 for (auto i(args.begin()); i != args.end(); ++i) {
522 if (i != args.begin()) {
523 std::cout << ", ";
525 writeType(*i);
527 std::cout << " >";
529 for (std::size_t i = 0; i != rank; ++i) {
530 std::cout << " >";
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()) {
539 std::cout << ", ";
541 writeName(*i);
543 std::cout << ')';
547 void writeEntity(
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)
563 std::cerr
564 << "Entity " << j << " should be an interface type"
565 << std::endl;
566 std::exit(EXIT_FAILURE);
568 writePublished(
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)
587 indent(modules, 1);
588 writeAnnotations(j->annotations);
589 std::cout << j->name << " = " << j->value;
590 if (j + 1 != ent2->getMembers().end()) {
591 std::cout << ',';
593 std::cout << '\n';
595 indent(modules);
596 std::cout << "};\n";
597 break;
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()) {
606 std::cout << ": ";
607 writeName(ent2->getDirectBase());
609 std::cout << " {\n";
610 for (auto & j: ent2->getDirectMembers()) {
611 indent(modules, 1);
612 writeAnnotations(j.annotations);
613 writeType(j.type);
614 std::cout << ' ' << j.name << ";\n";
616 indent(modules);
617 std::cout << "};\n";
618 break;
620 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
622 rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
623 ent2(
624 static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
625 ent.get()));
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()) {
632 std::cout << ", ";
634 std::cout << *j;
636 std::cout << "> {\n";
637 for (auto & j: ent2->getMembers()) {
638 indent(modules, 1);
639 writeAnnotations(j.annotations);
640 if (j.parameterized) {
641 std::cout << j.type;
642 } else {
643 writeType(j.type);
645 std::cout << ' ' << j.name << ";\n";
647 indent(modules);
648 std::cout << "};\n";
649 break;
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()) {
658 std::cout << ": ";
659 writeName(ent2->getDirectBase());
661 std::cout << " {\n";
662 for (auto & j: ent2->getDirectMembers()) {
663 indent(modules, 1);
664 writeAnnotations(j.annotations);
665 writeType(j.type);
666 std::cout << ' ' << j.name << ";\n";
668 indent(modules);
669 std::cout << "};\n";
670 break;
672 case unoidl::Entity::SORT_INTERFACE_TYPE:
674 rtl::Reference<unoidl::InterfaceTypeEntity> ent2(
675 static_cast<unoidl::InterfaceTypeEntity *>(
676 ent.get()));
677 writeAnnotationsPublished(ent);
678 std::cout << "interface " << id << " {\n";
679 for (auto & j: ent2->getDirectMandatoryBases()) {
680 indent(modules, 1);
681 writeAnnotations(j.annotations);
682 std::cout << "interface ";
683 writeName(j.name);
684 std::cout << ";\n";
686 for (auto & j: ent2->getDirectOptionalBases()) {
687 indent(modules, 1);
688 writeAnnotations(j.annotations);
689 std::cout << "[optional] interface ";
690 writeName(j.name);
691 std::cout << ";\n";
693 for (auto & j: ent2->getDirectAttributes()) {
694 indent(modules, 1);
695 writeAnnotations(j.annotations);
696 std::cout << "[attribute";
697 if (j.bound) {
698 std::cout << ", bound";
700 if (j.readOnly) {
701 std::cout << ", readonly";
703 std::cout << "] ";
704 writeType(j.type);
705 std::cout << ' ' << j.name;
706 if (!(j.getExceptions.empty() && j.setExceptions.empty())) {
707 std::cout << " {\n";
708 if (!j.getExceptions.empty()) {
709 indent(modules, 2);
710 std::cout << "get";
711 writeExceptionSpecification(j.getExceptions);
712 std::cout << ";\n";
714 if (!j.setExceptions.empty()) {
715 indent(modules, 2);
716 std::cout << "set";
717 writeExceptionSpecification(j.setExceptions);
718 std::cout << ";\n";
720 std::cout << " }";
722 std::cout << ";\n";
724 for (auto & j: ent2->getDirectMethods()) {
725 indent(modules, 1);
726 writeAnnotations(j.annotations);
727 writeType(j.returnType);
728 std::cout << ' ' << j.name << '(';
729 for (auto k(j.parameters.begin()); k != j.parameters.end();
730 ++k)
732 if (k != j.parameters.begin()) {
733 std::cout << ", ";
735 switch (k->direction) {
736 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN:
737 std::cout << "[in] ";
738 break;
739 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT:
740 std::cout << "[out] ";
741 break;
742 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT:
743 std::cout << "[inout] ";
744 break;
746 writeType(k->type);
747 std::cout << ' ' << k->name;
749 std::cout << ')';
750 writeExceptionSpecification(j.exceptions);
751 std::cout << ";\n";
753 indent(modules);
754 std::cout << "};\n";
755 break;
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";
765 break;
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()) {
774 indent(modules, 1);
775 writeAnnotations(j.annotations);
776 std::cout << "const ";
777 switch (j.value.type) {
778 case unoidl::ConstantValue::TYPE_BOOLEAN:
779 std::cout << "boolean";
780 break;
781 case unoidl::ConstantValue::TYPE_BYTE:
782 std::cout << "byte";
783 break;
784 case unoidl::ConstantValue::TYPE_SHORT:
785 std::cout << "short";
786 break;
787 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
788 std::cout << "unsigned short";
789 break;
790 case unoidl::ConstantValue::TYPE_LONG:
791 std::cout << "long";
792 break;
793 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
794 std::cout << "unsigned long";
795 break;
796 case unoidl::ConstantValue::TYPE_HYPER:
797 std::cout << "hyper";
798 break;
799 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
800 std::cout << "unsigned hyper";
801 break;
802 case unoidl::ConstantValue::TYPE_FLOAT:
803 std::cout << "float";
804 break;
805 case unoidl::ConstantValue::TYPE_DOUBLE:
806 std::cout << "double";
807 break;
809 std::cout << ' ' << j.name << " = ";
810 switch (j.value.type) {
811 case unoidl::ConstantValue::TYPE_BOOLEAN:
812 std::cout << (j.value.booleanValue ? "TRUE" : "FALSE");
813 break;
814 case unoidl::ConstantValue::TYPE_BYTE:
815 std::cout << int(j.value.byteValue);
816 break;
817 case unoidl::ConstantValue::TYPE_SHORT:
818 std::cout << j.value.shortValue;
819 break;
820 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
821 std::cout << j.value.unsignedShortValue;
822 break;
823 case unoidl::ConstantValue::TYPE_LONG:
824 std::cout << j.value.longValue;
825 break;
826 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
827 std::cout << j.value.unsignedLongValue;
828 break;
829 case unoidl::ConstantValue::TYPE_HYPER:
830 std::cout << j.value.hyperValue;
831 break;
832 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
833 std::cout << j.value.unsignedHyperValue;
834 break;
835 case unoidl::ConstantValue::TYPE_FLOAT:
836 std::cout << j.value.floatValue;
837 break;
838 case unoidl::ConstantValue::TYPE_DOUBLE:
839 std::cout << j.value.doubleValue;
840 break;
842 std::cout << ";\n";
844 indent(modules);
845 std::cout << "};\n";
846 break;
848 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
850 rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity> ent2(
851 static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
852 ent.get()));
853 writeAnnotationsPublished(ent);
854 std::cout << "service " << id << ": ";
855 writeName(ent2->getBase());
856 if (ent2->getConstructors().size() != 1
857 || !ent2->getConstructors().front().defaultConstructor)
859 std::cout << " {\n";
860 for (auto & j: ent2->getConstructors()) {
861 indent(modules, 1);
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()) {
868 std::cout << ", ";
870 std::cout << "[in] ";
871 writeType(k->type);
872 if (k->rest) {
873 std::cout << "...";
875 std::cout << ' ' << k->name;
877 std::cout << ')';
878 writeExceptionSpecification(j.exceptions);
879 std::cout << ";\n";
881 indent(modules);
882 std::cout << '}';
884 std::cout << ";\n";
885 break;
887 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
889 rtl::Reference<unoidl::AccumulationBasedServiceEntity> ent2(
890 static_cast<unoidl::AccumulationBasedServiceEntity *>(
891 ent.get()));
892 writeAnnotationsPublished(ent);
893 std::cout << "service " << id << " {\n";
894 for (auto & j: ent2->getDirectMandatoryBaseServices()) {
895 indent(modules, 1);
896 writeAnnotations(j.annotations);
897 std::cout << "service ";
898 writeName(j.name);
899 std::cout << ";\n";
901 for (auto & j: ent2->getDirectOptionalBaseServices()) {
902 indent(modules, 1);
903 writeAnnotations(j.annotations);
904 std::cout << "[optional] service ";
905 writeName(j.name);
906 std::cout << ";\n";
908 for (auto & j: ent2->getDirectMandatoryBaseInterfaces()) {
909 indent(modules, 1);
910 writeAnnotations(j.annotations);
911 std::cout << "interface ";
912 writeName(j.name);
913 std::cout << ";\n";
915 for (auto & j: ent2->getDirectOptionalBaseInterfaces()) {
916 indent(modules, 1);
917 writeAnnotations(j.annotations);
918 std::cout << "[optional] interface ";
919 writeName(j.name);
920 std::cout << ";\n";
922 for (auto & j: ent2->getDirectProperties()) {
923 indent(modules, 1);
924 writeAnnotations(j.annotations);
925 std::cout << "[property";
926 if ((j.attributes
927 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_BOUND)
928 != 0)
930 std::cout << ", bound";
932 if ((j.attributes
933 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED)
934 != 0)
936 std::cout << ", constrained";
938 if ((j.attributes
939 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_AMBIGUOUS)
940 != 0)
942 std::cout << ", maybeambiguous";
944 if ((j.attributes
945 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_DEFAULT)
946 != 0)
948 std::cout << ", maybedefault";
950 if ((j.attributes
951 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_VOID)
952 != 0)
954 std::cout << ", maybevoid";
956 if ((j.attributes
957 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL)
958 != 0)
960 std::cout << ", optional";
962 if ((j.attributes
963 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_READ_ONLY)
964 != 0)
966 std::cout << ", readonly";
968 if ((j.attributes
969 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_REMOVABLE)
970 != 0)
972 std::cout << ", removable";
974 if ((j.attributes
975 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_TRANSIENT)
976 != 0)
978 std::cout << ", transient";
980 std::cout << "] ";
981 writeType(j.type);
982 std::cout << ' ' << j.name << ";\n";
984 indent(modules);
985 std::cout << "};\n";
986 break;
988 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
990 rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2(
991 static_cast<unoidl::InterfaceBasedSingletonEntity *>(
992 ent.get()));
993 writeAnnotationsPublished(ent);
994 std::cout << "singleton " << id << ": ";
995 writeName(ent2->getBase());
996 std::cout << ";\n";
997 break;
999 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
1001 rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2(
1002 static_cast<unoidl::ServiceBasedSingletonEntity *>(
1003 ent.get()));
1004 writeAnnotationsPublished(ent);
1005 std::cout << "singleton " << id << " { service ";
1006 writeName(ent2->getBase());
1007 std::cout << "; };";
1008 break;
1010 case unoidl::Entity::SORT_MODULE:
1011 assert(false && "this cannot happen");
1018 SAL_IMPLEMENT_MAIN() {
1019 try {
1020 sal_uInt32 args = rtl_getAppCommandArgCount();
1021 if (args == 0) {
1022 badUsage();
1024 OUString arg;
1025 rtl_getAppCommandArg(0, &arg.pData);
1026 bool published = arg == "--published";
1027 if (published && args == 1) {
1028 badUsage();
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));
1034 try {
1035 prov = mgr->addProvider(uri);
1036 } catch (unoidl::NoSuchFileException &) {
1037 std::cerr
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) {
1052 std::cerr
1053 << "Bad input <" << e1.getUri() << ">: " << e1.getDetail()
1054 << std::endl;
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: */