152#include <fc_config.h>
175#define MAX_LEN_SECPATH 1024
178#define SAVE_TABLES TRUE
180#define SPECVEC_TAG astring
242 static const char *
const allowed =
"_.,-[]";
244 while (
'\0' != *
name) {
274 "Tried to insert same value twice: %s",
buf);
304 const char *filename,
309 struct section *psection =
nullptr;
330 secfile->
name =
nullptr;
336 log_verbose(
"Reading registry from \"%s\"", filename);
469 if (
tok[0] !=
'\"') {
479 for (j =
i + 1; j <
n_prev; j++) {
483 for (j =
n_prev; j <
i + 1; j++) {
536 "Finished registry before end of table");
657 if (filename ==
nullptr) {
658 filename = secfile->
name;
711 char *c, *first,
base[64];
746 first[offset - 2] =
'\0';
748 first[offset - 2] =
'0';
791 "an attempt to insert comment in the middle of table row.",
814 "%s.%s (or the entries are out of order). This means\n"
815 "a less efficient non-tabular format will be used.\n"
816 "To avoid this make sure all rows of a table are\n"
817 "filled out with an entry for every column.",
887 SECFILE_LOG(secfile,
nullptr,
"Error before closing %s: %s",
914 if (!any && secfile->
name) {
920 secfile->
name !=
nullptr ? secfile->
name :
"nameless",
923#ifdef FREECIV_TESTMATIC
925 secfile->
name !=
nullptr ? secfile->
name :
"nameless",
945 if (secfile ==
nullptr) {
947 }
else if (secfile->
name) {
948 return secfile->
name;
950 return "(anonymous)";
970 "Section and entry names must be separated by a dot.");
991 const char *path, ...)
1040 const bool *values,
size_t dim,
1042 const char *path, ...)
1061 for (
i = 1;
i <
dim;
i++) {
1078 const char *path, ...)
1127 const int *values,
size_t dim,
1129 const char *path, ...)
1148 for (
i = 1;
i <
dim;
i++) {
1165 const char *path, ...)
1213 const char *filename)
1237 const char *comment)
1266 const char *path, ...)
1286 log_error(
"Tried to insert wrong type of entry to section");
1324 const char *path, ...)
1346 log_error(
"Tried to insert wrong type of entry to section");
1382 for (
i = 1;
i <
dim;
i++) {
1385 "%s,%d",
fullpath, (
int)
i) !=
nullptr) {
1397 const char *filename,
1398 const char *path, ...)
1418 log_error(
"Tried to insert normal entry to different kind of section");
1437 const char *path, ...)
1494 const char *path, ...)
1516 for (
i = 1;
i <
dim;
i++) {
1543 const char *path, ...)
1563 if (
'\0' ==
str[0]) {
1619 const char *path, ...)
1645 for (
i = 1;
i <
dim;
i++) {
1663 int value,
bool bitwise,
1668 const char *path, ...)
1686 if (
'\0' ==
str[0]) {
1742 const int *values,
size_t dim,
1748 const char *path, ...)
1770 for (
i = 1;
i <
dim;
i++) {
1833 const char *path, ...)
1859 const char *path, ...)
1877 const char *path, ...)
1903 bool def,
const char *path, ...)
1933 size_t *
dim,
const char *path, ...)
1960 for (
i = 0;
i < *
dim;
i++) {
1963 "An error occurred when looking up to \"%s,%d\" entry.",
1979 const char *path, ...)
2005 const char *path, ...)
2036 const char *path, ...)
2059 "\"%s\" should be in the interval [%d, %d] but is %d;"
2060 "using the minimal value.",
2067 "\"%s\" should be in the interval [%d, %d] but is %d;"
2068 "using the maximal value.",
2082 size_t *
dim,
const char *path, ...)
2110 for (
i = 0;
i < *
dim;
i++) {
2113 "An error occurred when looking up to \"%s,%d\" entry.",
2128 const char *path, ...)
2153 float def,
const char *path, ...)
2181 const char *path, ...)
2212 const char *path, ...)
2245 size_t *
dim,
const char *path, ...)
2272 for (
i = 0;
i < *
dim;
i++) {
2276 "An error occurred when looking up to \"%s,%d\" entry.",
2294 const char *path, ...)
2325 "Entry \"%s\": no match for \"%s\".",
2339 const char *path, ...)
2382 const char *path, ...)
2411 for (
i = 0;
i < *
dim;
i++) {
2416 "An error occurred when looking up to \"%s,%d\" entry.",
2434 const char *path, ...)
2438 const char *
str, *p;
2462 if (
'\0' ==
str[0]) {
2481 "Entry \"%s\": no match for \"%s\".",
2487 }
while (p !=
nullptr);
2501 const char *path, ...)
2505 const char *
str, *p;
2526 if (
'\0' ==
str[0]) {
2549 }
while (p !=
nullptr);
2565 const char *path, ...)
2594 for (
i = 0;
i < *
dim;
i++) {
2599 "An error occurred when looking up to \"%s,%d\" entry.",
2615 int *pvalue,
bool bitwise,
2645 if (
'\0' ==
str[0]) {
2661 for (val = 0; (
name =
name_fn(data, val)); val++) {
2666 if (
name ==
nullptr) {
2668 "Entry \"%s\": no match for \"%s\".",
2672 *pvalue |= 1 << val;
2674 }
while (p !=
nullptr);
2676 for (val = 0; (
name =
name_fn(data, val)); val++) {
2682 if (
name ==
nullptr) {
2684 "Entry \"%s\": no match for \"%s\".",
2697 int defval,
bool bitwise,
2700 const char *path, ...)
2727 if (
'\0' ==
str[0]) {
2743 for (val = 0; (
name =
name_fn(data, val)); val++) {
2748 if (
name ==
nullptr) {
2750 "Entry \"%s\": no match for \"%s\".",
2756 }
while (p !=
nullptr);
2758 for (val = 0; (
name =
name_fn(data, val)); val++) {
2764 if (
name ==
nullptr) {
2766 "Entry \"%s\": no match for \"%s\".",
2780 size_t *
dim,
bool bitwise,
2810 for (
i = 0;
i < *
dim;
i++) {
2814 "An error occurred when looking up to \"%s,%d\" entry.",
2847 const char *path, ...)
2868 return (secfile !=
nullptr ? secfile->
sections :
nullptr);
2938 if (
name ==
nullptr ||
'\0' ==
name[0]) {
2983 if ((secfile = psection->
secfile)) {
3011 "After clearing all, %d entries are still remaining.",
3028 if (
name ==
nullptr ||
'\0' ==
name[0]) {
3036 "\"%s\" is not a valid section name for section \"%s\".",
3081 return (psection !=
nullptr ? psection->
entries :
nullptr);
3106 const char *path, ...)
3144 if (
name ==
nullptr ||
'\0' ==
name[0]) {
3169 pentry->comment =
nullptr;
3295 if ((psection =
pentry->psection)) {
3328 if (
pentry->comment !=
nullptr) {
3339 return (
pentry !=
nullptr ?
pentry->psection :
nullptr);
3377 psection =
pentry->psection;
3382 if (
name ==
nullptr ||
'\0' ==
name[0]) {
3383 SECFILE_LOG(secfile, psection,
"No new name for entry \"%s\".",
3390 "\"%s\" is not a valid entry name for entry \"%s\".",
3421 return (
pentry !=
nullptr ?
pentry->comment :
nullptr);
3433 if (
pentry->comment !=
nullptr) {
3445 return (0 <
pentry->used);
3465 && (
pentry->integer.value == 0
3466 ||
pentry->integer.value == 1)
3467 &&
pentry->psection !=
nullptr
3468 &&
pentry->psection->secfile !=
nullptr
3469 &&
pentry->psection->secfile->allow_digital_boolean) {
3475 ?
pentry->psection->secfile :
nullptr,
3479 if (
value !=
nullptr) {
3508 if (
value !=
nullptr) {
3538 if (
value !=
nullptr) {
3567 if (
value !=
nullptr) {
3605 return pentry->string.escaped;
3641 static char buf[8192];
3642 char *
dot =
nullptr;
3654 for (
i = 0;
buf[
i] !=
'\0' ;
i++) {
3655 if (
buf[
i] ==
'.') {
3660 if (
dot ==
nullptr) {
3669 if (
pentry->string.escaped) {
3671 if (
pentry->string.gt_marking) {
3676 }
else if (
pentry->string.raw) {
void astr_free(struct astring *astr)
void astr_set(struct astring *astr, const char *format,...)
void astr_init(struct astring *astr)
static const char * astr_str(const struct astring *astr) fc__attribute((nonnull(1)))
void bugreport_request(const char *reason_format,...)
bool are_deprecation_warnings_enabled(void)
#define log_deprecation_always(message,...)
static void base(QVariant data1, QVariant data2)
int fz_fprintf(fz_FILE *fp, const char *format,...)
fz_FILE * fz_from_file(const char *filename, const char *in_mode, enum fz_method method, int compress_level)
const char * fz_strerror(fz_FILE *fp)
int fz_fclose(fz_FILE *fp)
int fz_ferror(fz_FILE *fp)
#define log_verbose(message,...)
#define fc_assert(condition)
#define fc_assert_ret_val(condition, val)
#define log_error(message,...)
#define log_testmatic(message,...)
struct section_file * secfile_new(bool allow_duplicates)
const char * section_name(const struct section *psection)
void secfile_destroy(struct section_file *secfile)
static struct entry * entry_new(struct section *psection, const char *name)
int secfile_lookup_bitwise_enum_default_full(const struct section_file *secfile, int defval, secfile_enum_is_valid_fn_t is_valid_fn, secfile_enum_by_name_fn_t by_name_fn, const char *path,...)
void entry_set_comment(struct entry *pentry, const char *comment)
size_t secfile_insert_bool_vec_full(struct section_file *secfile, const bool *values, size_t dim, const char *comment, bool allow_replace, const char *path,...)
bool entry_bool_get(const struct entry *pentry, bool *value)
void section_destroy(struct section *psection)
bool secfile_lookup_float(const struct section_file *secfile, float *fval, const char *path,...)
void secfile_check_unused(const struct section_file *secfile)
int entry_path(const struct entry *pentry, char *buf, size_t buf_len)
bool secfile_lookup_int(const struct section_file *secfile, int *ival, const char *path,...)
struct section * secfile_insert_long_comment(struct section_file *secfile, const char *comment)
static struct entry * section_entry_filereference_new(struct section *psection, const char *name, const char *value)
bool secfile_entry_delete(struct section_file *secfile, const char *path,...)
bool entry_set_name(struct entry *pentry, const char *name)
bool secfile_lookup_enum_data(const struct section_file *secfile, int *pvalue, bool bitwise, secfile_enum_name_data_fn_t name_fn, secfile_data_t data, const char *path,...)
static bool secfile_hash_insert(struct section_file *secfile, struct entry *pentry)
bool entry_str_escaped(const struct entry *pentry)
struct entry * section_entry_int_new(struct section *psection, const char *name, int value)
struct entry * secfile_insert_bool_full(struct section_file *secfile, bool value, const char *comment, bool allow_replace, const char *path,...)
struct entry * secfile_insert_comment(struct section_file *secfile, const char *str, const char *path,...)
struct entry * secfile_insert_int_full(struct section_file *secfile, int value, const char *comment, bool allow_replace, const char *path,...)
struct section * entry_section(const struct entry *pentry)
static struct entry * section_entry_comment_new(struct section *psection, const char *comment)
struct section_list * secfile_sections_by_name_prefix(const struct section_file *secfile, const char *prefix)
int secfile_lookup_enum_default_data(const struct section_file *secfile, int defval, bool bitwise, secfile_enum_name_data_fn_t name_fn, secfile_data_t data, const char *path,...)
const struct entry_list * section_entries(const struct section *psection)
struct section_file * secfile_load_section(const char *filename, const char *section, bool allow_duplicates)
bool entry_bool_set(struct entry *pentry, bool value)
struct section_file * secfile_from_stream(fz_FILE *stream, bool allow_duplicates)
size_t secfile_insert_bitwise_enum_vec_full(struct section_file *secfile, const int *bitwise_vals, size_t dim, secfile_enum_name_fn_t name_fn, secfile_enum_iter_fn_t begin_fn, secfile_enum_iter_fn_t end_fn, secfile_enum_next_fn_t next_fn, const char *comment, bool allow_replace, const char *path,...)
static void entry_to_file(const struct entry *pentry, fz_FILE *fs)
static void entry_from_inf_token(struct section *psection, const char *name, const char *tok, struct inputfile *file)
bool entry_float_get(const struct entry *pentry, float *value)
const char ** secfile_lookup_str_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
bool entry_str_set_escaped(struct entry *pentry, bool escaped)
const char * entry_name(const struct entry *pentry)
struct entry * secfile_entry_lookup(const struct section_file *secfile, const char *path,...)
bool entry_str_get(const struct entry *pentry, const char **value)
struct entry * secfile_insert_enum_data_full(struct section_file *secfile, int value, bool bitwise, secfile_enum_name_data_fn_t name_fn, secfile_data_t data, const char *comment, bool allow_replace, const char *path,...)
bool entry_str_set_gt_marking(struct entry *pentry, bool gt_marking)
size_t secfile_insert_int_vec_full(struct section_file *secfile, const int *values, size_t dim, const char *comment, bool allow_replace, const char *path,...)
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
void entry_destroy(struct entry *pentry)
static bool entry_used(const struct entry *pentry)
void section_clear_all(struct section *psection)
int * secfile_lookup_int_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
bool entry_float_set(struct entry *pentry, float value)
float secfile_lookup_float_default(const struct section_file *secfile, float def, const char *path,...)
bool * secfile_lookup_bool_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
int secfile_lookup_plain_enum_default_full(const struct section_file *secfile, int defval, secfile_enum_is_valid_fn_t is_valid_fn, secfile_enum_by_name_fn_t by_name_fn, const char *path,...)
size_t secfile_insert_str_vec_full(struct section_file *secfile, const char *const *strings, size_t dim, const char *comment, bool allow_replace, bool no_escape, const char *path,...)
size_t secfile_insert_plain_enum_vec_full(struct section_file *secfile, const int *enumurators, size_t dim, secfile_enum_name_fn_t name_fn, const char *comment, bool allow_replace, const char *path,...)
bool secfile_save(const struct section_file *secfile, const char *filename, int compression_level, enum fz_method compression_method)
struct entry * secfile_insert_float_full(struct section_file *secfile, float value, const char *comment, bool allow_replace, const char *path,...)
struct section * secfile_insert_include(struct section_file *secfile, const char *filename)
struct entry * secfile_insert_plain_enum_full(struct section_file *secfile, int enumerator, secfile_enum_name_fn_t name_fn, const char *comment, bool allow_replace, const char *path,...)
bool secfile_lookup_bool_default(const struct section_file *secfile, bool def, const char *path,...)
bool entry_int_set(struct entry *pentry, int value)
static bool is_secfile_entry_name_valid(const char *name)
struct entry * section_entry_by_name(const struct section *psection, const char *name)
const struct section_list * secfile_sections(const struct section_file *secfile)
struct entry * secfile_insert_filereference(struct section_file *secfile, const char *filename, const char *path,...)
bool section_set_name(struct section *psection, const char *name)
struct entry * section_entry_str_new(struct section *psection, const char *name, const char *value, bool escaped)
struct entry * section_entry_float_new(struct section *psection, const char *name, float value)
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
struct entry * section_entry_lookup(const struct section *psection, const char *path,...)
bool entry_int_get(const struct entry *pentry, int *value)
int * secfile_lookup_bitwise_enum_vec_full(const struct section_file *secfile, size_t *dim, secfile_enum_is_valid_fn_t is_valid_fn, secfile_enum_by_name_fn_t by_name_fn, const char *path,...)
static void entry_use(struct entry *pentry)
int * secfile_lookup_enum_vec_data(const struct section_file *secfile, size_t *dim, bool bitwise, secfile_enum_name_data_fn_t name_fn, secfile_data_t data, const char *path,...)
struct entry * section_entry_bool_new(struct section *psection, const char *name, bool value)
bool secfile_lookup_plain_enum_full(const struct section_file *secfile, int *penumerator, secfile_enum_is_valid_fn_t is_valid_fn, secfile_enum_by_name_fn_t by_name_fn, const char *path,...)
const char * secfile_name(const struct section_file *secfile)
struct section * secfile_section_new(struct section_file *secfile, const char *name)
const char * entry_comment(const struct entry *pentry)
static bool secfile_hash_delete(struct section_file *secfile, struct entry *pentry)
struct entry * secfile_entry_by_path(const struct section_file *secfile, const char *path)
static struct section_file * secfile_from_input_file(struct inputfile *inf, const char *filename, const char *section, bool allow_duplicates)
struct section * secfile_section_by_name(const struct section_file *secfile, const char *name)
struct entry * secfile_insert_bitwise_enum_full(struct section_file *secfile, int bitwise_val, secfile_enum_name_fn_t name_fn, secfile_enum_iter_fn_t begin_fn, secfile_enum_iter_fn_t end_fn, secfile_enum_next_fn_t next_fn, const char *comment, bool allow_replace, const char *path,...)
struct entry * secfile_insert_str_full(struct section_file *secfile, const char *str, const char *comment, bool allow_replace, bool no_escape, enum entry_special_type stype, const char *path,...)
int * secfile_lookup_plain_enum_vec_full(const struct section_file *secfile, size_t *dim, secfile_enum_is_valid_fn_t is_valid_fn, secfile_enum_by_name_fn_t by_name_fn, const char *path,...)
struct section * secfile_section_lookup(const struct section_file *secfile, const char *path,...)
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
bool secfile_section_prefix_present(const struct section_file *secfile, const char *prefix)
static bool is_legal_table_entry_name(char c, bool num)
bool entry_str_set(struct entry *pentry, const char *value)
bool secfile_lookup_bitwise_enum_full(const struct section_file *secfile, int *penumerator, secfile_enum_is_valid_fn_t is_valid_fn, secfile_enum_by_name_fn_t by_name_fn, const char *path,...)
size_t secfile_insert_enum_vec_data_full(struct section_file *secfile, const int *values, size_t dim, bool bitwise, secfile_enum_name_data_fn_t name_fn, secfile_data_t data, const char *comment, bool allow_replace, const char *path,...)
bool secfile_lookup_bool(const struct section_file *secfile, bool *bval, const char *path,...)
static const char * datafilename(const char *filename)
int secfile_lookup_int_def_min_max(const struct section_file *secfile, int defval, int minval, int maxval, const char *path,...)
static struct section * secfile_insert_base(struct section_file *secfile, const char *path, const char **pent_name)
enum entry_type entry_type_get(const struct entry *pentry)
int(* secfile_enum_iter_fn_t)(void)
const char *(* secfile_enum_name_data_fn_t)(secfile_data_t data, int enumerator)
#define section_list_iterate(seclist, psection)
#define entry_list_iterate_end
bool(* secfile_enum_is_valid_fn_t)(int enumerator)
const char *(* secfile_enum_name_fn_t)(int enumerator)
#define section_list_iterate_end
#define entry_list_iterate(entlist, pentry)
int(* secfile_enum_by_name_fn_t)(const char *enum_name, int(*strcmp_fn)(const char *, const char *))
int(* secfile_enum_next_fn_t)(int enumerator)
const void * secfile_data_t
bool entry_from_token(struct section *psection, const char *name, const char *tok)
#define SECFILE_LOG(secfile, psection, format,...)
#define SECFILE_RETURN_VAL_IF_FAIL(secfile, psection, condition, value)
#define SECFILE_RETURN_IF_FAIL(secfile, psection, condition)
const char * fileinfoname(const struct strvec *dirs, const char *filename)
void interpret_tilde(char *buf, size_t buf_size, const char *filename)
void remove_leading_trailing_spaces(char *s)
const struct strvec * get_data_dirs(void)
struct section * psection
struct entry_hash * entries
struct section_file::@8 hash
struct section_list * sections
unsigned int num_includes
unsigned int num_long_comments
struct entry_list * entries
enum entry_special_type special
struct section_file * secfile
int fc_snprintf(char *str, size_t n, const char *format,...)
size_t fc_strlcpy(char *dest, const char *src, size_t n)
void make_escapes(const char *str, char *buf, size_t buf_len)
int fc_strcasecmp(const char *str0, const char *str1)
int cat_snprintf(char *str, size_t n, const char *format,...)
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
#define sz_strlcpy(dest, src)
#define sz_strlcat(dest, src)
#define fc_strncmp(_s1_, _s2_, _len_)