mirror of https://github.com/OpenTTD/OpenTTD
Codechange: replace char* from settingsgen
parent
47b5ca6115
commit
be53bd320d
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue