Read configuration from .xsys4rc config file

global config in $XSYSTEM4_HOME/.xsys4rc (default ~/.xsys4rc)
game-specific config in <game-dir>/.xsys4rc

Supported options so far are "font-mincho" and "font-gothic". Syntax is
the same as System40.ini. E.g.

    font-mincho = "/home/user/.fonts/msmincho.ttc"
This commit is contained in:
Nunuhara Cabbage
2020-08-07 19:12:51 -07:00
parent 80f0e7b436
commit bd8ad5583a
5 changed files with 74 additions and 15 deletions
+6 -1
View File
@@ -61,7 +61,12 @@ struct ini_entry {
struct ini_value value;
};
struct ini_entry *ini_parse(const char *path, size_t *nr_entries);
enum ini_error {
INI_FILE_ERROR = -1,
INI_DATA_ERROR = -2,
};
struct ini_entry *ini_parse(const char *path, int *nr_entries);
struct ini_entry *ini_make_entry(struct string *name, struct ini_value value);
void ini_free_entry(struct ini_entry *entry);
+12 -5
View File
@@ -24,6 +24,7 @@
#include "ini_parser.tab.h"
extern FILE *yini_in;
extern unsigned long yini_line;
static void list_assign(struct ini_value *list, size_t i, struct ini_value *item)
{
@@ -39,12 +40,15 @@ static void list_assign(struct ini_value *list, size_t i, struct ini_value *item
list->list[i] = *item;
}
struct ini_entry *ini_parse(const char *path, size_t *nr_entries)
struct ini_entry *ini_parse(const char *path, int *nr_entries)
{
struct ini_entry _e;
if (!(yini_in = fopen(path, "rb")))
ERROR("failed to open '%s': %s", path, strerror(errno));
if (!(yini_in = fopen(path, "rb"))) {
*nr_entries = INI_FILE_ERROR;
return NULL;
}
yini_line = 1;
yini_parse();
kvec_t(struct ini_entry) entries;
@@ -65,8 +69,10 @@ struct ini_entry *ini_parse(const char *path, size_t *nr_entries)
struct ini_entry *other = &kv_A(entries, i);
if (strcmp(e->name->text, other->name->text))
continue;
if (other->value.type != INI_LIST)
ERROR("list assignment to non-list: %s[%" SIZE_T_FMT "]", e->name, e->value._list_pos);
if (other->value.type != INI_LIST) {
WARNING("ignoring list assignment to non-list: %s[%" SIZE_T_FMT "]", e->name, e->value._list_pos);
goto end_list_assign;
}
free_string(e->name);
list = other;
break;
@@ -87,6 +93,7 @@ struct ini_entry *ini_parse(const char *path, size_t *nr_entries)
}
list_assign(&list->value, e->value._list_pos, e->value._list_value);
end_list_assign:
free(e->value._list_value);
free(e);
}
+1 -1
View File
@@ -52,7 +52,7 @@ true return TRUE;
false return FALSE;
Formation return FORMATION;
[0-9]+ yini_lval.i = atoi(yini_text); return INTEGER;
[a-zA-Z]+[a-zA-Z0-9]* yini_lval.s = make_string(yini_text, yini_leng); return IDENTIFIER;
[a-zA-Z]+[a-zA-Z0-9_-]* yini_lval.s = make_string(yini_text, yini_leng); return IDENTIFIER;
\" string_buf_ptr = string_buf; BEGIN(str);
+51 -4
View File
@@ -95,10 +95,12 @@ static int ini_integer(struct ini_entry *entry)
static void read_config(const char *path)
{
size_t ini_size;
int ini_size;
struct ini_entry *ini = ini_parse(path, &ini_size);
if (!ini)
ERROR("Failed to read %s", path);
for (size_t i = 0; i < ini_size; i++) {
for (int i = 0; i < ini_size; i++) {
if (!strcmp(ini[i].name->text, "GameName")) {
config.game_name = strdup(ini_string(&ini[i])->text);
} else if (!strcmp(ini[i].name->text, "CodeName")) {
@@ -115,6 +117,40 @@ static void read_config(const char *path)
free(ini);
}
static void read_user_config_file(const char *path)
{
int ini_size;
struct ini_entry *ini = ini_parse(path, &ini_size);
if (!ini)
return;
for (int i = 0; i < ini_size; i++) {
if (!strcmp(ini[i].name->text, "font-mincho")) {
font_paths[FONT_MINCHO] = xstrdup(ini_string(&ini[i])->text);
} else if (!strcmp(ini[i].name->text, "font-gothic")) {
font_paths[FONT_GOTHIC] = xstrdup(ini_string(&ini[i])->text);
}
ini_free_entry(&ini[i]);
}
free(ini);
}
static void read_user_config(void)
{
char *path;
// global config
path = xmalloc(PATH_MAX);
snprintf(path, PATH_MAX-1, "%s/.xsys4rc", config.home_dir);
read_user_config_file(path);
free(path);
// game-specific config
path = gamedir_path(".xsys4rc");
read_user_config_file(path);
free(path);
}
static char *ald_filenames[ALDFILETYPE_MAX][ALD_FILEMAX];
static int ald_count[ALDFILETYPE_MAX];
@@ -329,6 +365,9 @@ int main(int argc, char *argv[])
int err = AIN_SUCCESS;
bool audit = false;
char *font_mincho = NULL;
char *font_gothic = NULL;
while (1) {
static struct option long_options[] = {
{ "help", no_argument, 0, LOPT_HELP },
@@ -357,10 +396,10 @@ int main(int argc, char *argv[])
#endif
break;
case LOPT_FONT_MINCHO:
font_paths[FONT_MINCHO] = optarg;
font_mincho = optarg;
break;
case LOPT_FONT_GOTHIC:
font_paths[FONT_GOTHIC] = optarg;
font_gothic = optarg;
break;
}
}
@@ -394,6 +433,14 @@ int main(int argc, char *argv[])
#endif
config_init();
read_user_config();
// NOTE: some command line options are handled here so that they
// will override settings from .xsys4rc files
if (font_mincho)
font_paths[FONT_MINCHO] = font_mincho;
if (font_gothic)
font_paths[FONT_GOTHIC] = font_gothic;
if (!(ain = ain_open(ainfile, &err))) {
ERROR("%s", ain_strerror(err));
+4 -4
View File
@@ -142,10 +142,10 @@ static void pje_string_list(struct ini_entry *entry, struct string_list *out)
static void pje_parse(const char *path, struct pje_config *config)
{
size_t ini_size;
int ini_size;
struct ini_entry *ini = ini_parse(path, &ini_size);
for (size_t i = 0; i < ini_size; i++) {
for (int i = 0; i < ini_size; i++) {
if (!strcmp(ini[i].name->text, "ProjectName")) {
config->project_name = pje_string(&ini[i]);
} else if (!strcmp(ini[i].name->text, "CodeName")) {
@@ -200,10 +200,10 @@ static void pje_parse(const char *path, struct pje_config *config)
static void pje_parse_inc(const char *path, struct inc_config *config)
{
size_t ini_size;
int ini_size;
struct ini_entry *ini = ini_parse(path, &ini_size);
for (size_t i = 0; i < ini_size; i++) {
for (int i = 0; i < ini_size; i++) {
if (!strcmp(ini[i].name->text, "Source")) {
pje_string_list(&ini[i], &config->source);
} else if (!strcmp(ini[i].name->text, "SystemSource")) {