/* stdlib.h: General utilities. */

#ifndef _STDLIB_H
#define _STDLIB_H

#include <bits/attrs.h>
#include <stddef.h>

/* The result of a division operation on two integers. */
typedef struct
{
    int quot;
    int rem;
} div_t;

/* The result of a division operation on two long integers. */
typedef struct
{
    long quot;
    long rem;
} ldiv_t;

/* The result of a division operation on two long long integers. */
typedef struct
{
    long long quot;
    long long rem;
} lldiv_t;

#define MB_CUR_MAX 4

#define RAND_MAX 32767

#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1

#ifdef __cplusplus
extern "C"
{
#endif

    /* Return the absolute value of an integer. */
    int abs(int);

    /* Return the absolute value of a long integer. */
    long labs(long);

    /* Return the absolute value of a long long integer. */
    long long llabs(long long);

    /* Return the result of dividing two integers, including the remainder. */
    div_t div(int, int);

    /* Return the result of dividing two long integers, including the remainder. */
    ldiv_t ldiv(long, long);

    /* Return the result of dividing two long long integers, including the remainder. */
    lldiv_t lldiv(long long, long long);

    /* Allocate heap memory. */
    void* malloc(size_t size);

    /* Allocate zero-initialized heap memory. */
    void* calloc(size_t nmemb, size_t size);

    /* Resize allocated heap memory. */
    void* realloc(void* ptr, size_t size);

    /* Free heap memory. */
    void free(void* ptr);

    /* Abort the program without performing any normal cleanup. */
    __noreturn void abort();

    /* Register a handler to be run at normal program termination. */
    int atexit(void (*func)(void));

    /* Parse a decimal integer from a string. */
    int atoi(const char* s);

    /* Parse a decimal integer from a string. */
    long atol(const char* s);

    /* Parse a decimal integer from a string. */
    long long atoll(const char* s);

    double atof(const char*);

    double strtod(const char*, char**);

    /* Parse an integer of the specified base from a string, storing the first non-number character in endptr if
     * nonnull. */
    long strtol(const char* str, char** endptr, int base);

    /* Parse an unsigned integer of the specified base from a string, storing the first non-number character in
     * endptr if nonnull. */
    unsigned long strtoul(const char* str, char** endptr, int base);

#define strtoll strtol
#define strtoull strtoul

    /* Return the next pseudorandom number. */
    int rand();

    /* Set the pseudorandom number generator's seed, which will determine the sequence of numbers returned by rand(). */
    void srand(unsigned int seed);

    /* Exit the program normally, performing any registered cleanup actions. */
    __noreturn void exit(int status);

    /* Exit the program abnormally, without performing any registered cleanup actions. */
    __noreturn void _Exit(int status);

    /* Execute a shell command. */
    int system(const char* cmd);

    /* Get the value of an environment variable. */
    char* getenv(const char* key);

    /* Set the value of an environment variable. */
    int setenv(const char* key, const char* value, int overwrite);

    /* Remove a variable from the environment. */
    int unsetenv(const char* key);

    /* Clear all environment variables. */
    int clearenv(void);

    /* Sort an array of arbitrary elements using a comparison function. */
    void qsort(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*));

    void* bsearch(const void*, const void*, size_t, size_t, int (*)(const void*, const void*));

    /* Convert a multibyte character string to a wide character string. */
    size_t mbstowcs(wchar_t* buf, const char* src, size_t max);

    /* Convert a wide character string to a multibyte character string. */
    size_t wcstombs(char* buf, const wchar_t* src, size_t max);

    /* Create a unique directory from a template string whose last 6 bytes must be XXXXXX. */
    char* mkdtemp(char* _template);

    /* Create a unique file from a template string whose last 6 bytes must be XXXXXX. */
    int mkstemp(char* _template);

#ifdef __cplusplus
}
#endif

#endif