]> git.tdb.fi Git - builder.git/blob - source/buildinfo.cpp
Move to a more abstract way of defining warnings
[builder.git] / source / buildinfo.cpp
1 #include <algorithm>
2 #include <set>
3 #include <msp/strings/format.h>
4 #include "buildinfo.h"
5
6 using namespace std;
7 using namespace Msp;
8
9 namespace {
10
11 /** Removes any duplicate entries from a list, leaving only the first one.  The
12 order of other elements is preserved.  O(nlogn) efficiency. */
13 template<typename T>
14 void unique(list<T> &l)
15 {
16         set<T> seen;
17         for(typename list<T>::iterator i=l.begin(); i!=l.end(); )
18         {
19                 if(seen.count(*i))
20                         l.erase(i++);
21                 else
22                         seen.insert(*i++);
23         }
24 }
25
26 }
27
28
29 BuildInfo::BuildInfo():
30         libmode(DYNAMIC),
31         threads(false),
32         debug(false),
33         optimize(0),
34         strip(false),
35         warning_level(0),
36         fatal_warnings(false)
37 { }
38
39 void BuildInfo::update_from(const BuildInfo &bi, UpdateLevel level)
40 {
41         for(DefineMap::const_iterator i=bi.defines.begin(); i!=bi.defines.end(); ++i)
42                 defines[i->first] = i->second;
43         incpath.insert(incpath.end(), bi.incpath.begin(), bi.incpath.end());
44         if(level!=CHAINED)
45         {
46                 libpath.insert(libpath.end(), bi.libpath.begin(), bi.libpath.end());
47                 libs.insert(libs.end(), bi.libs.begin(), bi.libs.end());
48         }
49         threads = bi.threads;
50         if(level==LOCAL)
51         {
52                 libmode = bi.libmode;
53                 debug = bi.debug;
54                 optimize = bi.optimize;
55                 strip = bi.strip;
56                 warning_level = bi.warning_level;
57                 fatal_warnings = bi.fatal_warnings;
58         }
59
60         unique();
61 }
62
63 void BuildInfo::unique()
64 {
65         ::unique(incpath);
66         ::unique(libpath);
67         ::unique(libs);
68 }
69
70
71 BuildInfo::Loader::Loader(BuildInfo &bi):
72         DataFile::ObjectLoader<BuildInfo>(bi)
73 {
74         add("debug",    &BuildInfo::debug);
75         add("define",   &Loader::define);
76         add("incpath",  &Loader::incpath);
77         add("libpath",  &Loader::libpath);
78         add("library",  &Loader::library);
79         add("libmode",  &BuildInfo::libmode);
80         add("optimize", &BuildInfo::optimize);
81         add("strip",    &BuildInfo::strip);
82         add("threads",  &BuildInfo::threads);
83         add("warning_level", &BuildInfo::warning_level);
84         add("fatal_warnings", &BuildInfo::fatal_warnings);
85 }
86
87 void BuildInfo::Loader::incpath(const string &s)
88 {
89         obj.incpath.push_back(s);
90 }
91
92 void BuildInfo::Loader::define(const string &d, const string &v)
93 {
94         obj.defines[d] = v;
95 }
96
97 void BuildInfo::Loader::libpath(const string &s)
98 {
99         obj.libpath.push_back(s);
100 }
101
102 void BuildInfo::Loader::library(const string &s)
103 {
104         obj.libs.push_back(s);
105 }
106
107
108 void operator>>(LexicalConverter &conv, BuildInfo::LibraryMode &libmode)
109 {
110         if(conv.get()=="FORCE_STATIC")
111                 libmode = BuildInfo::FORCE_STATIC;
112         else if(conv.get()=="STATIC")
113                 libmode = BuildInfo::STATIC;
114         else if(conv.get()=="DYNAMIC")
115                 libmode = BuildInfo::DYNAMIC;
116         else if(conv.get()=="FORCE_DYNAMIC")
117                 libmode = BuildInfo::FORCE_DYNAMIC;
118         else
119                 throw lexical_error(format("Conversion of '%s' to LibraryMode", conv.get()));
120 }