shithub: lola

ref: 9c38a9649a00dd85689f55a1eef23a14cf5a82e3
dir: /util.c/

View raw version
#include "inc.h"

/* Center rect s in rect r */
Rectangle
centerrect(Rectangle r, Rectangle s)
{
	int dx = (Dx(r) - Dx(s))/2;
	int dy = (Dy(r) - Dy(s))/2;
	return rectaddpt(Rect(0, 0, Dx(s), Dy(s)), Pt(r.min.x+dx, r.min.y+dy));
}

void
borderTL(Image *img, Rectangle r, Image *c)
{
	// left
	draw(img, Rect(r.min.x, r.min.y, r.min.x+1, r.max.y),
		c, nil, ZP);
	// top
	draw(img, Rect(r.min.x, r.min.y, r.max.x, r.min.y+1),
		c, nil, ZP);
}

void
borderBR(Image *img, Rectangle r, Image *c)
{
	// bottom
	draw(img, Rect(r.min.x, r.max.y-1, r.max.x, r.max.y),
		c, nil, ZP);
	// right
	draw(img, Rect(r.max.x-1, r.min.y, r.max.x, r.max.y),
		c, nil, ZP);
}

void
winborder(Image *img, Rectangle r, Image *c1, Image *c2)
{
	borderTL(img, r, c1);
	borderBR(img, r, c2);
}


void
panic(char *s)
{
	fprint(2, "error: %s: %r\n", s);
	threadexitsall("error");
}

void*
emalloc(ulong size)
{
	void *p;

	p = malloc(size);
	if(p == nil)
		panic("malloc failed");
	memset(p, 0, size);
	return p;
}

void*
erealloc(void *p, ulong size)
{
	p = realloc(p, size);
	if(p == nil)
		panic("realloc failed");
	return p;
}

char*
estrdup(char *s)
{
	char *p;

	p = malloc(strlen(s)+1);
	if(p == nil)
		panic("strdup failed");
	strcpy(p, s);
	return p;
}

/* Handle backspaces in a rune string.
 * Set number of final runes,
 * return number of runes to be deleted initially */
int
handlebs(Stringpair *pair)
{
	int initial;
	Rune *start, *rp, *wp;
	int i;

	initial = 0;
	start = rp = wp = pair->s;
	for(i = 0; i < pair->ns; i++){
		if(*rp == '\b'){
			if(wp == start)
				initial++;
			else
				wp--;
		}else
			*wp++ = *rp;
		rp++;
	}
	pair->ns = wp - start;
	return initial;
}


void
cnvsize(RuneConvBuf *cnv, int nb)
{
	cnv->nb = nb;
	if(cnv->maxbuf < nb+UTFmax){
		cnv->maxbuf = nb+UTFmax;
		cnv->buf = erealloc(cnv->buf, cnv->maxbuf);
	}
}

int
r2bfill(RuneConvBuf *cnv, Rune *rp, int nr)
{
	int i;
	for(i = 0; cnv->n < cnv->nb && i < nr; i++)
		cnv->n += runetochar(&cnv->buf[cnv->n], &rp[i]);
	return i;
}
void
r2bfinish(RuneConvBuf *cnv, Stringpair *pair)
{
	int nb;

	nb = pair->ns;
	pair->ns = min(nb, cnv->n);
	memmove(pair->s, cnv->buf, pair->ns);
	cnv->n = max(0, cnv->n-nb);
	memmove(cnv->buf, cnv->buf+nb, cnv->n);
}

// TODO: not sure about the signature of this...
// maybe pass in allocated pair?
// don't include null runes
Stringpair
b2r(RuneConvBuf *cnv)
{
	Stringpair pair;
	Rune *rp;
	int i;

	rp = runemalloc(cnv->n);
	pair.s = rp;
	pair.ns = 0;
	i = 0;
	// TODO: optimize this
	// we know there are full runes until the end
	while(fullrune(cnv->buf+i, cnv->n-i)){
		i += chartorune(rp, cnv->buf+i);
		if(*rp){
			rp++;
			pair.ns++;
		}
	}
	memmove(cnv->buf, cnv->buf+i, cnv->n-i);
	cnv->n -= i;

	return pair;
}

int
qadd(Queue *q, char *data)
{
	if(q->full)
		return 0;
	q->q[q->wi++] = data;
	q->wi %= nelem(q->q);
	q->full = q->wi == q->ri;
	return 1;
}

char*
qget(Queue *q)
{
	char *data;

	data = q->q[q->ri++];
	q->ri %= nelem(q->q);
	q->full = FALSE;
	return data;
}

int
qempty(Queue *q)
{
	return q->ri == q->wi && !q->full;
}