Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:54:44

0001 // Copyright (c) 2017-2023, University of Cincinnati, developed by Henry Schreiner
0002 // under NSF AWARD 1414736 and by the respective contributors.
0003 // All rights reserved.
0004 //
0005 // SPDX-License-Identifier: BSD-3-Clause
0006 
0007 #pragma once
0008 
0009 // [CLI11:public_includes:set]
0010 #include <algorithm>
0011 #include <fstream>
0012 #include <iostream>
0013 #include <string>
0014 #include <vector>
0015 // [CLI11:public_includes:end]
0016 
0017 #include "Error.hpp"
0018 #include "StringTools.hpp"
0019 
0020 namespace CLI {
0021 // [CLI11:config_fwd_hpp:verbatim]
0022 
0023 class App;
0024 
0025 /// Holds values to load into Options
0026 struct ConfigItem {
0027     /// This is the list of parents
0028     std::vector<std::string> parents{};
0029 
0030     /// This is the name
0031     std::string name{};
0032 
0033     /// Listing of inputs
0034     std::vector<std::string> inputs{};
0035 
0036     /// The list of parents and name joined by "."
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 /// This class provides a converter for configuration files.
0045 class Config {
0046   protected:
0047     std::vector<ConfigItem> items{};
0048 
0049   public:
0050     /// Convert an app into a configuration
0051     virtual std::string to_config(const App *, bool, bool, std::string) const = 0;
0052 
0053     /// Convert a configuration into an app
0054     virtual std::vector<ConfigItem> from_config(std::istream &) const = 0;
0055 
0056     /// Get a flag value
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());  // LCOV_EXCL_LINE
0065     }
0066 
0067     /// Parse a config file, throw an error (ParseError:ConfigParseError or FileError) on failure
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     /// Virtual destructor
0077     virtual ~Config() = default;
0078 };
0079 
0080 /// This converter works with INI/TOML files; to write INI files use ConfigINI
0081 class ConfigBase : public Config {
0082   protected:
0083     /// the character used for comments
0084     char commentChar = '#';
0085     /// the character used to start an array '\0' is a default to not use
0086     char arrayStart = '[';
0087     /// the character used to end an array '\0' is a default to not use
0088     char arrayEnd = ']';
0089     /// the character used to separate elements in an array
0090     char arraySeparator = ',';
0091     /// the character used separate the name from the value
0092     char valueDelimiter = '=';
0093     /// the character to use around strings
0094     char stringQuote = '"';
0095     /// the character to use around single characters
0096     char characterQuote = '\'';
0097     /// the maximum number of layers to allow
0098     uint8_t maximumLayers{255};
0099     /// the separator used to separator parent layers
0100     char parentSeparatorChar{'.'};
0101     /// Specify the configuration index to use for arrayed sections
0102     int16_t configIndex{-1};
0103     /// Specify the configuration section that should be used
0104     std::string configSection{};
0105 
0106   public:
0107     std::string
0108     to_config(const App * /*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     /// Specify the configuration for comment characters
0112     ConfigBase *comment(char cchar) {
0113         commentChar = cchar;
0114         return this;
0115     }
0116     /// Specify the start and end characters for an array
0117     ConfigBase *arrayBounds(char aStart, char aEnd) {
0118         arrayStart = aStart;
0119         arrayEnd = aEnd;
0120         return this;
0121     }
0122     /// Specify the delimiter character for an array
0123     ConfigBase *arrayDelimiter(char aSep) {
0124         arraySeparator = aSep;
0125         return this;
0126     }
0127     /// Specify the delimiter between a name and value
0128     ConfigBase *valueSeparator(char vSep) {
0129         valueDelimiter = vSep;
0130         return this;
0131     }
0132     /// Specify the quote characters used around strings and characters
0133     ConfigBase *quoteCharacter(char qString, char qChar) {
0134         stringQuote = qString;
0135         characterQuote = qChar;
0136         return this;
0137     }
0138     /// Specify the maximum number of parents
0139     ConfigBase *maxLayers(uint8_t layers) {
0140         maximumLayers = layers;
0141         return this;
0142     }
0143     /// Specify the separator to use for parent layers
0144     ConfigBase *parentSeparator(char sep) {
0145         parentSeparatorChar = sep;
0146         return this;
0147     }
0148     /// get a reference to the configuration section
0149     std::string &sectionRef() { return configSection; }
0150     /// get the section
0151     CLI11_NODISCARD const std::string &section() const { return configSection; }
0152     /// specify a particular section of the configuration file to use
0153     ConfigBase *section(const std::string &sectionName) {
0154         configSection = sectionName;
0155         return this;
0156     }
0157 
0158     /// get a reference to the configuration index
0159     int16_t &indexRef() { return configIndex; }
0160     /// get the section index
0161     CLI11_NODISCARD int16_t index() const { return configIndex; }
0162     /// specify a particular index in the section to use (-1) for all sections to use
0163     ConfigBase *index(int16_t sectionIndex) {
0164         configIndex = sectionIndex;
0165         return this;
0166     }
0167 };
0168 
0169 /// the default Config is the TOML file format
0170 using ConfigTOML = ConfigBase;
0171 
0172 /// ConfigINI generates a "standard" INI compliant output
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 // [CLI11:config_fwd_hpp:end]
0185 }  // namespace CLI