/* llistlib.c */ /* Joe Simonson, Joey Lesh, and Todd Holloway */ /* Reads from a file and returns a linked list where * the nodes are structs which include next, current, * and the buffer. * Parameters: A FILE to read. */ #include #include #include #include "llistheader.h" char buf[200]; /*node *startNode;*/ /*///////////////////////////////////////////////////////////////////////////*/ /* Pur: createNode builds a new node whose contents are copied from the buffer. * Par: a buffer which is a string is passed. * Pre: there must exist a startNode. * Pos: a new node is created with its contents defined. * Pro: there could be a stack overflow if the buffer becomes too big. */ node *createNode(char *buffer) { struct node *current; char *currentline; /*Building the node and defining the value of its contents*/ current = (node *) malloc (sizeof(struct node)); currentline = (char *) malloc (strlen(buffer)+1); strcpy(currentline, buffer); current->contents = currentline; current->prior = NULL; current->tail = NULL; return current; }/* createNode(char)*/ /*///////////////////////////////////////////////////////////////////////////*/ /* Pur: Combines two lists * Par: two nodes, the first the start node of a list, the second a start node of a list to be added to the first list. * Pre: the nodes passed exist * Pos: the list specified by the second parameter is now linked at the * end of the list specified by the first parameter; the starting node * of this combined list is returned. * Pro: */ node *concat(node *initial_1, node *initial_2) { struct node *current; /* check for no initial list */ if (initial_1 == NULL) return initial_2; current = initial_1; while (current->tail != NULL) { current = current->tail; } current->tail = initial_2; initial_2->prior = current; return initial_1; } /*///////////////////////////////////////////////////////////////////////////*/ /* Pur: addNode will add a node after the node is passed. * Par: takes a buffer and a node which it will at a node after. * Pre: a list which at the very least contains a startNode. * Pos: a node is added after the node passed and all the pointers * are reassigned. * Pro: */ node *addNode(node *current, char *buffer){ node *newNode; if(current->tail == NULL) { newNode = createNode(buffer); newNode->prior = current; current->tail = newNode; newNode->tail = NULL; } else { newNode = createNode(buffer); newNode->prior = current; newNode->tail = current->tail; (newNode->tail)->prior = newNode; current->tail = newNode; } return newNode; }/*addNode(node)*/ /*///////////////////////////////////////////////////////////////////////////*/ /* Pur: deleteNode is passed a node which it will then remove from the list by * reassigning the pointers. It will then proceed to free both the * current node and the current node's contents. * Par: a node to be deleted. * Pre: there must exits a list which contains at least a startNode. * Pos: the tail and prior pointers are reassigned and the memory is freed. * Pro: if there is no list or if you try and delete an elment that is not in * the list. */ node *deleteNode(node *current, node *initialnode){ /* pre testing */ if (current != NULL) { if(current == initialnode) { (current->tail)->prior = NULL; initialnode = current->tail; free (current->contents); free (current); } else if(current->tail == NULL) { (current->prior)->tail = NULL; free (current->contents); free(current); } else { (current->prior)->tail = current->tail; (current->tail)->prior = current->prior; free(current->contents); free(current); } } return initialnode; }/*addNode(node)*/ /*///////////////////////////////////////////////////////////////////////////*/ /* Pur: getFirst finds the first element of the list for which the given * node is a part of. * Par: A node. * Pre: The node must exist. * Pos: The first node of the list is returned. * Pro: */ node *getFirst(node *a_node) { while (a_node->prior != NULL) a_node = a_node->prior; return a_node; } /*///////////////////////////////////////////////////////////////////////////*/ /* Pur: getLast finds the last element of the list for which the given * node is a part of. * Par: A node. * Pre: The node must exist. * Pos: The last node of the list is returned. * Pro: */ node *getLast(node *a_node) { while (a_node->tail != NULL) a_node = a_node->tail; return a_node; } /*///////////////////////////////////////////////////////////////////////////*/ /* Pur: exciseNode removes the given node from its list without deleting it, * then returns the node. * Par: A node. * Pre: The node must exist. * Pos: The nodes within the list no longer point to the specified node; the * node still exists, although it does not point to other nodes, and the * node is returned * Pro: Should not be used in place of delete, as the node remains in existence */ node *exciseNode(node *element) { if (element->tail) { if (element->prior) (element->prior)->tail = element->tail; (element->tail)->prior = element->prior; element->tail = NULL; } else if (element->prior) element->prior->tail = NULL; element->prior = NULL; element->tail = NULL; return element; } /*///////////////////////////////////////////////////////////////////////////*/ /* Pur: findNode searches for a node whose contents match the buffer which is * passed to the funtion. * Par: a buffer which is a pointer to a string. * Pre: there should exist a list that can be searched. * Pos: a node is found and then findNode returns that node. * Pro: */ node *findNode(char *buffer, node *initial_node_of_list){ node *current; current = initial_node_of_list; while(current != NULL) { if (strcmp(current->contents, buffer) == 0) return current; else current = current->tail; } return NULL; }/*findNode(char)*/ /*///////////////////////////////////////////////////////////////////////////*/ /* Pur: Prints to the screen the list, beginning with the given node and * ending at the end of the list. * Par: A node. * Pre: The node exists. * Pos: The linked list is printed to the screen. * Pro: */ void printLinkedList(node *current){ if (current != NULL) { while(current->tail != NULL) { printf("(%s) <-> ", current->contents); current = current->tail; }/*while*/ printf("(%s)", current->contents); printf(" END\n"); } else printf("ITS NULL stupid!\n"); }/*printLinkedList(node *)*/ /* writeListToFile(char *, node *) writes a list to the file. It first makes sure that it has the first node of the list and then progresses along the list until the end. The filename given will overwrite an existing file if allowed or will create a new file with the name pointed to by filename. Returns nothing. Pre: The file filename can be created or overwritten. Pre: listelement isn't null. Post: The file filename has been created or overwritten. */ void writeListToFile(char *filename, node *listelement) { FILE *fp; if ((fp = initialize(filename, "w")) != NULL) { listelement = getFirst(listelement); while (listelement != NULL) { if (0 == writeLine(fp, listelement->contents)) SPEW("ERROR: couldn't write to file!",""); listelement = listelement->tail; } fclose(fp); } }/* writeListToFile(char *, node *) */ /*///////////////////////////////////////////////////////////////////////////*/ /* Pur: readListFromFile reads a given file creating a linked list wherein * each line of the file exists as a node. * Par: the name of the file. * Pre: the file exists. * Pos: The first node of the new list is returned. * Pro: */ node *readListFromFile(char *filename) { int i = 0; char *linebuf; struct node *current; struct node *initial; FILE *fp = initialize(filename, "r"); linebuf = buf; /* initialize the first node */ if ((linebuf = readLine(fp, sizeof buf)) != NULL) { SPEW("in if", ""); initial = createNode(linebuf); current = initial; i++; } /* Our main loop that checks for EOF */ while((linebuf = readLine(fp, sizeof buf)) != NULL) { /* Copies the buffer into a memory location of the * appropriate size and then returns a pointer to the * location of that memory. */ current = addNode(current, linebuf); /*printf("Contents of current node: %s", current->contents); *printf("Contents of previous node: %s\n",previous->contents);*/ free(linebuf); i++; }/*while(!EOF)*/ /*printf("Contents of tail of tail of current node: %s", * ((cnp->tp)->tp)->hp); */ SPEW("Closing the file", ""); fclose(fp); SPEW("FILE closed", ""); printLinkedList(initial); return initial; }/*readLinkedList*/