1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#include "KeyValueRepositoryConfigfile.hxx"
19#include "Logger.hxx"
20
21namespace {
22 string trim(const string& str)
23 {
24 string::size_type first = str.find_first_not_of(' ');
25 return (first == string::npos) ? EmptyString :
26 str.substr(first, str.find_last_not_of(' ')-first+1);
27 }
28}
29
30// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
31KeyValueRepositoryConfigfile::KeyValueRepositoryConfigfile(const string& filename)
32 : myFilename(filename)
33{}
34
35// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
36std::map<string, Variant> KeyValueRepositoryConfigfile::load()
37{
38 std::map<string, Variant> values;
39
40 string line, key, value;
41 string::size_type equalPos, garbage;
42
43 ifstream in(myFilename);
44 if(!in || !in.is_open()) {
45 Logger::error("ERROR: Couldn't load from settings file " + myFilename);
46
47 return values;
48 }
49
50 while(getline(in, line))
51 {
52 // Strip all whitespace and tabs from the line
53 while((garbage = line.find("\t")) != string::npos)
54 line.erase(garbage, 1);
55
56 // Ignore commented and empty lines
57 if((line.length() == 0) || (line[0] == ';'))
58 continue;
59
60 // Search for the equal sign and discard the line if its not found
61 if((equalPos = line.find("=")) == string::npos)
62 continue;
63
64 // Split the line into key/value pairs and trim any whitespace
65 key = trim(line.substr(0, equalPos));
66 value = trim(line.substr(equalPos + 1, line.length() - key.length() - 1));
67
68 // Skip absent key
69 if(key.length() == 0)
70 continue;
71
72 values[key] = value;
73 }
74
75 return values;
76}
77
78// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
79void KeyValueRepositoryConfigfile::save(const std::map<string, Variant>& values)
80{
81ofstream out(myFilename);
82 if(!out || !out.is_open()) {
83 Logger::error("ERROR: Couldn't save to settings file " + myFilename);
84
85 return;
86 }
87
88 out << "; Stella configuration file" << endl
89 << ";" << endl
90 << "; Lines starting with ';' are comments and are ignored." << endl
91 << "; Spaces and tabs are ignored." << endl
92 << ";" << endl
93 << "; Format MUST be as follows:" << endl
94 << "; command = value" << endl
95 << ";" << endl
96 << "; Commands are the same as those specified on the commandline," << endl
97 << "; without the '-' character." << endl
98 << ";" << endl
99 << "; Values are the same as those allowed on the commandline." << endl
100 << "; Boolean values are specified as 1 (or true) and 0 (or false)" << endl
101 << ";" << endl;
102
103 // Write out each of the key and value pairs
104 for(const auto& pair: values)
105 out << pair.first << " = " << pair.second << endl;
106}
107