/** * list1.c * One wrapped implementation of lists. */ // +---------+-------------------------------------------------------- // | Headers | // +---------+ #include #include #include #include "node.h" #include "list.h" #ifdef UNIT_TESTS #include "utest.h" #endif // +-------+---------------------------------------------------------- // | Types | // +-------+ struct list { struct node *head; // The first element struct node *tail; // The last element int size; // The number of elements }; // +---------+-------------------------------------------------------- // | Globals | // +---------+ #ifdef UNIT_TESTS static int errors; #endif // +-----------------+------------------------------------------------ // | Basic Functions | // +-----------------+ struct list *new_list () { struct list *result; result = malloc (sizeof (struct list)); if (result != NULL) { result->head = NULL; result->tail = NULL; result->size = 0; } return result; } // new_list char * list_first (struct list *lst) { if (lst->head == NULL) return NULL; else return lst->head->data; } // list_first char * list_last (struct list *lst) { if (lst->tail == NULL) return NULL; else return lst->tail->data; } // list_last int list_length (struct list *lst) { return lst->size; } // list_length void list_print (struct list *lst, FILE *fp) { np_print (lst->head, fp); } // list_print int list_append (struct list *lst, char *str) { struct node *newnode = cons (str, NULL); if (newnode == NULL) return 0; if (lst->size == 0) { lst->head = newnode; lst->tail = newnode; } else { set_cdr (lst->tail, newnode); lst->tail = newnode; } ++(lst->size); return 1; } // list_append int list_prepend (struct list *lst, char *str) { struct node *newnode = cons (str, lst->head); if (newnode == NULL) return 0; lst->head = newnode; if (lst->size == 0) lst->tail = newnode; ++(lst->size); return 1; } // list_prepend int list_delete (struct list *lst, char *str) { struct node *previous; struct node *deleteme; // Special case: Empty list if (lst->head == NULL) return 0; // Special case: Deleting first element if (strcmp (lst->head->data, str) == 0) { deleteme = lst->head; lst->head = deleteme->next; free (deleteme); --(lst->size); return 1; } previous = lst->head; while ( (previous->next != NULL) && (strcmp (previous->next->data, str) != 0) ) previous = previous->next; if (previous->next == NULL) return 0; deleteme = previous->next; previous->next = deleteme->next; // Special case: Deleting last element if (deleteme == lst->tail) lst->tail = previous; free (deleteme); --(lst->size); return 1; } // list_delete int list_contains (struct list *lst, char *str) { struct node *um = lst->head; // Look at all of the data points (that is, the data in the node) // String compare that data to str while ( (um != NULL) && (strcmp (um->data, str) != 0) ) um = um->next; return (um != NULL); // Real C: return um; } // list_contains // +------------+----------------------------------------------------- // | Unit Tests | // +------------+ #ifdef UNIT_TESTS int main () { struct node *np = NULL; CHECK_INT (is_null (np), 1); fprintf (stderr, "%d errors encountered.\n", errors); return errors; } // main #endif // UNIT_TESTS