]> git.tdb.fi Git - builder.git/blob - source/config.cpp
Add comments
[builder.git] / source / config.cpp
1 #include <fstream>
2 #include <msp/error.h>
3 #include <msp/path/utils.h>
4 #include <msp/time/utils.h>
5 #include "config.h"
6
7 using namespace std;
8 using namespace Msp;
9
10 /**
11 Adds a configuration option.
12
13 @param   n  Option name
14 @param   v  Default value
15 @param   d  Description
16 */
17 void Config::add_option(const string &n, const string &v, const string &d)
18 {
19         options.insert(OptionMap::value_type(n, Option(n, v, d)));
20 }
21
22 /**
23 Gets the given option from the configuration.  If the option doesn't exist,
24 an Exception is thrown.
25 */
26 const Config::Option &Config::get_option(const string &name) const
27 {
28         OptionMap::const_iterator i=options.find(name);
29         if(i==options.end())
30                 throw Exception("Tried to access nonexistent option "+name);
31
32         return i->second;
33 }
34
35 /**
36 Checks whether an option with the given name exists.
37 */
38 bool Config::is_option(const string &name) const
39 {
40         return options.count(name);
41 }
42
43 /**
44 Processes options from the given raw option map.  Nonexistent options are
45 ignored.  If any options were changed, the mtime of the configuration is updated
46 to the current time.
47
48 @param   opts  A map to process options from
49
50 @return  Whether any option values were changed
51 */
52 bool Config::process(const RawOptionMap &opts)
53 {
54         bool changed=false;
55         for(RawOptionMap::const_iterator i=opts.begin(); i!=opts.end(); ++i)
56         {
57                 OptionMap::iterator j=options.find(i->first);
58                 if(j!=options.end())
59                 {
60                         if(i->second!=j->second.value)
61                                 changed=true;
62                         j->second.value=i->second;
63                 }
64         }
65
66         if(changed)
67                 mtime=Time::now();
68
69         return changed;
70 }
71
72 /**
73 Loads configuration from a file, if it exists.
74 */
75 void Config::load(const Path::Path &fn)
76 {
77         ifstream in(fn.str().c_str());
78         if(!in) return;
79
80         struct stat st;
81         Path::stat(fn, st);
82         mtime=Time::TimeStamp::from_unixtime(st.st_mtime);
83
84         Parser::Parser parser(in, fn.str());
85         Loader loader(*this);
86         loader.load(parser);
87 }
88
89 void Config::save(const Path::Path &fn) const
90 {
91         ofstream out(fn.str().c_str());
92         if(!out) return;
93         
94         for(OptionMap::const_iterator i=options.begin(); i!=options.end(); ++i)
95                 out<<"option \""<<i->second.name<<"\" \""<<i->second.value<<"\";\n";
96 }
97
98 Config::Option::Option(const string &n, const string &v, const string &d):
99         name(n),
100         defv(v),
101         descr(d),
102         value(v)
103 { }
104
105 Config::Loader::Loader(Config &c):
106         conf(c)
107 {
108         add("option", &Loader::option);
109 }
110
111 void Config::Loader::option(const string &n, const string &v)
112 {
113         OptionMap::iterator i=conf.options.find(n);
114         if(i!=conf.options.end())
115                 i->second.value=v;
116 }