1
0
Fork 0

Codechange: replace char* from settingsgen

pull/14156/head
Rubidium 2025-04-28 21:22:20 +02:00 committed by rubidium42
parent 47b5ca6115
commit be53bd320d
4 changed files with 66 additions and 88 deletions

View File

@ -101,14 +101,14 @@ bool IniFile::SaveToDisk(const std::string &filename)
return true; return true;
} }
/* virtual */ std::optional<FileHandle> IniFile::OpenFile(const std::string &filename, Subdirectory subdir, size_t *size) /* virtual */ std::optional<FileHandle> IniFile::OpenFile(std::string_view filename, Subdirectory subdir, size_t *size)
{ {
/* Open the text file in binary mode to prevent end-of-line translations /* Open the text file in binary mode to prevent end-of-line translations
* done by ftell() and friends, as defined by K&R. */ * done by ftell() and friends, as defined by K&R. */
return FioFOpenFile(filename, "rb", subdir, size); return FioFOpenFile(filename, "rb", subdir, size);
} }
/* virtual */ void IniFile::ReportFileError(const char * const pre, const char * const buffer, const char * const post) /* virtual */ void IniFile::ReportFileError(std::string_view pre, std::string_view buffer, std::string_view post)
{ {
ShowInfo("{}{}{}", pre, buffer, post); ShowInfo("{}{}{}", pre, buffer, post);
} }

View File

@ -183,7 +183,7 @@ void IniLoadFile::RemoveGroup(std::string_view name)
* @param subdir the sub directory to load the file from. * @param subdir the sub directory to load the file from.
* @pre nothing has been loaded yet. * @pre nothing has been loaded yet.
*/ */
void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir) void IniLoadFile::LoadFromDisk(std::string_view filename, Subdirectory subdir)
{ {
assert(this->groups.empty()); assert(this->groups.empty());

View File

@ -64,7 +64,7 @@ struct IniLoadFile {
IniGroup &CreateGroup(std::string_view name); IniGroup &CreateGroup(std::string_view name);
void RemoveGroup(std::string_view name); void RemoveGroup(std::string_view name);
void LoadFromDisk(const std::string &filename, Subdirectory subdir); void LoadFromDisk(std::string_view filename, Subdirectory subdir);
/** /**
* Open the INI file. * Open the INI file.
@ -73,7 +73,7 @@ struct IniLoadFile {
* @param[out] size Size of the opened file. * @param[out] size Size of the opened file.
* @return File handle of the opened file, or \c std::nullopt. * @return File handle of the opened file, or \c std::nullopt.
*/ */
virtual std::optional<FileHandle> OpenFile(const std::string &filename, Subdirectory subdir, size_t *size) = 0; virtual std::optional<FileHandle> OpenFile(std::string_view filename, Subdirectory subdir, size_t *size) = 0;
/** /**
* Report an error about the file contents. * Report an error about the file contents.
@ -81,7 +81,7 @@ struct IniLoadFile {
* @param buffer Part of the file with the error. * @param buffer Part of the file with the error.
* @param post Suffix text of the \a buffer part. * @param post Suffix text of the \a buffer part.
*/ */
virtual void ReportFileError(const char * const pre, const char * const buffer, const char * const post) = 0; virtual void ReportFileError(std::string_view pre, std::string_view buffer, std::string_view post) = 0;
}; };
/** Ini file that supports both loading and saving. */ /** Ini file that supports both loading and saving. */
@ -90,8 +90,8 @@ struct IniFile : IniLoadFile {
bool SaveToDisk(const std::string &filename); bool SaveToDisk(const std::string &filename);
std::optional<FileHandle> OpenFile(const std::string &filename, Subdirectory subdir, size_t *size) override; std::optional<FileHandle> OpenFile(std::string_view filename, Subdirectory subdir, size_t *size) override;
void ReportFileError(const char * const pre, const char * const buffer, const char * const post) override; void ReportFileError(std::string_view pre, std::string_view buffer, std::string_view post) override;
}; };
#endif /* INI_TYPE_H */ #endif /* INI_TYPE_H */

View File

