LibreOffice Module unoidl (master) 1
unoidl-read.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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 */
9
10#include <sal/config.h>
11
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>
20
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>
29#include <o3tl/string_view.hxx>
30
31namespace {
32
33void badUsage() {
34 std::cerr
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,"
39 " a single .idl")
40 << std::endl
41 << ("file, or a root directory of an .idl file tree. The complete"
42 " content of the")
43 << std::endl
44 << ("last <registry> is written to stdout; if --published is specified,"
45 " only the")
46 << std::endl
47 << ("published entities (plus any non-published entities referenced"
48 " from published")
49 << std::endl
50 << "via any unpublished optional bases) are written out. If --summary is specified,"
51 << std::endl
52 << "only a short summary is written, with the type and name of one entity per line."
53 << std::endl;
54 std::exit(EXIT_FAILURE);
55}
56
57OUString getArgumentUri(sal_uInt32 argument) {
58 OUString arg;
59 rtl_getAppCommandArg(argument, &arg.pData);
60 OUString url;
61 osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
62 if (e1 != osl::FileBase::E_None) {
63 std::cerr
64 << "Cannot convert \"" << arg << "\" to file URL, error code "
65 << +e1 << std::endl;
66 std::exit(EXIT_FAILURE);
67 }
68 OUString cwd;
69 oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData);
70 if (e2 != osl_Process_E_None) {
71 std::cerr
72 << "Cannot obtain working directory, error code " << +e2
73 << std::endl;
74 std::exit(EXIT_FAILURE);
75 }
76 OUString abs;
77 e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
78 if (e1 != osl::FileBase::E_None) {
79 std::cerr
80 << "Cannot make \"" << url
81 << "\" into an absolute file URL, error code " << +e1 << std::endl;
82 std::exit(EXIT_FAILURE);
83 }
84 return abs;
85}
86
87std::u16string_view decomposeType(
88 std::u16string_view type, std::size_t * rank,
89 std::vector<OUString> * typeArguments, bool * entity)
90{
91 assert(rank != nullptr);
92 assert(typeArguments != nullptr);
93 assert(entity != nullptr);
94 std::u16string_view nucl(type);
95 *rank = 0;
96 typeArguments->clear();
97 while (o3tl::starts_with(nucl, u"[]", &nucl)) {
98 ++*rank;
99 }
100 size_t i = nucl.find('<');
101 if (i != std::u16string_view::npos) {
102 std::u16string_view tmpl(nucl.substr(0, i));
103 do {
104 ++i; // skip '<' or ','
105 size_t j = i;
106 for (size_t level = 0; j != nucl.size(); ++j) {
107 sal_Unicode c = nucl[j];
108 if (c == ',') {
109 if (level == 0) {
110 break;
111 }
112 } else if (c == '<') {
113 ++level;
114 } else if (c == '>') {
115 if (level == 0) {
116 break;
117 }
118 --level;
119 }
120 }
121 if (j != nucl.size()) {
122 typeArguments->push_back(OUString(nucl.substr(i, j - i)));
123 }
124 i = j;
125 } while (i != nucl.size() && nucl[i] != '>');
126 assert(i == nucl.size() - 1 && nucl[i] == '>');
127 assert(!typeArguments->empty());
128 nucl = tmpl;
129 }
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"
136 && nucl != u"any";
137 assert(*entity || typeArguments->empty());
138 return nucl;
139}
140
141struct Entity {
142 enum class Sorted { NO, ACTIVE, YES };
143 enum class Written { NO, DECLARATION, DEFINITION };
144
145 explicit Entity(
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)
149 {}
150
152 std::set<OUString> dependencies;
153 std::set<OUString> interfaceDependencies;
154 bool relevant;
155 Sorted sorted;
156 Written written;
157 Entity * parent;
158};
159
160void insertEntityDependency(
161 rtl::Reference<unoidl::Manager> const & manager,
162 std::map<OUString, Entity>::iterator const & iterator,
163 OUString const & name, bool weakInterfaceDependency = false)
164{
165 assert(manager.is());
166 if (name == iterator->first)
167 return;
168
169 bool ifc = false;
170 if (weakInterfaceDependency) {
171 rtl::Reference<unoidl::Entity> ent(manager->findEntity(name));
172 if (!ent.is()) {
173 std::cerr << "Unknown entity " << name << std::endl;
174 std::exit(EXIT_FAILURE);
175 }
176 ifc = ent->getSort() == unoidl::Entity::SORT_INTERFACE_TYPE;
177 }
178 (ifc
179 ? iterator->second.interfaceDependencies
180 : iterator->second.dependencies)
181 .insert(name);
182}
183
184void insertEntityDependencies(
185 rtl::Reference<unoidl::Manager> const & manager,
186 std::map<OUString, Entity>::iterator const & iterator,
187 std::vector<OUString> const & names)
188{
189 for (auto & i: names) {
190 insertEntityDependency(manager, iterator, i);
191 }
192}
193
194void insertEntityDependencies(
195 rtl::Reference<unoidl::Manager> const & manager,
196 std::map<OUString, Entity>::iterator const & iterator,
197 std::vector<unoidl::AnnotatedReference> const & references)
198{
199 for (auto & i: references) {
200 insertEntityDependency(manager, iterator, i.name);
201 }
202}
203
204void insertTypeDependency(
205 rtl::Reference<unoidl::Manager> const & manager,
206 std::map<OUString, Entity>::iterator const & iterator,
207 std::u16string_view type)
208{
209 std::size_t rank;
210 std::vector<OUString> args;
211 bool entity;
212 OUString nucl(decomposeType(type, &rank, &args, &entity));
213 if (entity) {
214 insertEntityDependency(manager, iterator, nucl, true);
215 for (const auto & i: args) {
216 insertTypeDependency(manager, iterator, i);
217 }
218 }
219}
220
221void scanMap(
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)
225{
226 assert(cursor.is());
227 for (;;) {
228 OUString id;
229 rtl::Reference<unoidl::Entity> ent(cursor->getNext(&id));
230 if (!ent.is()) {
231 break;
232 }
233 OUString name(prefix + id);
234 if (ent->getSort() == unoidl::Entity::SORT_MODULE) {
235 Entity * p = nullptr;
236 if (modules) {
237 p = &entities.insert(std::make_pair(name, Entity(ent, !published, parent))).first
238 ->second;
239 }
240 scanMap(
241 manager,
242 static_cast<unoidl::ModuleEntity *>(ent.get())->createCursor(), modules,
243 published, Concat2View(name + "."), p, entities);
244 } else {
245 auto const pub = static_cast<unoidl::PublishableEntity *>(ent.get())->isPublished();
246 std::map<OUString, Entity>::iterator i(
247 entities.insert(
248 std::make_pair(
249 name,
250 Entity(
251 ent,
252 (!published
253 || pub),
254 parent)))
255 .first);
256 if (modules && published && pub) {
257 for (auto j = parent; j; j = j->parent) {
258 j->relevant = true;
259 }
260 }
261 switch (ent->getSort()) {
264 break;
266 {
268 static_cast<unoidl::PlainStructTypeEntity *>(
269 ent.get()));
270 if (!ent2->getDirectBase().isEmpty()) {
271 insertEntityDependency(
272 manager, i, ent2->getDirectBase());
273 }
274 for (auto & j: ent2->getDirectMembers()) {
275 insertTypeDependency(manager, i, j.type);
276 }
277 break;
278 }
280 {
282 ent2(
284 ent.get()));
285 for (auto & j: ent2->getMembers()) {
286 if (!j.parameterized) {
287 insertTypeDependency(manager, i, j.type);
288 }
289 }
290 break;
291 }
293 {
295 static_cast<unoidl::ExceptionTypeEntity *>(ent.get()));
296 if (!ent2->getDirectBase().isEmpty()) {
297 insertEntityDependency(
298 manager, i, ent2->getDirectBase());
299 }
300 for (auto & j: ent2->getDirectMembers()) {
301 insertTypeDependency(manager, i, j.type);
302 }
303 break;
304 }
306 {
308 static_cast<unoidl::InterfaceTypeEntity *>(
309 ent.get()));
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);
316 }
317 for (auto & j: ent2->getDirectMethods()) {
318 insertTypeDependency(manager, i, j.returnType);
319 for (auto & k: j.parameters) {
320 insertTypeDependency(manager, i, k.type);
321 }
322 insertEntityDependencies(manager, i, j.exceptions);
323 }
324 break;
325 }
327 {
329 static_cast<unoidl::TypedefEntity *>(ent.get()));
330 insertTypeDependency(manager, i, ent2->getType());
331 break;
332 }
334 {
336 ent2(
338 ent.get()));
339 insertEntityDependency(manager, i, ent2->getBase());
340 for (auto & j: ent2->getConstructors()) {
341 for (auto & k: j.parameters) {
342 insertTypeDependency(manager, i, k.type);
343 }
344 insertEntityDependencies(manager, i, j.exceptions);
345 }
346 break;
347 }
349 {
352 ent.get()));
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);
363 }
364 break;
365 }
367 {
370 ent.get()));
371 insertEntityDependency(manager, i, ent2->getBase());
372 break;
373 }
375 {
378 ent.get()));
379 insertEntityDependency(manager, i, ent2->getBase());
380 break;
381 }
383 assert(false && "this cannot happen");
384 }
385 }
386 }
387}
388
389void 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);
397 }
398 }
399 }
400 }
401}
402
403void visit(
404 std::map<OUString, Entity> & entities,
405 std::map<OUString, Entity>::iterator const & iterator,
406 std::vector<OUString> & result)
407{
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);
416 }
417 visit(entities, j, result);
418 }
419 }
420 iterator->second.sorted = Entity::Sorted::YES;
421 result.push_back(iterator->first);
422 break;
423 case Entity::Sorted::ACTIVE:
424 std::cerr
425 << "Entity " << iterator->first << " recursively depends on itself"
426 << std::endl;
427 std::exit(EXIT_FAILURE);
428 // fall-through avoids warnings
429 default:
430 break;
431 }
432}
433
434std::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);
438 }
439 return res;
440}
441
442void indent(std::vector<OUString> const & modules, unsigned int extra = 0) {
443 for (std::vector<OUString>::size_type i = 0; i != modules.size(); ++i) {
444 std::cout << ' ';
445 }
446 for (unsigned int i = 0; i != extra; ++i) {
447 std::cout << ' ';
448 }
449}
450
451void closeModules(
452 std::vector<OUString> & modules, std::vector<OUString>::size_type n)
453{
454 for (std::vector<OUString>::size_type i = 0; i != n; ++i) {
455 assert(!modules.empty());
456 modules.pop_back();
457 indent(modules);
458 std::cout << "};\n";
459 }
460}
461
462OUString openModulesFor(std::vector<OUString> & modules, std::u16string_view name)
463{
464 std::vector<OUString>::iterator i(modules.begin());
465 for (sal_Int32 j = 0;;) {
466 OUString id(o3tl::getToken(name, 0, '.', j));
467 if (j == -1) {
468 closeModules(
469 modules,
470 static_cast< std::vector<OUString>::size_type >(
471 modules.end() - i));
472 indent(modules);
473 return id;
474 }
475 if (i != modules.end()) {
476 if (id == *i) {
477 ++i;
478 continue;
479 }
480 closeModules(
481 modules,
482 static_cast< std::vector<OUString>::size_type >(
483 modules.end() - i));
484 i = modules.end();
485 }
486 indent(modules);
487 std::cout << "module " << id << " {\n";
488 modules.push_back(id);
489 i = modules.end();
490 }
491}
492
493void writeName(OUString const & name) {
494 std::cout << "::" << name.replaceAll(".", "::");
495}
496
497void writeAnnotations(std::vector<OUString> const & annotations) {
498 if (!annotations.empty()) {
499 std::cout << "/**";
500 for (auto & i: annotations) {
501 //TODO: i.indexOf("*/") == -1
502 std::cout << " @" << i;
503 }
504 std::cout << " */ ";
505 }
506}
507
508void writePublished(rtl::Reference<unoidl::PublishableEntity> const & entity) {
509 assert(entity.is());
510 if (entity->isPublished()) {
511 std::cout << "published ";
512 }
513}
514
515void writeAnnotationsPublished(
517{
518 assert(entity.is());
519 writeAnnotations(entity->getAnnotations());
520 writePublished(entity);
521}
522
523void writeType(std::u16string_view type) {
524 std::size_t rank;
525 std::vector<OUString> args;
526 bool entity;
527 OUString nucl(decomposeType(type, &rank, &args, &entity));
528 for (std::size_t i = 0; i != rank; ++i) {
529 std::cout << "sequence< ";
530 }
531 if (entity) {
532 writeName(nucl);
533 } else {
534 std::cout << nucl;
535 }
536 if (!args.empty()) {
537 std::cout << "< ";
538 for (auto i(args.begin()); i != args.end(); ++i) {
539 if (i != args.begin()) {
540 std::cout << ", ";
541 }
542 writeType(*i);
543 }
544 std::cout << " >";
545 }
546 for (std::size_t i = 0; i != rank; ++i) {
547 std::cout << " >";
548 }
549}
550
551void 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()) {
556 std::cout << ", ";
557 }
558 writeName(*i);
559 }
560 std::cout << ')';
561 }
562}
563
564void writeEntity(
565 std::map<OUString, Entity> & entities, std::vector<OUString> & modules,
566 OUString const & name)
567{
568 std::map<OUString, Entity>::iterator i(entities.find(name));
569 if (i == entities.end() || !i->second.relevant)
570 return;
571
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()
581 {
582 std::cerr
583 << "Entity " << j << " should be an interface type"
584 << std::endl;
585 std::exit(EXIT_FAILURE);
586 }
587 writePublished(
588 static_cast<unoidl::PublishableEntity *>(
589 k->second.entity.get()));
590 std::cout << "interface " << id << ";\n";
591 }
592 }
593 OUString id(openModulesFor(modules, name));
595 static_cast<unoidl::PublishableEntity *>(i->second.entity.get()));
596 switch (ent->getSort()) {
598 {
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)
605 {
606 indent(modules, 1);
607 writeAnnotations(j->annotations);
608 std::cout << j->name << " = " << j->value;
609 if (j + 1 != ent2->getMembers().end()) {
610 std::cout << ',';
611 }
612 std::cout << '\n';
613 }
614 indent(modules);
615 std::cout << "};\n";
616 break;
617 }
619 {
621 static_cast<unoidl::PlainStructTypeEntity *>(ent.get()));
622 writeAnnotationsPublished(ent);
623 std::cout << "struct " << id;
624 if (!ent2->getDirectBase().isEmpty()) {
625 std::cout << ": ";
626 writeName(ent2->getDirectBase());
627 }
628 std::cout << " {\n";
629 for (auto & j: ent2->getDirectMembers()) {
630 indent(modules, 1);
631 writeAnnotations(j.annotations);
632 writeType(j.type);
633 std::cout << ' ' << j.name << ";\n";
634 }
635 indent(modules);
636 std::cout << "};\n";
637 break;
638 }
640 {
642 ent2(
644 ent.get()));
645 writeAnnotationsPublished(ent);
646 std::cout << "struct " << id << '<';
647 for (auto j(ent2->getTypeParameters().begin());
648 j != ent2->getTypeParameters().end(); ++j)
649 {
650 if (j != ent2->getTypeParameters().begin()) {
651 std::cout << ", ";
652 }
653 std::cout << *j;
654 }
655 std::cout << "> {\n";
656 for (auto & j: ent2->getMembers()) {
657 indent(modules, 1);
658 writeAnnotations(j.annotations);
659 if (j.parameterized) {
660 std::cout << j.type;
661 } else {
662 writeType(j.type);
663 }
664 std::cout << ' ' << j.name << ";\n";
665 }
666 indent(modules);
667 std::cout << "};\n";
668 break;
669 }
671 {
673 static_cast<unoidl::ExceptionTypeEntity *>(ent.get()));
674 writeAnnotationsPublished(ent);
675 std::cout << "exception " << id;
676 if (!ent2->getDirectBase().isEmpty()) {
677 std::cout << ": ";
678 writeName(ent2->getDirectBase());
679 }
680 std::cout << " {\n";
681 for (auto & j: ent2->getDirectMembers()) {
682 indent(modules, 1);
683 writeAnnotations(j.annotations);
684 writeType(j.type);
685 std::cout << ' ' << j.name << ";\n";
686 }
687 indent(modules);
688 std::cout << "};\n";
689 break;
690 }
692 {
694 static_cast<unoidl::InterfaceTypeEntity *>(
695 ent.get()));
696 writeAnnotationsPublished(ent);
697 std::cout << "interface " << id << " {\n";
698 for (auto & j: ent2->getDirectMandatoryBases()) {
699 indent(modules, 1);
700 writeAnnotations(j.annotations);
701 std::cout << "interface ";
702 writeName(j.name);
703 std::cout << ";\n";
704 }
705 for (auto & j: ent2->getDirectOptionalBases()) {
706 indent(modules, 1);
707 writeAnnotations(j.annotations);
708 std::cout << "[optional] interface ";
709 writeName(j.name);
710 std::cout << ";\n";
711 }
712 for (auto & j: ent2->getDirectAttributes()) {
713 indent(modules, 1);
714 writeAnnotations(j.annotations);
715 std::cout << "[attribute";
716 if (j.bound) {
717 std::cout << ", bound";
718 }
719 if (j.readOnly) {
720 std::cout << ", readonly";
721 }
722 std::cout << "] ";
723 writeType(j.type);
724 std::cout << ' ' << j.name;
725 if (!(j.getExceptions.empty() && j.setExceptions.empty())) {
726 std::cout << " {\n";
727 if (!j.getExceptions.empty()) {
728 indent(modules, 2);
729 std::cout << "get";
730 writeExceptionSpecification(j.getExceptions);
731 std::cout << ";\n";
732 }
733 if (!j.setExceptions.empty()) {
734 indent(modules, 2);
735 std::cout << "set";
736 writeExceptionSpecification(j.setExceptions);
737 std::cout << ";\n";
738 }
739 std::cout << " }";
740 }
741 std::cout << ";\n";
742 }
743 for (auto & j: ent2->getDirectMethods()) {
744 indent(modules, 1);
745 writeAnnotations(j.annotations);
746 writeType(j.returnType);
747 std::cout << ' ' << j.name << '(';
748 for (auto k(j.parameters.begin()); k != j.parameters.end();
749 ++k)
750 {
751 if (k != j.parameters.begin()) {
752 std::cout << ", ";
753 }
754 switch (k->direction) {
756 std::cout << "[in] ";
757 break;
759 std::cout << "[out] ";
760 break;
762 std::cout << "[inout] ";
763 break;
764 }
765 writeType(k->type);
766 std::cout << ' ' << k->name;
767 }
768 std::cout << ')';
769 writeExceptionSpecification(j.exceptions);
770 std::cout << ";\n";
771 }
772 indent(modules);
773 std::cout << "};\n";
774 break;
775 }
777 {
779 static_cast<unoidl::TypedefEntity *>(ent.get()));
780 writeAnnotationsPublished(ent);
781 std::cout << "typedef ";
782 writeType(ent2->getType());
783 std::cout << ' ' << id << ";\n";
784 break;
785 }
787 {
789 static_cast<unoidl::ConstantGroupEntity *>(ent.get()));
790 writeAnnotationsPublished(ent);
791 std::cout << "constants " << id << " {\n";
792 for (auto & j: ent2->getMembers()) {
793 indent(modules, 1);
794 writeAnnotations(j.annotations);
795 std::cout << "const ";
796 switch (j.value.type) {
798 std::cout << "boolean";
799 break;
801 std::cout << "byte";
802 break;
804 std::cout << "short";
805 break;
807 std::cout << "unsigned short";
808 break;
810 std::cout << "long";
811 break;
813 std::cout << "unsigned long";
814 break;
816 std::cout << "hyper";
817 break;
819 std::cout << "unsigned hyper";
820 break;
822 std::cout << "float";
823 break;
825 std::cout << "double";
826 break;
827 }
828 std::cout << ' ' << j.name << " = ";
829 switch (j.value.type) {
831 std::cout << (j.value.booleanValue ? "TRUE" : "FALSE");
832 break;
834 std::cout << int(j.value.byteValue);
835 break;
837 std::cout << j.value.shortValue;
838 break;
840 std::cout << j.value.unsignedShortValue;
841 break;
843 std::cout << j.value.longValue;
844 break;
846 std::cout << j.value.unsignedLongValue;
847 break;
849 std::cout << j.value.hyperValue;
850 break;
852 std::cout << j.value.unsignedHyperValue;
853 break;
855 std::cout << j.value.floatValue;
856 break;
858 std::cout << j.value.doubleValue;
859 break;
860 }
861 std::cout << ";\n";
862 }
863 indent(modules);
864 std::cout << "};\n";
865 break;
866 }
868 {
871 ent.get()));
872 writeAnnotationsPublished(ent);
873 std::cout << "service " << id << ": ";
874 writeName(ent2->getBase());
875 if (ent2->getConstructors().size() != 1
876 || !ent2->getConstructors().front().defaultConstructor)
877 {
878 std::cout << " {\n";
879 for (auto & j: ent2->getConstructors()) {
880 indent(modules, 1);
881 writeAnnotations(j.annotations);
882 std::cout << j.name << '(';
883 for (auto k(j.parameters.begin());
884 k != j.parameters.end(); ++k)
885 {
886 if (k != j.parameters.begin()) {
887 std::cout << ", ";
888 }
889 std::cout << "[in] ";
890 writeType(k->type);
891 if (k->rest) {
892 std::cout << "...";
893 }
894 std::cout << ' ' << k->name;
895 }
896 std::cout << ')';
897 writeExceptionSpecification(j.exceptions);
898 std::cout << ";\n";
899 }
900 indent(modules);
901 std::cout << '}';
902 }
903 std::cout << ";\n";
904 break;
905 }
907 {
910 ent.get()));
911 writeAnnotationsPublished(ent);
912 std::cout << "service " << id << " {\n";
913 for (auto & j: ent2->getDirectMandatoryBaseServices()) {
914 indent(modules, 1);
915 writeAnnotations(j.annotations);
916 std::cout << "service ";
917 writeName(j.name);
918 std::cout << ";\n";
919 }
920 for (auto & j: ent2->getDirectOptionalBaseServices()) {
921 indent(modules, 1);
922 writeAnnotations(j.annotations);
923 std::cout << "[optional] service ";
924 writeName(j.name);
925 std::cout << ";\n";
926 }
927 for (auto & j: ent2->getDirectMandatoryBaseInterfaces()) {
928 indent(modules, 1);
929 writeAnnotations(j.annotations);
930 std::cout << "interface ";
931 writeName(j.name);
932 std::cout << ";\n";
933 }
934 for (auto & j: ent2->getDirectOptionalBaseInterfaces()) {
935 indent(modules, 1);
936 writeAnnotations(j.annotations);
937 std::cout << "[optional] interface ";
938 writeName(j.name);
939 std::cout << ";\n";
940 }
941 for (auto & j: ent2->getDirectProperties()) {
942 indent(modules, 1);
943 writeAnnotations(j.annotations);
944 std::cout << "[property";
945 if ((j.attributes
947 != 0)
948 {
949 std::cout << ", bound";
950 }
951 if ((j.attributes
953 != 0)
954 {
955 std::cout << ", constrained";
956 }
957 if ((j.attributes
959 != 0)
960 {
961 std::cout << ", maybeambiguous";
962 }
963 if ((j.attributes
965 != 0)
966 {
967 std::cout << ", maybedefault";
968 }
969 if ((j.attributes
971 != 0)
972 {
973 std::cout << ", maybevoid";
974 }
975 if ((j.attributes
977 != 0)
978 {
979 std::cout << ", optional";
980 }
981 if ((j.attributes
983 != 0)
984 {
985 std::cout << ", readonly";
986 }
987 if ((j.attributes
989 != 0)
990 {
991 std::cout << ", removable";
992 }
993 if ((j.attributes
995 != 0)
996 {
997 std::cout << ", transient";
998 }
999 std::cout << "] ";
1000 writeType(j.type);
1001 std::cout << ' ' << j.name << ";\n";
1002 }
1003 indent(modules);
1004 std::cout << "};\n";
1005 break;
1006 }
1008 {
1011 ent.get()));
1012 writeAnnotationsPublished(ent);
1013 std::cout << "singleton " << id << ": ";
1014 writeName(ent2->getBase());
1015 std::cout << ";\n";
1016 break;
1017 }
1019 {
1022 ent.get()));
1023 writeAnnotationsPublished(ent);
1024 std::cout << "singleton " << id << " { service ";
1025 writeName(ent2->getBase());
1026 std::cout << "; };";
1027 break;
1028 }
1030 assert(false && "this cannot happen");
1031 }
1032}
1033
1034void writeSummary(OUString const & name, Entity const & entity) {
1035 if (!entity.relevant) {
1036 return;
1037 }
1038 switch (entity.entity->getSort()) {
1040 std::cout << "enum";
1041 break;
1044 std::cout << "struct";
1045 break;
1047 std::cout << "exception";
1048 break;
1050 std::cout << "interface";
1051 break;
1053 std::cout << "typedef";
1054 break;
1056 std::cout << "constants";
1057 break;
1060 std::cout << "service";
1061 break;
1064 std::cout << "singleton";
1065 break;
1067 std::cout << "module";
1068 break;
1069 }
1070 std::cout << ' ' << name << '\n';
1071}
1072
1073}
1074
1076 try {
1077 sal_uInt32 args = rtl_getAppCommandArgCount();
1078 sal_uInt32 i = 0;
1079 bool published = false;
1080 bool summary = false;
1081 for (;; ++i) {
1082 if (i == args) {
1083 badUsage();
1084 }
1085 OUString arg;
1086 rtl_getAppCommandArg(i, &arg.pData);
1087 if (arg == "--published") {
1088 if (published) {
1089 badUsage();
1090 }
1091 published = true;
1092 } else if (arg == "--summary") {
1093 if (summary) {
1094 badUsage();
1095 }
1096 summary = true;
1097 } else {
1098 break;
1099 }
1100 }
1103 for (; i != args; ++i) {
1104 OUString uri(getArgumentUri(i));
1105 try {
1106 prov = mgr->addProvider(uri);
1107 } catch (unoidl::NoSuchFileException &) {
1108 std::cerr
1109 << "Input <" << uri << "> does not exist" << std::endl;
1110 std::exit(EXIT_FAILURE);
1111 }
1112 }
1113 std::map<OUString, Entity> ents;
1114 scanMap(mgr, prov->createRootCursor(), summary, published, u"", nullptr, ents);
1115 if (summary) {
1116 for (auto const & j: ents) {
1117 writeSummary(j.first, j.second);
1118 }
1119 } else {
1120 std::vector<OUString> sorted(sort(ents));
1121 std::vector<OUString> mods;
1122 for (const auto & j: sorted) {
1123 writeEntity(ents, mods, j);
1124 }
1125 closeModules(mods, mods.size());
1126 }
1127 return EXIT_SUCCESS;
1128 } catch (unoidl::FileFormatException & e1) {
1129 std::cerr
1130 << "Bad input <" << e1.getUri() << ">: " << e1.getDetail()
1131 << std::endl;
1132 std::exit(EXIT_FAILURE);
1133 } catch (std::exception & e1) {
1134 std::cerr << "Failure: " << e1.what() << std::endl;
1135 std::exit(EXIT_FAILURE);
1136 }
1137}
1138
1139/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
@ SORT_PLAIN_STRUCT_TYPE
Definition: unoidl.hxx:84
@ SORT_ACCUMULATION_BASED_SERVICE
Definition: unoidl.hxx:87
@ SORT_SINGLE_INTERFACE_BASED_SERVICE
Definition: unoidl.hxx:87
@ SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE
Definition: unoidl.hxx:85
@ SORT_INTERFACE_TYPE
Definition: unoidl.hxx:86
@ SORT_CONSTANT_GROUP
Definition: unoidl.hxx:86
@ SORT_EXCEPTION_TYPE
Definition: unoidl.hxx:85
@ SORT_INTERFACE_BASED_SINGLETON
Definition: unoidl.hxx:88
@ SORT_SERVICE_BASED_SINGLETON
Definition: unoidl.hxx:88
const OUString & getDetail() const
Definition: unoidl.hxx:60
const OUString & getUri() const
Definition: unoidl.hxx:58
virtual rtl::Reference< MapCursor > createCursor() const =0
rtl::Reference< ParseManager > manager
float u
const char * name
void * p
sal_Int64 n
int i
constexpr bool starts_with(std::basic_string_view< charT, traits > sv, std::basic_string_view< charT, traits > x) noexcept
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
args
SwNodeOffset abs(const SwNodeOffset &a)
const wchar_t *typedef int(__stdcall *DllNativeUnregProc)(int
sal_uInt16 sal_Unicode
Any result
SAL_IMPLEMENT_MAIN()