summaryrefslogtreecommitdiff
path: root/src/stdlib
diff options
context:
space:
mode:
Diffstat (limited to 'src/stdlib')
-rw-r--r--src/stdlib/EXIT_FAILURE.c15
-rw-r--r--src/stdlib/EXIT_SUCCESS.c15
-rw-r--r--src/stdlib/MB_CUR_MAX.c15
-rw-r--r--src/stdlib/NULL.ref3
-rw-r--r--src/stdlib/RAND_MAX.c14
-rw-r--r--src/stdlib/_Exit.c29
-rw-r--r--src/stdlib/abort.c27
-rw-r--r--src/stdlib/abs.c23
-rw-r--r--src/stdlib/atexit.c38
-rw-r--r--src/stdlib/atof.c19
-rw-r--r--src/stdlib/atoi.c19
-rw-r--r--src/stdlib/atol.c19
-rw-r--r--src/stdlib/atoll.c10
-rw-r--r--src/stdlib/bsearch.c44
-rw-r--r--src/stdlib/calloc.c33
-rw-r--r--src/stdlib/div.c22
-rw-r--r--src/stdlib/div_t.c17
-rw-r--r--src/stdlib/exit.c51
-rw-r--r--src/stdlib/free.c22
-rw-r--r--src/stdlib/getenv.c31
-rw-r--r--src/stdlib/labs.c22
-rw-r--r--src/stdlib/ldiv.c22
-rw-r--r--src/stdlib/ldiv_t.c17
-rw-r--r--src/stdlib/llabs.c18
-rw-r--r--src/stdlib/lldiv.c13
-rw-r--r--src/stdlib/lldiv_t.c10
-rw-r--r--src/stdlib/malloc.c23
-rw-r--r--src/stdlib/mblen.c33
-rw-r--r--src/stdlib/mbstowcs.c30
-rw-r--r--src/stdlib/mbtowc.c37
-rw-r--r--src/stdlib/qsort.c24
-rw-r--r--src/stdlib/rand.c19
-rw-r--r--src/stdlib/realloc.c58
-rw-r--r--src/stdlib/size_t.ref3
-rw-r--r--src/stdlib/srand.c19
-rw-r--r--src/stdlib/strtod.c37
-rw-r--r--src/stdlib/strtof.c9
-rw-r--r--src/stdlib/strtol.c60
-rw-r--r--src/stdlib/strtold.c9
-rw-r--r--src/stdlib/strtoll.c15
-rw-r--r--src/stdlib/strtoul.c53
-rw-r--r--src/stdlib/strtoull.c13
-rw-r--r--src/stdlib/system.c61
-rw-r--r--src/stdlib/wchar_t.ref3
-rw-r--r--src/stdlib/wcstombs.c25
-rw-r--r--src/stdlib/wctomb.c33
46 files changed, 1132 insertions, 0 deletions
diff --git a/src/stdlib/EXIT_FAILURE.c b/src/stdlib/EXIT_FAILURE.c
new file mode 100644
index 00000000..4558c660
--- /dev/null
+++ b/src/stdlib/EXIT_FAILURE.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+
+/** unsuccessful program termination **/
+
+#define EXIT_FAILURE (1)
+
+/***
+is used as the ARGUMENT(status) argument to FUNCTION(exit) or FUNCTION(_Exit),
+or the return value from FUNCTION(main), to indicate that the program is
+exiting unsuccessfully.
+***/
+
+/*
+STDC(1)
+*/
diff --git a/src/stdlib/EXIT_SUCCESS.c b/src/stdlib/EXIT_SUCCESS.c
new file mode 100644
index 00000000..ce2ed9df
--- /dev/null
+++ b/src/stdlib/EXIT_SUCCESS.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+
+/** successful program termination **/
+
+#define EXIT_SUCCESS (0)
+
+/***
+is used as the ARGUMENT(status) argument to FUNCTION(exit) or FUNCTION(_Exit),
+or the return value from FUNCTION(main), to indicate that the program is
+exiting successfully.
+***/
+
+/*
+STDC(1)
+*/
diff --git a/src/stdlib/MB_CUR_MAX.c b/src/stdlib/MB_CUR_MAX.c
new file mode 100644
index 00000000..4961e343
--- /dev/null
+++ b/src/stdlib/MB_CUR_MAX.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+
+/** current longest multibyte character **/
+
+#define MB_CUR_MAX (4)
+
+/***
+is the maximum number of bytes required to store any character in the current
+multibyte character set as specified by CONSTANT(LC_CTYPE).
+***/
+
+/*
+VALUE_MAX(CONSTANT(MB_LEN_MAX))
+STDC(1)
+*/
diff --git a/src/stdlib/NULL.ref b/src/stdlib/NULL.ref
new file mode 100644
index 00000000..87e994d4
--- /dev/null
+++ b/src/stdlib/NULL.ref
@@ -0,0 +1,3 @@
+#include <stdlib.h>
+REFERENCE(stddef/NULL.c)
+STDC(1)
diff --git a/src/stdlib/RAND_MAX.c b/src/stdlib/RAND_MAX.c
new file mode 100644
index 00000000..dbbdbde0
--- /dev/null
+++ b/src/stdlib/RAND_MAX.c
@@ -0,0 +1,14 @@
+#include <stdlib.h>
+
+/** random number range **/
+
+#define RAND_MAX (32767)
+
+/***
+is the maximum value returned by FUNCTION(rand).
+***/
+
+/*
+VALUE_MIN(32767)
+STDC(1)
+*/
diff --git a/src/stdlib/_Exit.c b/src/stdlib/_Exit.c
new file mode 100644
index 00000000..a90d4a24
--- /dev/null
+++ b/src/stdlib/_Exit.c
@@ -0,0 +1,29 @@
+#include <stdlib.h>
+#include "nonstd/syscall.h"
+
+/** cause normal program termination without handlers **/
+_Noreturn void _Exit(int status)
+{
+ __syscall("_exit", status);
+ for (;;);
+}
+
+/***
+The fn(exit) function causes the program to terminate normally, returning the
+value arg(status) to the host environment.
+
+No functions registered by fn(atexit) or fn(at_quick_exit) are called.
+***/
+
+/* UNSPECIFIED: - */
+/* UNDEFINED: - */
+/* IMPLEMENTATION: the successful termination value returned to the host environment when arg(status) is 0 of macro(EXIT_SUCESS) */
+/* IMPLEMENTATION: the unsuccessful termination value returned to the host environment when arg(status) is macro(EXIT_FAILURE) */
+/* IMPLEMENTATION: whether open streams are flushed */
+/* IMPLEMENTATION: whether open streams are closed */
+/* IMPLEMENTATION: whether temporary files are removed */
+/* LOCALE: - */
+
+/*
+STDC(199901)
+*/
diff --git a/src/stdlib/abort.c b/src/stdlib/abort.c
new file mode 100644
index 00000000..d079bdf1
--- /dev/null
+++ b/src/stdlib/abort.c
@@ -0,0 +1,27 @@
+#include <stdlib.h>
+#ifdef _POSIX_SOURCE
+#include "sys/types.h"
+#endif
+#include "signal.h"
+
+/** cause abnormal program termination **/
+
+_Noreturn void abort(void)
+{
+ raise(SIGABRT);
+ for(;;); /* silence gcc warning about returning */
+}
+
+/***
+causes the program to terminate abnormally, unless the
+signal CONSTANT(SIGABRT) is caught and the signal handler continues program
+execution.
+***/
+
+/*
+IMPLEMENTATION(whether open output streams are flushed)
+IMPLEMENTATION(whether open streams are closed)
+IMPLEMENTATION(whether temporary files are removed)
+IMPLEMENTATION(the value of unsuccessful termination returned to the host environment)
+STDC(1)
+*/
diff --git a/src/stdlib/abs.c b/src/stdlib/abs.c
new file mode 100644
index 00000000..9bc6ca28
--- /dev/null
+++ b/src/stdlib/abs.c
@@ -0,0 +1,23 @@
+#include <stdlib.h>
+#include "limits.h"
+
+/** absolute value **/
+
+int abs(int j)
+{
+ if (j == INT_MIN) {
+ /* undefined behavior */
+ }
+
+ return j < 0 ? -j : j;
+}
+
+/***
+computes the absolute value of ARGUMENT(j).
+***/
+
+/*
+UNDEFINED(ABS(ARGUMENT(j)) cannot be represented)
+RETURN_SUCCESS(ABS(j));
+STDC(1)
+*/
diff --git a/src/stdlib/atexit.c b/src/stdlib/atexit.c
new file mode 100644
index 00000000..180dc5e2
--- /dev/null
+++ b/src/stdlib/atexit.c
@@ -0,0 +1,38 @@
+#include <stdlib.h>
+#include "errno.h"
+#include "nonstd/internal.h"
+
+/** register a function to run at program exit **/
+
+int atexit(void (*func)(void))
+{
+ struct atexit *ae = __libc(ATEXIT);
+ while (ae->nfns == sizeof(ae->fns) / sizeof(ae->fns[0])) {
+ if (ae->next == NULL) {
+ ae->next = calloc(1, sizeof(*ae->next));
+ if (ae->next == NULL) {
+ #ifdef ENOMEM
+ errno = ENOMEM;
+ #endif
+ return 1;
+ }
+ ae->next->prev = ae;
+ }
+ ae = ae->next;
+ }
+ ae->fns[ae->nfns++] = func;
+ return 0;
+}
+
+/***
+registers the function ARGUMENT(func) to be called when the program
+exits normally by calling FUNCTION(exit) or returning from FUNCTION(main). The
+function must take no parameters and return no value.
+***/
+
+/*
+IMPLEMENTATION(The number of registrations allowed (at least 32))
+RETURN_FAILURE(NONZERO)
+RETURN_SUCCESS(0)
+STDC(1)
+*/
diff --git a/src/stdlib/atof.c b/src/stdlib/atof.c
new file mode 100644
index 00000000..c8fd2344
--- /dev/null
+++ b/src/stdlib/atof.c
@@ -0,0 +1,19 @@
+#include <stdlib.h>
+
+/** convert string to floating-point **/
+
+double atof(const char * nptr)
+{
+ return strtod(nptr, (char**)NULL);
+}
+
+/***
+converts the string at ARGUMENT(nptr) to a TYPE(double). The
+conversion goes until the first inappropriate character.
+***/
+
+/*
+LC_CTYPE
+RETURN_SUCCESS(the converted value)
+STDC(1)
+*/
diff --git a/src/stdlib/atoi.c b/src/stdlib/atoi.c
new file mode 100644
index 00000000..6e58dd22
--- /dev/null
+++ b/src/stdlib/atoi.c
@@ -0,0 +1,19 @@
+#include <stdlib.h>
+
+/** convert string to integer **/
+
+int atoi(const char * nptr)
+{
+ return (int)strtol(nptr, (char**)NULL, 10);
+}
+
+/***
+converts the string at ARGUMENT(nptr) to an TYPE(int) value,
+using base 10. The conversion goes until the first non-digit character.
+***/
+
+/*
+LC_CTYPE
+RETURN_SUCCESS(the converted value)
+STDC(1)
+*/
diff --git a/src/stdlib/atol.c b/src/stdlib/atol.c
new file mode 100644
index 00000000..6bcebf7d
--- /dev/null
+++ b/src/stdlib/atol.c
@@ -0,0 +1,19 @@
+#include <stdlib.h>
+
+/** convert string to long integer **/
+
+long int atol(const char * nptr)
+{
+ return strtol(nptr, (char**)NULL, 10);
+}
+
+/***
+converts the string at ARGUMENT(nptr) to a TYPE(long int) value,
+using base 10. The conversion goes until the first non-digit character.
+***/
+
+/*
+LC_CTYPE
+RETURN_SUCCESS(the converted value)
+STDC(1)
+*/
diff --git a/src/stdlib/atoll.c b/src/stdlib/atoll.c
new file mode 100644
index 00000000..bc098876
--- /dev/null
+++ b/src/stdlib/atoll.c
@@ -0,0 +1,10 @@
+#include <stdlib.h>
+
+long long int atoll(const char *nptr)
+{
+ return strtoll(str, (char**)NULL, 10);
+}
+
+/*
+STDC(199901)
+*/
diff --git a/src/stdlib/bsearch.c b/src/stdlib/bsearch.c
new file mode 100644
index 00000000..d625599f
--- /dev/null
+++ b/src/stdlib/bsearch.c
@@ -0,0 +1,44 @@
+#include <stdlib.h>
+
+/** binary search **/
+
+void * bsearch(const void * key, const void * base, size_t nmemb, size_t size, int (*compar)(const void *, const void*))
+{
+ /* TODO: testing */
+ void *ret = NULL;
+ size_t i = nmemb / 2;
+ unsigned int trip = 1;
+ (void)size;
+
+ while (ret == NULL) {
+ int comp = compar(key, base + i);
+ if (comp == 0) {
+ return (void*)(base + i);
+ } else if (comp > 0) {
+ i -= (nmemb >> trip);
+ } else {
+ i += (nmemb >> trip);
+ }
+ }
+ return NULL;
+}
+
+/***
+performs a binary search for ARGUMENT(key) in the array
+ARGUMENT(base), which contains ARGUMENT(nmemb) members of ARGUMENT(size) bytes
+each.
+
+The search is performed by calling ARGUMENT(compar) with the first argument of
+ARGUMENT(key), and the second being an element from the array at
+ARGUMENT(base). The function must return less than 0 if ARGUMENT(key) is less
+than the other element, 0 if they are equal, and greater than 0 if
+ARGUMENT(key) is greater than the other element.
+***/
+
+/*
+UNSPECIFIED(Which element is matched if two elements are equal)
+UNDEFINED(The array at ARGUMENT(base) is not sorted)
+RETURN_FAILURE(CONSTANT(NULL))
+RETURN_SUCCESS(a pointer to the matching element)
+STDC(1)
+*/
diff --git a/src/stdlib/calloc.c b/src/stdlib/calloc.c
new file mode 100644
index 00000000..aeed4aef
--- /dev/null
+++ b/src/stdlib/calloc.c
@@ -0,0 +1,33 @@
+#include <stdlib.h>
+#include "string.h"
+
+/** allocate and initialize memory **/
+
+void * calloc(size_t nmemb, size_t size)
+{
+ void *p = NULL;
+
+ if (nmemb == 0 || size == 0) {
+ return NULL;
+ }
+
+ p = realloc(NULL, size * nmemb);
+ if (p != NULL) {
+ memset(p, 0, size * nmemb);
+ }
+
+ return p;
+}
+
+/***
+allocates an array of ARGUMENT(nmemb) elements, each of which
+are ARGUMENT(size) bytes, and sets all their bits to 0.
+***/
+
+/*
+UNSPECIFIED(The order and contiguity of space allocated by success calls)
+IMPLEMENTATION(What is returned if ARGUMENT(nmemb) or ARGUMENT(size) is 0)
+RETURN_FAILURE(CONSTANT(NULL))
+RETURN_SUCCESS(a pointer to the newly allocated memory)
+STDC(1)
+*/
diff --git a/src/stdlib/div.c b/src/stdlib/div.c
new file mode 100644
index 00000000..dfd80652
--- /dev/null
+++ b/src/stdlib/div.c
@@ -0,0 +1,22 @@
+#include <stdlib.h>
+
+/** calculate quotient and remainder **/
+
+div_t div(int numer, int denom)
+{
+ div_t d;
+ d.quot = numer / denom;
+ d.rem = numer % denom;
+ return d;
+}
+
+/***
+computes both the quotient and remainder of ARGUMENT(numer)
+divided by ARGUMENT(denom).
+***/
+
+/*
+UNDEFINED(The result cannot be represented)
+RETURN_SUCCESS(a TYPEDEF(div_t) containing both the quotient and remainder)
+STDC(1)
+*/
diff --git a/src/stdlib/div_t.c b/src/stdlib/div_t.c
new file mode 100644
index 00000000..60acd660
--- /dev/null
+++ b/src/stdlib/div_t.c
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+
+/** quotient and remainder **/
+
+typedef struct {
+ int quot;
+ int rem;
+} div_t;
+
+/***
+is the type returned by FUNCTION(div) to hold both the quotient and remainder
+of an integer division.
+***/
+
+/*
+STDC(1)
+*/
diff --git a/src/stdlib/exit.c b/src/stdlib/exit.c
new file mode 100644
index 00000000..b0ba271d
--- /dev/null
+++ b/src/stdlib/exit.c
@@ -0,0 +1,51 @@
+#include <stdlib.h>
+#include "limits.h"
+#include "stddef.h"
+#include "nonstd/internal.h"
+#include "nonstd/syscall.h"
+
+/** cause normal program termination **/
+_Noreturn void exit(int status)
+{
+ struct atexit *ae = __libc(ATEXIT);
+
+ /* execute all atexit() registered functions in reverse order */
+ while (ae) {
+ int i = ae->nfns;
+ while (i > 0) {
+ ae->fns[--i]();
+ }
+ ae = ae->prev;
+ }
+
+ /* close all open files */
+ /*
+ while (__libc.stdio.lastfile) {
+ fclose(__libc.stdio.lastfile);
+ }
+ */
+
+ (void)status;
+ /* __syscall(__libc(SYSCALL_LOOKUP)("exit"), status); */
+ for (;;); /* quiet _Noreturn functions returns warning */
+}
+
+/***
+causes the program to terminate normally, returning the
+value ARGUMENT(status) to the host environment.
+
+First, all functions registered by FUNCTION(atexit) are called in the reverse
+order in which they were registered.
+
+Then, all open streams with unwritten buffered data are flushed. All open
+streams are closed. All temporary files created by FUNCTION(tmpfile) are
+removed.
+***/
+
+/*
+IMPLEMENTATION(The successful termination value returned to the host environment when ARGUMENT(status) is 0 or CONSTANT(EXIT_SUCESS))
+IMPLEMENTATION(The unsuccessful termination value returned to the host environment when ARGUMENT(status) is CONSTANT(EXIT_FAILURE))
+*/
+/*
+STDC(1)
+*/
diff --git a/src/stdlib/free.c b/src/stdlib/free.c
new file mode 100644
index 00000000..55a98a2f
--- /dev/null
+++ b/src/stdlib/free.c
@@ -0,0 +1,22 @@
+#include <stdlib.h>
+
+/** deallocate memory **/
+
+void free(void * ptr)
+{
+ if (ptr == NULL) {
+ return;
+ }
+
+ realloc(ptr, 0);
+}
+
+/***
+deallocates the memory at ARGUMENT(ptr). Specifying CONSTANT(NULL)
+causes nothing to happen.
+***/
+
+/*
+UNDEFINED(ARGUMENT(ptr) was not returned by a previous call to FUNCTION(calloc), FUNCTION(malloc), or FUNCTION(realloc))
+STDC(1)
+*/
diff --git a/src/stdlib/getenv.c b/src/stdlib/getenv.c
new file mode 100644
index 00000000..edf5c4f9
--- /dev/null
+++ b/src/stdlib/getenv.c
@@ -0,0 +1,31 @@
+#include <stdlib.h>
+#include "string.h"
+
+/** get an environment variable **/
+
+char * getenv(const char * name)
+{
+ extern char **environ;
+ int i = 0;
+
+ while (environ[i] != 0) {
+ if (!strncmp(environ[i], name, strlen(name)) && environ[i][strlen(name)] == '=')
+ return environ[i];
+ i++;
+ }
+
+ return NULL;
+}
+
+/***
+read the environment variable ARGUMENT(name) from the host environment.
+***/
+
+/*
+UNDEFINED(Modifying the returned string)
+IMPLEMENTATION(The set of environment variable names)
+IMPLEMENTATION(The method of altering the environment)
+RETURN_FAILURE(CONSTANT(NULL))
+RETURN_SUCCESS(a pointer to the environment string)
+STDC(1)
+*/
diff --git a/src/stdlib/labs.c b/src/stdlib/labs.c
new file mode 100644
index 00000000..fd092f5a
--- /dev/null
+++ b/src/stdlib/labs.c
@@ -0,0 +1,22 @@
+#include <stdlib.h>
+#include "limits.h"
+
+/** absolute value **/
+long int labs(long int j)
+{
+ if (j == LONG_MIN) {
+ /* undefined */
+ }
+
+ return j < 0 ? -j : j;
+}
+
+/***
+function computes the absolute value of ARGUMENT(j).
+***/
+
+/*
+UNDEFINED(ABS(ARGUMENT(j)) cannot be represented)
+RETURN_SUCCESS(ABS(ARGUMENT(j)))
+STDC(1)
+*/
diff --git a/src/stdlib/ldiv.c b/src/stdlib/ldiv.c
new file mode 100644
index 00000000..0aebaf49
--- /dev/null
+++ b/src/stdlib/ldiv.c
@@ -0,0 +1,22 @@
+#include <stdlib.h>
+
+/** calculate quotient and remainder **/
+
+ldiv_t ldiv(long int numer, long int denom)
+{
+ ldiv_t d;
+ d.quot = numer / denom;
+ d.rem = numer % denom;
+ return d;
+}
+
+/***
+computes both the quotient and remainder of ARGUMENT(numer)
+divided by ARGUMENT(denom).
+***/
+
+/*
+UNDEFINED(The result cannot be represented)
+RETURN_SUCCESS(a TYPEDEF(ldiv_t) containing both the quotient and remainder)
+STDC(1)
+*/
diff --git a/src/stdlib/ldiv_t.c b/src/stdlib/ldiv_t.c
new file mode 100644
index 00000000..00161cf6
--- /dev/null
+++ b/src/stdlib/ldiv_t.c
@@ -0,0 +1,17 @@
+#include <stdlib.h>
+
+/** long quotient and remainder **/
+
+typedef struct {
+ long int quot;
+ long int rem;
+} ldiv_t;
+
+/***
+is the type returned by FUNCTION(ldiv) to hold both the quotient and remainder
+of an integer division.
+***/
+
+/*
+STDC(1)
+*/
diff --git a/src/stdlib/llabs.c b/src/stdlib/llabs.c
new file mode 100644
index 00000000..2f474fe9
--- /dev/null
+++ b/src/stdlib/llabs.c
@@ -0,0 +1,18 @@
+#include <stdlib.h>
+
+long long int llabs(long long int j)
+{
+ if (j == LLONG_MIN) {
+ /* undefined */
+ }
+
+ if (j < 0) {
+ return -j;
+ }
+
+ return j;
+}
+
+/*
+STDC(199901)
+*/
diff --git a/src/stdlib/lldiv.c b/src/stdlib/lldiv.c
new file mode 100644
index 00000000..f4835ec2
--- /dev/null
+++ b/src/stdlib/lldiv.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+
+lldiv_t lldiv(long long int numer, long long int denom)
+{
+ lldiv_t d;
+ d.quot = numer / denom;
+ d.rem = numer % denom;
+ return d;
+}
+
+/*
+STDC(199901)
+*/
diff --git a/src/stdlib/lldiv_t.c b/src/stdlib/lldiv_t.c
new file mode 100644
index 00000000..e7e72e6b
--- /dev/null
+++ b/src/stdlib/lldiv_t.c
@@ -0,0 +1,10 @@
+#include <stdlib.h>
+
+typedef struct {
+ long long int quot;
+ long long int rem;
+} lldiv_t;
+
+/*
+STDC(199901)
+*/
diff --git a/src/stdlib/malloc.c b/src/stdlib/malloc.c
new file mode 100644
index 00000000..b2116fa7
--- /dev/null
+++ b/src/stdlib/malloc.c
@@ -0,0 +1,23 @@
+#include <stdlib.h>
+
+/** allocate memory **/
+void * malloc(size_t size)
+{
+ if (size == 0) {
+ return NULL;
+ }
+
+ return realloc(NULL, size);
+}
+
+/***
+allocates ARGUMENT(size) bytes of memory.
+***/
+
+/*
+UNSPECIFIED(The order and contiguity of space allocated by success calls)
+IMPLEMENTATION(What is returned if ARGUMENT(size) is 0)
+RETURN_FAILURE(CONSTANT(NULL))
+RETURN_SUCCESS(a pointer to the allocated space)
+STDC(1)
+*/
diff --git a/src/stdlib/mblen.c b/src/stdlib/mblen.c
new file mode 100644
index 00000000..db7c4f1c
--- /dev/null
+++ b/src/stdlib/mblen.c
@@ -0,0 +1,33 @@
+#include <stdlib.h>
+
+/** count bytes in multibyte character **/
+int mblen(const char * s, size_t n)
+{
+ /* FIXME: forward dependency on AMD1 */
+ #if 0
+ mbstate_t ps = 0;
+ return mbrlen(s, n, &ps);
+ #else
+ (void)s; (void)n;
+ return 0;
+ #endif
+}
+
+/***
+counts the number of bytes in the multibyte character
+starting at ARGUMENT(s), if the next ARGUMENT(n) or fewer bytes contain a full multibyte
+character.
+
+If ARGUMENT(s) is CONSTANT(NULL), THIS() tests whether multibyte encodings carry
+state dependency.
+***/
+
+/*
+LC_CTYPE
+RETURN(0, If ARGUMENT(s) is CONSTANT(NULL), multibyte encodings do not have state dependencies);
+RETURN(NZ, If ARGUMENT(s) is CONSTANT(NULL), multibyte encodings do have state dependencies);
+RETURN(-1, The ARGUMENT(n) bytes at ARGUMENT(s) do not form a valid mutlibyte character);
+RETURN(0, ARGUMENT(s) points to a null character);
+RETURN(TYPE(int), the number of bytes in the multibyte character);
+STDC(1)
+*/
diff --git a/src/stdlib/mbstowcs.c b/src/stdlib/mbstowcs.c
new file mode 100644
index 00000000..a5ce53d8
--- /dev/null
+++ b/src/stdlib/mbstowcs.c
@@ -0,0 +1,30 @@
+#include <stdlib.h>
+
+/** convert multibyte string to wide character string **/
+
+size_t mbstowcs(wchar_t * restrict pwcs, const char * restrict s, size_t n)
+{
+ /* FIXME: forward dependency on AMD1 */
+ #if 0
+ mbstate_t ps = 0;
+ return mbsrtowcs(pwcs, s, n, &ps);
+ #else
+ (void)pwcs; (void)s;
+ return n;
+ #endif
+}
+
+/***
+converts the string of multibyte characters ARGUMENT(s)
+to a string of wide characters, which are stored at ARGUMENT(pwcs). No more than
+ARGUMENT(n) wide characters are stored at ARGUMENT(pwcs). No further
+characters will be converted after a null character, which is converted.
+***/
+
+/*
+UNDEFINED(The memory regions of ARGUMENT(s) and ARGUMENT(pwcs) overlap)
+LC_CTYPE
+RETURN_FAILURE(-1)
+RETURN_SUCCESS(the number of wide characters converted, not counting any terminating zero)
+STDC(1)
+*/
diff --git a/src/stdlib/mbtowc.c b/src/stdlib/mbtowc.c
new file mode 100644
index 00000000..3704acd4
--- /dev/null
+++ b/src/stdlib/mbtowc.c
@@ -0,0 +1,37 @@
+#include <stdlib.h>
+
+/** convert a multibyte character to a wide character **/
+
+int mbtowc(wchar_t * restrict pwc, const char * restrict s, size_t n)
+{
+ /* FIXME: forward dependency on AMD1 */
+ #if 0
+ static mbstate_t ps = 0;
+ return mbrtowc(pwc, s, n, &ps);
+ #else
+ (void)pwc; (void)s; (void)n;
+ return 0;
+ #endif
+}
+
+/***
+converts the multibyte character, of no more than ARGUMENT(n) bytes, at
+ARGUMENT(s) to a wide character, which is stored at the address pointed to by
+ARGUMENT(pwc).
+
+If ARGUMENT(s) is CONSTANT(NULL), THIS() tests whether multibyte encodings carry
+state dependency.
+
+If ARGUMENT(pwc) is CONSTANT(NULL), THIS() counts the number of bytes in the
+multibyte character at ARGUMENT(s).
+***/
+
+/*
+LC_CTYPE
+RETURN(0, If ARGUMENT(s) is CONSTANT(NULL), multibyte encodings do not have state dependencies)
+RETURN(NONZERO, If ARGUMENT(s) is CONSTANT(NULL), multibyte encodings do have state dependencies)
+RETURN(-1, The ARGUMENT(n) bytes at ARGUMENT(s) do not form a valid mutlibyte character)
+RETURN(0, ARGUMENT(s) points to a null character)
+RETURN(TYPE(int), the number of bytes in the converted multibyte character)
+STDC(1)
+*/
diff --git a/src/stdlib/qsort.c b/src/stdlib/qsort.c
new file mode 100644
index 00000000..da4c5c15
--- /dev/null
+++ b/src/stdlib/qsort.c
@@ -0,0 +1,24 @@
+#include <stdlib.h>
+
+/** sort an array **/
+
+void qsort(void * base, size_t nmemb, size_t size, int (*compar)(const void *, const void *))
+{
+ (void)base; (void)nmemb; (void)size; (void)compar;
+ /* TODO */
+}
+
+/***
+sorts the array at ARGUMENT(base), which consists of ARGUMENT(nmemb) elements
+of ARGUMENT(size) bytes each.
+
+The sorting is performed by calling ARGUMENT(compar) with two elements of the
+array. The function must return less than 0 if the first argument is less
+than the second, 0 if they are equal, and greater than 0 if the first argument
+is greater than the second.
+***/
+
+/*
+UNSPECIFIED(The order of equal elements)
+STDC(1)
+*/
diff --git a/src/stdlib/rand.c b/src/stdlib/rand.c
new file mode 100644
index 00000000..bd561736
--- /dev/null
+++ b/src/stdlib/rand.c
@@ -0,0 +1,19 @@
+#include <stdlib.h>
+#include "nonstd/internal.h"
+
+/** get a pseudo-random number **/
+int rand(void)
+{
+ /* FIXME: forward dependency on POSIX.1c-1995 */
+ extern int rand_r(unsigned int*);
+ return rand_r(__libc(RAND));
+}
+
+/***
+computes a pseudo-random number in the range [0,CONSTANT(RAND_MAX)].
+***/
+
+/*
+RETURN_SUCCESS(a pseudo-random integer)
+STDC(1)
+*/
diff --git a/src/stdlib/realloc.c b/src/stdlib/realloc.c
new file mode 100644
index 00000000..f16ba8a5
--- /dev/null
+++ b/src/stdlib/realloc.c
@@ -0,0 +1,58 @@
+#include <stdlib.h>
+#if defined _POSIX_C_SOURCE && 199305L <= _POSIX_C_SOURCE
+#include "sys/types.h"
+#include "fcntl.h"
+#include "sys/mman.h"
+#endif
+
+/** change the amount of memory allocated **/
+
+void * realloc(void * ptr, size_t size)
+{
+#if defined _POSIX_C_SOURCE && 199305L <= _POSIX_C_SOURCE
+ /* FIXME: forward dependency on POSIX.1b-1993, non-std /dev/zero */
+ static int backing = -1;
+
+ if (backing == -1) {
+ backing = open("/dev/zero", O_RDWR /* | O_CLOEXEC */, 0);
+ }
+
+ if (ptr == NULL) {
+ /* malloc() */
+ return (void*)(long)mmap(NULL, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, backing, 0);
+ } else if (size == 0) {
+ /* free() */
+ }
+
+ /* TODO: reallocate */
+#else
+ (void)size;
+#endif
+
+ return ptr;
+}
+
+/***
+changes the amount of memory allocated to ARGUMENT(ptr) to ARGUMENT(size)
+bytes.
+
+If ARGUMENT(ptr) is CONSTANT(NULL), a new allocation is made.
+
+If ARGUMENT(size) is 0 and ARGUMENT(ptr) is not CONSTANT(NULL), the memory at ARGUMENT(ptr) is
+deallocated.
+
+Otherwise, the memory allocated to ARGUMENT(ptr) is resized. If enough memory cannot
+be allocated, ARGUMENT(ptr) will not change. If enough memory is available, the
+address of ARGUMENT(ptr) may change, but the contents will be the same up to the
+minimum of the old and new sizes.
+***/
+
+/*
+UNSPECIFIED(The order and contiguity of space allocated by success calls)
+UNDEFINED(ARGUMENT(ptr) is not CONSTANT(NULL) or a pointer returned by a previous call to FUNCTION(calloc), FUNCTION(malloc), or FUNCTION(realloc))
+UNDEFINED(ARGUMENT(ptr) has been previously deallocated by FUNCTION(free) or FUNCTION(realloc))
+RETURN_FAILURE(CONSTANT(NULL))
+RETURN_SUCCESS(a pointer to the reallocate space)
+STDC(1)
+*/
diff --git a/src/stdlib/size_t.ref b/src/stdlib/size_t.ref
new file mode 100644
index 00000000..e525842a
--- /dev/null
+++ b/src/stdlib/size_t.ref
@@ -0,0 +1,3 @@
+#include <stdlib.h>
+REFERENCE(stddef/size_t.c)
+STDC(1)
diff --git a/src/stdlib/srand.c b/src/stdlib/srand.c
new file mode 100644
index 00000000..66ce786e
--- /dev/null
+++ b/src/stdlib/srand.c
@@ -0,0 +1,19 @@
+#include <stdlib.h>
+#include "nonstd/internal.h"
+
+/** seed the pseudo-random number generator **/
+
+void srand(unsigned int seed)
+{
+ *((int*)__libc(RAND)) = seed;
+}
+
+/***
+seeds the pseudo-random number generator with ARGUMENT(seed). The
+sequence of pseudo-random numbers generated by a single seed is repeatable.
+Program execution begins with a seed of 1.
+***/
+
+/*
+STDC(1)
+*/
diff --git a/src/stdlib/strtod.c b/src/stdlib/strtod.c
new file mode 100644
index 00000000..4420b02e
--- /dev/null
+++ b/src/stdlib/strtod.c
@@ -0,0 +1,37 @@
+#include <stdlib.h>
+#include "errno.h"
+
+/** convert string to floating-point **/
+
+double strtod(const char * restrict nptr, char ** restrict endptr)
+{
+ (void)nptr; (void)endptr;
+ /* TODO */
+
+ if (0) {
+ errno = ERANGE; /* converted value out of range */
+ }
+
+ return 0.0;
+}
+
+/***
+converts the string at ARGUMENT(nptr) to a TYPE(double).
+Leading whitespace is ignored. The first character that is not a valid character
+for a floating-point constant and any characters after it are also ignored. A
+pointer to the first invalid character is stored in ARGUMENT(endptr), unless
+ARGUMENT(endptr) is CONSTANT(NULL).
+
+The converted portion of the string may start with an optional plus or minus
+sign, followed by a nonempty series of digits, optionally containing a
+decimal-point character. This may optionally be followed by an exponent.
+***/
+
+/*
+LC_CTYPE
+RETURN(ZERO, underflow or no conversion could be performed)
+RETURN(CONSTANT(HUGE_VAL), converted value too large)
+RETURN(CONSTANT(-HUGE_VAL), converted value too small)
+RETURN(VAR(a TYPE(double)), the converted value)
+STDC(1)
+*/
diff --git a/src/stdlib/strtof.c b/src/stdlib/strtof.c
new file mode 100644
index 00000000..b3da169c
--- /dev/null
+++ b/src/stdlib/strtof.c
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+
+float strtof(const char * restrict nptr, char ** restrict endptr)
+{
+}
+
+/*
+STDC(199901)
+*/
diff --git a/src/stdlib/strtol.c b/src/stdlib/strtol.c
new file mode 100644
index 00000000..247ac5de
--- /dev/null
+++ b/src/stdlib/strtol.c
@@ -0,0 +1,60 @@
+#include <stdlib.h>
+#include "limits.h"
+#include "errno.h"
+
+#if defined __STDC_VERSION__ && 199912L <= __STDC_VERSION__
+#include "inttypes.h"
+#else
+typedef long intmax_t;
+#define strtoimax(n, e, b) ((long)n & (long)e & (long)b) ? 0 : 0
+#endif
+
+/** convert string to long integer **/
+
+long int strtol(const char * restrict nptr, char ** restrict endptr, int base)
+{
+ /* FIXME: forward dependency on 9899-1999 */
+ intmax_t ret = strtoimax(nptr, endptr, base);
+
+ if (ret < LONG_MIN) {
+ ret = LONG_MIN;
+ errno = ERANGE; /* converted value out of range */
+ }
+
+ if (ret > LONG_MAX) {
+ ret = LONG_MAX;
+ errno = ERANGE; /* converted value out of range */
+ }
+
+ return (long int)ret;
+}
+
+/***
+converts the string at ARGUMENT(nptr) to a TYPE(long int).
+Leading whitespace is ignored. The first character that is not a valid character
+for a integer constant and any characters after it are also ignored. A pointer
+to the first invalid character is stored in ARGUMENT(endptr), unless
+ARGUMENT(endptr) is CONSTANT(NULL).
+
+The conversion is conducted in the base specified by ARGUMENT(base).
+Specifying 0 for ARGUMENT(base) will check the first few characters of
+ARGUMENT(nptr) to determine the conversion base. If it begins with LITERAL(0x)
+or LITERAL(0X), a base of 16 will be used. Otherwise, if it begins with
+CHAR(0), base 8 will be used. If neither of those occur, base 10 will be used.
+
+If ARGUMENT(base) is specified, it must be in the range [2,36]. For bases
+larger than 10, the letters CHAR(a) through CHAR(z) and their uppercase
+conversions are assigned the values 10 through 35. Base 16 numbers may be
+preceded by LITERAL(0x) or LITERAL(0X).
+
+The numeric string consists of an optional leading plus or minus followed by
+digits in the appropriate base.
+***/
+
+/*
+RETURN(ZERO, no conversion could be performed)
+RETURN(CONSTANT(LONG_MAX), converted value too large)
+RETURN(CONSTANT(LONG_MIN), converted value too small)
+RETURN(a TYPE(long int) value, the converted value)
+STDC(1)
+*/
diff --git a/src/stdlib/strtold.c b/src/stdlib/strtold.c
new file mode 100644
index 00000000..185f359e
--- /dev/null
+++ b/src/stdlib/strtold.c
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+
+long double strtold(const char * restrict nptr, char ** restrict endptr)
+{
+}
+
+/*
+STDC(199901)
+*/
diff --git a/src/stdlib/strtoll.c b/src/stdlib/strtoll.c
new file mode 100644
index 00000000..2f40229c
--- /dev/null
+++ b/src/stdlib/strtoll.c
@@ -0,0 +1,15 @@
+#include <stdlib.h>
+
+long long int strtoll(const char * restrict nptr, char ** restrict endptr, int base)
+{
+ intmax_t ret = strtoimax(nptr, endptr, base);
+ if (ret < LLONG_MIN) {
+ }
+ if (ret > LLONG_MAX) {
+ }
+ return (long long int)ret;
+}
+
+/*
+STDC(199901)
+*/
diff --git a/src/stdlib/strtoul.c b/src/stdlib/strtoul.c
new file mode 100644
index 00000000..9a00910b
--- /dev/null
+++ b/src/stdlib/strtoul.c
@@ -0,0 +1,53 @@
+#include <stdlib.h>
+#include "errno.h"
+#include "limits.h"
+
+#if defined __STDC_VERSION__ && 199912L <= __STDC_VERSION__
+#include "inttypes.h"
+#else
+typedef unsigned long uintmax_t;
+#define strtoumax(n, e, b) ((long)n & (long)e & (long)b ? 0 : 0)
+#endif
+
+/** convert string to unsigned long integer **/
+unsigned long int strtoul(const char * nptr, char ** endptr, int base)
+{
+ /* FIXME: forward dependency on 9899-1999 */
+ uintmax_t ret = strtoumax(nptr, endptr, base);
+
+ if (ret > ULONG_MAX) {
+ ret = ULONG_MAX;
+ errno = ERANGE; /* converted value too large */
+ }
+
+ return (unsigned long int)ret;
+}
+
+/***
+converts the string at ARGUMENT(nptr) to a
+type(unsigned long int). Leading whitespace is ignored. The first character
+that is not a valid character for a integer constant and any characters after
+it are also ignored. A pointer to the first invalid character is stored in
+ARGUMENT(endptr), unless ARGUMENT(endptr) is CONSTANT(NULL).
+
+The conversion is conducted in the base specified by ARGUMENT(base).
+Specifying 0 for ARGUMENT(base) will check the first few characters of
+ARGUMENT(nptr) to determine the conversion base. If it begins with LITERAL(0x)
+or LITERAL(0X), a base of 16 will be used. Otherwise, if it begins with
+CHAR(0), base 8 will be used. If neither of those occur, base 10 will be used.
+
+If ARGUMENT(base) is specified, it must be in the range [2,36]. For bases
+larger than 10, the letters CHAR(a) through CHAR(z) and their uppercase
+conversions are assigned the values 10 through 35. Base 16 numbers may be
+preceded by LITERAL(0x) or LITERAL(0X).
+
+The numeric string consists of an optional leading plus or minus followed by
+digits in the appropriate base.
+***/
+
+/*
+RETURN(ZERO, no conversion could be performed)
+RETURN(ULONG_MAX, converted value too large)
+RETURN(an TYPE(unsigned long int) value, the converted value)
+STDC(1)
+*/
diff --git a/src/stdlib/strtoull.c b/src/stdlib/strtoull.c
new file mode 100644
index 00000000..c95bac77
--- /dev/null
+++ b/src/stdlib/strtoull.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+
+unsigned long long int strtoull(const char * restrict nptr, char ** restrict endptr, int base)
+{
+ uintmax_t ret = strtoumax(nptr, endptr, base);
+ if (ret > ULLONG_MAX) {
+ }
+ return (unsigned long long int)ret;
+}
+
+/*
+STDC(199901)
+*/
diff --git a/src/stdlib/system.c b/src/stdlib/system.c
new file mode 100644
index 00000000..ac0d54d5
--- /dev/null
+++ b/src/stdlib/system.c
@@ -0,0 +1,61 @@
+#include <stdlib.h>
+
+#if defined _POSIX_SOURCE || defined _POSIX_C_SOURCE || defined _XOPEN_SOURCE
+# include "errno.h"
+# include "sys/types.h"
+# include "unistd.h"
+# include "sys/wait.h"
+# define USE_FORK
+#endif
+
+/** execute a command **/
+
+int system(const char * string)
+{
+ #if defined USE_FORK
+ pid_t pid;
+ int status;
+
+ if (string == NULL) {
+ return 0;
+ }
+
+ pid = fork();
+ if (pid < 0) {
+ /* errno comes from fork() */
+ return -1;
+ }
+
+ if (pid == 0) {
+ execl("/bin/sh", "sh", "-c", string, (char *)0);
+ _exit(1);
+ }
+
+ if (waitpid(pid, &status, 0) == -1) {
+ errno = ECHILD;
+ return -1;
+ }
+
+ return status;
+
+ #else
+ (void)string;
+ return 1;
+ #endif
+}
+
+/***
+runs the command ARGUMENT(string) using the host environment's command
+processor.
+
+Specifying CONSTANT(NULL) for ARGUMENT(string) tests whether a command
+processor is available.
+***/
+
+/*
+IMPLEMENTATION(How the command processor is invoked)
+IMPLEMENTATION(The return value when ARGUMENT(string) is not CONSTANT(NULL))
+RETURN(NONZERO, If ARGUMENT(string) is CONSTANT(NULL), a command processor is available)
+RETURN(0, If ARGUMENT(string) is CONSTANT(NULL), a command processor is not available)
+STDC(1)
+*/
diff --git a/src/stdlib/wchar_t.ref b/src/stdlib/wchar_t.ref
new file mode 100644
index 00000000..d551680b
--- /dev/null
+++ b/src/stdlib/wchar_t.ref
@@ -0,0 +1,3 @@
+#include <stdlib.h>
+REFERENCE(stddef/wchar_t.c)
+STDC(1)
diff --git a/src/stdlib/wcstombs.c b/src/stdlib/wcstombs.c
new file mode 100644
index 00000000..3643a5a4
--- /dev/null
+++ b/src/stdlib/wcstombs.c
@@ -0,0 +1,25 @@
+#include <stdlib.h>
+
+/** convert wide character string to multibyte string **/
+
+size_t wcstombs(char * restrict s, const wchar_t * restrict pwcs, size_t n)
+{
+ (void)s; (void)pwcs; (void)n;
+ /* TODO */
+ return 0;
+}
+
+/***
+converts the wide character string ARGUMENT(pwcs) to a multibyte string, which
+is stored at ARGUMENT(s), beginning in the initial shift state. No more than
+ARGUMENT(n) bytes are written to ARGUMENT(s). Conversion stops after reaching
+a null wide character, which is converted and stored.
+***/
+
+/*
+UNDEFINED(The memory regions of ARGUMENT(s) and ARGUMENT(pwcs) overlap)
+LC_CTYPE
+RETURN_FAILURE(-1)
+RETURN_SUCCESS(the number of bytes modified, not counting any terminating null)
+STDC(1)
+*/
diff --git a/src/stdlib/wctomb.c b/src/stdlib/wctomb.c
new file mode 100644
index 00000000..a2928a8b
--- /dev/null
+++ b/src/stdlib/wctomb.c
@@ -0,0 +1,33 @@
+#include <stdlib.h>
+
+/** convert wide character to multibyte character **/
+
+int wctomb(char * s, wchar_t wchar)
+{
+ /* FIXME: forward dependency on AMD1 */
+ #if 0
+ static mbstate_t ps = 0;
+ return wcrtomb(s, wchar, &ps);
+ #else
+ (void)s; (void)wchar;
+ return 0;
+ #endif
+}
+
+/***
+converts the wide character ARGUMENT(wchar) to a multibyte character, which is
+stored at the address ARGUMENT(s). At most CONSTANT(MB_CUR_MAX) bytes are
+stored.
+
+If ARGUMENT(s) is CONSTANT(NULL), fn(wctomb) tests whether multibyte encodings
+carry state dependency.
+***/
+
+/*
+LC_CTYPE
+RETURN(0, `If ARGUMENT(s) is CONSTANT(NULL), multibyte encodings do not have state dependencies')
+RETURN(NONZERO, `If ARGUMENT(s) is CONSTANT(NULL), multibyte encodings do have state dependencies')
+RETURN(-1, The value of ARGUMENT(wchar) does not correspond to a valid multibyte character)
+RETURN(TYPE(int), The number of bytes contained in the multibyte character corresponding to ARGUMENT(wchar))
+STDC(1)
+*/