/**
 * D header file for C99.
 *
 * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stdlib.h.html, _stdlib.h)
 *
 * Copyright: Copyright Sean Kelly 2005 - 2014.
 * License: Distributed under the
 *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
 *    (See accompanying file LICENSE)
 * Authors:   Sean Kelly
 * Standards: ISO/IEC 9899:1999 (E)
 * Source: $(DRUNTIMESRC src/core/stdc/_stdlib.d)
 */

module core.stdc.stdlib;

private import core.stdc.config;
public import core.stdc.stddef; // for wchar_t

version (OSX)
    version = Darwin;
else version (iOS)
    version = Darwin;
else version (TVOS)
    version = Darwin;
else version (WatchOS)
    version = Darwin;

extern (C):
@system:

/* Placed outside `nothrow` and `@nogc` in order to not constrain what the callback does.
 */
///
alias _compare_fp_t = int function(const void*, const void*);

nothrow:
@nogc:

///
inout(void)* bsearch(const void* key, inout(void)* base, size_t nmemb, size_t size, _compare_fp_t compar);
///
void    qsort(void* base, size_t nmemb, size_t size, _compare_fp_t compar);

// https://issues.dlang.org/show_bug.cgi?id=17188
@system unittest
{
    struct S
    {
        extern(C) static int cmp(const void*, const void*) { return 0; }
    }
    int[4] arr;
    qsort(arr.ptr, arr[0].sizeof, arr.length, &S.cmp);
    int key;
    bsearch(&key, arr.ptr, arr[0].sizeof, arr.length, &S.cmp);
}

///
struct div_t
{
    int quot,
        rem;
}

///
struct ldiv_t
{
    int quot,
        rem;
}

///
struct lldiv_t
{
    long quot,
         rem;
}

///
enum EXIT_SUCCESS = 0;
///
enum EXIT_FAILURE = 1;
///
enum MB_CUR_MAX   = 1;

///
version (Windows)      enum RAND_MAX = 0x7fff;
else version (CRuntime_Glibc)  enum RAND_MAX = 0x7fffffff;
else version (Darwin)  enum RAND_MAX = 0x7fffffff;
else version (FreeBSD) enum RAND_MAX = 0x7ffffffd;
else version (NetBSD)  enum RAND_MAX = 0x7fffffff;
else version (OpenBSD) enum RAND_MAX = 0x7fffffff;
else version (DragonFlyBSD) enum RAND_MAX = 0x7fffffff;
else version (Solaris) enum RAND_MAX = 0x7fff;
else version (CRuntime_Bionic) enum RAND_MAX = 0x7fffffff;
else version (CRuntime_Musl) enum RAND_MAX = 0x7fffffff;
else version (CRuntime_UClibc) enum RAND_MAX = 0x7fffffff;
else static assert( false, "Unsupported platform" );

///
double  atof(scope const char* nptr);
///
int     atoi(scope const char* nptr);
///
c_long  atol(scope const char* nptr);
///
long    atoll(scope const char* nptr);

///
double  strtod(scope inout(char)* nptr, scope inout(char)** endptr);
///
float   strtof(scope inout(char)* nptr, scope inout(char)** endptr);
///
c_long  strtol(scope inout(char)* nptr, scope inout(char)** endptr, int base);
///
long    strtoll(scope inout(char)* nptr, scope inout(char)** endptr, int base);
///
c_ulong strtoul(scope inout(char)* nptr, scope inout(char)** endptr, int base);
///
ulong   strtoull(scope inout(char)* nptr, scope inout(char)** endptr, int base);

version (CRuntime_Microsoft)
{
    // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
    ///
    extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
    {   // Fake it 'till we make it
        return strtod(nptr, endptr);
    }
}
else version (MinGW)
{
    ///
    real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
    ///
    alias __mingw_strtold strtold;
}
else
{
    /// Added to Bionic since Lollipop.
    real strtold(scope inout(char)* nptr, scope inout(char)** endptr);
}

// No unsafe pointer manipulation.
@trusted
{
    /// These two were added to Bionic in Lollipop.
    int     rand();
    ///
    void    srand(uint seed);
}

// We don't mark these @trusted. Given that they return a void*, one has
// to do a pointer cast to do anything sensible with the result. Thus,
// functions using these already have to be @trusted, allowing them to
// call @system stuff anyway.
///
void*   malloc(size_t size);
///
void*   calloc(size_t nmemb, size_t size);
///
void*   realloc(void* ptr, size_t size);
///
void    free(void* ptr);

///
void    abort() @safe;
///
void    exit(int status);
///
int     atexit(void function() func);
///
void    _Exit(int status);

///
char*   getenv(scope const char* name);
///
int     system(scope const char* string);

// These only operate on integer values.
@trusted
{
    ///
    pure int     abs(int j);
    ///
    pure c_long  labs(c_long j);
    ///
    pure long    llabs(long j);

    ///
    div_t   div(int numer, int denom);
    ///
    ldiv_t  ldiv(c_long numer, c_long denom);
    ///
    lldiv_t lldiv(long numer, long denom);
}

///
int     mblen(scope const char* s, size_t n);
///
int     mbtowc(scope wchar_t* pwc, scope const char* s, size_t n);
///
int     wctomb(scope char* s, wchar_t wc);
///
size_t  mbstowcs(scope wchar_t* pwcs, scope const char* s, size_t n);
///
size_t  wcstombs(scope char* s, scope const wchar_t* pwcs, size_t n);

///
version (DigitalMars)
{
    // See malloc comment about @trusted.
    void* alloca(size_t size) pure; // non-standard
}
else version (GNU)
{
    void* alloca(size_t size) pure; // compiler intrinsic
}
else version (LDC)
{
    pragma(LDC_alloca)
    void* alloca(size_t size) pure;
}

version (CRuntime_Microsoft)
{
    ///
    ulong  _strtoui64(scope inout(char)*, scope inout(char)**,int);
    ///
    ulong  _wcstoui64(scope inout(wchar)*, scope inout(wchar)**,int);

    ///
    long  _strtoi64(scope inout(char)*, scope inout(char)**,int);
    ///
    long  _wcstoi64(scope inout(wchar)*, scope inout(wchar)**,int);
}
