home *** CD-ROM | disk | FTP | other *** search
- /* -- File: line.c *
- -- *
- -- Author: Anthony Lander *
- -- Date: January 10, 1989. *
- -- *
- -- Description: *
- -- This library contains a rather complete set of functions for*
- -- creating and maintaining linked lists. *
- -- */
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <malloc.h>
- #include <memory.h>
- #include <string.h>
-
- #include "f_prot.h" /* Prototypes for all functions */
- #include "line.h" /* STRUCTs and #DEFINEs for LINE.C */
-
-
-
- struct _line *last_line = NULL; /* The last line in the linked list */
- struct _line *first_line = NULL; /* The first line in the list */
- /* Both NULL until initialized by */
- /* init_list() */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* ------------------------------------------------------------------------ */
- /* Function: Return the first line in the list */
- /* ------------------------------------------------------------------------ */
-
- struct _line *get_first_line()
- {
- return(first_line);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* ------------------------------------------------------------------------ */
- /* Function: Return the last line in the list */
- /* ------------------------------------------------------------------------ */
-
- struct _line *get_last_line()
- {
- return(last_line);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* ------------------------------------------------------------------------ */
- /* Function: Return a ptr to a line that's got space malloc()'ed for it */
- /* ------------------------------------------------------------------------ */
-
- /* -- Note: string is set to NULL. Length is set to 0. Prev and next are *
- -- set to NULL. *
- -- *
- -- takes: nothing *
- -- returns: NULL if there's no more memory *
- -- PTR to struct _line if a new line has been created *
- -- */
-
- struct _line *get_new_line()
- {
- struct _line *new_line;
-
- new_line = (struct _line *) malloc( sizeof(struct _line) );
-
- if(new_line == NULL) { /* malloc() failed */
- return(NULL);
- }
-
- /* Otherwise, NULL all of the pointers */
- new_line->string = NULL;
- new_line->length = 0;
- new_line->next_line = NULL;
- new_line->prev_line = NULL;
-
- return(new_line);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* ------------------------------------------------------------------------ */
- /* Function: Insert a line after another line. */
- /* ------------------------------------------------------------------------ */
-
- /* -- Takes: insert, a ptr with string, length, max_length set *
- -- correctly. after, a ptr to the line to add 'insert; *
- -- after. *
- -- Returns: None *
- -- *
- -- Notes: This function will set up the prev_line and next_line *
- -- pointers so that the inserted line will fit correctly in the *
- -- chain. It will also fix the last_line pointer, if needed. *
- -- */
-
- void insert_after_line(insert, after)
- struct _line *insert, /* line to insert */
- *after; /* line to insert it after */
- {
- /* -- if after is NULL, it means that we're creating the only line in *
- -- the list. Thus, we don't make an uplink for insert. *
- -- */
- if(after == NULL) {
- insert->prev_line = NULL;
- insert->next_line = NULL;
- first_line = insert;
- last_line = insert;
- return;
- }
-
- /* -- otherwise, we're inserting after an already existing line. *
- -- Check to see whether we're the new last line, and adjust *
- -- accordingly. *
- -- */
- insert->prev_line = after;
- insert->next_line = after->next_line;
- after->next_line = insert;
-
- if(insert->next_line == NULL) {
- last_line = insert;
- }
- /* if NOT the last line in the list, then set after->next's prev_line */
- else {
- (insert->next_line)->prev_line = insert;
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* ------------------------------------------------------------------------ */
- /* Function: Insert one line before another line */
- /* ------------------------------------------------------------------------ */
-
- /* -- Takes: insert, a ptr with string, length, max_length set *
- -- correctly. before, a ptr to the line to add 'insert' *
- -- before. *
- -- *
- -- Returns: None *
- -- *
- -- Notes: This function will set up the prev_line and next_line *
- -- pointers so that the inserted line will fit correctly in the *
- -- chain. It will also fix the first_line pointer if needed. *
- -- */
-
- void insert_before_line(insert, before)
- struct _line *insert, /* line to insert */
- *before; /* line to insert 'insert' before */
- {
-
- /* -- if before is NULL then we're creating the only line in the list. *
- -- Set up first_line and last_line, as well as insert's prev_line *
- -- and next_line links. *
- -- */
- if(before == NULL) {
- insert->prev_line = NULL;
- insert->next_line = NULL;
- last_line = insert;
- first_line = insert;
- return;
- }
-
-
- /* -- otherwise we're in the middle, so set insert's next and prev *
- -- pointers like this.... *
- -- */
- insert->next_line = before;
- insert->prev_line = before->prev_line;
-
-
- /* set before's prev pointer */
- before->prev_line = insert;
-
- /* if (insert->prev_line) is NULL, then it's the new start of the list */
- if(insert->prev_line == NULL) {
- first_line = insert;
- }
-
- /* Otherwise, reset (insert->prev_line)->next_line's pointer */
- else {
- (insert->prev_line)->next_line = insert;
- }
-
- /* Now set up (insert->prev_line)'s next_line link */
- if(insert->prev_line != NULL)
- (insert->prev_line)->next_line = insert;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* ------------------------------------------------------------------------ */
- /* Function: Delete a line from the list */
- /* ------------------------------------------------------------------------ */
-
- /* -- Takes: line to delete *
- -- Returns: nothing -- better be sure to pass a valid pointer! *
- -- *
- -- Notes: If you delete the first or last line, the first_ or last_ *
- -- line pointers will get updated *
- -- */
-
- void delete_line(delete)
- struct _line *delete;
- {
- /* -- SPECIAL CASE: The first and/or last line of the list. *
- -- These special cases are treated differently *
- -- so that we can deal with thier NULL pointers *
- -- in either prev_line, or next_line. *
- -- */
- if(delete == first_line || delete == last_line) {
-
- /* -- If we're the first line, and not the only line, then make *
- -- the next line the new first line. *
- -- */
- if((delete == first_line) && (delete->next_line != NULL))
- (delete->next_line)->prev_line = NULL;
-
- /* -- Test to see if we're (possibly also) the last line in the *
- -- list, but make sure we're not the only line in the list. *
- -- */
- if((delete == last_line) && (delete->prev_line != NULL))
- (delete->prev_line)->next_line = NULL;
- }
-
- /* OTHERWISE we're in the middle, so patch all links normally */
- else {
- (delete->prev_line)->next_line = delete->next_line;
- (delete->next_line)->prev_line = delete->prev_line;
- }
-
- /* -- now free the structure, but first release the string space *
- -- if it's been allocated. *
- -- */
-
- if(delete->string != NULL)
- free(delete->string);
-
-
- /* See if we have to adjust first_line and last_line */
- if(delete == first_line)
- first_line = delete->next_line;
-
- if(delete == last_line)
- last_line = delete->prev_line;
-
-
- free(delete);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* ------------------------------------------------------------------------ */
- /* Function: Delete all lines in the list */
- /* ------------------------------------------------------------------------ */
-
- /* -- Takes: Nothing *
- -- Returns: Nothing *
- -- *
- -- Notes: This goes through the list, starting at the top, and deletes *
- -- all of the lines (and strings in lines) until it gets to the *
- -- bottom. *
- -- */
-
- void delete_all_lines()
- {
- while(first_line != NULL) {
- if(first_line->string != NULL)
- free(first_line->string);
-
- free(first_line);
- first_line = first_line->next_line;
- }
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* ------------------------------------------------------------------------ */
- /* Function: Move a line before another line */
- /* ------------------------------------------------------------------------ */
-
- /* -- Takes: PTR to line to move. *
- -- PTR to line to move it before. *
- -- Returns: nothing. *
- -- *
- -- Notes: move_before just calls insert_before_line() and delete() *
- -- */
-
- void move_before_line(move, before)
- struct _line *move, /* Line to move */
- *before; /* Line to move it before (ahead of) */
- {
- struct _line *temp;
-
- temp = get_new_line();
- memcpy(temp, move, sizeof(struct _line));
-
- /* Now make a copy of move->string, 'cuz temp just has the address */
- temp->string = malloc(strlen(move->string)+1);
- strcpy(temp->string, move->string);
-
- /* make temp's *_line links point to NULL */
- temp->prev_line = NULL;
- temp->next_line = NULL;
-
- delete_line(move);
- insert_before_line(temp, before);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- /* ------------------------------------------------------------------------ */
- /* Function: Move a line after another line */
- /* ------------------------------------------------------------------------ */
-
- /* -- Takes: PTR to line to move. *
- -- PTR to line to move it after. *
- -- Returns: nothing. *
- -- *
- -- Notes: move_after just calls insert_after_line() and delete() *
- -- */
-
- void move_after_line(move, after)
- struct _line *move, /* line to move */
- *after; /* line to move after (follow) */
- {
- struct _line *temp;
-
- temp = get_new_line();
- memcpy(temp, move, sizeof(struct _line));
-
- /* Now make a copy of move->string, because temp just has the address */
- temp->string = malloc(strlen(move->string)+1);
- strcpy(temp->string, move->string);
-
- /* make temp's chains point to NULL */
- temp->prev_line = NULL;
- temp->next_line = NULL;
-
- delete_line(move);
- insert_after_line(temp, after);
- }
-
-