diff options
Diffstat (limited to 'src/stdlib')
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) +*/ |
