]> git.tdb.fi Git - builder.git/blob - source/config.cpp
Adjust to library changes
[builder.git] / source / config.cpp
1 /* $Id$
2
3 This file is part of builder
4 Copyright © 2006-2009  Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <msp/core/except.h>
9 #include <msp/fs/stat.h>
10 #include <msp/fs/utils.h>
11 #include <msp/io/except.h>
12 #include <msp/io/file.h>
13 #include <msp/io/print.h>
14 #include <msp/time/utils.h>
15 #include "builder.h"
16 #include "config.h"
17 #include "sourcepackage.h"
18
19 using namespace std;
20 using namespace Msp;
21
22 Config::Config(SourcePackage &p):
23         package(p),
24         freeze_mtime(false)
25 { }
26
27 void Config::add_option(const string &n, const string &v, const string &d)
28 {
29         options.insert(OptionMap::value_type(n, Option(n, v, d)));
30 }
31
32 const Config::Option &Config::get_option(const string &name) const
33 {
34         OptionMap::const_iterator i = options.find(name);
35         if(i==options.end())
36                 throw KeyError("Unknown option", name);
37
38         return i->second;
39 }
40
41 bool Config::is_option(const string &name) const
42 {
43         return options.count(name);
44 }
45
46 void Config::select_last_profile()
47 {
48         try
49         {
50                 IO::BufferedFile in((package.get_source()/".profile").str());
51                 string profile;
52                 in.getline(profile);
53                 set_option("profile", profile);
54         }
55         catch(const IO::file_not_found &)
56         { }
57
58         freeze_mtime = true;
59         package.get_builder().apply_profile_template(*this, get_option("profile").value);
60         freeze_mtime = false;
61
62         load();
63 }
64
65 void Config::select_profile(const string &profile)
66 {
67         set_option("profile", profile);
68
69         if(!package.get_builder().get_dry_run())
70         {
71                 IO::BufferedFile out((package.get_source()/".profile").str(), IO::M_WRITE);
72                 IO::print(out, "%s\n", profile);
73         }
74
75         freeze_mtime = true;
76         package.get_builder().apply_profile_template(*this, profile);
77         freeze_mtime = false;
78
79         load();
80 }
81
82 bool Config::update(const StringMap &opts)
83 {
84         bool changed = false;
85         for(StringMap::const_iterator i=opts.begin(); i!=opts.end(); ++i)
86         {
87                 if(set_option(i->first, i->second) && i->first!="profile")
88                         changed = true;
89         }
90
91         if(changed && !freeze_mtime)
92                 mtime = Time::now();
93
94         return changed;
95 }
96
97 void Config::finish()
98 {
99         for(OptionMap::iterator i=options.begin(); i!=options.end(); ++i)
100                 i->second.value = package.expand_string(i->second.value);
101 }
102
103 void Config::save() const
104 {
105         FS::Path fn = package.get_source()/".options";
106
107         OptionMap::const_iterator i = options.find("profile");
108         if(i!=options.end())
109                 fn = package.get_source()/(".options."+i->second.value);
110
111         IO::BufferedFile out(fn.str(), IO::M_WRITE);
112
113         for(i=options.begin(); i!=options.end(); ++i)
114                 IO::print(out, "option \"%s\" \"%s\";\n", i->second.name, i->second.value);
115 }
116
117 bool Config::set_option(const string &opt, const string &val)
118 {
119         bool result = false;
120
121         OptionMap::iterator i = options.find(opt);
122         if(i!=options.end())
123         {
124                 if(i->second.value!=val)
125                         result = true;
126                 i->second.value = val;
127         }
128
129         return result;
130 }
131
132 void Config::load()
133 {
134         FS::Path fn = package.get_source()/(".options."+get_option("profile").value);
135
136         try
137         {
138                 IO::BufferedFile in(fn.str());
139
140                 mtime = Time::TimeStamp::from_unixtime(FS::stat(fn).st_mtime);
141
142                 DataFile::Parser parser(in, fn.str());
143                 Loader loader(*this);
144                 loader.load(parser);
145         }
146         catch(const IO::file_not_found &)
147         { }
148 }
149
150
151 Config::Option::Option(const string &n, const string &v, const string &d):
152         name(n),
153         defv(v),
154         descr(d),
155         value(v)
156 { }
157
158
159 Config::Loader::Loader(Config &c):
160         conf(c)
161 {
162         add("option", &Loader::option);
163 }
164
165 void Config::Loader::option(const string &n, const string &v)
166 {
167         conf.set_option(n, v);
168 }