Introduce unoidl-read --summary mode

...as needed by odk/docs/idl/wikilinks.py

Change-Id: I6dd096338e9f200679810d33e89c8b9ce18f69f4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132752
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
This commit is contained in:
Stephan Bergmann
2022-04-09 13:15:01 +02:00
parent 2bf5658247
commit 29578ae139
2 changed files with 100 additions and 27 deletions
+1 -1
View File
@@ -22,7 +22,7 @@ allkinds = {}
# unfortunately we need to know what kind of entity to declare...
# generate this file like so:
# solver/unxlngx6/bin/regview solver/unxlngx6/bin/types.rdb | grep -A1 "type class:" | awk '/type class:/ { class = $NF } /type name:/ { gsub("/", ".", $NF); gsub("\"", "", $NF); print class, $NF }' > /tmp/kinds
# cat <(make -s cmd cmd='LD_LIBRARY_PATH=$(INSTDIR_FOR_BUILD)/program $(WORKDIR_FOR_BUILD)/LinkTarget/Executable/unoidl-read --summary $(INSTDIR)/program/types.rdb') <(make -s cmd cmd='LD_LIBRARY_PATH=$(INSTDIR_FOR_BUILD)/program $(WORKDIR_FOR_BUILD)/LinkTarget/Executable/unoidl-read --summary $(INSTDIR)/program/types.rdb $(INSTDIR)/program/types/offapi.rdb') | LC_ALL=C sort | LC_ALL=C uniq > /tmp/kinds
for line in open("/tmp/kinds") :
(kind,_,name) = line.strip().partition(" ")
allkinds[name] = kind
+99 -26
View File
@@ -32,7 +32,7 @@ namespace {
void badUsage() {
std::cerr
<< "Usage:" << std::endl << std::endl
<< " unoidl-read [--published] [<extra registries>] <registry>"
<< " unoidl-read [--published] [--summary] [<extra registries>] <registry>"
<< std::endl << std::endl
<< ("where each <registry> is either a new- or legacy-format .rdb file,"
" a single .idl")
@@ -46,7 +46,10 @@ void badUsage() {
<< ("published entities (plus any non-published entities referenced"
" from published")
<< std::endl
<< "via any unpublished optional bases) are written out." << std::endl;
<< "via any unpublished optional bases) are written out. If --summary is specified,"
<< std::endl
<< "only a short summary is written, with the type and name of one entity per line."
<< std::endl;
std::exit(EXIT_FAILURE);
}
@@ -139,9 +142,9 @@ struct Entity {
enum class Written { NO, DECLARATION, DEFINITION };
explicit Entity(
rtl::Reference<unoidl::Entity> const & theEntity, bool theRelevant):
rtl::Reference<unoidl::Entity> const & theEntity, bool theRelevant, Entity * theParent):
entity(theEntity), relevant(theRelevant), sorted(Sorted::NO),
written(Written::NO)
written(Written::NO), parent(theParent)
{}
rtl::Reference<unoidl::Entity> const entity;
@@ -150,6 +153,7 @@ struct Entity {
bool relevant;
Sorted sorted;
Written written;
Entity * parent;
};
void insertEntityDependency(
@@ -215,8 +219,8 @@ void insertTypeDependency(
void scanMap(
rtl::Reference<unoidl::Manager> const & manager,
rtl::Reference<unoidl::MapCursor> const & cursor, bool published,
std::u16string_view prefix, std::map<OUString, Entity> & entities)
rtl::Reference<unoidl::MapCursor> const & cursor, bool modules, bool published,
std::u16string_view prefix, Entity * parent, std::map<OUString, Entity> & entities)
{
assert(cursor.is());
for (;;) {
@@ -227,11 +231,17 @@ void scanMap(
}
OUString name(prefix + id);
if (ent->getSort() == unoidl::Entity::SORT_MODULE) {
Entity * p = nullptr;
if (modules) {
p = &entities.insert(std::make_pair(name, Entity(ent, !published, parent))).first
->second;
}
scanMap(
manager,
static_cast<unoidl::ModuleEntity *>(ent.get())->createCursor(),
published, OUStringConcatenation(name + "."), entities);
static_cast<unoidl::ModuleEntity *>(ent.get())->createCursor(), modules,
published, OUStringConcatenation(name + "."), p, entities);
} else {
auto const pub = static_cast<unoidl::PublishableEntity *>(ent.get())->isPublished();
std::map<OUString, Entity>::iterator i(
entities.insert(
std::make_pair(
@@ -239,10 +249,14 @@ void scanMap(
Entity(
ent,
(!published
|| (static_cast<unoidl::PublishableEntity *>(
ent.get())
->isPublished())))))
|| pub),
parent)))
.first);
if (modules && published && pub) {
for (auto j = parent; j; j = j->parent) {
j->relevant = true;
}
}
switch (ent->getSort()) {
case unoidl::Entity::SORT_ENUM_TYPE:
case unoidl::Entity::SORT_CONSTANT_GROUP:
@@ -1016,23 +1030,76 @@ void writeEntity(
}
}
void writeSummary(OUString const & name, Entity const & entity) {
if (!entity.relevant) {
return;
}
switch (entity.entity->getSort()) {
case unoidl::Entity::SORT_ENUM_TYPE:
std::cout << "enum";
break;
case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
std::cout << "struct";
break;
case unoidl::Entity::SORT_EXCEPTION_TYPE:
std::cout << "exception";
break;
case unoidl::Entity::SORT_INTERFACE_TYPE:
std::cout << "interface";
break;
case unoidl::Entity::SORT_TYPEDEF:
std::cout << "typedef";
break;
case unoidl::Entity::SORT_CONSTANT_GROUP:
std::cout << "constants";
break;
case unoidl::Entity::SORT_SINGLE_INTERFACE_BASED_SERVICE:
case unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE:
std::cout << "service";
break;
case unoidl::Entity::SORT_INTERFACE_BASED_SINGLETON:
case unoidl::Entity::SORT_SERVICE_BASED_SINGLETON:
std::cout << "singleton";
break;
case unoidl::Entity::SORT_MODULE:
std::cout << "module";
break;
}
std::cout << ' ' << name << '\n';
}
}
SAL_IMPLEMENT_MAIN() {
try {
sal_uInt32 args = rtl_getAppCommandArgCount();
if (args == 0) {
badUsage();
}
OUString arg;
rtl_getAppCommandArg(0, &arg.pData);
bool published = arg == "--published";
if (published && args == 1) {
badUsage();
sal_uInt32 i = 0;
bool published = false;
bool summary = false;
for (;; ++i) {
if (i == args) {
badUsage();
}
OUString arg;
rtl_getAppCommandArg(i, &arg.pData);
if (arg == "--published") {
if (published) {
badUsage();
}
published = true;
} else if (arg == "--summary") {
if (summary) {
badUsage();
}
summary = true;
} else {
break;
}
}
rtl::Reference<unoidl::Manager> mgr(new unoidl::Manager);
rtl::Reference<unoidl::Provider> prov;
for (sal_uInt32 i = (published ? 1 : 0); i != args; ++i) {
for (; i != args; ++i) {
OUString uri(getArgumentUri(i));
try {
prov = mgr->addProvider(uri);
@@ -1043,13 +1110,19 @@ SAL_IMPLEMENT_MAIN() {
}
}
std::map<OUString, Entity> ents;
scanMap(mgr, prov->createRootCursor(), published, u"", ents);
std::vector<OUString> sorted(sort(ents));
std::vector<OUString> mods;
for (const auto & i: sorted) {
writeEntity(ents, mods, i);
scanMap(mgr, prov->createRootCursor(), summary, published, u"", nullptr, ents);
if (summary) {
for (auto const & j: ents) {
writeSummary(j.first, j.second);
}
} else {
std::vector<OUString> sorted(sort(ents));
std::vector<OUString> mods;
for (const auto & j: sorted) {
writeEntity(ents, mods, j);
}
closeModules(mods, mods.size());
}
closeModules(mods, mods.size());
return EXIT_SUCCESS;
} catch (unoidl::FileFormatException & e1) {
std::cerr