#include #include #include #include "listlib.h" #define TRAV_INIT_SIZE 8 typedef struct list_struct { data_t item; struct list_struct *next; } list_t; static list_t endlist; static list_t *headptr = NULL; static list_t *tailptr = NULL; static list_t **travptrs = NULL; static int travptrs_size = 0; int accessdata(void) { /* return a nonnegative key if successful */ int i; list_t **newptrs; if (headptr == NULL) { /* can't access a completely empty list */ errno = EINVAL; return -1; } if (travptrs_size == 0) { /* first traversal */ travptrs = (list_t **)calloc(TRAV_INIT_SIZE, sizeof(list_t *)); if (travptrs == NULL) /* couldn't allocate space for traversal keys */ return -1; travptrs[0] = headptr; travptrs_size = TRAV_INIT_SIZE; return 0; } for (i = 0; i < travptrs_size; i++) { /* look for an empty slot for key */ if (travptrs[i] == NULL) { travptrs[i] = headptr; return i; } } newptrs = realloc(travptrs, 2*travptrs_size*sizeof(list_t *)); if (newptrs == NULL) /* couldn't expand the array of traversal keys */ return -1; travptrs = newptrs; travptrs[travptrs_size] = headptr; travptrs_size *= 2; return travptrs_size/2; } int adddata(data_t data) { /* allocate node for data and add to end of list */ list_t *newnode; int nodesize; nodesize = sizeof(list_t) + strlen(data.string) + 1; if ((newnode = (list_t *)(malloc(nodesize))) == NULL) /* couldn't add node */ return -1; newnode->item.time = data.time; newnode->item.string = (char *)newnode + sizeof(list_t); strcpy(newnode->item.string, data.string); newnode->next = NULL; if (headptr == NULL) headptr = newnode; else tailptr->next = newnode; tailptr = newnode; return 0; } int getdata(int key, data_t *datap) { /* copy next item and set datap->string */ list_t *t; if ( (key < 0) || (key >= travptrs_size) || (travptrs[key] == NULL) ) { errno = EINVAL; return -1; } if (travptrs[key] == &endlist) { /* end of list, set datap->string to NULL */ datap->string = NULL; travptrs[key] = NULL; return 0; /* reaching end of list natural condition, not an error */ } t = travptrs[key]; datap->string = (char *)malloc(strlen(t->item.string) + 1); if (datap->string == NULL) /* couldn't allocate space for returning string */ return -1; datap->time = t->item.time; strcpy(datap->string, t->item.string); if (t->next == NULL) travptrs[key] = &endlist; else travptrs[key] = t->next; return 0; } int freekey(int key) { /* free list entry corresponding to key */ if ( (key < 0) || (key >= travptrs_size) ) { /* key out of range */ errno = EINVAL; return -1; } travptrs[key] = NULL; return 0; }