| 1 | #include "Configuration.h"
|
|---|
| 2 |
|
|---|
| 3 | #include <iostream>
|
|---|
| 4 |
|
|---|
| 5 | using namespace std;
|
|---|
| 6 |
|
|---|
| 7 | // --------------------------------------------------------------------------
|
|---|
| 8 | //
|
|---|
| 9 | //! Main Doxygen/Autotools integration example program.
|
|---|
| 10 | //!
|
|---|
| 11 | //! @param conf Number of command line options.
|
|---|
| 12 | //! @param opt The command line options.
|
|---|
| 13 | //! @return The exit status.
|
|---|
| 14 | //
|
|---|
| 15 | void SetupConfiguration(Configuration &conf, int &opt)
|
|---|
| 16 | {
|
|---|
| 17 | /*
|
|---|
| 18 | // Default in case the option was not specified
|
|---|
| 19 | typed_value* default_value(const T& v)
|
|---|
| 20 | typed_value* default_value(const T& v, const std::string& textual)
|
|---|
| 21 |
|
|---|
| 22 | // Default value in case the option was given
|
|---|
| 23 | // forces -o to become -o5
|
|---|
| 24 | // forces --opt to become --opt=3
|
|---|
| 25 | typed_value* implicit_value(const T &v)
|
|---|
| 26 | typed_value* implicit_value(const T &v, const std::string& textual)
|
|---|
| 27 |
|
|---|
| 28 | // notifier function when the final value is determined
|
|---|
| 29 | typed_value* notifier(function1<void, const T&> f)
|
|---|
| 30 |
|
|---|
| 31 | /// Merge values from different sources (e.g. file, command line)
|
|---|
| 32 | typed_value* composing()
|
|---|
| 33 |
|
|---|
| 34 | // Specifies that the value can span multiple tokens.
|
|---|
| 35 | typed_value* multitoken()
|
|---|
| 36 | typed_value* zero_tokens()
|
|---|
| 37 |
|
|---|
| 38 | // Specifies that the value must occur.
|
|---|
| 39 | typed_value* required()
|
|---|
| 40 | */
|
|---|
| 41 |
|
|---|
| 42 | // To merge the options from several parsers (e.g. comand_line and
|
|---|
| 43 | // config file) use po_strings()->composing()
|
|---|
| 44 | /*
|
|---|
| 45 | po::options_description generic("Generic options");
|
|---|
| 46 | generic.add_options()
|
|---|
| 47 | ("help-config", "Print available configuration file options.")
|
|---|
| 48 | ("help-env", "Print available environment variables.")
|
|---|
| 49 | ("help", "Print available commandline options.")
|
|---|
| 50 | ("print-unknown", "Print unrecognized options.")
|
|---|
| 51 | ("config", po_string("config.txt"), "Set configuration file name.")
|
|---|
| 52 | ;
|
|---|
| 53 |
|
|---|
| 54 |
|
|---|
| 55 | // Declare the supported options.
|
|---|
| 56 | po::options_description generic("Generaic options");
|
|---|
| 57 | generic.add_options()
|
|---|
| 58 | // ("testreq", po_int()->required(), "set compression level (madatory)")
|
|---|
| 59 | ("default", po_string("my_default"), "set compression level")
|
|---|
| 60 | ("unknown", po_int(1), "set compression level")
|
|---|
| 61 | ("U", po_int(2)->implicit_value(1), "set compression level")
|
|---|
| 62 | ;
|
|---|
| 63 | */
|
|---|
| 64 | // Declare a group of options that will be
|
|---|
| 65 | // allowed both on command line and in
|
|---|
| 66 | // config file
|
|---|
| 67 | po::options_description config("Configuration");
|
|---|
| 68 | config.add_options()
|
|---|
| 69 | ("compression", var<int>(), "set compression level")
|
|---|
| 70 | ("optimization", var<int>(10, &opt), "optimization level")
|
|---|
| 71 | ("test-def", var<int>(42), "optimization level")
|
|---|
| 72 | ("include-path,I", vars<string>()/*->composing()*/, "include path")
|
|---|
| 73 | ("test,T", vars<string>()/*->composing()*/, "include path")
|
|---|
| 74 | ("file1", vars<string>(), "include path")
|
|---|
| 75 | ("int1", var<int>(), "include path")
|
|---|
| 76 | ("Int2", var<int>(), "include path")
|
|---|
| 77 | ("Int1", var<int>(), "include path")
|
|---|
| 78 | ("test-db", var<string>("database"), "include path")
|
|---|
| 79 | ("float1", var<double>(), "include path")
|
|---|
| 80 | // (",A", po_float(), "include path")
|
|---|
| 81 | ("radec", po::value<vector<double>>(), "include path")
|
|---|
| 82 | ("switch", po_switch(), "include path")
|
|---|
| 83 | ("bool", var<bool>()->implicit_value(true), "include path")
|
|---|
| 84 | ;
|
|---|
| 85 |
|
|---|
| 86 | // !!! Option which are "shorted" must be placed last.
|
|---|
| 87 | // Can this be switched off?
|
|---|
| 88 |
|
|---|
| 89 | po::options_description sections("Sections");
|
|---|
| 90 | config.add_options()
|
|---|
| 91 | ("unregistered", var<string>(), "include path")
|
|---|
| 92 | ("Section1.unregistered", var<string>(), "include path")
|
|---|
| 93 | // ("Section2*", po_string(), "include path")
|
|---|
| 94 | // The latter accepts all options starting with Section2.
|
|---|
| 95 | ;
|
|---|
| 96 |
|
|---|
| 97 | // Hidden options, will be allowed both on command line and
|
|---|
| 98 | // in config file, but will not be shown to the user.
|
|---|
| 99 | po::options_description hidden("Hidden options");
|
|---|
| 100 | hidden.add_options()
|
|---|
| 101 | ("input-file", vars<string>(), "input file")
|
|---|
| 102 | ("output-file", vars<string>(), "output file")
|
|---|
| 103 | ("test-file", vars<string>(), "test file")
|
|---|
| 104 | ;
|
|---|
| 105 |
|
|---|
| 106 | po::options_description env("Environment options");
|
|---|
| 107 | env.add_options()
|
|---|
| 108 | ("linux", var<string>(), "LINUX env")
|
|---|
| 109 | ("path", var<string>(), "PATH env")
|
|---|
| 110 | ("dns", var<string>(), "DIM_DNS_SERVER env")
|
|---|
| 111 | ;
|
|---|
| 112 |
|
|---|
| 113 | conf.AddEnv("linux", "LINUX");
|
|---|
| 114 | conf.AddEnv("path", "PATH");
|
|---|
| 115 | conf.AddEnv("dns", "DIM_DNS_SERVER");
|
|---|
| 116 |
|
|---|
| 117 | // define translation from position to name
|
|---|
| 118 | po::positional_options_description p;
|
|---|
| 119 | p.add("output-file", 2); // The first 2 positional options is output-file
|
|---|
| 120 | p.add("test-file", 3); // The next three positional options is output-file
|
|---|
| 121 | p.add("input-file", -1); // All others go to...
|
|---|
| 122 |
|
|---|
| 123 | conf.AddOptionsCommandline(config);
|
|---|
| 124 | conf.AddOptionsCommandline(sections);
|
|---|
| 125 | conf.AddOptionsCommandline(hidden, false);
|
|---|
| 126 |
|
|---|
| 127 | conf.AddOptionsConfigfile(config);
|
|---|
| 128 | conf.AddOptionsConfigfile(sections);
|
|---|
| 129 | conf.AddOptionsConfigfile(hidden, false);
|
|---|
| 130 |
|
|---|
| 131 | conf.AddOptionsEnvironment(env);
|
|---|
| 132 |
|
|---|
| 133 | conf.AddOptionsDatabase(config);
|
|---|
| 134 |
|
|---|
| 135 | conf.SetArgumentPositions(p);
|
|---|
| 136 | }
|
|---|
| 137 |
|
|---|
| 138 |
|
|---|
| 139 | int main(int argc, const char **argv)
|
|---|
| 140 | {
|
|---|
| 141 | int opt;
|
|---|
| 142 |
|
|---|
| 143 | Configuration conf(argv[0]);
|
|---|
| 144 | SetupConfiguration(conf, opt);
|
|---|
| 145 |
|
|---|
| 146 | po::variables_map vm;
|
|---|
| 147 | try
|
|---|
| 148 | {
|
|---|
| 149 | vm = conf.Parse(argc, argv);
|
|---|
| 150 | }
|
|---|
| 151 | catch (std::exception &e)
|
|---|
| 152 | {
|
|---|
| 153 | #if BOOST_VERSION > 104000
|
|---|
| 154 | po::multiple_occurrences *MO = dynamic_cast<po::multiple_occurrences*>(&e);
|
|---|
| 155 | if (MO)
|
|---|
| 156 | cout << "Error: " << e.what() << " of '" << MO->get_option_name() << "' option." << endl;
|
|---|
| 157 | else
|
|---|
| 158 | #endif
|
|---|
| 159 | cout << "Error: " << e.what() << endl;
|
|---|
| 160 | cout << endl;
|
|---|
| 161 |
|
|---|
| 162 | return -1;
|
|---|
| 163 | }
|
|---|
| 164 |
|
|---|
| 165 | if (conf.HasHelp() || conf.HasPrint())
|
|---|
| 166 | return -1;
|
|---|
| 167 |
|
|---|
| 168 | cout << "------------------------------" << endl;
|
|---|
| 169 |
|
|---|
| 170 | cout << "Program " << argv[0] << " started successfully." << endl;
|
|---|
| 171 |
|
|---|
| 172 | cout << conf.Has("switch") << " " << conf.Get<bool>("switch") << endl;
|
|---|
| 173 | cout << conf.Has("bool") << " " << conf.Get<bool>("bool") << endl;
|
|---|
| 174 |
|
|---|
| 175 | return 0;
|
|---|
| 176 | /*
|
|---|
| 177 | if (vm.count("compression"))
|
|---|
| 178 | cout << "Compression level was set to " << vm["compression"].as<int>() << ".\n";
|
|---|
| 179 | else
|
|---|
| 180 | cout << "Compression level was not set.\n";
|
|---|
| 181 |
|
|---|
| 182 |
|
|---|
| 183 | cout << "Test default is always: " << vm["test-def"].as<int>() << "\n";
|
|---|
| 184 | cout << "Optimization level is " << vm["optimization"].as<int>() << "\n";
|
|---|
| 185 | //cout << "Int2: " << vm["Int2"].as<int>() << "\n";
|
|---|
| 186 |
|
|---|
| 187 | cout << conf.GetString("unregistered") << endl;
|
|---|
| 188 | cout << conf.GetString("Section1.unregistered") << endl;
|
|---|
| 189 | cout << conf.Has("Section2.unregistered") << endl;
|
|---|
| 190 | cout << conf.GetString("Section2.Section3.unregistered") << endl;
|
|---|
| 191 | cout << "test-db: " << conf.GetString("test-db") << endl;
|
|---|
| 192 |
|
|---|
| 193 |
|
|---|
| 194 | if (vm.count("include-path"))
|
|---|
| 195 | {
|
|---|
| 196 | vector<string> v = vm["include-path"].as< vector<string> >();
|
|---|
| 197 | for (vector<string>::iterator s=v.begin(); s<v.end(); s++)
|
|---|
| 198 | cout << "Incl P: " << *s << endl;
|
|---|
| 199 | }
|
|---|
| 200 |
|
|---|
| 201 | if (vm.count("input-file"))
|
|---|
| 202 | {
|
|---|
| 203 | vector<string> v = vm["input-file"].as< vector<string> >();
|
|---|
| 204 | for (vector<string>::iterator s=v.begin(); s<v.end(); s++)
|
|---|
| 205 | cout << "Incl F: " << *s << endl;
|
|---|
| 206 | }
|
|---|
| 207 |
|
|---|
| 208 | if (vm.count("output-file"))
|
|---|
| 209 | {
|
|---|
| 210 | vector<string> v = vm["output-file"].as< vector<string> >();
|
|---|
| 211 | for (vector<string>::iterator s=v.begin(); s<v.end(); s++)
|
|---|
| 212 | cout << "Out: " << *s << endl;
|
|---|
| 213 | }
|
|---|
| 214 |
|
|---|
| 215 | if (vm.count("test-file"))
|
|---|
| 216 | {
|
|---|
| 217 | vector<string> v = vm["test-file"].as< vector<string> >();
|
|---|
| 218 | for (vector<string>::iterator s=v.begin(); s<v.end(); s++)
|
|---|
| 219 | cout << "Testf: " << *s << endl;
|
|---|
| 220 | }
|
|---|
| 221 |
|
|---|
| 222 | cout << "Linux: " << conf.Get<string>("linux") << endl;
|
|---|
| 223 |
|
|---|
| 224 | if (vm.count("path"))
|
|---|
| 225 | cout << "Path: " << vm["path"].as<string>() << endl;
|
|---|
| 226 | if (vm.count("file1"))
|
|---|
| 227 | cout << "File1: " << vm["file1"].as<string>() << endl;
|
|---|
| 228 | if (vm.count("int1"))
|
|---|
| 229 | cout << "Int1: " << vm["int1"].as<int>() << endl;
|
|---|
| 230 | if (vm.count("float1"))
|
|---|
| 231 | cout << "Float1: " << vm["float1"].as<float>() << endl;
|
|---|
| 232 |
|
|---|
| 233 | if (vm.count("test"))
|
|---|
| 234 | {
|
|---|
| 235 | vector<string> v = vm["test"].as< vector<string> >();
|
|---|
| 236 | for (vector<string>::iterator s=v.begin(); s<v.end(); s++)
|
|---|
| 237 | cout << "Test: " << *s << endl;
|
|---|
| 238 | }*/
|
|---|
| 239 | }
|
|---|
| 240 | // ***************************************************************************
|
|---|
| 241 | /** @example argv.cc
|
|---|
| 242 |
|
|---|
| 243 | Example for the usage of the class Configuration
|
|---|
| 244 |
|
|---|
| 245 | **/
|
|---|
| 246 | // ***************************************************************************
|
|---|