1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 #include "sal/config.h"
18 #include "osl/file.hxx"
19 #include "osl/process.h"
20 #include "rtl/character.hxx"
21 #include "rtl/process.h"
22 #include "rtl/ref.hxx"
23 #include "rtl/ustring.hxx"
25 #include "sal/types.h"
26 #include "unoidl/unoidl.hxx"
30 bool operator ==(ConstantValue
const & lhs
, ConstantValue
const & rhs
) {
31 if (lhs
.type
== rhs
.type
) {
33 case ConstantValue::TYPE_BOOLEAN
:
34 return lhs
.booleanValue
== rhs
.booleanValue
;
35 case ConstantValue::TYPE_BYTE
:
36 return lhs
.byteValue
== rhs
.byteValue
;
37 case ConstantValue::TYPE_SHORT
:
38 return lhs
.shortValue
== rhs
.shortValue
;
39 case ConstantValue::TYPE_UNSIGNED_SHORT
:
40 return lhs
.unsignedShortValue
== rhs
.unsignedShortValue
;
41 case ConstantValue::TYPE_LONG
:
42 return lhs
.longValue
== rhs
.longValue
;
43 case ConstantValue::TYPE_UNSIGNED_LONG
:
44 return lhs
.unsignedLongValue
== rhs
.unsignedLongValue
;
45 case ConstantValue::TYPE_HYPER
:
46 return lhs
.hyperValue
== rhs
.hyperValue
;
47 case ConstantValue::TYPE_UNSIGNED_HYPER
:
48 return lhs
.unsignedHyperValue
== rhs
.unsignedHyperValue
;
49 case ConstantValue::TYPE_FLOAT
:
50 return lhs
.floatValue
== rhs
.floatValue
;
51 case ConstantValue::TYPE_DOUBLE
:
52 return lhs
.doubleValue
== rhs
.doubleValue
;
58 bool operator !=(ConstantValue
const & lhs
, ConstantValue
const & rhs
) {
63 SingleInterfaceBasedServiceEntity::Constructor::Parameter
const & lhs
,
64 SingleInterfaceBasedServiceEntity::Constructor::Parameter
const & rhs
)
66 return lhs
.name
== rhs
.name
&& lhs
.type
== rhs
.type
&& lhs
.rest
== rhs
.rest
;
75 << "Usage:" << std::endl
<< std::endl
76 << (" unoidl-check [<extra registries A>] <registry A> -- [<extra"
78 << std::endl
<< " <registry B>" << std::endl
<< std::endl
79 << ("where each <registry> is either a new- or legacy-format .rdb file,"
82 << ("file, or a root directory of an .idl file tree. Check that each"
85 << "<registry A> is also present in <registry B> in a compatible form."
87 std::exit(EXIT_FAILURE
);
90 OUString
getArgumentUri(sal_uInt32 argument
, bool * delimiter
) {
92 rtl_getAppCommandArg(argument
, &arg
.pData
);
101 osl::FileBase::RC e1
= osl::FileBase::getFileURLFromSystemPath(arg
, url
);
102 if (e1
!= osl::FileBase::E_None
) {
104 << "Cannot convert \"" << arg
<< "\" to file URL, error code "
106 std::exit(EXIT_FAILURE
);
109 oslProcessError e2
= osl_getProcessWorkingDir(&cwd
.pData
);
110 if (e2
!= osl_Process_E_None
) {
112 << "Cannot obtain working directory, error code " << +e2
114 std::exit(EXIT_FAILURE
);
117 e1
= osl::FileBase::getAbsoluteFileURL(cwd
, url
, abs
);
118 if (e1
!= osl::FileBase::E_None
) {
120 << "Cannot make \"" << url
121 << "\" into an absolute file URL, error code " << +e1
<< std::endl
;
122 std::exit(EXIT_FAILURE
);
127 OUString
showDirection(
128 unoidl::InterfaceTypeEntity::Method::Parameter::Direction direction
)
131 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN
:
132 return OUString("[in]");
133 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT
:
134 return OUString("[out]");
135 case unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT
:
136 return OUString("[inout]");
138 assert(false && "this cannot happen"); for (;;) { std::abort(); }
142 struct EqualsAnnotation
{
143 EqualsAnnotation(OUString
const & name
): name_(name
) {}
145 bool operator ()(unoidl::AnnotatedReference
const & ref
)
146 { return ref
.name
== name_
; }
153 rtl::Reference
<unoidl::Provider
> const & providerB
, OUString
const & prefix
,
154 rtl::Reference
<unoidl::MapCursor
> const & cursor
)
156 assert(providerB
.is());
160 rtl::Reference
<unoidl::Entity
> entA(cursor
->getNext(&id
));
164 OUString
name(prefix
+ id
);
165 if (entA
->getSort() == unoidl::Entity::SORT_MODULE
) {
167 providerB
, name
+ ".",
168 (static_cast<unoidl::ModuleEntity
*>(entA
.get())
171 rtl::Reference
<unoidl::Entity
> entB(providerB
->findEntity(name
));
174 << "A entity " << name
<< " is not present in B"
176 std::exit(EXIT_FAILURE
);
178 if (entA
->getSort() != entB
->getSort()) {
180 << "A entity " << name
<< " is of different sort in B"
182 std::exit(EXIT_FAILURE
);
184 if ((dynamic_cast<unoidl::PublishableEntity
&>(*entA
.get())
186 && (!dynamic_cast<unoidl::PublishableEntity
&>(*entB
.get())
190 << "A published entity " << name
<< " is not published in B"
192 std::exit(EXIT_FAILURE
);
194 switch (entA
->getSort()) {
195 case unoidl::Entity::SORT_MODULE
:
196 assert(false && "this cannot happen");
197 //deliberate fall-through anyway
198 case unoidl::Entity::SORT_ENUM_TYPE
:
200 rtl::Reference
<unoidl::EnumTypeEntity
> ent2A(
201 static_cast<unoidl::EnumTypeEntity
*>(entA
.get()));
202 rtl::Reference
<unoidl::EnumTypeEntity
> ent2B(
203 static_cast<unoidl::EnumTypeEntity
*>(entB
.get()));
204 if (ent2A
->getMembers().size()
205 != ent2B
->getMembers().size())
208 << "enum type " << name
209 << " number of members changed from "
210 << ent2A
->getMembers().size() << " to "
211 << ent2B
->getMembers().size() << std::endl
;
212 std::exit(EXIT_FAILURE
);
214 for (std::vector
<unoidl::EnumTypeEntity::Member
>::const_iterator
215 i(ent2A
->getMembers().begin()),
216 j(ent2B
->getMembers().begin());
217 i
!= ent2A
->getMembers().end(); ++i
, ++j
)
219 if (i
->name
!= j
->name
|| i
->value
!= j
->value
) {
221 << "enum type " << name
<< " member #"
222 << i
- ent2A
->getMembers().begin() + 1
223 << " changed from " << i
->name
<< " = "
224 << i
->value
<< " to " << j
->name
<< " = "
225 << j
->value
<< std::endl
;
226 std::exit(EXIT_FAILURE
);
231 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE
:
233 rtl::Reference
<unoidl::PlainStructTypeEntity
> ent2A(
234 static_cast<unoidl::PlainStructTypeEntity
*>(
236 rtl::Reference
<unoidl::PlainStructTypeEntity
> ent2B(
237 static_cast<unoidl::PlainStructTypeEntity
*>(
239 if (ent2A
->getDirectBase() != ent2B
->getDirectBase()) {
241 << "plain struct type " << name
242 << " direct base changed from "
243 << (ent2A
->getDirectBase().isEmpty()
244 ? OUString("none") : ent2A
->getDirectBase())
246 << (ent2B
->getDirectBase().isEmpty()
247 ? OUString("none") : ent2B
->getDirectBase())
249 std::exit(EXIT_FAILURE
);
251 if (ent2A
->getDirectMembers().size()
252 != ent2B
->getDirectMembers().size())
255 << "plain struct type " << name
256 << " number of direct members changed from "
257 << ent2A
->getDirectMembers().size() << " to "
258 << ent2B
->getDirectMembers().size() << std::endl
;
259 std::exit(EXIT_FAILURE
);
261 for (std::vector
<unoidl::PlainStructTypeEntity::Member
>::const_iterator
262 i(ent2A
->getDirectMembers().begin()),
263 j(ent2B
->getDirectMembers().begin());
264 i
!= ent2A
->getDirectMembers().end(); ++i
, ++j
)
266 if (i
->name
!= j
->name
|| i
->type
!= j
->type
) {
268 << "plain struct type " << name
269 << " direct member #"
270 << i
- ent2A
->getDirectMembers().begin() + 1
271 << " changed from " << i
->type
<< " " << i
->name
272 << " to " << j
->type
<< " " << j
->name
274 std::exit(EXIT_FAILURE
);
279 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE
:
281 rtl::Reference
<unoidl::PolymorphicStructTypeTemplateEntity
>
283 static_cast<unoidl::PolymorphicStructTypeTemplateEntity
*>(
285 rtl::Reference
<unoidl::PolymorphicStructTypeTemplateEntity
>
287 static_cast<unoidl::PolymorphicStructTypeTemplateEntity
*>(
289 if (ent2A
->getTypeParameters().size()
290 != ent2B
->getTypeParameters().size())
293 << "polymorphic struct type template " << name
294 << " number of type parameters changed from "
295 << ent2A
->getTypeParameters().size() << " to "
296 << ent2B
->getTypeParameters().size() << std::endl
;
297 std::exit(EXIT_FAILURE
);
299 for (std::vector
<OUString
>::const_iterator
300 i(ent2A
->getTypeParameters().begin()),
301 j(ent2B
->getTypeParameters().begin());
302 i
!= ent2A
->getTypeParameters().end(); ++i
, ++j
)
306 << "polymorphic struct type template " << name
307 << " type parameter #"
308 << i
- ent2A
->getTypeParameters().begin() + 1
309 << " changed from " << *i
<< " to " << *j
311 std::exit(EXIT_FAILURE
);
314 if (ent2A
->getMembers().size()
315 != ent2B
->getMembers().size())
318 << "polymorphic struct type template " << name
319 << " number of members changed from "
320 << ent2A
->getMembers().size() << " to "
321 << ent2B
->getMembers().size() << std::endl
;
322 std::exit(EXIT_FAILURE
);
324 for (std::vector
<unoidl::PolymorphicStructTypeTemplateEntity::Member
>::const_iterator
325 i(ent2A
->getMembers().begin()),
326 j(ent2B
->getMembers().begin());
327 i
!= ent2A
->getMembers().end(); ++i
, ++j
)
329 if (i
->name
!= j
->name
|| i
->type
!= j
->type
330 || i
->parameterized
!= j
->parameterized
)
333 << "polymorphic struct type template " << name
335 << i
- ent2A
->getMembers().begin() + 1
338 ? OUString("parameterized ") : OUString())
339 << i
->type
<< " " << i
->name
342 ? OUString("parameterized ") : OUString())
343 << j
->type
<< " " << j
->name
345 std::exit(EXIT_FAILURE
);
350 case unoidl::Entity::SORT_EXCEPTION_TYPE
:
352 rtl::Reference
<unoidl::ExceptionTypeEntity
> ent2A(
353 static_cast<unoidl::ExceptionTypeEntity
*>(entA
.get()));
354 rtl::Reference
<unoidl::ExceptionTypeEntity
> ent2B(
355 static_cast<unoidl::ExceptionTypeEntity
*>(entB
.get()));
356 if (ent2A
->getDirectBase() != ent2B
->getDirectBase()) {
358 << "exception type " << name
359 << " direct base changed from "
360 << (ent2A
->getDirectBase().isEmpty()
361 ? OUString("none") : ent2A
->getDirectBase())
363 << (ent2B
->getDirectBase().isEmpty()
364 ? OUString("none") : ent2B
->getDirectBase())
366 std::exit(EXIT_FAILURE
);
368 if (ent2A
->getDirectMembers().size()
369 != ent2B
->getDirectMembers().size())
372 << "exception type " << name
373 << " number of direct members changed from "
374 << ent2A
->getDirectMembers().size() << " to "
375 << ent2B
->getDirectMembers().size() << std::endl
;
376 std::exit(EXIT_FAILURE
);
378 for (std::vector
<unoidl::ExceptionTypeEntity::Member
>::const_iterator
379 i(ent2A
->getDirectMembers().begin()),
380 j(ent2B
->getDirectMembers().begin());
381 i
!= ent2A
->getDirectMembers().end(); ++i
, ++j
)
383 if (i
->name
!= j
->name
|| i
->type
!= j
->type
) {
385 << "exception type " << name
386 << " direct member #"
387 << i
- ent2A
->getDirectMembers().begin() + 1
388 << " changed from " << i
->type
<< " " << i
->name
389 << " to " << j
->type
<< " " << j
->name
391 std::exit(EXIT_FAILURE
);
396 case unoidl::Entity::SORT_INTERFACE_TYPE
:
398 rtl::Reference
<unoidl::InterfaceTypeEntity
> ent2A(
399 static_cast<unoidl::InterfaceTypeEntity
*>(entA
.get()));
400 rtl::Reference
<unoidl::InterfaceTypeEntity
> ent2B(
401 static_cast<unoidl::InterfaceTypeEntity
*>(entB
.get()));
402 if (ent2A
->getDirectMandatoryBases().size()
403 != ent2B
->getDirectMandatoryBases().size())
406 << "interface type " << name
407 << " number of direct mandatory bases changed from "
408 << ent2A
->getDirectMandatoryBases().size() << " to "
409 << ent2B
->getDirectMandatoryBases().size()
411 std::exit(EXIT_FAILURE
);
413 for (std::vector
<unoidl::AnnotatedReference
>::const_iterator
414 i(ent2A
->getDirectMandatoryBases().begin()),
415 j(ent2B
->getDirectMandatoryBases().begin());
416 i
!= ent2A
->getDirectMandatoryBases().end(); ++i
, ++j
)
418 if (i
->name
!= j
->name
) {
420 << "interface type " << name
421 << " direct mandatory base #"
422 << (i
- ent2A
->getDirectMandatoryBases().begin()
424 << " changed from " << i
->name
<< " to "
425 << j
->name
<< std::endl
;
426 std::exit(EXIT_FAILURE
);
429 if (ent2A
->getDirectOptionalBases().size()
430 != ent2B
->getDirectOptionalBases().size())
433 << "interface type " << name
434 << " number of direct optional bases changed from "
435 << ent2A
->getDirectOptionalBases().size() << " to "
436 << ent2B
->getDirectOptionalBases().size()
438 std::exit(EXIT_FAILURE
);
440 for (std::vector
<unoidl::AnnotatedReference
>::const_iterator
441 i(ent2A
->getDirectOptionalBases().begin()),
442 j(ent2B
->getDirectOptionalBases().begin());
443 i
!= ent2A
->getDirectOptionalBases().end(); ++i
, ++j
)
445 if (i
->name
!= j
->name
) {
447 << "interface type " << name
448 << " direct optional base #"
449 << (i
- ent2A
->getDirectOptionalBases().begin()
451 << " changed from " << i
->name
<< " to "
452 << j
->name
<< std::endl
;
453 std::exit(EXIT_FAILURE
);
456 if (ent2A
->getDirectAttributes().size()
457 != ent2B
->getDirectAttributes().size())
460 << "interface type " << name
461 << " number of direct attributes changed from "
462 << ent2A
->getDirectAttributes().size() << " to "
463 << ent2B
->getDirectAttributes().size() << std::endl
;
464 std::exit(EXIT_FAILURE
);
466 for (std::vector
<unoidl::InterfaceTypeEntity::Attribute
>::const_iterator
467 i(ent2A
->getDirectAttributes().begin()),
468 j(ent2B
->getDirectAttributes().begin());
469 i
!= ent2A
->getDirectAttributes().end(); ++i
, ++j
)
471 if (i
->name
!= j
->name
|| i
->type
!= j
->type
472 || i
->bound
!= j
->bound
473 || i
->readOnly
!= j
->readOnly
474 || i
->getExceptions
!= j
->getExceptions
475 || i
->setExceptions
!= j
->setExceptions
)
478 << "interface type " << name
479 << " direct attribute #"
480 << i
- ent2A
->getDirectAttributes().begin() + 1
482 << (i
->bound
? OUString("bound ") : OUString())
484 ? OUString("read-only ") : OUString())
485 << i
->type
<< " " << i
->name
//TODO: exceptions
487 << (j
->bound
? OUString("bound ") : OUString())
489 ? OUString("read-only ") : OUString())
490 << j
->type
<< " " << j
->name
//TODO: exceptions
492 std::exit(EXIT_FAILURE
);
495 if (ent2A
->getDirectMethods().size()
496 != ent2B
->getDirectMethods().size())
499 << "interface type " << name
500 << " number of direct methods changed from "
501 << ent2A
->getDirectMethods().size() << " to "
502 << ent2B
->getDirectMethods().size() << std::endl
;
503 std::exit(EXIT_FAILURE
);
505 for (std::vector
<unoidl::InterfaceTypeEntity::Method
>::const_iterator
506 i(ent2A
->getDirectMethods().begin()),
507 j(ent2B
->getDirectMethods().begin());
508 i
!= ent2A
->getDirectMethods().end(); ++i
, ++j
)
510 if (i
->name
!= j
->name
|| i
->returnType
!= j
->returnType
511 || i
->exceptions
!= j
->exceptions
)
514 << "interface type " << name
515 << " direct method #"
516 << i
- ent2A
->getDirectMethods().begin() + 1
518 << i
->returnType
<< " " << i
->name
//TODO: exceptions
519 << " to " << j
->returnType
<< " " << j
->name
//TODO: exceptions
521 std::exit(EXIT_FAILURE
);
523 if (i
->parameters
.size() != j
->parameters
.size()) {
525 << "interface type " << name
526 << " direct method " << i
->name
527 << " number of parameters changed from "
528 << i
->parameters
.size() << " to "
529 << j
->parameters
.size() << std::endl
;
530 std::exit(EXIT_FAILURE
);
532 for (std::vector
<unoidl::InterfaceTypeEntity::Method::Parameter
>::const_iterator
533 k(i
->parameters
.begin()),
534 l(j
->parameters
.begin());
535 k
!= i
->parameters
.end(); ++k
, ++l
)
537 if (k
->type
!= l
->type
|| k
->direction
!= l
->direction
)
540 << "interface type " << name
541 << " direct method " << i
->name
543 << k
- i
->parameters
.begin() + 1
545 << showDirection(k
->direction
) << " "
547 << showDirection(l
->direction
) << " "
548 << l
->type
<< std::endl
;
549 std::exit(EXIT_FAILURE
);
551 if (k
->name
!= l
->name
) {
553 << "interface type " << name
554 << " direct method " << i
->name
556 << k
- i
->parameters
.begin() + 1
557 << " changed name from " << k
->name
558 << " to " << l
->name
<< std::endl
;
559 std::exit(EXIT_FAILURE
);
565 case unoidl::Entity::SORT_TYPEDEF
:
567 rtl::Reference
<unoidl::TypedefEntity
> ent2A(
568 static_cast<unoidl::TypedefEntity
*>(entA
.get()));
569 rtl::Reference
<unoidl::TypedefEntity
> ent2B(
570 static_cast<unoidl::TypedefEntity
*>(entB
.get()));
571 if (ent2A
->getType() != ent2B
->getType()) {
573 << "typedef " << name
<< " type changed from "
574 << ent2A
->getType() << " to " << ent2B
->getType()
576 std::exit(EXIT_FAILURE
);
580 case unoidl::Entity::SORT_CONSTANT_GROUP
:
582 rtl::Reference
<unoidl::ConstantGroupEntity
> ent2A(
583 static_cast<unoidl::ConstantGroupEntity
*>(entA
.get()));
584 rtl::Reference
<unoidl::ConstantGroupEntity
> ent2B(
585 static_cast<unoidl::ConstantGroupEntity
*>(entB
.get()));
586 for (std::vector
<unoidl::ConstantGroupEntity::Member
>::const_iterator
587 i(ent2A
->getMembers().begin());
588 i
!= ent2A
->getMembers().end(); ++i
)
591 for (std::vector
<unoidl::ConstantGroupEntity::Member
>::const_iterator
592 j(ent2B
->getMembers().begin());
593 j
!= ent2B
->getMembers().end(); ++j
)
595 if (i
->name
== j
->name
) {
596 if (i
->value
!= j
->value
) {
598 << "constant group " << name
599 << " member " << i
->name
600 << " changed value" << std::endl
;
601 std::exit(EXIT_FAILURE
);
609 << "A constant group " << name
<< " member "
610 << i
->name
<< " is not present in B"
612 std::exit(EXIT_FAILURE
);
617 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE
:
619 rtl::Reference
<unoidl::SingleInterfaceBasedServiceEntity
>
621 static_cast<unoidl::SingleInterfaceBasedServiceEntity
*>(
623 rtl::Reference
<unoidl::SingleInterfaceBasedServiceEntity
>
625 static_cast<unoidl::SingleInterfaceBasedServiceEntity
*>(
627 if (ent2A
->getBase() != ent2B
->getBase()) {
629 << "single-interface--based servcie " << name
630 << " base changed from " << ent2A
->getBase()
631 << " to " << ent2B
->getBase()
633 std::exit(EXIT_FAILURE
);
635 if (ent2A
->getConstructors().size()
636 != ent2B
->getConstructors().size())
639 << "single-interface--based service " << name
640 << " number of constructors changed from "
641 << ent2A
->getConstructors().size() << " to "
642 << ent2B
->getConstructors().size() << std::endl
;
643 std::exit(EXIT_FAILURE
);
645 for (std::vector
<unoidl::SingleInterfaceBasedServiceEntity::Constructor
>::const_iterator
646 i(ent2A
->getConstructors().begin()),
647 j(ent2B
->getConstructors().begin());
648 i
!= ent2A
->getConstructors().end(); ++i
, ++j
)
650 if (i
->name
!= j
->name
|| i
->parameters
!= j
->parameters
651 || i
->exceptions
!= j
->exceptions
652 || i
->defaultConstructor
!= j
->defaultConstructor
)
655 << "single-interface--based service " << name
657 << i
- ent2A
->getConstructors().begin() + 1
659 << (i
->defaultConstructor
660 ? OUString("default ") : i
->name
) //TODO: parameters, exceptions
662 << (j
->defaultConstructor
663 ? OUString("default ") : j
->name
) //TODO: parameters, exceptions
665 std::exit(EXIT_FAILURE
);
670 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE
:
672 rtl::Reference
<unoidl::AccumulationBasedServiceEntity
>
674 static_cast<unoidl::AccumulationBasedServiceEntity
*>(
676 rtl::Reference
<unoidl::AccumulationBasedServiceEntity
>
678 static_cast<unoidl::AccumulationBasedServiceEntity
*>(
680 if (ent2A
->getDirectMandatoryBaseServices().size()
681 != ent2B
->getDirectMandatoryBaseServices().size())
684 << "accumulation-based service " << name
685 << (" number of direct mandatory base services"
687 << ent2A
->getDirectMandatoryBaseServices().size()
689 << ent2B
->getDirectMandatoryBaseServices().size()
691 std::exit(EXIT_FAILURE
);
693 for (std::vector
<unoidl::AnnotatedReference
>::const_iterator
694 i(ent2A
->getDirectMandatoryBaseServices().begin()),
695 j(ent2B
->getDirectMandatoryBaseServices().begin());
696 i
!= ent2A
->getDirectMandatoryBaseServices().end();
699 if (i
->name
!= j
->name
) {
701 << "accumulation-based service " << name
702 << " direct mandatory base service #"
704 - (ent2A
->getDirectMandatoryBaseServices()
707 << " changed from " << i
->name
<< " to "
708 << j
->name
<< std::endl
;
709 std::exit(EXIT_FAILURE
);
712 if (ent2A
->getDirectOptionalBaseServices().size()
713 > ent2B
->getDirectOptionalBaseServices().size())
716 << "accumulation-based service " << name
717 << (" number of direct optional base services"
719 << ent2A
->getDirectOptionalBaseServices().size()
721 << ent2B
->getDirectOptionalBaseServices().size()
723 std::exit(EXIT_FAILURE
);
725 for (std::vector
<unoidl::AnnotatedReference
>::const_iterator
726 i(ent2A
->getDirectOptionalBaseServices().begin());
727 i
!= ent2A
->getDirectOptionalBaseServices().end();
731 ent2B
->getDirectOptionalBaseServices().begin(),
732 ent2B
->getDirectOptionalBaseServices().end(),
733 EqualsAnnotation(i
->name
))
734 == ent2B
->getDirectOptionalBaseServices().end())
737 << "accumulation-based service " << name
738 << " direct optional base service " << i
->name
739 << " was removed" << std::endl
;
740 std::exit(EXIT_FAILURE
);
743 if (ent2A
->getDirectMandatoryBaseInterfaces().size()
744 != ent2B
->getDirectMandatoryBaseInterfaces().size())
747 << "accumulation-based service " << name
748 << (" number of direct mandatory base interfaces"
750 << ent2A
->getDirectMandatoryBaseInterfaces().size()
752 << ent2B
->getDirectMandatoryBaseInterfaces().size()
754 std::exit(EXIT_FAILURE
);
756 for (std::vector
<unoidl::AnnotatedReference
>::const_iterator
757 i(ent2A
->getDirectMandatoryBaseInterfaces()
759 j(ent2B
->getDirectMandatoryBaseInterfaces()
761 i
!= ent2A
->getDirectMandatoryBaseInterfaces().end();
764 if (i
->name
!= j
->name
) {
766 << "accumulation-based service " << name
767 << " direct mandatory base interface #"
769 - (ent2A
->getDirectMandatoryBaseInterfaces()
772 << " changed from " << i
->name
<< " to "
773 << j
->name
<< std::endl
;
774 std::exit(EXIT_FAILURE
);
777 if (ent2A
->getDirectOptionalBaseInterfaces().size()
778 > ent2B
->getDirectOptionalBaseInterfaces().size())
781 << "accumulation-based service " << name
782 << (" number of direct optional base interfaces"
784 << ent2A
->getDirectOptionalBaseInterfaces().size()
786 << ent2B
->getDirectOptionalBaseInterfaces().size()
788 std::exit(EXIT_FAILURE
);
790 for (std::vector
<unoidl::AnnotatedReference
>::const_iterator
791 i(ent2A
->getDirectOptionalBaseInterfaces()
793 i
!= ent2A
->getDirectOptionalBaseInterfaces().end();
797 (ent2B
->getDirectOptionalBaseInterfaces()
799 ent2B
->getDirectOptionalBaseInterfaces().end(),
800 EqualsAnnotation(i
->name
))
801 == ent2B
->getDirectOptionalBaseInterfaces().end())
804 << "accumulation-based service " << name
805 << " direct optional base interface " << i
->name
806 << " was removed" << std::endl
;
807 std::exit(EXIT_FAILURE
);
810 if (ent2A
->getDirectProperties().size()
811 > ent2B
->getDirectProperties().size())
814 << "accumulation-based service " << name
815 << " number of direct properties changed from "
816 << ent2A
->getDirectProperties().size() << " to "
817 << ent2B
->getDirectProperties().size() << std::endl
;
818 std::exit(EXIT_FAILURE
);
820 for (std::vector
<unoidl::AccumulationBasedServiceEntity::Property
>::const_iterator
821 i(ent2A
->getDirectProperties().begin()),
822 j(ent2B
->getDirectProperties().begin());
823 i
!= ent2A
->getDirectProperties().end(); ++i
, ++j
)
825 if (i
->name
!= j
->name
|| i
->type
!= j
->type
826 || i
->attributes
!= j
->attributes
)
829 << "accumulation-based service " << name
830 << " direct property #"
831 << i
- ent2A
->getDirectProperties().begin() + 1
833 << i
->type
<< " " << i
->name
//TODO: attributes
835 << j
->type
<< " " << j
->name
//TODO: attributes
837 std::exit(EXIT_FAILURE
);
840 for (std::vector
<unoidl::AccumulationBasedServiceEntity::Property
>::const_iterator
841 i(ent2B
->getDirectProperties().begin()
842 + ent2A
->getDirectProperties().size());
843 i
!= ent2B
->getDirectProperties().end(); ++i
)
845 if ((i
->attributes
& unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL
) == 0)
848 << "B accumulation-based service " << name
849 << " additional direct property " << i
->name
850 << " is not optional" << std::endl
;
851 std::exit(EXIT_FAILURE
);
856 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON
:
858 rtl::Reference
<unoidl::InterfaceBasedSingletonEntity
> ent2A(
859 static_cast<unoidl::InterfaceBasedSingletonEntity
*>(
861 rtl::Reference
<unoidl::InterfaceBasedSingletonEntity
> ent2B(
862 static_cast<unoidl::InterfaceBasedSingletonEntity
*>(
864 if (ent2A
->getBase() != ent2B
->getBase()) {
866 << "interface-based singleton " << name
867 << " base changed from " << ent2A
->getBase()
868 << " to " << ent2B
->getBase() << std::endl
;
869 std::exit(EXIT_FAILURE
);
873 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON
:
875 rtl::Reference
<unoidl::ServiceBasedSingletonEntity
> ent2A(
876 static_cast<unoidl::ServiceBasedSingletonEntity
*>(
878 rtl::Reference
<unoidl::ServiceBasedSingletonEntity
> ent2B(
879 static_cast<unoidl::ServiceBasedSingletonEntity
*>(
881 if (ent2A
->getBase() != ent2B
->getBase()) {
883 << "service-based singleton " << name
884 << " base changed from " << ent2A
->getBase()
885 << " to " << ent2B
->getBase() << std::endl
;
886 std::exit(EXIT_FAILURE
);
895 bool valid(OUString
const & identifier
) {
896 for (sal_Int32 i
= 0;; ++i
) {
897 i
= identifier
.indexOf('_', i
);
901 if (!rtl::isAsciiUpperCase(identifier
[0]) || identifier
[i
- 1] == '_') {
908 rtl::Reference
<unoidl::Provider
> const & providerA
, OUString
const & prefix
,
909 rtl::Reference
<unoidl::MapCursor
> const & cursor
)
914 rtl::Reference
<unoidl::Entity
> entB(cursor
->getNext(&id
));
918 OUString
name(prefix
+ id
);
919 rtl::Reference
<unoidl::Entity
> entA(providerA
->findEntity(name
));
920 if (!(entA
.is() || valid(id
))) {
922 << "entity name " << name
<< " uses an invalid identifier"
924 std::exit(EXIT_FAILURE
);
926 switch (entB
->getSort()) {
927 case unoidl::Entity::SORT_MODULE
:
929 providerA
, name
+ ".",
930 (static_cast<unoidl::ModuleEntity
*>(entB
.get())
933 case unoidl::Entity::SORT_ENUM_TYPE
:
935 rtl::Reference
<unoidl::EnumTypeEntity
> ent2B(
936 static_cast<unoidl::EnumTypeEntity
*>(entB
.get()));
937 for (std::vector
<unoidl::EnumTypeEntity::Member
>::const_iterator
938 i(ent2B
->getMembers().begin());
939 i
!= ent2B
->getMembers().end(); ++i
)
941 if (!valid(i
->name
)) {
943 << "enum type " << name
<< " member " << i
->name
944 << " uses an invalid identifier" << std::endl
;
945 std::exit(EXIT_FAILURE
);
950 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE
:
952 rtl::Reference
<unoidl::PlainStructTypeEntity
> ent2B(
953 static_cast<unoidl::PlainStructTypeEntity
*>(
955 for (std::vector
<unoidl::PlainStructTypeEntity::Member
>::const_iterator
956 i(ent2B
->getDirectMembers().begin());
957 i
!= ent2B
->getDirectMembers().end(); ++i
)
959 if (!valid(i
->name
)) {
961 << "plain struct type " << name
<< " direct member "
962 << i
->name
<< " uses an invalid identifier"
964 std::exit(EXIT_FAILURE
);
969 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE
:
971 rtl::Reference
<unoidl::PolymorphicStructTypeTemplateEntity
>
974 unoidl::PolymorphicStructTypeTemplateEntity
*>(
976 for (std::vector
<OUString
>::const_iterator
i(
977 ent2B
->getTypeParameters().begin());
978 i
!= ent2B
->getTypeParameters().end(); ++i
)
982 << "polymorphic struct type template " << name
983 << " type parameter " << *i
984 << " uses an invalid identifier" << std::endl
;
985 std::exit(EXIT_FAILURE
);
988 for (std::vector
<unoidl::PolymorphicStructTypeTemplateEntity::Member
>::const_iterator
989 i(ent2B
->getMembers().begin());
990 i
!= ent2B
->getMembers().end(); ++i
)
992 if (!valid(i
->name
)) {
994 << "polymorphic struct type template " << name
995 << " member " << i
->name
996 << " uses an invalid identifier" << std::endl
;
997 std::exit(EXIT_FAILURE
);
1002 case unoidl::Entity::SORT_EXCEPTION_TYPE
:
1004 rtl::Reference
<unoidl::ExceptionTypeEntity
> ent2B(
1005 static_cast<unoidl::ExceptionTypeEntity
*>(entB
.get()));
1006 for (std::vector
<unoidl::ExceptionTypeEntity::Member
>::const_iterator
1007 i(ent2B
->getDirectMembers().begin());
1008 i
!= ent2B
->getDirectMembers().end(); ++i
)
1010 if (!valid(i
->name
)) {
1012 << "exception type " << name
<< " direct member "
1013 << i
->name
<< " uses an invalid identifier"
1015 std::exit(EXIT_FAILURE
);
1020 case unoidl::Entity::SORT_INTERFACE_TYPE
:
1022 rtl::Reference
<unoidl::InterfaceTypeEntity
> ent2B(
1023 static_cast<unoidl::InterfaceTypeEntity
*>(entB
.get()));
1024 for (std::vector
<unoidl::InterfaceTypeEntity::Attribute
>::const_iterator
1025 i(ent2B
->getDirectAttributes().begin());
1026 i
!= ent2B
->getDirectAttributes().end(); ++i
)
1028 if (!valid(i
->name
)) {
1030 << "interface type " << name
<< " direct attribute "
1031 << i
->name
<< " uses an invalid identifier"
1033 std::exit(EXIT_FAILURE
);
1036 for (std::vector
<unoidl::InterfaceTypeEntity::Method
>::const_iterator
1037 i(ent2B
->getDirectMethods().begin());
1038 i
!= ent2B
->getDirectMethods().end(); ++i
)
1040 if (!valid(i
->name
)) {
1042 << "interface type " << name
<< " direct method "
1043 << i
->name
<< " uses an invalid identifier"
1045 std::exit(EXIT_FAILURE
);
1047 for (std::vector
<unoidl::InterfaceTypeEntity::Method::Parameter
>::const_iterator
1048 j(i
->parameters
.begin());
1049 j
!= i
->parameters
.end(); ++j
)
1051 if (!valid(j
->name
)) {
1053 << "interface type " << name
1054 << " direct method " << i
->name
<< " parameter "
1055 << j
->name
<< " uses an invalid identifier"
1057 std::exit(EXIT_FAILURE
);
1063 case unoidl::Entity::SORT_TYPEDEF
:
1064 case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON
:
1065 case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON
:
1067 case unoidl::Entity::SORT_CONSTANT_GROUP
:
1069 rtl::Reference
<unoidl::ConstantGroupEntity
> ent2B(
1070 static_cast<unoidl::ConstantGroupEntity
*>(entB
.get()));
1071 for (std::vector
<unoidl::ConstantGroupEntity::Member
>::const_iterator
1072 i(ent2B
->getMembers().begin());
1073 i
!= ent2B
->getMembers().end(); ++i
)
1077 rtl::Reference
<unoidl::ConstantGroupEntity
> ent2A(
1078 static_cast<unoidl::ConstantGroupEntity
*>(
1080 for (std::vector
<unoidl::ConstantGroupEntity::Member
>::const_iterator
1081 j(ent2A
->getMembers().begin());
1082 j
!= ent2A
->getMembers().end(); ++j
)
1084 if (i
->name
== j
->name
) {
1090 if (!(found
|| valid(i
->name
))) {
1092 << "Constant group " << name
<< " member "
1093 << i
->name
<< " uses an invalid identifier"
1095 std::exit(EXIT_FAILURE
);
1100 case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE
:
1102 rtl::Reference
<unoidl::SingleInterfaceBasedServiceEntity
>
1104 static_cast<unoidl::SingleInterfaceBasedServiceEntity
*>(
1106 for (std::vector
<unoidl::SingleInterfaceBasedServiceEntity::Constructor
>::const_iterator
1107 i(ent2B
->getConstructors().begin());
1108 i
!= ent2B
->getConstructors().end(); ++i
)
1110 if (!valid(i
->name
)) {
1112 << "single-interface--based service " << name
1113 << " constructor " << i
->name
1114 << " uses an invalid identifier" << std::endl
;
1115 std::exit(EXIT_FAILURE
);
1117 for (std::vector
<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter
>::const_iterator
1118 j(i
->parameters
.begin());
1119 j
!= i
->parameters
.end(); ++j
)
1121 if (!valid(j
->name
)) {
1123 << "single-interface--based service " << name
1124 << " constructor " << i
->name
<< " parameter "
1125 << j
->name
<< " uses an invalid identifier"
1127 std::exit(EXIT_FAILURE
);
1133 case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE
:
1135 rtl::Reference
<unoidl::AccumulationBasedServiceEntity
> ent2B(
1136 static_cast<unoidl::AccumulationBasedServiceEntity
*>(
1138 std::vector
<unoidl::AccumulationBasedServiceEntity::Property
>::size_type
1140 ? (static_cast<unoidl::AccumulationBasedServiceEntity
*>(
1142 ->getDirectProperties().size())
1144 assert(n
<= ent2B
->getDirectProperties().size());
1145 for (std::vector
<unoidl::AccumulationBasedServiceEntity::Property
>::const_iterator
1146 i(ent2B
->getDirectProperties().begin() + n
);
1147 i
!= ent2B
->getDirectProperties().end(); ++i
)
1149 if (!valid(i
->name
)) {
1151 << "accumulation-based service " << name
1152 << " direct property " << i
->name
1153 << " uses an invalid identifier" << std::endl
;
1154 std::exit(EXIT_FAILURE
);
1165 SAL_IMPLEMENT_MAIN() {
1167 sal_uInt32 args
= rtl_getAppCommandArgCount();
1168 rtl::Reference
<unoidl::Manager
> mgr
[2];
1169 mgr
[0] = new unoidl::Manager
;
1170 mgr
[1] = new unoidl::Manager
;
1171 rtl::Reference
<unoidl::Provider
> prov
[2];
1173 for (sal_uInt32 i
= 0; i
!= args
; ++i
) {
1174 bool delimiter
= false;
1175 OUString
uri(getArgumentUri(i
, side
== 0 ? &delimiter
: 0));
1180 prov
[side
] = mgr
[side
]->addProvider(uri
);
1181 } catch (unoidl::NoSuchFileException
&) {
1183 << "Input <" << uri
<< "> does not exist" << std::endl
;
1184 std::exit(EXIT_FAILURE
);
1188 if (side
== 0 || !(prov
[0].is() && prov
[1].is())) {
1191 checkMap(prov
[1], "", prov
[0]->createRootCursor());
1192 checkIds(prov
[0], "", prov
[1]->createRootCursor());
1193 return EXIT_SUCCESS
;
1194 } catch (unoidl::FileFormatException
& e1
) {
1196 << "Bad input <" << e1
.getUri() << ">: " << e1
.getDetail()
1198 std::exit(EXIT_FAILURE
);
1202 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */