57 lines
2.8 KiB
C++
57 lines
2.8 KiB
C++
#pragma once
|
|
|
|
// Editing the two INI files a tower is configured by - config.ini and
|
|
// hardware.ini - without breaking them. Pure functions on file contents, so
|
|
// every rule is unit-testable; tools/fgc_config.cpp does the file IO around them.
|
|
//
|
|
// The rules exist because each has already broken a real file:
|
|
// - inih SPLITS a line longer than its buffer instead of truncating it, and the
|
|
// tail then parses as a bogus line of its own (see ini.h INI_MAX_LINE). A
|
|
// generated comment of exactly 200 characters once took out a whole config.
|
|
// - A value left in config.ini that hardware.ini also sets is dead, and warned
|
|
// about at every start. A placeholder left there is worse: deploy.sh's guard
|
|
// greps the raw text, so even a commented-out DEV_0000000000 trips it.
|
|
|
|
#include <map>
|
|
#include <optional>
|
|
#include <string>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace fgc {
|
|
|
|
// The longest line content inih reads whole. Its buffer is INI_MAX_LINE bytes
|
|
// and holds the newline and the terminator too.
|
|
std::size_t iniMaxLineContent();
|
|
|
|
// 1-based number of the first line too long for inih to read whole, or 0.
|
|
int firstOverlongIniLine(const std::string& contents);
|
|
|
|
// "Camera.rgb.id" -> {"Camera.rgb", "id"}: the key is after the LAST dot, since
|
|
// section names may contain dots and key names never do. nullopt when there is
|
|
// no dot, or either side is empty.
|
|
std::optional<std::pair<std::string, std::string>> splitIniKey(const std::string& flat);
|
|
|
|
// Every key the contents set, as "Section.key" -> value, exactly as the program
|
|
// reads them. Throws std::runtime_error naming the line if inih rejects it.
|
|
std::map<std::string, std::string> parseIniString(const std::string& contents);
|
|
|
|
// Set "Section.key" = value pairs. Grouped per section and applied through
|
|
// updateIniSectionKeys(), so comments and order survive, a missing key is
|
|
// appended, and a non-empty `provenance` keeps one ";prev" generation per
|
|
// changed key. Throws std::invalid_argument on a malformed key.
|
|
std::string applyIniSets(const std::string& contents,
|
|
const std::vector<std::pair<std::string, std::string>>& sets,
|
|
const std::string& provenance);
|
|
|
|
// Replace each live `key = value` line whose "Section.key" is in `drops` with a
|
|
// one-line comment "; <key> <note>", where note is the map's value. The VALUE is
|
|
// deliberately not kept: a dead placeholder in a comment still trips deploy.sh's
|
|
// raw-text guard, and a dead real value invites someone to "fix" the wrong file.
|
|
// Returns the new contents; `dropped` (if given) receives what was replaced.
|
|
std::string dropIniKeys(const std::string& contents,
|
|
const std::map<std::string, std::string>& drops,
|
|
std::vector<std::string>* dropped = nullptr);
|
|
|
|
} // namespace fgc
|