#include "zsh.mdh"
#include "linklist.pro"
mod_export LinkList
newlinklist(void)
{
LinkList list;
list = (LinkList) zhalloc(sizeof *list);
list->list.first = NULL;
list->list.last = &list->node;
list->list.flags = 0;
return list;
}
mod_export LinkList
znewlinklist(void)
{
LinkList list;
list = (LinkList) zalloc(sizeof *list);
list->list.first = NULL;
list->list.last = &list->node;
list->list.flags = 0;
return list;
}
mod_export LinkNode
insertlinknode(LinkList list, LinkNode node, void *dat)
{
LinkNode tmp, new;
tmp = node->next;
node->next = new = (LinkNode) zhalloc(sizeof *tmp);
new->prev = node;
new->dat = dat;
new->next = tmp;
if (tmp)
tmp->prev = new;
else
list->list.last = new;
return new;
}
mod_export LinkNode
zinsertlinknode(LinkList list, LinkNode node, void *dat)
{
LinkNode tmp, new;
tmp = node->next;
node->next = new = (LinkNode) zalloc(sizeof *tmp);
new->prev = node;
new->dat = dat;
new->next = tmp;
if (tmp)
tmp->prev = new;
else
list->list.last = new;
return new;
}
mod_export LinkNode
uinsertlinknode(LinkList list, LinkNode node, LinkNode new)
{
LinkNode tmp = node->next;
node->next = new;
new->prev = node;
new->next = tmp;
if (tmp)
tmp->prev = new;
else
list->list.last = new;
return new;
}
mod_export void
insertlinklist(LinkList l, LinkNode where, LinkList x)
{
LinkNode nx;
nx = where->next;
if (!firstnode(l))
return;
where->next = firstnode(l);
l->list.last->next = nx;
l->list.first->prev = where;
if (nx)
nx->prev = lastnode(l);
else
x->list.last = lastnode(l);
}
mod_export void *
getlinknode(LinkList list)
{
void *dat;
LinkNode node;
if (!(node = firstnode(list)))
return NULL;
dat = node->dat;
list->list.first = node->next;
if (node->next)
node->next->prev = &list->node;
else
list->list.last = &list->node;
zfree(node, sizeof *node);
return dat;
}
mod_export void *
ugetnode(LinkList list)
{
void *dat;
LinkNode node;
if (!(node = firstnode(list)))
return NULL;
dat = node->dat;
list->list.first = node->next;
if (node->next)
node->next->prev = &list->node;
else
list->list.last = &list->node;
return dat;
}
mod_export void *
remnode(LinkList list, LinkNode nd)
{
void *dat;
nd->prev->next = nd->next;
if (nd->next)
nd->next->prev = nd->prev;
else
list->list.last = nd->prev;
dat = nd->dat;
zfree(nd, sizeof *nd);
return dat;
}
mod_export void *
uremnode(LinkList list, LinkNode nd)
{
void *dat;
nd->prev->next = nd->next;
if (nd->next)
nd->next->prev = nd->prev;
else
list->list.last = nd->prev;
dat = nd->dat;
return dat;
}
mod_export void
freelinklist(LinkList list, FreeFunc freefunc)
{
LinkNode node, next;
for (node = firstnode(list); node; node = next) {
next = node->next;
if (freefunc)
freefunc(node->dat);
zfree(node, sizeof *node);
}
zfree(list, sizeof *list);
}
mod_export int
countlinknodes(LinkList list)
{
LinkNode nd;
int ct = 0;
for (nd = firstnode(list); nd; incnode(nd), ct++);
return ct;
}
mod_export void
rolllist(LinkList l, LinkNode nd)
{
l->list.last->next = firstnode(l);
l->list.first->prev = lastnode(l);
l->list.first = nd;
l->list.last = nd->prev;
nd->prev = &l->node;
l->list.last->next = 0;
}
mod_export LinkList
newsizedlist(int size)
{
LinkList list;
LinkNode node;
list = (LinkList) zhalloc(sizeof *list + (size * sizeof *node));
list->list.first = &list[1].node;
for (node = firstnode(list); size; size--, node++) {
node->prev = node - 1;
node->next = node + 1;
}
list->list.last = node - 1;
list->list.first->prev = &list->node;
node[-1].next = NULL;
return list;
}
mod_export LinkNode
linknodebydatum(LinkList list, void *dat)
{
LinkNode node;
for (node = firstnode(list); node; incnode(node))
if (getdata(node) == dat)
return node;
return NULL;
}
mod_export LinkNode
linknodebystring(LinkList list, char *dat)
{
LinkNode node;
for (node = firstnode(list); node; incnode(node))
if (!strcmp((char *)getdata(node), dat))
return node;
return NULL;
}
mod_export char **
hlinklist2array(LinkList list, int copy)
{
int l = countlinknodes(list);
char **ret = (char **) zhalloc((l + 1) * sizeof(char *)), **p;
LinkNode n;
for (n = firstnode(list), p = ret; n; incnode(n), p++) {
*p = (char *) getdata(n);
if (copy)
*p = dupstring(*p);
}
*p = NULL;
return ret;
}
mod_export char **
zlinklist2array(LinkList list)
{
int l = countlinknodes(list);
char **ret = (char **) zalloc((l + 1) * sizeof(char *)), **p;
LinkNode n;
for (n = firstnode(list), p = ret; n; incnode(n), p++) {
*p = ztrdup((char *) getdata(n));
}
*p = NULL;
return ret;
}