From d58957de3e0b9b7076a6f5dd49d5df8e78f5a826 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Fri, 16 Mar 2012 19:20:36 -0700 Subject: [PATCH] Add altos platform This has all of the stubs necessary to run pdclib on AltOS Signed-off-by: Keith Packard --- platform/altos/Readme.txt | 6 + platform/altos/functions/_PDCLIB/allocpages.c | 83 ++++ platform/altos/functions/_PDCLIB/fillbuffer.c | 39 ++ .../altos/functions/_PDCLIB/flushbuffer.c | 52 +++ platform/altos/functions/_PDCLIB/stdinit.c | 45 +++ platform/altos/functions/ctype/isspace.c | 46 +++ platform/altos/functions/ctype/tolower.c | 37 ++ platform/altos/includes/float.h | 80 ++++ platform/altos/includes/signal.h | 90 +++++ platform/altos/internals/_PDCLIB_config.h | 356 ++++++++++++++++++ 10 files changed, 834 insertions(+) create mode 100644 platform/altos/Readme.txt create mode 100644 platform/altos/functions/_PDCLIB/allocpages.c create mode 100644 platform/altos/functions/_PDCLIB/fillbuffer.c create mode 100644 platform/altos/functions/_PDCLIB/flushbuffer.c create mode 100644 platform/altos/functions/_PDCLIB/stdinit.c create mode 100644 platform/altos/functions/ctype/isspace.c create mode 100644 platform/altos/functions/ctype/tolower.c create mode 100644 platform/altos/includes/float.h create mode 100644 platform/altos/includes/signal.h create mode 100644 platform/altos/internals/_PDCLIB_config.h diff --git a/platform/altos/Readme.txt b/platform/altos/Readme.txt new file mode 100644 index 0000000..ec585e5 --- /dev/null +++ b/platform/altos/Readme.txt @@ -0,0 +1,6 @@ +$Id$ + +"AltOS" Platform Overlay +========================== + +An overlay for AltOS. All stdio operations go to the AltOS console. diff --git a/platform/altos/functions/_PDCLIB/allocpages.c b/platform/altos/functions/_PDCLIB/allocpages.c new file mode 100644 index 0000000..435e8c6 --- /dev/null +++ b/platform/altos/functions/_PDCLIB/allocpages.c @@ -0,0 +1,83 @@ +/* $Id$ */ + +/* _PDCLIB_allocpages( int const ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example implementation of _PDCLIB_allocpages() (declared in + _PDCLIB_config.h), fit for use with POSIX kernels. +*/ + +#include +#include + +int brk( void * ); +void * sbrk( intptr_t ); + +#ifndef _PDCLIB_GLUE_H +#define _PDCLIB_GLUE_H _PDCLIB_GLUE_H +#include <_PDCLIB_glue.h> +#endif + +static void * membreak = NULL; + +void * _PDCLIB_allocpages( int const n ) +{ + if ( membreak == NULL ) + { + /* first call, make sure end-of-heap is page-aligned */ + intptr_t unaligned = 0; + membreak = sbrk( 0 ); + unaligned = _PDCLIB_PAGESIZE - (intptr_t)membreak % _PDCLIB_PAGESIZE; + if ( unaligned < _PDCLIB_PAGESIZE ) + { + /* end-of-heap not page-aligned - adjust */ + if ( sbrk( unaligned ) != membreak ) + { + /* error */ + return NULL; + } + membreak = (char *)membreak + unaligned; + } + } + /* increasing or decreasing heap - standard operation */ + void * oldbreak = membreak; + membreak = (void *)( (char *)membreak + ( n * _PDCLIB_PAGESIZE ) ); + if ( brk( membreak ) == 0 ) + { + /* successful */ + return oldbreak; + } + else + { + /* out of memory */ + membreak = oldbreak; + return NULL; + } +} + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ +#ifndef REGTEST + { + char * startbreak = sbrk( 0 ); + TESTCASE( _PDCLIB_allocpages( 0 ) ); + TESTCASE( ( (char *)sbrk( 0 ) - startbreak ) <= _PDCLIB_PAGESIZE ); + startbreak = sbrk( 0 ); + TESTCASE( _PDCLIB_allocpages( 1 ) ); + TESTCASE( sbrk( 0 ) == startbreak + ( 1 * _PDCLIB_PAGESIZE ) ); + TESTCASE( _PDCLIB_allocpages( 5 ) ); + TESTCASE( sbrk( 0 ) == startbreak + ( 6 * _PDCLIB_PAGESIZE ) ); + TESTCASE( _PDCLIB_allocpages( -3 ) ); + TESTCASE( sbrk( 0 ) == startbreak + ( 3 * _PDCLIB_PAGESIZE ) ); + } +#endif + return TEST_RESULTS; +} + +#endif diff --git a/platform/altos/functions/_PDCLIB/fillbuffer.c b/platform/altos/functions/_PDCLIB/fillbuffer.c new file mode 100644 index 0000000..cf55c58 --- /dev/null +++ b/platform/altos/functions/_PDCLIB/fillbuffer.c @@ -0,0 +1,39 @@ +/* $Id$ */ + +/* _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example implementation of _PDCLIB_fillbuffer() fit for + use with POSIX kernels. +*/ + +#include + +#ifndef REGTEST +#include <_PDCLIB_glue.h> + +int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream ) +{ + stream->buffer[0] = inbyte(); + stream->pos.offset += 1; + stream->bufend = 1; + stream->bufidx = 0; + return 0; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + /* Testing covered by ftell.c */ + return TEST_RESULTS; +} + +#endif + diff --git a/platform/altos/functions/_PDCLIB/flushbuffer.c b/platform/altos/functions/_PDCLIB/flushbuffer.c new file mode 100644 index 0000000..2c54ce0 --- /dev/null +++ b/platform/altos/functions/_PDCLIB/flushbuffer.c @@ -0,0 +1,52 @@ +/* $Id$ */ + +/* _PDCLIB_flushbuffer( struct _PDCLIB_file_t * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example implementation of _PDCLIB_flushbuffer() fit for + use with POSIX kernels. +*/ + +#include + +#ifndef REGTEST +#include <_PDCLIB_glue.h> + +/* The number of attempts to complete an output buffer flushing before giving + * up. + * */ +#define _PDCLIB_IO_RETRIES 1 + +/* What the system should do after an I/O operation did not succeed, before */ +/* trying again. (Empty by default.) */ +#define _PDCLIB_IO_RETRY_OP( stream ) + +/* Must be provided by host system */ +extern void outbyte(char c); + +int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream ) +{ + char *c = stream->buffer; + int i = stream->bufidx; + while (i--) + outbyte(*c++); + return 0; +} + +#endif + + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + /* Testing covered by ftell.c */ + return TEST_RESULTS; +} + +#endif + diff --git a/platform/altos/functions/_PDCLIB/stdinit.c b/platform/altos/functions/_PDCLIB/stdinit.c new file mode 100644 index 0000000..8598e33 --- /dev/null +++ b/platform/altos/functions/_PDCLIB/stdinit.c @@ -0,0 +1,45 @@ +/* $Id$ */ + +/* _PDCLIB_stdinit + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example initialization of stdin, stdout and stderr to the integer + file descriptors 0, 1, and 2, respectively. This applies for a great variety + of operating systems, including POSIX compliant ones. +*/ + +#include +#include +#include + +#ifndef REGTEST + +/* In a POSIX system, stdin / stdout / stderr are equivalent to the (int) file + descriptors 0, 1, and 2 respectively. +*/ +/* TODO: This is proof-of-concept, requires finetuning. */ + +__attribute__ ((section(".text"))) +struct _PDCLIB_file_t * stdin = (struct _PDCLIB_file_t *) 1; +__attribute__ ((section(".text"))) +struct _PDCLIB_file_t * stdout = (struct _PDCLIB_file_t *) 1; +__attribute__ ((section(".text"))) +struct _PDCLIB_file_t * stderr = (struct _PDCLIB_file_t *) 1; + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + /* Testing covered by several other testdrivers using stdin / stdout / + stderr. + */ + return TEST_RESULTS; +} + +#endif diff --git a/platform/altos/functions/ctype/isspace.c b/platform/altos/functions/ctype/isspace.c new file mode 100644 index 0000000..4012f0a --- /dev/null +++ b/platform/altos/functions/ctype/isspace.c @@ -0,0 +1,46 @@ +/* $Id$ */ + +/* isspace( 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 + +#include + +int isspace( int c ) +{ + switch (c) { + case ' ': + case '\f': + case '\n': + case '\r': + case '\t': + case '\v': + return 1; + } + return 0; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( isspace( ' ' ) ); + TESTCASE( isspace( '\f' ) ); + TESTCASE( isspace( '\n' ) ); + TESTCASE( isspace( '\r' ) ); + TESTCASE( isspace( '\t' ) ); + TESTCASE( isspace( '\v' ) ); + TESTCASE( ! isspace( 'a' ) ); + return TEST_RESULTS; +} + +#endif diff --git a/platform/altos/functions/ctype/tolower.c b/platform/altos/functions/ctype/tolower.c new file mode 100644 index 0000000..44909e8 --- /dev/null +++ b/platform/altos/functions/ctype/tolower.c @@ -0,0 +1,37 @@ +/* $Id$ */ + +/* tolower( 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 + +#include + +int tolower( int c ) +{ + if ('A' <= c && c <= 'Z') + c = c + 'a' - 'A'; + return c; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( tolower( 'A' ) == 'a' ); + TESTCASE( tolower( 'Z' ) == 'z' ); + TESTCASE( tolower( 'a' ) == 'a' ); + TESTCASE( tolower( 'z' ) == 'z' ); + TESTCASE( tolower( '@' ) == '@' ); + TESTCASE( tolower( '[' ) == '[' ); + return TEST_RESULTS; +} +#endif diff --git a/platform/altos/includes/float.h b/platform/altos/includes/float.h new file mode 100644 index 0000000..de47aeb --- /dev/null +++ b/platform/altos/includes/float.h @@ -0,0 +1,80 @@ +/* $Id$ */ + +/* 7.7 Characteristics of floating types + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#ifndef _PDCLIB_FLOAT_H +#define _PDCLIB_FLOAT_H _PDCLIB_FLOAT_H + +#ifndef _PDCLIB_CONFIG_H +#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H +#include <_PDCLIB_config.h> +#endif + +#define FLT_ROUNDS _PDCLIB_FLT_ROUNDS +#define FLT_EVAL_METHOD _PDCLIB_FLT_EVAL_METHOD +#define DECIMAL_DIG _PDCLIB_DECIMAL_DIG + + /* Radix of exponent representation */ +#define FLT_RADIX __FLT_RADIX__ + /* Number of base-FLT_RADIX digits in the significand of a float */ +#define FLT_MANT_DIG __FLT_MANT_DIG__ + /* Number of decimal digits of precision in a float */ +#define FLT_DIG __FLT_DIG__ + /* Difference between 1.0 and the minimum float greater than 1.0 */ +#define FLT_EPSILON __FLT_EPSILON__ + /* Minimum int x such that FLT_RADIX**(x-1) is a normalised float */ +#define FLT_MIN_EXP __FLT_MIN_EXP__ + /* Minimum normalised float */ +#define FLT_MIN __FLT_MIN__ + /* Minimum int x such that 10**x is a normalised float */ +#define FLT_MIN_10_EXP __FLT_MIN_10_EXP__ + /* Maximum int x such that FLT_RADIX**(x-1) is a representable float */ +#define FLT_MAX_EXP __FLT_MAX_EXP__ + /* Maximum float */ +#define FLT_MAX __FLT_MAX__ + /* Maximum int x such that 10**x is a representable float */ +#define FLT_MAX_10_EXP __FLT_MAX_10_EXP__ + + /* Number of base-FLT_RADIX digits in the significand of a double */ +#define DBL_MANT_DIG __DBL_MANT_DIG__ + /* Number of decimal digits of precision in a double */ +#define DBL_DIG __DBL_DIG__ + /* Difference between 1.0 and the minimum double greater than 1.0 */ +#define DBL_EPSILON __DBL_EPSILON__ + /* Minimum int x such that FLT_RADIX**(x-1) is a normalised double */ +#define DBL_MIN_EXP __DBL_MIN_EXP__ + /* Minimum normalised double */ +#define DBL_MIN __DBL_MIN__ + /* Minimum int x such that 10**x is a normalised double */ +#define DBL_MIN_10_EXP __DBL_MIN_10_EXP__ + /* Maximum int x such that FLT_RADIX**(x-1) is a representable double */ +#define DBL_MAX_EXP __DBL_MAX_EXP__ + /* Maximum double */ +#define DBL_MAX __DBL_MAX__ + /* Maximum int x such that 10**x is a representable double */ +#define DBL_MAX_10_EXP __DBL_MAX_10_EXP__ + + /* Number of base-FLT_RADIX digits in the significand of a long double */ +#define LDBL_MANT_DIG __LDBL_MANT_DIG__ + /* Number of decimal digits of precision in a long double */ +#define LDBL_DIG __LDBL_DIG__ + /* Difference between 1.0 and the minimum long double greater than 1.0 */ +#define LDBL_EPSILON __LDBL_EPSILON__ + /* Minimum int x such that FLT_RADIX**(x-1) is a normalised long double */ +#define LDBL_MIN_EXP __LDBL_MIN_EXP__ + /* Minimum normalised long double */ +#define LDBL_MIN __LDBL_MIN__ + /* Minimum int x such that 10**x is a normalised long double */ +#define LDBL_MIN_10_EXP __LDBL_MIN_10_EXP__ + /* Maximum int x such that FLT_RADIX**(x-1) is a representable long double */ +#define LDBL_MAX_EXP __LDBL_MAX_EXP__ + /* Maximum long double */ +#define LDBL_MAX __LDBL_MAX__ + /* Maximum int x such that 10**x is a representable long double */ +#define LDBL_MAX_10_EXP __LDBL_MAX_10_EXP__ + +#endif diff --git a/platform/altos/includes/signal.h b/platform/altos/includes/signal.h new file mode 100644 index 0000000..9b812c9 --- /dev/null +++ b/platform/altos/includes/signal.h @@ -0,0 +1,90 @@ +/* $Id$ */ + +/* 7.14 Signal handling + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#ifndef _PDCLIB_SIGNAL_H +#define _PDCLIB_SIGNAL_H _PDCLIB_SIGNAL_H + +#ifndef _PDCLIB_CONFIG_H +#define _PDCLIB_CONFIG_H _PDCLIB_CONFIG_H +#include <_PDCLIB_config.h> +#endif + +/* Signals ------------------------------------------------------------------ */ + +/* A word on signals, to the people using PDCLib in their OS projects. + + The definitions of the C standard leave about everything that *could* be + useful to be "implementation defined". Without additional, non-standard + arrangements, it is not possible to turn them into a useful tool. + + This example implementation chose to "not generate any of these signals, + except as a result of explicit calls to the raise function", which is + allowed by the standard but of course does nothing for the usefulness of + . + + A useful signal handling would: + 1) make signal() a system call that registers the signal handler with the OS + 2) make raise() a system call triggering an OS signal to the running process + 3) make provisions that further signals of the same type are blocked until + the signal handler returns (optional for SIGILL) +*/ + +/* These are the values used by Linux. */ + +/* Abnormal termination / abort() */ +#define SIGABRT 6 +/* Arithmetic exception / division by zero / overflow */ +#define SIGFPE 8 +/* Illegal instruction */ +#define SIGILL 4 +/* Interactive attention signal */ +#define SIGINT 2 +/* Invalid memory access */ +#define SIGSEGV 11 +/* Termination request */ +#define SIGTERM 15 + +/* The following should be defined to pointer values that could NEVER point to + a valid signal handler function. (They are used as special arguments to + signal().) Again, these are the values used by Linux. +*/ +#define SIG_DFL (void (*)( int ))0 +#define SIG_ERR (void (*)( int ))-1 +#define SIG_IGN (void (*)( int ))1 + +typedef _PDCLIB_sig_atomic sig_atomic_t; + +/* Installs a signal handler "func" for the given signal. + A signal handler is a function that takes an integer as argument (the signal + number) and returns void. + + Note that a signal handler can do very little else than: + 1) assign a value to a static object of type "volatile sig_atomic_t", + 2) call signal() with the value of sig equal to the signal received, + 3) call _Exit(), + 4) call abort(). + Virtually everything else is undefind. + + The signal() function returns the previous installed signal handler, which + at program start may be SIG_DFL or SIG_ILL. (This implementation uses + SIG_DFL for all handlers.) If the request cannot be honored, SIG_ERR is + returned and errno is set to an unspecified positive value. +*/ +void (*signal( int sig, void (*func)( int ) ) )( int ); + +/* Raises the given signal (executing the registered signal handler with the + given signal number as parameter). + This implementation does not prevent further signals of the same time from + occuring, but executes signal( sig, SIG_DFL ) before entering the signal + handler (i.e., a second signal before the signal handler re-registers itself + or SIG_IGN will end the program). + Returns zero if successful, nonzero otherwise. */ +int raise( int sig ); + +#endif + diff --git a/platform/altos/internals/_PDCLIB_config.h b/platform/altos/internals/_PDCLIB_config.h new file mode 100644 index 0000000..64cc98d --- /dev/null +++ b/platform/altos/internals/_PDCLIB_config.h @@ -0,0 +1,356 @@ +/* $Id$ */ + +/* Internal PDCLib configuration <_PDCLIB_config.h> + (Generic Template) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* -------------------------------------------------------------------------- */ +/* Misc */ +/* -------------------------------------------------------------------------- */ + +/* The character (sequence) your platform uses as newline. */ +#define _PDCLIB_endl "\n" + +/* exit() can signal success to the host environment by the value of zero or */ +/* the constant EXIT_SUCCESS. Failure is signaled by EXIT_FAILURE. Note that */ +/* any other return value is "implementation-defined", i.e. your environment */ +/* is not required to handle it gracefully. Set your definitions here. */ +#define _PDCLIB_SUCCESS 0 +#define _PDCLIB_FAILURE -1 + +/* qsort() in requires a function that swaps two memory areas. */ +/* Below is a naive implementation that can be improved significantly for */ +/* specific platforms, e.g. by swapping int instead of char. */ +#define _PDCLIB_memswp( i, j, size ) char tmp; do { tmp = *i; *i++ = *j; *j++ = tmp; } while ( --size ); + +/* Define this to some compiler directive that can be written after the */ +/* parameter list of a function declaration to indicate the function does */ +/* never return. If your compiler does not support such a directive, define */ +/* to nothing. (This is to avoid warnings with the exit functions under GCC.) */ +#define _PDCLIB_NORETURN __attribute__(( noreturn )) + +/* The maximum value that errno can be set to. This is used to set the size */ +/* of the array in struct lconv () holding error messages for the */ +/* strerror() and perror() functions. (If you change this value because you */ +/* are using additional errno values, you *HAVE* to provide appropriate error */ +/* messages for *ALL* locales.) */ +/* Default is 4 (0, ERANGE, EDOM, EILSEQ). */ +#define _PDCLIB_ERRNO_MAX 4 + +/* -------------------------------------------------------------------------- */ +/* Integers */ +/* -------------------------------------------------------------------------- */ +/* Assuming 8-bit char, two's-complement architecture here. 'short' being */ +/* 16 bit, 'int' being either 16, 32 or 64 bit, 'long' being either 32 or 64 */ +/* bit (but 64 bit only if 'int' is 32 bit), and 'long long' being 64 bit if */ +/* 'long' is not, 64 or 128 bit otherwise. */ +/* Author is quite willing to support other systems but would like to hear of */ +/* interest in such support and details on the to-be-supported architecture */ +/* first, before going to lengths about it. */ +/* -------------------------------------------------------------------------- */ + +/* Comment out (or delete) the line below if your 'char' type is unsigned. */ +#define _PDCLIB_CHAR_SIGNED 1 + +/* Width of the integer types short, int, long, and long long, in bytes. */ +/* SHRT == 2, INT >= SHRT, LONG >= INT >= 4, LLONG >= LONG - check your */ +/* compiler manuals. */ +#define _PDCLIB_SHRT_BYTES 2 +#define _PDCLIB_INT_BYTES 4 +#define _PDCLIB_LONG_BYTES 4 +#define _PDCLIB_LLONG_BYTES 8 + +/* defines the div() function family that allows taking quotient */ +/* and remainder of an integer division in one operation. Many platforms */ +/* support this in hardware / opcode, and the standard permits ordering of */ +/* the return structure in any way to fit the hardware. That is why those */ +/* structs can be configured here. */ + +struct _PDCLIB_div_t +{ + int quot; + int rem; +}; + +struct _PDCLIB_ldiv_t +{ + long int quot; + long int rem; +}; + +struct _PDCLIB_lldiv_t +{ + long long int quot; + long long int rem; +}; + +/* -------------------------------------------------------------------------- */ +/* defines a set of integer types that are of a minimum width, and */ +/* "usually fastest" on the system. (If, for example, accessing a single char */ +/* requires the CPU to access a complete int and then mask out the char, the */ +/* "usually fastest" type of at least 8 bits would be int, not char.) */ +/* If you do not have information on the relative performance of the types, */ +/* the standard allows you to define any type that meets minimum width and */ +/* signedness requirements. */ +/* The defines below are just configuration for the real typedefs and limit */ +/* definitions done in <_PDCLIB_int.h>. The uppercase define shall be either */ +/* SHRT, INT, LONG, or LLONG (telling which values to use for the *_MIN and */ +/* *_MAX limits); the lowercase define either short, int, long, or long long */ +/* (telling the actual type to use). */ +/* The third define is the length modifier used for the type in printf() and */ +/* scanf() functions (used in ). */ +/* If you require a non-standard datatype to define the "usually fastest" */ +/* types, PDCLib as-is doesn't support that. Please contact the author with */ +/* details on your platform in that case, so support can be added. */ +/* -------------------------------------------------------------------------- */ + +#define _PDCLIB_FAST8 INT +#define _PDCLIB_fast8 int +#define _PDCLIB_FAST8_CONV + +#define _PDCLIB_FAST16 INT +#define _PDCLIB_fast16 int +#define _PDCLIB_FAST16_CONV + +#define _PDCLIB_FAST32 INT +#define _PDCLIB_fast32 int +#define _PDCLIB_FAST32_CONV + +#define _PDCLIB_FAST64 LLONG +#define _PDCLIB_fast64 long long +#define _PDCLIB_FAST64_CONV ll + +/* -------------------------------------------------------------------------- */ +/* What follows are a couple of "special" typedefs and their limits. Again, */ +/* the actual definition of the limits is done in <_PDCLIB_int.h>, and the */ +/* defines here are merely "configuration". See above for details. */ +/* -------------------------------------------------------------------------- */ + +/* The result type of substracting two pointers */ +#define _PDCLIB_ptrdiff int +#define _PDCLIB_PTRDIFF INT +#define _PDCLIB_PTR_CONV + +/* An integer type that can be accessed as atomic entity (think asynchronous + interrupts). The type itself is not defined in a freestanding environment, + but its limits are. (Don't ask.) +*/ +#define _PDCLIB_sig_atomic int +#define _PDCLIB_SIG_ATOMIC INT + +/* Result type of the 'sizeof' operator (must be unsigned) */ +#define _PDCLIB_size unsigned int +#define _PDCLIB_SIZE UINT + +/* Large enough an integer to hold all character codes of the largest supported + locale. +*/ +#define _PDCLIB_wchar unsigned short +#define _PDCLIB_WCHAR USHRT + +#define _PDCLIB_intptr int +#define _PDCLIB_INTPTR INT + +/* Largest supported integer type. Implementation note: see _PDCLIB_atomax(). */ +#define _PDCLIB_intmax long long int +#define _PDCLIB_INTMAX LLONG +#define _PDCLIB_MAX_CONV ll +/* You are also required to state the literal suffix for the intmax type */ +#define _PDCLIB_INTMAX_LITERAL ll + +/* defines imaxdiv(), which is equivalent to the div() function */ +/* family (see further above) with intmax_t as basis. */ + +struct _PDCLIB_imaxdiv_t +{ + _PDCLIB_intmax quot; + _PDCLIB_intmax rem; +}; + +/* -------------------------------------------------------------------------- */ +/* Floating Point */ +/* -------------------------------------------------------------------------- */ + +/* Whether the implementation rounds toward zero (0), to nearest (1), toward + positive infinity (2), or toward negative infinity (3). (-1) signifies + indeterminable rounding, any other value implementation-specific rounding. +*/ +#define _PDCLIB_FLT_ROUNDS -1 + +/* Whether the implementation uses exact-width precision (0), promotes float + to double (1), or promotes float and double to long double (2). (-1) + signifies indeterminable behaviour, any other value implementation-specific + behaviour. +*/ +#define _PDCLIB_FLT_EVAL_METHOD -1 + +/* "Number of the decimal digits (n), such that any floating-point number in the + widest supported floating type with p(max) radix (b) digits can be rounded to + a floating-point number with (n) decimal digits and back again without change + to the value p(max) log(10)b if (b) is a power of 10, [1 + p(max) log(10)b] + otherwise." + 64bit IEC 60559 double format (53bit mantissa) is DECIMAL_DIG 17. + 80bit IEC 60559 double-extended format (64bit mantissa) is DECIMAL_DIG 21. +*/ +#define _PDCLIB_DECIMAL_DIG 17 + +/* -------------------------------------------------------------------------- */ +/* Platform-dependent macros defined by the standard headers. */ +/* -------------------------------------------------------------------------- */ + +/* The offsetof macro + Contract: Expand to an integer constant expression of type size_t, which + represents the offset in bytes to the structure member from the beginning + of the structure. If the specified member is a bitfield, behaviour is + undefined. + There is no standard-compliant way to do this. + This implementation casts an integer zero to 'pointer to type', and then + takes the address of member. This is undefined behaviour but should work on + most compilers. +*/ +#define _PDCLIB_offsetof( type, member ) ( (size_t) &( ( (type *) 0 )->member ) ) + +/* Variable Length Parameter List Handling () + The macros defined by are highly dependent on the calling + conventions used, and you probably have to replace them with builtins of + your compiler. The following generic implementation works only for pure + stack-based architectures, and only if arguments are aligned to pointer + type. Credits to Michael Moody, who contributed this to the Public Domain. +*/ + +/* Internal helper macro. va_round is not part of . */ +#define _PDCLIB_va_round( type ) ( (sizeof(type) + sizeof(void *) - 1) & ~(sizeof(void *) - 1) ) + +typedef char * _PDCLIB_va_list; +#define _PDCLIB_va_arg( ap, type ) ( (ap) += (_PDCLIB_va_round(type)), ( *(type*) ( (ap) - (_PDCLIB_va_round(type)) ) ) ) +#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", part 1 */ +/* These are values and data type definitions that you would have to adapt to */ +/* the capabilities and requirements of your OS. */ +/* The actual *functions* of the OS interface are declared in _PDCLIB_glue.h. */ +/* -------------------------------------------------------------------------- */ + +/* Memory management -------------------------------------------------------- */ + +/* Set this to the page size of your OS. If your OS does not support paging, set + to an appropriate value. (Too small, and malloc() will call the kernel too + often. Too large, and you will waste memory.) +*/ +#define _PDCLIB_PAGESIZE 4096 + +/* Set this to the minimum memory node size. Any malloc() for a smaller size + will be satisfied by a malloc() of this size instead (to avoid excessive + fragmentation). +*/ +#define _PDCLIB_MINALLOC 8 + +/* I/O ---------------------------------------------------------------------- */ + +/* The type of the file descriptor returned by _PDCLIB_open(). */ +typedef int _PDCLIB_fd_t; + +/* The value (of type _PDCLIB_fd_t) returned by _PDCLIB_open() if the operation + failed. +*/ +#define _PDCLIB_NOHANDLE ( (_PDCLIB_fd_t) -1 ) + +/* The default size for file buffers. Must be at least 256. */ +#define _PDCLIB_BUFSIZ 1024 + +/* The minimum number of files the implementation can open simultaneously. Must + be at least 8. Depends largely on how the bookkeeping is done by fopen() / + freopen() / fclose(). The example implementation limits the number of open + files only by available memory. +*/ +#define _PDCLIB_FOPEN_MAX 8 + +/* Length of the longest filename the implementation guarantees to support. */ +#define _PDCLIB_FILENAME_MAX 128 + +/* Maximum length of filenames generated by tmpnam(). (See tmpfile.c.) */ +#define _PDCLIB_L_tmpnam 46 + +/* Number of distinct file names that can be generated by tmpnam(). */ +#define _PDCLIB_TMP_MAX 50 + +/* The values of SEEK_SET, SEEK_CUR and SEEK_END, used by fseek(). + Since at least one platform (POSIX) uses the same symbols for its own "seek" + function, we use whatever the host defines (if it does define them). +*/ +#define _PDCLIB_SEEK_SET 0 +#define _PDCLIB_SEEK_CUR 1 +#define _PDCLIB_SEEK_END 2 + +/* The number of characters that can be buffered with ungetc(). The standard + guarantees only one (1); anything larger would make applications relying on + this capability dependent on implementation-defined behaviour (not good). +*/ +#define _PDCLIB_UNGETCBUFSIZE 1 + +/* errno -------------------------------------------------------------------- */ + +/* These are the values that _PDCLIB_errno can be set to by the library. + + By keeping PDCLib's errno in the _PDCLIB_* namespace, the library is capable + to "translate" between errno values used by the hosting operating system and + those used and passed out by the library. + + Example: In the example platform, the remove() function uses the unlink() + system call as backend. Linux sets its errno to EISDIR if you try to unlink() + a directory, but POSIX demands EPERM. Within the remove() function, you can + catch the 'errno == EISDIR', and set '_PDCLIB_errno = _PDCLIB_EPERM'. Anyone + using PDCLib's will "see" EPERM instead of EISDIR (the _PDCLIB_* + prefix removed by mechanics). + + If you do not want that kind of translation, you might want to "match" the + values used by PDCLib with those used by the host OS, as to avoid confusion. + + The standard only defines three distinct errno values: ERANGE, EDOM, and + EILSEQ. The standard leaves it up to "the implementation" whether there are + any more beyond those three. There is some controversy as to whether errno is + such a good idea at all, so you might want to come up with a different error + reporting facility for your platform. Since errno values beyond the three + defined by the standard are not portable anyway (unless you look at POSIX), + having your own error reporting facility would not hurt anybody either. +*/ +#define _PDCLIB_ERANGE 1 +#define _PDCLIB_EDOM 2 +#define _PDCLIB_EILSEQ 3 + +/* The following is not strictly "configuration", but there is no better place + to explain it than here. + + PDCLib strives to be as generic as possible, so by default it does NOT define + any values beyond the three standard ones above, even where it would have + been prudent and convenient to do so. Any errno "caught" from the host OS, + and some internal error conditions as well, are all lumped together into the + value of '_PDCLIB_ERROR'. + + '_PDCLIB_ERROR' is STRICLY meant as a PLACEHOLDER only. + + You should NEVER ship an adaption of PDCLib still using that particular + value. You should NEVER write code that *tests* for that value. Indeed it is + not even conforming, since errno values should be defined as beginning with + an uppercase 'E', and there is no mechanics in to unmask that + particular value (for exactly that reason). + + There also is no error message available for this value through either the + strerror() or perror() functions. It is being reported as "unknown" error. + + The idea is that you scan the source of PDCLib for occurrences of this macro + and replace _PDCLIB_ERROR with whatever additional errno value you came up + with for your platform. + + If you cannot find it within you to do that, tell your clients to check for + an errno value larger than zero. That, at least, would be standard compliant + (and fully portable). +*/ +#define _PDCLIB_ERROR 4 + -- 2.30.2