Blob Blame History Raw

#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);
}