|
|
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.