Mercurial > hg > early-roguelike
diff urogue/list.c @ 256:c495a4f288c6
Import UltraRogue from the Roguelike Restoration Project (r1490)
author | John "Elwin" Edwards |
---|---|
date | Tue, 31 Jan 2017 19:56:04 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/urogue/list.c Tue Jan 31 19:56:04 2017 -0500 @@ -0,0 +1,222 @@ +/* + list.c - Functions for dealing with linked lists of goodies + + UltraRogue: The Ultimate Adventure in the Dungeons of Doom + Copyright (C) 1985, 1986, 1992, 1993, 1995 Herb Chong + All rights reserved. + + Based on "Advanced Rogue" + Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka + All rights reserved. + + Based on "Rogue: Exploring the Dungeons of Doom" + Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman + All rights reserved. + + See the file LICENSE.TXT for full copyright and licensing information. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "rogue.h" + +static char errbuf[2 * LINELEN]; + +/* + ur_alloc() + ur_free() + + These are just calls to the system alloc and free, and they also adjust + the totals. The buffer is cleared out because idents need to be zero + before going into the pack, or they will be used as indices! +*/ + +void * +ur_alloc(size_t size) +{ + char *buf_p; + + total++; + + buf_p = mem_malloc(size); + + if (buf_p == NULL) + return(NULL); + + memset(buf_p,0,size); + + return(buf_p); +} + +void +ur_free(void *buf_p) +{ + mem_free(buf_p); + total--; +} + +/* + detach() + Takes an item out of whatever linked list it might be in + .... function needs to be renamed.... +*/ + +void +_detach(struct linked_list **list, struct linked_list *item) +{ + if (*list == item) + *list = next(item); + + if (prev(item) != NULL) + item->l_prev->l_next = next(item); + + if (next(item) != NULL) + item->l_next->l_prev = prev(item); + + item->l_next = NULL; + item->l_prev = NULL; +} + +/* + _attach() + add an item to the head of a list + ... this needs to be renamed as well ... +*/ + +void +_attach(struct linked_list **list, struct linked_list *item) +{ + if (*list != NULL) + { + item->l_next = *list; + (*list)->l_prev = item; + item->l_prev = NULL; + } + else + { + item->l_next = NULL; + item->l_prev = NULL; + } + + *list = item; +} + +/* + _attach_after() + + Attaches the given item after the supplied one in the list. If the listed + item is NULL, the new item is attached at the head of the list. +*/ + +void +_attach_after(linked_list **list_pp, linked_list *list_p, linked_list *new_p) +{ + if (list_p == NULL) + { + _attach(list_pp, new_p); /* stuff it at the beginning */ + return; + } + + if (next(list_p) != NULL) /* something after this one? */ + { + new_p->l_next = next(list_p); + list_p->l_next->l_prev = new_p; + } + else + new_p->l_next = NULL; + + list_p->l_next = new_p; + new_p->l_prev = list_p; +} + +/* + _free_list() + Throw the whole blamed thing away +*/ + +void +_free_list(linked_list **ptr) +{ + linked_list *item; + + while(*ptr != NULL) + { + item = *ptr; + *ptr = next(item); + discard(item); + } +} + +/* + discard() + free up an item +*/ + +void +discard(struct linked_list *item) +{ + throw_away(item->data.obj); + ur_free(item); +} + +/* + throw_away() + toss out something (like discard, but without the link_list) +*/ + +void +throw_away(struct object *ptr) +{ + free_ident(ptr); + ur_free(ptr); +} + +/* + new_item() + get a new item with a specified size +*/ + +struct linked_list * +new_item(int size) +{ + struct linked_list *item; + + if ((item = new_list()) == NULL) + msg("Ran out of memory for header after %d items.", total); + + if ((item->data.l_data = new_alloc(size)) == NULL) + msg("Ran out of memory for data after %d items.", total); + + item->l_next = item->l_prev = NULL; + + return(item); +} + +void * +new_alloc(size_t size) +{ + void *space = ur_alloc(size); + + if (space == NULL) + { + sprintf(errbuf, "Rogue ran out of memory."); + fatal(errbuf); + } + + return(space); +} + +struct linked_list * +new_list(void) +{ + union /* ugly_lint_hack */ + { + struct linked_list *ll; + void *vptr; + } newp; + + newp.vptr = mem_malloc(sizeof(struct linked_list)); + memset(newp.vptr,0,sizeof(struct linked_list)); + return(newp.ll); +}