#pragma once
#if !defined(UTILS_H)
#define UTILS_H

#include <errno.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/uio.h>
#include <syslog.h>
#include <unistd.h>

#define _pexit(s)                                                              \
  do {                                                                         \
    fprintf(stderr, "[pinns:e]: %s: %s\n", s, strerror(errno));                \
    _exit(EXIT_FAILURE);                                                       \
  } while (0)

#define pexit(s)                                                               \
  do {                                                                         \
    fprintf(stderr, "[pinns:e]: %s: %s\n", s, strerror(errno));                \
    exit(EXIT_FAILURE);                                                        \
  } while (0)

#define pexitf(fmt, ...)                                                       \
  do {                                                                         \
    fprintf(stderr, "[pinns:e]: " fmt ": %s\n", ##__VA_ARGS__,                 \
            strerror(errno));                                                  \
    exit(EXIT_FAILURE);                                                        \
  } while (0)

#define pwarn(s)                                                               \
  do {                                                                         \
    fprintf(stderr, "[pinns:w]: %s: %s\n", s, strerror(errno));                \
  } while (0)

#define pwarnf(fmt, ...)                                                       \
  do {                                                                         \
    fprintf(stderr, "[pinns:e]: " fmt ": %s\n", ##__VA_ARGS__,                 \
            strerror(errno));                                                  \
  } while (0)

#define nexit(s)                                                               \
  do {                                                                         \
    fprintf(stderr, "[pinns:e] %s\n", s);                                      \
    exit(EXIT_FAILURE);                                                        \
  } while (0)

#define nexitf(fmt, ...)                                                       \
  do {                                                                         \
    fprintf(stderr, "[pinns:e]: " fmt "\n", ##__VA_ARGS__);                    \
    exit(EXIT_FAILURE);                                                        \
  } while (0)

#define nwarn(s)                                                               \
  do {                                                                         \
    fprintf(stderr, "[pinns:w]: %s\n", s);                                     \
  } while (0);

#define nwarnf(fmt, ...)                                                       \
  do {                                                                         \
    fprintf(stderr, "[pinns:w]: " fmt "\n", ##__VA_ARGS__);                    \
  } while (0);

#define _cleanup_(x) __attribute__((cleanup(x)))

static inline void freep(void *p) { free(*(void **)p); }

static inline void closep(int *fd) {
  if (*fd >= 0)
    close(*fd);
  *fd = -1;
}

static inline void fclosep(FILE **fp) {
  if (*fp)
    fclose(*fp);
  *fp = NULL;
}

#define _cleanup_free_ _cleanup_(freep)
#define _cleanup_close_ _cleanup_(closep)
#define _cleanup_fclose_ _cleanup_(fclosep)

#endif /* !defined(UTILS_H) */
