1/* $Id: genlist.c,v 1.2 2004/07/12 20:43:50 ludvigm Exp $ */ 2 3/* 4 * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. 5 * Contributed by: Michal Ludvig <mludvig@suse.cz>, SUSE Labs 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33#include <stdio.h> 34#include <stdlib.h> 35#include <sys/queue.h> 36 37#include "genlist.h" 38 39struct genlist * 40genlist_init (void) 41{ 42 struct genlist *new = calloc(sizeof(struct genlist), 1); 43 TAILQ_INIT(new); 44 return new; 45} 46 47struct genlist_entry * 48genlist_insert (struct genlist *head, void *data) 49{ 50 struct genlist_entry *entry = calloc(sizeof(struct genlist_entry), 1); 51 entry->data = data; 52 TAILQ_INSERT_HEAD(head, entry, chain); 53 return entry; 54} 55 56struct genlist_entry * 57genlist_append (struct genlist *head, void *data) 58{ 59 struct genlist_entry *entry = calloc(sizeof(struct genlist_entry), 1); 60 entry->data = data; 61 TAILQ_INSERT_TAIL(head, entry, chain); 62 return entry; 63} 64 65void * 66genlist_foreach (struct genlist *head, genlist_func_t func, void *arg) 67{ 68 struct genlist_entry *p; 69 void *ret = NULL; 70 TAILQ_FOREACH(p, head, chain) { 71 ret = (*func)(p->data, arg); 72 if (ret) 73 break; 74 } 75 76 return ret; 77} 78 79void * 80genlist_next (struct genlist *head, struct genlist_entry **buf) 81{ 82 struct genlist_entry *p; 83 84 if (head) 85 p = TAILQ_FIRST(head); 86 else 87 p = (buf && *buf) ? TAILQ_NEXT(*buf, chain) : NULL; 88 if (buf) 89 *buf = p; 90 return (p ? p->data : NULL); 91} 92 93void 94genlist_free (struct genlist *head, genlist_freedata_t func) 95{ 96 struct genlist_entry *p; 97 98 while ((p = TAILQ_LAST(head, genlist)) != NULL) { 99 TAILQ_REMOVE(head, p, chain); 100 if (func) 101 func(p->data); 102 free(p); 103 } 104 free(head); 105} 106 107 108#if 0 109/* Here comes the example... */ 110struct conf { 111 struct genlist *l1, *l2; 112}; 113 114void * 115print_entry(void *entry, void *arg) 116{ 117 if (!entry) 118 return NULL; 119 printf("%s\n", (char *)entry); 120 return NULL; 121} 122 123void 124dump_list(struct genlist *head) 125{ 126 genlist_foreach(head, print_entry, NULL); 127} 128 129void 130free_data(void *data) 131{ 132 printf ("removing %s\n", (char *)data); 133} 134 135int main() 136{ 137 struct conf *cf; 138 char *cp; 139 struct genlist_entry *gpb; 140 141 cf = calloc(sizeof(struct conf), 1); 142 cf->l1 = genlist_init(); 143 cf->l2 = genlist_init(); 144 145 genlist_insert(cf->l1, "Ahoj"); 146 genlist_insert(cf->l1, "Cau"); 147 genlist_insert(cf->l1, "Nazdar"); 148 genlist_insert(cf->l1, "Te buch"); 149 150 genlist_append(cf->l2, "Curak"); 151 genlist_append(cf->l2, "Kozy"); 152 genlist_append(cf->l2, "Pica"); 153 genlist_append(cf->l2, "Prdel"); 154 155 printf("List 2\n"); 156 dump_list(cf->l2); 157 printf("\nList 1\n"); 158 dump_list(cf->l1); 159 160 printf("\nList 2 - using genlist_next()\n"); 161 for (cp = genlist_next (cf->l2, &gpb); cp; cp = genlist_next (0, &gpb)) 162 printf("%s\n", cp); 163 164 printf("\nFreeing List 1\n"); 165 /* the data here isn't actually alloc'd so we would really call 166 * genlist_free (cf->l1, 0); but to illustrate the idea */ 167 genlist_free (cf->l1, free_data); 168 cf->l1 = 0; 169 170 return 0; 171} 172#endif 173