#include "common.h"
void* alloc(size_t size) {
void *p = calloc(1, size);
if (!p) DIE("cannot allocate %llu bytes of memory", (unsigned long long)size);
return p;
}
void* alloc2d(size_t cnt, size_t size) {
if (cnt < 0) return NULL;
size_t ps = cnt*sizeof(void*);
char **p = (char**)alloc(ps + cnt*size);
char *d = ((char*)p) + ps;
if (size) for(size_t i = 0; i < cnt; ++i) p[i] = d + i*size;
return p;
}
char* vstrprintf(const char *fmt, va_list args) {
va_list copy;
va_copy(copy, args);
int size = vsnprintf(NULL, 0, fmt, copy);
va_end(copy);
if (size < 0) size = 0;
++size;
char *buf = alloc(size+1);
vsnprintf(buf, size, fmt, args);
return buf;
}
char* strprintf(const char *format, ...) {
va_list args;
va_start(args,format);
char* s = vstrprintf(format, args);
va_end(args);
return s;
}
char* unquote(char *s, char prefix, char suffix) {
char *s0 = NULL, *s1 = s;
for(char *c = s; *c; ++c) {
if (isspace(*c)) continue;
if (!s0) s0 = c;
s1 = c+1;
}
if (!s0) s0 = s;
if (s0 < s1 && *s0 == prefix) ++s0;
if (s0 < s1 && *(s1-1) == suffix) --s1;
memmove(s, s0, s1 - s0);
s[s1-s0] = 0;
return s;
}
char* readline(FILE *f) {
size_t len = 0, blen = 1024;
char *buf = alloc(blen+1);
while(1) {
int ch = fgetc(f);
if (ch <= 0 || ch == '\n')
break;
if (len+1 >= blen) {
size_t bl = blen + blen/8;
buf = realloc(buf, bl);
if (!buf) DIE("cannot re-allocate %llu bytes of memory", (unsigned long long)bl);
memset(buf + blen, 0, bl - blen);
blen = bl;
}
buf[len++] = ch;
}
buf[len++] = 0;
buf = realloc(buf, len);
if (!buf) DIE("cannot re-allocate %llu bytes of memory", (unsigned long long)len);
return buf;
}
void cubicto(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3, int levels) {
if (--levels <= 0) { lineTo(x3, y3); return; }
double xx0 = (x0 + x1)/2, yy0 = (y0 + y1)/2;
double xx1 = (x1 + x2)/2, yy1 = (y1 + y2)/2;
double xx2 = (x2 + x3)/2, yy2 = (y2 + y3)/2;
double xxx0 = (xx0 + xx1)/2, yyy0 = (yy0 + yy1)/2;
double xxx1 = (xx1 + xx2)/2, yyy1 = (yy1 + yy2)/2;
double xxxx = (xxx0 + xxx1)/2, yyyy = (yyy0 + yyy1)/2;
cubicto(x0, y0, xx0, yy0, xxx0, yyy0, xxxx, yyyy, levels);
cubicto(xxxx, yyyy, xxx1, yyy1, xx2, yy2, x3, y3, levels);
}