removed pdclib, strange things were happening..., user shell kinda works now

This commit is contained in:
2026-07-06 22:13:57 -05:00
parent 7d76f0ec73
commit 6d7a23d747
308 changed files with 829 additions and 41231 deletions

View File

@@ -1,10 +0,0 @@
This directory holds various "internals" of PDCLib:
- definitions of helper functions not specified by the standard (hidden in the
_PDCLIB_* namespace);
- definitions of data objects, both internal (like _PDCLIB_digits) and specified by
the standard (_PDCLIB_errno);
- test drivers for functionality that does not have its own implementation
file to put the test driver in (stdarg).

View File

@@ -1,48 +0,0 @@
/* _PDCLIB_Exit( int )
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_Exit() fit for use with POSIX
kernels.
*/
#include <stdlib.h>
#ifndef REGTEST
#include "pdclib/_PDCLIB_glue.h"
#ifdef __cplusplus
extern "C" {
#endif
extern _PDCLIB_Noreturn void _exit( int status ) _PDCLIB_NORETURN;
#ifdef __cplusplus
}
#endif
void _PDCLIB_Exit( int status )
{
_exit( status );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
int UNEXPECTED_RETURN = 0;
_PDCLIB_Exit( 0 );
TESTCASE( UNEXPECTED_RETURN );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,59 +0,0 @@
/* _PDCLIB_atomax( const char * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <string.h>
#include <ctype.h>
#ifndef REGTEST
_PDCLIB_intmax_t _PDCLIB_atomax( const char * s )
{
_PDCLIB_intmax_t rc = 0;
char sign = '+';
const char * x;
/* TODO: In other than "C" locale, additional patterns may be defined */
while ( isspace( (unsigned char)*s ) )
{
++s;
}
if ( *s == '+' )
{
++s;
}
else if ( *s == '-' )
{
sign = *( s++ );
}
/* TODO: Earlier version was missing tolower() but was not caught by tests */
while ( ( x = (const char *)memchr( _PDCLIB_digits, tolower( (unsigned char)*( s++ ) ), 10 ) ) != NULL )
{
rc = rc * 10 + ( x - _PDCLIB_digits );
}
return ( sign == '+' ) ? rc : -rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
/* basic functionality */
TESTCASE( _PDCLIB_atomax( "123" ) == 123 );
/* testing skipping of leading whitespace and trailing garbage */
TESTCASE( _PDCLIB_atomax( " \n\v\t\f123xyz" ) == 123 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,83 +0,0 @@
/* _PDCLIB_bigint_add( bigint_t *, bigint_t const * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
void _PDCLIB_bigint_add( _PDCLIB_bigint_t * bigint, _PDCLIB_bigint_t const * other )
{
unsigned i = 0;
_PDCLIB_bigint_arith_t arith = 0;
for ( i = bigint->size; i < other->size; ++i )
{
bigint->data[i] = 0;
}
bigint->size = i;
for ( i = 0; i < bigint->size; ++i )
{
arith += bigint->data[i] + other->data[i];
bigint->data[i] = arith & ( ( (_PDCLIB_bigint_arith_t)1 << _PDCLIB_BIGINT_DIGIT_BITS ) - 1 );
arith >>= _PDCLIB_BIGINT_DIGIT_BITS;
}
if ( arith > 0 )
{
bigint->data[i] = arith;
--(bigint->size);
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
_PDCLIB_bigint_t bigint;
_PDCLIB_bigint_t testdata[] =
{
{ 1, { 0x0001u } },
{ 2, { (_PDCLIB_bigint_digit_t)( ( (_PDCLIB_bigint_arith_t)1 << _PDCLIB_BIGINT_DIGIT_BITS ) - 1 ), 0x0001u } },
{ 1, { 0x0002u } },
{ 2, { 0x0001u, 0x0002u } },
{ 2, { 0x0000u, 0x0002u } }
};
/* 1 + 1 */
_PDCLIB_bigint_from_digit( &bigint, 1 );
_PDCLIB_bigint_add( &bigint, &bigint );
_PDCLIB_bigint_cmp( &bigint, &testdata[2] );
/* 1 + 0x0001 0xFFFF -- carry */
_PDCLIB_bigint_add( &bigint, &testdata[1] );
_PDCLIB_bigint_cmp( &bigint, &testdata[3] );
/* 0x0001 0xFFFF + 1 -- carry */
_PDCLIB_bigint_from_bigint( &bigint, &testdata[1] );
_PDCLIB_bigint_add( &bigint, &testdata[0] );
_PDCLIB_bigint_cmp( &bigint, &testdata[4] );
/* 0 + 0 */
_PDCLIB_bigint_from_digit( &bigint, 0 );
_PDCLIB_bigint_add( &bigint, &bigint );
TESTCASE( bigint.size == 0 );
/* 0 + 1 */
_PDCLIB_bigint_add( &bigint, &testdata[0] );
_PDCLIB_bigint_cmp( &bigint, &testdata[0] );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,74 +0,0 @@
/* _PDCLIB_bigint_cmp( bigint_t const *, bigint_t const * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
int _PDCLIB_bigint_cmp( _PDCLIB_bigint_t const * lhs, _PDCLIB_bigint_t const * rhs )
{
_PDCLIB_size_t i = lhs->size;
if ( i != rhs->size )
{
return i > rhs->size ? 1 : -1;
}
while ( i-- > 0 )
{
if ( lhs->data[i] != rhs->data[i] )
{
return lhs->data[i] > rhs->data[i] ? 1 : -1;
}
}
return 0;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
_PDCLIB_bigint_t lhs, rhs;
_PDCLIB_bigint_t testdata[] =
{
{ 2, { 0, 0x0001u } },
{ 1, { 1 } }
};
_PDCLIB_bigint_from_digit( &lhs, 0 );
_PDCLIB_bigint_from_digit( &rhs, 0 );
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) == 0 );
_PDCLIB_bigint_add( &lhs, &testdata[1] );
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) > 0 );
_PDCLIB_bigint_add( &rhs, &testdata[1] );
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) == 0 );
_PDCLIB_bigint_add( &rhs, &testdata[1] );
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) < 0 );
_PDCLIB_bigint_from_bigint( &lhs, &testdata[0] );
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) > 0 );
_PDCLIB_bigint_from_bigint( &rhs, &testdata[0] );
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) == 0 );
_PDCLIB_bigint_add( &rhs, &testdata[1] );
TESTCASE( _PDCLIB_bigint_cmp( &lhs, &rhs ) < 0 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,83 +0,0 @@
/* _PDCLIB_bigint_digit_log2( bigint_t const * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
#include <stdio.h>
int _PDCLIB_bigint_digit_log2( _PDCLIB_bigint_digit_t digit )
{
unsigned char log2_lookup[] =
{
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7
};
_PDCLIB_bigint_digit_t t;
#if _PDCLIB_BIGINT_DIGIT_BITS > 16
if ( ( t = ( digit >> 24 ) ) )
{
return log2_lookup[ t ] + 24;
}
else if ( ( t = ( digit >> 16 ) ) )
{
return log2_lookup[ t ] + 16;
}
else
#endif
if ( ( t = ( digit >> 8 ) ) )
{
return log2_lookup[ t ] + 8;
}
else if ( digit > 0 )
{
return log2_lookup[ digit ];
}
else
{
return -1;
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <math.h>
int main( void )
{
#ifndef REGTEST
unsigned i;
for ( i = 1; i < (1 << _PDCLIB_BIGINT_DIGIT_BITS); ++i )
{
//TESTCASE( _PDCLIB_bigint_digit_log2( i ) == (int)log2( i ) );
}
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,135 +0,0 @@
/* _PDCLIB_bigint_div( bigint_t *, bigint_t const * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
#include <assert.h>
unsigned _PDCLIB_bigint_div( _PDCLIB_bigint_t * dividend, _PDCLIB_bigint_t const * divisor )
{
_PDCLIB_bigint_digit_t quotient;
_PDCLIB_size_t s = dividend->size;
_PDCLIB_size_t i;
assert( divisor->size > 0 );
assert( s <= divisor->size );
assert( divisor->data[ divisor->size - 1 ] < _PDCLIB_BIGINT_DIGIT_MAX );
if ( s < divisor->size || dividend->data[ s - 1 ] < divisor->data[ s - 1 ])
{
return 0;
}
/* With dividend truncated, and divisor + 1,
this quotient might be one short of correct.
*/
quotient = dividend->data[ s - 1 ] / ( divisor->data[ s - 1 ] + 1 );
if ( quotient > 0 )
{
/* dividend = dividend - (divisor * quotient) */
_PDCLIB_bigint_arith_t t = 0;
_PDCLIB_bigint_arith_t d = 0;
for ( i = 0; i < s; ++i )
{
t += (_PDCLIB_bigint_arith_t)divisor->data[i] * quotient;
d = (_PDCLIB_bigint_arith_t)dividend->data[i] - ( t & _PDCLIB_BIGINT_DIGIT_MAX ) - d;
dividend->data[i] = d & _PDCLIB_BIGINT_DIGIT_MAX;
t >>= _PDCLIB_BIGINT_DIGIT_BITS;
d >>= _PDCLIB_BIGINT_DIGIT_BITS;
d &= 1;
}
}
/* dividend might have leading zero digits here,
but that does not matter for the compare or
the subsequent substraction.
*/
if ( _PDCLIB_bigint_cmp( dividend, divisor ) >= 0 )
{
/* quotient was too small, substract divisor once more. */
_PDCLIB_bigint_arith_t d = 0;
++quotient;
for ( i = 0; i < s; ++i )
{
d = (_PDCLIB_bigint_arith_t)dividend->data[i] - divisor->data[i] - d;
dividend->data[i] = d & _PDCLIB_BIGINT_DIGIT_MAX;
d >>= _PDCLIB_BIGINT_DIGIT_BITS;
d &= 1;
}
}
/* size down dividend if it has leading zero digits. */
while ( dividend->size > 0 && dividend->data[ dividend->size - 1 ] == 0 )
{
--dividend->size;
}
return quotient;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
_PDCLIB_bigint_t dividend;
_PDCLIB_bigint_t divisor;
_PDCLIB_bigint_t testdata[] =
{
{ 1, { 0x1234 } },
{ 2, { 0x2345, 0x0001 } },
{ 1, { 0x4000 } },
{ 1, { 0x3FFF } },
{ 1, { 0x0001 } },
{ 1, { _PDCLIB_BIGINT_DIGIT_MAX } },
{ 1, { 0xFFF9 } },
{ 1, { 0x1C71 } }
};
/* dividend < divisor */
_PDCLIB_bigint_from_bigint( &dividend, &testdata[0] );
_PDCLIB_bigint_from_bigint( &divisor, &testdata[1] );
TESTCASE( _PDCLIB_bigint_div( &dividend, &divisor ) == 0 );
TESTCASE( _PDCLIB_bigint_cmp( &dividend, &testdata[0] ) == 0 );
_PDCLIB_bigint_from_bigint( &dividend, &testdata[3] );
_PDCLIB_bigint_from_bigint( &divisor, &testdata[2] );
TESTCASE( _PDCLIB_bigint_div( &dividend, &divisor ) == 0 );
TESTCASE( _PDCLIB_bigint_cmp( &dividend, &testdata[3] ) == 0 );
/* dividend = divisor + 1 */
_PDCLIB_bigint_from_bigint( &dividend, &testdata[2] );
_PDCLIB_bigint_from_bigint( &divisor, &testdata[3] );
TESTCASE( _PDCLIB_bigint_div( &dividend, &divisor ) == 1 );
TESTCASE( _PDCLIB_bigint_cmp( &dividend, &testdata[4] ) == 0 );
/* dividend = divisor * 9 */
_PDCLIB_bigint_from_bigint( &dividend, &testdata[6] );
_PDCLIB_bigint_from_bigint( &divisor, &testdata[7] );
TESTCASE( _PDCLIB_bigint_div( &dividend, &divisor ) == 9 );
TESTCASE( dividend.size == 0 );
/* dividend = divisor * 9 + rem */
_PDCLIB_bigint_from_bigint( &dividend, &testdata[5] );
_PDCLIB_bigint_from_digit( &divisor, testdata[5].data[0] / 9 );
TESTCASE( _PDCLIB_bigint_div( &dividend, &divisor ) == 9 );
TESTCASE( dividend.data[0] == ( testdata[5].data[0] % 9 ) );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,54 +0,0 @@
/* _PDCLIB_bigint_from_bigint( bigint_t *, bigint_t const * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
void _PDCLIB_bigint_from_bigint( _PDCLIB_bigint_t * bigint, _PDCLIB_bigint_t const * other )
{
_PDCLIB_size_t i;
for ( i = 0; i < other->size; ++i )
{
bigint->data[i] = other->data[i];
}
bigint->size = other->size;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
_PDCLIB_bigint_t bigint;
_PDCLIB_bigint_t testdata[] =
{
/* Only 16bit, works with 32bit digits as well. */
{ 0, { 0u } },
{ 1, { 0xFFFFu } },
{ 2, { 0xAAAAu, 0xFFFFu } }
};
_PDCLIB_bigint_from_bigint( &bigint, &testdata[0] );
TESTCASE( bigint.size == 0 );
_PDCLIB_bigint_from_bigint( &bigint, &testdata[1] );
_PDCLIB_bigint_cmp( &bigint, &testdata[1] );
_PDCLIB_bigint_from_bigint( &bigint, &testdata[2] );
_PDCLIB_bigint_cmp( &bigint, &testdata[2] );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,43 +0,0 @@
/* _PDCLIB_bigint_from_digit( bigint_t *, digit_t )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
void _PDCLIB_bigint_from_digit( _PDCLIB_bigint_t * bigint, _PDCLIB_bigint_digit_t digit )
{
bigint->size = ( digit > 0 );
bigint->data[0] = digit;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
_PDCLIB_bigint_t bigint;
_PDCLIB_bigint_from_digit( &bigint, 0 );
TESTCASE( bigint.size == 0 );
_PDCLIB_bigint_from_digit( &bigint, 1 );
TESTCASE( bigint.size == 1 );
TESTCASE( bigint.data[0] == 1 );
_PDCLIB_bigint_from_digit( &bigint, _PDCLIB_BIGINT_DIGIT_MAX );
TESTCASE( bigint.size == 1 );
TESTCASE( bigint.data[0] == _PDCLIB_BIGINT_DIGIT_MAX );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,131 +0,0 @@
/* _PDCLIB_bigint_from_pow10( bigint_t *, unsigned )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
void _PDCLIB_bigint_from_pow10( _PDCLIB_bigint_t * bigint, unsigned pow )
{
_PDCLIB_bigint_t powers_of_10[] =
{
{ 1, { 0x0001u } },
{ 1, { 0x000au } },
{ 1, { 0x0064u } },
{ 1, { 0x03e8u } },
{ 1, { 0x2710u } },
{ 2, { 0x86a0u, 0x0001u } },
{ 2, { 0x4240u, 0x000fu } },
{ 2, { 0x9680u, 0x0098u } },
{ 2, { 0xe100u, 0x05f5u } },
{ 4, { 0x0000u, 0x6fc1u, 0x86f2u, 0x0023u } },
{ 7, { 0x0000u, 0x0000u, 0xef81u, 0x85acu,
0x415bu, 0x2d6du, 0x04eeu } },
{ 14, { 0x0000u, 0x0000u, 0x0000u, 0x0000u,
0x1f01u, 0xbf6au, 0xed64u, 0x6e38u,
0x97edu, 0xdaa7u, 0xf9f4u, 0xe93fu,
0x4f03u, 0x0018u } },
{ 27, { 0x0000u, 0x0000u, 0x0000u, 0x0000u,
0x0000u, 0x0000u, 0x0000u, 0x0000u,
0x3e01u, 0x2e95u, 0x9909u, 0x03dfu,
0x38fdu, 0x0f15u, 0xe42fu, 0x2374u,
0xf5ecu, 0xd3cfu, 0xdc08u, 0xc404u,
0xb0dau, 0xbccdu, 0x7f19u, 0xa633u,
0x2603u, 0xe91fu, 0x024eu } },
{ 54, { 0x0000u, 0x0000u, 0x0000u, 0x0000u,
0x0000u, 0x0000u, 0x0000u, 0x0000u,
0x0000u, 0x0000u, 0x0000u, 0x0000u,
0x0000u, 0x0000u, 0x0000u, 0x0000u,
0x7c01u, 0x982eu, 0x875bu, 0xbed3u,
0x9f72u, 0xd8d9u, 0x2f87u, 0x1215u,
0x50c6u, 0x6bdeu, 0x6e70u, 0xcf4au,
0xd80fu, 0xd595u, 0x716eu, 0x26b2u,
0x66b0u, 0xadc6u, 0x3624u, 0x1d15u,
0xd35au, 0x3c42u, 0x540eu, 0x63ffu,
0x73c0u, 0xcc55u, 0xef17u, 0x65f9u,
0x28f2u, 0x55bcu, 0xc7f7u, 0x80dcu,
0xeddcu, 0xf46eu, 0xefceu, 0x5fdcu,
0x53f7u, 0x0005u } }
};
_PDCLIB_size_t index = 8;
_PDCLIB_bigint_from_bigint( bigint, &powers_of_10[ pow & 7 ] );
pow >>= 3;
while ( pow > 0 )
{
if ( pow & 1 )
{
_PDCLIB_bigint_mul( bigint, &powers_of_10[ index ] );
}
pow >>= 1;
++index;
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
_PDCLIB_bigint_t bigint;
_PDCLIB_bigint_from_pow10( &bigint, 0 );
TESTCASE( bigint.size == 1 );
TESTCASE( bigint.data[0] == 1 );
_PDCLIB_bigint_from_pow10( &bigint, 1 );
TESTCASE( bigint.size == 1 );
TESTCASE( bigint.data[0] == 10 );
_PDCLIB_bigint_from_pow10( &bigint, 2 );
TESTCASE( bigint.size == 1 );
TESTCASE( bigint.data[0] == 100 );
_PDCLIB_bigint_from_pow10( &bigint, 3 );
TESTCASE( bigint.size == 1 );
TESTCASE( bigint.data[0] == 1000 );
_PDCLIB_bigint_from_pow10( &bigint, 4 );
TESTCASE( bigint.size == 1 );
TESTCASE( bigint.data[0] == 10000 );
_PDCLIB_bigint_from_pow10( &bigint, 5 );
TESTCASE( bigint.size == 2 );
TESTCASE( bigint.data[1] == 1 );
TESTCASE( bigint.data[0] == 34464 );
_PDCLIB_bigint_from_pow10( &bigint, 6 );
TESTCASE( bigint.size == 2 );
TESTCASE( bigint.data[1] == 15 );
TESTCASE( bigint.data[0] == 16960 );
_PDCLIB_bigint_from_pow10( &bigint, 7 );
TESTCASE( bigint.size == 2 );
TESTCASE( bigint.data[1] == 152 );
TESTCASE( bigint.data[0] == 38528 );
_PDCLIB_bigint_from_pow10( &bigint, 8 );
TESTCASE( bigint.size == 2 );
TESTCASE( bigint.data[1] == 1525 );
TESTCASE( bigint.data[0] == 57600 );
_PDCLIB_bigint_from_pow10( &bigint, 9 );
TESTCASE( bigint.size == 2 );
TESTCASE( bigint.data[1] == 15258 );
TESTCASE( bigint.data[0] == 51712 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,54 +0,0 @@
/* _PDCLIB_bigint_from_pow2( bigint_t *, unsigned )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
#include <stdlib.h>
void _PDCLIB_bigint_from_pow2( _PDCLIB_bigint_t * bigint, unsigned pow )
{
ldiv_t dv = ldiv( pow, _PDCLIB_BIGINT_DIGIT_BITS );
long i;
for ( i = 0; i < dv.quot; ++i )
{
bigint->data[i] = 0;
}
bigint->data[i] = 1u << dv.rem;
bigint->size = i + 1;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
_PDCLIB_bigint_t bigint;
_PDCLIB_bigint_from_pow2( &bigint, 0 );
TESTCASE( bigint.size == 1 );
TESTCASE( bigint.data[0] == 1 );
_PDCLIB_bigint_from_pow2( &bigint, 1 );
TESTCASE( bigint.size == 1 );
TESTCASE( bigint.data[0] == 2 );
_PDCLIB_bigint_from_pow2( &bigint, 2 );
TESTCASE( bigint.size == 1 );
TESTCASE( bigint.data[0] == 4 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,64 +0,0 @@
/* _PDCLIB_bigint_log2( bigint_t const * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
int _PDCLIB_bigint_log2( _PDCLIB_bigint_t const * bigint )
{
_PDCLIB_size_t s = bigint->size;
if ( s == 0 )
{
return -1;
}
--s;
return _PDCLIB_bigint_digit_log2( bigint->data[ s ] ) + s * _PDCLIB_BIGINT_DIGIT_BITS;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
_PDCLIB_bigint_t bigint;
_PDCLIB_bigint_t one;
_PDCLIB_bigint_from_digit( &bigint, 0 );
_PDCLIB_bigint_from_digit( &one, 1 );
TESTCASE( _PDCLIB_bigint_log2( &bigint ) == -1 );
TESTCASE( _PDCLIB_bigint_log2( &one ) == 0 );
_PDCLIB_bigint_mul10( &one );
TESTCASE( _PDCLIB_bigint_log2( &one ) == 3 );
_PDCLIB_bigint_mul10( &one );
TESTCASE( _PDCLIB_bigint_log2( &one ) == 6 );
_PDCLIB_bigint_mul10( &one );
TESTCASE( _PDCLIB_bigint_log2( &one ) == 9 );
_PDCLIB_bigint_mul10( &one );
TESTCASE( _PDCLIB_bigint_log2( &one ) == 13 );
_PDCLIB_bigint_mul10( &one );
TESTCASE( _PDCLIB_bigint_log2( &one ) == 16 );
_PDCLIB_bigint_mul10( &one );
TESTCASE( _PDCLIB_bigint_log2( &one ) == 19 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,121 +0,0 @@
/* _PDCLIB_bigint_mul( bigint_t *, bigint_t const * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
void _PDCLIB_bigint_mul( _PDCLIB_bigint_t * bigint, _PDCLIB_bigint_t const * other )
{
_PDCLIB_size_t s = other->size;
_PDCLIB_size_t b = bigint->size;
if ( s == 0 || b == 0 )
{
_PDCLIB_bigint_from_digit( bigint, 0 );
return;
}
{
_PDCLIB_bigint_t result = { s + b, { 0 } };
_PDCLIB_bigint_t const * small;
_PDCLIB_bigint_t const * big;
if ( s <= b )
{
small = other;
big = bigint;
}
else
{
small = bigint;
big = other;
}
for ( s = 0; s < small->size; ++s )
{
_PDCLIB_bigint_arith_t t = 0;
for ( b = 0; b < big->size; ++b )
{
t += result.data[ s + b ]
+ (_PDCLIB_bigint_arith_t)small->data[ s ]
* (_PDCLIB_bigint_arith_t)big->data[ b ];
result.data[ s + b ] = t & ( ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS ) - 1 );
t >>= _PDCLIB_BIGINT_DIGIT_BITS;
}
result.data[ s + b ] = t & ( ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS ) - 1 );
}
while ( result.data[ result.size - 1 ] == 0 )
{
--result.size;
}
_PDCLIB_bigint_from_bigint( bigint, &result );
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
_PDCLIB_bigint_t bigint;
_PDCLIB_bigint_t testdata[] =
{
{ 1, { 0x0001u } },
{ 1, { 0x0002u } },
{ 1, { ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS) - 1 } },
{ 2, { ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS) - 1, 1u } }
};
_PDCLIB_bigint_from_bigint( &bigint, &testdata[0] );
_PDCLIB_bigint_mul( &bigint, &testdata[0] );
TESTCASE( bigint.size == 1 );
TESTCASE( bigint.data[0] == 1u );
_PDCLIB_bigint_mul( &bigint, &testdata[1] );
TESTCASE( bigint.size == 1 );
TESTCASE( bigint.data[0] == 2u );
_PDCLIB_bigint_mul( &bigint, &testdata[2] );
TESTCASE( bigint.size == 2 );
TESTCASE( bigint.data[0] == ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS) - 2 );
TESTCASE( bigint.data[1] == 1u );
_PDCLIB_bigint_mul( &bigint, &testdata[1] );
TESTCASE( bigint.size == 2 );
TESTCASE( bigint.data[0] == ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS) - 4 );
TESTCASE( bigint.data[1] == 3u );
_PDCLIB_bigint_from_bigint( &bigint, &testdata[3] );
_PDCLIB_bigint_mul( &bigint, &bigint );
TESTCASE( bigint.data[0] == 1 );
TESTCASE( bigint.data[1] == ( (_PDCLIB_bigint_arith_t)1u << _PDCLIB_BIGINT_DIGIT_BITS) - 4 );
#if _PDCLIB_BIGINT_DIGIT_BITS == 16
TESTCASE( bigint.size == 3 );
TESTCASE( bigint.data[2] == 3 );
#else
TESTCASE( bigint.size == 2 );
#endif
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,58 +0,0 @@
/* _PDCLIB_bigint_mul10( bigint_t * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
void _PDCLIB_bigint_mul10( _PDCLIB_bigint_t * bigint )
{
_PDCLIB_bigint_arith_t t = 0;
_PDCLIB_size_t i;
for ( i = 0; i < bigint->size; ++i )
{
t = (_PDCLIB_bigint_arith_t)bigint->data[ i ] * 10 + t;
bigint->data[ i ] = t & _PDCLIB_BIGINT_DIGIT_MAX;
t >>= _PDCLIB_BIGINT_DIGIT_BITS;
}
if ( t > 0 )
{
bigint->data[ bigint->size++ ] = t;
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
_PDCLIB_bigint_t bigint;
_PDCLIB_bigint_t testdata[] =
{
{ 2, { 0x8080u, 0x0101u } },
{ 2, { 0x0500u, 0x0a0fu } },
{ 1, { 0x000au } }
};
_PDCLIB_bigint_from_digit( &bigint, 1 );
_PDCLIB_bigint_mul10( &bigint );
TESTCASE( _PDCLIB_bigint_cmp( &bigint, &testdata[2] ) == 0 );
_PDCLIB_bigint_from_bigint( &bigint, &testdata[0] );
_PDCLIB_bigint_mul10( &bigint );
TESTCASE( _PDCLIB_bigint_cmp( &bigint, &testdata[1] ) == 0 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,30 +0,0 @@
/* _PDCLIB_bigint_mul_pow10( bigint_t *, int pow10 )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
void _PDCLIB_bigint_mul_pow10( _PDCLIB_bigint_t * bigint, int pow10 )
{
_PDCLIB_bigint_t multiplier;
_PDCLIB_bigint_from_pow10( &multiplier, pow10 );
_PDCLIB_bigint_mul( bigint, &multiplier );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( NO_TESTDRIVER );
return TEST_RESULTS;
}
#endif

View File

@@ -1,83 +0,0 @@
/* _PDCLIB_bigint_shl( bigint_t *, size_t )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
#include <stdlib.h>
void _PDCLIB_bigint_shl( _PDCLIB_bigint_t * bigint, _PDCLIB_size_t bits )
{
ldiv_t dv = ldiv( bits, _PDCLIB_BIGINT_DIGIT_BITS );
_PDCLIB_bigint_arith_t t = 0;
size_t i;
if ( dv.quot > 0 )
{
i = bigint->size;
/* shifting whole digits */
while ( i-- > 0 )
{
bigint->data[ i + dv.quot ] = bigint->data[ i ];
}
bigint->size += dv.quot;
/* zero out shifted low digits */
while ( (long)i < dv.quot )
{
bigint->data[ i++ ] = 0;
}
}
for ( i = dv.quot; i < bigint->size; ++i )
{
t = ( (_PDCLIB_bigint_arith_t)bigint->data[ i ] << dv.rem ) + t;
bigint->data[ i ] = t & _PDCLIB_BIGINT_DIGIT_MAX;
t >>= _PDCLIB_BIGINT_DIGIT_BITS;
}
if ( t > 0 )
{
bigint->data[ bigint->size++ ] = t;
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
_PDCLIB_bigint_t bigint;
_PDCLIB_bigint_t testdata[] =
{
{ 2, { 0x8080u, 0x0101u } },
{ 3, { 0x0000u, 0x0100u, 0x0203u } }
};
_PDCLIB_bigint_from_digit( &bigint, 1 );
_PDCLIB_bigint_shl( &bigint, 2 );
TESTCASE( bigint.size == 1 );
TESTCASE( bigint.data[0] == 4 );
_PDCLIB_bigint_from_bigint( &bigint, &testdata[0] );
_PDCLIB_bigint_shl( &bigint, _PDCLIB_BIGINT_DIGIT_BITS + 1 );
TESTCASE( bigint.size == 3 );
TESTCASE( bigint.data[0] == 0 );
TESTCASE( bigint.data[1] == 0x0100 );
TESTCASE( bigint.data[2] == 0x0203 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,73 +0,0 @@
/* _PDCLIB_changemode( FILE * stream, int mode )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
/* This is a utility function used by freopen, to allow for a rather
specific bit of trickery.
ISO/IEC 9899:2011 (i.e., the ISO C standard) is ambiguous in the case
of the filename argument being NULL. It states that the mode of the
open stream could be _changed_ in implementation-defined circumstances.
While it goes on to state that freopen will "first attempt to close any
file that is associated with the specified stream", it is not quite
clear if the "implementation-defined circumstances" mentioned earlier
would include changing the mode without actually closing the file.
IEEE Std 1003.1, 2004 Edition (POSIX) on the other hand is less
ambiguous, as it states that "the file descriptor associated with the
stream need not be closed if the call to freopen() succeeds" for the
same case (filename being NULL).
This function gets called by PDCLib's freopen() in just that case,
allowing you to perform whatever mode changes YOUR implementation
decides to support. Return zero if the change requested is not
supported and freopen() should attempt the close-and-open-again way.
Return INT_MIN if the change request is not supported and freopen()
should fail. Return any other value if the requested mode change was
supported and successful.
*/
/* This is a dummy implementation of _PDCLIB_open() not supporting any
mode changes.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_glue.h"
#include <limits.h>
#include <stddef.h>
int _PDCLIB_changemode( struct _PDCLIB_file_t * stream, unsigned int mode )
{
if ( mode == 0 )
{
return INT_MIN;
}
/* Attempt mode change without closing the stream */
if ( stream->filename == NULL )
{
/* Standard stream, no filename for reopen */
return INT_MIN;
}
else
{
/* Stream with file associated, attempt reopen */
return 0;
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* No test drivers. */
return TEST_RESULTS;
}
#endif

View File

@@ -1,44 +0,0 @@
/* _PDCLIB_close( _PDCLIB_fd_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_close() fit for use with POSIX
kernels.
*/
#include <stdio.h>
#ifndef REGTEST
#include "pdclib/_PDCLIB_glue.h"
#ifdef __cplusplus
extern "C" {
#endif
extern int close( int fd );
#ifdef __cplusplus
}
#endif
int _PDCLIB_close( int fd )
{
return close( fd );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* No testdriver; tested in driver for _PDCLIB_open(). */
return TEST_RESULTS;
}
#endif

View File

@@ -1,38 +0,0 @@
/* _PDCLIB_closeall( void )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdio.h>
#ifndef REGTEST
extern struct _PDCLIB_file_t * _PDCLIB_filelist;
void _PDCLIB_closeall( void )
{
struct _PDCLIB_file_t * stream = _PDCLIB_filelist;
struct _PDCLIB_file_t * next;
while ( stream != NULL )
{
next = stream->next;
fclose( stream );
stream = next;
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* No testdriver */
return TEST_RESULTS;
}
#endif

View File

@@ -1,33 +0,0 @@
/* _PDCLIB_digits
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_internal.h"
const char _PDCLIB_digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
/* For _PDCLIB/print.c only; obsolete with ctype.h */
const char _PDCLIB_Xdigits[] = "0123456789ABCDEF";
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <string.h>
int main( void )
{
#ifndef REGTEST
TESTCASE( strcmp( _PDCLIB_digits, "0123456789abcdefghijklmnopqrstuvwxyz" ) == 0 );
TESTCASE( strcmp( _PDCLIB_Xdigits, "0123456789ABCDEF" ) == 0 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,114 +0,0 @@
/* _PDCLIB_filemode( const char * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stddef.h>
#ifndef REGTEST
/* Helper function that parses the C-style mode string passed to fopen() into
the PDCLib flags FREAD, FWRITE, FAPPEND, FRW (read-write) and FBIN (binary
mode).
*/
unsigned int _PDCLIB_filemode( const char * const mode )
{
unsigned rc = 0;
size_t i;
if ( mode == NULL )
{
return 0;
}
switch ( mode[0] )
{
case 'r':
rc |= _PDCLIB_FREAD;
break;
case 'w':
rc |= _PDCLIB_FWRITE;
break;
case 'a':
rc |= _PDCLIB_FAPPEND | _PDCLIB_FWRITE;
break;
default:
/* Other than read, write, or append - invalid */
return 0;
}
for ( i = 1; i < 4; ++i )
{
switch ( mode[i] )
{
case '+':
if ( rc & _PDCLIB_FRW )
{
/* Duplicates are invalid */
return 0;
}
rc |= _PDCLIB_FRW;
break;
case 'b':
if ( rc & _PDCLIB_FBIN )
{
/* Duplicates are invalid */
return 0;
}
rc |= _PDCLIB_FBIN;
break;
case '\0':
/* End of mode */
return rc;
default:
/* Other than read/write or binary - invalid. */
return 0;
}
}
/* Longer than three chars - invalid. */
return 0;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
TESTCASE( _PDCLIB_filemode( "r" ) == _PDCLIB_FREAD );
TESTCASE( _PDCLIB_filemode( "w" ) == _PDCLIB_FWRITE );
TESTCASE( _PDCLIB_filemode( "a" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE ) );
TESTCASE( _PDCLIB_filemode( "r+" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW ) );
TESTCASE( _PDCLIB_filemode( "w+" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW ) );
TESTCASE( _PDCLIB_filemode( "a+" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FRW ) );
TESTCASE( _PDCLIB_filemode( "rb" ) == ( _PDCLIB_FREAD | _PDCLIB_FBIN ) );
TESTCASE( _PDCLIB_filemode( "wb" ) == ( _PDCLIB_FWRITE | _PDCLIB_FBIN ) );
TESTCASE( _PDCLIB_filemode( "ab" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FBIN ) );
TESTCASE( _PDCLIB_filemode( "r+b" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW | _PDCLIB_FBIN ) );
TESTCASE( _PDCLIB_filemode( "w+b" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) );
TESTCASE( _PDCLIB_filemode( "a+b" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) );
TESTCASE( _PDCLIB_filemode( "rb+" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW | _PDCLIB_FBIN ) );
TESTCASE( _PDCLIB_filemode( "wb+" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) );
TESTCASE( _PDCLIB_filemode( "ab+" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) );
TESTCASE( _PDCLIB_filemode( "x" ) == 0 );
TESTCASE( _PDCLIB_filemode( "r++" ) == 0 );
TESTCASE( _PDCLIB_filemode( "wbb" ) == 0 );
TESTCASE( _PDCLIB_filemode( "a+bx" ) == 0 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,77 +0,0 @@
/* _PDCLIB_fillbuffer( 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_fillbuffer() fit for
use with POSIX kernels.
*/
#include <stdio.h>
#ifndef REGTEST
#include "pdclib/_PDCLIB_glue.h"
#include "pdclib/_PDCLIB_platform_errno.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef long ssize_t;
extern ssize_t read( int fd, void * buf, size_t count );
#ifdef __cplusplus
}
#endif
int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream )
{
/* No need to handle buffers > INT_MAX, as PDCLib doesn't allow them */
ssize_t rc = read( stream->handle, stream->buffer, stream->bufsize );
if ( rc > 0 )
{
/* Reading successful. */
if ( !( stream->status & _PDCLIB_FBIN ) )
{
/* TODO: Text stream conversion here */
}
stream->pos.offset += rc;
stream->bufend = rc;
stream->bufidx = 0;
return 0;
}
if ( rc < 0 )
{
/* The 1:1 mapping done in _PDCLIB_config.h ensures
this works.
*/
*_PDCLIB_errno_func() = errno;
/* Flag the stream */
stream->status |= _PDCLIB_ERRORFLAG;
return EOF;
}
/* End-of-File */
stream->status |= _PDCLIB_EOFFLAG;
return EOF;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* Testing covered by ftell.c */
return TEST_RESULTS;
}
#endif

View File

@@ -1,103 +0,0 @@
/* _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 <stdio.h>
#include <string.h>
#ifndef REGTEST
#include "pdclib/_PDCLIB_glue.h"
#include "pdclib/_PDCLIB_platform_errno.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef long ssize_t;
extern ssize_t write( int fd, const void * buf, size_t count );
#ifdef __cplusplus
}
#endif
/* The number of attempts of 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 )
int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream )
{
/* No need to handle buffers > INT_MAX, as PDCLib doesn't allow them */
_PDCLIB_size_t written = 0;
int rc;
unsigned int retries;
if ( !( stream->status & _PDCLIB_FBIN ) )
{
/* TODO: Text stream conversion here */
}
/* Keep trying to write data until everything is written, an error
occurs, or the configured number of retries is exceeded.
*/
for ( retries = _PDCLIB_IO_RETRIES; retries > 0; --retries )
{
rc = ( int )write( stream->handle, stream->buffer + written, stream->bufidx - written );
if ( rc < 0 )
{
/* The 1:1 mapping done in _PDCLIB_config.h ensures
this works.
*/
*_PDCLIB_errno_func() = errno;
/* Flag the stream */
stream->status |= _PDCLIB_ERRORFLAG;
/* Move unwritten remains to begin of buffer. */
stream->bufidx -= written;
memmove( stream->buffer, stream->buffer + written, stream->bufidx );
return EOF;
}
written += ( _PDCLIB_size_t )rc;
stream->pos.offset += rc;
if ( written == stream->bufidx )
{
/* Buffer written completely. */
stream->bufidx = 0;
return 0;
}
}
/* Number of retries exceeded. */
*_PDCLIB_errno_func() = _PDCLIB_EAGAIN;
stream->status |= _PDCLIB_ERRORFLAG;
/* Move unwritten remains to begin of buffer. */
stream->bufidx -= written;
memmove( stream->buffer, stream->buffer + written, stream->bufidx );
return EOF;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* Testing covered by ftell.c */
return TEST_RESULTS;
}
#endif

View File

@@ -1,106 +0,0 @@
/* _PDCLIB_fp_from_dbl( _PDCLIB_fp_t *, double )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
#include <stdlib.h>
#include <string.h>
void _PDCLIB_fp_from_dbl( _PDCLIB_fp_t * fp, double d )
{
memcpy( fp->mantissa.data, &d, sizeof( double ) );
fp->sign = _PDCLIB_DBL_SIGN( fp->mantissa.data );
fp->exponent = _PDCLIB_DBL_EXP( fp->mantissa.data );
fp->mantissa.size = _PDCLIB_DBL_SIZE( fp->mantissa.data );
switch ( fp->exponent )
{
case 0:
fp->state = _PDCLIB_FP_SUBNORMAL;
fp->exponent = 1 - ( _PDCLIB_DBL_MAX_EXP - 1 );
fp->scale = _PDCLIB_DBL_MANT_DIG - 1;
break;
case ( _PDCLIB_DBL_MAX_EXP - 1 ) + _PDCLIB_DBL_MAX_EXP:
fp->state = _PDCLIB_FP_NAN;
break;
default:
{
div_t dv = div( _PDCLIB_DBL_MANT_DIG - 1, _PDCLIB_BIGINT_DIGIT_BITS );
fp->state = _PDCLIB_FP_NORMAL;
if ( dv.rem == 0 )
{
fp->mantissa.data[ fp->mantissa.size++ ] = 1u;
}
else
{
fp->mantissa.data[ dv.quot ] |= ( 1u << dv.rem );
}
fp->exponent -= ( _PDCLIB_DBL_MAX_EXP - 1 );
fp->scale = _PDCLIB_DBL_MANT_DIG - 1;
break;
}
}
while ( fp->mantissa.size > 0 && fp->mantissa.data[ fp->mantissa.size - 1 ] == 0 )
{
--fp->mantissa.size;
}
if ( ( fp->state == _PDCLIB_FP_NAN ) && ( fp->mantissa.size == 0 ) )
{
fp->state = _PDCLIB_FP_INF;
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
_PDCLIB_fp_t fp;
_PDCLIB_bigint_t t;
/* Normal */
_PDCLIB_fp_from_dbl( &fp, -1.0 );
_PDCLIB_bigint_from_pow2( &t, _PDCLIB_DBL_MANT_DIG - 1 );
TESTCASE( fp.state == _PDCLIB_FP_NORMAL );
TESTCASE( _PDCLIB_bigint_cmp( &fp.mantissa, &t ) == 0 );
TESTCASE( fp.scale == ( _PDCLIB_DBL_MANT_DIG - 1 ) );
TESTCASE( fp.exponent == 0 );
/* Inf */
_PDCLIB_fp_from_dbl( &fp, 1e500 );
TESTCASE( fp.state == _PDCLIB_FP_INF );
TESTCASE( fp.mantissa.size == 0 );
/* NaN */
_PDCLIB_fp_from_dbl( &fp, -0.0/0.0 );
_PDCLIB_bigint_from_pow2( &t, _PDCLIB_DBL_MANT_DIG - 2 );
TESTCASE( fp.state == _PDCLIB_FP_NAN );
TESTCASE( _PDCLIB_bigint_cmp( &fp.mantissa, &t ) == 0 );
/* Subnormal */
_PDCLIB_fp_from_dbl( &fp, _PDCLIB_DBL_MIN / 2 );
_PDCLIB_bigint_from_pow2( &t, _PDCLIB_DBL_MANT_DIG - 2 );
TESTCASE( fp.state == _PDCLIB_FP_SUBNORMAL );
TESTCASE( _PDCLIB_bigint_cmp( &fp.mantissa, &t ) == 0 );
TESTCASE( fp.scale == ( _PDCLIB_DBL_MANT_DIG - 1 ) );
TESTCASE( fp.exponent == (_PDCLIB_int_least16_t)(1 - ( _PDCLIB_DBL_MAX_EXP - 1 ) ) );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,106 +0,0 @@
/* _PDCLIB_fp_from_ldbl( _PDCLIB_fp_t *, long double )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
#include <stdlib.h>
#include <string.h>
void _PDCLIB_fp_from_ldbl( _PDCLIB_fp_t * fp, long double ld )
{
memcpy( fp->mantissa.data, &ld, sizeof( long double ) );
fp->sign = _PDCLIB_LDBL_SIGN( fp->mantissa.data );
fp->exponent = _PDCLIB_LDBL_EXP( fp->mantissa.data );
fp->mantissa.size = _PDCLIB_LDBL_SIZE( fp->mantissa.data );
switch ( fp->exponent )
{
case 0:
fp->state = _PDCLIB_FP_SUBNORMAL;
fp->exponent = 1 - ( _PDCLIB_LDBL_MAX_EXP - 1 );
fp->scale = _PDCLIB_LDBL_MANT_DIG - 1;
break;
case ( _PDCLIB_LDBL_MAX_EXP - 1 ) + _PDCLIB_LDBL_MAX_EXP:
fp->state = _PDCLIB_FP_NAN;
break;
default:
{
div_t dv = div( _PDCLIB_LDBL_MANT_DIG - 1, _PDCLIB_BIGINT_DIGIT_BITS );
fp->state = _PDCLIB_FP_NORMAL;
if ( dv.rem == 0 )
{
fp->mantissa.data[ fp->mantissa.size++ ] = 1u;
}
else
{
fp->mantissa.data[ dv.quot ] |= ( 1u << dv.rem );
}
fp->exponent -= ( _PDCLIB_LDBL_MAX_EXP - 1 );
fp->scale = _PDCLIB_LDBL_MANT_DIG - 1;
break;
}
}
while ( fp->mantissa.size > 0 && fp->mantissa.data[ fp->mantissa.size - 1 ] == 0 )
{
--fp->mantissa.size;
}
if ( ( fp->state == _PDCLIB_FP_NAN ) && ( fp->mantissa.size == 0 ) )
{
fp->state = _PDCLIB_FP_INF;
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
_PDCLIB_fp_t fp;
_PDCLIB_bigint_t t;
/* Normal */
_PDCLIB_fp_from_ldbl( &fp, -1.0L );
_PDCLIB_bigint_from_pow2( &t, _PDCLIB_LDBL_MANT_DIG - 1 );
TESTCASE( fp.state == _PDCLIB_FP_NORMAL );
TESTCASE( _PDCLIB_bigint_cmp( &fp.mantissa, &t ) == 0 );
TESTCASE( fp.scale == ( _PDCLIB_LDBL_MANT_DIG - 1 ) );
TESTCASE( fp.exponent == 0 );
/* Inf */
_PDCLIB_fp_from_ldbl( &fp, 1e5000L );
TESTCASE( fp.state == _PDCLIB_FP_INF );
TESTCASE( fp.mantissa.size == 0 );
/* NaN */
_PDCLIB_fp_from_ldbl( &fp, -0.0L/0.0L );
_PDCLIB_bigint_from_pow2( &t, _PDCLIB_LDBL_MANT_DIG - 2 );
TESTCASE( fp.state == _PDCLIB_FP_NAN );
TESTCASE( _PDCLIB_bigint_cmp( &fp.mantissa, &t ) == 0 );
/* Subnormal */
_PDCLIB_fp_from_ldbl( &fp, _PDCLIB_LDBL_MIN / 2L );
_PDCLIB_bigint_from_pow2( &t, _PDCLIB_LDBL_MANT_DIG - 2 );
TESTCASE( fp.state == _PDCLIB_FP_SUBNORMAL );
TESTCASE( _PDCLIB_bigint_cmp( &fp.mantissa, &t ) == 0 );
TESTCASE( fp.scale == ( _PDCLIB_LDBL_MANT_DIG - 1 ) );
TESTCASE( fp.exponent == (_PDCLIB_int_least16_t)(1 - ( _PDCLIB_LDBL_MAX_EXP - 1 ) ) );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,49 +0,0 @@
/* _PDCLIB_getstream( FILE * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdio.h>
#ifndef REGTEST
#include "pdclib/_PDCLIB_internal.h"
extern struct _PDCLIB_file_t * _PDCLIB_filelist;
int _PDCLIB_getstream( struct _PDCLIB_file_t * stream )
{
struct _PDCLIB_file_t * previous;
if ( ! _PDCLIB_isstream( stream, &previous ) )
{
*_PDCLIB_errno_func() = _PDCLIB_EBADF;
return EOF;
}
if ( previous != NULL )
{
previous->next = stream->next;
}
else
{
_PDCLIB_filelist = stream->next;
}
return 0;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* No testdriver */
return TEST_RESULTS;
}
#endif

View File

@@ -1,82 +0,0 @@
/* _PDCLIB_init_file_t( _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.
*/
#ifndef REGTEST
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef __STDC_NO_THREADS__
#include <threads.h>
#endif
struct _PDCLIB_file_t * _PDCLIB_init_file_t( struct _PDCLIB_file_t * stream )
{
struct _PDCLIB_file_t * rc = stream;
if ( rc == NULL )
{
if ( ( rc = (struct _PDCLIB_file_t *)malloc( sizeof( struct _PDCLIB_file_t ) ) ) == NULL )
{
/* No memory */
return NULL;
}
}
if ( ( rc->buffer = (char *)malloc( BUFSIZ ) ) == NULL )
{
/* No memory */
free( rc );
return NULL;
}
rc->bufsize = BUFSIZ;
rc->bufidx = 0;
rc->bufend = 0;
rc->pos.offset = 0;
rc->pos.status = 0;
rc->ungetidx = 0;
rc->status = _PDCLIB_FREEBUFFER;
#ifndef __STDC_NO_THREADS__
if ( stream == NULL )
{
/* If called by freopen() (stream not NULL), mutex is already
initialized.
*/
if ( mtx_init( &rc->mtx, mtx_plain | mtx_recursive ) != thrd_success )
{
/* could not initialize stream mutex */
free( rc->buffer );
free( rc );
return NULL;
}
}
#endif
/* TODO: Setting mbstate */
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
TESTCASE( NO_TESTDRIVER );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,39 +0,0 @@
/* _PDCLIB_is_leap( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_internal.h"
int _PDCLIB_is_leap( int year_offset )
{
/* year given as offset from 1900, matching tm.tm_year in <time.h> */
long long year = year_offset + 1900ll;
return ( ( year % 4 ) == 0 && ( ( year % 25 ) != 0 || ( year % 400 ) == 0 ) );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
/* 1901 not leap */
TESTCASE( ! _PDCLIB_is_leap( 1 ) );
/* 1904 leap */
TESTCASE( _PDCLIB_is_leap( 4 ) );
/* 1900 not leap */
TESTCASE( ! _PDCLIB_is_leap( 0 ) );
/* 2000 leap */
TESTCASE( _PDCLIB_is_leap( 100 ) );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,49 +0,0 @@
/* _PDCLIB_isstream( FILE *, FILE ** )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdio.h>
#ifndef REGTEST
#include "pdclib/_PDCLIB_internal.h"
extern struct _PDCLIB_file_t * _PDCLIB_filelist;
int _PDCLIB_isstream( struct _PDCLIB_file_t * stream, struct _PDCLIB_file_t ** previous )
{
struct _PDCLIB_file_t * current = _PDCLIB_filelist;
if ( previous != NULL )
{
*previous = NULL;
}
while ( ( current != NULL ) && ( current != stream ) )
{
if ( previous != NULL )
{
*previous = current;
}
current = current->next;
}
return current != NULL;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* No testdriver */
return TEST_RESULTS;
}
#endif

View File

@@ -1,63 +0,0 @@
/* _PDCLIB_load_lc_collate( const char *, const char * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pdclib/_PDCLIB_internal.h"
struct _PDCLIB_lc_collate_t * _PDCLIB_load_lc_collate( const char * path, const char * locale )
{
struct _PDCLIB_lc_collate_t * rc = NULL;
const char * extension = "_collate.dat";
char * file = (char *)malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
if ( file )
{
FILE * fh;
strcpy( file, path );
strcat( file, locale );
strcat( file, extension );
if ( ( fh = fopen( file, "rb" ) ) != NULL )
{
if ( ( rc = (struct _PDCLIB_lc_collate_t *)malloc( sizeof( struct _PDCLIB_lc_collate_t ) ) ) != NULL )
{
/* TODO: Collation data */
rc->alloced = 1;
}
fclose( fh );
}
free( file );
}
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
TESTCASE( NO_TESTDRIVER );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,365 +0,0 @@
/* _PDCLIB_load_lc_ctype( const char *, const char * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include <inttypes.h>
#include <limits.h>
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pdclib/_PDCLIB_internal.h"
struct _PDCLIB_lc_ctype_t * _PDCLIB_load_lc_ctype( const char * path, const char * locale )
{
struct _PDCLIB_lc_ctype_t * rc = NULL;
const char * extension = "_ctype.dat";
char * file = (char *)malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
if ( file )
{
FILE * fh;
strcpy( file, path );
strcat( file, locale );
strcat( file, extension );
if ( ( fh = fopen( file, "rb" ) ) != NULL )
{
if ( ( rc = (struct _PDCLIB_lc_ctype_t *)malloc( sizeof( struct _PDCLIB_lc_ctype_t ) ) ) != NULL )
{
struct _PDCLIB_lc_ctype_entry_t * entry;
if ( ( entry = (struct _PDCLIB_lc_ctype_entry_t *)malloc( sizeof( struct _PDCLIB_lc_ctype_entry_t ) * _PDCLIB_CHARSET_SIZE + 1 ) ) != NULL )
{
rc->entry = entry + 1;
rc->entry[ -1 ].flags = rc->entry[ -1 ].upper = rc->entry[ -1 ].lower = 0;
if ( fscanf( fh, "%x %x %x %x %x %x", &rc->digits_low, &_PDCLIB_lc_ctype->digits_high, &_PDCLIB_lc_ctype->Xdigits_low, &_PDCLIB_lc_ctype->Xdigits_high, &_PDCLIB_lc_ctype->xdigits_low, &_PDCLIB_lc_ctype->xdigits_high ) == 6 )
{
size_t i;
for ( i = 0; i < _PDCLIB_CHARSET_SIZE; ++i )
{
if ( fscanf( fh, "%" SCNx16 " %hhx %hhx", &rc->entry[ i ].flags, &rc->entry[ i ].upper, &rc->entry[ i ].lower ) != 3 )
{
fclose( fh );
free( file );
free( rc->entry - 1 );
free( rc );
return NULL;
}
}
}
rc->alloced = 1;
}
else
{
free( rc );
}
}
fclose( fh );
}
free( file );
}
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <ctype.h>
int main( void )
{
#ifndef REGTEST
FILE * fh = fopen( "test_ctype.dat", "wb" );
TESTCASE( fh != NULL );
/* For test purposes, let's set up a charset that only has the hex digits */
/* 0x00..0x09 - digits */
/* 0x11..0x16 - Xdigits */
/* 0x21..0x26 - xdigits */
TESTCASE( fprintf( fh, "%x %x\n", 0x00, 0x09 ) );
TESTCASE( fprintf( fh, "%x %x %x %x\n", 0x11, 0x16, 0x21, 0x26 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x00, 0x00 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x01, 0x01 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x02, 0x02 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x03, 0x03 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x04, 0x04 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x05, 0x05 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x06, 0x06 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x07, 0x07 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x08, 0x08 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH, 0x09, 0x09 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x0A, 0x0A ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x0B, 0x0B ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x0C, 0x0C ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x0D, 0x0D ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x0E, 0x0E ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x0F, 0x0F ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x10, 0x10 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x11, 0x11 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x12, 0x12 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x13, 0x13 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x14, 0x14 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x15, 0x15 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x16, 0x16 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x17, 0x17 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x18, 0x18 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x19, 0x19 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x1A, 0x1A ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x1B, 0x1B ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x1C, 0x1C ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x1D, 0x1D ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x1E, 0x1E ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x1F, 0x1F ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x20, 0x20 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x21, 0x21 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x22, 0x22 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x23, 0x23 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x24, 0x24 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x25, 0x25 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x26, 0x26 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x27, 0x27 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x28, 0x28 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x29, 0x29 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x2A, 0x2A ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x2B, 0x2B ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x2C, 0x2C ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x2D, 0x2D ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x2E, 0x2E ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x2F, 0x2F ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x30, 0x30 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x31, 0x31 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x32, 0x32 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x33, 0x33 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x34, 0x34 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x35, 0x35 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x36, 0x36 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x37, 0x37 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x38, 0x38 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x39, 0x39 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x3A, 0x3A ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x3B, 0x3B ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x3C, 0x3C ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x3D, 0x3D ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x3E, 0x3E ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x3F, 0x3F ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x40, 0x40 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x41, 0x41 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x42, 0x42 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x43, 0x43 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x44, 0x44 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x45, 0x45 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x46, 0x46 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x47, 0x47 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x48, 0x48 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x49, 0x49 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x4A, 0x4A ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x4B, 0x4B ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x4C, 0x4C ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x4D, 0x4D ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x4E, 0x4E ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x4F, 0x4F ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x50, 0x50 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x51, 0x51 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x52, 0x52 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x53, 0x53 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x54, 0x54 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x55, 0x55 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x56, 0x56 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x57, 0x57 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x58, 0x58 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x59, 0x59 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x5A, 0x5A ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x5B, 0x5B ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x5C, 0x5C ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x5D, 0x5D ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x5E, 0x5E ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x5F, 0x5F ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x60, 0x60 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x61, 0x61 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x62, 0x62 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x63, 0x63 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x64, 0x64 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x65, 0x65 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x66, 0x66 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x67, 0x67 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x68, 0x68 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x69, 0x69 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x6A, 0x6A ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x6B, 0x6B ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x6C, 0x6C ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x6D, 0x6D ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x6E, 0x6E ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x6F, 0x6F ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x70, 0x70 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x71, 0x71 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x72, 0x72 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x73, 0x73 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x74, 0x74 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x75, 0x75 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x76, 0x76 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x77, 0x77 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x78, 0x78 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x79, 0x79 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x7A, 0x7A ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x7B, 0x7B ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x7C, 0x7C ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x7D, 0x7D ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x7E, 0x7E ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x7F, 0x7F ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x80, 0x80 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x81, 0x81 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x82, 0x82 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x83, 0x83 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x84, 0x84 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x85, 0x85 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x86, 0x86 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x87, 0x87 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x88, 0x88 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x89, 0x89 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x8A, 0x8A ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x8B, 0x8B ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x8C, 0x8C ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x8D, 0x8D ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x8E, 0x8E ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x8F, 0x8F ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x90, 0x90 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x91, 0x91 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x92, 0x92 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x93, 0x93 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x94, 0x94 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x95, 0x95 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x96, 0x96 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x97, 0x97 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x98, 0x98 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x99, 0x99 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x9A, 0x9A ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x9B, 0x9B ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x9C, 0x9C ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x9D, 0x9D ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x9E, 0x9E ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0x9F, 0x9F ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA0, 0xA0 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA1, 0xA1 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA2, 0xA2 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA3, 0xA3 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA4, 0xA4 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA5, 0xA5 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA6, 0xA6 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA7, 0xA7 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA8, 0xA8 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xA9, 0xA9 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xAA, 0xAA ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xAB, 0xAB ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xAC, 0xAC ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xAD, 0xAD ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xAE, 0xAE ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xAF, 0xAF ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB0, 0xB0 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB1, 0xB1 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB2, 0xB2 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB3, 0xB3 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB4, 0xB4 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB5, 0xB5 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB6, 0xB6 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB7, 0xB7 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB8, 0xB8 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xB9, 0xB9 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xBA, 0xBA ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xBB, 0xBB ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xBC, 0xBC ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xBD, 0xBD ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xBE, 0xBE ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xBF, 0xBF ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC0, 0xC0 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC1, 0xC1 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC2, 0xC2 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC3, 0xC3 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC4, 0xC4 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC5, 0xC5 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC6, 0xC6 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC7, 0xC7 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC8, 0xC8 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xC9, 0xC9 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xCA, 0xCA ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xCB, 0xCB ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xCC, 0xCC ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xCD, 0xCD ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xCE, 0xCE ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xCF, 0xCF ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD0, 0xD0 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD1, 0xD1 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD2, 0xD2 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD3, 0xD3 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD4, 0xD4 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD5, 0xD5 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD6, 0xD6 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD7, 0xD7 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD8, 0xD8 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xD9, 0xD9 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xDA, 0xDA ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xDB, 0xDB ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xDC, 0xDC ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xDD, 0xDD ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xDE, 0xDE ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xDF, 0xDF ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE0, 0xE0 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE1, 0xE1 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE2, 0xE2 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE3, 0xE3 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE4, 0xE4 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE5, 0xE5 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE6, 0xE6 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE7, 0xE7 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE8, 0xE8 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xE9, 0xE9 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xEA, 0xEA ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xEB, 0xEB ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xEC, 0xEC ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xED, 0xED ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xEE, 0xEE ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xEF, 0xEF ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF0, 0xF0 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF1, 0xF1 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF2, 0xF2 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF3, 0xF3 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF4, 0xF4 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF5, 0xF5 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF6, 0xF6 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF7, 0xF7 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF8, 0xF8 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xF9, 0xF9 ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xFA, 0xFA ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xFB, 0xFB ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xFC, 0xFC ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xFD, 0xFD ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xFE, 0xFE ) );
TESTCASE( fprintf( fh, "%x %x %x\n", 0x00, 0xFF, 0xFF ) );
fclose( fh );
TESTCASE( _PDCLIB_load_lc_ctype( "./", "test" ) != NULL );
remove( "test_ctype.dat" );
/*
TESTCASE( isdigit( 0x00 ) && ! isxdigit( 0x00 ) && ! isalpha( 0x00 ) );
TESTCASE( ! isdigit( 0x11 ) && isxdigit( 0x11 ) && isalpha( 0x11 ) && isupper( 0x11 ) && ! islower( 0x11 ) );
TESTCASE( ! isdigit( 0x21 ) && isxdigit( 0x21 ) && isalpha( 0x21 ) && ! isupper( 0x11 ) && islower( 0x11 ) );
*/
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,88 +0,0 @@
/* _PDCLIB_load_lc_messages( const char *, const char * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pdclib/_PDCLIB_internal.h"
struct _PDCLIB_lc_messages_t * _PDCLIB_load_lc_messages( const char * path, const char * locale )
{
struct _PDCLIB_lc_messages_t * rc = NULL;
const char * extension = "_messages.dat";
char * file = (char *)malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
if ( file )
{
FILE * fh;
strcpy( file, path );
strcat( file, locale );
strcat( file, extension );
if ( ( fh = fopen( file, "rb" ) ) != NULL )
{
if ( ( rc = (struct _PDCLIB_lc_messages_t *)malloc( sizeof( struct _PDCLIB_lc_messages_t ) ) ) != NULL )
{
char * data = _PDCLIB_load_lines( fh, _PDCLIB_ERRNO_MAX );
if ( data != NULL )
{
size_t i;
for ( i = 0; i < _PDCLIB_ERRNO_MAX; ++i )
{
rc->errno_texts[ i ] = data;
data += strlen( data ) + 1;
}
rc->alloced = 1;
}
else
{
free( rc );
rc = NULL;
}
}
fclose( fh );
}
free( file );
}
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
FILE * fh = fopen( "test_numeric.dat", "wb" );
struct _PDCLIB_lc_lconv_numeric_t * lc;
TESTCASE( fh != NULL );
TESTCASE( fputs( ",\n.\n\n", fh ) != EOF );
fclose( fh );
TESTCASE( ( lc = _PDCLIB_load_lc_numeric( "./", "test" ) ) );
remove( "test_numeric.dat" );
TESTCASE( strcmp( lc->decimal_point, "," ) == 0 );
TESTCASE( strcmp( lc->thousands_sep, "." ) == 0 );
TESTCASE( strcmp( lc->grouping, "" ) == 0 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,158 +0,0 @@
/* _PDCLIB_load_lc_monetary( const char *, const char * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pdclib/_PDCLIB_internal.h"
struct _PDCLIB_lc_lconv_monetary_t * _PDCLIB_load_lc_monetary( const char * path, const char * locale )
{
struct _PDCLIB_lc_lconv_monetary_t * rc = NULL;
const char * extension = "_monetary.dat";
char * file = (char *)malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
if ( file )
{
FILE * fh;
strcpy( file, path );
strcat( file, locale );
strcat( file, extension );
if ( ( fh = fopen( file, "rb" ) ) != NULL )
{
if ( ( rc = (struct _PDCLIB_lc_lconv_monetary_t *)malloc( sizeof( struct _PDCLIB_lc_lconv_monetary_t ) ) ) != NULL )
{
char buffer[ 14 ];
char * data = _PDCLIB_load_lines( fh, 7 );
if ( data != NULL )
{
if ( fread( buffer, 1, 14, fh ) == 14 )
{
rc->mon_decimal_point = data;
data += strlen( data ) + 1;
rc->mon_thousands_sep = data;
data += strlen( data ) + 1;
rc->mon_grouping = data;
data += strlen( data ) + 1;
rc->positive_sign = data;
data += strlen( data ) + 1;
rc->negative_sign = data;
data += strlen( data ) + 1;
rc->currency_symbol = data;
data += strlen( data ) + 1;
rc->int_curr_symbol = data;
rc->frac_digits = buffer[ 0 ];
rc->p_cs_precedes = buffer[ 1 ];
rc->n_cs_precedes = buffer[ 2 ];
rc->p_sep_by_space = buffer[ 3 ];
rc->n_sep_by_space = buffer[ 4 ];
rc->p_sign_posn = buffer[ 5 ];
rc->n_sign_posn = buffer[ 6 ];
rc->int_frac_digits = buffer[ 7 ];
rc->int_p_cs_precedes = buffer[ 8 ];
rc->int_n_cs_precedes = buffer[ 9 ];
rc->int_p_sep_by_space = buffer[ 10 ];
rc->int_n_sep_by_space = buffer[ 11 ];
rc->int_p_sign_posn = buffer[ 12 ];
rc->int_n_sign_posn = buffer[ 13 ];
}
else
{
free( data );
free( rc );
rc = NULL;
}
}
else
{
free( rc );
rc = NULL;
}
}
fclose( fh );
}
free( file );
}
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
FILE * fh = fopen( "test_monetary.dat", "wb" );
struct _PDCLIB_lc_lconv_monetary_t * lc;
TESTCASE( fh != NULL );
fprintf( fh, "%s\n", "," ); /* mon_decimal_point */
fprintf( fh, "%s\n", "." ); /* mon_thousands_sep */
fprintf( fh, "%s\n", "3" ); /* mon_grouping */
fprintf( fh, "%s\n", "" ); /* positive_sign */
fprintf( fh, "%s\n", "-" ); /* negative_sign */
fprintf( fh, "%s\n", "\xa4" ); /* currency_symbol */
fprintf( fh, "%s\n", "EUR" ); /* int_curr_symbol */
fputc( 2, fh ); /* frac_digits */
fputc( 0, fh ); /* p_cs_precedes */
fputc( 0, fh ); /* n_cs_precedes */
fputc( 1, fh ); /* p_sep_by_space */
fputc( 1, fh ); /* n_sep_by_space */
fputc( 1, fh ); /* p_sign_posn */
fputc( 1, fh ); /* n_sign_posn */
fputc( 2, fh ); /* int_frac_digits */
fputc( 0, fh ); /* int_p_cs_precedes */
fputc( 0, fh ); /* int_n_cs_precedes */
fputc( 1, fh ); /* int_p_sep_by_space */
fputc( 1, fh ); /* int_n_sep_by_space */
fputc( 1, fh ); /* int_p_sign_posn */
fputc( 1, fh ); /* int_n_sign_posn */
fprintf( fh, "\n" );
fclose( fh );
TESTCASE( ( lc = _PDCLIB_load_lc_monetary( "./", "test" ) ) );
remove( "test_monetary.dat" );
TESTCASE( strcmp( lc->mon_decimal_point, "," ) == 0 );
TESTCASE( strcmp( lc->mon_thousands_sep, "." ) == 0 );
TESTCASE( strcmp( lc->mon_grouping, "3" ) == 0 );
TESTCASE( strcmp( lc->positive_sign, "" ) == 0 );
TESTCASE( strcmp( lc->negative_sign, "-" ) == 0 );
TESTCASE( strcmp( lc->currency_symbol, "\xa4" ) == 0 );
TESTCASE( strcmp( lc->int_curr_symbol, "EUR" ) == 0 );
TESTCASE( lc->frac_digits == 2 );
TESTCASE( lc->p_cs_precedes == 0 );
TESTCASE( lc->n_cs_precedes == 0 );
TESTCASE( lc->p_sep_by_space == 1 );
TESTCASE( lc->n_sep_by_space == 1 );
TESTCASE( lc->p_sign_posn == 1 );
TESTCASE( lc->n_sign_posn == 1 );
TESTCASE( lc->int_frac_digits == 2 );
TESTCASE( lc->int_p_cs_precedes == 0 );
TESTCASE( lc->int_n_cs_precedes == 0 );
TESTCASE( lc->int_p_sep_by_space == 1 );
TESTCASE( lc->int_n_sep_by_space == 1 );
TESTCASE( lc->int_p_sign_posn == 1 );
TESTCASE( lc->int_n_sign_posn == 1 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,84 +0,0 @@
/* _PDCLIB_load_lc_numeric( const char *, const char * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pdclib/_PDCLIB_internal.h"
struct _PDCLIB_lc_lconv_numeric_t * _PDCLIB_load_lc_numeric( const char * path, const char * locale )
{
struct _PDCLIB_lc_lconv_numeric_t * rc = NULL;
const char * extension = "_numeric.dat";
char * file = (char *)malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
if ( file )
{
FILE * fh;
strcpy( file, path );
strcat( file, locale );
strcat( file, extension );
if ( ( fh = fopen( file, "rb" ) ) != NULL )
{
if ( ( rc = (struct _PDCLIB_lc_lconv_numeric_t *)malloc( sizeof( struct _PDCLIB_lc_lconv_numeric_t ) ) ) != NULL )
{
char * data = _PDCLIB_load_lines( fh, 3 );
if ( data != NULL )
{
rc->decimal_point = data;
data += strlen( data ) + 1;
rc->thousands_sep = data;
data += strlen( data ) + 1;
rc->grouping = data;
}
else
{
free( rc );
rc = NULL;
}
}
fclose( fh );
}
free( file );
}
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
FILE * fh = fopen( "test_numeric.dat", "wb" );
struct _PDCLIB_lc_lconv_numeric_t * lc;
TESTCASE( fh != NULL );
TESTCASE( fputs( ",\n.\n\n", fh ) != EOF );
fclose( fh );
TESTCASE( ( lc = _PDCLIB_load_lc_numeric( "./", "test" ) ) );
remove( "test_numeric.dat" );
TESTCASE( strcmp( lc->decimal_point, "," ) == 0 );
TESTCASE( strcmp( lc->thousands_sep, "." ) == 0 );
TESTCASE( strcmp( lc->grouping, "" ) == 0 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,165 +0,0 @@
/* _PDCLIB_load_lc_time( const char *, const char * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include <locale.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pdclib/_PDCLIB_internal.h"
struct _PDCLIB_lc_time_t * _PDCLIB_load_lc_time( const char * path, const char * locale )
{
struct _PDCLIB_lc_time_t * rc = NULL;
const char * extension = "_time.dat";
char * file = (char *)malloc( strlen( path ) + strlen( locale ) + strlen( extension ) + 1 );
if ( file )
{
FILE * fh;
strcpy( file, path );
strcat( file, locale );
strcat( file, extension );
if ( ( fh = fopen( file, "rb" ) ) != NULL )
{
if ( ( rc = (struct _PDCLIB_lc_time_t *)malloc( sizeof( struct _PDCLIB_lc_time_t ) ) ) != NULL )
{
char * data = _PDCLIB_load_lines( fh, 44 );
if ( data != NULL )
{
size_t i;
for ( i = 0; i < 12; ++i )
{
rc->month_name_abbr[ i ] = data;
data += strlen( data ) + 1;
}
for ( i = 0; i < 12; ++i )
{
rc->month_name_full[ i ] = data;
data += strlen( data ) + 1;
}
for ( i = 0; i < 7; ++i )
{
rc->day_name_abbr[ i ] = data;
data += strlen( data ) + 1;
}
for ( i = 0; i < 7; ++i )
{
rc->day_name_full[ i ] = data;
data += strlen( data ) + 1;
}
rc->alloced = 1;
}
else
{
free( rc );
rc = NULL;
}
}
fclose( fh );
}
free( file );
}
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
FILE * fh = fopen( "test_time.dat", "wb" );
struct _PDCLIB_lc_time_t * lc;
TESTCASE( fh != NULL );
/* month name abbreviation */
TESTCASE( fprintf( fh, "%s\n", "Jan" ) == 4 );
TESTCASE( fprintf( fh, "%s\n", "Feb" ) == 4 );
TESTCASE( fprintf( fh, "%s\n", "M\xe4r" ) == 4 );
TESTCASE( fprintf( fh, "%s\n", "Apr" ) == 4 );
TESTCASE( fprintf( fh, "%s\n", "Mai" ) == 4 );
TESTCASE( fprintf( fh, "%s\n", "Jun" ) == 4 );
TESTCASE( fprintf( fh, "%s\n", "Jul" ) == 4 );
TESTCASE( fprintf( fh, "%s\n", "Aug" ) == 4 );
TESTCASE( fprintf( fh, "%s\n", "Sep" ) == 4 );
TESTCASE( fprintf( fh, "%s\n", "Okt" ) == 4 );
TESTCASE( fprintf( fh, "%s\n", "Nov" ) == 4 );
TESTCASE( fprintf( fh, "%s\n", "Dez" ) == 4 );
/* month name full */
TESTCASE( fprintf( fh, "%s\n", "Januar" ) == 7 );
TESTCASE( fprintf( fh, "%s\n", "Februar" ) == 8 );
TESTCASE( fprintf( fh, "%s\n", "M\xe4rz" ) == 5 );
TESTCASE( fprintf( fh, "%s\n", "April" ) == 6 );
TESTCASE( fprintf( fh, "%s\n", "Mai" ) == 4 );
TESTCASE( fprintf( fh, "%s\n", "Juni" ) == 5 );
TESTCASE( fprintf( fh, "%s\n", "Juli" ) == 5 );
TESTCASE( fprintf( fh, "%s\n", "August" ) == 7 );
TESTCASE( fprintf( fh, "%s\n", "September" ) == 10 );
TESTCASE( fprintf( fh, "%s\n", "Oktober" ) == 8 );
TESTCASE( fprintf( fh, "%s\n", "November" ) == 9 );
TESTCASE( fprintf( fh, "%s\n", "Dezember" ) == 9 );
/* day name abbreviation */
TESTCASE( fprintf( fh, "%s\n", "So" ) == 3 );
TESTCASE( fprintf( fh, "%s\n", "Mo" ) == 3 );
TESTCASE( fprintf( fh, "%s\n", "Di" ) == 3 );
TESTCASE( fprintf( fh, "%s\n", "Mi" ) == 3 );
TESTCASE( fprintf( fh, "%s\n", "Do" ) == 3 );
TESTCASE( fprintf( fh, "%s\n", "Fr" ) == 3 );
TESTCASE( fprintf( fh, "%s\n", "Sa" ) == 3 );
/* day name full */
TESTCASE( fprintf( fh, "%s\n", "Sonntag" ) == 8 );
TESTCASE( fprintf( fh, "%s\n", "Montag" ) == 7 );
TESTCASE( fprintf( fh, "%s\n", "Dienstag" ) == 9 );
TESTCASE( fprintf( fh, "%s\n", "Mittwoch" ) == 9 );
TESTCASE( fprintf( fh, "%s\n", "Donnerstag" ) == 11 );
TESTCASE( fprintf( fh, "%s\n", "Freitag" ) == 8 );
TESTCASE( fprintf( fh, "%s\n", "Samstag" ) == 8 );
TESTCASE( fprintf( fh, "%s\n", "%a %d %b %Y %T %Z" ) == 18 ); /* date time format (%c) */
TESTCASE( fprintf( fh, "%s\n", "%I:%M:%S" ) == 9 ); /* 12-hour time format (%r) */
TESTCASE( fprintf( fh, "%s\n", "%d.%m.%Y" ) == 9 ); /* date format (%x) */
TESTCASE( fprintf( fh, "%s\n", "%H:%M:%S" ) == 9 ); /* time format (%X) */
TESTCASE( fprintf( fh, "%s\n", "" ) == 1 ); /* AM */
TESTCASE( fprintf( fh, "%s\n", "" ) == 1 ); /* PM */
fclose( fh );
TESTCASE( ( lc = _PDCLIB_load_lc_time( "./", "test" ) ) );
remove( "test_time.dat" );
TESTCASE( strcmp( lc->month_name_abbr[ 0 ], "Jan" ) == 0 );
TESTCASE( strcmp( lc->month_name_abbr[ 11 ], "Dez" ) == 0 );
TESTCASE( strcmp( lc->month_name_full[ 0 ], "Januar" ) == 0 );
TESTCASE( strcmp( lc->month_name_full[ 11 ], "Dezember" ) == 0 );
TESTCASE( strcmp( lc->day_name_abbr[ 0 ], "So" ) == 0 );
TESTCASE( strcmp( lc->day_name_abbr[ 6 ], "Sa" ) == 0 );
TESTCASE( strcmp( lc->day_name_full[ 0 ], "Sonntag" ) == 0 );
TESTCASE( strcmp( lc->day_name_full[ 6 ], "Samstag" ) == 0 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,81 +0,0 @@
/* _PDCLIB_load_lines( FILE *, size_t )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdio.h>
#include <stdlib.h>
#ifndef REGTEST
char * _PDCLIB_load_lines( FILE * fh, size_t lines )
{
size_t required = 0;
long pos = ftell( fh );
char * rc = NULL;
int c;
/* Count the number of characters */
while ( lines && ( c = fgetc( fh ) ) != EOF )
{
if ( c == '\n' )
{
--lines;
}
++required;
}
if ( ! feof( fh ) )
{
if ( ( rc = (char *)malloc( required ) ) != NULL )
{
size_t i;
fseek( fh, pos, SEEK_SET );
fread( rc, 1, required, fh );
for ( i = 0; i < required; ++i )
{
if ( rc[ i ] == '\n' )
{
rc[ i ] = '\0';
}
}
}
}
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
FILE * fh = fopen( "test_lines.txt", "w+" );
char * rc;
TESTCASE( fh != NULL );
TESTCASE( fputs( "Foo\n\nBar\n", fh ) != EOF );
rewind( fh );
rc = _PDCLIB_load_lines( fh, 3 );
fclose( fh );
remove( "test_lines.txt" );
TESTCASE( rc != NULL );
TESTCASE( strcmp( rc, "Foo" ) == 0 );
TESTCASE( strcmp( rc + 4, "" ) == 0 );
TESTCASE( strcmp( rc + 5, "Bar" ) == 0 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,96 +0,0 @@
/* _PDCLIB_naive_ptod( const char *, char ** endptr )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_internal.h"
#include <ctype.h>
#include <string.h>
long double _PDCLIB_naive_etod( const char * s, char ** endptr )
{
/* This is nowhere good enough, just a quick approximation */
long double rc = 0.0;
while ( isdigit( (unsigned char)*s ) )
{
rc = rc * 10 + ( *s++ - '0' );
}
if ( *s == '.' )
{
long double fraction = 0.0;
long double scale = 1.0;
++s;
while ( isdigit( (unsigned char)*s ) )
{
fraction = fraction * 10 + ( *s++ - '0' );
scale *= 10;
}
rc += ( fraction / scale );
}
if ( tolower( (unsigned char)*s ) == 'e' )
{
char sign = '+';
long double exp = 0.0;
long double scale = 1.0;
++s;
if ( *s == '-' )
{
sign = *s++;
}
else if ( *s == '+' )
{
++s;
}
while ( isdigit( (unsigned char)*s ) )
{
exp = ( exp * 10 ) + ( *s++ - '0' );
}
while ( exp > 0 )
{
scale *= 10;
--exp;
}
if ( sign == '+' )
{
rc *= scale;
}
else
{
rc /= scale;
}
}
if ( endptr != NULL )
{
*endptr = (char *)s;
}
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* Tested by strtof / strtol / strtold */
return TEST_RESULTS;
}
#endif

View File

@@ -1,97 +0,0 @@
/* _PDCLIB_naive_ptod( const char *, char ** endptr )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_internal.h"
#include <ctype.h>
#include <string.h>
long double _PDCLIB_naive_ptod( const char * s, char ** endptr )
{
/* This is nowhere good enough, just a quick approximation */
long double rc = 0.0;
const char * x;
while ( ( x = (const char *)memchr( _PDCLIB_digits, tolower( (unsigned char)*s ), 16 ) ) != NULL )
{
rc = rc * 16 + ( x - _PDCLIB_digits );
}
if ( *s == '.' )
{
long double fraction = 0.0;
long double scale = 1.0;
++s;
while ( ( x = (const char *)memchr( _PDCLIB_digits, tolower( (unsigned char)*s ), 16 ) ) != NULL )
{
fraction = fraction * 16 + ( x - _PDCLIB_digits );
scale *= 16;
}
rc += ( fraction / scale );
}
if ( tolower( (unsigned char)*s ) == 'p' )
{
char sign = '+';
long double exp = 0.0;
long double scale = 1.0;
++s;
if ( *s == '-' )
{
sign = *s++;
}
else if ( *s == '+' )
{
++s;
}
while ( isdigit( (unsigned char)*s ) )
{
exp = ( exp * 10 ) + ( *s++ - '0' );
}
while ( exp > 0 )
{
scale *= 2;
--exp;
}
if ( sign == '+' )
{
rc *= scale;
}
else
{
rc /= scale;
}
}
if ( endptr != NULL )
{
*endptr = (char *)s;
}
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* Tested by strtof / strtol / strtold */
return TEST_RESULTS;
}
#endif

View File

@@ -1,42 +0,0 @@
/* _PDCLIB_prepread( 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.
*/
#include <stdio.h>
#ifndef REGTEST
#include "pdclib/_PDCLIB_glue.h"
int _PDCLIB_prepread( struct _PDCLIB_file_t * stream )
{
if ( ( stream->bufidx > stream->bufend ) ||
( stream->status & ( _PDCLIB_FWRITE | _PDCLIB_FAPPEND | _PDCLIB_ERRORFLAG | _PDCLIB_WIDESTREAM | _PDCLIB_EOFFLAG ) ) ||
!( stream->status & ( _PDCLIB_FREAD | _PDCLIB_FRW ) ) )
{
/* Function called on illegal (e.g. output) stream. */
*_PDCLIB_errno_func() = _PDCLIB_EBADF;
stream->status |= _PDCLIB_ERRORFLAG;
return EOF;
}
stream->status |= _PDCLIB_FREAD | _PDCLIB_BYTESTREAM;
return 0;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* Testing covered by ftell.c */
return TEST_RESULTS;
}
#endif

View File

@@ -1,39 +0,0 @@
/* _PDCLIB_prepwrite( 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.
*/
#include <stdio.h>
#ifndef REGTEST
int _PDCLIB_prepwrite( struct _PDCLIB_file_t * stream )
{
if ( ( stream->bufidx < stream->bufend ) || ( stream->ungetidx > 0 ) ||
( stream->status & ( _PDCLIB_FREAD | _PDCLIB_ERRORFLAG | _PDCLIB_WIDESTREAM | _PDCLIB_EOFFLAG ) ) ||
!( stream->status & ( _PDCLIB_FWRITE | _PDCLIB_FAPPEND | _PDCLIB_FRW ) ) )
{
/* Function called on illegal (e.g. input) stream. */
*_PDCLIB_errno_func() = _PDCLIB_EBADF;
stream->status |= _PDCLIB_ERRORFLAG;
return EOF;
}
stream->status |= _PDCLIB_FWRITE | _PDCLIB_BYTESTREAM;
return 0;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* Testing covered by ftell.c */
return TEST_RESULTS;
}
#endif

View File

@@ -1,493 +0,0 @@
/* _PDCLIB_print( const char *, struct _PDCLIB_status_t * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <inttypes.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stddef.h>
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status )
{
const char * orig_spec = spec;
if ( *( ++spec ) == '%' )
{
/* %% -> print single '%' */
PUT( *spec );
return ++spec;
}
/* Initializing status structure */
status->flags = 0;
status->base = 0;
status->current = 0;
status->width = 0;
status->prec = EOF;
/* First come 0..n flags */
do
{
switch ( *spec )
{
case '-':
/* left-aligned output */
status->flags |= E_minus;
++spec;
break;
case '+':
/* positive numbers prefixed with '+' */
status->flags |= E_plus;
++spec;
break;
case '#':
/* alternative format: leading 0x for hex, 0 for octal,
forced decimal point for floats, trailing zeroes not
removed for %g/%G
*/
status->flags |= E_alt;
++spec;
break;
case ' ':
/* positive numbers prefixed with ' ' */
status->flags |= E_space;
++spec;
break;
case '0':
/* right-aligned padding done with '0' instead of ' ' */
status->flags |= E_zero;
++spec;
break;
default:
/* not a flag, exit flag parsing */
status->flags |= E_done;
break;
}
} while ( !( status->flags & E_done ) );
/* Optional field width */
if ( *spec == '*' )
{
/* Retrieve width value from argument stack */
int width = va_arg( status->arg, int );
if ( width < 0 )
{
status->flags |= E_minus;
status->width = abs( width );
}
else
{
status->width = width;
}
++spec;
}
else
{
/* If a width is given, strtol() will return its value. If not given,
strtol() will return zero. In both cases, endptr will point to the
rest of the conversion specifier - just what we need.
*/
status->width = ( int )strtol( spec, ( char ** )&spec, 10 );
}
/* Optional precision */
if ( *spec == '.' )
{
++spec;
if ( *spec == '*' )
{
/* Retrieve precision value from argument stack. A negative value
is as if no precision is given - as precision is initalized to
EOF (negative), there is no need for testing for negative here.
*/
status->prec = va_arg( status->arg, int );
++spec;
}
else
{
char * endptr;
status->prec = ( int )strtol( spec, &endptr, 10 );
if ( spec == endptr )
{
/* Decimal point but no number - equals zero */
status->prec = 0;
}
spec = endptr;
}
}
/* Optional length modifier
We step one character ahead in any case, and step back only if we find
there has been no length modifier (or step ahead another character if it
has been "hh" or "ll").
*/
switch ( *( spec++ ) )
{
case 'h':
if ( *spec == 'h' )
{
/* hh -> char */
status->flags |= E_char;
++spec;
}
else
{
/* h -> short */
status->flags |= E_short;
}
break;
case 'l':
if ( *spec == 'l' )
{
/* ll -> long long */
status->flags |= E_llong;
++spec;
}
else
{
/* k -> long */
status->flags |= E_long;
}
break;
case 'j':
/* j -> intmax_t, which might or might not be long long */
status->flags |= E_intmax;
break;
case 'z':
/* z -> size_t, which might or might not be unsigned int */
status->flags |= E_size;
break;
case 't':
/* t -> ptrdiff_t, which might or might not be long */
status->flags |= E_ptrdiff;
break;
case 'L':
/* L -> long double */
status->flags |= E_ldouble;
break;
default:
--spec;
break;
}
/* Conversion specifier */
switch ( *spec )
{
case 'd':
/* FALLTHROUGH */
case 'i':
status->base = 10;
break;
case 'o':
status->base = 8;
status->flags |= E_unsigned;
break;
case 'u':
status->base = 10;
status->flags |= E_unsigned;
break;
case 'x':
status->base = 16;
status->flags |= ( E_lower | E_unsigned );
break;
case 'X':
status->base = 16;
status->flags |= E_unsigned;
break;
case 'f':
status->base = 2;
status->flags |= ( E_decimal | E_double | E_lower );
break;
case 'F':
status->base = 2;
status->flags |= ( E_decimal | E_double );
break;
case 'e':
status->base = 2;
status->flags |= ( E_exponent | E_double | E_lower );
break;
case 'E':
status->base = 2;
status->flags |= ( E_exponent | E_double );
break;
case 'g':
status->base = 2;
status->flags |= ( E_generic | E_double | E_lower );
break;
case 'G':
status->base = 2;
status->flags |= ( E_generic | E_double );
break;
case 'a':
status->base = 2;
status->flags |= ( E_hexa | E_double | E_lower );
break;
case 'A':
status->base = 2;
status->flags |= ( E_hexa | E_double );
break;
case 'c':
/* TODO: wide chars. */
{
char c[1];
c[0] = ( char )va_arg( status->arg, int );
status->flags |= E_char;
_PDCLIB_print_string( c, status );
return ++spec;
}
case 's':
/* TODO: wide chars. */
_PDCLIB_print_string( va_arg( status->arg, char * ), status );
return ++spec;
case 'p':
status->base = 16;
status->flags |= ( E_lower | E_unsigned | E_alt | E_pointer );
break;
case 'n':
{
int * val = va_arg( status->arg, int * );
*val = status->i;
return ++spec;
}
default:
/* No conversion specifier. Bad conversion. */
return orig_spec;
}
/* Do the actual output based on our findings */
if ( status->base != 0 )
{
/* TODO: Check for invalid flag combinations. */
if ( status->flags & E_double )
{
/* Floating Point conversions */
if ( status->flags & E_ldouble )
{
long double value = va_arg( status->arg, long double );
_PDCLIB_fp_t fp;
_PDCLIB_fp_from_ldbl( &fp, value );
_PDCLIB_print_fp( &fp, status );
}
else
{
double value = va_arg( status->arg, double );
_PDCLIB_fp_t fp;
_PDCLIB_fp_from_dbl( &fp, value );
_PDCLIB_print_fp( &fp, status );
}
}
else
{
/* Having a precision cancels out any zero flag. */
if ( status->prec != EOF )
{
status->flags &= ~E_zero;
}
if ( status->flags & E_unsigned )
{
/* Integer conversions (unsigned) */
uintmax_t value;
imaxdiv_t div;
switch ( status->flags & ( E_char | E_short | E_long | E_llong | E_size | E_pointer | E_intmax ) )
{
case E_char:
value = ( uintmax_t )( unsigned char )va_arg( status->arg, int );
break;
case E_short:
value = ( uintmax_t )( unsigned short )va_arg( status->arg, int );
break;
case 0:
value = ( uintmax_t )va_arg( status->arg, unsigned int );
break;
case E_long:
value = ( uintmax_t )va_arg( status->arg, unsigned long );
break;
case E_llong:
value = ( uintmax_t )va_arg( status->arg, unsigned long long );
break;
case E_size:
value = ( uintmax_t )va_arg( status->arg, size_t );
break;
case E_pointer:
value = ( uintmax_t )( uintptr_t )va_arg( status->arg, void * );
break;
case E_intmax:
value = va_arg( status->arg, uintmax_t );
break;
default:
puts( "UNSUPPORTED PRINTF FLAG COMBINATION" );
return NULL;
}
div.quot = value / status->base;
div.rem = value % status->base;
_PDCLIB_print_integer( div, status );
}
else
{
/* Integer conversions (signed) */
intmax_t value;
switch ( status->flags & ( E_char | E_short | E_long | E_llong | E_intmax ) )
{
case E_char:
value = ( intmax_t )( char )va_arg( status->arg, int );
break;
case E_short:
value = ( intmax_t )( short )va_arg( status->arg, int );
break;
case 0:
value = ( intmax_t )va_arg( status->arg, int );
break;
case E_long:
value = ( intmax_t )va_arg( status->arg, long );
break;
case E_llong:
value = ( intmax_t )va_arg( status->arg, long long );
break;
case E_ptrdiff:
value = ( intmax_t )va_arg( status->arg, ptrdiff_t );
break;
case E_intmax:
value = va_arg( status->arg, intmax_t );
break;
default:
puts( "UNSUPPORTED PRINTF FLAG COMBINATION" );
return NULL;
}
_PDCLIB_print_integer( imaxdiv( value, status->base ), status );
}
}
if ( status->flags & E_minus )
{
/* Left-aligned filling */
while ( status->current < status->width )
{
PUT( ' ' );
++( status->current );
}
}
if ( status->i >= status->n && status->n > 0 )
{
status->s[status->n - 1] = '\0';
}
}
return ++spec;
}
#endif
#ifdef TEST
#define _PDCLIB_FILEID "_PDCLIB/print.c"
#define _PDCLIB_STRINGIO
#include "_PDCLIB_test.h"
#ifndef REGTEST
static int testprintf( char * buffer, const char * format, ... )
{
/* Members: base, flags, n, i, current, s, width, prec, stream, arg */
struct _PDCLIB_status_t status;
status.base = 0;
status.flags = 0;
status.n = 100;
status.i = 0;
status.current = 0;
status.s = buffer;
status.width = 0;
status.prec = EOF;
status.stream = NULL;
va_start( status.arg, format );
memset( buffer, '\0', 100 );
if ( *( _PDCLIB_print( format, &status ) ) != '\0' )
{
printf( "_PDCLIB_print() did not return end-of-specifier on '%s'.\n", format );
++TEST_RESULTS;
}
va_end( status.arg );
return status.i;
}
#endif
#define TEST_CONVERSION_ONLY
#include <float.h>
int main( void )
{
#ifndef REGTEST
char target[100];
#include "printf_testcases.h"
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,390 +0,0 @@
/* _PDCLIB_print_fp( _PDCLIB_fp_t *, struct _PDCLIB_status_t * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
#include <string.h>
#include <stdlib.h>
#define MIN( x, y ) ( ( x < y ) ? x : y )
static char * exp_to_buffer( int exponent, char * buffer )
{
div_t dv = div( exponent, 10 );
if ( dv.quot > 0 )
{
buffer = exp_to_buffer( dv.quot, buffer );
}
*buffer++ = _PDCLIB_digits[ dv.rem ];
return buffer;
}
static void _PDCLIB_format_e( struct _PDCLIB_status_t * status, char * buffer, int exp10, char sign )
{
size_t len = strlen( buffer );
int exponent = ( len + exp10 ) - 1;
int i;
char exp_buffer[8];
char * current;
/* Print exponent to exp_buffer */
current = exp_buffer;
*current++ = ( status->flags & E_lower ) ? 'e' : 'E';
if ( exponent < 0 )
{
*current++ = '-';
exponent *= -1;
}
else
{
*current++ = '+';
}
if ( exponent > -10 && exponent < 10 )
{
*current++ = '0';
}
current = exp_to_buffer( exponent, current );
*current = '\0';
/* Left padding, if applicable */
if ( ! ( status->flags & E_minus ) )
{
i = ( sign != '\0' )
+ 1
+ ( status->prec > 0 || status->flags & E_alt )
+ ( ( status->prec > 0 ) ? status->prec : 0 )
+ ( current - exp_buffer );
if ( ( sign != '\0' ) && ( status->flags & E_zero ) )
{
PUT( sign );
status->current++;
}
for ( ; (size_t)i < status->width; ++i )
{
PUT( ( status->flags & E_zero ) ? '0' : ' ' );
status->current++;
}
if ( ( sign != '\0' ) && ! ( status->flags & E_zero ) )
{
PUT( sign );
status->current++;
}
}
else if ( sign != '\0' )
{
PUT( sign );
status->current++;
}
/* Print buffer */
current = buffer;
PUT( _PDCLIB_digits[ (size_t)*current++ ] );
status->current++;
if ( status->prec > 0 || status->flags & E_alt )
{
PUT( '.' );
status->current++;
}
for ( i = 0; i < status->prec; ++i )
{
if ( *current != '\0' )
{
PUT( _PDCLIB_digits[ (size_t)*current++ ] );
status->current++;
}
else if ( ! ( status->flags & E_generic ) )
{
PUT( '0' );
status->current++;
}
}
/* Print exponent */
for ( current = exp_buffer; *current != '\0'; ++current )
{
PUT( *current );
status->current++;
}
}
static void _PDCLIB_format_f( struct _PDCLIB_status_t * status, char * buffer, int exp10, char sign )
{
size_t len = strlen( buffer );
/* Left padding, if applicable */
if ( ! ( status->flags & E_minus ) )
{
size_t i = ( sign != '\0' )
+ ( ( (int)len + exp10 > 0 ) ? ( len + exp10 ) : 1 )
+ ( status->prec > 0 || status->flags & E_alt )
+ ( ( status->prec > 0 ) ? status->prec : 0 );
if ( ( sign != '\0' ) && ( status->flags & E_zero ) )
{
PUT( sign );
status->current++;
}
for ( ; i < status->width; ++i )
{
PUT( ( status->flags & E_zero ) ? '0' : ' ' );
status->current++;
}
if ( ( sign != '\0' ) && ! ( status->flags & E_zero ) )
{
PUT( sign );
status->current++;
}
}
else if ( sign != '\0' )
{
PUT( sign );
status->current++;
}
if ( exp10 >= 0 )
{
/* Print buffer, period, zeroes to precision */
/* len + exp10 + [period + [prec]] */
int i;
for ( i = 0; (size_t)i < len; ++i )
{
PUT( _PDCLIB_digits[ (size_t)buffer[i] ] );
status->current++;
}
for ( i = 0; i < exp10; ++i )
{
PUT( _PDCLIB_digits[0] );
status->current++;
}
if ( ( ( ! ( status->flags & E_generic ) ) && status->prec > 0 ) || status->flags & E_alt )
{
PUT( '.' );
status->current++;
}
len = status->prec;
}
else
{
int n = len + exp10;
int i;
if ( n > 0 )
{
/* Print n from buffer, period, rest from buffer, zeroes to precision */
for ( i = 0; i < n; ++i )
{
PUT( _PDCLIB_digits[ (size_t)buffer[i] ] );
status->current++;
}
if ( status->prec > 0 || status->flags & E_alt )
{
PUT( '.' );
status->current++;
}
for ( i = 0; buffer[ i + n ] != '\0'; ++i )
{
PUT( _PDCLIB_digits[ (size_t)buffer[ i + n ] ] );
status->current++;
}
len = status->prec - i;
}
else
{
/* Print zero, period, -n zeroes, buffer, zeroes to precision */
PUT( _PDCLIB_digits[0] );
status->current++;
if ( status->prec > 0 || status->flags & E_alt )
{
PUT( '.' );
status->current++;
}
for ( i = 0; i < -n; ++i )
{
PUT( _PDCLIB_digits[0] );
status->current++;
}
for ( i = 0; buffer[i] != '\0'; ++i )
{
PUT( _PDCLIB_digits[ (size_t)buffer[i] ] );
status->current++;
}
n = -n + i;
len = status->prec - n;
}
}
if ( ! ( status->flags & E_generic ) )
{
for ( ; len > 0; --len )
{
PUT( _PDCLIB_digits[0] );
status->current++;
}
}
}
static void _PDCLIB_format_infnan( struct _PDCLIB_status_t * status, int state, char sign )
{
size_t i;
char const * s = ( state == _PDCLIB_FP_INF )
? ( ( status->flags & E_lower ) ? "inf" : "INF" )
: ( ( status->flags & E_lower ) ? "nan" : "NAN" );
/* Left padding, if applicable */
if ( ! ( status->flags & E_minus ) )
{
i = ( sign != '\0' ) ? 4 : 3;
for ( i = ( sign != '\0' ) ? 4 : 3; i < status->width; ++i )
{
PUT( ' ' );
status->current++;
}
}
if ( sign != '\0' )
{
PUT( sign );
status->current++;
}
for ( i = 0; i < 3; ++i )
{
PUT( s[i] );
}
status->current += 3;
}
void _PDCLIB_print_fp( _PDCLIB_fp_t * fp,
struct _PDCLIB_status_t * status )
{
char buffer[ _PDCLIB_LDBL_MANT_DIG + 10 ];
/* Turning sign bit into sign character. */
if ( fp->sign == 1 )
{
fp->sign = '-';
}
else if ( status->flags & E_plus )
{
fp->sign = '+';
}
else if ( status->flags & E_space )
{
fp->sign = ' ';
}
else
{
fp->sign = '\0';
}
if ( fp->state == _PDCLIB_FP_INF || fp->state == _PDCLIB_FP_NAN )
{
_PDCLIB_format_infnan( status, fp->state, fp->sign );
return;
}
if ( status->flags & E_hexa )
{
_PDCLIB_print_fp_hexa( fp, status, buffer );
return;
}
else
{
int exp10;
if ( status->prec < 0 )
{
status->prec = 6;
}
switch ( status->flags & ( E_decimal | E_exponent | E_generic ) )
{
case E_decimal:
{
exp10 = _PDCLIB_print_fp_deci( fp, status, buffer );
_PDCLIB_format_f( status, buffer, exp10, fp->sign );
break;
}
case E_exponent:
{
exp10 = _PDCLIB_print_fp_deci( fp, status, buffer );
_PDCLIB_format_e( status, buffer, exp10, fp->sign );
break;
}
case E_generic:
{
_PDCLIB_bigint_t mant;
int exponent;
_PDCLIB_bigint_from_bigint( &mant, &fp->mantissa );
if ( status->prec == 0 )
{
status->prec = 1;
}
exp10 = _PDCLIB_print_fp_deci( fp, status, buffer );
exponent = ( strlen( buffer ) + exp10 ) - 1;
if ( exponent >= -4 && exponent < status->prec )
{
_PDCLIB_bigint_from_bigint( &fp->mantissa, &mant );
status->flags &= ~E_generic;
status->flags |= E_decimal;
status->prec -= exponent + 1;
exp10 = _PDCLIB_print_fp_deci( fp, status, buffer );
status->flags |= E_generic;
_PDCLIB_format_f( status, buffer, exp10, fp->sign );
}
else
{
status->prec -= 1;
_PDCLIB_format_e( status, buffer, exp10, fp->sign );
}
break;
}
}
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( int argc, char * argv[] )
{
/* Tested by _PDCLIB_print testdriver */
return TEST_RESULTS;
}
#endif

View File

@@ -1,211 +0,0 @@
/* _PDCLIB_print_fp_deci( _PDCLIB_fp_t *, struct _PDCLIB_status_t *, char )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
#include <float.h>
static int prep( _PDCLIB_bigint_t * mantissa, int exponent )
{
/* log10(2) to 128bit precision */
const long double log_10_2 = 0.30102999566398119521373889472449302l;
/* Get an approximation of the base 10 exponent we are looking at
and make it fall one short in most cases as correction is easier
that way.
*/
double guess = (double)( _PDCLIB_bigint_log2( mantissa ) + exponent ) * log_10_2 - 0.69;
int exp10 = ( (int)guess < guess ) ? (int)guess + 1 : (int)guess;
return exp10;
}
int _PDCLIB_print_fp_deci( _PDCLIB_fp_t * fp,
struct _PDCLIB_status_t * status,
char * buffer )
{
char * current = buffer;
_PDCLIB_bigint_t divisor;
_PDCLIB_bigint_digit_t msd;
int digit;
int cutoff;
/* No decimal point in the mantissa, so we adjust the exponent. */
int exponent = fp->exponent - fp->scale;
int exp10 = prep( &fp->mantissa, exponent );
if ( ( status->flags & E_decimal ) && ( status->prec >= 0 ) && ( exp10 <= -status->prec ) )
{
exp10 = -status->prec + 1;
}
/* Set up the fraction. */
if ( exponent > 0 )
{
_PDCLIB_bigint_shl( &fp->mantissa, exponent );
_PDCLIB_bigint_from_digit( &divisor, 1 );
}
else
{
_PDCLIB_bigint_from_pow2( &divisor, -exponent );
}
/* Using the approx. exp10, scale the fraction close to where
we could start dividing.
*/
if ( exp10 > 0 )
{
_PDCLIB_bigint_mul_pow10( &divisor, exp10 );
}
else if ( exp10 < 0 )
{
_PDCLIB_bigint_mul_pow10( &fp->mantissa, -exp10 );
}
/* Now we know if our approximation was good or needs correction.
This is why we substracted as much as we could in prep(), as
correctiong for one short is the cheaper operation.
*/
if ( _PDCLIB_bigint_cmp( &fp->mantissa, &divisor ) >= 0 )
{
++exp10;
}
else
{
_PDCLIB_bigint_mul10( &fp->mantissa );
}
/* We make sure the fraction is scaled properly.
The previous operations already ensured that
the mantissa is no more than divisor * 10.
Now we make sure that the divisor has enough
bits in the most significant digit to give a
proper result, and that both mantissa and the
divisor are scaled to the same bigint length.
*/
msd = divisor.data[ divisor.size - 1 ];
if ( ( msd < 8 ) || ( msd > ( _PDCLIB_BIGINT_DIGIT_MAX / 10 ) ) )
{
int shift = ( ( _PDCLIB_BIGINT_DIGIT_BITS * 2 - 5 ) - _PDCLIB_bigint_digit_log2( msd ) ) % 32;
_PDCLIB_bigint_shl( &fp->mantissa, shift );
_PDCLIB_bigint_shl( &divisor, shift );
}
/* Main loop - divide, generate digits, multiply with 10, repeat */
switch ( status->flags & ( E_decimal | E_exponent | E_generic ) )
{
case E_decimal:
cutoff = -status->prec;
break;
case E_exponent:
case E_generic:
cutoff = exp10 - status->prec - 1;
break;
}
for (;;)
{
digit = _PDCLIB_bigint_div( &fp->mantissa, &divisor );
--exp10;
if ( fp->mantissa.size == 0 || exp10 == cutoff )
{
break;
}
*current++ = _PDCLIB_digits[ digit ];
_PDCLIB_bigint_mul10( &fp->mantissa );
}
/* rounding */
{
int roundup = 0;
switch ( FLT_ROUNDS )
{
case 3: /*FE_DOWNWARD*/
roundup = ( fp->sign == '-' );
break;
case 2: /*FE_UPWARD*/
roundup = ( fp->sign != '-' );
break;
case 0: /*FE_TOWARDZERO*/
roundup = 0;
break;
default:
case 1: /*FE_TONEAREST*/
{
int compare;
_PDCLIB_bigint_shl( &fp->mantissa, 1 );
compare = _PDCLIB_bigint_cmp( &fp->mantissa, &divisor );
if ( ( compare > 0 ) /* Over 0.5 */
|| ( ( compare == 0 ) && ( digit & 1 ) ) ) /* Break tie to even */
{
roundup = 1;
}
}
if ( roundup )
{
if ( digit < 9 )
{
*current++ = _PDCLIB_digits[ ++digit ];
}
else
{
for (;;)
{
++exp10;
if ( current == buffer )
{
*current++ = _PDCLIB_digits[1];
++exp10;
break;
}
if ( *--current != _PDCLIB_digits[9] )
{
++*current++;
break;
}
}
}
}
else
{
*current++ = _PDCLIB_digits[ digit ];
}
}
while ( *(current - 1) == '0' )
{
--current;
++exp10;
}
}
*current = '\0';
return exp10;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( int argc, char * argv[] )
{
/* Tested by _PDCLIB_print testdriver */
return TEST_RESULTS;
}
#endif

View File

@@ -1,268 +0,0 @@
/* _PDCLIB_print_fp_hexa( _PDCLIB_bigint_t *, struct _PDCLIB_status_t *, char )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
#include <float.h>
#include <stdbool.h>
#include <stdlib.h>
static inline void round_up( char * buffer, size_t index )
{
if ( buffer[ index ] < '\017' )
{
++buffer[ index ];
}
else
{
buffer[ index ] = '\0';
round_up( buffer, index - 1 );
}
}
static inline void round( char * buffer, size_t last_non_zero, size_t prec, char sign )
{
switch ( FLT_ROUNDS )
{
case 0: /*FE_TOWARDZERO*/
break;
default: /*FE_TONEAREST*/
case 1:
if ( buffer[ prec + 1 ] > '\005' )
{
round_up( buffer, prec );
}
else if ( buffer[ prec + 1 ] == '\005' )
{
if ( last_non_zero > ( prec + 1 ) || ( buffer[ prec ] % 2 ) )
{
round_up( buffer, prec );
}
}
break;
case 2: /*FE_UPWARD*/
if ( sign != '-' )
{
round_up( buffer, prec );
}
break;
case 3: /*FE_DOWNWARD*/
if ( sign == '-' )
{
round_up( buffer, prec );
}
break;
}
}
static char * print_exp( char * buffer, int exp )
{
div_t dv = div( exp, 10 );
if ( dv.quot > 0 )
{
buffer = print_exp( buffer, dv.quot );
}
*buffer = _PDCLIB_digits[ dv.rem ];
return ++buffer;
}
static size_t print_mant( _PDCLIB_fp_t * fp, struct _PDCLIB_status_t * status, char * buffer )
{
size_t i;
int last_non_zero;
size_t mant_dig = ( ( status->flags & E_ldouble ) ? _PDCLIB_LDBL_MANT_DIG : _PDCLIB_DBL_MANT_DIG ) - 1;
size_t log2 = _PDCLIB_bigint_log2( &fp->mantissa );
char * bufend = buffer;
if ( ( mant_dig % 4 ) > 0 )
{
/* alignment */
int shift = 4 - ( mant_dig % 4 );
_PDCLIB_bigint_shl( &fp->mantissa, shift );
mant_dig += shift;
log2 += shift;
}
if ( mant_dig > log2 )
{
/* subnormal, leading zeroes */
for ( i = 0; i <= ( mant_dig - log2 - 1 ) / 4; ++i )
{
*bufend++ = '\0';
}
}
for ( i = log2 / 4 + 1; i > 0; --i, ++bufend )
{
/* data nibbles */
div_t dv = div( i - 1, _PDCLIB_BIGINT_DIGIT_BITS / 4 );
if ( ( *bufend = ( fp->mantissa.data[ dv.quot ] >> ( dv.rem * 4 ) ) & 0xfu ) > 0 )
{
last_non_zero = bufend - buffer;
}
}
if ( status->prec >= 0 )
{
/* check rounding */
if ( last_non_zero > ( status->prec + 1 ) )
{
round( buffer, last_non_zero, status->prec, fp->sign );
}
return status->prec + 1;
}
else
{
/* no precision given */
return last_non_zero + 1;
}
}
void _PDCLIB_print_fp_hexa( _PDCLIB_fp_t * fp,
struct _PDCLIB_status_t * status,
char * buffer )
{
_PDCLIB_static_assert( _PDCLIB_FLT_RADIX == 2, "Assuming 2-based Floating Point" );
char const * digits = ( status->flags & E_lower ) ? _PDCLIB_digits : _PDCLIB_Xdigits;
int exp = (_PDCLIB_bigint_sdigit_t)fp->exponent;
/* sign + "0x" + dec + "." + ( LDBL_MANT_DIG / 4 )
+ 'p' + sign + exp[5] + '\0' <= 41
...but how could I do THAT? :-)
*/
char * current = buffer;
size_t count;
size_t i;
/* significant */
if ( fp->mantissa.size == 0 )
{
*current++ = '0';
exp = 0;
}
else
{
count = print_mant( fp, status, current );
*current = digits[ (size_t)*current ];
++current;
if ( ( count > 1 && status->prec != 0 ) || status->flags & E_alt )
{
for ( i = count; i > 1; --i )
{
current[ i ] = current[ i - 1 ];
}
*current++ = '.'; /* TODO: decimal point */
}
for ( i = 1; i < count; ++i )
{
*current = digits[ (size_t)*current ];
++current;
}
}
/* exponent */
*current++ = ( status->flags & E_lower ) ? 'p' : 'P';
if ( exp < 0 )
{
*current++ = '-';
exp *= -1;
}
else
{
*current++ = '+';
}
current = print_exp( current, exp );
*current = '\0';
/* output */
count = ( current - buffer ) + ( ( fp->sign == '\0' ) ? 2 : 3 );
count = ( status->width > count ) ? ( status->width - count ) : 0;
if ( ( count > 0 ) && ! ( status->flags & E_minus ) && ! ( status->flags & E_zero ) )
{
for ( i = 0; i < count; ++i )
{
PUT( ' ' );
status->current++;
}
}
if ( fp->sign != '\0' )
{
PUT( fp->sign );
status->current++;
}
PUT( '0' );
PUT( ( status->flags & E_lower ) ? 'x' : 'X' );
status->current += 2;
if ( ( count > 0 ) && ! ( status->flags & E_minus ) && ( status->flags & E_zero ) )
{
for ( i = 0; i < count; ++i )
{
PUT( '0' );
status->current++;
}
}
current = buffer;
while ( *current != '\0' )
{
PUT( *current++ );
status->current++;
}
if ( ( count > 0 ) && ( status->flags & E_minus ) )
{
for ( i = 0; i < count; ++i )
{
PUT( ' ' );
status->current++;
}
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( int argc, char * argv[] )
{
/* Tested by _PDCLIB_print testdriver */
#ifndef REGTEST
char buffer[100];
*(print_exp( buffer, 0 )) = '\0';
TESTCASE( strcmp( buffer, "0" ) == 0 );
*(print_exp( buffer, 9 )) = '\0';
TESTCASE( strcmp( buffer, "9" ) == 0 );
*(print_exp( buffer, 10 )) = '\0';
TESTCASE( strcmp( buffer, "10" ) == 0 );
*(print_exp( buffer, 100 )) = '\0';
TESTCASE( strcmp( buffer, "100" ) == 0 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,175 +0,0 @@
/* _PDCLIB_print_integer
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include <inttypes.h>
#include <stdio.h>
#include "pdclib/_PDCLIB_print.h"
static void intformat( intmax_t value, struct _PDCLIB_status_t * status )
{
/* At worst, we need two prefix characters (hex prefix). */
char preface[3] = "\0";
size_t preidx = 0;
if ( status->prec < 0 )
{
status->prec = 1;
}
if ( ( status->flags & E_alt ) && ( status->base == 16 || status->base == 8 ) && ( value != 0 ) )
{
/* Octal / hexadecimal prefix for "%#" conversions */
preface[ preidx++ ] = '0';
if ( status->base == 16 )
{
preface[ preidx++ ] = ( status->flags & E_lower ) ? 'x' : 'X';
}
}
if ( value < 0 )
{
/* Negative sign for negative values - at all times. */
preface[ preidx++ ] = '-';
}
else if ( !( status->flags & E_unsigned ) )
{
/* plus sign / extra space are only for signed conversions */
if ( status->flags & E_plus )
{
preface[ preidx++ ] = '+';
}
else
{
if ( status->flags & E_space )
{
preface[ preidx++ ] = ' ';
}
}
}
{
/* At this point, status->current has the number of digits queued up.
Determine if we have a precision requirement to pad those.
*/
size_t prec_pads = ( ( _PDCLIB_size_t )status->prec > status->current ) ? ( ( _PDCLIB_size_t )status->prec - status->current ) : 0;
if ( !( status->flags & ( E_minus | E_zero ) ) )
{
/* Space padding is only done if no zero padding or left alignment
is requested. Calculate the number of characters that WILL be
printed, including any prefixes determined above.
*/
/* The number of characters to be printed, plus prefixes if any. */
/* This line contained probably the most stupid, time-wasting bug
I've ever perpetrated. Greetings to Samface, DevL, and all
sceners at Breakpoint 2006.
*/
size_t characters = preidx + ( ( status->current > ( _PDCLIB_size_t )status->prec ) ? status->current : ( _PDCLIB_size_t )status->prec );
if ( status->width > characters )
{
size_t i;
for ( i = 0; i < status->width - characters; ++i )
{
PUT( ' ' );
++( status->current );
}
}
}
/* Now we did the padding, do the prefixes (if any). */
preidx = 0;
while ( preface[ preidx ] != '\0' )
{
PUT( preface[ preidx++ ] );
++( status->current );
}
/* Do the precision padding if necessary. */
while ( prec_pads-- > 0 )
{
PUT( '0' );
++( status->current );
}
if ( ( !( status->flags & E_minus ) ) && ( status->flags & E_zero ) )
{
/* If field is not left aligned, and zero padding is requested, do
so.
*/
while ( status->current < status->width )
{
PUT( '0' );
++( status->current );
}
}
}
}
/* This function recursively converts a given integer value to a character
stream. The conversion is done under the control of a given status struct
and written either to a character string or a stream, depending on that
same status struct. The status struct also keeps the function from exceeding
snprintf() limits, and enables any necessary padding / prefixing of the
output once the number of characters to be printed is known, which happens
at the lowermost recursion level.
*/
void _PDCLIB_print_integer( imaxdiv_t div, struct _PDCLIB_status_t * status )
{
if ( status->current == 0 && div.quot == 0 && div.rem == 0 && status->prec == 0 )
{
intformat( 0, status );
}
else
{
++(status->current);
if ( div.quot != 0 )
{
_PDCLIB_print_integer( imaxdiv( div.quot, status->base ), status );
}
else
{
intformat( div.rem, status );
}
if ( div.rem < 0 )
{
div.rem *= -1;
}
if ( status->flags & E_lower )
{
PUT( _PDCLIB_digits[ div.rem ] );
}
else
{
PUT( _PDCLIB_Xdigits[ div.rem ] );
}
}
}
#endif
#ifdef TEST
#include <stddef.h>
#include "_PDCLIB_test.h"
int main( void )
{
/* Tested by the various *printf() drivers. */
return TEST_RESULTS;
}
#endif

View File

@@ -1,85 +0,0 @@
/* _PDCLIB_print_string
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "pdclib/_PDCLIB_print.h"
/* Print a "string" (%c, %s) under control of a given status struct. See
INT2BASE().
*/
void _PDCLIB_print_string( const char * s, struct _PDCLIB_status_t * status )
{
if ( status->flags & E_char )
{
status->prec = 1;
}
else
{
if ( status->prec < 0 )
{
status->prec = strlen( s );
}
else
{
int i;
for ( i = 0; i < status->prec; ++i )
{
if ( s[i] == 0 )
{
status->prec = i;
break;
}
}
}
}
if ( !( status->flags & E_minus ) && ( status->width > ( _PDCLIB_size_t )status->prec ) )
{
while ( status->current < ( status->width - status->prec ) )
{
PUT( ' ' );
++( status->current );
}
}
while ( status->prec > 0 )
{
PUT( *( s++ ) );
--( status->prec );
++( status->current );
}
if ( status->flags & E_minus )
{
while ( status->width > status->current )
{
PUT( ' ' );
++( status->current );
}
}
}
#endif
#ifdef TEST
#include <stddef.h>
#include "_PDCLIB_test.h"
int main( void )
{
/* Tested by _PDCLIB_print testdriver */
return TEST_RESULTS;
}
#endif

View File

@@ -1,61 +0,0 @@
/* _PDCLIB_realpath( const char * path )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_glue.h"
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
extern char * realpath( const char * file_name, char * resolved_name );
#ifdef __cplusplus
}
#endif
char * _PDCLIB_realpath( const char * path )
{
/* TODO: PATH_MAX but that seems difficult to come by */
char buffer[ 4096 ];
char * resolved_name;
if ( realpath( path, buffer ) == NULL )
{
return NULL;
}
/* Need to do our own alloc-and-copy here, as realpath()
would be linked to the system malloc(), and if our
fclose() would run our free() on someone else's memory,
results are more interesting than we would like to see.
*/
if ( ( resolved_name = malloc( strlen( buffer + 1 ) ) ) == NULL )
{
return NULL;
}
return strcpy( resolved_name, buffer );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* No test drivers. */
return TEST_RESULTS;
}
#endif

View File

@@ -1,42 +0,0 @@
/* _PDCLIB_remove( const char * )
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_remove() fit for use with
POSIX kernels.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_glue.h"
#ifdef __cplusplus
extern "C" {
#endif
extern int unlink( const char * );
#ifdef __cplusplus
}
#endif
int _PDCLIB_remove( const char * pathname )
{
return unlink( pathname );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* Testing covered by ftell.c (and several others) */
return TEST_RESULTS;
}
#endif

View File

@@ -1,117 +0,0 @@
/* _PDCLIB_rename( const char *, const char * )
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_rename() fit for use with
POSIX kernels.
*/
#include <stdio.h>
#ifndef REGTEST
/* Having to jump through some hoops here so including fcntl.h does
work. Linux struggles with redefinitions of SEEK_SET et al. if
we set _GNU_SOURCE, but Cygwin needs that to actually get to the
AT_FDCWD definition.
*/
#ifdef __linux__
#define _ATFILE_SOURCE 1
#else
#define _GNU_SOURCE 1
#endif
#include "pdclib/_PDCLIB_glue.h"
#include "pdclib/_PDCLIB_defguard.h"
#include "pdclib/_PDCLIB_platform_errno.h"
/* The system calls provided for renaming are rename(), renameat()
and renameat2(). Using rename() is not possible, since we have
that symbol in our library and would end up with a recursive
call. But we *can* use renameat() with default parameters!
AT_FDCWD is declared in fcntl.h. We need to manually declare
renameat() here as it is declared in system's <stdio.h>.
*/
#include "pdclib/_PDCLIB_platform_fcntl.h"
#ifdef __cplusplus
extern "C" {
#endif
int renameat( int, const char *, int, const char * );
#ifdef __cplusplus
}
#endif
int _PDCLIB_rename( const char * oldpath, const char * newpath )
{
/* Whether existing newpath is overwritten is implementation-
defined. This system call *does* overwrite.
*/
if ( renameat( AT_FDCWD, oldpath, AT_FDCWD, newpath ) != 0 )
{
/* The 1:1 mapping in _PDCLIB_config.h ensures this works. */
*_PDCLIB_errno_func() = errno;
return -1;
}
else
{
return 0;
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <stdlib.h>
int main( void )
{
#ifndef REGTEST
FILE * file;
remove( testfile1 );
remove( testfile2 );
/* check that neither file exists */
TESTCASE( fopen( testfile1, "r" ) == NULL );
TESTCASE( fopen( testfile2, "r" ) == NULL );
/* rename file 1 to file 2 - expected to fail */
TESTCASE( _PDCLIB_rename( testfile1, testfile2 ) == -1 );
/* create file 1 */
TESTCASE( ( file = fopen( testfile1, "w" ) ) != NULL );
TESTCASE( fputc( 'x', file ) == 'x' );
TESTCASE( fclose( file ) == 0 );
/* check that file 1 exists */
TESTCASE( ( file = fopen( testfile1, "r" ) ) != NULL );
TESTCASE( fclose( file ) == 0 );
/* rename file 1 to file 2 */
TESTCASE( _PDCLIB_rename( testfile1, testfile2 ) == 0 );
/* check that file 2 exists, file 1 does not */
TESTCASE( fopen( testfile1, "r" ) == NULL );
TESTCASE( ( file = fopen( testfile2, "r" ) ) != NULL );
TESTCASE( fclose( file ) == 0 );
/* create another file 1 */
TESTCASE( ( file = fopen( testfile1, "w" ) ) != NULL );
TESTCASE( fputc( 'x', file ) == 'x' );
TESTCASE( fclose( file ) == 0 );
/* check that file 1 exists */
TESTCASE( ( file = fopen( testfile1, "r" ) ) != NULL );
TESTCASE( fclose( file ) == 0 );
/* Whether existing destination files are overwritten or not
is implementation-defined.
This implementation *does* overwrite.
*/
TESTCASE( _PDCLIB_rename( testfile1, testfile2 ) == 0 );
/* remove both files */
remove( testfile1 );
remove( testfile2 );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,781 +0,0 @@
/* _PDCLIB_scan( const char *, struct _PDCLIB_status_t * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdint.h>
#include <ctype.h>
#include <string.h>
#include <stddef.h>
#include <limits.h>
#ifndef REGTEST
#include "pdclib/_PDCLIB_glue.h"
/* Using an integer's bits as flags for both the conversion flags and length
modifiers.
*/
#define E_suppressed 1<<0
#define E_char 1<<6
#define E_short 1<<7
#define E_long 1<<8
#define E_llong 1<<9
#define E_intmax 1<<10
#define E_size 1<<11
#define E_ptrdiff 1<<12
#define E_pointer 1<<13
#define E_ldouble 1<<14
#define E_unsigned 1<<16
/* Helper function to get a character from the string or stream, whatever is
used for input. When reading from a string, returns EOF on end-of-string
so that handling of the return value can be uniform for both streams and
strings.
*/
static int GET( struct _PDCLIB_status_t * status )
{
int rc = EOF;
if ( status->stream != NULL )
{
if ( _PDCLIB_CHECKBUFFER( status->stream ) != EOF )
{
rc = _PDCLIB_GETC( status->stream );
}
}
else
{
rc = ( *status->s == '\0' ) ? EOF : ( unsigned char ) * ( ( status->s )++ );
}
if ( rc != EOF )
{
++( status->i );
++( status->current );
}
return rc;
}
/* Helper function to put a read character back into the string or stream,
whatever is used for input.
*/
static void UNGET( int c, struct _PDCLIB_status_t * status )
{
if ( status->stream != NULL )
{
ungetc( c, status->stream ); /* TODO: Error? */
}
else
{
--( status->s );
}
--( status->i );
--( status->current );
}
/* Helper function to check if a character is part of a given scanset */
static int IN_SCANSET( const char * scanlist, const char * end_scanlist, int rc )
{
/* SOLAR */
int previous = -1;
while ( scanlist != end_scanlist )
{
if ( ( *scanlist == '-' ) && ( previous != -1 ) )
{
/* possible scangroup ("a-z") */
if ( ++scanlist == end_scanlist )
{
/* '-' at end of scanlist does not describe a scangroup */
return rc == '-';
}
while ( ++previous <= ( unsigned char )*scanlist )
{
if ( previous == rc )
{
return 1;
}
}
previous = -1;
}
else
{
/* not a scangroup, check verbatim */
if ( rc == ( unsigned char )*scanlist )
{
return 1;
}
previous = ( unsigned char )( *scanlist++ );
}
}
return 0;
}
const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status )
{
/* generic input character */
int rc;
const char * prev_spec;
const char * orig_spec = spec;
int value_parsed;
if ( *( ++spec ) == '%' )
{
/* %% -> match single '%' */
rc = GET( status );
switch ( rc )
{
case EOF:
/* input error */
if ( status->n == 0 )
{
status->n = -1;
}
return NULL;
case '%':
return ++spec;
default:
UNGET( rc, status );
break;
}
}
/* Initializing status structure */
status->flags = 0;
status->base = -1;
status->current = 0;
status->width = 0;
status->prec = 0;
/* '*' suppresses assigning parsed value to variable */
if ( *spec == '*' )
{
status->flags |= E_suppressed;
++spec;
}
/* If a width is given, strtol() will return its value. If not given,
strtol() will return zero. In both cases, endptr will point to the
rest of the conversion specifier - just what we need.
*/
prev_spec = spec;
status->width = ( int )strtol( spec, ( char ** )&spec, 10 );
if ( spec == prev_spec )
{
status->width = SIZE_MAX;
}
/* Optional length modifier
We step one character ahead in any case, and step back only if we find
there has been no length modifier (or step ahead another character if it
has been "hh" or "ll").
*/
switch ( *( spec++ ) )
{
case 'h':
if ( *spec == 'h' )
{
/* hh -> char */
status->flags |= E_char;
++spec;
}
else
{
/* h -> short */
status->flags |= E_short;
}
break;
case 'l':
if ( *spec == 'l' )
{
/* ll -> long long */
status->flags |= E_llong;
++spec;
}
else
{
/* l -> long */
status->flags |= E_long;
}
break;
case 'j':
/* j -> intmax_t, which might or might not be long long */
status->flags |= E_intmax;
break;
case 'z':
/* z -> size_t, which might or might not be unsigned int */
status->flags |= E_size;
break;
case 't':
/* t -> ptrdiff_t, which might or might not be long */
status->flags |= E_ptrdiff;
break;
case 'L':
/* L -> long double */
status->flags |= E_ldouble;
break;
default:
--spec;
break;
}
/* Conversion specifier */
/* whether valid input had been parsed */
value_parsed = 0;
switch ( *spec )
{
case 'd':
status->base = 10;
break;
case 'i':
status->base = 0;
break;
case 'o':
status->base = 8;
status->flags |= E_unsigned;
break;
case 'u':
status->base = 10;
status->flags |= E_unsigned;
break;
case 'x':
status->base = 16;
status->flags |= E_unsigned;
break;
case 'f':
case 'F':
case 'e':
case 'E':
case 'g':
case 'G':
case 'a':
case 'A':
break;
case 'c':
{
char * c = NULL;
if ( !( status->flags & E_suppressed ) )
{
c = va_arg( status->arg, char * );
}
/* for %c, default width is one */
if ( status->width == SIZE_MAX )
{
status->width = 1;
}
/* reading until width reached or input exhausted */
while ( ( status->current < status->width ) &&
( ( rc = GET( status ) ) != EOF ) )
{
if ( c != NULL )
{
*( c++ ) = rc;
}
value_parsed = 1;
}
/* width or input exhausted */
if ( value_parsed )
{
if ( c != NULL )
{
++status->n;
}
return ++spec;
}
else
{
/* input error, no character read */
if ( status->n == 0 )
{
status->n = -1;
}
return NULL;
}
}
case 's':
{
char * c = NULL;
if ( !( status->flags & E_suppressed ) )
{
c = va_arg( status->arg, char * );
}
while ( ( status->current < status->width ) &&
( ( rc = GET( status ) ) != EOF ) )
{
if ( isspace( (unsigned char)rc ) )
{
UNGET( rc, status );
if ( value_parsed )
{
/* matching sequence terminated by whitespace */
if ( c != NULL )
{
*c = '\0';
++status->n;
}
return ++spec;
}
else
{
/* matching error */
return NULL;
}
}
else
{
/* match */
if ( c != NULL )
{
*( c++ ) = rc;
}
value_parsed = 1;
}
}
/* width or input exhausted */
if ( value_parsed )
{
if ( c != NULL )
{
*c = '\0';
++status->n;
}
return ++spec;
}
else
{
/* input error, no character read */
if ( status->n == 0 )
{
status->n = -1;
}
return NULL;
}
}
case '[':
{
const char * endspec = spec;
int negative_scanlist = 0;
char * c = NULL;
if ( !( status->flags & E_suppressed ) )
{
c = va_arg( status->arg, char * );
}
if ( *( ++endspec ) == '^' )
{
negative_scanlist = 1;
++endspec;
}
spec = endspec;
do
{
/* TODO: This can run beyond a malformed format string */
++endspec;
} while ( *endspec != ']' );
/* read according to scanlist, equiv. to %s above */
while ( ( status->current < status->width ) &&
( ( rc = GET( status ) ) != EOF ) )
{
if ( negative_scanlist )
{
if ( IN_SCANSET( spec, endspec, rc ) )
{
UNGET( rc, status );
break;
}
}
else
{
if ( ! IN_SCANSET( spec, endspec, rc ) )
{
UNGET( rc, status );
break;
}
}
if ( c != NULL )
{
*( c++ ) = rc;
}
value_parsed = 1;
}
/* width or input exhausted */
if ( value_parsed )
{
if ( c != NULL )
{
*c = '\0';
++status->n;
}
return ++endspec;
}
else
{
if ( status->n == 0 )
{
status->n = -1;
}
return NULL;
}
}
case 'p':
status->base = 16;
status->flags |= E_pointer;
break;
case 'n':
{
if ( !( status->flags & E_suppressed ) )
{
int * val = va_arg( status->arg, int * );
*val = status->i;
}
return ++spec;
}
default:
/* No conversion specifier. Bad conversion. */
return orig_spec;
}
if ( status->base != -1 )
{
/* integer conversion */
uintmax_t value = 0; /* absolute value read */
int prefix_parsed = 0;
int sign = 0;
while ( ( status->current < status->width ) &&
( ( rc = GET( status ) ) != EOF ) )
{
if ( isspace( (unsigned char)rc ) )
{
if ( sign )
{
/* matching sequence terminated by whitespace */
UNGET( rc, status );
break;
}
else
{
/* leading whitespace not counted against width */
status->current--;
}
}
else
{
if ( ! sign )
{
/* no sign parsed yet */
switch ( rc )
{
case '-':
sign = -1;
break;
case '+':
sign = 1;
break;
default:
/* not a sign; put back character */
sign = 1;
UNGET( rc, status );
break;
}
}
else
{
if ( ! prefix_parsed )
{
/* no prefix (0x... for hex, 0... for octal) parsed yet */
prefix_parsed = 1;
if ( rc != '0' )
{
/* not a prefix; if base not yet set, set to decimal */
if ( status->base == 0 )
{
status->base = 10;
}
UNGET( rc, status );
}
else
{
/* starts with zero, so it might be a prefix. */
/* check what follows next (might be 0x...) */
if ( ( status->current < status->width ) &&
( ( rc = GET( status ) ) != EOF ) )
{
if ( tolower( (unsigned char)rc ) == 'x' )
{
/* 0x... would be prefix for hex base... */
if ( ( status->base == 0 ) ||
( status->base == 16 ) )
{
status->base = 16;
}
else
{
/* ...unless already set to other value */
UNGET( rc, status );
value_parsed = 1;
}
}
else
{
/* 0... but not 0x.... would be octal prefix */
UNGET( rc, status );
if ( status->base == 0 )
{
status->base = 8;
}
/* in any case we have read a zero */
value_parsed = 1;
}
}
else
{
/* failed to read beyond the initial zero */
value_parsed = 1;
break;
}
}
}
else
{
char * digitptr = (char *)memchr( _PDCLIB_digits, tolower( (unsigned char)rc ), status->base );
if ( digitptr == NULL )
{
/* end of input item */
UNGET( rc, status );
break;
}
value *= status->base;
value += digitptr - _PDCLIB_digits;
value_parsed = 1;
}
}
}
}
/* width or input exhausted, or non-matching character */
if ( ! value_parsed )
{
/* out of input before anything could be parsed - input error */
/* FIXME: if first character does not match, value_parsed is not set - but it is NOT an input error */
if ( ( status->n == 0 ) && ( rc == EOF ) )
{
status->n = -1;
}
return NULL;
}
/* convert value to target type and assign to parameter */
if ( !( status->flags & E_suppressed ) )
{
switch ( status->flags & ( E_char | E_short | E_long | E_llong |
E_intmax | E_size | E_ptrdiff | E_pointer |
E_unsigned ) )
{
case E_char:
*( va_arg( status->arg, char * ) ) = ( char )( value * sign );
break;
case E_char | E_unsigned:
*( va_arg( status->arg, unsigned char * ) ) = ( unsigned char )( value * sign );
break;
case E_short:
*( va_arg( status->arg, short * ) ) = ( short )( value * sign );
break;
case E_short | E_unsigned:
*( va_arg( status->arg, unsigned short * ) ) = ( unsigned short )( value * sign );
break;
case 0:
*( va_arg( status->arg, int * ) ) = ( int )( value * sign );
break;
case E_unsigned:
*( va_arg( status->arg, unsigned int * ) ) = ( unsigned int )( value * sign );
break;
case E_long:
*( va_arg( status->arg, long * ) ) = ( long )( value * sign );
break;
case E_long | E_unsigned:
*( va_arg( status->arg, unsigned long * ) ) = ( unsigned long )( value * sign );
break;
case E_llong:
*( va_arg( status->arg, long long * ) ) = ( long long )( value * sign );
break;
case E_llong | E_unsigned:
*( va_arg( status->arg, unsigned long long * ) ) = ( unsigned long long )( value * sign );
break;
case E_intmax:
*( va_arg( status->arg, intmax_t * ) ) = ( intmax_t )( value * sign );
break;
case E_intmax | E_unsigned:
*( va_arg( status->arg, uintmax_t * ) ) = ( uintmax_t )( value * sign );
break;
case E_size:
/* E_size always implies unsigned */
*( va_arg( status->arg, size_t * ) ) = ( size_t )( value * sign );
break;
case E_ptrdiff:
/* E_ptrdiff always implies signed */
*( va_arg( status->arg, ptrdiff_t * ) ) = ( ptrdiff_t )( value * sign );
break;
case E_pointer:
/* E_pointer always implies unsigned */
*( uintptr_t * )( va_arg( status->arg, void * ) ) = ( uintptr_t )( value * sign );
break;
default:
fputs( "UNSUPPORTED SCANF FLAG COMBINATIONi\n", stdout );
return NULL; /* behaviour unspecified */
}
++( status->n );
}
return ++spec;
}
/* TODO: Floats. */
return NULL;
}
#endif
#ifdef TEST
#define _PDCLIB_FILEID "_PDCLIB/scan.c"
#define _PDCLIB_STRINGIO
#include "_PDCLIB_test.h"
#ifndef REGTEST
static int testscanf( const char * s, const char * format, ... )
{
struct _PDCLIB_status_t status;
char const * rc;
status.n = 0;
status.i = 0;
status.s = ( char * )s;
status.stream = NULL;
va_start( status.arg, format );
rc = _PDCLIB_scan( format, &status );
if ( rc != NULL && rc[0] != '\0' )
{
printf( "_PDCLIB_scan() did not return end-of-specifier on '%s'.\n", format );
++TEST_RESULTS;
}
if ( rc == NULL && s[0] != '\0' )
{
printf( "_PDCLIB_scan() returned NULL on '%s' input.", s );
++TEST_RESULTS;
}
va_end( status.arg );
return status.n;
}
#endif
#define TEST_CONVERSION_ONLY
int main( void )
{
#ifndef REGTEST
char source[100];
#include "scanf_testcases.h"
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,19 +0,0 @@
/* _PDCLIB_seed
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
unsigned long int _PDCLIB_seed = 1;
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* no tests for raw data */
return TEST_RESULTS;
}
#endif

View File

@@ -1,81 +0,0 @@
/* int_least64_t _PDCLIB_seek( FILE *, int_least64_t, int )
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_seek() fit for use with POSIX
kernels.
*/
#ifndef REGTEST
#include <stdio.h>
#include <stdint.h>
#include "pdclib/_PDCLIB_glue.h"
#include "pdclib/_PDCLIB_platform_errno.h"
#ifdef __cplusplus
extern "C" {
#endif
extern int64_t lseek64( int fd, _PDCLIB_int_least64_t offset, int whence );
extern long lseek( int fd, long offset, int whence );
#ifdef __cplusplus
}
#endif
_PDCLIB_int_least64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, _PDCLIB_int_least64_t offset, int whence )
{
_PDCLIB_int_least64_t rc;
switch ( whence )
{
case SEEK_SET:
case SEEK_CUR:
case SEEK_END:
/* EMPTY - OK */
break;
default:
*_PDCLIB_errno_func() = _PDCLIB_EINVAL;
return EOF;
break;
}
#ifdef __CYGWIN__
rc = lseek( stream->handle, offset, whence );
#else
rc = lseek64( stream->handle, offset, whence );
#endif
if ( rc != EOF )
{
stream->ungetidx = 0;
stream->bufidx = 0;
stream->bufend = 0;
stream->pos.offset = rc;
return rc;
}
/* The 1:1 mapping in _PDCLIB_config.h ensures that this works. */
*_PDCLIB_errno_func() = errno;
return EOF;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* Testing covered by ftell.c */
return TEST_RESULTS;
}
#endif

View File

@@ -1,598 +0,0 @@
/* _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 <stdio.h>
#include <locale.h>
#include <limits.h>
#ifndef REGTEST
#include "pdclib/_PDCLIB_tzcode.h"
/* 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. */
static char _PDCLIB_sin_buffer[BUFSIZ];
static char _PDCLIB_sout_buffer[BUFSIZ];
static char _PDCLIB_serr_buffer[BUFSIZ];
static struct _PDCLIB_file_t _PDCLIB_serr = { 2, _PDCLIB_serr_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, { 0 }, _IONBF | _PDCLIB_FWRITE,
#ifndef __STDC_NO_THREADS__
_PDCLIB_MTX_RECURSIVE_INIT,
#endif
NULL, NULL
};
static struct _PDCLIB_file_t _PDCLIB_sout = { 1, _PDCLIB_sout_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, { 0 }, _IOLBF | _PDCLIB_FWRITE,
#ifndef __STDC_NO_THREADS__
_PDCLIB_MTX_RECURSIVE_INIT,
#endif
NULL, &_PDCLIB_serr
};
static struct _PDCLIB_file_t _PDCLIB_sin = { 0, _PDCLIB_sin_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, { 0 }, _IOLBF | _PDCLIB_FREAD,
#ifndef __STDC_NO_THREADS__
_PDCLIB_MTX_RECURSIVE_INIT,
#endif
NULL, &_PDCLIB_sout
};
struct _PDCLIB_file_t * stdin = &_PDCLIB_sin;
struct _PDCLIB_file_t * stdout = &_PDCLIB_sout;
struct _PDCLIB_file_t * stderr = &_PDCLIB_serr;
/* FIXME: This approach is a possible attack vector. */
struct _PDCLIB_file_t * _PDCLIB_filelist = &_PDCLIB_sin;
#ifndef __STDC_NO_THREADS__
_PDCLIB_mtx_t _PDCLIB_filelist_mtx = _PDCLIB_MTX_PLAIN_INIT;
_PDCLIB_mtx_t _PDCLIB_time_mtx = _PDCLIB_MTX_PLAIN_INIT;
#endif
/* "C" locale - defaulting to ASCII-7.
1 kByte (+ 4 byte) of <ctype.h> data.
Each line: flags, lowercase, uppercase.
*/
static struct _PDCLIB_lc_ctype_entry_t _ctype_entries_C[ _PDCLIB_CHARSET_SIZE + 1 ] =
{
{ /* EOF */ 0, 0, 0 },
{ /* NUL */ _PDCLIB_CTYPE_CNTRL, 0x00, 0x00 },
{ /* SOH */ _PDCLIB_CTYPE_CNTRL, 0x01, 0x01 },
{ /* STX */ _PDCLIB_CTYPE_CNTRL, 0x02, 0x02 },
{ /* ETX */ _PDCLIB_CTYPE_CNTRL, 0x03, 0x03 },
{ /* EOT */ _PDCLIB_CTYPE_CNTRL, 0x04, 0x04 },
{ /* ENQ */ _PDCLIB_CTYPE_CNTRL, 0x05, 0x05 },
{ /* ACK */ _PDCLIB_CTYPE_CNTRL, 0x06, 0x06 },
{ /* BEL */ _PDCLIB_CTYPE_CNTRL, 0x07, 0x07 },
{ /* BS */ _PDCLIB_CTYPE_CNTRL, 0x08, 0x08 },
{ /* HT */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_BLANK | _PDCLIB_CTYPE_SPACE, 0x09, 0x09 },
{ /* LF */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0A, 0x0A },
{ /* VT */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0B, 0x0B },
{ /* FF */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0C, 0x0C },
{ /* CR */ _PDCLIB_CTYPE_CNTRL | _PDCLIB_CTYPE_SPACE, 0x0D, 0x0D },
{ /* SO */ _PDCLIB_CTYPE_CNTRL, 0x0E, 0x0E },
{ /* SI */ _PDCLIB_CTYPE_CNTRL, 0x0F, 0x0F },
{ /* DLE */ _PDCLIB_CTYPE_CNTRL, 0x10, 0x10 },
{ /* DC1 */ _PDCLIB_CTYPE_CNTRL, 0x11, 0x11 },
{ /* DC2 */ _PDCLIB_CTYPE_CNTRL, 0x12, 0x12 },
{ /* DC3 */ _PDCLIB_CTYPE_CNTRL, 0x13, 0x13 },
{ /* DC4 */ _PDCLIB_CTYPE_CNTRL, 0x14, 0x14 },
{ /* NAK */ _PDCLIB_CTYPE_CNTRL, 0x15, 0x15 },
{ /* SYN */ _PDCLIB_CTYPE_CNTRL, 0x16, 0x16 },
{ /* ETB */ _PDCLIB_CTYPE_CNTRL, 0x17, 0x17 },
{ /* CAN */ _PDCLIB_CTYPE_CNTRL, 0x18, 0x18 },
{ /* EM */ _PDCLIB_CTYPE_CNTRL, 0x19, 0x19 },
{ /* SUB */ _PDCLIB_CTYPE_CNTRL, 0x1A, 0x1A },
{ /* ESC */ _PDCLIB_CTYPE_CNTRL, 0x1B, 0x1B },
{ /* FS */ _PDCLIB_CTYPE_CNTRL, 0x1C, 0x1C },
{ /* GS */ _PDCLIB_CTYPE_CNTRL, 0x1D, 0x1D },
{ /* RS */ _PDCLIB_CTYPE_CNTRL, 0x1E, 0x1E },
{ /* US */ _PDCLIB_CTYPE_CNTRL, 0x1F, 0x1F },
{ /* SP */ _PDCLIB_CTYPE_BLANK | _PDCLIB_CTYPE_SPACE, 0x20, 0x20 },
{ /* '!' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x21, 0x21 },
{ /* '"' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x22, 0x22 },
{ /* '#' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x23, 0x23 },
{ /* '$' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x24, 0x24 },
{ /* '%' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x25, 0x25 },
{ /* '&' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x26, 0x26 },
{ /* ''' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x27, 0x27 },
{ /* '(' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x28, 0x28 },
{ /* ')' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x29, 0x29 },
{ /* '*' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2A, 0x2A },
{ /* '+' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2B, 0x2B },
{ /* ',' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2C, 0x2C },
{ /* '-' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2D, 0x2D },
{ /* '.' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2E, 0x2E },
{ /* '/' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x2F, 0x2F },
{ /* '0' */ _PDCLIB_CTYPE_GRAPH, 0x30, 0x30 },
{ /* '1' */ _PDCLIB_CTYPE_GRAPH, 0x31, 0x31 },
{ /* '2' */ _PDCLIB_CTYPE_GRAPH, 0x32, 0x32 },
{ /* '3' */ _PDCLIB_CTYPE_GRAPH, 0x33, 0x33 },
{ /* '4' */ _PDCLIB_CTYPE_GRAPH, 0x34, 0x34 },
{ /* '5' */ _PDCLIB_CTYPE_GRAPH, 0x35, 0x35 },
{ /* '6' */ _PDCLIB_CTYPE_GRAPH, 0x36, 0x36 },
{ /* '7' */ _PDCLIB_CTYPE_GRAPH, 0x37, 0x37 },
{ /* '8' */ _PDCLIB_CTYPE_GRAPH, 0x38, 0x38 },
{ /* '9' */ _PDCLIB_CTYPE_GRAPH, 0x39, 0x39 },
{ /* ':' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3A, 0x3A },
{ /* ';' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3B, 0x3B },
{ /* '<' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3C, 0x3C },
{ /* '=' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3D, 0x3D },
{ /* '>' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3E, 0x3E },
{ /* '?' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x3F, 0x3F },
{ /* '@' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x40, 0x40 },
{ /* 'A' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x41, 0x61 },
{ /* 'B' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x42, 0x62 },
{ /* 'C' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x43, 0x63 },
{ /* 'D' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x44, 0x64 },
{ /* 'E' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x45, 0x65 },
{ /* 'F' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x46, 0x66 },
{ /* 'G' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x47, 0x67 },
{ /* 'H' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x48, 0x68 },
{ /* 'I' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x49, 0x69 },
{ /* 'J' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4A, 0x6A },
{ /* 'K' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4B, 0x6B },
{ /* 'L' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4C, 0x6C },
{ /* 'M' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4D, 0x6D },
{ /* 'N' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4E, 0x6E },
{ /* 'O' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x4F, 0x6F },
{ /* 'P' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x50, 0x70 },
{ /* 'Q' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x51, 0x71 },
{ /* 'R' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x52, 0x72 },
{ /* 'S' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x53, 0x73 },
{ /* 'T' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x54, 0x74 },
{ /* 'U' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x55, 0x75 },
{ /* 'V' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x56, 0x76 },
{ /* 'W' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x57, 0x77 },
{ /* 'X' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x58, 0x78 },
{ /* 'Y' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x59, 0x79 },
{ /* 'Z' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_UPPER, 0x5A, 0x7A },
{ /* '[' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5B, 0x5B },
{ /* '\' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5C, 0x5C },
{ /* ']' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5D, 0x5D },
{ /* '^' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5E, 0x5E },
{ /* '_' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x5F, 0x5F },
{ /* '`' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x60, 0x60 },
{ /* 'a' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x41, 0x61 },
{ /* 'b' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x42, 0x62 },
{ /* 'c' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x43, 0x63 },
{ /* 'd' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x44, 0x64 },
{ /* 'e' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x45, 0x65 },
{ /* 'f' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x46, 0x66 },
{ /* 'g' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x47, 0x67 },
{ /* 'h' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x48, 0x68 },
{ /* 'i' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x49, 0x69 },
{ /* 'j' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4A, 0x6A },
{ /* 'k' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4B, 0x6B },
{ /* 'l' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4C, 0x6C },
{ /* 'm' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4D, 0x6D },
{ /* 'n' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4E, 0x6E },
{ /* 'o' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x4F, 0x6F },
{ /* 'p' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x50, 0x70 },
{ /* 'q' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x51, 0x71 },
{ /* 'r' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x52, 0x72 },
{ /* 's' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x53, 0x73 },
{ /* 't' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x54, 0x74 },
{ /* 'u' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x55, 0x75 },
{ /* 'v' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x56, 0x76 },
{ /* 'w' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x57, 0x77 },
{ /* 'x' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x58, 0x78 },
{ /* 'y' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x59, 0x79 },
{ /* 'z' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_ALPHA | _PDCLIB_CTYPE_LOWER, 0x5A, 0x7A },
{ /* '{' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7B, 0x7B },
{ /* '|' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7C, 0x7C },
{ /* '}' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7D, 0x7D },
{ /* '~' */ _PDCLIB_CTYPE_GRAPH | _PDCLIB_CTYPE_PUNCT, 0x7E, 0x7E },
{ /* DEL */ _PDCLIB_CTYPE_CNTRL, 0x7F, 0x7F },
{ 0x00, 0x80, 0x80 },
{ 0x00, 0x81, 0x81 },
{ 0x00, 0x82, 0x82 },
{ 0x00, 0x83, 0x83 },
{ 0x00, 0x84, 0x84 },
{ 0x00, 0x85, 0x85 },
{ 0x00, 0x86, 0x86 },
{ 0x00, 0x87, 0x87 },
{ 0x00, 0x88, 0x88 },
{ 0x00, 0x89, 0x89 },
{ 0x00, 0x8A, 0x8A },
{ 0x00, 0x8B, 0x8B },
{ 0x00, 0x8C, 0x8C },
{ 0x00, 0x8D, 0x8D },
{ 0x00, 0x8E, 0x8E },
{ 0x00, 0x8F, 0x8F },
{ 0x00, 0x90, 0x90 },
{ 0x00, 0x91, 0x91 },
{ 0x00, 0x92, 0x92 },
{ 0x00, 0x93, 0x93 },
{ 0x00, 0x94, 0x94 },
{ 0x00, 0x95, 0x95 },
{ 0x00, 0x96, 0x96 },
{ 0x00, 0x97, 0x97 },
{ 0x00, 0x98, 0x98 },
{ 0x00, 0x99, 0x99 },
{ 0x00, 0x9A, 0x9A },
{ 0x00, 0x9B, 0x9B },
{ 0x00, 0x9C, 0x9C },
{ 0x00, 0x9D, 0x9D },
{ 0x00, 0x9E, 0x9E },
{ 0x00, 0x9F, 0x9F },
{ 0x00, 0xA0, 0xA0 },
{ 0x00, 0xA1, 0xA1 },
{ 0x00, 0xA2, 0xA2 },
{ 0x00, 0xA3, 0xA3 },
{ 0x00, 0xA4, 0xA4 },
{ 0x00, 0xA5, 0xA5 },
{ 0x00, 0xA6, 0xA6 },
{ 0x00, 0xA7, 0xA7 },
{ 0x00, 0xA8, 0xA8 },
{ 0x00, 0xA9, 0xA9 },
{ 0x00, 0xAA, 0xAA },
{ 0x00, 0xAB, 0xAB },
{ 0x00, 0xAC, 0xAC },
{ 0x00, 0xAD, 0xAD },
{ 0x00, 0xAE, 0xAE },
{ 0x00, 0xAF, 0xAF },
{ 0x00, 0xB0, 0xB0 },
{ 0x00, 0xB1, 0xB1 },
{ 0x00, 0xB2, 0xB2 },
{ 0x00, 0xB3, 0xB3 },
{ 0x00, 0xB4, 0xB4 },
{ 0x00, 0xB5, 0xB5 },
{ 0x00, 0xB6, 0xB6 },
{ 0x00, 0xB7, 0xB7 },
{ 0x00, 0xB8, 0xB8 },
{ 0x00, 0xB9, 0xB9 },
{ 0x00, 0xBA, 0xBA },
{ 0x00, 0xBB, 0xBB },
{ 0x00, 0xBC, 0xBC },
{ 0x00, 0xBD, 0xBD },
{ 0x00, 0xBE, 0xBE },
{ 0x00, 0xBF, 0xBF },
{ 0x00, 0xC0, 0xC0 },
{ 0x00, 0xC1, 0xC1 },
{ 0x00, 0xC2, 0xC2 },
{ 0x00, 0xC3, 0xC3 },
{ 0x00, 0xC4, 0xC4 },
{ 0x00, 0xC5, 0xC5 },
{ 0x00, 0xC6, 0xC6 },
{ 0x00, 0xC7, 0xC7 },
{ 0x00, 0xC8, 0xC8 },
{ 0x00, 0xC9, 0xC9 },
{ 0x00, 0xCA, 0xCA },
{ 0x00, 0xCB, 0xCB },
{ 0x00, 0xCC, 0xCC },
{ 0x00, 0xCD, 0xCD },
{ 0x00, 0xCE, 0xCE },
{ 0x00, 0xCF, 0xCF },
{ 0x00, 0xD0, 0xD0 },
{ 0x00, 0xD1, 0xD1 },
{ 0x00, 0xD2, 0xD2 },
{ 0x00, 0xD3, 0xD3 },
{ 0x00, 0xD4, 0xD4 },
{ 0x00, 0xD5, 0xD5 },
{ 0x00, 0xD6, 0xD6 },
{ 0x00, 0xD7, 0xD7 },
{ 0x00, 0xD8, 0xD8 },
{ 0x00, 0xD9, 0xD9 },
{ 0x00, 0xDA, 0xDA },
{ 0x00, 0xDB, 0xDB },
{ 0x00, 0xDC, 0xDC },
{ 0x00, 0xDD, 0xDD },
{ 0x00, 0xDE, 0xDE },
{ 0x00, 0xDF, 0xDF },
{ 0x00, 0xE0, 0xE0 },
{ 0x00, 0xE1, 0xE1 },
{ 0x00, 0xE2, 0xE2 },
{ 0x00, 0xE3, 0xE3 },
{ 0x00, 0xE4, 0xE4 },
{ 0x00, 0xE5, 0xE5 },
{ 0x00, 0xE6, 0xE6 },
{ 0x00, 0xE7, 0xE7 },
{ 0x00, 0xE8, 0xE8 },
{ 0x00, 0xE9, 0xE9 },
{ 0x00, 0xEA, 0xEA },
{ 0x00, 0xEB, 0xEB },
{ 0x00, 0xEC, 0xEC },
{ 0x00, 0xED, 0xED },
{ 0x00, 0xEE, 0xEE },
{ 0x00, 0xEF, 0xEF },
{ 0x00, 0xF0, 0xF0 },
{ 0x00, 0xF1, 0xF1 },
{ 0x00, 0xF2, 0xF2 },
{ 0x00, 0xF3, 0xF3 },
{ 0x00, 0xF4, 0xF4 },
{ 0x00, 0xF5, 0xF5 },
{ 0x00, 0xF6, 0xF6 },
{ 0x00, 0xF7, 0xF7 },
{ 0x00, 0xF8, 0xF8 },
{ 0x00, 0xF9, 0xF9 },
{ 0x00, 0xFA, 0xFA },
{ 0x00, 0xFB, 0xFB },
{ 0x00, 0xFC, 0xFC },
{ 0x00, 0xFD, 0xFD },
{ 0x00, 0xFE, 0xFE },
{ 0x00, 0xFF, 0xFF }
};
struct _PDCLIB_lc_ctype_t _PDCLIB_lc_ctype_C = { 0, 0x30, 0x39, 0x41, 0x46, 0x61, 0x66, &_ctype_entries_C[1] };
struct _PDCLIB_lc_ctype_t * _PDCLIB_lc_ctype = &_PDCLIB_lc_ctype_C;
struct _PDCLIB_lc_collate_t _PDCLIB_lc_collate_C = { 0 };
struct _PDCLIB_lc_collate_t * _PDCLIB_lc_collate = &_PDCLIB_lc_collate_C;
struct lconv _PDCLIB_lconv =
{
/* decimal_point */ ( char * )".",
/* thousands_sep */ ( char * )"",
/* grouping */ ( char * )"",
/* mon_decimal_point */ ( char * )"",
/* mon_thousands_sep */ ( char * )"",
/* mon_grouping */ ( char * )"",
/* positive_sign */ ( char * )"",
/* negative_sign */ ( char * )"",
/* currency_symbol */ ( char * )"",
/* int_curr_symbol */ ( char * )"",
/* frac_digits */ CHAR_MAX,
/* p_cs_precedes */ CHAR_MAX,
/* n_cs_precedes */ CHAR_MAX,
/* p_sep_by_space */ CHAR_MAX,
/* n_sep_by_space */ CHAR_MAX,
/* p_sign_posn */ CHAR_MAX,
/* n_sign_posn */ CHAR_MAX,
/* int_frac_digits */ CHAR_MAX,
/* int_p_cs_precedes */ CHAR_MAX,
/* int_n_cs_precedes */ CHAR_MAX,
/* int_p_sep_by_space */ CHAR_MAX,
/* int_n_sep_by_space */ CHAR_MAX,
/* int_p_sign_posn */ CHAR_MAX,
/* int_n_sign_posn */ CHAR_MAX
};
struct _PDCLIB_lc_numeric_monetary_t _PDCLIB_lc_numeric_monetary =
{
&_PDCLIB_lconv,
0, /* numeric_allocated */
0 /* monetary_allocated */
};
struct _PDCLIB_lc_messages_t _PDCLIB_lc_messages_C =
{
0,
/* _PDCLIB_errno_texts */
{
/* unknown error */ ( char * )"unknown error",
/* EPERM */ ( char * )"EPERM (Operation not permitted)",
/* ENOENT */ ( char * )"ENOENT (No such file or directory)",
/* ESRCH */ ( char * )"ESRCH (No such process)",
/* EINTR */ ( char * )"EINTR (Interrupted function)",
/* EIO */ ( char * )"EIO (I/O error)",
/* ENXIO */ ( char * )"ENXIO (No such device or address)",
/* E2BIG */ ( char * )"E2BIG (Argument list too long)",
/* ENOEXEC */ ( char * )"ENOEXEC (Executable file format error)",
/* EBADF */ ( char * )"EBADF (Bad file descriptor)",
/* ECHILD */ ( char * )"ECHILD (No child processes)",
/* EAGAIN */ ( char * )"EAGAIN (Resource unavailable, try again)",
/* ENOMEM */ ( char * )"ENOMEM (Not enough space)",
/* EACCES */ ( char * )"EACCES (Permission denied)",
/* EFAULT */ ( char * )"EFAULT (Bad address)",
/* unknown error */ ( char * )"unknown error",
/* EBUSY */ ( char * )"EBUSY (Device or resource busy)",
/* EEXIST */ ( char * )"EEXIST (File exists)",
/* EXDEV */ ( char * )"EXDEV (Cross-device link)",
/* ENODEV */ ( char * )"ENODEV (No such device)",
/* ENOTDIR */ ( char * )"ENOTDIR (Not a directory)",
/* EISDIR */ ( char * )"EISDIR (Is a directory)",
/* EINVAL */ ( char * )"EINVAL (Invalid argument)",
/* ENFILE */ ( char * )"ENFILE (Too many files open in system)",
/* EMFILE */ ( char * )"EMFILE (File descriptor value too large)",
/* ENOTTY */ ( char * )"ENOTTY (Inappropriate I/O control operation)",
/* ETXTBSY */ ( char * )"ETXTBSY (Text file busy)",
/* EFBIG */ ( char * )"EFBIG (File too large)",
/* ENOSPC */ ( char * )"ENOSPC (No space left on device)",
/* ESPIPE */ ( char * )"ESPIPE (Invalid seek)",
/* EROFS */ ( char * )"EROFS (Read-only file system)",
/* EMLINK */ ( char * )"EMLINK (Too many links)",
/* EPIPE */ ( char * )"EPIPE (Broken pipe)",
/* EDOM */ ( char * )"EDOM (Mathematics argument out of domain of function)",
/* ERANGE */ ( char * )"ERANGE (Result too large)",
/* EDEADLK */ ( char * )"EDEADLK (Resource deadlock would occur)",
/* ENAMETOOLONG */ ( char * )"ENAMETOOLONG (Filename too long)",
/* ENOLCK */ ( char * )"ENOLCK (No locks available)",
/* ENOSYS */ ( char * )"ENOSYS (Function not supported)",
/* ENOTEMPTY */ ( char * )"ENOTEMPTY (Directory not empty)",
/* ELOOP */ ( char * )"ELOOP (Too many levels of symbolic links)",
/* unknown error */ ( char * )"unknown error",
/* ENOMSG */ ( char * )"ENOMSG (No message of the desired type)",
/* EIDRM */ ( char * )"EIDRM (Identifier removed)",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* ENOSTR */ ( char * )"ENOSTR (Not a STREAM)",
/* ENODATA */ ( char * )"ENODATA (No message is available on the STREAM head read queue)",
/* ETIME */ ( char * )"ETIME (Stream ioctl() timeout)",
/* ENOSR */ ( char * )"ENOSR (No STREAM resources)",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* ENOLINK */ ( char * )"ENOLINK (Link has been severed)",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* EPROTO */ ( char * )"EPROTO (Protocol error)",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* EBADMSG */ ( char * )"EBADMSG (Bad message)",
/* EOVERFLOW */ ( char * )"EOVERFLOW (Value too large to be stored in data type)",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* EILSEQ */ ( char * )"EILSEQ (Illegal byte sequence)",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* ENOTSOCK */ ( char * )"ENOTSOCK (Not a socket)",
/* EDESTADDRREQ */ ( char * )"EDESTADDRREQ (Destination address required)",
/* EMSGSIZE */ ( char * )"EMSGSIZE (Message too large)",
/* EPROTOTYPE */ ( char * )"EPROTOTYPE (Protocol wrong type for socket)",
/* ENOPROTOOPT */ ( char * )"ENOPROTOOPT (Protocol not available)",
/* EPROTONOSUPPORT */ ( char * )"EPROTONOSUPPORT (Protocol not supported)",
/* unknown error */ ( char * )"unknown error",
/* ENOTSUP */ ( char * )"ENOTSUP (Not supported)",
/* unknown error */ ( char * )"unknown error",
/* EAFNOSUPPORT */ ( char * )"EAFNOSUPPORT (Address family not supported)",
/* EADDRINUSE */ ( char * )"EADDRINUSE (Address in use)",
/* EADDRNOTAVAIL */ ( char * )"EADDRNOTAVAIL (Address not available)",
/* ENETDOWN */ ( char * )"ENETDOWN (Network is down)",
/* ENETUNREACH */ ( char * )"ENETUNREACH (Network unreachable)",
/* ENETRESET */ ( char * )"ENETRESET (Connection aborted by network)",
/* ECONNABORTED */ ( char * )"ECONNABORTED (Connection aborted)",
/* ECONNRESET */ ( char * )"ECONNRESET (Connection reset)",
/* ENOBUFS */ ( char * )"ENOBUFS (No buffer space available)",
/* EISCONN */ ( char * )"EISCONN (Socket is connected)",
/* ENOTCONN */ ( char * )"ENOTCONN (The socket is not connected)",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* ETIMEDOUT */ ( char * )"ETIMEDOUT (Connection timed out)",
/* ECONNREFUSED */ ( char * )"ECONNREFUSED (Connection refused)",
/* unknown error */ ( char * )"unknown error",
/* EHOSTUNREACH */ ( char * )"EHOSTUNREACH (Host is unreachable)",
/* EALREADY */ ( char * )"EALREADY (Connection already in progress)",
/* EINPROGRESS */ ( char * )"EINPROGRESS (Operation in progress)",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* ECANCELED */ ( char * )"ECANCELED (Operation canceled)",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* unknown error */ ( char * )"unknown error",
/* EOWNERDEAD */ ( char * )"EOWNERDEAD (Previous owner died)",
/* ENOTRECOVERABLE */ ( char * )"ENOTRECOVERABLE (State not recoverable)",
}
};
struct _PDCLIB_lc_messages_t * _PDCLIB_lc_messages = &_PDCLIB_lc_messages_C;
struct _PDCLIB_lc_time_t _PDCLIB_lc_time_C =
{
0,
/* _PDCLIB_month_name_abbr */
{
( char * )"Jan",
( char * )"Feb",
( char * )"Mar",
( char * )"Apr",
( char * )"May",
( char * )"Jun",
( char * )"Jul",
( char * )"Aug",
( char * )"Sep",
( char * )"Oct",
( char * )"Nov",
( char * )"Dec"
},
/* _PDCLIB_month_name_full */
{
( char * )"January",
( char * )"February",
( char * )"March",
( char * )"April",
( char * )"May",
( char * )"June",
( char * )"July",
( char * )"August",
( char * )"September",
( char * )"October",
( char * )"November",
( char * )"December"
},
/* _PDCLIB_day_name_abbr */
{
( char * )"Sun",
( char * )"Mon",
( char * )"Tue",
( char * )"Wed",
( char * )"Thu",
( char * )"Fri",
( char * )"Sat"
},
/* _PDCLIB_day_name_full */
{
( char * )"Sunday",
( char * )"Monday",
( char * )"Tuesday",
( char * )"Wednesday",
( char * )"Thursday",
( char * )"Friday",
( char * )"Saturday"
},
/* date / time format */ ( char * )"%a %b %e %T %Y",
/* 12h time format */ ( char * )"%I:%M:%S %p",
/* date format */ ( char * )"%m/%d/%y",
/* time format */ ( char * )"%T",
/* AM / PM designation */
{
( char * )"AM",
( char * )"PM"
}
};
struct _PDCLIB_lc_time_t * _PDCLIB_lc_time = &_PDCLIB_lc_time_C;
struct state _PDCLIB_lclmem;
struct state _PDCLIB_gmtmem;
/* Section 4.12.3 of X3.159-1989 requires that
Except for the strftime function, these functions [asctime,
ctime, gmtime, localtime] return values in one of two static
objects: a broken-down time structure and an array of char.
Thanks to Paul Eggert for noting this.
*/
struct tm _PDCLIB_tm;
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
/* Testing covered by several other testdrivers using stdin / stdout /
stderr.
*/
return TEST_RESULTS;
}
#endif

View File

@@ -1,135 +0,0 @@
/* _PDCLIB_strtod_prelim( const char *, char *, int * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#include <stddef.h>
#include <string.h>
#ifndef REGTEST
int _PDCLIB_strtod_prelim( const char * p, char * sign, char ** endptr )
{
int base = 10;
/* skipping leading whitespace */
while ( isspace( (unsigned char)*p ) )
{
++p;
}
/* determining / skipping sign */
if ( *p != '+' && *p != '-' )
{
*sign = '+';
}
else
{
*sign = *( p++ );
}
/* determining base */
if ( *p == '0' )
{
++p;
if ( *p == 'x' || *p == 'X' )
{
int period = 0;
base = 16;
++p;
if ( *p == '.' )
{
++p;
period = 1;
}
/* catching a border case here: "0x" followed by a non-digit should
be parsed as the unprefixed zero.
We have to "rewind" the parsing.
*/
if ( memchr( _PDCLIB_digits, tolower( (unsigned char)*p ), base ) == NULL )
{
p -= ( 2 + period );
}
}
else
{
--p;
}
}
else
{
/* inf / nan(...) */
/* Repurposing base: 0 for no match, -1 for inf, -2 for nan */
if ( tolower( (unsigned char)p[0] ) == 'i' && tolower( (unsigned char)p[1] ) == 'n' && tolower( (unsigned char)p[2] ) == 'f' )
{
p += 3;
base = -1;
}
else if ( tolower( (unsigned char)p[0] ) == 'n' && tolower( (unsigned char)p[1] ) == 'a' && tolower( (unsigned char)p[2] ) == 'n' )
{
const char * n = p + 3;
p = n;
base = -2;
if ( *n == '(' )
{
while ( *++n && *n != ')' );
if ( *n == ')' )
{
p = n + 1;
}
}
}
}
*endptr = (char *)p;
return base;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
int base = 0;
char sign = '\0';
char test1[] = " 123";
char test2[] = "\t+0123";
char test3[] = "\v-0x123";
TESTCASE( _PDCLIB_strtox_prelim( test1, &sign, &base ) == &test1[2] );
TESTCASE( sign == '+' );
TESTCASE( base == 10 );
base = 0;
sign = '\0';
TESTCASE( _PDCLIB_strtox_prelim( test2, &sign, &base ) == &test2[2] );
TESTCASE( sign == '+' );
TESTCASE( base == 8 );
base = 0;
sign = '\0';
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == &test3[4] );
TESTCASE( sign == '-' );
TESTCASE( base == 16 );
base = 10;
sign = '\0';
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == &test3[2] );
TESTCASE( sign == '-' );
TESTCASE( base == 10 );
base = 1;
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == NULL );
base = 37;
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == NULL );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,186 +0,0 @@
/* _PDCLIB_strtok( char *, rsize_t *, const char *, char ** )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#define __STDC_WANT_LIB_EXT1__ 1
#include <string.h>
#include <stdint.h>
#include <stdlib.h>
char * _PDCLIB_strtok( char * _PDCLIB_restrict s1, rsize_t * _PDCLIB_restrict s1max, const char * _PDCLIB_restrict s2, char ** _PDCLIB_restrict ptr )
{
const char * p = s2;
if ( s1max == NULL || s2 == NULL || ptr == NULL || ( s1 == NULL && *ptr == NULL ) || *s1max > RSIZE_MAX )
{
_PDCLIB_constraint_handler( _PDCLIB_CONSTRAINT_VIOLATION( _PDCLIB_EINVAL ) );
return NULL;
}
if ( s1 != NULL )
{
/* new string */
*ptr = s1;
}
else
{
/* old string continued */
if ( *ptr == NULL )
{
/* No old string, no new string, nothing to do */
return NULL;
}
s1 = *ptr;
}
/* skip leading s2 characters */
while ( *p && *s1 )
{
if ( *s1 == *p )
{
/* found separator; skip and start over */
if ( *s1max == 0 )
{
_PDCLIB_constraint_handler( _PDCLIB_CONSTRAINT_VIOLATION( _PDCLIB_EINVAL ) );
return NULL;
}
++s1;
--( *s1max );
p = s2;
continue;
}
++p;
}
if ( ! *s1 )
{
/* no more to parse */
*ptr = s1;
return NULL;
}
/* skipping non-s2 characters */
*ptr = s1;
while ( **ptr )
{
p = s2;
while ( *p )
{
if ( **ptr == *p++ )
{
/* found separator; overwrite with '\0', position *ptr, return */
if ( *s1max == 0 )
{
_PDCLIB_constraint_handler( _PDCLIB_CONSTRAINT_VIOLATION( _PDCLIB_EINVAL ) );
return NULL;
}
--( *s1max );
*( ( *ptr )++ ) = '\0';
return s1;
}
}
if ( *s1max == 0 )
{
_PDCLIB_constraint_handler( _PDCLIB_CONSTRAINT_VIOLATION( _PDCLIB_EINVAL ) );
return NULL;
}
--( *s1max );
++( *ptr );
}
/* parsed to end of string */
return s1;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#ifndef REGTEST
static int HANDLER_CALLS = 0;
static void test_handler( const char * _PDCLIB_restrict msg, void * _PDCLIB_restrict ptr, errno_t error )
{
++HANDLER_CALLS;
}
#endif
int main( void )
{
#ifndef REGTEST
/* The original PDCLib strtok() test */
char s[] = "_a_bc__d_";
rsize_t max = strlen( s );
char * p;
TESTCASE( _PDCLIB_strtok( s, &max, "_", &p ) == &s[1] );
TESTCASE( max == 6 );
TESTCASE( s[1] == 'a' );
TESTCASE( s[2] == '\0' );
TESTCASE( _PDCLIB_strtok( NULL, &max, "_", &p ) == &s[3] );
TESTCASE( max == 3 );
TESTCASE( s[3] == 'b' );
TESTCASE( s[4] == 'c' );
TESTCASE( s[5] == '\0' );
TESTCASE( _PDCLIB_strtok( NULL, &max, "_", &p ) == &s[7] );
TESTCASE( max == 0 );
TESTCASE( s[6] == '_' );
TESTCASE( s[7] == 'd' );
TESTCASE( s[8] == '\0' );
TESTCASE( _PDCLIB_strtok( NULL, &max, "_", &p ) == NULL );
TESTCASE( max == 0 );
strcpy( s, "ab_cd" );
max = strlen( s );
TESTCASE( _PDCLIB_strtok( s, &max, "_", &p ) == &s[0] );
TESTCASE( s[0] == 'a' );
TESTCASE( s[1] == 'b' );
TESTCASE( s[2] == '\0' );
TESTCASE( _PDCLIB_strtok( NULL, &max, "_", &p ) == &s[3] );
TESTCASE( s[3] == 'c' );
TESTCASE( s[4] == 'd' );
TESTCASE( s[5] == '\0' );
TESTCASE( _PDCLIB_strtok( NULL, &max, "_", &p ) == NULL );
/* Testing the constraint handling */
strcpy( s, "ab.cd" );
max = 2;
TESTCASE( set_constraint_handler_s( test_handler ) == abort_handler_s );
TESTCASE( _PDCLIB_strtok( s, &max, ".", &p ) == NULL );
TESTCASE( HANDLER_CALLS == 1 );
{
/* The strtok_s() example code from the standard */
char str1[] = "?a???b,,,#c";
char str2[] = "\t \t";
rsize_t max1 = strlen( str1 );
rsize_t max2 = strlen( str2 );
char * ptr1;
char * ptr2;
TESTCASE( _PDCLIB_strtok( str1, &max1, "?", &ptr1 ) == &str1[1] );
TESTCASE( _PDCLIB_strtok( NULL, &max1, ",", &ptr1 ) == &str1[3] );
TESTCASE( _PDCLIB_strtok( str2, &max2, " \t", &ptr2 ) == NULL );
TESTCASE( _PDCLIB_strtok( NULL, &max1, "#,", &ptr1 ) == &str1[10] );
TESTCASE( _PDCLIB_strtok( NULL, &max1, "?", &ptr1 ) == NULL );
}
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,99 +0,0 @@
/* _PDCLIB_strtox_main( const char **, int, _PDCLIB_uintmax_t, _PDCLIB_uintmax_t, int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <stdint.h>
#ifndef REGTEST
_PDCLIB_uintmax_t _PDCLIB_strtox_main( const char ** p, unsigned int base, uintmax_t error, uintmax_t limit, char * sign )
{
_PDCLIB_uintmax_t rc = 0;
int digit = -1;
const char * x;
_PDCLIB_uintmax_t limval = limit / base;
int limdigit = limit % base;
while ( ( x = (const char *)memchr( _PDCLIB_digits, tolower( (unsigned char)**p ), base ) ) != NULL )
{
digit = x - _PDCLIB_digits;
if ( ( rc < limval ) || ( ( rc == limval ) && ( digit <= limdigit ) ) )
{
rc = rc * base + ( unsigned )digit;
++( *p );
}
else
{
errno = ERANGE;
/* TODO: Only if endptr != NULL - but do we really want *another* parameter? */
/* TODO: Earlier version was missing tolower() here but was not caught by tests */
while ( memchr( _PDCLIB_digits, tolower( (unsigned char)**p ), base ) != NULL )
{
++( *p );
}
/* TODO: This is ugly, but keeps caller from negating the error value */
*sign = '+';
return error;
}
}
if ( digit == -1 )
{
*p = NULL;
return 0;
}
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <errno.h>
int main( void )
{
#ifndef REGTEST
const char * p;
char test[] = "123_";
char fail[] = "xxx";
char sign = '-';
/* basic functionality */
p = test;
errno = 0;
TESTCASE( _PDCLIB_strtox_main( &p, 10u, ( uintmax_t )999, ( uintmax_t )999, &sign ) == 123 );
TESTCASE( errno == 0 );
TESTCASE( p == &test[3] );
/* proper functioning to smaller base */
p = test;
TESTCASE( _PDCLIB_strtox_main( &p, 8u, ( uintmax_t )999, ( uintmax_t )999, &sign ) == 0123 );
TESTCASE( errno == 0 );
TESTCASE( p == &test[3] );
/* overflowing subject sequence must still return proper endptr */
p = test;
TESTCASE( _PDCLIB_strtox_main( &p, 4u, ( uintmax_t )999, ( uintmax_t )6, &sign ) == 999 );
TESTCASE( errno == ERANGE );
TESTCASE( p == &test[3] );
TESTCASE( sign == '+' );
/* testing conversion failure */
errno = 0;
p = fail;
sign = '-';
TESTCASE( _PDCLIB_strtox_main( &p, 10u, ( uintmax_t )999, ( uintmax_t )999, &sign ) == 0 );
TESTCASE( p == NULL );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,113 +0,0 @@
/* _PDCLIB_strtox_prelim( const char *, char *, int * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#include <stddef.h>
#include <string.h>
#ifndef REGTEST
const char * _PDCLIB_strtox_prelim( const char * p, char * sign, int * base )
{
/* skipping leading whitespace */
while ( isspace( (unsigned char)*p ) )
{
++p;
}
/* determining / skipping sign */
if ( *p != '+' && *p != '-' )
{
*sign = '+';
}
else
{
*sign = *( p++ );
}
/* determining base */
if ( *p == '0' )
{
++p;
if ( ( *base == 0 || *base == 16 ) && ( *p == 'x' || *p == 'X' ) )
{
*base = 16;
++p;
/* catching a border case here: "0x" followed by a non-digit should
be parsed as the unprefixed zero.
We have to "rewind" the parsing; having the base set to 16 if it
was zero previously does not hurt, as the result is zero anyway.
*/
if ( memchr( _PDCLIB_digits, tolower( (unsigned char)*p ), *base ) == NULL )
{
p -= 2;
}
}
else if ( *base == 0 )
{
*base = 8;
/* back up one digit, so that a plain zero is decoded correctly
(and endptr is set correctly as well).
(2019-01-15, Giovanni Mascellani)
*/
--p;
}
else
{
--p;
}
}
else if ( ! *base )
{
*base = 10;
}
return ( ( *base >= 2 ) && ( *base <= 36 ) ) ? p : NULL;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
int base = 0;
char sign = '\0';
char test1[] = " 123";
char test2[] = "\t+0123";
char test3[] = "\v-0x123";
TESTCASE( _PDCLIB_strtox_prelim( test1, &sign, &base ) == &test1[2] );
TESTCASE( sign == '+' );
TESTCASE( base == 10 );
base = 0;
sign = '\0';
TESTCASE( _PDCLIB_strtox_prelim( test2, &sign, &base ) == &test2[2] );
TESTCASE( sign == '+' );
TESTCASE( base == 8 );
base = 0;
sign = '\0';
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == &test3[4] );
TESTCASE( sign == '-' );
TESTCASE( base == 16 );
base = 10;
sign = '\0';
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == &test3[2] );
TESTCASE( sign == '-' );
TESTCASE( base == 10 );
base = 1;
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == NULL );
base = 37;
TESTCASE( _PDCLIB_strtox_prelim( test3, &sign, &base ) == NULL );
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,73 +0,0 @@
/* _PDCLIB_assert( const char * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#ifndef REGTEST
void _PDCLIB_assert99( const char * const message1, const char * const function, const char * const message2 )
{
fputs( message1, stderr );
fputs( function, stderr );
fputs( message2, stderr );
abort();
}
void _PDCLIB_assert89( const char * const message )
{
fputs( message, stderr );
abort();
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <signal.h>
static int EXPECTED_ABORT = 0;
static int UNEXPECTED_ABORT = 1;
static void aborthandler( int sig )
{
TESTCASE( ! EXPECTED_ABORT );
exit( ( signed int )TEST_RESULTS );
}
#ifdef NDEBUG
#error Compiling test drivers with NDEBUG set is a questionable choice...
#endif
#define NDEBUG
#include <assert.h>
static int disabled_test( void )
{
int i = 0;
assert( i == 0 ); /* NDEBUG set, condition met */
assert( i == 1 ); /* NDEBUG set, condition fails */
return i;
}
#undef NDEBUG
#include <assert.h>
int main( void )
{
TESTCASE( signal( SIGABRT, &aborthandler ) != SIG_ERR );
TESTCASE( disabled_test() == 0 );
assert( UNEXPECTED_ABORT ); /* NDEBUG not set, condition met */
assert( EXPECTED_ABORT ); /* NDEBUG not set, condition fails - should abort */
return TEST_RESULTS;
}
#endif

