diff options
author | Stephan Bergmann <sbergman@redhat.com> | 2014-04-11 08:36:21 +0200 |
---|---|---|
committer | Stephan Bergmann <sbergman@redhat.com> | 2014-04-11 08:41:09 +0200 |
commit | a3be37674609adf68e533f31f120bbdc1abe5f7a (patch) | |
tree | fb58b7657ecf5b2eb4681d49f64bdbd61e4607f8 /unoidl | |
parent | fb1b0c1f7bb4f61ce7ed04480c495cacaec63a15 (diff) |
unoidl-check: Also check for invalid UNOIDL identifiers
...but only in those parts of registry B that are not also in registry A. That
way, we can detect newly introduced violations while ignoring the old
(published) violations for backwards compatibility.
Change-Id: Ifb8ea98fffca29647aa6677a5ade86e5b194ddee
Diffstat (limited to 'unoidl')
-rw-r--r-- | unoidl/source/unoidl-check.cxx | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/unoidl/source/unoidl-check.cxx b/unoidl/source/unoidl-check.cxx index 33487f5ea14f..3a0dd36b8070 100644 --- a/unoidl/source/unoidl-check.cxx +++ b/unoidl/source/unoidl-check.cxx @@ -17,6 +17,7 @@ #include "osl/file.hxx" #include "osl/process.h" +#include "rtl/character.hxx" #include "rtl/process.h" #include "rtl/ref.hxx" #include "rtl/ustring.hxx" @@ -890,6 +891,274 @@ void checkMap( } } +bool valid(OUString const & identifier) { + for (sal_Int32 i = 0;; ++i) { + i = identifier.indexOf('_', i); + if (i == -1) { + return true; + } + if (!rtl::isAsciiUpperCase(identifier[0]) || identifier[i - 1] == '_') { + return false; + } + } +} + +void checkIds( + rtl::Reference<unoidl::Provider> const & providerA, OUString const & prefix, + rtl::Reference<unoidl::MapCursor> const & cursor) +{ + assert(cursor.is()); + for (;;) { + OUString id; + rtl::Reference<unoidl::Entity> entB(cursor->getNext(&id)); + if (!entB.is()) { + break; + } + OUString name(prefix + id); + rtl::Reference<unoidl::Entity> entA(providerA->findEntity(name)); + if (!(entA.is() || valid(id))) { + std::cerr + << "entity name " << name << " uses an invalid identifier" + << std::endl; + std::exit(EXIT_FAILURE); + } + switch (entB->getSort()) { + case unoidl::Entity::SORT_MODULE: + checkIds( + providerA, name + ".", + (static_cast<unoidl::ModuleEntity *>(entB.get()) + ->createCursor())); + break; + case unoidl::Entity::SORT_ENUM_TYPE: + if (!entA.is()) { + rtl::Reference<unoidl::EnumTypeEntity> ent2B( + static_cast<unoidl::EnumTypeEntity *>(entB.get())); + for (std::vector<unoidl::EnumTypeEntity::Member>::const_iterator + i(ent2B->getMembers().begin()); + i != ent2B->getMembers().end(); ++i) + { + if (!valid(i->name)) { + std::cerr + << "enum type " << name << " member " << i->name + << " uses an invalid identifier" << std::endl; + std::exit(EXIT_FAILURE); + } + } + } + break; + case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE: + if (!entA.is()) { + rtl::Reference<unoidl::PlainStructTypeEntity> ent2B( + static_cast<unoidl::PlainStructTypeEntity *>( + entB.get())); + for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator + i(ent2B->getDirectMembers().begin()); + i != ent2B->getDirectMembers().end(); ++i) + { + if (!valid(i->name)) { + std::cerr + << "plain struct type " << name << " direct member " + << i->name << " uses an invalid identifier" + << std::endl; + std::exit(EXIT_FAILURE); + } + } + } + break; + case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE: + if (!entA.is()) { + rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity> + ent2B( + static_cast< + unoidl::PolymorphicStructTypeTemplateEntity *>( + entB.get())); + for (std::vector<OUString>::const_iterator i( + ent2B->getTypeParameters().begin()); + i != ent2B->getTypeParameters().end(); ++i) + { + if (!valid(*i)) { + std::cerr + << "polymorphic struct type template " << name + << " type parameter " << *i + << " uses an invalid identifier" << std::endl; + std::exit(EXIT_FAILURE); + } + } + for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::const_iterator + i(ent2B->getMembers().begin()); + i != ent2B->getMembers().end(); ++i) + { + if (!valid(i->name)) { + std::cerr + << "polymorphic struct type template " << name + << " member " << i->name + << " uses an invalid identifier" << std::endl; + std::exit(EXIT_FAILURE); + } + } + } + break; + case unoidl::Entity::SORT_EXCEPTION_TYPE: + if (!entA.is()) { + rtl::Reference<unoidl::ExceptionTypeEntity> ent2B( + static_cast<unoidl::ExceptionTypeEntity *>(entB.get())); + for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator + i(ent2B->getDirectMembers().begin()); + i != ent2B->getDirectMembers().end(); ++i) + { + if (!valid(i->name)) { + std::cerr + << "exception type " << name << " direct member " + << i->name << " uses an invalid identifier" + << std::endl; + std::exit(EXIT_FAILURE); + } + } + } + break; + case unoidl::Entity::SORT_INTERFACE_TYPE: + if (!entA.is()) { + rtl::Reference<unoidl::InterfaceTypeEntity> ent2B( + static_cast<unoidl::InterfaceTypeEntity *>(entB.get())); + for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator + i(ent2B->getDirectAttributes().begin()); + i != ent2B->getDirectAttributes().end(); ++i) + { + if (!valid(i->name)) { + std::cerr + << "interface type " << name << " direct attribute " + << i->name << " uses an invalid identifier" + << std::endl; + std::exit(EXIT_FAILURE); + } + } + for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator + i(ent2B->getDirectMethods().begin()); + i != ent2B->getDirectMethods().end(); ++i) + { + if (!valid(i->name)) { + std::cerr + << "interface type " << name << " direct method " + << i->name << " uses an invalid identifier" + << std::endl; + std::exit(EXIT_FAILURE); + } + for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::const_iterator + j(i->parameters.begin()); + j != i->parameters.end(); ++j) + { + if (!valid(j->name)) { + std::cerr + << "interface type " << name + << " direct method " << i->name << " parameter " + << j->name << " uses an invalid identifier" + << std::endl; + std::exit(EXIT_FAILURE); + } + } + } + } + break; + case unoidl::Entity::SORT_TYPEDEF: + case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON: + case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON: + break; + case unoidl::Entity::SORT_CONSTANT_GROUP: + { + rtl::Reference<unoidl::ConstantGroupEntity> ent2B( + static_cast<unoidl::ConstantGroupEntity *>(entB.get())); + for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator + i(ent2B->getMembers().begin()); + i != ent2B->getMembers().end(); ++i) + { + bool found = false; + if (entA.is()) { + rtl::Reference<unoidl::ConstantGroupEntity> ent2A( + static_cast<unoidl::ConstantGroupEntity *>( + entA.get())); + for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator + j(ent2A->getMembers().begin()); + j != ent2A->getMembers().end(); ++j) + { + if (i->name == j->name) { + found = true; + break; + } + } + } + if (!(found || valid(i->name))) { + std::cerr + << "Constant group " << name << " member " + << i->name << " uses an invalid identifier" + << std::endl; + std::exit(EXIT_FAILURE); + } + } + break; + } + case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE: + if (!entA.is()) { + rtl::Reference<unoidl::SingleInterfaceBasedServiceEntity> + ent2B( + static_cast<unoidl::SingleInterfaceBasedServiceEntity *>( + entB.get())); + for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor>::const_iterator + i(ent2B->getConstructors().begin()); + i != ent2B->getConstructors().end(); ++i) + { + if (!valid(i->name)) { + std::cerr + << "single-interface--based service " << name + << " constructor " << i->name + << " uses an invalid identifier" << std::endl; + std::exit(EXIT_FAILURE); + } + for (std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter>::const_iterator + j(i->parameters.begin()); + j != i->parameters.end(); ++j) + { + if (!valid(j->name)) { + std::cerr + << "single-interface--based service " << name + << " constructor " << i->name << " parameter " + << j->name << " uses an invalid identifier" + << std::endl; + std::exit(EXIT_FAILURE); + } + } + } + } + break; + case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE: + { + rtl::Reference<unoidl::AccumulationBasedServiceEntity> ent2B( + static_cast<unoidl::AccumulationBasedServiceEntity *>( + entB.get())); + std::vector<unoidl::AccumulationBasedServiceEntity::Property>::size_type + n(entA.is() + ? (static_cast<unoidl::AccumulationBasedServiceEntity *>( + entA.get()) + ->getDirectProperties().size()) + : 0); + assert(n <= ent2B->getDirectProperties().size()); + for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::const_iterator + i(ent2B->getDirectProperties().begin() + n); + i != ent2B->getDirectProperties().end(); ++i) + { + if (!valid(i->name)) { + std::cerr + << "accumulation-based service " << name + << " direct property " << i->name + << " uses an invalid identifier" << std::endl; + std::exit(EXIT_FAILURE); + } + } + break; + } + } + } +} + } SAL_IMPLEMENT_MAIN() { @@ -920,6 +1189,7 @@ SAL_IMPLEMENT_MAIN() { badUsage(); } checkMap(prov[1], "", prov[0]->createRootCursor()); + checkIds(prov[0], "", prov[1]->createRootCursor()); return EXIT_SUCCESS; } catch (unoidl::FileFormatException & e1) { std::cerr |