1 | // Copyright 2016 The SwiftShader Authors. All Rights Reserved. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #include "Configurator.hpp" |
16 | |
17 | #include <iostream> |
18 | #include <fstream> |
19 | |
20 | using namespace std; |
21 | |
22 | #include <stdio.h> |
23 | #include <stdarg.h> |
24 | #include <ctype.h> |
25 | |
26 | #if defined(__unix__) |
27 | #include <unistd.h> |
28 | #endif |
29 | |
30 | namespace sw |
31 | { |
32 | Configurator::Configurator(string iniPath) |
33 | { |
34 | path = iniPath; |
35 | |
36 | readFile(); |
37 | } |
38 | |
39 | Configurator::~Configurator() |
40 | { |
41 | } |
42 | |
43 | bool Configurator::readFile() |
44 | { |
45 | #if defined(__unix__) |
46 | if(access(path.c_str(), R_OK) != 0) |
47 | { |
48 | return false; |
49 | } |
50 | #endif |
51 | |
52 | fstream file(path.c_str(), ios::in); |
53 | if(file.fail()) return false; |
54 | |
55 | string line; |
56 | string keyName; |
57 | |
58 | while(getline(file, line)) |
59 | { |
60 | if(line.length()) |
61 | { |
62 | if(line[line.length() - 1] == '\r') |
63 | { |
64 | line = line.substr(0, line.length() - 1); |
65 | } |
66 | |
67 | if(!isprint(line[0])) |
68 | { |
69 | // printf("Failing on char %d\n", line[0]); |
70 | file.close(); |
71 | return false; |
72 | } |
73 | |
74 | string::size_type pLeft = line.find_first_of(";#[=" ); |
75 | |
76 | if(pLeft != string::npos) |
77 | { |
78 | switch(line[pLeft]) |
79 | { |
80 | case '[': |
81 | { |
82 | string::size_type pRight = line.find_last_of("]" ); |
83 | |
84 | if(pRight != string::npos && pRight > pLeft) |
85 | { |
86 | keyName = line.substr(pLeft + 1, pRight - pLeft - 1); |
87 | addKeyName(keyName); |
88 | } |
89 | } |
90 | break; |
91 | case '=': |
92 | { |
93 | string valueName = line.substr(0, pLeft); |
94 | string value = line.substr(pLeft + 1); |
95 | addValue(keyName, valueName, value); |
96 | } |
97 | break; |
98 | case ';': |
99 | case '#': |
100 | // Ignore comments |
101 | break; |
102 | } |
103 | } |
104 | } |
105 | } |
106 | |
107 | file.close(); |
108 | |
109 | if(names.size()) |
110 | { |
111 | return true; |
112 | } |
113 | |
114 | return false; |
115 | } |
116 | |
117 | void Configurator::writeFile(std::string title) |
118 | { |
119 | #if defined(__unix__) |
120 | if(access(path.c_str(), W_OK) != 0) |
121 | { |
122 | return; |
123 | } |
124 | #endif |
125 | |
126 | fstream file(path.c_str(), ios::out); |
127 | if(file.fail()) return; |
128 | |
129 | file << "; " << title << endl << endl; |
130 | |
131 | for(unsigned int keyID = 0; keyID < sections.size(); keyID++) |
132 | { |
133 | file << "[" << names[keyID] << "]" << endl; |
134 | |
135 | for(unsigned int valueID = 0; valueID < sections[keyID].names.size(); valueID++) |
136 | { |
137 | file << sections[keyID].names[valueID] << "=" << sections[keyID].values[valueID] << endl; |
138 | } |
139 | |
140 | file << endl; |
141 | } |
142 | |
143 | file.close(); |
144 | } |
145 | |
146 | int Configurator::findKey(string keyName) const |
147 | { |
148 | for(unsigned int keyID = 0; keyID < names.size(); keyID++) |
149 | { |
150 | if(names[keyID] == keyName) |
151 | { |
152 | return keyID; |
153 | } |
154 | } |
155 | |
156 | return -1; |
157 | } |
158 | |
159 | int Configurator::findValue(unsigned int keyID, string valueName) const |
160 | { |
161 | if(!sections.size() || keyID >= sections.size()) |
162 | { |
163 | return -1; |
164 | } |
165 | |
166 | for(unsigned int valueID = 0; valueID < sections[keyID].names.size(); ++valueID) |
167 | { |
168 | if(sections[keyID].names[valueID] == valueName) |
169 | { |
170 | return valueID; |
171 | } |
172 | } |
173 | |
174 | return -1; |
175 | } |
176 | |
177 | unsigned int Configurator::addKeyName(string keyName) |
178 | { |
179 | names.resize(names.size() + 1, keyName); |
180 | sections.resize(sections.size() + 1); |
181 | return (unsigned int)names.size() - 1; |
182 | } |
183 | |
184 | void Configurator::addValue(string const keyName, string const valueName, string const value) |
185 | { |
186 | int keyID = findKey(keyName); |
187 | |
188 | if(keyID == -1) |
189 | { |
190 | keyID = addKeyName(keyName); |
191 | } |
192 | |
193 | int valueID = findValue(keyID, valueName); |
194 | |
195 | if(valueID == -1) |
196 | { |
197 | sections[keyID].names.resize(sections[keyID].names.size() + 1, valueName); |
198 | sections[keyID].values.resize(sections[keyID].values.size() + 1, value); |
199 | } |
200 | else |
201 | { |
202 | sections[keyID].values[valueID] = value; |
203 | } |
204 | } |
205 | |
206 | string Configurator::getValue(string keyName, string valueName, string defaultValue) const |
207 | { |
208 | int keyID = findKey(keyName); |
209 | if(keyID == -1) return defaultValue; |
210 | int valueID = findValue((unsigned int)keyID, valueName); |
211 | if(valueID == -1) return defaultValue; |
212 | |
213 | return sections[keyID].values[valueID]; |
214 | } |
215 | |
216 | int Configurator::getInteger(string keyName, string valueName, int defaultValue) const |
217 | { |
218 | char svalue[256]; |
219 | |
220 | sprintf(svalue, "%d" , defaultValue); |
221 | |
222 | return atoi(getValue(keyName, valueName, svalue).c_str()); |
223 | } |
224 | |
225 | bool Configurator::getBoolean(string keyName, string valueName, bool defaultValue) const |
226 | { |
227 | return getInteger(keyName, valueName, (int)defaultValue) != 0; |
228 | } |
229 | |
230 | double Configurator::getFloat(string keyName, string valueName, double defaultValue) const |
231 | { |
232 | char svalue[256]; |
233 | |
234 | sprintf(svalue, "%f" , defaultValue); |
235 | |
236 | return atof(getValue(keyName, valueName, svalue).c_str()); |
237 | } |
238 | |
239 | unsigned int Configurator::getFormatted(string keyName, string valueName, char *format, |
240 | void *v1, void *v2, void *v3, void *v4, |
241 | void *v5, void *v6, void *v7, void *v8, |
242 | void *v9, void *v10, void *v11, void *v12, |
243 | void *v13, void *v14, void *v15, void *v16) |
244 | { |
245 | string value = getValue(keyName, valueName); |
246 | |
247 | if(!value.length()) return false; |
248 | |
249 | unsigned int nVals = sscanf(value.c_str(), format, |
250 | v1, v2, v3, v4, v5, v6, v7, v8, |
251 | v9, v10, v11, v12, v13, v14, v15, v16); |
252 | |
253 | return nVals; |
254 | } |
255 | } |
256 | |