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 : //deliberate fall-through anyway
614 : case unoidl::Entity::SORT_ENUM_TYPE:
615 : {
616 : rtl::Reference<unoidl::EnumTypeEntity> ent2(
617 0 : static_cast<unoidl::EnumTypeEntity *>(ent.get()));
618 0 : writeAnnotationsPublished(ent);
619 0 : std::cout << "enum " << id << " {\n";
620 0 : for (std::vector<unoidl::EnumTypeEntity::Member>::const_iterator
621 0 : j(ent2->getMembers().begin());
622 0 : j != ent2->getMembers().end(); ++j)
623 : {
624 0 : indent(modules, 1);
625 0 : writeAnnotations(j->annotations);
626 0 : std::cout << j->name << " = " << j->value;
627 0 : if (j + 1 != ent2->getMembers().end()) {
628 0 : std::cout << ',';
629 : }
630 0 : std::cout << '\n';
631 : }
632 0 : indent(modules);
633 0 : std::cout << "};\n";
634 0 : break;
635 : }
636 : case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
637 : {
638 : rtl::Reference<unoidl::PlainStructTypeEntity> ent2(
639 0 : static_cast<unoidl::PlainStructTypeEntity *>(ent.get()));
640 0 : writeAnnotationsPublished(ent);
641 0 : std::cout << "struct " << id;
642 0 : if (!ent2->getDirectBase().isEmpty()) {
643 0 : std::cout << ": ";
644 0 : writeName(ent2->getDirectBase());
645 : }
646 0 : std::cout << " {\n";
647 0 : for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator
648 0 : j(ent2->getDirectMembers().begin());
649 0 : j != ent2->getDirectMembers().end(); ++j)
650 : {
651 0 : indent(modules, 1);
652 0 : writeAnnotations(j->annotations);
653 0 : writeType(j->type);
654 0 : std::cout << ' ' << j->name << ";\n";
655 : }
656 0 : indent(modules);
657 0 : std::cout << "};\n";
658 0 : break;
659 : }
660 : case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
661 : {
662 : rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity>
663 : ent2(
664 : static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
665 0 : ent.get()));
666 0 : writeAnnotationsPublished(ent);
667 0 : std::cout << "struct " << id << '<';
668 0 : for (std::vector<OUString>::const_iterator j(
669 0 : ent2->getTypeParameters().begin());
670 0 : j != ent2->getTypeParameters().end(); ++j)
671 : {
672 0 : if (j != ent2->getTypeParameters().begin()) {
673 0 : std::cout << ", ";
674 : }
675 0 : std::cout << *j;
676 : }
677 0 : std::cout << "> {\n";
678 0 : for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::const_iterator
679 0 : j(ent2->getMembers().begin());
680 0 : j != ent2->getMembers().end(); ++j)
681 : {
682 0 : indent(modules, 1);
683 0 : writeAnnotations(j->annotations);
684 0 : if (j->parameterized) {
685 0 : std::cout << j->type;
686 : } else {
687 0 : writeType(j->type);
688 : }
689 0 : std::cout << ' ' << j->name << ";\n";
690 : }
691 0 : indent(modules);
692 0 : std::cout << "};\n";
693 0 : break;
694 : }
695 : case unoidl::Entity::SORT_EXCEPTION_TYPE:
696 : {
697 : rtl::Reference<unoidl::ExceptionTypeEntity> ent2(
698 0 : static_cast<unoidl::ExceptionTypeEntity *>(ent.get()));
699 0 : writeAnnotationsPublished(ent);
700 0 : std::cout << "exception " << id;
701 0 : if (!ent2->getDirectBase().isEmpty()) {
702 0 : std::cout << ": ";
703 0 : writeName(ent2->getDirectBase());
704 : }
705 0 : std::cout << " {\n";
706 0 : for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator
707 0 : j(ent2->getDirectMembers().begin());
708 0 : j != ent2->getDirectMembers().end(); ++j)
709 : {
710 0 : indent(modules, 1);
711 0 : writeAnnotations(j->annotations);
712 0 : writeType(j->type);
713 0 : std::cout << ' ' << j->name << ";\n";
714 : }
715 0 : indent(modules);
716 0 : std::cout << "};\n";
717 0 : break;
718 : }
719 : case unoidl::Entity::SORT_INTERFACE_TYPE:
720 : {
721 : rtl::Reference<unoidl::InterfaceTypeEntity> ent2(
722 : static_cast<unoidl::InterfaceTypeEntity *>(
723 0 : ent.get()));
724 0 : writeAnnotationsPublished(ent);
725 0 : std::cout << "interface " << id << " {\n";
726 0 : for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
727 0 : ent2->getDirectMandatoryBases().begin());
728 0 : j != ent2->getDirectMandatoryBases().end(); ++j)
729 : {
730 0 : indent(modules, 1);
731 0 : writeAnnotations(j->annotations);
732 0 : std::cout << "interface ";
733 0 : writeName(j->name);
734 0 : std::cout << ";\n";
735 : }
736 0 : for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
737 0 : ent2->getDirectOptionalBases().begin());
738 0 : j != ent2->getDirectOptionalBases().end(); ++j)
739 : {
740 0 : indent(modules, 1);
741 0 : writeAnnotations(j->annotations);
742 0 : std::cout << "[optional] interface ";
743 0 : writeName(j->name);
744 0 : std::cout << ";\n";
745 : }
746 0 : for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
747 0 : j(ent2->getDirectAttributes().begin());
748 0 : j != ent2->getDirectAttributes().end(); ++j)
749 : {
750 0 : indent(modules, 1);
751 0 : writeAnnotations(j->annotations);
752 0 : std::cout << "[attribute";
753 0 : if (j->bound) {
754 0 : std::cout << ", bound";
755 : }
756 0 : if (j->readOnly) {
757 0 : std::cout << ", readonly";
758 : }
759 0 : std::cout << "] ";
760 0 : writeType(j->type);
761 0 : std::cout << ' ' << j->name;
762 0 : if (!(j->getExceptions.empty() && j->setExceptions.empty()))
763 : {
764 0 : std::cout << " {\n";
765 0 : if (!j->getExceptions.empty()) {
766 0 : indent(modules, 2);
767 0 : std::cout << "get";
768 0 : writeExceptionSpecification(j->getExceptions);
769 0 : std::cout << ";\n";
770 : }
771 0 : if (!j->setExceptions.empty()) {
772 0 : indent(modules, 2);
773 0 : std::cout << "set";
774 0 : writeExceptionSpecification(j->setExceptions);
775 0 : std::cout << ";\n";
776 : }
777 0 : std::cout << " }";
778 : }
779 0 : std::cout << ";\n";
780 : }
781 0 : for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
782 0 : j(ent2->getDirectMethods().begin());
783 0 : j != ent2->getDirectMethods().end(); ++j)
784 : {
785 0 : indent(modules, 1);
786 0 : writeAnnotations(j->annotations);
787 0 : writeType(j->returnType);
788 0 : std::cout << ' ' << j->name << '(';
789 0 : for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator
790 0 : k(j->parameters.begin());
791 0 : k != j->parameters.end(); ++k)
792 : {
793 0 : if (k != j->parameters.begin()) {
794 0 : std::cout << ", ";
795 : }
796 0 : switch (k->direction) {
797 : case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN:
798 0 : std::cout << "[in] ";
799 0 : break;
800 : case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT:
801 0 : std::cout << "[out] ";
802 0 : break;
803 : case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT:
804 0 : std::cout << "[inout] ";
805 0 : break;
806 : }
807 0 : writeType(k->type);
808 0 : std::cout << ' ' << k->name;
809 : }
810 0 : std::cout << ')';
811 0 : writeExceptionSpecification(j->exceptions);
812 0 : std::cout << ";\n";
813 : }
814 0 : indent(modules);
815 0 : std::cout << "};\n";
816 0 : break;
817 : }
818 : case unoidl::Entity::SORT_TYPEDEF:
819 : {
820 : rtl::Reference<unoidl::TypedefEntity> ent2(
821 0 : static_cast<unoidl::TypedefEntity *>(ent.get()));
822 0 : writeAnnotationsPublished(ent);
823 0 : std::cout << "typedef ";
824 0 : writeType(ent2->getType());
825 0 : std::cout << ' ' << id << ";\n";
826 0 : break;
827 : }
828 : case unoidl::Entity::SORT_CONSTANT_GROUP:
829 : {
830 : rtl::Reference<unoidl::ConstantGroupEntity> ent2(
831 0 : static_cast<unoidl::ConstantGroupEntity *>(ent.get()));
832 0 : writeAnnotationsPublished(ent);
833 0 : std::cout << "constants " << id << " {\n";
834 0 : for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
835 0 : j(ent2->getMembers().begin());
836 0 : j != ent2->getMembers().end(); ++j)
837 : {
838 0 : indent(modules, 1);
839 0 : writeAnnotations(j->annotations);
840 0 : std::cout << "const ";
841 0 : switch (j->value.type) {
842 : case unoidl::ConstantValue::TYPE_BOOLEAN:
843 0 : std::cout << "boolean";
844 0 : break;
845 : case unoidl::ConstantValue::TYPE_BYTE:
846 0 : std::cout << "byte";
847 0 : break;
848 : case unoidl::ConstantValue::TYPE_SHORT:
849 0 : std::cout << "short";
850 0 : break;
851 : case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
852 0 : std::cout << "unsigned short";
853 0 : break;
854 : case unoidl::ConstantValue::TYPE_LONG:
855 0 : std::cout << "long";
856 0 : break;
857 : case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
858 0 : std::cout << "unsigned long";
859 0 : break;
860 : case unoidl::ConstantValue::TYPE_HYPER:
861 0 : std::cout << "hyper";
862 0 : break;
863 : case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
864 0 : std::cout << "unsigned hyper";
865 0 : break;
866 : case unoidl::ConstantValue::TYPE_FLOAT:
867 0 : std::cout << "float";
868 0 : break;
869 : case unoidl::ConstantValue::TYPE_DOUBLE:
870 0 : std::cout << "double";
871 0 : break;
872 : }
873 0 : std::cout << ' ' << j->name << " = ";
874 0 : switch (j->value.type) {
875 : case unoidl::ConstantValue::TYPE_BOOLEAN:
876 0 : std::cout << (j->value.booleanValue ? "TRUE" : "FALSE");
877 0 : break;
878 : case unoidl::ConstantValue::TYPE_BYTE:
879 0 : std::cout << int(j->value.byteValue);
880 0 : break;
881 : case unoidl::ConstantValue::TYPE_SHORT:
882 0 : std::cout << j->value.shortValue;
883 0 : break;
884 : case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
885 0 : std::cout << j->value.unsignedShortValue;
886 0 : break;
887 : case unoidl::ConstantValue::TYPE_LONG:
888 0 : std::cout << j->value.longValue;
889 0 : break;
890 : case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
891 0 : std::cout << j->value.unsignedLongValue;
892 0 : break;
893 : case unoidl::ConstantValue::TYPE_HYPER:
894 0 : std::cout << j->value.hyperValue;
895 0 : break;
896 : case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
897 0 : std::cout << j->value.unsignedHyperValue;
898 0 : break;
899 : case unoidl::ConstantValue::TYPE_FLOAT:
900 0 : std::cout << j->value.floatValue;
901 0 : break;
902 : case unoidl::ConstantValue::TYPE_DOUBLE:
903 0 : std::cout << j->value.doubleValue;
904 0 : break;
905 : }
906 0 : std::cout << ";\n";
907 : }
908 0 : indent(modules);
909 0 : std::cout << "};\n";
910 0 : break;
911 : }
912 : case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
913 : {
914 : rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity> ent2(
915 : static_cast<unoidl::SingleInterfaceBasedServiceEntity *>(
916 0 : ent.get()));
917 0 : writeAnnotationsPublished(ent);
918 0 : std::cout << "service " << id << ": ";
919 0 : writeName(ent2->getBase());
920 0 : if (ent2->getConstructors().size() != 1
921 0 : || !ent2->getConstructors().front().defaultConstructor)
922 : {
923 0 : std::cout << " {\n";
924 0 : for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::const_iterator
925 0 : j(ent2->getConstructors().begin());
926 0 : j != ent2->getConstructors().end(); ++j)
927 : {
928 0 : indent(modules, 1);
929 0 : writeAnnotations(j->annotations);
930 0 : std::cout << j->name << '(';
931 0 : for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter>::const_iterator
932 0 : k(j->parameters.begin());
933 0 : k != j->parameters.end(); ++k)
934 : {
935 0 : if (k != j->parameters.begin()) {
936 0 : std::cout << ", ";
937 : }
938 0 : std::cout << "[in] ";
939 0 : writeType(k->type);
940 0 : if (k->rest) {
941 0 : std::cout << "...";
942 : }
943 0 : std::cout << ' ' << k->name;
944 : }
945 0 : std::cout << ')';
946 0 : writeExceptionSpecification(j->exceptions);
947 0 : std::cout << ";\n";
948 : }
949 0 : indent(modules);
950 0 : std::cout << '}';
951 : }
952 0 : std::cout << ";\n";
953 0 : break;
954 : }
955 : case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
956 : {
957 : rtl::Reference<unoidl::AccumulationBasedServiceEntity> ent2(
958 : static_cast<unoidl::AccumulationBasedServiceEntity *>(
959 0 : ent.get()));
960 0 : writeAnnotationsPublished(ent);
961 0 : std::cout << "service " << id << " {\n";
962 0 : for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
963 0 : ent2->getDirectMandatoryBaseServices().begin());
964 0 : j != ent2->getDirectMandatoryBaseServices().end(); ++j)
965 : {
966 0 : indent(modules, 1);
967 0 : writeAnnotations(j->annotations);
968 0 : std::cout << "service ";
969 0 : writeName(j->name);
970 0 : std::cout << ";\n";
971 : }
972 0 : for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
973 0 : ent2->getDirectOptionalBaseServices().begin());
974 0 : j != ent2->getDirectOptionalBaseServices().end(); ++j)
975 : {
976 0 : indent(modules, 1);
977 0 : writeAnnotations(j->annotations);
978 0 : std::cout << "[optional] service ";
979 0 : writeName(j->name);
980 0 : std::cout << ";\n";
981 : }
982 0 : for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
983 0 : ent2->getDirectMandatoryBaseInterfaces().begin());
984 0 : j != ent2->getDirectMandatoryBaseInterfaces().end(); ++j)
985 : {
986 0 : indent(modules, 1);
987 0 : writeAnnotations(j->annotations);
988 0 : std::cout << "interface ";
989 0 : writeName(j->name);
990 0 : std::cout << ";\n";
991 : }
992 0 : for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
993 0 : ent2->getDirectOptionalBaseInterfaces().begin());
994 0 : j != ent2->getDirectOptionalBaseInterfaces().end(); ++j)
995 : {
996 0 : indent(modules, 1);
997 0 : writeAnnotations(j->annotations);
998 0 : std::cout << "[optional] interface ";
999 0 : writeName(j->name);
1000 0 : std::cout << ";\n";
1001 : }
1002 0 : for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator
1003 0 : j(ent2->getDirectProperties().begin());
1004 0 : j != ent2->getDirectProperties().end(); ++j)
1005 : {
1006 0 : indent(modules, 1);
1007 0 : writeAnnotations(j->annotations);
1008 0 : std::cout << "[property";
1009 0 : if ((j->attributes
1010 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_BOUND)
1011 : != 0)
1012 : {
1013 0 : std::cout << ", bound";
1014 : }
1015 0 : if ((j->attributes
1016 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED)
1017 : != 0)
1018 : {
1019 0 : std::cout << ", constrained";
1020 : }
1021 0 : if ((j->attributes
1022 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_AMBIGUOUS)
1023 : != 0)
1024 : {
1025 0 : std::cout << ", maybeambiguous";
1026 : }
1027 0 : if ((j->attributes
1028 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_DEFAULT)
1029 : != 0)
1030 : {
1031 0 : std::cout << ", maybedefault";
1032 : }
1033 0 : if ((j->attributes
1034 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_VOID)
1035 : != 0)
1036 : {
1037 0 : std::cout << ", maybevoid";
1038 : }
1039 0 : if ((j->attributes
1040 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL)
1041 : != 0)
1042 : {
1043 0 : std::cout << ", optional";
1044 : }
1045 0 : if ((j->attributes
1046 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_READ_ONLY)
1047 : != 0)
1048 : {
1049 0 : std::cout << ", readonly";
1050 : }
1051 0 : if ((j->attributes
1052 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_REMOVABLE)
1053 : != 0)
1054 : {
1055 0 : std::cout << ", removable";
1056 : }
1057 0 : if ((j->attributes
1058 0 : & unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_TRANSIENT)
1059 : != 0)
1060 : {
1061 0 : std::cout << ", transient";
1062 : }
1063 0 : std::cout << "] ";
1064 0 : writeType(j->type);
1065 0 : std::cout << ' ' << j->name << ";\n";
1066 : }
1067 0 : indent(modules);
1068 0 : std::cout << "};\n";
1069 0 : break;
1070 : }
1071 : case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
1072 : {
1073 : rtl::Reference<unoidl::InterfaceBasedSingletonEntity> ent2(
1074 : static_cast<unoidl::InterfaceBasedSingletonEntity *>(
1075 0 : ent.get()));
1076 0 : writeAnnotationsPublished(ent);
1077 0 : std::cout << "singleton " << id << ": ";
1078 0 : writeName(ent2->getBase());
1079 0 : std::cout << ";\n";
1080 0 : break;
1081 : }
1082 : case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
1083 : {
1084 : rtl::Reference<unoidl::ServiceBasedSingletonEntity> ent2(
1085 : static_cast<unoidl::ServiceBasedSingletonEntity *>(
1086 0 : ent.get()));
1087 0 : writeAnnotationsPublished(ent);
1088 0 : std::cout << "singleton " << id << " { service ";
1089 0 : writeName(ent2->getBase());
1090 0 : std::cout << "; };";
1091 0 : break;
1092 : }
1093 0 : }
1094 : }
1095 0 : }
1096 :
1097 : }
1098 :
1099 0 : SAL_IMPLEMENT_MAIN() {
1100 : try {
1101 0 : sal_uInt32 args = rtl_getAppCommandArgCount();
1102 0 : if (args == 0) {
1103 0 : badUsage();
1104 : }
1105 0 : OUString arg;
1106 0 : rtl_getAppCommandArg(0, &arg.pData);
1107 0 : bool published = arg == "--published";
1108 0 : if (published && args == 1) {
1109 0 : badUsage();
1110 : }
1111 0 : rtl::Reference<unoidl::Manager> mgr(new unoidl::Manager);
1112 0 : rtl::Reference<unoidl::Provider> prov;
1113 0 : for (sal_uInt32 i = (published ? 1 : 0); i != args; ++i) {
1114 0 : OUString uri(getArgumentUri(i));
1115 : try {
1116 0 : prov = mgr->addProvider(uri);
1117 0 : } catch (unoidl::NoSuchFileException &) {
1118 : std::cerr
1119 0 : << "Input <" << uri << "> does not exist" << std::endl;
1120 0 : std::exit(EXIT_FAILURE);
1121 : }
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: */
|