]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - gui.c
gui: Improve check_key_map_args().
[paraslash.git] / gui.c
diff --git a/gui.c b/gui.c
index 02d67bc67e182422528c9214a76cc3114c1bbdd0..ead752096464a0519648a13d82a39fd64d9a7d1e 100644 (file)
--- a/gui.c
+++ b/gui.c
@@ -84,9 +84,6 @@ struct gui_command {
 
 static struct gui_theme theme;
 
-static int _argc;
-static char **_argv;
-
 static void com_help(void);
 static void com_reread_conf(void);
 static void com_enlarge_top_win(void);
@@ -386,7 +383,6 @@ static int first_visible_rbe(unsigned *lines)
                int rbe_lines;
                if (!rbe)
                        return i - 1;
-//             fprintf(stderr, "found: %s\n", rbe->msg);
                rbe_lines = NUM_LINES(rbe->len);
                if (rbe_lines > bot.lines)
                        return -1;
@@ -470,7 +466,6 @@ static void rb_add_entry(int color, char *msg)
        new->len = len;
        new->msg = msg;
        old = ringbuffer_add(bot_win_rb, new);
-//     fprintf(stderr, "added: %s\n", new->msg);
        if (old) {
                free(old->msg);
                free(old);
@@ -519,29 +514,22 @@ static int loglevel;
 
 static __printf_2_3 void curses_log(int ll, const char *fmt,...)
 {
-       int color;
-       char *msg;
        va_list ap;
-       unsigned bytes;
 
-       if (ll < loglevel || !curses_active())
+       if (ll < loglevel)
                return;
-       switch (ll) {
-               case LL_DEBUG:
-               case LL_INFO:
-               case LL_NOTICE:
-                       color = COLOR_MSG;
-                       break;
-               default:
-                       color = COLOR_ERRMSG;
-       }
        va_start(ap, fmt);
-       bytes = xvasprintf(&msg, fmt, ap);
+       if (curses_active()) {
+               int color = ll <= LL_NOTICE? COLOR_MSG : COLOR_ERRMSG;
+               char *msg;
+               unsigned bytes = xvasprintf(&msg, fmt, ap);
+               if (bytes > 0 && msg[bytes - 1] == '\n')
+                       msg[bytes - 1] = '\0'; /* cut trailing newline */
+               rb_add_entry(color, msg);
+               wrefresh(bot.win);
+       } else if (cmd_pid <= 0) /* no external command running */
+               vfprintf(stderr, fmt, ap);
        va_end(ap);
-       if (bytes > 0 && msg[bytes - 1] == '\n')
-               msg[bytes - 1] = '\0'; /* cut trailing newline */
-       rb_add_entry(color, msg);
-       wrefresh(bot.win);
 }
 __printf_2_3 void (*para_log)(int, const char*, ...) = curses_log;
 
@@ -555,39 +543,25 @@ static void setup_signal_handling(void)
        para_install_sighandler(SIGUSR1);
 }
 
-/* kill every process in the process group and exit */
-__noreturn static void kill_pg_and_die(int ret)
-{
-       para_sigaction(SIGTERM, SIG_IGN);
-       kill(0, SIGTERM);
-       exit(ret);
-}
-
 static void shutdown_curses(void)
 {
        def_prog_mode();
        endwin();
 }
 
-__noreturn static void finish(int ret)
-{
-       shutdown_curses();
-       kill_pg_and_die(ret);
-}
-
-/*
- * exit curses and print given message to stdout/stderr
- */
-__noreturn __printf_2_3 static void msg_n_exit(int ret, const char* fmt, ...)
+/* disable curses, print a message, kill running processes and exit */
+__noreturn __printf_2_3 static void die(int exit_code, const char* fmt, ...)
 {
        va_list argp;
-       FILE *outfd = ret? stderr: stdout;
 
        shutdown_curses();
        va_start(argp, fmt);
-       vfprintf(outfd, fmt, argp);
+       vfprintf(stderr, fmt, argp);
        va_end(argp);
-       kill_pg_and_die(ret);
+       /* kill every process in the process group and exit */
+       para_sigaction(SIGTERM, SIG_IGN);
+       kill(0, SIGTERM);
+       exit(exit_code);
 }
 
 /*
@@ -627,7 +601,7 @@ static void init_wins(int top_lines)
                sb.win = newwin(sb.lines, sb.cols, sb_y, 0);
                in.win = newwin(in.lines, in.cols, in_y, 0);
                if (!top.win || !bot.win || !sb.win || !in.win || !sep.win)
-                       msg_n_exit(1, "Error: Cannot create curses windows\n");
+                       die(EXIT_FAILURE, "Error: Cannot create curses windows\n");
                wclear(bot.win);
                wclear(sb.win);
                wclear(in.win);
@@ -766,7 +740,7 @@ static void clear_all_items(void)
 static void init_pair_or_die(short pair, short f, short b)
 {
        if (init_pair(pair, f, b) == ERR)
-               msg_n_exit(EXIT_FAILURE, "fatal: init_pair() failed\n");
+               die(EXIT_FAILURE, "fatal: init_pair() failed\n");
 }
 
 static void init_colors_or_die(void)
@@ -774,9 +748,9 @@ static void init_colors_or_die(void)
        int i;
 
        if (!has_colors())
-               msg_n_exit(EXIT_FAILURE, "fatal: No color term\n");
+               die(EXIT_FAILURE, "fatal: No color term\n");
        if (start_color() == ERR)
-               msg_n_exit(EXIT_FAILURE, "fatal: failed to start colors\n");
+               die(EXIT_FAILURE, "fatal: failed to start colors\n");
        FOR_EACH_STATUS_ITEM(i)
                if (theme.data[i].len)
                        init_pair_or_die(i + 1, theme.data[i].fg,
@@ -797,19 +771,19 @@ static void init_curses(void)
        if (curses_active())
                return;
        if (top.win && refresh() == ERR) /* refresh is really needed */
-               msg_n_exit(EXIT_FAILURE, "refresh() failed\n");
+               die(EXIT_FAILURE, "refresh() failed\n");
        if (LINES < theme.lines_min || COLS < theme.cols_min)
-               msg_n_exit(EXIT_FAILURE, "Error: Terminal (%dx%d) too small"
+               die(EXIT_FAILURE, "Terminal (%dx%d) too small"
                        " (need at least %dx%d)\n", COLS, LINES,
                        theme.cols_min, theme.lines_min);
        curs_set(0); /* make cursor invisible, ignore errors */
        nonl(); /* do not NL->CR/NL on output, always returns OK */
        /* don't echo input */
        if (noecho() == ERR)
-               msg_n_exit(EXIT_FAILURE, "fatal: noecho() failed\n");
+               die(EXIT_FAILURE, "fatal: noecho() failed\n");
        /* take input chars one at a time, no wait for \n */
        if (cbreak() == ERR)
-               msg_n_exit(EXIT_FAILURE, "fatal: cbreak() failed\n");
+               die(EXIT_FAILURE, "fatal: cbreak() failed\n");
        init_colors_or_die();
        clear(); /* ignore non-fatal errors */
        init_wins(theme.top_lines_default);
@@ -850,36 +824,31 @@ err_out:
        return 0;
 }
 
-static int check_key_map_args(void)
+static void check_key_map_args_or_die(void)
 {
-       char *s;
-       int i, ret = -1;
-       char *tmp = NULL, *handler, *arg;
+       int i;
+       char *tmp = NULL;
 
        for (i = 0; i < conf.key_map_given; ++i) {
-               s = conf.key_map_arg[i];
-               if (!(*s))
-                       goto out;
+               char *handler, *arg;
+
                free(tmp);
-               tmp = para_strdup(s);
+               tmp = para_strdup(conf.key_map_arg[i]);
                if (!split_key_map(tmp, &handler, &arg))
-                       goto out;
+                       break;
                if (strlen(handler) != 1)
-                       goto out;
-               if (*handler != 'x'
-                       && *handler != 'd'
-                       && *handler != 'i'
-                       && *handler != 'p')
-                       goto out;
+                       break;
+               if (*handler != 'x' && *handler != 'd' && *handler != 'i'
+                               && *handler != 'p')
+                       break;
                if (*handler != 'i')
                        continue;
                if (find_cmd_byname(arg) < 0)
-                       goto out;
+                       break;
        }
-       ret = 0;
-out:
+       if (i != conf.key_map_given)
+               die(EXIT_FAILURE, "invalid key map: %s\n", conf.key_map_arg[i]);
        free(tmp);
-       return ret;
 }
 
 /*
@@ -889,8 +858,7 @@ static void handle_signal(int sig)
 {
        switch (sig) {
        case SIGTERM:
-               msg_n_exit(EXIT_FAILURE,
-                       "only the good die young (caught SIGTERM))\n");
+               die(EXIT_FAILURE, "only the good die young (caught SIGTERM)\n");
                return;
        case SIGWINCH:
                if (curses_active()) {
@@ -1250,7 +1218,6 @@ static void com_scroll_up(void)
                        break;
                rbe_lines = NUM_LINES(rbe->len);
                lines += rbe_lines;
-//             fprintf(stderr, "msg: %s\n", rbe->msg);
                wattron(bot.win, COLOR_PAIR(rbe->color));
                waddstr(bot.win, "\n");
                waddstr(bot.win, rbe->msg);
@@ -1306,7 +1273,6 @@ static void com_reread_conf(void)
                return;
        }
        PARA_INFO_LOG("rereading command line options and config file\n");
-       gui_cmdline_parser_ext(_argc, _argv, &conf, &params);
        /*
         * Despite .print_errors is set to 0, gengetopt will print to stderr
         * anyway, and exit on errors. So we have to shutdown curses first.
@@ -1315,8 +1281,7 @@ static void com_reread_conf(void)
        gui_cmdline_parser_config_file(cf, &conf, &params);
        init_curses();
        PARA_NOTICE_LOG("config file reloaded\n");
-       if (check_key_map_args() < 0)
-               finish(EXIT_FAILURE);
+       check_key_map_args_or_die();
 }
 
 static void com_help(void)
@@ -1363,7 +1328,6 @@ static void com_shrink_top_win(void)
                return;
        }
        init_wins(top.lines - 1);
-       wclear(top.win);
        print_all_items();
        print_in_bar(COLOR_MSG, "%s", "decreased top window");
 }
@@ -1375,7 +1339,6 @@ static void com_enlarge_top_win(void)
                return;
        }
        init_wins(top.lines + 1);
-       wclear(top.win);
        print_all_items();
        print_in_bar(COLOR_MSG, "increased top window");
 }
@@ -1387,7 +1350,7 @@ static void com_version(void)
 
 __noreturn static void com_quit(void)
 {
-       finish(0);
+       die(EXIT_SUCCESS, "%s", "");
 }
 
 static void com_refresh(void)
@@ -1464,20 +1427,15 @@ int main(int argc, char *argv[])
        int ret;
        char *cf;
 
-       _argc = argc;
-       _argv = argv;
-
        gui_cmdline_parser(argc, argv, &conf); /* exits on errors */
        loglevel = get_loglevel_by_name(conf.loglevel_arg);
        version_handle_flag("gui", conf.version_given);
        if (conf.help_given || conf.detailed_help_given)
                print_help_and_die();
        cf = configfile_exists();
-       if (!cf && conf.config_file_given) {
-               fprintf(stderr, "can not read config file %s\n",
+       if (!cf && conf.config_file_given)
+               die(EXIT_FAILURE, "can not read config file %s\n",
                        conf.config_file_arg);
-               exit(EXIT_FAILURE);
-       }
        if (cf) {
                struct gui_cmdline_parser_params params = {
                        .override = 0,
@@ -1489,10 +1447,7 @@ int main(int argc, char *argv[])
                gui_cmdline_parser_config_file(cf, &conf, &params);
                loglevel = get_loglevel_by_name(conf.loglevel_arg);
        }
-       if (check_key_map_args() < 0) {
-               fprintf(stderr, "invalid key map\n");
-               exit(EXIT_FAILURE);
-       }
+       check_key_map_args_or_die();
        theme_init(conf.theme_arg, &theme);
        setup_signal_handling();
        bot_win_rb = ringbuffer_new(RINGBUFFER_SIZE);