From 75d8a8b69dc99e6c587b4e40e81f6cb04d47dffa Mon Sep 17 00:00:00 2001 From: Nunuhara Cabbage Date: Sun, 1 Jan 2023 19:28:59 -0800 Subject: [PATCH] Improve usage error reporting Print usage information when there is an error in the command line arguments. Also, wait for keypress before exiting on Windows so that the user can read the error message. --- src/system4.c | 58 ++++++++++++++++++++++++++++++++++----------- subprojects/libsys4 | 2 +- 2 files changed, 45 insertions(+), 15 deletions(-) diff --git a/src/system4.c b/src/system4.c index baa2ac0..121e607 100644 --- a/src/system4.c +++ b/src/system4.c @@ -120,12 +120,12 @@ static void read_mixer_channels(struct ini_entry *entry) } } -static void read_config(const char *path) +static bool read_config(const char *path) { int ini_size; struct ini_entry *ini = ini_parse(path, &ini_size); if (!ini) - ERROR("Failed to read %s", path); + return false; for (int i = 0; i < ini_size; i++) { if (!strcmp(ini[i].name->text, "GameName")) { @@ -148,6 +148,7 @@ static void read_config(const char *path) ini_free_entry(&ini[i]); } free(ini); + return true; } static void read_user_config_file(const char *path) @@ -258,25 +259,29 @@ static void config_init(void) mkdir_p(new_save_dir); } -static void config_init_with_ini(const char *ini_path) +static bool config_init_with_ini(const char *ini_path) { - read_config(ini_path); + if (!read_config(ini_path)) + return false; if (!config.ain_filename) ERROR("No AIN filename specified in %s", ini_path); char *tmp = strdup(ini_path); config.game_dir = strdup(dirname(tmp)); free(tmp); config_init(); + return true; } -static void config_init_with_dir(const char *dir) +static bool config_init_with_dir(const char *dir) { char path[PATH_MAX]; snprintf(path, PATH_MAX, "%s/System40.ini", dir); if (!file_exists(path)) { snprintf(path, PATH_MAX, "%s/AliceStart.ini", dir); + if (!file_exists(path)) + return false; } - config_init_with_ini(path); + return config_init_with_ini(path); } static void config_init_with_ain(const char *ain_path) @@ -335,7 +340,7 @@ static void ain_audit(FILE *f, struct ain *ain) static void usage(void) { - puts("Usage: xsystem4 "); + puts("Usage: xsystem4 [options] [inifile-or-directory]"); puts(" -h, --help Display this message and exit"); puts(" -v, --version Display the version and exit"); puts(" -a, --audit Audit AIN file for xsystem4 compatibility"); @@ -352,6 +357,17 @@ static void usage(void) #endif } +static _Noreturn void _usage_error(const char *fmt, ...) +{ + usage(); + puts(""); + + va_list ap; + va_start(ap, fmt); + sys_verror(fmt, ap); +} +#define usage_error(fmt, ...) _usage_error("Error: " fmt "\n", ##__VA_ARGS__) + enum { LOPT_HELP = 256, LOPT_VERSION, @@ -369,8 +385,19 @@ enum { #endif }; +static void windows_error_handler(const char *msg) +{ + sys_warning("%s", msg); + sys_warning("Press any key to exit...\n"); + getchar(); + sys_exit(1); +} + int main(int argc, char *argv[]) { +#ifdef _WIN32 + sys_error_handler = windows_error_handler; +#endif initialize_instructions(); char *ainfile; int err = AIN_SUCCESS; @@ -464,19 +491,22 @@ int main(int argc, char *argv[]) argv += optind; if (argc < 1) { - config_init_with_dir("."); + if (!config_init_with_dir(".")) { + if (!config_init_with_dir("../")) + usage_error("Failed to find game in current or parent directory"); + } } else if (argc > 1) { - usage(); - ERROR("Too many arguments"); + usage_error("Too many arguments"); } else if (is_directory(argv[0])) { - config_init_with_dir(argv[0]); + if (!config_init_with_dir(argv[0])) + usage_error("Failed to find game in '%s'", argv[0]); } else if (!strcasecmp(file_extension(argv[0]), "ini")) { - config_init_with_ini(argv[0]); + if (!config_init_with_ini(argv[0])) + usage_error("Failed to read .ini file '%s'", argv[0]); } else if (!strcasecmp(file_extension(argv[0]), "ain")) { config_init_with_ain(argv[0]); } else { - usage(); - ERROR("Can't initialize game with argument '%s'", argv[0]); + usage_error("Can't initialize game with argument '%s'", argv[0]); } ainfile = gamedir_path(config.ain_filename); diff --git a/subprojects/libsys4 b/subprojects/libsys4 index 499b505..767ad88 160000 --- a/subprojects/libsys4 +++ b/subprojects/libsys4 @@ -1 +1 @@ -Subproject commit 499b505ad9a99d85cd1b2747d09364c4e2f5de2b +Subproject commit 767ad88d3dbc5fb289bdf3ba2fb2b3246d9190b5