View File

@@ -1,71 +0,0 @@
/* _PDCLIB_errno
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_internal.h"
#if __STDC_VERSION__ >= 201112L && ! defined( __STDC_NO_THREADS__ )
_Thread_local int _PDCLIB_errno = 0;
#else
static int _PDCLIB_errno = 0;
#endif
int * _PDCLIB_errno_func()
{
return &_PDCLIB_errno;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <errno.h>
#if ! defined( REGTEST ) && __STDC_VERSION__ >= 201112L && ! defined( __STDC_NO_THREADS__ )
#include <threads.h>
static int thread_func( void * arg )
{
TESTCASE( errno == 0 );
*_PDCLIB_errno_func() = 1;
TESTCASE( errno == 1 );
thrd_exit( 0 );
}
#endif
int main( void )
{
errno = 0;
TESTCASE( errno == 0 );
errno = EDOM;
TESTCASE( errno == EDOM );
errno = ERANGE;
TESTCASE( errno == ERANGE );
#if ! defined( REGTEST ) && __STDC_VERSION__ >= 201112L && ! defined( __STDC_NO_THREADS__ )
{
thrd_t t;
struct timespec spec = { 1, 0 };
int rc;
TESTCASE( thrd_create( &t, thread_func, NULL ) == thrd_success );
TESTCASE( thrd_sleep( &spec, NULL ) == 0 );
TESTCASE( errno == ERANGE );
TESTCASE( thrd_join( t, &rc ) == thrd_success );
TESTCASE( rc == 0 );
}
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,120 +0,0 @@
/* stdarg
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <stdarg.h>
#include <limits.h>
#include <float.h>
#ifdef TEST
#include "_PDCLIB_test.h"
typedef int ( *intfunc_t )( void );
#define TAG_END 0
#define TAG_INT 1
#define TAG_LONG 2
#define TAG_LLONG 3
#define TAG_DBL 4
#define TAG_LDBL 5
#define TAG_INTPTR 6
#define TAG_LDBLPTR 7
#define TAG_FUNCPTR 8
static int dummy( void )
{
return INT_MAX;
}
static int test( int s, ... )
{
va_list ap;
va_start( ap, s );
for ( ;; )
{
switch ( s )
{
case TAG_INT:
{
TESTCASE( va_arg( ap, int ) == INT_MAX );
s = va_arg( ap, int );
break;
}
case TAG_LONG:
{
TESTCASE( va_arg( ap, long ) == LONG_MAX );
s = va_arg( ap, int );
break;
}
case TAG_LLONG:
{
TESTCASE( va_arg( ap, long long ) == LLONG_MAX );
s = va_arg( ap, int );
break;
}
case TAG_DBL:
{
TESTCASE( va_arg( ap, double ) == DBL_MAX );
s = va_arg( ap, int );
break;
}
case TAG_LDBL:
{
TESTCASE( va_arg( ap, long double ) == LDBL_MAX );
s = va_arg( ap, int );
break;
}
case TAG_INTPTR:
{
TESTCASE( *( va_arg( ap, int * ) ) == INT_MAX );
s = va_arg( ap, int );
break;
}
case TAG_LDBLPTR:
{
TESTCASE( *( va_arg( ap, long double * ) ) == LDBL_MAX );
s = va_arg( ap, int );
break;
}
case TAG_FUNCPTR:
{
intfunc_t function;
TESTCASE( ( function = va_arg( ap, intfunc_t ) ) == dummy );
TESTCASE( function() == INT_MAX );
s = va_arg( ap, int );
break;
}
case TAG_END:
{
va_end( ap );
return 0;
}
}
}
}
int main( void )
{
int x = INT_MAX;
long double d = LDBL_MAX;
test( TAG_END );
test( TAG_INT, INT_MAX, TAG_END );
test( TAG_LONG, LONG_MAX, TAG_LLONG, LLONG_MAX, TAG_END );
test( TAG_DBL, DBL_MAX, TAG_LDBL, LDBL_MAX, TAG_END );
test( TAG_INTPTR, &x, TAG_LDBLPTR, &d, TAG_FUNCPTR, dummy, TAG_END );
return TEST_RESULTS;
}
#endif

View File

@@ -1,154 +0,0 @@
--- malloc-2.8.6.c 2024-05-01 19:50:19.477383272 +0200
+++ malloc.c 2024-05-02 21:47:51.377419724 +0200
@@ -1,3 +1,63 @@
+/* malloc( size_t )
+ calloc( size_t, size_t )
+ realloc( void *, size_t )
+ aligned_alloc( size_t, size_t )
+ free( void * )
+
+ This file is part of the Public Domain C Library (PDCLib).
+ Permission is granted to use, modify, and / or redistribute at will.
+
+ It is a slightly modified copy of Doug Lea's malloc(), retrieved from
+ ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+ at version 2.8.6, which is released under CC0 license just as PDCLib.
+*/
+
+/* Declared implicitly by dlmalloc. This declaration avoids the warning. */
+#include <stdint.h>
+void * sbrk( intptr_t );
+
+#ifndef REGTEST
+
+#include "pdclib/_PDCLIB_config.h"
+#include "pdclib/_PDCLIB_defguard.h"
+
+/* Have all functions herein use the dl* prefix */
+#define USE_DL_PREFIX 1
+
+/* Thread safety */
+#define USE_LOCKS 1
+
+/* Hide all functions herein as internal to the library */
+#define DLMALLOC_EXPORT _PDCLIB_LOCAL
+
+/* Unhide the standard functions. (Their declarations with the
+ DLMALLOC_EXPORT modifier below has been commented out; they
+ are declared _PDCLIB_PUBLIC in <stdlib.h>, marking them
+ exported from the library.)
+*/
+#define dlmalloc malloc
+#define dlcalloc calloc
+#define dlrealloc realloc
+#define dlfree free
+#if __STDC_VERSION__ >= 201112L
+#define dlmemalign aligned_alloc
+#endif
+
+#endif
+
+#ifdef TEST
+
+#include "_PDCLIB_test.h"
+
+int main( void )
+{
+ TESTCASE( NO_TESTDRIVER );
+ return TEST_RESULTS;
+}
+
+#endif
+
+/* ------------------------------------------------------------------- */
/*
This is a version (aka dlmalloc) of malloc/free/realloc written by
Doug Lea and released to the public domain, as explained at
@@ -585,8 +645,15 @@
#define MAX_SIZE_T (~(size_t)0)
#ifndef USE_LOCKS /* ensure true if spin or recursive locks set */
-#define USE_LOCKS ((defined(USE_SPIN_LOCKS) && USE_SPIN_LOCKS != 0) || \
- (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0))
+/* defined() in the expansion of a macro is non-portable behavior
+ and runs afoul of -Wextra.
+*/
+#if ((defined(USE_SPIN_LOCKS) && USE_SPIN_LOCKS != 0) || \
+ (defined(USE_RECURSIVE_LOCKS) && USE_RECURSIVE_LOCKS != 0))
+#define USE_LOCKS 1
+#else
+#define USE_LOCKS 0
+#endif
#endif /* USE_LOCKS */
#if USE_LOCKS /* Spin locks for gcc >= 4.1, older gcc on x86, MSC >= 1310 */
@@ -851,7 +918,7 @@
maximum supported value of n differs across systems, but is in all
cases less than the maximum representable value of a size_t.
*/
-DLMALLOC_EXPORT void* dlmalloc(size_t);
+/*DLMALLOC_EXPORT void* dlmalloc(size_t);*/
/*
free(void* p)
@@ -860,14 +927,14 @@
It has no effect if p is null. If p was not malloced or already
freed, free(p) will by default cause the current program to abort.
*/
-DLMALLOC_EXPORT void dlfree(void*);
+/*DLMALLOC_EXPORT void dlfree(void*);*/
/*
calloc(size_t n_elements, size_t element_size);
Returns a pointer to n_elements * element_size bytes, with all locations
set to zero.
*/
-DLMALLOC_EXPORT void* dlcalloc(size_t, size_t);
+/*DLMALLOC_EXPORT void* dlcalloc(size_t, size_t);*/
/*
realloc(void* p, size_t n)
@@ -891,7 +958,7 @@
The old unix realloc convention of allowing the last-free'd chunk
to be used as an argument to realloc is not supported.
*/
-DLMALLOC_EXPORT void* dlrealloc(void*, size_t);
+/*DLMALLOC_EXPORT void* dlrealloc(void*, size_t);*/
/*
realloc_in_place(void* p, size_t n)
@@ -996,7 +1063,7 @@
guarantee that this number of bytes can actually be obtained from
the system.
*/
-DLMALLOC_EXPORT size_t dlmalloc_footprint_limit();
+DLMALLOC_EXPORT size_t dlmalloc_footprint_limit(void);
/*
malloc_set_footprint_limit();
@@ -1256,8 +1323,8 @@
p = malloc(n);
assert(malloc_usable_size(p) >= 256);
-*/
size_t dlmalloc_usable_size(void*);
+*/
#endif /* ONLY_MSPACES */
@@ -5376,6 +5443,7 @@
return change_mparam(param_number, value);
}
+/*
size_t dlmalloc_usable_size(void* mem) {
if (mem != 0) {
mchunkptr p = mem2chunk(mem);
@@ -5384,6 +5452,7 @@
}
return 0;
}
+*/
#endif /* !ONLY_MSPACES */

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +0,0 @@
Major parts of PDCLib's <time.h> implementation are based on IANA's reference
implementation, tzcode.
https://data.iana.org/time-zones/tz-link.html
The latest version of tzcode can be downloaded at:
https://www.iana.org/time-zones/repository/tzcode-latest.tar.gz
At the time of this writing, the latest tzcode version used as basis is 2020a.

