removed pdclib, strange things were happening..., user shell kinda works now
This commit is contained in:
@@ -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).
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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( ÷nd, &testdata[0] );
|
||||
_PDCLIB_bigint_from_bigint( &divisor, &testdata[1] );
|
||||
TESTCASE( _PDCLIB_bigint_div( ÷nd, &divisor ) == 0 );
|
||||
TESTCASE( _PDCLIB_bigint_cmp( ÷nd, &testdata[0] ) == 0 );
|
||||
|
||||
_PDCLIB_bigint_from_bigint( ÷nd, &testdata[3] );
|
||||
_PDCLIB_bigint_from_bigint( &divisor, &testdata[2] );
|
||||
TESTCASE( _PDCLIB_bigint_div( ÷nd, &divisor ) == 0 );
|
||||
TESTCASE( _PDCLIB_bigint_cmp( ÷nd, &testdata[3] ) == 0 );
|
||||
|
||||
/* dividend = divisor + 1 */
|
||||
_PDCLIB_bigint_from_bigint( ÷nd, &testdata[2] );
|
||||
_PDCLIB_bigint_from_bigint( &divisor, &testdata[3] );
|
||||
TESTCASE( _PDCLIB_bigint_div( ÷nd, &divisor ) == 1 );
|
||||
TESTCASE( _PDCLIB_bigint_cmp( ÷nd, &testdata[4] ) == 0 );
|
||||
|
||||
/* dividend = divisor * 9 */
|
||||
_PDCLIB_bigint_from_bigint( ÷nd, &testdata[6] );
|
||||
_PDCLIB_bigint_from_bigint( &divisor, &testdata[7] );
|
||||
TESTCASE( _PDCLIB_bigint_div( ÷nd, &divisor ) == 9 );
|
||||
TESTCASE( dividend.size == 0 );
|
||||
|
||||
/* dividend = divisor * 9 + rem */
|
||||
_PDCLIB_bigint_from_bigint( ÷nd, &testdata[5] );
|
||||
_PDCLIB_bigint_from_digit( &divisor, testdata[5].data[0] / 9 );
|
||||
TESTCASE( _PDCLIB_bigint_div( ÷nd, &divisor ) == 9 );
|
||||
TESTCASE( dividend.data[0] == ( testdata[5].data[0] % 9 ) );
|
||||
#endif
|
||||
|
||||
return TEST_RESULTS;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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.
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
Reference in New Issue
Block a user