1 #include "core/command.hpp"
2 #include "core/dispatch.hpp"
3 #include "core/globalwrap.hpp"
4 #include "core/misc.hpp"
5 #include "core/settings.hpp"
6 #include "library/string.hpp"
14 globalwrap
<std::map
<std::string
, setting
*>> settings
;
16 function_ptr_command
<const std::string
&> set_setting("set-setting", "set a setting",
17 "Syntax: set-setting <setting> [<value>]\nSet setting to a new value. Omit <value> to set to ''\n",
18 [](const std::string
& t
) throw(std::bad_alloc
, std::runtime_error
) {
19 auto r
= regex("([^ \t]+)([ \t]+(|[^ \t].*))?", t
, "Setting name required.");
20 setting::set(r
[1], r
[3]);
21 messages
<< "Setting '" << r
[1] << "' set to '" << r
[3] << "'" << std::endl
;
24 function_ptr_command
<const std::string
&> unset_setting("unset-setting", "unset a setting",
25 "Syntax: unset-setting <setting>\nTry to unset a setting. Note that not all settings can be unset\n",
26 [](const std::string
& t
) throw(std::bad_alloc
, std::runtime_error
) {
27 auto r
= regex("([^ \t]+)[ \t]*", t
, "Expected setting name and nothing else");
29 messages
<< "Setting '" << r
[1] << "' unset" << std::endl
;
32 function_ptr_command
<const std::string
&> get_command("get-setting", "get value of a setting",
33 "Syntax: get-setting <setting>\nShow value of setting\n",
34 [](const std::string
& t
) throw(std::bad_alloc
, std::runtime_error
) {
35 auto r
= regex("([^ \t]+)[ \t]*", t
, "Expected setting name and nothing else");
36 if(setting::is_set(r
[1]))
37 messages
<< "Setting '" << r
[1] << "' has value '"
38 << setting::get(r
[1]) << "'" << std::endl
;
40 messages
<< "Setting '" << r
[1] << "' is unset" << std::endl
;
43 function_ptr_command
<> show_settings("show-settings", "Show values of all settings",
44 "Syntax: show-settings\nShow value of all settings\n",
45 []() throw(std::bad_alloc
, std::runtime_error
) {
46 for(auto i
: setting::get_settings_set()) {
47 if(!setting::is_set(i
))
48 messages
<< i
<< ": (unset)" << std::endl
;
50 messages
<< i
<< ": " << setting::get(i
) << std::endl
;
57 static mutex
& m
= mutex::aquire();
64 stlock_hold() { stlock().lock(); }
65 ~stlock_hold() { stlock().unlock(); }
67 stlock_hold(const stlock_hold
& k
);
68 stlock_hold
& operator=(const stlock_hold
& k
);
72 std::map
<std::string
, std::string
> setting::invalid_values
;
73 bool setting::storage_mode
= false;
75 setting::setting(const std::string
& name
) throw(std::bad_alloc
)
78 mut
= &mutex::aquire();
79 settings()[settingname
= name
] = this;
82 setting::~setting() throw()
86 settings().erase(settingname
);
89 setting
* setting::get_by_name(const std::string
& name
)
92 if(!settings().count(name
))
93 throw std::runtime_error("No such setting '" + name
+ "'");
94 return settings()[name
];
97 void setting::set(const std::string
& _setting
, const std::string
& value
) throw(std::bad_alloc
, std::runtime_error
)
101 tochange
= get_by_name(_setting
);
104 invalid_values
[_setting
] = value
;
109 lock_holder
lck(tochange
);
110 tochange
->set(value
);
111 invalid_values
.erase(_setting
);
113 information_dispatch::do_setting_change(_setting
, value
);
114 } catch(std::bad_alloc
& e
) {
116 } catch(std::exception
& e
) {
118 invalid_values
[_setting
] = value
;
119 throw std::runtime_error("Can't set setting '" + _setting
+ "': " + e
.what());
123 bool setting::blank(bool really
) throw(std::bad_alloc
, std::runtime_error
)
128 bool setting::blankable(const std::string
& _setting
) throw(std::bad_alloc
, std::runtime_error
)
130 setting
* tochange
= get_by_name(_setting
);
133 lock_holder
lck(tochange
);
134 return tochange
->blank(false);
141 void setting::blank(const std::string
& _setting
) throw(std::bad_alloc
, std::runtime_error
)
143 setting
* tochange
= get_by_name(_setting
);
146 lock_holder
lck(tochange
);
147 if(!tochange
->blank(true))
148 throw std::runtime_error("This setting can't be cleared");
149 invalid_values
.erase(_setting
);
151 information_dispatch::do_setting_clear(_setting
);
152 } catch(std::bad_alloc
& e
) {
154 } catch(std::exception
& e
) {
155 throw std::runtime_error("Can't clear setting '" + _setting
+ "': " + e
.what());
159 std::string
setting::get(const std::string
& _setting
) throw(std::bad_alloc
, std::runtime_error
)
161 setting
* tochange
= get_by_name(_setting
);
163 lock_holder
lck(tochange
);
164 return tochange
->get();
168 bool setting::is_set(const std::string
& _setting
) throw(std::bad_alloc
, std::runtime_error
)
170 setting
* tochange
= get_by_name(_setting
);
172 lock_holder
lck(tochange
);
173 return tochange
->is_set();
177 std::set
<std::string
> setting::get_settings_set() throw(std::bad_alloc
)
179 std::set
<std::string
> r
;
180 for(auto i
: settings())
185 void setting::set_storage_mode(bool enable
) throw()
187 storage_mode
= enable
;
190 std::map
<std::string
, std::string
> setting::get_invalid_values() throw(std::bad_alloc
)
192 return invalid_values
;
196 numeric_setting::numeric_setting(const std::string
& sname
, int32_t minv
, int32_t maxv
, int32_t dflt
)
197 throw(std::bad_alloc
)
205 bool numeric_setting::is_set() throw()
210 void numeric_setting::set(const std::string
& _value
) throw(std::bad_alloc
, std::runtime_error
)
212 int32_t v
= parse_value
<int32_t>(_value
);
213 if(v
< minimum
|| v
> maximum
) {
214 std::ostringstream x
;
215 x
<< "Value out of range (" << minimum
<< " - " << maximum
<< ")";
216 throw std::runtime_error(x
.str());
221 std::string
numeric_setting::get() throw(std::bad_alloc
)
223 std::ostringstream x
;
228 numeric_setting::operator int32_t() throw()
230 lock_holder
lck(this);
234 boolean_setting::boolean_setting(const std::string
& sname
, bool dflt
) throw(std::bad_alloc
)
240 bool boolean_setting::is_set() throw()
245 void boolean_setting::set(const std::string
& v
) throw(std::bad_alloc
, std::runtime_error
)
247 switch(string_to_bool(v
)) {
255 throw std::runtime_error("Invalid value for boolean setting");
259 std::string
boolean_setting::get() throw(std::bad_alloc
)
267 boolean_setting::operator bool() throw()
269 lock_holder
lck(this);
273 path_setting::path_setting(const std::string
& sname
) throw(std::bad_alloc
)
280 bool path_setting::blank(bool really
) throw(std::bad_alloc
, std::runtime_error
)
289 bool path_setting::is_set() throw()
294 void path_setting::set(const std::string
& value
) throw(std::bad_alloc
, std::runtime_error
)
305 std::string
path_setting::get() throw(std::bad_alloc
)
310 path_setting::operator std::string()
312 lock_holder
lck(this);