[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.148 and 1.149

version 1.148, 2019/05/10 18:04:06 version 1.149, 2019/05/23 11:13:30
Line 214 
Line 214 
                 log_debug("%s: argv[%d]=%s", prefix, i, argv[i]);                  log_debug("%s: argv[%d]=%s", prefix, i, argv[i]);
 }  }
   
   void
   cmd_prepend_argv(int *argc, char ***argv, char *arg)
   {
           char    **new_argv;
           int       i;
   
           new_argv = xreallocarray(NULL, (*argc) + 1, sizeof *new_argv);
           new_argv[0] = xstrdup(arg);
           for (i = 0; i < *argc; i++)
                   new_argv[1 + i] = (*argv)[i];
   
           free(*argv);
           *argv = new_argv;
           (*argc)++;
   }
   
   void
   cmd_append_argv(int *argc, char ***argv, char *arg)
   {
           *argv = xreallocarray(*argv, (*argc) + 1, sizeof **argv);
           (*argv)[(*argc)++] = xstrdup(arg);
   }
   
 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 318 
Line 341 
         return (buf);          return (buf);
 }  }
   
 static int  char *
 cmd_try_alias(int *argc, char ***argv)  cmd_get_alias(const char *name)
 {  {
         struct options_entry             *o;          struct options_entry            *o;
         struct options_array_item        *a;          struct options_array_item       *a;
         union options_value              *ov;          union options_value             *ov;
         int                               old_argc = *argc, new_argc, i;          size_t                           wanted, n;
         char                            **old_argv = *argv, **new_argv;          const char                      *equals;
         size_t                            wanted;  
         const char                       *cp = NULL;  
   
         o = options_get_only(global_options, "command-alias");          o = options_get_only(global_options, "command-alias");
         if (o == NULL)          if (o == NULL)
                 return (-1);                  return (NULL);
         wanted = strlen(old_argv[0]);          wanted = strlen(name);
   
         a = options_array_first(o);          a = options_array_first(o);
         while (a != NULL) {          while (a != NULL) {
                 ov = options_array_item_value(a);                  ov = options_array_item_value(a);
                 cp = strchr(ov->string, '=');  
                 if (cp != NULL &&                  equals = strchr(ov->string, '=');
                     (size_t)(cp - ov->string) == wanted &&                  if (equals != NULL) {
                     strncmp(old_argv[0], ov->string, wanted) == 0)                          n = equals - ov->string;
                         break;                          if (n == wanted && strncmp(name, ov->string, n) == 0)
                                   return (xstrdup(equals + 1));
                   }
   
                 a = options_array_next(a);                  a = options_array_next(a);
         }          }
         if (a == NULL)          return (NULL);
                 return (-1);  }
   
         if (cmd_string_split(cp + 1, &new_argc, &new_argv) != 0)  static const struct cmd_entry *
                 return (-1);  cmd_find(const char *name, char **cause)
   {
           const struct cmd_entry **loop, *entry, *found = NULL;
           int                      ambiguous;
           char                     s[BUFSIZ];
   
         *argc = new_argc + old_argc - 1;          ambiguous = 0;
         *argv = xcalloc((*argc) + 1, sizeof **argv);          for (loop = cmd_table; *loop != NULL; loop++) {
                   entry = *loop;
                   if (entry->alias != NULL && strcmp(entry->alias, name) == 0) {
                           ambiguous = 0;
                           found = entry;
                           break;
                   }
   
         for (i = 0; i < new_argc; i++)                  if (strncmp(entry->name, name, strlen(name)) != 0)
                 (*argv)[i] = xstrdup(new_argv[i]);                          continue;
         for (i = 1; i < old_argc; i++)                  if (found != NULL)
                 (*argv)[new_argc + i - 1] = xstrdup(old_argv[i]);                          ambiguous = 1;
                   found = entry;
   
         log_debug("alias: %s=%s", old_argv[0], cp + 1);                  if (strcmp(entry->name, name) == 0)
         for (i = 0; i < *argc; i++)                          break;
                 log_debug("alias: argv[%d] = %s", i, (*argv)[i]);          }
           if (ambiguous)
                   goto ambiguous;
           if (found == NULL) {
                   xasprintf(cause, "unknown command: %s", name);
                   return (NULL);
           }
           return (found);
   
         cmd_free_argv(new_argc, new_argv);  ambiguous:
         return (0);          *s = '\0';
           for (loop = cmd_table; *loop != NULL; loop++) {
                   entry = *loop;
                   if (strncmp(entry->name, name, strlen(name)) != 0)
                           continue;
                   if (strlcat(s, entry->name, sizeof s) >= sizeof s)
                           break;
                   if (strlcat(s, ", ", sizeof s) >= sizeof s)
                           break;
           }
           s[strlen(s) - 2] = '\0';
           xasprintf(cause, "ambiguous command: %s, could be: %s", name, s);
           return (NULL);
 }  }
   
 struct cmd *  struct cmd *
 cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause)  cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause)
 {  {
           const struct cmd_entry  *entry;
         const char              *name;          const char              *name;
         const struct cmd_entry **entryp, *entry;  
         struct cmd              *cmd;          struct cmd              *cmd;
         struct args             *args;          struct args             *args;
         char                     s[BUFSIZ];  
         int                      ambiguous, allocated = 0;  
   
         *cause = NULL;  
         if (argc == 0) {          if (argc == 0) {
                 xasprintf(cause, "no command");                  xasprintf(cause, "no command");
                 return (NULL);                  return (NULL);
         }          }
         name = argv[0];          name = argv[0];
   
 retry:          entry = cmd_find(name, cause);
         ambiguous = 0;          if (entry == NULL)
         entry = NULL;  
         for (entryp = cmd_table; *entryp != NULL; entryp++) {  
                 if ((*entryp)->alias != NULL &&  
                     strcmp((*entryp)->alias, argv[0]) == 0) {  
                         ambiguous = 0;  
                         entry = *entryp;  
                         break;  
                 }  
   
                 if (strncmp((*entryp)->name, argv[0], strlen(argv[0])) != 0)  
                         continue;  
                 if (entry != NULL)  
                         ambiguous = 1;  
                 entry = *entryp;  
   
                 /* Bail now if an exact match. */  
                 if (strcmp(entry->name, argv[0]) == 0)  
                         break;  
         }  
         if ((ambiguous || entry == NULL) &&  
             server_proc != NULL &&  
             !allocated &&  
             cmd_try_alias(&argc, &argv) == 0) {  
                 allocated = 1;  
                 goto retry;  
         }  
         if (ambiguous)  
                 goto ambiguous;  
         if (entry == NULL) {  
                 xasprintf(cause, "unknown command: %s", name);  
                 return (NULL);                  return (NULL);
         }  
         cmd_log_argv(argc, argv, entry->name);          cmd_log_argv(argc, argv, entry->name);
   
         args = args_parse(entry->args.template, argc, argv);          args = args_parse(entry->args.template, argc, argv);
Line 435 
Line 455 
                 cmd->file = xstrdup(file);                  cmd->file = xstrdup(file);
         cmd->line = line;          cmd->line = line;
   
         if (allocated)          cmd->alias = NULL;
                 cmd_free_argv(argc, argv);          cmd->argc = argc;
           cmd->argv = cmd_copy_argv(argc, argv);
   
         return (cmd);          return (cmd);
   
 ambiguous:  
         *s = '\0';  
         for (entryp = cmd_table; *entryp != NULL; entryp++) {  
                 if (strncmp((*entryp)->name, argv[0], strlen(argv[0])) != 0)  
                         continue;  
                 if (strlcat(s, (*entryp)->name, sizeof s) >= sizeof s)  
                         break;  
                 if (strlcat(s, ", ", sizeof s) >= sizeof s)  
                         break;  
         }  
         s[strlen(s) - 2] = '\0';  
         xasprintf(cause, "ambiguous command: %s, could be: %s", name, s);  
         return (NULL);  
   
 usage:  usage:
         if (args != NULL)          if (args != NULL)
                 args_free(args);                  args_free(args);
         xasprintf(cause, "usage: %s %s", entry->name, entry->usage);          xasprintf(cause, "usage: %s %s", entry->name, entry->usage);
         return (NULL);          return (NULL);
   }
   
   void
   cmd_free(struct cmd *cmd)
   {
           free(cmd->alias);
           cmd_free_argv(cmd->argc, cmd->argv);
   
           free(cmd->file);
   
           args_free(cmd->args);
           free(cmd);
 }  }
   
 char *  char *

Legend:
Removed from v.1.148  
changed lines
  Added in v.1.149