compiled newlib, need to hook up the system calls
This commit is contained in:
10
rocklibc/src/_PDCLIB/Readme.txt
Normal file
10
rocklibc/src/_PDCLIB/Readme.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
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).
|
||||
48
rocklibc/src/_PDCLIB/_PDCLIB_Exit.c
Normal file
48
rocklibc/src/_PDCLIB/_PDCLIB_Exit.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/* _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
|
||||
59
rocklibc/src/_PDCLIB/_PDCLIB_atomax.c
Normal file
59
rocklibc/src/_PDCLIB/_PDCLIB_atomax.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/* _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
|
||||
83
rocklibc/src/_PDCLIB/_PDCLIB_bigint_add.c
Normal file
83
rocklibc/src/_PDCLIB/_PDCLIB_bigint_add.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/* _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
|
||||
74
rocklibc/src/_PDCLIB/_PDCLIB_bigint_cmp.c
Normal file
74
rocklibc/src/_PDCLIB/_PDCLIB_bigint_cmp.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/* _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
|
||||
83
rocklibc/src/_PDCLIB/_PDCLIB_bigint_digit_log2.c
Normal file
83
rocklibc/src/_PDCLIB/_PDCLIB_bigint_digit_log2.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/* _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
|
||||
135
rocklibc/src/_PDCLIB/_PDCLIB_bigint_div.c
Normal file
135
rocklibc/src/_PDCLIB/_PDCLIB_bigint_div.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/* _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
|
||||
54
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_bigint.c
Normal file
54
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_bigint.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/* _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
|
||||
43
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_digit.c
Normal file
43
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_digit.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/* _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
|
||||
131
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_pow10.c
Normal file
131
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_pow10.c
Normal file
@@ -0,0 +1,131 @@
|
||||
/* _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
|
||||
54
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_pow2.c
Normal file
54
rocklibc/src/_PDCLIB/_PDCLIB_bigint_from_pow2.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/* _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
|
||||
64
rocklibc/src/_PDCLIB/_PDCLIB_bigint_log2.c
Normal file
64
rocklibc/src/_PDCLIB/_PDCLIB_bigint_log2.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/* _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
|
||||
121
rocklibc/src/_PDCLIB/_PDCLIB_bigint_mul.c
Normal file
121
rocklibc/src/_PDCLIB/_PDCLIB_bigint_mul.c
Normal file
@@ -0,0 +1,121 @@
|
||||
/* _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
|
||||
58
rocklibc/src/_PDCLIB/_PDCLIB_bigint_mul10.c
Normal file
58
rocklibc/src/_PDCLIB/_PDCLIB_bigint_mul10.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/* _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
|
||||
30
rocklibc/src/_PDCLIB/_PDCLIB_bigint_mul_pow10.c
Normal file
30
rocklibc/src/_PDCLIB/_PDCLIB_bigint_mul_pow10.c
Normal file
@@ -0,0 +1,30 @@
|
||||
/* _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
|
||||
83
rocklibc/src/_PDCLIB/_PDCLIB_bigint_shl.c
Normal file
83
rocklibc/src/_PDCLIB/_PDCLIB_bigint_shl.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/* _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
|
||||
73
rocklibc/src/_PDCLIB/_PDCLIB_changemode.c
Normal file
73
rocklibc/src/_PDCLIB/_PDCLIB_changemode.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/* _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
|
||||
44
rocklibc/src/_PDCLIB/_PDCLIB_close.c
Normal file
44
rocklibc/src/_PDCLIB/_PDCLIB_close.c
Normal file
@@ -0,0 +1,44 @@
|
||||
/* _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
|
||||
38
rocklibc/src/_PDCLIB/_PDCLIB_closeall.c
Normal file
38
rocklibc/src/_PDCLIB/_PDCLIB_closeall.c
Normal file
@@ -0,0 +1,38 @@
|
||||
/* _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
|
||||
33
rocklibc/src/_PDCLIB/_PDCLIB_digits.c
Normal file
33
rocklibc/src/_PDCLIB/_PDCLIB_digits.c
Normal file
@@ -0,0 +1,33 @@
|
||||
/* _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
|
||||
114
rocklibc/src/_PDCLIB/_PDCLIB_filemode.c
Normal file
114
rocklibc/src/_PDCLIB/_PDCLIB_filemode.c
Normal file
@@ -0,0 +1,114 @@
|
||||
/* _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
|
||||
77
rocklibc/src/_PDCLIB/_PDCLIB_fillbuffer.c
Normal file
77
rocklibc/src/_PDCLIB/_PDCLIB_fillbuffer.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/* _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
|
||||
103
rocklibc/src/_PDCLIB/_PDCLIB_flushbuffer.c
Normal file
103
rocklibc/src/_PDCLIB/_PDCLIB_flushbuffer.c
Normal file
@@ -0,0 +1,103 @@
|
||||
/* _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
|
||||
106
rocklibc/src/_PDCLIB/_PDCLIB_fp_from_dbl.c
Normal file
106
rocklibc/src/_PDCLIB/_PDCLIB_fp_from_dbl.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/* _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
|
||||
106
rocklibc/src/_PDCLIB/_PDCLIB_fp_from_ldbl.c
Normal file
106
rocklibc/src/_PDCLIB/_PDCLIB_fp_from_ldbl.c
Normal file
@@ -0,0 +1,106 @@
|
||||
/* _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
|
||||
49
rocklibc/src/_PDCLIB/_PDCLIB_getstream.c
Normal file
49
rocklibc/src/_PDCLIB/_PDCLIB_getstream.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/* _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
|
||||
82
rocklibc/src/_PDCLIB/_PDCLIB_init_file_t.c
Normal file
82
rocklibc/src/_PDCLIB/_PDCLIB_init_file_t.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/* _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
|
||||
39
rocklibc/src/_PDCLIB/_PDCLIB_is_leap.c
Normal file
39
rocklibc/src/_PDCLIB/_PDCLIB_is_leap.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/* _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
|
||||
49
rocklibc/src/_PDCLIB/_PDCLIB_isstream.c
Normal file
49
rocklibc/src/_PDCLIB/_PDCLIB_isstream.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/* _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
|
||||
63
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_collate.c
Normal file
63
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_collate.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/* _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
|
||||
365
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_ctype.c
Normal file
365
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_ctype.c
Normal file
@@ -0,0 +1,365 @@
|
||||
/* _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
|
||||
88
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_messages.c
Normal file
88
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_messages.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/* _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
|
||||
158
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_monetary.c
Normal file
158
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_monetary.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/* _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
|
||||
84
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_numeric.c
Normal file
84
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_numeric.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/* _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
|
||||
165
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_time.c
Normal file
165
rocklibc/src/_PDCLIB/_PDCLIB_load_lc_time.c
Normal file
@@ -0,0 +1,165 @@
|
||||
/* _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
|
||||
81
rocklibc/src/_PDCLIB/_PDCLIB_load_lines.c
Normal file
81
rocklibc/src/_PDCLIB/_PDCLIB_load_lines.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/* _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
|
||||
96
rocklibc/src/_PDCLIB/_PDCLIB_naive_etod.c
Normal file
96
rocklibc/src/_PDCLIB/_PDCLIB_naive_etod.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/* _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
|
||||
97
rocklibc/src/_PDCLIB/_PDCLIB_naive_ptod.c
Normal file
97
rocklibc/src/_PDCLIB/_PDCLIB_naive_ptod.c
Normal file
@@ -0,0 +1,97 @@
|
||||
/* _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
|
||||
42
rocklibc/src/_PDCLIB/_PDCLIB_prepread.c
Normal file
42
rocklibc/src/_PDCLIB/_PDCLIB_prepread.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/* _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
|
||||
39
rocklibc/src/_PDCLIB/_PDCLIB_prepwrite.c
Normal file
39
rocklibc/src/_PDCLIB/_PDCLIB_prepwrite.c
Normal file
@@ -0,0 +1,39 @@
|
||||
/* _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
|
||||
493
rocklibc/src/_PDCLIB/_PDCLIB_print.c
Normal file
493
rocklibc/src/_PDCLIB/_PDCLIB_print.c
Normal file
@@ -0,0 +1,493 @@
|
||||
/* _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
|
||||
390
rocklibc/src/_PDCLIB/_PDCLIB_print_fp.c
Normal file
390
rocklibc/src/_PDCLIB/_PDCLIB_print_fp.c
Normal file
@@ -0,0 +1,390 @@
|
||||
/* _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
|
||||
211
rocklibc/src/_PDCLIB/_PDCLIB_print_fp_deci.c
Normal file
211
rocklibc/src/_PDCLIB/_PDCLIB_print_fp_deci.c
Normal file
@@ -0,0 +1,211 @@
|
||||
/* _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
|
||||
268
rocklibc/src/_PDCLIB/_PDCLIB_print_fp_hexa.c
Normal file
268
rocklibc/src/_PDCLIB/_PDCLIB_print_fp_hexa.c
Normal file
@@ -0,0 +1,268 @@
|
||||
/* _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
|
||||
175
rocklibc/src/_PDCLIB/_PDCLIB_print_integer.c
Normal file
175
rocklibc/src/_PDCLIB/_PDCLIB_print_integer.c
Normal file
@@ -0,0 +1,175 @@
|
||||
/* _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
|
||||
85
rocklibc/src/_PDCLIB/_PDCLIB_print_string.c
Normal file
85
rocklibc/src/_PDCLIB/_PDCLIB_print_string.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/* _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
|
||||
61
rocklibc/src/_PDCLIB/_PDCLIB_realpath.c
Normal file
61
rocklibc/src/_PDCLIB/_PDCLIB_realpath.c
Normal file
@@ -0,0 +1,61 @@
|
||||
/* _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
|
||||
42
rocklibc/src/_PDCLIB/_PDCLIB_remove.c
Normal file
42
rocklibc/src/_PDCLIB/_PDCLIB_remove.c
Normal file
@@ -0,0 +1,42 @@
|
||||
/* _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
|
||||
117
rocklibc/src/_PDCLIB/_PDCLIB_rename.c
Normal file
117
rocklibc/src/_PDCLIB/_PDCLIB_rename.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/* _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
|
||||
781
rocklibc/src/_PDCLIB/_PDCLIB_scan.c
Normal file
781
rocklibc/src/_PDCLIB/_PDCLIB_scan.c
Normal file
@@ -0,0 +1,781 @@
|
||||
/* _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
|
||||
19
rocklibc/src/_PDCLIB/_PDCLIB_seed.c
Normal file
19
rocklibc/src/_PDCLIB/_PDCLIB_seed.c
Normal file
@@ -0,0 +1,19 @@
|
||||
/* _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
|
||||
81
rocklibc/src/_PDCLIB/_PDCLIB_seek.c
Normal file
81
rocklibc/src/_PDCLIB/_PDCLIB_seek.c
Normal file
@@ -0,0 +1,81 @@
|
||||
/* 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
|
||||
598
rocklibc/src/_PDCLIB/_PDCLIB_stdinit.c
Normal file
598
rocklibc/src/_PDCLIB/_PDCLIB_stdinit.c
Normal file
@@ -0,0 +1,598 @@
|
||||
/* _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
|
||||
135
rocklibc/src/_PDCLIB/_PDCLIB_strtod_prelim.c
Normal file
135
rocklibc/src/_PDCLIB/_PDCLIB_strtod_prelim.c
Normal file
@@ -0,0 +1,135 @@
|
||||
/* _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
|
||||
186
rocklibc/src/_PDCLIB/_PDCLIB_strtok.c
Normal file
186
rocklibc/src/_PDCLIB/_PDCLIB_strtok.c
Normal file
@@ -0,0 +1,186 @@
|
||||
/* _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
|
||||
99
rocklibc/src/_PDCLIB/_PDCLIB_strtox_main.c
Normal file
99
rocklibc/src/_PDCLIB/_PDCLIB_strtox_main.c
Normal file
@@ -0,0 +1,99 @@
|
||||
/* _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
|
||||
113
rocklibc/src/_PDCLIB/_PDCLIB_strtox_prelim.c
Normal file
113
rocklibc/src/_PDCLIB/_PDCLIB_strtox_prelim.c
Normal file
@@ -0,0 +1,113 @@
|
||||
/* _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
|
||||
73
rocklibc/src/_PDCLIB/assert.c
Normal file
73
rocklibc/src/_PDCLIB/assert.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/* _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
|
||||
71
rocklibc/src/_PDCLIB/errno.c
Normal file
71
rocklibc/src/_PDCLIB/errno.c
Normal file
@@ -0,0 +1,71 @@
|
||||
/* _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
|
||||
120
rocklibc/src/_PDCLIB/stdarg.c
Normal file
120
rocklibc/src/_PDCLIB/stdarg.c
Normal file
@@ -0,0 +1,120 @@
|
||||
/* 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
|
||||
Reference in New Issue
Block a user