base64: Use para_isspace() everywhere.
[paraslash.git] / play.c
diff --git a/play.c b/play.c
index 1b3cc933926da62c9c6f6914759b66f015ac61ee..a7ce563baafae4e39e33de07867669085c648ac3 100644 (file)
--- a/play.c
+++ b/play.c
@@ -13,7 +13,6 @@
 #include "para.h"
 #include "list.h"
 #include "play.cmdline.h"
-#include "filter.cmdline.h"
 #include "error.h"
 #include "ggo.h"
 #include "buffer_tree.h"
@@ -263,7 +262,7 @@ static int get_playback_error(struct play_task *pt)
 static int eof_cleanup(struct play_task *pt)
 {
        struct writer *w = writers + DEFAULT_WRITER;
-       struct filter *decoder = filters + pt->fn.filter_num;
+       const struct filter *decoder = filter_get(pt->fn.filter_num);
        int ret;
 
        ret = get_playback_error(pt);
@@ -277,7 +276,8 @@ static int eof_cleanup(struct play_task *pt)
        memset(&pt->wn, 0, sizeof(struct writer_node));
 
        task_reap(&pt->fn.task);
-       decoder->close(&pt->fn);
+       if (decoder->close)
+               decoder->close(&pt->fn);
        btr_remove_node(&pt->fn.btrn);
        free(pt->fn.conf);
        memset(&pt->fn, 0, sizeof(struct filter_node));
@@ -368,7 +368,7 @@ static int load_file(struct play_task *pt)
        const char *af;
        char *tmp, buf[20];
        int ret;
-       struct filter *decoder;
+       const struct filter *decoder;
 
        btr_remove_node(&pt->rn.btrn);
        if (!pt->rn.receiver || pt->next_file != pt->current_file) {
@@ -393,7 +393,7 @@ static int load_file(struct play_task *pt)
        if (ret < 0)
                goto fail;
        pt->fn.filter_num = ret;
-       decoder = filters + ret;
+       decoder = filter_get(ret);
        pt->fn.btrn = btr_new_node(&(struct btr_node_description)
                EMBRACE(.name = decoder->name, .parent = pt->rn.btrn,
                        .handler = decoder->execute, .context = &pt->fn));
@@ -591,6 +591,28 @@ static char *get_key_map_seq(int key)
                get_internal_key_map_seq(key) : get_user_key_map_seq(key);
 }
 
+static char *get_key_map_seq_safe(int key)
+{
+       const char hex[] = "0123456789abcdef";
+       char *seq = get_key_map_seq(key), *sseq;
+       size_t n, len = strlen(seq);
+
+       if (len == 1 && isprint(*seq))
+               return seq;
+       sseq = para_malloc(2 + 2 * len + 1);
+       sseq[0] = '0';
+       sseq[1] = 'x';
+       for (n = 0; n < len; n++) {
+               uint8_t val = (seq[n] & 0xf0) >> 4;
+               sseq[2 + 2 * n] = hex[val];
+               val = seq[n] & 0xf;
+               sseq[2 + 2 * n + 1] = hex[val];
+       }
+       free(seq);
+       sseq[2 + 2 * n] = '\0';
+       return sseq;
+}
+
 static inline char *get_internal_key_map_cmd(int key)
 {
        return para_strdup(default_commands[get_internal_key_map_idx(key)]);
@@ -619,15 +641,8 @@ static char **get_mapped_keyseqs(void)
 
        result = para_malloc((NUM_MAPPED_KEYS + 1) * sizeof(char *));
        FOR_EACH_MAPPED_KEY(i) {
-               int idx = get_key_map_idx(i);
                char *seq = get_key_map_seq(i);
-               char *cmd = get_key_map_cmd(i);
-               bool internal = is_internal_key(i);
-               PARA_DEBUG_LOG("%s key sequence #%d: %s -> %s\n",
-                       internal? "internal" : "user-defined",
-                       idx, seq, cmd);
                result[i] = seq;
-               free(cmd);
        }
        result[i] = NULL;
        return result;
@@ -716,7 +731,7 @@ static int com_help(struct play_task *pt, int argc, char **argv)
                        FOR_EACH_MAPPED_KEY(i) {
                                bool internal = is_internal_key(i);
                                int idx = get_key_map_idx(i);
-                               char *seq = get_key_map_seq(i);
+                               char *seq = get_key_map_seq_safe(i);
                                char *cmd = get_key_map_cmd(i);
                                sz = xasprintf(&buf,
                                        "%s key #%d: %s -> %s\n",
@@ -921,6 +936,8 @@ static int com_jmp(struct play_task *pt, int argc, char **argv)
                return ret;
        if (percent < 0 || percent > 100)
                return -ERRNO_TO_PARA_ERROR(EINVAL);
+       if (percent == 100)
+               return com_next(pt, 1, (char *[]){"next", NULL});
        if (pt->playing && !pt->fn.btrn)
                return 0;
        pt->start_chunk = percent * pt->num_chunks / 100;
@@ -1029,7 +1046,7 @@ static void sigint_handler(int sig)
  * stderr. Once the i9e subsystem has been initialized, we switch to the i9e
  * log facility.
  */
-static void session_open(__a_unused struct play_task *pt)
+static void session_open(struct play_task *pt)
 {
        int ret;
        char *history_file;