Skip to content
Merged
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
75 changes: 54 additions & 21 deletions src/lib/Lib/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ struct PublicSettingsVisitor {
std::string& value,
ReferenceDirectories const& dirs,
PublicSettings::OptionProperties const& opts,
bool const usingDefault) {
bool const usingDefault)
{
// If the path is not absolute, we need to expand it
if (!files::isAbsolute(value))
{
Expand Down Expand Up @@ -256,39 +257,71 @@ struct PublicSettingsVisitor {
PublicSettings::OptionProperties const& opts,
bool const usingDefault) const
{
for (auto& value : values)
// Move command line sink values to appropriate destinations
// Normalization happens later for each destination
if (opts.commandLineSink && opts.filenameMapping.has_value())
{
MRDOCS_TRY(normalizeCmdLineSink(self, values, opts));
}
else
{
MRDOCS_DECL(normalizeStringPath(self, name, value, dirs, opts, usingDefault));
// General case, normalize each path
for (auto& value : values)
{
MRDOCS_TRY(normalizeStringPath(self, name, value, dirs, opts, usingDefault));
}
}
return {};
}

template <class T>
Expected<void>
normalizeCmdLineSink(
PublicSettings& self,
T& values,
PublicSettings::OptionProperties const& opts) const
{
// Move command line sink values to appropriate destinations
if (opts.commandLineSink && opts.filenameMapping.has_value())
for (auto& value : values)
{
for (auto& value : values)
std::string_view filename = files::getFileName(value);
auto it = opts.filenameMapping->find(std::string(filename));
if (it == opts.filenameMapping->end())
{
report::warn("command line input: unknown destination for filename \"{}\"", filename);
continue;
}
// Assign the value to the destination option of the map
std::string const& destOption = it->second;
bool foundOption = false;
bool setOption = false;
self.visit(
[&]<typename U>(
std::string_view const optionName, U& optionValue)
{
for (auto const& map = opts.filenameMapping.value();
auto& [from, to] : map)
if constexpr (std::convertible_to<U, std::string>)
{
auto filename = files::getFileName(value);
if (filename == from)
if (optionName == destOption)
{
self.visit(
[&]<typename U>(
std::string_view const otherName, U& otherValue)
foundOption = true;
if (optionValue.empty())
{
if constexpr (std::convertible_to<U, std::string>)
{
if (otherName == to)
{
otherValue = value;
}
}
});
optionValue = value;
setOption = true;
}
}
}
});
if (!foundOption)
{
report::warn("command line input: cannot find destination option \"{}\"", destOption);
}
else if (!setOption)
{
report::warn("command line input: destination option was \"{}\" already set", destOption);
}
}

values.clear();
return {};
}

Expand Down
4 changes: 2 additions & 2 deletions src/lib/Lib/ConfigOptions.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"command-line-sink": true,
"filename-mapping": {
"mrdocs.yml": "config",
"compile_commands.json": "compilationDatabase",
"CMakeLists.txt": "compilationDatabase"
"compile_commands.json": "compilation-database",
"CMakeLists.txt": "compilation-database"
},
"relative-to": "<cwd>",
"must-exist": true,
Expand Down
56 changes: 32 additions & 24 deletions src/tool/ToolMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
#include <llvm/Support/PrettyStackTrace.h>
#include <llvm/Support/Signals.h>
#include <cstdlib>
#include <ranges>

extern int main(int argc, char const** argv);

namespace clang {
namespace mrdocs {
namespace clang::mrdocs {

extern
int
Expand All @@ -47,7 +47,7 @@ print_version(llvm::raw_ostream& os)
<< "\n";
}

Expected<std::pair<std::string, ReferenceDirectories>>
Expected<ReferenceDirectories>
getReferenceDirectories(std::string const& execPath)
{
ReferenceDirectories dirs;
Expand All @@ -58,36 +58,37 @@ getReferenceDirectories(std::string const& execPath)
return Unexpected(formatError("Unable to determine current working directory: {}", ec.message()));
}
dirs.cwd = std::string(cwd.data(), cwd.size());
return dirs;
}

Expected<std::string>
getConfigPath(ReferenceDirectories const& dirs)
{
std::string configPath;
if (toolArgs.config.getValue() != "")
auto cmdLineFilenames = std::ranges::views::transform(
toolArgs.cmdLineInputs, files::getFileName);
if (!toolArgs.config.getValue().empty())
{
// From explicit --config argument
configPath = toolArgs.config.getValue();
}
else
else if (auto const it = std::ranges::find(cmdLineFilenames, "mrdocs.yml");
it != cmdLineFilenames.end())
{
llvm::cl::list<std::string>& inputs = toolArgs.cmdLineInputs;
for (auto& input: inputs)
{
if (files::getFileName(input) == "mrdocs.yml")
{
configPath = input;
break;
}
}
// From implicit command line inputs
configPath = *(it.base());
}
if (configPath.empty())
else if (files::exists("./mrdocs.yml"))
{
if (files::exists("./mrdocs.yml"))
{
configPath = "./mrdocs.yml";
}
// From current directory
configPath = "./mrdocs.yml";
}
if (configPath.empty())
else
{
return Unexpected(formatError("The config path is missing"));
}
configPath = files::makeAbsolute(configPath, dirs.cwd);
return std::make_pair(configPath, dirs);
return configPath;
}

int
Expand Down Expand Up @@ -129,7 +130,15 @@ mrdocs_main(int argc, char const** argv)
report::fatal("Failed to determine reference directories: {}", res.error().message());
return EXIT_FAILURE;
}
auto [configPath, dirs] = *res;
auto dirs = *std::move(res);

auto expConfigPath = getConfigPath(dirs);
if (!expConfigPath)
{
report::fatal("Failed to determine config path: {}", expConfigPath.error().message());
return EXIT_FAILURE;
}
auto configPath = *std::move(expConfigPath);

// Generate
auto exp = DoGenerateAction(configPath, dirs, argv);
Expand All @@ -156,8 +165,7 @@ reportUnhandledException(
sys::PrintStackTrace(llvm::errs());
}

} // mrdocs
} // clang
} // clang::mrdocs

int
main(int argc, char const** argv)
Expand Down
10 changes: 5 additions & 5 deletions util/generate-config-info.py
Original file line number Diff line number Diff line change
Expand Up @@ -839,11 +839,11 @@ def generate_toolargs_final_option_initializer(option, category_str, parents=Non
if option['command-line-sink']:
constructor_args.append('llvm::cl::Sink')
if 'default' in option:
if option["type"] in ['string', 'enum']:
constructor_args.append(f'llvm::cl::init("{option["default"]}")')
elif option["type"] in ['path', 'file-path', 'dir-path']:
constructor_args.append(f'llvm::cl::init("{remove_reference_dir_from_path(option["default"])}")')
elif option['type'] in ['unsigned', 'int']:
# if option["type"] in ['string', 'enum']:
# constructor_args.append(f'llvm::cl::init("{option["default"]}")')
# elif option["type"] in ['path', 'file-path', 'dir-path']:
# constructor_args.append(f'llvm::cl::init("{remove_reference_dir_from_path(option["default"])}")')
if option['type'] in ['unsigned', 'int']:
constructor_args.append(f'llvm::cl::init({option["default"]})')
elif option['type'] == 'bool':
bool_str = 'true' if option['default'] else 'false'
Expand Down
Loading