📄 lld.c
字号:
Retval = LLDnodeInsertFrom( List, DataPtr );
va_end( DataPtr );
return Retval ;
}
int LLDnodeAdd( int List, ... ) /* insert _AFTER_ current node */
{
va_list DataPtr ;
int Retval ;
/* set DataPtr to the address of "..."
then action, cleanup and return.
*/
va_start( DataPtr, List );
Retval = LLDnodeAddFrom( List, DataPtr );
va_end( DataPtr );
return Retval ;
}
int LLDnodePrepend( int List, ... ) /* insert as first node */
{
va_list DataPtr ;
int Retval ;
/* set DataPtr to the address of "..."
then action, cleanup and return.
*/
va_start( DataPtr, List );
Retval = LLDnodePrependFrom( List, DataPtr );
va_end( DataPtr );
return Retval ;
}
int LLDnodeAppend( int List, ... ) /* insert as last node */
{
va_list DataPtr ;
int Retval ;
/* set DataPtr to the address of "..."
then action, cleanup and return.
*/
va_start( DataPtr, List );
Retval = LLDnodeAppendFrom( List, DataPtr );
va_end( DataPtr );
return Retval ;
}
int LLDnodeInsertFrom( int List, void * Source )
{ /* insert _BEFORE_ current node */
struct Node * New ;
assert( (unsigned) List < ListCount );
/* create new node if possible
*/
New = NODE_MALLOC( List );
if( NULL == New )
{
return ERR_MEMORY ;
}
/* fill node with data, link to next and previous nodes
and adjust current node pointer
*/
memcpy( & New->data, Source, ListControl[ List ].itemsize );
New->next = ListControl[ List ].current;
New->prev = ListControl[ List ].current->prev;
ListControl[ List ].current->prev = New ;
New->prev->next = New ;
ListControl[ List ].current = New ;
return NO_PROBLEMS;
}
int LLDnodeAddFrom( int List, void * Source )
{ /* insert _AFTER_ current node */
struct Node * New ;
assert( (unsigned) List < ListCount );
/* create new node if possible
*/
New = NODE_MALLOC( List );
if( NULL == New )
{
return ERR_MEMORY ;
}
/* fill node with data and link to next and previous nodes
with special handling when the current node pointer points
to the dummy tail node: i.e it is an empty list.
(the same case in a non-empty list is made not to occur.)
*/
memcpy( & New->data, Source, ListControl[ List ].itemsize );
if( NULL != ListControl[ List ].current->next )
ListControl[ List ].current = ListControl[ List ].current->next ;
New->next = ListControl[ List ].current;
New->prev = ListControl[ List ].current->prev;
ListControl[ List ].current->prev = New ;
New->prev->next = New ;
ListControl[ List ].current = New ;
return NO_PROBLEMS;
}
int LLDnodePrependFrom( int List, void * Source )
{ /* insert as first node */
struct Node * New ;
assert( (unsigned) List < ListCount );
/* create new node if possible
*/
New = NODE_MALLOC( List );
if( NULL == New )
{
return ERR_MEMORY ;
}
/* fill node with data and link to dummy head and actual first nodes
*/
memcpy( & New->data, Source, ListControl[ List ].itemsize );
New->prev = ListControl[ List ].first; /* == .first->next->prev */
New->next = ListControl[ List ].first->next;
ListControl[ List ].first->next = New;
New->next->prev = New ;
/* Prevent .current from pointing at the dummy tail
(New is the only normal node...)
*/
if( NULL == ListControl[ List ].current->next )
ListControl[ List ].current = New;
return NO_PROBLEMS;
}
int LLDnodeAppendFrom( int List, void * Source )
{ /* insert as last node */
struct Node * New ;
assert( (unsigned) List < ListCount );
/* create new node if possible
*/
New = NODE_MALLOC( List );
if( NULL == New )
{
return ERR_MEMORY ;
}
/* fill node with data and link to dummy tail and actual last nodes
*/
memcpy( & New->data, Source, ListControl[ List ].itemsize );
New->next = ListControl[ List ].last ; /* == .last->prev->next */
New->prev = ListControl[ List ].last->prev;
ListControl[ List ].last->prev = New ;
New->prev->next = New ;
/* Prevent .current from pointing at the dummy tail
(New is the only normal node...)
*/
if( NULL == ListControl[ List ].current->next )
ListControl[ List ].current = New;
return NO_PROBLEMS;
}
void LLDnodeDelete( int List )
{
struct Node * Old = ListControl[ List ].current ;
assert( (unsigned) List < ListCount );
if( NULL == ListControl[ List ].current->next )
{
return ; /* don't delete dummy tail node (list is empty) */
}
/* adjust links
*/
Old->prev->next = Old->next ;
Old->next->prev = Old->prev ;
/* adjust current node pointer
prevent it from pointing to the dummy tail node
*/
if( NULL != Old->next->next )
ListControl[ List ].current = Old->next ;
else
ListControl[ List ].current = Old->prev ;
NODE_FREE( Old );
return ;
}
int LLDnodeFind( int List, CompFunPtr Compare, void * DataPtr )
{ /* FindFirst/FindNext format may be needed ... */
int RetVal ;
assert( (unsigned) List < ListCount );
if( NULL == ListControl[ List ].first->next->next ) /* empty list ? */
{
return 2; /* a compare usually returns just -1, 0 or 1 !!! */
}
/* note: current->next will never be NULL in a non-empty list */
if( NULL == Compare ) /* default to memcmp with .itemsize */
{
while( 0 != (RetVal = memcmp( DataPtr,
& ListControl[ List ].current->data,
ListControl[ List ].itemsize ))
&& NULL != ListControl[ List ].current->next->next )
{
ListControl[ List ].current=ListControl[ List ].current->next;
}
return RetVal ;
}
else
{
while( 0 != (RetVal = (*Compare)( DataPtr,
& ListControl[ List ].current->data ))
&& NULL != ListControl[ List ].current->next->next )
{
ListControl[ List ].current=ListControl[ List ].current->next;
}
return RetVal ;
}
}
/* ---- current node pointer management ------------------------------- */
int LLDnodePtr2First( int List )
{
assert( (unsigned) List < ListCount );
ListControl[ List ].current = ListControl[ List ].first->next ;
return NULL != ListControl[ List ].first->next->next ;
}
int LLDnodePtr2Last( int List )
{
assert( (unsigned) List < ListCount );
ListControl[ List ].current = ListControl[ List ].last->prev ;
return NULL != ListControl[ List ].last->prev->prev ;
}
int LLDnodePtr2Next( int List )
{
assert( (unsigned) List < ListCount );
if( NULL == ListControl[ List ].current->next /* empty list ? */
|| NULL == ListControl[ List ].current->next->next ) /* at end ?*/
{
return 0 ; /* do not allow the current node pointer */
} /* to point at the dummy tail node ... */
ListControl[ List ].current = ListControl[ List ].current->next ;
return 1 ;
}
int LLDnodePtr2Prev( int List )
{
assert( (unsigned) List < ListCount );
if( NULL == ListControl[ List ].current->prev /* empty list ? */
|| NULL == ListControl[ List ].current->prev->prev ) /* begin ? */
{
return 0 ; /* do not allow the current node pointer */
} /* to point at the dummy head node ... */
ListControl[ List ].current = ListControl[ List ].current->prev ;
return 1 ;
}
/* ---- stored data management ---------------------------------------- */
int LLDnodeInt( int List )
{
return ListControl[ List ].current->data;
}
long LLDnodeLong( int List )
{
return *((long *) &ListControl[ List ].current->data );
}
void * LLDnodePtr( int List )
{
return *((void **) &ListControl[ List ].current->data );
}
void FAR * LLDnodeFptr( int List )
{
return *((void FAR **) &ListControl[ List ].current->data );
}
int LLDnodeDataTo( int List, void * Destination )
{
if( NULL != Destination )
{
memcpy( Destination,
& ListControl[ List ].current->data,
ListControl[ List ].itemsize );
}
return ListControl[ List ].itemsize ; /* size needed for blob */
}
/* ==== LLD.c end ==================================================== */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -