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

Diff for /src/usr.bin/tmux/options.c between version 1.38 and 1.39

version 1.38, 2019/03/15 21:54:47 version 1.39, 2019/03/18 11:58:40
Line 30 
Line 30 
  * a red-black tree.   * a red-black tree.
  */   */
   
   struct options_array_item {
           u_int                            index;
           char                            *value;
           RB_ENTRY(options_array_item)     entry;
   };
   RB_HEAD(options_array, options_array_item);
   static int
   options_array_cmp(struct options_array_item *a1, struct options_array_item *a2)
   {
           if (a1->index < a2->index)
                   return (-1);
           if (a1->index > a2->index)
                   return (1);
           return (0);
   }
   RB_GENERATE_STATIC(options_array, options_array_item, entry, options_array_cmp);
   
 struct options_entry {  struct options_entry {
         struct options                           *owner;          struct options                           *owner;
   
Line 40 
Line 57 
                 char                             *string;                  char                             *string;
                 long long                         number;                  long long                         number;
                 struct style                      style;                  struct style                      style;
                 struct {                  struct options_array              array;
                         const char              **array;  
                         u_int                     arraysize;  
                 };  
         };          };
   
         RB_ENTRY(options_entry)                   entry;          RB_ENTRY(options_entry)                   entry;
Line 56 
Line 70 
   
 static struct options_entry     *options_add(struct options *, const char *);  static struct options_entry     *options_add(struct options *, const char *);
   
 #define OPTIONS_ARRAY_LIMIT 1000  
   
 #define OPTIONS_IS_STRING(o)                                            \  #define OPTIONS_IS_STRING(o)                                            \
         ((o)->tableentry == NULL ||                                     \          ((o)->tableentry == NULL ||                                     \
             (o)->tableentry->type == OPTIONS_TABLE_STRING)              (o)->tableentry->type == OPTIONS_TABLE_STRING)
Line 163 
Line 175 
         o = options_add(oo, oe->name);          o = options_add(oo, oe->name);
         o->tableentry = oe;          o->tableentry = oe;
   
           if (oe->type == OPTIONS_TABLE_ARRAY)
                   RB_INIT(&o->array);
   
         return (o);          return (o);
 }  }
   
Line 210 
Line 225 
 options_remove(struct options_entry *o)  options_remove(struct options_entry *o)
 {  {
         struct options  *oo = o->owner;          struct options  *oo = o->owner;
         u_int            i;  
   
         if (OPTIONS_IS_STRING(o))          if (OPTIONS_IS_STRING(o))
                 free((void *)o->string);                  free(o->string);
         else if (OPTIONS_IS_ARRAY(o)) {          else if (OPTIONS_IS_ARRAY(o))
                 for (i = 0; i < o->arraysize; i++)                  options_array_clear(o);
                         free((void *)o->array[i]);  
                 free(o->array);  
         }  
   
         RB_REMOVE(options_tree, &oo->tree, o);          RB_REMOVE(options_tree, &oo->tree, o);
         free(o);          free(o);
Line 236 
Line 247 
         return (o->tableentry);          return (o->tableentry);
 }  }
   
   static struct options_array_item *
   options_array_item(struct options_entry *o, u_int idx)
   {
           struct options_array_item       a;
   
           a.index = idx;
           return (RB_FIND(options_array, &o->array, &a));
   }
   
   static void
   options_array_free(struct options_entry *o, struct options_array_item *a)
   {
           free(a->value);
           RB_REMOVE(options_array, &o->array, a);
           free(a);
   }
   
 void  void
 options_array_clear(struct options_entry *o)  options_array_clear(struct options_entry *o)
 {  {
         if (OPTIONS_IS_ARRAY(o))          struct options_array_item       *a, *a1;
                 o->arraysize = 0;  
           if (!OPTIONS_IS_ARRAY(o))
                   return;
   
           RB_FOREACH_SAFE(a, options_array, &o->array, a1)
               options_array_free(o, a);
 }  }
   
 const char *  const char *
 options_array_get(struct options_entry *o, u_int idx)  options_array_get(struct options_entry *o, u_int idx)
 {  {
           struct options_array_item       *a;
   
         if (!OPTIONS_IS_ARRAY(o))          if (!OPTIONS_IS_ARRAY(o))
                 return (NULL);                  return (NULL);
         if (idx >= o->arraysize)          a = options_array_item(o, idx);
           if (a == NULL)
                 return (NULL);                  return (NULL);
         return (o->array[idx]);          return (a->value);
 }  }
   
 int  int
 options_array_set(struct options_entry *o, u_int idx, const char *value,  options_array_set(struct options_entry *o, u_int idx, const char *value,
     int append)      int append)
 {  {
         char    *new;          struct options_array_item       *a;
         u_int    i;          char                            *new;
   
         if (!OPTIONS_IS_ARRAY(o))          if (!OPTIONS_IS_ARRAY(o))
                 return (-1);                  return (-1);
   
         if (idx >= OPTIONS_ARRAY_LIMIT)          a = options_array_item(o, idx);
                 return (-1);          if (value == NULL) {
         if (idx >= o->arraysize) {                  if (a != NULL)
                 o->array = xreallocarray(o->array, idx + 1, sizeof *o->array);                          options_array_free(o, a);
                 for (i = o->arraysize; i < idx + 1; i++)                  return (0);
                         o->array[i] = NULL;  
                 o->arraysize = idx + 1;  
         }          }
   
         new = NULL;          if (a == NULL) {
         if (value != NULL) {                  a = xcalloc(1, sizeof *a);
                 if (o->array[idx] != NULL && append)                  a->index = idx;
                         xasprintf(&new, "%s%s", o->array[idx], value);                  a->value = xstrdup(value);
                   RB_INSERT(options_array, &o->array, a);
           } else {
                   free(a->value);
                   if (a != NULL && append)
                           xasprintf(&new, "%s%s", a->value, value);
                 else                  else
                         new = xstrdup(value);                          new = xstrdup(value);
                   a->value = new;
         }          }
   
         free((void *)o->array[idx]);  
         o->array[idx] = new;  
         return (0);          return (0);
 }  }
   
 int  
 options_array_size(struct options_entry *o, u_int *size)  
 {  
         if (!OPTIONS_IS_ARRAY(o))  
                 return (-1);  
         if (size != NULL)  
                 *size = o->arraysize;  
         return (0);  
 }  
   
 void  void
 options_array_assign(struct options_entry *o, const char *s)  options_array_assign(struct options_entry *o, const char *s)
 {  {
Line 310 
Line 338 
         while ((next = strsep(&string, separator)) != NULL) {          while ((next = strsep(&string, separator)) != NULL) {
                 if (*next == '\0')                  if (*next == '\0')
                         continue;                          continue;
                 for (i = 0; i < OPTIONS_ARRAY_LIMIT; i++) {                  for (i = 0; i < UINT_MAX; i++) {
                         if (i >= o->arraysize || o->array[i] == NULL)                          if (options_array_item(o, i) == NULL)
                                 break;                                  break;
                 }                  }
                 if (i == OPTIONS_ARRAY_LIMIT)                  if (i == UINT_MAX)
                         break;                          break;
                 options_array_set(o, i, next, 0);                  options_array_set(o, i, next, 0);
         }          }
         free(copy);          free(copy);
 }  }
   
   struct options_array_item *
   options_array_first(struct options_entry *o)
   {
           if (!OPTIONS_IS_ARRAY(o))
                   return (NULL);
           return (RB_MIN(options_array, &o->array));
   }
   
   struct options_array_item *
   options_array_next(struct options_array_item *a)
   {
           return (RB_NEXT(options_array, &o->array, a));
   }
   
   u_int
   options_array_item_index(struct options_array_item *a)
   {
           return (a->index);
   }
   
   const char *
   options_array_item_value(struct options_array_item *a)
   {
           return (a->value);
   }
   
 int  int
   options_isarray(struct options_entry *o)
   {
           return (OPTIONS_IS_ARRAY(o));
   }
   
   int
 options_isstring(struct options_entry *o)  options_isstring(struct options_entry *o)
 {  {
         if (o->tableentry == NULL)  
                 return (1);  
         return (OPTIONS_IS_STRING(o) || OPTIONS_IS_ARRAY(o));          return (OPTIONS_IS_STRING(o) || OPTIONS_IS_ARRAY(o));
 }  }
   
 const char *  const char *
 options_tostring(struct options_entry *o, int idx, int numeric)  options_tostring(struct options_entry *o, int idx, int numeric)
 {  {
         static char      s[1024];          static char                      s[1024];
         const char      *tmp;          const char                      *tmp;
           struct options_array_item       *a;
   
         if (OPTIONS_IS_ARRAY(o)) {          if (OPTIONS_IS_ARRAY(o)) {
                 if (idx == -1)                  if (idx == -1)
                         return (NULL);                          return (NULL);
                 if ((u_int)idx >= o->arraysize || o->array[idx] == NULL)                  a = options_array_item(o, idx);
                   if (a == NULL)
                         return ("");                          return ("");
                 return (o->array[idx]);                  return (a->value);
         }          }
         if (OPTIONS_IS_STYLE(o))          if (OPTIONS_IS_STYLE(o))
                 return (style_tostring(&o->style));                  return (style_tostring(&o->style));

Legend:
Removed from v.1.38  
changed lines
  Added in v.1.39