#include <stdio.h>
#include <stdlib.h>
#include "aocutils.h"

int text2array(int **dst, const char *r) {
    int *a = malloc(sizeof *a);
    int na = 0, sa = 1;
    char *err;
    int v;
    for (;;) {
        if (na == sa) {
            int *tmp = realloc(a, (size_t)(2*sa)*sizeof *tmp);
            if (!tmp) exit(EXIT_FAILURE);
            a = tmp;
            sa *= 2;
        }
        v = (int)strtol(r, &err, 10);
        a[na++] = v;
        if (!*err) break;
        r = err;
    }
    *dst = a;
    return na;
}

size_t slurp(char **dst, const char *fn) {
    if (*dst) {
        fprintf(stderr, "slurp() must be called with a pointer to void!\n");
        exit(EXIT_FAILURE);
    }
    FILE *h = fopen(fn, "r");
    if (!h) {
        perror(fn);
        exit(EXIT_FAILURE);
    }

    int ch;
    char *tmp = malloc(512);
    size_t s = 512;
    size_t r = 0;
    while ((ch = fgetc(h)) != EOF) {
        if (r == s) {
            //grow tmp
            char *ttmp = realloc(tmp, (13*s)/8);
            if (ttmp) {
                tmp = ttmp;
                s = (13*s)/8;
            } else {
                free(tmp);
                return 0;
            }
        }
        tmp[r++] = (char)ch;
    }
    fclose(h);
    *dst = tmp;

    return r;
}

int max3(int a, int b, int c) {
    if (a > b) {
        if (a > c) return a;
        return c;
    } else {
        if (b > c) return b;
    }
    return c;
}

double fmax3(double a, double b, double c) {
    if (a > b) {
        if (a > c) return a;
        return c;
    } else {
        if (b > c) return b;
    }
    return c;
}

long max3l(long a, long b, long c) {
    if (a > b) {
        if (a > c) return a;
        return c;
    } else {
        if (b > c) return b;
    }
    return c;
}

int min3(int a, int b, int c) {
    if (a < b) {
        if (a < c) return a;
        return c;
    } else {
        if (b < c) return b;
    }
    return c;
}

double fmin3(double a, double b, double c) {
    if (a < b) {
        if (a < c) return a;
        return c;
    } else {
        if (b < c) return b;
    }
    return c;
}

long min3l(long a, long b, long c) {
    if (a < b) {
        if (a < c) return a;
        return c;
    } else {
        if (b < c) return b;
    }
    return c;
}
