[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.43 and 1.44

version 1.43, 2016/10/16 17:55:14 version 1.44, 2016/10/16 19:04:05
Line 26 
Line 26 
 #include "tmux.h"  #include "tmux.h"
   
 /* Global command queue. */  /* Global command queue. */
 static struct cmd_q_list global_queue = TAILQ_HEAD_INITIALIZER(global_queue);  static struct cmdq_list global_queue = TAILQ_HEAD_INITIALIZER(global_queue);
   
 /* Get command queue name. */  /* Get command queue name. */
 static const char *  static const char *
Line 41 
Line 41 
 }  }
   
 /* Get command queue from client. */  /* Get command queue from client. */
 static struct cmd_q_list *  static struct cmdq_list *
 cmdq_get(struct client *c)  cmdq_get(struct client *c)
 {  {
         if (c == NULL)          if (c == NULL)
Line 51 
Line 51 
   
 /* Append an item. */  /* Append an item. */
 void  void
 cmdq_append(struct client *c, struct cmd_q *cmdq)  cmdq_append(struct client *c, struct cmdq_item *item)
 {  {
         struct cmd_q_list       *queue = cmdq_get(c);          struct cmdq_list        *queue = cmdq_get(c);
         struct cmd_q            *next;          struct cmdq_item        *next;
   
         do {          do {
                 next = cmdq->next;                  next = item->next;
                 cmdq->next = NULL;                  item->next = NULL;
   
                 if (c != NULL)                  if (c != NULL)
                         c->references++;                          c->references++;
                 cmdq->client = c;                  item->client = c;
   
                 cmdq->queue = queue;                  item->queue = queue;
                 TAILQ_INSERT_TAIL(queue, cmdq, entry);                  TAILQ_INSERT_TAIL(queue, item, entry);
   
                 cmdq = next;                  item = next;
         } while (cmdq != NULL);          } while (item != NULL);
 }  }
   
 /* Insert an item. */  /* Insert an item. */
 void  void
 cmdq_insert_after(struct cmd_q *after, struct cmd_q *cmdq)  cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item)
 {  {
         struct client           *c = after->client;          struct client           *c = after->client;
         struct cmd_q_list       *queue = after->queue;          struct cmdq_list        *queue = after->queue;
         struct cmd_q            *next;          struct cmdq_item        *next;
   
         do {          do {
                 next = cmdq->next;                  next = item->next;
                 cmdq->next = NULL;                  item->next = NULL;
   
                 if (c != NULL)                  if (c != NULL)
                         c->references++;                          c->references++;
                 cmdq->client = c;                  item->client = c;
   
                 cmdq->queue = queue;                  item->queue = queue;
                 if (after->next != NULL)                  if (after->next != NULL)
                         TAILQ_INSERT_AFTER(queue, after->next, cmdq, entry);                          TAILQ_INSERT_AFTER(queue, after->next, item, entry);
                 else                  else
                         TAILQ_INSERT_AFTER(queue, after, cmdq, entry);                          TAILQ_INSERT_AFTER(queue, after, item, entry);
                 after->next = cmdq;                  after->next = item;
   
                 cmdq = next;                  item = next;
         } while (cmdq != NULL);          } while (item != NULL);
 }  }
   
 /* Remove an item. */  /* Remove an item. */
 static void  static void
 cmdq_remove(struct cmd_q *cmdq)  cmdq_remove(struct cmdq_item *item)
 {  {
         free((void *)cmdq->hook);          free((void *)item->hook);
   
         if (cmdq->client != NULL)          if (item->client != NULL)
                 server_client_unref(cmdq->client);                  server_client_unref(item->client);
   
         if (cmdq->type == CMD_Q_COMMAND)          if (item->type == CMDQ_COMMAND)
                 cmd_list_free(cmdq->cmdlist);                  cmd_list_free(item->cmdlist);
   
         TAILQ_REMOVE(cmdq->queue, cmdq, entry);          TAILQ_REMOVE(item->queue, item, entry);
         free(cmdq);          free(item);
 }  }
   
 /* Set command group. */  /* Set command group. */
Line 125 
Line 125 
   
 /* Remove all subsequent items that match this item's group. */  /* Remove all subsequent items that match this item's group. */
 static void  static void
 cmdq_remove_group(struct cmd_q *cmdq)  cmdq_remove_group(struct cmdq_item *item)
 {  {
         struct cmd_q    *this, *next;          struct cmdq_item        *this, *next;
   
         this = TAILQ_NEXT(cmdq, entry);          this = TAILQ_NEXT(item, entry);
         while (this != NULL) {          while (this != NULL) {
                 next = TAILQ_NEXT(this, entry);                  next = TAILQ_NEXT(this, entry);
                 if (this->group == cmdq->group)                  if (this->group == item->group)
                         cmdq_remove(this);                          cmdq_remove(this);
                 this = next;                  this = next;
         }          }
 }  }
   
 /* Get a command for the command queue. */  /* Get a command for the command queue. */
 struct cmd_q *  struct cmdq_item *
 cmdq_get_command(struct cmd_list *cmdlist, struct cmd_find_state *current,  cmdq_get_command(struct cmd_list *cmdlist, struct cmd_find_state *current,
     struct mouse_event *m, int flags)      struct mouse_event *m, int flags)
 {  {
         struct cmd_q    *cmdq, *first = NULL, *last = NULL;          struct cmdq_item        *item, *first = NULL, *last = NULL;
         struct cmd      *cmd;          struct cmd              *cmd;
         u_int            group = cmdq_next_group();          u_int                    group = cmdq_next_group();
   
         TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {          TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
                 cmdq = xcalloc(1, sizeof *cmdq);                  item = xcalloc(1, sizeof *item);
                 cmdq->type = CMD_Q_COMMAND;                  item->type = CMDQ_COMMAND;
                 cmdq->group = group;                  item->group = group;
                 cmdq->flags = flags;                  item->flags = flags;
   
                 cmdq->cmdlist = cmdlist;                  item->cmdlist = cmdlist;
                 cmdq->cmd = cmd;                  item->cmd = cmd;
   
                 if (current != NULL)                  if (current != NULL)
                         cmd_find_copy_state(&cmdq->current, current);                          cmd_find_copy_state(&item->current, current);
                 if (m != NULL)                  if (m != NULL)
                         memcpy(&cmdq->mouse, m, sizeof cmdq->mouse);                          memcpy(&item->mouse, m, sizeof item->mouse);
                 cmdlist->references++;                  cmdlist->references++;
   
                 if (first == NULL)                  if (first == NULL)
                         first = cmdq;                          first = item;
                 if (last != NULL)                  if (last != NULL)
                         last->next = cmdq;                          last->next = item;
                 last = cmdq;                  last = item;
         }          }
         return (first);          return (first);
 }  }
   
 /* Fire command on command queue. */  /* Fire command on command queue. */
 static enum cmd_retval  static enum cmd_retval
 cmdq_fire_command(struct cmd_q *cmdq)  cmdq_fire_command(struct cmdq_item *item)
 {  {
         struct client           *c = cmdq->client;          struct client           *c = item->client;
         struct cmd              *cmd = cmdq->cmd;          struct cmd              *cmd = item->cmd;
         enum cmd_retval          retval;          enum cmd_retval          retval;
         const char              *name;          const char              *name;
         struct cmd_find_state   *fsp, fs;          struct cmd_find_state   *fsp, fs;
         int                      flags;          int                      flags;
   
         flags = !!(cmd->flags & CMD_CONTROL);          flags = !!(cmd->flags & CMD_CONTROL);
         cmdq_guard(cmdq, "begin", flags);          cmdq_guard(item, "begin", flags);
   
         if (cmd_prepare_state(cmd, cmdq) != 0) {          if (cmd_prepare_state(cmd, item) != 0) {
                 retval = CMD_RETURN_ERROR;                  retval = CMD_RETURN_ERROR;
                 goto out;                  goto out;
         }          }
         if (cmdq->client == NULL)          if (item->client == NULL)
                 cmdq->client = cmd_find_client(cmdq, NULL, CMD_FIND_QUIET);                  item->client = cmd_find_client(item, NULL, CMD_FIND_QUIET);
   
         retval = cmd->entry->exec(cmd, cmdq);          retval = cmd->entry->exec(cmd, item);
         if (retval == CMD_RETURN_ERROR)          if (retval == CMD_RETURN_ERROR)
                 goto out;                  goto out;
   
         if (cmd->entry->flags & CMD_AFTERHOOK) {          if (cmd->entry->flags & CMD_AFTERHOOK) {
                 name = cmd->entry->name;                  name = cmd->entry->name;
                 if (cmd_find_valid_state(&cmdq->state.tflag))                  if (cmd_find_valid_state(&item->state.tflag))
                         fsp = &cmdq->state.tflag;                          fsp = &item->state.tflag;
                 else {                  else {
                         if (cmd_find_current(&fs, cmdq, CMD_FIND_QUIET) != 0)                          if (cmd_find_current(&fs, item, CMD_FIND_QUIET) != 0)
                                 goto out;                                  goto out;
                         fsp = &fs;                          fsp = &fs;
                 }                  }
                 hooks_insert(fsp->s->hooks, cmdq, fsp, "after-%s", name);                  hooks_insert(fsp->s->hooks, item, fsp, "after-%s", name);
         }          }
   
 out:  out:
         cmdq->client = c;          item->client = c;
         if (retval == CMD_RETURN_ERROR)          if (retval == CMD_RETURN_ERROR)
                 cmdq_guard(cmdq, "error", flags);                  cmdq_guard(item, "error", flags);
         else          else
                 cmdq_guard(cmdq, "end", flags);                  cmdq_guard(item, "end", flags);
         return (retval);          return (retval);
 }  }
   
 /* Get a callback for the command queue. */  /* Get a callback for the command queue. */
 struct cmd_q *  struct cmdq_item *
 cmdq_get_callback(cmd_q_cb cb, void *data)  cmdq_get_callback(cmdq_cb cb, void *data)
 {  {
         struct cmd_q    *cmdq;          struct cmdq_item        *item;
   
         cmdq = xcalloc(1, sizeof *cmdq);          item = xcalloc(1, sizeof *item);
         cmdq->type = CMD_Q_CALLBACK;          item->type = CMDQ_CALLBACK;
         cmdq->group = 0;          item->group = 0;
         cmdq->flags = 0;          item->flags = 0;
   
         cmdq->cb = cb;          item->cb = cb;
         cmdq->data = data;          item->data = data;
   
         return (cmdq);          return (item);
 }  }
   
 /* Fire callback on callback queue. */  /* Fire callback on callback queue. */
 static enum cmd_retval  static enum cmd_retval
 cmdq_fire_callback(struct cmd_q *cmdq)  cmdq_fire_callback(struct cmdq_item *item)
 {  {
         return (cmdq->cb(cmdq, cmdq->data));          return (item->cb(item, item->data));
 }  }
   
 /* Process next item on command queue. */  /* Process next item on command queue. */
 u_int  u_int
 cmdq_next(struct client *c)  cmdq_next(struct client *c)
 {  {
         struct cmd_q_list       *queue = cmdq_get(c);          struct cmdq_list        *queue = cmdq_get(c);
         const char              *name = cmdq_name(c);          const char              *name = cmdq_name(c);
         struct cmd_q            *cmdq;          struct cmdq_item        *item;
         enum cmd_retval          retval;          enum cmd_retval          retval;
         u_int                    items = 0;          u_int                    items = 0;
         static u_int             number;          static u_int             number;
Line 256 
Line 256 
                 log_debug("%s %s: empty", __func__, name);                  log_debug("%s %s: empty", __func__, name);
                 return (0);                  return (0);
         }          }
         if (TAILQ_FIRST(queue)->flags & CMD_Q_WAITING) {          if (TAILQ_FIRST(queue)->flags & CMDQ_WAITING) {
                 log_debug("%s %s: waiting", __func__, name);                  log_debug("%s %s: waiting", __func__, name);
                 return (0);                  return (0);
         }          }
   
         log_debug("%s %s: enter", __func__, name);          log_debug("%s %s: enter", __func__, name);
         for (;;) {          for (;;) {
                 cmdq = TAILQ_FIRST(queue);                  item = TAILQ_FIRST(queue);
                 if (cmdq == NULL)                  if (item == NULL)
                         break;                          break;
                 log_debug("%s %s: type %d, flags %x", __func__, name,                  log_debug("%s %s: type %d, flags %x", __func__, name,
                     cmdq->type, cmdq->flags);                      item->type, item->flags);
   
                 /*                  /*
                  * Any item with the waiting flag set waits until an external                   * Any item with the waiting flag set waits until an external
                  * event clears the flag (for example, a job - look at                   * event clears the flag (for example, a job - look at
                  * run-shell).                   * run-shell).
                  */                   */
                 if (cmdq->flags & CMD_Q_WAITING)                  if (item->flags & CMDQ_WAITING)
                         goto waiting;                          goto waiting;
   
                 /*                  /*
                  * Items are only fired once, once the fired flag is set, a                   * Items are only fired once, once the fired flag is set, a
                  * waiting flag can only be cleared by an external event.                   * waiting flag can only be cleared by an external event.
                  */                   */
                 if (~cmdq->flags & CMD_Q_FIRED) {                  if (~item->flags & CMDQ_FIRED) {
                         cmdq->time = time(NULL);                          item->time = time(NULL);
                         cmdq->number = ++number;                          item->number = ++number;
   
                         switch (cmdq->type)                          switch (item->type)
                         {                          {
                         case CMD_Q_COMMAND:                          case CMDQ_COMMAND:
                                 retval = cmdq_fire_command(cmdq);                                  retval = cmdq_fire_command(item);
   
                                 /*                                  /*
                                  * If a command returns an error, remove any                                   * If a command returns an error, remove any
                                  * subsequent commands in the same group.                                   * subsequent commands in the same group.
                                  */                                   */
                                 if (retval == CMD_RETURN_ERROR)                                  if (retval == CMD_RETURN_ERROR)
                                         cmdq_remove_group(cmdq);                                          cmdq_remove_group(item);
                                 break;                                  break;
                         case CMD_Q_CALLBACK:                          case CMDQ_CALLBACK:
                                 retval = cmdq_fire_callback(cmdq);                                  retval = cmdq_fire_callback(item);
                                 break;                                  break;
                         default:                          default:
                                 retval = CMD_RETURN_ERROR;                                  retval = CMD_RETURN_ERROR;
                                 break;                                  break;
                         }                          }
                         cmdq->flags |= CMD_Q_FIRED;                          item->flags |= CMDQ_FIRED;
   
                         if (retval == CMD_RETURN_WAIT) {                          if (retval == CMD_RETURN_WAIT) {
                                 cmdq->flags |= CMD_Q_WAITING;                                  item->flags |= CMDQ_WAITING;
                                 goto waiting;                                  goto waiting;
                         }                          }
                         items++;                          items++;
                 }                  }
                 cmdq_remove(cmdq);                  cmdq_remove(item);
         }          }
   
         log_debug("%s %s: exit (empty)", __func__, name);          log_debug("%s %s: exit (empty)", __func__, name);
