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

Diff for /src/usr.bin/tmux/cmd.c between version 1.117 and 1.118

version 1.117, 2015/12/13 21:53:57 version 1.118, 2015/12/14 00:31:54
Line 207 
Line 207 
         NULL          NULL
 };  };
   
 static void              cmd_clear_state(struct cmd_state *);  
 static struct client    *cmd_get_state_client(struct cmd_q *, int);  
 static int               cmd_set_state_flag(struct cmd *, struct cmd_q *, char);  
   
 int  int
 cmd_pack_argv(int argc, char **argv, char *buf, size_t len)  cmd_pack_argv(int argc, char **argv, char *buf, size_t len)
 {  {
Line 409 
Line 405 
 }  }
   
 static int  static int
 cmd_set_state_flag(struct cmd *cmd, struct cmd_q *cmdq, char c)  cmd_prepare_state_flag(struct cmd_find_state *fs, enum cmd_entry_flag flag,
       const char *target, struct cmd_q *cmdq)
 {  {
         struct cmd_state        *state = &cmdq->state;          int     targetflags, error;
         struct cmd_find_state   *fsf = NULL;  
         const char              *flag;  
         int                      flags = cmd->entry->flags, everything = 0;  
         int                      allflags = 0, targetflags, error;  
         struct session          *s;  
         struct window           *w;  
         struct winlink          *wl;  
         struct window_pane      *wp;  
   
         /* Set up state for either -t or -s. */          if (flag == CMD_SESSION_WITHPANE) {
         if (c == 't') {                  if (target != NULL && target[strcspn(target, ":.")] != '\0')
                 fsf = &cmdq->state.tflag;                          flag = CMD_PANE;
                 allflags = CMD_ALL_T;                  else
         } else if (c == 's') {                          flag = CMD_SESSION;
                 fsf = &cmdq->state.sflag;  
                 allflags = CMD_ALL_S;  
         }          }
   
         /*          switch (flag) {
          * If the command wants something and no argument is present, use the          case CMD_NONE:
          * base command instead.          case CMD_CLIENT:
          */          case CMD_CLIENT_CANFAIL:
         flag = args_get(cmd->args, c);                  return (0);
         if (flag == NULL) {          case CMD_SESSION:
                 if ((flags & allflags) == 0)          case CMD_SESSION_CANFAIL:
                         return (0); /* doesn't care about flag */          case CMD_SESSION_PREFERUNATTACHED:
                 cmd = cmdq->cmd;          case CMD_SESSION_WITHPANE:
                 everything = 1;  
                 flag = args_get(cmd->args, c);  
         }  
   
         /*  
          * If no flag and the current command is allowed to fail, just skip to  
          * fill in as much we can, otherwise continue and fail later if needed.  
          */  
         if (flag == NULL && (flags & CMD_CANFAIL))  
                 goto complete_everything;  
   
         /* Fill in state using command (current or base) flags. */  
         if (flags & CMD_PREFERUNATTACHED)  
                 targetflags = CMD_FIND_PREFER_UNATTACHED;  
         else  
                 targetflags = 0;                  targetflags = 0;
         switch (cmd->entry->flags & allflags) {                  if (flag == CMD_SESSION_CANFAIL)
         case 0:                          targetflags |= CMD_FIND_QUIET;
                 break;                  if (flag == CMD_SESSION_PREFERUNATTACHED)
         case CMD_SESSION_T|CMD_PANE_T:                          targetflags |= CMD_FIND_PREFER_UNATTACHED;
         case CMD_SESSION_S|CMD_PANE_S:  
                 if (flag != NULL && flag[strcspn(flag, ":.")] != '\0') {  
                         error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_PANE,  
                             targetflags);  
                         if (error != 0)  
                                 return (-1);  
                 } else {  
                         error = cmd_find_target(fsf, cmdq, flag,  
                             CMD_FIND_SESSION, targetflags);  
                         if (error != 0)  
                                 return (-1);  
   
                         if (flag == NULL) {                  error = cmd_find_target(fs, cmdq, target, CMD_FIND_SESSION,
                                 fsf->wl = fsf->s->curw;  
                                 fsf->wp = fsf->s->curw->window->active;  
                         } else {  
                                 s = fsf->s;  
                                 if ((w = window_find_by_id_str(flag)) != NULL)  
                                         wp = w->active;  
                                 else {  
                                         wp = window_pane_find_by_id_str(flag);  
                                         if (wp != NULL)  
                                                 w = wp->window;  
                                 }  
                                 wl = winlink_find_by_window(&s->windows, w);  
                                 if (wl != NULL) {  
                                         fsf->wl = wl;  
                                         fsf->wp = wp;  
                                 }  
                         }  
                 }  
                 break;  
         case CMD_MOVEW_R|CMD_INDEX_T:  
         case CMD_MOVEW_R|CMD_INDEX_S:  
                 error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_SESSION,  
                     targetflags|CMD_FIND_QUIET);  
                 if (error != 0) {  
                         error = cmd_find_target(fsf, cmdq, flag,  
                             CMD_FIND_WINDOW, CMD_FIND_WINDOW_INDEX);  
                         if (error != 0)  
                                 return (-1);  
                 }  
                 break;  
         case CMD_SESSION_T:  
         case CMD_SESSION_S:  
                 error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_SESSION,  
                     targetflags);                      targetflags);
                 if (error != 0)                  if (error != 0 && flag != CMD_SESSION_CANFAIL)
                         return (-1);                          return (-1);
                 break;                  break;
         case CMD_WINDOW_MARKED_T:          case CMD_MOVEW_R:
         case CMD_WINDOW_MARKED_S:                  error = cmd_find_target(fs, cmdq, target, CMD_FIND_SESSION,
                 targetflags |= CMD_FIND_DEFAULT_MARKED;                      CMD_FIND_QUIET);
                   if (error == 0)
                           break;
                   flag = CMD_WINDOW_INDEX;
                 /* FALLTHROUGH */                  /* FALLTHROUGH */
         case CMD_WINDOW_T:          case CMD_WINDOW:
         case CMD_WINDOW_S:          case CMD_WINDOW_CANFAIL:
                 error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_WINDOW,          case CMD_WINDOW_MARKED:
           case CMD_WINDOW_INDEX:
                   targetflags = 0;
                   if (flag == CMD_WINDOW_CANFAIL)
                           targetflags |= CMD_FIND_QUIET;
                   if (flag == CMD_WINDOW_MARKED)
                           targetflags |= CMD_FIND_DEFAULT_MARKED;
                   if (flag == CMD_WINDOW_INDEX)
                           targetflags |= CMD_FIND_WINDOW_INDEX;
   
                   error = cmd_find_target(fs, cmdq, target, CMD_FIND_WINDOW,
                     targetflags);                      targetflags);
                 if (error != 0)                  if (error != 0 && flag != CMD_WINDOW_CANFAIL)
                         return (-1);                          return (-1);
                 break;                  break;
         case CMD_PANE_MARKED_T:          case CMD_PANE:
         case CMD_PANE_MARKED_S:          case CMD_PANE_CANFAIL:
                 targetflags |= CMD_FIND_DEFAULT_MARKED;          case CMD_PANE_MARKED:
                 /* FALLTHROUGH */                  targetflags = 0;
         case CMD_PANE_T:                  if (flag == CMD_PANE_CANFAIL)
         case CMD_PANE_S:                          targetflags |= CMD_FIND_QUIET;
                 error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_PANE,                  if (flag == CMD_PANE_MARKED)
                           targetflags |= CMD_FIND_DEFAULT_MARKED;
   
                   error = cmd_find_target(fs, cmdq, target, CMD_FIND_PANE,
                     targetflags);                      targetflags);
                 if (error != 0)                  if (error != 0 && flag != CMD_PANE_CANFAIL)
                         return (-1);                          return (-1);
                 break;                  break;
         case CMD_INDEX_T:  
         case CMD_INDEX_S:  
                 error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_WINDOW,  
                     CMD_FIND_WINDOW_INDEX);  
                 if (error != 0)  
                         return (-1);  
                 break;  
         default:  
                 fatalx("too many -%c for %s", c, cmd->entry->name);  
         }          }
   
         /*  
          * If this is still the current command, it wants what it asked for and  
          * nothing more. If it's the base command, fill in as much as possible  
          * because the current command may have different flags.  
          */  
         if (!everything)  
                 return (0);  
   
 complete_everything:  
         if (fsf->s == NULL) {  
                 if (state->c != NULL)  
                         fsf->s = state->c->session;  
                 if (fsf->s == NULL) {  
                         error = cmd_find_target(fsf, cmdq, NULL,  
                             CMD_FIND_SESSION, CMD_FIND_QUIET);  
                         if (error != 0)  
                                 fsf->s = NULL;  
                 }  
                 if (fsf->s == NULL) {  
                         if (flags & CMD_CANFAIL)  
                                 return (0);  
                         cmdq_error(cmdq, "no current session");  
                         return (-1);  
                 }  
         }  
         if (fsf->wl == NULL) {  
                 error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_WINDOW, 0);  
                 if (error != 0)  
                         return (-1);  
         }  
         if (fsf->wp == NULL) {  
                 error = cmd_find_target(fsf, cmdq, flag, CMD_FIND_PANE, 0);  
                 if (error != 0)  
                         return (-1);  
         }  
         return (0);          return (0);
 }  }
   
 static struct client *  
 cmd_get_state_client(struct cmd_q *cmdq, int quiet)  
 {  
         struct cmd      *cmd = cmdq->cmd;  
         struct args     *args = cmd->args;  
   
         switch (cmd->entry->flags & (CMD_CLIENT_C|CMD_CLIENT_T)) {  
         case 0:  
                 return (cmd_find_client(cmdq, NULL, 1));  
         case CMD_CLIENT_C:  
                 return (cmd_find_client(cmdq, args_get(args, 'c'), quiet));  
         case CMD_CLIENT_T:  
                 return (cmd_find_client(cmdq, args_get(args, 't'), quiet));  
         default:  
                 fatalx("both -t and -c for %s", cmd->entry->name);  
         }  
 }  
   
 int  int
 cmd_prepare_state(struct cmd *cmd, struct cmd_q *cmdq)  cmd_prepare_state(struct cmd *cmd, struct cmd_q *cmdq)
 {  {
         struct cmd_state        *state = &cmdq->state;          const struct cmd_entry          *entry = cmd->entry;
         struct args             *args = cmd->args;          struct cmd_state                *state = &cmdq->state;
         const char              *cflag, *tflag;          char                            *tmp;
         char                    *tmp;          enum cmd_entry_flag              flag;
         int                      error, quiet;          const char                      *s;
           int                              error;
   
         tmp = cmd_print(cmd);          tmp = cmd_print(cmd);
         log_debug("preparing state for: %s (client %p)", tmp, cmdq->client);          log_debug("preparing state for %s (client %p)", tmp, cmdq->client);
         free(tmp);          free(tmp);
   
         /* Start with an empty state. */  
         cmd_clear_state(state);          cmd_clear_state(state);
   
         /* No error messages if can fail. */          flag = cmd->entry->cflag;
         quiet = 0;          if (flag == CMD_NONE) {
         if (cmd->entry->flags & CMD_CLIENT_CANFAIL)                  flag = cmd->entry->tflag;
                 quiet = 1;                  if (flag == CMD_CLIENT || flag == CMD_CLIENT_CANFAIL)
                           s = args_get(cmd->args, 't');
         /*  
          * If the command wants a client and provides -c or -t, use it. If not,  
          * try the base command instead via cmd_get_state_client. No client is  
          * allowed if no flags, otherwise it must be available.  
          */  
         switch (cmd->entry->flags & (CMD_CLIENT_C|CMD_CLIENT_T)) {  
         case 0:  
                 state->c = cmd_get_state_client(cmdq, 1);  
                 break;  
         case CMD_CLIENT_C:  
                 cflag = args_get(args, 'c');  
                 if (cflag == NULL)  
                         state->c = cmd_get_state_client(cmdq, quiet);  
                 else                  else
                         state->c = cmd_find_client(cmdq, cflag, quiet);                          s = NULL;
                 if (!quiet && state->c == NULL)          } else
                   s = args_get(cmd->args, 'c');
           switch (flag) {
           case CMD_CLIENT:
                   state->c = cmd_find_client(cmdq, s, 0);
                   if (state->c == NULL)
                         return (-1);                          return (-1);
                 break;                  break;
         case CMD_CLIENT_T:  
                 tflag = args_get(args, 't');  
                 if (tflag == NULL)  
                         state->c = cmd_get_state_client(cmdq, 0);  
                 else  
                         state->c = cmd_find_client(cmdq, tflag, 0);  
                 state->c = cmd_find_client(cmdq, args_get(args, 't'), quiet);  
                 if (!quiet && state->c == NULL)  
                         return (-1);  
                 break;  
         default:          default:
                 fatalx("both -c and -t for %s", cmd->entry->name);                  state->c = cmd_find_client(cmdq, s, 1);
                   break;
         }          }
   
         error = cmd_set_state_flag(cmd, cmdq, 't');          s = args_get(cmd->args, 't');
         if (error == 0)          log_debug("preparing -t state: target %s", s == NULL ? "none" : s);
                 error = cmd_set_state_flag(cmd, cmdq, 's');  
         return (error);          error = cmd_prepare_state_flag(&state->tflag, entry->tflag, s, cmdq);
           if (error != 0)
                   return (error);
   
           s = args_get(cmd->args, 's');
           log_debug("preparing -s state: target %s", s == NULL ? "none" : s);
   
           error = cmd_prepare_state_flag(&state->sflag, entry->sflag, s, cmdq);
           if (error != 0)
                   return (error);
   
           return (0);
 }  }
   
 char *  char *

Legend:
Removed from v.1.117  
changed lines
  Added in v.1.118