/****************************************************************************
 * util.[ch]: Miscellaneous generic utility functions, defs, and macros.
 *
 * If you want the error handlers to mention program name, call set_prog_name
 * at the beginning of your program.
 ****************************************************************************/

#ifndef UTIL_H
#define UTIL_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>

/* Types */

#undef boolean
#undef FALSE
#undef TRUE

#define boolean int
#define FALSE  0
#define TRUE   1

typedef char       int8;
typedef short      int16;
typedef int        int32;
typedef long long  int64;

typedef unsigned char       uint8;
typedef unsigned short      uint16;
typedef unsigned int        uint32;
typedef unsigned long long  uint64;

/* Macros */

#define STR_EQUAL(a,b)          (strcmp((a),(b)) == 0)
#define STR_EQUAL_I(a,b)        (strcasecmp((a),(b)) == 0)
#define STR_STARTS_WITH(a,b)    (strncmp((a),(b),strlen(b)) == 0)
#define STR_STARTS_WITH_I(a,b)  (strncasecmp((a),(b),strlen(b)) == 0)
#define IS_EMPTY_STRING(s)      ((s)[0] == '\0')

#undef MIN
#undef MAX

#define MIN(x,y)   ((x) < (y) ? (x) : (y))
#define MAX(x,y)   ((x) > (y) ? (x) : (y))

#define ROUND(x)   (int32)((x) + 0.5)

/* Prototypes */

char*    dgets(FILE* f);
char*    dsprintf(const char* format, ...);
char*    dstrcat(char** dest, const char* src);
boolean  is_blank(const char* str);
boolean  is_hexadecimal(const char* str);
boolean  is_numeric(const char* str);
int32    num_digits(uint32 num);
void*    safe_calloc(size_t count, size_t element_size);
void*    safe_malloc(size_t len);
void*    safe_realloc(void* mem, size_t len);
char*    safe_strdup(const char* str);
void     trim_whitespace(char* str);
char*    vdsprintf(const char* format, va_list args);

/* Error Handlers */

void     warn(const char *format, ...);
void     error_abort(const char* format, ...);
void     sys_error_abort(const char* format, ...);
void     sys_warn(const char *format, ...);
void     set_prog_name(const char* prog);

#endif
