All pastes #466662 Raw Edit

Miscellany

public c v1 · immutable
·published 2007-05-01 03:12 UTC
rendered paste body
/* Modifies dst, but never the actual dst pointer */void tconfig_merge(struct tconfig_block *src, struct tconfig_block *dst){  struct tconfig_block *tmp;  int depth      = 0;  /* We want to start at the initial positions and traverse down from    * there, copying the keys and values and subkeys maintaining current   * order if it already exists.   */  if (src == NULL || dst == NULL)    return;  while (src != NULL)  {          if (src->child != NULL)    {      /* Do wildcards recursively, I only figure it will       * get a few levels in depth       */      if ((src->value != NULL) && !strcmp(src->value,"*"))      {        /* The trick is to loop through the current depth         * matching the key to the wildcard's key, if so,         * and call this function after going to child of each         * making them both in the toplevel during the merge         */        tmp = dst;        while (tmp->prev != NULL) tmp = tmp->prev;                while (tmp != NULL)        {          if (tmp->key != NULL)          {            if (!strcmp(src->key,tmp->key))            {              if (tmp->child == NULL)              {                tmp->child         = tmalloc(sizeof(struct tconfig_block));                tmp->child->parent = tmp;                tmp                = tmp->child;                tmp->key           = NULL;                tmp->value         = NULL;                tmp->prev          = NULL;                tmp->next          = NULL;                tmp->child         = NULL;                tmp                = tmp->parent; /* Return back to the parent */              }               tconfig_merge(src->child,tmp->child);            }          }           tmp = tmp->next;        }         src = src->next;        continue;      }      tmp = dst;      /* Make sure it's at the beginning */      while (tmp->prev != NULL) tmp = tmp->prev;      while (tmp != NULL)      {        if (tmp->key != NULL)        {          if (!strcmp(src->key,tmp->key) && !strcmp(src->value,tmp->value))          {            /* It's a match, merely attach to it */            dst = tmp->child;            break;          }        }        tmp = tmp->next;      }      if (tmp == NULL)      {        /* No matches, create they key/value parent node */        while (dst->next != NULL && dst->key != NULL) dst = dst->next;                if (dst->key != NULL)        {          dst->next = tmalloc(sizeof(struct tconfig_block));                  dst->next->prev    = dst;           dst->next->next    = NULL;          dst                = dst->next;        }               dst->key           = tstrdup(src->key);        dst->value         = tstrdup(src->value);        dst->parent        = NULL;        dst->child         = tmalloc(sizeof(struct tconfig_block));        dst->child->parent = dst;        dst                = dst->child;                dst->key           = NULL;        dst->value         = NULL;        dst->child         = NULL;        dst->prev          = NULL;        dst->next          = NULL;      }       depth++;      src = src->child;      continue;    }    tmp = dst;    /* Make sure it's at the beginning */    while (tmp->prev != NULL) tmp = tmp->prev;    while (tmp != NULL)    {      if (tmp->key != NULL)      {        /* No Duplicate keys on merge unless prepended with @ */        if (!strcmp(src->key,tmp->key) && src->key[0] != '@')        {          /* Ignore dupes */          break;        }      }      tmp = tmp->next;    }    if (tmp == NULL)    {      /* go to the end of the list */      while (dst->next != NULL && dst->key != NULL) dst = dst->next;      if (dst->key != NULL)      {        dst->next       = tmalloc(sizeof(struct tconfig_block));        dst->next->prev = dst;        dst             = dst->next;        dst->next       = NULL;        dst->parent     = NULL;        dst->child      = NULL;      }      if (src->key[0] == '@')        dst->key      = tstrdup(&src->key[1]);      else        dst->key      = tstrdup(src->key);      dst->value      = tstrdup(src->value);      dst->next       = NULL;    }    while (src->next == NULL)    {      if (depth == 0)        return;      while (src->prev != NULL) src = src->prev;            /* Do the same to dst */      while (dst->prev != NULL) dst = dst->prev;            src = src->parent;      dst = dst->parent;      depth--;     }         src = src->next;  }  }