From 064097d5ed6eb8c2cfd337c29ac3ebc471e557b8 Mon Sep 17 00:00:00 2001 From: solar Date: Mon, 26 Dec 2005 10:27:14 +0000 Subject: [PATCH] Added exit, _Exit, atexit. --- Readme.txt | 4 ++- functions/stdlib/_Exit.c | 33 ++++++++++++++++++++++ functions/stdlib/atexit.c | 53 +++++++++++++++++++++++++++++++++++ functions/stdlib/exit.c | 51 ++++++++++++++++++++++++++++++++++ includes/stdlib.h | 57 ++++++++++++++++++++++++++++++++------ internals/_PDCLIB_config.h | 9 ++++++ 6 files changed, 198 insertions(+), 9 deletions(-) create mode 100644 functions/stdlib/_Exit.c create mode 100644 functions/stdlib/atexit.c create mode 100644 functions/stdlib/exit.c diff --git a/Readme.txt b/Readme.txt index b7b43ed..6e0ffca 100644 --- a/Readme.txt +++ b/Readme.txt @@ -150,4 +150,6 @@ Adds test drivers, fixes some bugs in . v0.4 - unreleased Implementations for parts of . -(strtol, strtoul, atoi, atol, atoll, rand, srand, bsearch, qsort.) +(strtol, strtoul, atoi, atol, atoll, rand, srand, bsearch, qsort, abort, +exit / _Exit (partial), atexit.) + diff --git a/functions/stdlib/_Exit.c b/functions/stdlib/_Exit.c new file mode 100644 index 0000000..d5b31f8 --- /dev/null +++ b/functions/stdlib/_Exit.c @@ -0,0 +1,33 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* _Exit( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +void _Exit( int status ) +{ + _PDCLIB_Exit( status ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main() +{ + int NO_TESTDRIVER = 0; + BEGIN_TESTS; + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdlib/atexit.c b/functions/stdlib/atexit.c new file mode 100644 index 0000000..573e4ba --- /dev/null +++ b/functions/stdlib/atexit.c @@ -0,0 +1,53 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* atexit( void (*)( void ) ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +/* TODO: Required by both atexit() and exit(). */ +struct _PDCLIB_exitfunc_t +{ + struct _PDCLIB_exitfunc_t * next; + void (*func)( void ); +}; + +extern struct _PDCLIB_exitfunc_t * regstack; + +int atexit( void (*func)( void ) ) +{ + struct _PDCLIB_exitfunc_t * regfunc = (struct _PDCLIB_exitfunc_t *)malloc( sizeof( struct _PDCLIB_exitfunc_t ) ); + if ( regfunc == NULL ) + { + return -1; + } + else + { + regfunc->func = func; + regfunc->next = regstack; + regstack = regfunc; + return 0; + } +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main() +{ + int NO_TESTDRIVER = 0; + BEGIN_TESTS; + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdlib/exit.c b/functions/stdlib/exit.c new file mode 100644 index 0000000..f093fe0 --- /dev/null +++ b/functions/stdlib/exit.c @@ -0,0 +1,51 @@ +/* $Id$ */ + +/* Release $Name$ */ + +/* exit( int ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +/* TODO: Required by both atexit() and exit(). */ +struct _PDCLIB_exitfunc_t +{ + struct _PDCLIB_exitfunc_t * next; + void (*func)( void ); +}; + +struct _PDCLIB_exitfunc_t * regstack = NULL; + +void exit( int status ) +{ + struct _PDCLIB_exitfunc_t * next = regstack; + while ( next != NULL ) + { + next->func(); + regstack = next->next; + free( next ); + next = regstack; + } + /* TODO: Flush and close open streams. Remove tmpfile() files. */ + _Exit( status ); +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main() +{ + int NO_TESTDRIVER = 0; + BEGIN_TESTS; + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/includes/stdlib.h b/includes/stdlib.h index b48dae9..a83bd1e 100644 --- a/includes/stdlib.h +++ b/includes/stdlib.h @@ -16,10 +16,6 @@ #include <_PDCLIB_int.h> #endif -typedef struct _PDCLIB_div_t div_t; -typedef struct _PDCLIB_ldiv_t ldiv_t; -typedef struct _PDCLIB_lldiv_t lldiv_t; - #ifndef _PDCLIB_SIZE_T_DEFINED #define _PDCLIB_SIZE_T_DEFINED _PDCLIB_SIZE_T_DEFINED typedef _PDCLIB_size_t size_t; @@ -31,31 +27,72 @@ typedef _PDCLIB_size_t size_t; /* Numeric conversion functions */ -int atoi( const char * nptr ); -long int atol( const char * nptr ); -long long int atoll( const char * nptr ); - +/* TODO: atof(), strtof(), strtod(), strtold() */ + +/* Seperate 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. +*/ long int strtol( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base ); long long int strtoll( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base ); unsigned long int strtoul( const char * _PDCLIB_restrict nptr, char * * _PDCLIB_restrict endptr, int base ); 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.) +*/ +int atoi( const char * nptr ); +long int atol( const char * nptr ); +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;) +*/ int rand(); + +/* Initialize a new pseudo-random sequence with the starting seed. Same seeds + result in the same pseudo-random sequence. The default seed is 1. +*/ void srand( unsigned int seed ); /* Memory management functions */ +void * malloc( size_t size ); +void free( void * ptr ); /* Communication with the environment */ void abort(); void exit( int status ); +void _Exit( int status ); /* Searching and sorting */ @@ -68,6 +105,10 @@ int abs( int j ); long int labs( long int j ); long long int llabs( long long int j ); +typedef struct _PDCLIB_div_t div_t; +typedef struct _PDCLIB_ldiv_t ldiv_t; +typedef struct _PDCLIB_lldiv_t lldiv_t; + div_t div( int numer, int denom ); ldiv_t ldiv( long int numer, long int denom ); lldiv_t lldiv( long long int numer, long long int denom ); diff --git a/internals/_PDCLIB_config.h b/internals/_PDCLIB_config.h index d2188ff..2fa66c7 100644 --- a/internals/_PDCLIB_config.h +++ b/internals/_PDCLIB_config.h @@ -199,3 +199,12 @@ typedef char * _PDCLIB_va_list; #define _PDCLIB_va_copy( dest, src ) ( (dest) = (src), (void)0 ) #define _PDCLIB_va_end( ap ) ( (ap) = (void *)0, (void)0 ) #define _PDCLIB_va_start( ap, parmN ) ( (ap) = (char *) &parmN + ( _PDCLIB_va_round(parmN) ), (void)0 ) + +/* -------------------------------------------------------------------------- */ +/* OS "glue" */ +/* This is where PDCLib interfaces with the operating system. The examples */ +/* below are POSIX calls; provide your OS' equivalents. */ +/* -------------------------------------------------------------------------- */ + +/* A system call that terminates the calling process */ +#define _PDCLIB_Exit( x ) _exit( x ) -- 2.40.0