diff --git a/src/main.c b/src/main.c index f1a24fa..51737f9 100644 --- a/src/main.c +++ b/src/main.c @@ -22,42 +22,25 @@ struct cmdarg { const char* long_opt; ///< Long option name const char* format; ///< Format description const char* help; ///< Help string - const char* value; ///< Argument value }; // clang-format off -static struct cmdarg arguments[] = { - { 'g', "gallery", NULL, "start in gallery mode", NULL }, - { 'r', "recursive", NULL, "read directories recursively", NULL }, - { 'o', "order", "ORDER", "set sort order for image list: none/[alpha]/reverse/random", NULL }, - { 's', "scale", "SCALE", "set initial image scale: [optimal]/fit/width/height/fill/real", NULL }, - { 'l', "slideshow", NULL, "activate slideshow mode on startup", NULL }, - { 'p', "position", "POS", "set window position [parent]/X,Y", NULL }, - { 'w', "size", "SIZE", "set window size: fullscreen/[parent]/image/W,H", NULL }, - { 'f', "fullscreen", NULL, "show image in full screen mode", NULL }, - { 'a', "class", "NAME", "set window class/app_id", NULL }, - { 'c', "config", "S.K=V", "set configuration parameter: section.key=value", NULL }, - { 'v', "version", NULL, "print version info and exit", NULL }, - { 'h', "help", NULL, "print this help and exit", NULL }, +static const struct cmdarg arguments[] = { + { 'g', "gallery", NULL, "start in gallery mode" }, + { 'r', "recursive", NULL, "read directories recursively" }, + { 'o', "order", "ORDER", "set sort order for image list: none/[alpha]/reverse/random" }, + { 's', "scale", "SCALE", "set initial image scale: [optimal]/fit/width/height/fill/real" }, + { 'l', "slideshow", NULL, "activate slideshow mode on startup" }, + { 'p', "position", "POS", "set window position [parent]/X,Y" }, + { 'w', "size", "SIZE", "set window size: fullscreen/[parent]/image/W,H" }, + { 'f', "fullscreen", NULL, "show image in full screen mode" }, + { 'a', "class", "NAME", "set window class/app_id" }, + { 'c', "config", "S.K=V", "set configuration parameter: section.key=value" }, + { 'v', "version", NULL, "print version info and exit" }, + { 'h', "help", NULL, "print this help and exit" }, }; // clang-format on -/** - * Get argument description by it short opt. - * @param short_opt short opt to find - * @return pointer to the argument description or NULL if not found - */ -static struct cmdarg* get_arg(char short_opt) -{ - for (size_t i = 0; i < ARRAY_SIZE(arguments); ++i) { - struct cmdarg* arg = &arguments[i]; - if (arg->short_opt == short_opt) { - return arg; - } - } - return NULL; -} - /** * Print usage info. */ @@ -96,9 +79,9 @@ static void print_version(void) * Parse command line arguments. * @param argc number of arguments to parse * @param argv arguments array - * @return index of the first non option argument, or -1 if error + * @return index of the first non option argument */ -static int parse_cmdargs(int argc, char* argv[]) +static int parse_cmdargs(int argc, char* argv[], struct config** cfg) { struct option options[1 + ARRAY_SIZE(arguments)]; char short_opts[ARRAY_SIZE(arguments) * 2]; @@ -124,75 +107,56 @@ static int parse_cmdargs(int argc, char* argv[]) // parse arguments while ((opt = getopt_long(argc, argv, short_opts, options, NULL)) != -1) { - struct cmdarg* arg; - - if (opt == '?') { - return -1; - } - arg = get_arg(opt); - if (!arg) { - return -1; - } - - arg->value = arg->format ? optarg : arg->long_opt; - } - - return optind; -} - -/** - * Load configuration. - * @return pointer to config instnce or NULL on error - */ -static struct config* load_config(void) -{ - struct config* cfg = config_load(); - - for (size_t i = 0; i < ARRAY_SIZE(arguments); ++i) { - const struct cmdarg* arg = &arguments[i]; - if (!arg->value) { - continue; - } - switch (arg->short_opt) { + switch (opt) { case 'g': - config_set(&cfg, APP_CFG_SECTION, APP_CFG_MODE, + config_set(cfg, APP_CFG_SECTION, APP_CFG_MODE, APP_MODE_GALLERY); break; case 'r': - config_set(&cfg, IMGLIST_SECTION, IMGLIST_RECURSIVE, "yes"); + config_set(cfg, IMGLIST_SECTION, IMGLIST_RECURSIVE, "yes"); break; case 'o': - config_set(&cfg, IMGLIST_SECTION, IMGLIST_ORDER, arg->value); + config_set(cfg, IMGLIST_SECTION, IMGLIST_ORDER, optarg); break; case 's': - config_set(&cfg, VIEWER_SECTION, VIEWER_SCALE, arg->value); + config_set(cfg, VIEWER_SECTION, VIEWER_SCALE, optarg); break; case 'l': - config_set(&cfg, VIEWER_SECTION, VIEWER_SLIDESHOW, "yes"); + config_set(cfg, VIEWER_SECTION, VIEWER_SLIDESHOW, "yes"); break; case 'p': - config_set(&cfg, APP_CFG_SECTION, APP_CFG_POSITION, arg->value); + config_set(cfg, APP_CFG_SECTION, APP_CFG_POSITION, optarg); break; case 'w': - config_set(&cfg, APP_CFG_SECTION, APP_CFG_SIZE, arg->value); + config_set(cfg, APP_CFG_SECTION, APP_CFG_SIZE, optarg); break; case 'f': - config_set(&cfg, APP_CFG_SECTION, APP_CFG_SIZE, APP_FULLSCREEN); + config_set(cfg, APP_CFG_SECTION, APP_CFG_SIZE, APP_FULLSCREEN); break; case 'a': - config_set(&cfg, APP_CFG_SECTION, APP_CFG_APP_ID, arg->value); + config_set(cfg, APP_CFG_SECTION, APP_CFG_APP_ID, optarg); break; case 'c': - if (!config_set_arg(&cfg, arg->value)) { + if (!config_set_arg(cfg, optarg)) { fprintf(stderr, "WARNING: Invalid config agrument: \"%s\"\n", - arg->value); + optarg); } break; + case 'v': + print_version(); + exit(EXIT_SUCCESS); + break; + case 'h': + print_help(); + exit(EXIT_SUCCESS); + break; + default: + exit(EXIT_FAILURE); } } - return cfg; + return optind; } /** @@ -200,30 +164,17 @@ static struct config* load_config(void) */ int main(int argc, char* argv[]) { - bool rc = false; + bool rc; struct config* cfg; int argn; setlocale(LC_ALL, ""); - // parse command line arguments - argn = parse_cmdargs(argc, argv); - if (argn < 0) { - return EXIT_FAILURE; - } - if (get_arg('v')->value) { - print_version(); - return EXIT_SUCCESS; - } - if (get_arg('h')->value) { - print_help(); - return EXIT_SUCCESS; - } - - cfg = load_config(); + cfg = config_load(); + argn = parse_cmdargs(argc, argv, &cfg); rc = app_init(cfg, (const char**)&argv[argn], argc - argn); - if (rc) { + if (cfg && rc) { config_check(cfg); } config_free(cfg);