/* * freeItemDataStruct * ---------------------------------- * * Unallocates a void* data interpreting it as an ItemData*. * * @item --------------------> Void* to interpret as ItemData* and unallocate. * * @return ------------------> None. * */ void freeItemDataStruct( void* item ){ ItemData* i = (ItemData*)item; if( i == NULL ){ return; } unallocate( i->author ); unallocate( i->title ); // numCopies gets taken care of when full struct is unallocated ListNode* nodeToDelete = i->patronsCurrentlyRenting; while( nodeToDelete != NULL ){ ListNode* next = nodeToDelete->next; // Get data, its a pointer to a ListNode containing an patron PatronData* patronToCollectFrom = (PatronData*)((ListNode*) nodeToDelete->data)->data; // find listnode with data address of p deleteNode( &patronToCollectFrom->itemsCurrentlyRenting, findNodeWithData( patronToCollectFrom->itemsCurrentlyRenting, i ), NULL ); unallocate( nodeToDelete ); nodeToDelete = next; } unallocate( i ); }
/* * deleteNode * ---------------------------------- * * Frees the existing specified ListNode, calling freeVoidDataFunction * which properly unallocates its void* data. * * @currentHead -------------> List to delete node from. * @nodeToDelete ------------> Node that we want to delete. * @freeVoidDataFunction ----> Function pointer which determines how to clean up node's void* data. * * @return ------------------> _Bool indicating success or failure. * */ _Bool deleteNode( ListNode** currentHead, ListNode* nodeToDelete, void(*freeVoidDataFunction)(void* data) ){ // The address of the outside variable is NULL??? // or its an empty list or nodeToDelete is null if( currentHead == NULL || *currentHead == NULL || nodeToDelete == NULL ){ return 0; } // special case if head is node to delete if( *currentHead == nodeToDelete ){ // take out of list // if only element in list next is null // when outside ptr is dereferenced goes to ptr to next *currentHead = nodeToDelete->next; // delete everything related to nodeToDelete // if null then void* data is just a pointer to ListNode // so no special freeing is needed if( freeVoidDataFunction != NULL ){ (*freeVoidDataFunction)(nodeToDelete->data); } unallocate( nodeToDelete ); return 1; } ListNode* nodeToCheck = *currentHead; while( nodeToCheck != NULL ){ ListNode* nextNode = nodeToCheck->next; if( nextNode == nodeToDelete ){ // take nextNode out of list nodeToCheck->next = nextNode->next; // if null then void* data is just a pointer // so no special freeing is needed if( freeVoidDataFunction != NULL ){ (*freeVoidDataFunction)(nextNode->data); } unallocate( nextNode ); return 1; } nodeToCheck = nextNode; } return 0; }
/** * Iterate through the LL deallocating ll nodes. * * @param db - database linked list to deallocate */ void deallocate_db( dbentry* db ) { dbentry* curr = db; dbentry* next = NULL; while ( curr ) { next = curr->artist_next; unallocate(curr->artist); unallocate(curr->title); unallocate(curr); curr = next; } }
int db_student_remove( db_database* db, char* id ) { int cmp; // Find student in the database db_student* student = db->students; while ( student != NULL ) { cmp = strcmp( student->id, id ); if ( cmp == 0 ) { break; } student = student->next; } // Student not found if ( student == NULL ) { return DBERR_STUDENT_NOT_EXISTS; } // Remove associated enrollments db_enrollment_remove_student( db, id ); // Remove student from the list if ( student->last == NULL && student->next == NULL ) { db->students = NULL; } else if ( student->last == NULL ) { db->students = student->next; student->next->last = NULL; } else if ( student->next == NULL ) { student->last->next = NULL; } else { student->last->next = student->next; student->next->last = student->last; } unallocate( student->name ); unallocate( student->id ); unallocate( student ); return 0; }
/* * freePatronDataStruct * ---------------------------------- * * Unallocates a void* data interpreting it as an PatronData*. * * @patron ------------------> Void* to interpret as PatronData* and unallocate. * * @return ------------------> None. * */ void freePatronDataStruct( void* patron ){ PatronData* p = (PatronData*)patron; if( p == NULL ){ return; } unallocate( p->name ); // pid gets taken care of when full struct is unallocated // unallocate the actual nodes of items currently renting // dont worry about the void* data in them because those point to // other item nodes that will take care of themselves ListNode* nodeToDelete = p->itemsCurrentlyRenting; while( nodeToDelete != NULL ){ ListNode* next = nodeToDelete->next; // this is a node // it has a void* data which contains an address of a listnode // whom contains a void* data to an item // go to this other listnode and cast its void* data to an item // within this item loop through its patronsCurrentlyrenting LL // find the node containg a void* data with the patrons address // delete this node // Get data, its a pointer to a ListNode containing an item ItemData* itemToReturn = (ItemData*)((ListNode*)nodeToDelete->data)->data; // find listnode with data address of p ListNode* pcr = itemToReturn->patronsCurrentlyRenting; deleteNode( &pcr, findNodeWithData( pcr, p ), NULL ); unallocate( nodeToDelete ); nodeToDelete = next; } unallocate( p ); }
char* trim(char* in) { char* input = allocate((INPUTLEN*sizeof(char))+1); if ( input == NULL ) { return NULL; } in[INPUTLEN] = '\0'; input[0] = '\0'; char* curr = strtok( in, WHITESPACE ); strncat(input, curr, strlen(curr)); curr = strtok( NULL, WHITESPACE ); while(NULL != curr) { strncat(input, " ", 1); strncat(input, curr, strlen(curr)); curr = strtok( NULL, WHITESPACE ); } int len = strlen(input); char *output = allocate((len*sizeof(char))+1); if ( output == NULL ) { unallocate( input ); return NULL; } strncpy(output,input,len+1); unallocate(input); return output; }
/** * Trim the input and limit it to a certain number of characters * given the action. * * @param in - Input to operation on. * @param action - action to limit for. * * @return pointer to newly allocated input */ char* trim_limit( char* in, inaction_t action ) { char *stripped = trim(in); if ( stripped == NULL ) { return NULL; } if (action == artists) { if ( strlen( stripped ) > 25 ) { char* limited = allocate((25*sizeof(char))+1); if ( limited == NULL ) { unallocate( stripped ); return NULL; } strncpy(limited, stripped, 25); limited[25] = '\0'; unallocate(stripped); return limited; } } else if (action == titles) { if ( strlen( stripped ) > 40 ) { char* limited = allocate((40*sizeof(char))+1); if ( limited == NULL ) { unallocate( stripped ); return NULL; } strncpy(limited, stripped, 40); limited[40] = '\0'; unallocate(stripped); return limited; } } return stripped; }
/** * Sort the list by artist and by title using qsort(...) * * @param alist - pointer to pointer of the artist head node. * @param tlist - pointer to pointer of the title head node. */ void sort( dbentry** alist, dbentry** tlist ) { dbentry* curr = *alist; int dblen = length( curr ); dbentry** dbItems = allocate(dblen * sizeof(dbentry*)); if ( !checkalloc( dbItems ) ) { *alist = NULL; *tlist = NULL; } // Copy linked list node pointers to db items for( int i = 0; NULL != curr; i++, curr = curr->artist_next ) { dbItems[i] = curr; } // Sort db items by artist name qsort( dbItems, dblen, sizeof( dbentry* ), artist_comp ); // reconstruct artist links in newly sorted values *alist = dbItems[0]; curr = dbItems[0]; for( int i = 1; i < dblen; i++ ) { curr->artist_next = dbItems[i]; curr = curr->artist_next; curr->artist_next = NULL; } /* Now sort db items by title name */ qsort( dbItems, dblen, sizeof( dbentry* ), title_comp ); // reconstruct title links innewly sorted values *tlist = dbItems[0]; curr = dbItems[0]; for( int i = 1; i < dblen; i++ ) { curr->title_next = dbItems[i]; curr = curr->title_next; curr->title_next = NULL; } unallocate(dbItems); return; }
void run(int buf, int col) { compute(buf, col); printf("\nBUFFER = %d\n", BUFF); printf("COLUMNS = %d\n", COLS); printf("ROWS = %d\n", ROWS); printf("FULL = %d\n", FULL); printf("END = %d\n", END); printf("SIZE = %d\n\n", SIZE); int *par = allocate(FULL); init_data(par); printf("\nINITIAL\n"); print(par); printf("\nSORTED\n"); pinsortc(par, nThreads); print(par); unallocate(par); }
/** * Read in the database file given, returning the head of the linked list. * * @param filename - filename/path to open. * * @return head element to the database linked list. */ dbentry* read_db(char *filename) { FILE *file_fd = fopen( filename, "r" ); dbentry* head = NULL; char *buffer = NULL; if (file_fd == NULL) { fputs(DB_FILE_ERROR,stderr); return NULL; } else { int count_n = 0; bool first = true; dbentry* curr = NULL; buffer = allocate(DB_INPUT_LIMIT*sizeof(char)); if ( !checkalloc(buffer) ) { fclose(file_fd); return NULL; } while ( !feof(file_fd) ) { if ( count_n == DB_SIZE_LIMIT ) { fputs( DB_TRUNK_ERROR, stderr ); break; } char *ret; /** Read all fields for this entry fom file */ ret = fgets(buffer, DB_INPUT_LIMIT, file_fd); if ( ret == NULL ) break; char *artist = trim_limit(buffer,artists); if (!checkalloc( artist )) { goto allocfail; } ret = fgets(buffer, DB_INPUT_LIMIT, file_fd); if ( ret == NULL ) break; char *title = trim_limit(buffer, titles); if ( !checkalloc( title ) ) { unallocate( artist ); goto allocfail; } ret = fgets(buffer, DB_INPUT_LIMIT, file_fd); if ( ret == NULL ) break; char ntracks = (char) atoi(buffer); ret = fgets(buffer, DB_INPUT_LIMIT , file_fd); if ( ret == NULL ) break; int time_m = 0; int time_s = 0; sscanf( buffer, "%d:%d", &time_m, &time_s ); /* make sure this isn't a duplicate */ if ( searchdb( head, artist, title ) ) { fprintf(stderr,"Duplicate entry: '%s' '%s'\n",artist, title); unallocate(artist); unallocate(title); continue; } /** create ll node to hold this entry */ curr = allocate(sizeof(dbentry)); if ( !checkalloc( curr ) ) { unallocate( artist ); unallocate( title ); goto allocfail; } curr->artist = artist; curr->title = title; curr->tracks = ntracks; curr->time_m = time_m; curr->time_s = time_s; curr->title_next = NULL; if ( first ) { /* Set the next pointer NULL so we know where the ll stops */ curr->artist_next = NULL; head = curr; first = false; } else { /* prepend to the head of the list */ curr->artist_next = head; head = curr; } count_n++; } unallocate(buffer); } fclose( file_fd ); return head; allocfail: unallocate(buffer); deallocate_db( head ); head = NULL; fclose(file_fd); return NULL; }