OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-cogutil commits / f5dd740

Remove Config.h Config.cc -- never should have been
Took almost two decades to exterminate this cockroach.
f5dd74018f125e4ccf6df42cd08a744546478645
by Linas Vepštas <linasvepstas@gmail.com> · 2025-12-13T05:57:49.000Z

Changed files (5) +0 -493

opencog/util/CMakeLists.txt +0 -2
……@@ -11,7 +11,6 @@ ADD_DEFINITIONS(
1111ADD_LIBRARY(cogutil SHARED
1212 algorithm.h
1313 backtrace-symbols.c
14 Config.cc
1514 exceptions.cc
1615 lazy_selector.cc
1716 lazy_random_selector.cc
……@@ -99,7 +98,6 @@ INSTALL(FILES
9998 async_method_caller.h
10099 backtrace-symbols.h
101100 cogutil.h
102 Config.h
103101 Counter.h
104102 concurrent_queue.h
105103 concurrent_set.h
opencog/util/Config.cc +0 -260
……@@ -1,260 +0,0 @@
1/*
2 * opencog/util/Config.cc
3 *
4 * Copyright (C) 2008 by OpenCog Foundation
5 * All Rights Reserved
6 *
7 * Written by Gustavo Gama <gama@vettalabs.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License v3 as
11 * published by the Free Software Foundation and including the exceptions
12 * at http://opencog.org/wiki/Licenses
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program; if not, write to:
21 * Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24
25#include "Config.h"
26#include "Logger.h"
27
28#include <iostream>
29#include <filesystem>
30#include <fstream>
31#include <sstream>
32#include <cstdio>
33#include <cstdlib>
34
35#include <errno.h>
36#include <unistd.h>
37
38#include <opencog/util/platform.h>
39#include <opencog/util/exceptions.h>
40
41using namespace opencog;
42using namespace std;
43
44// Returns a string with leading/trailing characters of a set stripped
45static char const* blank_chars = " \t\f\v\n\r";
46static string strip(string const& str, char const *strip_chars = blank_chars)
47{
48 string::size_type const first = str.find_first_not_of(strip_chars);
49 return (first == string::npos) ?
50 string() :
51 str.substr(first, str.find_last_not_of(strip_chars) - first + 1);
52}
53
54Config::~Config()
55{
56}
57
58Config::Config()
59{
60 reset();
61}
62
63void Config::reset()
64{
65 _table.clear();
66}
67
68static const char* DEFAULT_CONFIG_FILENAME = "opencog.conf";
69
70void Config::load(const char* filename)
71{
72 if (NULL == filename or 0 == filename[0])
73 filename = DEFAULT_CONFIG_FILENAME;
74
75 std::filesystem::path configPath(filename);
76 if (not std::filesystem::exists(configPath))
77 {
78 logger().warn("Can't find config file \"%s\"\n", filename);
79 throw IOException(TRACE_INFO,
80 "Can't find config file \"%s\"", filename);
81 }
82
83 // Try to open it
84 ifstream fin;
85 fin.open(filename);
86 if (!fin or !fin.good() or !fin.is_open())
87 {
88 logger().warn("Cannot open config file \"%s\"\n", filename);
89 throw IOException(TRACE_INFO,
90 "Unable to open config file \"%s\"", filename);
91 }
92
93 string line;
94 string name;
95 string value;
96 unsigned int line_number = 0;
97 bool have_name = false;
98 bool have_value = false;
99
100 // Read and parse the config file.
101 while (++line_number, fin.good() and getline(fin, line))
102 {
103 string::size_type idx;
104
105 // Find comment and discard the rest of the line.
106 if ((idx = line.find('#')) != string::npos) {
107 line.replace(idx, line.size() - idx, "");
108 }
109
110 // Search for the '=' character.
111 if ((idx = line.find('=')) != string::npos)
112 {
113 // Select name and value
114 name = line.substr(0, idx);
115 value = line.substr(idx + 1);
116
117 // Strip out whitespace, etc.
118 name = strip(name);
119 value = strip(value);
120 value = strip(value, "\"");
121
122 have_name = true;
123
124 // Look for trailing comma.
125 if (',' != value[value.size()-1])
126 have_value = true;
127 }
128
129 // Append more to value
130 else if ((string::npos != line.find_first_not_of(blank_chars)) &&
131 have_name &&
132 !have_value)
133 {
134 value += strip(line);
135
136 // Look for trailing comma.
137 if (',' != value[value.size()-1])
138 have_value = true;
139 }
140
141 else if (line.find_first_not_of(blank_chars) != string::npos)
142 {
143 // This might print the diagnostics to the default log file
144 // location. Note that the config file itself contains the
145 // log file location that is supposed to be used, so this
146 // printing is happening "too early", before the logger is
147 // fully initialized. Such is life; this is still a lot easier
148 // than debugging the thrown exception in a debugger.
149 setup_logger();
150 logger().warn("Invalid config file entry at line %d in %s\n",
151 line_number, filename);
152
153 throw InvalidParamException(TRACE_INFO,
154 "[ERROR] invalid configuration entry (line %d)",
155 line_number);
156 }
157
158 if (have_name && have_value)
159 {
160 // Finally, store the entries.
161 _table[name] = value;
162 have_name = false;
163 have_value = false;
164 value = "";
165 }
166 }
167 fin.close();
168
169 // Finish configuring the logger... The config file itself
170 // contains the location of the log file. This is working around
171 // a chicken-and-egg problem with reporting config file issues.
172 setup_logger();
173}
174
175void Config::setup_logger()
176{
177 if (has("LOG_FILE"))
178 logger().set_filename(get("LOG_FILE"));
179 if (has("LOG_LEVEL"))
180 logger().set_level(get("LOG_LEVEL"));
181 if (has("BACK_TRACE_LOG_LEVEL"))
182 logger().set_backtrace_level(get("BACK_TRACE_LOG_LEVEL"));
183 if (has("LOG_TO_STDOUT"))
184 logger().set_print_to_stdout_flag(get_bool("LOG_TO_STDOUT"));
185 if (has("LOG_TIMESTAMP"))
186 logger().set_timestamp_flag(get_bool("LOG_TIMESTAMP"));
187}
188
189const bool Config::has(const string &name) const
190{
191 return (_table.find(name) != _table.end());
192}
193
194void Config::set(const std::string &parameter_name,
195 const std::string &parameter_value)
196{
197 _table[parameter_name] = parameter_value;
198}
199
200const string& Config::get(const string& name, const string& dfl) const
201{
202 if (not has(name)) return dfl;
203 return _table.find(name)->second;
204}
205
206const string& Config::operator[](const string &name) const
207{
208 if (not has(name))
209 throw InvalidParamException(TRACE_INFO,
210 "[ERROR] parameter not found (%s)",
211 name.c_str());
212 return _table.find(name)->second;
213}
214
215int Config::get_int(const string &name, int dfl) const
216{
217 if (not has(name)) return dfl;
218 return std::stoi(get(name));
219}
220
221long Config::get_long(const string &name, long dfl) const
222{
223 if (not has(name)) return dfl;
224 return std::stol(get(name));
225}
226
227double Config::get_double(const string &name, double dfl) const
228{
229 if (not has(name)) return dfl;
230 return std::stod(get(name));
231}
232
233bool Config::get_bool(const string &name, bool dfl) const
234{
235 if (not has(name)) return dfl;
236 if (0 == get(name).compare("true")) return true;
237 if (0 == get(name).compare("false")) return false;
238 throw InvalidParamException(TRACE_INFO,
239 "[ERROR] invalid bool parameter (%s: %s)",
240 name.c_str(), get(name).c_str());
241}
242
243std::string Config::to_string() const
244{
245 std::ostringstream oss;
246 oss << "{\"";
247 for (auto it = _table.begin(); it != _table.end(); ++it) {
248 if (it != _table.begin()) oss << "\", \"";
249 oss << it->first << "\" => \"" << it->second;
250 }
251 oss << "\"}";
252 return oss.str();
253}
254
255// create and return the single instance
256Config& opencog::config()
257{
258 static std::unique_ptr<Config> instance(new Config());
259 return *instance;
260}
opencog/util/Config.h +0 -87
……@@ -1,87 +0,0 @@
1/*
2 * opencog/util/Config.h
3 *
4 * Copyright (C) 2008 by OpenCog Foundation
5 * All Rights Reserved
6 *
7 * Written by Gustavo Gama <gama@vettalabs.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License v3 as
11 * published by the Free Software Foundation and including the exceptions
12 * at http://opencog.org/wiki/Licenses
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program; if not, write to:
21 * Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24
25#ifndef _OPENCOG_CONFIG_H
26#define _OPENCOG_CONFIG_H
27
28#include <map>
29#include <string>
30
31namespace opencog
32{
33/** \addtogroup grp_cogutil
34 * @{
35 */
36
37//! library-wide configuration; keys and values are strings
38class Config
39{
40protected:
41 std::map<std::string, std::string> _table;
42 void setup_logger();
43
44public:
45 Config(void);
46 ~Config();
47
48 //! Reset configuration to default.
49 void reset();
50
51 //! Parse the indicated file for parameter values.
52 void load(const char* config_file);
53
54 //! Return true if a parameter exists.
55 const bool has(const std::string &parameter_name) const;
56
57 //! Set the value of a given parameter.
58 void set(const std::string &parameter_name, const std::string &parameter_value);
59
60 //! Return current value of a given parameter.
61 const std::string& get(const std::string &, const std::string& = "") const;
62 //! Return current value of a given parameter.
63 const std::string& operator[](const std::string &) const;
64
65 //! Return current value of a given parameter as an integer.
66 int get_int(const std::string &, int = 0) const;
67
68 //! Return current value of a given parameter as an long.
69 long get_long(const std::string &, long = 0) const;
70
71 //! Return current value of a given parameter as a double.
72 double get_double(const std::string &, double = 0.0) const;
73
74 //! Return current value of a given parameter as a boolean.
75 bool get_bool(const std::string &, bool = false) const;
76
77 //! Dump all configuration parameters to a string.
78 std::string to_string() const;
79};
80
81//! singleton instance (following meyer's design pattern)
82Config& config();
83
84/** @}*/
85} // namespace opencog
86
87#endif // _OPENCOG_CONFIG_H
tests/util/CMakeLists.txt +0 -1
……@@ -12,7 +12,6 @@ LINK_LIBRARIES(
1212)
1313
1414ADD_CXXTEST(algorithmUTest)
15ADD_CXXTEST(ConfigUTest)
1615ADD_CXXTEST(CounterUTest)
1716ADD_CXXTEST(LoggerUTest)
1817ADD_CXXTEST(numericUTest)
tests/util/ConfigUTest.cxxtest +0 -143
……@@ -1,143 +0,0 @@
1/*
2 * tests/util/ConfigUTest.cxxtest
3 *
4 * Copyright (C) 2008 by OpenCog Foundation
5 * All Rights Reserved
6 *
7 * Written by Gustavo Gama <gama@vettalabs.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License v3 as
11 * published by the Free Software Foundation and including the exceptions
12 * at http://opencog.org/wiki/Licenses
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program; if not, write to:
21 * Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24
25#include <cstdio>
26#include <fstream>
27#include <iostream>
28
29#include <opencog/util/Config.h>
30#include <opencog/util/exceptions.h>
31
32using namespace opencog;
33
34class ConfigUTest : public CxxTest::TestSuite
35{
36
37public:
38 ConfigUTest() {}
39 void setUp() {}
40 void tearDown() {}
41
42 void testDefault()
43 {
44 TS_ASSERT_THROWS(config()["INVALID_PARAM"], InvalidParamException&);
45 TS_ASSERT(config().get("SERVER_PORT", "17001") == "17001");
46 TS_ASSERT(config().get_int("SERVER_PORT", 17001) == 17001);
47 TS_ASSERT(config().get_double("SERVER_PORT", 17001.0) == 17001.0);
48 TS_ASSERT(config().get("LOG_FILE", "opencog_server.log") == "opencog_server.log");
49 TS_ASSERT(config().get("LOG_LEVEL", "info") == "info");
50 TS_ASSERT(config().get("BACK_TRACE_LOG_LEVEL", "error") == "error"); // C++ stack traces only on error!
51 TS_ASSERT(config().get_bool("LOG_TO_STDOUT", true));
52 TS_ASSERT(config().get_int("SERVER_CYCLE_DURATION", 100) == 100);
53 TS_ASSERT(!config().get_bool("EXTERNAL_TICK_MODE"));
54 TS_ASSERT(config().get_int("STARTING_STI_FUNDS", 10000) == 10000);
55 TS_ASSERT(config().get_int("STARTING_LTI_FUNDS", 10000) == 10000);
56 TS_ASSERT(config().get_int("STI_FUNDS_BUFFER", 10000) == 10000);
57 TS_ASSERT(config().get_int("LTI_FUNDS_BUFFER", 10000) == 10000);
58 TS_ASSERT(config().get_int("MIN_STI", -400) == -400);
59 TS_ASSERT(config().get("PROMPT", "opencog> ") == "opencog> ");
60 TS_ASSERT(config().get("MODULES", "libbuiltinreqs.so") == "libbuiltinreqs.so");
61 }
62
63
64 void testLoadFromFile()
65 {
66 // first, write the configuration file
67 const char *config_file_name = "ConfigUTest.config";
68 std::ofstream out(config_file_name);
69 out << "# ConfigUTest file; commented initial line\n";
70 out << " # Another comment line with blank prefix\n";
71 out << " PARAM1 = VALUE1\n";
72 out << " PARAM2 = VALUE2 \n";
73 out << "PARAM3=VALUE3\n";
74 out << "COMPOSED PARAMETER NAME 4 = VALUE4\n";
75 out << "# another comment, just for kicks\n";
76 out << "PARAM5 = COMPOSED PARAMETER VALUE 5 \n";
77 out << "PARAM6 = VALUE6 # end of line comments\n";
78 out << " PARAM7 = 248 # integer parameter\n";
79 out << "PARAM8 =1.2584 # double parameter\n";
80 //out << "PARAM9= -29847.167015 $&@*a786A!$alk # double parameter and useless discarded extra characters\n";
81 out << "PARAM9= -29847.167015 # double parameter\n";
82 out << "STI_FUNDS_BUFFER = 200\n";
83 out << "LTI_FUNDS_BUFFER = 10\n";
84 out << "LOG_TO_STDOUT = false\n";
85 out.close();
86
87 // reset configuration to default parameters
88 config().reset();
89
90 // check default parameters before and after loading file
91 TS_ASSERT(config().get_int("STI_FUNDS_BUFFER", 10000) == 10000);
92 TS_ASSERT(config().get_int("LTI_FUNDS_BUFFER", 10000) == 10000);
93 config().load(config_file_name);
94 TS_ASSERT(config().get_int("STI_FUNDS_BUFFER", 10000) == 200);
95 TS_ASSERT(config().get_int("LTI_FUNDS_BUFFER", 10000) == 10);
96 TS_ASSERT(!config().get_bool("LOG_TO_STDOUT", true));
97
98 // check remaining parameters from file
99 TS_ASSERT(config().get("PARAM1") == "VALUE1");
100 TS_ASSERT(config()["PARAM2"] == "VALUE2");
101 TS_ASSERT(config()["PARAM3"] == "VALUE3");
102 TS_ASSERT(config()["COMPOSED PARAMETER NAME 4"] == "VALUE4");
103 TS_ASSERT(config()["PARAM5"] == "COMPOSED PARAMETER VALUE 5");
104 TS_ASSERT(config()["PARAM6"] == "VALUE6");
105 TS_ASSERT(config().get_int("PARAM7", 999) == 248);
106 TS_ASSERT(config().get_double("PARAM8", 3.14159) == 1.2584);
107 TS_ASSERT(config().get_double("PARAM9", 2.718281828) == -29847.167015);
108
109 // finally, remove the temporary file and free the string with its name
110 std::remove(config_file_name);
111 }
112
113 void testSet()
114 {
115 // reset configuration to default parameters
116 config().reset();
117
118 // check default parameters before and setting the new value
119 TS_ASSERT(config().get("STI_FUNDS_BUFFER", "10000") == "10000");
120 TS_ASSERT(config().get_int("STI_FUNDS_BUFFER", 10000) == 10000);
121 config().set("STI_FUNDS_BUFFER", "200");
122 TS_ASSERT(config().get("STI_FUNDS_BUFFER", "10000") == "200");
123 TS_ASSERT(config().get_int("STI_FUNDS_BUFFER", 10000) == 200);
124 }
125
126 /**
127 * Check that setting a boolean parameter and getting an int
128 * raises an InvalidParamException
129 */
130 void testGetType()
131 {
132 config().reset();
133
134 config().set("BOOL_PARAM1", "true");
135 config().set("BOOL_PARAM2", "false");
136
137 TS_ASSERT_EQUALS(config().get_bool("BOOL_PARAM1"), true);
138 TS_ASSERT_THROWS_ANYTHING(config().get_int("BOOL_PARAM2"));
139 TS_ASSERT_THROWS_ANYTHING(config().get_long("BOOL_PARAM2"));
140 TS_ASSERT_THROWS_ANYTHING(config().get_double("BOOL_PARAM2"));
141 }
142
143}; // class