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