Skip to content

Commit 8da09e3

Browse files
committed
feat(lib): public API for generator registration
closes #313
1 parent 4763d86 commit 8da09e3

File tree

8 files changed

+239
-44
lines changed

8 files changed

+239
-44
lines changed

include/mrdocs/Generator.hpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
8+
// Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
89
//
910
// Official repository: https://github.com/cppalliance/mrdocs
1011
//
@@ -19,6 +20,7 @@
1920
#include <mrdocs/Config.hpp>
2021
#include <mrdocs/Corpus.hpp>
2122
#include <mrdocs/Support/Error.hpp>
23+
#include <memory>
2224
#include <ostream>
2325
#include <string>
2426
#include <string_view>
@@ -201,11 +203,50 @@ class MRDOCS_VISIBLE
201203
@param outputPath The specified output path, which can be a directory or file.
202204
@param extension The file extension to use for single-page output.
203205
*/
206+
MRDOCS_DECL
204207
Expected<std::string>
205208
getSinglePageFullPath(
206209
std::string_view outputPath,
207210
std::string_view extension);
208211

212+
/** Install a custom generator.
213+
214+
This function registers a generator with the global
215+
generator registry, making it available for use.
216+
217+
Plugins can use this function to register custom
218+
generators.
219+
220+
@par Thread Safety
221+
This function is thread-safe and may be called
222+
concurrently from multiple threads.
223+
224+
@return An error if a generator with the same id
225+
already exists.
226+
227+
@param G The generator to install. Ownership is
228+
transferred to the registry.
229+
*/
230+
MRDOCS_DECL
231+
Expected<void>
232+
installGenerator(std::unique_ptr<Generator> G);
233+
234+
/** Find a generator by its id.
235+
236+
@par Thread Safety
237+
This function is thread-safe and may be called
238+
concurrently from multiple threads.
239+
240+
@return A pointer to the generator, or `nullptr`
241+
if no generator with the given id exists.
242+
243+
@param id The symbolic name of the generator.
244+
The name must be an exact match, including case.
245+
*/
246+
MRDOCS_DECL
247+
Generator const*
248+
findGenerator(std::string_view id) noexcept;
249+
209250
} // mrdocs
210251

211252

src/lib/Support/Generator.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
8+
// Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
89
//
910
// Official repository: https://github.com/cppalliance/mrdocs
1011
//
1112

1213
#include <lib/AST/ExtractDocComment.hpp>
1314
#include <lib/Support/Chrono.hpp>
15+
#include <lib/Support/GeneratorRegistryImpl.hpp>
1416
#include <lib/Support/Path.hpp>
1517
#include <mrdocs/Generator.hpp>
1618
#include <mrdocs/Support/Error.hpp>
@@ -156,5 +158,17 @@ getSinglePageFullPath(
156158
return fileName.str().str();
157159
}
158160

161+
Expected<void>
162+
installGenerator(std::unique_ptr<Generator> G)
163+
{
164+
return getGeneratorRegistryImpl().insert(std::move(G));
165+
}
166+
167+
Generator const*
168+
findGenerator(std::string_view id) noexcept
169+
{
170+
return getGeneratorRegistryImpl().find(id);
171+
}
172+
159173
} // mrdocs
160174

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55
//
66
// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
7+
// Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
78
//
89
// Official repository: https://github.com/cppalliance/mrdocs
910
//
1011

11-
#ifndef MRDOCS_API_GENERATORS_HPP
12-
#define MRDOCS_API_GENERATORS_HPP
12+
#ifndef MRDOCS_LIB_SUPPORT_GENERATORREGISTRY_HPP
13+
#define MRDOCS_LIB_SUPPORT_GENERATORREGISTRY_HPP
1314

1415
#include <mrdocs/Platform.hpp>
1516
#include <mrdocs/Generator.hpp>
@@ -22,11 +23,11 @@ namespace mrdocs {
2223
/** A dynamic list of @ref Generator elements.
2324
*/
2425
class MRDOCS_VISIBLE
25-
Generators
26+
GeneratorRegistry
2627
{
2728
protected:
2829
/// Construct an empty generator registry; only derived singletons create this.
29-
Generators() noexcept = default;
30+
GeneratorRegistry() noexcept = default;
3031

3132
public:
3233
/// Pointer type for generator entries.
@@ -48,7 +49,7 @@ class MRDOCS_VISIBLE
4849
*/
4950
MRDOCS_DECL
5051
virtual
51-
~Generators() noexcept;
52+
~GeneratorRegistry() noexcept;
5253

5354
/** Return an iterator to the beginning.
5455
*/
@@ -78,13 +79,7 @@ class MRDOCS_VISIBLE
7879
std::string_view name) const noexcept = 0;
7980
};
8081

81-
/** Return a reference to the global Generators instance.
82-
*/
83-
MRDOCS_DECL
84-
Generators const&
85-
getGenerators() noexcept;
86-
8782
} // mrdocs
8883

8984

90-
#endif // MRDOCS_API_GENERATORS_HPP
85+
#endif // MRDOCS_LIB_SUPPORT_GENERATORREGISTRY_HPP
Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55
//
66
// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
7+
// Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
78
//
89
// Official repository: https://github.com/cppalliance/mrdocs
910
//
1011

11-
#include "GeneratorsImpl.hpp"
12+
#include "GeneratorRegistryImpl.hpp"
1213
#include <mrdocs/Support/Report.hpp>
1314
#include <llvm/ADT/STLExtras.h>
1415

@@ -27,11 +28,11 @@ extern
2728
std::unique_ptr<Generator>
2829
makeHTMLGenerator();
2930