View File

@@ -1,53 +0,0 @@
/* _PDCLIB_gmtcheck( void )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_tzcode.h"
#ifndef __STDC_NO_THREADS__
#include <threads.h>
extern mtx_t _PDCLIB_time_mtx;
#endif
static void gmtload( struct state * sp )
{
if ( _PDCLIB_tzload( gmt, sp, true ) != 0 )
{
_PDCLIB_tzparse( gmt, sp, true );
}
}
void _PDCLIB_gmtcheck( void )
{
static bool gmt_is_set;
_PDCLIB_LOCK( _PDCLIB_time_mtx );
if ( ! gmt_is_set )
{
gmtload( &_PDCLIB_gmtmem );
gmt_is_set = true;
}
_PDCLIB_UNLOCK( _PDCLIB_time_mtx );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,43 +0,0 @@
/* _PDCLIB_gmtsub( struct state const *, time_t const *, int_fast32_t, struct tm * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_tzcode.h"
/* gmtsub is to gmtime as localsub is to localtime. */
struct tm * _PDCLIB_gmtsub( struct state const * sp, time_t const * timep, int_fast32_t offset, struct tm * tmp )
{
struct tm * result;
result = _PDCLIB_timesub( timep, offset, &_PDCLIB_gmtmem, tmp );
#ifdef TM_ZONE
/* Could get fancy here and deliver something such as
"+xx" or "-xx" if offset is non-zero,
but this is no time for a treasure hunt.
*/
tmp->TM_ZONE = ( (char *)( offset ? wildabbr : &_PDCLIB_gmtmem ? _PDCLIB_gmtptr.chars : gmt ) );
#endif
return result;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,45 +0,0 @@
/* _PDCLIB_increment_overflow( int *, int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_tzcode.h"
/* Normalize logic courtesy Paul Eggert. */
bool _PDCLIB_increment_overflow( int * ip, int j )
{
int const i = *ip;
/* If i >= 0 there can only be overflow if i + j > INT_MAX
or if j > INT_MAX - i; given i >= 0, INT_MAX - i cannot overflow.
If i < 0 there can only be overflow if i + j < INT_MIN
or if j < INT_MIN - i; given i < 0, INT_MIN - i cannot overflow.
*/
if ( ( i >= 0 ) ? ( j > _PDCLIB_INT_MAX - i ) : ( j < _PDCLIB_INT_MIN - i ) )
{
return true;
}
*ip += j;
return false;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,35 +0,0 @@
/* _PDCLIB_init_ttinfo( struct ttinfo *, int_fast32_t, bool, int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_tzcode.h"
/* Initialize *S to a value based on UTOFF, ISDST, and DESIGIDX. */
void _PDCLIB_init_ttinfo( struct ttinfo * s, int_fast32_t utoff, bool isdst, int desigidx )
{
s->utoff = utoff;
s->isdst = isdst;
s->desigidx = desigidx;
s->ttisstd = false;
s->ttisut = false;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,164 +0,0 @@
/* _PDCLIB_localsub( struct state const *, time_t const *, int_fast32_t, struct tm * const )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_tzcode.h"
/* The easy way to behave "as if no library function calls" localtime
is to not call it, so we drop its guts into "localsub", which can be
freely called. (And no, the PANS doesn't require the above behavior,
but it *is* desirable.)
If successful and SETNAME is nonzero,
set the applicable parts of tzname, timezone and altzone;
however, it's OK to omit this step if the timezone is POSIX-compatible,
since in that case tzset should have already done this step correctly.
SETNAME's type is intfast32_t for compatibility with gmtsub,
but it is actually a boolean and its value should be 0 or 1.
*/
/*ARGSUSED*/
struct tm * _PDCLIB_localsub( struct state const * sp, time_t const * timep, int_fast32_t setname, struct tm * const tmp )
{
const struct ttinfo * ttisp;
int i;
struct tm * result;
const time_t t = *timep;
if ( sp == NULL )
{
/* Don't bother to set tzname etc.; tzset has already done it. */
return _PDCLIB_gmtsub( &_PDCLIB_gmtmem, timep, 0, tmp );
}
if ( ( sp->goback && t < sp->ats[ 0 ] ) || ( sp->goahead && t > sp->ats[ sp->timecnt - 1 ] ) )
{
time_t newt = t;
time_t seconds;
time_t years;
if ( t < sp->ats[ 0 ] )
{
seconds = sp->ats[ 0 ] - t;
}
else
{
seconds = t - sp->ats[ sp->timecnt - 1 ];
}
--seconds;
years = ( seconds / SECSPERREPEAT + 1 ) * YEARSPERREPEAT;
seconds = years * AVGSECSPERYEAR;
if ( t < sp->ats[ 0 ] )
{
newt += seconds;
}
else
{
newt -= seconds;
}
if ( newt < sp->ats[ 0 ] || newt > sp->ats[ sp->timecnt - 1 ] )
{
return NULL; /* "cannot happen" */
}
result = _PDCLIB_localsub( sp, &newt, setname, tmp );
if ( result )
{
int_fast64_t newy;
newy = result->tm_year;
if ( t < sp->ats[ 0 ] )
{
newy -= years;
}
else
{
newy += years;
}
if ( ! ( _PDCLIB_INT_MIN <= newy && newy <= _PDCLIB_INT_MAX ) )
{
return NULL;
}
result->tm_year = newy;
}
return result;
}
if ( sp->timecnt == 0 || t < sp->ats[ 0 ] )
{
i = sp->defaulttype;
}
else
{
int lo = 1;
int hi = sp->timecnt;
while ( lo < hi )
{
int mid = ( lo + hi ) >> 1;
if ( t < sp->ats[ mid ] )
{
hi = mid;
}
else
{
lo = mid + 1;
}
}
i = (int) sp->types[ lo - 1 ];
}
ttisp = &sp->ttis[ i ];
/* To get (wrong) behavior that's compatible with System V Release 2.0
you'd replace the statement below with
t += ttisp->utoff;
timesub( &t, 0L, sp, tmp );
*/
result = _PDCLIB_timesub( &t, ttisp->utoff, sp, tmp );
if ( result )
{
result->tm_isdst = ttisp->isdst;
#ifdef TM_ZONE
result->TM_ZONE = (char *) &sp->chars[ ttisp->desigidx ];
#endif /* defined TM_ZONE */
if ( setname )
{
_PDCLIB_update_tzname_etc( sp, ttisp );
}
}
return result;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,46 +0,0 @@
/* _PDCLIB_localtime_tzset( time_t const *, struct tm *, bool )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_tzcode.h"
#ifndef __STDC_NO_THREADS__
#include <threads.h>
extern mtx_t _PDCLIB_time_mtx;
#endif
#include <string.h>
struct tm * _PDCLIB_localtime_tzset( time_t const * timep, struct tm * tmp, bool setname )
{
_PDCLIB_LOCK( _PDCLIB_time_mtx );
if ( setname || ! lcl_is_set )
{
_PDCLIB_tzset_unlocked();
}
tmp = _PDCLIB_localsub( &_PDCLIB_lclmem, timep, setname, tmp );
_PDCLIB_UNLOCK( _PDCLIB_time_mtx );
return tmp;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,528 +0,0 @@
/* _PDCLIB_mktime_tzname( struct state *, struct tm *, bool )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_tzcode.h"
/* Adapted from code provided by Robert Elz, who writes:
The "best" way to do mktime I think is based on an idea of Bob
Kridle's (so its said...) from a long time ago.
It does a binary search of the time_t space. Since time_t's are
just 32 bits, its a max of 32 iterations (even at 64 bits it
would still be very reasonable).
*/
#ifndef WRONG
#define WRONG (-1)
#endif
/* Normalize logic courtesy Paul Eggert. */
static bool increment_overflow32( int_fast32_t * lp, int m )
{
int_fast32_t const l = *lp;
if ( ( l >= 0 ) ? ( m > _PDCLIB_INT_FAST32_MAX - l ) : ( m < _PDCLIB_INT_FAST32_MIN - l ) )
{
return true;
}
*lp += m;
return false;
}
static bool normalize_overflow( int * tensptr, int * unitsptr, int base )
{
int tensdelta;
tensdelta = ( *unitsptr >= 0 ) ?
( *unitsptr / base ) :
( -1 - ( -1 - *unitsptr ) / base );
*unitsptr -= tensdelta * base;
return _PDCLIB_increment_overflow( tensptr, tensdelta );
}
static bool normalize_overflow32( int_fast32_t * tensptr, int * unitsptr, int base )
{
int tensdelta;
tensdelta = ( *unitsptr >= 0 ) ?
( *unitsptr / base ) :
( -1 - ( -1 - *unitsptr ) / base );
*unitsptr -= tensdelta * base;
return increment_overflow32( tensptr, tensdelta );
}
static int tmcomp( const struct tm * atmp, const struct tm * btmp )
{
int result;
if ( atmp->tm_year != btmp->tm_year )
{
return atmp->tm_year < btmp->tm_year ? -1 : 1;
}
if ( ( result = ( atmp->tm_mon - btmp->tm_mon ) ) == 0 &&
( result = ( atmp->tm_mday - btmp->tm_mday ) ) == 0 &&
( result = ( atmp->tm_hour - btmp->tm_hour ) ) == 0 &&
( result = ( atmp->tm_min - btmp->tm_min ) ) == 0 )
{
result = atmp->tm_sec - btmp->tm_sec;
}
return result;
}
static time_t time2sub( struct tm * tmp, struct tm *(*funcp)( struct state const *, time_t const *, int_fast32_t, struct tm * ), struct state const * sp, const int_fast32_t offset, bool * okayp, bool do_norm_secs )
{
int dir;
int i, j;
int saved_seconds;
int_fast32_t li;
time_t lo;
time_t hi;
int_fast32_t y;
time_t newt;
time_t t;
struct tm yourtm, mytm;
*okayp = false;
yourtm = *tmp;
if ( do_norm_secs )
{
if ( normalize_overflow( &yourtm.tm_min, &yourtm.tm_sec, SECSPERMIN ) )
{
return WRONG;
}
}
if ( normalize_overflow( &yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR ) )
{
return WRONG;
}
if ( normalize_overflow( &yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY ) )
{
return WRONG;
}
y = yourtm.tm_year;
if ( normalize_overflow32( &y, &yourtm.tm_mon, MONSPERYEAR ) )
{
return WRONG;
}
/* Turn y into an actual year number for now.
It is converted back to an offset from TM_YEAR_BASE later.
*/
if ( increment_overflow32( &y, TM_YEAR_BASE ) )
{
return WRONG;
}
while ( yourtm.tm_mday <= 0 )
{
if ( increment_overflow32( &y, -1 ) )
{
return WRONG;
}
li = y + ( 1 < yourtm.tm_mon );
yourtm.tm_mday += year_lengths[ _PDCLIB_is_leap( li ) ];
}
while ( yourtm.tm_mday > DAYSPERLYEAR )
{
li = y + ( 1 < yourtm.tm_mon );
yourtm.tm_mday -= year_lengths[ _PDCLIB_is_leap( li ) ];
if ( increment_overflow32( &y, 1 ) )
{
return WRONG;
}
}
for ( ; ; )
{
i = mon_lengths[ _PDCLIB_is_leap( y ) ][ yourtm.tm_mon ];
if ( yourtm.tm_mday <= i )
{
break;
}
yourtm.tm_mday -= i;
if ( ++yourtm.tm_mon >= MONSPERYEAR )
{
yourtm.tm_mon = 0;
if ( increment_overflow32( &y, 1 ) )
{
return WRONG;
}
}
}
if ( increment_overflow32( &y, -TM_YEAR_BASE ) )
{
return WRONG;
}
if ( ! ( _PDCLIB_INT_MIN <= y && y <= _PDCLIB_INT_MAX ) )
{
return WRONG;
}
yourtm.tm_year = y;
if ( yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN )
{
saved_seconds = 0;
}
else if ( y + TM_YEAR_BASE < EPOCH_YEAR )
{
/* We can't set tm_sec to 0, because that might push the
time below the minimum representable time.
Set tm_sec to 59 instead.
This assumes that the minimum representable time is
not in the same minute that a leap second was deleted from,
which is a safer assumption than using 58 would be.
*/
if ( _PDCLIB_increment_overflow( &yourtm.tm_sec, 1 - SECSPERMIN ) )
{
return WRONG;
}
saved_seconds = yourtm.tm_sec;
yourtm.tm_sec = SECSPERMIN - 1;
}
else
{
saved_seconds = yourtm.tm_sec;
yourtm.tm_sec = 0;
}
/* Do a binary search (this works whatever time_t's type is). */
lo = _PDCLIB_TIME_MIN;
hi = _PDCLIB_TIME_MAX;
for ( ; ; )
{
t = lo / 2 + hi / 2;
if ( t < lo )
{
t = lo;
}
else if ( t > hi )
{
t = hi;
}
if ( ! funcp( sp, &t, offset, &mytm ) )
{
/* Assume that t is too extreme to be represented in
a struct tm; arrange things so that it is less
extreme on the next pass.
*/
dir = ( t > 0 ) ? 1 : -1;
}
else
{
dir = tmcomp( &mytm, &yourtm );
}
if ( dir != 0 )
{
if ( t == lo )
{
if ( t == _PDCLIB_TIME_MAX )
{
return WRONG;
}
++t;
++lo;
}
else if ( t == hi )
{
if ( t == _PDCLIB_TIME_MIN )
{
return WRONG;
}
--t;
--hi;
}
if ( lo > hi )
{
return WRONG;
}
if ( dir > 0 )
{
hi = t;
}
else
{
lo = t;
}
continue;
}
#if defined TM_GMTOFF && ! UNINIT_TRAP
if ( mytm.TM_GMTOFF != yourtm.TM_GMTOFF
&& ( yourtm.TM_GMTOFF < 0
? ( -SECSPERDAY <= yourtm.TM_GMTOFF
&& ( mytm.TM_GMTOFF <=
( SMALLEST ( _PDCLIB_INT_FAST32_MAX, _PDCLIB_LONG_MAX )
+ yourtm.TM_GMTOFF ) ) )
: ( yourtm.TM_GMTOFF <= SECSPERDAY
&& ( ( BIGGEST ( _PDCLIB_INT_FAST32_MIN, _PDCLIB_LONG_MIN )
+ yourtm.TM_GMTOFF )
<= mytm.TM_GMTOFF ) ) ) )
{
/* MYTM matches YOURTM except with the wrong UT offset.
YOURTM.TM_GMTOFF is plausible, so try it instead.
It's OK if YOURTM.TM_GMTOFF contains uninitialized data,
since the guess gets checked.
*/
time_t altt = t;
int_fast32_t diff = mytm.TM_GMTOFF - yourtm.TM_GMTOFF;
if ( ! increment_overflow_time( &altt, diff ) )
{
struct tm alttm;
if ( funcp( sp, &altt, offset, &alttm )
&& alttm.tm_isdst == mytm.tm_isdst
&& alttm.TM_GMTOFF == yourtm.TM_GMTOFF
&& tmcomp( &alttm, &yourtm ) == 0 )
{
t = altt;
mytm = alttm;
}
}
}
#endif
if ( yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst )
{
break;
}
/* Right time, wrong type.
Hunt for right time, right type.
It's okay to guess wrong since the guess
gets checked.
*/
if ( sp == NULL )
{
return WRONG;
}
for ( i = sp->typecnt - 1; i >= 0; --i )
{
if ( sp->ttis[ i ].isdst != yourtm.tm_isdst )
{
continue;
}
for ( j = sp->typecnt - 1; j >= 0; --j )
{
if ( sp->ttis[ j ].isdst == yourtm.tm_isdst )
{
continue;
}
newt = ( t + sp->ttis[ j ].utoff - sp->ttis[ i ].utoff );
if ( ! funcp( sp, &newt, offset, &mytm ) )
{
continue;
}
if ( tmcomp( &mytm, &yourtm ) != 0 )
{
continue;
}
if ( mytm.tm_isdst != yourtm.tm_isdst )
{
continue;
}
/* We have a match. */
t = newt;
goto label;
}
}
return WRONG;
}
label:
newt = t + saved_seconds;
if ( ( newt < t ) != ( saved_seconds < 0 ) )
{
return WRONG;
}
t = newt;
if ( funcp( sp, &t, offset, tmp ) )
{
*okayp = true;
}
return t;
}
static time_t time2( struct tm * tmp, struct tm *(*funcp)( struct state const *, time_t const *, int_fast32_t, struct tm * ), struct state const * sp, const int_fast32_t offset, bool * okayp )
{
time_t t;
/* First try without normalization of seconds
(in case tm_sec contains a value associated with a leap second).
If that fails, try with normalization of seconds.
*/
t = time2sub( tmp, funcp, sp, offset, okayp, false );
return *okayp ? t : time2sub( tmp, funcp, sp, offset, okayp, true );
}
static time_t time1( struct tm * tmp, struct tm *(*funcp)( struct state const *, time_t const *, int_fast32_t, struct tm * ), struct state const * sp, const int_fast32_t offset )
{
time_t t;
int samei, otheri;
int sameind, otherind;
int i;
int nseen;
char seen[TZ_MAX_TYPES];
unsigned char types[TZ_MAX_TYPES];
bool okay;
if ( tmp == NULL )
{
*_PDCLIB_errno_func() = _PDCLIB_EINVAL;
return WRONG;
}
if ( tmp->tm_isdst > 1 )
{
tmp->tm_isdst = 1;
}
t = time2( tmp, funcp, sp, offset, &okay );
if ( okay )
{
return t;
}
if ( tmp->tm_isdst < 0 )
{
#ifdef PCTS
/* POSIX Conformance Test Suite code courtesy Grant Sullivan. */
tmp->tm_isdst = 0; /* reset to std and try again */
#else
return t;
#endif
}
/* We're supposed to assume that somebody took a time of one type
and did some math on it that yielded a "struct tm" that's bad.
We try to divine the type they started from and adjust to the
type they need.
*/
if ( sp == NULL )
{
return WRONG;
}
for ( i = 0; i < sp->typecnt; ++i )
{
seen[ i ] = false;
}
nseen = 0;
for ( i = sp->timecnt - 1; i >= 0; --i )
{
if ( ! seen[ sp->types[ i ] ] )
{
seen[ sp->types[ i ] ] = true;
types[ nseen++ ] = sp->types[ i ];
}
}
for ( sameind = 0; sameind < nseen; ++sameind )
{
samei = types[ sameind ];
if ( sp->ttis[ samei ].isdst != tmp->tm_isdst )
{
continue;
}
for ( otherind = 0; otherind < nseen; ++otherind )
{
otheri = types[ otherind ];
if ( sp->ttis[ otheri ].isdst == tmp->tm_isdst )
{
continue;
}
tmp->tm_sec += ( sp->ttis[ otheri ].utoff - sp->ttis[ samei ].utoff );
tmp->tm_isdst = ! tmp->tm_isdst;
t = time2( tmp, funcp, sp, offset, &okay );
if ( okay )
{
return t;
}
tmp->tm_sec -= ( sp->ttis[ otheri ].utoff - sp->ttis[ samei ].utoff );
tmp->tm_isdst = ! tmp->tm_isdst;
}
}
return WRONG;
}
time_t _PDCLIB_mktime_tzname( struct state * sp, struct tm * tmp, bool setname )
{
if ( sp )
{
return time1( tmp, _PDCLIB_localsub, sp, setname );
}
else
{
_PDCLIB_gmtcheck();
return time1( tmp, _PDCLIB_gmtsub, &_PDCLIB_gmtmem, 0 );
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,190 +0,0 @@
/* _PDCLIB_timesub( const time_t *, int_fast32_t, const struct state *, struct tm * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_tzcode.h"
/* Return the number of leap years through the end of the given year
where, to make the math easy, the answer for year zero is defined as zero.
*/
static int leaps_thru_end_of_nonneg( int y )
{
return y / 4 - y / 100 + y / 400;
}
static int leaps_thru_end_of( const int y )
{
return ( y < 0
? -1 - leaps_thru_end_of_nonneg( -1 - y )
: leaps_thru_end_of_nonneg( y ) );
}
struct tm * _PDCLIB_timesub( const time_t * timep, int_fast32_t offset, const struct state * sp, struct tm * tmp )
{
const struct lsinfo * lp;
time_t tdays;
int idays; /* unsigned would be so 2003 */
int_fast64_t rem;
int y;
const int * ip;
int_fast64_t corr;
bool hit;
int i;
corr = 0;
hit = false;
i = ( sp == NULL ) ? 0 : sp->leapcnt;
while ( --i >= 0 )
{
lp = &sp->lsis[ i ];
if ( *timep >= lp->trans )
{
corr = lp->corr;
hit = ( *timep == lp->trans && ( i == 0 ? 0 : lp[ -1 ].corr ) < corr );
break;
}
}
y = EPOCH_YEAR;
tdays = *timep / SECSPERDAY;
rem = *timep % SECSPERDAY;
while ( tdays < 0 || tdays >= year_lengths[ _PDCLIB_is_leap( y ) ] )
{
int newy;
time_t tdelta;
int idelta;
int leapdays;
tdelta = tdays / DAYSPERLYEAR;
if ( ! ( ( ! _PDCLIB_TYPE_SIGNED( time_t ) || _PDCLIB_INT_MIN <= tdelta ) && tdelta <= _PDCLIB_INT_MAX ) )
{
goto out_of_range;
}
idelta = tdelta;
if ( idelta == 0 )
{
idelta = ( tdays < 0 ) ? -1 : 1;
}
newy = y;
if ( _PDCLIB_increment_overflow( &newy, idelta ) )
{
goto out_of_range;
}
leapdays = leaps_thru_end_of( newy - 1 ) - leaps_thru_end_of( y - 1 );
tdays -= ( (time_t)newy - y ) * DAYSPERNYEAR;
tdays -= leapdays;
y = newy;
}
/* Given the range, we can now fearlessly cast... */
idays = tdays;
rem += offset - corr;
while ( rem < 0 )
{
rem += SECSPERDAY;
--idays;
}
while ( rem >= SECSPERDAY )
{
rem -= SECSPERDAY;
++idays;
}
while ( idays < 0 )
{
if ( _PDCLIB_increment_overflow( &y, -1 ) )
{
goto out_of_range;
}
idays += year_lengths[ _PDCLIB_is_leap( y ) ];
}
while ( idays >= year_lengths[ _PDCLIB_is_leap( y ) ] )
{
idays -= year_lengths[ _PDCLIB_is_leap( y ) ];
if ( _PDCLIB_increment_overflow( &y, 1 ) )
{
goto out_of_range;
}
}
tmp->tm_year = y;
if ( _PDCLIB_increment_overflow( &tmp->tm_year, -TM_YEAR_BASE ) )
{
goto out_of_range;
}
tmp->tm_yday = idays;
/* The "extra" mods below avoid overflow problems. */
tmp->tm_wday = EPOCH_WDAY +
( ( y - EPOCH_YEAR ) % DAYSPERWEEK ) *
( DAYSPERNYEAR % DAYSPERWEEK ) +
leaps_thru_end_of( y - 1 ) -
leaps_thru_end_of( EPOCH_YEAR - 1 ) +
idays;
tmp->tm_wday %= DAYSPERWEEK;
if ( tmp->tm_wday < 0 )
{
tmp->tm_wday += DAYSPERWEEK;
}
tmp->tm_hour = (int)( rem / SECSPERHOUR );
rem %= SECSPERHOUR;
tmp->tm_min = (int)( rem / SECSPERMIN );
/* A positive leap second requires a special
representation. This uses "... ??:59:60" et seq.
*/
tmp->tm_sec = (int) ( rem % SECSPERMIN ) + hit;
ip = mon_lengths[ _PDCLIB_is_leap( y ) ];
for ( tmp->tm_mon = 0; idays >= ip[ tmp->tm_mon ]; ++( tmp->tm_mon ) )
{
idays -= ip[ tmp->tm_mon ];
}
tmp->tm_mday = (int)( idays + 1 );
tmp->tm_isdst = 0;
#ifdef TM_GMTOFF
tmp->TM_GMTOFF = offset;
#endif /* defined TM_GMTOFF */
return tmp;
out_of_range:
*_PDCLIB_errno_func() = _PDCLIB_EOVERFLOW;
return NULL;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,683 +0,0 @@
/* _PDCLIB_tzload( char const *, struct _PDCLIB_timezone *, bool )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_tzcode.h"
#include <errno.h>
#include <stdio.h>
#include <string.h>
static int_fast32_t detzcode( const char * codep )
{
int_fast32_t result;
int i;
int_fast32_t one = 1;
int_fast32_t halfmaxval = one << ( 32 - 2 );
int_fast32_t maxval = halfmaxval - 1 + halfmaxval;
int_fast32_t minval = -1 - maxval;
result = codep[ 0 ] & 0x7f;
for ( i = 1; i < 4; ++i )
{
result = ( result << 8 ) | ( codep[ i ] & 0xff );
}
if ( codep[ 0 ] & 0x80 )
{
/* Do two's-complement negation even on non-two's-complement machines.
If the result would be minval - 1, return minval.
*/
result -= ! _PDCLIB_TWOS_COMPLEMENT && result != 0;
result += minval;
}
return result;
}
static int_fast64_t detzcode64( const char * codep )
{
uint_fast64_t result;
int i;
int_fast64_t one = 1;
int_fast64_t halfmaxval = one << ( 64 - 2 );
int_fast64_t maxval = halfmaxval - 1 + halfmaxval;
int_fast64_t minval = - _PDCLIB_TWOS_COMPLEMENT - maxval;
result = codep[ 0 ] & 0x7f;
for ( i = 1; i < 8; ++i )
{
result = ( result << 8 ) | ( codep[ i ] & 0xff );
}
if ( codep[ 0 ] & 0x80 )
{
/* Do two's-complement negation even on non-two's-complement machines.
If the result would be minval - 1, return minval.
*/
result -= ! _PDCLIB_TWOS_COMPLEMENT && result != 0;
result += minval;
}
return result;
}
static bool differ_by_repeat( const time_t t1, const time_t t0 )
{
if ( ( sizeof( time_t ) * _PDCLIB_CHAR_BIT ) - _PDCLIB_TYPE_SIGNED( time_t ) < SECSPERREPEAT_BITS )
{
return 0;
}
return ( t1 - t0 ) == SECSPERREPEAT;
}
static bool typesequiv( const struct state * sp, int a, int b )
{
bool result;
if ( sp == NULL ||
a < 0 || a >= sp->typecnt ||
b < 0 || b >= sp->typecnt )
{
result = false;
}
else
{
const struct ttinfo * ap = &sp->ttis[ a ];
const struct ttinfo * bp = &sp->ttis[ b ];
result = ( ap->utoff == bp->utoff &&
ap->isdst == bp->isdst &&
ap->ttisstd == bp->ttisstd &&
ap->ttisut == bp->ttisut &&
( strcmp( &sp->chars[ ap->desigidx ], &sp->chars[ bp->desigidx ] ) == 0 )
);
}
return result;
}
#define TZ_MAGIC "TZif"
struct tzhead
{
char tzh_magic[ 4 ]; /* TZ_MAGIC */
char tzh_version[ 1 ]; /* '\0' or '2' or '3' as of 2013 */
char tzh_reserved[ 15 ]; /* reserved; must be zero */
char tzh_ttisutcnt[ 4 ]; /* coded number of trans. time flags */
char tzh_ttisstdcnt[ 4 ]; /* coded number of trans. time flags */
char tzh_leapcnt[ 4 ]; /* coded number of leap seconds */
char tzh_timecnt[ 4 ]; /* coded number of transition times */
char tzh_typecnt[ 4 ]; /* coded number of local time types */
char tzh_charcnt[ 4 ]; /* coded number of abbr. chars */
};
/* Input buffer for data read from a compiled tz file. */
union input_buffer
{
/* The first part of the buffer, interpreted as a header. */
struct tzhead tzhead;
/* The entire buffer. */
char buf[ 2 * sizeof ( struct tzhead ) + 2 * sizeof ( struct state ) + 4 * TZ_MAX_TIMES ];
};
/* _PDCLIB_TZDIR with a trailing '/' rather than a trailing '\0'. */
static char const tzdirslash[ sizeof _PDCLIB_TZDIR + 1 ] = _PDCLIB_TZDIR "/";
/* Local storage needed for 'tzloadbody'. */
union local_storage
{
/* The results of analyzing the file's contents after it is opened. */
struct file_analysis
{
/* The input buffer. */
union input_buffer u;
/* A temporary state used for parsing a TZ string in the file. */
struct state st;
} u;
/* The file name to be opened. */
char fullname[ BIGGEST ( sizeof ( struct file_analysis ), sizeof tzdirslash + 1024 ) ];
};
static int_fast64_t leapcorr( struct state const * sp, time_t t )
{
struct lsinfo const * lp;
int i;
i = sp->leapcnt;
while ( --i >= 0 )
{
lp = &sp->lsis[ i ];
if ( t >= lp->trans )
{
return lp->corr;
}
}
return 0;
}
/* Load tz data from the file named NAME into *SP. Read extended
format if DOEXTEND. Use *LSP for temporary storage. Return 0 on
success, an errno value on failure. */
static int tzloadbody( char const * name, struct state * sp, bool doextend, union local_storage * lsp )
{
int i;
FILE * fid;
int stored;
size_t nread;
bool doaccess;
union input_buffer * up = &lsp->u.u;
size_t tzheadsize = sizeof ( struct tzhead );
sp->goback = sp->goahead = false;
if ( ! name )
{
name = _PDCLIB_TZDEFAULT;
if ( ! name )
{
return _PDCLIB_EINVAL;
}
}
if ( name[ 0 ] == ':' )
{
++name;
}
doaccess = name[ 0 ] == '/';
if ( ! doaccess )
{
char const * dot;
size_t namelen = strlen( name );
if ( sizeof lsp->fullname - sizeof tzdirslash <= namelen )
{
return _PDCLIB_ENAMETOOLONG;
}
/* Create a string "TZDIR/NAME". Using sprintf here
would pull in stdio (and would fail if the
resulting string length exceeded INT_MAX!).
*/
memcpy( lsp->fullname, tzdirslash, sizeof tzdirslash );
strcpy( lsp->fullname + sizeof tzdirslash, name );
/* Set doaccess if NAME contains a ".." file name
component, as such a name could read a file outside
the TZDIR virtual subtree.
*/
for ( dot = name; ( dot = strchr( dot, '.' ) ); ++dot )
{
if ( ( dot == name || dot[ -1 ] == '/' ) && dot[ 1 ] == '.' && ( dot[ 2 ] == '/' || ! dot[ 2 ] ) )
{
doaccess = true;
break;
}
}
name = lsp->fullname;
}
fid = fopen( name, "rb" );
if ( fid == NULL )
{
return errno;
}
nread = fread( up->buf, 1, sizeof up->buf, fid );
if ( nread < tzheadsize )
{
int err = errno;
if ( ! ferror( fid ) )
{
err = _PDCLIB_EINVAL;
}
fclose( fid );
return err;
}
if ( fclose( fid ) == EOF )
{
return errno;
}
for ( stored = 4; stored <= 8; stored *= 2 )
{
int_fast32_t ttisstdcnt = detzcode( up->tzhead.tzh_ttisstdcnt );
int_fast32_t ttisutcnt = detzcode( up->tzhead.tzh_ttisutcnt );
int_fast64_t prevtr = 0;
int_fast32_t prevcorr = 0;
int_fast32_t leapcnt = detzcode( up->tzhead.tzh_leapcnt );
int_fast32_t timecnt = detzcode( up->tzhead.tzh_timecnt );
int_fast32_t typecnt = detzcode( up->tzhead.tzh_typecnt );
int_fast32_t charcnt = detzcode( up->tzhead.tzh_charcnt );
char const *p = up->buf + tzheadsize;
/* Although tzfile(5) currently requires typecnt to be nonzero,
support future formats that may allow zero typecnt
in files that have a TZ string and no transitions.
*/
if ( ! ( 0 <= leapcnt && leapcnt < TZ_MAX_LEAPS
&& 0 <= typecnt && typecnt < TZ_MAX_TYPES
&& 0 <= timecnt && timecnt < TZ_MAX_TIMES
&& 0 <= charcnt && charcnt < TZ_MAX_CHARS
&& ( ttisstdcnt == typecnt || ttisstdcnt == 0 )
&& ( ttisutcnt == typecnt || ttisutcnt == 0 ) ) )
{
return _PDCLIB_EINVAL;
}
if ( nread
< ( tzheadsize /* struct tzhead */
+ timecnt * stored /* ats */
+ timecnt /* types */
+ typecnt * 6 /* ttinfos */
+ charcnt /* chars */
+ leapcnt * ( stored + 4 ) /* lsinfos */
+ ttisstdcnt /* ttisstds */
+ ttisutcnt ) ) /* ttisuts */
{
return _PDCLIB_EINVAL;
}
sp->leapcnt = leapcnt;
sp->timecnt = timecnt;
sp->typecnt = typecnt;
sp->charcnt = charcnt;
/* Read transitions, discarding those out of time_t range.
But pretend the last transition before _PDCLIB_TIME_MIN
occurred at _PDCLIB_TIME_MIN.
*/
timecnt = 0;
for ( i = 0; i < sp->timecnt; ++i )
{
int_fast64_t at = stored == 4 ? detzcode( p ) : detzcode64( p );
sp->types[ i ] = at <= _PDCLIB_TIME_MAX;
if ( sp->types[ i ] )
{
time_t attime = ( ( _PDCLIB_TYPE_SIGNED( time_t ) ? at < _PDCLIB_TIME_MIN : at < 0 ) ? _PDCLIB_TIME_MIN : at );
if ( timecnt && attime <= sp->ats[ timecnt - 1 ] )
{
if ( attime < sp->ats[ timecnt - 1 ] )
{
return _PDCLIB_EINVAL;
}
sp->types[ i - 1 ] = 0;
timecnt--;
}
sp->ats[ timecnt++ ] = attime;
}
p += stored;
}
timecnt = 0;
for ( i = 0; i < sp->timecnt; ++i )
{
unsigned char typ = *p++;
if ( sp->typecnt <= typ )
{
return _PDCLIB_EINVAL;
}
if ( sp->types[ i ] )
{
sp->types[ timecnt++ ] = typ;
}
}
sp->timecnt = timecnt;
for ( i = 0; i < sp->typecnt; ++i )
{
struct ttinfo * ttisp;
unsigned char isdst, desigidx;
ttisp = &sp->ttis[ i ];
ttisp->utoff = detzcode( p );
p += 4;
isdst = *p++;
if ( ! ( isdst < 2 ) )
{
return _PDCLIB_EINVAL;
}
ttisp->isdst = isdst;
desigidx = *p++;
if ( ! ( desigidx < sp->charcnt ) )
{
return _PDCLIB_EINVAL;
}
ttisp->desigidx = desigidx;
}
for ( i = 0; i < sp->charcnt; ++i )
{
sp->chars[ i ] = *p++;
}
sp->chars[ i ] = '\0'; /* ensure '\0' at end */
/* Read leap seconds, discarding those out of time_t range. */
leapcnt = 0;
for ( i = 0; i < sp->leapcnt; ++i )
{
int_fast64_t tr = stored == 4 ? detzcode( p ) : detzcode64( p );
int_fast32_t corr = detzcode( p + stored );
p += stored + 4;
/* Leap seconds cannot occur before the Epoch. */
if ( tr < 0 )
{
return _PDCLIB_EINVAL;
}
if ( tr <= _PDCLIB_TIME_MAX )
{
/* Leap seconds cannot occur more than once per UTC month,
and UTC months are at least 28 days long (minus 1
second for a negative leap second). Each leap second's
correction must differ from the previous one's by 1
second.
*/
if ( tr - prevtr < 28 * SECSPERDAY - 1 || ( corr != prevcorr - 1 && corr != prevcorr + 1 ) )
{
return _PDCLIB_EINVAL;
}
sp->lsis[ leapcnt ].trans = prevtr = tr;
sp->lsis[ leapcnt ].corr = prevcorr = corr;
++leapcnt;
}
}
sp->leapcnt = leapcnt;
for ( i = 0; i < sp->typecnt; ++i )
{
struct ttinfo * ttisp;
ttisp = &sp->ttis[ i ];
if ( ttisstdcnt == 0 )
{
ttisp->ttisstd = false;
}
else
{
if ( *p != true && *p != false )
{
return _PDCLIB_EINVAL;
}
ttisp->ttisstd = *p++;
}
}
for ( i = 0; i < sp->typecnt; ++i )
{
struct ttinfo * ttisp;
ttisp = &sp->ttis[ i ];
if ( ttisutcnt == 0 )
{
ttisp->ttisut = false;
}
else
{
if ( *p != true && *p != false )
{
return _PDCLIB_EINVAL;
}
ttisp->ttisut = *p++;
}
}
/* If this is an old file, we're done. */
if ( up->tzhead.tzh_version[ 0 ] == '\0' )
{
break;
}
nread -= p - up->buf;
memmove( up->buf, p, nread );
}
if ( doextend && nread > 2 && up->buf[ 0 ] == '\n' && up->buf[ nread - 1 ] == '\n' && sp->typecnt + 2 <= TZ_MAX_TYPES )
{
struct state *ts = &lsp->u.st;
up->buf[ nread - 1 ] = '\0';
if ( _PDCLIB_tzparse( &up->buf[ 1 ], ts, false ) )
{
/* Attempt to reuse existing abbreviations.
Without this, America/Anchorage would be right on
the edge after 2037 when TZ_MAX_CHARS is 50, as
sp->charcnt equals 40 (for LMT AST AWT APT AHST
AHDT YST AKDT AKST) and ts->charcnt equals 10
(for AKST AKDT). Reusing means sp->charcnt can
stay 40 in this example. */
int gotabbr = 0;
int charcnt = sp->charcnt;
for ( i = 0; i < ts->typecnt; ++i )
{
char * tsabbr = ts->chars + ts->ttis[ i ].desigidx;
int j;
for ( j = 0; j < charcnt; ++j )
{
if ( strcmp( sp->chars + j, tsabbr ) == 0 )
{
ts->ttis[ i ].desigidx = j;
++gotabbr;
break;
}
}
if ( ! ( j < charcnt ) )
{
int tsabbrlen = strlen( tsabbr );
if ( j + tsabbrlen < TZ_MAX_CHARS )
{
strcpy( sp->chars + j, tsabbr );
charcnt = j + tsabbrlen + 1;
ts->ttis[ i ].desigidx = j;
++gotabbr;
}
}
}
if ( gotabbr == ts->typecnt )
{
sp->charcnt = charcnt;
/* Ignore any trailing, no-op transitions generated
by zic as they don't help here and can run afoul
of bugs in zic 2016j or earlier. */
while ( 1 < sp->timecnt && ( sp->types[ sp->timecnt - 1 ] == sp->types[ sp->timecnt - 2 ] ) )
{
sp->timecnt--;
}
for ( i = 0; i < ts->timecnt; ++i )
{
if ( sp->timecnt == 0 || ( sp->ats[ sp->timecnt - 1 ] < ts->ats[ i ] + leapcorr( sp, ts->ats[ i ] ) ) )
{
break;
}
}
while ( i < ts->timecnt && sp->timecnt < TZ_MAX_TIMES )
{
sp->ats[ sp->timecnt ] = ts->ats[ i ] + leapcorr( sp, ts->ats[ i ] );
sp->types[ sp->timecnt ] = ( sp->typecnt + ts->types[ i ] );
sp->timecnt++;
++i;
}
for ( i = 0; i < ts->typecnt; ++i )
{
sp->ttis[ sp->typecnt++ ] = ts->ttis[ i ];
}
}
}
}
if ( sp->typecnt == 0 )
{
return _PDCLIB_EINVAL;
}
if ( sp->timecnt > 1 )
{
for ( i = 1; i < sp->timecnt; ++i )
{
if ( typesequiv( sp, sp->types[ i ], sp->types[ 0 ] ) && differ_by_repeat( sp->ats[ i ], sp->ats[ 0 ] ) )
{
sp->goback = true;
break;
}
}
for ( i = sp->timecnt - 2; i >= 0; --i )
{
if ( typesequiv( sp, sp->types[ sp->timecnt - 1 ], sp->types[ i ] ) && differ_by_repeat( sp->ats[ sp->timecnt - 1 ], sp->ats[ i ] ) )
{
sp->goahead = true;
break;
}
}
}
/* Infer sp->defaulttype from the data. Although this default
type is always zero for data from recent tzdb releases,
things are trickier for data from tzdb 2018e or earlier.
The first set of heuristics work around bugs in 32-bit data
generated by tzdb 2013c or earlier. The workaround is for
zones like Australia/Macquarie where timestamps before the
first transition have a time type that is not the earliest
standard-time type. See:
https://mm.icann.org/pipermail/tz/2013-May/019368.html
*/
/* If type 0 is unused in transitions, it's the type to use for early times. */
for ( i = 0; i < sp->timecnt; ++i )
{
if ( sp->types[ i ] == 0 )
{
break;
}
}
i = i < sp->timecnt ? -1 : 0;
/* Absent the above,
if there are transition times
and the first transition is to a daylight time
find the standard type less than and closest to
the type of the first transition.
*/
if ( i < 0 && sp->timecnt > 0 && sp->ttis[ sp->types[ 0 ] ].isdst )
{
i = sp->types[ 0 ];
while ( --i >= 0 )
{
if ( ! sp->ttis[ i ].isdst )
{
break;
}
}
}
/* The next heuristics are for data generated by tzdb 2018e or
earlier, for zones like EST5EDT where the first transition
is to DST.
*/
/* If no result yet, find the first standard type.
If there is none, punt to type zero.
*/
if ( i < 0 )
{
i = 0;
while ( sp->ttis[ i ].isdst )
{
if ( ++i >= sp->typecnt )
{
i = 0;
break;
}
}
}
/* A simple 'sp->defaulttype = 0;' would suffice here if we
didn't have to worry about 2018e-or-earlier data. Even
simpler would be to remove the defaulttype member and just
use 0 in its place.
*/
sp->defaulttype = i;
return 0;
}
/* Load tz data from the file named NAME into *SP. Read extended
format if DOEXTEND. Return 0 on success, an errno value on failure.
*/
int _PDCLIB_tzload( char const * name, struct state * sp, bool doextend )
{
union local_storage ls;
return tzloadbody( name, sp, doextend, &ls );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,775 +0,0 @@
/* _PDCLIB_tzparse( char const *, struct _PDCLIB_timezone *, bool )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_tzcode.h"
#include <ctype.h>
#include <string.h>
/* The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
Default to US rules as of 2017-05-07.
POSIX does not specify the default DST rules;
for historical reasons, US rules are a common default.
*/
#ifndef TZDEFRULESTRING
#define TZDEFRULESTRING ",M3.2.0,M11.1.0"
#endif
#ifndef TZDEFRULES
#define TZDEFRULES "posixrules"
#endif
enum rule_t
{
JULIAN_DAY, /* Jn = Julian day */
DAY_OF_YEAR, /* n = day of year */
MONTH_NTH_DAY_OF_WEEK /* Mm.n.d = month, week, day of week */
};
struct rule
{
enum rule_t type; /* type of rule */
int day; /* day number of rule */
int week; /* week number of rule */
int mon; /* month number of rule */
int_fast32_t time; /* transition time of rule */
};
/* Given a pointer into a timezone string, extract a number from that string.
Check that the number is within a specified range; if it is not, return
NULL.
Otherwise, return a pointer to the first character not part of the number.
*/
static const char * getnum( const char * strp, int * nump, int min, int max )
{
char c;
int num;
if ( strp == NULL || ! isdigit( (unsigned char)( c = *strp ) ) )
{
return NULL;
}
num = 0;
do
{
num = num * 10 + ( c - '0' );
if ( num > max )
{
return NULL; /* illegal value */
}
c = *++strp;
} while ( isdigit( (unsigned char)c ) );
if ( num < min )
{
return NULL; /* illegal value */
}
*nump = num;
return strp;
}
/* Given a pointer into a timezone string, extract a number of seconds,
in hh[:mm[:ss]] form, from the string.
If any error occurs, return NULL.
Otherwise, return a pointer to the first character not part of the number
of seconds.
*/
static const char * getsecs( const char * strp, int_fast32_t * secsp )
{
int num;
/* 'HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like
"M10.4.6/26", which does not conform to Posix,
but which specifies the equivalent of
"02:00 on the first Sunday on or after 23 Oct".
*/
strp = getnum( strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1 );
if ( strp == NULL )
{
return NULL;
}
*secsp = num * (int_fast32_t) SECSPERHOUR;
if ( *strp == ':' )
{
++strp;
strp = getnum( strp, &num, 0, MINSPERHOUR - 1 );
if ( strp == NULL )
{
return NULL;
}
*secsp += num * SECSPERMIN;
if ( *strp == ':' )
{
++strp;
/* 'SECSPERMIN' allows for leap seconds. */
strp = getnum( strp, &num, 0, SECSPERMIN );
if ( strp == NULL )
{
return NULL;
}
*secsp += num;
}
}
return strp;
}
/* Given a pointer into a timezone string, extract an offset, in
[+-]hh[:mm[:ss]] form, from the string.
If any error occurs, return NULL.
Otherwise, return a pointer to the first character not part of the time.
*/
static const char * getoffset( const char * strp, int_fast32_t * offsetp )
{
bool neg = false;
if ( *strp == '-' )
{
neg = true;
++strp;
}
else if ( *strp == '+' )
{
++strp;
}
strp = getsecs( strp, offsetp );
if ( strp == NULL )
{
return NULL; /* illegal time */
}
if ( neg )
{
*offsetp = - *offsetp;
}
return strp;
}
/* Given a pointer into a timezone string, extract a rule in the form
date[/time]. See POSIX section 8 for the format of "date" and "time".
If a valid rule is not found, return NULL.
Otherwise, return a pointer to the first character not part of the rule.
*/
static const char * getrule( const char * strp, struct rule * rulep )
{
if ( *strp == 'J' )
{
/* Julian day. */
rulep->type = JULIAN_DAY;
++strp;
strp = getnum( strp, &rulep->day, 1, DAYSPERNYEAR );
}
else if ( *strp == 'M' )
{
/* Month, week, day. */
rulep->type = MONTH_NTH_DAY_OF_WEEK;
++strp;
strp = getnum( strp, &rulep->mon, 1, MONSPERYEAR );
if ( strp == NULL )
{
return NULL;
}
if ( *strp++ != '.' )
{
return NULL;
}
strp = getnum( strp, &rulep->week, 1, 5 );
if ( strp == NULL )
{
return NULL;
}
if ( *strp++ != '.' )
{
return NULL;
}
strp = getnum( strp, &rulep->day, 0, DAYSPERWEEK - 1 );
}
else if ( isdigit( (unsigned char)*strp ) )
{
/* Day of year. */
rulep->type = DAY_OF_YEAR;
strp = getnum( strp, &rulep->day, 0, DAYSPERLYEAR - 1 );
}
else
{
return NULL; /* invalid format */
}
if ( strp == NULL )
{
return NULL;
}
if ( *strp == '/' )
{
/* Time specified. */
++strp;
strp = getoffset( strp, &rulep->time );
}
else
{
rulep->time = 2 * SECSPERHOUR; /* default = 2:00:00 */
}
return strp;
}
/* Given a year, a rule, and the offset from UT at the time that rule takes
effect, calculate the year-relative time that rule takes effect.
*/
static int_fast32_t transtime( const int year, struct rule const * rulep, const int_fast32_t offset )
{
bool leapyear;
int_fast32_t value = 0;
int i;
int d;
int m1;
int yy0;
int yy1;
int yy2;
int dow;
leapyear = _PDCLIB_is_leap( year );
switch ( rulep->type )
{
case JULIAN_DAY:
/* Jn - Julian day, 1 == January 1, 60 == March 1 even in leap
years.
In non-leap years, or if the day number is 59 or less, just
add SECSPERDAY times the day number-1 to the time of
January 1, midnight, to get the day.
*/
value = ( rulep->day - 1 ) * SECSPERDAY;
if ( leapyear && rulep->day >= 60 )
{
value += SECSPERDAY;
}
break;
case DAY_OF_YEAR:
/* n - day of year.
Just add SECSPERDAY times the day number to the time of
January 1, midnight, to get the day.
*/
value = rulep->day * SECSPERDAY;
break;
case MONTH_NTH_DAY_OF_WEEK:
/* Mm.n.d - nth "dth day" of month m. */
/* Use Zeller's Congruence to get day-of-week of first day of
month.
*/
m1 = ( rulep->mon + 9 ) % 12 + 1;
yy0 = ( rulep->mon <= 2 ) ? ( year - 1 ) : year;
yy1 = yy0 / 100;
yy2 = yy0 % 100;
dow = ( ( 26 * m1 - 2 ) / 10 + 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1 ) % 7;
if ( dow < 0 )
{
dow += DAYSPERWEEK;
}
/* "dow" is the day-of-week of the first day of the month. Get
the day-of-month (zero-origin) of the first "dow" day of the
month.
*/
d = rulep->day - dow;
if ( d < 0 )
{
d += DAYSPERWEEK;
}
for ( i = 1; i < rulep->week; ++i )
{
if ( d + DAYSPERWEEK >= mon_lengths[ leapyear ][ rulep->mon - 1 ] )
{
break;
}
d += DAYSPERWEEK;
}
/* "d" is the day-of-month (zero-origin) of the day we want. */
value = d * SECSPERDAY;
for ( i = 0; i < rulep->mon - 1; ++i )
{
value += mon_lengths[ leapyear ][ i ] * SECSPERDAY;
}
break;
}
/* "value" is the year-relative time of 00:00:00 UT on the day in
question. To get the year-relative time of the specified local
time on that day, add the transition time and the current offset
from UT.
*/
return value + rulep->time + offset;
}
/* Given a pointer into a timezone string, scan until a character that is not
a valid character in a time zone abbreviation is found.
Return a pointer to that character.
*/
static const char * getzname( const char * strp )
{
char c;
while ( ( c = *strp ) != '\0' && ! isdigit( (unsigned char)c ) && c != ',' && c != '-' && c != '+' )
{
++strp;
}
return strp;
}
/* Given a pointer into an extended timezone string, scan until the ending
delimiter of the time zone abbreviation is located.
Return a pointer to the delimiter.
As with getzname above, the legal character set is actually quite
restricted, with other characters producing undefined results.
We don't do any checking here; checking is done later in common-case code.
*/
static const char * getqzname( const char *strp, const int delim )
{
int c;
while ( ( c = *strp ) != '\0' && c != delim )
{
++strp;
}
return strp;
}
static bool increment_overflow_time( time_t * tp, int_fast32_t j )
{
/* This is like
'if (! (_PDCLIB_TIME_MIN <= *tp + j && *tp + j <= _PDCLIB_TIME_MAX)) ...',
except that it does the right thing even if *tp + j would overflow.
*/
if ( ! ( j < 0
? ( _PDCLIB_TYPE_SIGNED( time_t ) ? _PDCLIB_TIME_MIN - j <= *tp : -1 - j < *tp )
: *tp <= _PDCLIB_TIME_MAX - j ) )
{
return true;
}
*tp += j;
return false;
}
/* Given a POSIX section 8-style TZ string, fill in the rule tables as
appropriate.
*/
bool _PDCLIB_tzparse( const char * name, struct state * sp, bool lastditch )
{
const char * stdname;
const char * dstname;
size_t stdlen;
size_t dstlen;
size_t charcnt;
int_fast32_t stdoffset;
int_fast32_t dstoffset;
char * cp;
bool load_ok;
stdname = name;
if ( lastditch )
{
stdlen = sizeof gmt - 1;
name += stdlen;
stdoffset = 0;
}
else
{
if ( *name == '<' )
{
name++;
stdname = name;
name = getqzname( name, '>' );
if ( *name != '>' )
{
return false;
}
stdlen = name - stdname;
name++;
}
else
{
name = getzname( name );
stdlen = name - stdname;
}
if ( ! stdlen )
{
return false;
}
name = getoffset( name, &stdoffset );
if ( name == NULL )
{
return false;
}
}
charcnt = stdlen + 1;
if ( sizeof sp->chars < charcnt )
{
return false;
}
load_ok = _PDCLIB_tzload( TZDEFRULES, sp, false ) == 0;
if ( ! load_ok )
{
sp->leapcnt = 0; /* so, we're off a little */
}
if ( *name != '\0' )
{
if ( *name == '<' )
{
dstname = ++name;
name = getqzname( name, '>' );
if ( *name != '>' )
{
return false;
}
dstlen = name - dstname;
name++;
}
else
{
dstname = name;
name = getzname( name );
dstlen = name - dstname; /* length of DST abbr. */
}
if ( ! dstlen )
{
return false;
}
charcnt += dstlen + 1;
if ( sizeof sp->chars < charcnt )
{
return false;
}
if ( *name != '\0' && *name != ',' && *name != ';' )
{
name = getoffset( name, &dstoffset );
if ( name == NULL )
{
return false;
}
}
else
{
dstoffset = stdoffset - SECSPERHOUR;
}
if ( *name == '\0' && ! load_ok )
{
name = TZDEFRULESTRING;
}
if ( *name == ',' || *name == ';' )
{
struct rule start;
struct rule end;
int year;
int yearlim;
int timecnt;
time_t janfirst;
int_fast32_t janoffset = 0;
int yearbeg;
++name;
if ( ( name = getrule( name, &start ) ) == NULL )
{
return false;
}
if ( *name++ != ',' )
{
return false;
}
if ( ( name = getrule( name, &end ) ) == NULL )
{
return false;
}
if ( *name != '\0' )
{
return false;
}
sp->typecnt = 2; /* standard time and DST */
/* Two transitions per year, from EPOCH_YEAR forward. */
_PDCLIB_init_ttinfo( &sp->ttis[ 0 ], -stdoffset, false, 0 );
_PDCLIB_init_ttinfo( &sp->ttis[ 1 ], -dstoffset, true, stdlen + 1 );
sp->defaulttype = 0;
timecnt = 0;
janfirst = 0;
yearbeg = EPOCH_YEAR;
do
{
int_fast32_t yearsecs = year_lengths[ _PDCLIB_is_leap( yearbeg - 1 ) ] * SECSPERDAY;
yearbeg--;
if ( increment_overflow_time( &janfirst, -yearsecs ) )
{
janoffset = -yearsecs;
break;
}
} while ( EPOCH_YEAR - YEARSPERREPEAT / 2 < yearbeg );
yearlim = yearbeg + YEARSPERREPEAT + 1;
for ( year = yearbeg; year < yearlim; year++ )
{
int_fast32_t starttime = transtime( year, &start, stdoffset ), endtime = transtime( year, &end, dstoffset );
int_fast32_t yearsecs = ( year_lengths[ _PDCLIB_is_leap( year ) ] * SECSPERDAY );
bool reversed = endtime < starttime;
if ( reversed )
{
int_fast32_t swap = starttime;
starttime = endtime;
endtime = swap;
}
if ( reversed
|| ( starttime < endtime
&& ( endtime - starttime
< ( yearsecs
+ ( stdoffset - dstoffset ) ) ) ) )
{
if ( TZ_MAX_TIMES - 2 < timecnt )
{
break;
}
sp->ats[ timecnt ] = janfirst;
if ( ! increment_overflow_time( &sp->ats[ timecnt ], janoffset + starttime ) )
{
sp->types[ timecnt++ ] = ! reversed;
}
sp->ats[ timecnt ] = janfirst;
if ( ! increment_overflow_time( &sp->ats[ timecnt ], janoffset + endtime ) )
{
sp->types[ timecnt++ ] = reversed;
yearlim = year + YEARSPERREPEAT + 1;
}
}
if ( increment_overflow_time ( &janfirst, janoffset + yearsecs ) )
{
break;
}
janoffset = 0;
}
sp->timecnt = timecnt;
if ( ! timecnt )
{
sp->ttis[ 0 ] = sp->ttis[ 1 ];
sp->typecnt = 1; /* Perpetual DST. */
}
else if ( YEARSPERREPEAT < year - yearbeg )
{
sp->goback = sp->goahead = true;
}
}
else
{
int_fast32_t theirstdoffset;
int_fast32_t theirdstoffset;
int_fast32_t theiroffset;
bool isdst;
int i;
int j;
if ( *name != '\0' )
{
return false;
}
/* Initial values of theirstdoffset and theirdstoffset. */
theirstdoffset = 0;
for ( i = 0; i < sp->timecnt; ++i )
{
j = sp->types[ i ];
if ( ! sp->ttis[ j ].isdst )
{
theirstdoffset = - sp->ttis[ j ].utoff;
break;
}
}
theirdstoffset = 0;
for ( i = 0; i < sp->timecnt; ++i )
{
j = sp->types[ i ];
if ( sp->ttis[ j ].isdst )
{
theirdstoffset = - sp->ttis[ j ].utoff;
break;
}
}
/* Initially we're assumed to be in standard time. */
isdst = false;
theiroffset = theirstdoffset;
/* Now juggle transition times and types
tracking offsets as you do.
*/
for ( i = 0; i < sp->timecnt; ++i )
{
j = sp->types[ i ];
sp->types[ i ] = sp->ttis[ j ].isdst;
if ( sp->ttis[ j ].ttisut )
{
/* No adjustment to transition time */
}
else
{
/* If daylight saving time is in
effect, and the transition time was
not specified as standard time, add
the daylight saving time offset to
the transition time; otherwise, add
the standard time offset to the
transition time.
*/
/* Transitions from DST to DDST
will effectively disappear since
POSIX provides for only one DST
offset.
*/
if ( isdst && ! sp->ttis[ j ].ttisstd )
{
sp->ats[ i ] += dstoffset - theirdstoffset;
}
else
{
sp->ats[ i ] += stdoffset - theirstdoffset;
}
}
theiroffset = -sp->ttis[ j ].utoff;
if ( sp->ttis[ j ].isdst )
{
theirdstoffset = theiroffset;
}
else
{
theirstdoffset = theiroffset;
}
}
/* Finally, fill in ttis. */
_PDCLIB_init_ttinfo( &sp->ttis[ 0 ], -stdoffset, false, 0 );
_PDCLIB_init_ttinfo( &sp->ttis[ 1 ], -dstoffset, true, stdlen + 1 );
sp->typecnt = 2;
sp->defaulttype = 0;
}
}
else
{
dstlen = 0;
sp->typecnt = 1; /* only standard time */
sp->timecnt = 0;
_PDCLIB_init_ttinfo( &sp->ttis[ 0 ], -stdoffset, false, 0 );
sp->defaulttype = 0;
}
sp->charcnt = charcnt;
cp = sp->chars;
memcpy( cp, stdname, stdlen );
cp += stdlen;
*cp++ = '\0';
if ( dstlen != 0 )
{
memcpy( cp, dstname, dstlen );
*( cp + dstlen ) = '\0';
}
return true;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,185 +0,0 @@
/* _PDCLIB_tzset_unlocked( void )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_tzcode.h"
#include <stdlib.h>
#include <string.h>
#ifndef TZ_ABBR_MAX_LEN
#define TZ_ABBR_MAX_LEN 16
#endif
#ifndef TZ_ABBR_CHAR_SET
#define TZ_ABBR_CHAR_SET "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._"
#endif
#ifndef TZ_ABBR_ERR_CHAR
#define TZ_ABBR_ERR_CHAR '_'
#endif
/* This string was in the Factory zone through version 2016f. */
#define GRANDPARENTED "Local time zone must be set--see zic manual page"
#ifndef TZ_STRLEN_MAX
#define TZ_STRLEN_MAX 255
#endif
static char lcl_TZname[ TZ_STRLEN_MAX + 1 ];
int lcl_is_set = 0;
static void scrub_abbrs( struct state * sp )
{
int i;
/* First, replace bogus characters. */
for ( i = 0; i < sp->charcnt; ++i )
{
if ( strchr( TZ_ABBR_CHAR_SET, sp->chars[ i ] ) == NULL )
{
sp->chars[ i ] = TZ_ABBR_ERR_CHAR;
}
}
/* Second, truncate long abbreviations. */
for ( i = 0; i < sp->typecnt; ++i )
{
const struct ttinfo * const ttisp = &sp->ttis[ i ];
char * cp = &sp->chars[ ttisp->desigidx ];
if ( strlen( cp ) > TZ_ABBR_MAX_LEN && strcmp( cp, GRANDPARENTED ) != 0 )
{
*( cp + TZ_ABBR_MAX_LEN ) = '\0';
}
}
}
/* Initialize *SP to a value appropriate for the TZ setting NAME.
Return 0 on success, an errno value on failure.
*/
static int zoneinit( struct state * sp, char const * name )
{
if (name && ! name[0])
{
/* User wants it fast rather than right. */
sp->leapcnt = 0; /* so, we're off a little */
sp->timecnt = 0;
sp->typecnt = 0;
sp->charcnt = 0;
sp->goback = sp->goahead = false;
_PDCLIB_init_ttinfo( &sp->ttis[ 0 ], 0, false, 0 );
strcpy( sp->chars, gmt );
sp->defaulttype = 0;
return 0;
}
else
{
int err = _PDCLIB_tzload( name, sp, true );
if ( err != 0 && name && name[ 0 ] != ':' && _PDCLIB_tzparse( name, sp, false ) )
{
err = 0;
}
if ( err == 0 )
{
scrub_abbrs( sp );
}
return err;
}
}
static void settzname( void )
{
struct state * const sp = &_PDCLIB_lclmem;
int i;
#if HAVE_TZNAME
tzname[ 0 ] = tzname[ 1 ] = (char *) ( sp ? wildabbr : gmt );
#endif
#if USG_COMPAT
daylight = 0;
timezone = 0;
#endif
#if ALTZONE
altzone = 0;
#endif
if ( sp == NULL )
{
return;
}
/* And to get the latest time zone abbreviations into tzname... */
for ( i = 0; i < sp->typecnt; ++i )
{
const struct ttinfo * const ttisp = &sp->ttis[ i ];
_PDCLIB_update_tzname_etc( sp, ttisp );
}
for ( i = 0; i < sp->timecnt; ++i )
{
const struct ttinfo * const ttisp = &sp->ttis[ sp->types[ i ] ];
_PDCLIB_update_tzname_etc( sp, ttisp );
#if USG_COMPAT
if ( ttisp->isdst )
{
daylight = 1;
}
#endif
}
}
static void tzsetlcl( char const * name )
{
struct state * sp = &_PDCLIB_lclmem;
int lcl = name ? strlen( name ) < sizeof lcl_TZname : -1;
if ( lcl < 0
? lcl_is_set < 0
: 0 < lcl_is_set && strcmp( lcl_TZname, name ) == 0 )
{
return;
}
if ( sp )
{
if ( zoneinit( sp, name ) != 0 )
{
zoneinit( sp, "" );
}
if ( 0 < lcl )
{
strcpy( lcl_TZname, name );
}
}
settzname();
lcl_is_set = lcl;
}
void _PDCLIB_tzset_unlocked( void )
{
tzsetlcl( getenv( "TZ" ) );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,44 +0,0 @@
/* _PDCLIB_update_tzname_etc( struct state const *, struct ttinfo const * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#ifndef REGTEST
#include "pdclib/_PDCLIB_tzcode.h"
void _PDCLIB_update_tzname_etc( struct state const * sp, struct ttinfo const * ttisp )
{
#if HAVE_TZNAME
tzname[ ttisp->isdst ] = (char *) &sp->chars[ ttisp->desigidx ];
#endif
#if USG_COMPAT
if ( ! ttisp->isdst )
{
timezone = - ttisp->utoff;
}
#endif
#if ALTZONE
if ( ttisp->isdst )
{
altzone = - ttisp->utoff;
}
#endif
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
#ifndef REGTEST
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,38 +0,0 @@
/* isalnum( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include <locale.h>
int isalnum( int c )
{
return ( isdigit( c ) || isalpha( c ) );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isalnum( 'a' ) );
TESTCASE( isalnum( 'z' ) );
TESTCASE( isalnum( 'A' ) );
TESTCASE( isalnum( 'Z' ) );
TESTCASE( isalnum( '0' ) );
TESTCASE( isalnum( '9' ) );
TESTCASE( ! isalnum( ' ' ) );
TESTCASE( ! isalnum( '\n' ) );
TESTCASE( ! isalnum( '@' ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,34 +0,0 @@
/* isalpha( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include <locale.h>
int isalpha( int c )
{
return ( _PDCLIB_lc_ctype->entry[c].flags & _PDCLIB_CTYPE_ALPHA );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isalpha( 'a' ) );
TESTCASE( isalpha( 'z' ) );
TESTCASE( ! isalpha( ' ' ) );
TESTCASE( ! isalpha( '1' ) );
TESTCASE( ! isalpha( '@' ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,35 +0,0 @@
/* isblank( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include <locale.h>
int isblank( int c )
{
return ( _PDCLIB_lc_ctype->entry[c].flags & _PDCLIB_CTYPE_BLANK );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isblank( ' ' ) );
TESTCASE( isblank( '\t' ) );
TESTCASE( ! isblank( '\v' ) );
TESTCASE( ! isblank( '\r' ) );
TESTCASE( ! isblank( 'x' ) );
TESTCASE( ! isblank( '@' ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,33 +0,0 @@
/* iscntrl( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include <locale.h>
int iscntrl( int c )
{
return ( _PDCLIB_lc_ctype->entry[c].flags & _PDCLIB_CTYPE_CNTRL );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( iscntrl( '\a' ) );
TESTCASE( iscntrl( '\b' ) );
TESTCASE( iscntrl( '\n' ) );
TESTCASE( ! iscntrl( ' ' ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,34 +0,0 @@
/* isdigit( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include <locale.h>
int isdigit( int c )
{
return ( c >= _PDCLIB_lc_ctype->digits_low && c <= _PDCLIB_lc_ctype->digits_high );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isdigit( '0' ) );
TESTCASE( isdigit( '9' ) );
TESTCASE( ! isdigit( ' ' ) );
TESTCASE( ! isdigit( 'a' ) );
TESTCASE( ! isdigit( '@' ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,37 +0,0 @@
/* isgraph( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include <locale.h>
int isgraph( int c )
{
return ( _PDCLIB_lc_ctype->entry[c].flags & _PDCLIB_CTYPE_GRAPH );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isgraph( 'a' ) );
TESTCASE( isgraph( 'z' ) );
TESTCASE( isgraph( 'A' ) );
TESTCASE( isgraph( 'Z' ) );
TESTCASE( isgraph( '@' ) );
TESTCASE( ! isgraph( '\t' ) );
TESTCASE( ! isgraph( '\0' ) );
TESTCASE( ! isgraph( ' ' ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,35 +0,0 @@
/* islower( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include <locale.h>
int islower( int c )
{
return ( _PDCLIB_lc_ctype->entry[c].flags & _PDCLIB_CTYPE_LOWER );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( islower( 'a' ) );
TESTCASE( islower( 'z' ) );
TESTCASE( ! islower( 'A' ) );
TESTCASE( ! islower( 'Z' ) );
TESTCASE( ! islower( ' ' ) );
TESTCASE( ! islower( '@' ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,38 +0,0 @@
/* isprint( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include <locale.h>
int isprint( int c )
{
/* FIXME: Space as of current locale charset, not source charset. */
return ( _PDCLIB_lc_ctype->entry[c].flags & _PDCLIB_CTYPE_GRAPH ) || ( c == ' ' );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isprint( 'a' ) );
TESTCASE( isprint( 'z' ) );
TESTCASE( isprint( 'A' ) );
TESTCASE( isprint( 'Z' ) );
TESTCASE( isprint( '@' ) );
TESTCASE( ! isprint( '\t' ) );
TESTCASE( ! isprint( '\0' ) );
TESTCASE( isprint( ' ' ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,38 +0,0 @@
/* ispunct( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include <locale.h>
int ispunct( int c )
{
return ( _PDCLIB_lc_ctype->entry[c].flags & _PDCLIB_CTYPE_PUNCT );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( ! ispunct( 'a' ) );
TESTCASE( ! ispunct( 'z' ) );
TESTCASE( ! ispunct( 'A' ) );
TESTCASE( ! ispunct( 'Z' ) );
TESTCASE( ispunct( '@' ) );
TESTCASE( ispunct( '.' ) );
TESTCASE( ! ispunct( '\t' ) );
TESTCASE( ! ispunct( '\0' ) );
TESTCASE( ! ispunct( ' ' ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,36 +0,0 @@
/* 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 <ctype.h>
#ifndef REGTEST
#include <locale.h>
int isspace( int c )
{
return ( _PDCLIB_lc_ctype->entry[c].flags & _PDCLIB_CTYPE_SPACE );
}
#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

View File

@@ -1,35 +0,0 @@
/* isupper( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include <locale.h>
int isupper( int c )
{
return ( _PDCLIB_lc_ctype->entry[c].flags & _PDCLIB_CTYPE_UPPER );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isupper( 'A' ) );
TESTCASE( isupper( 'Z' ) );
TESTCASE( ! isupper( 'a' ) );
TESTCASE( ! isupper( 'z' ) );
TESTCASE( ! isupper( ' ' ) );
TESTCASE( ! isupper( '@' ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,42 +0,0 @@
/* isxdigit( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include <locale.h>
int isxdigit( int c )
{
return ( isdigit( c ) ||
( c >= _PDCLIB_lc_ctype->Xdigits_low && c <= _PDCLIB_lc_ctype->Xdigits_high ) ||
( c >= _PDCLIB_lc_ctype->xdigits_low && c <= _PDCLIB_lc_ctype->xdigits_high )
);
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( isxdigit( '0' ) );
TESTCASE( isxdigit( '9' ) );
TESTCASE( isxdigit( 'a' ) );
TESTCASE( isxdigit( 'f' ) );
TESTCASE( ! isxdigit( 'g' ) );
TESTCASE( isxdigit( 'A' ) );
TESTCASE( isxdigit( 'F' ) );
TESTCASE( ! isxdigit( 'G' ) );
TESTCASE( ! isxdigit( '@' ) );
TESTCASE( ! isxdigit( ' ' ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,35 +0,0 @@
/* 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 <ctype.h>
#ifndef REGTEST
#include <locale.h>
int tolower( int c )
{
return _PDCLIB_lc_ctype->entry[c].lower;
}
#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

View File

@@ -1,35 +0,0 @@
/* toupper( int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <ctype.h>
#ifndef REGTEST
#include <locale.h>
int toupper( int c )
{
return _PDCLIB_lc_ctype->entry[c].upper;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( toupper( 'a' ) == 'A' );
TESTCASE( toupper( 'z' ) == 'Z' );
TESTCASE( toupper( 'A' ) == 'A' );
TESTCASE( toupper( 'Z' ) == 'Z' );
TESTCASE( toupper( '@' ) == '@' );
TESTCASE( toupper( '[' ) == '[' );
return TEST_RESULTS;
}
#endif

View File

@@ -1,32 +0,0 @@
/* imaxabs( intmax_t )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <inttypes.h>
#ifndef REGTEST
intmax_t imaxabs( intmax_t j )
{
return ( j >= 0 ) ? j : -j;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <limits.h>
int main( void )
{
TESTCASE( imaxabs( ( intmax_t )0 ) == 0 );
TESTCASE( imaxabs( INTMAX_MAX ) == INTMAX_MAX );
TESTCASE( imaxabs( INTMAX_MIN + 1 ) == -( INTMAX_MIN + 1 ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,39 +0,0 @@
/* lldiv( long long int, long long int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <inttypes.h>
#ifndef REGTEST
imaxdiv_t imaxdiv( intmax_t numer, intmax_t denom )
{
imaxdiv_t rc;
rc.quot = numer / denom;
rc.rem = numer % denom;
return rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
imaxdiv_t result;
result = imaxdiv( ( intmax_t )5, ( intmax_t )2 );
TESTCASE( result.quot == 2 && result.rem == 1 );
result = imaxdiv( ( intmax_t )-5, ( intmax_t )2 );
TESTCASE( result.quot == -2 && result.rem == -1 );
result = imaxdiv( ( intmax_t )5, ( intmax_t )-2 );
TESTCASE( result.quot == -2 && result.rem == 1 );
TESTCASE( sizeof( result.quot ) == sizeof( intmax_t ) );
TESTCASE( sizeof( result.rem ) == sizeof( intmax_t ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,158 +0,0 @@
/* strtoimax( const char *, char **, int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <limits.h>
#include <inttypes.h>
#ifndef REGTEST
#include <stddef.h>
intmax_t strtoimax( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base )
{
intmax_t rc;
char sign = '+';
const char * p = _PDCLIB_strtox_prelim( nptr, &sign, &base );
if ( base < 2 || base > 36 )
{
return 0;
}
if ( sign == '+' )
{
rc = ( intmax_t )_PDCLIB_strtox_main( &p, ( unsigned )base, ( uintmax_t )INTMAX_MAX, ( uintmax_t )INTMAX_MAX, &sign );
}
else
{
rc = ( intmax_t )_PDCLIB_strtox_main( &p, ( unsigned )base, ( uintmax_t )INTMAX_MIN, ( ( uintmax_t )INTMAX_MAX + 1 ), &sign );
}
if ( endptr != NULL )
{
*endptr = ( p != NULL ) ? ( char * ) p : ( char * ) nptr;
}
return ( sign == '+' ) ? rc : -rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <errno.h>
int main( void )
{
char * endptr;
/* this, to base 36, overflows even a 256 bit integer */
char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_";
/* tricky border case */
char tricky[] = "+0xz";
errno = 0;
/* basic functionality */
TESTCASE( strtoimax( "123", NULL, 10 ) == 123 );
/* proper detecting of default base 10 */
TESTCASE( strtoimax( "456", NULL, 0 ) == 456 );
/* proper functioning to smaller base */
TESTCASE( strtoimax( "14", NULL, 8 ) == 12 );
/* proper autodetecting of octal */
TESTCASE( strtoimax( "016", NULL, 0 ) == 14 );
/* proper autodetecting of hexadecimal, lowercase 'x' */
TESTCASE( strtoimax( "0xFF", NULL, 0 ) == 255 );
/* proper autodetecting of hexadecimal, uppercase 'X' */
TESTCASE( strtoimax( "0Xa1", NULL, 0 ) == 161 );
/* proper handling of border case: 0x followed by non-hexdigit */
TESTCASE( strtoimax( tricky, &endptr, 0 ) == 0 );
/* newlib completely balks at this parse, so we _NOREG it */
TESTCASE_NOREG( endptr == tricky + 2 );
/* proper handling of border case: 0 followed by non-octdigit */
TESTCASE( strtoimax( tricky, &endptr, 8 ) == 0 );
TESTCASE( endptr == tricky + 2 );
/* errno should still be 0 */
TESTCASE( errno == 0 );
/* overflowing subject sequence must still return proper endptr */
TESTCASE( strtoimax( overflow, &endptr, 36 ) == INTMAX_MIN );
TESTCASE( errno == ERANGE );
TESTCASE( ( endptr - overflow ) == 53 );
/* same for positive */
errno = 0;
TESTCASE( strtoimax( overflow + 1, &endptr, 36 ) == INTMAX_MAX );
TESTCASE( errno == ERANGE );
TESTCASE( ( endptr - overflow ) == 53 );
/* testing skipping of leading whitespace */
TESTCASE( strtoimax( " \n\v\t\f789", NULL, 0 ) == 789 );
/* testing conversion failure */
TESTCASE( strtoimax( overflow, &endptr, 10 ) == 0 );
TESTCASE( endptr == overflow );
endptr = NULL;
TESTCASE( strtoimax( overflow, &endptr, 0 ) == 0 );
TESTCASE( endptr == overflow );
/* These tests assume two-complement, but conversion should work for */
/* one-complement and signed magnitude just as well. Anyone having a */
/* platform to test this on? */
errno = 0;
#if INTMAX_MAX >> 62 == 1
/* testing "odd" overflow, i.e. base is not a power of two */
TESTCASE( strtoimax( "9223372036854775807", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "9223372036854775808", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == ERANGE );
errno = 0;
TESTCASE( strtoimax( "-9223372036854775807", NULL, 0 ) == ( INTMAX_MIN + 1 ) );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-9223372036854775808", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-9223372036854775809", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == ERANGE );
/* testing "even" overflow, i.e. base is power of two */
errno = 0;
TESTCASE( strtoimax( "0x7fffffffffffffff", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "0x8000000000000000", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == ERANGE );
errno = 0;
TESTCASE( strtoimax( "-0x7fffffffffffffff", NULL, 0 ) == ( INTMAX_MIN + 1 ) );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-0x8000000000000000", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-0x8000000000000001", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == ERANGE );
#elif LLONG_MAX >> 126 == 1
/* testing "odd" overflow, i.e. base is not a power of two */
TESTCASE( strtoimax( "170141183460469231731687303715884105728", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "170141183460469231731687303715884105729", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == ERANGE );
errno = 0;
TESTCASE( strtoimax( "-170141183460469231731687303715884105728", NULL, 0 ) == ( INTMAX_MIN + 1 ) );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-170141183460469231731687303715884105729", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-170141183460469231731687303715884105730", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == ERANGE );
/* testing "even" overflow, i.e. base is power of two */
errno = 0;
TESTCASE( strtoimax( "0x7fffffffffffffffffffffffffffffff", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "0x80000000000000000000000000000000", NULL, 0 ) == INTMAX_MAX );
TESTCASE( errno == ERANGE );
errno = 0;
TESTCASE( strtoimax( "-0x7fffffffffffffffffffffffffffffff", NULL, 0 ) == ( INTMAX_MIN + 1 ) );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-0x80000000000000000000000000000000", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == 0 );
TESTCASE( strtoimax( "-0x80000000000000000000000000000001", NULL, 0 ) == INTMAX_MIN );
TESTCASE( errno == ERANGE );
#else
#error Unsupported width of 'intmax_t' (neither 64 nor 128 bit).
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,122 +0,0 @@
/* strtoumax( const char *, char **, int )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <limits.h>
#include <inttypes.h>
#ifndef REGTEST
#include <stddef.h>
uintmax_t strtoumax( const char * _PDCLIB_restrict nptr, char ** _PDCLIB_restrict endptr, int base )
{
uintmax_t rc;
char sign = '+';
const char * p = _PDCLIB_strtox_prelim( nptr, &sign, &base );
if ( base < 2 || base > 36 )
{
return 0;
}
rc = _PDCLIB_strtox_main( &p, ( unsigned )base, ( uintmax_t )UINTMAX_MAX, ( uintmax_t )UINTMAX_MAX, &sign );
if ( endptr != NULL )
{
*endptr = ( p != NULL ) ? ( char * ) p : ( char * ) nptr;
}
return ( sign == '+' ) ? rc : -rc;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <errno.h>
int main( void )
{
char * endptr;
/* this, to base 36, overflows even a 256 bit integer */
char overflow[] = "-ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ_";
/* tricky border case */
char tricky[] = "+0xz";
errno = 0;
/* basic functionality */
TESTCASE( strtoumax( "123", NULL, 10 ) == 123 );
/* proper detecting of default base 10 */
TESTCASE( strtoumax( "456", NULL, 0 ) == 456 );
/* proper functioning to smaller base */
TESTCASE( strtoumax( "14", NULL, 8 ) == 12 );
/* proper autodetecting of octal */
TESTCASE( strtoumax( "016", NULL, 0 ) == 14 );
/* proper autodetecting of hexadecimal, lowercase 'x' */
TESTCASE( strtoumax( "0xFF", NULL, 0 ) == 255 );
/* proper autodetecting of hexadecimal, uppercase 'X' */
TESTCASE( strtoumax( "0Xa1", NULL, 0 ) == 161 );
/* proper handling of border case: 0x followed by non-hexdigit */
TESTCASE( strtoumax( tricky, &endptr, 0 ) == 0 );
/* newlib completely balks at this parse, so we _NOREG it */
TESTCASE_NOREG( endptr == tricky + 2 );
/* proper handling of border case: 0 followed by non-octdigit */
TESTCASE( strtoumax( tricky, &endptr, 8 ) == 0 );
TESTCASE( endptr == tricky + 2 );
/* errno should still be 0 */
TESTCASE( errno == 0 );
/* overflowing subject sequence must still return proper endptr */
TESTCASE( strtoumax( overflow, &endptr, 36 ) == UINTMAX_MAX );
TESTCASE( errno == ERANGE );
TESTCASE( ( endptr - overflow ) == 53 );
/* same for positive */
errno = 0;
TESTCASE( strtoumax( overflow + 1, &endptr, 36 ) == UINTMAX_MAX );
TESTCASE( errno == ERANGE );
TESTCASE( ( endptr - overflow ) == 53 );
/* testing skipping of leading whitespace */
TESTCASE( strtoumax( " \n\v\t\f789", NULL, 0 ) == 789 );
/* testing conversion failure */
TESTCASE( strtoumax( overflow, &endptr, 10 ) == 0 );
TESTCASE( endptr == overflow );
endptr = NULL;
TESTCASE( strtoumax( overflow, &endptr, 0 ) == 0 );
TESTCASE( endptr == overflow );
errno = 0;
/* uintmax_t -> long long -> 64 bit */
#if UINTMAX_MAX >> 63 == 1
/* testing "odd" overflow, i.e. base is not power of two */
TESTCASE( strtoumax( "18446744073709551615", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoumax( "18446744073709551616", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == ERANGE );
/* testing "even" overflow, i.e. base is power of two */
errno = 0;
TESTCASE( strtoumax( "0xFFFFFFFFFFFFFFFF", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoumax( "0x10000000000000000", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == ERANGE );
/* uintmax_t -> long long -> 128 bit */
#elif UINTMAX_MAX >> 127 == 1
/* testing "odd" overflow, i.e. base is not power of two */
TESTCASE( strtoumax( "340282366920938463463374607431768211455", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoumax( "340282366920938463463374607431768211456", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == ERANGE );
/* testing "even" everflow, i.e. base is power of two */
errno = 0;
TESTCASE( strtoumax( "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == 0 );
TESTCASE( strtoumax( "0x100000000000000000000000000000000", NULL, 0 ) == UINTMAX_MAX );
TESTCASE( errno == ERANGE );
#else
#error Unsupported width of 'uintmax_t' (neither 64 nor 128 bit).
#endif
return TEST_RESULTS;
}
#endif

View File

@@ -1,32 +0,0 @@
/* localeconv( void )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <locale.h>
#ifndef REGTEST
struct lconv * localeconv( void )
{
return _PDCLIB_lc_numeric_monetary.lconv;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
struct lconv * lconv;
TESTCASE( ( lconv = localeconv() ) != NULL );
TESTCASE( strcmp( lconv->decimal_point, "." ) == 0 );
TESTCASE( strcmp( lconv->thousands_sep, "" ) == 0 );
TESTCASE( ( strcmp( lconv->grouping, "" ) == 0 ) || ( strcmp( lconv->grouping, "\x7f" ) == 0 ) );
return TEST_RESULTS;
}
#endif

View File

@@ -1,269 +0,0 @@
/* setlocale( int, const char * )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#ifndef REGTEST
#if 0
static const char * _PDCLIB_LC_category_name[ _PDCLIB_LC_COUNT ] = { NULL, "LC_COLLATE", "LC_CTYPE", "LC_MONETARY", "LC_NUMERIC", "LC_TIME", "LC_MESSAGES" };
static const char * _PDCLIB_default_locale( int category )
{
const char * s;
/* The standard states (7.22.4.6 (3), "the implementation shall behave
as if no library function calls the getenv function." That is,
however, in context of the previous paragraph stating that getenv
"need not avoid data races with other threads of execution that
modify the environment list".
PDCLib does not provide means of modifying the environment list.
*/
if ( ( s = getenv( "LC_ALL" ) ) == NULL )
{
if ( category == LC_ALL || ( s = getenv( _PDCLIB_LC_category_name[ category ] ) ) == NULL )
{
if ( ( s = getenv( "LANG" ) ) == NULL )
{
s = "C";
}
}
}
return s;
}
#endif
char * setlocale( int category, const char * locale )
{
/* All below is very much work-in-progress, so we do a dumb-dummy
return here.
*/
if ( locale == NULL || ! strcmp( locale, "C" ) )
{
return ( char * )"C";
}
else
{
return NULL;
}
#if 0
/* Path to locale data files - _PDCLIB_LOCALE_PATH unless overruled
by the environment variable whose name is defined by preprocessor
symbol _PDCLIB_LOCALE_PATH_ENV (defaulting to PDCLIB_I18N).
Both of these definitions are set in _PDCLIB_config.h.
*/
const char * path = _PDCLIB_LOCALE_PATH;
struct _PDCLIB_lc_lconv_numeric_t * numeric = NULL;
struct _PDCLIB_lc_lconv_monetary_t * monetary = NULL;
struct _PDCLIB_lc_collate_t * collate = NULL;
struct _PDCLIB_lc_ctype_t * ctype = NULL;
struct _PDCLIB_lc_messages_t * messages = NULL;
struct _PDCLIB_lc_time_t * time = NULL;
char * rc = ( char * )locale;
if ( category < 0 || category >= _PDCLIB_LC_COUNT )
{
/* Bad category */
return NULL;
}
if ( locale == NULL )
{
/* NULL - Return current locale settings */
/* TODO */
}
if ( strlen( locale ) == 0 )
{
/* "" - Use default locale */
locale = _PDCLIB_default_locale( category );
}
if ( getenv( _PDCLIB_value2string( _PDCLIB_LOCALE_PATH_ENV ) ) != NULL )
{
path = getenv( _PDCLIB_value2string( _PDCLIB_LOCALE_PATH_ENV ) );
}
/* We have to do this in two runs. As we might be facing LC_ALL, we
need to be certain all the loads are successful before we start
to overwrite the current locale settings, because there is no way
this function could report a _partial_ success.
*/
/* Run One -- get all the data for the new locale setting */
if ( category == LC_COLLATE || category == LC_ALL )
{
if ( !( collate = _PDCLIB_load_lc_collate( path, locale ) ) )
{
rc = NULL;
}
}
if ( category == LC_CTYPE || category == LC_ALL )
{
if ( !( ctype = _PDCLIB_load_lc_ctype( path, locale ) ) )
{
rc = NULL;
}
}
if ( category == LC_MONETARY || category == LC_ALL )
{
if ( !( monetary = _PDCLIB_load_lc_monetary( path, locale ) ) )
{
rc = NULL;
}
}
if ( category == LC_NUMERIC || category == LC_ALL )
{
if ( !( numeric = _PDCLIB_load_lc_numeric( path, locale ) ) )
{
rc = NULL;
}
}
if ( category == LC_TIME || category == LC_ALL )
{
if ( !( time = _PDCLIB_load_lc_time( path, locale ) ) )
{
rc = NULL;
}
}
if ( category == LC_MESSAGES || category == LC_ALL )
{
if ( !( messages = _PDCLIB_load_lc_messages( path, locale ) ) )
{
rc = NULL;
}
}
/* Run Two -- continue or release resources */
if ( rc != NULL )
{
if ( category == LC_COLLATE || category == LC_ALL )
{
if ( _PDCLIB_lc_collate->alloced )
{
/* free resources */
}
*_PDCLIB_lc_collate = *collate;
free( collate );
}
if ( category == LC_CTYPE || category == LC_ALL )
{
if ( _PDCLIB_lc_ctype->alloced )
{
free( _PDCLIB_lc_ctype->entry - 1 );
}
*_PDCLIB_lc_ctype = *ctype;
free( ctype );
}
if ( category == LC_MONETARY || category == LC_ALL )
{
if ( _PDCLIB_lc_numeric_monetary.monetary_alloced )
{
free( _PDCLIB_lc_numeric_monetary.lconv->mon_decimal_point );
}
_PDCLIB_lc_numeric_monetary.lconv->mon_decimal_point = monetary->mon_decimal_point;
_PDCLIB_lc_numeric_monetary.lconv->mon_thousands_sep = monetary->mon_thousands_sep;
_PDCLIB_lc_numeric_monetary.lconv->mon_grouping = monetary->mon_grouping;
_PDCLIB_lc_numeric_monetary.lconv->positive_sign = monetary->positive_sign;
_PDCLIB_lc_numeric_monetary.lconv->negative_sign = monetary->negative_sign;
_PDCLIB_lc_numeric_monetary.lconv->currency_symbol = monetary->currency_symbol;
_PDCLIB_lc_numeric_monetary.lconv->int_curr_symbol = monetary->int_curr_symbol;
_PDCLIB_lc_numeric_monetary.lconv->frac_digits = monetary->frac_digits;
_PDCLIB_lc_numeric_monetary.lconv->p_cs_precedes = monetary->p_cs_precedes;
_PDCLIB_lc_numeric_monetary.lconv->n_cs_precedes = monetary->n_cs_precedes;
_PDCLIB_lc_numeric_monetary.lconv->p_sep_by_space = monetary->p_sep_by_space;
_PDCLIB_lc_numeric_monetary.lconv->n_sep_by_space = monetary->n_sep_by_space;
_PDCLIB_lc_numeric_monetary.lconv->p_sign_posn = monetary->p_sign_posn;
_PDCLIB_lc_numeric_monetary.lconv->n_sign_posn = monetary->n_sign_posn;
_PDCLIB_lc_numeric_monetary.lconv->int_frac_digits = monetary->int_frac_digits;
_PDCLIB_lc_numeric_monetary.lconv->int_p_cs_precedes = monetary->int_p_cs_precedes;
_PDCLIB_lc_numeric_monetary.lconv->int_n_cs_precedes = monetary->int_n_cs_precedes;
_PDCLIB_lc_numeric_monetary.lconv->int_p_sep_by_space = monetary->int_p_sep_by_space;
_PDCLIB_lc_numeric_monetary.lconv->int_n_sep_by_space = monetary->int_n_sep_by_space;
_PDCLIB_lc_numeric_monetary.lconv->int_p_sign_posn = monetary->int_p_sign_posn;
_PDCLIB_lc_numeric_monetary.lconv->int_n_sign_posn = monetary->int_n_sign_posn;
_PDCLIB_lc_numeric_monetary.monetary_alloced = 1;
free( monetary );
}
if ( category == LC_NUMERIC || category == LC_ALL )
{
if ( _PDCLIB_lc_numeric_monetary.numeric_alloced )
{
free( _PDCLIB_lc_numeric_monetary.lconv->decimal_point );
}
_PDCLIB_lc_numeric_monetary.lconv->decimal_point = numeric->decimal_point;
_PDCLIB_lc_numeric_monetary.lconv->thousands_sep = numeric->thousands_sep;
_PDCLIB_lc_numeric_monetary.lconv->grouping = numeric->grouping;
_PDCLIB_lc_numeric_monetary.numeric_alloced = 1;
free( numeric );
}
if ( category == LC_TIME || category == LC_ALL )
{
if ( _PDCLIB_lc_time->alloced )
{
free( _PDCLIB_lc_time->month_name_abbr[ 0 ] );
}
*_PDCLIB_lc_time = *time;
free( time );
}
if ( category == LC_MESSAGES || category == LC_ALL )
{
if ( _PDCLIB_lc_messages->alloced )
{
free( _PDCLIB_lc_messages->errno_texts[ 0 ] );
}
*_PDCLIB_lc_messages = *messages;
free( messages );
}
}
return NULL;
#endif
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
TESTCASE( strcmp( setlocale( LC_ALL, "C" ), "C" ) == 0 );
#ifndef REGTEST
TESTCASE( setlocale( LC_ALL, "" ) == NULL );
#endif
TESTCASE( strcmp( setlocale( LC_ALL, NULL ), "C" ) == 0 );
return TEST_RESULTS;
}
#endif

View File

@@ -1,114 +0,0 @@
/* fabs( double )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <math.h>
#ifndef REGTEST
double fabs( double x )
{
if ( isnan( x ) )
{
return NAN;
}
return ( x < 0.0 ) ? -x : x;
}
float fabsf( float x )
{
if ( isnan( x ) )
{
return NAN;
}
return ( x < 0.0 ) ? -x : x;
}
long double fabsl( long double x )
{
if ( isnan( x ) )
{
return NAN;
}
return ( x < 0.0 ) ? -x : x;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <errno.h>
int main( void )
{
float f;
double d;
long double ld;
TESTCASE( fabsf( 3.15f ) == 3.15f );
TESTCASE( fabsf( -3.15f ) == 3.15f );
errno = 0;
TESTCASE( fabsf( INFINITY ) == INFINITY );
TESTCASE( errno == 0 );
errno = 0;
TESTCASE( fabsf( -INFINITY ) == INFINITY );
TESTCASE( errno == 0 );
errno = 0;
f = fabsf( NAN );
TESTCASE( isnan( f ) );
TESTCASE( ! signbit( f ) );
TESTCASE( errno == 0 );
f = fabsf( -NAN );
TESTCASE( isnan( f ) );
TESTCASE( ! signbit( f ) );
TESTCASE( errno == 0 );
TESTCASE( fabs( 3.15 ) == 3.15 );
TESTCASE( fabs( -3.15 ) == 3.15 );
errno = 0;
TESTCASE( fabs( INFINITY ) == INFINITY );
TESTCASE( errno == 0 );
errno = 0;
TESTCASE( fabs( -INFINITY ) == INFINITY );
TESTCASE( errno == 0 );
errno = 0;
d = fabs( NAN );
TESTCASE( isnan( d ) );
TESTCASE( ! signbit( d ) );
TESTCASE( errno == 0 );
d = fabs( -NAN );
TESTCASE( isnan( d ) );
TESTCASE( ! signbit( d ) );
TESTCASE( errno == 0 );
TESTCASE( fabsl( 3.15l ) == 3.15l );
TESTCASE( fabsl( -3.15l ) == 3.15l );
errno = 0;
TESTCASE( fabsl( INFINITY ) == INFINITY );
TESTCASE( errno == 0 );
errno = 0;
TESTCASE( fabsl( -INFINITY ) == INFINITY );
TESTCASE( errno == 0 );
errno = 0;
ld = fabsl( NAN );
TESTCASE( isnan( ld ) );
TESTCASE( ! signbit( ld ) );
TESTCASE( errno == 0 );
ld = fabsl( -NAN );
TESTCASE( isnan( ld ) );
TESTCASE( ! signbit( ld ) );
TESTCASE( errno == 0 );
return TEST_RESULTS;
}
#endif

View File

@@ -1,74 +0,0 @@
/* fdim( double )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <math.h>
#ifndef REGTEST
double fdim( double x, double y )
{
return fmax( x - y, 0 );
}
float fdimf( float x, float y )
{
return fmaxf( x - y, 0 );
}
long double fdiml( long double x, long double y )
{
return fmaxl( x - y, 0 );
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
float f1, f2;
double d1, d2;
long double ld1, ld2;
f1 = 3.5f;
f2 = 3.75f;
TESTCASE( fdimf( f1, f2 ) == 0.0f );
TESTCASE( fdimf( f2, f1 ) == 0.25f );
TESTCASE( fdimf( f1, INFINITY ) == 0.0f );
TESTCASE( fdimf( INFINITY, f1 ) == INFINITY );
TESTCASE( fdimf( f1, -INFINITY ) == INFINITY );
TESTCASE( fdimf( -INFINITY, f1 ) == 0.0f );
TESTCASE( fdimf( f1, NAN ) != f1 );
TESTCASE( fdimf( NAN, f1 ) != f1 );
d1 = 3.5;
d2 = 3.75;
TESTCASE( fdim( d1, d2 ) == 0.0 );
TESTCASE( fdim( d2, d1 ) == 0.25 );
TESTCASE( fdim( d1, INFINITY ) == 0.0 );
TESTCASE( fdim( INFINITY, d1 ) == INFINITY );
TESTCASE( fdim( d1, -INFINITY ) == INFINITY );
TESTCASE( fdim( -INFINITY, d1 ) == 0.0 );
TESTCASE( fdim( d1, NAN ) != d1 );
TESTCASE( fdim( NAN, d1 ) != d1 );
ld1 = 3.5l;
ld2 = 3.75l;
TESTCASE( fdiml( ld1, ld2 ) == 0.0l );
TESTCASE( fdiml( ld2, ld1 ) == 0.25l );
TESTCASE( fdiml( ld1, INFINITY ) == 0.0l );
TESTCASE( fdiml( INFINITY, ld1 ) == INFINITY );
TESTCASE( fdiml( ld1, -INFINITY ) == INFINITY );
TESTCASE( fdiml( -INFINITY, ld1 ) == 0.0l );
TESTCASE( fdiml( ld1, NAN ) != ld1 );
TESTCASE( fdiml( NAN, ld1 ) != ld1 );
return TEST_RESULTS;
}
#endif

View File

@@ -1,105 +0,0 @@
/* fmax( double )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <math.h>
#ifndef REGTEST
double fmax( double x, double y )
{
if ( isnan( x ) ) return y;
if ( isnan( y ) ) return x;
return ( x > y ) ? x : y;
}
float fmaxf( float x, float y )
{
if ( isnan( x ) ) return y;
if ( isnan( y ) ) return x;
return ( x > y ) ? x : y;
}
long double fmaxl( long double x, long double y )
{
if ( isnan( x ) ) return y;
if ( isnan( y ) ) return x;
return ( x > y ) ? x : y;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
float f1, f2;
double d1, d2;
long double ld1, ld2;
f1 = 3.15f;
f2 = 3.16f;
TESTCASE( fmaxf( f1, f2 ) == f2 );
TESTCASE( fmaxf( f2, f1 ) == f2 );
TESTCASE( fmaxf( f1, f1 ) == f1 );
TESTCASE( fmaxf( f1, INFINITY ) == INFINITY );
TESTCASE( fmaxf( INFINITY, f1 ) == INFINITY );
TESTCASE( fmaxf( f1, -INFINITY ) == f1 );
TESTCASE( fmaxf( -INFINITY, f1 ) == f1 );
TESTCASE( fmaxf( f1, NAN ) == f1 );
TESTCASE( fmaxf( NAN, f1 ) == f1 );
TESTCASE( fmaxf( f1, -NAN ) == f1 );
TESTCASE( fmaxf( -NAN, f1 ) == f1 );
TESTCASE( fmaxf( NAN, NAN ) != fmaxf( NAN, NAN ) );
f1 = 0.0f;
f2 = -0.0f;
TESTCASE( fmaxf( f1, f2 ) == f1 );
TESTCASE( fmaxf( f2, f1 ) == f1 );
d1 = 3.15f;
d2 = 3.16f;
TESTCASE( fmax( d1, d2 ) == d2 );
TESTCASE( fmax( d2, d1 ) == d2 );
TESTCASE( fmax( d1, d1 ) == d1 );
TESTCASE( fmax( d1, INFINITY ) == INFINITY );
TESTCASE( fmax( INFINITY, d1 ) == INFINITY );
TESTCASE( fmax( d1, -INFINITY ) == d1 );
TESTCASE( fmax( -INFINITY, d1 ) == d1 );
TESTCASE( fmax( d1, NAN ) == d1 );
TESTCASE( fmax( NAN, d1 ) == d1 );
TESTCASE( fmax( d1, -NAN ) == d1 );
TESTCASE( fmax( -NAN, d1 ) == d1 );
TESTCASE( fmax( NAN, NAN ) != fmax( NAN, NAN ) );
d1 = 0.0;
d2 = -0.0;
TESTCASE( fmax( d1, d2 ) == d1 );
TESTCASE( fmax( d2, d1 ) == d1 );
ld1 = 3.15f;
ld2 = 3.16f;
TESTCASE( fmaxl( ld1, ld2 ) == ld2 );
TESTCASE( fmaxl( ld2, ld1 ) == ld2 );
TESTCASE( fmaxl( ld1, ld1 ) == ld1 );
TESTCASE( fmaxl( ld1, INFINITY ) == INFINITY );
TESTCASE( fmaxl( INFINITY, ld1 ) == INFINITY );
TESTCASE( fmaxl( ld1, -INFINITY ) == ld1 );
TESTCASE( fmaxl( -INFINITY, ld1 ) == ld1 );
TESTCASE( fmaxl( ld1, NAN ) == ld1 );
TESTCASE( fmaxl( NAN, ld1 ) == ld1 );
TESTCASE( fmaxl( ld1, -NAN ) == ld1 );
TESTCASE( fmaxl( -NAN, ld1 ) == ld1 );
TESTCASE( fmaxl( NAN, NAN ) != fmaxl( NAN, NAN ) );
ld1 = 0.0;
ld2 = -0.0;
TESTCASE( fmaxl( ld1, ld2 ) == ld1 );
TESTCASE( fmaxl( ld2, ld1 ) == ld1 );
return TEST_RESULTS;
}
#endif

View File

@@ -1,105 +0,0 @@
/* fmin( double )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <math.h>
#ifndef REGTEST
double fmin( double x, double y )
{
if ( isnan( x ) ) return y;
if ( isnan( y ) ) return x;
return ( x < y ) ? x : y;
}
float fminf( float x, float y )
{
if ( isnan( x ) ) return y;
if ( isnan( y ) ) return x;
return ( x < y ) ? x : y;
}
long double fminl( long double x, long double y )
{
if ( isnan( x ) ) return y;
if ( isnan( y ) ) return x;
return ( x < y ) ? x : y;
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
int main( void )
{
float f1, f2;
double d1, d2;
long double ld1, ld2;
f1 = 3.16f;
f2 = 3.15f;
TESTCASE( fminf( f1, f2 ) == f2 );
TESTCASE( fminf( f2, f1 ) == f2 );
TESTCASE( fminf( f1, f1 ) == f1 );
TESTCASE( fminf( f1, INFINITY ) == f1 );
TESTCASE( fminf( INFINITY, f1 ) == f1 );
TESTCASE( fminf( f1, -INFINITY ) == -INFINITY );
TESTCASE( fminf( -INFINITY, f1 ) == -INFINITY );
TESTCASE( fminf( f1, NAN ) == f1 );
TESTCASE( fminf( NAN, f1 ) == f1 );
TESTCASE( fminf( f1, -NAN ) == f1 );
TESTCASE( fminf( -NAN, f1 ) == f1 );
TESTCASE( fminf( NAN, NAN ) != fminf( NAN, NAN ) );
f1 = -0.0f;
f2 = 0.0f;
TESTCASE( fminf( f1, f2 ) == f1 );
TESTCASE( fminf( f2, f1 ) == f1 );
d1 = 3.16f;
d2 = 3.15f;
TESTCASE( fmin( d1, d2 ) == d2 );
TESTCASE( fmin( d2, d1 ) == d2 );
TESTCASE( fmin( d1, d1 ) == d1 );
TESTCASE( fmin( d1, INFINITY ) == d1 );
TESTCASE( fmin( INFINITY, d1 ) == d1 );
TESTCASE( fmin( d1, -INFINITY ) == -INFINITY );
TESTCASE( fmin( -INFINITY, d1 ) == -INFINITY );
TESTCASE( fmin( d1, NAN ) == d1 );
TESTCASE( fmin( NAN, d1 ) == d1 );
TESTCASE( fmin( d1, -NAN ) == d1 );
TESTCASE( fmin( -NAN, d1 ) == d1 );
TESTCASE( fmin( NAN, NAN ) != fmin( NAN, NAN ) );
d1 = -0.0;
d2 = 0.0;
TESTCASE( fmin( d1, d2 ) == d1 );
TESTCASE( fmin( d2, d1 ) == d1 );
ld1 = 3.16f;
ld2 = 3.15f;
TESTCASE( fminl( ld1, ld2 ) == ld2 );
TESTCASE( fminl( ld2, ld1 ) == ld2 );
TESTCASE( fminl( ld1, ld1 ) == ld1 );
TESTCASE( fminl( ld1, INFINITY ) == ld1 );
TESTCASE( fminl( INFINITY, ld1 ) == ld1 );
TESTCASE( fminl( ld1, -INFINITY ) == -INFINITY );
TESTCASE( fminl( -INFINITY, ld1 ) == -INFINITY );
TESTCASE( fminl( ld1, NAN ) == ld1 );
TESTCASE( fminl( NAN, ld1 ) == ld1 );
TESTCASE( fminl( ld1, -NAN ) == ld1 );
TESTCASE( fminl( -NAN, ld1 ) == ld1 );
TESTCASE( fminl( NAN, NAN ) != fminl( NAN, NAN ) );
ld1 = -0.0;
ld2 = 0.0;
TESTCASE( fminl( ld1, ld2 ) == ld1 );
TESTCASE( fminl( ld2, ld1 ) == ld1 );
return TEST_RESULTS;
}
#endif

View File

@@ -1,161 +0,0 @@
/* fpclassify( double )
This file is part of the Public Domain C Library (PDCLib).
Permission is granted to use, modify, and / or redistribute at will.
*/
#include <math.h>
#ifndef REGTEST
#include "pdclib/_PDCLIB_print.h"
#include <string.h>
int _PDCLIB_fpclassifyd( double x )
{
_PDCLIB_bigint_digit_t data[ sizeof( double ) / sizeof( _PDCLIB_bigint_digit_t ) ];
_PDCLIB_bigint_digit_t digit = 0;
size_t size;
size_t i;
int exp;
memcpy( data, &x, sizeof( double ) );
exp = _PDCLIB_DBL_EXP( data );
size = _PDCLIB_DBL_SIZE( data );
for ( i = 0; i < size; ++i )
{
digit |= data[i];
}
switch ( exp )
{
case ( ( _PDCLIB_DBL_MAX_EXP - 1 ) + _PDCLIB_DBL_MAX_EXP ):
return ( digit == 0 ) ? FP_INFINITE : FP_NAN;
case 0:
return ( digit == 0 ) ? FP_ZERO : FP_SUBNORMAL;
default:
return FP_NORMAL;
}
}
int _PDCLIB_fpclassifyf( float x )
{
_PDCLIB_bigint_digit_t data[ sizeof( float ) / sizeof( _PDCLIB_bigint_digit_t ) ];
_PDCLIB_bigint_digit_t digit = 0;
size_t size;
size_t i;
int exp;
memcpy( data, &x, sizeof( float ) );
exp = _PDCLIB_FLT_EXP( data );
size = _PDCLIB_FLT_SIZE( data );
for ( i = 0; i < size; ++i )
{
digit |= data[i];
}
switch ( exp )
{
case ( ( _PDCLIB_FLT_MAX_EXP - 1 ) + _PDCLIB_FLT_MAX_EXP ):
return ( digit == 0 ) ? FP_INFINITE : FP_NAN;
case 0:
return ( digit == 0 ) ? FP_ZERO : FP_SUBNORMAL;
default:
return FP_NORMAL;
}
}
int _PDCLIB_fpclassifyl( long double x )
{
_PDCLIB_bigint_digit_t data[ sizeof( long double ) / sizeof( _PDCLIB_bigint_digit_t ) ];
_PDCLIB_bigint_digit_t digit = 0;
size_t size;
size_t i;
int exp;
memcpy( data, &x, sizeof( long double ) );
exp = _PDCLIB_LDBL_EXP( data );
size = _PDCLIB_LDBL_SIZE( data );
for ( i = 0; i < size; ++i )
{
digit |= data[i];
}
switch ( exp )
{
case ( ( _PDCLIB_LDBL_MAX_EXP - 1 ) + _PDCLIB_LDBL_MAX_EXP ):
return ( digit == 0 ) ? FP_INFINITE : FP_NAN;
case 0:
return ( digit == 0 ) ? FP_ZERO : FP_SUBNORMAL;
default:
return FP_NORMAL;
}
}
#endif
#ifdef TEST
#include "_PDCLIB_test.h"
#include <float.h>
int main( void )
{
float f;
double d;
long double ld;
f = 0.123;
TESTCASE( fpclassify( f ) == FP_NORMAL );
f = FLT_MIN;
TESTCASE( fpclassify( f ) == FP_NORMAL );
f = FLT_MIN / 2;
TESTCASE( fpclassify( f ) == FP_SUBNORMAL );
f = 0.0;
TESTCASE( fpclassify( f ) == FP_ZERO );
f = FLT_MAX;
TESTCASE( fpclassify( f ) == FP_NORMAL );
f = FLT_MAX * 2;
TESTCASE( fpclassify( f ) == FP_INFINITE );
f = 0.0 / 0.0;
TESTCASE( fpclassify( f ) == FP_NAN );
d = 0.123;
TESTCASE( fpclassify( d ) == FP_NORMAL );
d = DBL_MIN;
TESTCASE( fpclassify( d ) == FP_NORMAL );
d = DBL_MIN / 2;
TESTCASE( fpclassify( d ) == FP_SUBNORMAL );
d = 0.0;
TESTCASE( fpclassify( d ) == FP_ZERO );
d = DBL_MAX;
TESTCASE( fpclassify( d ) == FP_NORMAL );
d = DBL_MAX * 2;
TESTCASE( fpclassify( d ) == FP_INFINITE );
d = 0.0 / 0.0;
TESTCASE( fpclassify( d ) == FP_NAN );
ld = 0.123;
TESTCASE( fpclassify( ld ) == FP_NORMAL );
ld = LDBL_MIN;
TESTCASE( fpclassify( ld ) == FP_NORMAL );
ld = LDBL_MIN / 2;
TESTCASE( fpclassify( ld ) == FP_SUBNORMAL );
ld = 0.0;
TESTCASE( fpclassify( ld ) == FP_ZERO );
ld = LDBL_MAX;
TESTCASE( fpclassify( ld ) == FP_NORMAL );
ld = LDBL_MAX * 2;
TESTCASE( fpclassify( ld ) == FP_INFINITE );
ld = 0.0 / 0.0;
TESTCASE( fpclassify( ld ) == FP_NAN );
return TEST_RESULTS;
}
#endif

Some files were not shown because too many files have changed in this diff Show More