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