ref: 769b10f0ceafba306a3b53bee27f633e67ab11d3
dir: /util.c/
#include "inc.h"
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;
}