Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: tagfiles generation for cross-referencing in doxygen format #670

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions include/mrdocs/Corpus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,39 @@ class MRDOCS_VISIBLE
}
}

/** Visit the members of specified Info.

This function iterates the members of the specified
Info `I`. For each member associated with a
function with the same name as the member, the
function object `f` is invoked with the member
as the first argument, followed by `args...`.

When there are more than one member function
with the same name, the function object `f` is
invoked with an @ref OverloadSet as the first
argument, followed by `args...`.

@param I The Info to traverse.
@param pred The predicate to use to determine if the member should be visited.
@param f The function to invoke with the member as the first argument, followed by `args...`.
@param args The arguments to pass to the function.
*/
template <InfoParent T, class Pred, class F, class... Args>
void
traverseIf(
T const& I, Pred&& pred, F&& f, Args&&... args) const
{
for (auto const& id : I.Members)
{
if (pred(get(id)))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::forward<Pred>(pred)(get(id)) ? I'm not sure.

{
visit(get(id), std::forward<F>(f),
std::forward<Args>(args)...);
}
}
}

/** Visit the function members of specified Info.

This function iterates the members of the specified
Expand Down
5 changes: 4 additions & 1 deletion include/mrdocs/Generator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -115,13 +115,16 @@ class MRDOCS_VISIBLE
@param os The stream to write to.

@param corpus The metadata to emit.

@param fileName The file name to use for the output.
*/
MRDOCS_DECL
virtual
Error
buildOne(
std::ostream& os,
Corpus const& corpus) const = 0;
Corpus const& corpus,
std::string_view fileName) const = 0;

