mirror of
https://github.com/CLIUtils/CLI11.git
synced 2025-04-29 20:23:55 +00:00
Refactor some of the configuration file handling code. Make it easier to get the actual file that was processed, and allow extras in the config file to be ignored (default now), captured or errored. fix std::error reference and formatting add test for required but no default and fix a shadow warning on 'required' from gcc 4.8 Test correctness of config write-read loop fix config generation for flag definitions make the config output conform with toml continue work on the config file interpretation and construction get all the ini tests working again with the cleaned up features. update formatting rename IniTest to ConfigFileTest to better reflect actual tests and add a few more test of the configTOML disambiguate enable/disable by default to an enumeration, and to make room for a configurable option to allow subcommands to be triggered by a config file. add a ConfigBase class to generally reflect a broader class of configuration files formats of similar nature to INI files add configurable to app and allow it to trigger subcommands add test of ini formatting add section support to the config files so sections can be opened and closed and the callbacks triggered as appropriate. add handling of option groups to the config file output add subcommand and option group configuration to config file output subsubcom test on config files fix a few sign comparison warnings and formatting start working on the book edits for configuration and a few more tests more test to check for subcommand close in config files more tests for coverage generalize section opening and closing add more tests and some fixes for different configurations yet more tests of different situations related to configuration files test more paths for configuration file sections remove some unused code and fix some codacy warnings update readme with updates from configuration files more book edits and README formatting remove extra space Apply suggestions from code review Co-Authored-By: Henry Schreiner <HenrySchreinerIII@gmail.com> fix some comments and documentation fix spacing Rename size_t -> std::size_t Fix compiler warnings with -Wsign-conversion Fix new warnings with -Wsign-conversion in PR
128 lines
3.5 KiB
C++
128 lines
3.5 KiB
C++
#pragma once
|
|
|
|
// Distributed under the 3-Clause BSD License. See accompanying
|
|
// file LICENSE or https://github.com/CLIUtils/CLI11 for details.
|
|
|
|
#include <algorithm>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
#include "CLI/Error.hpp"
|
|
#include "CLI/StringTools.hpp"
|
|
|
|
namespace CLI {
|
|
|
|
class App;
|
|
|
|
/// Holds values to load into Options
|
|
struct ConfigItem {
|
|
/// This is the list of parents
|
|
std::vector<std::string> parents{};
|
|
|
|
/// This is the name
|
|
std::string name{};
|
|
|
|
/// Listing of inputs
|
|
std::vector<std::string> inputs{};
|
|
|
|
/// The list of parents and name joined by "."
|
|
std::string fullname() const {
|
|
std::vector<std::string> tmp = parents;
|
|
tmp.emplace_back(name);
|
|
return detail::join(tmp, ".");
|
|
}
|
|
};
|
|
|
|
/// This class provides a converter for configuration files.
|
|
class Config {
|
|
protected:
|
|
std::vector<ConfigItem> items{};
|
|
|
|
public:
|
|
/// Convert an app into a configuration
|
|
virtual std::string to_config(const App *, bool, bool, std::string) const = 0;
|
|
|
|
/// Convert a configuration into an app
|
|
virtual std::vector<ConfigItem> from_config(std::istream &) const = 0;
|
|
|
|
/// Get a flag value
|
|
virtual std::string to_flag(const ConfigItem &item) const {
|
|
if(item.inputs.size() == 1) {
|
|
return item.inputs.at(0);
|
|
}
|
|
throw ConversionError::TooManyInputsFlag(item.fullname());
|
|
}
|
|
|
|
/// Parse a config file, throw an error (ParseError:ConfigParseError or FileError) on failure
|
|
std::vector<ConfigItem> from_file(const std::string &name) {
|
|
std::ifstream input{name};
|
|
if(!input.good())
|
|
throw FileError::Missing(name);
|
|
|
|
return from_config(input);
|
|
}
|
|
|
|
/// Virtual destructor
|
|
virtual ~Config() = default;
|
|
};
|
|
|
|
/// This converter works with INI/TOML files; to write proper TOML files use ConfigTOML
|
|
class ConfigBase : public Config {
|
|
protected:
|
|
/// the character used for comments
|
|
char commentChar = ';';
|
|
/// the character used to start an array '\0' is a default to not use
|
|
char arrayStart = '\0';
|
|
/// the character used to end an array '\0' is a default to not use
|
|
char arrayEnd = '\0';
|
|
/// the character used to separate elements in an array
|
|
char arraySeparator = ' ';
|
|
/// the character used separate the name from the value
|
|
char valueDelimiter = '=';
|
|
|
|
public:
|
|
std::string
|
|
to_config(const App * /*app*/, bool default_also, bool write_description, std::string prefix) const override;
|
|
|
|
std::vector<ConfigItem> from_config(std::istream &input) const override;
|
|
/// Specify the configuration for comment characters
|
|
ConfigBase *comment(char cchar) {
|
|
commentChar = cchar;
|
|
return this;
|
|
}
|
|
/// Specify the start and end characters for an array
|
|
ConfigBase *arrayBounds(char aStart, char aEnd) {
|
|
arrayStart = aStart;
|
|
arrayEnd = aEnd;
|
|
return this;
|
|
}
|
|
/// Specify the delimiter character for an array
|
|
ConfigBase *arrayDelimiter(char aSep) {
|
|
arraySeparator = aSep;
|
|
return this;
|
|
}
|
|
/// Specify the delimiter between a name and value
|
|
ConfigBase *valueSeparator(char vSep) {
|
|
valueDelimiter = vSep;
|
|
return this;
|
|
}
|
|
};
|
|
|
|
/// the default Config is the INI file format
|
|
using ConfigINI = ConfigBase;
|
|
|
|
/// ConfigTOML generates a TOML compliant output
|
|
class ConfigTOML : public ConfigINI {
|
|
|
|
public:
|
|
ConfigTOML() {
|
|
commentChar = '#';
|
|
arrayStart = '[';
|
|
arrayEnd = ']';
|
|
arraySeparator = ',';
|
|
valueDelimiter = '=';
|
|
}
|
|
};
|
|
} // namespace CLI
|