Line 325 
Line 325 
   
 /* Print a guard line. */  /* Print a guard line. */
 void  void
 cmdq_guard(struct cmd_q *cmdq, const char *guard, int flags)  cmdq_guard(struct cmdq_item *item, const char *guard, int flags)
 {  {
         struct client   *c = cmdq->client;          struct client   *c = item->client;
   
         if (c == NULL || !(c->flags & CLIENT_CONTROL))          if (c == NULL || !(c->flags & CLIENT_CONTROL))
                 return;                  return;
   
         evbuffer_add_printf(c->stdout_data, "%%%s %ld %u %d\n", guard,          evbuffer_add_printf(c->stdout_data, "%%%s %ld %u %d\n", guard,
             (long)cmdq->time, cmdq->number, flags);              (long)item->time, item->number, flags);
         server_client_push_stdout(c);          server_client_push_stdout(c);
 }  }
   
 /* Show message from command. */  /* Show message from command. */
 void  void
 cmdq_print(struct cmd_q *cmdq, const char *fmt, ...)  cmdq_print(struct cmdq_item *item, const char *fmt, ...)
 {  {
         struct client   *c = cmdq->client;          struct client   *c = item->client;
         struct window   *w;          struct window   *w;
         va_list          ap;          va_list          ap;
         char            *tmp, *msg;          char            *tmp, *msg;
Line 376 
Line 376 
   
 /* Show error from command. */  /* Show error from command. */
 void  void
 cmdq_error(struct cmd_q *cmdq, const char *fmt, ...)  cmdq_error(struct cmdq_item *item, const char *fmt, ...)
 {  {
         struct client   *c = cmdq->client;          struct client   *c = item->client;
         struct cmd      *cmd = cmdq->cmd;          struct cmd      *cmd = item->cmd;
         va_list          ap;          va_list          ap;
         char            *msg;          char            *msg;
         size_t           msglen;          size_t           msglen;

Legend:
Removed from v.1.43  
changed lines
  Added in v.1.44