Annotation of mstools/samples/deb/linklist.c, revision 1.1

1.1     ! root        1: // ************************************************************************
        !             2: // LinkList.C - Ordered Double Linked List Package
        !             3: // ************************************************************************
        !             4: // PURPOSE: Provide a generalized sorted double linked list package
        !             5: //
        !             6: // FUNCTIONS:
        !             7: //   InitList          - initialize/clear list
        !             8: //   CreateNode        - allocate a new node that can be put into list
        !             9: //   InsertNode        - insert a new node into the list
        !            10: //   DeleteCurrentNode - remove a node from the list
        !            11: //   GetNextNode       - get the next (right) node from the CurrentNode
        !            12: //   GetPreviousNode   - get the previous (left) node from the
        !            13: //                       CurrentNode
        !            14: //   GetNode           - get nth Occurence of a node that matches a
        !            15: //                       key(s)
        !            16: //   GetListError      - get the error value
        !            17: //
        !            18: // COMMENTS: The application must serialize access to the linked list
        !            19: //
        !            20: //   Format of the Ordering and Matching functions is as follows:
        !            21: //
        !            22: //   int OrderFunc( PNODE pNodeOne, PNODE pNodeTwo )
        !            23: //   {
        !            24: //     if( (pNodeOne->NodeData).Key <  (pNodeTwo->NodeData).Key )
        !            25: //       return( LEFT_OF  );
        !            26: //     if( (pNodeOne->NodeData).Key == (pNodeTwo->NodeData).Key )
        !            27: //       return( MATCH    );
        !            28: //     if( (pNodeOne->NodeData).Key  > (pNodeTwo->NodeData).Key )
        !            29: //       return( RIGHT_OF );
        !            30: //   }
        !            31: //
        !            32: // ************************************************************************
        !            33: #include <StdLib.H>     // malloc(), free()
        !            34: #include <StdIO.H>      // printf()
        !            35: #include "LinkList.H"
        !            36: 
        !            37: //-- NULL pointer dereferencing checking macro
        !            38: #define CHECH_POINTER( Node )                                  \
        !            39:           if( Node == NULL ) {                                 \
        !            40:             printf("Attempt to dereference NULL.\n");          \
        !            41:             return(pList->ListError = DEREFERENCE_NULL_ERROR); \
        !            42:           }
        !            43: 
        !            44: //-- "member" functions that return the private data
        !            45: int   GetListError(   PLIST pList ) { return( pList->ListError );    }
        !            46: PNODE GetFirstNode(   PLIST pList ) { return( pList->pFirstNode );   }
        !            47: PNODE GetCurrentNode( PLIST pList ) { return( pList->pCurrentNode ); }
        !            48: PNODE GetLastNode(    PLIST pList ) { return( pList->pLastNode );    }
        !            49: 
        !            50: 
        !            51: // ************************************************************************
        !            52: // FUNCTION : InitList( PLIST pList, int (*)(PNODE, PNODE) )
        !            53: // PURPOSE  : initialize/clear list, registers the ordering function
        !            54: // COMMENTS :
        !            55: // ************************************************************************
        !            56: int
        !            57: InitList( PLIST pList, int (*OrderFunc)( PNODE pNodeOne, PNODE pNodeTwo ) )
        !            58: {
        !            59:   PNODE pTempNode;
        !            60: 
        !            61:   //-- remove all nodes if the list is not empty
        !            62:   while( ( (pList->pFirstNode) != NULL) && ( (pList->ListError) == NO_ERROR_FOUND) ) {
        !            63:     pTempNode = (pList->pFirstNode);
        !            64:     if( DeleteCurrentNode( pList ) < NO_ERROR_FOUND ) {
        !            65:       (pList->ListError) = NO_NODE_ERROR;
        !            66:       return( pList->ListError );
        !            67:     }
        !            68:   }
        !            69: 
        !            70:   //-- initialize the "private" pointers to NULL
        !            71:   (pList->pFirstNode)   = NULL;
        !            72:   (pList->pCurrentNode) = NULL;
        !            73:   (pList->pLastNode)    = NULL;
        !            74: 
        !            75:   //-- register the link list data ordering function
        !            76:   (pList->OrderFunction) = OrderFunc;
        !            77: 
        !            78:   (pList->ListError)    = NO_ERROR_FOUND;
        !            79:   return( pList->ListError );
        !            80: }
        !            81: 
        !            82: 
        !            83: // ************************************************************************
        !            84: // FUNCTION : CreateNode( PLIST pList, PNODE* )
        !            85: // PURPOSE  : create/allocate a new node that can be put into list
        !            86: // COMMENTS :
        !            87: // ************************************************************************
        !            88: int
        !            89: CreateNode( PLIST pList, PNODE* ppNewNode )
        !            90: {
        !            91:   (*ppNewNode) = (PNODE) malloc(sizeof(NODE));
        !            92:   if(*ppNewNode == NULL) {
        !            93:     printf("malloc failed.\n");
        !            94:     (pList->ListError) = NO_NODE_ERROR;
        !            95:     return( pList->ListError );
        !            96:   }
        !            97:   ((*ppNewNode)->pRightLink) = NULL;
        !            98:   ((*ppNewNode)->pLeftLink)  = NULL;
        !            99: 
        !           100:   (pList->ListError)         = NO_ERROR_FOUND;
        !           101:   return( pList->ListError );
        !           102: }
        !           103: 
        !           104: 
        !           105: // ************************************************************************
        !           106: // FUNCTION : InsertNode( PLIST pList, PNODE )
        !           107: // PURPOSE  : insert a new node into the list
        !           108: // COMMENTS : all nodes must have a unique key entry (from order
        !           109: //            function), if a match is found during an insert then the
        !           110: //            old node gets replaced with the new node
        !           111: //            NOTE: changes pList->pCurrentNode
        !           112: // ************************************************************************
        !           113: int
        !           114: InsertNode( PLIST pList, PNODE pNewNode )
        !           115: {
        !           116:   int Position;
        !           117:   int LastPosition;
        !           118: 
        !           119:   if( (pList->pFirstNode) == NULL ) {
        !           120: 
        !           121:     (pList->pFirstNode)   = pNewNode;
        !           122:     (pList->pLastNode)    = pNewNode;
        !           123:     (pList->pCurrentNode) = pNewNode;
        !           124:     (pList->ListError)    = NO_ERROR_FOUND;
        !           125: 
        !           126:     return( pList->ListError );
        !           127:   }
        !           128: 
        !           129:   Position = (*(pList->OrderFunction))( pNewNode, pList->pCurrentNode );
        !           130: 
        !           131:   //-- search for insertion point
        !           132:   while( (pList->pCurrentNode) != NULL ) {
        !           133: 
        !           134:     LastPosition = Position;
        !           135:     Position = (*(pList->OrderFunction))(pNewNode, pList->pCurrentNode);
        !           136: 
        !           137:     if( (pList->pFirstNode) == (pList->pLastNode) )
        !           138:       break;
        !           139: 
        !           140:     if( Position != LastPosition )
        !           141:       break;
        !           142: 
        !           143:     if( (pList->pCurrentNode) == (pList->pFirstNode) ) {
        !           144:       if( Position == RIGHT_OF ) {
        !           145:         (pList->pCurrentNode) = ((pList->pCurrentNode)->pRightLink);
        !           146:         continue;
        !           147:       }
        !           148:       break;
        !           149:     }
        !           150: 
        !           151:     if( (pList->pCurrentNode) == (pList->pLastNode) ) {
        !           152:       if( Position == LEFT_OF ) {
        !           153:         (pList->pCurrentNode) = ((pList->pCurrentNode)->pLeftLink);
        !           154:         continue;
        !           155:       }
        !           156:       break;
        !           157:     }
        !           158: 
        !           159:     if( Position == LastPosition ) {
        !           160:       if( Position == LEFT_OF) {
        !           161:         (pList->pCurrentNode) = ((pList->pCurrentNode)->pLeftLink);
        !           162:         continue;
        !           163:       }
        !           164:       if( Position == RIGHT_OF ) {
        !           165:         (pList->pCurrentNode) = ((pList->pCurrentNode)->pRightLink);
        !           166:         continue;
        !           167:       }
        !           168:       break;
        !           169:     }
        !           170: 
        !           171:   }
        !           172: 
        !           173:   //-- now, insert the pNewNode
        !           174:   switch( Position ) {
        !           175: 
        !           176:     case LEFT_OF:
        !           177:       (pNewNode->pRightLink) = (pList->pCurrentNode);
        !           178:       (pNewNode->pLeftLink)  = ((pList->pCurrentNode)->pLeftLink);
        !           179:       if( (pList->pCurrentNode) == (pList->pFirstNode) )
        !           180:         (pList->pFirstNode) = pNewNode;
        !           181:       else
        !           182:         (((pList->pCurrentNode)->pLeftLink)->pRightLink) = pNewNode;
        !           183:       ((pList->pCurrentNode)->pLeftLink)  = pNewNode;
        !           184:       break;
        !           185: 
        !           186:     case RIGHT_OF:
        !           187:       (pNewNode->pLeftLink)  = (pList->pCurrentNode);
        !           188:       (pNewNode->pRightLink) = ((pList->pCurrentNode)->pRightLink);
        !           189:       if( (pList->pCurrentNode) == (pList->pLastNode) )
        !           190:         (pList->pLastNode) = pNewNode;
        !           191:       else
        !           192:         (((pList->pCurrentNode)->pRightLink)->pLeftLink) = pNewNode;
        !           193:       ((pList->pCurrentNode)->pRightLink)  = pNewNode;
        !           194:       break;
        !           195: 
        !           196:     case MATCH:
        !           197:       (pNewNode->pLeftLink)  = ((pList->pCurrentNode)->pLeftLink);
        !           198:       (pNewNode->pRightLink) = ((pList->pCurrentNode)->pRightLink);
        !           199:       DestroyNode( pList->pCurrentNode );
        !           200:       break;
        !           201: 
        !           202:   }
        !           203:   (pList->pCurrentNode) = pNewNode;
        !           204: 
        !           205:   (pList->ListError)    = NO_ERROR_FOUND;
        !           206:   return( pList->ListError );
        !           207: }
        !           208: 
        !           209: 
        !           210: // ************************************************************************
        !           211: // FUNCTION : DestroyNode( PNODE )
        !           212: // PURPOSE  : deallocates a node
        !           213: // COMMENTS :
        !           214: // ************************************************************************
        !           215: int
        !           216: DestroyNode( PNODE pNode )
        !           217: {
        !           218:   free( pNode );
        !           219:   return( 1 );
        !           220: }
        !           221: 
        !           222: 
        !           223: // ************************************************************************
        !           224: // FUNCTION : DeleteCurrentNode( PLIST pList )
        !           225: // PURPOSE  : delete pList->pCurrentNode from the list and deallocate it
        !           226: // COMMENTS : changes pList->pCurrentNode. Typically, GetNode is called first so
        !           227: //            pList->pCurrentNode points to the correct node
        !           228: // ************************************************************************
        !           229: int
        !           230: DeleteCurrentNode( PLIST pList )
        !           231: {
        !           232:   PNODE pOldCurrentNode;
        !           233: 
        !           234:   if( (pList->pCurrentNode) != NULL ) {
        !           235:     pOldCurrentNode = (pList->pCurrentNode);
        !           236: 
        !           237:     if( pOldCurrentNode == (pList->pFirstNode) ) {
        !           238:       (pList->pFirstNode)   = (pOldCurrentNode->pRightLink);
        !           239:       (pList->pCurrentNode) = (pOldCurrentNode->pRightLink);
        !           240:     }
        !           241:     else {
        !           242:       ((pOldCurrentNode->pLeftLink)->pRightLink) = (pOldCurrentNode->pRightLink);
        !           243:       (pList->pCurrentNode) = (pOldCurrentNode->pLeftLink);
        !           244:     }
        !           245: 
        !           246:     if( pOldCurrentNode == (pList->pLastNode) )
        !           247:       (pList->pLastNode)    = (pOldCurrentNode->pLeftLink);
        !           248:     else
        !           249:       ((pOldCurrentNode->pRightLink)->pLeftLink) = (pOldCurrentNode->pLeftLink);
        !           250: 
        !           251:     DestroyNode( pOldCurrentNode );
        !           252: 
        !           253:     (pList->ListError) = NO_ERROR_FOUND;
        !           254:     return( pList->ListError );
        !           255:   }
        !           256: 
        !           257:   (pList->ListError) = NO_ERROR_FOUND;
        !           258:   return( pList->ListError );
        !           259: }
        !           260: 
        !           261: 
        !           262: // ************************************************************************
        !           263: // FUNCTION : GetNextNode( PLIST pList, PNODE* )
        !           264: // PURPOSE  : get the next (right) node from the pList->pCurrentNode
        !           265: // COMMENTS : Does not change pList->pCurrentNode
        !           266: // ************************************************************************
        !           267: int
        !           268: GetNextNode( PLIST pList, PNODE* ppNode )
        !           269: {
        !           270:   CHECH_POINTER( ppNode );
        !           271:   if( ((*ppNode)->pRightLink) == NULL )
        !           272:     return( (pList->ListError) = NO_NEXT_NODE_ERROR );
        !           273:   (*ppNode) = ((*ppNode)->pRightLink);
        !           274: 
        !           275:   (pList->ListError) = NO_ERROR_FOUND;
        !           276:   return( pList->ListError );
        !           277: }
        !           278: 
        !           279: 
        !           280: // ************************************************************************
        !           281: // FUNCTION : GetPreviousNode( PLIST pList, PNODE* )
        !           282: // PURPOSE  : get the previous (left) node from the pList->pCurrentNode
        !           283: // COMMENTS : Does not change pList->pCurrentNode
        !           284: // ************************************************************************
        !           285: int
        !           286: GetPreviousNode( PLIST pList, PNODE* ppNode )
        !           287: {
        !           288:   CHECH_POINTER( ppNode );
        !           289:   if( ((*ppNode)->pLeftLink) == NULL )
        !           290:     return( (pList->ListError) = NO_PREV_NODE_ERROR);
        !           291:   (*ppNode) = ((*ppNode)->pLeftLink);
        !           292: 
        !           293:   (pList->ListError) = NO_ERROR_FOUND;
        !           294:   return( pList->ListError );
        !           295: }
        !           296: 
        !           297: 
        !           298: // ************************************************************************
        !           299: // FUNCTION : GetNode( PLIST pList, PNODE*, int (*)(PNODE, PNODE), int )
        !           300: // PURPOSE  : get nth Occurence of a node from the list that matches a
        !           301: //            key(s).
        !           302: // COMMENTS : may use the ordering function or a new matching function
        !           303: //            if not searching for a match based on the primary
        !           304: //            ordering key.  Note: the matching and ordering functions
        !           305: //            have the same definition.
        !           306: //            NOTE: changes pList->pCurrentNode
        !           307: // ************************************************************************
        !           308: int
        !           309: GetNode( PLIST pList, PNODE* ppKeyNode,
        !           310:          int  (*MatchFunction)( PNODE pNodeOne, PNODE pNodeTwo ),
        !           311:          int  Occurence )
        !           312: {
        !           313:   int Position;
        !           314: 
        !           315:   //-- if match and order are same function
        !           316:   if( MatchFunction == (pList->OrderFunction) ) {
        !           317:     int  LastPosition;
        !           318: 
        !           319:     Position = (*MatchFunction)(*ppKeyNode, pList->pCurrentNode);
        !           320:     LastPosition = Position;
        !           321: 
        !           322:     while( Occurence ) {
        !           323:       if( (Position == LEFT_OF) && (LastPosition == LEFT_OF)
        !           324:           && ( (pList->pCurrentNode) != (pList->pFirstNode) ) )
        !           325:         (pList->pCurrentNode) = ((pList->pCurrentNode)->pLeftLink);
        !           326:       else if( (Position == RIGHT_OF) && (LastPosition == RIGHT_OF)
        !           327:             && ( (pList->pCurrentNode) != (pList->pLastNode) ) )
        !           328:         (pList->pCurrentNode) = ((pList->pCurrentNode)->pRightLink);
        !           329:       else {
        !           330:         Occurence--;
        !           331:         continue;
        !           332:       }
        !           333:       LastPosition = Position;
        !           334:       Position = (*MatchFunction)(*ppKeyNode, pList->pCurrentNode);
        !           335:     }
        !           336: 
        !           337:   }
        !           338:   else {  // match and order are not the same function, thus start
        !           339:           // the search at the front of the list
        !           340:     (pList->pCurrentNode) = (pList->pFirstNode);
        !           341: 
        !           342:     while( (Occurence > 0) && ( (pList->pCurrentNode) != NULL)) {
        !           343:       Position = (*MatchFunction)(*ppKeyNode, pList->pCurrentNode);
        !           344:       if(Position == MATCH)
        !           345:         Occurence--;
        !           346:       if(Occurence > 0 )
        !           347:         (pList->pCurrentNode) = ((pList->pCurrentNode)->pRightLink);
        !           348:     }
        !           349: 
        !           350:   }
        !           351: 
        !           352:   if( (Position == MATCH) && (Occurence == 0) ) {
        !           353:     *ppKeyNode = (pList->pCurrentNode);
        !           354: 
        !           355:     (pList->ListError) = NO_ERROR_FOUND;
        !           356:     return( pList->ListError );
        !           357:   }
        !           358: 
        !           359:   (pList->ListError) = NO_MATCH_ERROR;
        !           360:   return( pList->ListError );
        !           361: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.