plist.c
Go to the documentation of this file.
00001 #include "../stdafx.h"
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <assert.h>
00005 #include "plist.h"
00006 
00007 /*
00008  * A plist is a double-linked list of key-value pairs
00009  * It can be circular or not.
00010  */
00011 
00012 /*
00013  * This is a node in a plist
00014  */
00015 struct plist_node {
00016         void *pn_key;
00017         void *pn_value;
00018         struct plist_node *pn_next;
00019         struct plist_node *pn_prev;
00020 };
00021 
00022 /*
00023  * Adds a new entry into a plist.
00024  * if !*root it creates a node where prev and next point to itself
00025  * else, inserts itself in the list before *root
00026  * returns 1 on success, 0 on NOMEM failure.
00027  */
00028 int
00029 plist_add(void *k, void *v, plist_node_t **root)
00030 {
00031         plist_node_t *n;
00032 
00033         if (!(n = malloc(sizeof (*n))))
00034                 return 0;
00035         n->pn_key = k;
00036         n->pn_value = v;
00037         if (!*root) {
00038                 n->pn_next = n;
00039                 n->pn_prev = n;
00040                 *root = n;
00041         } else {
00042                 n->pn_prev = (*root)->pn_prev;
00043                 n->pn_next = (*root);
00044                 (*root)->pn_prev->pn_next = n;
00045                 (*root)->pn_prev = n;
00046         }
00047         return 1;
00048 }
00049 
00050 /*
00051  * traverse list until cur == *root or cur == 0, freeing each node
00052  * (list could be either circular or not)
00053  * note that the key and value pointers are still valid.
00054  */
00055 void
00056 plist_clear(plist_node_t **root)
00057 {
00058         plist_node_t *cur;
00059         plist_node_t *fr;
00060 
00061         cur = *root;
00062         while (cur) {
00063                 fr = cur;
00064                 cur = cur->pn_next;
00065                 free(fr); fr = NULL;
00066                 if (cur == *root) {
00067                         *root = NULL;
00068                         return;
00069                 }
00070         }
00071 }
00072 
00073 /*
00074  * removes a node from a plist where the key pointer == k
00075  * if ov is not null, it will point to the old value from the removed node
00076  * This only removes the 1st occurance of k.
00077  * returns 1 on success, 0 if k was not in the list
00078  */
00079 int
00080 plist_remove(void *k, plist_node_t **rootp, void **ov)
00081 {
00082         plist_node_t *cur;
00083 
00084         cur = *rootp;
00085         while (cur) {
00086                 if (cur->pn_key == k) {
00087                         if (ov)
00088                                 *ov = cur->pn_value;
00089                         cur->pn_prev->pn_next = cur->pn_next;
00090                         cur->pn_next->pn_prev = cur->pn_prev;
00091                         if (cur->pn_next == cur)
00092                                 *rootp = NULL;
00093                         else if (*rootp == cur)
00094                                 *rootp = cur->pn_next;
00095                         free(cur); cur = NULL;
00096                         return 1;
00097                 }
00098                 cur = cur->pn_next;
00099                 if (cur == *rootp)
00100                         return 0;
00101         }
00102         return 0;
00103 }
00104 
00105 /*
00106  * finds k in plist.
00107  * if ov != 0, it will be set to the value pointer
00108  * returns 1 when the key is found, 0 if not found.
00109  */
00110 int
00111 plist_contains(void *k, plist_node_t *root, void **ov)
00112 {
00113         plist_node_t *cur;
00114 
00115         cur = root;
00116         while (cur) {
00117                 if (cur->pn_key == k) {
00118                         if (ov)
00119                                 *ov = cur->pn_value;
00120                         return 1;
00121                 }
00122                 cur = cur->pn_next;
00123                 if (cur == root)
00124                         return 0;
00125         }
00126         return 0;
00127 }
00128 
00129 /*
00130  * traverses the plist from start, until we get back to start or next==0
00131  * runs func with key, val, arg.
00132  * if func returns 0, stops traversing and returns 0
00133  * else returns 1 for success
00134  */
00135 int
00136 plist_walk(plist_node_t *start, int (*func)(const void *k, const void *v,
00137     void *arg), void *arg)
00138 {
00139         plist_node_t *cur;
00140         int res;
00141 
00142         cur = start;
00143         while (cur) {
00144                 if (!(res = func(cur->pn_key, cur->pn_value, arg)))
00145                         return res;
00146                 cur = cur->pn_next;
00147                 if (cur == start)
00148                         return 1;
00149         }
00150         return 1;
00151 }


pedal_monitor
Author(s): Pedro Mendes
autogenerated on Fri Jun 6 2014 18:37:21