| 84 | } |
| 85 | |
| 86 | void Settings::SettingsFileParser::saveSettingsFile( |
| 87 | const std::filesystem::path& file, const CategorySettingValueMap& settings) |
| 88 | { |
| 89 | using CategorySettingStatusMap = std::map<CategorySetting, bool>; |
| 90 | |
| 91 | // No options have been written to the file yet. |
| 92 | CategorySettingStatusMap written; |
| 93 | for (auto it = settings.begin(); it != settings.end(); ++it) |
| 94 | { |
| 95 | written[it->first] = false; |
| 96 | } |
| 97 | |
| 98 | // Have we substantively changed the settings file? |
| 99 | bool changed = false; |
| 100 | |
| 101 | // Were there any lines at all in the file? |
| 102 | bool existing = false; |
| 103 | |
| 104 | // Is an entirely blank line queued to be added? |
| 105 | bool emptyLineQueued = false; |
| 106 | |
| 107 | // The category/section we're currently in. |
| 108 | std::string currentCategory; |
| 109 | |
| 110 | // Open the existing settings.cfg file to copy comments. This might not be the same file |
| 111 | // as the output file if we're copying the setting from the default settings.cfg for the |
| 112 | // first time. A minor change in API to pass the source file might be in order here. |
| 113 | std::ifstream istream; |
| 114 | istream.open(file); |
| 115 | |
| 116 | // Create a new string stream to write the current settings to. It's likely that the |
| 117 | // input file and the output file are the same, so this stream serves as a temporary file |
| 118 | // of sorts. The setting files aren't very large so there's no performance issue. |
| 119 | std::stringstream ostream; |
| 120 | |
| 121 | // For every line in the input file... |
| 122 | while (!istream.eof() && !istream.fail()) |
| 123 | { |
| 124 | std::string line; |
| 125 | std::getline(istream, line); |
| 126 | |
| 127 | // The current character position in the line. |
| 128 | size_t i = 0; |
| 129 | |
| 130 | // An empty line was queued. |
| 131 | if (emptyLineQueued) |
| 132 | { |
| 133 | emptyLineQueued = false; |
| 134 | // We're still going through the current category, so we should copy it. |
| 135 | if (currentCategory.empty() || istream.eof() || line[i] != '[') |
| 136 | ostream << std::endl; |
| 137 | } |
| 138 | |
| 139 | // Don't add additional newlines at the end of the file otherwise. |
| 140 | if (istream.eof()) |
| 141 | continue; |
| 142 | |
| 143 | // Queue entirely blank lines to add them if desired. |