aoc-2019-c

Advent of Code 2019 Solutions in C
git clone https://git.sinitax.com/sinitax/aoc-2019-c
Log | Files | Refs | README | sfeed.txt

util.c (2457B)


      1#include "util.h"
      2#include "aoc.h"
      3
      4#include <ctype.h>
      5#include <stdint.h>
      6#include <stdio.h>
      7
      8void
      9die(const char *fmtstr, ...)
     10{
     11	va_list ap;
     12
     13	va_start(ap, fmtstr);
     14	fprintf(stderr, "\n");
     15	vfprintf(stderr, fmtstr, ap);
     16	fprintf(stderr, "\n");
     17	va_end(ap);
     18
     19	abort();
     20}
     21
     22bool
     23readtok(char *buf, size_t buflen, char sep, const char **pos, const char *end)
     24{
     25	const char *c;
     26	size_t len;
     27
     28	if (*pos >= end)
     29		return false;
     30
     31	len = 0;
     32	for (c = *pos; c != end && *c != sep; c++) {
     33		if (len == buflen) die("util: readline: no space");
     34		buf[len++] = *c;
     35	}
     36
     37	if (len == buflen)
     38		die("util: readline: no space");
     39	buf[len++] = '\0';
     40	*pos = c + 1;
     41
     42	return true;
     43}
     44
     45int64_t
     46parsei64(const char *str)
     47{
     48	int64_t val;
     49	char *end;
     50
     51	val = strtoll(str, &end, 0);
     52	if (end && *end && !isspace(*end))
     53		die("util: parsei64: invalid %s", str);
     54
     55	return val;
     56}
     57
     58char *
     59aprintf(const char *fmtstr, ...)
     60{
     61	va_list ap, cpy;
     62	ssize_t nb;
     63	char *str;
     64
     65	va_copy(cpy, ap);
     66
     67	va_start(cpy, fmtstr);
     68	nb = vsnprintf(NULL, 0, fmtstr, cpy);
     69	if (nb < 0) die("util: aprintf: invalid fmtstr: %s", fmtstr);
     70	va_end(cpy);
     71
     72	str = malloc((size_t) nb + 1);
     73	if (!str) die("util: aprintf: malloc %lu", nb + 1);
     74
     75	va_start(ap, fmtstr);
     76	nb = vsnprintf(str, (size_t) nb + 1, fmtstr, ap);
     77	va_end(ap);
     78
     79	return str;
     80}
     81
     82char *
     83strdup(const char *str)
     84{
     85	char *alloc;
     86
     87	alloc = malloc(strlen(str) + 1);
     88	strcpy(alloc, str);
     89
     90	return alloc;
     91}
     92
     93char *
     94apprintf(char *str, const char *fmtstr, ...)
     95{
     96	va_list ap, cpy;
     97	ssize_t nb;
     98	size_t len;
     99
    100	len = str ? strlen(str) : 0;
    101
    102	va_copy(cpy, ap);
    103
    104	va_start(cpy, fmtstr);
    105	nb = vsnprintf(NULL, 0, fmtstr, cpy);
    106	if (nb < 0) die("util: aprintf: invalid fmtstr: %s", fmtstr);
    107	va_end(cpy);
    108
    109	str = realloc(str, len + (size_t) nb + 1);
    110	if (!str) die("util: aprintf: realloc %lu", nb + 1);
    111
    112	va_start(ap, fmtstr);
    113	nb = vsnprintf(str + len, (size_t) nb + 1, fmtstr, ap);
    114	va_end(ap);
    115
    116	return str;
    117}
    118
    119void *
    120memdup(const void *data, size_t size)
    121{
    122	void *new;
    123
    124	new = malloc(size);
    125	if (!new) die("util: memdup: malloc %lu", size);
    126	memcpy(new, data, size);
    127	return new;
    128}
    129
    130void
    131readall(FILE *file, void **data, size_t *size)
    132{
    133	ssize_t pos;
    134
    135	fseek(file, 0, SEEK_END);
    136	pos = ftell(file);
    137	if (pos < 0) die("util: readall: ftell");
    138	*size = (size_t) pos;
    139	fseek(file, 0, SEEK_SET);
    140
    141	*data = malloc(*size);
    142	if (!*data) die("util: readall: malloc %lu", *size);
    143
    144	if (fread(*data, 1, *size, file) != *size)
    145		die("util: readall: incomplete");
    146}