made a lot of changes
This commit is contained in:
parent
2f92b46a9d
commit
e00f89ea6f
27
lang/cem/libcc.ansi/stdlib/.distr
Normal file
27
lang/cem/libcc.ansi/stdlib/.distr
Normal file
|
@ -0,0 +1,27 @@
|
|||
LIST
|
||||
Makefile
|
||||
abort.c
|
||||
abs.c
|
||||
atexit.c
|
||||
atof.c
|
||||
atoi.c
|
||||
atol.c
|
||||
bsearch.c
|
||||
div.c
|
||||
exit.c
|
||||
ext_comp.c
|
||||
ext_fmt.h
|
||||
getenv.c
|
||||
labs.c
|
||||
ldiv.c
|
||||
mblen.c
|
||||
mbstowcs.c
|
||||
mbtowc.c
|
||||
qsort.c
|
||||
rand.c
|
||||
strtod.c
|
||||
strtol.c
|
||||
system.c
|
||||
wcstombs.c
|
||||
wctomb.c
|
||||
malloc
|
|
@ -1,12 +1,12 @@
|
|||
slib
|
||||
ext_fmt.h
|
||||
abort.c
|
||||
abs.c
|
||||
atof.c
|
||||
atoi.c
|
||||
atol.c
|
||||
bsearch.c
|
||||
calloc.c
|
||||
div.c
|
||||
atexit.c
|
||||
exit.c
|
||||
getenv.c
|
||||
labs.c
|
||||
|
@ -22,3 +22,4 @@ strtol.c
|
|||
system.c
|
||||
wcstombs.c
|
||||
wctomb.c
|
||||
ext_comp.c
|
||||
|
|
43
lang/cem/libcc.ansi/stdlib/Makefile
Normal file
43
lang/cem/libcc.ansi/stdlib/Makefile
Normal file
|
@ -0,0 +1,43 @@
|
|||
CFLAGS=-L -LIB
|
||||
|
||||
.SUFFIXES: .o .e .c
|
||||
|
||||
.e.o:
|
||||
$(CC) $(CFLAGS) -c -o $@ $*.e
|
||||
|
||||
clean:
|
||||
rm -rf abort.o abs.o atof.o atoi.o atol.o bsearch.o div.o \
|
||||
atexit.o exit.o getenv.o labs.o ldiv.o malloc.o mblen.o \
|
||||
mbstowcs.o mbtowc.o qsort.o rand.o strtod.o strtol.o \
|
||||
system.o wcstombs.o wctomb.o ext_comp.o malloc.c OLIST
|
||||
|
||||
malloc/malloc.c:
|
||||
-(cd malloc; make)
|
||||
|
||||
malloc.c: malloc/malloc.c
|
||||
-cp malloc/malloc.c malloc.c
|
||||
|
||||
abort.o:
|
||||
abs.o:
|
||||
atof.o:
|
||||
atoi.o:
|
||||
atol.o:
|
||||
bsearch.o:
|
||||
div.o:
|
||||
atexit.o:
|
||||
exit.o:
|
||||
getenv.o:
|
||||
labs.o:
|
||||
ldiv.o:
|
||||
malloc.o:
|
||||
mblen.o:
|
||||
mbstowcs.o:
|
||||
mbtowc.o:
|
||||
qsort.o:
|
||||
rand.o:
|
||||
strtod.o:
|
||||
strtol.o:
|
||||
system.o:
|
||||
wcstombs.o:
|
||||
wctomb.o:
|
||||
ext_comp.o:
|
17
lang/cem/libcc.ansi/stdlib/atexit.c
Normal file
17
lang/cem/libcc.ansi/stdlib/atexit.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
/* $Header$ */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#define NEXITS 32
|
||||
|
||||
extern void (*__functab[NEXITS])(void);
|
||||
extern int __funccnt;
|
||||
|
||||
int
|
||||
atexit(void (*func)(void))
|
||||
{
|
||||
if (__funccnt >= NEXITS)
|
||||
return 1;
|
||||
__functab[__funccnt++] = func;
|
||||
return 0;
|
||||
}
|
|
@ -4,12 +4,16 @@
|
|||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#ifndef NOFLOAT
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
double
|
||||
atof(const char *nptr)
|
||||
{
|
||||
return strtod(nptr, (char **) NULL);
|
||||
double d;
|
||||
int e = errno;
|
||||
|
||||
d = strtod(nptr, (char **) NULL);
|
||||
errno = e;
|
||||
return d;
|
||||
}
|
||||
#endif /* NOFLOAT */
|
||||
|
|
|
@ -5,9 +5,14 @@
|
|||
/* $Header$ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
int
|
||||
atoi(const char *nptr)
|
||||
{
|
||||
return (int)strtol(nptr, (char **)NULL, 10);
|
||||
int i, e = errno;
|
||||
|
||||
i = (int)strtol(nptr, (char **)NULL, 10);
|
||||
errno = e;
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -5,9 +5,15 @@
|
|||
/* $Header$ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
long
|
||||
atol(const char *nptr)
|
||||
{
|
||||
return strtol(nptr, (char **)NULL, 10);
|
||||
long l;
|
||||
int e = errno;
|
||||
|
||||
l = strtol(nptr, (char **)NULL, 10);
|
||||
errno = e;
|
||||
return l;
|
||||
}
|
||||
|
|
|
@ -11,18 +11,18 @@ bsearch(register const void *key, register const void *base,
|
|||
register size_t nmemb, register size_t size,
|
||||
int (*compar)(const void *, const void *))
|
||||
{
|
||||
register void *mid_point;
|
||||
register const void *mid_point;
|
||||
register int cmp;
|
||||
|
||||
while (nmemb > 0) {
|
||||
mid_point = base + size * (nmemb >> 1);
|
||||
mid_point = (char *)base + size * (nmemb >> 1);
|
||||
if ((cmp = (*compar)(key, mid_point)) == 0)
|
||||
return(mid_point);
|
||||
return (void *)mid_point;
|
||||
if (cmp >= 0) {
|
||||
base = mid_point + size;
|
||||
base = (char *)mid_point + size;
|
||||
nmemb = (nmemb - 1) >> 1;
|
||||
} else
|
||||
nmemb >>= 1;
|
||||
}
|
||||
return((void *)NULL);
|
||||
return (void *)NULL;
|
||||
}
|
||||
|
|
|
@ -4,39 +4,32 @@
|
|||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define NEXITS 32
|
||||
|
||||
static void (*functab[NEXITS])(void);
|
||||
static int funccnt = 0;
|
||||
void (*__functab[NEXITS])(void);
|
||||
int __funccnt = 0;
|
||||
|
||||
extern void _cleanup(void);
|
||||
extern void _exit(int);
|
||||
/* only fflush when there is output */
|
||||
int (*_fflush)(FILE *stream) = NULL;
|
||||
|
||||
static void
|
||||
_calls(void)
|
||||
{
|
||||
register int i = funccnt;
|
||||
register int i = __funccnt;
|
||||
|
||||
/* "Called in reversed order of their registration" */
|
||||
while (--i >= 0)
|
||||
(*functab[i])();
|
||||
(*__functab[i])();
|
||||
}
|
||||
|
||||
void
|
||||
exit(int status)
|
||||
{
|
||||
_calls();
|
||||
_cleanup() ;
|
||||
if (_fflush) _fflush((FILE *)NULL) ;
|
||||
_exit(status) ;
|
||||
}
|
||||
|
||||
int
|
||||
atexit(void (*func)(void))
|
||||
{
|
||||
if (funccnt >= NEXITS)
|
||||
return 1;
|
||||
functab[funccnt++] = func;
|
||||
return 0;
|
||||
}
|
||||
|
|
688
lang/cem/libcc.ansi/stdlib/ext_comp.c
Normal file
688
lang/cem/libcc.ansi/stdlib/ext_comp.c
Normal file
|
@ -0,0 +1,688 @@
|
|||
/*
|
||||
(c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
|
||||
/* $Header$ */
|
||||
|
||||
/* extended precision arithmetic for the strtod() and cvt() routines */
|
||||
|
||||
/* This may require some more work when long doubles get bigger than 8
|
||||
bytes. In this case, these routines may become obsolete. ???
|
||||
*/
|
||||
|
||||
#include "ext_fmt.h"
|
||||
#include <float.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
static int b64_add(struct mantissa *e1, struct mantissa *e2);
|
||||
static b64_sft(struct mantissa *e1, int n);
|
||||
|
||||
static
|
||||
mul_ext(struct EXTEND *e1, struct EXTEND *e2, struct EXTEND *e3)
|
||||
{
|
||||
/* Multiply the extended numbers e1 and e2, and put the
|
||||
result in e3.
|
||||
*/
|
||||
register int i,j; /* loop control */
|
||||
unsigned short mp[4];
|
||||
unsigned short mc[4];
|
||||
unsigned short result[8]; /* result */
|
||||
|
||||
register unsigned short *pres;
|
||||
|
||||
/* first save the sign (XOR) */
|
||||
e3->sign = e1->sign ^ e2->sign;
|
||||
|
||||
/* compute new exponent */
|
||||
e3->exp = e1->exp + e2->exp + 1;
|
||||
|
||||
/* check for overflow/underflow ??? */
|
||||
|
||||
/* 128 bit multiply of mantissas */
|
||||
|
||||
/* assign unknown long formats */
|
||||
/* to known unsigned word formats */
|
||||
mp[0] = e1->m1 >> 16;
|
||||
mp[1] = (unsigned short) e1->m1;
|
||||
mp[2] = e1->m2 >> 16;
|
||||
mp[3] = (unsigned short) e1->m2;
|
||||
mc[0] = e2->m1 >> 16;
|
||||
mc[1] = (unsigned short) e2->m1;
|
||||
mc[2] = e2->m2 >> 16;
|
||||
mc[3] = (unsigned short) e2->m2;
|
||||
for (i = 8; i--;) {
|
||||
result[i] = 0;
|
||||
}
|
||||
/*
|
||||
* fill registers with their components
|
||||
*/
|
||||
for(i=4, pres = &result[4];i--;pres--) if (mp[i]) {
|
||||
unsigned short k = 0;
|
||||
unsigned long mpi = mp[i];
|
||||
for(j=4;j--;) {
|
||||
unsigned long tmp = (unsigned long)pres[j] + k;
|
||||
if (mc[j]) tmp += mpi * mc[j];
|
||||
pres[j] = tmp;
|
||||
k = tmp >> 16;
|
||||
}
|
||||
pres[-1] = k;
|
||||
}
|
||||
|
||||
if (! (result[0] & 0x8000)) {
|
||||
e3->exp--;
|
||||
for (i = 0; i <= 3; i++) {
|
||||
result[i] <<= 1;
|
||||
if (result[i+1]&0x8000) result[i] |= 1;
|
||||
}
|
||||
result[4] <<= 1;
|
||||
}
|
||||
/*
|
||||
* combine the registers to a total
|
||||
*/
|
||||
e3->m1 = ((unsigned long)(result[0]) << 16) + result[1];
|
||||
e3->m2 = ((unsigned long)(result[2]) << 16) + result[3];
|
||||
if (result[4] & 0x8000) {
|
||||
if (++e3->m2 == 0) {
|
||||
if (++e3->m1 == 0) {
|
||||
e3->m1 = 0x80000000;
|
||||
e3->exp++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
add_ext(struct EXTEND *e1, struct EXTEND *e2, struct EXTEND *e3)
|
||||
{
|
||||
/* Add two extended numbers e1 and e2, and put the result
|
||||
in e3
|
||||
*/
|
||||
struct EXTEND ce2;
|
||||
int diff;
|
||||
|
||||
if ((e2->m1 | e2->m2) == 0L) {
|
||||
*e3 = *e1;
|
||||
return;
|
||||
}
|
||||
if ((e1->m1 | e1->m2) == 0L) {
|
||||
*e3 = *e2;
|
||||
return;
|
||||
}
|
||||
ce2 = *e2;
|
||||
*e3 = *e1;
|
||||
e1 = &ce2;
|
||||
|
||||
/* adjust mantissas to equal power */
|
||||
diff = e3->exp - e1->exp;
|
||||
if (diff < 0) {
|
||||
diff = -diff;
|
||||
e3->exp += diff;
|
||||
b64_sft(&(e3->mantissa), diff);
|
||||
}
|
||||
else if (diff > 0) {
|
||||
e1->exp += diff;
|
||||
b64_sft(&(e1->mantissa), diff);
|
||||
}
|
||||
if (e1->sign != e3->sign) {
|
||||
/* e3 + e1 = e3 - (-e1) */
|
||||
if (e1->m1 > e3->m1 ||
|
||||
(e1->m1 == e3->m1 && e1->m2 > e3->m2)) {
|
||||
/* abs(e1) > abs(e3) */
|
||||
if (e3->m2 > e1->m2) {
|
||||
e1->m1 -= 1; /* carry in */
|
||||
}
|
||||
e1->m1 -= e3->m1;
|
||||
e1->m2 -= e3->m2;
|
||||
*e3 = *e1;
|
||||
}
|
||||
else {
|
||||
if (e1->m2 > e3->m2)
|
||||
e3->m1 -= 1; /* carry in */
|
||||
e3->m1 -= e1->m1;
|
||||
e3->m2 -= e1->m2;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (b64_add(&e3->mantissa,&e1->mantissa)) {/* addition carry */
|
||||
b64_sft(&e3->mantissa,1);/* shift mantissa one bit RIGHT */
|
||||
e3->m1 |= 0x80000000L; /* set max bit */
|
||||
e3->exp++; /* increase the exponent */
|
||||
}
|
||||
}
|
||||
if ((e3->m2 | e3->m1) != 0L) {
|
||||
/* normalize */
|
||||
if (e3->m1 == 0L) {
|
||||
e3->m1 = e3->m2; e3->m2 = 0L; e3->exp -= 32;
|
||||
}
|
||||
if (!(e3->m1 & 0x80000000)) {
|
||||
unsigned long l = 0x40000000;
|
||||
int cnt = -1;
|
||||
|
||||
while (! (l & e3->m1)) {
|
||||
l >>= 1; cnt--;
|
||||
}
|
||||
e3->exp += cnt;
|
||||
b64_sft(&(e3->mantissa), cnt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
cmp_ext(struct EXTEND *e1, struct EXTEND *e2)
|
||||
{
|
||||
struct EXTEND tmp;
|
||||
|
||||
e2->sign = ! e2->sign;
|
||||
add_ext(e1, e2, &tmp);
|
||||
e2->sign = ! e2->sign;
|
||||
if (tmp.m1 == 0 && tmp.m2 == 0) return 0;
|
||||
if (tmp.sign) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static
|
||||
b64_sft(struct mantissa *e1, int n)
|
||||
{
|
||||
if (n > 0) {
|
||||
if (n > 63) {
|
||||
e1->l_32 = 0;
|
||||
e1->h_32 = 0;
|
||||
return;
|
||||
}
|
||||
if (n >= 32) {
|
||||
e1->l_32 = e1->h_32;
|
||||
e1->h_32 = 0;
|
||||
n -= 32;
|
||||
}
|
||||
if (n > 0) {
|
||||
e1->l_32 >>= n;
|
||||
if (e1->h_32 != 0) {
|
||||
e1->l_32 |= (e1->h_32 << (32 - n));
|
||||
e1->h_32 >>= n;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
n = -n;
|
||||
if (n > 0) {
|
||||
if (n > 63) {
|
||||
e1->l_32 = 0;
|
||||
e1->h_32 = 0;
|
||||
return;
|
||||
}
|
||||
if (n >= 32) {
|
||||
e1->h_32 = e1->l_32;
|
||||
e1->l_32 = 0;
|
||||
n -= 32;
|
||||
}
|
||||
if (n > 0) {
|
||||
e1->h_32 <<= n;
|
||||
if (e1->l_32 != 0) {
|
||||
e1->h_32 |= (e1->l_32 >> (32 - n));
|
||||
e1->l_32 <<= n;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
b64_add(struct mantissa *e1, struct mantissa *e2)
|
||||
/*
|
||||
* pointers to 64 bit 'registers'
|
||||
*/
|
||||
{
|
||||
register int overflow;
|
||||
int carry;
|
||||
|
||||
/* add higher pair of 32 bits */
|
||||
overflow = ((unsigned long) 0xFFFFFFFF - e1->h_32 < e2->h_32);
|
||||
e1->h_32 += e2->h_32;
|
||||
|
||||
/* add lower pair of 32 bits */
|
||||
carry = ((unsigned long) 0xFFFFFFFF - e1->l_32 < e2->l_32);
|
||||
e1->l_32 += e2->l_32;
|
||||
if ((carry) && (++e1->h_32 == 0))
|
||||
return(1); /* had a 64 bit overflow */
|
||||
else
|
||||
return(overflow); /* return status from higher add */
|
||||
}
|
||||
|
||||
/* The following tables can be computed with the following bc(1)
|
||||
program:
|
||||
|
||||
obase=16
|
||||
scale=0
|
||||
define t(x){
|
||||
auto a, b, c
|
||||
a=2;b=1;c=2^32;n=1
|
||||
while(a<x) {
|
||||
b=a;n+=n;a*=a
|
||||
}
|
||||
n/=2
|
||||
a=b
|
||||
while(b<x) {
|
||||
a=b;b*=c;n+=32
|
||||
}
|
||||
n-=32
|
||||
b=a
|
||||
while(a<x) {
|
||||
b=a;a+=a;n+=1
|
||||
}
|
||||
n-=1
|
||||
x*=16^16
|
||||
b=x%a
|
||||
x/=a
|
||||
if(a<=(2*b)) x+=1
|
||||
obase=10
|
||||
n
|
||||
obase=16
|
||||
return(x)
|
||||
}
|
||||
for (i=1;i<28;i++) {
|
||||
t(10^i)
|
||||
}
|
||||
0
|
||||
for (i=1;i<20;i++) {
|
||||
t(10^(28*i))
|
||||
}
|
||||
0
|
||||
define r(x){
|
||||
auto a, b, c
|
||||
a=2;b=1;c=2^32;n=1
|
||||
while(a<x) {
|
||||
b=a;n+=n;a*=a
|
||||
}
|
||||
n/=2
|
||||
a=b
|
||||
while(b<x) {
|
||||
a=b;b*=c;n+=32
|
||||
}
|
||||
n-=32
|
||||
b=a
|
||||
while(a<x) {
|
||||
b=a;a+=a;n+=1
|
||||
}
|
||||
a=b
|
||||
a*=16^16
|
||||
b=a%x
|
||||
a/=x
|
||||
if(x<=(2*b)) a+=1
|
||||
obase=10
|
||||
-n
|
||||
obase=16
|
||||
return(a)
|
||||
}
|
||||
for (i=1;i<28;i++) {
|
||||
r(10^i)
|
||||
}
|
||||
0
|
||||
for (i=1;i<20;i++) {
|
||||
r(10^(28*i))
|
||||
}
|
||||
0
|
||||
|
||||
*/
|
||||
static struct EXTEND ten_powers[] = { /* representation of 10 ** i */
|
||||
{ 0, 0, 0x80000000, 0 },
|
||||
{ 0, 3, 0xA0000000, 0 },
|
||||
{ 0, 6, 0xC8000000, 0 },
|
||||
{ 0, 9, 0xFA000000, 0 },
|
||||
{ 0, 13, 0x9C400000, 0 },
|
||||
{ 0, 16, 0xC3500000, 0 },
|
||||
{ 0, 19, 0xF4240000, 0 },
|
||||
{ 0, 23, 0x98968000, 0 },
|
||||
{ 0, 26, 0xBEBC2000, 0 },
|
||||
{ 0, 29, 0xEE6B2800, 0 },
|
||||
{ 0, 33, 0x9502F900, 0 },
|
||||
{ 0, 36, 0xBA43B740, 0 },
|
||||
{ 0, 39, 0xE8D4A510, 0 },
|
||||
{ 0, 43, 0x9184E72A, 0 },
|
||||
{ 0, 46, 0xB5E620F4, 0x80000000 },
|
||||
{ 0, 49, 0xE35FA931, 0xA0000000 },
|
||||
{ 0, 53, 0x8E1BC9BF, 0x04000000 },
|
||||
{ 0, 56, 0xB1A2BC2E, 0xC5000000 },
|
||||
{ 0, 59, 0xDE0B6B3A, 0x76400000 },
|
||||
{ 0, 63, 0x8AC72304, 0x89E80000 },
|
||||
{ 0, 66, 0xAD78EBC5, 0xAC620000 },
|
||||
{ 0, 69, 0xD8D726B7, 0x177A8000 },
|
||||
{ 0, 73, 0x87867832, 0x6EAC9000 },
|
||||
{ 0, 76, 0xA968163F, 0x0A57B400 },
|
||||
{ 0, 79, 0xD3C21BCE, 0xCCEDA100 },
|
||||
{ 0, 83, 0x84595161, 0x401484A0 },
|
||||
{ 0, 86, 0xA56FA5B9, 0x9019A5C8 },
|
||||
{ 0, 89, 0xCECB8F27, 0xF4200F3A }
|
||||
};
|
||||
static struct EXTEND big_ten_powers[] = { /* representation of 10 ** (28*i) */
|
||||
{ 0, 0, 0x80000000, 0 },
|
||||
{ 0, 93, 0x813F3978, 0xF8940984 },
|
||||
{ 0, 186, 0x82818F12, 0x81ED44A0 },
|
||||
{ 0, 279, 0x83C7088E, 0x1AAB65DB },
|
||||
{ 0, 372, 0x850FADC0, 0x9923329E },
|
||||
{ 0, 465, 0x865B8692, 0x5B9BC5C2 },
|
||||
{ 0, 558, 0x87AA9AFF, 0x79042287 },
|
||||
{ 0, 651, 0x88FCF317, 0xF22241E2 },
|
||||
{ 0, 744, 0x8A5296FF, 0xE33CC930 },
|
||||
{ 0, 837, 0x8BAB8EEF, 0xB6409C1A },
|
||||
{ 0, 930, 0x8D07E334, 0x55637EB3 },
|
||||
{ 0, 1023, 0x8E679C2F, 0x5E44FF8F },
|
||||
{ 0, 1116, 0x8FCAC257, 0x558EE4E6 },
|
||||
{ 0, 1209, 0x91315E37, 0xDB165AA9 },
|
||||
{ 0, 1302, 0x929B7871, 0xDE7F22B9 },
|
||||
{ 0, 1395, 0x940919BB, 0xD4620B6D },
|
||||
{ 0, 1488, 0x957A4AE1, 0xEBF7F3D4 },
|
||||
{ 0, 1581, 0x96EF14C6, 0x454AA840 },
|
||||
{ 0, 1674, 0x98678061, 0x27ECE4F5 },
|
||||
{ 0, 1767, 0x99E396C1, 0x3A3ACFF2 }
|
||||
};
|
||||
|
||||
static struct EXTEND r_ten_powers[] = { /* representation of 10 ** -i */
|
||||
{ 0, 0, 0x80000000, 0 },
|
||||
{ 0, -4, 0xCCCCCCCC, 0xCCCCCCCD },
|
||||
{ 0, -7, 0xA3D70A3D, 0x70A3D70A },
|
||||
{ 0, -10, 0x83126E97, 0x8D4FDF3B },
|
||||
{ 0, -14, 0xD1B71758, 0xE219652C },
|
||||
{ 0, -17, 0xA7C5AC47, 0x1B478423 },
|
||||
{ 0, -20, 0x8637BD05, 0xAF6C69B6 },
|
||||
{ 0, -24, 0xD6BF94D5, 0xE57A42BC },
|
||||
{ 0, -27, 0xABCC7711, 0x8461CEFD },
|
||||
{ 0, -30, 0x89705F41, 0x36B4A597 },
|
||||
{ 0, -34, 0xDBE6FECE, 0xBDEDD5BF },
|
||||
{ 0, -37, 0xAFEBFF0B, 0xCB24AAFF },
|
||||
{ 0, -40, 0x8CBCCC09, 0x6F5088CC },
|
||||
{ 0, -44, 0xE12E1342, 0x4BB40E13 },
|
||||
{ 0, -47, 0xB424DC35, 0x095CD80F },
|
||||
{ 0, -50, 0x901D7CF7, 0x3AB0ACD9 },
|
||||
{ 0, -54, 0xE69594BE, 0xC44DE15B },
|
||||
{ 0, -57, 0xB877AA32, 0x36A4B449 },
|
||||
{ 0, -60, 0x9392EE8E, 0x921D5D07 },
|
||||
{ 0, -64, 0xEC1E4A7D, 0xB69561A5 },
|
||||
{ 0, -67, 0xBCE50864, 0x92111AEB },
|
||||
{ 0, -70, 0x971DA050, 0x74DA7BEF },
|
||||
{ 0, -74, 0xF1C90080, 0xBAF72CB1 },
|
||||
{ 0, -77, 0xC16D9A00, 0x95928A27 },
|
||||
{ 0, -80, 0x9ABE14CD, 0x44753B53 },
|
||||
{ 0, -84, 0xF79687AE, 0xD3EEC551 },
|
||||
{ 0, -87, 0xC6120625, 0x76589DDB },
|
||||
{ 0, -90, 0x9E74D1B7, 0x91E07E48 }
|
||||
};
|
||||
|
||||
static struct EXTEND r_big_ten_powers[] = { /* representation of 10 ** -(28*i) */
|
||||
{ 0, 0, 0x80000000, 0 },
|
||||
{ 0, -94, 0xFD87B5F2, 0x8300CA0E },
|
||||
{ 0, -187, 0xFB158592, 0xBE068D2F },
|
||||
{ 0, -280, 0xF8A95FCF, 0x88747D94 },
|
||||
{ 0, -373, 0xF64335BC, 0xF065D37D },
|
||||
{ 0, -466, 0xF3E2F893, 0xDEC3F126 },
|
||||
{ 0, -559, 0xF18899B1, 0xBC3F8CA2 },
|
||||
{ 0, -652, 0xEF340A98, 0x172AACE5 },
|
||||
{ 0, -745, 0xECE53CEC, 0x4A314EBE },
|
||||
{ 0, -838, 0xEA9C2277, 0x23EE8BCB },
|
||||
{ 0, -931, 0xE858AD24, 0x8F5C22CA },
|
||||
{ 0, -1024, 0xE61ACF03, 0x3D1A45DF },
|
||||
{ 0, -1117, 0xE3E27A44, 0x4D8D98B8 },
|
||||
{ 0, -1210, 0xE1AFA13A, 0xFBD14D6E },
|
||||
{ 0, -1303, 0xDF82365C, 0x497B5454 },
|
||||
{ 0, -1396, 0xDD5A2C3E, 0xAB3097CC },
|
||||
{ 0, -1489, 0xDB377599, 0xB6074245 },
|
||||
{ 0, -1582, 0xD91A0545, 0xCDB51186 },
|
||||
{ 0, -1675, 0xD701CE3B, 0xD387BF48 },
|
||||
{ 0, -1768, 0xD4EEC394, 0xD6258BF8 }
|
||||
};
|
||||
|
||||
#define TP (sizeof(ten_powers)/sizeof(ten_powers[0]))
|
||||
#define BTP (sizeof(big_ten_powers)/sizeof(big_ten_powers[0]))
|
||||
#define MAX_EXP (TP * BTP - 1)
|
||||
|
||||
static
|
||||
add_exponent(struct EXTEND *e, int exp)
|
||||
{
|
||||
int neg = exp < 0;
|
||||
int divsz, modsz;
|
||||
struct EXTEND x;
|
||||
|
||||
if (neg) exp = -exp;
|
||||
divsz = exp / TP;
|
||||
modsz = exp % TP;
|
||||
if (neg) {
|
||||
mul_ext(e, &r_ten_powers[modsz], &x);
|
||||
mul_ext(&x, &r_big_ten_powers[divsz], e);
|
||||
}
|
||||
else {
|
||||
mul_ext(e, &ten_powers[modsz], &x);
|
||||
mul_ext(&x, &big_ten_powers[divsz], e);
|
||||
}
|
||||
}
|
||||
|
||||
_str_ext_cvt(char *s, char **ss, struct EXTEND *e)
|
||||
{
|
||||
/* Like strtod, but for extended precision */
|
||||
register int c;
|
||||
int dotseen = 0;
|
||||
int digitseen = 0;
|
||||
int exp = 0;
|
||||
|
||||
if (ss) *ss = s;
|
||||
while (isspace(*s)) s++;
|
||||
|
||||
e->sign = 0;
|
||||
e->exp = 0;
|
||||
e->m1 = e->m2 = 0;
|
||||
|
||||
c = *s;
|
||||
switch(c) {
|
||||
case '-':
|
||||
e->sign = 1;
|
||||
case '+':
|
||||
s++;
|
||||
}
|
||||
while (c = *s++, isdigit(c) || (c == '.' && ! dotseen++)) {
|
||||
if (c == '.') continue;
|
||||
digitseen = 1;
|
||||
if (e->m1 <= (unsigned long)(0xFFFFFFFF)/10) {
|
||||
struct mantissa a1;
|
||||
|
||||
a1 = e->mantissa;
|
||||
b64_sft(&(e->mantissa), -3);
|
||||
b64_sft(&a1, -1);
|
||||
b64_add(&(e->mantissa), &a1);
|
||||
a1.h_32 = 0;
|
||||
a1.l_32 = c - '0';
|
||||
b64_add(&(e->mantissa), &a1);
|
||||
}
|
||||
else exp++;
|
||||
if (dotseen) exp--;
|
||||
}
|
||||
if (! digitseen) return;
|
||||
|
||||
if (ss) *ss = s - 1;
|
||||
|
||||
if (c == 'E' || c == 'e') {
|
||||
int exp1 = 0;
|
||||
int sign = 1;
|
||||
|
||||
switch(*s) {
|
||||
case '-':
|
||||
sign = -1;
|
||||
case '+':
|
||||
s++;
|
||||
}
|
||||
if (c = *s, isdigit(c)) {
|
||||
do {
|
||||
int tmp;
|
||||
|
||||
exp1 = 10 * exp1 + (c - '0');
|
||||
if ((tmp = sign * exp1 + exp) > MAX_EXP ||
|
||||
tmp < -MAX_EXP) {
|
||||
errno = ERANGE;
|
||||
}
|
||||
} while (c = *++s, isdigit(c));
|
||||
if (ss) *ss = s;
|
||||
}
|
||||
exp += sign * exp1;
|
||||
if (errno == ERANGE) exp = sign * MAX_EXP;
|
||||
}
|
||||
if (e->m1 == 0 && e->m2 == 0) return;
|
||||
e->exp = 63;
|
||||
while (! (e->m1 & 0x80000000)) {
|
||||
b64_sft(&(e->mantissa),-1);
|
||||
e->exp--;
|
||||
}
|
||||
add_exponent(e, exp);
|
||||
}
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#define NDIGITS 128
|
||||
|
||||
char *
|
||||
_ext_str_cvt(struct EXTEND *e, int ndigit, int *decpt, int *sign, int ecvtflag)
|
||||
{
|
||||
/* Like cvt(), but for extended precision */
|
||||
|
||||
static char buf[NDIGITS+1];
|
||||
register char *p = buf;
|
||||
register char *pe;
|
||||
|
||||
if (ndigit < 0) ndigit = 0;
|
||||
if (ndigit > NDIGITS) ndigit = NDIGITS;
|
||||
pe = &buf[ndigit];
|
||||
buf[0] = '\0';
|
||||
|
||||
*sign = 0;
|
||||
if (e->sign) {
|
||||
*sign = 1;
|
||||
e->sign = 0;
|
||||
}
|
||||
|
||||
*decpt = 0;
|
||||
if (e->m1 != 0) {
|
||||
register struct EXTEND *pp = &big_ten_powers[1];
|
||||
|
||||
while(cmp_ext(e,pp) >= 0) pp++;
|
||||
pp--;
|
||||
mul_ext(e,&r_big_ten_powers[pp-big_ten_powers],e);
|
||||
*decpt += (pp - big_ten_powers) * TP;
|
||||
pp = &ten_powers[1];
|
||||
while(pp < &ten_powers[TP] && cmp_ext(e, pp) >= 0) pp++;
|
||||
pp--;
|
||||
mul_ext(e, &r_ten_powers[pp-ten_powers], e);
|
||||
*decpt += pp - ten_powers;
|
||||
|
||||
if (cmp_ext(e, &ten_powers[0]) < 0) {
|
||||
pp = &r_big_ten_powers[1];
|
||||
while(cmp_ext(e,pp) < 0) pp++;
|
||||
pp--;
|
||||
mul_ext(e, &big_ten_powers[pp - r_big_ten_powers], e);
|
||||
*decpt -= (pp - r_big_ten_powers) * TP;
|
||||
/* here, value >= 10 ** -28 */
|
||||
mul_ext(e, &ten_powers[1], e);
|
||||
(*decpt)--;
|
||||
pp = &r_ten_powers[0];
|
||||
while(cmp_ext(e, pp) < 0) pp++;
|
||||
mul_ext(e, &ten_powers[pp - r_ten_powers], e);
|
||||
*decpt -= pp - r_ten_powers;
|
||||
}
|
||||
(*decpt)++; /* because now value in [1.0, 10.0) */
|
||||
}
|
||||
if (! ecvtflag) {
|
||||
/* for fcvt() we need ndigit digits behind the dot */
|
||||
pe += *decpt;
|
||||
if (pe > &buf[NDIGITS]) pe = &buf[NDIGITS];
|
||||
}
|
||||
while (p <= pe) {
|
||||
if (e->exp >= 0 && e->m1 != 0) {
|
||||
struct EXTEND x;
|
||||
|
||||
x.m2 = 0; x.exp = e->exp;
|
||||
x.sign = 1;
|
||||
x.m1 = e->m1>>(31-e->exp);
|
||||
*p++ = (x.m1) + '0';
|
||||
if (x.m1) {
|
||||
x.m1 = x.m1 << (31-e->exp);
|
||||
add_ext(e, &x, e);
|
||||
}
|
||||
}
|
||||
else *p++ = '0';
|
||||
if (e->m1) mul_ext(e, &ten_powers[1], e);
|
||||
}
|
||||
if (pe >= buf) {
|
||||
p = pe;
|
||||
*p += 5; /* round of at the end */
|
||||
while (*p > '9') {
|
||||
*p = '0';
|
||||
if (p > buf) ++*--p;
|
||||
else {
|
||||
*p = '1';
|
||||
++*decpt;
|
||||
if (! ecvtflag) {
|
||||
/* maybe add another digit at the end,
|
||||
because the point was shifted right
|
||||
*/
|
||||
if (pe > buf) *pe = '0';
|
||||
pe++;
|
||||
}
|
||||
}
|
||||
}
|
||||
*pe = '\0';
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
_dbl_ext_cvt(double value, struct EXTEND *e)
|
||||
{
|
||||
/* Convert double to extended
|
||||
*/
|
||||
int exponent;
|
||||
register int i;
|
||||
|
||||
value = frexp(value, &exponent);
|
||||
e->sign = value < 0.0;
|
||||
if (e->sign) value = -value;
|
||||
e->exp = exponent - 1;
|
||||
e->m1 = 0;
|
||||
e->m2 = 0;
|
||||
for (i = 64; i > 0 && value != 0; i--) {
|
||||
double ipart;
|
||||
|
||||
b64_sft(&(e->mantissa),-1);
|
||||
value = modf(2.0*value, &ipart);
|
||||
if (ipart) {
|
||||
e->m2 |= 1;
|
||||
}
|
||||
}
|
||||
if (i > 0) b64_sft(&(e->mantissa),-i);
|
||||
}
|
||||
|
||||
static struct EXTEND max_d;
|
||||
static struct EXTEND min_d;
|
||||
|
||||
double
|
||||
_ext_dbl_cvt(struct EXTEND *e)
|
||||
{
|
||||
/* Convert extended to double
|
||||
*/
|
||||
double f;
|
||||
int sign = e->sign;
|
||||
|
||||
e->sign = 0;
|
||||
if (e->m1 == 0 && e->m2 == 0) {
|
||||
return 0.0;
|
||||
}
|
||||
if (max_d.exp == 0) {
|
||||
_dbl_ext_cvt(DBL_MAX, &max_d);
|
||||
_dbl_ext_cvt(DBL_MIN, &min_d);
|
||||
}
|
||||
if (cmp_ext(e, &min_d) < 0) {
|
||||
f = 0.0;
|
||||
errno = ERANGE;
|
||||
}
|
||||
else if (cmp_ext(&max_d, e) < 0) {
|
||||
f = HUGE_VAL;
|
||||
errno = ERANGE;
|
||||
}
|
||||
else f = ldexp(ldexp((double)e->m1, 32) + (double)e->m2, e->exp-63);
|
||||
if (sign) f = -f;
|
||||
return f;
|
||||
}
|
13
lang/cem/libcc.ansi/stdlib/ext_fmt.h
Normal file
13
lang/cem/libcc.ansi/stdlib/ext_fmt.h
Normal file
|
@ -0,0 +1,13 @@
|
|||
struct mantissa {
|
||||
unsigned long h_32;
|
||||
unsigned long l_32;
|
||||
};
|
||||
|
||||
struct EXTEND {
|
||||
short sign;
|
||||
short exp;
|
||||
struct mantissa mantissa;
|
||||
#define m1 mantissa.h_32
|
||||
#define m2 mantissa.l_32
|
||||
};
|
||||
|
|
@ -6,23 +6,23 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
extern char **environ;
|
||||
extern const char **environ;
|
||||
|
||||
char *
|
||||
getenv(const char *name)
|
||||
{
|
||||
register char **v = environ;
|
||||
register char *p, *q;
|
||||
register const char **v = environ;
|
||||
register const char *p, *q;
|
||||
|
||||
if (v == (char **)NULL || name == (char *)NULL)
|
||||
if (v == NULL || name == NULL)
|
||||
return (char *)NULL;
|
||||
while ((p = *v++) != (char *)NULL) {
|
||||
while ((p = *v++) != NULL) {
|
||||
q = name;
|
||||
while (*q && (*q++ == *p++))
|
||||
/* EMPTY */ ;
|
||||
if (*q || (*p != '='))
|
||||
continue;
|
||||
return(p+1);
|
||||
return (char *)p + 1;
|
||||
}
|
||||
return((char *)NULL);
|
||||
return (char *)NULL;
|
||||
}
|
||||
|
|
|
@ -7,14 +7,12 @@
|
|||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#define CHAR_SHIFT 8
|
||||
|
||||
int
|
||||
mblen(const char *s, size_t n)
|
||||
{
|
||||
if (s == (char *)NULL)
|
||||
return 0;
|
||||
if (*s == '\0')
|
||||
return 0;
|
||||
if (n < 1 || n > MB_CUR_MAX)
|
||||
return -1;
|
||||
return MB_LEN_MAX;
|
||||
if (s == (const char *)NULL) return 0; /* no state dependent codings */
|
||||
if (n <= 0) return 0;
|
||||
return (*s != 0);
|
||||
}
|
||||
|
|
|
@ -5,20 +5,16 @@
|
|||
/* $Header$ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <locale.h>
|
||||
#include <limits.h>
|
||||
|
||||
size_t
|
||||
mbstowcs(register wchar_t *pwcs, register const char *s, size_t n)
|
||||
{
|
||||
register int i = 0;
|
||||
register int i = n;
|
||||
|
||||
while (i < n) {
|
||||
i++;
|
||||
*pwcs++ = *s++;
|
||||
if (*s == '\0')
|
||||
return i;
|
||||
while (--i >= 0) {
|
||||
if (!(*pwcs++ = *s++))
|
||||
return n - i - 1;
|
||||
}
|
||||
return n;
|
||||
return n - i;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,15 +8,11 @@
|
|||
#include <limits.h>
|
||||
|
||||
int
|
||||
mbtowc(register wchar_t *pwc, register const char *s, size_t n)
|
||||
mbtowc(wchar_t *pwc, register const char *s, size_t n)
|
||||
{
|
||||
if (s == (char *)NULL)
|
||||
return 0;
|
||||
if (*s == '\0')
|
||||
return 0;
|
||||
if (n < 1 || n > MB_CUR_MAX)
|
||||
return -1;
|
||||
if (pwc != (wchar_t *)NULL)
|
||||
*pwc = *s;
|
||||
return MB_CUR_MAX;
|
||||
if (s == (const char *)NULL) return 0;
|
||||
if (*s == '\0') return 0;
|
||||
if (n <= 0) return 0;
|
||||
if (pwc) *pwc = *s;
|
||||
return (*s != 0);
|
||||
}
|
||||
|
|
|
@ -6,24 +6,24 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
|
||||
static void qsort1(void *, void *, size_t);
|
||||
static int (*qcompar)(const void *, const void *);
|
||||
static void qexchange(void *, void *, size_t);
|
||||
static void q3exchange(void *, void *, void *, size_t);
|
||||
static void qsort1(char *, char *, size_t);
|
||||
static int (*qcompar)(const char *, const char *);
|
||||
static void qexchange(char *, char *, size_t);
|
||||
static void q3exchange(char *, char *, char *, size_t);
|
||||
|
||||
void
|
||||
qsort(void *base, size_t nel, size_t width,
|
||||
int (*compar)(const void *, const void *))
|
||||
{
|
||||
qcompar = compar;
|
||||
qsort1(base, base + (nel - 1) * width, width);
|
||||
qcompar = (int (*)(const char *, const char *)) compar;
|
||||
qsort1(base, (char *)base + (nel - 1) * width, width);
|
||||
}
|
||||
|
||||
static void
|
||||
qsort1(void *a1, void *a2, register size_t width)
|
||||
qsort1(char *a1, char *a2, register size_t width)
|
||||
{
|
||||
register const void *left, *right;
|
||||
register const void *lefteq, *righteq;
|
||||
register char *left, *right;
|
||||
register char *lefteq, *righteq;
|
||||
int cmp;
|
||||
|
||||
for (;;) {
|
||||
|
@ -110,7 +110,7 @@ again:
|
|||
}
|
||||
|
||||
static void
|
||||
qexchange(register void *p, register void *q,
|
||||
qexchange(register char *p, register char *q,
|
||||
register size_t n)
|
||||
{
|
||||
register int c;
|
||||
|
@ -123,7 +123,7 @@ qexchange(register void *p, register void *q,
|
|||
}
|
||||
|
||||
static void
|
||||
q3exchange(register void *p, register void *q, register void *r,
|
||||
q3exchange(register char *p, register char *q, register char *r,
|
||||
register size_t n)
|
||||
{
|
||||
register int c;
|
||||
|
|
|
@ -11,7 +11,7 @@ static unsigned long int next = 1;
|
|||
int rand(void)
|
||||
{
|
||||
next = next * 1103515245 + 12345;
|
||||
return((unsigned int)(next/(2 * (RAND_MAX +1)) % (RAND_MAX+1));
|
||||
return (unsigned int)(next/(2 * (RAND_MAX +1)) % (RAND_MAX+1));
|
||||
}
|
||||
|
||||
void srand(unsigned int seed)
|
||||
|
|
|
@ -1,103 +1,15 @@
|
|||
/*
|
||||
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#ifndef NOFLOAT
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include "ext_fmt.h"
|
||||
|
||||
#define MAX (LONG_MAX/10)
|
||||
void _str_ext_cvt(char *s, char **ss, struct EXTEND *e);
|
||||
double _ext_dbl_cvt(struct EXTEND *e);
|
||||
|
||||
double
|
||||
strtod(register const char *p, register char **pp)
|
||||
strtod(char *p, char **pp)
|
||||
{
|
||||
register int c;
|
||||
int exp = 0, sign = 1, expsign = 0;
|
||||
double fl;
|
||||
long lowl = 0, highl = 0, pos = 1;
|
||||
int dotseen = 0;
|
||||
int digit_seen = 0;
|
||||
struct EXTEND e;
|
||||
|
||||
if (pp) *pp = p;
|
||||
while (isspace(*p)) p++;
|
||||
c = *p;
|
||||
|
||||
switch (c) {
|
||||
case '-':
|
||||
sign = -1;
|
||||
/* fallthrough */
|
||||
case '+':
|
||||
p++;
|
||||
}
|
||||
|
||||
while (isdigit(c = *p++) || (c == '.' && ! dotseen++)) {
|
||||
if (c == '.') continue;
|
||||
digit_seen = 1;
|
||||
if (highl < MAX) {
|
||||
highl = (highl << 3) + (highl << 1) + (c - '0');
|
||||
}
|
||||
else if (pos < MAX) {
|
||||
pos = (pos << 3) + (pos << 1);
|
||||
lowl = (lowl << 3) + (lowl << 1) + (c - '0');
|
||||
}
|
||||
else exp++;
|
||||
if (dotseen) exp--;
|
||||
}
|
||||
if (! digit_seen) return 0.0;
|
||||
fl = highl;
|
||||
if (pos > 1) {
|
||||
fl = pos * fl + lowl;
|
||||
}
|
||||
|
||||
if (pp) *pp = p-1;
|
||||
|
||||
if (c == 'E' || c == 'e') {
|
||||
int exp1 = 0;
|
||||
int sign = 1;
|
||||
|
||||
switch (*p) {
|
||||
case '-':
|
||||
sign = -1;
|
||||
/* fallthrough */
|
||||
case '+':
|
||||
p++;
|
||||
}
|
||||
if (isdigit(c = *p)) {
|
||||
do {
|
||||
exp1 = 10 * exp1 + c - '0';
|
||||
} while (isdigit(c = *++p));
|
||||
if (pp) *pp = p;
|
||||
}
|
||||
exp += sign * exp1;
|
||||
}
|
||||
|
||||
if (fl == 0.0) return 0.0;
|
||||
|
||||
if (exp < 0) {
|
||||
expsign = 1;
|
||||
exp = -exp;
|
||||
}
|
||||
|
||||
if (exp != 0) {
|
||||
int oldexp = exp;
|
||||
double exp5 = 5.0;
|
||||
double correction = 1.0;
|
||||
|
||||
while (exp) {
|
||||
if (exp % 2) correction *= exp5;
|
||||
exp /= 2;
|
||||
if (exp != 0) exp5 *= exp5;
|
||||
}
|
||||
if (expsign) fl = fl / correction;
|
||||
else fl = fl * correction;
|
||||
|
||||
fl = ldexp(fl, expsign ? -oldexp : oldexp);
|
||||
}
|
||||
|
||||
return sign * fl;
|
||||
_str_ext_cvt(p, pp, &e);
|
||||
return _ext_dbl_cvt(&e);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -4,50 +4,95 @@
|
|||
*/
|
||||
/* $Header$ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static unsigned long
|
||||
string2long(register const char *nptr, char **endptr,
|
||||
int base, int is_signed);
|
||||
|
||||
long int
|
||||
strtol(register const char *p, char **pp, int base)
|
||||
strtol(register const char *nptr, char **endptr, int base)
|
||||
{
|
||||
register long val, v;
|
||||
register int c;
|
||||
int sign = 1;
|
||||
|
||||
if (pp) *pp = p;
|
||||
while (isspace(*p)) p++;
|
||||
c = *p;
|
||||
|
||||
switch (c) {
|
||||
case '-':
|
||||
sign = -1;
|
||||
/* fallthrough */
|
||||
case '+':
|
||||
p++;
|
||||
}
|
||||
|
||||
/* this is bizare */
|
||||
if (base==16 && *p=='0' && (*(p+1)=='x' || *(p+1)=='X'))
|
||||
p += 2;
|
||||
|
||||
while (isdigit(c = *p++) || isalpha(c)) {
|
||||
if (isalpha(c))
|
||||
v = 10 + (isupper(c) ? c - 'A' : c - 'a');
|
||||
else
|
||||
v = c - '0';
|
||||
if (v >= base) {
|
||||
p--;
|
||||
break;
|
||||
}
|
||||
val = (val * base) + v;
|
||||
}
|
||||
if (pp) *pp = p-1;
|
||||
return sign * val;
|
||||
return (signed long)string2long(nptr, endptr, base, 1);
|
||||
}
|
||||
|
||||
|
||||
unsigned long int
|
||||
strtoul(register const char *p, char **pp, int base)
|
||||
strtoul(register const char *nptr, char **endptr, int base)
|
||||
{
|
||||
return (unsigned long)strtol(p, pp, base);
|
||||
return (unsigned long)string2long(nptr, endptr, base, 0);
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
string2long(register const char *nptr, char ** const endptr,
|
||||
int base, int is_signed)
|
||||
{
|
||||
register int v;
|
||||
register unsigned long val = 0;
|
||||
register int c;
|
||||
int ovfl = 0, sign = 1;
|
||||
const char *startnptr = nptr, *nrstart;
|
||||
|
||||
if (endptr) *endptr = (char *)nptr;
|
||||
while (isspace(*nptr)) nptr++;
|
||||
c = *nptr;
|
||||
|
||||
if (c == '-' || c == '+') {
|
||||
if (c == '-') sign = -1;
|
||||
nptr++;
|
||||
}
|
||||
nrstart = nptr; /* start of the number */
|
||||
|
||||
/* When base is 0, the syntax determines the actual base */
|
||||
if (base == 0)
|
||||
if (*nptr == '0')
|
||||
if (*++nptr == 'x' || *nptr == 'X') {
|
||||
base = 16;
|
||||
nptr++;
|
||||
}
|
||||
else base = 8;
|
||||
else base = 10;
|
||||
else if (base==16 && *nptr=='0' && (*++nptr =='x' || *nptr =='X'))
|
||||
nptr++;
|
||||
|
||||
while (isdigit(c = *nptr) || isalpha(c)) {
|
||||
if (!ovfl) {
|
||||
if (isalpha(c))
|
||||
v = 10 + (isupper(c) ? c - 'A' : c - 'a');
|
||||
else
|
||||
v = c - '0';
|
||||
if (v >= base) break;
|
||||
if (val > (ULONG_MAX - v) / base) ovfl++;
|
||||
val = (val * base) + v;
|
||||
}
|
||||
nptr++;
|
||||
}
|
||||
if (endptr) {
|
||||
if (nrstart == nptr) *endptr = (char *)startnptr;
|
||||
else *endptr = (char *)nptr;
|
||||
}
|
||||
|
||||
/* We can't represent a negative unsigned long, nor a long that
|
||||
* is smaller than LONG_MIN or larger than LONG_MAX.
|
||||
*/
|
||||
if (!ovfl) {
|
||||
if (!is_signed)
|
||||
if (sign < 0 && val != 0)
|
||||
ovfl++;
|
||||
else if (((sign < 0 && val > -LONG_MIN)
|
||||
|| (sign > 0 && val > LONG_MAX)))
|
||||
ovfl++;
|
||||
}
|
||||
|
||||
if (ovfl) {
|
||||
errno = ERANGE;
|
||||
if (is_signed)
|
||||
if (sign < 0) return LONG_MIN;
|
||||
else return LONG_MAX;
|
||||
else return ULONG_MAX;
|
||||
}
|
||||
if (is_signed) return (unsigned long) sign * val;
|
||||
else return val;
|
||||
}
|
||||
|
|
|
@ -11,13 +11,11 @@
|
|||
size_t
|
||||
wcstombs(register char *s, register const wchar_t *pwcs, size_t n)
|
||||
{
|
||||
register int i = 0;
|
||||
register int i = n;
|
||||
|
||||
while (i < n) {
|
||||
i++;
|
||||
*s++ = *pwcs++;
|
||||
if (*s == '\0')
|
||||
return i;
|
||||
while (--i >= 0) {
|
||||
if (!(*s++ = *pwcs))
|
||||
return n - i - 1;
|
||||
}
|
||||
return n;
|
||||
return n - i;
|
||||
}
|
||||
|
|
|
@ -10,10 +10,8 @@
|
|||
int
|
||||
wctomb(char *s, wchar_t wchar)
|
||||
{
|
||||
if (s != (char *)NULL) {
|
||||
*s = wchar;
|
||||
return MB_LEN_MAX;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
if (!s) return 0; /* no state dependent codings */
|
||||
|
||||
*s = wchar;
|
||||
return (wchar != 0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue