[BACK]Return to cmd-queue.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Diff for /src/usr.bin/tmux/cmd-queue.c between version 1.87 and 1.88

version 1.87, 2020/04/13 14:46:04 version 1.88, 2020/04/13 15:55:51
Line 145 
Line 145 
         return (item->client);          return (item->client);
 }  }
   
   /* Get item state. */
   struct cmdq_state *
   cmdq_get_state(struct cmdq_item *item)
   {
           return (item->state);
   }
   
 /* Get item target. */  /* Get item target. */
 struct cmd_find_state *  struct cmd_find_state *
 cmdq_get_target(struct cmdq_item *item)  cmdq_get_target(struct cmdq_item *item)
Line 180 
Line 187 
         return (item->state->flags);          return (item->state->flags);
 }  }
   
   /* Create a new state. */
   struct cmdq_state *
   cmdq_new_state(struct cmd_find_state *current, struct key_event *event,
       int flags)
   {
           struct cmdq_state       *state;
   
           state = xcalloc(1, sizeof *state);
           state->references = 1;
           state->flags = flags;
   
           if (event != NULL)
                   memcpy(&state->event, event, sizeof state->event);
           else
                   state->event.key = KEYC_NONE;
           if (current != NULL && cmd_find_valid_state(current))
                   cmd_find_copy_state(&state->current, current);
           else
                   cmd_find_clear_state(&state->current, 0);
   
           return (state);
   }
   
   /* Add a reference to a state. */
   struct cmdq_state *
   cmdq_link_state(struct cmdq_state *state)
   {
           state->references++;
           return (state);
   }
   
   /* Make a copy of a state. */
   struct cmdq_state *
   cmdq_copy_state(struct cmdq_state *state)
   {
           return (cmdq_new_state(&state->current, &state->event, state->flags));
   }
   
   /* Free a state. */
   void
   cmdq_free_state(struct cmdq_state *state)
   {
           if (--state->references == 0)
                   free(state);
   }
   
   /* Add a format to command queue. */
   void
   cmdq_add_format(struct cmdq_state *state, const char *key, const char *fmt, ...)
   {
           va_list  ap;
           char    *value;
   
           va_start(ap, fmt);
           xvasprintf(&value, fmt, ap);
           va_end(ap);
   
           if (state->formats == NULL)
                   state->formats = format_create(NULL, NULL, FORMAT_NONE, 0);
           format_add(state->formats, key, "%s", value);
   
           free(value);
   }
   
 /* Merge formats from item. */  /* Merge formats from item. */
 void  void
 cmdq_merge_formats(struct cmdq_item *item, struct format_tree *ft)  cmdq_merge_formats(struct cmdq_item *item, struct format_tree *ft)
Line 249 
Line 320 
 /* Insert a hook. */  /* Insert a hook. */
 void  void
 cmdq_insert_hook(struct session *s, struct cmdq_item *item,  cmdq_insert_hook(struct session *s, struct cmdq_item *item,
     struct cmd_find_state *fs, const char *fmt, ...)      struct cmd_find_state *current, const char *fmt, ...)
 {  {
           struct cmdq_state               *state = item->state;
         struct options                  *oo;          struct options                  *oo;
         va_list                          ap;          va_list                          ap;
         char                            *name;          char                            *name;
         struct cmdq_item                *new_item;          struct cmdq_item                *new_item;
           struct cmdq_state               *new_state;
         struct options_entry            *o;          struct options_entry            *o;
         struct options_array_item       *a;          struct options_array_item       *a;
         struct cmd_list                 *cmdlist;          struct cmd_list                 *cmdlist;
Line 277 
Line 350 
         }          }
         log_debug("running hook %s (parent %p)", name, item);          log_debug("running hook %s (parent %p)", name, item);
   
           /*
            * The hooks get a new state because they should not update the current
            * target or formats for any subsequent commands.
            */
           new_state = cmdq_new_state(current, &state->event, CMDQ_STATE_NOHOOKS);
           cmdq_add_format(new_state, "hook", "%s", name);
   
         a = options_array_first(o);          a = options_array_first(o);
         while (a != NULL) {          while (a != NULL) {
                 cmdlist = options_array_item_value(a)->cmdlist;                  cmdlist = options_array_item_value(a)->cmdlist;
                 if (cmdlist == NULL) {                  if (cmdlist != NULL) {
                         a = options_array_next(a);                          new_item = cmdq_get_command(cmdlist, new_state);
                         continue;                          if (item != NULL)
                                   item = cmdq_insert_after(item, new_item);
                           else
                                   item = cmdq_append(NULL, new_item);
                 }                  }
   
                 new_item = cmdq_get_command(cmdlist, fs, NULL,  
                     CMDQ_STATE_NOHOOKS);  
                 cmdq_format(new_item, "hook", "%s", name);  
                 if (item != NULL)  
                         item = cmdq_insert_after(item, new_item);  
                 else  
                         item = cmdq_append(NULL, new_item);  
   
                 a = options_array_next(a);                  a = options_array_next(a);
         }          }
   
           cmdq_free_state(new_state);
         free(name);          free(name);
 }  }
   
