]> git.neil.brown.name Git - edlib.git/blobdiff - core-keymap.c
TODO: clean out done items.
[edlib.git] / core-keymap.c
index c2b6e492ae9932a507575aa716d0b3d7670fd858..fb7101b0511c7e51b9879df5b045a6666446512a 100644 (file)
@@ -222,6 +222,11 @@ void key_add(struct map *map safe, const char *k safe, struct command *comm)
 
        if (!comm)
                return;
+       if (strcmp(k, "Close") == 0 &&
+           !comm->closed_ok) {
+               LOG("WARNING: Command %s registered for \"Close\" but not marked closed_ok",
+                   comm->name);
+       }
 
        pos = key_find(map, k);
        /* cases:
@@ -430,14 +435,19 @@ void LOG_BT(void)
        LOG("End Backtrace");
 }
 
-static int do_comm_call(struct command *comm safe,
-                       const struct cmd_info *ci safe)
+int do_comm_call(struct command *comm safe, const struct cmd_info *ci safe)
 {
        struct backtrace bt;
        int ret;
 
+       if (ci->home->damaged & DAMAGED_DEAD)
+               return Efail;
        if (times_up_fast(ci->home))
                return Efail;
+       if ((ci->home->damaged & DAMAGED_CLOSED) &&
+           !comm->closed_ok)
+               return Efallthrough;
+
        if (backtrace_depth > 100) {
                backtrace_depth = 0;
                LOG("Recursion limit of 100 reached");
@@ -481,8 +491,12 @@ int key_lookup(struct map *m safe, const struct cmd_info *ci safe)
        }
 }
 
-int key_lookup_prefix(struct map *m safe, const struct cmd_info *ci safe)
+int key_lookup_prefix(struct map *m safe, const struct cmd_info *ci safe,
+                     bool simple)
 {
+       /* A "Simple" lookup avoids the backtrace.  It is used in
+        * signal handlers.
+        */
        const char *k = ci->key;
        int len = strlen(k);
        int pos = key_find(m, k);
@@ -498,7 +512,10 @@ int key_lookup_prefix(struct map *m safe, const struct cmd_info *ci safe)
                if (comm && comm != prev) {
                        ((struct cmd_info*)ci)->comm = comm;
                        ((struct cmd_info*)ci)->key = m->keys[pos+i];
-                       ret = do_comm_call(comm, ci);
+                       if (simple)
+                               ret = comm->func(ci);
+                       else
+                               ret = do_comm_call(comm, ci);
                        ASSERT(ret >= Efallthrough || ret < Eunused);
                        prev = comm;
                        /* something might have been added, recalc
@@ -558,11 +575,13 @@ int key_handle(const struct cmd_info *ci safe)
 
        while (p) {
                int ret = Efallthrough;
-               if (p->handle && !(p->damaged & DAMAGED_DEAD)) {
+               if (p->handle &&
+                   (p->handle->closed_ok ||
+                    !(p->damaged & DAMAGED_CLOSED))) {
                        vci->home = p;
                        vci->comm = p->handle;
                        /* Don't add this to the call stack as it
-                        * should simple call the desired function and
+                        * should simply call the desired function and
                         * that will appear on the call stack.
                         */
                        ret = p->handle->func(ci);