2005-08-26 17:39:27 +00:00
//
//
// bg_lib,c -- standard C library replacement routines used by code
// compiled for the virtual machine
2007-09-22 20:32:11 +00:00
# ifdef Q3_VM
2005-10-26 19:45:21 +00:00
# include "../qcommon/q_shared.h"
2005-08-26 17:39:27 +00:00
/*-
* Copyright ( c ) 1992 , 1993
* The Regents of the University of California . All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
2006-01-18 18:46:32 +00:00
* 3. Neither the name of the University nor the names of its contributors
2005-08-26 17:39:27 +00:00
* may be used to endorse or promote products derived from this software
* without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ` ` AS IS ' ' AND
* ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT
* LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE .
*/
2005-10-27 21:13:47 +00:00
# include "bg_lib.h"
2005-08-26 17:39:27 +00:00
# if defined(LIBC_SCCS) && !defined(lint)
#if 0
static char sccsid [ ] = " @(#)qsort.c 8.1 (Berkeley) 6/4/93 " ;
# endif
static const char rcsid [ ] =
# endif /* LIBC_SCCS and not lint */
static char * med3 ( char * , char * , char * , cmp_t * ) ;
static void swapfunc ( char * , char * , int , int ) ;
/*
* Qsort routine from Bentley & McIlroy ' s " Engineering a Sort Function " .
*/
# define swapcode(TYPE, parmi, parmj, n) { \
long i = ( n ) / sizeof ( TYPE ) ; \
register TYPE * pi = ( TYPE * ) ( parmi ) ; \
register TYPE * pj = ( TYPE * ) ( parmj ) ; \
do { \
register TYPE t = * pi ; \
* pi + + = * pj ; \
* pj + + = t ; \
} while ( - - i > 0 ) ; \
}
# define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
es % sizeof ( long ) ? 2 : es = = sizeof ( long ) ? 0 : 1 ;
static void
swapfunc ( a , b , n , swaptype )
char * a , * b ;
int n , swaptype ;
{
if ( swaptype < = 1 )
swapcode ( long , a , b , n )
else
swapcode ( char , a , b , n )
}
# define swap(a, b) \
if ( swaptype = = 0 ) { \
long t = * ( long * ) ( a ) ; \
* ( long * ) ( a ) = * ( long * ) ( b ) ; \
* ( long * ) ( b ) = t ; \
} else \
swapfunc ( a , b , es , swaptype )
# define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
static char *
med3 ( a , b , c , cmp )
char * a , * b , * c ;
cmp_t * cmp ;
{
return cmp ( a , b ) < 0 ?
( cmp ( b , c ) < 0 ? b : ( cmp ( a , c ) < 0 ? c : a ) )
: ( cmp ( b , c ) > 0 ? b : ( cmp ( a , c ) < 0 ? a : c ) ) ;
}
void
qsort ( a , n , es , cmp )
void * a ;
size_t n , es ;
cmp_t * cmp ;
{
char * pa , * pb , * pc , * pd , * pl , * pm , * pn ;
int d , r , swaptype , swap_cnt ;
loop : SWAPINIT ( a , es ) ;
swap_cnt = 0 ;
if ( n < 7 ) {
for ( pm = ( char * ) a + es ; pm < ( char * ) a + n * es ; pm + = es )
for ( pl = pm ; pl > ( char * ) a & & cmp ( pl - es , pl ) > 0 ;
pl - = es )
swap ( pl , pl - es ) ;
return ;
}
pm = ( char * ) a + ( n / 2 ) * es ;
if ( n > 7 ) {
pl = a ;
pn = ( char * ) a + ( n - 1 ) * es ;
if ( n > 40 ) {
d = ( n / 8 ) * es ;
pl = med3 ( pl , pl + d , pl + 2 * d , cmp ) ;
pm = med3 ( pm - d , pm , pm + d , cmp ) ;
pn = med3 ( pn - 2 * d , pn - d , pn , cmp ) ;
}
pm = med3 ( pl , pm , pn , cmp ) ;
}
swap ( a , pm ) ;
pa = pb = ( char * ) a + es ;
pc = pd = ( char * ) a + ( n - 1 ) * es ;
for ( ; ; ) {
while ( pb < = pc & & ( r = cmp ( pb , a ) ) < = 0 ) {
if ( r = = 0 ) {
swap_cnt = 1 ;
swap ( pa , pb ) ;
pa + = es ;
}
pb + = es ;
}
while ( pb < = pc & & ( r = cmp ( pc , a ) ) > = 0 ) {
if ( r = = 0 ) {
swap_cnt = 1 ;
swap ( pc , pd ) ;
pd - = es ;
}
pc - = es ;
}
if ( pb > pc )
break ;
swap ( pb , pc ) ;
swap_cnt = 1 ;
pb + = es ;
pc - = es ;
}
if ( swap_cnt = = 0 ) { /* Switch to insertion sort */
for ( pm = ( char * ) a + es ; pm < ( char * ) a + n * es ; pm + = es )
for ( pl = pm ; pl > ( char * ) a & & cmp ( pl - es , pl ) > 0 ;
pl - = es )
swap ( pl , pl - es ) ;
return ;
}
pn = ( char * ) a + n * es ;
2011-05-15 13:27:24 +00:00
r = MIN ( pa - ( char * ) a , pb - pa ) ;
2005-08-26 17:39:27 +00:00
vecswap ( a , pb - r , r ) ;
2011-05-15 13:27:24 +00:00
r = MIN ( pd - pc , pn - pd - es ) ;
2005-08-26 17:39:27 +00:00
vecswap ( pb , pn - r , r ) ;
if ( ( r = pb - pa ) > es )
qsort ( a , r / es , es , cmp ) ;
if ( ( r = pd - pc ) > es ) {
/* Iterate rather than recurse to save stack space */
a = pn - r ;
n = r / es ;
goto loop ;
}
/* qsort(pn - r, r / es, es, cmp);*/
}
//==================================================================================
size_t strlen ( const char * string ) {
const char * s ;
s = string ;
while ( * s ) {
s + + ;
}
return s - string ;
}
char * strcat ( char * strDestination , const char * strSource ) {
char * s ;
s = strDestination ;
while ( * s ) {
s + + ;
}
while ( * strSource ) {
* s + + = * strSource + + ;
}
* s = 0 ;
return strDestination ;
}
char * strcpy ( char * strDestination , const char * strSource ) {
char * s ;
s = strDestination ;
while ( * strSource ) {
* s + + = * strSource + + ;
}
* s = 0 ;
return strDestination ;
}
int strcmp ( const char * string1 , const char * string2 ) {
while ( * string1 = = * string2 & & * string1 & & * string2 ) {
string1 + + ;
string2 + + ;
}
return * string1 - * string2 ;
}
char * strchr ( const char * string , int c ) {
while ( * string ) {
if ( * string = = c ) {
return ( char * ) string ;
}
string + + ;
}
2011-05-14 14:55:54 +00:00
if ( c )
return NULL ;
else
2011-05-14 20:24:34 +00:00
return ( char * ) string ;
2005-08-26 17:39:27 +00:00
}
2011-05-15 14:08:03 +00:00
char * strrchr ( const char * string , int c )
{
2011-05-15 14:58:56 +00:00
const char * found = NULL ;
2011-05-15 14:08:03 +00:00
while ( * string )
{
if ( * string = = c )
found = string ;
string + + ;
}
if ( c )
return ( char * ) found ;
else
return ( char * ) string ;
}
2005-08-26 17:39:27 +00:00
char * strstr ( const char * string , const char * strCharSet ) {
while ( * string ) {
int i ;
for ( i = 0 ; strCharSet [ i ] ; i + + ) {
if ( string [ i ] ! = strCharSet [ i ] ) {
break ;
}
}
if ( ! strCharSet [ i ] ) {
return ( char * ) string ;
}
string + + ;
}
return ( char * ) 0 ;
}
int tolower ( int c ) {
if ( c > = ' A ' & & c < = ' Z ' ) {
c + = ' a ' - ' A ' ;
}
return c ;
}
int toupper ( int c ) {
if ( c > = ' a ' & & c < = ' z ' ) {
c + = ' A ' - ' a ' ;
}
return c ;
}
2011-02-08 21:27:45 +00:00
void * memmove ( void * dest , const void * src , size_t count )
{
size_t i ;
if ( count )
{
if ( dest > src )
{
2011-02-08 21:38:49 +00:00
i = count ;
2011-02-08 21:27:45 +00:00
do
{
i - - ;
2011-02-08 21:38:49 +00:00
( ( char * ) dest ) [ i ] = ( ( char * ) src ) [ i ] ;
2011-02-08 21:27:45 +00:00
} while ( i > 0 ) ;
2005-08-26 17:39:27 +00:00
}
2011-02-08 21:27:45 +00:00
else
{
for ( i = 0 ; i < count ; i + + )
( ( char * ) dest ) [ i ] = ( ( char * ) src ) [ i ] ;
2005-08-26 17:39:27 +00:00
}
}
2011-02-08 21:27:45 +00:00
2005-08-26 17:39:27 +00:00
return dest ;
}
#if 0
double floor ( double x ) {
return ( int ) ( x + 0x40000000 ) - 0x40000000 ;
}
void * memset ( void * dest , int c , size_t count ) {
while ( count - - ) {
( ( char * ) dest ) [ count ] = c ;
}
return dest ;
}
void * memcpy ( void * dest , const void * src , size_t count ) {
while ( count - - ) {
( ( char * ) dest ) [ count ] = ( ( char * ) src ) [ count ] ;
}
return dest ;
}
char * strncpy ( char * strDest , const char * strSource , size_t count ) {
char * s ;
s = strDest ;
while ( * strSource & & count ) {
* s + + = * strSource + + ;
count - - ;
}
while ( count - - ) {
* s + + = 0 ;
}
return strDest ;
}
double sqrt ( double x ) {
float y ;
float delta ;
float maxError ;
if ( x < = 0 ) {
return 0 ;
}
// initial guess
y = x / 2 ;
// refine
maxError = x * 0.001 ;
do {
delta = ( y * y ) - x ;
y - = delta / ( 2 * y ) ;
} while ( delta > maxError | | delta < - maxError ) ;
return y ;
}
float sintable [ 1024 ] = {
0.000000 , 0.001534 , 0.003068 , 0.004602 , 0.006136 , 0.007670 , 0.009204 , 0.010738 ,
0.012272 , 0.013805 , 0.015339 , 0.016873 , 0.018407 , 0.019940 , 0.021474 , 0.023008 ,
0.024541 , 0.026075 , 0.027608 , 0.029142 , 0.030675 , 0.032208 , 0.033741 , 0.035274 ,
0.036807 , 0.038340 , 0.039873 , 0.041406 , 0.042938 , 0.044471 , 0.046003 , 0.047535 ,
0.049068 , 0.050600 , 0.052132 , 0.053664 , 0.055195 , 0.056727 , 0.058258 , 0.059790 ,
0.061321 , 0.062852 , 0.064383 , 0.065913 , 0.067444 , 0.068974 , 0.070505 , 0.072035 ,
0.073565 , 0.075094 , 0.076624 , 0.078153 , 0.079682 , 0.081211 , 0.082740 , 0.084269 ,
0.085797 , 0.087326 , 0.088854 , 0.090381 , 0.091909 , 0.093436 , 0.094963 , 0.096490 ,
0.098017 , 0.099544 , 0.101070 , 0.102596 , 0.104122 , 0.105647 , 0.107172 , 0.108697 ,
0.110222 , 0.111747 , 0.113271 , 0.114795 , 0.116319 , 0.117842 , 0.119365 , 0.120888 ,
0.122411 , 0.123933 , 0.125455 , 0.126977 , 0.128498 , 0.130019 , 0.131540 , 0.133061 ,
0.134581 , 0.136101 , 0.137620 , 0.139139 , 0.140658 , 0.142177 , 0.143695 , 0.145213 ,
0.146730 , 0.148248 , 0.149765 , 0.151281 , 0.152797 , 0.154313 , 0.155828 , 0.157343 ,
0.158858 , 0.160372 , 0.161886 , 0.163400 , 0.164913 , 0.166426 , 0.167938 , 0.169450 ,
0.170962 , 0.172473 , 0.173984 , 0.175494 , 0.177004 , 0.178514 , 0.180023 , 0.181532 ,
0.183040 , 0.184548 , 0.186055 , 0.187562 , 0.189069 , 0.190575 , 0.192080 , 0.193586 ,
0.195090 , 0.196595 , 0.198098 , 0.199602 , 0.201105 , 0.202607 , 0.204109 , 0.205610 ,
0.207111 , 0.208612 , 0.210112 , 0.211611 , 0.213110 , 0.214609 , 0.216107 , 0.217604 ,
0.219101 , 0.220598 , 0.222094 , 0.223589 , 0.225084 , 0.226578 , 0.228072 , 0.229565 ,
0.231058 , 0.232550 , 0.234042 , 0.235533 , 0.237024 , 0.238514 , 0.240003 , 0.241492 ,
0.242980 , 0.244468 , 0.245955 , 0.247442 , 0.248928 , 0.250413 , 0.251898 , 0.253382 ,
0.254866 , 0.256349 , 0.257831 , 0.259313 , 0.260794 , 0.262275 , 0.263755 , 0.265234 ,
0.266713 , 0.268191 , 0.269668 , 0.271145 , 0.272621 , 0.274097 , 0.275572 , 0.277046 ,
0.278520 , 0.279993 , 0.281465 , 0.282937 , 0.284408 , 0.285878 , 0.287347 , 0.288816 ,
0.290285 , 0.291752 , 0.293219 , 0.294685 , 0.296151 , 0.297616 , 0.299080 , 0.300543 ,
0.302006 , 0.303468 , 0.304929 , 0.306390 , 0.307850 , 0.309309 , 0.310767 , 0.312225 ,
0.313682 , 0.315138 , 0.316593 , 0.318048 , 0.319502 , 0.320955 , 0.322408 , 0.323859 ,
0.325310 , 0.326760 , 0.328210 , 0.329658 , 0.331106 , 0.332553 , 0.334000 , 0.335445 ,
0.336890 , 0.338334 , 0.339777 , 0.341219 , 0.342661 , 0.344101 , 0.345541 , 0.346980 ,
0.348419 , 0.349856 , 0.351293 , 0.352729 , 0.354164 , 0.355598 , 0.357031 , 0.358463 ,
0.359895 , 0.361326 , 0.362756 , 0.364185 , 0.365613 , 0.367040 , 0.368467 , 0.369892 ,
0.371317 , 0.372741 , 0.374164 , 0.375586 , 0.377007 , 0.378428 , 0.379847 , 0.381266 ,
0.382683 , 0.384100 , 0.385516 , 0.386931 , 0.388345 , 0.389758 , 0.391170 , 0.392582 ,
0.393992 , 0.395401 , 0.396810 , 0.398218 , 0.399624 , 0.401030 , 0.402435 , 0.403838 ,
0.405241 , 0.406643 , 0.408044 , 0.409444 , 0.410843 , 0.412241 , 0.413638 , 0.415034 ,
0.416430 , 0.417824 , 0.419217 , 0.420609 , 0.422000 , 0.423390 , 0.424780 , 0.426168 ,
0.427555 , 0.428941 , 0.430326 , 0.431711 , 0.433094 , 0.434476 , 0.435857 , 0.437237 ,
0.438616 , 0.439994 , 0.441371 , 0.442747 , 0.444122 , 0.445496 , 0.446869 , 0.448241 ,
0.449611 , 0.450981 , 0.452350 , 0.453717 , 0.455084 , 0.456449 , 0.457813 , 0.459177 ,
0.460539 , 0.461900 , 0.463260 , 0.464619 , 0.465976 , 0.467333 , 0.468689 , 0.470043 ,
0.471397 , 0.472749 , 0.474100 , 0.475450 , 0.476799 , 0.478147 , 0.479494 , 0.480839 ,
0.482184 , 0.483527 , 0.484869 , 0.486210 , 0.487550 , 0.488889 , 0.490226 , 0.491563 ,
0.492898 , 0.494232 , 0.495565 , 0.496897 , 0.498228 , 0.499557 , 0.500885 , 0.502212 ,
0.503538 , 0.504863 , 0.506187 , 0.507509 , 0.508830 , 0.510150 , 0.511469 , 0.512786 ,
0.514103 , 0.515418 , 0.516732 , 0.518045 , 0.519356 , 0.520666 , 0.521975 , 0.523283 ,
0.524590 , 0.525895 , 0.527199 , 0.528502 , 0.529804 , 0.531104 , 0.532403 , 0.533701 ,
0.534998 , 0.536293 , 0.537587 , 0.538880 , 0.540171 , 0.541462 , 0.542751 , 0.544039 ,
0.545325 , 0.546610 , 0.547894 , 0.549177 , 0.550458 , 0.551738 , 0.553017 , 0.554294 ,
0.555570 , 0.556845 , 0.558119 , 0.559391 , 0.560662 , 0.561931 , 0.563199 , 0.564466 ,
0.565732 , 0.566996 , 0.568259 , 0.569521 , 0.570781 , 0.572040 , 0.573297 , 0.574553 ,
0.575808 , 0.577062 , 0.578314 , 0.579565 , 0.580814 , 0.582062 , 0.583309 , 0.584554 ,
0.585798 , 0.587040 , 0.588282 , 0.589521 , 0.590760 , 0.591997 , 0.593232 , 0.594466 ,
0.595699 , 0.596931 , 0.598161 , 0.599389 , 0.600616 , 0.601842 , 0.603067 , 0.604290 ,
0.605511 , 0.606731 , 0.607950 , 0.609167 , 0.610383 , 0.611597 , 0.612810 , 0.614022 ,
0.615232 , 0.616440 , 0.617647 , 0.618853 , 0.620057 , 0.621260 , 0.622461 , 0.623661 ,
0.624859 , 0.626056 , 0.627252 , 0.628446 , 0.629638 , 0.630829 , 0.632019 , 0.633207 ,
0.634393 , 0.635578 , 0.636762 , 0.637944 , 0.639124 , 0.640303 , 0.641481 , 0.642657 ,
0.643832 , 0.645005 , 0.646176 , 0.647346 , 0.648514 , 0.649681 , 0.650847 , 0.652011 ,
0.653173 , 0.654334 , 0.655493 , 0.656651 , 0.657807 , 0.658961 , 0.660114 , 0.661266 ,
0.662416 , 0.663564 , 0.664711 , 0.665856 , 0.667000 , 0.668142 , 0.669283 , 0.670422 ,
0.671559 , 0.672695 , 0.673829 , 0.674962 , 0.676093 , 0.677222 , 0.678350 , 0.679476 ,
0.680601 , 0.681724 , 0.682846 , 0.683965 , 0.685084 , 0.686200 , 0.687315 , 0.688429 ,
0.689541 , 0.690651 , 0.691759 , 0.692866 , 0.693971 , 0.695075 , 0.696177 , 0.697278 ,
0.698376 , 0.699473 , 0.700569 , 0.701663 , 0.702755 , 0.703845 , 0.704934 , 0.706021 ,
0.707107 , 0.708191 , 0.709273 , 0.710353 , 0.711432 , 0.712509 , 0.713585 , 0.714659 ,
0.715731 , 0.716801 , 0.717870 , 0.718937 , 0.720003 , 0.721066 , 0.722128 , 0.723188 ,
0.724247 , 0.725304 , 0.726359 , 0.727413 , 0.728464 , 0.729514 , 0.730563 , 0.731609 ,
0.732654 , 0.733697 , 0.734739 , 0.735779 , 0.736817 , 0.737853 , 0.738887 , 0.739920 ,
0.740951 , 0.741980 , 0.743008 , 0.744034 , 0.745058 , 0.746080 , 0.747101 , 0.748119 ,
0.749136 , 0.750152 , 0.751165 , 0.752177 , 0.753187 , 0.754195 , 0.755201 , 0.756206 ,
0.757209 , 0.758210 , 0.759209 , 0.760207 , 0.761202 , 0.762196 , 0.763188 , 0.764179 ,
0.765167 , 0.766154 , 0.767139 , 0.768122 , 0.769103 , 0.770083 , 0.771061 , 0.772036 ,
0.773010 , 0.773983 , 0.774953 , 0.775922 , 0.776888 , 0.777853 , 0.778817 , 0.779778 ,
0.780737 , 0.781695 , 0.782651 , 0.783605 , 0.784557 , 0.785507 , 0.786455 , 0.787402 ,
0.788346 , 0.789289 , 0.790230 , 0.791169 , 0.792107 , 0.793042 , 0.793975 , 0.794907 ,
0.795837 , 0.796765 , 0.797691 , 0.798615 , 0.799537 , 0.800458 , 0.801376 , 0.802293 ,
0.803208 , 0.804120 , 0.805031 , 0.805940 , 0.806848 , 0.807753 , 0.808656 , 0.809558 ,
0.810457 , 0.811355 , 0.812251 , 0.813144 , 0.814036 , 0.814926 , 0.815814 , 0.816701 ,
0.817585 , 0.818467 , 0.819348 , 0.820226 , 0.821103 , 0.821977 , 0.822850 , 0.823721 ,
0.824589 , 0.825456 , 0.826321 , 0.827184 , 0.828045 , 0.828904 , 0.829761 , 0.830616 ,
0.831470 , 0.832321 , 0.833170 , 0.834018 , 0.834863 , 0.835706 , 0.836548 , 0.837387 ,
0.838225 , 0.839060 , 0.839894 , 0.840725 , 0.841555 , 0.842383 , 0.843208 , 0.844032 ,
0.844854 , 0.845673 , 0.846491 , 0.847307 , 0.848120 , 0.848932 , 0.849742 , 0.850549 ,
0.851355 , 0.852159 , 0.852961 , 0.853760 , 0.854558 , 0.855354 , 0.856147 , 0.856939 ,
0.857729 , 0.858516 , 0.859302 , 0.860085 , 0.860867 , 0.861646 , 0.862424 , 0.863199 ,
0.863973 , 0.864744 , 0.865514 , 0.866281 , 0.867046 , 0.867809 , 0.868571 , 0.869330 ,
0.870087 , 0.870842 , 0.871595 , 0.872346 , 0.873095 , 0.873842 , 0.874587 , 0.875329 ,
0.876070 , 0.876809 , 0.877545 , 0.878280 , 0.879012 , 0.879743 , 0.880471 , 0.881197 ,
0.881921 , 0.882643 , 0.883363 , 0.884081 , 0.884797 , 0.885511 , 0.886223 , 0.886932 ,
0.887640 , 0.888345 , 0.889048 , 0.889750 , 0.890449 , 0.891146 , 0.891841 , 0.892534 ,
0.893224 , 0.893913 , 0.894599 , 0.895284 , 0.895966 , 0.896646 , 0.897325 , 0.898001 ,
0.898674 , 0.899346 , 0.900016 , 0.900683 , 0.901349 , 0.902012 , 0.902673 , 0.903332 ,
0.903989 , 0.904644 , 0.905297 , 0.905947 , 0.906596 , 0.907242 , 0.907886 , 0.908528 ,
0.909168 , 0.909806 , 0.910441 , 0.911075 , 0.911706 , 0.912335 , 0.912962 , 0.913587 ,
0.914210 , 0.914830 , 0.915449 , 0.916065 , 0.916679 , 0.917291 , 0.917901 , 0.918508 ,
0.919114 , 0.919717 , 0.920318 , 0.920917 , 0.921514 , 0.922109 , 0.922701 , 0.923291 ,
0.923880 , 0.924465 , 0.925049 , 0.925631 , 0.926210 , 0.926787 , 0.927363 , 0.927935 ,
0.928506 , 0.929075 , 0.929641 , 0.930205 , 0.930767 , 0.931327 , 0.931884 , 0.932440 ,
0.932993 , 0.933544 , 0.934093 , 0.934639 , 0.935184 , 0.935726 , 0.936266 , 0.936803 ,
0.937339 , 0.937872 , 0.938404 , 0.938932 , 0.939459 , 0.939984 , 0.940506 , 0.941026 ,
0.941544 , 0.942060 , 0.942573 , 0.943084 , 0.943593 , 0.944100 , 0.944605 , 0.945107 ,
0.945607 , 0.946105 , 0.946601 , 0.947094 , 0.947586 , 0.948075 , 0.948561 , 0.949046 ,
0.949528 , 0.950008 , 0.950486 , 0.950962 , 0.951435 , 0.951906 , 0.952375 , 0.952842 ,
0.953306 , 0.953768 , 0.954228 , 0.954686 , 0.955141 , 0.955594 , 0.956045 , 0.956494 ,
0.956940 , 0.957385 , 0.957826 , 0.958266 , 0.958703 , 0.959139 , 0.959572 , 0.960002 ,
0.960431 , 0.960857 , 0.961280 , 0.961702 , 0.962121 , 0.962538 , 0.962953 , 0.963366 ,
0.963776 , 0.964184 , 0.964590 , 0.964993 , 0.965394 , 0.965793 , 0.966190 , 0.966584 ,
0.966976 , 0.967366 , 0.967754 , 0.968139 , 0.968522 , 0.968903 , 0.969281 , 0.969657 ,
0.970031 , 0.970403 , 0.970772 , 0.971139 , 0.971504 , 0.971866 , 0.972226 , 0.972584 ,
0.972940 , 0.973293 , 0.973644 , 0.973993 , 0.974339 , 0.974684 , 0.975025 , 0.975365 ,
0.975702 , 0.976037 , 0.976370 , 0.976700 , 0.977028 , 0.977354 , 0.977677 , 0.977999 ,
0.978317 , 0.978634 , 0.978948 , 0.979260 , 0.979570 , 0.979877 , 0.980182 , 0.980485 ,
0.980785 , 0.981083 , 0.981379 , 0.981673 , 0.981964 , 0.982253 , 0.982539 , 0.982824 ,
0.983105 , 0.983385 , 0.983662 , 0.983937 , 0.984210 , 0.984480 , 0.984749 , 0.985014 ,
0.985278 , 0.985539 , 0.985798 , 0.986054 , 0.986308 , 0.986560 , 0.986809 , 0.987057 ,
0.987301 , 0.987544 , 0.987784 , 0.988022 , 0.988258 , 0.988491 , 0.988722 , 0.988950 ,
0.989177 , 0.989400 , 0.989622 , 0.989841 , 0.990058 , 0.990273 , 0.990485 , 0.990695 ,
0.990903 , 0.991108 , 0.991311 , 0.991511 , 0.991710 , 0.991906 , 0.992099 , 0.992291 ,
0.992480 , 0.992666 , 0.992850 , 0.993032 , 0.993212 , 0.993389 , 0.993564 , 0.993737 ,
0.993907 , 0.994075 , 0.994240 , 0.994404 , 0.994565 , 0.994723 , 0.994879 , 0.995033 ,
0.995185 , 0.995334 , 0.995481 , 0.995625 , 0.995767 , 0.995907 , 0.996045 , 0.996180 ,
0.996313 , 0.996443 , 0.996571 , 0.996697 , 0.996820 , 0.996941 , 0.997060 , 0.997176 ,
0.997290 , 0.997402 , 0.997511 , 0.997618 , 0.997723 , 0.997825 , 0.997925 , 0.998023 ,
0.998118 , 0.998211 , 0.998302 , 0.998390 , 0.998476 , 0.998559 , 0.998640 , 0.998719 ,
0.998795 , 0.998870 , 0.998941 , 0.999011 , 0.999078 , 0.999142 , 0.999205 , 0.999265 ,
0.999322 , 0.999378 , 0.999431 , 0.999481 , 0.999529 , 0.999575 , 0.999619 , 0.999660 ,
0.999699 , 0.999735 , 0.999769 , 0.999801 , 0.999831 , 0.999858 , 0.999882 , 0.999905 ,
0.999925 , 0.999942 , 0.999958 , 0.999971 , 0.999981 , 0.999989 , 0.999995 , 0.999999
} ;
double sin ( double x ) {
int index ;
int quad ;
index = 1024 * x / ( M_PI * 0.5 ) ;
quad = ( index > > 10 ) & 3 ;
index & = 1023 ;
switch ( quad ) {
case 0 :
return sintable [ index ] ;
case 1 :
return sintable [ 1023 - index ] ;
case 2 :
return - sintable [ index ] ;
case 3 :
return - sintable [ 1023 - index ] ;
}
return 0 ;
}
double cos ( double x ) {
int index ;
int quad ;
index = 1024 * x / ( M_PI * 0.5 ) ;
quad = ( index > > 10 ) & 3 ;
index & = 1023 ;
switch ( quad ) {
case 3 :
return sintable [ index ] ;
case 0 :
return sintable [ 1023 - index ] ;
case 1 :
return - sintable [ index ] ;
case 2 :
return - sintable [ 1023 - index ] ;
}
return 0 ;
}
/*
void create_acostable ( void ) {
int i ;
FILE * fp ;
float a ;
fp = fopen ( " c: \\ acostable.txt " , " w " ) ;
fprintf ( fp , " float acostable[] = { " ) ;
for ( i = 0 ; i < 1024 ; i + + ) {
if ( ! ( i & 7 ) )
fprintf ( fp , " \n " ) ;
a = acos ( ( float ) - 1 + i / 512 ) ;
fprintf ( fp , " %1.8f, " , a ) ;
}
fprintf ( fp , " \n } \n " ) ;
fclose ( fp ) ;
}
*/
float acostable [ ] = {
3.14159265 , 3.07908248 , 3.05317551 , 3.03328655 , 3.01651113 , 3.00172442 , 2.98834964 , 2.97604422 ,
2.96458497 , 2.95381690 , 2.94362719 , 2.93393068 , 2.92466119 , 2.91576615 , 2.90720289 , 2.89893629 ,
2.89093699 , 2.88318015 , 2.87564455 , 2.86831188 , 2.86116621 , 2.85419358 , 2.84738169 , 2.84071962 ,
2.83419760 , 2.82780691 , 2.82153967 , 2.81538876 , 2.80934770 , 2.80341062 , 2.79757211 , 2.79182724 ,
2.78617145 , 2.78060056 , 2.77511069 , 2.76969824 , 2.76435988 , 2.75909250 , 2.75389319 , 2.74875926 ,
2.74368816 , 2.73867752 , 2.73372510 , 2.72882880 , 2.72398665 , 2.71919677 , 2.71445741 , 2.70976688 ,
2.70512362 , 2.70052613 , 2.69597298 , 2.69146283 , 2.68699438 , 2.68256642 , 2.67817778 , 2.67382735 ,
2.66951407 , 2.66523692 , 2.66099493 , 2.65678719 , 2.65261279 , 2.64847088 , 2.64436066 , 2.64028133 ,
2.63623214 , 2.63221238 , 2.62822133 , 2.62425835 , 2.62032277 , 2.61641398 , 2.61253138 , 2.60867440 ,
2.60484248 , 2.60103507 , 2.59725167 , 2.59349176 , 2.58975488 , 2.58604053 , 2.58234828 , 2.57867769 ,
2.57502832 , 2.57139977 , 2.56779164 , 2.56420354 , 2.56063509 , 2.55708594 , 2.55355572 , 2.55004409 ,
2.54655073 , 2.54307530 , 2.53961750 , 2.53617701 , 2.53275354 , 2.52934680 , 2.52595650 , 2.52258238 ,
2.51922417 , 2.51588159 , 2.51255441 , 2.50924238 , 2.50594525 , 2.50266278 , 2.49939476 , 2.49614096 ,
2.49290115 , 2.48967513 , 2.48646269 , 2.48326362 , 2.48007773 , 2.47690482 , 2.47374472 , 2.47059722 ,
2.46746215 , 2.46433933 , 2.46122860 , 2.45812977 , 2.45504269 , 2.45196720 , 2.44890314 , 2.44585034 ,
2.44280867 , 2.43977797 , 2.43675809 , 2.43374890 , 2.43075025 , 2.42776201 , 2.42478404 , 2.42181622 ,
2.41885841 , 2.41591048 , 2.41297232 , 2.41004380 , 2.40712480 , 2.40421521 , 2.40131491 , 2.39842379 ,
2.39554173 , 2.39266863 , 2.38980439 , 2.38694889 , 2.38410204 , 2.38126374 , 2.37843388 , 2.37561237 ,
2.37279910 , 2.36999400 , 2.36719697 , 2.36440790 , 2.36162673 , 2.35885335 , 2.35608768 , 2.35332964 ,
2.35057914 , 2.34783610 , 2.34510044 , 2.34237208 , 2.33965094 , 2.33693695 , 2.33423003 , 2.33153010 ,
2.32883709 , 2.32615093 , 2.32347155 , 2.32079888 , 2.31813284 , 2.31547337 , 2.31282041 , 2.31017388 ,
2.30753373 , 2.30489988 , 2.30227228 , 2.29965086 , 2.29703556 , 2.29442632 , 2.29182309 , 2.28922580 ,
2.28663439 , 2.28404881 , 2.28146900 , 2.27889490 , 2.27632647 , 2.27376364 , 2.27120637 , 2.26865460 ,
2.26610827 , 2.26356735 , 2.26103177 , 2.25850149 , 2.25597646 , 2.25345663 , 2.25094195 , 2.24843238 ,
2.24592786 , 2.24342836 , 2.24093382 , 2.23844420 , 2.23595946 , 2.23347956 , 2.23100444 , 2.22853408 ,
2.22606842 , 2.22360742 , 2.22115104 , 2.21869925 , 2.21625199 , 2.21380924 , 2.21137096 , 2.20893709 ,
2.20650761 , 2.20408248 , 2.20166166 , 2.19924511 , 2.19683280 , 2.19442469 , 2.19202074 , 2.18962092 ,
2.18722520 , 2.18483354 , 2.18244590 , 2.18006225 , 2.17768257 , 2.17530680 , 2.17293493 , 2.17056692 ,
2.16820274 , 2.16584236 , 2.16348574 , 2.16113285 , 2.15878367 , 2.15643816 , 2.15409630 , 2.15175805 ,
2.14942338 , 2.14709226 , 2.14476468 , 2.14244059 , 2.14011997 , 2.13780279 , 2.13548903 , 2.13317865 ,
2.13087163 , 2.12856795 , 2.12626757 , 2.12397047 , 2.12167662 , 2.11938600 , 2.11709859 , 2.11481435 ,
2.11253326 , 2.11025530 , 2.10798044 , 2.10570867 , 2.10343994 , 2.10117424 , 2.09891156 , 2.09665185 ,
2.09439510 , 2.09214129 , 2.08989040 , 2.08764239 , 2.08539725 , 2.08315496 , 2.08091550 , 2.07867884 ,
2.07644495 , 2.07421383 , 2.07198545 , 2.06975978 , 2.06753681 , 2.06531651 , 2.06309887 , 2.06088387 ,
2.05867147 , 2.05646168 , 2.05425445 , 2.05204979 , 2.04984765 , 2.04764804 , 2.04545092 , 2.04325628 ,
2.04106409 , 2.03887435 , 2.03668703 , 2.03450211 , 2.03231957 , 2.03013941 , 2.02796159 , 2.02578610 ,
2.02361292 , 2.02144204 , 2.01927344 , 2.01710710 , 2.01494300 , 2.01278113 , 2.01062146 , 2.00846399 ,
2.00630870 , 2.00415556 , 2.00200457 , 1.99985570 , 1.99770895 , 1.99556429 , 1.99342171 , 1.99128119 ,
1.98914271 , 1.98700627 , 1.98487185 , 1.98273942 , 1.98060898 , 1.97848051 , 1.97635399 , 1.97422942 ,
1.97210676 , 1.96998602 , 1.96786718 , 1.96575021 , 1.96363511 , 1.96152187 , 1.95941046 , 1.95730088 ,
1.95519310 , 1.95308712 , 1.95098292 , 1.94888050 , 1.94677982 , 1.94468089 , 1.94258368 , 1.94048818 ,
1.93839439 , 1.93630228 , 1.93421185 , 1.93212308 , 1.93003595 , 1.92795046 , 1.92586659 , 1.92378433 ,
1.92170367 , 1.91962459 , 1.91754708 , 1.91547113 , 1.91339673 , 1.91132385 , 1.90925250 , 1.90718266 ,
1.90511432 , 1.90304746 , 1.90098208 , 1.89891815 , 1.89685568 , 1.89479464 , 1.89273503 , 1.89067683 ,
1.88862003 , 1.88656463 , 1.88451060 , 1.88245794 , 1.88040664 , 1.87835668 , 1.87630806 , 1.87426076 ,
1.87221477 , 1.87017008 , 1.86812668 , 1.86608457 , 1.86404371 , 1.86200412 , 1.85996577 , 1.85792866 ,
1.85589277 , 1.85385809 , 1.85182462 , 1.84979234 , 1.84776125 , 1.84573132 , 1.84370256 , 1.84167495 ,
1.83964848 , 1.83762314 , 1.83559892 , 1.83357582 , 1.83155381 , 1.82953289 , 1.82751305 , 1.82549429 ,
1.82347658 , 1.82145993 , 1.81944431 , 1.81742973 , 1.81541617 , 1.81340362 , 1.81139207 , 1.80938151 ,
1.80737194 , 1.80536334 , 1.80335570 , 1.80134902 , 1.79934328 , 1.79733848 , 1.79533460 , 1.79333164 ,
1.79132959 , 1.78932843 , 1.78732817 , 1.78532878 , 1.78333027 , 1.78133261 , 1.77933581 , 1.77733985 ,
1.77534473 , 1.77335043 , 1.77135695 , 1.76936428 , 1.76737240 , 1.76538132 , 1.76339101 , 1.76140148 ,
1.75941271 , 1.75742470 , 1.75543743 , 1.75345090 , 1.75146510 , 1.74948002 , 1.74749565 , 1.74551198 ,
1.74352900 , 1.74154672 , 1.73956511 , 1.73758417 , 1.73560389 , 1.73362426 , 1.73164527 , 1.72966692 ,
1.72768920 , 1.72571209 , 1.72373560 , 1.72175971 , 1.71978441 , 1.71780969 , 1.71583556 , 1.71386199 ,
1.71188899 , 1.70991653 , 1.70794462 , 1.70597325 , 1.70400241 , 1.70203209 , 1.70006228 , 1.69809297 ,
1.69612416 , 1.69415584 , 1.69218799 , 1.69022062 , 1.68825372 , 1.68628727 , 1.68432127 , 1.68235571 ,
1.68039058 , 1.67842588 , 1.67646160 , 1.67449772 , 1.67253424 , 1.67057116 , 1.66860847 , 1.66664615 ,
1.66468420 , 1.66272262 , 1.66076139 , 1.65880050 , 1.65683996 , 1.65487975 , 1.65291986 , 1.65096028 ,
1.64900102 , 1.64704205 , 1.64508338 , 1.64312500 , 1.64116689 , 1.63920905 , 1.63725148 , 1.63529416 ,
1.63333709 , 1.63138026 , 1.62942366 , 1.62746728 , 1.62551112 , 1.62355517 , 1.62159943 , 1.61964388 ,
1.61768851 , 1.61573332 , 1.61377831 , 1.61182346 , 1.60986877 , 1.60791422 , 1.60595982 , 1.60400556 ,
1.60205142 , 1.60009739 , 1.59814349 , 1.59618968 , 1.59423597 , 1.59228235 , 1.59032882 , 1.58837536 ,
1.58642196 , 1.58446863 , 1.58251535 , 1.58056211 , 1.57860891 , 1.57665574 , 1.57470259 , 1.57274945 ,
1.57079633 , 1.56884320 , 1.56689007 , 1.56493692 , 1.56298375 , 1.56103055 , 1.55907731 , 1.55712403 ,
1.55517069 , 1.55321730 , 1.55126383 , 1.54931030 , 1.54735668 , 1.54540297 , 1.54344917 , 1.54149526 ,
1.53954124 , 1.53758710 , 1.53563283 , 1.53367843 , 1.53172389 , 1.52976919 , 1.52781434 , 1.52585933 ,
1.52390414 , 1.52194878 , 1.51999323 , 1.51803748 , 1.51608153 , 1.51412537 , 1.51216900 , 1.51021240 ,
1.50825556 , 1.50629849 , 1.50434117 , 1.50238360 , 1.50042576 , 1.49846765 , 1.49650927 , 1.49455060 ,
1.49259163 , 1.49063237 , 1.48867280 , 1.48671291 , 1.48475270 , 1.48279215 , 1.48083127 , 1.47887004 ,
1.47690845 , 1.47494650 , 1.47298419 , 1.47102149 , 1.46905841 , 1.46709493 , 1.46513106 , 1.46316677 ,
1.46120207 , 1.45923694 , 1.45727138 , 1.45530538 , 1.45333893 , 1.45137203 , 1.44940466 , 1.44743682 ,
1.44546850 , 1.44349969 , 1.44153038 , 1.43956057 , 1.43759024 , 1.43561940 , 1.43364803 , 1.43167612 ,
1.42970367 , 1.42773066 , 1.42575709 , 1.42378296 , 1.42180825 , 1.41983295 , 1.41785705 , 1.41588056 ,
1.41390346 , 1.41192573 , 1.40994738 , 1.40796840 , 1.40598877 , 1.40400849 , 1.40202755 , 1.40004594 ,
1.39806365 , 1.39608068 , 1.39409701 , 1.39211264 , 1.39012756 , 1.38814175 , 1.38615522 , 1.38416795 ,
1.38217994 , 1.38019117 , 1.37820164 , 1.37621134 , 1.37422025 , 1.37222837 , 1.37023570 , 1.36824222 ,
1.36624792 , 1.36425280 , 1.36225684 , 1.36026004 , 1.35826239 , 1.35626387 , 1.35426449 , 1.35226422 ,
1.35026307 , 1.34826101 , 1.34625805 , 1.34425418 , 1.34224937 , 1.34024364 , 1.33823695 , 1.33622932 ,
1.33422072 , 1.33221114 , 1.33020059 , 1.32818904 , 1.32617649 , 1.32416292 , 1.32214834 , 1.32013273 ,
1.31811607 , 1.31609837 , 1.31407960 , 1.31205976 , 1.31003885 , 1.30801684 , 1.30599373 , 1.30396951 ,
1.30194417 , 1.29991770 , 1.29789009 , 1.29586133 , 1.29383141 , 1.29180031 , 1.28976803 , 1.28773456 ,
1.28569989 , 1.28366400 , 1.28162688 , 1.27958854 , 1.27754894 , 1.27550809 , 1.27346597 , 1.27142257 ,
1.26937788 , 1.26733189 , 1.26528459 , 1.26323597 , 1.26118602 , 1.25913471 , 1.25708205 , 1.25502803 ,
1.25297262 , 1.25091583 , 1.24885763 , 1.24679802 , 1.24473698 , 1.24267450 , 1.24061058 , 1.23854519 ,
1.23647833 , 1.23440999 , 1.23234015 , 1.23026880 , 1.22819593 , 1.22612152 , 1.22404557 , 1.22196806 ,
1.21988898 , 1.21780832 , 1.21572606 , 1.21364219 , 1.21155670 , 1.20946958 , 1.20738080 , 1.20529037 ,
1.20319826 , 1.20110447 , 1.19900898 , 1.19691177 , 1.19481283 , 1.19271216 , 1.19060973 , 1.18850553 ,
1.18639955 , 1.18429178 , 1.18218219 , 1.18007079 , 1.17795754 , 1.17584244 , 1.17372548 , 1.17160663 ,
1.16948589 , 1.16736324 , 1.16523866 , 1.16311215 , 1.16098368 , 1.15885323 , 1.15672081 , 1.15458638 ,
1.15244994 , 1.15031147 , 1.14817095 , 1.14602836 , 1.14388370 , 1.14173695 , 1.13958808 , 1.13743709 ,
1.13528396 , 1.13312866 , 1.13097119 , 1.12881153 , 1.12664966 , 1.12448556 , 1.12231921 , 1.12015061 ,
1.11797973 , 1.11580656 , 1.11363107 , 1.11145325 , 1.10927308 , 1.10709055 , 1.10490563 , 1.10271831 ,
1.10052856 , 1.09833638 , 1.09614174 , 1.09394462 , 1.09174500 , 1.08954287 , 1.08733820 , 1.08513098 ,
1.08292118 , 1.08070879 , 1.07849378 , 1.07627614 , 1.07405585 , 1.07183287 , 1.06960721 , 1.06737882 ,
1.06514770 , 1.06291382 , 1.06067715 , 1.05843769 , 1.05619540 , 1.05395026 , 1.05170226 , 1.04945136 ,
1.04719755 , 1.04494080 , 1.04268110 , 1.04041841 , 1.03815271 , 1.03588399 , 1.03361221 , 1.03133735 ,
1.02905939 , 1.02677830 , 1.02449407 , 1.02220665 , 1.01991603 , 1.01762219 , 1.01532509 , 1.01302471 ,
1.01072102 , 1.00841400 , 1.00610363 , 1.00378986 , 1.00147268 , 0.99915206 , 0.99682798 , 0.99450039 ,
0.99216928 , 0.98983461 , 0.98749636 , 0.98515449 , 0.98280898 , 0.98045980 , 0.97810691 , 0.97575030 ,
0.97338991 , 0.97102573 , 0.96865772 , 0.96628585 , 0.96391009 , 0.96153040 , 0.95914675 , 0.95675912 ,
0.95436745 , 0.95197173 , 0.94957191 , 0.94716796 , 0.94475985 , 0.94234754 , 0.93993099 , 0.93751017 ,
0.93508504 , 0.93265556 , 0.93022170 , 0.92778341 , 0.92534066 , 0.92289341 , 0.92044161 , 0.91798524 ,
0.91552424 , 0.91305858 , 0.91058821 , 0.90811309 , 0.90563319 , 0.90314845 , 0.90065884 , 0.89816430 ,
0.89566479 , 0.89316028 , 0.89065070 , 0.88813602 , 0.88561619 , 0.88309116 , 0.88056088 , 0.87802531 ,
0.87548438 , 0.87293806 , 0.87038629 , 0.86782901 , 0.86526619 , 0.86269775 , 0.86012366 , 0.85754385 ,
0.85495827 , 0.85236686 , 0.84976956 , 0.84716633 , 0.84455709 , 0.84194179 , 0.83932037 , 0.83669277 ,
0.83405893 , 0.83141877 , 0.82877225 , 0.82611928 , 0.82345981 , 0.82079378 , 0.81812110 , 0.81544172 ,
0.81275556 , 0.81006255 , 0.80736262 , 0.80465570 , 0.80194171 , 0.79922057 , 0.79649221 , 0.79375655 ,
0.79101352 , 0.78826302 , 0.78550497 , 0.78273931 , 0.77996593 , 0.77718475 , 0.77439569 , 0.77159865 ,
0.76879355 , 0.76598029 , 0.76315878 , 0.76032891 , 0.75749061 , 0.75464376 , 0.75178826 , 0.74892402 ,
0.74605092 , 0.74316887 , 0.74027775 , 0.73737744 , 0.73446785 , 0.73154885 , 0.72862033 , 0.72568217 ,
0.72273425 , 0.71977644 , 0.71680861 , 0.71383064 , 0.71084240 , 0.70784376 , 0.70483456 , 0.70181469 ,
0.69878398 , 0.69574231 , 0.69268952 , 0.68962545 , 0.68654996 , 0.68346288 , 0.68036406 , 0.67725332 ,
0.67413051 , 0.67099544 , 0.66784794 , 0.66468783 , 0.66151492 , 0.65832903 , 0.65512997 , 0.65191753 ,
0.64869151 , 0.64545170 , 0.64219789 , 0.63892987 , 0.63564741 , 0.63235028 , 0.62903824 , 0.62571106 ,
0.62236849 , 0.61901027 , 0.61563615 , 0.61224585 , 0.60883911 , 0.60541564 , 0.60197515 , 0.59851735 ,
0.59504192 , 0.59154856 , 0.58803694 , 0.58450672 , 0.58095756 , 0.57738911 , 0.57380101 , 0.57019288 ,
0.56656433 , 0.56291496 , 0.55924437 , 0.55555212 , 0.55183778 , 0.54810089 , 0.54434099 , 0.54055758 ,
0.53675018 , 0.53291825 , 0.52906127 , 0.52517867 , 0.52126988 , 0.51733431 , 0.51337132 , 0.50938028 ,
0.50536051 , 0.50131132 , 0.49723200 , 0.49312177 , 0.48897987 , 0.48480547 , 0.48059772 , 0.47635573 ,
0.47207859 , 0.46776530 , 0.46341487 , 0.45902623 , 0.45459827 , 0.45012983 , 0.44561967 , 0.44106652 ,
0.43646903 , 0.43182577 , 0.42713525 , 0.42239588 , 0.41760600 , 0.41276385 , 0.40786755 , 0.40291513 ,
0.39790449 , 0.39283339 , 0.38769946 , 0.38250016 , 0.37723277 , 0.37189441 , 0.36648196 , 0.36099209 ,
0.35542120 , 0.34976542 , 0.34402054 , 0.33818204 , 0.33224495 , 0.32620390 , 0.32005298 , 0.31378574 ,
0.30739505 , 0.30087304 , 0.29421096 , 0.28739907 , 0.28042645 , 0.27328078 , 0.26594810 , 0.25841250 ,
0.25065566 , 0.24265636 , 0.23438976 , 0.22582651 , 0.21693146 , 0.20766198 , 0.19796546 , 0.18777575 ,
0.17700769 , 0.16554844 , 0.15324301 , 0.13986823 , 0.12508152 , 0.10830610 , 0.08841715 , 0.06251018 ,
}
double acos ( double x ) {
int index ;
if ( x < - 1 )
x = - 1 ;
if ( x > 1 )
x = 1 ;
index = ( float ) ( 1.0 + x ) * 511.9 ;
return acostable [ index ] ;
}
double atan2 ( double y , double x ) {
float base ;
float temp ;
float dir ;
float test ;
int i ;
if ( x < 0 ) {
if ( y > = 0 ) {
// quad 1
base = M_PI / 2 ;
temp = x ;
x = y ;
y = - temp ;
} else {
// quad 2
base = M_PI ;
x = - x ;
y = - y ;
}
} else {
if ( y < 0 ) {
// quad 3
base = 3 * M_PI / 2 ;
temp = x ;
x = - y ;
y = temp ;
}
}
if ( y > x ) {
base + = M_PI / 2 ;
temp = x ;
x = y ;
y = temp ;
dir = - 1 ;
} else {
dir = 1 ;
}
// calcualte angle in octant 0
if ( x = = 0 ) {
return base ;
}
y / = x ;
for ( i = 0 ; i < 512 ; i + + ) {
test = sintable [ i ] / sintable [ 1023 - i ] ;
if ( test > y ) {
break ;
}
}
return base + dir * i * ( M_PI / 2048 ) ;
}
# endif
double tan ( double x ) {
return sin ( x ) / cos ( x ) ;
}
static int randSeed = 0 ;
void srand ( unsigned seed ) {
randSeed = seed ;
}
int rand ( void ) {
randSeed = ( 69069 * randSeed + 1 ) ;
return randSeed & 0x7fff ;
}
double atof ( const char * string ) {
float sign ;
float value ;
int c ;
// skip whitespace
while ( * string < = ' ' ) {
if ( ! * string ) {
return 0 ;
}
string + + ;
}
// check sign
switch ( * string ) {
case ' + ' :
string + + ;
sign = 1 ;
break ;
case ' - ' :
string + + ;
sign = - 1 ;
break ;
default :
sign = 1 ;
break ;
}
// read digits
value = 0 ;
c = string [ 0 ] ;
if ( c ! = ' . ' ) {
do {
c = * string + + ;
if ( c < ' 0 ' | | c > ' 9 ' ) {
break ;
}
c - = ' 0 ' ;
value = value * 10 + c ;
} while ( 1 ) ;
} else {
string + + ;
}
// check for decimal point
if ( c = = ' . ' ) {
double fraction ;
fraction = 0.1 ;
do {
c = * string + + ;
if ( c < ' 0 ' | | c > ' 9 ' ) {
break ;
}
c - = ' 0 ' ;
value + = c * fraction ;
fraction * = 0.1 ;
} while ( 1 ) ;
}
// not handling 10e10 notation...
return value * sign ;
}
double _atof ( const char * * stringPtr ) {
const char * string ;
float sign ;
float value ;
2007-09-05 18:17:46 +00:00
int c = ' 0 ' ;
2005-08-26 17:39:27 +00:00
string = * stringPtr ;
// skip whitespace
while ( * string < = ' ' ) {
if ( ! * string ) {
* stringPtr = string ;
return 0 ;
}
string + + ;
}
// check sign
switch ( * string ) {
case ' + ' :
string + + ;
sign = 1 ;
break ;
case ' - ' :
string + + ;
sign = - 1 ;
break ;
default :
sign = 1 ;
break ;
}
// read digits
value = 0 ;
if ( string [ 0 ] ! = ' . ' ) {
do {
c = * string + + ;
if ( c < ' 0 ' | | c > ' 9 ' ) {
break ;
}
c - = ' 0 ' ;
value = value * 10 + c ;
} while ( 1 ) ;
}
// check for decimal point
if ( c = = ' . ' ) {
double fraction ;
fraction = 0.1 ;
do {
c = * string + + ;
if ( c < ' 0 ' | | c > ' 9 ' ) {
break ;
}
c - = ' 0 ' ;
value + = c * fraction ;
fraction * = 0.1 ;
} while ( 1 ) ;
}
// not handling 10e10 notation...
* stringPtr = string ;
return value * sign ;
}
2009-10-21 10:18:46 +00:00
/*
= = = = = = = = = = = = = =
strtod
Without an errno variable , this is a fair bit less useful than it is in libc
but it ' s still a fair bit more capable than atof or _atof
Handles inf [ inity ] , nan ( ignoring case ) , hexadecimals , and decimals
Handles decimal exponents like 10e10 and hex exponents like 0x7f8 p20
10e10 = = 10000000000 ( power of ten )
0x7f8 p20 = = 0x7f800000 ( decimal power of two )
The variable pointed to by endptr will hold the location of the first character
in the nptr string that was not used in the conversion
= = = = = = = = = = = = = =
*/
2011-02-04 16:09:05 +00:00
double strtod ( const char * nptr , char * * endptr )
2009-10-21 10:18:46 +00:00
{
double res ;
qboolean neg = qfalse ;
// skip whitespace
while ( isspace ( * nptr ) )
nptr + + ;
// special string parsing
if ( Q_stricmpn ( nptr , " nan " , 3 ) = = 0 )
{
floatint_t nan ;
2011-02-04 15:07:32 +00:00
if ( endptr )
2011-02-04 16:09:05 +00:00
* endptr = ( char * ) & nptr [ 3 ] ;
2011-02-04 15:07:32 +00:00
2009-10-21 10:18:46 +00:00
// nan can be followed by a bracketed number (in hex, octal,
// or decimal) which is then put in the mantissa
// this can be used to generate signalling or quiet NaNs, for
// example (though I doubt it'll ever be used)
// note that nan(0) is infinity!
if ( nptr [ 3 ] = = ' ( ' )
{
2011-02-04 16:09:05 +00:00
char * end ;
2009-10-21 10:18:46 +00:00
int mantissa = strtol ( & nptr [ 4 ] , & end , 0 ) ;
if ( * end = = ' ) ' )
{
nan . ui = 0x7f800000 | ( mantissa & 0x7fffff ) ;
if ( endptr )
* endptr = & end [ 1 ] ;
return nan . f ;
}
}
nan . ui = 0x7fffffff ;
return nan . f ;
}
if ( Q_stricmpn ( nptr , " inf " , 3 ) = = 0 )
{
floatint_t inf ;
inf . ui = 0x7f800000 ;
if ( endptr = = NULL )
return inf . f ;
if ( Q_stricmpn ( & nptr [ 3 ] , " inity " , 5 ) = = 0 )
2011-02-04 16:09:05 +00:00
* endptr = ( char * ) & nptr [ 8 ] ;
2009-10-21 10:18:46 +00:00
else
2011-02-04 16:09:05 +00:00
* endptr = ( char * ) & nptr [ 3 ] ;
2009-10-21 10:18:46 +00:00
return inf . f ;
}
// normal numeric parsing
// sign
if ( * nptr = = ' - ' )
{
nptr + + ;
neg = qtrue ;
}
else if ( * nptr = = ' + ' )
nptr + + ;
// hex
if ( Q_stricmpn ( nptr , " 0x " , 2 ) = = 0 )
{
// track if we use any digits
const char * s = & nptr [ 1 ] , * end = s ;
nptr + = 2 ;
res = 0 ;
while ( qtrue )
{
if ( isdigit ( * nptr ) )
res = 16 * res + ( * nptr + + - ' 0 ' ) ;
else if ( * nptr > = ' A ' & & * nptr < = ' F ' )
res = 16 * res + 10 + * nptr + + - ' A ' ;
else if ( * nptr > = ' a ' & & * nptr < = ' f ' )
res = 16 * res + 10 + * nptr + + - ' a ' ;
else
break ;
}
// if nptr moved, save it
if ( end + 1 < nptr )
end = nptr ;
if ( * nptr = = ' . ' )
{
float place ;
nptr + + ;
// 1.0 / 16.0 == 0.0625
// I don't expect the float accuracy to hold out for
// very long but since we need to know the length of
// the string anyway we keep on going regardless
for ( place = 0.0625 ; ; place / = 16.0 )
{
if ( isdigit ( * nptr ) )
res + = place * ( * nptr + + - ' 0 ' ) ;
else if ( * nptr > = ' A ' & & * nptr < = ' F ' )
res + = place * ( 10 + * nptr + + - ' A ' ) ;
else if ( * nptr > = ' a ' & & * nptr < = ' f ' )
res + = place * ( 10 + * nptr + + - ' a ' ) ;
else
break ;
}
if ( end < nptr )
end = nptr ;
}
// parse an optional exponent, representing multiplication
// by a power of two
// exponents are only valid if we encountered at least one
// digit already (and have therefore set end to something)
if ( end ! = s & & tolower ( * nptr ) = = ' p ' )
{
int exp ;
float res2 ;
// apparently (confusingly) the exponent should be
// decimal
2011-02-04 16:09:05 +00:00
exp = strtol ( & nptr [ 1 ] , ( char * * ) & end , 10 ) ;
2009-10-21 10:18:46 +00:00
if ( & nptr [ 1 ] = = end )
{
// no exponent
if ( endptr )
2011-02-04 16:09:05 +00:00
* endptr = ( char * ) nptr ;
2009-10-21 10:18:46 +00:00
return res ;
}
if ( exp > 0 )
{
while ( exp - - > 0 )
{
res2 = res * 2 ;
// check for infinity
if ( res2 < = res )
break ;
res = res2 ;
}
}
else
{
while ( exp + + < 0 )
{
res2 = res / 2 ;
// check for underflow
if ( res2 > = res )
break ;
res = res2 ;
}
}
}
if ( endptr )
2011-02-04 16:09:05 +00:00
* endptr = ( char * ) end ;
2009-10-21 10:18:46 +00:00
return res ;
}
// decimal
else
{
// track if we find any digits
const char * end = nptr , * p = nptr ;
// this is most of the work
for ( res = 0 ; isdigit ( * nptr ) ;
res = 10 * res + * nptr + + - ' 0 ' ) ;
// if nptr moved, we read something
if ( end < nptr )
end = nptr ;
if ( * nptr = = ' . ' )
{
// fractional part
float place ;
nptr + + ;
for ( place = 0.1 ; isdigit ( * nptr ) ; place / = 10.0 )
res + = ( * nptr + + - ' 0 ' ) * place ;
// if nptr moved, we read something
if ( end + 1 < nptr )
end = nptr ;
}
// exponent
// meaningless without having already read digits, so check
// we've set end to something
if ( p ! = end & & tolower ( * nptr ) = = ' e ' )
{
int exp ;
float res10 ;
2011-02-04 16:09:05 +00:00
exp = strtol ( & nptr [ 1 ] , ( char * * ) & end , 10 ) ;
2009-10-21 10:18:46 +00:00
if ( & nptr [ 1 ] = = end )
{
// no exponent
if ( endptr )
2011-02-04 16:09:05 +00:00
* endptr = ( char * ) nptr ;
2009-10-21 10:18:46 +00:00
return res ;
}
if ( exp > 0 )
{
while ( exp - - > 0 )
{
res10 = res * 10 ;
// check for infinity to save us time
if ( res10 < = res )
break ;
res = res10 ;
}
}
else if ( exp < 0 )
{
while ( exp + + < 0 )
{
res10 = res / 10 ;
// check for underflow
// (test for 0 would probably be just
// as good)
if ( res10 > = res )
break ;
res = res10 ;
}
}
}
if ( endptr )
2011-02-04 16:09:05 +00:00
* endptr = ( char * ) end ;
2009-10-21 10:18:46 +00:00
return res ;
}
}
2005-08-26 17:39:27 +00:00
int atoi ( const char * string ) {
int sign ;
int value ;
int c ;
// skip whitespace
while ( * string < = ' ' ) {
if ( ! * string ) {
return 0 ;
}
string + + ;
}
// check sign
switch ( * string ) {
case ' + ' :
string + + ;
sign = 1 ;
break ;
case ' - ' :
string + + ;
sign = - 1 ;
break ;
default :
sign = 1 ;
break ;
}
// read digits
value = 0 ;
do {
c = * string + + ;
if ( c < ' 0 ' | | c > ' 9 ' ) {
break ;
}
c - = ' 0 ' ;
value = value * 10 + c ;
} while ( 1 ) ;
// not handling 10e10 notation...
return value * sign ;
}
int _atoi ( const char * * stringPtr ) {
int sign ;
int value ;
int c ;
const char * string ;
string = * stringPtr ;
// skip whitespace
while ( * string < = ' ' ) {
if ( ! * string ) {
return 0 ;
}
string + + ;
}
// check sign
switch ( * string ) {
case ' + ' :
string + + ;
sign = 1 ;
break ;
case ' - ' :
string + + ;
sign = - 1 ;
break ;
default :
sign = 1 ;
break ;
}
// read digits
value = 0 ;
do {
c = * string + + ;
if ( c < ' 0 ' | | c > ' 9 ' ) {
break ;
}
c - = ' 0 ' ;
value = value * 10 + c ;
} while ( 1 ) ;
// not handling 10e10 notation...
* stringPtr = string ;
return value * sign ;
}
2009-10-21 10:18:46 +00:00
/*
= = = = = = = = = = = = = =
strtol
Handles any base from 2 to 36. If base is 0 then it guesses
decimal , hex , or octal based on the format of the number ( leading 0 or 0 x )
Will not overflow - returns LONG_MIN or LONG_MAX as appropriate
* endptr is set to the location of the first character not used
= = = = = = = = = = = = = =
*/
2011-02-04 16:09:05 +00:00
long strtol ( const char * nptr , char * * endptr , int base )
2009-10-21 10:18:46 +00:00
{
long res ;
qboolean pos = qtrue ;
if ( endptr )
2011-02-04 16:09:05 +00:00
* endptr = ( char * ) nptr ;
2009-10-21 10:18:46 +00:00
// bases other than 0, 2, 8, 16 are very rarely used, but they're
// not much extra effort to support
if ( base < 0 | | base = = 1 | | base > 36 )
return 0 ;
// skip leading whitespace
while ( isspace ( * nptr ) )
nptr + + ;
// sign
if ( * nptr = = ' - ' )
{
nptr + + ;
pos = qfalse ;
}
else if ( * nptr = = ' + ' )
nptr + + ;
// look for base-identifying sequences e.g. 0x for hex, 0 for octal
if ( nptr [ 0 ] = = ' 0 ' )
{
nptr + + ;
// 0 is always a valid digit
if ( endptr )
2011-02-04 16:09:05 +00:00
* endptr = ( char * ) nptr ;
2009-10-21 10:18:46 +00:00
if ( * nptr = = ' x ' | | * nptr = = ' X ' )
{
if ( base ! = 0 & & base ! = 16 )
{
// can't be hex, reject x (accept 0)
if ( endptr )
2011-02-04 16:09:05 +00:00
* endptr = ( char * ) nptr ;
2009-10-21 10:18:46 +00:00
return 0 ;
}
nptr + + ;
base = 16 ;
}
else if ( base = = 0 )
base = 8 ;
}
else if ( base = = 0 )
base = 10 ;
res = 0 ;
while ( qtrue )
{
int val ;
if ( isdigit ( * nptr ) )
val = * nptr - ' 0 ' ;
else if ( islower ( * nptr ) )
val = 10 + * nptr - ' a ' ;
else if ( isupper ( * nptr ) )
val = 10 + * nptr - ' A ' ;
else
break ;
if ( val > = base )
break ;
// we go negative because LONG_MIN is further from 0 than
// LONG_MAX
if ( res < ( LONG_MIN + val ) / base )
res = LONG_MIN ; // overflow
else
res = res * base - val ;
nptr + + ;
if ( endptr )
2011-02-04 16:09:05 +00:00
* endptr = ( char * ) nptr ;
2009-10-21 10:18:46 +00:00
}
if ( pos )
{
// can't represent LONG_MIN positive
if ( res = = LONG_MIN )
res = LONG_MAX ;
else
res = - res ;
}
return res ;
}
2005-08-26 17:39:27 +00:00
int abs ( int n ) {
return n < 0 ? - n : n ;
}
double fabs ( double x ) {
return x < 0 ? - x : x ;
}
//=========================================================
2008-03-25 21:36:09 +00:00
/*
* New implementation by Patrick Powell and others for vsnprintf .
* Supports length checking in strings .
*/
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
/*
* Copyright Patrick Powell 1995
* This code is based on code written by Patrick Powell ( papowell @ astart . com )
* It may be used for any purpose as long as this notice remains intact
* on all source code distributions
*/
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
/**************************************************************
* Original :
* Patrick Powell Tue Apr 11 09 : 48 : 21 PDT 1995
* A bombproof version of doprnt ( dopr ) included .
* Sigh . This sort of thing is always nasty do deal with . Note that
* the version here does not include floating point . . .
*
* snprintf ( ) is used instead of sprintf ( ) as it does limit checks
* for string length . This covers a nasty loophole .
*
* The other functions are there to prevent NULL pointers from
* causing nast effects .
*
* More Recently :
* Brandon Long < blong @ fiction . net > 9 / 15 / 96 for mutt 0.43
* This was ugly . It is still ugly . I opted out of floating point
* numbers , but the formatter understands just about everything
* from the normal C string format , at least as far as I can tell from
* the Solaris 2.5 printf ( 3 S ) man page .
*
* Brandon Long < blong @ fiction . net > 10 / 22 / 97 for mutt 0.87 .1
* Ok , added some minimal floating point support , which means this
* probably requires libm on most operating systems . Don ' t yet
* support the exponent ( e , E ) and sigfig ( g , G ) . Also , fmtint ( )
* was pretty badly broken , it just wasn ' t being exercised in ways
* which showed it , so that ' s been fixed . Also , formated the code
* to mutt conventions , and removed dead code left over from the
* original . Also , there is now a builtin - test , just compile with :
* gcc - DTEST_SNPRINTF - o snprintf snprintf . c - lm
* and run snprintf for results .
*
* Thomas Roessler < roessler @ guug . de > 01 / 27 / 98 for mutt 0.89 i
* The PGP code was using unsigned hexadecimal formats .
* Unfortunately , unsigned formats simply didn ' t work .
*
* Michael Elkins < me @ cs . hmc . edu > 03 / 05 / 98 for mutt 0.90 .8
* The original code assumed that both snprintf ( ) and vsnprintf ( ) were
* missing . Some systems only have snprintf ( ) but not vsnprintf ( ) , so
* the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF .
*
* Andrew Tridgell ( tridge @ samba . org ) Oct 1998
* fixed handling of % .0f
* added test for HAVE_LONG_DOUBLE
*
* Russ Allbery < rra @ stanford . edu > 2000 - 08 - 26
* fixed return value to comply with C99
* fixed handling of snprintf ( NULL , . . . )
*
* Hrvoje Niksic < hniksic @ arsdigita . com > 2000 - 11 - 04
* include < config . h > instead of " config.h " .
* moved TEST_SNPRINTF stuff out of HAVE_SNPRINTF ifdef .
* include < stdio . h > for NULL .
* added support and test cases for long long .
* don ' t declare argument types to ( v ) snprintf if stdarg is not used .
* use int instead of short int as 2 nd arg to va_arg .
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
/* BDR 2002-01-13 %e and %g were being ignored. Now do something,
if not necessarily correctly */
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
# if (SIZEOF_LONG_DOUBLE > 0)
/* #ifdef HAVE_LONG_DOUBLE */
# define LDOUBLE long double
# else
# define LDOUBLE double
# endif
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
# if (SIZEOF_LONG_LONG > 0)
/* #ifdef HAVE_LONG_LONG */
# define LLONG long long
# else
# define LLONG long
# endif
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
static int dopr ( char * buffer , size_t maxlen , const char * format ,
va_list args ) ;
static int fmtstr ( char * buffer , size_t * currlen , size_t maxlen ,
char * value , int flags , int min , int max ) ;
static int fmtint ( char * buffer , size_t * currlen , size_t maxlen ,
LLONG value , int base , int min , int max , int flags ) ;
static int fmtfp ( char * buffer , size_t * currlen , size_t maxlen ,
LDOUBLE fvalue , int min , int max , int flags ) ;
static int dopr_outch ( char * buffer , size_t * currlen , size_t maxlen , char c ) ;
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
/*
* dopr ( ) : poor man ' s version of doprintf
*/
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
/* format read states */
# define DP_S_DEFAULT 0
# define DP_S_FLAGS 1
# define DP_S_MIN 2
# define DP_S_DOT 3
# define DP_S_MAX 4
# define DP_S_MOD 5
# define DP_S_MOD_L 6
# define DP_S_CONV 7
# define DP_S_DONE 8
/* format flags - Bits */
# define DP_F_MINUS (1 << 0)
# define DP_F_PLUS (1 << 1)
# define DP_F_SPACE (1 << 2)
# define DP_F_NUM (1 << 3)
# define DP_F_ZERO (1 << 4)
# define DP_F_UP (1 << 5)
# define DP_F_UNSIGNED (1 << 6)
/* Conversion Flags */
# define DP_C_SHORT 1
# define DP_C_LONG 2
# define DP_C_LLONG 3
# define DP_C_LDOUBLE 4
# define char_to_int(p) (p - '0')
static int dopr ( char * buffer , size_t maxlen , const char * format , va_list args )
{
char ch ;
LLONG value ;
LDOUBLE fvalue ;
char * strvalue ;
int min ;
int max ;
int state ;
int flags ;
int cflags ;
int total ;
size_t currlen ;
state = DP_S_DEFAULT ;
currlen = flags = cflags = min = 0 ;
max = - 1 ;
ch = * format + + ;
total = 0 ;
while ( state ! = DP_S_DONE )
{
if ( ch = = ' \0 ' )
state = DP_S_DONE ;
switch ( state )
{
case DP_S_DEFAULT :
if ( ch = = ' % ' )
state = DP_S_FLAGS ;
else
total + = dopr_outch ( buffer , & currlen , maxlen , ch ) ;
ch = * format + + ;
break ;
case DP_S_FLAGS :
switch ( ch )
{
case ' - ' :
flags | = DP_F_MINUS ;
ch = * format + + ;
break ;
case ' + ' :
flags | = DP_F_PLUS ;
ch = * format + + ;
break ;
case ' ' :
flags | = DP_F_SPACE ;
ch = * format + + ;
break ;
case ' # ' :
flags | = DP_F_NUM ;
ch = * format + + ;
break ;
case ' 0 ' :
flags | = DP_F_ZERO ;
ch = * format + + ;
break ;
default :
state = DP_S_MIN ;
break ;
}
break ;
case DP_S_MIN :
if ( ' 0 ' < = ch & & ch < = ' 9 ' )
{
min = 10 * min + char_to_int ( ch ) ;
ch = * format + + ;
}
else if ( ch = = ' * ' )
{
min = va_arg ( args , int ) ;
ch = * format + + ;
state = DP_S_DOT ;
}
else
state = DP_S_DOT ;
break ;
case DP_S_DOT :
if ( ch = = ' . ' )
{
state = DP_S_MAX ;
ch = * format + + ;
}
else
state = DP_S_MOD ;
break ;
case DP_S_MAX :
if ( ' 0 ' < = ch & & ch < = ' 9 ' )
{
if ( max < 0 )
max = 0 ;
max = 10 * max + char_to_int ( ch ) ;
ch = * format + + ;
}
else if ( ch = = ' * ' )
{
max = va_arg ( args , int ) ;
ch = * format + + ;
state = DP_S_MOD ;
}
else
state = DP_S_MOD ;
break ;
case DP_S_MOD :
switch ( ch )
{
case ' h ' :
cflags = DP_C_SHORT ;
ch = * format + + ;
break ;
case ' l ' :
cflags = DP_C_LONG ;
ch = * format + + ;
break ;
case ' L ' :
cflags = DP_C_LDOUBLE ;
ch = * format + + ;
break ;
default :
break ;
}
if ( cflags ! = DP_C_LONG )
state = DP_S_CONV ;
else
state = DP_S_MOD_L ;
break ;
case DP_S_MOD_L :
switch ( ch )
{
case ' l ' :
cflags = DP_C_LLONG ;
ch = * format + + ;
break ;
default :
break ;
2005-08-26 17:39:27 +00:00
}
2008-03-25 21:36:09 +00:00
state = DP_S_CONV ;
break ;
case DP_S_CONV :
switch ( ch )
{
case ' d ' :
case ' i ' :
if ( cflags = = DP_C_SHORT )
value = ( short int ) va_arg ( args , int ) ;
else if ( cflags = = DP_C_LONG )
value = va_arg ( args , long int ) ;
else if ( cflags = = DP_C_LLONG )
value = va_arg ( args , LLONG ) ;
else
value = va_arg ( args , int ) ;
total + = fmtint ( buffer , & currlen , maxlen , value , 10 , min , max , flags ) ;
break ;
case ' o ' :
flags | = DP_F_UNSIGNED ;
if ( cflags = = DP_C_SHORT )
// value = (unsigned short int) va_arg (args, unsigned short int); // Thilo: This does not work because the rcc compiler cannot do that cast correctly.
2008-03-26 03:13:30 +00:00
value = va_arg ( args , unsigned int ) & ( ( 1 < < sizeof ( unsigned short int ) * 8 ) - 1 ) ; // Using this workaround instead.
2008-03-25 21:36:09 +00:00
else if ( cflags = = DP_C_LONG )
value = va_arg ( args , unsigned long int ) ;
else if ( cflags = = DP_C_LLONG )
value = va_arg ( args , unsigned LLONG ) ;
else
value = va_arg ( args , unsigned int ) ;
total + = fmtint ( buffer , & currlen , maxlen , value , 8 , min , max , flags ) ;
break ;
case ' u ' :
flags | = DP_F_UNSIGNED ;
if ( cflags = = DP_C_SHORT )
2008-03-26 03:13:30 +00:00
value = va_arg ( args , unsigned int ) & ( ( 1 < < sizeof ( unsigned short int ) * 8 ) - 1 ) ;
2008-03-25 21:36:09 +00:00
else if ( cflags = = DP_C_LONG )
value = va_arg ( args , unsigned long int ) ;
else if ( cflags = = DP_C_LLONG )
value = va_arg ( args , unsigned LLONG ) ;
else
value = va_arg ( args , unsigned int ) ;
total + = fmtint ( buffer , & currlen , maxlen , value , 10 , min , max , flags ) ;
break ;
case ' X ' :
flags | = DP_F_UP ;
case ' x ' :
flags | = DP_F_UNSIGNED ;
if ( cflags = = DP_C_SHORT )
2008-03-26 03:13:30 +00:00
value = va_arg ( args , unsigned int ) & ( ( 1 < < sizeof ( unsigned short int ) * 8 ) - 1 ) ;
2008-03-25 21:36:09 +00:00
else if ( cflags = = DP_C_LONG )
value = va_arg ( args , unsigned long int ) ;
else if ( cflags = = DP_C_LLONG )
value = va_arg ( args , unsigned LLONG ) ;
else
value = va_arg ( args , unsigned int ) ;
total + = fmtint ( buffer , & currlen , maxlen , value , 16 , min , max , flags ) ;
break ;
case ' f ' :
if ( cflags = = DP_C_LDOUBLE )
fvalue = va_arg ( args , LDOUBLE ) ;
else
fvalue = va_arg ( args , double ) ;
/* um, floating point? */
total + = fmtfp ( buffer , & currlen , maxlen , fvalue , min , max , flags ) ;
break ;
case ' E ' :
flags | = DP_F_UP ;
case ' e ' :
if ( cflags = = DP_C_LDOUBLE )
fvalue = va_arg ( args , LDOUBLE ) ;
else
fvalue = va_arg ( args , double ) ;
/* um, floating point? */
total + = fmtfp ( buffer , & currlen , maxlen , fvalue , min , max , flags ) ;
break ;
case ' G ' :
flags | = DP_F_UP ;
case ' g ' :
if ( cflags = = DP_C_LDOUBLE )
fvalue = va_arg ( args , LDOUBLE ) ;
else
fvalue = va_arg ( args , double ) ;
/* um, floating point? */
total + = fmtfp ( buffer , & currlen , maxlen , fvalue , min , max , flags ) ;
break ;
case ' c ' :
total + = dopr_outch ( buffer , & currlen , maxlen , va_arg ( args , int ) ) ;
break ;
case ' s ' :
strvalue = va_arg ( args , char * ) ;
total + = fmtstr ( buffer , & currlen , maxlen , strvalue , flags , min , max ) ;
break ;
case ' p ' :
strvalue = va_arg ( args , void * ) ;
total + = fmtint ( buffer , & currlen , maxlen , ( long ) strvalue , 16 , min ,
max , flags ) ;
break ;
case ' n ' :
if ( cflags = = DP_C_SHORT )
{
short int * num ;
num = va_arg ( args , short int * ) ;
* num = currlen ;
}
else if ( cflags = = DP_C_LONG )
{
long int * num ;
num = va_arg ( args , long int * ) ;
* num = currlen ;
}
else if ( cflags = = DP_C_LLONG )
{
LLONG * num ;
num = va_arg ( args , LLONG * ) ;
* num = currlen ;
}
else
{
int * num ;
num = va_arg ( args , int * ) ;
* num = currlen ;
}
break ;
case ' % ' :
total + = dopr_outch ( buffer , & currlen , maxlen , ch ) ;
break ;
case ' w ' :
/* not supported yet, treat as next char */
ch = * format + + ;
break ;
default :
/* Unknown, skip */
break ;
}
ch = * format + + ;
state = DP_S_DEFAULT ;
flags = cflags = min = 0 ;
max = - 1 ;
break ;
case DP_S_DONE :
break ;
default :
/* hmm? */
break ; /* some picky compilers need this */
}
}
2011-02-09 01:31:26 +00:00
if ( maxlen > 0 )
buffer [ currlen ] = ' \0 ' ;
2008-03-25 21:36:09 +00:00
return total ;
}
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
static int fmtstr ( char * buffer , size_t * currlen , size_t maxlen ,
char * value , int flags , int min , int max )
{
int padlen , strln ; /* amount to pad */
int cnt = 0 ;
int total = 0 ;
if ( value = = 0 )
{
value = " <NULL> " ;
}
for ( strln = 0 ; value [ strln ] ; + + strln ) ; /* strlen */
if ( max > = 0 & & max < strln )
strln = max ;
padlen = min - strln ;
if ( padlen < 0 )
padlen = 0 ;
if ( flags & DP_F_MINUS )
padlen = - padlen ; /* Left Justify */
while ( padlen > 0 )
{
total + = dopr_outch ( buffer , currlen , maxlen , ' ' ) ;
- - padlen ;
}
while ( * value & & ( ( max < 0 ) | | ( cnt < max ) ) )
{
total + = dopr_outch ( buffer , currlen , maxlen , * value + + ) ;
+ + cnt ;
}
while ( padlen < 0 )
{
total + = dopr_outch ( buffer , currlen , maxlen , ' ' ) ;
+ + padlen ;
}
return total ;
}
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
static int fmtint ( char * buffer , size_t * currlen , size_t maxlen ,
LLONG value , int base , int min , int max , int flags )
{
int signvalue = 0 ;
unsigned LLONG uvalue ;
char convert [ 24 ] ;
int place = 0 ;
int spadlen = 0 ; /* amount to space pad */
int zpadlen = 0 ; /* amount to zero pad */
const char * digits ;
int total = 0 ;
if ( max < 0 )
max = 0 ;
uvalue = value ;
if ( ! ( flags & DP_F_UNSIGNED ) )
{
if ( value < 0 ) {
signvalue = ' - ' ;
uvalue = - value ;
}
else
if ( flags & DP_F_PLUS ) /* Do a sign (+/i) */
signvalue = ' + ' ;
else
if ( flags & DP_F_SPACE )
signvalue = ' ' ;
}
if ( flags & DP_F_UP )
/* Should characters be upper case? */
digits = " 0123456789ABCDEF " ;
else
digits = " 0123456789abcdef " ;
do {
convert [ place + + ] = digits [ uvalue % ( unsigned ) base ] ;
uvalue = ( uvalue / ( unsigned ) base ) ;
} while ( uvalue & & ( place < sizeof ( convert ) ) ) ;
if ( place = = sizeof ( convert ) ) place - - ;
convert [ place ] = 0 ;
zpadlen = max - place ;
spadlen = min - MAX ( max , place ) - ( signvalue ? 1 : 0 ) ;
if ( zpadlen < 0 ) zpadlen = 0 ;
if ( spadlen < 0 ) spadlen = 0 ;
if ( flags & DP_F_ZERO )
{
zpadlen = MAX ( zpadlen , spadlen ) ;
spadlen = 0 ;
}
if ( flags & DP_F_MINUS )
spadlen = - spadlen ; /* Left Justifty */
# ifdef DEBUG_SNPRINTF
dprint ( 1 , ( debugfile , " zpad: %d, spad: %d, min: %d, max: %d, place: %d \n " ,
zpadlen , spadlen , min , max , place ) ) ;
# endif
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
/* Spaces */
while ( spadlen > 0 )
{
total + = dopr_outch ( buffer , currlen , maxlen , ' ' ) ;
- - spadlen ;
}
/* Sign */
if ( signvalue )
total + = dopr_outch ( buffer , currlen , maxlen , signvalue ) ;
/* Zeros */
if ( zpadlen > 0 )
{
while ( zpadlen > 0 )
{
total + = dopr_outch ( buffer , currlen , maxlen , ' 0 ' ) ;
- - zpadlen ;
}
}
/* Digits */
while ( place > 0 )
total + = dopr_outch ( buffer , currlen , maxlen , convert [ - - place ] ) ;
/* Left Justified spaces */
while ( spadlen < 0 ) {
total + = dopr_outch ( buffer , currlen , maxlen , ' ' ) ;
+ + spadlen ;
}
return total ;
}
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
static LDOUBLE abs_val ( LDOUBLE value )
{
LDOUBLE result = value ;
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
if ( value < 0 )
result = - value ;
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
return result ;
2005-08-26 17:39:27 +00:00
}
2008-03-25 21:36:09 +00:00
static LDOUBLE pow10 ( int exp )
{
LDOUBLE result = 1 ;
while ( exp )
{
result * = 10 ;
exp - - ;
}
return result ;
}
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
static long round ( LDOUBLE value )
{
long intpart ;
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
intpart = value ;
value = value - intpart ;
if ( value > = 0.5 )
intpart + + ;
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
return intpart ;
}
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
static int fmtfp ( char * buffer , size_t * currlen , size_t maxlen ,
LDOUBLE fvalue , int min , int max , int flags )
{
int signvalue = 0 ;
LDOUBLE ufvalue ;
char iconvert [ 20 ] ;
char fconvert [ 20 ] ;
int iplace = 0 ;
int fplace = 0 ;
int padlen = 0 ; /* amount to pad */
int zpadlen = 0 ;
int caps = 0 ;
int total = 0 ;
long intpart ;
long fracpart ;
/*
* AIX manpage says the default is 0 , but Solaris says the default
* is 6 , and sprintf on AIX defaults to 6
*/
if ( max < 0 )
max = 6 ;
ufvalue = abs_val ( fvalue ) ;
if ( fvalue < 0 )
signvalue = ' - ' ;
else
if ( flags & DP_F_PLUS ) /* Do a sign (+/i) */
signvalue = ' + ' ;
else
if ( flags & DP_F_SPACE )
signvalue = ' ' ;
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
#if 0
if ( flags & DP_F_UP ) caps = 1 ; /* Should characters be upper case? */
# endif
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
intpart = ufvalue ;
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
/*
* Sorry , we only support 9 digits past the decimal because of our
* conversion method
*/
if ( max > 9 )
max = 9 ;
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
/* We "cheat" by converting the fractional part to integer by
* multiplying by a factor of 10
*/
fracpart = round ( ( pow10 ( max ) ) * ( ufvalue - intpart ) ) ;
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
if ( fracpart > = pow10 ( max ) )
{
intpart + + ;
fracpart - = pow10 ( max ) ;
}
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
# ifdef DEBUG_SNPRINTF
dprint ( 1 , ( debugfile , " fmtfp: %f =? %d.%d \n " , fvalue , intpart , fracpart ) ) ;
# endif
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
/* Convert integer part */
do {
iconvert [ iplace + + ] =
( caps ? " 0123456789ABCDEF " : " 0123456789abcdef " ) [ intpart % 10 ] ;
intpart = ( intpart / 10 ) ;
} while ( intpart & & ( iplace < 20 ) ) ;
if ( iplace = = 20 ) iplace - - ;
iconvert [ iplace ] = 0 ;
/* Convert fractional part */
do {
fconvert [ fplace + + ] =
( caps ? " 0123456789ABCDEF " : " 0123456789abcdef " ) [ fracpart % 10 ] ;
fracpart = ( fracpart / 10 ) ;
} while ( fracpart & & ( fplace < 20 ) ) ;
if ( fplace = = 20 ) fplace - - ;
fconvert [ fplace ] = 0 ;
/* -1 for decimal point, another -1 if we are printing a sign */
padlen = min - iplace - max - 1 - ( ( signvalue ) ? 1 : 0 ) ;
zpadlen = max - fplace ;
if ( zpadlen < 0 )
zpadlen = 0 ;
if ( padlen < 0 )
padlen = 0 ;
if ( flags & DP_F_MINUS )
padlen = - padlen ; /* Left Justifty */
if ( ( flags & DP_F_ZERO ) & & ( padlen > 0 ) )
{
if ( signvalue )
{
total + = dopr_outch ( buffer , currlen , maxlen , signvalue ) ;
- - padlen ;
signvalue = 0 ;
}
while ( padlen > 0 )
{
total + = dopr_outch ( buffer , currlen , maxlen , ' 0 ' ) ;
- - padlen ;
}
}
while ( padlen > 0 )
{
total + = dopr_outch ( buffer , currlen , maxlen , ' ' ) ;
- - padlen ;
}
if ( signvalue )
total + = dopr_outch ( buffer , currlen , maxlen , signvalue ) ;
while ( iplace > 0 )
total + = dopr_outch ( buffer , currlen , maxlen , iconvert [ - - iplace ] ) ;
/*
* Decimal point . This should probably use locale to find the correct
* char to print out .
*/
if ( max > 0 )
{
total + = dopr_outch ( buffer , currlen , maxlen , ' . ' ) ;
while ( zpadlen - - > 0 )
total + = dopr_outch ( buffer , currlen , maxlen , ' 0 ' ) ;
while ( fplace > 0 )
total + = dopr_outch ( buffer , currlen , maxlen , fconvert [ - - fplace ] ) ;
}
while ( padlen < 0 )
{
total + = dopr_outch ( buffer , currlen , maxlen , ' ' ) ;
+ + padlen ;
}
return total ;
}
2005-08-26 17:39:27 +00:00
2008-03-25 21:36:09 +00:00
static int dopr_outch ( char * buffer , size_t * currlen , size_t maxlen , char c )
{
if ( * currlen + 1 < maxlen )
buffer [ ( * currlen ) + + ] = c ;
return 1 ;
}
int Q_vsnprintf ( char * str , size_t length , const char * fmt , va_list args )
{
return dopr ( str , length , fmt , args ) ;
}
int Q_snprintf ( char * str , size_t length , const char * fmt , . . . )
{
va_list ap ;
int retval ;
va_start ( ap , fmt ) ;
retval = Q_vsnprintf ( str , length , fmt , ap ) ;
va_end ( ap ) ;
return retval ;
2005-08-26 17:39:27 +00:00
}
/* this is really crappy */
int sscanf ( const char * buffer , const char * fmt , . . . ) {
int cmd ;
2009-10-21 10:18:46 +00:00
va_list ap ;
2005-08-26 17:39:27 +00:00
int count ;
2009-10-21 10:18:46 +00:00
size_t len ;
2005-08-26 17:39:27 +00:00
2009-10-21 10:18:46 +00:00
va_start ( ap , fmt ) ;
2005-08-26 17:39:27 +00:00
count = 0 ;
while ( * fmt ) {
if ( fmt [ 0 ] ! = ' % ' ) {
fmt + + ;
continue ;
}
2009-10-21 10:18:46 +00:00
fmt + + ;
cmd = * fmt ;
if ( isdigit ( cmd ) ) {
len = ( size_t ) _atoi ( & fmt ) ;
cmd = * ( fmt - 1 ) ;
} else {
len = MAX_STRING_CHARS - 1 ;
fmt + + ;
}
2005-08-26 17:39:27 +00:00
switch ( cmd ) {
case ' i ' :
case ' d ' :
case ' u ' :
2009-10-21 10:18:46 +00:00
* ( va_arg ( ap , int * ) ) = _atoi ( & buffer ) ;
2005-08-26 17:39:27 +00:00
break ;
case ' f ' :
2009-10-21 10:18:46 +00:00
* ( va_arg ( ap , float * ) ) = _atof ( & buffer ) ;
break ;
case ' s ' :
{
char * s = va_arg ( ap , char * ) ;
while ( isspace ( * buffer ) )
buffer + + ;
while ( * buffer & & ! isspace ( * buffer ) & & len - - > 0 )
* s + + = * buffer + + ;
* s + + = ' \0 ' ;
2005-08-26 17:39:27 +00:00
break ;
2009-10-21 10:18:46 +00:00
}
2005-08-26 17:39:27 +00:00
}
}
2009-10-21 10:18:46 +00:00
va_end ( ap ) ;
2005-08-26 17:39:27 +00:00
return count ;
}
# endif