fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / unoidl / source / unoidl-read.cxx
blob99a202437d20f8265d01c95fea1e8926416dbd96
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 <cstddef>
14 #include <cstdlib>
15 #include <iostream>
16 #include <map>
17 #include <set>
18 #include <utility>
19 #include <vector>
21 #include "osl/file.h"
22 #include "osl/file.hxx"
23 #include "osl/process.h"
24 #include "rtl/process.h"
25 #include "rtl/ref.hxx"
26 #include "rtl/ustring.hxx"
27 #include "sal/main.h"
28 #include "sal/types.h"
29 #include "unoidl/unoidl.hxx"
31 namespace {
33 void badUsage() {
34 std::cerr
35 << "Usage:" << std::endl << std::endl
36 << " unoidl-read [--published] [<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." << std::endl;
51 std::exit(EXIT_FAILURE);
54 OUString getArgumentUri(sal_uInt32 argument) {
55 OUString arg;
56 rtl_getAppCommandArg(argument, &arg.pData);
57 OUString url;
58 osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
59 if (e1 != osl::FileBase::E_None) {
60 std::cerr
61 << "Cannot convert \"" << arg << "\" to file URL, error code "
62 << +e1 << std::endl;
63 std::exit(EXIT_FAILURE);
65 OUString cwd;
66 oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData);
67 if (e2 != osl_Process_E_None) {
68 std::cerr
69 << "Cannot obtain working directory, error code " << +e2
70 << std::endl;
71 std::exit(EXIT_FAILURE);
73 OUString abs;
74 e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
75 if (e1 != osl::FileBase::E_None) {
76 std::cerr
77 << "Cannot make \"" << url
78 << "\" into an absolute file URL, error code " << +e1 << std::endl;
79 std::exit(EXIT_FAILURE);
81 return abs;
84 OUString decomposeType(
85 OUString const & type, std::size_t * rank,
86 std::vector<OUString> * typeArguments, bool * entity)
88 assert(rank != 0);
89 assert(typeArguments != 0);
90 assert(entity != 0);
91 OUString nucl(type);
92 *rank = 0;
93 typeArguments->clear();
94 while (nucl.startsWith("[]", &nucl)) {
95 ++*rank;
97 sal_Int32 i = nucl.indexOf('<');
98 if (i != -1) {
99 OUString tmpl(nucl.copy(0, i));
100 do {
101 ++i; // skip '<' or ','
102 sal_Int32 j = i;
103 for (sal_Int32 level = 0; j != nucl.getLength(); ++j) {
104 sal_Unicode c = nucl[j];
105 if (c == ',') {
106 if (level == 0) {
107 break;
109 } else if (c == '<') {
110 ++level;
111 } else if (c == '>') {
112 if (level == 0) {
113 break;
115 --level;
118 if (j != nucl.getLength()) {
119 typeArguments->push_back(nucl.copy(i, j - i));
121 i = j;
122 } while (i != nucl.getLength() && nucl[i] != '>');
123 assert(i == nucl.getLength() - 1 && nucl[i] == '>');
124 assert(!typeArguments->empty());
125 nucl = tmpl;
127 assert(!nucl.isEmpty());
128 *entity = nucl != "void" && nucl != "boolean" && nucl != "byte"
129 && nucl != "short" && nucl != "unsigned short" && nucl != "long"
130 && nucl != "unsigned long" && nucl != "hyper"
131 && nucl != "unsigned hyper" && nucl != "float" && nucl != "double"
132 && nucl != "char" && nucl != "string" && nucl != "type"
133 && nucl != "any";
134 assert(*entity || typeArguments->empty());
135 return nucl;
138 struct Entity {
139 enum class Sorted { NO, ACTIVE, YES };
141 explicit Entity(
142 rtl::Reference<unoidl::Entity> const & theEntity, bool theRelevant):
143 entity(theEntity), relevant(theRelevant), sorted(Sorted::NO),
144 written(false)
147 rtl::Reference<unoidl::Entity> const entity;
148 std::set<OUString> dependencies;
149 std::set<OUString> interfaceDependencies;
150 bool relevant;
151 Sorted sorted;
152 bool 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 bool ifc = false;
163 if (weakInterfaceDependency) {
164 rtl::Reference<unoidl::Entity> ent(manager->findEntity(name));
165 if (!ent.is()) {
166 std::cerr << "Unknown entity " << name << std::endl;
167 std::exit(EXIT_FAILURE);
169 ifc = ent->getSort() == unoidl::Entity::SORT_INTERFACE_TYPE;
171 (ifc
172 ? iterator->second.interfaceDependencies
173 : iterator->second.dependencies)
174 .insert(name);
178 void insertEntityDependencies(
179 rtl::Reference<unoidl::Manager> const & manager,
180 std::map<OUString, Entity>::iterator const & iterator,
181 std::vector<OUString> const & names)
183 for (std::vector<OUString>::const_iterator i(names.begin());
184 i != names.end(); ++i)
186 insertEntityDependency(manager, iterator, *i);
190 void insertEntityDependencies(
191 rtl::Reference<unoidl::Manager> const & manager,
192 std::map<OUString, Entity>::iterator const & iterator,
193 std::vector<unoidl::AnnotatedReference> const & references)
195 for (std::vector<unoidl::AnnotatedReference>::const_iterator i(
196 references.begin());
197 i != references.end(); ++i)
199 insertEntityDependency(manager, iterator, i->name);
203 void insertTypeDependency(
204 rtl::Reference<unoidl::Manager> const & manager,
205 std::map<OUString, Entity>::iterator const & iterator,
206 OUString const & type)
208 std::size_t rank;
209 std::vector<OUString> args;
210 bool entity;
211 OUString nucl(decomposeType(type, &rank, &args, &entity));
212 if (entity) {
213 insertEntityDependency(manager, iterator, nucl, true);
214 for (std::vector<OUString>::iterator i(args.begin()); i != args.end();
215 ++i)
217 insertTypeDependency(manager, iterator, *i);
222 void scanMap(
223 rtl::Reference<unoidl::Manager> const & manager,
224 rtl::Reference<unoidl::MapCursor> const & cursor, bool published,
225 OUString const & prefix, std::map<OUString, Entity> & entities)
227 assert(cursor.is());
228 for (;;) {
229 OUString id;
230 rtl::Reference<unoidl::Entity> ent(cursor->getNext(&id));
231 if (!ent.is()) {
232 break;
234 OUString name(prefix + id);
235 if (ent->getSort() == unoidl::Entity::SORT_MODULE) {
236 scanMap(
237 manager,
238 static_cast<unoidl::ModuleEntity *>(ent.get())->createCursor(),
239 published, name + ".", entities);
240 } else {
241 std::map<OUString, Entity>::iterator i(
242 entities.insert(
243 std::make_pair(
244 name,
245 Entity(
246 ent,
247 (!published
248 || (static_cast<unoidl::PublishableEntity *>(
249 ent.get())
250 ->isPublished())))))
251 .first);
252 switch (ent->getSort()) {
253 case unoidl::Entity::SORT_MODULE:
254 assert(false && "this cannot happen");
255 case unoidl::Entity::SORT_ENUM_TYPE:
256 case unoidl::Entity::SORT_CONSTANT_GROUP:
257 break;
258 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
260 rtl::Reference<unoidl::PlainStructTypeEntity> ent2(
261 static_cast<unoidl::PlainStructTypeEntity *>(
262 ent.get()));
263 if (!ent2->getDirectBase().isEmpty()) {
264 insertEntityDependency(
265 manager, i, ent2->getDirectBase());
267 for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator
268 j(ent2->getDirectMembers().begin());
269 j != ent2->getDirectMembers().end(); ++j)
271 insertTypeDependency(manager, i, j->type);
273 break;
275 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
277 rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
278 ent2(
279 static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
280 ent.get()));
281 for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::const_iterator
282 j(ent2->getMembers().begin());
283 j != ent2->getMembers().end(); ++j)
285 if (!j->parameterized) {
286 insertTypeDependency(manager, i, j->type);
289 break;
291 case unoidl::Entity::SORT_EXCEPTION_TYPE:
293 rtl::Reference<unoidl::ExceptionTypeEntity> ent2(
294 static_cast<unoidl::ExceptionTypeEntity *>(ent.get()));
295 if (!ent2->getDirectBase().isEmpty()) {
296 insertEntityDependency(
297 manager, i, ent2->getDirectBase());
299 for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator
300 j(ent2->getDirectMembers().begin());
301 j != ent2->getDirectMembers().end(); ++j)
303 insertTypeDependency(manager, i, j->type);
305 break;
307 case unoidl::Entity::SORT_INTERFACE_TYPE:
309 rtl::Reference<unoidl::InterfaceTypeEntity> ent2(
310 static_cast<unoidl::InterfaceTypeEntity *>(
311 ent.get()));
312 insertEntityDependencies(
313 manager, i, ent2->getDirectMandatoryBases());
314 insertEntityDependencies(
315 manager, i, ent2->getDirectOptionalBases());
316 for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
317 j(ent2->getDirectAttributes().begin());
318 j != ent2->getDirectAttributes().end(); ++j)
320 insertTypeDependency(manager, i, j->type);
322 for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
323 j(ent2->getDirectMethods().begin());
324 j != ent2->getDirectMethods().end(); ++j)
326 insertTypeDependency(manager, i, j->returnType);
327 for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator
328 k(j->parameters.begin());
329 k != j->parameters.end(); ++k)
331 insertTypeDependency(manager, i, k->type);
333 insertEntityDependencies(manager, i, j->exceptions);
335 break;
337 case unoidl::Entity::SORT_TYPEDEF:
339 rtl::Reference<unoidl::TypedefEntity> ent2(
340 static_cast<unoidl::TypedefEntity *>(ent.get()));
341 insertTypeDependency(manager, i, ent2->getType());
342 break;
344 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
346 rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
347 ent2(
348 static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
349 ent.get()));
350 insertEntityDependency(manager, i, ent2->getBase());
351 for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::const_iterator
352 j(ent2->getConstructors().begin());
353 j != ent2->getConstructors().end(); ++j)
355 for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter>::const_iterator
356 k(j->parameters.begin());
357 k != j->parameters.end(); ++k)
359 insertTypeDependency(manager, i, k->type);
361 insertEntityDependencies(manager, i, j->exceptions);
363 break;
365 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
367 rtl::Reference<unoidl::AccumulationBasedServiceEntity> ent2(
368 static_cast<unoidl::AccumulationBasedServiceEntity *>(
369 ent.get()));
370 insertEntityDependencies(
371 manager, i, ent2->getDirectMandatoryBaseServices());
372 insertEntityDependencies(
373 manager, i, ent2->getDirectOptionalBaseServices());
374 insertEntityDependencies(
375 manager, i, ent2->getDirectMandatoryBaseInterfaces());
376 insertEntityDependencies(
377 manager, i, ent2->getDirectOptionalBaseInterfaces());
378 for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
379 j(ent2->getDirectProperties().begin());
380 j != ent2->getDirectProperties().end(); ++j)
382 insertTypeDependency(manager, i, j->type);
384 break;
386 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
388 rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2(
389 static_cast<unoidl::InterfaceBasedSingletonEntity *>(
390 ent.get()));
391 insertEntityDependency(manager, i, ent2->getBase());
392 break;
394 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
396 rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2(
397 static_cast<unoidl::ServiceBasedSingletonEntity *>(
398 ent.get()));
399 insertEntityDependency(manager, i, ent2->getBase());
400 break;
407 void propagateRelevant(std::map<OUString, Entity> & entities, Entity & entity) {
408 if (!entity.relevant) {
409 entity.relevant = true;
410 if (entity.sorted != Entity::Sorted::YES) {
411 for (std::set<OUString>::iterator i(entity.dependencies.begin());
412 i != entity.dependencies.end(); ++i)
414 std::map<OUString, Entity>::iterator j(entities.find(*i));
415 if (j != entities.end()) {
416 propagateRelevant(entities, j->second);
423 void visit(
424 std::map<OUString, Entity> & entities,
425 std::map<OUString, Entity>::iterator const & iterator,
426 std::vector<OUString> & result)
428 switch (iterator->second.sorted) {
429 case Entity::Sorted::NO:
430 iterator->second.sorted = Entity::Sorted::ACTIVE;
431 for (std::set<OUString>::iterator i(
432 iterator->second.dependencies.begin());
433 i != iterator->second.dependencies.end(); ++i)
435 std::map<OUString, Entity>::iterator j(entities.find(*i));
436 if (j != entities.end()) {
437 if (iterator->second.relevant) {
438 propagateRelevant(entities, j->second);
440 visit(entities, j, result);
443 iterator->second.sorted = Entity::Sorted::YES;
444 result.push_back(iterator->first);
445 break;
446 case Entity::Sorted::ACTIVE:
447 std::cerr
448 << "Entity " << iterator->first << " recursively depends on itself"
449 << std::endl;
450 std::exit(EXIT_FAILURE);
451 // fall-through avoids warnings
452 default:
453 break;
457 std::vector<OUString> sort(std::map<OUString, Entity> & entities) {
458 std::vector<OUString> res;
459 for (std::map<OUString, Entity>::iterator i(entities.begin());
460 i != entities.end(); ++i)
462 visit(entities, i, res);
464 return res;
467 void indent(std::vector<OUString> const & modules, unsigned int extra = 0) {
468 for (std::vector<OUString>::size_type i = 0; i != modules.size(); ++i) {
469 std::cout << ' ';
471 for (unsigned int i = 0; i != extra; ++i) {
472 std::cout << ' ';
476 void closeModules(
477 std::vector<OUString> & modules, std::vector<OUString>::size_type n) {
478 for (std::vector<OUString>::size_type i = 0; i != n; ++i) {
479 assert(!modules.empty());
480 modules.pop_back();
481 indent(modules);
482 std::cout << "};\n";
486 OUString openModulesFor(std::vector<OUString> & modules, OUString const & name)
488 std::vector<OUString>::iterator i(modules.begin());
489 for (sal_Int32 j = 0;;) {
490 OUString id(name.getToken(0, '.', j));
491 if (j == -1) {
492 closeModules(
493 modules,
494 static_cast< std::vector<OUString>::size_type >(
495 modules.end() - i));
496 indent(modules);
497 return id;
499 if (i != modules.end()) {
500 if (id == *i) {
501 ++i;
502 continue;
504 closeModules(
505 modules,
506 static_cast< std::vector<OUString>::size_type >(
507 modules.end() - i));
508 i = modules.end();
510 indent(modules);
511 std::cout << "module " << id << " {\n";
512 modules.push_back(id);
513 i = modules.end();
517 void writeName(OUString const & name) {
518 std::cout << "::" << name.replaceAll(".", "::");
521 void writeAnnotations(std::vector<OUString> const & annotations) {
522 if (!annotations.empty()) {
523 std::cout << "/**";
524 for (std::vector<OUString>::const_iterator i(annotations.begin());
525 i != annotations.end(); ++i)
527 //TODO: i->indexOf("*/") == -1
528 std::cout << " @" << *i;
530 std::cout << " */ ";
534 void writePublished(rtl::Reference<unoidl::PublishableEntity> const & entity) {
535 assert(entity.is());
536 if (entity->isPublished()) {
537 std::cout << "published ";
541 void writeAnnotationsPublished(
542 rtl::Reference<unoidl::PublishableEntity> const & entity)
544 assert(entity.is());
545 writeAnnotations(entity->getAnnotations());
546 writePublished(entity);
549 void writeType(OUString const & type) {
550 std::size_t rank;
551 std::vector<OUString> args;
552 bool entity;
553 OUString nucl(decomposeType(type, &rank, &args, &entity));
554 for (std::size_t i = 0; i != rank; ++i) {
555 std::cout << "sequence< ";
557 if (entity) {
558 writeName(nucl);
559 } else {
560 std::cout << nucl;
562 if (!args.empty()) {
563 std::cout << "< ";
564 for (std::vector<OUString>::iterator i(args.begin()); i != args.end();
565 ++i)
567 if (i != args.begin()) {
568 std::cout << ", ";
570 writeType(*i);
572 std::cout << " >";
574 for (std::size_t i = 0; i != rank; ++i) {
575 std::cout << " >";
579 void writeExceptionSpecification(std::vector<OUString> const & exceptions) {
580 if (!exceptions.empty()) {
581 std::cout << " raises (";
582 for (std::vector<OUString>::const_iterator i(exceptions.begin());
583 i != exceptions.end(); ++i)
585 if (i != exceptions.begin()) {
586 std::cout << ", ";
588 writeName(*i);
590 std::cout << ')';
594 void writeEntity(
595 std::map<OUString, Entity> & entities, std::vector<OUString> & modules,
596 OUString const & name)
598 std::map<OUString, Entity>::iterator i(entities.find(name));
599 if (i != entities.end() && i->second.relevant) {
600 assert(!i->second.written);
601 i->second.written = true;
602 for (std::set<OUString>::iterator j(
603 i->second.interfaceDependencies.begin());
604 j != i->second.interfaceDependencies.end(); ++j)
606 std::map<OUString, Entity>::iterator k(entities.find(*j));
607 if (k != entities.end() && !k->second.written) {
608 OUString id(openModulesFor(modules, *j));
609 if (k->second.entity->getSort()
610 != unoidl::Entity::SORT_INTERFACE_TYPE)
612 std::cerr
613 << "Entity " << *j << " should be an interface type"
614 << std::endl;
615 std::exit(EXIT_FAILURE);
617 writePublished(
618 static_cast<unoidl::PublishableEntity *>(
619 k->second.entity.get()));
620 std::cout << "interface " << id << ";\n";
623 OUString id(openModulesFor(modules, name));
624 rtl::Reference<unoidl::PublishableEntity> ent(
625 static_cast<unoidl::PublishableEntity *>(i->second.entity.get()));
626 switch (ent->getSort()) {
627 case unoidl::Entity::SORT_MODULE:
628 assert(false && "this cannot happen");
629 //deliberate fall-through anyway
630 case unoidl::Entity::SORT_ENUM_TYPE:
632 rtl::Reference<unoidl::EnumTypeEntity> ent2(
633 static_cast<unoidl::EnumTypeEntity *>(ent.get()));
634 writeAnnotationsPublished(ent);
635 std::cout << "enum " << id << " {\n";
636 for (std::vector<unoidl::EnumTypeEntity::Member>::const_iterator
637 j(ent2->getMembers().begin());
638 j != ent2->getMembers().end(); ++j)
640 indent(modules, 1);
641 writeAnnotations(j->annotations);
642 std::cout << j->name << " = " << j->value;
643 if (j + 1 != ent2->getMembers().end()) {
644 std::cout << ',';
646 std::cout << '\n';
648 indent(modules);
649 std::cout << "};\n";
650 break;
652 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
654 rtl::Reference<unoidl::PlainStructTypeEntity> ent2(
655 static_cast<unoidl::PlainStructTypeEntity *>(ent.get()));
656 writeAnnotationsPublished(ent);
657 std::cout << "struct " << id;
658 if (!ent2->getDirectBase().isEmpty()) {
659 std::cout << ": ";
660 writeName(ent2->getDirectBase());
662 std::cout << " {\n";
663 for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator
664 j(ent2->getDirectMembers().begin());
665 j != ent2->getDirectMembers().end(); ++j)
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_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
678 rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
679 ent2(
680 static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
681 ent.get()));
682 writeAnnotationsPublished(ent);
683 std::cout << "struct " << id << '<';
684 for (std::vector<OUString>::const_iterator j(
685 ent2->getTypeParameters().begin());
686 j != ent2->getTypeParameters().end(); ++j)
688 if (j != ent2->getTypeParameters().begin()) {
689 std::cout << ", ";
691 std::cout << *j;
693 std::cout << "> {\n";
694 for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::const_iterator
695 j(ent2->getMembers().begin());
696 j != ent2->getMembers().end(); ++j)
698 indent(modules, 1);
699 writeAnnotations(j->annotations);
700 if (j->parameterized) {
701 std::cout << j->type;
702 } else {
703 writeType(j->type);
705 std::cout << ' ' << j->name << ";\n";
707 indent(modules);
708 std::cout << "};\n";
709 break;
711 case unoidl::Entity::SORT_EXCEPTION_TYPE:
713 rtl::Reference<unoidl::ExceptionTypeEntity> ent2(
714 static_cast<unoidl::ExceptionTypeEntity *>(ent.get()));
715 writeAnnotationsPublished(ent);
716 std::cout << "exception " << id;
717 if (!ent2->getDirectBase().isEmpty()) {
718 std::cout << ": ";
719 writeName(ent2->getDirectBase());
721 std::cout << " {\n";
722 for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator
723 j(ent2->getDirectMembers().begin());
724 j != ent2->getDirectMembers().end(); ++j)
726 indent(modules, 1);
727 writeAnnotations(j->annotations);
728 writeType(j->type);
729 std::cout << ' ' << j->name << ";\n";
731 indent(modules);
732 std::cout << "};\n";
733 break;
735 case unoidl::Entity::SORT_INTERFACE_TYPE:
737 rtl::Reference<unoidl::InterfaceTypeEntity> ent2(
738 static_cast<unoidl::InterfaceTypeEntity *>(
739 ent.get()));
740 writeAnnotationsPublished(ent);
741 std::cout << "interface " << id << " {\n";
742 for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
743 ent2->getDirectMandatoryBases().begin());
744 j != ent2->getDirectMandatoryBases().end(); ++j)
746 indent(modules, 1);
747 writeAnnotations(j->annotations);
748 std::cout << "interface ";
749 writeName(j->name);
750 std::cout << ";\n";
752 for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
753 ent2->getDirectOptionalBases().begin());
754 j != ent2->getDirectOptionalBases().end(); ++j)
756 indent(modules, 1);
757 writeAnnotations(j->annotations);
758 std::cout << "[optional] interface ";
759 writeName(j->name);
760 std::cout << ";\n";
762 for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
763 j(ent2->getDirectAttributes().begin());
764 j != ent2->getDirectAttributes().end(); ++j)
766 indent(modules, 1);
767 writeAnnotations(j->annotations);
768 std::cout << "[attribute";
769 if (j->bound) {
770 std::cout << ", bound";
772 if (j->readOnly) {
773 std::cout << ", readonly";
775 std::cout << "] ";
776 writeType(j->type);
777 std::cout << ' ' << j->name;
778 if (!(j->getExceptions.empty() && j->setExceptions.empty()))
780 std::cout << " {\n";
781 if (!j->getExceptions.empty()) {
782 indent(modules, 2);
783 std::cout << "get";
784 writeExceptionSpecification(j->getExceptions);
785 std::cout << ";\n";
787 if (!j->setExceptions.empty()) {
788 indent(modules, 2);
789 std::cout << "set";
790 writeExceptionSpecification(j->setExceptions);
791 std::cout << ";\n";
793 std::cout << " }";
795 std::cout << ";\n";
797 for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
798 j(ent2->getDirectMethods().begin());
799 j != ent2->getDirectMethods().end(); ++j)
801 indent(modules, 1);
802 writeAnnotations(j->annotations);
803 writeType(j->returnType);
804 std::cout << ' ' << j->name << '(';
805 for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator
806 k(j->parameters.begin());
807 k != j->parameters.end(); ++k)
809 if (k != j->parameters.begin()) {
810 std::cout << ", ";
812 switch (k->direction) {
813 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN:
814 std::cout << "[in] ";
815 break;
816 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT:
817 std::cout << "[out] ";
818 break;
819 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT:
820 std::cout << "[inout] ";
821 break;
823 writeType(k->type);
824 std::cout << ' ' << k->name;
826 std::cout << ')';
827 writeExceptionSpecification(j->exceptions);
828 std::cout << ";\n";
830 indent(modules);
831 std::cout << "};\n";
832 break;
834 case unoidl::Entity::SORT_TYPEDEF:
836 rtl::Reference<unoidl::TypedefEntity> ent2(
837 static_cast<unoidl::TypedefEntity *>(ent.get()));
838 writeAnnotationsPublished(ent);
839 std::cout << "typedef ";
840 writeType(ent2->getType());
841 std::cout << ' ' << id << ";\n";
842 break;
844 case unoidl::Entity::SORT_CONSTANT_GROUP:
846 rtl::Reference<unoidl::ConstantGroupEntity> ent2(
847 static_cast<unoidl::ConstantGroupEntity *>(ent.get()));
848 writeAnnotationsPublished(ent);
849 std::cout << "constants " << id << " {\n";
850 for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
851 j(ent2->getMembers().begin());
852 j != ent2->getMembers().end(); ++j)
854 indent(modules, 1);
855 writeAnnotations(j->annotations);
856 std::cout << "const ";
857 switch (j->value.type) {
858 case unoidl::ConstantValue::TYPE_BOOLEAN:
859 std::cout << "boolean";
860 break;
861 case unoidl::ConstantValue::TYPE_BYTE:
862 std::cout << "byte";
863 break;
864 case unoidl::ConstantValue::TYPE_SHORT:
865 std::cout << "short";
866 break;
867 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
868 std::cout << "unsigned short";
869 break;
870 case unoidl::ConstantValue::TYPE_LONG:
871 std::cout << "long";
872 break;
873 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
874 std::cout << "unsigned long";
875 break;
876 case unoidl::ConstantValue::TYPE_HYPER:
877 std::cout << "hyper";
878 break;
879 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
880 std::cout << "unsigned hyper";
881 break;
882 case unoidl::ConstantValue::TYPE_FLOAT:
883 std::cout << "float";
884 break;
885 case unoidl::ConstantValue::TYPE_DOUBLE:
886 std::cout << "double";
887 break;
889 std::cout << ' ' << j->name << " = ";
890 switch (j->value.type) {
891 case unoidl::ConstantValue::TYPE_BOOLEAN:
892 std::cout << (j->value.booleanValue ? "TRUE" : "FALSE");
893 break;
894 case unoidl::ConstantValue::TYPE_BYTE:
895 std::cout << int(j->value.byteValue);
896 break;
897 case unoidl::ConstantValue::TYPE_SHORT:
898 std::cout << j->value.shortValue;
899 break;
900 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
901 std::cout << j->value.unsignedShortValue;
902 break;
903 case unoidl::ConstantValue::TYPE_LONG:
904 std::cout << j->value.longValue;
905 break;
906 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
907 std::cout << j->value.unsignedLongValue;
908 break;
909 case unoidl::ConstantValue::TYPE_HYPER:
910 std::cout << j->value.hyperValue;
911 break;
912 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
913 std::cout << j->value.unsignedHyperValue;
914 break;
915 case unoidl::ConstantValue::TYPE_FLOAT:
916 std::cout << j->value.floatValue;
917 break;
918 case unoidl::ConstantValue::TYPE_DOUBLE:
919 std::cout << j->value.doubleValue;
920 break;
922 std::cout << ";\n";
924 indent(modules);
925 std::cout << "};\n";
926 break;
928 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
930 rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity> ent2(
931 static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
932 ent.get()));
933 writeAnnotationsPublished(ent);
934 std::cout << "service " << id << ": ";
935 writeName(ent2->getBase());
936 if (ent2->getConstructors().size() != 1
937 || !ent2->getConstructors().front().defaultConstructor)
939 std::cout << " {\n";
940 for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::const_iterator
941 j(ent2->getConstructors().begin());
942 j != ent2->getConstructors().end(); ++j)
944 indent(modules, 1);
945 writeAnnotations(j->annotations);
946 std::cout << j->name << '(';
947 for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter>::const_iterator
948 k(j->parameters.begin());
949 k != j->parameters.end(); ++k)
951 if (k != j->parameters.begin()) {
952 std::cout << ", ";
954 std::cout << "[in] ";
955 writeType(k->type);
956 if (k->rest) {
957 std::cout << "...";
959 std::cout << ' ' << k->name;
961 std::cout << ')';
962 writeExceptionSpecification(j->exceptions);
963 std::cout << ";\n";
965 indent(modules);
966 std::cout << '}';
968 std::cout << ";\n";
969 break;
971 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
973 rtl::Reference<unoidl::AccumulationBasedServiceEntity> ent2(
974 static_cast<unoidl::AccumulationBasedServiceEntity *>(
975 ent.get()));
976 writeAnnotationsPublished(ent);
977 std::cout << "service " << id << " {\n";
978 for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
979 ent2->getDirectMandatoryBaseServices().begin());
980 j != ent2->getDirectMandatoryBaseServices().end(); ++j)
982 indent(modules, 1);
983 writeAnnotations(j->annotations);
984 std::cout << "service ";
985 writeName(j->name);
986 std::cout << ";\n";
988 for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
989 ent2->getDirectOptionalBaseServices().begin());
990 j != ent2->getDirectOptionalBaseServices().end(); ++j)
992 indent(modules, 1);
993 writeAnnotations(j->annotations);
994 std::cout << "[optional] service ";
995 writeName(j->name);
996 std::cout << ";\n";
998 for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
999 ent2->getDirectMandatoryBaseInterfaces().begin());
1000 j != ent2->getDirectMandatoryBaseInterfaces().end(); ++j)
1002 indent(modules, 1);
1003 writeAnnotations(j->annotations);
1004 std::cout << "interface ";
1005 writeName(j->name);
1006 std::cout << ";\n";
1008 for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
1009 ent2->getDirectOptionalBaseInterfaces().begin());
1010 j != ent2->getDirectOptionalBaseInterfaces().end(); ++j)
1012 indent(modules, 1);
1013 writeAnnotations(j->annotations);
1014 std::cout << "[optional] interface ";
1015 writeName(j->name);
1016 std::cout << ";\n";
1018 for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
1019 j(ent2->getDirectProperties().begin());
1020 j != ent2->getDirectProperties().end(); ++j)
1022 indent(modules, 1);
1023 writeAnnotations(j->annotations);
1024 std::cout << "[property";
1025 if ((j->attributes
1026 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_BOUND)
1027 != 0)
1029 std::cout << ", bound";
1031 if ((j->attributes
1032 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED)
1033 != 0)
1035 std::cout << ", constrained";
1037 if ((j->attributes
1038 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_AMBIGUOUS)
1039 != 0)
1041 std::cout << ", maybeambiguous";
1043 if ((j->attributes
1044 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_DEFAULT)
1045 != 0)
1047 std::cout << ", maybedefault";
1049 if ((j->attributes
1050 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_VOID)
1051 != 0)
1053 std::cout << ", maybevoid";
1055 if ((j->attributes
1056 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL)
1057 != 0)
1059 std::cout << ", optional";
1061 if ((j->attributes
1062 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_READ_ONLY)
1063 != 0)
1065 std::cout << ", readonly";
1067 if ((j->attributes
1068 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_REMOVABLE)
1069 != 0)
1071 std::cout << ", removable";
1073 if ((j->attributes
1074 & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_TRANSIENT)
1075 != 0)
1077 std::cout << ", transient";
1079 std::cout << "] ";
1080 writeType(j->type);
1081 std::cout << ' ' << j->name << ";\n";
1083 indent(modules);
1084 std::cout << "};\n";
1085 break;
1087 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
1089 rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2(
1090 static_cast<unoidl::InterfaceBasedSingletonEntity *>(
1091 ent.get()));
1092 writeAnnotationsPublished(ent);
1093 std::cout << "singleton " << id << ": ";
1094 writeName(ent2->getBase());
1095 std::cout << ";\n";
1096 break;
1098 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
1100 rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2(
1101 static_cast<unoidl::ServiceBasedSingletonEntity *>(
1102 ent.get()));
1103 writeAnnotationsPublished(ent);
1104 std::cout << "singleton " << id << " { service ";
1105 writeName(ent2->getBase());
1106 std::cout << "; };";
1107 break;
1115 SAL_IMPLEMENT_MAIN() {
1116 try {
1117 sal_uInt32 args = rtl_getAppCommandArgCount();
1118 if (args == 0) {
1119 badUsage();
1121 OUString arg;
1122 rtl_getAppCommandArg(0, &arg.pData);
1123 bool published = arg == "--published";
1124 if (published && args == 1) {
1125 badUsage();
1127 rtl::Reference<unoidl::Manager> mgr(new unoidl::Manager);
1128 rtl::Reference<unoidl::Provider> prov;
1129 for (sal_uInt32 i = (published ? 1 : 0); i != args; ++i) {
1130 OUString uri(getArgumentUri(i));
1131 try {
1132 prov = mgr->addProvider(uri);
1133 } catch (unoidl::NoSuchFileException &) {
1134 std::cerr
1135 << "Input <" << uri << "> does not exist" << std::endl;
1136 std::exit(EXIT_FAILURE);
1139 std::map<OUString, Entity> ents;
1140 scanMap(mgr, prov->createRootCursor(), published, "", ents);
1141 std::vector<OUString> sorted(sort(ents));
1142 std::vector<OUString> mods;
1143 for (std::vector<OUString>::iterator i(sorted.begin());
1144 i != sorted.end(); ++i)
1146 writeEntity(ents, mods, *i);
1148 closeModules(mods, mods.size());
1149 return EXIT_SUCCESS;
1150 } catch (unoidl::FileFormatException & e1) {
1151 std::cerr
1152 << "Bad input <" << e1.getUri() << ">: " << e1.getDetail()
1153 << std::endl;
1154 std::exit(EXIT_FAILURE);
1158 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */