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

Diff for /src/usr.bin/tmux/arguments.c between version 1.4 and 1.5

version 1.4, 2012/07/10 11:53:01 version 1.5, 2013/05/31 12:19:34
Line 18 
Line 18 
   
 #include <sys/types.h>  #include <sys/types.h>
   
 #include <bitstring.h>  
 #include <stdlib.h>  #include <stdlib.h>
 #include <string.h>  #include <string.h>
   
 #include "tmux.h"  #include "tmux.h"
   
   /*
    * Manipulate command arguments.
    */
   
   struct args_entry       *args_find(struct args *, u_char);
   
   RB_GENERATE(args_tree, args_entry, entry, args_cmp);
   
   /* Arguments tree comparison function. */
   int
   args_cmp(struct args_entry *a1, struct args_entry *a2)
   {
           return (a1->flag - a2->flag);
   }
   
 /* Create an arguments set with no flags. */  /* Create an arguments set with no flags. */
 struct args *  struct args *
 args_create(int argc, ...)  args_create(int argc, ...)
Line 33 
Line 47 
         int              i;          int              i;
   
         args = xcalloc(1, sizeof *args);          args = xcalloc(1, sizeof *args);
         if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL)  
                 fatal("bit_alloc failed");  
   
         args->argc = argc;          args->argc = argc;
         if (argc == 0)          if (argc == 0)
Line 50 
Line 62 
         return (args);          return (args);
 }  }
   
   /* Find a flag in the arguments tree. */
   struct args_entry *
   args_find(struct args *args, u_char ch)
   {
           struct args_entry       entry;
   
           entry.flag = ch;
           return (RB_FIND(args_tree, &args->tree, &entry));
   }
   
 /* Parse an argv and argc into a new argument set. */  /* Parse an argv and argc into a new argument set. */
 struct args *  struct args *
 args_parse(const char *template, int argc, char **argv)  args_parse(const char *template, int argc, char **argv)
Line 59 
Line 81 
         int              opt;          int              opt;
   
         args = xcalloc(1, sizeof *args);          args = xcalloc(1, sizeof *args);
         if ((args->flags = bit_alloc(SCHAR_MAX)) == NULL)  
                 fatal("bit_alloc failed");  
   
         optreset = 1;          optreset = 1;
         optind = 1;          optind = 1;
   
         while ((opt = getopt(argc, argv, template)) != -1) {          while ((opt = getopt(argc, argv, template)) != -1) {
                 if (opt < 0 || opt >= SCHAR_MAX)                  if (opt < 0)
                         continue;                          continue;
                 if (opt == '?' || (ptr = strchr(template, opt)) == NULL) {                  if (opt == '?' || (ptr = strchr(template, opt)) == NULL) {
                         free(args->flags);                          args_free(args);
                         free(args);  
                         return (NULL);                          return (NULL);
                 }                  }
                   args_set(args, opt, optarg);
                 bit_set(args->flags, opt);  
                 if (ptr[1] == ':') {  
                         free(args->values[opt]);  
                         args->values[opt] = xstrdup(optarg);  
                 }  
         }          }
         argc -= optind;          argc -= optind;
         argv += optind;          argv += optind;
Line 93 
Line 107 
 void  void
 args_free(struct args *args)  args_free(struct args *args)
 {  {
         u_int   i;          struct args_entry       *entry;
           struct args_entry       *entry1;
   
         cmd_free_argv(args->argc, args->argv);          cmd_free_argv(args->argc, args->argv);
   
         for (i = 0; i < SCHAR_MAX; i++)          RB_FOREACH_SAFE(entry, args_tree, &args->tree, entry1) {
                 free(args->values[i]);                  RB_REMOVE(args_tree, &args->tree, entry);
                   free(entry->value);
                   free(entry);
           }
   
         free(args->flags);  
         free(args);          free(args);
 }  }
   
Line 108 
Line 125 
 size_t  size_t
 args_print(struct args *args, char *buf, size_t len)  args_print(struct args *args, char *buf, size_t len)
 {  {
         size_t           off;          size_t                   off;
         int              i;          int                      i;
         const char      *quotes;          const char              *quotes;
           struct args_entry       *entry;
   
         /* There must be at least one byte at the start. */          /* There must be at least one byte at the start. */
         if (len == 0)          if (len == 0)
Line 119 
Line 137 
   
         /* Process the flags first. */          /* Process the flags first. */
         buf[off++] = '-';          buf[off++] = '-';
         for (i = 0; i < SCHAR_MAX; i++) {          RB_FOREACH(entry, args_tree, &args->tree) {
                 if (!bit_test(args->flags, i) || args->values[i] != NULL)                  if (entry->value != NULL)
                         continue;                          continue;
   
                 if (off == len - 1) {                  if (off == len - 1) {
                         buf[off] = '\0';                          buf[off] = '\0';
                         return (len);                          return (len);
                 }                  }
                 buf[off++] = i;                  buf[off++] = entry->flag;
                 buf[off] = '\0';                  buf[off] = '\0';
         }          }
         if (off == 1)          if (off == 1)
                 buf[--off] = '\0';                  buf[--off] = '\0';
   
         /* Then the flags with arguments. */          /* Then the flags with arguments. */
         for (i = 0; i < SCHAR_MAX; i++) {          RB_FOREACH(entry, args_tree, &args->tree) {
                 if (!bit_test(args->flags, i) || args->values[i] == NULL)                  if (entry->value == NULL)
                         continue;                          continue;
   
                 if (off >= len) {                  if (off >= len) {
Line 143 
Line 161 
                         return (len);                          return (len);
                 }                  }
   
                 if (strchr(args->values[i], ' ') != NULL)                  if (strchr(entry->value, ' ') != NULL)
                         quotes = "\"";                          quotes = "\"";
                 else                  else
                         quotes = "";                          quotes = "";
                 off += xsnprintf(buf + off, len - off, "%s-%c %s%s%s",                  off += xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
                     off != 0 ? " " : "", i, quotes, args->values[i], quotes);                      off != 0 ? " " : "", entry->flag, quotes, entry->value,
                       quotes);
         }          }
   
         /* And finally the argument vector. */          /* And finally the argument vector. */
Line 173 
Line 192 
 int  int
 args_has(struct args *args, u_char ch)  args_has(struct args *args, u_char ch)
 {  {
         return (bit_test(args->flags, ch));          return (args_find(args, ch) == NULL ? 0 : 1);
 }  }
   
 /* Set argument value. */  /* Set argument value in the arguments tree. */
 void  void
 args_set(struct args *args, u_char ch, const char *value)  args_set(struct args *args, u_char ch, const char *value)
 {  {
         free(args->values[ch]);          struct args_entry       *entry;
   
           /* Replace existing argument. */
           if ((entry = args_find(args, ch)) != NULL) {
                   free(entry->value);
                   if (value != NULL)
                           entry->value = xstrdup(value);
                   else
                           entry->value = NULL;
                   return;
           }
   
           entry = xcalloc(1, sizeof *entry);
           entry->flag = ch;
         if (value != NULL)          if (value != NULL)
                 args->values[ch] = xstrdup(value);                  entry->value = xstrdup(value);
         else  
                 args->values[ch] = NULL;          RB_INSERT(args_tree, &args->tree, entry);
         bit_set(args->flags, ch);  
 }  }
   
 /* Get argument value. Will be NULL if it isn't present. */  /* Get argument value. Will be NULL if it isn't present. */
 const char *  const char *
 args_get(struct args *args, u_char ch)  args_get(struct args *args, u_char ch)
 {  {
         return (args->values[ch]);          struct args_entry       *entry;
   
           if ((entry = args_find(args, ch)) == NULL)
                   return (NULL);
           return (entry->value);
 }  }
   
 /* Convert an argument value to a number. */  /* Convert an argument value to a number. */
 long long  long long
 args_strtonum(struct args *args,  args_strtonum(struct args *args, u_char ch, long long minval, long long maxval,
     u_char ch, long long minval, long long maxval, char **cause)      char **cause)
 {  {
         const char      *errstr;          const char              *errstr;
         long long        ll;          long long                ll;
           struct args_entry       *entry;
   
         if (!args_has(args, ch)) {          if ((entry = args_find(args, ch)) == NULL) {
                 *cause = xstrdup("missing");                  *cause = xstrdup("missing");
                 return (0);                  return (0);
         }          }
   
         ll = strtonum(args->values[ch], minval, maxval, &errstr);          ll = strtonum(entry->value, minval, maxval, &errstr);
         if (errstr != NULL) {          if (errstr != NULL) {
                 *cause = xstrdup(errstr);                  *cause = xstrdup(errstr);
                 return (0);                  return (0);

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5