Line 310 
Line 385 
 static void  static void
 cmdq_remove(struct cmdq_item *item)  cmdq_remove(struct cmdq_item *item)
 {  {
         if (item->state != NULL && --item->state->references == 0) {  
                 if (item->state->formats != NULL)  
                         format_free(item->state->formats);  
                 free(item->state);  
         }  
   
         if (item->client != NULL)          if (item->client != NULL)
                 server_client_unref(item->client);                  server_client_unref(item->client);
   
         if (item->cmdlist != NULL)          if (item->cmdlist != NULL)
                 cmd_list_free(item->cmdlist);                  cmd_list_free(item->cmdlist);
           cmdq_free_state(item->state);
   
         TAILQ_REMOVE(item->queue, item, entry);          TAILQ_REMOVE(item->queue, item, entry);
   
Line 347 
Line 416 
   
 /* Get a command for the command queue. */  /* Get a command for the command queue. */
 struct cmdq_item *  struct cmdq_item *
 cmdq_get_command(struct cmd_list *cmdlist, struct cmd_find_state *current,  cmdq_get_command(struct cmd_list *cmdlist, struct cmdq_state *state)
     struct key_event *event, int flags)  
 {  {
         struct cmdq_item        *item, *first = NULL, *last = NULL;          struct cmdq_item        *item, *first = NULL, *last = NULL;
         struct cmd              *cmd;          struct cmd              *cmd;
         const struct cmd_entry  *entry;          const struct cmd_entry  *entry;
         struct cmdq_state       *state = NULL;          int                      created = 0;
         u_int                    group, last_group = 0;  
   
         cmd = cmd_list_first(cmdlist, &group);          if (state == NULL) {
                   state = cmdq_new_state(NULL, NULL, 0);
                   created = 1;
           }
   
           cmd = cmd_list_first(cmdlist);
         while (cmd != NULL) {          while (cmd != NULL) {
                 if (group != last_group) {  
                         state = xcalloc(1, sizeof *state);  
                         if (current != NULL)  
                                 cmd_find_copy_state(&state->current, current);  
                         else  
                                 cmd_find_clear_state(&state->current, 0);  
                         if (event != NULL) {  
                                 memcpy(&state->event, event,  
                                     sizeof state->event);  
                         }  
                         state->flags = flags;  
                         last_group = group;  
                 }  
                 entry = cmd_get_entry(cmd);                  entry = cmd_get_entry(cmd);
   
                 item = xcalloc(1, sizeof *item);                  item = xcalloc(1, sizeof *item);
                 xasprintf(&item->name, "[%s/%p]", entry->name, item);                  xasprintf(&item->name, "[%s/%p]", entry->name, item);
                 item->type = CMDQ_COMMAND;                  item->type = CMDQ_COMMAND;
                 item->group = group;  
   
                 item->state = state;                  item->group = cmd_get_group(cmd);
                   item->state = cmdq_link_state(state);
   
                 item->cmdlist = cmdlist;                  item->cmdlist = cmdlist;
                 item->cmd = cmd;                  item->cmd = cmd;
   
                   cmdlist->references++;
                 log_debug("%s: %s group %u", __func__, item->name, item->group);                  log_debug("%s: %s group %u", __func__, item->name, item->group);
   
                 state->references++;  
                 cmdlist->references++;  
   
                 if (first == NULL)                  if (first == NULL)
                         first = item;                          first = item;
                 if (last != NULL)                  if (last != NULL)
                         last->next = item;                          last->next = item;
                 last = item;                  last = item;
   
                 cmd = cmd_list_next(cmd, &group);                  cmd = cmd_list_next(cmd);
         }          }
   
           if (created)
                   cmdq_free_state(state);
         return (first);          return (first);
 }  }
   
Line 484 
Line 545 
         item = xcalloc(1, sizeof *item);          item = xcalloc(1, sizeof *item);
         xasprintf(&item->name, "[%s/%p]", name, item);          xasprintf(&item->name, "[%s/%p]", name, item);
         item->type = CMDQ_CALLBACK;          item->type = CMDQ_CALLBACK;
   
         item->group = 0;          item->group = 0;
           item->state = cmdq_new_state(NULL, NULL, 0);
   
         item->cb = cb;          item->cb = cb;
         item->data = data;          item->data = data;
Line 516 
Line 579 
 cmdq_fire_callback(struct cmdq_item *item)  cmdq_fire_callback(struct cmdq_item *item)
 {  {
         return (item->cb(item, item->data));          return (item->cb(item, item->data));
 }  
   
 /* Add a format to command queue. */  
 void  
 cmdq_format(struct cmdq_item *item, const char *key, const char *fmt, ...)  
 {  
         struct cmdq_state       *state = item->state;  
         va_list                  ap;  
         char                    *value;  
   
         va_start(ap, fmt);  
         xvasprintf(&value, fmt, ap);  
         va_end(ap);  
   
         if (state->formats == NULL)  
                 state->formats = format_create(NULL, NULL, FORMAT_NONE, 0);  
         format_add(state->formats, key, "%s", value);  
   
         free(value);  
 }  }
   
 /* Process next item on command queue. */  /* Process next item on command queue. */

Legend:
Removed from v.1.87  
changed lines
  Added in v.1.88