从DNS服务器应用极广的BIND9.9.2 中提取的双向链表,可以用于自己的程序,也可以用来理解BIND
2012-12-21 17:34
357 查看
有三个文件list.h, boolean.h和main.c
------list.h ---------
----boolean.h------
-----main.c-----
------list.h ---------
/* * Copyright (C) 2004, 2006, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1997-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id$ */ #ifndef ISC_LIST_H #define ISC_LIST_H 1 #include "boolean.h" #ifdef ISC_LIST_CHECKINIT #define ISC_LINK_INSIST(x) ISC_INSIST(x) #else #define ISC_LINK_INSIST(x) #define ISC_INSIST #endif #define ISC_LIST(type) struct { type *head, *tail; } #define ISC_LIST_INIT(list) \ do { (list).head = NULL; (list).tail = NULL; } while (0) #define ISC_LINK(type) struct { type *prev, *next; } #define ISC_LINK_INIT_TYPE(elt, link, type) \ do { \ (elt)->link.prev = (type *)(-1); \ (elt)->link.next = (type *)(-1); \ } while (0) #define ISC_LINK_INIT(elt, link) \ ISC_LINK_INIT_TYPE(elt, link, void) #define ISC_LINK_LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1)) #define ISC_LIST_HEAD(list) ((list).head) #define ISC_LIST_TAIL(list) ((list).tail) #define ISC_LIST_EMPTY(list) ISC_TF((list).head == NULL) #define __ISC_LIST_PREPENDUNSAFE(list, elt, link) \ do { \ if ((list).head != NULL) \ (list).head->link.prev = (elt); \ else \ (list).tail = (elt); \ (elt)->link.prev = NULL; \ (elt)->link.next = (list).head; \ (list).head = (elt); \ } while (0) #define ISC_LIST_PREPEND(list, elt, link) \ do { \ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ __ISC_LIST_PREPENDUNSAFE(list, elt, link); \ } while (0) #define ISC_LIST_INITANDPREPEND(list, elt, link) \ __ISC_LIST_PREPENDUNSAFE(list, elt, link) #define __ISC_LIST_APPENDUNSAFE(list, elt, link) \ do { \ if ((list).tail != NULL) \ (list).tail->link.next = (elt); \ else \ (list).head = (elt); \ (elt)->link.prev = (list).tail; \ (elt)->link.next = NULL; \ (list).tail = (elt); \ } while (0) #define ISC_LIST_APPEND(list, elt, link) \ do { \ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ __ISC_LIST_APPENDUNSAFE(list, elt, link); \ } while (0) #define ISC_LIST_INITANDAPPEND(list, elt, link) \ __ISC_LIST_APPENDUNSAFE(list, elt, link) #define __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type) \ do { \ if ((elt)->link.next != NULL) \ (elt)->link.next->link.prev = (elt)->link.prev; \ else { \ ISC_INSIST((list).tail == (elt)); \ (list).tail = (elt)->link.prev; \ } \ if ((elt)->link.prev != NULL) \ (elt)->link.prev->link.next = (elt)->link.next; \ else { \ ISC_INSIST((list).head == (elt)); \ (list).head = (elt)->link.next; \ } \ (elt)->link.prev = (type *)(-1); \ (elt)->link.next = (type *)(-1); \ } while (0) #define __ISC_LIST_UNLINKUNSAFE(list, elt, link) \ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, void) #define ISC_LIST_UNLINK_TYPE(list, elt, link, type) \ do { \ ISC_LINK_INSIST(ISC_LINK_LINKED(elt, link)); \ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type); \ } while (0) #define ISC_LIST_UNLINK(list, elt, link) \ ISC_LIST_UNLINK_TYPE(list, elt, link, void) #define ISC_LIST_PREV(elt, link) ((elt)->link.prev) #define ISC_LIST_NEXT(elt, link) ((elt)->link.next) #define __ISC_LIST_INSERTBEFOREUNSAFE(list, before, elt, link) \ do { \ if ((before)->link.prev == NULL) \ ISC_LIST_PREPEND(list, elt, link); \ else { \ (elt)->link.prev = (before)->link.prev; \ (before)->link.prev = (elt); \ (elt)->link.prev->link.next = (elt); \ (elt)->link.next = (before); \ } \ } while (0) #define ISC_LIST_INSERTBEFORE(list, before, elt, link) \ do { \ ISC_LINK_INSIST(ISC_LINK_LINKED(before, link)); \ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ __ISC_LIST_INSERTBEFOREUNSAFE(list, before, elt, link); \ } while (0) #define __ISC_LIST_INSERTAFTERUNSAFE(list, after, elt, link) \ do { \ if ((after)->link.next == NULL) \ ISC_LIST_APPEND(list, elt, link); \ else { \ (elt)->link.next = (after)->link.next; \ (after)->link.next = (elt); \ (elt)->link.next->link.prev = (elt); \ (elt)->link.prev = (after); \ } \ } while (0) #define ISC_LIST_INSERTAFTER(list, after, elt, link) \ do { \ ISC_LINK_INSIST(ISC_LINK_LINKED(after, link)); \ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \ __ISC_LIST_INSERTAFTERUNSAFE(list, after, elt, link); \ } while (0) #define ISC_LIST_APPENDLIST(list1, list2, link) \ do { \ if (ISC_LIST_EMPTY(list1)) \ (list1) = (list2); \ else if (!ISC_LIST_EMPTY(list2)) { \ (list1).tail->link.next = (list2).head; \ (list2).head->link.prev = (list1).tail; \ (list1).tail = (list2).tail; \ } \ (list2).head = NULL; \ (list2).tail = NULL; \ } while (0) #define ISC_LIST_PREPENDLIST(list1, list2, link) \ do { \ if (ISC_LIST_EMPTY(list1)) \ (list1) = (list2); \ else if (!ISC_LIST_EMPTY(list2)) { \ (list2).tail->link.next = (list1).head; \ (list1).head->link.prev = (list2).tail; \ (list1).head = (list2).head; \ } \ (list2).head = NULL; \ (list2).tail = NULL; \ } while (0) #define ISC_LIST_ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link) #define __ISC_LIST_ENQUEUEUNSAFE(list, elt, link) \ __ISC_LIST_APPENDUNSAFE(list, elt, link) #define ISC_LIST_DEQUEUE(list, elt, link) \ ISC_LIST_UNLINK_TYPE(list, elt, link, void) #define ISC_LIST_DEQUEUE_TYPE(list, elt, link, type) \ ISC_LIST_UNLINK_TYPE(list, elt, link, type) #define __ISC_LIST_DEQUEUEUNSAFE(list, elt, link) \ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, void) #define __ISC_LIST_DEQUEUEUNSAFE_TYPE(list, elt, link, type) \ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type) #endif /* ISC_LIST_H */
----boolean.h------
/* * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /* $Id: boolean.h,v 1.19 2007/06/19 23:47:18 tbox Exp $ */ #ifndef ISC_BOOLEAN_H #define ISC_BOOLEAN_H 1 /*! \file isc/boolean.h */ typedef enum { isc_boolean_false = 0, isc_boolean_true = 1 } isc_boolean_t; #define ISC_FALSE isc_boolean_false #define ISC_TRUE isc_boolean_true #define ISC_TF(x) ((x) ? ISC_TRUE : ISC_FALSE) #endif /* ISC_BOOLEAN_H */
-----main.c-----
#include <stdio.h> #include <stdlib.h> #include "list.h" #define LIST(type) ISC_LIST(type) #define INIT_LIST(type) ISC_LIST_INIT(type) #define LINK(type) ISC_LINK(type) #define INIT_LINK(elt, link) ISC_LINK_INIT(elt, link) #define HEAD(list) ISC_LIST_HEAD(list) #define TAIL(list) ISC_LIST_TAIL(list) #define EMPTY(list) ISC_LIST_EMPTY(list) #define PREV(elt, link) ISC_LIST_PREV(elt, link) #define NEXT(elt, link) ISC_LIST_NEXT(elt, link) #define APPEND(list, elt, link) ISC_LIST_APPEND(list, elt, link) #define PREPEND(list, elt, link) ISC_LIST_PREPEND(list, elt, link) #define UNLINK(list, elt, link) ISC_LIST_UNLINK(list, elt, link) #define ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link) #define DEQUEUE(list, elt, link) ISC_LIST_UNLINK(list, elt, link) #define INSERTBEFORE(li, b, e, ln) ISC_LIST_INSERTBEFORE(li, b, e, ln) #define INSERTAFTER(li, a, e, ln) ISC_LIST_INSERTAFTER(li, a, e, ln) #define APPENDLIST(list1, list2, link) ISC_LIST_APPENDLIST(list1, list2, link) //有两个测试,均验证通过 #if 0 typedef struct dns_dbimplementation dns_dbimplementation_t; struct dns_dbimplementation { ISC_LINK(dns_dbimplementation_t) link; const char * name; }; static LIST(dns_dbimplementation_t) implementations; void dump() { dns_dbimplementation_t *imp; for (imp = ISC_LIST_HEAD(implementations); imp != NULL; imp = ISC_LIST_NEXT(imp, link)) { printf("%s\n",imp->name); } } void main() { ISC_LIST_INIT(implementations); dns_dbimplementation_t rbtimp; rbtimp.name = "rbt1"; ISC_LINK_INIT(&rbtimp, link); ISC_LIST_APPEND(implementations.link, &rbtimp, link); dns_dbimplementation_t rbtimp2; rbtimp2.name = "rbt2"; ISC_LINK_INIT(&rbtimp2, link); ISC_LIST_APPEND(implementations, &rbtimp2, link); dump(); ISC_LIST_UNLINK(implementations, &rbtimp2, link); dump(); } #else struct isc__task { char name[16]; LINK(isc__task_t) ready_link; }; typedef struct isc__task isc__task_t; typedef ISC_LIST(isc__task_t) isc__tasklist_t; typedef struct isc__taskmgr isc__taskmgr_t; struct isc__taskmgr { unsigned int workers; isc__tasklist_t ready_tasks; }; /* list可以理解为链表节点的列表,它的元素是链表节点, LINK可以理解为链表的一个节点 */ void main() { isc__taskmgr_t *manager; isc__task_t *task; isc__tasklist_t new_ready_tasks;//list ISC_LIST_INIT(new_ready_tasks);//list ENQUEUE(new_ready_tasks, task, ready_link);// ISC_LIST_APPENDLIST(manager->ready_tasks, new_ready_tasks, ready_link); } #endif
相关文章推荐
- Log4net是.Net 的全部应用(可以用来记录自己的日志中心的日志)
- 写了一个程序用来处理字符串,把一张列表中的题目序号提取出来,然后跟自己昨晚的列表比较,找出来还没有做过的题目列表
- c#动态编译,自己做了个c#脚本管理框架,可以作为其他应用的插件使用。增强程序的拓展性
- 普通管理类程序开发之难度系数、层次之说法,可以看看自己停留在哪个层次,不足之处,请大家一起补充
- 今天就教大家查看手机的内存使用情况,可以帮你查看自己的程序占用了多大的内存(图文说明)
- 有了这些免费无限次的API 接口,再也不愁没有服务器开发不了APP了,也可以自己开发小程序了
- Android模拟内存紧张,应用被杀死如何模拟应用程序被杀掉? 更新:Daniel Lew指出,最简单的方法是在DDMS中点击”Stop Porcess”杀掉你的程序,在你调试程序的时候可以这样做。
- 链表实现的堆栈程序(仅供自己学习使用)
- 自己写的链表倒置和链表排列程序
- Java与数据库的结合,应用实例。以学生表、选课表为例。可以自己扩展功能。
- 自己的程序编程变成windows可以运行的.exe文件----py2exe
- NET简单的一个画图程序 使用简单 自己可以相关自己的内容进行配置就可以使用了
- 使用野狗做后端,开发微信小程序不需要后端工程师,前端自己就可以搞定了
- 想在自己的android应用中获得当天的天气情况,这该怎么做呢?不用担心。中国国家气象局提供了获取所在城市天气预报信息接口。通过这个接口,我们就可以获取天气信息了。
- Struts 2.x仍然明显落后于时代。 Struts 2.x这一类老牌Web MVC开发框架仅能用于开发瘦客户端应用,无法用来开发对于交互体验要求更高的应用。
- C++ 标准模板库STL 双向链表 list 使用方法与应用介绍(一)
- 一个用于练习链表的“跳马”程序
- 理解Linux环境变量及配置文件执行顺序 博客分类: Linux 每个用户都有自己专属的运行环境,这个环境是由一组变量所定义,这些变量称之为环境变量。用户可以修改环境变量以满足自己的要求。
- 自己写的基于MFC对话框的用于调试程序的UDP客户端服务器端程序
- C# 创建、部署和调用WebService的简单示例 webservice 可以用于分布式应用程序之间的交互,和不同程序之间的交互。 概念性的东西就不说太多,下面开始创建一个简单的webservi