IoList *IoList_rawClone(IoList *proto) { IoObject *self = IoObject_rawClonePrimitive(proto); IoObject_tag_(self, IoObject_tag(proto)); IoObject_setDataPointer_(self, List_clone(DATA(proto))); return self; }
List * List_prependList(List * list, List * prePendList) { ListIterator * prependIterator; void * data; List * newList; if(list == NULL || prePendList == NULL) return NULL; newList = List_clone(list); prependIterator = ListIterator_create(prePendList); data = ListIterator_seekToLast(prependIterator); while(data != NULL) { List_addFront(newList, data); data = ListIterator_previousItem(prependIterator); } ListIterator_destroy(prependIterator); return newList; }
static List * List_clone(List * list) { if(list == NULL) return NULL; List * ret = List_createNode_sol(list->str); ret->next = List_clone(list->next); return ret; }
List * List_insertList(List * list, int position, List * insertList) { ListIterator * newIterator; ListIterator * insertIterator; void * data; List * newList; if(list == NULL || insertList == NULL) return NULL; if(position < 0 || position > List_getLength(list)) return NULL; if(position == 0) return List_prependList(list, insertList); if(position == List_getLength(list)) return List_appendList(list, insertList); newList = List_clone(list); newIterator = ListIterator_create(newList); insertIterator = ListIterator_create(insertList); if(ListIterator_seekToPosition(newIterator, position) == NULL) { ListIterator_destroy(newIterator); ListIterator_destroy(insertIterator); List_destroy(newList); return NULL; } data = ListIterator_seekToFirst(insertIterator); while(data != NULL) { if(!ListIterator_insertValue(newIterator, data)) { ListIterator_destroy(newIterator); ListIterator_destroy(insertIterator); List_destroy(newList); return NULL; } ListIterator_nextItem(newIterator); data = ListIterator_nextItem(insertIterator); } ListIterator_destroy(newIterator); ListIterator_destroy(insertIterator); return newList; }
List * List_appendList(List * list, List * appendList) { ListIterator * appendIterator; void * data; List * newList; if(list == NULL || appendList == NULL) return NULL; newList = List_clone(list); appendIterator = ListIterator_create(appendList); data = ListIterator_seekToFirst(appendIterator); while(data != NULL) { List_addBack(newList, data); data = ListIterator_nextItem(appendIterator); } ListIterator_destroy(appendIterator); return newList; }
static int test_merge(List * lhs, List * rhs, int (*compar)(const char *, const char *)) { int success = TRUE; // until proven otherwise // First make sure our lists are sorted... lhs = List_sort_sol(lhs, compar); rhs = List_sort_sol(rhs, compar); // What are we testing? printf("Testing List_merge(lhs, rhs, compar), where:\n\n"); printf("+ compar is: "); print_compar(compar); printf("\n"); printf("+ lhs is: "); List_print(lhs); printf("\n"); printf("+ rhs is: "); List_print(rhs); printf("\n"); // Check that the student doesn't reallocate nodes... store lhs/rhs pointers int len = List_length_sol(lhs) + List_length_sol(rhs); List * * nodeArr = malloc(len * sizeof(List *)); int ind = 0; List * node = NULL; node = lhs; while(node != NULL) { nodeArr[ind++] = node; node = node->next; } node = rhs; while(node != NULL) { nodeArr[ind++] = node; node = node->next; } // Clone lhs, rhs, and get the solution List * solution = List_merge_sol(List_clone(lhs), List_clone(rhs), compar); // Run the students code List * merged = List_merge(lhs, rhs, compar); printf("\nmerged is : "); List_print(merged); printf("\nsolution is: "); List_print(solution); printf("\n"); // Are we the correct length? int merged_len = List_length_sol(merged); if(merged_len != len) { printf("Error: merged solution has length %d, but it should be %d\n", merged_len, len); success = FALSE; } // Check the solution is in order, and that every Node pointer is in nodeArr List * sol_node = solution; node = merged; while(node != NULL && sol_node != NULL) { int found = FALSE; for(ind = 0; ind < len && !found; ++ind) found = (nodeArr[ind] == node); if(!found) { printf("Error: merged list contained a node with pointer %p; \n" "however, this pointer was not in either of the inputs.\n" "(i.e., 'lhs', or 'rhs'.) You must not create or destroy\n" "any nodes when writing the merge function.\n", node); success = FALSE; } if(strcmp(node->str, sol_node->str) != 0) { printf("Error: merged list not in order (!)\n"); success = FALSE; } sol_node = sol_node->next; node = node->next; } // Cleanup. free(nodeArr); List_destroy_sol(solution); List_destroy_sol(merged); return success; }