158 #include <KFilterDev>
173 #define MAX_LEN_SECPATH 1024
176 #define SAVE_TABLES true
183 const QString &
name,
const QString &tok,
219 static struct entry *
236 static const auto allowed = QStringLiteral(
"_.,-[]");
238 for (
const auto &c :
name) {
239 if (!c.isLetterOrNumber() && !allowed.contains(c)) {
250 struct entry *pentry)
253 struct entry *hentry;
263 hentry = secfile->
hash.
entries->value(buf,
nullptr);
268 "Tried to insert same value twice: %s", buf);
280 struct entry *pentry)
299 const QString &filename,
304 struct section *psection =
nullptr;
305 struct section *single_section =
nullptr;
306 bool table_state =
false;
307 int table_lineno = 0;
313 bool found_my_section =
false;
322 if (!filename.isEmpty()) {
328 if (!filename.isEmpty()) {
329 qDebug(
"Reading registry from \"%s\"", qUtf8Printable(filename));
331 qDebug(
"Reading registry");
343 if (!tok.isEmpty()) {
344 if (found_my_section) {
353 inf,
"Found requested section; finishing")));
359 qUtf8Printable(
inf_log_str(inf,
"New section during table")));
373 single_section = psection;
374 found_my_section =
true;
381 qUtf8Printable(
inf_log_str(inf,
"Expected end of line")));
390 qUtf8Printable(
inf_log_str(inf,
"Misplaced \"}\"")));
397 qUtf8Printable(
inf_log_str(inf,
"Expected end of line")));
408 int num_columns = columns.size();
414 qUtf8Printable(
inf_log_str(inf,
"Expected value")));
419 if (i < num_columns) {
420 field_name = QStringLiteral(
"%1%2.%3").arg(
421 base_name, QString::number(table_lineno), columns.at(i));
423 field_name = QStringLiteral(
"%1%2.%3,%4")
424 .arg(base_name, QString::number(table_lineno),
425 columns.at(num_columns - 1),
426 QString::number((i - num_columns + 1)));
434 qUtf8Printable(
inf_log_str(inf,
"Expected end of line")));
444 qUtf8Printable(
inf_log_str(inf,
"Expected entry name")));
461 qUtf8Printable(
inf_log_str(inf,
"Expected value")));
465 if (tok[0] !=
'\"') {
468 inf,
"Table column header non-string")));
472 columns.append(tok.mid(1));
478 qUtf8Printable(
inf_log_str(inf,
"Expected end of line")));
493 qUtf8Printable(
inf_log_str(inf,
"Expected value")));
501 QStringLiteral(
"%1,%2").arg(base_name, QString::number(i));
507 qUtf8Printable(
inf_log_str(inf,
"Expected end of line")));
522 if (!found_my_section) {
597 return (num ? QChar::isLetterOrNumber(c) : QChar::isLetter(c)) || c ==
'_';
616 char pentry_name[128];
617 const char *col_entry_name;
618 const struct entry_list_link *ent_iter, *save_iter, *col_iter;
619 struct entry *pentry, *col_pentry;
624 if (filename.isEmpty()) {
625 filename = secfile->
name;
629 auto fs = std::make_unique<KFilterDev>(real_filename);
630 fs->open(QIODevice::WriteOnly);
633 SECFILE_LOG(secfile,
nullptr,
_(
"Could not open %s for writing"),
634 qUtf8Printable((real_filename)));
642 ent_iter && (pentry = entry_list_link_data(ent_iter));
643 ent_iter = entry_list_link_next(ent_iter)) {
652 ent_iter && (pentry = entry_list_link_data(ent_iter));
653 ent_iter = entry_list_link_next(ent_iter)) {
668 ent_iter && (pentry = entry_list_link_data(ent_iter));
669 ent_iter = entry_list_link_next(ent_iter)) {
679 char *c, *first,
base[64];
680 int offset, irow, icol, ncol;
694 c = first = pentry_name;
701 if (0 != strncmp(c,
"0.", 2)) {
710 first[offset - 2] =
'\0';
712 first[offset - 2] =
'0';
719 save_iter = ent_iter;
723 col_iter = save_iter;
724 for (; (col_pentry = entry_list_link_data(col_iter));
725 col_iter = entry_list_link_next(col_iter)) {
727 if (strncmp(col_entry_name, first, offset) != 0) {
743 col_iter = save_iter;
747 pentry = entry_list_link_data(ent_iter);
748 col_pentry = entry_list_link_data(col_iter);
754 if ((!pentry) || (strcmp(
entry_name(pentry), expect) != 0)) {
767 "In file %s, there is no entry in the registry for\n"
768 "%s.%s (or the entries are out of order). This means\n"
769 "a less efficient non-tabular format will be used.\n"
770 "To avoid this make sure all rows of a table are\n"
771 "filled out with an entry for every column.",
785 ent_iter = entry_list_link_next(ent_iter);
786 col_iter = entry_list_link_next(col_iter);
793 col_iter = save_iter;
812 col_iter = entry_list_link_next(ent_iter);
813 col_pentry = entry_list_link_data(col_iter);
814 if (
nullptr == col_pentry) {
817 fc_snprintf(pentry_name,
sizeof(pentry_name),
"%s,%d",
819 if (0 != strcmp(pentry_name,
entry_name(col_pentry))) {
840 if (fs->error() != 0) {
841 SECFILE_LOG(secfile,
nullptr,
"Error before closing %s: %s",
842 qUtf8Printable(real_filename),
843 qUtf8Printable(fs->errorString()));
866 if (!any && secfile->
name) {
867 qDebug(
"Unused entries in file %s:", secfile->
name);
870 qCWarning(deprecations_category,
"%s: unused entry: %s.%s",
871 secfile->
name !=
nullptr ? secfile->
name :
"nameless",
888 if (
nullptr == secfile) {
890 }
else if (secfile->
name) {
891 return secfile->
name;
893 return "(anonymous)";
902 const char **pent_name)
910 ent_name = strchr(fullpath,
'.');
913 "Section and entry names must be separated by a dot.");
919 *pent_name = path + (ent_name - fullpath) + 1;
933 bool allow_replace,
const char *path,
937 const char *ent_name;
939 struct entry *pentry =
nullptr;
944 va_start(args, path);
955 if (
nullptr != pentry) {
967 if (
nullptr == pentry) {
971 if (
nullptr != pentry &&
nullptr !=
comment) {
983 const bool *values,
size_t dim,
984 const char *
comment,
bool allow_replace,
985 const char *path, ...)
993 va_start(args, path);
1002 allow_replace,
"%s", fullpath)) {
1005 for (i = 1; i < dim; i++) {
1008 allow_replace,
"%s,%d", fullpath,
1009 static_cast<int>(i))) {
1022 bool allow_replace,
const char *path,
1026 const char *ent_name;
1028 struct entry *pentry =
nullptr;
1033 va_start(args, path);
1042 if (allow_replace) {
1044 if (
nullptr != pentry) {
1056 if (
nullptr == pentry) {
1060 if (
nullptr != pentry &&
nullptr !=
comment) {
1072 const int *values,
size_t dim,
1073 const char *
comment,
bool allow_replace,
1074 const char *path, ...)
1082 va_start(args, path);
1091 allow_replace,
"%s", fullpath)) {
1094 for (i = 1; i < dim; i++) {
1097 allow_replace,
"%s,%d", fullpath,
1098 static_cast<int>(i))) {
1111 bool allow_replace,
const char *path,
1115 const char *ent_name;
1117 struct entry *pentry =
nullptr;
1122 va_start(args, path);
1131 if (allow_replace) {
1133 if (
nullptr != pentry) {
1145 if (
nullptr == pentry) {
1149 if (
nullptr != pentry &&
nullptr !=
comment) {
1160 const char *filename)
1185 const char *comment)
1190 fc_snprintf(buffer,
sizeof(buffer),
"long_comment_%u",
1211 const char *str,
const char *
comment,
1212 bool allow_replace,
bool no_escape,
1214 const char *path, ...)
1217 const char *ent_name;
1219 struct entry *pentry =
nullptr;
1224 va_start(args, path);
1234 qCritical(
"Tried to insert wrong type of entry to section");
1238 if (allow_replace) {
1240 if (
nullptr != pentry) {
1252 if (
nullptr == pentry) {
1256 if (
nullptr != pentry &&
nullptr !=
comment) {
1261 pentry->
string.raw =
true;
1272 const char *
const *strings,
size_t dim,
1273 const char *
comment,
bool allow_replace,
1274 bool no_escape,
const char *path, ...)
1282 va_start(args, path);
1295 for (i = 1; i < dim; i++) {
1299 "%s,%d", fullpath,
static_cast<int>(i))) {
1313 size_t dim,
const char *
comment,
1314 bool allow_replace,
bool no_escape,
1315 const char *path, ...)
1323 va_start(args, path);
1329 if (dim > 0 && !strings.isEmpty()
1332 comment, allow_replace, no_escape,
1336 for (i = 1; i < dim && i < strings.size(); i++) {
1339 secfile, qUtf8Printable(strings[i]),
comment, allow_replace,
1340 no_escape,
EST_NORMAL,
"%s,%d", fullpath,
static_cast<int>(i))) {
1352 const char *filename,
1353 const char *path, ...)
1356 const char *ent_name;
1358 struct entry *pentry =
nullptr;
1363 va_start(args, path);
1373 qCritical(
"Tried to insert normal entry to different kind of section");
1377 if (
nullptr == pentry) {
1392 const char *path, ...)
1396 const char *ent_name;
1398 struct entry *pentry =
nullptr;
1403 str = name_fn(enumerator);
1406 va_start(args, path);
1415 if (allow_replace) {
1417 if (
nullptr != pentry) {
1429 if (
nullptr == pentry) {
1433 if (
nullptr != pentry &&
nullptr !=
comment) {
1445 const int *enumurators,
size_t dim,
1449 const char *path, ...)
1458 va_start(args, path);
1467 secfile, enumurators[0], name_fn,
comment, allow_replace,
1471 for (i = 1; i < dim; i++) {
1474 comment, allow_replace,
"%s,%d",
1475 fullpath,
static_cast<int>(i))) {
1490 const char *
comment,
bool allow_replace,
const char *path, ...)
1493 const char *ent_name;
1495 struct entry *pentry =
nullptr;
1507 if (0 != bitwise_val) {
1508 for (i = begin_fn(); i != end_fn(); i = next_fn(i)) {
1509 if (i & bitwise_val) {
1510 if (
'\0' == str[0]) {
1519 va_start(args, path);
1528 if (allow_replace) {
1530 if (
nullptr != pentry) {
1542 if (
nullptr == pentry) {
1546 if (
nullptr != pentry &&
nullptr !=
comment) {
1558 struct section_file *secfile,
const int *bitwise_vals,
size_t dim,
1561 const char *
comment,
bool allow_replace,
const char *path, ...)
1573 va_start(args, path);
1582 secfile, bitwise_vals[0], name_fn, begin_fn, end_fn,
1583 next_fn,
comment, allow_replace,
"%s", fullpath)) {
1586 for (i = 1; i < dim; i++) {
1589 secfile, bitwise_vals[i], name_fn, begin_fn, end_fn, next_fn,
1590 comment, allow_replace,
"%s,%d", fullpath,
1591 static_cast<int>(i))) {
1606 const char *
comment,
bool allow_replace,
const char *path, ...)
1609 const char *ent_name, *val_name;
1611 struct entry *pentry =
nullptr;
1622 for (i = 0; (val_name = name_fn(data, i)); i++) {
1623 if ((1 << i) &
value) {
1624 if (
'\0' == str[0]) {
1633 if (!(val_name = name_fn(data,
value))) {
1640 va_start(args, path);
1649 if (allow_replace) {
1651 if (
nullptr != pentry) {
1663 if (
nullptr == pentry) {
1667 if (
nullptr != pentry &&
nullptr !=
comment) {
1679 struct section_file *secfile,
const int *values,
size_t dim,
1681 const char *
comment,
bool allow_replace,
const char *path, ...)
1690 va_start(args, path);
1699 secfile, values[0], bitwise, name_fn, data,
comment,
1700 allow_replace,
"%s", fullpath)) {
1703 for (i = 1; i < dim; i++) {
1706 secfile, values[i], bitwise, name_fn, data,
comment,
1707 allow_replace,
"%s,%d", fullpath,
static_cast<int>(i))) {
1731 len = qstrlen(fullpath);
1732 if (
len > 2 && fullpath[
len - 2] ==
',' && fullpath[
len - 1] ==
'0') {
1733 fullpath[
len - 2] =
'\0';
1747 ent_name = strchr(fullpath,
'.');
1770 struct entry *pentry;
1774 va_start(args, path);
1779 SECFILE_LOG(secfile,
nullptr,
"Path %s does not exists.", fullpath);
1792 const char *path, ...)
1799 va_start(args, path);
1810 const char *path, ...)
1813 const struct entry *pentry;
1818 va_start(args, path);
1823 SECFILE_LOG(secfile,
nullptr,
"\"%s\" entry doesn't exist.", fullpath);
1835 bool def,
const char *path, ...)
1838 const struct entry *pentry;
1844 va_start(args, path);
1863 const char *path, ...)
1866 const struct entry *pentry;
1871 va_start(args, path);
1876 SECFILE_LOG(secfile,
nullptr,
"\"%s\" entry doesn't exist.", fullpath);
1888 const char *path, ...)
1891 const struct entry *pentry;
1897 va_start(args, path);
1918 int defval,
int minval,
int maxval,
1919 const char *path, ...)
1922 const struct entry *pentry;
1928 va_start(args, path);
1940 if (
value < minval) {
1942 "\"%s\" should be in the interval [%d, %d] but is %d;"
1943 "using the minimal value.",
1944 fullpath, minval, maxval,
value);
1948 if (
value > maxval) {
1950 "\"%s\" should be in the interval [%d, %d] but is %d;"
1951 "using the maximal value.",
1952 fullpath, minval, maxval,
value);
1965 const char *path, ...)
1975 va_start(args, path);
1982 static_cast<int>(i))) {
1989 SECFILE_LOG(secfile,
nullptr,
"\"%s\" entry doesn't exist.", fullpath);
1994 for (i = 0; i < *dim; i++) {
1996 static_cast<int>(i))) {
1998 "An error occurred when looking up to \"%s,%d\" entry.",
2013 const char *path, ...)
2016 const struct entry *pentry;
2022 va_start(args, path);
2027 SECFILE_LOG(secfile,
nullptr,
"\"%s\" entry doesn't exist.", fullpath);
2043 const char *def,
const char *path,
2047 const struct entry *pentry;
2053 va_start(args, path);
2075 size_t *dim,
const char *path, ...)
2085 va_start(args, path);
2092 static_cast<int>(i))) {
2099 SECFILE_LOG(secfile,
nullptr,
"\"%s\" entry doesn't exist.", fullpath);
2103 vec =
new const char *[i];
2104 for (i = 0; i < *dim; i++) {
2106 static_cast<int>(i)))) {
2108 "An error occurred when looking up to \"%s,%d\" entry.",
2126 const char *path, ...)
2129 const struct entry *pentry;
2140 va_start(args, path);
2145 SECFILE_LOG(secfile,
nullptr,
"\"%s\" entry doesn't exist.", fullpath);
2153 *penumerator = by_name_fn(str, strcmp);
2154 if (is_valid_fn(*penumerator)) {
2159 "Entry \"%s\": no match for \"%s\".",
entry_name(pentry), str);
2172 const struct entry *pentry;
2183 va_start(args, path);
2195 val = by_name_fn(str, strcmp);
2196 if (is_valid_fn(val)) {
2225 va_start(args, path);
2232 static_cast<int>(i))) {
2239 SECFILE_LOG(secfile,
nullptr,
"\"%s\" entry doesn't exist.", fullpath);
2244 for (i = 0; i < *dim; i++) {
2246 by_name_fn,
"%s,%d", fullpath,
2247 static_cast<int>(i))) {
2249 "An error occurred when looking up to \"%s,%d\" entry.",
2267 const char *path, ...)
2270 const struct entry *pentry;
2271 const char *str, *p;
2283 va_start(args, path);
2288 SECFILE_LOG(secfile,
nullptr,
"\"%s\" entry doesn't exist.", fullpath);
2297 if (
'\0' == str[0]) {
2304 p = strchr(str,
'|');
2313 val = by_name_fn(val_name, strcmp);
2314 if (!is_valid_fn(val)) {
2316 "Entry \"%s\": no match for \"%s\".",
entry_name(pentry),
2320 *penumerator |= val;
2322 }
while (
nullptr != p);
2336 const struct entry *pentry;
2337 const char *str, *p;
2348 va_start(args, path);
2360 if (
'\0' == str[0]) {
2368 p = strchr(str,
'|');
2377 val = by_name_fn(val_name, strcmp);
2378 if (!is_valid_fn(val)) {
2383 }
while (
nullptr != p);
2410 va_start(args, path);
2417 static_cast<int>(i))) {
2424 SECFILE_LOG(secfile,
nullptr,
"\"%s\" entry doesn't exist.", fullpath);
2429 for (i = 0; i < *dim; i++) {
2431 by_name_fn,
"%s,%d", fullpath,
2432 static_cast<int>(i))) {
2434 "An error occurred when looking up to \"%s,%d\" entry.",
2450 int *pvalue,
bool bitwise,
2455 const struct entry *pentry;
2456 const char *str, *p, *
name;
2465 va_start(args, path);
2470 SECFILE_LOG(secfile,
nullptr,
"\"%s\" entry doesn't exist.", fullpath);
2480 if (
'\0' == str[0]) {
2487 p = strchr(str,
'|');
2496 for (val = 0; (
name = name_fn(data, val)); val++) {
2501 if (
nullptr ==
name) {
2503 "Entry \"%s\": no match for \"%s\".",
entry_name(pentry),
2507 *pvalue |= 1 << val;
2509 }
while (
nullptr != p);
2511 for (val = 0; (
name = name_fn(data, val)); val++) {
2517 if (
nullptr ==
name) {
2519 "Entry \"%s\": no match for \"%s\".",
entry_name(pentry),
2532 int defval,
bool bitwise,
2538 const struct entry *pentry;
2539 const char *str, *p, *
name;
2547 va_start(args, path);
2552 SECFILE_LOG(secfile,
nullptr,
"\"%s\" entry doesn't exist.", fullpath);
2562 if (
'\0' == str[0]) {
2569 p = strchr(str,
'|');
2578 for (val = 0; (
name = name_fn(data, val)); val++) {
2579 if (0 == strcmp(
name, val_name)) {
2583 if (
nullptr ==
name) {
2585 "Entry \"%s\": no match for \"%s\".",
entry_name(pentry),
2591 }
while (
nullptr != p);
2593 for (val = 0; (
name = name_fn(data, val)); val++) {
2594 if (0 == strcmp(
name, str)) {
2599 if (
nullptr ==
name) {
2601 "Entry \"%s\": no match for \"%s\".",
entry_name(pentry),
2614 const QString &
name)
2633 const char *path, ...)
2640 va_start(args, path);
2651 const struct section_list *
2654 return (
nullptr != secfile ? secfile->
sections :
nullptr);
2662 struct section_list *
2666 struct section_list *matches =
nullptr;
2672 len = qstrlen(prefix);
2680 if (
nullptr == matches) {
2681 matches = section_list_new();
2683 section_list_append(matches, psection);
2695 const QString &
name)
2701 if (
nullptr ==
name ||
'\0' ==
name[0]) {
2708 qUtf8Printable(
name));
2716 qUtf8Printable(
name));
2722 psection->
name = qstrdup(qUtf8Printable(
name));
2747 if ((secfile = psection->
secfile)) {
2749 if (section_list_remove(secfile->
sections, psection)) {
2758 entry_list_destroy(psection->
entries);
2759 delete[] psection->
name;
2771 entry_list_clear(psection->
entries);
2773 if (0 < entry_list_size(psection->
entries)) {
2775 "After clearing all, %d entries are still remaining.",
2776 entry_list_size(psection->
entries));
2786 return (
nullptr != psection ? psection->
entries :
nullptr);
2793 const QString &
name)
2816 struct entry *pentry;
2822 if (
nullptr ==
name ||
'\0' ==
name[0]) {
2829 qUtf8Printable(
name));
2836 qUtf8Printable(
name));
2841 pentry->
name = qstrdup(qUtf8Printable(
name));
2865 if (
nullptr != pentry) {
2881 if (
nullptr != pentry) {
2897 if (
nullptr != pentry) {
2909 const QString &
name,
2914 if (
nullptr != pentry) {
2916 pentry->
string.value = qstrdup(qUtf8Printable(
value));
2918 pentry->
string.raw =
false;
2919 pentry->
string.gt_marking =
false;
2928 static struct entry *
2934 if (
nullptr != pentry) {
2950 if (
nullptr == pentry) {
2954 if ((psection = pentry->
psection)) {
2956 if (entry_list_remove(psection->
entries, pentry)) {
2968 switch (pentry->
type) {
2976 delete[] pentry->
string.value;
2985 delete[] pentry->
name;
2996 return (
nullptr != pentry ? pentry->
psection :
nullptr);
3022 return (
nullptr != pentry ? pentry->
name :
nullptr);
3039 if (
nullptr ==
name ||
'\0' ==
name[0]) {
3040 SECFILE_LOG(secfile, psection,
"No new name for entry \"%s\".",
3047 "\"%s\" is not a valid entry name for entry \"%s\".",
name,
3055 if (
nullptr != pother && pother != pentry) {
3078 return (
nullptr != pentry ? pentry->
comment :
nullptr);
3086 if (
nullptr == pentry) {
3099 return (0 < pentry->
used);
3127 if (
nullptr !=
value) {
3155 if (
nullptr !=
value) {
3185 if (
nullptr !=
value) {
3213 if (
nullptr !=
value) {
3234 old_val = pentry->
string.value;
3259 static char buf[8192];
3261 switch (pentry->
type) {
3264 fs->write(pentry->
boolean.value ?
"TRUE" :
"FALSE") > 0,
false);
3267 auto number = QString::number(pentry->
integer.value);
3271 auto number = QString::number(pentry->
floating.value,
'f');
3272 if (!number.contains(
'.')) {
3273 number += QStringLiteral(
".0");
3278 if (pentry->
string.escaped) {
3280 if (pentry->
string.gt_marking) {
3287 }
else if (pentry->
string.raw) {
3291 fs->write(
"$" + QByteArray(pentry->
string.value) +
"$") > 0,
3297 fs->write(
"*" + QByteArray(pentry->
string.value) +
"*") > 0,
false);
3311 const QString &
name,
const QString &tok,
3315 qCritical(
"%s", qUtf8Printable(
3316 inf_log_str(inf,
"Entry value not recognized: %s",
3317 qUtf8Printable(tok))));
static void base(QVariant data1, QVariant data2)
Action "Build Base" for choice dialog.
#define fc_assert(condition)
#define fc_assert_ret_val(condition, val)
struct section_file * secfile_new(bool allow_duplicates)
Create a new empty section file.
const char * section_name(const struct section *psection)
Returns the section name.
void secfile_destroy(struct section_file *secfile)
Free a section file.
bool secfile_save(const struct section_file *secfile, QString filename)
Save the previously filled in section_file to disk.
const char * entry_comment(const struct entry *pentry)
Returns the comment associated to this entry.
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,...)
Lookup an enumerator value in the secfile.
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,...)
Insert 'dim' boolean entries at 'path,0', 'path,1' etc.
struct entry * secfile_insert_int_full(struct section_file *secfile, int value, const char *comment, bool allow_replace, const char *path,...)
Insert a integer entry.
bool entry_bool_get(const struct entry *pentry, bool *value)
Gets an boolean value.
void section_destroy(struct section *psection)
Remove this section from the secfile.
struct section * entry_section(const struct entry *pentry)
Returns the parent section of this entry.
void secfile_check_unused(const struct section_file *secfile)
Print log messages for any entries in the file which have not been looked up – ie,...
int entry_path(const struct entry *pentry, char *buf, size_t buf_len)
Build the entry path.
bool secfile_lookup_int(const struct section_file *secfile, int *ival, const char *path,...)
Lookup a integer value in the secfile.
static struct section * secfile_insert_base(struct section_file *secfile, const char *path, const char **pent_name)
Seperates the section and entry names.
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,...)
Insert a bitwise value entry.
struct section_file * secfile_from_stream(QIODevice *stream, bool allow_duplicates)
Create a section file from a stream.
static struct entry * section_entry_filereference_new(struct section *psection, const char *name, const char *value)
Returns a new entry of type ENTRY_FILEREFERENCE.
struct entry * secfile_insert_filereference(struct section_file *secfile, const char *filename, const char *path,...)
Insert a read-from-a-file string entry.
struct entry * section_entry_str_new(struct section *psection, const QString &name, const QString &value, bool escaped)
Returns a new entry of type ENTRY_STR.
struct entry * secfile_entry_lookup(const struct section_file *secfile, const char *path,...)
Returns the entry at "fullpath" or nullptr if not matched.
bool secfile_entry_delete(struct section_file *secfile, const char *path,...)
Delete an entry.
bool entry_set_name(struct entry *pentry, const char *name)
Sets the name of the entry.
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,...)
Lookup a value saved as string in the secfile.
static bool secfile_hash_insert(struct section_file *secfile, struct entry *pentry)
Insert an entry into the hash table.
int * secfile_lookup_int_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
Lookup a integer vector in the secfile.
const char * entry_name(const struct entry *pentry)
Returns the name of this entry.
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,...)
Lookup a value saved as string in the secfile.
bool entry_bool_set(struct entry *pentry, bool value)
Sets an boolean value.
const char * secfile_lookup_str(const struct section_file *secfile, const char *path,...)
Lookup a string value in the secfile.
const char ** secfile_lookup_str_vec(const struct section_file *secfile, size_t *dim, const char *path,...)
Lookup a string vector in the secfile.
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,...)
Insert 'dim' string entries at 'path,0', 'path,1' etc.
bool entry_float_get(const struct entry *pentry, float *value)
Gets an floating value.
bool entry_str_get(const struct entry *pentry, const char **value)
Gets an string 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,...)
Insert an enumerator value entry that we only have a name accessor function.
bool entry_str_set_gt_marking(struct entry *pentry, bool gt_marking)
Sets if the string should get gettext marking.
static entry * entry_new(struct section *psection, const QString &name)
Returns a new entry.
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,...)
Insert 'dim' integer entries at 'path,0', 'path,1' etc.
void entry_destroy(struct entry *pentry)
Entry structure destructor.
static bool entry_used(const struct entry *pentry)
Returns TRUE if this entry has been used.
void section_clear_all(struct section *psection)
Remove all entries.
const char * secfile_name(const struct section_file *secfile)
Return the filename the section file was loaded as, or "(anonymous)" if this sectionfile was created ...
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,...)
Insert a string entry.
bool entry_float_set(struct entry *pentry, float value)
Sets an floating value.
struct section * secfile_section_by_name(const struct section_file *secfile, const QString &name)
Returns the first section matching the name.
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,...)
Lookup an enumerator value in the secfile.
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,...)
Insert 'dim' string entries at 'path,0', 'path,1' etc.
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,...)
Insert 'dim' string entries at 'path,0', 'path,1' etc.
static struct section_file * secfile_from_input_file(struct inputfile *inf, const QString &filename, const QString §ion, bool allow_duplicates)
Base function to load a section file.
struct section_file * secfile_load_section(const QString &filename, const QString §ion, bool allow_duplicates)
Create a section file from a file, read only one particular section.
bool secfile_lookup_bool_default(const struct section_file *secfile, bool def, const char *path,...)
Lookup a boolean value in the secfile.
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,...)
Lookup a enumerator vector in the secfile.
struct section * secfile_insert_long_comment(struct section_file *secfile, const char *comment)
Insert a long comment entry.
bool entry_int_set(struct entry *pentry, int value)
Sets an integer value.
const char * secfile_lookup_str_default(const struct section_file *secfile, const char *def, const char *path,...)
Lookup a string value in the secfile.
struct entry * secfile_entry_by_path(const struct section_file *secfile, const char *path)
Returns the entry by the name or nullptr if not matched.
static bool entry_to_file(const struct entry *pentry, QIODevice *fs)
Push an entry into a file stream.
struct entry * secfile_insert_float_full(struct section_file *secfile, float value, const char *comment, bool allow_replace, const char *path,...)
Insert a floating entry.
static QString datafilename(const QString &filename)
Simplification of fileinfoname().
int secfile_lookup_int_default(const struct section_file *secfile, int def, const char *path,...)
Lookup a integer value in the secfile.
struct entry * section_entry_by_name(const struct section *psection, const QString &name)
Returns the first entry matching the name.
bool entry_int_get(const struct entry *pentry, int *value)
Gets an integer value.
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,...)
Insert a enumerator entry.
static void entry_use(struct entry *pentry)
Increase the used count.
static bool is_secfile_entry_name_valid(const QString &name)
Ensure name is correct to use it as section or entry name.
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,...)
Lookup an enumerator value in the secfile.
static void entry_from_inf_token(struct section *psection, const QString &name, const QString &tok, struct inputfile *file)
Creates a new entry from the token.
static bool secfile_hash_delete(struct section_file *secfile, struct entry *pentry)
Delete an entry from the hash table.
struct entry * secfile_insert_bool_full(struct section_file *secfile, bool value, const char *comment, bool allow_replace, const char *path,...)
Insert a boolean entry.
const struct section_list * secfile_sections(const struct section_file *secfile)
Returns the list of sections.
struct section * secfile_insert_include(struct section_file *secfile, const char *filename)
Insert a include entry.
static bool is_legal_table_entry_name(char c, bool num)
Returns TRUE iff the character is legal in a table entry name.
bool entry_str_set(struct entry *pentry, const char *value)
Sets an string value.
struct section * secfile_section_new(struct section_file *secfile, const QString &name)
Create a new section in the secfile.
struct section * secfile_section_lookup(const struct section_file *secfile, const char *path,...)
Find a section by path.
struct entry * section_entry_int_new(struct section *psection, const QString &name, int value)
Returns a new entry of type ENTRY_INT.
struct entry * section_entry_bool_new(struct section *psection, const QString &name, bool value)
Returns a new entry of type ENTRY_BOOL.
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,...)
Lookup a bitwise enumerator value in the secfile.
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,...)
Insert 'dim' entries at 'path,0', 'path,1' etc.
struct section_list * secfile_sections_by_name_prefix(const struct section_file *secfile, const char *prefix)
Returns the list of sections which match the name prefix.
const struct entry_list * section_entries(const struct section *psection)
Returns a list containing all the entries.
void entry_set_comment(struct entry *pentry, const QString &comment)
Sets a comment for the entry.
bool secfile_lookup_bool(const struct section_file *secfile, bool *bval, const char *path,...)
Lookup a boolean value in the secfile.
struct entry * section_entry_float_new(struct section *psection, const QString &name, float value)
Returns a new entry of type ENTRY_FLOAT.
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,...)
Lookup a enumerator vector in the secfile.
int secfile_lookup_int_def_min_max(const struct section_file *secfile, int defval, int minval, int maxval, const char *path,...)
Lookup a integer value in the secfile.
enum entry_type entry_type_get(const struct entry *pentry)
Returns the type of this entry or ENTRY_ILLEGAL or error.
#define section_list_iterate(seclist, psection)
#define entry_list_iterate_end
bool(* secfile_enum_is_valid_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 *))
const char *(* secfile_enum_name_fn_t)(int enumerator)
int(* secfile_enum_iter_fn_t)()
const char *(* secfile_enum_name_data_fn_t)(secfile_data_t data, int enumerator)
int(* secfile_enum_next_fn_t)(int enumerator)
const void * secfile_data_t
bool entry_from_token(struct section *psection, const QString &name, const QString &tok)
Add entry to section from token.
#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 QStringList & get_data_dirs()
Returns a list of data directory paths, in the order in which they should be searched.
QString interpret_tilde(const QString &filename)
Interpret ~ in filename as home dir.
QString fileinfoname(const QStringList &dirs, const QString &filename)
Returns a filename to access the specified file from a directory by searching all specified directori...
void remove_leading_trailing_spaces(char *s)
Removes leading and trailing spaces in string pointed to by 's'.
struct entry::@1::@3 boolean
struct entry::@1::@5 floating
struct section * psection
struct entry::@1::@6 string
struct entry::@1::@4 integer
struct section_file::@7 hash
QMultiHash< QString, struct entry * > * entries
struct section_list * sections
bool allow_digital_boolean
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,...)
See also fc_utf8_snprintf_trunc(), fc_utf8_snprintf_rep().
size_t fc_strlcpy(char *dest, const char *src, size_t n)
fc_strlcpy() provides utf-8 version of (non-standard) function strlcpy() It is intended as more user-...
void make_escapes(const char *str, char *buf, size_t buf_len)
Copies a string and convert the following characters:
int fc_strcasecmp(const char *str0, const char *str1)
Compare strings like strcmp(), but ignoring case.
int cat_snprintf(char *str, size_t n, const char *format,...)
cat_snprintf is like a combination of fc_snprintf and fc_strlcat; it does snprintf to the end of an e...
int fc_vsnprintf(char *str, size_t n, const char *format, va_list ap)
#define sz_strlcpy(dest, src)