Annotation of sbbs/src/xpdev/link_list.h, revision 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.