30-
Generators::
31-
~Generators() noexcept = default;
31+
GeneratorRegistry::
32+
~GeneratorRegistry() noexcept = default;
3233

3334
void
34-
GeneratorsImpl::
35+
GeneratorRegistryImpl::
3536
refresh_plist()
3637
{
3738
plist_.clear();
@@ -40,19 +41,20 @@ refresh_plist()
4041
plist_.push_back(g.get());
4142
}
4243

43-
GeneratorsImpl::
44-
GeneratorsImpl()
44+
GeneratorRegistryImpl::
45+
GeneratorRegistryImpl()
4546
{
4647
insert(makeAdocGenerator());
4748
insert(makeXMLGenerator());
4849
insert(makeHTMLGenerator());
4950
}
5051

5152
Generator const*
52-
GeneratorsImpl::
53+
GeneratorRegistryImpl::
5354
find(
5455
std::string_view id) const noexcept
5556
{
57+
std::lock_guard<std::mutex> lock(mutex_);
5658
for (auto const& li : list_)
5759
{
5860
if(li->id() == id)
@@ -64,30 +66,34 @@ find(
6466
}
6567

6668
Expected<void>
67-
GeneratorsImpl::
69+
GeneratorRegistryImpl::
6870
insert(
6971
std::unique_ptr<Generator> G)
7072
{
71-
MRDOCS_CHECK(find(G->id()) == nullptr, formatError("generator id=\"{}\" already exists", G->id()));
73+
if (!G)
74+
{
75+
return Unexpected(formatError("cannot install null generator"));
76+
}
77+
std::lock_guard<std::mutex> lock(mutex_);
78+
for (auto const& li : list_)
79+
{
80+
if (li->id() == G->id())
81+
{
82+
return Unexpected(formatError("generator id=\"{}\" already exists", G->id()));
83+
}
84+
}
7285
list_.emplace_back(std::move(G));
7386
refresh_plist();
7487
return {};
7588
}
7689

7790
//------------------------------------------------
7891

79-
GeneratorsImpl&
80-
getGeneratorsImpl() noexcept
92+
GeneratorRegistryImpl&
93+
getGeneratorRegistryImpl() noexcept
8194
{
82-
static GeneratorsImpl impl;
95+
static GeneratorRegistryImpl impl;
8396
return impl;
8497
}
8598

86-
Generators const&
87-
getGenerators() noexcept
88-
{
89-
return getGeneratorsImpl();
90-
}
91-
9299
} // mrdocs
93-
Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,36 +4,39 @@
44
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
55
//
66
// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
7+
// Copyright (c) 2023 Alan de Freitas (alandefreitas@gmail.com)
78
//
89
// Official repository: https://github.com/cppalliance/mrdocs
910
//
1011

11-
#ifndef MRDOCS_LIB_SUPPORT_GENERATORSIMPL_HPP
12-
#define MRDOCS_LIB_SUPPORT_GENERATORSIMPL_HPP
12+
#ifndef MRDOCS_LIB_SUPPORT_GENERATORREGISTRYIMPL_HPP
13+
#define MRDOCS_LIB_SUPPORT_GENERATORREGISTRYIMPL_HPP
1314

1415
#include <mrdocs/Platform.hpp>
15-
#include <mrdocs/Generators.hpp>
16+
#include <lib/Support/GeneratorRegistry.hpp>
1617
#include <mrdocs/Support/Error.hpp>
1718
#include <llvm/ADT/SmallVector.h>
1819
#include <memory>
20+
#include <mutex>
1921
#include <vector>
2022

2123

2224
namespace mrdocs {
2325

24-
/** Implementaiton of Generators.
26+
/** Implementation of GeneratorRegistry.
2527
*/
2628
class MRDOCS_VISIBLE
27-
GeneratorsImpl : public Generators
29+
GeneratorRegistryImpl : public GeneratorRegistry
2830
{
31+
mutable std::mutex mutex_;
2932
llvm::SmallVector<Generator const*, 3> plist_;
3033
llvm::SmallVector<
3134
std::unique_ptr<Generator>> list_;
3235

3336
void refresh_plist();
3437

3538
public:
36-
GeneratorsImpl();
39+
GeneratorRegistryImpl();
3740

3841
iterator
3942
begin() const noexcept override
@@ -57,10 +60,10 @@ class MRDOCS_VISIBLE
5760
insert(std::unique_ptr<Generator> G);
5861
};
5962

60-
/** Return a reference to the global GeneratorsImpl instance.
63+
/** Return a reference to the global GeneratorRegistryImpl instance.
6164
*/
62-
GeneratorsImpl&
63-
getGeneratorsImpl() noexcept;
65+
GeneratorRegistryImpl&
66+
getGeneratorRegistryImpl() noexcept;
6467

6568
} // mrdocs
6669

src/test/TestRunner.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#include <lib/Support/Path.hpp>
2424
#include <lib/Support/Report.hpp>
2525
#include <mrdocs/Config.hpp>
26-
#include <mrdocs/Generators.hpp>
26+
#include <mrdocs/Generator.hpp>
2727
#include <mrdocs/Support/Error.hpp>
2828
#include <test_suite/diff.hpp>
2929
#include <llvm/Support/CommandLine.h>
@@ -37,7 +37,7 @@ namespace mrdocs {
3737

3838
TestRunner::
3939
TestRunner(std::string_view generator)
40-
: gen_(getGenerators().find(generator))
40+
: gen_(findGenerator(generator))
4141
{
4242
MRDOCS_ASSERT(gen_ != nullptr);
4343
}

0 commit comments

Comments
 (0)