@ -8,6 +8,7 @@
/** @file settingsgen.cpp Tool to create computer-readable settings. */ /** @file settingsgen.cpp Tool to create computer-readable settings. */
#include "../stdafx.h" #include "../stdafx.h"
#include "../core/string_consumer.hpp"
#include "../string_func.h" #include "../string_func.h"
#include "../strings_type.h" #include "../strings_type.h"
#include "../misc/getoptdata.h" #include "../misc/getoptdata.h"
@ -47,11 +48,9 @@ public:
* @param length Length of the text in bytes. * @param length Length of the text in bytes.
* @return Number of bytes actually stored. * @return Number of bytes actually stored.
*/ */
size_t Add(const char *text, size_t length) size_t Add(std::string_view text)
{ {
size_t store_size = std::min(length, OUTPUT_BLOCK_SIZE - this->size); size_t store_size = text.copy(this->data + this->size, OUTPUT_BLOCK_SIZE - this->size);
assert(store_size <= OUTPUT_BLOCK_SIZE);
MemCpyT(this->data + this->size, text, store_size);
this->size += store_size; this->size += store_size;
return store_size; return store_size;
} }
@ -96,24 +95,19 @@ public:
/** /**
* Add text to the output storage. * Add text to the output storage.
* @param text Text to store. * @param text Text to store.
* @param length Length of the text in bytes, \c 0 means 'length of the string'.
*/ */
void Add(const char *text, size_t length = 0) void Add(std::string_view text)
{ {
if (length == 0) length = strlen(text); if (!text.empty() && this->BufferHasRoom()) {
size_t stored_size = this->output_buffer[this->output_buffer.size() - 1].Add(text);
if (length > 0 && this->BufferHasRoom()) { text.remove_prefix(stored_size);
size_t stored_size = this->output_buffer[this->output_buffer.size() - 1].Add(text, length);
length -= stored_size;
text += stored_size;
} }
while (length > 0) { while (!text.empty()) {
OutputBuffer &block = this->output_buffer.emplace_back(); OutputBuffer &block = this->output_buffer.emplace_back();
block.Clear(); // Initialize the new block. block.Clear(); // Initialize the new block.
size_t stored_size = block.Add(text, length); size_t stored_size = block.Add(text);
length -= stored_size; text.remove_prefix(stored_size);
text += stored_size;
} }
} }
@ -156,7 +150,7 @@ struct SettingsIniFile : IniLoadFile {
{ {
} }
std::optional<FileHandle> OpenFile(const std::string &filename, Subdirectory, size_t *size) override std::optional<FileHandle> OpenFile(std::string_view filename, Subdirectory, size_t *size) override
{ {
/* Open the text file in binary mode to prevent end-of-line translations /* Open the text file in binary mode to prevent end-of-line translations
* done by ftell() and friends, as defined by K&R. */ * done by ftell() and friends, as defined by K&R. */
@ -170,7 +164,7 @@ struct SettingsIniFile : IniLoadFile {
return in; return in;
} }
void ReportFileError(const char * const pre, const char * const buffer, const char * const post) override void ReportFileError(std::string_view pre, std::string_view buffer, std::string_view post) override
{ {
FatalError("{}{}{}", pre, buffer, post); FatalError("{}{}{}", pre, buffer, post);
} }
@ -179,25 +173,25 @@ struct SettingsIniFile : IniLoadFile {
OutputStore _stored_output; ///< Temporary storage of the output, until all processing is done. OutputStore _stored_output; ///< Temporary storage of the output, until all processing is done.
OutputStore _post_amble_output; ///< Similar to _stored_output, but for the post amble. OutputStore _post_amble_output; ///< Similar to _stored_output, but for the post amble.
static const char *PREAMBLE_GROUP_NAME = "pre-amble"; ///< Name of the group containing the pre amble. static std::string_view PREAMBLE_GROUP_NAME = "pre-amble"; ///< Name of the group containing the pre amble.
static const char *POSTAMBLE_GROUP_NAME = "post-amble"; ///< Name of the group containing the post amble. static std::string_view POSTAMBLE_GROUP_NAME = "post-amble"; ///< Name of the group containing the post amble.
static const char *TEMPLATES_GROUP_NAME = "templates"; ///< Name of the group containing the templates. static std::string_view TEMPLATES_GROUP_NAME = "templates"; ///< Name of the group containing the templates.
static const char *VALIDATION_GROUP_NAME = "validation"; ///< Name of the group containing the validation statements. static std::string_view VALIDATION_GROUP_NAME = "validation"; ///< Name of the group containing the validation statements.
static const char *DEFAULTS_GROUP_NAME = "defaults"; ///< Name of the group containing default values for the template variables. static std::string_view DEFAULTS_GROUP_NAME = "defaults"; ///< Name of the group containing default values for the template variables.
/** /**
* Dump a #IGT_SEQUENCE group into #_stored_output. * Dump a #IGT_SEQUENCE group into #_stored_output.
* @param ifile Loaded INI data. * @param ifile Loaded INI data.
* @param group_name Name of the group to copy. * @param group_name Name of the group to copy.
*/ */
static void DumpGroup(const IniLoadFile &ifile, const char * const group_name) static void DumpGroup(const IniLoadFile &ifile, std::string_view group_name)
{ {
const IniGroup *grp = ifile.GetGroup(group_name); const IniGroup *grp = ifile.GetGroup(group_name);
if (grp != nullptr && grp->type == IGT_SEQUENCE) { if (grp != nullptr && grp->type == IGT_SEQUENCE) {
for (const IniItem &item : grp->items) { for (const IniItem &item : grp->items) {
if (!item.name.empty()) { if (!item.name.empty()) {
_stored_output.Add(item.name.c_str()); _stored_output.Add(item.name);
_stored_output.Add("\n", 1); _stored_output.Add("\n");
} }
} }
} }
@ -208,14 +202,14 @@ static void DumpGroup(const IniLoadFile &ifile, const char * const group_name)
* @param name Name of the item to find. * @param name Name of the item to find.
* @param grp Group currently being expanded (searched first). * @param grp Group currently being expanded (searched first).
* @param defaults Fallback group to search, \c nullptr skips the search. * @param defaults Fallback group to search, \c nullptr skips the search.
* @return Text of the item if found, else \c nullptr. * @return Text of the item if found, else \c std::nullopt.
*/ */
static const char *FindItemValue(const char *name, const IniGroup *grp, const IniGroup *defaults) static std::optional<std::string_view> FindItemValue(std::string_view name, const IniGroup *grp, const IniGroup *defaults)
{ {
const IniItem *item = grp->GetItem(name); const IniItem *item = grp->GetItem(name);
if (item == nullptr && defaults != nullptr) item = defaults->GetItem(name); if (item == nullptr && defaults != nullptr) item = defaults->GetItem(name);
if (item == nullptr || !item->value.has_value()) return nullptr; if (item == nullptr) return std::nullopt;
return item->value->c_str(); return item->value;
} }
/** /**
@ -227,58 +221,42 @@ static const char *FindItemValue(const char *name, const IniGroup *grp, const In
*/ */
static void DumpLine(const IniItem *item, const IniGroup *grp, const IniGroup *default_grp, OutputStore &output) static void DumpLine(const IniItem *item, const IniGroup *grp, const IniGroup *default_grp, OutputStore &output)
{ {
static const int MAX_VAR_LENGTH = 64;
/* Prefix with #if/#ifdef/#ifndef */ /* Prefix with #if/#ifdef/#ifndef */
static const auto pp_lines = {"if", "ifdef", "ifndef"}; static const auto pp_lines = {"if", "ifdef", "ifndef"};
int count = 0; int count = 0;
for (const auto &name : pp_lines) { for (const auto &name : pp_lines) {
const char *condition = FindItemValue(name, grp, default_grp); auto condition = FindItemValue(name, grp, default_grp);
if (condition != nullptr) { if (condition.has_value()) {
output.Add("#", 1); output.Add("#");
output.Add(name); output.Add(name);
output.Add(" ", 1); output.Add(" ");
output.Add(condition); output.Add(*condition);
output.Add("\n", 1); output.Add("\n");
count++; count++;
} }
} }
/* Output text of the template, except template variables of the form '$[_a-z0-9]+' which get replaced by their value. */ /* Output text of the template, except template variables of the form '$[_a-z0-9]+' which get replaced by their value. */
const char *txt = item->value->c_str(); static const std::string_view variable_name_characters = "_abcdefghijklmnopqrstuvwxyz0123456789";
while (*txt != '\0') { StringConsumer consumer{*item->value};
if (*txt != '$') { while (consumer.AnyBytesLeft()) {
output.Add(txt, 1); char c = consumer.ReadChar();
txt++; if (c != '$' || consumer.ReadIf("$")) {
continue; /* No $ or $$ (literal $). */
} output.Add(std::string_view{&c, 1});
txt++;
if (*txt == '$') { // Literal $
output.Add(txt, 1);
txt++;
continue; continue;
} }
/* Read variable. */ std::string_view variable = consumer.ReadUntilCharNotIn(variable_name_characters);
char variable[MAX_VAR_LENGTH]; if (!variable.empty()) {
int i = 0;
while (i < MAX_VAR_LENGTH - 1) {
if (!(txt[i] == '_' || (txt[i] >= 'a' && txt[i] <= 'z') || (txt[i] >= '0' && txt[i] <= '9'))) break;
variable[i] = txt[i];
i++;
}
variable[i] = '\0';
txt += i;
if (i > 0) {
/* Find the text to output. */ /* Find the text to output. */
const char *valitem = FindItemValue(variable, grp, default_grp); auto valitem = FindItemValue(variable, grp, default_grp);
if (valitem != nullptr) output.Add(valitem); if (valitem.has_value()) output.Add(*valitem);
} else { } else {
output.Add("$", 1); output.Add("$");
} }
} }
output.Add("\n", 1); // \n after the expanded template. output.Add("\n"); // \n after the expanded template.
while (count > 0) { while (count > 0) {
output.Add("#endif\n"); output.Add("#endif\n");
count--; count--;
@ -323,13 +301,13 @@ static void DumpSections(const IniLoadFile &ifile)
* @param fname Filename of file to append. * @param fname Filename of file to append.
* @param out_fp Output stream to write to. * @param out_fp Output stream to write to.
*/ */
static void AppendFile(const char *fname, FILE *out_fp) static void AppendFile(std::optional<std::string_view> fname, FILE *out_fp)
{ {
if (fname == nullptr) return; if (!fname.has_value()) return;
auto in_fp = FileHandle::Open(fname, "r"); auto in_fp = FileHandle::Open(*fname, "r");
if (!in_fp.has_value()) { if (!in_fp.has_value()) {
FatalError("Cannot open file {} for copying", fname); FatalError("Cannot open file {} for copying", *fname);
} }
char buffer[4096]; char buffer[4096];
@ -348,7 +326,7 @@ static void AppendFile(const char *fname, FILE *out_fp)
* @param n2 Second file. * @param n2 Second file.
* @return True if both files are identical. * @return True if both files are identical.
*/ */
static bool CompareFiles(const char *n1, const char *n2) static bool CompareFiles(std::string_view n1, std::string_view n2)
{ {
auto f2 = FileHandle::Open(n2, "rb"); auto f2 = FileHandle::Open(n2, "rb");
if (!f2.has_value()) return false; if (!f2.has_value()) return false;
@ -402,7 +380,7 @@ static const OptionData _opts[] = {
* *
* @param fname Ini file to process. @return Exit status of the processing. * @param fname Ini file to process. @return Exit status of the processing.
*/ */
static void ProcessIniFile(const char *fname) static void ProcessIniFile(std::string_view fname)
{ {
static const IniLoadFile::IniGroupNameList seq_groups = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME}; static const IniLoadFile::IniGroupNameList seq_groups = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME};
@ -421,9 +399,9 @@ static void ProcessIniFile(const char *fname)
*/ */
int CDECL main(int argc, char *argv[]) int CDECL main(int argc, char *argv[])
{ {
const char *output_file = nullptr; std::optional<std::string_view> output_file;
const char *before_file = nullptr; std::optional<std::string_view> before_file;
const char *after_file = nullptr; std::optional<std::string_view> after_file;
GetOptData mgo(std::span(argv + 1, argc - 1), _opts); GetOptData mgo(std::span(argv + 1, argc - 1), _opts);
for (;;) { for (;;) {
@ -465,13 +443,13 @@ int CDECL main(int argc, char *argv[])
for (auto &argument : mgo.arguments) ProcessIniFile(argument); for (auto &argument : mgo.arguments) ProcessIniFile(argument);
/* Write output. */ /* Write output. */
if (output_file == nullptr) { if (!output_file.has_value()) {
AppendFile(before_file, stdout); AppendFile(before_file, stdout);
_stored_output.Write(stdout); _stored_output.Write(stdout);
_post_amble_output.Write(stdout); _post_amble_output.Write(stdout);
AppendFile(after_file, stdout); AppendFile(after_file, stdout);
} else { } else {
static const char * const tmp_output = "tmp2.xxx"; static const std::string_view tmp_output = "tmp2.xxx";
auto fp = FileHandle::Open(tmp_output, "w"); auto fp = FileHandle::Open(tmp_output, "w");
if (!fp.has_value()) { if (!fp.has_value()) {
@ -484,13 +462,13 @@ int CDECL main(int argc, char *argv[])
fp.reset(); fp.reset();
std::error_code error_code; std::error_code error_code;
if (CompareFiles(tmp_output, output_file)) { if (CompareFiles(tmp_output, *output_file)) {
/* Files are equal. tmp2.xxx is not needed. */ /* Files are equal. tmp2.xxx is not needed. */
std::filesystem::remove(tmp_output, error_code); std::filesystem::remove(tmp_output, error_code);
} else { } else {
/* Rename tmp2.xxx to output file. */ /* Rename tmp2.xxx to output file. */
std::filesystem::rename(tmp_output, output_file, error_code); std::filesystem::rename(tmp_output, *output_file, error_code);
if (error_code) FatalError("rename({}, {}) failed: {}", tmp_output, output_file, error_code.message()); if (error_code) FatalError("rename({}, {}) failed: {}", tmp_output, *output_file, error_code.message());
} }
} }
return 0; return 0;