Line data Source code
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 <cstddef>
14 : #include <cstdlib>
15 : #include <iostream>
16 : #include <map>
17 : #include <set>
18 : #include <utility>
19 : #include <vector>
20 :
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"
30 :
31 : namespace {
32 :
33 0 : void badUsage() {
34 : std::cerr
35 0 : << "Usage:" << std::endl << std::endl
36 0 : << " unoidl-read [--published] [<extra registries>] <registry>"
37 0 : << std::endl << std::endl
38 : << ("where each <registry> is either a new- or legacy-format .rdb file,"
39 0 : " a single .idl")
40 0 : << std::endl
41 : << ("file, or a root directory of an .idl file tree. The complete"
42 0 : " content of the")
43 0 : << std::endl
44 : << ("last <registry> is written to stdout; if --published is specified,"
45 0 : " only the")
46 0 : << std::endl
47 : << ("published entities (plus any non-published entities referenced"
48 0 : " from published")
49 0 : << std::endl
50 0 : << "via any unpublished optional bases) are written out." << std::endl;
51 0 : std::exit(EXIT_FAILURE);
52 : }
53 :
54 0 : OUString getArgumentUri(sal_uInt32 argument) {
55 0 : OUString arg;
56 0 : rtl_getAppCommandArg(argument, &arg.pData);
57 0 : OUString url;
58 0 : osl::FileBase::RC e1 = osl::FileBase::getFileURLFromSystemPath(arg, url);
59 0 : if (e1 != osl::FileBase::E_None) {
60 : std::cerr
61 0 : << "Cannot convert \"" << arg << "\" to file URL, error code "
62 0 : << +e1 << std::endl;
63 0 : std::exit(EXIT_FAILURE);
64 : }
65 0 : OUString cwd;
66 0 : oslProcessError e2 = osl_getProcessWorkingDir(&cwd.pData);
67 0 : if (e2 != osl_Process_E_None) {
68 : std::cerr
69 0 : << "Cannot obtain working directory, error code " << +e2
70 0 : << std::endl;
71 0 : std::exit(EXIT_FAILURE);
72 : }
73 0 : OUString abs;
74 0 : e1 = osl::FileBase::getAbsoluteFileURL(cwd, url, abs);
75 0 : if (e1 != osl::FileBase::E_None) {
76 : std::cerr
77 0 : << "Cannot make \"" << url
78 0 : << "\" into an absolute file URL, error code " << +e1 << std::endl;
79 0 : std::exit(EXIT_FAILURE);
80 : }
81 0 : return abs;
82 : }
83 :
84 0 : OUString decomposeType(
85 : OUString const & type, std::size_t * rank,
86 : std::vector<OUString> * typeArguments, bool * entity)
87 : {
88 : assert(rank != 0);
89 : assert(typeArguments != 0);
90 : assert(entity != 0);
91 0 : OUString nucl(type);
92 0 : *rank = 0;
93 0 : typeArguments->clear();
94 0 : while (nucl.startsWith("[]", &nucl)) {
95 0 : ++*rank;
96 : }
97 0 : sal_Int32 i = nucl.indexOf('<');
98 0 : if (i != -1) {
99 0 : OUString tmpl(nucl.copy(0, i));
100 0 : do {
101 0 : ++i; // skip '<' or ','
102 0 : sal_Int32 j = i;
103 0 : for (sal_Int32 level = 0; j != nucl.getLength(); ++j) {
104 0 : sal_Unicode c = nucl[j];
105 0 : if (c == ',') {
106 0 : if (level == 0) {
107 0 : break;
108 : }
109 0 : } else if (c == '<') {
110 0 : ++level;
111 0 : } else if (c == '>') {
112 0 : if (level == 0) {
113 0 : break;
114 : }
115 0 : --level;
116 : }
117 : }
118 0 : if (j != nucl.getLength()) {
119 0 : typeArguments->push_back(nucl.copy(i, j - i));
120 : }
121 0 : i = j;
122 0 : } while (i != nucl.getLength() && nucl[i] != '>');
123 : assert(i == nucl.getLength() - 1 && nucl[i] == '>');
124 : assert(!typeArguments->empty());
125 0 : nucl = tmpl;
126 : }
127 : assert(!nucl.isEmpty());
128 0 : *entity = nucl != "void" && nucl != "boolean" && nucl != "byte"
129 0 : && nucl != "short" && nucl != "unsigned short" && nucl != "long"
130 0 : && nucl != "unsigned long" && nucl != "hyper"
131 0 : && nucl != "unsigned hyper" && nucl != "float" && nucl != "double"
132 0 : && nucl != "char" && nucl != "string" && nucl != "type"
133 0 : && nucl != "any";
134 : assert(*entity || typeArguments->empty());
135 0 : return nucl;
136 : }
137 :
138 0 : struct Entity {
139 : enum class Sorted { NO, ACTIVE, YES };
140 :
141 0 : explicit Entity(
142 : rtl::Reference<unoidl::Entity> const & theEntity, bool theRelevant):
143 : entity(theEntity), relevant(theRelevant), sorted(Sorted::NO),
144 0 : written(false)
145 0 : {}
146 :
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;
153 : };
154 :
155 0 : void insertEntityDependency(
156 : rtl::Reference<unoidl::Manager> const & manager,
157 : std::map<OUString, Entity>::iterator const & iterator,
158 : OUString const & name, bool weakInterfaceDependency = false)
159 : {
160 : assert(manager.is());
161 0 : if (name != iterator->first) {
162 0 : bool ifc = false;
163 0 : if (weakInterfaceDependency) {
164 0 : rtl::Reference<unoidl::Entity> ent(manager->findEntity(name));
165 0 : if (!ent.is()) {
166 0 : std::cerr << "Unknown entity " << name << std::endl;
167 0 : std::exit(EXIT_FAILURE);
168 : }
169 0 : ifc = ent->getSort() == unoidl::Entity::SORT_INTERFACE_TYPE;
170 : }
171 : (ifc
172 0 : ? iterator->second.interfaceDependencies
173 0 : : iterator->second.dependencies)
174 0 : .insert(name);
175 : }
176 0 : }
177 :
178 0 : void insertEntityDependencies(
179 : rtl::Reference<unoidl::Manager> const & manager,
180 : std::map<OUString, Entity>::iterator const & iterator,
181 : std::vector<OUString> const & names)
182 : {
183 0 : for (std::vector<OUString>::const_iterator i(names.begin());
184 0 : i != names.end(); ++i)
185 : {
186 0 : insertEntityDependency(manager, iterator, *i);
187 : }
188 0 : }
189 :
190 0 : void insertEntityDependencies(
191 : rtl::Reference<unoidl::Manager> const & manager,
192 : std::map<OUString, Entity>::iterator const & iterator,
193 : std::vector<unoidl::AnnotatedReference> const & references)
194 : {
195 0 : for (std::vector<unoidl::AnnotatedReference>::const_iterator i(
196 0 : references.begin());
197 0 : i != references.end(); ++i)
198 : {
199 0 : insertEntityDependency(manager, iterator, i->name);
200 : }
201 0 : }
202 :
203 0 : void insertTypeDependency(
204 : rtl::Reference<unoidl::Manager> const & manager,
205 : std::map<OUString, Entity>::iterator const & iterator,
206 : OUString const & type)
207 : {
208 : std::size_t rank;
209 0 : std::vector<OUString> args;
210 : bool entity;
211 0 : OUString nucl(decomposeType(type, &rank, &args, &entity));
212 0 : if (entity) {
213 0 : insertEntityDependency(manager, iterator, nucl, true);
214 0 : for (std::vector<OUString>::iterator i(args.begin()); i != args.end();
215 : ++i)
216 : {
217 0 : insertTypeDependency(manager, iterator, *i);
218 : }
219 0 : }
220 0 : }
221 :
222 0 : 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)
226 : {
227 : assert(cursor.is());
228 : for (;;) {
229 0 : OUString id;
230 0 : rtl::Reference<unoidl::Entity> ent(cursor->getNext(&id));
231 0 : if (!ent.is()) {
232 0 : break;
233 : }
234 0 : OUString name(prefix + id);
235 0 : if (ent->getSort() == unoidl::Entity::SORT_MODULE) {
236 : scanMap(
237 : manager,
238 0 : static_cast<unoidl::ModuleEntity *>(ent.get())->createCursor(),
239 0 : 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 0 : (!published
248 0 : || (static_cast<unoidl::PublishableEntity *>(
249 0 : ent.get())
250 0 : ->isPublished())))))
251 0 : .first);
252 0 : 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 0 : break;
258 : case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
259 : {
260 : rtl::Reference<unoidl::PlainStructTypeEntity> ent2(
261 : static_cast<unoidl::PlainStructTypeEntity *>(
262 0 : ent.get()));
263 0 : if (!ent2->getDirectBase().isEmpty()) {
264 : insertEntityDependency(
265 0 : manager, i, ent2->getDirectBase());
266 : }
267 0 : for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator
268 0 : j(ent2->getDirectMembers().begin());
269 0 : j != ent2->getDirectMembers().end(); ++j)
270 : {
271 0 : insertTypeDependency(manager, i, j->type);
272 : }
273 0 : break;
274 : }
275 : case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
276 : {
277 : rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
278 : ent2(
279 : static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
280 0 : ent.get()));
281 0 : for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::const_iterator
282 0 : j(ent2->getMembers().begin());
283 0 : j != ent2->getMembers().end(); ++j)
284 : {
285 0 : if (!j->parameterized) {
286 0 : insertTypeDependency(manager, i, j->type);
287 : }
288 : }
289 0 : break;
290 : }
291 : case unoidl::Entity::SORT_EXCEPTION_TYPE:
292 : {
293 : rtl::Reference<unoidl::ExceptionTypeEntity> ent2(
294 0 : static_cast<unoidl::ExceptionTypeEntity *>(ent.get()));
295 0 : if (!ent2->getDirectBase().isEmpty()) {
296 : insertEntityDependency(
297 0 : manager, i, ent2->getDirectBase());
298 : }
299 0 : for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator
300 0 : j(ent2->getDirectMembers().begin());
301 0 : j != ent2->getDirectMembers().end(); ++j)
302 : {
303 0 : insertTypeDependency(manager, i, j->type);
304 : }
305 0 : break;
306 : }
307 : case unoidl::Entity::SORT_INTERFACE_TYPE:
308 : {
309 : rtl::Reference<unoidl::InterfaceTypeEntity> ent2(
310 : static_cast<unoidl::InterfaceTypeEntity *>(
311 0 : ent.get()));
312 : insertEntityDependencies(
313 0 : manager, i, ent2->getDirectMandatoryBases());
314 : insertEntityDependencies(
315 0 : manager, i, ent2->getDirectOptionalBases());
316 0 : for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
317 0 : j(ent2->getDirectAttributes().begin());
318 0 : j != ent2->getDirectAttributes().end(); ++j)
319 : {
320 0 : insertTypeDependency(manager, i, j->type);
321 : }
322 0 : for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
323 0 : j(ent2->getDirectMethods().begin());
324 0 : j != ent2->getDirectMethods().end(); ++j)
325 : {
326 0 : insertTypeDependency(manager, i, j->returnType);
327 0 : for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator
328 0 : k(j->parameters.begin());
329 0 : k != j->parameters.end(); ++k)
330 : {
331 0 : insertTypeDependency(manager, i, k->type);
332 : }
333 0 : insertEntityDependencies(manager, i, j->exceptions);
334 : }
335 0 : break;
336 : }
337 : case unoidl::Entity::SORT_TYPEDEF:
338 : {
339 : rtl::Reference<unoidl::TypedefEntity> ent2(
340 0 : static_cast<unoidl::TypedefEntity *>(ent.get()));
341 0 : insertTypeDependency(manager, i, ent2->getType());
342 0 : break;
343 : }
344 : case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
345 : {
346 : rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity>
347 : ent2(
348 : static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
349 0 : ent.get()));
350 0 : insertEntityDependency(manager, i, ent2->getBase());
351 0 : for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::const_iterator
352 0 : j(ent2->getConstructors().begin());
353 0 : j != ent2->getConstructors().end(); ++j)
354 : {
355 0 : for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter>::const_iterator
356 0 : k(j->parameters.begin());
357 0 : k != j->parameters.end(); ++k)
358 : {
359 0 : insertTypeDependency(manager, i, k->type);
360 : }
361 0 : insertEntityDependencies(manager, i, j->exceptions);
362 : }
363 0 : break;
364 : }
365 : case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
366 : {
367 : rtl::Reference<unoidl::AccumulationBasedServiceEntity> ent2(
368 : static_cast<unoidl::AccumulationBasedServiceEntity *>(
369 0 : ent.get()));
370 : insertEntityDependencies(
371 0 : manager, i, ent2->getDirectMandatoryBaseServices());
372 : insertEntityDependencies(
373 0 : manager, i, ent2->getDirectOptionalBaseServices());
374 : insertEntityDependencies(
375 0 : manager, i, ent2->getDirectMandatoryBaseInterfaces());
376 : insertEntityDependencies(
377 0 : manager, i, ent2->getDirectOptionalBaseInterfaces());
378 0 : for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
379 0 : j(ent2->getDirectProperties().begin());
380 0 : j != ent2->getDirectProperties().end(); ++j)
381 : {
382 0 : insertTypeDependency(manager, i, j->type);
383 : }
384 0 : break;
385 : }
386 : case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
387 : {
388 : rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2(
389 : static_cast<unoidl::InterfaceBasedSingletonEntity *>(
390 0 : ent.get()));
391 0 : insertEntityDependency(manager, i, ent2->getBase());
392 0 : break;
393 : }
394 : case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
395 : {
396 : rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2(
397 : static_cast<unoidl::ServiceBasedSingletonEntity *>(
398 0 : ent.get()));
399 0 : insertEntityDependency(manager, i, ent2->getBase());
400 0 : break;
401 : }
402 : }
403 : }
404 0 : }
405 0 : }
406 :
407 0 : void propagateRelevant(std::map<OUString, Entity> & entities, Entity & entity) {
408 0 : if (!entity.relevant) {
409 0 : entity.relevant = true;
410 0 : if (entity.sorted != Entity::Sorted::YES) {
411 0 : for (std::set<OUString>::iterator i(entity.dependencies.begin());
412 0 : i != entity.dependencies.end(); ++i)
413 : {
414 0 : std::map<OUString, Entity>::iterator j(entities.find(*i));
415 0 : if (j != entities.end()) {
416 0 : propagateRelevant(entities, j->second);
417 : }
418 : }
419 : }
420 : }
421 0 : }
422 :
423 0 : void visit(
424 : std::map<OUString, Entity> & entities,
425 : std::map<OUString, Entity>::iterator const & iterator,
426 : std::vector<OUString> & result)
427 : {
428 0 : switch (iterator->second.sorted) {
429 : case Entity::Sorted::NO:
430 0 : iterator->second.sorted = Entity::Sorted::ACTIVE;
431 0 : for (std::set<OUString>::iterator i(
432 0 : iterator->second.dependencies.begin());
433 0 : i != iterator->second.dependencies.end(); ++i)
434 : {
435 0 : std::map<OUString, Entity>::iterator j(entities.find(*i));
436 0 : if (j != entities.end()) {
437 0 : if (iterator->second.relevant) {
438 0 : propagateRelevant(entities, j->second);
439 : }
440 0 : visit(entities, j, result);
441 : }
442 : }
443 0 : iterator->second.sorted = Entity::Sorted::YES;
444 0 : result.push_back(iterator->first);
445 0 : break;
446 : case Entity::Sorted::ACTIVE:
447 : std::cerr
448 0 : << "Entity " << iterator->first << " recursively depends on itself"
449 0 : << std::endl;
450 0 : std::exit(EXIT_FAILURE);
451 : // fall-through avoids warnings
452 : default:
453 0 : break;
454 : }
455 0 : }
456 :
457 0 : std::vector<OUString> sort(std::map<OUString, Entity> & entities) {
458 0 : std::vector<OUString> res;
459 0 : for (std::map<OUString, Entity>::iterator i(entities.begin());
460 0 : i != entities.end(); ++i)
461 : {
462 0 : visit(entities, i, res);
463 : }
464 0 : return res;
465 : }
466 :
467 0 : void indent(std::vector<OUString> const & modules, unsigned int extra = 0) {
468 0 : for (std::vector<OUString>::size_type i = 0; i != modules.size(); ++i) {
469 0 : std::cout << ' ';
470 : }
471 0 : for (unsigned int i = 0; i != extra; ++i) {
472 0 : std::cout << ' ';
473 : }
474 0 : }
475 :
476 0 : void closeModules(
477 : std::vector<OUString> & modules, std::vector<OUString>::size_type n) {
478 0 : for (std::vector<OUString>::size_type i = 0; i != n; ++i) {
479 : assert(!modules.empty());
480 0 : modules.pop_back();
481 0 : indent(modules);
482 0 : std::cout << "};\n";
483 : }
484 0 : }
485 :
486 0 : OUString openModulesFor(std::vector<OUString> & modules, OUString const & name)
487 : {
488 0 : std::vector<OUString>::iterator i(modules.begin());
489 0 : for (sal_Int32 j = 0;;) {
490 0 : OUString id(name.getToken(0, '.', j));
491 0 : if (j == -1) {
492 : closeModules(
493 : modules,
494 : static_cast< std::vector<OUString>::size_type >(
495 0 : modules.end() - i));
496 0 : indent(modules);
497 0 : return id;
498 : }
499 0 : if (i != modules.end()) {
500 0 : if (id == *i) {
501 0 : ++i;
502 0 : continue;
503 : }
504 : closeModules(
505 : modules,
506 : static_cast< std::vector<OUString>::size_type >(
507 0 : modules.end() - i));
508 0 : i = modules.end();
509 : }
510 0 : indent(modules);
511 0 : std::cout << "module " << id << " {\n";
512 0 : modules.push_back(id);
513 0 : i = modules.end();
514 0 : }
515 : }
516 :
517 0 : void writeName(OUString const & name) {
518 0 : std::cout << "::" << name.replaceAll(".", "::");
519 0 : }
520 :
521 0 : void writeAnnotations(std::vector<OUString> const & annotations) {
522 0 : if (!annotations.empty()) {
523 0 : std::cout << "/**";
524 0 : for (std::vector<OUString>::const_iterator i(annotations.begin());
525 0 : i != annotations.end(); ++i)
526 : {
527 : //TODO: i->indexOf("*/") == -1
528 0 : std::cout << " @" << *i;
529 : }
530 0 : std::cout << " */ ";
531 : }
532 0 : }
533 :
534 0 : void writePublished(rtl::Reference<unoidl::PublishableEntity> const & entity) {
535 : assert(entity.is());
536 0 : if (entity->isPublished()) {
537 0 : std::cout << "published ";
538 : }
539 0 : }
540 :
541 0 : void writeAnnotationsPublished(
542 : rtl::Reference<unoidl::PublishableEntity> const & entity)
543 : {
544 : assert(entity.is());
545 0 : writeAnnotations(entity->getAnnotations());
546 0 : writePublished(entity);
547 0 : }
548 :
549 0 : void writeType(OUString const & type) {
550 : std::size_t rank;
551 0 : std::vector<OUString> args;
552 : bool entity;
553 0 : OUString nucl(decomposeType(type, &rank, &args, &entity));
554 0 : for (std::size_t i = 0; i != rank; ++i) {
555 0 : std::cout << "sequence< ";
556 : }
557 0 : if (entity) {
558 0 : writeName(nucl);
559 : } else {
560 0 : std::cout << nucl;
561 : }
562 0 : if (!args.empty()) {
563 0 : std::cout << "< ";
564 0 : for (std::vector<OUString>::iterator i(args.begin()); i != args.end();
565 : ++i)
566 : {
567 0 : if (i != args.begin()) {
568 0 : std::cout << ", ";
569 : }
570 0 : writeType(*i);
571 : }
572 0 : std::cout << " >";
573 : }
574 0 : for (std::size_t i = 0; i != rank; ++i) {
575 0 : std::cout << " >";
576 0 : }
577 0 : }
578 :
579 0 : void writeExceptionSpecification(std::vector<OUString> const & exceptions) {
580 0 : if (!exceptions.empty()) {
581 0 : std::cout << " raises (";
582 0 : for (std::vector<OUString>::const_iterator i(exceptions.begin());
583 0 : i != exceptions.end(); ++i)
584 : {
585 0 : if (i != exceptions.begin()) {
586 0 : std::cout << ", ";
587 : }
588 0 : writeName(*i);
589 : }
590 0 : std::cout << ')';
591 : }
592 0 : }
593 :
594 0 : void writeEntity(
595 : std::map<OUString, Entity> & entities, std::vector<OUString> & modules,
596 : OUString const & name)
597 : {
598 0 : std::map<OUString, Entity>::iterator i(entities.find(name));
599 0 : if (i != entities.end() && i->second.relevant) {
600 : assert(!i->second.written);
601 0 : i->second.written = true;
602 0 : for (std::set<OUString>::iterator j(
603 0 : i->second.interfaceDependencies.begin());
604 0 : j != i->second.interfaceDependencies.end(); ++j)
605 : {
606 0 : std::map<OUString, Entity>::iterator k(entities.find(*j));
607 0 : if (k != entities.end() && !k->second.written) {
608 0 : OUString id(openModulesFor(modules, *j));
609 0 : if (k->second.entity->getSort()
610 : != unoidl::Entity::SORT_INTERFACE_TYPE)
611 : {
612 : std::cerr
613 0 : << "Entity " << *j << " should be an interface type"
614 0 : << std::endl;
615 0 : std::exit(EXIT_FAILURE);
616 : }
617 : writePublished(
618 : static_cast<unoidl::PublishableEntity *>(
619 0 : k->second.entity.get()));
620 0 : std::cout << "interface " << id << ";\n";
621 : }
622 : }
623 0 : OUString id(openModulesFor(modules, name));
624 : rtl::Reference<unoidl::PublishableEntity> ent(
625 0 : static_cast<unoidl::PublishableEntity *>(i->second.entity.get()));
626 0 : 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:
631 : {
632 : rtl::Reference<unoidl::EnumTypeEntity> ent2(
633 0 : static_cast<unoidl::EnumTypeEntity *>(ent.get()));
634 0 : writeAnnotationsPublished(ent);
635 0 : std::cout << "enum " << id << " {\n";
636 0 : for (std::vector<unoidl::EnumTypeEntity::Member>::const_iterator
637 0 : j(ent2->getMembers().begin());
638 0 : j != ent2->getMembers().end(); ++j)
639 : {
640 0 : indent(modules, 1);
641 0 : writeAnnotations(j->annotations);
642 0 : std::cout << j->name << " = " << j->value;
643 0 : if (j + 1 != ent2->getMembers().end()) {
644 0 : std::cout << ',';
645 : }
646 0 : std::cout << '\n';
647 : }
648 0 : indent(modules);
649 0 : std::cout << "};\n";
650 0 : break;
651 : }
652 : case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
653 : {
654 : rtl::Reference<unoidl::PlainStructTypeEntity> ent2(
655 0 : static_cast<unoidl::PlainStructTypeEntity *>(ent.get()));
656 0 : writeAnnotationsPublished(ent);
657 0 : std::cout << "struct " << id;
658 0 : if (!ent2->getDirectBase().isEmpty()) {
659 0 : std::cout << ": ";
660 0 : writeName(ent2->getDirectBase());
661 : }
662 0 : std::cout << " {\n";
663 0 : for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator
664 0 : j(ent2->getDirectMembers().begin());
665 0 : j != ent2->getDirectMembers().end(); ++j)
666 : {
667 0 : indent(modules, 1);
668 0 : writeAnnotations(j->annotations);
669 0 : writeType(j->type);
670 0 : std::cout << ' ' << j->name << ";\n";
671 : }
672 0 : indent(modules);
673 0 : std::cout << "};\n";
674 0 : break;
675 : }
676 : case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
677 : {
678 : rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
679 : ent2(
680 : static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
681 0 : ent.get()));
682 0 : writeAnnotationsPublished(ent);
683 0 : std::cout << "struct " << id << '<';
684 0 : for (std::vector<OUString>::const_iterator j(
685 0 : ent2->getTypeParameters().begin());
686 0 : j != ent2->getTypeParameters().end(); ++j)
687 : {
688 0 : if (j != ent2->getTypeParameters().begin()) {
689 0 : std::cout << ", ";
690 : }
691 0 : std::cout << *j;
692 : }
693 0 : std::cout << "> {\n";
694 0 : for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::const_iterator
695 0 : j(ent2->getMembers().begin());
696 0 : j != ent2->getMembers().end(); ++j)
697 : {
698 0 : indent(modules, 1);
699 0 : writeAnnotations(j->annotations);
700 0 : if (j->parameterized) {
701 0 : std::cout << j->type;
702 : } else {
703 0 : writeType(j->type);
704 : }
705 0 : std::cout << ' ' << j->name << ";\n";
706 : }
707 0 : indent(modules);
708 0 : std::cout << "};\n";
709 0 : break;
710 : }
711 : case unoidl::Entity::SORT_EXCEPTION_TYPE:
712 : {
713 : rtl::Reference<unoidl::ExceptionTypeEntity> ent2(
714 0 : static_cast<unoidl::ExceptionTypeEntity *>(ent.get()));
715 0 : writeAnnotationsPublished(ent);
716 0 : std::cout << "exception " << id;
717 0 : if (!ent2->getDirectBase().isEmpty()) {
718 0 : std::cout << ": ";
719 0 : writeName(ent2->getDirectBase());
720 : }
721 0 : std::cout << " {\n";
722 0 : for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator
723 0 : j(ent2->getDirectMembers().begin());
724 0 : j != ent2->getDirectMembers().end(); ++j)
725 : {
726 0 : indent(modules, 1);
727 0 : writeAnnotations(j->annotations);
728 0 : writeType(j->type);
729 0 : std::cout << ' ' << j->name << ";\n";
730 : }
731 0 : indent(modules);
732 0 : std::cout << "};\n";
733 0 : break;
734 : }
735 : case unoidl::Entity::SORT_INTERFACE_TYPE:
736 : {
737 : rtl::Reference<unoidl::InterfaceTypeEntity> ent2(
738 : static_cast<unoidl::InterfaceTypeEntity *>(
739 0 : ent.get()));
740 0 : writeAnnotationsPublished(ent);
741 0 : std::cout << "interface " << id << " {\n";
742 0 : for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
743 0 : ent2->getDirectMandatoryBases().begin());
744 0 : j != ent2->getDirectMandatoryBases().end(); ++j)
745 : {
746 0 : indent(modules, 1);
747 0 : writeAnnotations(j->annotations);
748 0 : std::cout << "interface ";
749 0 : writeName(j->name);
750 0 : std::cout << ";\n";
751 : }
752 0 : for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
753 0 : ent2->getDirectOptionalBases().begin());
754 0 : j != ent2->getDirectOptionalBases().end(); ++j)
755 : {
756 0 : indent(modules, 1);
757 0 : writeAnnotations(j->annotations);
758 0 : std::cout << "[optional] interface ";
759 0 : writeName(j->name);
760 0 : std::cout << ";\n";
761 : }
762 0 : for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
763 0 : j(ent2->getDirectAttributes().begin());
764 0 : j != ent2->getDirectAttributes().end(); ++j)
765 : {
766 0 : indent(modules, 1);
767 0 : writeAnnotations(j->annotations);
768 0 : std::cout << "[attribute";
769 0 : if (j->bound) {
770 0 : std::cout << ", bound";
771 : }
772 0 : if (j->readOnly) {
773 0 : std::cout << ", readonly";
774 : }
775 0 : std::cout << "] ";
776 0 : writeType(j->type);
777 0 : std::cout << ' ' << j->name;
778 0 : if (!(j->getExceptions.empty() && j->setExceptions.empty()))
779 : {
780 0 : std::cout << " {\n";
781 0 : if (!j->getExceptions.empty()) {
782 0 : indent(modules, 2);
783 0 : std::cout << "get";
784 0 : writeExceptionSpecification(j->getExceptions);
785 0 : std::cout << ";\n";
786 : }
787 0 : if (!j->setExceptions.empty()) {
788 0 : indent(modules, 2);
789 0 : std::cout << "set";
790 0 : writeExceptionSpecification(j->setExceptions);
791 0 : std::cout << ";\n";
792 : }
793 0 : std::cout << " }";
794 : }
795 0 : std::cout << ";\n";
796 : }
797 0 : for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
798 0 : j(ent2->getDirectMethods().begin());
799 0 : j != ent2->getDirectMethods().end(); ++j)
800 : {
801 0 : indent(modules, 1);
802 0 : writeAnnotations(j->annotations);
803 0 : writeType(j->returnType);
804 0 : std::cout << ' ' << j->name << '(';
805 0 : for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator
806 0 : k(j->parameters.begin());
807 0 : k != j->parameters.end(); ++k)
808 : {
809 0 : if (k != j->parameters.begin()) {
810 0 : std::cout << ", ";
811 : }
812 0 : switch (k->direction) {
813 : case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN:
814 0 : std::cout << "[in] ";
815 0 : break;
816 : case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT:
817 0 : std::cout << "[out] ";
818 0 : break;
819 : case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT:
820 0 : std::cout << "[inout] ";
821 0 : break;
822 : }
823 0 : writeType(k->type);
824 0 : std::cout << ' ' << k->name;
825 : }
826 0 : std::cout << ')';
827 0 : writeExceptionSpecification(j->exceptions);
828 0 : std::cout << ";\n";
829 : }
830 0 : indent(modules);
831 0 : std::cout << "};\n";
832 0 : break;
833 : }
834 : case unoidl::Entity::SORT_TYPEDEF:
835 : {
836 : rtl::Reference<unoidl::TypedefEntity> ent2(
837 0 : static_cast<unoidl::TypedefEntity *>(ent.get()));
838 0 : writeAnnotationsPublished(ent);
839 0 : std::cout << "typedef ";
840 0 : writeType(ent2->getType());
841 0 : std::cout << ' ' << id << ";\n";
842 0 : break;
843 : }
844 : case unoidl::Entity::SORT_CONSTANT_GROUP:
845 : {
846 : rtl::Reference<unoidl::ConstantGroupEntity> ent2(
847 0 : static_cast<unoidl::ConstantGroupEntity *>(ent.get()));
848 0 : writeAnnotationsPublished(ent);
849 0 : std::cout << "constants " << id << " {\n";
850 0 : for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
851 0 : j(ent2->getMembers().begin());
852 0 : j != ent2->getMembers().end(); ++j)
853 : {
854 0 : indent(modules, 1);
855 0 : writeAnnotations(j->annotations);
856 0 : std::cout << "const ";
857 0 : switch (j->value.type) {
858 : case unoidl::ConstantValue::TYPE_BOOLEAN:
859 0 : std::cout << "boolean";
860 0 : break;
861 : case unoidl::ConstantValue::TYPE_BYTE:
862 0 : std::cout << "byte";
863 0 : break;
864 : case unoidl::ConstantValue::TYPE_SHORT:
865 0 : std::cout << "short";
866 0 : break;
867 : case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
868 0 : std::cout << "unsigned short";
869 0 : break;
870 : case unoidl::ConstantValue::TYPE_LONG:
871 0 : std::cout << "long";
872 0 : break;
873 : case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
874 0 : std::cout << "unsigned long";
875 0 : break;
876 : case unoidl::ConstantValue::TYPE_HYPER:
877 0 : std::cout << "hyper";
878 0 : break;
879 : case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
880 0 : std::cout << "unsigned hyper";
881 0 : break;
882 : case unoidl::ConstantValue::TYPE_FLOAT:
883 0 : std::cout << "float";
884 0 : break;
885 : case unoidl::ConstantValue::TYPE_DOUBLE:
886 0 : std::cout << "double";
887 0 : break;
888 : }
889 0 : std::cout << ' ' << j->name << " = ";
890 0 : switch (j->value.type) {
891 : case unoidl::ConstantValue::TYPE_BOOLEAN:
892 0 : std::cout << (j->value.booleanValue ? "TRUE" : "FALSE");
893 0 : break;
894 : case unoidl::ConstantValue::TYPE_BYTE:
895 0 : std::cout << int(j->value.byteValue);
896 0 : break;
897 : case unoidl::ConstantValue::TYPE_SHORT:
898 0 : std::cout << j->value.shortValue;
899 0 : break;
900 : case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
901 0 : std::cout << j->value.unsignedShortValue;
902 0 : break;
903 : case unoidl::ConstantValue::TYPE_LONG:
904 0 : std::cout << j->value.longValue;
905 0 : break;
906 : case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
907 0 : std::cout << j->value.unsignedLongValue;
908 0 : break;
909 : case unoidl::ConstantValue::TYPE_HYPER:
910 0 : std::cout << j->value.hyperValue;
911 0 : break;
912 : case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
913 0 : std::cout << j->value.unsignedHyperValue;
914 0 : break;
915 : case unoidl::ConstantValue::TYPE_FLOAT:
916 0 : std::cout << j->value.floatValue;
917 0 : break;
918 : case unoidl::ConstantValue::TYPE_DOUBLE:
919 0 : std::cout << j->value.doubleValue;
920 0 : break;
921 : }
922 0 : std::cout << ";\n";
923 : }
924 0 : indent(modules);
925 0 : std::cout << "};\n";
926 0 : break;
927 : }
928 : case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
929 : {
930 : rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity> ent2(
931 : static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
932 0 : ent.get()));
933 0 : writeAnnotationsPublished(ent);
934 0 : std::cout << "service " << id << ": ";
935 0 : writeName(ent2->getBase());
936 0 : if (ent2->getConstructors().size() != 1
937 0 : || !ent2->getConstructors().front().defaultConstructor)
938 : {
939 0 : std::cout << " {\n";
940 0 : for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::const_iterator
941 0 : j(ent2->getConstructors().begin());
942 0 : j != ent2->getConstructors().end(); ++j)
943 : {
944 0 : indent(modules, 1);
945 0 : writeAnnotations(j->annotations);
946 0 : std::cout << j->name << '(';
947 0 : for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter>::const_iterator
948 0 : k(j->parameters.begin());
949 0 : k != j->parameters.end(); ++k)
950 : {
951 0 : if (k != j->parameters.begin()) {
952 0 : std::cout << ", ";
953 : }
954 0 : std::cout << "[in] ";
955 0 : writeType(k->type);
956 0 : if (k->rest) {
957 0 : std::cout << "...";
958 : }
959 0 : std::cout << ' ' << k->name;
960 : }
961 0 : std::cout << ')';
962 0 : writeExceptionSpecification(j->exceptions);
963 0 : std::cout << ";\n";
964 : }
965 0 : indent(modules);
966 0 : std::cout << '}';
967 : }
968 0 : std::cout << ";\n";
969 0 : break;
970 : }
971 : case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
972 : {
973 : rtl::Reference<unoidl::AccumulationBasedServiceEntity> ent2(
974 : static_cast<unoidl::AccumulationBasedServiceEntity *>(
975 0 : ent.get()));
976 0 : writeAnnotationsPublished(ent);
977 0 : std::cout << "service " << id << " {\n";
978 0 : for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
979 0 : ent2->getDirectMandatoryBaseServices().begin());
980 0 : j != ent2->getDirectMandatoryBaseServices().end(); ++j)
981 : {
982 0 : indent(modules, 1);
983 0 : writeAnnotations(j->annotations);
984 0 : std::cout << "service ";
985 0 : writeName(j->name);
986 0 : std::cout << ";\n";
987 : }
988 0 : for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
989 0 : ent2->getDirectOptionalBaseServices().begin());
990 0 : j != ent2->getDirectOptionalBaseServices().end(); ++j)
991 : {
992 0 : indent(modules, 1);
993 0 : writeAnnotations(j->annotations);
994 0 : std::cout << "[optional] service ";
995 0 : writeName(j->name);
996 0 : std::cout << ";\n";
997 : }
998 0 : for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
999 0 : ent2->getDirectMandatoryBaseInterfaces().begin());
1000 0 : j != ent2->getDirectMandatoryBaseInterfaces().end(); ++j)
1001 : {
1002 0 : indent(modules, 1);
1003 0 : writeAnnotations(j->annotations);
1004 0 : std::cout << "interface ";
1005 0 : writeName(j->name);
1006 0 : std::cout << ";\n";
1007 : }
1008 0 : for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
1009 0 : ent2->getDirectOptionalBaseInterfaces().begin());
1010 0 : j != ent2->getDirectOptionalBaseInterfaces().end(); ++j)
1011 : {
1012 0 : indent(modules, 1);
1013 0 : writeAnnotations(j->annotations);
1014 0 : std::cout << "[optional] interface ";
1015 0 : writeName(j->name);
1016 0 : std::cout << ";\n";
1017 : }
1018 0 : for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
1019 0 : j(ent2->getDirectProperties().begin());
1020 0 : j != ent2->getDirectProperties().end(); ++j)
1021 : {
1022 0 : indent(modules, 1);
1023 0 : writeAnnotations(j->annotations);
1024 0 : std::cout << "[property";
1025 0 : if ((j->attributes
1026 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_BOUND)
1027 : != 0)
1028 : {
1029 0 : std::cout << ", bound";
1030 : }
1031 0 : if ((j->attributes
1032 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED)
1033 : != 0)
1034 : {
1035 0 : std::cout << ", constrained";
1036 : }
1037 0 : if ((j->attributes
1038 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_AMBIGUOUS)
1039 : != 0)
1040 : {
1041 0 : std::cout << ", maybeambiguous";
1042 : }
1043 0 : if ((j->attributes
1044 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_DEFAULT)
1045 : != 0)
1046 : {
1047 0 : std::cout << ", maybedefault";
1048 : }
1049 0 : if ((j->attributes
1050 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_VOID)
1051 : != 0)
1052 : {
1053 0 : std::cout << ", maybevoid";
1054 : }
1055 0 : if ((j->attributes
1056 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL)
1057 : != 0)
1058 : {
1059 0 : std::cout << ", optional";
1060 : }
1061 0 : if ((j->attributes
1062 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_READ_ONLY)
1063 : != 0)
1064 : {
1065 0 : std::cout << ", readonly";
1066 : }
1067 0 : if ((j->attributes
1068 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_REMOVABLE)
1069 : != 0)
1070 : {
1071 0 : std::cout << ", removable";
1072 : }
1073 0 : if ((j->attributes
1074 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_TRANSIENT)
1075 : != 0)
1076 : {
1077 0 : std::cout << ", transient";
1078 : }
1079 0 : std::cout << "] ";
1080 0 : writeType(j->type);
1081 0 : std::cout << ' ' << j->name << ";\n";
1082 : }
1083 0 : indent(modules);
1084 0 : std::cout << "};\n";
1085 0 : break;
1086 : }
1087 : case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
1088 : {
1089 : rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2(
1090 : static_cast<unoidl::InterfaceBasedSingletonEntity *>(
1091 0 : ent.get()));
1092 0 : writeAnnotationsPublished(ent);
1093 0 : std::cout << "singleton " << id << ": ";
1094 0 : writeName(ent2->getBase());
1095 0 : std::cout << ";\n";
1096 0 : break;
1097 : }
1098 : case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
1099 : {
1100 : rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2(
1101 : static_cast<unoidl::ServiceBasedSingletonEntity *>(
1102 0 : ent.get()));
1103 0 : writeAnnotationsPublished(ent);
1104 0 : std::cout << "singleton " << id << " { service ";
1105 0 : writeName(ent2->getBase());
1106 0 : std::cout << "; };";
1107 0 : break;
1108 : }
1109 0 : }
1110 : }
1111 0 : }
1112 :
1113 : }
1114 :
1115 0 : SAL_IMPLEMENT_MAIN() {
1116 : try {
1117 0 : sal_uInt32 args = rtl_getAppCommandArgCount();
1118 0 : if (args == 0) {
1119 0 : badUsage();
1120 : }
1121 0 : OUString arg;
1122 0 : rtl_getAppCommandArg(0, &arg.pData);
1123 0 : bool published = arg == "--published";
1124 0 : if (published && args == 1) {
1125 0 : badUsage();
1126 : }
1127 0 : rtl::Reference<unoidl::Manager> mgr(new unoidl::Manager);
1128 0 : rtl::Reference<unoidl::Provider> prov;
1129 0 : for (sal_uInt32 i = (published ? 1 : 0); i != args; ++i) {
1130 0 : OUString uri(getArgumentUri(i));
1131 : try {
1132 0 : prov = mgr->addProvider(uri);
1133 0 : } catch (unoidl::NoSuchFileException &) {
1134 : std::cerr
1135 0 : << "Input <" << uri << "> does not exist" << std::endl;
1136 0 : std::exit(EXIT_FAILURE);
1137 : }
1138 0 : }
1139 0 : std::map<OUString, Entity> ents;
1140 0 : scanMap(mgr, prov->createRootCursor(), published, "", ents);
1141 0 : std::vector<OUString> sorted(sort(ents));
1142 0 : std::vector<OUString> mods;
1143 0 : for (std::vector<OUString>::iterator i(sorted.begin());
1144 0 : i != sorted.end(); ++i)
1145 : {
1146 0 : writeEntity(ents, mods, *i);
1147 : }
1148 0 : closeModules(mods, mods.size());
1149 0 : return EXIT_SUCCESS;
1150 0 : } catch (unoidl::FileFormatException & e1) {
1151 : std::cerr
1152 0 : << "Bad input <" << e1.getUri() << ">: " << e1.getDetail()
1153 0 : << std::endl;
1154 0 : std::exit(EXIT_FAILURE);
1155 : }
1156 0 : }
1157 :
1158 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|