|
OpenTTD Source
14.0-beta3
|
Go to the documentation of this file.
10 #include "../stdafx.h"
11 #include "../string_func.h"
12 #include "../strings_type.h"
13 #include "../misc/getoptdata.h"
14 #include "../ini_type.h"
15 #include "../core/mem_func.hpp"
16 #include "../error_func.h"
18 #if !defined(_WIN32) || defined(__CYGWIN__)
23 #include "../safeguards.h"
32 fmt::print(stderr,
"settingsgen: FATAL: {}\n", msg);
53 size_t Add(
const char *text,
size_t length)
58 this->
size += store_size;
68 if (fwrite(this->
data, 1, this->
size, out_fp) != this->
size) {
69 FatalError(
"Cannot write output");
105 void Add(
const char *text,
size_t length = 0)
107 if (length == 0) length = strlen(text);
111 length -= stored_size;
117 size_t stored_size = block.
Add(text, length);
118 length -= stored_size;
130 out_data.Write(out_fp);
142 return num_blocks > 0 && this->
output_buffer[num_blocks - 1].HasRoom();
166 FILE *in = fopen(filename.c_str(),
"rb");
167 if (in ==
nullptr)
return nullptr;
169 fseek(in, 0L, SEEK_END);
172 fseek(in, 0L, SEEK_SET);
176 void ReportFileError(
const char *
const pre,
const char *
const buffer,
const char *
const post)
override
178 FatalError(
"{}{}{}", pre, buffer, post);
201 if (!item.
name.empty()) {
219 if (item ==
nullptr && defaults !=
nullptr) item = defaults->
GetItem(name);
220 if (item ==
nullptr || !item->
value.has_value())
return nullptr;
221 return item->
value->c_str();
233 static const int MAX_VAR_LENGTH = 64;
236 static const auto pp_lines = {
"if",
"ifdef",
"ifndef"};
238 for (
const auto &name : pp_lines) {
239 const char *condition =
FindItemValue(name, grp, default_grp);
240 if (condition !=
nullptr) {
244 output.
Add(condition);
251 const char *txt = item->
value->c_str();
252 while (*txt !=
'\0') {
266 char variable[MAX_VAR_LENGTH];
268 while (i < MAX_VAR_LENGTH - 1) {
269 if (!(txt[i] ==
'_' || (txt[i] >=
'a' && txt[i] <=
'z') || (txt[i] >=
'0' && txt[i] <=
'9')))
break;
270 variable[i] = txt[i];
278 const char *valitem =
FindItemValue(variable, grp, default_grp);
279 if (valitem !=
nullptr) output.
Add(valitem);
286 output.
Add(
"#endif\n");
302 if (templates_grp ==
nullptr)
return;
307 if (std::find(std::begin(special_group_names), std::end(special_group_names), grp.
name) != std::end(special_group_names))
continue;
310 if (template_item ==
nullptr || !template_item->
value.has_value()) {
311 FatalError(
"Cannot find template {}", grp.
name);
315 if (validation_grp !=
nullptr) {
317 if (validation_item !=
nullptr && validation_item->
value.has_value()) {
329 static void CopyFile(
const char *fname, FILE *out_fp)
331 if (fname ==
nullptr)
return;
333 FILE *in_fp = fopen(fname,
"r");
334 if (in_fp ==
nullptr) {
335 FatalError(
"Cannot open file {} for copying", fname);
341 length = fread(buffer, 1,
lengthof(buffer), in_fp);
342 if (fwrite(buffer, 1, length, out_fp) != length) {
343 FatalError(
"Cannot copy file");
345 }
while (length ==
lengthof(buffer));
358 FILE *f2 = fopen(n2,
"rb");
359 if (f2 ==
nullptr)
return false;
361 FILE *f1 = fopen(n1,
"rb");
364 FatalError(
"can't open {}", n1);
371 l1 = fread(b1, 1,
sizeof(b1), f1);
372 l2 = fread(b2, 1,
sizeof(b2), f2);
374 if (l1 != l2 || memcmp(b1, b2, l1) != 0) {
433 int CDECL
main(
int argc,
char *argv[])
435 const char *output_file =
nullptr;
436 const char *before_file =
nullptr;
437 const char *after_file =
nullptr;
446 fmt::print(
"settingsgen\n"
447 "Usage: settingsgen [options] ini-file...\n"
449 " -h, -?, --help Print this help message and exit\n"
450 " -b FILE, --before FILE Copy FILE before all settings\n"
451 " -a FILE, --after FILE Copy FILE after all settings\n"
452 " -o FILE, --output FILE Write output to FILE\n");
456 output_file = mgo.
opt;
460 after_file = mgo.
opt;
464 before_file = mgo.
opt;
468 fmt::print(stderr,
"Invalid arguments\n");
479 if (output_file ==
nullptr) {
485 static const char *
const tmp_output =
"tmp2.xxx";
487 FILE *fp = fopen(tmp_output,
"w");
489 FatalError(
"Cannot open file {}", tmp_output);
505 if (rename(tmp_output, output_file) == -1) FatalError(
"rename() failed");
static void ProcessIniFile(const char *fname)
Process a single INI file.
static bool CompareFiles(const char *n1, const char *n2)
Compare two files for identity.
void Write(FILE *out_fp) const
Write all stored output to the output stream.
static void DumpGroup(const IniLoadFile &ifile, const char *const group_name)
Dump a IGT_SEQUENCE group into _stored_output.
char data[OUTPUT_BLOCK_SIZE]
Stored data.
void Clear()
Prepare buffer for use.
static const char * DEFAULTS_GROUP_NAME
Name of the group containing default values for the template variables.
A single "line" in an ini file.
const IniItem * GetItem(const std::string &name) const
Get the item with the given name.
A group within an ini file.
#define GETOPT_VALUE(shortname, longname)
Short option with value.
void FatalErrorI(const std::string &msg)
Report a fatal error.
OutputStore _post_amble_output
Similar to _stored_output, but for the post amble.
bool BufferHasRoom() const
Does the buffer have room without adding a new OutputBuffer block?
OutputStore _stored_output
Temporary storage of the output, until all processing is done.
std::list< IniItem > items
all items in the group
size_t size
Number of bytes stored in data.
const IniGroupNameList seq_group_names
list of group names that are sequences.
const IniGroupNameList list_group_names
list of group names that are lists
Ini file that only supports loading.
char ** argv
Remaining command line arguments.
static const char * POSTAMBLE_GROUP_NAME
Name of the group containing the post amble.
void MemCpyT(T *destination, const T *source, size_t num=1)
Type-safe version of memcpy().
void Clear()
Clear the temporary storage.
static const size_t OUTPUT_BLOCK_SIZE
Block size of the buffer in OutputBuffer.
#define GETOPT_NOVAL(shortname, longname)
Short option without value.
std::optional< std::string > value
The value of this item.
#define GETOPT_END()
Option terminator.
bool HasRoom() const
Does the block have room for more data?
#define GETOPT_GENERAL(id, shortname, longname, flags)
General macro for creating an option.
OutputBufferVector output_buffer
Vector of blocks containing the stored output.
char * opt
Option value, if available (else nullptr).
const IniGroup * GetGroup(const std::string &name) const
Get the group with the given name.
IniGroupType type
type of group
Data storage for parsing command line options.
Derived class for loading INI files without going through Fio stuff.
void Write(FILE *out_fp) const
Dump buffer to the output stream.
Temporarily store output.
std::vector< OutputBuffer > OutputBufferVector
Vector type for output buffers.
SettingsIniFile(const IniGroupNameList &list_group_names={}, const IniGroupNameList &seq_group_names={})
Construct a new ini loader.
static const OptionData _opts[]
Options of settingsgen.
static const char * PREAMBLE_GROUP_NAME
Name of the group containing the pre amble.
size_t Add(const char *text, size_t length)
Add text to the output buffer.
static const char * VALIDATION_GROUP_NAME
Name of the group containing the validation statements.
int CDECL main(int argc, char *argv[])
And the main program (what else?)
std::string name
name of group
IniLoadFile(const IniGroupNameList &list_group_names={}, const IniGroupNameList &seq_group_names={})
Construct a new in-memory Ini file representation.
@ NO_DIRECTORY
A path without any base directory.
@ IGT_SEQUENCE
A list of uninterpreted lines, terminated by the next group block.
Subdirectory
The different kinds of subdirectories OpenTTD uses.
static void CopyFile(const char *fname, FILE *out_fp)
Copy a file to the output.
int GetOpt()
Find the next option.
std::list< IniGroup > groups
all groups in the ini
std::string name
The name of this item.
void Add(const char *text, size_t length=0)
Add text to the output storage.
#define lengthof(x)
Return the length of an fixed size array.
Output buffer for a block of data.
void LoadFromDisk(const std::string &filename, Subdirectory subdir)
Load the Ini file's data from the disk.
static void DumpSections(const IniLoadFile &ifile)
Output all non-special sections through the template / template variable expansion system.
@ ODF_NO_VALUE
A plain option (no value attached to it).
int numleft
Number of arguments left in argv.
FILE * OpenFile(const std::string &filename, Subdirectory, size_t *size) override
Open the INI file.
void ReportFileError(const char *const pre, const char *const buffer, const char *const post) override
Report an error about the file contents.
static const char * TEMPLATES_GROUP_NAME
Name of the group containing the templates.
static void DumpLine(const IniItem *item, const IniGroup *grp, const IniGroup *default_grp, OutputStore &output)
Parse a single entry via a template and output this.
static const char * FindItemValue(const char *name, const IniGroup *grp, const IniGroup *defaults)
Find the value of a template variable.