GCC Code Coverage Report | |||||||||||||||||||||
|
|||||||||||||||||||||
Line | Branch | Exec | Source |
1 |
/* |
||
2 |
* The ManaPlus Client |
||
3 |
* Copyright (C) 2004-2009 The Mana World Development Team |
||
4 |
* Copyright (C) 2009-2010 The Mana Developers |
||
5 |
* Copyright (C) 2011-2019 The ManaPlus Developers |
||
6 |
* Copyright (C) 2019-2021 Andrei Karas |
||
7 |
* |
||
8 |
* This file is part of The ManaPlus Client. |
||
9 |
* |
||
10 |
* This program is free software; you can redistribute it and/or modify |
||
11 |
* it under the terms of the GNU General Public License as published by |
||
12 |
* the Free Software Foundation; either version 2 of the License, or |
||
13 |
* any later version. |
||
14 |
* |
||
15 |
* This program is distributed in the hope that it will be useful, |
||
16 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
17 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
18 |
* GNU General Public License for more details. |
||
19 |
* |
||
20 |
* You should have received a copy of the GNU General Public License |
||
21 |
* along with this program. If not, see <http://www.gnu.org/licenses/>. |
||
22 |
*/ |
||
23 |
|||
24 |
#include "configuration.h" |
||
25 |
|||
26 |
#include "variabledata.h" |
||
27 |
|||
28 |
#include "fs/files.h" |
||
29 |
#include "fs/paths.h" |
||
30 |
|||
31 |
#include "fs/virtfs/fs.h" |
||
32 |
|||
33 |
#include "listeners/configlistener.h" |
||
34 |
|||
35 |
#include "utils/cast.h" |
||
36 |
#include "utils/checkutils.h" |
||
37 |
#include "utils/foreach.h" |
||
38 |
#ifdef DEBUG_CONFIG |
||
39 |
#include "utils/stringmap.h" |
||
40 |
#endif // DEBUG_CONFIG |
||
41 |
|||
42 |
#include "debug.h" |
||
43 |
|||
44 |
#ifdef DEBUG_CONFIG |
||
45 |
StringIntMap optionsCount; |
||
46 |
#define GETLOG() if (logger) {logger->log("config get: " + key); \ |
||
47 |
if (mIsMain) optionsCount[key] = 1; } |
||
48 |
#else // DEBUG_CONFIG |
||
49 |
#define GETLOG() |
||
50 |
#endif // DEBUG_CONFIG |
||
51 |
|||
52 |
1 |
Configuration config; // XML file configuration reader |
|
53 |
1 |
Configuration serverConfig; // XML file server configuration reader |
|
54 |
1 |
Configuration features; // XML file features |
|
55 |
1 |
Configuration branding; // XML branding information reader |
|
56 |
1 |
Configuration paths; // XML default paths information reader |
|
57 |
|||
58 |
✓✓ | 3 |
const std::string unusedKeys[] = |
59 |
{ |
||
60 |
"BotCheckerWindowSticky", |
||
61 |
"afkmessage", |
||
62 |
"BotCheckerWindowVisible", |
||
63 |
"BotCheckerWindowWinX", |
||
64 |
"BotCheckerWindowWinY", |
||
65 |
"hideShield", |
||
66 |
"AttackRange", |
||
67 |
"emoteshortcut0", |
||
68 |
"screenshotDirectory2", |
||
69 |
"AttackRangeBorder", |
||
70 |
"AttackRangeBorderDelay", |
||
71 |
"AttackRangeBorderGradient", |
||
72 |
"AttackRangeDelay", |
||
73 |
"AttackRangeGradient", |
||
74 |
"Being", |
||
75 |
"BeingDelay", |
||
76 |
"BeingGradient", |
||
77 |
"BeingPopupSkin", |
||
78 |
"BotCheckerWindowSkin", |
||
79 |
"BuySellSkin", |
||
80 |
"BuySkin", |
||
81 |
"ChatSkin", |
||
82 |
"CollisionHighlight", |
||
83 |
"CollisionHighlightDelay", |
||
84 |
"CollisionHighlightGradient", |
||
85 |
"ColorCross", |
||
86 |
"ColorCrossDelay", |
||
87 |
"ColorCrossGradient", |
||
88 |
"ColorExperience", |
||
89 |
"ColorExperienceGradient", |
||
90 |
"ColorPickup", |
||
91 |
"ColorPickupGradient", |
||
92 |
"DebugSkin", |
||
93 |
"DropShortcutSkin", |
||
94 |
"EmoteShortcutSkin", |
||
95 |
"EquipmentSkin", |
||
96 |
"ExpInfo", |
||
97 |
"ExpInfoDelay", |
||
98 |
"ExpInfoGradient", |
||
99 |
"Experience", |
||
100 |
"ExperienceGradient", |
||
101 |
"GM", |
||
102 |
"GMDelay", |
||
103 |
"GMGradient", |
||
104 |
"Guild", |
||
105 |
"GuildDelay", |
||
106 |
"GuildGradient", |
||
107 |
"GuildSkin", |
||
108 |
"HelpSkin", |
||
109 |
"Hit CriticalDelay", |
||
110 |
"Hit CriticalGradient", |
||
111 |
"Hit Monster Player", |
||
112 |
"Hit Monster PlayerGradient", |
||
113 |
"Hit Player Monster", |
||
114 |
"Hit Player MonsterGradient", |
||
115 |
"HitCriticalDelay", |
||
116 |
"HitCriticalGradient", |
||
117 |
"HitLocalPlayerCriticalDelay", |
||
118 |
"HitLocalPlayerCriticalGradient", |
||
119 |
"HitLocalPlayerMiss", |
||
120 |
"HitLocalPlayerMissDelay", |
||
121 |
"HitLocalPlayerMissGradient", |
||
122 |
"HitLocalPlayerMonster", |
||
123 |
"HitLocalPlayerMonsterDelay", |
||
124 |
"HitLocalPlayerMonsterGradient", |
||
125 |
"HitMonsterPlayer", |
||
126 |
"HitMonsterPlayerDelay", |
||
127 |
"HitMonsterPlayerGradient", |
||
128 |
"HitPlayerMonster", |
||
129 |
"HitPlayerMonsterDelay", |
||
130 |
"HitPlayerMonsterGradient", |
||
131 |
"HomePlace", |
||
132 |
"HomePlaceBorder", |
||
133 |
"HomePlaceBorderDelay", |
||
134 |
"HomePlaceBorderGradient", |
||
135 |
"HomePlaceDelay", |
||
136 |
"HomePlaceGradient", |
||
137 |
"InventorySkin", |
||
138 |
"ItemPopupSkin", |
||
139 |
"ItemShortcutSkin", |
||
140 |
"Kill statsSkin", |
||
141 |
"MiniStatusSkin", |
||
142 |
"MinimapSkin", |
||
143 |
"Miss", |
||
144 |
"MissDelay", |
||
145 |
"MissGradient", |
||
146 |
"Monster", |
||
147 |
"MonsterAttackRange", |
||
148 |
"MonsterAttackRangeDelay", |
||
149 |
"MonsterAttackRangeGradient", |
||
150 |
"MonsterDelay", |
||
151 |
"MonsterGradient", |
||
152 |
"NPC", |
||
153 |
"NPCDelay", |
||
154 |
"NPCGradient", |
||
155 |
"NpcTextSkin", |
||
156 |
"OutfitsSkin", |
||
157 |
"Particle", |
||
158 |
"ParticleDelay", |
||
159 |
"ParticleGradient", |
||
160 |
"PartyDelay", |
||
161 |
"PartyGradient", |
||
162 |
"PartySkin", |
||
163 |
"Personal ShopSkin", |
||
164 |
"Pickup", |
||
165 |
"PickupGradient", |
||
166 |
"Player", |
||
167 |
"PlayerDelay", |
||
168 |
"PlayerGradient", |
||
169 |
"PopupMenuSkin", |
||
170 |
"PortalHighlight", |
||
171 |
"PortalHighlightDelay", |
||
172 |
"PortalHighlightGradient", |
||
173 |
"RecorderSkin", |
||
174 |
"RecorderWinX", |
||
175 |
"RecorderWinY", |
||
176 |
"RoadPoint", |
||
177 |
"RoadPointDelay", |
||
178 |
"RoadPointGradient", |
||
179 |
"Self", |
||
180 |
"SelfDelay", |
||
181 |
"SelfGradient", |
||
182 |
"SellSkin", |
||
183 |
"ServerDialogSkin", |
||
184 |
"ShopSkin", |
||
185 |
"SkillsSkin", |
||
186 |
"SocialCreatePopupSkin", |
||
187 |
"SocialSkin", |
||
188 |
"SpecialsSkin", |
||
189 |
"SpeechSkin", |
||
190 |
"SpellPopupSkin", |
||
191 |
"SpellShortcutSkin", |
||
192 |
"StatusPopupSkin", |
||
193 |
"StatusSkin", |
||
194 |
"StorageSkin", |
||
195 |
"TextCommandEditorSkin", |
||
196 |
"TextPopupSkin", |
||
197 |
"TradeSkin", |
||
198 |
"WhoIsOnlineSkin", |
||
199 |
"emoteshortcut1", |
||
200 |
"emoteshortcut2", |
||
201 |
"emoteshortcut3", |
||
202 |
"emoteshortcut4", |
||
203 |
"emoteshortcut5", |
||
204 |
"emoteshortcut6", |
||
205 |
"emoteshortcut7", |
||
206 |
"emoteshortcut8", |
||
207 |
"emoteshortcut9", |
||
208 |
"emoteshortcut10", |
||
209 |
"emoteshortcut11", |
||
210 |
"emoteshortcut12", |
||
211 |
"emoteshortcut13", |
||
212 |
"fastOpenGL", |
||
213 |
"keyAutoCompleteChat", |
||
214 |
"keyDeActivateChat", |
||
215 |
"keyTargetClosest", |
||
216 |
"keyWindowParty", |
||
217 |
"mapalpha", |
||
218 |
"port", |
||
219 |
"shopBuyList", |
||
220 |
"shopSellList", |
||
221 |
"OutfitAwayIndex", |
||
222 |
"playerHomes", |
||
223 |
"remember", |
||
224 |
"screenshotDirectory", |
||
225 |
"" |
||
226 |
✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✓✗✓✗ ✗✗ |
333 |
}; |
227 |
|||
228 |
void ConfigurationObject::setValue(const std::string &key, |
||
229 |
const std::string &value) |
||
230 |
{ |
||
231 |
58678 |
mOptions[key] = value; |
|
232 |
} |
||
233 |
|||
234 |
501 |
void ConfigurationObject::deleteKey(const std::string &key) |
|
235 |
{ |
||
236 |
1002 |
mOptions.erase(key); |
|
237 |
501 |
} |
|
238 |
|||
239 |
29337 |
void Configuration::setValue(const std::string &key, |
|
240 |
const std::string &value) |
||
241 |
{ |
||
242 |
58674 |
ConfigurationObject::setValue(key, value); |
|
243 |
29337 |
mUpdated = true; |
|
244 |
|||
245 |
// Notify listeners |
||
246 |
58674 |
const ListenerMapIterator list = mListenerMap.find(key); |
|
247 |
✓✓ | 58674 |
if (list != mListenerMap.end()) |
248 |
{ |
||
249 |
590 |
Listeners listeners = list->second; |
|
250 |
✓✓ | 885 |
FOR_EACH (ListenerIterator, i, listeners) |
251 |
✓✗ | 2732 |
(*i)->optionChanged(key); |
252 |
} |
||
253 |
29337 |
} |
|
254 |
|||
255 |
1 |
void Configuration::incValue(const std::string &key) |
|
256 |
{ |
||
257 |
GETLOG(); |
||
258 |
3 |
const Options::const_iterator iter = mOptions.find(key); |
|
259 |
✓✗ | 3 |
setValue(key, (iter != mOptions.end()) |
260 |
4 |
? atoi(iter->second.c_str()) + 1 : 1); |
|
261 |
1 |
} |
|
262 |
|||
263 |
2 |
void Configuration::setSilent(const std::string &key, |
|
264 |
const std::string &value) |
||
265 |
{ |
||
266 |
4 |
ConfigurationObject::setValue(key, value); |
|
267 |
2 |
} |
|
268 |
|||
269 |
10223 |
std::string ConfigurationObject::getValue(const std::string &key, |
|
270 |
const std::string &deflt) const |
||
271 |
{ |
||
272 |
GETLOG(); |
||
273 |
20446 |
const Options::const_iterator iter = mOptions.find(key); |
|
274 |
✓✓ | 38708 |
return ((iter != mOptions.end()) ? iter->second : deflt); |
275 |
} |
||
276 |
|||
277 |
8637 |
int ConfigurationObject::getValue(const std::string &key, |
|
278 |
const int deflt) const |
||
279 |
{ |
||
280 |
GETLOG(); |
||
281 |
17274 |
const Options::const_iterator iter = mOptions.find(key); |
|
282 |
✓✓ | 42270 |
return (iter != mOptions.end()) ? atoi(iter->second.c_str()) : deflt; |
283 |
} |
||
284 |
|||
285 |
8554 |
int ConfigurationObject::getValueInt(const std::string &key, |
|
286 |
const int deflt) const |
||
287 |
{ |
||
288 |
GETLOG(); |
||
289 |
17108 |
const Options::const_iterator iter = mOptions.find(key); |
|
290 |
✓✓ | 42215 |
return (iter != mOptions.end()) ? atoi(iter->second.c_str()) : deflt; |
291 |
} |
||
292 |
|||
293 |
261 |
bool ConfigurationObject::getValueBool(const std::string &key, |
|
294 |
const bool deflt) const |
||
295 |
{ |
||
296 |
GETLOG(); |
||
297 |
522 |
const Options::const_iterator iter = mOptions.find(key); |
|
298 |
✓✓ | 522 |
if (iter != mOptions.end()) |
299 |
54 |
return atoi(iter->second.c_str()) != 0 ? true : false; |
|
300 |
return deflt; |
||
301 |
} |
||
302 |
|||
303 |
8 |
unsigned ConfigurationObject::getValue(const std::string &key, |
|
304 |
const unsigned deflt) const |
||
305 |
{ |
||
306 |
GETLOG(); |
||
307 |
16 |
const Options::const_iterator iter = mOptions.find(key); |
|
308 |
✓✓ | 21 |
return (iter != mOptions.end()) ? CAST_U32( |
309 |
23 |
atol(iter->second.c_str())) : deflt; |
|
310 |
} |
||
311 |
|||
312 |
6 |
double ConfigurationObject::getValue(const std::string &key, |
|
313 |
const double deflt) const |
||
314 |
{ |
||
315 |
GETLOG(); |
||
316 |
12 |
const Options::const_iterator iter = mOptions.find(key); |
|
317 |
✓✓ | 27 |
return (iter != mOptions.end()) ? atof(iter->second.c_str()) : deflt; |
318 |
} |
||
319 |
|||
320 |
408 |
void ConfigurationObject::deleteList(const std::string &name) |
|
321 |
{ |
||
322 |
✗✓ | 408 |
for (ConfigurationList::const_iterator |
323 |
1224 |
it = mContainerOptions[name].begin(); |
|
324 |
816 |
it != mContainerOptions[name].end(); ++it) |
|
325 |
{ |
||
326 |
delete *it; |
||
327 |
} |
||
328 |
|||
329 |
816 |
mContainerOptions[name].clear(); |
|
330 |
408 |
} |
|
331 |
|||
332 |
1353 |
void ConfigurationObject::clear() |
|
333 |
{ |
||
334 |
✓✓ | 1557 |
for (std::map<std::string, ConfigurationList>::const_iterator |
335 |
4059 |
it = mContainerOptions.begin(); |
|
336 |
3114 |
it != mContainerOptions.end(); ++it) |
|
337 |
{ |
||
338 |
204 |
deleteList(it->first); |
|
339 |
} |
||
340 |
2706 |
mOptions.clear(); |
|
341 |
2706 |
mContainerOptions.clear(); |
|
342 |
1353 |
} |
|
343 |
|||
344 |
209 |
ConfigurationObject::ConfigurationObject() : |
|
345 |
mOptions(), |
||
346 |
#ifdef DEBUG_CONFIG |
||
347 |
mContainerOptions(), |
||
348 |
mLogKeys(false), |
||
349 |
mIsMain(false) |
||
350 |
#else // DEBUG_CONFIG |
||
351 |
|||
352 |
627 |
mContainerOptions() |
|
353 |
#endif // DEBUG_CONFIG |
||
354 |
{ |
||
355 |
204 |
} |
|
356 |
|||
357 |
1040 |
ConfigurationObject::~ConfigurationObject() |
|
358 |
{ |
||
359 |
209 |
clear(); |
|
360 |
413 |
} |
|
361 |
|||
362 |
5 |
Configuration::Configuration() : |
|
363 |
ConfigurationObject(), |
||
364 |
mListenerMap(), |
||
365 |
mConfigPath(), |
||
366 |
mDefaultsData(), |
||
367 |
mDirectory(), |
||
368 |
mFilename(), |
||
369 |
mUseResManager(UseVirtFs_false), |
||
370 |
35 |
mUpdated(false) |
|
371 |
{ |
||
372 |
#ifdef DEBUG_CONFIG |
||
373 |
mLogKeys = false; |
||
374 |
mIsMain = false; |
||
375 |
#endif // DEBUG_CONFIG |
||
376 |
} |
||
377 |
|||
378 |
1441 |
void Configuration::cleanDefaults() |
|
379 |
{ |
||
380 |
✓✓ | 221490 |
for (DefaultsData::const_iterator iter = mDefaultsData.begin(); |
381 |
434334 |
iter != mDefaultsData.end(); |
|
382 |
++iter) |
||
383 |
{ |
||
384 |
✓✗ | 215726 |
delete iter->second; |
385 |
} |
||
386 |
2882 |
mDefaultsData.clear(); |
|
387 |
1441 |
} |
|
388 |
|||
389 |
35 |
Configuration::~Configuration() |
|
390 |
{ |
||
391 |
5 |
cleanDefaults(); |
|
392 |
5 |
} |
|
393 |
|||
394 |
void Configuration::unload() |
||
395 |
{ |
||
396 |
cleanDefaults(); |
||
397 |
mConfigPath.clear(); |
||
398 |
mDirectory.clear(); |
||
399 |
mFilename.clear(); |
||
400 |
mUseResManager = UseVirtFs_false; |
||
401 |
ConfigurationObject::clear(); |
||
402 |
} |
||
403 |
|||
404 |
1033 |
int Configuration::getIntValue(const std::string &key) const |
|
405 |
{ |
||
406 |
GETLOG(); |
||
407 |
1033 |
int defaultValue = 0; |
|
408 |
2066 |
const Options::const_iterator iter = mOptions.find(key); |
|
409 |
✓✓ | 2066 |
if (iter == mOptions.end()) |
410 |
{ |
||
411 |
const DefaultsData::const_iterator itdef |
||
412 |
1770 |
= mDefaultsData.find(key); |
|
413 |
|||
414 |
✓✓✗✓ ✓✓ |
2654 |
if (itdef != mDefaultsData.end() && (itdef->second != nullptr)) |
415 |
{ |
||
416 |
884 |
const VariableData *const data = itdef->second; |
|
417 |
const VariableData::DataType type = static_cast< |
||
418 |
884 |
VariableData::DataType>(data->getType()); |
|
419 |
✓✓ | 884 |
if (type == VariableData::DATA_INT) |
420 |
{ |
||
421 |
defaultValue = (static_cast<const IntData*>( |
||
422 |
880 |
data))->getData(); |
|
423 |
} |
||
424 |
✓✓ | 4 |
else if (type == VariableData::DATA_STRING) |
425 |
{ |
||
426 |
1 |
defaultValue = atoi((static_cast<const StringData*>( |
|
427 |
2 |
data))->getData().c_str()); |
|
428 |
} |
||
429 |
✓✓ | 3 |
else if (type == VariableData::DATA_BOOL) |
430 |
{ |
||
431 |
✓✓ | 2 |
if ((static_cast<const BoolData*>(data))->getData()) |
432 |
defaultValue = 1; |
||
433 |
else |
||
434 |
1 |
defaultValue = 0; |
|
435 |
} |
||
436 |
✓✗ | 1 |
else if (type == VariableData::DATA_FLOAT) |
437 |
{ |
||
438 |
1 |
defaultValue = CAST_S32( |
|
439 |
1 |
(static_cast<const FloatData*>(data))->getData()); |
|
440 |
} |
||
441 |
} |
||
442 |
else |
||
443 |
{ |
||
444 |
✓✗ | 4 |
reportAlways( |
445 |
"%s: No integer value in registry for key %s", |
||
446 |
mConfigPath.c_str(), |
||
447 |
key.c_str()) |
||
448 |
} |
||
449 |
} |
||
450 |
else |
||
451 |
{ |
||
452 |
444 |
defaultValue = atoi(iter->second.c_str()); |
|
453 |
} |
||
454 |
1032 |
return defaultValue; |
|
455 |
} |
||
456 |
|||
457 |
1 |
int Configuration::resetIntValue(const std::string &key) |
|
458 |
{ |
||
459 |
GETLOG(); |
||
460 |
1 |
int defaultValue = 0; |
|
461 |
3 |
const DefaultsData::const_iterator itdef = mDefaultsData.find(key); |
|
462 |
✗✓ | 2 |
if (itdef == mDefaultsData.end()) |
463 |
{ |
||
464 |
reportAlways("%s: No integer value in registry for key %s", |
||
465 |
mConfigPath.c_str(), |
||
466 |
key.c_str()) |
||
467 |
} |
||
468 |
else |
||
469 |
{ |
||
470 |
1 |
const VariableData *const data = itdef->second; |
|
471 |
✓✗✗✓ ✓✗ |
2 |
if (data != nullptr && |
472 |
1 |
data->getType() == VariableData::DATA_INT) |
|
473 |
{ |
||
474 |
defaultValue = (static_cast<const IntData*>( |
||
475 |
1 |
data))->getData(); |
|
476 |
} |
||
477 |
else |
||
478 |
{ |
||
479 |
reportAlways("%s: No integer value in registry for key %s", |
||
480 |
mConfigPath.c_str(), |
||
481 |
key.c_str()) |
||
482 |
} |
||
483 |
} |
||
484 |
1 |
setValue(key, defaultValue); |
|
485 |
1 |
return defaultValue; |
|
486 |
} |
||
487 |
|||
488 |
3975 |
std::string Configuration::getStringValue(const std::string &key) const |
|
489 |
{ |
||
490 |
GETLOG(); |
||
491 |
3975 |
std::string defaultValue; |
|
492 |
7950 |
const Options::const_iterator iter = mOptions.find(key); |
|
493 |
✓✓ | 7950 |
if (iter == mOptions.end()) |
494 |
{ |
||
495 |
const DefaultsData::const_iterator |
||
496 |
7880 |
itdef = mDefaultsData.find(key); |
|
497 |
|||
498 |
✓✓✗✓ ✓✓ |
11819 |
if (itdef != mDefaultsData.end() && |
499 |
3939 |
(itdef->second != nullptr)) |
|
500 |
{ |
||
501 |
3939 |
const VariableData *const data = itdef->second; |
|
502 |
const VariableData::DataType type = static_cast< |
||
503 |
✓✗ | 3939 |
VariableData::DataType>(data->getType()); |
504 |
✓✓ | 3939 |
if (type == VariableData::DATA_STRING) |
505 |
{ |
||
506 |
defaultValue = (static_cast<const StringData*>( |
||
507 |
3841 |
data))->getData(); |
|
508 |
} |
||
509 |
✓✓ | 98 |
else if (type == VariableData::DATA_BOOL) |
510 |
{ |
||
511 |
✓✓ | 4 |
if ((static_cast<const BoolData*>(data))->getData()) |
512 |
defaultValue = "1"; |
||
513 |
else |
||
514 |
defaultValue = "0"; |
||
515 |
} |
||
516 |
✓✓ | 94 |
else if (type == VariableData::DATA_INT) |
517 |
{ |
||
518 |
✓✗ | 182 |
defaultValue = toString((static_cast<const IntData*>( |
519 |
91 |
data))->getData()); |
|
520 |
} |
||
521 |
✓✗ | 3 |
else if (type == VariableData::DATA_FLOAT) |
522 |
{ |
||
523 |
✓✗ | 6 |
defaultValue = toString((static_cast<const FloatData*>( |
524 |
3 |
data))->getData()); |
|
525 |
} |
||
526 |
} |
||
527 |
else |
||
528 |
{ |
||
529 |
✓✗✓✗ ✓✗✓✗ |
4 |
reportAlways("%s: No string value in registry for key %s", |
530 |
mConfigPath.c_str(), |
||
531 |
key.c_str()) |
||
532 |
} |
||
533 |
} |
||
534 |
else |
||
535 |
{ |
||
536 |
35 |
defaultValue = iter->second; |
|
537 |
} |
||
538 |
3974 |
return defaultValue; |
|
539 |
} |
||
540 |
|||
541 |
|||
542 |
70 |
float Configuration::getFloatValue(const std::string &key) const |
|
543 |
{ |
||
544 |
GETLOG(); |
||
545 |
70 |
float defaultValue = 0.0F; |
|
546 |
140 |
const Options::const_iterator iter = mOptions.find(key); |
|
547 |
✓✓ | 140 |
if (iter == mOptions.end()) |
548 |
{ |
||
549 |
const DefaultsData::const_iterator itdef |
||
550 |
118 |
= mDefaultsData.find(key); |
|
551 |
|||
552 |
✓✓✗✓ ✓✓ |
176 |
if (itdef != mDefaultsData.end() && |
553 |
58 |
(itdef->second != nullptr)) |
|
554 |
{ |
||
555 |
58 |
const VariableData *const data = itdef->second; |
|
556 |
const VariableData::DataType type = static_cast< |
||
557 |
58 |
VariableData::DataType>(data->getType()); |
|
558 |
✓✓ | 58 |
if (type == VariableData::DATA_FLOAT) |
559 |
{ |
||
560 |
54 |
defaultValue = static_cast<float>( |
|
561 |
54 |
(static_cast<const FloatData*>(data))->getData()); |
|
562 |
} |
||
563 |
✓✓ | 4 |
else if (type == VariableData::DATA_STRING) |
564 |
{ |
||
565 |
2 |
defaultValue = static_cast<float>(atof(( |
|
566 |
static_cast<const StringData*>( |
||
567 |
1 |
data))->getData().c_str())); |
|
568 |
} |
||
569 |
✓✓ | 3 |
else if (type == VariableData::DATA_BOOL) |
570 |
{ |
||
571 |
✓✓ | 2 |
if ((static_cast<const BoolData*>(data))->getData()) |
572 |
defaultValue = 1; |
||
573 |
else |
||
574 |
1 |
defaultValue = 0; |
|
575 |
} |
||
576 |
✓✗ | 1 |
else if (type == VariableData::DATA_INT) |
577 |
{ |
||
578 |
1 |
defaultValue = static_cast<float>(( |
|
579 |
static_cast<const IntData*>( |
||
580 |
1 |
data))->getData()); |
|
581 |
} |
||
582 |
} |
||
583 |
else |
||
584 |
{ |
||
585 |
✓✗ | 4 |
reportAlways("%s: No float value in registry for key %s", |
586 |
mConfigPath.c_str(), |
||
587 |
key.c_str()) |
||
588 |
} |
||
589 |
} |
||
590 |
else |
||
591 |
{ |
||
592 |
33 |
defaultValue = static_cast<float>(atof(iter->second.c_str())); |
|
593 |
} |
||
594 |
69 |
return defaultValue; |
|
595 |
} |
||
596 |
|||
597 |
2411 |
bool Configuration::getBoolValue(const std::string &key) const |
|
598 |
{ |
||
599 |
GETLOG(); |
||
600 |
2411 |
bool defaultValue = false; |
|
601 |
4822 |
const Options::const_iterator iter = mOptions.find(key); |
|
602 |
✓✓ | 4822 |
if (iter == mOptions.end()) |
603 |
{ |
||
604 |
const DefaultsData::const_iterator itdef |
||
605 |
4794 |
= mDefaultsData.find(key); |
|
606 |
|||
607 |
✓✓✗✓ ✓✓ |
7190 |
if (itdef != mDefaultsData.end() && |
608 |
2396 |
(itdef->second != nullptr)) |
|
609 |
{ |
||
610 |
2396 |
const VariableData *const data = itdef->second; |
|
611 |
const VariableData::DataType type = static_cast< |
||
612 |
2396 |
VariableData::DataType>(data->getType()); |
|
613 |
✓✓ | 2396 |
if (type == VariableData::DATA_BOOL) |
614 |
{ |
||
615 |
defaultValue = (static_cast<const BoolData*>( |
||
616 |
2391 |
data))->getData(); |
|
617 |
} |
||
618 |
✓✓ | 5 |
else if (type == VariableData::DATA_INT) |
619 |
{ |
||
620 |
✓✓ | 3 |
if ((static_cast<const IntData*>(data))->getData() != 0) |
621 |
defaultValue = true; |
||
622 |
else |
||
623 |
2 |
defaultValue = false; |
|
624 |
} |
||
625 |
✓✓ | 2 |
else if (type == VariableData::DATA_STRING) |
626 |
{ |
||
627 |
✗✓ | 1 |
if ((static_cast<const StringData*>( |
628 |
1 |
data))->getData() != "0") |
|
629 |
{ |
||
630 |
defaultValue = true; |
||
631 |
} |
||
632 |
else |
||
633 |
{ |
||
634 |
defaultValue = false; |
||
635 |
} |
||
636 |
} |
||
637 |
✓✓ | 2396 |
if (type == VariableData::DATA_FLOAT) |
638 |
{ |
||
639 |
✓✗ | 1 |
if (CAST_S32((static_cast<const FloatData*>( |
640 |
1 |
data))->getData()) != 0) |
|
641 |
{ |
||
642 |
defaultValue = true; |
||
643 |
} |
||
644 |
else |
||
645 |
{ |
||
646 |
1 |
defaultValue = false; |
|
647 |
} |
||
648 |
} |
||
649 |
} |
||
650 |
else |
||
651 |
{ |
||
652 |
✓✗ | 4 |
reportAlways( |
653 |
"%s: No boolean value in registry for key %s", |
||
654 |
mConfigPath.c_str(), |
||
655 |
key.c_str()) |
||
656 |
} |
||
657 |
} |
||
658 |
else |
||
659 |
{ |
||
660 |
14 |
defaultValue = getBoolFromString(iter->second); |
|
661 |
} |
||
662 |
|||
663 |
2410 |
return defaultValue; |
|
664 |
} |
||
665 |
|||
666 |
2 |
bool Configuration::resetBoolValue(const std::string &key) |
|
667 |
{ |
||
668 |
GETLOG(); |
||
669 |
2 |
bool defaultValue = false; |
|
670 |
6 |
const DefaultsData::const_iterator itdef = mDefaultsData.find(key); |
|
671 |
|||
672 |
✗✓ | 4 |
if (itdef == mDefaultsData.end()) |
673 |
{ |
||
674 |
reportAlways("%s: No boolean value in registry for key %s", |
||
675 |
mConfigPath.c_str(), |
||
676 |
key.c_str()) |
||
677 |
} |
||
678 |
else |
||
679 |
{ |
||
680 |
2 |
const VariableData *const data = itdef->second; |
|
681 |
✓✗✗✓ ✓✗ |
4 |
if (data != nullptr && |
682 |
2 |
data->getType() == VariableData::DATA_BOOL) |
|
683 |
{ |
||
684 |
2 |
defaultValue = (static_cast<const BoolData*>(data))->getData(); |
|
685 |
} |
||
686 |
else |
||
687 |
{ |
||
688 |
reportAlways("%s: No boolean value in registry for key %s", |
||
689 |
mConfigPath.c_str(), |
||
690 |
key.c_str()) |
||
691 |
} |
||
692 |
} |
||
693 |
|||
694 |
4 |
setValue(key, defaultValue); |
|
695 |
2 |
return defaultValue; |
|
696 |
} |
||
697 |
|||
698 |
|||
699 |
368 |
void ConfigurationObject::initFromXML(XmlNodeConstPtrConst parentNode) |
|
700 |
{ |
||
701 |
368 |
clear(); |
|
702 |
|||
703 |
✓✗ | 368 |
if (parentNode == nullptr) |
704 |
return; |
||
705 |
|||
706 |
✓✓ | 114240 |
for_each_xml_child_node(node, parentNode) |
707 |
{ |
||
708 |
✗✓ | 113872 |
if (xmlNameEqual(node, "list")) |
709 |
{ |
||
710 |
// list option handling |
||
711 |
const std::string name = XML::getProperty(node, |
||
712 |
"name", std::string()); |
||
713 |
|||
714 |
for_each_xml_child_node(subnode, node) |
||
715 |
{ |
||
716 |
if (xmlNameEqual(subnode, name.c_str()) && |
||
717 |
xmlTypeEqual(subnode, XML_ELEMENT_NODE)) |
||
718 |
{ |
||
719 |
ConfigurationObject *const cobj = new ConfigurationObject; |
||
720 |
cobj->initFromXML(subnode); // recurse |
||
721 |
mContainerOptions[name].push_back(cobj); |
||
722 |
} |
||
723 |
} |
||
724 |
} |
||
725 |
✓✓ | 113872 |
else if (xmlNameEqual(node, "option")) |
726 |
{ |
||
727 |
// single option handling |
||
728 |
const std::string name = XML::getProperty(node, |
||
729 |
✓✗ | 170256 |
"name", std::string()); |
730 |
✓✗ | 56752 |
if (!name.empty()) |
731 |
{ |
||
732 |
✓✗✓✗ |
113504 |
mOptions[name] = XML::getProperty(node, |
733 |
170256 |
"value", std::string()); |
|
734 |
} |
||
735 |
} // otherwise ignore |
||
736 |
} |
||
737 |
} |
||
738 |
|||
739 |
368 |
void Configuration::init(const std::string &filename, |
|
740 |
const UseVirtFs useResManager, |
||
741 |
const SkipError skipError) |
||
742 |
{ |
||
743 |
368 |
cleanDefaults(); |
|
744 |
368 |
clear(); |
|
745 |
736 |
mFilename = filename; |
|
746 |
368 |
mUseResManager = useResManager; |
|
747 |
|||
748 |
✗✓ | 368 |
if (useResManager == UseVirtFs_true) |
749 |
{ |
||
750 |
mConfigPath = "virtfs://" + filename; |
||
751 |
mDirectory.clear(); |
||
752 |
if (VirtFs::exists(filename) == false) |
||
753 |
{ |
||
754 |
logger->log("Warning: No configuration file (%s)", |
||
755 |
filename.c_str()); |
||
756 |
return; |
||
757 |
} |
||
758 |
} |
||
759 |
else |
||
760 |
{ |
||
761 |
736 |
mConfigPath = filename; |
|
762 |
368 |
logger->log1("init 1"); |
|
763 |
✓✗ | 1104 |
mDirectory = getRealPath(getFileDir(filename)); |
764 |
✗✓ | 368 |
if (Files::existsLocal(filename) == false) |
765 |
{ |
||
766 |
logger->log("Warning: No configuration file (%s)", |
||
767 |
filename.c_str()); |
||
768 |
return; |
||
769 |
} |
||
770 |
} |
||
771 |
|||
772 |
XML::Document doc(filename, |
||
773 |
useResManager, |
||
774 |
736 |
skipError); |
|
775 |
✓✗ | 368 |
logger->log1("init 2"); |
776 |
✓✗✗✓ |
368 |
if (doc.rootNode() == nullptr) |
777 |
{ |
||
778 |
logger->log("Couldn't open configuration file: %s", filename.c_str()); |
||
779 |
return; |
||
780 |
} |
||
781 |
|||
782 |
✓✗ | 368 |
XmlNodeConstPtrConst rootNode = doc.rootNode(); |
783 |
|||
784 |
✓✗✓✗ ✗✓✗✓ |
368 |
if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "configuration")) |
785 |
{ |
||
786 |
logger->log("Warning: No configuration file (%s)", filename.c_str()); |
||
787 |
return; |
||
788 |
} |
||
789 |
|||
790 |
✓✗ | 368 |
initFromXML(rootNode); |
791 |
} |
||
792 |
|||
793 |
void Configuration::reInit() |
||
794 |
{ |
||
795 |
XML::Document doc(mFilename, mUseResManager, SkipError_false); |
||
796 |
if (doc.rootNode() == nullptr) |
||
797 |
{ |
||
798 |
logger->log("Couldn't open configuration file: %s", mFilename.c_str()); |
||
799 |
return; |
||
800 |
} |
||
801 |
|||
802 |
XmlNodeConstPtrConst rootNode = doc.rootNode(); |
||
803 |
|||
804 |
if ((rootNode == nullptr) || !xmlNameEqual(rootNode, "configuration")) |
||
805 |
{ |
||
806 |
logger->log("Warning: No configuration file (%s)", mFilename.c_str()); |
||
807 |
return; |
||
808 |
} |
||
809 |
|||
810 |
initFromXML(rootNode); |
||
811 |
} |
||
812 |
|||
813 |
358 |
void ConfigurationObject::writeToXML(XmlTextWriterPtr writer) |
|
814 |
{ |
||
815 |
✓✓ | 1790 |
FOR_EACH (Options::const_iterator, i, mOptions) |
816 |
{ |
||
817 |
#ifdef DEBUG_CONFIG |
||
818 |
if (mLogKeys) |
||
819 |
{ |
||
820 |
if (optionsCount.find(i->first) == optionsCount.end()) |
||
821 |
logger->log("unused configuration option: " + i->first); |
||
822 |
} |
||
823 |
#endif // DEBUG_CONFIG |
||
824 |
|||
825 |
43081 |
XmlTextWriterStartElement(writer, "option"); |
|
826 |
86162 |
XmlTextWriterWriteAttribute(writer, "name", i->first.c_str()); |
|
827 |
86162 |
XmlTextWriterWriteAttribute(writer, "value", i->second.c_str()); |
|
828 |
43081 |
XmlTextWriterEndElement(writer); |
|
829 |
} |
||
830 |
|||
831 |
✓✓ | 512 |
for (std::map<std::string, ConfigurationList>::const_iterator |
832 |
1790 |
it = mContainerOptions.begin(), it_fend = mContainerOptions.end(); |
|
833 |
it != it_fend; ++ it) |
||
834 |
{ |
||
835 |
308 |
const char *const name = it->first.c_str(); |
|
836 |
|||
837 |
154 |
XmlTextWriterStartElement(writer, "list"); |
|
838 |
154 |
XmlTextWriterWriteAttribute(writer, "name", name); |
|
839 |
|||
840 |
// recurse on all elements |
||
841 |
✗✓ | 616 |
FOR_EACH (ConfigurationList::const_iterator, elt_it, it->second) |
842 |
{ |
||
843 |
XmlTextWriterStartElement(writer, name); |
||
844 |
if (*elt_it != nullptr) |
||
845 |
(*elt_it)->writeToXML(writer); |
||
846 |
XmlTextWriterEndElement(writer); |
||
847 |
} |
||
848 |
|||
849 |
154 |
XmlTextWriterEndElement(writer); |
|
850 |
} |
||
851 |
358 |
} |
|
852 |
|||
853 |
void Configuration::writeUpdated() |
||
854 |
{ |
||
855 |
if (mUpdated) |
||
856 |
write(); |
||
857 |
} |
||
858 |
|||
859 |
612 |
void Configuration::write() |
|
860 |
{ |
||
861 |
BLOCK_START("Configuration::write") |
||
862 |
✓✓ | 1224 |
if (mConfigPath.empty()) |
863 |
{ |
||
864 |
BLOCK_END("Configuration::write") |
||
865 |
return; |
||
866 |
} |
||
867 |
|||
868 |
358 |
mUpdated = false; |
|
869 |
// Do not attempt to write to file that cannot be opened for writing |
||
870 |
716 |
FILE *const testFile = fopen(mConfigPath.c_str(), "w"); |
|
871 |
✗✓ | 358 |
if (testFile == nullptr) |
872 |
{ |
||
873 |
reportAlways("Configuration::write() couldn't open %s for writing", |
||
874 |
mConfigPath.c_str()) |
||
875 |
BLOCK_END("Configuration::write") |
||
876 |
return; |
||
877 |
} |
||
878 |
358 |
fclose(testFile); |
|
879 |
|||
880 |
716 |
XmlTextWriterPtr writer = XmlNewTextWriterFilename( |
|
881 |
mConfigPath.c_str(), 0); |
||
882 |
|||
883 |
✗✓ | 358 |
if (writer == nullptr) |
884 |
{ |
||
885 |
logger->log1("Configuration::write() error while creating writer"); |
||
886 |
BLOCK_END("Configuration::write") |
||
887 |
return; |
||
888 |
} |
||
889 |
|||
890 |
358 |
logger->log1("Configuration::write() writing configuration..."); |
|
891 |
|||
892 |
358 |
XmlTextWriterSetIndent(writer, 1); |
|
893 |
358 |
XmlTextWriterStartDocument(writer, nullptr, nullptr, nullptr); |
|
894 |
// xmlTextWriterStartDocument(writer, nullptr, "utf8", nullptr); |
||
895 |
358 |
XmlTextWriterStartRootElement(writer, "configuration"); |
|
896 |
|||
897 |
358 |
writeToXML(writer); |
|
898 |
|||
899 |
358 |
XmlTextWriterEndDocument(writer); |
|
900 |
XmlSaveTextWriterFilename(writer, |
||
901 |
mConfigPath.c_str()); |
||
902 |
358 |
XmlFreeTextWriter(writer); |
|
903 |
BLOCK_END("Configuration::write") |
||
904 |
} |
||
905 |
|||
906 |
2817 |
void Configuration::addListener(const std::string &key, |
|
907 |
ConfigListener *const listener) |
||
908 |
{ |
||
909 |
5634 |
mListenerMap[key].push_front(listener); |
|
910 |
2817 |
} |
|
911 |
|||
912 |
470 |
void Configuration::removeListener(const std::string &key, |
|
913 |
ConfigListener *const listener) |
||
914 |
{ |
||
915 |
470 |
mListenerMap[key].remove(listener); |
|
916 |
470 |
} |
|
917 |
|||
918 |
#ifdef ENABLE_CHECKS |
||
919 |
void Configuration::checkListeners(ConfigListener *const listener, |
||
920 |
const char *const file, |
||
921 |
const unsigned line) |
||
922 |
{ |
||
923 |
FOR_EACH (ListenerMapIterator, it, mListenerMap) |
||
924 |
{ |
||
925 |
Listeners listeners = it->second; |
||
926 |
FOR_EACH (ListenerIterator, it2, listeners) |
||
927 |
{ |
||
928 |
if (*it2 == listener) |
||
929 |
{ |
||
930 |
logger->log("detected not cleaned listener: %p, %s:%u", |
||
931 |
static_cast<void*>(listener), file, line); |
||
932 |
exit(1); |
||
933 |
} |
||
934 |
} |
||
935 |
} |
||
936 |
} |
||
937 |
#endif // ENABLE_CHECKS |
||
938 |
|||
939 |
1099 |
void Configuration::removeListeners(ConfigListener *const listener) |
|
940 |
{ |
||
941 |
✓✓ | 3297 |
FOR_EACH (ListenerMapIterator, it, mListenerMap) |
942 |
29071 |
(it->second).remove(listener); |
|
943 |
1099 |
} |
|
944 |
|||
945 |
204 |
void Configuration::removeOldKeys() |
|
946 |
{ |
||
947 |
✓✗✗✓ |
1428 |
if (mOptions.find(unusedKeys[0]) != mOptions.end() || |
948 |
✓✗✗✓ |
1428 |
mOptions.find(unusedKeys[1]) != mOptions.end() || |
949 |
816 |
mOptions.find(unusedKeys[2]) != mOptions.end()) |
|
950 |
{ |
||
951 |
int f = 0; |
||
952 |
while (!unusedKeys[f].empty()) |
||
953 |
{ |
||
954 |
deleteKey(unusedKeys[f]); |
||
955 |
logger->log("remove unused key: " + unusedKeys[f]); |
||
956 |
f ++; |
||
957 |
} |
||
958 |
for (f = 0; f < 80; f ++) |
||
959 |
{ |
||
960 |
const std::string str = toString(f); |
||
961 |
deleteKey("Outfit" + str); |
||
962 |
deleteKey("OutfitUnequip" + str); |
||
963 |
deleteKey("commandShortcutCmd" + str); |
||
964 |
deleteKey("commandShortcutFlags" + str); |
||
965 |
deleteKey("commandShortcutSymbol" + str); |
||
966 |
deleteKey("drop" + str); |
||
967 |
deleteKey("shortcut" + str); |
||
968 |
} |
||
969 |
} |
||
970 |
✓✗✓✗ |
207 |
} |
Generated by: GCOVR (Version 3.3) |