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;
}
/* 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
* done by ftell() and friends, as defined by K&R. */
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);
}

View File

@ -183,7 +183,7 @@ void IniLoadFile::RemoveGroup(std::string_view name)
* @param subdir the sub directory to load the file from.
* @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());

View File

@ -64,7 +64,7 @@ struct IniLoadFile {
IniGroup &CreateGroup(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.
@ -73,7 +73,7 @@ struct IniLoadFile {
* @param[out] size Size of the opened file.
* @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.
@ -81,7 +81,7 @@ struct IniLoadFile {
* @param buffer Part of the file with the error.
* @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. */
@ -90,8 +90,8 @@ struct IniFile : IniLoadFile {
bool SaveToDisk(const std::string &filename);
std::optional<FileHandle> OpenFile(const std::string &filename, Subdirectory subdir, size_t *size) override;
void ReportFileError(const char * const pre, const char * const buffer, const char * const post) override;
std::optional<FileHandle> OpenFile(std::string_view filename, Subdirectory subdir, size_t *size) override;
void ReportFileError(std::string_view pre, std::string_view buffer, std::string_view post) override;
};
#endif /* INI_TYPE_H */

View File

@ -8,6 +8,7 @@
/** @file settingsgen.cpp Tool to create computer-readable settings. */
#include "../stdafx.h"
#include "../core/string_consumer.hpp"
#include "../string_func.h"
#include "../strings_type.h"
#include "../misc/getoptdata.h"
@ -47,11 +48,9 @@ public:
* @param length Length of the text in bytes.
* @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);
assert(store_size <= OUTPUT_BLOCK_SIZE);
MemCpyT(this->data + this->size, text, store_size);
size_t store_size = text.copy(this->data + this->size, OUTPUT_BLOCK_SIZE - this->size);
this->size += store_size;
return store_size;
}
@ -96,24 +95,19 @@ public:
/**
* Add text to the output storage.
* @param text Text to store.
* @param length Length of the text in bytes, \c 0 means 'length of the string'.
* @param text Text to store.
*/
void Add(const char *text, size_t length = 0)
void Add(std::string_view text)
{
if (length == 0) length = strlen(text);
if (length > 0 && this->BufferHasRoom()) {
size_t stored_size = this->output_buffer[this->output_buffer.size() - 1].Add(text, length);
length -= stored_size;
text += stored_size;
if (!text.empty() && this->BufferHasRoom()) {
size_t stored_size = this->output_buffer[this->output_buffer.size() - 1].Add(text);
text.remove_prefix(stored_size);
}
while (length > 0) {
while (!text.empty()) {
OutputBuffer &block = this->output_buffer.emplace_back();
block.Clear(); // Initialize the new block.
size_t stored_size = block.Add(text, length);
length -= stored_size;
text += stored_size;
size_t stored_size = block.Add(text);
text.remove_prefix(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
* done by ftell() and friends, as defined by K&R. */
@ -170,7 +164,7 @@ struct SettingsIniFile : IniLoadFile {
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);
}
@ -179,25 +173,25 @@ struct SettingsIniFile : IniLoadFile {
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.
static const char *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 const char *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 const char *DEFAULTS_GROUP_NAME = "defaults"; ///< Name of the group containing default values for the template variables.
static std::string_view PREAMBLE_GROUP_NAME = "pre-amble"; ///< Name of the group containing the pre amble.
static std::string_view POSTAMBLE_GROUP_NAME = "post-amble"; ///< Name of the group containing the post amble.
static std::string_view TEMPLATES_GROUP_NAME = "templates"; ///< Name of the group containing the templates.
static std::string_view VALIDATION_GROUP_NAME = "validation"; ///< Name of the group containing the validation statements.
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.
* @param ifile Loaded INI data.
* @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);
if (grp != nullptr && grp->type == IGT_SEQUENCE) {
for (const IniItem &item : grp->items) {
if (!item.name.empty()) {
_stored_output.Add(item.name.c_str());
_stored_output.Add("\n", 1);
_stored_output.Add(item.name);
_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 grp Group currently being expanded (searched first).
* @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);
if (item == nullptr && defaults != nullptr) item = defaults->GetItem(name);
if (item == nullptr || !item->value.has_value()) return nullptr;
return item->value->c_str();
if (item == nullptr) return std::nullopt;
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 const int MAX_VAR_LENGTH = 64;
/* Prefix with #if/#ifdef/#ifndef */
static const auto pp_lines = {"if", "ifdef", "ifndef"};
int count = 0;
for (const auto &name : pp_lines) {
const char *condition = FindItemValue(name, grp, default_grp);
if (condition != nullptr) {
output.Add("#", 1);
auto condition = FindItemValue(name, grp, default_grp);
if (condition.has_value()) {
output.Add("#");
output.Add(name);
output.Add(" ", 1);
output.Add(condition);
output.Add("\n", 1);
output.Add(" ");
output.Add(*condition);
output.Add("\n");
count++;
}
}
/* 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();
while (*txt != '\0') {
if (*txt != '$') {
output.Add(txt, 1);
txt++;
continue;
}
txt++;
if (*txt == '$') { // Literal $
output.Add(txt, 1);
txt++;
static const std::string_view variable_name_characters = "_abcdefghijklmnopqrstuvwxyz0123456789";
StringConsumer consumer{*item->value};
while (consumer.AnyBytesLeft()) {
char c = consumer.ReadChar();
if (c != '$' || consumer.ReadIf("$")) {
/* No $ or $$ (literal $). */
output.Add(std::string_view{&c, 1});
continue;
}
/* Read variable. */
char variable[MAX_VAR_LENGTH];
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) {
std::string_view variable = consumer.ReadUntilCharNotIn(variable_name_characters);
if (!variable.empty()) {
/* Find the text to output. */
const char *valitem = FindItemValue(variable, grp, default_grp);
if (valitem != nullptr) output.Add(valitem);
auto valitem = FindItemValue(variable, grp, default_grp);
if (valitem.has_value()) output.Add(*valitem);
} 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) {
output.Add("#endif\n");
count--;
@ -323,13 +301,13 @@ static void DumpSections(const IniLoadFile &ifile)
* @param fname Filename of file to append.
* @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()) {
FatalError("Cannot open file {} for copying", fname);
FatalError("Cannot open file {} for copying", *fname);
}
char buffer[4096];
@ -348,7 +326,7 @@ static void AppendFile(const char *fname, FILE *out_fp)
* @param n2 Second file.
* @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");
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.
*/
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};
@ -421,9 +399,9 @@ static void ProcessIniFile(const char *fname)
*/
int CDECL main(int argc, char *argv[])
{
const char *output_file = nullptr;
const char *before_file = nullptr;
const char *after_file = nullptr;
std::optional<std::string_view> output_file;
std::optional<std::string_view> before_file;
std::optional<std::string_view> after_file;
GetOptData mgo(std::span(argv + 1, argc - 1), _opts);
for (;;) {
@ -465,13 +443,13 @@ int CDECL main(int argc, char *argv[])
for (auto &argument : mgo.arguments) ProcessIniFile(argument);
/* Write output. */
if (output_file == nullptr) {
if (!output_file.has_value()) {
AppendFile(before_file, stdout);
_stored_output.Write(stdout);
_post_amble_output.Write(stdout);
AppendFile(after_file, stdout);
} 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");
if (!fp.has_value()) {
@ -484,13 +462,13 @@ int CDECL main(int argc, char *argv[])
fp.reset();
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. */
std::filesystem::remove(tmp_output, error_code);
} else {
/* Rename tmp2.xxx to output file. */
std::filesystem::rename(tmp_output, output_file, error_code);
if (error_code) FatalError("rename({}, {}) failed: {}", tmp_output, output_file, error_code.message());
std::filesystem::rename(tmp_output, *output_file, error_code);
if (error_code) FatalError("rename({}, {}) failed: {}", tmp_output, *output_file, error_code.message());
}
}
return 0;