⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lls.c

📁 C语言库函数的源代码,是C语言学习参考的好文档。
💻 C
📖 第 1 页 / 共 2 页
字号:

    va_end( DataPtr );
    return Retval ;
}

int LLSnodeAppend( 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 = LLSnodeAppendFrom( List, DataPtr );

    va_end( DataPtr );
    return Retval ;
}

int LLSnodeInsertFrom( 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 and link to previous node
       Note that explicitly changing .current is not necessary!
    */
    memcpy( & New->data, Source, ListControl[ List ].itemsize );
    New->next = ListControl[ List ].current->next;
    ListControl[ List ].current->next = New ;

#ifdef USE_LASTPTR
    /* advance last node pointer if needed
    */
    if( NULL != ListControl[ List ].last->next->next )
        ListControl[ List ].last = ListControl[ List ].last->next ;

#endif

    return NO_PROBLEMS;
}

int LLSnodeAddFrom( 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 previous node,
       with special handling if the list is empty
       Note that the changing of .current is the only difference with
       the LLSnodeInsertFrom() function!
    */
    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->next;
    ListControl[ List ].current->next = New;

#ifdef USE_LASTPTR
    /* advance last node pointer if needed
    */
    if( NULL != ListControl[ List ].last->next->next )
        ListControl[ List ].last = ListControl[ List ].last->next ;

#endif

    return NO_PROBLEMS;
}

int LLSnodePrependFrom( 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
    */
    memcpy( & New->data, Source, ListControl[ List ].itemsize );
    New->next = ListControl[ List ].first->next;
    ListControl[ List ].first->next = New;

    if( NULL != New->next && NULL == New->next->next )
    {
        /* The new node is not the only node and is the node preceding
           the actual last node.
           So it is the first of only two valid nodes.
           Note that before insertion of 'New ' .current was .first
           As was the optional last node pointer.
           Note also that this section is a consequence of using a
           'trailing' current node pointer!
        */
        ListControl[ List ].current = New ; /* == .current->next */

#ifdef USE_LASTPTR

        ListControl[ List ].last = New ; /* == .last->next */

#endif

    }

    return NO_PROBLEMS;
}

int LLSnodeAppendFrom( 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
    */
    memcpy( & New->data, Source, ListControl[ List ].itemsize );
    New->next = NULL ;

#ifdef USE_LASTPTR

    if( NULL != ListControl[ List ].last->next )    /* non empty list ? */
        ListControl[ List ].last = ListControl[ List ].last->next ;
    ListControl[ List ].last->next = New ;

#else

    {
        struct Node * Tmp = ListControl[ List ].current;

        while( NULL != Tmp->next ) /* find last node */
            Tmp = Tmp->next ;

        Tmp->next = New ;
    }

#endif

    return NO_PROBLEMS;
}

void LLSnodeDelete( int List )
{
    {
        struct Node * Old = ListControl[ List ].current->next ;

        assert( (unsigned) List < ListCount );

        if( NULL == ListControl[ List ].current->next )
        {
            return ;  /* nothing there to delete ... */
        }

        ListControl[ List ].current->next = Old->next ;
        NODE_FREE( Old );
    }

    /* Modification to prevent current and last node pointers pointing
       past the last node of a list: adjust the current and last node
       pointers when the last node was deleted
    */
    if( NULL == ListControl[ List ].current->next )
    {
        struct Node * Tmp = ListControl[ List ].first;

        if( NULL != Tmp->next )                 /* list not empty ?     */
            while( NULL != Tmp->next->next )    /* find the node before */
                Tmp = Tmp->next ;               /* the last node        */

        ListControl[ List ].current = Tmp ;

#ifdef USE_LASTPTR

        ListControl[ List ].last = Tmp ;

#endif

    }
    return ;
}

int LLSnodeFind( int List, CompFunPtr Compare, void * DataPtr )
{                        /* FindFirst/FindNext format may be needed ... */
    int RetVal ;

    assert( (unsigned) List < ListCount );

    if( NULL == ListControl[ List ].first->next )
    {
        return 2; /* a compare usually returns just -1, 0 or 1 !!! */
    }

    if( NULL == Compare ) /* default to memcmp with .itemsize */
    {
        while( 0 != (RetVal = memcmp( DataPtr,
                                & ListControl[ List ].current->next->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->next->data ))
               && NULL != ListControl[ List ].current->next->next )
        {
            ListControl[ List ].current=ListControl[ List ].current->next;
        }
        return RetVal ;
    }
}

/* ---- current node pointer management ------------------------------- */

int  LLSnodePtr2First( int List )
{
    assert( (unsigned) List < ListCount );

    ListControl[ List ].current = ListControl[ List ].first ;

    return NULL != ListControl[ List ].first->next ;
}

int  LLSnodePtr2Last( int List )
{
    assert( (unsigned) List < ListCount );

#ifdef USE_LASTPTR

    ListControl[ List ].current = ListControl[ List ].last ;

    return NULL != ListControl[ List ].first->next ;

#else

    /* special handling for empty list
    */
    if( NULL == ListControl[ List ].first->next )
    {
        return 0; /* .current also same as .first */
    }

    /* Let the current node pointer point to the last valid node
    */
    while( NULL != ListControl[ List ].current->next->next )
        ListControl[ List ].current = ListControl[ List ].current->next ;

    return 1;

#endif

}

int  LLSnodePtr2Next( int List )
{
    assert( (unsigned) List < ListCount );

    if( NULL == ListControl[ List ].current->next       /* empty list ? */
        || NULL == ListControl[ List ].current->next->next ) /* at end ?*/
    {
        return 0 ;             /* note: 'at end' condition added to     */
    }                          /* to prevent .current pointing past end */

    ListControl[ List ].current = ListControl[ List ].current->next ;
    return 1 ;
}

int  LLSnodePtr2Prev( int List )
{
    struct Node * Prev ;

    assert( (unsigned) List < ListCount );

    Prev = ListControl[ List ].first ;
    if( NULL == Prev->next                       /* empty list or */
        || ListControl[ List ].current == Prev ) /* at beginning? */
    {
        return 0 ;
    }

    /* Find previous Node
    */
    while( Prev->next != ListControl[ List ].current )
        Prev = Prev->next ;

    ListControl[ List ].current = Prev ;

    return 1 ;
}

/* ---- stored data management ---------------------------------------- */

int LLSnodeInt( int List )
{
    return ListControl[ List ].current->next->data;
}

long LLSnodeLong( int List )
{
    return *((long *) &ListControl[ List ].current->next->data );
}

void * LLSnodePtr( int List )
{
    return *((void **) &ListControl[ List ].current->next->data );
}

void FAR * LLSnodeFptr( int List )
{
    return *((void FAR **) &ListControl[ List ].current->next->data );
}

int LLSnodeDataTo( int List, void * Destination )
{
    if( NULL != Destination )
    {
        memcpy( Destination,
                & ListControl[ List ].current->next->data,
                ListControl[ List ].itemsize );
    }

    return ListControl[ List ].itemsize ;       /* size needed for blob */
}

/* ==== LLS.c  end ==================================================== */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -