void list_merge (list_t * dest, list_t * sour, int compare (const void *, const void *)) { lnode_t *dn, *sn, *tn; lnode_t *d_nil = list_nil (dest), *s_nil = list_nil (sour); /* Nothing to do if source and destination list are the same. */ if (dest == sour) return; /* overflow check */ nassert (list_count (sour) + list_count (dest) >= list_count (sour)); /* lists must be sorted */ nassert (list_is_sorted (sour, compare)); nassert (list_is_sorted (dest, compare)); dn = list_first_priv (dest); sn = list_first_priv (sour); while (dn != d_nil && sn != s_nil) { if (compare (lnode_get (dn), lnode_get (sn)) >= 0) { tn = lnode_next (sn); list_delete (sour, sn); list_ins_before (dest, sn, dn); sn = tn; } else { dn = lnode_next (dn); } } if (dn != d_nil) return; if (sn != s_nil) list_transfer (dest, sour, sn); }
int test_linked_list() { int i,j, result = 0; List_Node *test_node1 = NULL; List_Node *test_node2 = NULL; List_Node *test_node3 = NULL; List_Node *pTrack[5]; void* pArr[6]; List_Head *test_list1 = list_new(); List_Head *test_list2 = list_new(); test_msg_start("Test Linked List Creation"); if(test_list1 == NULL) result++; test_msg_end(result); test_msg_start("Test Linked List Empty Length - Using Variable"); if(test_list1->count != 0) result++; test_msg_end(result); test_msg_start("Test Linked List Empty Length - Using Length Function"); if(list_len(test_list1) != 0 ) result++; test_msg_end(result); test_msg_start("Test Linked List - Adding Node To Empty List"); if(list_ins_tail(test_list1) == NULL) result++; test_msg_end(result); test_msg_start("Test Linked List - Adding Node To Non-Empty List"); if(list_ins_tail(test_list1) == NULL) result++; test_msg_end(result); test_msg_start("Test Linked List - Clearing List With More Than One Node"); list_clear(test_list1); if(test_list1->count != 0) result++; if(list_len(test_list1) != 0 ) result++; test_msg_end(result); test_msg_start("Test Linked List - Clearing List With No Nodes"); list_clear(test_list1); if(test_list1->count != 0) result++; if(list_len(test_list1) != 0 ) result++; test_msg_end(result); test_msg_start("Test Linked List End - No Nodes"); list_clear(test_list1); if(list_tail(test_list1) != NULL) result++; test_msg_end(result); test_msg_start("Test Linked List End - One Node Only"); list_clear(test_list1); test_node1 = list_ins_tail(test_list1); if(test_node1 == NULL) result++; if(list_tail(test_list1) != test_node1) result++; test_msg_end(result); test_msg_start("Test Linked List End - More Than One Node"); list_clear(test_list1); list_ins_tail(test_list1); test_node1 = list_ins_tail(test_list1); if(test_node1 == NULL) result++; if(list_tail(test_list1) != test_node1) result++; test_msg_end(result); test_msg_start("Test Linked List - Removing Node From List With More Than One Node"); list_clear(test_list1); test_node1 = list_ins_tail(test_list1); test_node2 = list_ins_head(test_list1); list_rm_node(test_list1, test_node1); if(test_list1->pNext != test_node2) result++; test_msg_end(result); test_msg_start("Test Linked List - Removing Node From Empty List"); list_clear(test_list1); test_node1 = (List_Node*)&test_list1; /* pointer points to known bad location */ /* should not crash but return gracefully */ if(list_rm_node(test_list1, test_node1) != -1) result++; test_msg_end(result); test_msg_start("Test Linked List - Inserting Node After"); list_clear(test_list1); test_node1 = NULL; test_node2 = NULL; test_node1 = list_ins_tail(test_list1); test_node2 = list_ins_after(test_list1, test_node1); /* test beginning */ if(test_list1->pNext != test_node1) result++; /*...and end nodes. */ if(list_tail(test_list1) != test_node2) result++; /* end node next should be null */ if(list_tail(test_list1)->pNext != NULL) result++; test_msg_end(result); test_msg_start("Test Linked List - Inserting Node Before"); list_clear(test_list1); test_node1 = NULL; test_node2 = NULL; test_node1 = list_ins_head(test_list1); test_node2 = list_ins_before(test_list1, test_node1); /* test beginning */ if(test_list1->pNext != test_node2) result++; /*...and end nodes. */ if(list_tail(test_list1) != test_node1) result++; /* end node next should be null */ if(list_tail(test_list1)->pNext != NULL) result++; test_msg_end(result); test_msg_start("Test Linked List - Test Lengths"); list_clear(test_list1); if(list_len(test_list1) != 0) result++; /* adding nodes using each function */ list_ins_head(test_list1); if(list_len(test_list1) != 1) result++; list_ins_tail(test_list1); if(list_len(test_list1) != 2) result++; list_ins_before(test_list1, list_tail(test_list1)); if(list_len(test_list1) != 3) result++; list_ins_after(test_list1, list_tail(test_list1)); if(list_len(test_list1) != 4) result++; test_msg_end(result); test_msg_start("Test Linked List - Previous Node Check"); list_clear(test_list1); test_node1 = NULL; test_node2 = NULL; if(list_prev_node(test_list1, NULL) != NULL) result++; if(list_prev_node(NULL, test_list1->pNext) != NULL) result++; if(list_prev_node(NULL, test_node1 + 1000) != NULL) result++; test_node1 = list_ins_head(test_list1); if(list_prev_node(test_list1, test_list1->pNext) != NULL) result++; test_node2 = list_ins_head(test_list1); if(list_prev_node(test_list1, test_node1) != test_node2) result++; if(list_prev_node(test_list1, test_node2) != NULL) result++; test_msg_end(result); test_msg_start("Test Linked List - Removing Nodes By Address"); /* removing nodes from various places */ list_clear(test_list1); test_node1 = NULL; test_node2 = NULL; if(list_rm_node(NULL, test_list1->pNext)!= -1) result++; if(list_rm_node(test_list1, NULL) != -1) result++; test_node1 = list_ins_head(test_list1); test_node2 = list_ins_head(test_list1); list_rm_node(test_list1, test_list1->pNext); if(list_len(test_list1) != 1) result++; test_node1 = list_tail(test_list1); list_rm_node(test_list1, test_node1); if(list_len(test_list1) != 0) result++; if(list_rm_node(test_list1, list_tail(test_list1)) != -1) result++; test_msg_end(result); test_msg_start("Test Linked List - Removing Nodes After Address"); list_clear(test_list1); test_node1 = NULL; test_node2 = NULL; test_node1 = list_ins_tail(test_list1); test_node2 = list_ins_tail(test_list1); if(list_rm_next(test_list1, test_node1) != 1) result++; test_msg_end(result); test_msg_start("Test Linked List - Removing Nodes Before Address"); list_clear(test_list1); test_node1 = NULL; test_node2 = NULL; if(list_rm_before(test_list1, NULL) != -1) result++; if(list_rm_before(NULL, NULL) != -1) result++; if(list_rm_before(test_list1 + 1000, NULL) != -1) result++; test_node1 = list_ins_tail(test_list1); test_node2 = list_ins_tail(test_list1); if(list_rm_before(test_list1, test_node2 + 1000) != -1) result++; if(list_rm_before(test_list1, test_node2) != 1) result++; test_msg_end(result); test_msg_start("Test Linked List - Copying List"); list_clear(test_list1); list_clear(test_list2); test_node1 = list_ins_tail(test_list1); test_node1->pData = &result; test_node2 = list_ins_tail(test_list1); if(list_copy(test_list2, test_list1) != 0) result++; if(test_list1->pNext == test_list2->pNext) result++; if(test_list1->count != 2) result++; if(test_list2->count != 2) result++; if(test_list1->pNext->pData != test_list2->pNext->pData) result++; test_msg_end(result); test_msg_start("Test Linked List - Copying Empty List"); list_clear(test_list1); list_clear(test_list2); if(list_copy(test_list2, test_list1) != 0) result++; if(test_list1->pNext != NULL) result++; if(test_list2->pNext != NULL) result++; if(test_list1->count != 0) result++; if(test_list2->count != 0) result++; test_msg_end(result); test_msg_start("Test Linked List - Get Node Address By Node Number - First Node"); list_clear(test_list1); test_node1 = list_ins_head(test_list1); test_node2 = list_ins_head(test_list1); test_node3 = list_get_num(test_list1, 1); if(test_node3 != test_node2) result++; test_msg_end(result); test_msg_start("Test Linked List - Get Node Address By Node Number - Middle Node"); list_clear(test_list1); list_ins_tail(test_list1); list_ins_tail(test_list1); list_ins_tail(test_list1); list_ins_tail(test_list1); test_node2 = list_ins_tail(test_list1); list_ins_tail(test_list1); list_ins_tail(test_list1); list_ins_tail(test_list1); list_ins_tail(test_list1); test_node3 = list_get_num(test_list1, 5); if(test_node3 != test_node2) result++; test_msg_end(result); test_msg_start("Test Linked List - Get Node Address By Node Number - Last Node"); list_clear(test_list1); test_node1 = list_ins_tail(test_list1); test_node2 = list_ins_tail(test_list1); test_node3 = list_get_num(test_list1, 2); if(test_node3 != test_node2) result++; test_msg_end(result); test_msg_start("Test Linked List - Get Node Address By Node Number - Empty List"); list_clear(test_list1); test_node1 = list_get_num(test_list1, 1); if(test_node1 != NULL) result++; test_node1 = list_get_num(test_list1, 55); if(test_node1 != NULL) result++; test_msg_end(result); test_msg_start("Test Linked List - Swap Nodes In List"); list_clear(test_list1); test_node1 = list_ins_tail(test_list1); test_node2 = list_ins_tail(test_list1); test_node3 = list_ins_tail(test_list1); pTrack[1] = test_node1->pNext; pTrack[2] = test_node2->pNext; if(list_node_swap(test_node1, test_node2) != 0) result++; if(test_node1->pNext != pTrack[2]) result++; if(test_node2->pNext != pTrack[1]) result++; test_msg_end(result); test_msg_start("Test Linked List - List Reverse - Pointer Tracking"); list_clear(test_list1); for(i = 0; i < 5; i++) { pTrack[i] = list_ins_tail(test_list1); pTrack[i]->pData = &pTrack[i]->pData; } test_list1 = list_reverse(test_list1); for(i = 1, j = 4; i <= 4; i++, j--) { test_node1 = list_get_num(test_list1, i); if(test_node1->pData != pTrack[j]) result++; } test_msg_end(result); test_msg_start("Test Linked List - List Next Preprocessor"); list_clear(test_list1); list_clear(test_list2); test_node1 = NULL; test_node2 = NULL; test_node1 = list_ins_head(test_list1); test_node2 = list_ins_head(test_list1); if(list_next(test_node1) == test_node2) result++; test_msg_end(result); test_msg_start("Test Linked List - Default Payload"); list_clear(test_list1); test_node1 = NULL; test_node2 = NULL; test_node1 = list_ins_tail(test_list1); test_node2 = list_ins_tail(test_list1); if(test_node1->pData != NULL) result++; /* make data point to something and test again... */ test_node1->pData = test_node1; if(list_data(test_node1) != test_node1) result++; test_msg_end(result); test_msg_start("Test Linked List - List Is Head Preprocessor"); if(list_is_head(test_list1, test_node2) != 0) result++; if(list_is_head(test_list1, test_node1) != 1) result++; test_msg_end(result); test_msg_start("Test Linked List - List Is Tail Preprocessor"); if(list_is_tail(test_node2) != 1) result++; if(list_is_tail(test_node1) != 0) result++; test_msg_end(result); test_msg_start("Test Linked List - List Head Preprocessor"); if(list_head(test_list1) != test_node1) result++; test_msg_end(result); test_msg_start("Test Linked List - Append Lists - Pointer Tracking"); list_clear(test_list1); list_clear(test_list2); list_ins_tail(test_list1); list_ins_tail(test_list1); list_ins_tail(test_list1); pTrack[0] = list_ins_tail(test_list1); pTrack[1] = list_ins_tail(test_list2); list_ins_tail(test_list2); list_ins_tail(test_list2); list_append(test_list1, test_list2); if(test_list1->count != 7) result++; if(!list_search(test_list1, pTrack[0])) result++; if(!list_search(test_list1, pTrack[1])) result++; if(pTrack[0] != list_get_num(test_list1, 4)) result++; if(pTrack[1] != list_get_num(test_list1, 5)) result++; test_msg_end(result); test_msg_start("Test Linked List - Create Data Array - Pointer Tracking"); list_clear(test_list1); pTrack[0] = list_ins_tail(test_list1); pTrack[0] = pTrack[0]->pData = &test_list1; pTrack[1] = list_ins_tail(test_list1); pTrack[1] = pTrack[1]->pData = &test_list2; pTrack[2] = list_ins_tail(test_list1); pTrack[2] = pTrack[2]->pData = &pTrack; pTrack[3] = list_ins_tail(test_list1); pTrack[3] = pTrack[3]->pData = &test_node1; pTrack[4] = list_ins_tail(test_list1); pTrack[4] = pTrack[4]->pData = &test_node2; pArr[5] = &test_list1; if(list_data_array(test_list1, pArr, 6) != 0) result++; if(pArr[0] != pTrack[0]) result++; if(pArr[1] != pTrack[1]) result++; if(pArr[2] != pTrack[2]) result++; if(pArr[3] != pTrack[3]) result++; if(pArr[4] != pTrack[4]) result++; if(pArr[5] != NULL) result++; test_msg_end(result); test_msg_start("Test Linked List - Create Node Array - Pointer Tracking"); list_clear(test_list1); pTrack[0] = list_ins_tail(test_list1); pTrack[1] = list_ins_tail(test_list1); pTrack[2] = list_ins_tail(test_list1); pTrack[3] = list_ins_tail(test_list1); pTrack[4] = list_ins_tail(test_list1); pArr[5] = &test_list1; if(list_node_array(test_list1, pArr, 6) != 0) result++; if(pArr[0] != pTrack[0]) result++; if(pArr[1] != pTrack[1]) result++; if(pArr[2] != pTrack[2]) result++; if(pArr[3] != pTrack[3]) result++; if(pArr[4] != pTrack[4]) result++; if(pArr[5] != NULL) result++; test_msg_end(result); test_msg_start("Test Linked List - Search List"); list_clear(test_list1); if(list_search(test_list1, test_node1) != 0) result++; test_node1 = list_ins_head(test_list1); if(list_search(test_list1, test_node1) != 1) result++; if(list_search(test_list1, test_node2) != 0) result++; if(list_search(test_list1, test_node3) != 0) result++; if(list_search(test_list1, NULL) != 0) result++; if(list_search(test_list1, (List_Node *)test_list1) != 0) result++; test_node2 = list_ins_head(test_list1); if(list_search(test_list1, test_node1) != 1) result++; if(list_search(test_list1, test_node2) != 1) result++; if(list_search(test_list1, test_node3) != 0) result++; if(list_search(test_list1, NULL) != 0) result++; if(list_search(test_list1, (List_Node *)test_list1) != 0) result++; list_clear(test_list1); if(list_search(test_list1, test_node1) != 0) result++; if(list_search(test_list1, test_node2) != 0) result++; if(list_search(test_list1, test_node3) != 0) result++; if(list_search(test_list1, NULL) != 0) result++; if(list_search(test_list1, (List_Node *)test_list1) != 0) result++; test_msg_end(result); return result; }
void list_append (list_t * list, lnode_t * node) { list_ins_before (list, node, &list->nilnode); }
static void TimerCalcNextRun(Timer *timer, lnode_t *node) { struct tm *newtime; Timer *CurTimer, *NextTimer; lnode_t *CurNode, *NextNode; newtime = localtime(&timer->lastrun); switch(timer->type) { case TIMER_TYPE_DAILY: newtime->tm_hour = 0; newtime->tm_min = 0; newtime->tm_sec = 0; newtime->tm_mday += 1; break; case TIMER_TYPE_WEEKLY: /* weekly and monthly timers can run at any time */ newtime->tm_mday += 7; break; case TIMER_TYPE_MONTHLY: newtime->tm_mon += 1; break; case TIMER_TYPE_INTERVAL: newtime->tm_sec += timer->interval; break; case TIMER_TYPE_COUNTDOWN: #if 0 if( me.now - timer->lastrun < timer->interval ) { timer->interval -= ( me.now - timer->lastrun ); timer->lastrun = me.now; continue; } #endif newtime->tm_sec += timer->interval; break; } timer->nextrun = mktime(newtime); if (list_count(timerlist) == 0) { /* the list is empty, insert at the top */ node = lnode_create_prepend(timerlist, timer); return; } else { if (!node) node = lnode_create(timer); else list_delete(timerlist, node); } /* now move though the timer list and insert this at the right order */ CurNode = list_first(timerlist); NextNode = list_next(timerlist, CurNode); while (CurNode != NULL) { if (CurNode) CurTimer = lnode_get(CurNode); if (NextNode) { /* if the NextNode is NULL, we are at the end of the list already */ NextTimer = lnode_get(NextNode); } else { /* if the timer is after the CurNode, then */ if (CurTimer->nextrun < timer->nextrun) /* insert it afterwards */ list_ins_after(timerlist, node, CurNode); else /* else insert it before */ list_ins_before(timerlist, node, CurNode); /* and exit the while loop */ break; } /* if the Curent Timer is going to run before this one */ if (CurTimer->nextrun < timer->nextrun) { /* and the next timer is also going to run before this one */ if (NextTimer->nextrun < timer->nextrun) { /* then Swap CurNode for NextNode */ CurNode = NextNode; /* and get a new NextNode */ NextNode = list_next(timerlist, CurNode); } else { /* otherwise insert it after the NextNode */ list_ins_after(timerlist, node, CurNode); break; } } else { /* its before CurTimer, so insert it beforehand */ list_ins_before(timerlist, node, CurNode); break; } } NextSchedule(); }