Linked List
#ifndef __LIST_H__ #define __LIST_H__ #include <stdint.h> #define LIST_ITEM_VAR() LIST_ITEM_T item #define LIST_ITEM_PTR(x) LIST_ITEM_T * x #define LIST_ITEM_PAIR(x, y) LIST_ITEM_T * x, * y //#define list_entry(pItem, T) ( (T *)(pItem) ) #define LIST_ITEM_U8_PTR( pItem ) ( (uint8_t *)(pItem) ) #define LIST_ITEM_OFFSET( T, mItem ) ( (uint32_t) ( &( (T *) 0)->mItem) ) #define list_entry(T, pItem ) \ ( (T *) ( LIST_ITEM_U8_PTR( pItem ) - LIST_ITEM_OFFSET( T, item ) ) ) // iterate over a list safe against removal of list entry // // pList : LIST_T // pItem : LIST_ITEM_T < loop counter > // pTempItem : LIST_ITEM_T < temporary storage > // #define list_for_each( pList, pItem, pTemp ) \ for ( pItem = ((pList)->Head).pNext, \ pTemp = pItem->pNext; \ pItem != (& (pList)->Head ); \ pItem = pTemp, pTemp = pItem->pNext ) typedef struct _LIST_ITEM { struct _LIST_ITEM * pNext; struct _LIST_ITEM * pPrev; } LIST_ITEM_T; typedef struct { LIST_ITEM_T Head; uint32_t count; } LIST_T; void list_init( LIST_T * pList ); void list_remove( LIST_T * pList, LIST_ITEM_T * pItem ); void list_insert( LIST_T * pList, LIST_ITEM_T * pItem ); void list_append( LIST_T * pList, LIST_ITEM_T * pItem ); void list_make_first( LIST_T * pList, LIST_ITEM_T * pItem ); void list_make_last( LIST_T * pList, LIST_ITEM_T * pItem ); #endif /* __LIST_H__ */
#include "list.h" void list_item_init( LIST_ITEM_T * pItem ) { pItem->pNext = pItem; pItem->pPrev = pItem; } void list_item_replace( LIST_ITEM_T *pNew, LIST_ITEM_T *pOld ) { pNew->pNext = pOld->pNext; pNew->pNext->pPrev = pNew; pNew->pPrev = pOld->pPrev; pNew->pPrev->pNext = pNew; list_item_init( pOld ); } // Insert a new entry between two known consecutive entries void list_item_add( // LIST_ITEM_T *pItem, LIST_ITEM_T *pPrev, LIST_ITEM_T *pNext ) { pNext->pPrev = pItem; pItem->pNext = pNext; pItem->pPrev = pPrev; pPrev->pNext = pItem; } // Delete a list entry by making the prev/next entries point to each other void list_item_del( LIST_ITEM_T *pPrev, LIST_ITEM_T *pNext ) { pNext->pPrev = pPrev; pPrev->pNext = pNext; } void list_init( LIST_T * pList ) { pList->count = 0; list_item_init( &pList->Head ); } // tests whether a list is empty unsigned int list_empty( LIST_T * pList ) { return ( pList->count == 0 ); // return ( &( pList->Head ).pNext = &( pList->Head ) ); // return ( &( pList->Head ).pPrev = &( pList->Head ) ); } void list_insert( LIST_T * pList, LIST_ITEM_T * pItem ) { list_item_add( pItem, &pList->Head, ( &pList->Head )->pNext ); pList->count++; } void list_append( LIST_T * pList, LIST_ITEM_T * pItem ) { list_item_add( pItem, ( &pList->Head )->pPrev, ( &pList->Head ) ); pList->count++; } // deletes entry from list and reinitialize it void list_remove( LIST_T * pList, LIST_ITEM_T * pItem ) { list_item_del( pItem->pPrev, pItem->pNext ); list_item_init( pItem ); pList->count--; } void list_make_first( LIST_T * pList, LIST_ITEM_T * pItem ) { list_remove( pList, pItem ); list_insert( pList, pItem ); } void list_make_last( LIST_T * pList, LIST_ITEM_T * pItem ) { list_remove( pList, pItem ); list_append( pList, pItem ); } void list_demo_func( int * pi ) { ( *pi )++; } #define ITEM_COUNT ( 4 ) void list_demo( void ) { typedef struct { LIST_ITEM_VAR(); void (*func)( int * pi ); int a; } STRUCT_T; LIST_T list; STRUCT_T items[ ITEM_COUNT ]; STRUCT_T * pStruct; list_init( &list ); // Head <--> Items[0] <--> Items[1] <--> Items[2] <--> Items[3] <--> Head for ( unsigned int i = 0; i < ITEM_COUNT; i++ ) list_append( &list, &items[ i ].item ); unsigned int x = 0; LIST_ITEM_PAIR( pItem, pTemp ); list_for_each( &list, pItem, pTemp) { pStruct = list_entry( STRUCT_T, pItem ); pStruct->a = x++; pStruct->func = list_demo_func; pStruct->func( &pStruct->a ); } // Head <--> Items[0] <--> Items[1] <--> Items[3] <--> Head list_for_each( &list, pItem, pTemp) { pStruct = list_entry( STRUCT_T, pItem ); if ( pStruct->a == 3 ) list_remove( &list, pItem ); } }
#ifndef __LIST_H__ #define __LIST_H__ #include <stdint.h> #define LIST_NODE_HEAD( TAG ) \ typedef struct TAG \ { \ LIST_ITEM_T list_item; #define LIST_NODE_TAIL( NODE ) \ } NODE; typedef struct _LIST_ITEM { struct _LIST_ITEM * pNext; struct _LIST_ITEM * pPrev; } LIST_ITEM_T; typedef struct { LIST_ITEM_T * pHead; uint32_t count; } LIST_T; void list_init( LIST_T * pList ); void list_delete( LIST_T * pList, void * pNode ); void list_insert( LIST_T * pList, void * pNode, uint32_t tail ); void * list_get_head( LIST_T * pList ); void * list_get_next( LIST_T * pList, void * pNode ); #endif /* __LIST_H__ */
#include "list.h" void list_init( LIST_T * pList ) { pList->count = 0; pList->pHead = 0; } void * list_get_head( LIST_T * pList ) { if ( pList->count == 0 ) return 0; return pList->pHead; } void * list_get_next( LIST_T * pList, void * pNode ) { LIST_ITEM_T * pItem = (LIST_ITEM_T *) ( pNode ); if ( pItem->pNext == pList->pHead ) return 0; return pItem->pNext; } void list_insert( LIST_T * pList, void * pNode, uint32_t tail ) { LIST_ITEM_T * pItem = (LIST_ITEM_T *) ( pNode ); if ( pList->count == 0 ) { pItem->pNext = pItem; pItem->pPrev = pItem; } else { pItem->pNext = pList->pHead; pItem->pPrev = pList->pHead->pPrev; pList->pHead->pPrev->pNext = pItem; pList->pHead->pPrev = pItem; } if ( tail ) pList->pHead = pItem->pNext; else pList->pHead = pItem; pList->count++; } void list_delete( LIST_T * pList, void * pNode ) { LIST_ITEM_T * pItem = LIST_ITEM_PTR( pNode ); if ( pList->count ) {
if ( pItem == pList->pHead )
pList->pHead = pItem->pNext;
pItem->pNext->pPrev = pItem->pPrev; pItem->pPrev->pNext = pItem->pNext; pList->count--; } } LIST_NODE_HEAD( _S ) uint32_t memb; LIST_NODE_TAIL( S ) void list_demo( void ) { LIST_T list; S s[ 4 ]; S * pS; list_init( &list ); for ( uint32_t i = 0; i < 4; i++ ) list_insert( &list, &s[ i ], 1 ); pS = (S *) list_get_head( &list ); while ( pS ) { pS->memb = (uint32_t) pS; pS = (S *) list_get_next( &list, pS ); } for ( uint32_t i = 0; i < 4; i++ ) list_delete( &list, &s[ i ] ); }