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