/** Build the reference as a single page to a file.

Expand Down
66 changes: 63 additions & 3 deletions src/lib/Gen/adoc/AdocGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
#include "MultiPageVisitor.hpp"
#include "SinglePageVisitor.hpp"
#include "lib/Support/LegibleNames.hpp"
#include "lib/Support/RawOstream.hpp"
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/Path.h>
#include <mrdocs/Metadata/DomMetadata.hpp>
#include <mrdocs/Support/Error.hpp>
#include <mrdocs/Support/Path.hpp>
#include <fstream>
#include <optional>
#include <vector>

Expand Down Expand Up @@ -70,10 +74,35 @@ build(
if(! ex)
return ex.error();

MultiPageVisitor visitor(*ex, outputPath, corpus);
std::string path = files::appendPath(outputPath, "reference.tag.xml");
if(auto err = files::createDirectory(outputPath))
{
return err;
}

std::ofstream os;
try
{
os.open(path,
std::ios_base::binary |
std::ios_base::out |
std::ios_base::trunc // | std::ios_base::noreplace
);
}
catch(std::exception const& ex)
{
return formatError("std::ofstream(\"{}\") threw \"{}\"", path, ex.what());
}

RawOstream raw_os(os);
auto tagfileWriter = TagfileWriter(raw_os, corpus);
tagfileWriter.initialize();

MultiPageVisitor visitor(*ex, outputPath, corpus, tagfileWriter);
visitor(corpus.globalNamespace());

auto errors = ex->wait();
tagfileWriter.finalize();
if(! errors.empty())
return Error(errors);
return Error::success();
Expand All @@ -83,8 +112,12 @@ Error
AdocGenerator::
buildOne(
std::ostream& os,
Corpus const& corpus) const
Corpus const& corpus,
std::string_view outputPath) const
{
namespace path = llvm::sys::path;
using SmallString = llvm::SmallString<0>;

auto options = loadOptions(corpus);
if(! options)
return options.error();
Expand All @@ -106,9 +139,36 @@ buildOne(
if(! errors.empty())
return {errors};

SinglePageVisitor visitor(*ex, corpus, os);
SmallString fileName(outputPath);
path::replace_extension(fileName, "tag.xml");
auto parentDir = files::getParentDir(fileName.str());
if(auto err = files::createDirectory(parentDir))
{
return err;
}

std::ofstream osTagfile;
try
{
osTagfile.open(fileName.str().str(),
std::ios_base::binary |
std::ios_base::out |
std::ios_base::trunc // | std::ios_base::noreplace
);
}
catch(std::exception const& ex)
{
return formatError("std::ofstream(\"{}\") threw \"{}\"", fileName.str().str(), ex.what());
}

RawOstream raw_os(osTagfile);
auto tagfileWriter = TagfileWriter(raw_os, corpus);
tagfileWriter.initialize();

SinglePageVisitor visitor(*ex, corpus, os, outputPath, tagfileWriter);
visitor(corpus.globalNamespace());
errors = ex->wait();
tagfileWriter.finalize();
if(! errors.empty())
return {errors};

Expand Down
3 changes: 2 additions & 1 deletion src/lib/Gen/adoc/AdocGenerator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ class AdocGenerator
Error
buildOne(
std::ostream& os,
Corpus const& corpus) const override;
Corpus const& corpus,
std::string_view fileName) const override;
};

} // adoc
Expand Down
8 changes: 6 additions & 2 deletions src/lib/Gen/adoc/MultiPageVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,12 @@ operator()(T const& I)
{
ex_.async([this, &I](Builder& builder)
{
if(const auto r = builder(I))
writePage(*r, builder.domCorpus.getXref(I));
if(const auto r = builder(I))
{
auto const xref = builder.domCorpus.getXref(I);
writePage(*r, xref);
tagfileWriter_(I, xref);
}
else
r.error().Throw();
if constexpr(
Expand Down
6 changes: 5 additions & 1 deletion src/lib/Gen/adoc/MultiPageVisitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define MRDOCS_LIB_GEN_ADOC_MULTIPAGEVISITOR_HPP

#include "Builder.hpp"
#include <lib/Lib/TagfileWriter.hpp>
#include <mrdocs/Support/ExecutorGroup.hpp>
#include <mutex>
#include <ostream>
Expand All @@ -29,6 +30,7 @@ class MultiPageVisitor
ExecutorGroup<Builder>& ex_;
std::string_view outputPath_;
Corpus const& corpus_;
TagfileWriter& tagfileWriter_;

void
writePage(
Expand All @@ -39,10 +41,12 @@ class MultiPageVisitor
MultiPageVisitor(
ExecutorGroup<Builder>& ex,
std::string_view outputPath,
Corpus const& corpus) noexcept
Corpus const& corpus,
TagfileWriter& tagfileWriter) noexcept
: ex_(ex)
, outputPath_(outputPath)
, corpus_(corpus)
, tagfileWriter_(tagfileWriter)
{
}

Expand Down
5 changes: 4 additions & 1 deletion src/lib/Gen/adoc/SinglePageVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ operator()(T const& I)
{
ex_.async([this, &I, page = numPages_++](Builder& builder)
{
if(auto r = builder(I))
if(auto r = builder(I))
{
writePage(*r, page);
tagfileWriter_(I, fileName_);
}
else
r.error().Throw();
});
Expand Down
9 changes: 8 additions & 1 deletion src/lib/Gen/adoc/SinglePageVisitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "Builder.hpp"
#include <mrdocs/MetadataFwd.hpp>
#include <lib/Lib/TagfileWriter.hpp>
#include <mrdocs/Support/ExecutorGroup.hpp>
#include <mutex>
#include <ostream>
Expand All @@ -35,16 +36,22 @@ class SinglePageVisitor
std::size_t topPage_ = 0;
std::vector<std::optional<
std::string>> pages_;
std::string fileName_;
TagfileWriter& tagfileWriter_;

void writePage(std::string pageText, std::size_t pageNumber);
public:
SinglePageVisitor(
ExecutorGroup<Builder>& ex,
Corpus const& corpus,
std::ostream& os) noexcept
std::ostream& os,
std::string_view fileName,
TagfileWriter& tagfileWriter) noexcept
: ex_(ex)
, corpus_(corpus)
, os_(os)
, fileName_(fileName)
, tagfileWriter_(tagfileWriter)
{
}

Expand Down
66 changes: 63 additions & 3 deletions src/lib/Gen/html/HTMLGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
#include "MultiPageVisitor.hpp"
#include "SinglePageVisitor.hpp"
#include "lib/Support/LegibleNames.hpp"
#include "lib/Support/RawOstream.hpp"
#include <llvm/Support/FileSystem.h>
#include <llvm/Support/Path.h>
#include <mrdocs/Metadata/DomMetadata.hpp>
#include <mrdocs/Support/Error.hpp>
#include <mrdocs/Support/Path.hpp>
#include <fstream>
#include <optional>
#include <vector>

Expand Down Expand Up @@ -67,9 +71,34 @@ build(
if(! ex)
return ex.error();

MultiPageVisitor visitor(*ex, outputPath, corpus);
std::string path = files::appendPath(outputPath, "reference.tag.xml");
if(auto err = files::createDirectory(outputPath))
{
return err;
}

std::ofstream os;
try
{
os.open(path,
std::ios_base::binary |
std::ios_base::out |
std::ios_base::trunc // | std::ios_base::noreplace
);
}
catch(std::exception const& ex)
{
return formatError("std::ofstream(\"{}\") threw \"{}\"", path, ex.what());
}

RawOstream raw_os(os);
auto tagfileWriter = TagfileWriter(raw_os, corpus);
tagfileWriter.initialize();

MultiPageVisitor visitor(*ex, outputPath, corpus, tagfileWriter);
visitor(corpus.globalNamespace());
auto errors = ex->wait();
tagfileWriter.finalize();
if(! errors.empty())
return Error(errors);
return Error::success();
Expand All @@ -79,8 +108,12 @@ Error
HTMLGenerator::
buildOne(
std::ostream& os,
Corpus const& corpus) const
Corpus const& corpus,
std::string_view outputPath) const
{
namespace path = llvm::sys::path;
using SmallString = llvm::SmallString<0>;

HTMLCorpus domCorpus(corpus);
auto ex = createExecutors(domCorpus);
if(! ex)
Expand All @@ -98,9 +131,36 @@ buildOne(
if(! errors.empty())
return Error(errors);

SinglePageVisitor visitor(*ex, corpus, os);
SmallString fileName(outputPath);
path::replace_extension(fileName, "tag.xml");
auto parentDir = files::getParentDir(fileName.str());
if(auto err = files::createDirectory(parentDir))
{
return err;
}

std::ofstream osTagfile;
try
{
osTagfile.open(fileName.str().str(),
std::ios_base::binary |
std::ios_base::out |
std::ios_base::trunc // | std::ios_base::noreplace
);
}
catch(std::exception const& ex)
{
return formatError("std::ofstream(\"{}\") threw \"{}\"", fileName.str().str(), ex.what());
}

RawOstream raw_os(osTagfile);
auto tagfileWriter = TagfileWriter(raw_os, corpus);
tagfileWriter.initialize();

SinglePageVisitor visitor(*ex, corpus, os, outputPath, tagfileWriter);
visitor(corpus.globalNamespace());
errors = ex->wait();
tagfileWriter.finalize();
if(! errors.empty())
return Error(errors);

Expand Down
3 changes: 2 additions & 1 deletion src/lib/Gen/html/HTMLGenerator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ class HTMLGenerator
Error
buildOne(
std::ostream& os,
Corpus const& corpus) const override;
Corpus const& corpus,
std::string_view fileName) const override;
};

} // html
Expand Down
1 change: 1 addition & 0 deletions src/lib/Gen/html/MultiPageVisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ renderPage(
std::ios_base::trunc // | std::ios_base::noreplace
);
os.write(pageText.data(), pageText.size());
tagfileWriter_(I, fileName);
}
catch(std::exception const& ex)
{
Expand Down
Loading
Loading