wm: glendy

ref: d5c2af3bcb04031bd6f2724a480b9c7758eeacbb
dir: /util.c/

View raw version
#include "port.h"

#include "util.h"
#include "engine.h"

int
isnum(char *s, unsigned int n)
{
	if(strlen(s) < n)
		n = strlen(s);
	
	for(unsigned int i = 0 ; i < n ; i++)
	{
		if(s[i] > '9' || s[i] < '0')
			return 0;
	}
	return 1;
}

int
strtodir(char *s)
{
	int d;
	
	if(strcmp(s, "NE") == 0)
		d = NE;
	else if(strcmp(s, "E") == 0)
		d =  E;
	else if(strcmp(s, "SE") == 0)
		d = SE;
	else if(strcmp(s, "W") == 0)
		d =  W;
	else if(strcmp(s, "SW") == 0)
		d = SW;
	else if(strcmp(s, "NW") == 0)
		d = NW;
	else
		return Err;

	return d;
}

char*
dirtostr(int dir)
{
	switch(dir)
	{
		case NE:
			return "NE";
		case E:
			return "E";
		case SE:
			return "SE";
		case SW:
			return "SW";
		case W:
			return "W";
		case NW:
			return "NW";
		default:
			return nil;
	}
}

/* xx yy\0
static Point
parseput(char *s)
{
	int x, y;
	int len;
	
	x = atoi(s);
	s = strchr(s, ' ');
	if(end == nil)
	{
		dprint("parseput(): end nil\n");
		sysfatal("parseput(): incomplete line");
	}
	y = atoi(s);
	return Pt(x, y);
}
*/

Point
parseput(char *x, char *y)
{
	if(isnum(x, 2) != 1 && isnum(y, 2) != 1)
		sysfatal("parseput(): input isnt a number?");
	
	return Pt(atoi(x), atoi(y));
}

int
dprint(char *fmt, ...)
{
	va_list va;
	int n;

	if(!debug)
		return 0;
	
	va_start(va, fmt);
	n = vfprint(2, fmt, va);
	va_end(va);
	return n;
}

void*
emalloc(unsigned long n)
{
	void *p;

	p = malloc(n);
	if(p == nil)
		sysfatal("malloc: %r");
	
	return p;	
}
/* list */
int
lladd(List *last, void *data)
{
	List *temp;

	dprint("lladd(%p, %p)\n", last, data);
	
	if(last->next != nil)
	{
		dprint("lladd(): last->next != nil\n");
		return 0;
	}
	
	else
	{
		dprint("lladd(): adding a new entry\n");
		temp = llnew();
	
		last->next = temp;
		temp->data = data;
		return 1;
	}
}

void
llappend(List *first, void *data)
{
	List *temp, *last;

	dprint("llappend(%p, %p)\n", first, data);

	
	/* workaround for first entry */	
	if(first->data == nil)
		temp = first;
	else
	{
		for(last = first;
		last->next != nil  && last != last->next;
		last = last->next)
			;
		temp = llnew();
		last->next = temp;
	}

	temp->data = data;
}

List*
llnew(void)
{
	List *l;
	l = (List*)emalloc(sizeof(List));
	l->next = nil;
	l->data = nil;
		
	return l;
}

/* returns nth item from list  */
void*
lookup(List *l, int n)
{
	List *tmp;
	
	dprint("lookup(%p, %d)\n", l, n);
	/* cycles thru list if n > list size */
	for(tmp = l ; --n > 0 ; tmp = tmp->next)
		;
	
	return tmp->data;
}

/* quene */

void
qadd(Quene *q, void *data)
{	
	dprint("qadd(%p, %p)\n", q, data);
	
	q->len++;
	if(q->head == nil || q->tail == nil)
	{
		dprint("qadd(): q->head == nil || q->tail == nil\n");
		q->head = llnew();
		q->head->data = data;
		q->tail = q->head;
	}
	else
	{
		dprint("qadd(): q->head != nil && q->tail != nil\n");
		llappend(q->head, data);	
		q->tail = (q->tail->next == nil) ? q->tail : q->tail->next;
	}
}

/*
void
qnext(Quene *q)
{
	List *oldfirst;
	if(q->len-- == 0)
		sysfatal("qnext(): q->len == 0");
	
	oldfirst = q->head;
	
	// what??
	if(q->head == nil)
		q->head = q->head->next;
	
	if(q->tail == oldfirst)
		q->tail->data = nil;
		
	free(oldfirst);
}
*/

void
qnext(Quene *q)
{
	List *tmp;
	
	dprint("qnext(%p)\n", q);
	if(q->head == nil)
		return;
	
	tmp = q->head;
	q->head = q->head->next;
	 
	if(q->head == nil)
	    q->tail = nil;
	
	q->len--;
	free(tmp);
}

/* we don't free items, free stuff elsewhere */
void
qdel(Quene *q, List *item)
{
	List *prev = nil, *next;

	if(q->len == 0 || item == nil
	|| q->head == nil || q->tail == nil)
		return;

	
	/* we can't use lldel, because we can't update q->tail if l == q->tail */
	for(List *t = q->head ; t->next != nil  && t != t->next ; t = t->next)
	{
		/* maybe we should use memcmp */
		if(t == item)
		{
			next = t->next;

			/* these may be nil and that's fine */
			if(item == q->head)
				q->head = q->head->next;
			if(item == q->tail)
				q->tail = q->tail->next;

			if(prev != nil)
				prev->next = next;
		}

		prev = t;
	}
}