/* General utilities This file is part of the Public Domain C Library (PDCLib). Permission is granted to use, modify, and / or redistribute at will. */ #ifndef _PDCLIB_STDLIB_H #define _PDCLIB_STDLIB_H _PDCLIB_STDLIB_H #ifdef __cplusplus extern "C" { #endif #include "pdclib/_PDCLIB_lib_ext1.h" #include "pdclib/_PDCLIB_internal.h" #ifndef _PDCLIB_SIZE_T_DEFINED #define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED typedef _PDCLIB_size_t size_t; #endif #ifndef _PDCLIB_NULL_DEFINED #define _PDCLIB_NULL_DEFINED _PDCLIB_NULL_DEFINED #define NULL _PDCLIB_NULL #endif /* Numeric conversion functions */ /* TODO: atof(), strtof(), strtod(), strtold() */ _PDCLIB_PUBLIC double atof( const char * nptr ); _PDCLIB_PUBLIC double strtod( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr ); _PDCLIB_PUBLIC float strtof( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr ); _PDCLIB_PUBLIC long double strtold( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr ); /* Separate the character array nptr into three parts: A (possibly empty) sequence of whitespace characters, a character representation of an integer to the given base, and trailing invalid characters (including the terminating null character). If base is 0, assume it to be 10, unless the integer representation starts with 0x / 0X (setting base to 16) or 0 (setting base to 8). If given, base can be anything from 0 to 36, using the 26 letters of the base alphabet (both lowercase and uppercase) as digits 10 through 35. The integer representation is then converted into the return type of the function. It can start with a '+' or '-' sign. If the sign is '-', the result of the conversion is negated. If the conversion is successful, the converted value is returned. If endptr is not a NULL pointer, a pointer to the first trailing invalid character is returned in *endptr. If no conversion could be performed, zero is returned (and nptr in *endptr, if endptr is not a NULL pointer). If the converted value does not fit into the return type, the functions return LONG_MIN, LONG_MAX, ULONG_MAX, LLONG_MIN, LLONG_MAX, or ULLONG_MAX respectively, depending on the sign of the integer representation and the return type, and errno is set to ERANGE. */ /* There is strtoimax() and strtoumax() in operating on intmax_t / uintmax_t, if the long long versions do not suit your needs. */ _PDCLIB_PUBLIC long int strtol( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base ); _PDCLIB_PUBLIC long long int strtoll( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base ); _PDCLIB_PUBLIC unsigned long int strtoul( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base ); _PDCLIB_PUBLIC unsigned long long int strtoull( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base ); /* These functions are the equivalent of (int)strtol( nptr, NULL, 10 ), strtol( nptr, NULL, 10 ) and strtoll(nptr, NULL, 10 ) respectively, with the exception that they do not have to handle overflow situations in any defined way. (PDCLib does not simply forward these to their strtox() equivalents, but provides a simpler atox() function that saves a couple of tests and simply continues with the conversion in case of overflow.) */ _PDCLIB_PUBLIC int atoi( const char * nptr ); _PDCLIB_PUBLIC long int atol( const char * nptr ); _PDCLIB_PUBLIC long long int atoll( const char * nptr ); /* Pseudo-random sequence generation functions */ extern unsigned long int _PDCLIB_seed; #define RAND_MAX 32767 /* Returns the next number in a pseudo-random sequence, which is between 0 and RAND_MAX. (PDCLib uses the implementation suggested by the standard document, which is next = next * 1103515245 + 12345; return (unsigned int)(next/65536) % 32768;) */ _PDCLIB_PUBLIC int rand( void ); /* Initialize a new pseudo-random sequence with the starting seed. Same seeds result in the same pseudo-random sequence. The default seed is 1. */ _PDCLIB_PUBLIC void srand( unsigned int seed ); /* Memory management functions */ /* Allocate a chunk of heap memory of given size. If request could not be satisfied, return NULL. Otherwise, return a pointer to the allocated memory. Memory contents are undefined. */ _PDCLIB_PUBLIC void * malloc( size_t size ); /* Allocate a chunk of heap memory that is large enough to hold nmemb elements of the given size, and zero-initialize that memory. If request could not be satisfied, return NULL. Otherwise, return a pointer to the allocated memory. */ _PDCLIB_PUBLIC void * calloc( size_t nmemb, size_t size ); /* De-allocate a chunk of heap memory previously allocated using malloc(), calloc(), or realloc(), and pointed to by ptr. If ptr does not match a pointer previously returned by the mentioned allocation functions, or free() has already been called for this ptr, behaviour is undefined. */ _PDCLIB_PUBLIC void free( void * ptr ); /* Resize a chunk of memory previously allocated with malloc() and pointed to by ptr to the given size (which might be larger or smaller than the original size). Returns a pointer to the reallocated memory, or NULL if the request could not be satisfied. Note that the resizing might include a memcpy() from the original location to a different one, so the return value might or might not equal ptr. If size is larger than the original size, the value of memory beyond the original size is undefined. If ptr is NULL, realloc() behaves like malloc(). */ _PDCLIB_PUBLIC void * realloc( void * ptr, size_t size ); /* Communication with the environment */ /* These two can be passed to exit() or _Exit() as status values, to signal successful and unsuccessful program termination, respectively. EXIT_SUCCESS can be replaced by 0. How successful or unsuccessful program termination are signaled to the environment, and what happens if exit() or _Exit() are being called with a value that is neither of the three, is defined by the hosting OS and its glue function. */ #define EXIT_SUCCESS _PDCLIB_SUCCESS #define EXIT_FAILURE _PDCLIB_FAILURE /* Initiate abnormal process termination, unless programm catches SIGABRT and does not return from the signal handler. This implementantion flushes all streams, closes all files, and removes any temporary files before exiting with EXIT_FAILURE. abort() does not return. */ _PDCLIB_PUBLIC _PDCLIB_Noreturn void abort( void ) _PDCLIB_NORETURN; /* Register a function that will be called on quick_exit(). At least 32 functions can be registered this way, and will be called in reverse order of registration (last-in, first-out). Returns zero if registration is successfull, nonzero if it failed. */ _PDCLIB_PUBLIC int at_quick_exit( void ( *func )( void ) ); /* Register a function that will be called on exit(), or when main() returns. At least 32 functions can be registered this way, and will be called in reverse order of registration (last-in, first-out). Returns zero if registration is successfull, nonzero if it failed. */ _PDCLIB_PUBLIC int atexit( void ( *func )( void ) ); /* Normal process termination. Functions registered by atexit() (see above) are called, streams flushed, files closed and temporary files removed before the program is terminated with the given status. (See comment for EXIT_SUCCESS and EXIT_FAILURE above.) exit() does not return. */ _PDCLIB_PUBLIC _PDCLIB_Noreturn void exit( int status ) _PDCLIB_NORETURN; /* Normal process termination. Functions registered by at_quick_exit() (see above) are called, streams flushed, files closed and temporary files removed before the program is terminated with the given status. (See comment for EXIT_SUCCESS and EXIT_FAILURE above.) quick_exit() does not return. */ _PDCLIB_PUBLIC _PDCLIB_Noreturn void quick_exit( int status ) _PDCLIB_NORETURN; /* Normal process termination. Functions registered by atexit()/at_quick_exit() (see above) are NOT CALLED. This implementation DOES flush streams, close files and removes temporary files before the program is teminated with the given status. (See comment for EXIT_SUCCESS and EXIT_FAILURE above.) _Exit() does not return. */ _PDCLIB_PUBLIC _PDCLIB_Noreturn void _Exit( int status ) _PDCLIB_NORETURN; /* Search an environment-provided key-value map for the given key name, and return a pointer to the associated value string (or NULL if key name cannot be found). The value string pointed to might be overwritten by a subsequent call to getenv(). The library never calls getenv() itself. Details on the provided keys and how to set / change them are determined by the hosting OS and its glue function. */ _PDCLIB_PUBLIC char * getenv( const char * name ); /* If string is a NULL pointer, system() returns nonzero if a command processor is available, and zero otherwise. If string is not a NULL pointer, it is passed to the command processor. If system() returns, it does so with a value that is determined by the hosting OS and its glue function. */ _PDCLIB_PUBLIC int system( const char * string ); /* Searching and sorting */ /* Do a binary search for a given key in the array with a given base pointer, which consists of nmemb elements that are of the given size each. To compare the given key with an element from the array, the given function compar is called (with key as first parameter and a pointer to the array member as second parameter); the function should return a value less than, equal to, or greater than 0 if the key is considered to be less than, equal to, or greater than the array element, respectively. The function returns a pointer to a matching element found, or NULL if no match is found. */ _PDCLIB_PUBLIC void * bsearch( const void * key, const void * base, size_t nmemb, size_t size, int ( *compar )( const void *, const void * ) ); /* Do a quicksort on an array with a given base pointer, which consists of nmemb elements that are of the given size each. To compare two elements from the array, the given function compar is called, which should return a value less than, equal to, or greater than 0 if the first argument is considered to be less than, equal to, or greater than the second argument, respectively. If two elements are compared equal, their order in the sorted array is not specified. */ _PDCLIB_PUBLIC void qsort( void * base, size_t nmemb, size_t size, int ( *compar )( const void *, const void * ) ); /* Integer arithmetic functions */ /* Return the absolute value of the argument. Note that on machines using two- complement's notation (most modern CPUs), the largest negative value cannot be represented as positive value. In this case, behaviour is unspecified. */ _PDCLIB_PUBLIC int abs( int j ); _PDCLIB_PUBLIC long int labs( long int j ); _PDCLIB_PUBLIC long long int llabs( long long int j ); /* These structures each have a member quot and a member rem, of type int (for div_t), long int (for ldiv_t) and long long it (for lldiv_t) respectively. The order of the members is platform-defined to allow the div() functions below to be implemented efficiently. */ typedef struct _PDCLIB_div_t div_t; typedef struct _PDCLIB_ldiv_t ldiv_t; typedef struct _PDCLIB_lldiv_t lldiv_t; /* Return quotient (quot) and remainder (rem) of an integer division in one of the structs above. */ _PDCLIB_PUBLIC div_t div( int numer, int denom ); _PDCLIB_PUBLIC ldiv_t ldiv( long int numer, long int denom ); _PDCLIB_PUBLIC lldiv_t lldiv( long long int numer, long long int denom ); /* TODO: Multibyte / wide character conversion functions */ /* TODO: Macro MB_CUR_MAX */ /* _PDCLIB_PUBLIC int mblen( const char * s, size_t n ); _PDCLIB_PUBLIC int mbtowc( wchar_t * _PDCLIB_restrict pwc, const char * _PDCLIB_restrict s, size_t n ); _PDCLIB_PUBLIC int wctomb( char * s, wchar_t wc ); _PDCLIB_PUBLIC size_t mbstowcs( wchar_t * _PDCLIB_restrict pwcs, const char * _PDCLIB_restrict s, size_t n ); _PDCLIB_PUBLIC size_t wcstombs( char * _PDCLIB_restrict s, const wchar_t * _PDCLIB_restrict pwcs, size_t n ); */ /* Annex K -- Bounds-checking interfaces */ #if ( __STDC_WANT_LIB_EXT1__ + 0 ) != 0 #ifndef _PDCLIB_ERRNO_T_DEFINED #define _PDCLIB_ERRNO_T_DEFINED _PDCLIB_ERRNO_T_DEFINED typedef int errno_t; #endif #ifndef _PDCLIB_RSIZE_T_DEFINED #define _PDCLIB_RSIZE_T_DEFINED _PDCLIB_RSIZE_T_DEFINED typedef size_t rsize_t; #endif /* A function type that can serve as a constraint handler (see below). The first parameter is an error message on the constraint violation, the second parameter a pointer to an implementation-defined object, the third an error code related to the constraint violation. If the function calling the constraint handler is defined to return errno_t, the third parameter will be identical to the return value of that function. This implementation sets the second parameter of the constraint handler call to NULL. */ typedef void ( *constraint_handler_t )( const char * _PDCLIB_restrict msg, void * _PDCLIB_restrict ptr, errno_t error ); /* The currently active constraint violation handler. This implementation sets abort_handler_s as the default constraint violation handler. */ extern constraint_handler_t _PDCLIB_constraint_handler; /* Set the given function as the new constraint violation handler. */ _PDCLIB_PUBLIC constraint_handler_t set_constraint_handler_s( constraint_handler_t handler ); /* One of two predefined constraint violation handlers. When called, it will print an error message (including the message passed as the first parameter to the handler function) and call abort(). */ _PDCLIB_PUBLIC void abort_handler_s( const char * _PDCLIB_restrict msg, void * _PDCLIB_restrict ptr, errno_t error ); /* One of two predefined constraint violation handlers. Simply returns, ignoring the constraint violation. */ _PDCLIB_PUBLIC void ignore_handler_s( const char * _PDCLIB_restrict msg, void * _PDCLIB_restrict ptr, errno_t error ); /* Search an environment-provided key-value map for the given key name. If the name is found, - if len is not NULL, the length of the associated value string is stored in that location. - if len < maxsize, the value string is copied to the indicated location. If the name is not found, - if len is not NULL, a zero is stored in that location. - if maxsize > 0, value[0] is set to the null character. Details on the provided keys and how to set / change them are determined by the hosting OS and its glue function. The following conditions will be considered runtime constraint violations: - value being a NULL pointer. - maxsize == 0 or maxsize > RSIZE_MAX. In case of a constraint violation, if len is not NULL a zero will be stored at that location, and the environment key-value map not searched. The currently active constraint violation handler function will be called (see set_constraint_handler_s()). */ _PDCLIB_PUBLIC errno_t getenv_s( size_t * _PDCLIB_restrict len, char * _PDCLIB_restrict value, rsize_t maxsize, const char * _PDCLIB_restrict name ); /* Do a binary search for a given key in the array with a given base pointer, which consists of nmemb elements that are of the given size each. To compare the given key with an element from the array, the given function compar is called (with key as first parameter, a pointer to the array member as second parameter, and the context parameter passed to bsearch_s() as third parameter); the function should return a value less than, equal to, or greater than 0 if the key is considered to be less than, equal to, or greater than the array element, respectively. The function returns a pointer to a matching element found, or NULL if no match is found. The following conditions will be considered runtime constraint violations: - nmemb or size > RSIZE_MAX. - nmemb > 0 and either of key, base, or compar being a null pointer. In case of a constraint violation, the array will not be searched. The currently active constraint violation handler function will be called (see set_constraint_handler_s()). */ _PDCLIB_PUBLIC void * bsearch_s( const void * key, const void * base, rsize_t nmemb, rsize_t size, int ( *compar )( const void * k, const void * y, void * context ), void * context ); /* Do a quicksort on an array with a given base pointer, which consists of nmemb elements that are of the given size each. To compare two elements from the array, the given function compar is called, with the first two arguments being pointers to the two objects to be compared, and the third argument being the context parameter passed to qsort_s. The compar function should return a value less than, equal to, or greater than 0 if the first argument is considered to be less than, equal to, or greater than the second argument, respectively. If two elements are compared equal, their order in the sorted array is not specified. The following conditions will be considered runtime constraint violations: - nmemb or size > RSIZE_MAX. - nmemb > 0 and either of base or compar being a null pointer. In case of a constraint violation, the array will not be sorted. The currently active constraint violation handler function will be called (see set_constraint_handler_s()). */ _PDCLIB_PUBLIC errno_t qsort_s( void * base, rsize_t nmemb, rsize_t size, int ( *compar )( const void * x, const void * y, void * context ), void * context ); /* TODO: Multibyte / wide character functions */ #endif #ifdef __cplusplus } #endif /* Extension hook for downstream projects that want to have non-standard extensions to standard headers. */ #ifdef _PDCLIB_EXTEND_STDLIB_H #include _PDCLIB_EXTEND_STDLIB_H #endif #endif