|
|
1.1 root 1: /* link_list.h */
2:
3: /* Double-Linked-list library */
4:
5: /* $Id: link_list.h,v 1.21 2006/04/01 02:19:46 rswindell Exp $ */
6:
7: /****************************************************************************
8: * @format.tab-size 4 (Plain Text/Source Code File Header) *
9: * @format.use-tabs true (see http://www.synchro.net/ptsc_hdr.html) *
10: * *
11: * Copyright 2006 Rob Swindell - http://www.synchro.net/copyright.html *
12: * *
13: * This library is free software; you can redistribute it and/or *
14: * modify it under the terms of the GNU Lesser General Public License *
15: * as published by the Free Software Foundation; either version 2 *
16: * of the License, or (at your option) any later version. *
17: * See the GNU Lesser General Public License for more details: lgpl.txt or *
18: * http://www.fsf.org/copyleft/lesser.html *
19: * *
20: * Anonymous FTP access to the most recent released source is available at *
21: * ftp://vert.synchro.net, ftp://cvs.synchro.net and ftp://ftp.synchro.net *
22: * *
23: * Anonymous CVS access to the development source and modification history *
24: * is available at cvs.synchro.net:/cvsroot/sbbs, example: *
25: * cvs -d :pserver:[email protected]:/cvsroot/sbbs login *
26: * (just hit return, no password is necessary) *
27: * cvs -d :pserver:[email protected]:/cvsroot/sbbs checkout src *
28: * *
29: * For Synchronet coding style and modification guidelines, see *
30: * http://www.synchro.net/source.html *
31: * *
32: * You are encouraged to submit any modifications (preferably in Unix diff *
33: * format) via e-mail to [email protected] *
34: * *
35: * Note: If this box doesn't appear square, then you need to fix your tabs. *
36: ****************************************************************************/
37:
38: #ifndef _LINK_LIST_H
39: #define _LINK_LIST_H
40:
41: #include <stddef.h> /* size_t */
42: #include "wrapdll.h"
43: #include "str_list.h" /* string list functions and types */
44:
45: #if defined(LINK_LIST_THREADSAFE)
46: #include "threadwrap.h" /* mutexes */
47: #include "semwrap.h" /* semaphores */
48: #endif
49:
50: #if defined(__cplusplus)
51: extern "C" {
52: #endif
53:
54: #define FIRST_NODE ((list_node_t*)NULL) /* Special value to specify first node in list */
55: #define LAST_NODE ((list_node_t*)-1) /* Special value to specify last node in list */
56:
57: /* Valid link_list_t.flags bits */
58: #define LINK_LIST_MALLOC (1<<0) /* List/node allocated with malloc() */
59: #define LINK_LIST_ALWAYS_FREE (1<<1) /* ALWAYS free node data in listFreeNodes() */
60: #define LINK_LIST_NEVER_FREE (1<<2) /* NEVER free node data (careful of memory leaks!) */
61: #define LINK_LIST_MUTEX (1<<3) /* Mutex-protected linked-list */
62: #define LINK_LIST_SEMAPHORE (1<<4) /* Semaphore attached to linked-list */
63: #define LINK_LIST_NODE_LOCKED (1<<5) /* Node is locked */
64: #define LINK_LIST_ATTACH (1<<6) /* Attach during init */
65:
66: typedef struct list_node {
67: void* data; /* pointer to some kind of data */
68: struct list_node* next; /* next node in list (or NULL) */
69: struct list_node* prev; /* previous node in list (or NULL) */
70: struct link_list* list;
71: unsigned long flags; /* private use flags */
72: } list_node_t;
73:
74: typedef struct link_list {
75: list_node_t* first; /* first node in list (or NULL) */
76: list_node_t* last; /* last node in list (or NULL) */
77: unsigned long flags; /* private use flags */
78: long count; /* number of nodes in list */
79: void* private_data; /* for use by the application only */
80: long refs; /* reference counter (attached clients) */
81: #if defined(LINK_LIST_THREADSAFE)
82: pthread_mutex_t mutex;
83: sem_t sem;
84: #endif
85: } link_list_t;
86:
87: /* Initialization, Allocation, and Freeing of Lists and Nodes */
88: DLLEXPORT link_list_t* DLLCALL listInit(link_list_t* /* NULL to auto-allocate */, long flags);
89: DLLEXPORT BOOL DLLCALL listFree(link_list_t*);
90: DLLEXPORT long DLLCALL listFreeNodes(link_list_t*);
91: DLLEXPORT BOOL DLLCALL listFreeNodeData(list_node_t* node);
92:
93: /* Increment/decrement reference counter (and auto-free when zero), returns -1 on error */
94: DLLEXPORT long DLLCALL listAttach(link_list_t*);
95: DLLEXPORT long DLLCALL listDetach(link_list_t*);
96:
97: #if defined(LINK_LIST_THREADSAFE)
98: DLLEXPORT BOOL DLLCALL listSemPost(link_list_t*);
99: DLLEXPORT BOOL DLLCALL listSemWait(link_list_t*);
100: DLLEXPORT BOOL DLLCALL listSemTryWait(link_list_t*);
101: DLLEXPORT BOOL DLLCALL listSemTryWaitBlock(link_list_t*, unsigned long timeout);
102: #endif
103:
104: /* Lock/unlock mutex-protected linked lists (no-op for unprotected lists) */
105: DLLEXPORT void DLLCALL listLock(const link_list_t*);
106: DLLEXPORT void DLLCALL listUnlock(const link_list_t*);
107:
108: /* Return count or index of nodes, or -1 on error */
109: DLLEXPORT long DLLCALL listCountNodes(const link_list_t*);
110: DLLEXPORT long DLLCALL listNodeIndex(const link_list_t*, list_node_t*);
111:
112: /* Get/Set list private data */
113: DLLEXPORT void* DLLCALL listSetPrivateData(link_list_t*, void*);
114: DLLEXPORT void* DLLCALL listGetPrivateData(link_list_t*);
115:
116: /* Return an allocated string list (which must be freed), array of all strings in linked list */
117: DLLEXPORT str_list_t DLLCALL listStringList(const link_list_t*);
118:
119: /* Return an allocated string list (which must be freed), subset of strings in linked list */
120: DLLEXPORT str_list_t DLLCALL listSubStringList(const list_node_t*, long max);
121:
122: /* Free a string list returned from either of the above functions */
123: DLLEXPORT void* DLLCALL listFreeStringList(str_list_t);
124:
125: /* Extract subset (up to max number of nodes) in linked list (src_node) and place into dest_list */
126: /* dest_list == NULL, then allocate a return a new linked list */
127: DLLEXPORT link_list_t* DLLCALL listExtract(link_list_t* dest_list, const list_node_t* src_node, long max);
128:
129: /* Simple search functions returning found node or NULL on error */
130: DLLEXPORT list_node_t* DLLCALL listNodeAt(const link_list_t*, long index);
131: DLLEXPORT list_node_t* DLLCALL listFindNode(const link_list_t*, const void* data, size_t length);
132:
133: /* Convenience functions */
134: DLLEXPORT list_node_t* DLLCALL listFirstNode(const link_list_t*);
135: DLLEXPORT list_node_t* DLLCALL listLastNode(const link_list_t*);
136: DLLEXPORT list_node_t* DLLCALL listNextNode(const list_node_t*);
137: DLLEXPORT list_node_t* DLLCALL listPrevNode(const list_node_t*);
138: DLLEXPORT void* DLLCALL listNodeData(const list_node_t*);
139:
140: /* Primitive node locking */
141: DLLEXPORT BOOL DLLCALL listLockNode(list_node_t*);
142: DLLEXPORT BOOL DLLCALL listUnlockNode(list_node_t*);
143: DLLEXPORT BOOL DLLCALL listNodeIsLocked(const list_node_t*);
144:
145: /* Add node to list, returns pointer to new node or NULL on error */
146: DLLEXPORT list_node_t* DLLCALL listAddNode(link_list_t*, void* data, list_node_t* after /* NULL=insert */);
147:
148: /* Add array of node data to list, returns number of nodes added (or negative on error) */
149: DLLEXPORT long DLLCALL listAddNodes(link_list_t*, void** data, list_node_t* after /* NULL=insert */);
150:
151: /* Add node to list, allocating and copying the data for the node */
152: DLLEXPORT list_node_t* DLLCALL listAddNodeData(link_list_t*, const void* data, size_t length, list_node_t* after);
153:
154: /* Add node to list, allocating and copying ASCIIZ string data */
155: DLLEXPORT list_node_t* DLLCALL listAddNodeString(link_list_t*, const char* str, list_node_t* after);
156:
157: /* Add a list of strings to the linked list, allocating and copying each */
158: DLLEXPORT long DLLCALL listAddStringList(link_list_t*, str_list_t, list_node_t* after);
159:
160: /* Add a list of nodes from a source linked list */
161: DLLEXPORT long DLLCALL listAddNodeList(link_list_t*, const link_list_t* src, list_node_t* after);
162:
163: /* Merge a source linked list into the destination linked list */
164: /* after merging, the nodes in the source linked list should not be modified or freed */
165: DLLEXPORT long DLLCALL listMerge(link_list_t* dest, const link_list_t* src, list_node_t* after);
166:
167: /* Swap the data pointers and flags for 2 nodes (possibly in separate lists) */
168: DLLEXPORT BOOL DLLCALL listSwapNodes(list_node_t* node1, list_node_t* node2);
169:
170: /* Convenience macros for pushing, popping, and inserting nodes */
171: #define listPushNode(list, data) listAddNode(list, data, LAST_NODE)
172: #define listInsertNode(list, data) listAddNode(list, data, FIRST_NODE)
173: #define listPushNodeData(list, data, length) listAddNodeData(list, data, length, LAST_NODE)
174: #define listInsertNodeData(list, data, length) listAddNodeData(list, data, length, FIRST_NODE)
175: #define listPushNodeString(list, str) listAddNodeString(list, str, LAST_NODE)
176: #define listInsertNodeString(list, str) listAddNodeString(list, str, FIRST_NODE)
177: #define listPushStringList(list, str_list) listAddStringList(list, str_list, LAST_NODE)
178: #define listInsertStringList(list, str_list) listAddStringList(list, str_list, FIRST_NODE)
179: #define listPopNode(list) listRemoveNode(list, LAST_NODE, FALSE)
180: #define listShiftNode(list) listRemoveNode(list, FIRST_NODE, FALSE)
181:
182: /* Remove node from list, returning the node's data (if not free'd) */
183: DLLEXPORT void* DLLCALL listRemoveNode(link_list_t*, list_node_t* /* NULL=first */, BOOL free_data);
184:
185: /* Remove multiple nodes from list, returning the number of nodes removed */
186: DLLEXPORT long DLLCALL listRemoveNodes(link_list_t*, list_node_t* /* NULL=first */, long count, BOOL free_data);
187:
188: #if defined(__cplusplus)
189: }
190: #endif
191:
192: #endif /* Don't add anything after this line */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.