/* * * liblx.h: definitions necessary for the liblx package * * * $Revision: 1.2 $ * $Date: 2001/06/25 19:39:00 $ * $Author: hakenes $ * * (C) 1992-2001 Rolf Hakenes , under the GNU GPL. * * liblx is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * liblx is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You may have received a copy of the GNU General Public License * along with liblx; see the file COPYING. If not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. * */ #ifndef LIBLX_H #define LIBLX_H #ifndef NULL #define NULL 0 #endif /* * * list support structures * */ struct NODE { struct NODE *Succ; struct NODE *Pred; char *Name; unsigned short HashKey; }; struct LIST { struct NODE *Head; struct NODE *Tail; char *Name; unsigned long Size; }; /* * * memory managment structures * */ struct MEM_ENTRY { struct MEM_ENTRY *Succ; struct MEM_ENTRY *Pred; unsigned long Size; }; struct MEM_CHUNK { struct MEM_CHUNK *Succ; struct MEM_CHUNK *Pred; unsigned long Size; struct MEM_ENTRY *FirstFreeMemEntry; struct MEM_ENTRY *FirstUsedMemEntry; }; #ifdef __cplusplus extern "C" { #endif /* * * list functions (package xList) * */ unsigned short xHashKey (char *); struct LIST *xNewList (char *); struct NODE *xNewNode (char *, unsigned long); struct NODE *xFindName (struct LIST *, char *); /* * * memory management * */ void xMemAllo (unsigned long, unsigned char **); void xMemFre (unsigned char *); void xMemFreeAll (struct MEM_CHUNK **); void xMemMerge (struct MEM_CHUNK **); struct MEM_CHUNK **xGetRemember (void); void xSetRemember (struct MEM_CHUNK **); void xPrintMemList (struct MEM_CHUNK **); unsigned long xGetMemSize (struct MEM_CHUNK **); extern unsigned long xAllocatedMemory; char *xSetText (char *); #ifdef __cplusplus } #endif #define MEM_CHUNK_SIZE 65536 #define xMemAlloc(size, ptr) \ xMemAllo (((unsigned long)((size))), ((unsigned char **)((ptr)))) #define xMemFree(ptr) xMemFre (((unsigned char *)((ptr)))) /* * * list support macros * */ /*---------------------------------------------------------------------* | | | xCreateNode (NodeStruct,Name) allocates a correctly sized and | | typed node struct. | | | *---------------------------------------------------------------------*/ #define xCreateNode(NodeStruct,Name) \ (NodeStruct) = (void *) xNewNode(Name, sizeof(*(NodeStruct))) /*---------------------------------------------------------------------* | | | xSize (List) scans for the ->Size field of a list struct | | | *---------------------------------------------------------------------*/ #define xSize(List) ((List) ? ((struct LIST *)(List))->Size : 0) /*---------------------------------------------------------------------* | | | xName (NodeStruct) scans for the ->Node.Name of a node struct | | | *---------------------------------------------------------------------*/ #define xName(NodeStruct) (((struct NODE *)(NodeStruct))->Name) /*---------------------------------------------------------------------* | | | xSucc (NodeStruct) scans for the ->Node.Succ of a node struct | | | *---------------------------------------------------------------------*/ #define xSucc(NodeStruct) (((struct NODE *)(NodeStruct))->Succ) /*---------------------------------------------------------------------* | | | xPred (NodeStruct) scans for the ->Node.Pred of a node struct | | | *---------------------------------------------------------------------*/ #define xPred(NodeStruct) (((struct NODE *)(NodeStruct))->Pred) /*---------------------------------------------------------------------* | | | xForeach(List,NodeStruct) builds a loop to process each list | | element. | | | *---------------------------------------------------------------------*/ #define xForeach(List,NodeStruct) \ if (List) for ((NodeStruct) = (void *) ((struct LIST *)(List))->Head; \ (NodeStruct); (NodeStruct) = (void *) xSucc (NodeStruct)) /*---------------------------------------------------------------------* | | | xForeachReverse(List,NodeStruct) builds a loop to process each | | element in reverse order. | | | *---------------------------------------------------------------------*/ #define xForeachReverse(List,NodeStruct) \ if (List) for ((NodeStruct) = (void *) ((struct LIST *)(List))->Tail; \ NodeStruct; (NodeStruct) = (void *) xPred (NodeStruct)) /*---------------------------------------------------------------------* | | | xRemove(List,NodeStruct) unchains a node struct out of a list. | | | *---------------------------------------------------------------------*/ #define xRemove(List,NodeStruct) \ do \ { \ struct NODE *TmpNode; \ struct LIST *TmpList; \ \ TmpNode = ((struct NODE *)(NodeStruct)); \ TmpList = ((struct LIST *)(List)); \ \ if (TmpNode->Pred) \ (TmpNode->Pred)->Succ = TmpNode->Succ; \ else TmpList->Head = TmpNode->Succ; \ if (TmpNode->Succ) \ (TmpNode->Succ)->Pred = TmpNode->Pred; \ else TmpList->Tail = TmpNode->Pred; \ TmpList->Size --; \ } while (0) /************************************************************************* * * * function : xAddHead * * * * arguments : List - pointer to a LIST structure * * * * Node - pointer to a NODE structure * * * *-----------------------------------------------------------------------* * * * xAddHead() inserts 'Node' at the head of 'List'. * * * *************************************************************************/ #define xAddHead(List, NodeStruct) \ do { \ struct NODE *TmpNode; \ struct LIST *TmpList; \ \ TmpNode = ((struct NODE *)(NodeStruct)); \ TmpList = ((struct LIST *)(List)); \ \ if (TmpList->Head) { \ TmpNode->Pred = NULL; \ TmpNode->Succ = TmpList->Head; \ (TmpList->Head)->Pred = TmpNode; \ TmpList->Head = TmpNode; } \ else { \ TmpList->Head = TmpNode; \ TmpList->Tail = TmpNode; \ TmpNode->Pred = NULL; \ TmpNode->Succ = NULL; } \ TmpList->Size++; \ } while (0) /************************************************************************* * * * function : xAddTail * * * * arguments : List - pointer to a LIST structure * * * * Node - pointer to a NODE structure * * * *-----------------------------------------------------------------------* * * * xAddTail() inserts 'Node' at the tail of 'List'. * * * *************************************************************************/ #define xAddTail(List, NodeStruct) \ do { \ struct NODE *TmpNode; \ struct LIST *TmpList; \ \ TmpNode = ((struct NODE *)(NodeStruct)); \ TmpList = ((struct LIST *)(List)); \ \ if (TmpList->Head) { \ TmpNode->Succ = NULL; \ TmpNode->Pred = TmpList->Tail; \ (TmpList->Tail)->Succ = TmpNode; \ TmpList->Tail = TmpNode; } \ else { \ TmpList->Head = TmpNode; \ TmpList->Tail = TmpNode; \ TmpNode->Pred = NULL; \ TmpNode->Succ = NULL; } \ TmpList->Size++; \ } while (0) /************************************************************************* * * * function : xRemHead * * * * arguments : List - pointer to a LIST structure * * * *-----------------------------------------------------------------------* * * * xRemHead() removes a Node from head of 'List'. * * * *************************************************************************/ #define xRemHead(List) \ do { \ struct LIST *TmpList; \ \ TmpList = ((struct LIST *)(List)); \ \ if (TmpList->Head) \ { \ TmpList->Head = (TmpList->Head)->Succ; \ if (TmpList->Head) (TmpList->Head)->Pred = NULL; \ else TmpList->Tail = NULL; \ TmpList->Size--; \ } \ } while (0) /************************************************************************* * * * function : xRemTail * * * * arguments : List - pointer to a LIST structure * * * *-----------------------------------------------------------------------* * * * xRemTail() removes a Node from the tail of 'List'. * * * *************************************************************************/ #define xRemTail(List) \ do { \ struct LIST *TmpList; \ \ TmpList = ((struct LIST *)(List)); \ \ if (TmpList->Tail) \ { \ TmpList->Tail = (TmpList->Tail)->Pred; \ if (TmpList->Tail) (TmpList->Tail)->Succ = NULL; \ else TmpList->Head = NULL; \ TmpList->Size--; \ } \ } while (0) /************************************************************************* * * * function : xConCat * * * * arguments : DestinationList - pointer to the destination * * LIST structure * * * * SourceList - pointer to the source LIST structure * * * *-----------------------------------------------------------------------* * * * xConCat() concats 'SourceList' with 'DestinationList' and clears * * 'SourceList'. * * * *************************************************************************/ #define xConCat(DestinationList, SourceList) \ do { \ struct LIST *SrcList; \ struct LIST *DstList; \ \ SrcList = ((struct LIST *)(SourceList)); \ DstList = ((struct LIST *)(DestinationList)); \ \ if (DstList && SrcList) \ { \ if (DstList->Head) { \ if (SrcList->Head) { \ (DstList->Tail)->Succ = SrcList->Head; \ (SrcList->Head)->Pred = DstList->Tail; \ DstList->Tail = SrcList->Tail; \ DstList->Size += SrcList->Size; \ SrcList->Size = 0; \ SrcList->Head = NULL; \ SrcList->Tail = NULL; } } \ else { \ DstList->Head = SrcList->Head; \ DstList->Tail = SrcList->Tail; \ DstList->Size += SrcList->Size; \ SrcList->Size = 0; \ SrcList->Head = NULL; \ SrcList->Tail = NULL; } \ } \ else if (SrcList) ((struct LIST *)(DestinationList)) = SrcList; \ } while (0) #define xJoinList(SourceList, DestinationList, NodeStruct) \ do { \ struct NODE *KeyNode; \ struct NODE *TmpNode; \ struct LIST *SrcList; \ struct LIST *DstList; \ \ KeyNode = ((struct NODE *)(NodeStruct)); \ SrcList = ((struct LIST *)(SourceList)); \ DstList = ((struct LIST *)(DestinationList)); \ \ if (SrcList->Head) \ { \ TmpNode = KeyNode->Succ; \ KeyNode->Succ = SrcList->Head; \ SrcList->Tail->Succ = TmpNode; \ SrcList->Head->Pred = KeyNode; \ if (!TmpNode) DstList->Tail = SrcList->Tail; \ else TmpNode->Pred = SrcList->Tail; \ DstList->Size += SrcList->Size; \ SrcList->Size = 0; \ SrcList->Head = NULL; \ SrcList->Tail = NULL; \ } \ } while (0) #define xJoin(SourceNode, DestinationList, NodeStruct) \ do { \ struct NODE *KeyNode; \ struct NODE *TmpNode; \ struct NODE *SrcNode; \ struct LIST *DstList; \ \ KeyNode = ((struct NODE *)(NodeStruct)); \ SrcNode = ((struct NODE *)(SourceNode)); \ DstList = ((struct LIST *)(DestinationList)); \ \ if (SrcNode) \ { \ TmpNode = KeyNode->Succ; \ KeyNode->Succ = SrcNode; \ SrcNode->Succ = TmpNode; \ SrcNode->Pred = KeyNode; \ if (!TmpNode) DstList->Tail = SrcNode; \ else TmpNode->Pred = SrcNode; \ DstList->Size += 1; \ } \ } while (0) #define xClearList(SrcList) \ do { \ (SrcList)->Size = 0; \ (SrcList)->Head = NULL; \ (SrcList)->Tail = NULL; \ } while (0) #define xSetName(nodestruct, name) \ do { \ struct NODE *TmpNode; \ \ TmpNode = (struct NODE *) (nodestruct); \ \ TmpNode->Name = xSetText (name); \ TmpNode->HashKey = xHashKey (name); \ } while (0) #endif