1 /**
2  * D header file for C99.
3  *
4  * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_stdlib.h.html, _stdlib.h)
5  *
6  * Copyright: Copyright Sean Kelly 2005 - 2014.
7  * License: Distributed under the
8  *      $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0).
9  *    (See accompanying file LICENSE)
10  * Authors:   Sean Kelly
11  * Standards: ISO/IEC 9899:1999 (E)
12  * Source: $(DRUNTIMESRC src/core/stdc/_stdlib.d)
13  */
14 
15 module core.stdc.stdlib;
16 
17 import core.stdc.config;
18 public import core.stdc.stddef; // for wchar_t
19 
20 version (OSX)
21     version = Darwin;
22 else version (iOS)
23     version = Darwin;
24 else version (TVOS)
25     version = Darwin;
26 else version (WatchOS)
27     version = Darwin;
28 
29 extern (C):
30 @system:
31 
32 /* Placed outside `nothrow` and `@nogc` in order to not constrain what the callback does.
33  */
34 ///
35 alias _compare_fp_t = int function(const void*, const void*);
36 
37 nothrow:
38 @nogc:
39 
40 ///
41 inout(void)* bsearch(const void* key, inout(void)* base, size_t nmemb, size_t size, _compare_fp_t compar);
42 ///
43 void    qsort(void* base, size_t nmemb, size_t size, _compare_fp_t compar);
44 
45 // https://issues.dlang.org/show_bug.cgi?id=17188
46 @system unittest
47 {
48     struct S
49     {
cmpS50         extern(C) static int cmp(const void*, const void*) { return 0; }
51     }
52     int[4] arr;
53     qsort(arr.ptr, arr[0].sizeof, arr.length, &S.cmp);
54     int key;
55     bsearch(&key, arr.ptr, arr[0].sizeof, arr.length, &S.cmp);
56 }
57 
58 ///
59 struct div_t
60 {
61     int quot,
62         rem;
63 }
64 
65 ///
66 struct ldiv_t
67 {
68     int quot,
69         rem;
70 }
71 
72 ///
73 struct lldiv_t
74 {
75     long quot,
76          rem;
77 }
78 
79 ///
80 enum EXIT_SUCCESS = 0;
81 ///
82 enum EXIT_FAILURE = 1;
83 ///
84 enum MB_CUR_MAX   = 1;
85 
86 ///
87 version (Windows)      enum RAND_MAX = 0x7fff;
88 else version (CRuntime_Glibc)  enum RAND_MAX = 0x7fffffff;
89 else version (Darwin)  enum RAND_MAX = 0x7fffffff;
90 else version (FreeBSD) enum RAND_MAX = 0x7ffffffd;
91 else version (NetBSD)  enum RAND_MAX = 0x7fffffff;
92 else version (OpenBSD) enum RAND_MAX = 0x7fffffff;
93 else version (DragonFlyBSD) enum RAND_MAX = 0x7fffffff;
94 else version (Solaris) enum RAND_MAX = 0x7fff;
95 else version (CRuntime_Bionic) enum RAND_MAX = 0x7fffffff;
96 else version (CRuntime_Musl) enum RAND_MAX = 0x7fffffff;
97 else version (CRuntime_UClibc) enum RAND_MAX = 0x7fffffff;
98 else static assert( false, "Unsupported platform" );
99 
100 ///
101 double  atof(scope const char* nptr);
102 ///
103 int     atoi(scope const char* nptr);
104 ///
105 c_long  atol(scope const char* nptr);
106 ///
107 long    atoll(scope const char* nptr);
108 
109 ///
110 double  strtod(scope inout(char)* nptr, scope inout(char)** endptr);
111 ///
112 float   strtof(scope inout(char)* nptr, scope inout(char)** endptr);
113 ///
114 c_long  strtol(scope inout(char)* nptr, scope inout(char)** endptr, int base);
115 ///
116 long    strtoll(scope inout(char)* nptr, scope inout(char)** endptr, int base);
117 ///
118 c_ulong strtoul(scope inout(char)* nptr, scope inout(char)** endptr, int base);
119 ///
120 ulong   strtoull(scope inout(char)* nptr, scope inout(char)** endptr, int base);
121 
version(CRuntime_Microsoft)122 version (CRuntime_Microsoft)
123 {
124     version (MinGW)
125     {
126         ///
127         real __mingw_strtold(scope inout(char)* nptr, scope inout(char)** endptr);
128         ///
129         alias __mingw_strtold strtold;
130     }
131     else
132     {
133         // strtold exists starting from VS2013, so we give it D linkage to avoid link errors
134         ///
135         extern (D) real strtold(scope inout(char)* nptr, inout(char)** endptr)
136         {   // Fake it 'till we make it
137             return strtod(nptr, endptr);
138         }
139     }
140 }
141 else
142 {
143     /// Added to Bionic since Lollipop.
144     real strtold(scope inout(char)* nptr, scope inout(char)** endptr);
145 }
146 
147 // No unsafe pointer manipulation.
148 @trusted
149 {
150     /// These two were added to Bionic in Lollipop.
151     int     rand();
152     ///
153     void    srand(uint seed);
154 }
155 
156 // We don't mark these @trusted. Given that they return a void*, one has
157 // to do a pointer cast to do anything sensible with the result. Thus,
158 // functions using these already have to be @trusted, allowing them to
159 // call @system stuff anyway.
160 ///
161 void*   malloc(size_t size);
162 ///
163 void*   calloc(size_t nmemb, size_t size);
164 ///
165 void*   realloc(void* ptr, size_t size);
166 ///
167 void    free(void* ptr);
168 
169 ///
170 noreturn abort() @safe;
171 ///
172 noreturn exit(int status);
173 ///
174 int     atexit(void function() func);
175 ///
176 noreturn _Exit(int status);
177 
178 ///
179 char*   getenv(scope const char* name);
180 ///
181 int     system(scope const char* string);
182 
183 // These only operate on integer values.
184 @trusted
185 {
186     ///
187     pure int     abs(int j);
188     ///
189     pure c_long  labs(c_long j);
190     ///
191     pure long    llabs(long j);
192 
193     ///
194     div_t   div(int numer, int denom);
195     ///
196     ldiv_t  ldiv(c_long numer, c_long denom);
197     ///
198     lldiv_t lldiv(long numer, long denom);
199 }
200 
201 ///
202 int     mblen(scope const char* s, size_t n);
203 ///
204 int     mbtowc(scope wchar_t* pwc, scope const char* s, size_t n);
205 ///
206 int     wctomb(scope char* s, wchar_t wc);
207 ///
208 size_t  mbstowcs(scope wchar_t* pwcs, scope const char* s, size_t n);
209 ///
210 size_t  wcstombs(scope char* s, scope const wchar_t* pwcs, size_t n);
211 
212 ///
version(DigitalMars)213 version (DigitalMars)
214 {
215     // See malloc comment about @trusted.
216     void* alloca(size_t size) pure; // non-standard
217 }
version(GNU)218 else version (GNU)
219 {
220     void* alloca(size_t size) pure; // compiler intrinsic
221 }
version(LDC)222 else version (LDC)
223 {
224     pragma(LDC_alloca)
225     void* alloca(size_t size) pure;
226 }
227 
version(CRuntime_Microsoft)228 version (CRuntime_Microsoft)
229 {
230     ///
231     ulong  _strtoui64(scope inout(char)*, scope inout(char)**,int);
232     ///
233     ulong  _wcstoui64(scope inout(wchar)*, scope inout(wchar)**,int);
234 
235     ///
236     long  _strtoi64(scope inout(char)*, scope inout(char)**,int);
237     ///
238     long  _wcstoi64(scope inout(wchar)*, scope inout(wchar)**,int);
239 }
240