File indexing completed on 2025-09-17 08:54:00
0001
0002
0003
0004
0005
0006
0007 #pragma once
0008
0009
0010
0011
0012 #include <algorithm>
0013 #include <fstream>
0014 #include <iostream>
0015 #include <memory>
0016 #include <string>
0017 #include <vector>
0018
0019
0020 #include "Error.hpp"
0021 #include "StringTools.hpp"
0022
0023 namespace CLI {
0024
0025
0026 class App;
0027
0028
0029 struct ConfigItem {
0030
0031 std::vector<std::string> parents{};
0032
0033
0034 std::string name{};
0035
0036 std::vector<std::string> inputs{};
0037
0038 bool multiline{false};
0039
0040 CLI11_NODISCARD std::string fullname() const {
0041 std::vector<std::string> tmp = parents;
0042 tmp.emplace_back(name);
0043 return detail::join(tmp, ".");
0044 (void)multiline;
0045 }
0046 };
0047
0048
0049 class Config {
0050 protected:
0051 std::vector<ConfigItem> items{};
0052
0053 public:
0054
0055 virtual std::string to_config(const App *, bool, bool, std::string) const = 0;
0056
0057
0058 virtual std::vector<ConfigItem> from_config(std::istream &) const = 0;
0059
0060
0061 CLI11_NODISCARD virtual std::string to_flag(const ConfigItem &item) const {
0062 if(item.inputs.size() == 1) {
0063 return item.inputs.at(0);
0064 }
0065 if(item.inputs.empty()) {
0066 return "{}";
0067 }
0068 throw ConversionError::TooManyInputsFlag(item.fullname());
0069 }
0070
0071
0072 CLI11_NODISCARD std::vector<ConfigItem> from_file(const std::string &name) const {
0073 std::ifstream input{name};
0074 if(!input.good())
0075 throw FileError::Missing(name);
0076
0077 return from_config(input);
0078 }
0079
0080
0081 virtual ~Config() = default;
0082 };
0083
0084
0085 class ConfigBase : public Config {
0086 protected:
0087
0088 char commentChar = '#';
0089
0090 char arrayStart = '[';
0091
0092 char arrayEnd = ']';
0093
0094 char arraySeparator = ',';
0095
0096 char valueDelimiter = '=';
0097
0098 char stringQuote = '"';
0099
0100 char literalQuote = '\'';
0101
0102 uint8_t maximumLayers{255};
0103
0104 char parentSeparatorChar{'.'};
0105
0106 bool commentDefaultsBool = false;
0107
0108 bool allowMultipleDuplicateFields{false};
0109
0110 int16_t configIndex{-1};
0111
0112 std::string configSection{};
0113
0114 public:
0115 std::string
0116 to_config(const App * , bool default_also, bool write_description, std::string prefix) const override;
0117
0118 std::vector<ConfigItem> from_config(std::istream &input) const override;
0119
0120 ConfigBase *comment(char cchar) {
0121 commentChar = cchar;
0122 return this;
0123 }
0124
0125 ConfigBase *arrayBounds(char aStart, char aEnd) {
0126 arrayStart = aStart;
0127 arrayEnd = aEnd;
0128 return this;
0129 }
0130
0131 ConfigBase *arrayDelimiter(char aSep) {
0132 arraySeparator = aSep;
0133 return this;
0134 }
0135
0136 ConfigBase *valueSeparator(char vSep) {
0137 valueDelimiter = vSep;
0138 return this;
0139 }
0140
0141 ConfigBase *quoteCharacter(char qString, char literalChar) {
0142 stringQuote = qString;
0143 literalQuote = literalChar;
0144 return this;
0145 }
0146
0147 ConfigBase *maxLayers(uint8_t layers) {
0148 maximumLayers = layers;
0149 return this;
0150 }
0151
0152 ConfigBase *parentSeparator(char sep) {
0153 parentSeparatorChar = sep;
0154 return this;
0155 }
0156
0157 ConfigBase *commentDefaults(bool comDef = true) {
0158 commentDefaultsBool = comDef;
0159 return this;
0160 }
0161
0162 std::string §ionRef() { return configSection; }
0163
0164 CLI11_NODISCARD const std::string §ion() const { return configSection; }
0165
0166 ConfigBase *section(const std::string §ionName) {
0167 configSection = sectionName;
0168 return this;
0169 }
0170
0171
0172 int16_t &indexRef() { return configIndex; }
0173
0174 CLI11_NODISCARD int16_t index() const { return configIndex; }
0175
0176 ConfigBase *index(int16_t sectionIndex) {
0177 configIndex = sectionIndex;
0178 return this;
0179 }
0180
0181 ConfigBase *allowDuplicateFields(bool value = true) {
0182 allowMultipleDuplicateFields = value;
0183 return this;
0184 }
0185 };
0186
0187
0188 using ConfigTOML = ConfigBase;
0189
0190
0191 class ConfigINI : public ConfigTOML {
0192
0193 public:
0194 ConfigINI() {
0195 commentChar = ';';
0196 arrayStart = '\0';
0197 arrayEnd = '\0';
0198 arraySeparator = ' ';
0199 valueDelimiter = '=';
0200 }
0201 };
0202
0203 }