Annotation of sbbs/src/xpdev/link_list.h, revision 1.1.1.1

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 */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.