commit
91a978fa95
|
@ -12,7 +12,7 @@ vars.plats = {
|
||||||
"linuxppc",
|
"linuxppc",
|
||||||
"osx386",
|
"osx386",
|
||||||
"osxppc",
|
"osxppc",
|
||||||
--"qemuppc",
|
-- --"qemuppc",
|
||||||
"pc86",
|
"pc86",
|
||||||
"rpi",
|
"rpi",
|
||||||
"pdpv7",
|
"pdpv7",
|
||||||
|
@ -22,7 +22,7 @@ vars.plats_with_tests = {
|
||||||
"linux68k",
|
"linux68k",
|
||||||
"linux386",
|
"linux386",
|
||||||
"linuxppc",
|
"linuxppc",
|
||||||
--"qemuppc",
|
-- --"qemuppc",
|
||||||
"pc86",
|
"pc86",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
|
if [ "$1" = "" ]; then
|
||||||
|
echo "No tests."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
succeeding="$(find "$@" -size 0)"
|
succeeding="$(find "$@" -size 0)"
|
||||||
notsucceeding="$(find "$@" ! -size 0)"
|
notsucceeding="$(find "$@" ! -size 0)"
|
||||||
if [ "$notsucceeding" != "" ]; then
|
if [ "$notsucceeding" != "" ]; then
|
||||||
|
|
|
@ -16,6 +16,6 @@ typedef struct{
|
||||||
int strlength;
|
int strlength;
|
||||||
} String;
|
} String;
|
||||||
|
|
||||||
String *_newstr() ;
|
extern String *_newstr(char* str);
|
||||||
|
|
||||||
#define MAXSTRING 1024
|
#define MAXSTRING 1024
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
assert.c
|
|
|
@ -1,2 +0,0 @@
|
||||||
clean:
|
|
||||||
rm -f assert.o OLIST
|
|
|
@ -1,14 +0,0 @@
|
||||||
/*
|
|
||||||
* assert.c - diagnostics
|
|
||||||
*/
|
|
||||||
/* $Id$ */
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
void __bad_assertion(const char *mess) {
|
|
||||||
|
|
||||||
fputs(mess, stderr);
|
|
||||||
abort();
|
|
||||||
}
|
|
|
@ -2,12 +2,12 @@ include("plat/build.lua")
|
||||||
|
|
||||||
tabgen {
|
tabgen {
|
||||||
name = "ctype_tab",
|
name = "ctype_tab",
|
||||||
srcs = { "./ctype/char.tab" }
|
srcs = { "./core/ctype/char.tab" }
|
||||||
}
|
}
|
||||||
|
|
||||||
normalrule {
|
normalrule {
|
||||||
name = "ctype_files",
|
name = "ctype_files",
|
||||||
ins = { "./ctype/genfiles" },
|
ins = { "./core/ctype/genfiles" },
|
||||||
outleaves = {
|
outleaves = {
|
||||||
"isalnum.c",
|
"isalnum.c",
|
||||||
"isalpha.c",
|
"isalpha.c",
|
||||||
|
@ -33,31 +33,31 @@ for _, plat in ipairs(vars.plats) do
|
||||||
srcs = {
|
srcs = {
|
||||||
"+ctype_files",
|
"+ctype_files",
|
||||||
"+ctype_tab",
|
"+ctype_tab",
|
||||||
"./ctype/*.c",
|
"./core/ctype/*.c",
|
||||||
"./errno/*.c",
|
"./core/errno/*.c",
|
||||||
"./locale/*.c",
|
"./core/locale/*.c",
|
||||||
"./malloc/*.c",
|
"./core/math/*.c",
|
||||||
"./math/*.c", -- hypot.c
|
"./core/math/*.e",
|
||||||
"./math/*.e",
|
"./core/misc/*.c",
|
||||||
"./misc/environ.c", -- don't build everything here as it's all obsolete
|
"./core/setjmp/*.c",
|
||||||
"./setjmp/*.c",
|
"./core/setjmp/*.e",
|
||||||
"./setjmp/*.e",
|
"./core/stdlib/*.c",
|
||||||
"./signal/*.c",
|
"./core/string/*.c",
|
||||||
"./assert/*.c",
|
"./core/time/*.c",
|
||||||
"./stdio/*.c",
|
"./sys/exit/*.c",
|
||||||
"./stdlib/*.c",
|
"./sys/malloc/*.c",
|
||||||
"./string/*.c",
|
"./sys/misc/*.c",
|
||||||
"./time/*.c",
|
"./sys/stdio/*.c",
|
||||||
},
|
},
|
||||||
hdrs = {}, -- must be empty
|
hdrs = {}, -- must be empty
|
||||||
deps = {
|
deps = {
|
||||||
"lang/cem/libcc.ansi/headers+pkg",
|
"lang/cem/libcc.ansi/headers+pkg",
|
||||||
"plat/"..plat.."/include+pkg",
|
"plat/"..plat.."/include+pkg",
|
||||||
"./malloc/malloc.h",
|
"./core/math/localmath.h",
|
||||||
"./math/localmath.h",
|
"./core/stdlib/ext_fmt.h",
|
||||||
"./stdio/loc_incl.h",
|
"./core/time/loc_time.h",
|
||||||
"./stdlib/ext_fmt.h",
|
"./sys/malloc/malloc.h",
|
||||||
"./time/loc_time.h",
|
"./sys/stdio/loc_incl.h",
|
||||||
},
|
},
|
||||||
vars = { plat = plat }
|
vars = { plat = plat }
|
||||||
}
|
}
|
||||||
|
|
19
lang/cem/libcc.ansi/core/README.md
Normal file
19
lang/cem/libcc.ansi/core/README.md
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
This directory contains the libc core: functions here may depend on other
|
||||||
|
libc functions _only_ (so, no `unistd.h` stuff). Plats don't get to configure
|
||||||
|
this, so nothing here should add any overhead if the function isn't linked.
|
||||||
|
|
||||||
|
Examples of what goes here:
|
||||||
|
|
||||||
|
- `strcmp()` --- because it's pure code.
|
||||||
|
- `setjmp()` --- in EM, it's portable.
|
||||||
|
- `assert()` --- because it only calls other core functions (`fputs()`
|
||||||
|
and `abort()`).
|
||||||
|
|
||||||
|
Examples of what doesn't go here:
|
||||||
|
|
||||||
|
- `malloc()` --- because it calls the `unistd.h` function `sbrk()` (and so a
|
||||||
|
plat might want to swap it out).
|
||||||
|
- stdio --- because it calls the `unistd.h` functions `read()`, `write()`
|
||||||
|
etc.
|
||||||
|
- `signal()` --- because it can't be implemented portably and needs to go
|
||||||
|
in the plat.
|
6
lang/cem/libcc.ansi/core/ctype/tolower.c
Normal file
6
lang/cem/libcc.ansi/core/ctype/tolower.c
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int tolower(int c)
|
||||||
|
{
|
||||||
|
return isupper(c) ? c - 'A' + 'a' : c;
|
||||||
|
}
|
6
lang/cem/libcc.ansi/core/ctype/toupper.c
Normal file
6
lang/cem/libcc.ansi/core/ctype/toupper.c
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
int toupper(int c)
|
||||||
|
{
|
||||||
|
return islower(c) ? c - 'a' + 'A' : c;
|
||||||
|
}
|
47
lang/cem/libcc.ansi/core/errno/errlist.c
Normal file
47
lang/cem/libcc.ansi/core/errno/errlist.c
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
const char* _sys_errlist[] = {
|
||||||
|
"Error 0",
|
||||||
|
"Not owner",
|
||||||
|
"No such file or directory",
|
||||||
|
"No such process",
|
||||||
|
"Interrupted system call",
|
||||||
|
"I/O error",
|
||||||
|
"No such device or address",
|
||||||
|
"Arg list too long",
|
||||||
|
"Exec format error",
|
||||||
|
"Bad file number",
|
||||||
|
"No children",
|
||||||
|
"No more processes",
|
||||||
|
"Not enough core",
|
||||||
|
"Permission denied",
|
||||||
|
"Bad address",
|
||||||
|
"Block device required",
|
||||||
|
"Mount device busy",
|
||||||
|
"File exists",
|
||||||
|
"Cross-device link",
|
||||||
|
"No such device",
|
||||||
|
"Not a directory",
|
||||||
|
"Is a directory",
|
||||||
|
"Invalid argument",
|
||||||
|
"File table overflow",
|
||||||
|
"Too many open files",
|
||||||
|
"Not a typewriter",
|
||||||
|
"Text file busy",
|
||||||
|
"File too large",
|
||||||
|
"No space left on device",
|
||||||
|
"Illegal seek",
|
||||||
|
"Read-only file system",
|
||||||
|
"Too many links",
|
||||||
|
"Broken pipe",
|
||||||
|
"Math argument",
|
||||||
|
"Result too large"
|
||||||
|
};
|
||||||
|
|
||||||
|
const int _sys_nerr = sizeof(_sys_errlist) / sizeof(_sys_errlist[0]);
|
19
lang/cem/libcc.ansi/core/errno/perror.c
Normal file
19
lang/cem/libcc.ansi/core/errno/perror.c
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* perror.c - print an error message on the standard error output
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void perror(const char* s)
|
||||||
|
{
|
||||||
|
if (s && *s)
|
||||||
|
{
|
||||||
|
(void)fputs(s, stderr);
|
||||||
|
(void)fputs(": ", stderr);
|
||||||
|
}
|
||||||
|
(void)fputs(strerror(errno), stderr);
|
||||||
|
(void)fputs("\n", stderr);
|
||||||
|
}
|
|
@ -4,19 +4,18 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* I don't know why, but X3J11 says that strerror() should be in declared
|
* I don't know why, but X3J11 says that strerror() should be in declared
|
||||||
* in <string.h>. That is why the function is defined here.
|
* in <string.h>. That is why the function is defined here.
|
||||||
*/
|
*/
|
||||||
char *
|
char* strerror(register int errnum)
|
||||||
strerror(register int errnum)
|
|
||||||
{
|
{
|
||||||
extern const char *_sys_errlist[];
|
extern const char* _sys_errlist[];
|
||||||
extern const int _sys_nerr;
|
extern const int _sys_nerr;
|
||||||
|
|
||||||
if (errnum < 0 || errnum >= _sys_nerr)
|
if (errnum < 0 || errnum >= _sys_nerr)
|
||||||
return "unknown error";
|
return "unknown error";
|
||||||
return (char *)_sys_errlist[errnum];
|
return (char*)_sys_errlist[errnum];
|
||||||
}
|
}
|
|
@ -3,15 +3,15 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
|
||||||
extern struct lconv _lc;
|
extern struct lconv _lc;
|
||||||
|
|
||||||
struct lconv *
|
struct lconv*
|
||||||
localeconv(void)
|
localeconv(void)
|
||||||
{
|
{
|
||||||
register struct lconv *lcp = &_lc;
|
register struct lconv* lcp = &_lc;
|
||||||
|
|
||||||
lcp->decimal_point = ".";
|
lcp->decimal_point = ".";
|
||||||
lcp->thousands_sep = "";
|
lcp->thousands_sep = "";
|
30
lang/cem/libcc.ansi/core/locale/setlocale.c
Normal file
30
lang/cem/libcc.ansi/core/locale/setlocale.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* setlocale - set the programs locale
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct lconv _lc;
|
||||||
|
|
||||||
|
char* setlocale(int category, const char* locale)
|
||||||
|
{
|
||||||
|
if (!locale)
|
||||||
|
return "C";
|
||||||
|
if (*locale && strcmp(locale, "C"))
|
||||||
|
return (char*)NULL;
|
||||||
|
|
||||||
|
switch (category)
|
||||||
|
{
|
||||||
|
case LC_ALL:
|
||||||
|
case LC_CTYPE:
|
||||||
|
case LC_COLLATE:
|
||||||
|
case LC_TIME:
|
||||||
|
case LC_NUMERIC:
|
||||||
|
case LC_MONETARY:
|
||||||
|
return *locale ? (char*)locale : "C";
|
||||||
|
default:
|
||||||
|
return (char*)NULL;
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,66 +6,79 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "localmath.h"
|
#include <ack/config.h>
|
||||||
|
#include "localmath.h"
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
static double
|
static double
|
||||||
asin_acos(double x, int cosfl)
|
asin_acos(double x, int cosfl)
|
||||||
{
|
{
|
||||||
int negative = x < 0;
|
int negative = x < 0;
|
||||||
int i;
|
int i;
|
||||||
double g;
|
double g;
|
||||||
static double p[] = {
|
static double p[] = {
|
||||||
-0.27368494524164255994e+2,
|
-0.27368494524164255994e+2,
|
||||||
0.57208227877891731407e+2,
|
0.57208227877891731407e+2,
|
||||||
-0.39688862997540877339e+2,
|
-0.39688862997540877339e+2,
|
||||||
0.10152522233806463645e+2,
|
0.10152522233806463645e+2,
|
||||||
-0.69674573447350646411e+0
|
-0.69674573447350646411e+0
|
||||||
};
|
};
|
||||||
static double q[] = {
|
static double q[] = {
|
||||||
-0.16421096714498560795e+3,
|
-0.16421096714498560795e+3,
|
||||||
0.41714430248260412556e+3,
|
0.41714430248260412556e+3,
|
||||||
-0.38186303361750149284e+3,
|
-0.38186303361750149284e+3,
|
||||||
0.15095270841030604719e+3,
|
0.15095270841030604719e+3,
|
||||||
-0.23823859153670238830e+2,
|
-0.23823859153670238830e+2,
|
||||||
1.0
|
1.0
|
||||||
};
|
};
|
||||||
|
|
||||||
if (__IsNan(x)) {
|
if (__IsNan(x))
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (negative) {
|
if (negative)
|
||||||
|
{
|
||||||
x = -x;
|
x = -x;
|
||||||
}
|
}
|
||||||
if (x > 0.5) {
|
if (x > 0.5)
|
||||||
|
{
|
||||||
i = 1;
|
i = 1;
|
||||||
if (x > 1) {
|
if (x > 1)
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
g = 0.5 - 0.5 * x;
|
g = 0.5 - 0.5 * x;
|
||||||
x = - sqrt(g);
|
x = -sqrt(g);
|
||||||
x += x;
|
x += x;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
/* ??? avoid underflow ??? */
|
/* ??? avoid underflow ??? */
|
||||||
i = 0;
|
i = 0;
|
||||||
g = x * x;
|
g = x * x;
|
||||||
}
|
}
|
||||||
x += x * g * POLYNOM4(g, p) / POLYNOM5(g, q);
|
x += x * g * POLYNOM4(g, p) / POLYNOM5(g, q);
|
||||||
if (cosfl) {
|
if (cosfl)
|
||||||
if (! negative) x = -x;
|
{
|
||||||
|
if (!negative)
|
||||||
|
x = -x;
|
||||||
}
|
}
|
||||||
if ((cosfl == 0) == (i == 1)) {
|
if ((cosfl == 0) == (i == 1))
|
||||||
|
{
|
||||||
x = (x + M_PI_4) + M_PI_4;
|
x = (x + M_PI_4) + M_PI_4;
|
||||||
}
|
}
|
||||||
else if (cosfl && negative && i == 1) {
|
else if (cosfl && negative && i == 1)
|
||||||
|
{
|
||||||
x = (x + M_PI_2) + M_PI_2;
|
x = (x + M_PI_2) + M_PI_2;
|
||||||
}
|
}
|
||||||
if (! cosfl && negative) x = -x;
|
if (!cosfl && negative)
|
||||||
|
x = -x;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,3 +93,5 @@ acos(double x)
|
||||||
{
|
{
|
||||||
return asin_acos(x, 1);
|
return asin_acos(x, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -6,10 +6,13 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "localmath.h"
|
#include <ack/config.h>
|
||||||
|
#include "localmath.h"
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
double
|
double
|
||||||
atan(double x)
|
atan(double x)
|
||||||
|
@ -26,47 +29,55 @@ atan(double x)
|
||||||
-0.83758299368150059274e+0
|
-0.83758299368150059274e+0
|
||||||
};
|
};
|
||||||
static double q[] = {
|
static double q[] = {
|
||||||
0.41066306682575781263e+2,
|
0.41066306682575781263e+2,
|
||||||
0.86157349597130242515e+2,
|
0.86157349597130242515e+2,
|
||||||
0.59578436142597344465e+2,
|
0.59578436142597344465e+2,
|
||||||
0.15024001160028576121e+2,
|
0.15024001160028576121e+2,
|
||||||
1.0
|
1.0
|
||||||
};
|
};
|
||||||
static double a[] = {
|
static double a[] = {
|
||||||
0.0,
|
0.0,
|
||||||
0.52359877559829887307710723554658381, /* pi/6 */
|
0.52359877559829887307710723554658381, /* pi/6 */
|
||||||
M_PI_2,
|
M_PI_2,
|
||||||
1.04719755119659774615421446109316763 /* pi/3 */
|
1.04719755119659774615421446109316763 /* pi/3 */
|
||||||
};
|
};
|
||||||
|
|
||||||
int neg = x < 0;
|
int neg = x < 0;
|
||||||
int n;
|
int n;
|
||||||
double g;
|
double g;
|
||||||
|
|
||||||
if (__IsNan(x)) {
|
if (__IsNan(x))
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
if (neg) {
|
if (neg)
|
||||||
|
{
|
||||||
x = -x;
|
x = -x;
|
||||||
}
|
}
|
||||||
if (x > 1.0) {
|
if (x > 1.0)
|
||||||
x = 1.0/x;
|
{
|
||||||
|
x = 1.0 / x;
|
||||||
n = 2;
|
n = 2;
|
||||||
}
|
}
|
||||||
else n = 0;
|
else
|
||||||
|
n = 0;
|
||||||
|
|
||||||
if (x > 0.26794919243112270647) { /* 2-sqtr(3) */
|
if (x > 0.26794919243112270647)
|
||||||
|
{ /* 2-sqtr(3) */
|
||||||
n = n + 1;
|
n = n + 1;
|
||||||
x = (((0.73205080756887729353*x-0.5)-0.5)+x)/
|
x = (((0.73205080756887729353 * x - 0.5) - 0.5) + x) / (1.73205080756887729353 + x);
|
||||||
(1.73205080756887729353+x);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ??? avoid underflow ??? */
|
/* ??? avoid underflow ??? */
|
||||||
|
|
||||||
g = x * x;
|
g = x * x;
|
||||||
x += x * g * POLYNOM3(g, p) / POLYNOM4(g, q);
|
x += x * g * POLYNOM3(g, p) / POLYNOM4(g, q);
|
||||||
if (n > 1) x = -x;
|
if (n > 1)
|
||||||
|
x = -x;
|
||||||
x += a[n];
|
x += a[n];
|
||||||
return neg ? -x : x;
|
return neg ? -x : x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -6,37 +6,49 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "localmath.h"
|
#include <ack/config.h>
|
||||||
|
#include "localmath.h"
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
double
|
double
|
||||||
atan2(double y, double x)
|
atan2(double y, double x)
|
||||||
{
|
{
|
||||||
double absx, absy, val;
|
double absx, absy, val;
|
||||||
|
|
||||||
if (x == 0 && y == 0) {
|
if (x == 0 && y == 0)
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
absy = y < 0 ? -y : y;
|
absy = y < 0 ? -y : y;
|
||||||
absx = x < 0 ? -x : x;
|
absx = x < 0 ? -x : x;
|
||||||
if (absy - absx == absy) {
|
if (absy - absx == absy)
|
||||||
|
{
|
||||||
/* x negligible compared to y */
|
/* x negligible compared to y */
|
||||||
return y < 0 ? -M_PI_2 : M_PI_2;
|
return y < 0 ? -M_PI_2 : M_PI_2;
|
||||||
}
|
}
|
||||||
if (absx - absy == absx) {
|
if (absx - absy == absx)
|
||||||
|
{
|
||||||
/* y negligible compared to x */
|
/* y negligible compared to x */
|
||||||
val = 0.0;
|
val = 0.0;
|
||||||
}
|
}
|
||||||
else val = atan(y/x);
|
else
|
||||||
if (x > 0) {
|
val = atan(y / x);
|
||||||
|
if (x > 0)
|
||||||
|
{
|
||||||
/* first or fourth quadrant; already correct */
|
/* first or fourth quadrant; already correct */
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
if (y < 0) {
|
if (y < 0)
|
||||||
|
{
|
||||||
/* third quadrant */
|
/* third quadrant */
|
||||||
return val - M_PI;
|
return val - M_PI;
|
||||||
}
|
}
|
||||||
return val + M_PI;
|
return val + M_PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -6,15 +6,21 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
double
|
double
|
||||||
ceil(double x)
|
ceil(double x)
|
||||||
{
|
{
|
||||||
double val;
|
double val;
|
||||||
|
|
||||||
return modf(x, &val) > 0 ? val + 1.0 : val ;
|
return modf(x, &val) > 0 ? val + 1.0 : val;
|
||||||
/* this also works if modf always returns a positive
|
/* this also works if modf always returns a positive
|
||||||
fractional part
|
fractional part
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -6,11 +6,13 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "localmath.h"
|
#include <ack/config.h>
|
||||||
|
#include "localmath.h"
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
double
|
double
|
||||||
exp(double x)
|
exp(double x)
|
||||||
|
@ -32,41 +34,49 @@ exp(double x)
|
||||||
0.63121894374398503557e-3,
|
0.63121894374398503557e-3,
|
||||||
0.75104028399870046114e-6
|
0.75104028399870046114e-6
|
||||||
};
|
};
|
||||||
double xn, g;
|
double xn, g;
|
||||||
int n;
|
int n;
|
||||||
int negative = x < 0;
|
int negative = x < 0;
|
||||||
|
|
||||||
if (__IsNan(x)) {
|
if (__IsNan(x))
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
if (x < M_LN_MIN_D) {
|
if (x < M_LN_MIN_D)
|
||||||
|
{
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
if (x > M_LN_MAX_D) {
|
if (x > M_LN_MAX_D)
|
||||||
|
{
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
return HUGE_VAL;
|
return HUGE_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (negative) x = -x;
|
if (negative)
|
||||||
|
x = -x;
|
||||||
|
|
||||||
/* ??? avoid underflow ??? */
|
/* ??? avoid underflow ??? */
|
||||||
|
|
||||||
n = x * M_LOG2E + 0.5; /* 1/ln(2) = log2(e), 0.5 added for rounding */
|
n = x * M_LOG2E + 0.5; /* 1/ln(2) = log2(e), 0.5 added for rounding */
|
||||||
xn = n;
|
xn = n;
|
||||||
{
|
{
|
||||||
double x1 = (long) x;
|
double x1 = (long)x;
|
||||||
double x2 = x - x1;
|
double x2 = x - x1;
|
||||||
|
|
||||||
g = ((x1-xn*0.693359375)+x2) - xn*(-2.1219444005469058277e-4);
|
g = ((x1 - xn * 0.693359375) + x2) - xn * (-2.1219444005469058277e-4);
|
||||||
}
|
}
|
||||||
if (negative) {
|
if (negative)
|
||||||
|
{
|
||||||
g = -g;
|
g = -g;
|
||||||
n = -n;
|
n = -n;
|
||||||
}
|
}
|
||||||
xn = g * g;
|
xn = g * g;
|
||||||
x = g * POLYNOM2(xn, p);
|
x = g * POLYNOM2(xn, p);
|
||||||
n += 1;
|
n += 1;
|
||||||
return (ldexp(0.5 + x/(POLYNOM3(xn, q) - x), n));
|
return (ldexp(0.5 + x / (POLYNOM3(xn, q) - x), n));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -5,9 +5,15 @@
|
||||||
* Author: Ceriel J.H. Jacobs
|
* Author: Ceriel J.H. Jacobs
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
double
|
double
|
||||||
fabs(double x)
|
fabs(double x)
|
||||||
{
|
{
|
||||||
return x < 0 ? -x : x;
|
return x < 0 ? -x : x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -6,15 +6,21 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
double
|
double
|
||||||
floor(double x)
|
floor(double x)
|
||||||
{
|
{
|
||||||
double val;
|
double val;
|
||||||
|
|
||||||
return modf(x, &val) < 0 ? val - 1.0 : val ;
|
return modf(x, &val) < 0 ? val - 1.0 : val;
|
||||||
/* this also works if modf always returns a positive
|
/* this also works if modf always returns a positive
|
||||||
fractional part
|
fractional part
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
45
lang/cem/libcc.ansi/core/math/fmod.c
Normal file
45
lang/cem/libcc.ansi/core/math/fmod.c
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
/* fmod function */
|
||||||
|
/* Author Robert R. Hall (hall@crach.cts.com) */
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
|
double(fmod)(double x, double y)
|
||||||
|
{ /* compute fmod(x, y) */
|
||||||
|
double t;
|
||||||
|
int n, neg;
|
||||||
|
int ychar, xchar;
|
||||||
|
|
||||||
|
if (y == 0.0)
|
||||||
|
{
|
||||||
|
errno = EDOM;
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
/* fmod(finite, finite) */
|
||||||
|
if (y < 0.0)
|
||||||
|
y = -y;
|
||||||
|
if (x < 0.0)
|
||||||
|
x = -x, neg = 1;
|
||||||
|
else
|
||||||
|
neg = 0;
|
||||||
|
t = frexp(y, &ychar);
|
||||||
|
/* substract |y| until |x| < |y| */
|
||||||
|
|
||||||
|
t = frexp(x, &xchar);
|
||||||
|
for (n = xchar - ychar; 0 <= n; --n)
|
||||||
|
{
|
||||||
|
/* try to substract |y|*2^n */
|
||||||
|
t = ldexp(y, n);
|
||||||
|
if (t <= x)
|
||||||
|
x -= t;
|
||||||
|
}
|
||||||
|
return (neg ? -x : x);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -5,7 +5,11 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
mes 2,_EM_WSIZE,_EM_PSIZE
|
mes 2,_EM_WSIZE,_EM_PSIZE
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
exp $frexp
|
exp $frexp
|
||||||
pro $frexp,0
|
pro $frexp,0
|
||||||
lal 0
|
lal 0
|
||||||
|
@ -16,3 +20,5 @@
|
||||||
sti _EM_WSIZE
|
sti _EM_WSIZE
|
||||||
ret _EM_DSIZE
|
ret _EM_DSIZE
|
||||||
end
|
end
|
||||||
|
#endif
|
||||||
|
|
|
@ -7,5 +7,11 @@
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
double __huge_val = 1.0e+1000; /* This will generate a warning */
|
double __huge_val = 1.0e+1000; /* This will generate a warning */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -6,29 +6,37 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
double
|
double
|
||||||
hypot(double x,double y)
|
hypot(double x, double y)
|
||||||
{
|
{
|
||||||
/* Computes sqrt(x*x+y*y), avoiding overflow */
|
/* Computes sqrt(x*x+y*y), avoiding overflow */
|
||||||
|
|
||||||
if (x < 0) x = -x;
|
if (x < 0)
|
||||||
if (y < 0) y = -y;
|
x = -x;
|
||||||
if (x > y) {
|
if (y < 0)
|
||||||
|
y = -y;
|
||||||
|
if (x > y)
|
||||||
|
{
|
||||||
double t = y;
|
double t = y;
|
||||||
y = x;
|
y = x;
|
||||||
x = t;
|
x = t;
|
||||||
}
|
}
|
||||||
/* sqrt(x*x+y*y) = sqrt(y*y*(x*x/(y*y)+1.0)) = y*sqrt(x*x/(y*y)+1.0) */
|
/* sqrt(x*x+y*y) = sqrt(y*y*(x*x/(y*y)+1.0)) = y*sqrt(x*x/(y*y)+1.0) */
|
||||||
if (y == 0.0) return 0.0;
|
if (y == 0.0)
|
||||||
|
return 0.0;
|
||||||
x /= y;
|
x /= y;
|
||||||
return y*sqrt(x*x+1.0);
|
return y * sqrt(x * x + 1.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct complex {
|
struct complex
|
||||||
double r,i;
|
{
|
||||||
|
double r, i;
|
||||||
};
|
};
|
||||||
|
|
||||||
double
|
double
|
||||||
|
@ -36,3 +44,6 @@ cabs(struct complex p_compl)
|
||||||
{
|
{
|
||||||
return hypot(p_compl.r, p_compl.i);
|
return hypot(p_compl.r, p_compl.i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
19
lang/cem/libcc.ansi/core/math/isnan.c
Normal file
19
lang/cem/libcc.ansi/core/math/isnan.c
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
#include <math.h>
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
|
__IsNan(double d)
|
||||||
|
{
|
||||||
|
#if defined(__vax) || defined(__pdp)
|
||||||
|
#else
|
||||||
|
float f = d;
|
||||||
|
|
||||||
|
if ((*((long*)&f) & 0x7f800000) == 0x7f800000 && (*((long*)&f) & 0x007fffff) != 0)
|
||||||
|
return 1;
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -4,9 +4,12 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
double
|
double
|
||||||
ldexp(double fl, int exp)
|
ldexp(double fl, int exp)
|
||||||
|
@ -14,42 +17,55 @@ ldexp(double fl, int exp)
|
||||||
int sign = 1;
|
int sign = 1;
|
||||||
int currexp;
|
int currexp;
|
||||||
|
|
||||||
if (__IsNan(fl)) {
|
if (__IsNan(fl))
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return fl;
|
return fl;
|
||||||
}
|
}
|
||||||
if (fl == 0.0) return 0.0;
|
if (fl == 0.0)
|
||||||
if (fl<0) {
|
return 0.0;
|
||||||
|
if (fl < 0)
|
||||||
|
{
|
||||||
fl = -fl;
|
fl = -fl;
|
||||||
sign = -1;
|
sign = -1;
|
||||||
}
|
}
|
||||||
if (fl > DBL_MAX) { /* for infinity */
|
if (fl > DBL_MAX)
|
||||||
|
{ /* for infinity */
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
return sign * fl;
|
return sign * fl;
|
||||||
}
|
}
|
||||||
fl = frexp(fl,&currexp);
|
fl = frexp(fl, &currexp);
|
||||||
exp += currexp;
|
exp += currexp;
|
||||||
if (exp > 0) {
|
if (exp > 0)
|
||||||
if (exp > DBL_MAX_EXP) {
|
{
|
||||||
|
if (exp > DBL_MAX_EXP)
|
||||||
|
{
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
return sign * HUGE_VAL;
|
return sign * HUGE_VAL;
|
||||||
}
|
}
|
||||||
while (exp>30) {
|
while (exp > 30)
|
||||||
fl *= (double) (1L << 30);
|
{
|
||||||
|
fl *= (double)(1L << 30);
|
||||||
exp -= 30;
|
exp -= 30;
|
||||||
}
|
}
|
||||||
fl *= (double) (1L << exp);
|
fl *= (double)(1L << exp);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
/* number need not be normalized */
|
/* number need not be normalized */
|
||||||
if (exp < DBL_MIN_EXP - DBL_MANT_DIG) {
|
if (exp < DBL_MIN_EXP - DBL_MANT_DIG)
|
||||||
|
{
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
while (exp<-30) {
|
while (exp < -30)
|
||||||
fl /= (double) (1L << 30);
|
{
|
||||||
|
fl /= (double)(1L << 30);
|
||||||
exp += 30;
|
exp += 30;
|
||||||
}
|
}
|
||||||
fl /= (double) (1L << -exp);
|
fl /= (double)(1L << -exp);
|
||||||
}
|
}
|
||||||
return sign * fl;
|
return sign * fl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "localmath.h"
|
#include <ack/config.h>
|
||||||
|
#include "localmath.h"
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
double
|
double
|
||||||
log(double x)
|
log(double x)
|
||||||
|
@ -20,48 +23,59 @@ log(double x)
|
||||||
*/
|
*/
|
||||||
static double a[] = {
|
static double a[] = {
|
||||||
-0.64124943423745581147e2,
|
-0.64124943423745581147e2,
|
||||||
0.16383943563021534222e2,
|
0.16383943563021534222e2,
|
||||||
-0.78956112887491257267e0
|
-0.78956112887491257267e0
|
||||||
};
|
};
|
||||||
static double b[] = {
|
static double b[] = {
|
||||||
-0.76949932108494879777e3,
|
-0.76949932108494879777e3,
|
||||||
0.31203222091924532844e3,
|
0.31203222091924532844e3,
|
||||||
-0.35667977739034646171e2,
|
-0.35667977739034646171e2,
|
||||||
1.0
|
1.0
|
||||||
};
|
};
|
||||||
|
|
||||||
double znum, zden, z, w;
|
double znum, zden, z, w;
|
||||||
int exponent;
|
int exponent;
|
||||||
|
|
||||||
if (__IsNan(x)) {
|
if (__IsNan(x))
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
if (x < 0) {
|
if (x < 0)
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return -HUGE_VAL;
|
return -HUGE_VAL;
|
||||||
}
|
}
|
||||||
else if (x == 0) {
|
else if (x == 0)
|
||||||
|
{
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
return -HUGE_VAL;
|
return -HUGE_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x <= DBL_MAX) {
|
if (x <= DBL_MAX)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
else return x; /* for infinity and Nan */
|
else
|
||||||
|
return x; /* for infinity and Nan */
|
||||||
x = frexp(x, &exponent);
|
x = frexp(x, &exponent);
|
||||||
if (x > M_1_SQRT2) {
|
if (x > M_1_SQRT2)
|
||||||
|
{
|
||||||
znum = (x - 0.5) - 0.5;
|
znum = (x - 0.5) - 0.5;
|
||||||
zden = x * 0.5 + 0.5;
|
zden = x * 0.5 + 0.5;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
znum = x - 0.5;
|
znum = x - 0.5;
|
||||||
zden = znum * 0.5 + 0.5;
|
zden = znum * 0.5 + 0.5;
|
||||||
exponent--;
|
exponent--;
|
||||||
}
|
}
|
||||||
z = znum/zden; w = z * z;
|
z = znum / zden;
|
||||||
x = z + z * w * (POLYNOM2(w,a)/POLYNOM3(w,b));
|
w = z * z;
|
||||||
|
x = z + z * w * (POLYNOM2(w, a) / POLYNOM3(w, b));
|
||||||
z = exponent;
|
z = exponent;
|
||||||
x += z * (-2.121944400546905827679e-4);
|
x += z * (-2.121944400546905827679e-4);
|
||||||
return x + z * 0.693359375;
|
return x + z * 0.693359375;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -6,25 +6,34 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "localmath.h"
|
#include <ack/config.h>
|
||||||
|
#include "localmath.h"
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
double
|
double
|
||||||
log10(double x)
|
log10(double x)
|
||||||
{
|
{
|
||||||
if (__IsNan(x)) {
|
if (__IsNan(x))
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
if (x < 0) {
|
if (x < 0)
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return -HUGE_VAL;
|
return -HUGE_VAL;
|
||||||
}
|
}
|
||||||
else if (x == 0) {
|
else if (x == 0)
|
||||||
|
{
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
return -HUGE_VAL;
|
return -HUGE_VAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return log(x) / M_LN10;
|
return log(x) / M_LN10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -4,8 +4,11 @@
|
||||||
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
mes 2,_EM_WSIZE,_EM_PSIZE
|
mes 2,_EM_WSIZE,_EM_PSIZE
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
exp $modf
|
exp $modf
|
||||||
pro $modf,0
|
pro $modf,0
|
||||||
lal 0
|
lal 0
|
||||||
|
@ -20,3 +23,4 @@
|
||||||
sti _EM_DSIZE
|
sti _EM_DSIZE
|
||||||
ret _EM_DSIZE
|
ret _EM_DSIZE
|
||||||
end
|
end
|
||||||
|
#endif
|
|
@ -6,95 +6,123 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
double
|
double
|
||||||
pow(double x, double y)
|
pow(double x, double y)
|
||||||
{
|
{
|
||||||
double y_intpart, y_fractpart, fp;
|
double y_intpart, y_fractpart, fp;
|
||||||
int negexp, negx;
|
int negexp, negx;
|
||||||
int ex, newexp;
|
int ex, newexp;
|
||||||
unsigned long yi;
|
unsigned long yi;
|
||||||
|
|
||||||
if (x == 1.0) return x;
|
if (x == 1.0)
|
||||||
|
return x;
|
||||||
|
|
||||||
if (x == 0 && y <= 0) {
|
if (x == 0 && y <= 0)
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y == 0) return 1.0;
|
if (y == 0)
|
||||||
|
return 1.0;
|
||||||
|
|
||||||
if (y < 0) {
|
if (y < 0)
|
||||||
|
{
|
||||||
y = -y;
|
y = -y;
|
||||||
negexp = 1;
|
negexp = 1;
|
||||||
}
|
}
|
||||||
else negexp = 0;
|
else
|
||||||
|
negexp = 0;
|
||||||
|
|
||||||
y_fractpart = modf(y, &y_intpart);
|
y_fractpart = modf(y, &y_intpart);
|
||||||
|
|
||||||
if (y_fractpart != 0) {
|
if (y_fractpart != 0)
|
||||||
if (x < 0) {
|
{
|
||||||
|
if (x < 0)
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
negx = 0;
|
negx = 0;
|
||||||
if (x < 0) {
|
if (x < 0)
|
||||||
|
{
|
||||||
x = -x;
|
x = -x;
|
||||||
negx = 1;
|
negx = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y_intpart > ULONG_MAX) {
|
if (y_intpart > ULONG_MAX)
|
||||||
if (negx && modf(y_intpart/2.0, &y_fractpart) == 0) {
|
{
|
||||||
|
if (negx && modf(y_intpart / 2.0, &y_fractpart) == 0)
|
||||||
|
{
|
||||||
negx = 0;
|
negx = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
x = log(x);
|
x = log(x);
|
||||||
|
|
||||||
/* Beware of overflow in the multiplication */
|
/* Beware of overflow in the multiplication */
|
||||||
if (x > 1.0 && y > DBL_MAX/x) {
|
if (x > 1.0 && y > DBL_MAX / x)
|
||||||
|
{
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
return HUGE_VAL;
|
return HUGE_VAL;
|
||||||
}
|
}
|
||||||
if (negexp) y = -y;
|
if (negexp)
|
||||||
|
y = -y;
|
||||||
|
|
||||||
if (negx) return -exp(x*y);
|
if (negx)
|
||||||
|
return -exp(x * y);
|
||||||
return exp(x * y);
|
return exp(x * y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y_fractpart != 0) {
|
if (y_fractpart != 0)
|
||||||
|
{
|
||||||
fp = exp(y_fractpart * log(x));
|
fp = exp(y_fractpart * log(x));
|
||||||
}
|
}
|
||||||
else fp = 1.0;
|
else
|
||||||
|
fp = 1.0;
|
||||||
yi = y_intpart;
|
yi = y_intpart;
|
||||||
if (! (yi & 1)) negx = 0;
|
if (!(yi & 1))
|
||||||
|
negx = 0;
|
||||||
x = frexp(x, &ex);
|
x = frexp(x, &ex);
|
||||||
newexp = 0;
|
newexp = 0;
|
||||||
for (;;) {
|
for (;;)
|
||||||
if (yi & 1) {
|
{
|
||||||
|
if (yi & 1)
|
||||||
|
{
|
||||||
fp *= x;
|
fp *= x;
|
||||||
newexp += ex;
|
newexp += ex;
|
||||||
}
|
}
|
||||||
yi >>= 1;
|
yi >>= 1;
|
||||||
if (yi == 0) break;
|
if (yi == 0)
|
||||||
|
break;
|
||||||
x *= x;
|
x *= x;
|
||||||
ex <<= 1;
|
ex <<= 1;
|
||||||
if (x < 0.5) {
|
if (x < 0.5)
|
||||||
|
{
|
||||||
x += x;
|
x += x;
|
||||||
ex -= 1;
|
ex -= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (negexp) {
|
if (negexp)
|
||||||
fp = 1.0/fp;
|
{
|
||||||
|
fp = 1.0 / fp;
|
||||||
newexp = -newexp;
|
newexp = -newexp;
|
||||||
}
|
}
|
||||||
if (negx) {
|
if (negx)
|
||||||
|
{
|
||||||
return -ldexp(fp, newexp);
|
return -ldexp(fp, newexp);
|
||||||
}
|
}
|
||||||
return ldexp(fp, newexp);
|
return ldexp(fp, newexp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "localmath.h"
|
#include <ack/config.h>
|
||||||
|
#include "localmath.h"
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
static double
|
static double
|
||||||
sinus(double x, int cos_flag)
|
sinus(double x, int cos_flag)
|
||||||
|
@ -21,39 +24,44 @@ sinus(double x, int cos_flag)
|
||||||
|
|
||||||
static double r[] = {
|
static double r[] = {
|
||||||
-0.16666666666666665052e+0,
|
-0.16666666666666665052e+0,
|
||||||
0.83333333333331650314e-2,
|
0.83333333333331650314e-2,
|
||||||
-0.19841269841201840457e-3,
|
-0.19841269841201840457e-3,
|
||||||
0.27557319210152756119e-5,
|
0.27557319210152756119e-5,
|
||||||
-0.25052106798274584544e-7,
|
-0.25052106798274584544e-7,
|
||||||
0.16058936490371589114e-9,
|
0.16058936490371589114e-9,
|
||||||
-0.76429178068910467734e-12,
|
-0.76429178068910467734e-12,
|
||||||
0.27204790957888846175e-14
|
0.27204790957888846175e-14
|
||||||
};
|
};
|
||||||
|
|
||||||
double y;
|
double y;
|
||||||
int neg = 1;
|
int neg = 1;
|
||||||
|
|
||||||
if (__IsNan(x)) {
|
if (__IsNan(x))
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
if (x < 0) {
|
if (x < 0)
|
||||||
|
{
|
||||||
x = -x;
|
x = -x;
|
||||||
neg = -1;
|
neg = -1;
|
||||||
}
|
}
|
||||||
if (cos_flag) {
|
if (cos_flag)
|
||||||
|
{
|
||||||
neg = 1;
|
neg = 1;
|
||||||
y = M_PI_2 + x;
|
y = M_PI_2 + x;
|
||||||
}
|
}
|
||||||
else y = x;
|
else
|
||||||
|
y = x;
|
||||||
|
|
||||||
/* ??? avoid loss of significance, if y is too large, error ??? */
|
/* ??? avoid loss of significance, if y is too large, error ??? */
|
||||||
|
|
||||||
y = y * M_1_PI + 0.5;
|
y = y * M_1_PI + 0.5;
|
||||||
|
|
||||||
if (y >= DBL_MAX/M_PI) return 0.0;
|
if (y >= DBL_MAX / M_PI)
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
/* Use extended precision to calculate reduced argument.
|
/* Use extended precision to calculate reduced argument.
|
||||||
Here we used 12 bits of the mantissa for a1.
|
Here we used 12 bits of the mantissa for a1.
|
||||||
Also split x in integer part x1 and fraction part x2.
|
Also split x in integer part x1 and fraction part x2.
|
||||||
*/
|
*/
|
||||||
|
@ -63,8 +71,10 @@ sinus(double x, int cos_flag)
|
||||||
double x1, x2;
|
double x1, x2;
|
||||||
|
|
||||||
modf(y, &y);
|
modf(y, &y);
|
||||||
if (modf(0.5*y, &x1)) neg = -neg;
|
if (modf(0.5 * y, &x1))
|
||||||
if (cos_flag) y -= 0.5;
|
neg = -neg;
|
||||||
|
if (cos_flag)
|
||||||
|
y -= 0.5;
|
||||||
x2 = modf(x, &x1);
|
x2 = modf(x, &x1);
|
||||||
x = x1 - y * A1;
|
x = x1 - y * A1;
|
||||||
x += x2;
|
x += x2;
|
||||||
|
@ -72,8 +82,9 @@ sinus(double x, int cos_flag)
|
||||||
#undef A1
|
#undef A1
|
||||||
#undef A2
|
#undef A2
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x < 0) {
|
if (x < 0)
|
||||||
|
{
|
||||||
neg = -neg;
|
neg = -neg;
|
||||||
x = -x;
|
x = -x;
|
||||||
}
|
}
|
||||||
|
@ -82,7 +93,7 @@ sinus(double x, int cos_flag)
|
||||||
|
|
||||||
y = x * x;
|
y = x * x;
|
||||||
x += x * y * POLYNOM7(y, r);
|
x += x * y * POLYNOM7(y, r);
|
||||||
return neg==-1 ? -x : x;
|
return neg == -1 ? -x : x;
|
||||||
}
|
}
|
||||||
|
|
||||||
double
|
double
|
||||||
|
@ -94,6 +105,10 @@ sin(double x)
|
||||||
double
|
double
|
||||||
cos(double x)
|
cos(double x)
|
||||||
{
|
{
|
||||||
if (x < 0) x = -x;
|
if (x < 0)
|
||||||
|
x = -x;
|
||||||
return sinus(x, 1);
|
return sinus(x, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "localmath.h"
|
#include <ack/config.h>
|
||||||
|
#include "localmath.h"
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
static double
|
static double
|
||||||
sinh_cosh(double x, int cosh_flag)
|
sinh_cosh(double x, int cosh_flag)
|
||||||
|
@ -27,42 +30,48 @@ sinh_cosh(double x, int cosh_flag)
|
||||||
};
|
};
|
||||||
static double q[] = {
|
static double q[] = {
|
||||||
-0.21108770058106271242e+7,
|
-0.21108770058106271242e+7,
|
||||||
0.36162723109421836460e+5,
|
0.36162723109421836460e+5,
|
||||||
-0.27773523119650701167e+3,
|
-0.27773523119650701167e+3,
|
||||||
1.0
|
1.0
|
||||||
};
|
};
|
||||||
int negative = x < 0;
|
int negative = x < 0;
|
||||||
double y = negative ? -x : x;
|
double y = negative ? -x : x;
|
||||||
|
|
||||||
if (__IsNan(x)) {
|
if (__IsNan(x))
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
if (! cosh_flag && y <= 1.0) {
|
if (!cosh_flag && y <= 1.0)
|
||||||
|
{
|
||||||
/* ??? check for underflow ??? */
|
/* ??? check for underflow ??? */
|
||||||
y = y * y;
|
y = y * y;
|
||||||
return x + x * y * POLYNOM3(y, p)/POLYNOM3(y,q);
|
return x + x * y * POLYNOM3(y, p) / POLYNOM3(y, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y >= M_LN_MAX_D) {
|
if (y >= M_LN_MAX_D)
|
||||||
/* exp(y) would cause overflow */
|
{
|
||||||
#define LNV 0.69316101074218750000e+0
|
/* exp(y) would cause overflow */
|
||||||
#define VD2M1 0.52820835025874852469e-4
|
#define LNV 0.69316101074218750000e+0
|
||||||
double w = y - LNV;
|
#define VD2M1 0.52820835025874852469e-4
|
||||||
|
double w = y - LNV;
|
||||||
if (w < M_LN_MAX_D+M_LN2-LNV) {
|
|
||||||
|
if (w < M_LN_MAX_D + M_LN2 - LNV)
|
||||||
|
{
|
||||||
x = exp(w);
|
x = exp(w);
|
||||||
x += VD2M1 * x;
|
x += VD2M1 * x;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
x = HUGE_VAL;
|
x = HUGE_VAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
double z = exp(y);
|
{
|
||||||
|
double z = exp(y);
|
||||||
x = 0.5 * (z + (cosh_flag ? 1.0 : -1.0)/z);
|
|
||||||
|
x = 0.5 * (z + (cosh_flag ? 1.0 : -1.0) / z);
|
||||||
}
|
}
|
||||||
return negative ? -x : x;
|
return negative ? -x : x;
|
||||||
}
|
}
|
||||||
|
@ -76,6 +85,10 @@ sinh(double x)
|
||||||
double
|
double
|
||||||
cosh(double x)
|
cosh(double x)
|
||||||
{
|
{
|
||||||
if (x < 0) x = -x;
|
if (x < 0)
|
||||||
|
x = -x;
|
||||||
return sinh_cosh(x, 1);
|
return sinh_cosh(x, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -6,11 +6,14 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
#define NITER 5
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
|
#define NITER 5
|
||||||
|
|
||||||
double
|
double
|
||||||
sqrt(double x)
|
sqrt(double x)
|
||||||
|
@ -18,26 +21,35 @@ sqrt(double x)
|
||||||
int exponent;
|
int exponent;
|
||||||
double val;
|
double val;
|
||||||
|
|
||||||
if (__IsNan(x)) {
|
if (__IsNan(x))
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
if (x <= 0) {
|
if (x <= 0)
|
||||||
if (x < 0) errno = EDOM;
|
{
|
||||||
|
if (x < 0)
|
||||||
|
errno = EDOM;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x > DBL_MAX) return x; /* for infinity */
|
if (x > DBL_MAX)
|
||||||
|
return x; /* for infinity */
|
||||||
|
|
||||||
val = frexp(x, &exponent);
|
val = frexp(x, &exponent);
|
||||||
if (exponent & 1) {
|
if (exponent & 1)
|
||||||
|
{
|
||||||
exponent--;
|
exponent--;
|
||||||
val *= 2;
|
val *= 2;
|
||||||
}
|
}
|
||||||
val = ldexp(val + 1.0, exponent/2 - 1);
|
val = ldexp(val + 1.0, exponent / 2 - 1);
|
||||||
/* was: val = (val + 1.0)/2.0; val = ldexp(val, exponent/2); */
|
/* was: val = (val + 1.0)/2.0; val = ldexp(val, exponent/2); */
|
||||||
for (exponent = NITER - 1; exponent >= 0; exponent--) {
|
for (exponent = NITER - 1; exponent >= 0; exponent--)
|
||||||
|
{
|
||||||
val = (val + x / val) / 2.0;
|
val = (val + x / val) / 2.0;
|
||||||
}
|
}
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "localmath.h"
|
#include <ack/config.h>
|
||||||
|
#include "localmath.h"
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
double
|
double
|
||||||
tan(double x)
|
tan(double x)
|
||||||
|
@ -21,56 +24,64 @@ tan(double x)
|
||||||
|
|
||||||
int negative = x < 0;
|
int negative = x < 0;
|
||||||
int invert = 0;
|
int invert = 0;
|
||||||
double y;
|
double y;
|
||||||
static double p[] = {
|
static double p[] = {
|
||||||
1.0,
|
1.0,
|
||||||
-0.13338350006421960681e+0,
|
-0.13338350006421960681e+0,
|
||||||
0.34248878235890589960e-2,
|
0.34248878235890589960e-2,
|
||||||
-0.17861707342254426711e-4
|
-0.17861707342254426711e-4
|
||||||
};
|
};
|
||||||
static double q[] = {
|
static double q[] = {
|
||||||
1.0,
|
1.0,
|
||||||
-0.46671683339755294240e+0,
|
-0.46671683339755294240e+0,
|
||||||
0.25663832289440112864e-1,
|
0.25663832289440112864e-1,
|
||||||
-0.31181531907010027307e-3,
|
-0.31181531907010027307e-3,
|
||||||
0.49819433993786512270e-6
|
0.49819433993786512270e-6
|
||||||
};
|
};
|
||||||
|
|
||||||
if (__IsNan(x)) {
|
if (__IsNan(x))
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
if (negative) x = -x;
|
if (negative)
|
||||||
|
x = -x;
|
||||||
|
|
||||||
/* ??? avoid loss of significance, error if x is too large ??? */
|
/* ??? avoid loss of significance, error if x is too large ??? */
|
||||||
|
|
||||||
y = x * M_2_PI + 0.5;
|
y = x * M_2_PI + 0.5;
|
||||||
|
|
||||||
if (y >= DBL_MAX/M_PI_2) return 0.0;
|
if (y >= DBL_MAX / M_PI_2)
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
/* Use extended precision to calculate reduced argument.
|
/* Use extended precision to calculate reduced argument.
|
||||||
Here we used 12 bits of the mantissa for a1.
|
Here we used 12 bits of the mantissa for a1.
|
||||||
Also split x in integer part x1 and fraction part x2.
|
Also split x in integer part x1 and fraction part x2.
|
||||||
*/
|
*/
|
||||||
#define A1 1.57080078125
|
#define A1 1.57080078125
|
||||||
#define A2 -4.454455103380768678308e-6
|
#define A2 -4.454455103380768678308e-6
|
||||||
{
|
{
|
||||||
double x1, x2;
|
double x1, x2;
|
||||||
|
|
||||||
modf(y, &y);
|
modf(y, &y);
|
||||||
if (modf(0.5*y, &x1)) invert = 1;
|
if (modf(0.5 * y, &x1))
|
||||||
|
invert = 1;
|
||||||
x2 = modf(x, &x1);
|
x2 = modf(x, &x1);
|
||||||
x = x1 - y * A1;
|
x = x1 - y * A1;
|
||||||
x += x2;
|
x += x2;
|
||||||
x -= y * A2;
|
x -= y * A2;
|
||||||
#undef A1
|
#undef A1
|
||||||
#undef A2
|
#undef A2
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ??? avoid underflow ??? */
|
/* ??? avoid underflow ??? */
|
||||||
y = x * x;
|
y = x * x;
|
||||||
x += x * y * POLYNOM2(y, p+1);
|
x += x * y * POLYNOM2(y, p + 1);
|
||||||
y = POLYNOM4(y, q);
|
y = POLYNOM4(y, q);
|
||||||
if (negative) x = -x;
|
if (negative)
|
||||||
return invert ? -y/x : x/y;
|
x = -x;
|
||||||
|
return invert ? -y / x : x / y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -6,10 +6,13 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "localmath.h"
|
#include <ack/config.h>
|
||||||
|
#include "localmath.h"
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
double
|
double
|
||||||
tanh(double x)
|
tanh(double x)
|
||||||
|
@ -25,31 +28,39 @@ tanh(double x)
|
||||||
-0.96437492777225469787e+0
|
-0.96437492777225469787e+0
|
||||||
};
|
};
|
||||||
static double q[] = {
|
static double q[] = {
|
||||||
0.48402357071988688686e+4,
|
0.48402357071988688686e+4,
|
||||||
0.22337720718962312926e+4,
|
0.22337720718962312926e+4,
|
||||||
0.11274474380534949335e+3,
|
0.11274474380534949335e+3,
|
||||||
1.0
|
1.0
|
||||||
};
|
};
|
||||||
int negative = x < 0;
|
int negative = x < 0;
|
||||||
|
|
||||||
if (__IsNan(x)) {
|
if (__IsNan(x))
|
||||||
|
{
|
||||||
errno = EDOM;
|
errno = EDOM;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
if (negative) x = -x;
|
if (negative)
|
||||||
|
x = -x;
|
||||||
|
|
||||||
if (x >= 0.5*M_LN_MAX_D) {
|
if (x >= 0.5 * M_LN_MAX_D)
|
||||||
|
{
|
||||||
x = 1.0;
|
x = 1.0;
|
||||||
}
|
}
|
||||||
#define LN3D2 0.54930614433405484570e+0 /* ln(3)/2 */
|
#define LN3D2 0.54930614433405484570e+0 /* ln(3)/2 */
|
||||||
else if (x > LN3D2) {
|
else if (x > LN3D2)
|
||||||
x = 0.5 - 1.0/(exp(x+x)+1.0);
|
{
|
||||||
|
x = 0.5 - 1.0 / (exp(x + x) + 1.0);
|
||||||
x += x;
|
x += x;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
/* ??? avoid underflow ??? */
|
/* ??? avoid underflow ??? */
|
||||||
double g = x*x;
|
double g = x * x;
|
||||||
x += x * g * POLYNOM2(g, p)/POLYNOM3(g, q);
|
x += x * g * POLYNOM2(g, p) / POLYNOM3(g, q);
|
||||||
}
|
}
|
||||||
return negative ? -x : x;
|
return negative ? -x : x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
14
lang/cem/libcc.ansi/core/misc/abort.c
Normal file
14
lang/cem/libcc.ansi/core/misc/abort.c
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
/*
|
||||||
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
void abort(void)
|
||||||
|
{
|
||||||
|
raise(SIGABRT);
|
||||||
|
}
|
15
lang/cem/libcc.ansi/core/misc/assert.c
Normal file
15
lang/cem/libcc.ansi/core/misc/assert.c
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* assert.c - diagnostics
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void __bad_assertion(const char* mess)
|
||||||
|
{
|
||||||
|
|
||||||
|
fputs(mess, stderr);
|
||||||
|
abort();
|
||||||
|
}
|
72
lang/cem/libcc.ansi/core/misc/getopt.c
Normal file
72
lang/cem/libcc.ansi/core/misc/getopt.c
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* getopt - parse command-line options
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define ERR(s, c) \
|
||||||
|
if (opterr) \
|
||||||
|
{ \
|
||||||
|
fputs(argv[0], stderr); \
|
||||||
|
fputs(s, stderr); \
|
||||||
|
fputc(c, stderr); \
|
||||||
|
fputc('\n', stderr); \
|
||||||
|
}
|
||||||
|
|
||||||
|
int opterr = 1;
|
||||||
|
int optind = 1;
|
||||||
|
int optopt;
|
||||||
|
char* optarg;
|
||||||
|
|
||||||
|
int getopt(int argc, char** argv, char* opts)
|
||||||
|
{
|
||||||
|
static int sp = 1;
|
||||||
|
register c;
|
||||||
|
register char* cp;
|
||||||
|
|
||||||
|
if (sp == 1)
|
||||||
|
if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
|
||||||
|
return EOF;
|
||||||
|
else if (!strcmp(argv[optind], "--"))
|
||||||
|
{
|
||||||
|
optind++;
|
||||||
|
return EOF;
|
||||||
|
}
|
||||||
|
optopt = c = argv[optind][sp];
|
||||||
|
if (c == ':' || (cp = strchr(opts, c)) == NULL)
|
||||||
|
{
|
||||||
|
ERR(": illegal option -- ", c);
|
||||||
|
if (argv[optind][++sp] == '\0')
|
||||||
|
{
|
||||||
|
optind++;
|
||||||
|
sp = 1;
|
||||||
|
}
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
if (*++cp == ':')
|
||||||
|
{
|
||||||
|
if (argv[optind][sp + 1] != '\0')
|
||||||
|
optarg = &argv[optind++][sp + 1];
|
||||||
|
else if (++optind >= argc)
|
||||||
|
{
|
||||||
|
ERR(": option requires an argument -- ", c);
|
||||||
|
sp = 1;
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
optarg = argv[optind++];
|
||||||
|
sp = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (argv[optind][++sp] == '\0')
|
||||||
|
{
|
||||||
|
sp = 1;
|
||||||
|
optind++;
|
||||||
|
}
|
||||||
|
optarg = NULL;
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
|
@ -4,15 +4,17 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#if defined(_POSIX_SOURCE)
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#endif
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
int
|
#if ACKCONF_WANT_EMULATED_RAISE
|
||||||
raise(int sig)
|
|
||||||
|
int raise(int sig)
|
||||||
{
|
{
|
||||||
if (sig < 0 || sig > _NSIG)
|
if (sig < 0 || sig > _NSIG)
|
||||||
return -1;
|
return -1;
|
||||||
return kill(getpid(), sig);
|
return kill(getpid(), sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -3,37 +3,38 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#if defined(_POSIX_SOURCE)
|
#if defined(_POSIX_SOURCE)
|
||||||
|
|
||||||
/* This can't be done in setjmp.e, since SIG_SETMASK is defined in
|
/* This can't be done in setjmp.e, since SIG_SETMASK is defined in
|
||||||
* <signal.h>. This is a C-file, which can't be included.
|
* <signal.h>. This is a C-file, which can't be included.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
int _sigprocmask(int, sigset_t *, sigset_t *);
|
int _sigprocmask(int, sigset_t*, sigset_t*);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
__testsigset(void) {
|
__testsigset(void)
|
||||||
|
{
|
||||||
/* This switch compiles when a sigset_t has the right size. */
|
/* This switch compiles when a sigset_t has the right size. */
|
||||||
switch(0) {
|
switch (0)
|
||||||
case 0:
|
{
|
||||||
case sizeof(sigset_t) <= sizeof(long): break;
|
case 0:
|
||||||
|
case sizeof(sigset_t) <= sizeof(long):
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void __newsigset(sigset_t* p)
|
||||||
__newsigset(sigset_t *p)
|
|
||||||
{
|
{
|
||||||
/* The SIG_SETMASK is not significant */
|
/* The SIG_SETMASK is not significant */
|
||||||
_sigprocmask(SIG_SETMASK, NULL, p);
|
_sigprocmask(SIG_SETMASK, NULL, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void __oldsigset(sigset_t* p)
|
||||||
__oldsigset(sigset_t *p)
|
|
||||||
{
|
{
|
||||||
_sigprocmask(SIG_SETMASK, p, NULL);
|
_sigprocmask(SIG_SETMASK, p, NULL);
|
||||||
}
|
}
|
||||||
#endif /* _POSIX_SOURCE */
|
#endif /* _POSIX_SOURCE */
|
|
@ -3,12 +3,12 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int
|
int fgetpos(FILE* stream, fpos_t* pos)
|
||||||
fgetpos(FILE *stream, fpos_t *pos)
|
|
||||||
{
|
{
|
||||||
*pos = ftell(stream);
|
*pos = ftell(stream);
|
||||||
if (*pos == -1) return -1;
|
if (*pos == -1)
|
||||||
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
|
@ -3,10 +3,9 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
int
|
int fsetpos(FILE* stream, fpos_t* pos)
|
||||||
fsetpos(FILE *stream, fpos_t *pos)
|
|
||||||
{
|
{
|
||||||
return fseek(stream, *pos, SEEK_SET);
|
return fseek(stream, *pos, SEEK_SET);
|
||||||
}
|
}
|
31
lang/cem/libcc.ansi/core/stdio/gets.c
Normal file
31
lang/cem/libcc.ansi/core/stdio/gets.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* gets.c - read a line from a stream
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
char* gets(char* s)
|
||||||
|
{
|
||||||
|
register FILE* stream = stdin;
|
||||||
|
register int ch;
|
||||||
|
register char* ptr;
|
||||||
|
|
||||||
|
ptr = s;
|
||||||
|
while ((ch = getc(stream)) != EOF && ch != '\n')
|
||||||
|
*ptr++ = ch;
|
||||||
|
|
||||||
|
if (ch == EOF)
|
||||||
|
{
|
||||||
|
if (feof(stream))
|
||||||
|
{
|
||||||
|
if (ptr == s)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ptr = '\0';
|
||||||
|
return s;
|
||||||
|
}
|
21
lang/cem/libcc.ansi/core/stdio/getw.c
Normal file
21
lang/cem/libcc.ansi/core/stdio/getw.c
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* getw - read a word from a stream
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int getw(register FILE* stream)
|
||||||
|
{
|
||||||
|
register int cnt = sizeof(int);
|
||||||
|
int w;
|
||||||
|
register char* p = (char*)&w;
|
||||||
|
|
||||||
|
while (cnt--)
|
||||||
|
{
|
||||||
|
*p++ = getc(stream);
|
||||||
|
}
|
||||||
|
if (feof(stream) || ferror(stream))
|
||||||
|
return EOF;
|
||||||
|
return w;
|
||||||
|
}
|
20
lang/cem/libcc.ansi/core/stdio/putw.c
Normal file
20
lang/cem/libcc.ansi/core/stdio/putw.c
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
/*
|
||||||
|
* putw - write an word on a stream
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
int putw(int w, register FILE* stream)
|
||||||
|
{
|
||||||
|
register int cnt = sizeof(int);
|
||||||
|
register char* p = (char*)&w;
|
||||||
|
|
||||||
|
while (cnt--)
|
||||||
|
{
|
||||||
|
putc(*p++, stream);
|
||||||
|
}
|
||||||
|
if (ferror(stream))
|
||||||
|
return EOF;
|
||||||
|
return w;
|
||||||
|
}
|
|
@ -3,12 +3,10 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "loc_incl.h"
|
|
||||||
|
|
||||||
void
|
void rewind(FILE* stream)
|
||||||
rewind(FILE *stream)
|
|
||||||
{
|
{
|
||||||
(void) fseek(stream, 0L, SEEK_SET);
|
(void)fseek(stream, 0L, SEEK_SET);
|
||||||
clearerr(stream);
|
clearerr(stream);
|
||||||
}
|
}
|
|
@ -4,10 +4,9 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int
|
int abs(register int i)
|
||||||
abs(register int i)
|
|
||||||
{
|
{
|
||||||
return i >= 0 ? i : -i;
|
return i >= 0 ? i : -i;
|
||||||
}
|
}
|
|
@ -4,16 +4,20 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
double
|
#if ACKCONF_WANT_FLOAT
|
||||||
(atof)(const char *nptr)
|
|
||||||
|
double(atof)(const char* nptr)
|
||||||
{
|
{
|
||||||
double d;
|
double d;
|
||||||
int e = errno;
|
int e = errno;
|
||||||
|
|
||||||
d = strtod(nptr, (char **) NULL);
|
d = strtod(nptr, (char**)NULL);
|
||||||
errno = e;
|
errno = e;
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -4,24 +4,27 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
/* We do not use strtol here for backwards compatibility in behaviour on
|
/* We do not use strtol here for backwards compatibility in behaviour on
|
||||||
overflow.
|
overflow.
|
||||||
*/
|
*/
|
||||||
int
|
int atoi(register const char* nptr)
|
||||||
atoi(register const char *nptr)
|
|
||||||
{
|
{
|
||||||
int total = 0;
|
int total = 0;
|
||||||
int minus = 0;
|
int minus = 0;
|
||||||
|
|
||||||
while (isspace(*nptr)) nptr++;
|
while (isspace(*nptr))
|
||||||
if (*nptr == '+') nptr++;
|
nptr++;
|
||||||
else if (*nptr == '-') {
|
if (*nptr == '+')
|
||||||
|
nptr++;
|
||||||
|
else if (*nptr == '-')
|
||||||
|
{
|
||||||
minus = 1;
|
minus = 1;
|
||||||
nptr++;
|
nptr++;
|
||||||
}
|
}
|
||||||
while (isdigit(*nptr)) {
|
while (isdigit(*nptr))
|
||||||
|
{
|
||||||
total *= 10;
|
total *= 10;
|
||||||
total += (*nptr++ - '0');
|
total += (*nptr++ - '0');
|
||||||
}
|
}
|
|
@ -4,24 +4,27 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
/* We do not use strtol here for backwards compatibility in behaviour on
|
/* We do not use strtol here for backwards compatibility in behaviour on
|
||||||
overflow.
|
overflow.
|
||||||
*/
|
*/
|
||||||
long
|
long atol(register const char* nptr)
|
||||||
atol(register const char *nptr)
|
|
||||||
{
|
{
|
||||||
long total = 0;
|
long total = 0;
|
||||||
int minus = 0;
|
int minus = 0;
|
||||||
|
|
||||||
while (isspace(*nptr)) nptr++;
|
while (isspace(*nptr))
|
||||||
if (*nptr == '+') nptr++;
|
nptr++;
|
||||||
else if (*nptr == '-') {
|
if (*nptr == '+')
|
||||||
|
nptr++;
|
||||||
|
else if (*nptr == '-')
|
||||||
|
{
|
||||||
minus = 1;
|
minus = 1;
|
||||||
nptr++;
|
nptr++;
|
||||||
}
|
}
|
||||||
while (isdigit(*nptr)) {
|
while (isdigit(*nptr))
|
||||||
|
{
|
||||||
total *= 10;
|
total *= 10;
|
||||||
total += (*nptr++ - '0');
|
total += (*nptr++ - '0');
|
||||||
}
|
}
|
30
lang/cem/libcc.ansi/core/stdlib/bsearch.c
Normal file
30
lang/cem/libcc.ansi/core/stdlib/bsearch.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void* bsearch(register const void* key, register const void* base,
|
||||||
|
register size_t nmemb, register size_t size,
|
||||||
|
int (*compar)(const void*, const void*))
|
||||||
|
{
|
||||||
|
register const void* mid_point;
|
||||||
|
register int cmp;
|
||||||
|
|
||||||
|
while (nmemb > 0)
|
||||||
|
{
|
||||||
|
mid_point = (char*)base + size * (nmemb >> 1);
|
||||||
|
if ((cmp = (*compar)(key, mid_point)) == 0)
|
||||||
|
return (void*)mid_point;
|
||||||
|
if (cmp >= 0)
|
||||||
|
{
|
||||||
|
base = (char*)mid_point + size;
|
||||||
|
nmemb = (nmemb - 1) >> 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
nmemb >>= 1;
|
||||||
|
}
|
||||||
|
return (void*)NULL;
|
||||||
|
}
|
|
@ -4,17 +4,17 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
div_t
|
div_t div(register int numer, register int denom)
|
||||||
div(register int numer, register int denom)
|
|
||||||
{
|
{
|
||||||
div_t r;
|
div_t r;
|
||||||
|
|
||||||
r.quot = numer / denom; /* might trap if denom == 0 */
|
r.quot = numer / denom; /* might trap if denom == 0 */
|
||||||
r.rem = numer % denom;
|
r.rem = numer % denom;
|
||||||
|
|
||||||
if (r.rem != 0 && (numer > 0) != (r.rem > 0)) {
|
if (r.rem != 0 && (numer > 0) != (r.rem > 0))
|
||||||
|
{
|
||||||
r.quot++;
|
r.quot++;
|
||||||
r.rem -= denom;
|
r.rem -= denom;
|
||||||
}
|
}
|
30
lang/cem/libcc.ansi/core/stdlib/ecvt.c
Normal file
30
lang/cem/libcc.ansi/core/stdlib/ecvt.c
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_STDIO_FLOAT
|
||||||
|
|
||||||
|
#include "ext_fmt.h"
|
||||||
|
|
||||||
|
static char*
|
||||||
|
cvt(long double value, int ndigit, int* decpt, int* sign, int ecvtflag)
|
||||||
|
{
|
||||||
|
struct EXTEND e;
|
||||||
|
|
||||||
|
_dbl_ext_cvt(value, &e);
|
||||||
|
return _ext_str_cvt(&e, ndigit, decpt, sign, ecvtflag);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* _ecvt(long double value, int ndigit, int* decpt, int* sign)
|
||||||
|
{
|
||||||
|
|
||||||
|
return cvt(value, ndigit, decpt, sign, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* _fcvt(long double value, int ndigit, int* decpt, int* sign)
|
||||||
|
{
|
||||||
|
return cvt(value, ndigit, decpt, sign, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
839
lang/cem/libcc.ansi/core/stdlib/ext_comp.c
Normal file
839
lang/cem/libcc.ansi/core/stdlib/ext_comp.c
Normal file
|
@ -0,0 +1,839 @@
|
||||||
|
/*
|
||||||
|
(c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/* 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>
|
||||||
|
#include <ack/config.h>
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
|
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 (int)(sizeof(ten_powers) / sizeof(ten_powers[0]))
|
||||||
|
#define BTP (int)(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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _str_ext_cvt(const 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 = (char*)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 = (char*)s - 1;
|
||||||
|
|
||||||
|
if (c == 'E' || c == 'e')
|
||||||
|
{
|
||||||
|
int exp1 = 0;
|
||||||
|
int sign = 1;
|
||||||
|
int exp_overflow = 0;
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
exp_overflow = 1;
|
||||||
|
}
|
||||||
|
} while (c = *++s, isdigit(c));
|
||||||
|
if (ss)
|
||||||
|
*ss = (char*)s;
|
||||||
|
}
|
||||||
|
exp += sign * exp1;
|
||||||
|
if (exp_overflow)
|
||||||
|
{
|
||||||
|
exp = sign * MAX_EXP;
|
||||||
|
if (e->m1 != 0 || e->m2 != 0)
|
||||||
|
errno = ERANGE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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>
|
||||||
|
|
||||||
|
static ten_mult(struct EXTEND* e)
|
||||||
|
{
|
||||||
|
struct EXTEND e1 = *e;
|
||||||
|
|
||||||
|
e1.exp++;
|
||||||
|
e->exp += 3;
|
||||||
|
add_ext(e, &e1, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NDIGITS 128
|
||||||
|
#define NSIGNIFICANT 19
|
||||||
|
|
||||||
|
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];
|
||||||
|
struct EXTEND m;
|
||||||
|
register char* p = buf;
|
||||||
|
register char* pe;
|
||||||
|
int findex = 0;
|
||||||
|
|
||||||
|
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++;
|
||||||
|
findex = pp - big_ten_powers;
|
||||||
|
if (findex >= BTP)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pp--;
|
||||||
|
findex = pp - big_ten_powers;
|
||||||
|
mul_ext(e, &r_big_ten_powers[findex], e);
|
||||||
|
*decpt += findex * TP;
|
||||||
|
pp = &ten_powers[1];
|
||||||
|
while (pp < &ten_powers[TP] && cmp_ext(e, pp) >= 0)
|
||||||
|
pp++;
|
||||||
|
pp--;
|
||||||
|
findex = pp - ten_powers;
|
||||||
|
*decpt += findex;
|
||||||
|
|
||||||
|
if (cmp_ext(e, &ten_powers[0]) < 0)
|
||||||
|
{
|
||||||
|
pp = &r_big_ten_powers[1];
|
||||||
|
while (cmp_ext(e, pp) < 0)
|
||||||
|
pp++;
|
||||||
|
pp--;
|
||||||
|
findex = pp - r_big_ten_powers;
|
||||||
|
mul_ext(e, &big_ten_powers[findex], e);
|
||||||
|
*decpt -= findex * TP;
|
||||||
|
/* here, value >= 10 ** -28 */
|
||||||
|
ten_mult(e);
|
||||||
|
(*decpt)--;
|
||||||
|
pp = &r_ten_powers[0];
|
||||||
|
while (cmp_ext(e, pp) < 0)
|
||||||
|
pp++;
|
||||||
|
findex = pp - r_ten_powers;
|
||||||
|
mul_ext(e, &ten_powers[findex], e);
|
||||||
|
*decpt -= findex;
|
||||||
|
findex = 0;
|
||||||
|
}
|
||||||
|
(*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];
|
||||||
|
}
|
||||||
|
m.exp = -62;
|
||||||
|
m.sign = 0;
|
||||||
|
m.m1 = 0xA0000000;
|
||||||
|
m.m2 = 0;
|
||||||
|
while (p <= pe)
|
||||||
|
{
|
||||||
|
struct EXTEND oneminm;
|
||||||
|
|
||||||
|
if (p - pe > NSIGNIFICANT)
|
||||||
|
{
|
||||||
|
findex = 0;
|
||||||
|
e->m1 = 0;
|
||||||
|
}
|
||||||
|
if (findex)
|
||||||
|
{
|
||||||
|
struct EXTEND tc, oldtc;
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
oldtc.exp = 0;
|
||||||
|
oldtc.sign = 0;
|
||||||
|
oldtc.m1 = 0;
|
||||||
|
oldtc.m2 = 0;
|
||||||
|
tc = ten_powers[findex];
|
||||||
|
while (cmp_ext(e, &tc) >= 0)
|
||||||
|
{
|
||||||
|
oldtc = tc;
|
||||||
|
add_ext(&tc, &ten_powers[findex], &tc);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
*p++ = count + '0';
|
||||||
|
oldtc.sign = 1;
|
||||||
|
add_ext(e, &oldtc, e);
|
||||||
|
findex--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (e->m1)
|
||||||
|
{
|
||||||
|
m.sign = 1;
|
||||||
|
add_ext(&ten_powers[0], &m, &oneminm);
|
||||||
|
m.sign = 0;
|
||||||
|
if (e->exp >= 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';
|
||||||
|
x.m1 = x.m1 << (31 - e->exp);
|
||||||
|
add_ext(e, &x, e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*p++ = '0';
|
||||||
|
/* Check that remainder is still significant */
|
||||||
|
if (cmp_ext(&m, e) > 0 || cmp_ext(e, &oneminm) > 0)
|
||||||
|
{
|
||||||
|
if (e->m1 && e->exp >= -1)
|
||||||
|
*(p - 1) += 1;
|
||||||
|
e->m1 = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ten_mult(&m);
|
||||||
|
ten_mult(e);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*p++ = '0';
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _dbl_ext_cvt(double value, struct EXTEND* e)
|
||||||
|
{
|
||||||
|
/* Convert double to extended
|
||||||
|
*/
|
||||||
|
int exponent;
|
||||||
|
|
||||||
|
value = frexp(value, &exponent);
|
||||||
|
e->sign = value < 0.0;
|
||||||
|
if (e->sign)
|
||||||
|
value = -value;
|
||||||
|
e->exp = exponent - 1;
|
||||||
|
value *= 4294967296.0;
|
||||||
|
e->m1 = value;
|
||||||
|
value -= e->m1;
|
||||||
|
value *= 4294967296.0;
|
||||||
|
e->m2 = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct EXTEND max_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);
|
||||||
|
}
|
||||||
|
if (cmp_ext(&max_d, e) < 0)
|
||||||
|
{
|
||||||
|
f = HUGE_VAL;
|
||||||
|
errno = ERANGE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
f = ldexp((double)e->m1 * 4294967296.0 + (double)e->m2, e->exp - 63);
|
||||||
|
if (sign)
|
||||||
|
f = -f;
|
||||||
|
if (f == 0.0 && (e->m1 != 0 || e->m2 != 0))
|
||||||
|
{
|
||||||
|
errno = ERANGE;
|
||||||
|
}
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
22
lang/cem/libcc.ansi/core/stdlib/ext_fmt.h
Normal file
22
lang/cem/libcc.ansi/core/stdlib/ext_fmt.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef _EXT_FMT_H
|
||||||
|
#define _EXT_FMT_H
|
||||||
|
|
||||||
|
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
|
||||||
|
};
|
||||||
|
|
||||||
|
extern void _str_ext_cvt(const char* s, char** ss, struct EXTEND* e);
|
||||||
|
extern double _ext_dbl_cvt(struct EXTEND* e);
|
||||||
|
extern void _dbl_ext_cvt(double value, struct EXTEND* e);
|
||||||
|
extern char* _ext_str_cvt(struct EXTEND* e, int ndigit, int* decpt, int* sign, int ecvtflag);
|
||||||
|
|
||||||
|
#endif
|
|
@ -15,9 +15,9 @@ extern char* _findenv(const char* name, int* offset);
|
||||||
*/
|
*/
|
||||||
char* getenv(const char* name)
|
char* getenv(const char* name)
|
||||||
{
|
{
|
||||||
int offset;
|
int offset;
|
||||||
|
|
||||||
return(_findenv(name,&offset));
|
return (_findenv(name, &offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -31,21 +31,22 @@ char* getenv(const char* name)
|
||||||
*/
|
*/
|
||||||
char* _findenv(register const char* name, int* offset)
|
char* _findenv(register const char* name, int* offset)
|
||||||
{
|
{
|
||||||
extern char **environ;
|
extern char** environ;
|
||||||
register int len;
|
register int len;
|
||||||
register char **P;
|
register char** P;
|
||||||
register const char *C;
|
register const char* C;
|
||||||
|
|
||||||
if (!environ)
|
if (!environ)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (C = name,len = 0;*C && *C != '=';++C,++len);
|
for (C = name, len = 0; *C && *C != '='; ++C, ++len)
|
||||||
for (P = environ;*P;++P)
|
;
|
||||||
if (!strncmp(*P,name,len))
|
for (P = environ; *P; ++P)
|
||||||
if (*(C = *P + len) == '=') {
|
if (!strncmp(*P, name, len))
|
||||||
*offset = P - environ;
|
if (*(C = *P + len) == '=')
|
||||||
return (char*)(++C);
|
{
|
||||||
}
|
*offset = P - environ;
|
||||||
return(NULL);
|
return (char*)(++C);
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,10 +4,9 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
long
|
long labs(register long l)
|
||||||
labs(register long l)
|
|
||||||
{
|
{
|
||||||
return l >= 0 ? l : -l;
|
return l >= 0 ? l : -l;
|
||||||
}
|
}
|
|
@ -4,17 +4,18 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
ldiv_t
|
ldiv_t
|
||||||
ldiv(register long numer, register long denom)
|
ldiv(register long numer, register long denom)
|
||||||
{
|
{
|
||||||
ldiv_t r;
|
ldiv_t r;
|
||||||
|
|
||||||
r.quot = numer / denom; /* might trap if denom == 0 */
|
r.quot = numer / denom; /* might trap if denom == 0 */
|
||||||
r.rem = numer % denom;
|
r.rem = numer % denom;
|
||||||
|
|
||||||
if (r.rem != 0 && (numer > 0) != (r.rem > 0)) {
|
if (r.rem != 0 && (numer > 0) != (r.rem > 0))
|
||||||
|
{
|
||||||
r.quot++;
|
r.quot++;
|
||||||
r.rem -= denom;
|
r.rem -= denom;
|
||||||
}
|
}
|
|
@ -4,15 +4,16 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
#define CHAR_SHIFT 8
|
#define CHAR_SHIFT 8
|
||||||
|
|
||||||
int
|
int(mblen)(const char* s, size_t n)
|
||||||
(mblen)(const char *s, size_t n)
|
|
||||||
{
|
{
|
||||||
if (s == (const char *)NULL) return 0; /* no state dependent codings */
|
if (s == (const char*)NULL)
|
||||||
if (n <= 0) return 0;
|
return 0; /* no state dependent codings */
|
||||||
|
if (n <= 0)
|
||||||
|
return 0;
|
||||||
return (*s != 0);
|
return (*s != 0);
|
||||||
}
|
}
|
|
@ -4,17 +4,17 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
mbstowcs(register wchar_t *pwcs, register const char *s, size_t n)
|
mbstowcs(register wchar_t* pwcs, register const char* s, size_t n)
|
||||||
{
|
{
|
||||||
register int i = n;
|
register int i = n;
|
||||||
|
|
||||||
while (--i >= 0) {
|
while (--i >= 0)
|
||||||
|
{
|
||||||
if (!(*pwcs++ = *s++))
|
if (!(*pwcs++ = *s++))
|
||||||
return n - i - 1;
|
return n - i - 1;
|
||||||
}
|
}
|
||||||
return n - i;
|
return n - i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,16 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
int
|
int mbtowc(wchar_t* pwc, register const char* s, size_t n)
|
||||||
mbtowc(wchar_t *pwc, register const char *s, size_t n)
|
|
||||||
{
|
{
|
||||||
if (s == (const char *)NULL) return 0;
|
if (s == (const char*)NULL)
|
||||||
if (n <= 0) return 0;
|
return 0;
|
||||||
if (pwc) *pwc = *s;
|
if (n <= 0)
|
||||||
|
return 0;
|
||||||
|
if (pwc)
|
||||||
|
*pwc = *s;
|
||||||
return (*s != 0);
|
return (*s != 0);
|
||||||
}
|
}
|
|
@ -4,39 +4,45 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define ENTRY_INC 10
|
#define ENTRY_INC 10
|
||||||
#define rounded(x) (((x / ENTRY_INC) + 1) * ENTRY_INC)
|
#define rounded(x) (((x / ENTRY_INC) + 1) * ENTRY_INC)
|
||||||
|
|
||||||
extern char **environ;
|
extern char** environ;
|
||||||
|
|
||||||
int
|
int putenv(char* name)
|
||||||
putenv(char *name)
|
|
||||||
{
|
{
|
||||||
register char **v = environ;
|
register char** v = environ;
|
||||||
register char *r;
|
register char* r;
|
||||||
static int size = 0;
|
static int size = 0;
|
||||||
/* When size != 0, it contains the number of entries in the
|
/* When size != 0, it contains the number of entries in the
|
||||||
* table (including the final NULL pointer). This means that the
|
* table (including the final NULL pointer). This means that the
|
||||||
* last non-null entry is environ[size - 2].
|
* last non-null entry is environ[size - 2].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (!name) return 0;
|
if (!name)
|
||||||
if (r = strchr(name, '=')) {
|
return 0;
|
||||||
|
if (r = strchr(name, '='))
|
||||||
|
{
|
||||||
register const char *p, *q;
|
register const char *p, *q;
|
||||||
|
|
||||||
*r = '\0';
|
*r = '\0';
|
||||||
|
|
||||||
if (v != NULL) {
|
if (v != NULL)
|
||||||
while ((p = *v) != NULL) {
|
{
|
||||||
|
while ((p = *v) != NULL)
|
||||||
|
{
|
||||||
q = name;
|
q = name;
|
||||||
while (*q && (*q++ == *p++))
|
while (*q && (*q++ == *p++))
|
||||||
/* EMPTY */ ;
|
/* EMPTY */;
|
||||||
if (*q || (*p != '=')) {
|
if (*q || (*p != '='))
|
||||||
|
{
|
||||||
v++;
|
v++;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
/* The name was already in the
|
/* The name was already in the
|
||||||
* environment.
|
* environment.
|
||||||
*/
|
*/
|
||||||
|
@ -50,23 +56,28 @@ putenv(char *name)
|
||||||
v = environ;
|
v = environ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!size) {
|
if (!size)
|
||||||
register char **p;
|
{
|
||||||
|
register char** p;
|
||||||
register int i = 0;
|
register int i = 0;
|
||||||
|
|
||||||
if (v)
|
if (v)
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
i++;
|
i++;
|
||||||
} while (*v++);
|
} while (*v++);
|
||||||
if (!(v = malloc(rounded(i) * sizeof(char **))))
|
if (!(v = malloc(rounded(i) * sizeof(char**))))
|
||||||
return 1;
|
return 1;
|
||||||
size = i;
|
size = i;
|
||||||
p = environ;
|
p = environ;
|
||||||
environ = v;
|
environ = v;
|
||||||
while (*v++ = *p++); /* copy the environment */
|
while (*v++ = *p++)
|
||||||
|
; /* copy the environment */
|
||||||
v = environ;
|
v = environ;
|
||||||
} else if (!(size % ENTRY_INC)) {
|
}
|
||||||
if (!(v = realloc(environ, rounded(size) * sizeof(char **))))
|
else if (!(size % ENTRY_INC))
|
||||||
|
{
|
||||||
|
if (!(v = realloc(environ, rounded(size) * sizeof(char**))))
|
||||||
return 1;
|
return 1;
|
||||||
environ = v;
|
environ = v;
|
||||||
}
|
}
|
|
@ -4,36 +4,38 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
static void qsort1(char *, char *, size_t);
|
static void qsort1(char*, char*, size_t);
|
||||||
static int (*qcompar)(const char *, const char *);
|
static int (*qcompar)(const char*, const char*);
|
||||||
static void qexchange(char *, char *, size_t);
|
static void qexchange(char*, char*, size_t);
|
||||||
static void q3exchange(char *, char *, char *, size_t);
|
static void q3exchange(char*, char*, char*, size_t);
|
||||||
|
|
||||||
void
|
void qsort(void* base, size_t nel, size_t width,
|
||||||
qsort(void *base, size_t nel, size_t width,
|
int (*compar)(const void*, const void*))
|
||||||
int (*compar)(const void *, const void *))
|
|
||||||
{
|
{
|
||||||
/* when nel is 0, the expression '(nel - 1) * width' is wrong */
|
/* when nel is 0, the expression '(nel - 1) * width' is wrong */
|
||||||
if (!nel) return;
|
if (!nel)
|
||||||
qcompar = (int (*)(const char *, const char *)) compar;
|
return;
|
||||||
qsort1(base, (char *)base + (nel - 1) * width, width);
|
qcompar = (int (*)(const char*, const char*))compar;
|
||||||
|
qsort1(base, (char*)base + (nel - 1) * width, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qsort1(char *a1, char *a2, register size_t width)
|
qsort1(char* a1, char* a2, register size_t width)
|
||||||
{
|
{
|
||||||
register char *left, *right;
|
register char *left, *right;
|
||||||
register char *lefteq, *righteq;
|
register char *lefteq, *righteq;
|
||||||
int cmp;
|
int cmp;
|
||||||
|
|
||||||
for (;;) {
|
for (;;)
|
||||||
if (a2 <= a1) return;
|
{
|
||||||
|
if (a2 <= a1)
|
||||||
|
return;
|
||||||
left = a1;
|
left = a1;
|
||||||
right = a2;
|
right = a2;
|
||||||
lefteq = righteq = a1 + width * (((a2-a1)+width)/(2*width));
|
lefteq = righteq = a1 + width * (((a2 - a1) + width) / (2 * width));
|
||||||
/*
|
/*
|
||||||
Pick an element in the middle of the array.
|
Pick an element in the middle of the array.
|
||||||
We will collect the equals around it.
|
We will collect the equals around it.
|
||||||
"lefteq" and "righteq" indicate the left and right
|
"lefteq" and "righteq" indicate the left and right
|
||||||
|
@ -41,13 +43,16 @@ qsort1(char *a1, char *a2, register size_t width)
|
||||||
Smaller elements end up left of it, larger elements end
|
Smaller elements end up left of it, larger elements end
|
||||||
up right of it.
|
up right of it.
|
||||||
*/
|
*/
|
||||||
again:
|
again:
|
||||||
while (left < lefteq && (cmp = (*qcompar)(left, lefteq)) <= 0) {
|
while (left < lefteq && (cmp = (*qcompar)(left, lefteq)) <= 0)
|
||||||
if (cmp < 0) {
|
{
|
||||||
|
if (cmp < 0)
|
||||||
|
{
|
||||||
/* leave it where it is */
|
/* leave it where it is */
|
||||||
left += width;
|
left += width;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
/* equal, so exchange with the element to
|
/* equal, so exchange with the element to
|
||||||
the left of the "equal"-interval.
|
the left of the "equal"-interval.
|
||||||
*/
|
*/
|
||||||
|
@ -55,11 +60,14 @@ again:
|
||||||
qexchange(left, lefteq, width);
|
qexchange(left, lefteq, width);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while (right > righteq) {
|
while (right > righteq)
|
||||||
if ((cmp = (*qcompar)(right, righteq)) < 0) {
|
{
|
||||||
|
if ((cmp = (*qcompar)(right, righteq)) < 0)
|
||||||
|
{
|
||||||
/* smaller, should go to left part
|
/* smaller, should go to left part
|
||||||
*/
|
*/
|
||||||
if (left < lefteq) {
|
if (left < lefteq)
|
||||||
|
{
|
||||||
/* yes, we had a larger one at the
|
/* yes, we had a larger one at the
|
||||||
left, so we can just exchange
|
left, so we can just exchange
|
||||||
*/
|
*/
|
||||||
|
@ -80,16 +88,19 @@ again:
|
||||||
lefteq += width;
|
lefteq += width;
|
||||||
left = lefteq;
|
left = lefteq;
|
||||||
}
|
}
|
||||||
else if (cmp == 0) {
|
else if (cmp == 0)
|
||||||
|
{
|
||||||
/* equal, so exchange with the element to
|
/* equal, so exchange with the element to
|
||||||
the right of the "equal-interval"
|
the right of the "equal-interval"
|
||||||
*/
|
*/
|
||||||
righteq += width;
|
righteq += width;
|
||||||
qexchange(right, righteq, width);
|
qexchange(right, righteq, width);
|
||||||
}
|
}
|
||||||
else /* just leave it */ right -= width;
|
else /* just leave it */
|
||||||
|
right -= width;
|
||||||
}
|
}
|
||||||
if (left < lefteq) {
|
if (left < lefteq)
|
||||||
|
{
|
||||||
/* larger element to the left, but no more room,
|
/* larger element to the left, but no more room,
|
||||||
so move the "equal-interval" one place to the
|
so move the "equal-interval" one place to the
|
||||||
left, and the larger element to the right
|
left, and the larger element to the right
|
||||||
|
@ -112,12 +123,13 @@ again:
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qexchange(register char *p, register char *q,
|
qexchange(register char* p, register char* q,
|
||||||
register size_t n)
|
register size_t n)
|
||||||
{
|
{
|
||||||
register int c;
|
register int c;
|
||||||
|
|
||||||
while (n-- > 0) {
|
while (n-- > 0)
|
||||||
|
{
|
||||||
c = *p;
|
c = *p;
|
||||||
*p++ = *q;
|
*p++ = *q;
|
||||||
*q++ = c;
|
*q++ = c;
|
||||||
|
@ -125,12 +137,13 @@ qexchange(register char *p, register char *q,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
q3exchange(register char *p, register char *q, register char *r,
|
q3exchange(register char* p, register char* q, register char* r,
|
||||||
register size_t n)
|
register size_t n)
|
||||||
{
|
{
|
||||||
register int c;
|
register int c;
|
||||||
|
|
||||||
while (n-- > 0) {
|
while (n-- > 0)
|
||||||
|
{
|
||||||
c = *p;
|
c = *p;
|
||||||
*p++ = *r;
|
*p++ = *r;
|
||||||
*r++ = *q;
|
*r++ = *q;
|
|
@ -4,14 +4,14 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
static unsigned long int next = 1;
|
static unsigned long int next = 1;
|
||||||
|
|
||||||
int rand(void)
|
int rand(void)
|
||||||
{
|
{
|
||||||
next = next * 1103515245 + 12345;
|
next = next * 1103515245 + 12345;
|
||||||
return (unsigned int)(next/(2 * (RAND_MAX +1L)) % (RAND_MAX+1L));
|
return (unsigned int)(next / (2 * (RAND_MAX + 1L)) % (RAND_MAX + 1L));
|
||||||
}
|
}
|
||||||
|
|
||||||
void srand(unsigned int seed)
|
void srand(unsigned int seed)
|
94
lang/cem/libcc.ansi/core/stdlib/setenv.c
Normal file
94
lang/cem/libcc.ansi/core/stdlib/setenv.c
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
extern char* _findenv(const char* name, int* offset);
|
||||||
|
extern char** environ;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* setenv(name,value,rewrite)
|
||||||
|
* Set the value of the environmental variable "name" to be
|
||||||
|
* "value". If rewrite is set, replace any current value.
|
||||||
|
*/
|
||||||
|
int setenv(register const char* name, register const char* value, int rewrite)
|
||||||
|
{
|
||||||
|
static int alloced = 0; /* if allocated space before */
|
||||||
|
register char* C;
|
||||||
|
int l_value,
|
||||||
|
offset;
|
||||||
|
|
||||||
|
if (*value == '=') /* no `=' in value */
|
||||||
|
++value;
|
||||||
|
l_value = strlen(value);
|
||||||
|
if ((C = _findenv(name, &offset)))
|
||||||
|
{ /* find if already exists */
|
||||||
|
if (!rewrite)
|
||||||
|
return (0);
|
||||||
|
if (strlen(C) >= l_value)
|
||||||
|
{ /* old larger; copy over */
|
||||||
|
while (*C++ = *value++)
|
||||||
|
;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* create new slot */
|
||||||
|
register int cnt = 0;
|
||||||
|
register char** P;
|
||||||
|
|
||||||
|
if (environ)
|
||||||
|
for (P = environ; *P; ++P, ++cnt)
|
||||||
|
;
|
||||||
|
if (alloced)
|
||||||
|
{ /* just increase size */
|
||||||
|
environ = (char**)realloc((char*)environ,
|
||||||
|
(unsigned)(sizeof(char*) * (cnt + 2)));
|
||||||
|
if (!environ)
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* get new space */
|
||||||
|
alloced = 1; /* copy old entries into it */
|
||||||
|
P = (char**)malloc((unsigned)(sizeof(char*) * (cnt + 2)));
|
||||||
|
if (!P)
|
||||||
|
return (-1);
|
||||||
|
if (environ)
|
||||||
|
bcopy(environ, P, cnt * sizeof(char*));
|
||||||
|
environ = P;
|
||||||
|
}
|
||||||
|
environ[cnt + 1] = NULL;
|
||||||
|
offset = cnt;
|
||||||
|
}
|
||||||
|
for (C = (char*) name; *C && *C != '='; ++C)
|
||||||
|
; /* no `=' in name */
|
||||||
|
if (!(environ[offset] = /* name + `=' + value */
|
||||||
|
malloc((unsigned)((int)(C - name) + l_value + 2))))
|
||||||
|
return (-1);
|
||||||
|
for (C = environ[offset]; (*C = *name++) && *C != '='; ++C)
|
||||||
|
;
|
||||||
|
for (*C++ = '='; *C++ = *value++;)
|
||||||
|
;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unsetenv(name) --
|
||||||
|
* Delete environmental variable "name".
|
||||||
|
*/
|
||||||
|
int unsetenv(const char* name)
|
||||||
|
{
|
||||||
|
register char** P;
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
while (_findenv(name, &offset)) /* if set multiple times */
|
||||||
|
for (P = &environ[offset];; ++P)
|
||||||
|
if (!(*P = *(P + 1)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
18
lang/cem/libcc.ansi/core/stdlib/strtod.c
Normal file
18
lang/cem/libcc.ansi/core/stdlib/strtod.c
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <ack/config.h>
|
||||||
|
#include "ext_fmt.h"
|
||||||
|
|
||||||
|
#if ACKCONF_WANT_FLOAT
|
||||||
|
|
||||||
|
double
|
||||||
|
strtod(const char* p, char** pp)
|
||||||
|
{
|
||||||
|
struct EXTEND e;
|
||||||
|
|
||||||
|
_str_ext_cvt(p, pp, &e);
|
||||||
|
return _ext_dbl_cvt(&e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
116
lang/cem/libcc.ansi/core/stdlib/strtol.c
Normal file
116
lang/cem/libcc.ansi/core/stdlib/strtol.c
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
/*
|
||||||
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#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* nptr, char** endptr, int base)
|
||||||
|
{
|
||||||
|
return (signed long)string2long(nptr, endptr, base, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long int
|
||||||
|
strtoul(register const char* nptr, char** endptr, int 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 unsigned 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;
|
||||||
|
else
|
||||||
|
val = (val * base) + v;
|
||||||
|
}
|
||||||
|
nptr++;
|
||||||
|
}
|
||||||
|
if (endptr)
|
||||||
|
{
|
||||||
|
if (nrstart == nptr)
|
||||||
|
*endptr = (char*)startnptr;
|
||||||
|
else
|
||||||
|
*endptr = (char*)nptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ovfl)
|
||||||
|
{
|
||||||
|
/* Overflow is only possible when converting a signed long.
|
||||||
|
* The "-(LONG_MIN+1)+(unsigned long) 1" construction is there
|
||||||
|
* to prevent overflow warnings on -LONG_MIN.
|
||||||
|
*/
|
||||||
|
if (is_signed
|
||||||
|
&& ((sign < 0 && val > -(LONG_MIN + 1) + (unsigned long)1)
|
||||||
|
|| (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;
|
||||||
|
}
|
||||||
|
return (sign * val);
|
||||||
|
}
|
|
@ -4,16 +4,17 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
wcstombs(register char *s, register const wchar_t *pwcs, size_t n)
|
wcstombs(register char* s, register const wchar_t* pwcs, size_t n)
|
||||||
{
|
{
|
||||||
register int i = n;
|
register int i = n;
|
||||||
|
|
||||||
while (--i >= 0) {
|
while (--i >= 0)
|
||||||
|
{
|
||||||
if (!(*s++ = *pwcs++))
|
if (!(*s++ = *pwcs++))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
|
@ -4,13 +4,13 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
int
|
int wctomb(char* s, wchar_t wchar)
|
||||||
wctomb(char *s, wchar_t wchar)
|
|
||||||
{
|
{
|
||||||
if (!s) return 0; /* no state dependent codings */
|
if (!s)
|
||||||
|
return 0; /* no state dependent codings */
|
||||||
|
|
||||||
*s = wchar;
|
*s = wchar;
|
||||||
return 1;
|
return 1;
|
25
lang/cem/libcc.ansi/core/string/memchr.c
Normal file
25
lang/cem/libcc.ansi/core/string/memchr.c
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
void* memchr(const void* s, register int c, register size_t n)
|
||||||
|
{
|
||||||
|
register const unsigned char* s1 = s;
|
||||||
|
|
||||||
|
c = (unsigned char)c;
|
||||||
|
if (n)
|
||||||
|
{
|
||||||
|
n++;
|
||||||
|
while (--n > 0)
|
||||||
|
{
|
||||||
|
if (*s1++ != c)
|
||||||
|
continue;
|
||||||
|
return (void*)--s1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -4,17 +4,19 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
int
|
int memcmp(const void* s1, const void* s2, size_t n)
|
||||||
memcmp(const void *s1, const void *s2, size_t n)
|
|
||||||
{
|
{
|
||||||
register const unsigned char *p1 = s1, *p2 = s2;
|
register const unsigned char *p1 = s1, *p2 = s2;
|
||||||
|
|
||||||
if (n) {
|
if (n)
|
||||||
|
{
|
||||||
n++;
|
n++;
|
||||||
while (--n > 0) {
|
while (--n > 0)
|
||||||
if (*p1++ == *p2++) continue;
|
{
|
||||||
|
if (*p1++ == *p2++)
|
||||||
|
continue;
|
||||||
return *--p1 - *--p2;
|
return *--p1 - *--p2;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,18 +4,18 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void *
|
void* memcpy(void* s1, const void* s2, register size_t n)
|
||||||
memcpy(void *s1, const void *s2, register size_t n)
|
|
||||||
{
|
{
|
||||||
register char *p1 = s1;
|
register char* p1 = s1;
|
||||||
register const char *p2 = s2;
|
register const char* p2 = s2;
|
||||||
|
|
||||||
|
if (n)
|
||||||
if (n) {
|
{
|
||||||
n++;
|
n++;
|
||||||
while (--n > 0) {
|
while (--n > 0)
|
||||||
|
{
|
||||||
*p1++ = *p2++;
|
*p1++ = *p2++;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,26 +4,31 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void *
|
void* memmove(void* s1, const void* s2, register size_t n)
|
||||||
memmove(void *s1, const void *s2, register size_t n)
|
|
||||||
{
|
{
|
||||||
register char *p1 = s1;
|
register char* p1 = s1;
|
||||||
register const char *p2 = s2;
|
register const char* p2 = s2;
|
||||||
|
|
||||||
if (n>0) {
|
if (n > 0)
|
||||||
if (p2 <= p1 && p2 + n > p1) {
|
{
|
||||||
|
if (p2 <= p1 && p2 + n > p1)
|
||||||
|
{
|
||||||
/* overlap, copy backwards */
|
/* overlap, copy backwards */
|
||||||
p1 += n;
|
p1 += n;
|
||||||
p2 += n;
|
p2 += n;
|
||||||
n++;
|
n++;
|
||||||
while (--n > 0) {
|
while (--n > 0)
|
||||||
|
{
|
||||||
*--p1 = *--p2;
|
*--p1 = *--p2;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
n++;
|
n++;
|
||||||
while (--n > 0) {
|
while (--n > 0)
|
||||||
|
{
|
||||||
*p1++ = *p2++;
|
*p1++ = *p2++;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,16 +4,17 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
void *
|
void* memset(void* s, register int c, register size_t n)
|
||||||
memset(void *s, register int c, register size_t n)
|
|
||||||
{
|
{
|
||||||
register char *s1 = s;
|
register char* s1 = s;
|
||||||
|
|
||||||
if (n>0) {
|
if (n > 0)
|
||||||
|
{
|
||||||
n++;
|
n++;
|
||||||
while (--n > 0) {
|
while (--n > 0)
|
||||||
|
{
|
||||||
*s1++ = c;
|
*s1++ = c;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,17 +4,16 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
char *
|
char* strcat(char* ret, register const char* s2)
|
||||||
strcat(char *ret, register const char *s2)
|
|
||||||
{
|
{
|
||||||
register char *s1 = ret;
|
register char* s1 = ret;
|
||||||
|
|
||||||
while (*s1++ != '\0')
|
while (*s1++ != '\0')
|
||||||
/* EMPTY */ ;
|
/* EMPTY */;
|
||||||
s1--;
|
s1--;
|
||||||
while (*s1++ = *s2++)
|
while (*s1++ = *s2++)
|
||||||
/* EMPTY */ ;
|
/* EMPTY */;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
|
@ -4,15 +4,16 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
char *
|
char* strchr(register const char* s, register int c)
|
||||||
strchr(register const char *s, register int c)
|
|
||||||
{
|
{
|
||||||
c = (char) c;
|
c = (char)c;
|
||||||
|
|
||||||
while (c != *s) {
|
while (c != *s)
|
||||||
if (*s++ == '\0') return NULL;
|
{
|
||||||
|
if (*s++ == '\0')
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
return (char *)s;
|
return (char*)s;
|
||||||
}
|
}
|
23
lang/cem/libcc.ansi/core/string/strcmp.c
Normal file
23
lang/cem/libcc.ansi/core/string/strcmp.c
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int strcmp(register const char* s1, register const char* s2)
|
||||||
|
{
|
||||||
|
while (*s1 == *s2++)
|
||||||
|
{
|
||||||
|
if (*s1++ == '\0')
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (*s1 == '\0')
|
||||||
|
return -1;
|
||||||
|
if (*--s2 == '\0')
|
||||||
|
return 1;
|
||||||
|
return (unsigned char)*s1 - (unsigned char)*s2;
|
||||||
|
}
|
|
@ -4,14 +4,15 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
|
|
||||||
int
|
int strcoll(register const char* s1, register const char* s2)
|
||||||
strcoll(register const char *s1, register const char *s2)
|
|
||||||
{
|
{
|
||||||
while (*s1 == *s2++) {
|
while (*s1 == *s2++)
|
||||||
if (*s1++ == '\0') {
|
{
|
||||||
|
if (*s1++ == '\0')
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,15 +4,14 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
char *
|
char* strcpy(char* ret, register const char* s2)
|
||||||
strcpy(char *ret, register const char *s2)
|
|
||||||
{
|
{
|
||||||
register char *s1 = ret;
|
register char* s1 = ret;
|
||||||
|
|
||||||
while (*s1++ = *s2++)
|
while (*s1++ = *s2++)
|
||||||
/* EMPTY */ ;
|
/* EMPTY */;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
|
@ -4,16 +4,17 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
strcspn(const char *string, const char *notin)
|
strcspn(const char* string, const char* notin)
|
||||||
{
|
{
|
||||||
register const char *s1, *s2;
|
register const char *s1, *s2;
|
||||||
|
|
||||||
for (s1 = string; *s1; s1++) {
|
for (s1 = string; *s1; s1++)
|
||||||
for(s2 = notin; *s2 != *s1 && *s2; s2++)
|
{
|
||||||
/* EMPTY */ ;
|
for (s2 = notin; *s2 != *s1 && *s2; s2++)
|
||||||
|
/* EMPTY */;
|
||||||
if (*s2)
|
if (*s2)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
|
@ -7,12 +7,11 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
char*
|
char* strdup(const char* s)
|
||||||
strdup(const char *s)
|
|
||||||
{
|
{
|
||||||
int len = strlen(s);
|
int len = strlen(s);
|
||||||
char *p = malloc(len+1);
|
char* p = malloc(len + 1);
|
||||||
if (p)
|
if (p)
|
||||||
memcpy(p, s, len+1);
|
memcpy(p, s, len + 1);
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
|
@ -4,15 +4,15 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
strlen(const char *org)
|
strlen(const char* org)
|
||||||
{
|
{
|
||||||
register const char *s = org;
|
register const char* s = org;
|
||||||
|
|
||||||
while (*s++)
|
while (*s++)
|
||||||
/* EMPTY */ ;
|
/* EMPTY */;
|
||||||
|
|
||||||
return --s - org;
|
return --s - org;
|
||||||
}
|
}
|
|
@ -4,22 +4,26 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
char *
|
char* strncat(char* ret, register const char* s2, size_t n)
|
||||||
strncat(char *ret, register const char *s2, size_t n)
|
|
||||||
{
|
{
|
||||||
register char *s1 = ret;
|
register char* s1 = ret;
|
||||||
|
|
||||||
if (n > 0) {
|
if (n > 0)
|
||||||
|
{
|
||||||
while (*s1++)
|
while (*s1++)
|
||||||
/* EMPTY */ ;
|
/* EMPTY */;
|
||||||
s1--;
|
s1--;
|
||||||
while (*s1++ = *s2++) {
|
while (*s1++ = *s2++)
|
||||||
if (--n > 0) continue;
|
{
|
||||||
|
if (--n > 0)
|
||||||
|
continue;
|
||||||
*s1 = '\0';
|
*s1 = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
} else return s1;
|
}
|
||||||
|
else
|
||||||
|
return s1;
|
||||||
}
|
}
|
|
@ -4,22 +4,26 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
int
|
int strncmp(register const char* s1, register const char* s2, register size_t n)
|
||||||
strncmp(register const char *s1, register const char *s2, register size_t n)
|
|
||||||
{
|
{
|
||||||
if (n) {
|
if (n)
|
||||||
do {
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
if (*s1 != *s2++)
|
if (*s1 != *s2++)
|
||||||
break;
|
break;
|
||||||
if (*s1++ == '\0')
|
if (*s1++ == '\0')
|
||||||
return 0;
|
return 0;
|
||||||
} while (--n > 0);
|
} while (--n > 0);
|
||||||
if (n > 0) {
|
if (n > 0)
|
||||||
if (*s1 == '\0') return -1;
|
{
|
||||||
if (*--s2 == '\0') return 1;
|
if (*s1 == '\0')
|
||||||
return (unsigned char) *s1 - (unsigned char) *s2;
|
return -1;
|
||||||
|
if (*--s2 == '\0')
|
||||||
|
return 1;
|
||||||
|
return (unsigned char)*s1 - (unsigned char)*s2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
26
lang/cem/libcc.ansi/core/string/strncpy.c
Normal file
26
lang/cem/libcc.ansi/core/string/strncpy.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
||||||
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
char* strncpy(char* ret, register const char* s2, register size_t n)
|
||||||
|
{
|
||||||
|
register char* s1 = ret;
|
||||||
|
|
||||||
|
if (n > 0)
|
||||||
|
{
|
||||||
|
while ((*s1++ = *s2++) && --n > 0)
|
||||||
|
/* EMPTY */;
|
||||||
|
if ((*--s2 == '\0') && --n > 0)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
*s1++ = '\0';
|
||||||
|
} while (--n > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -4,19 +4,19 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
char *
|
char* strpbrk(register const char* string, register const char* brk)
|
||||||
strpbrk(register const char *string, register const char *brk)
|
|
||||||
{
|
{
|
||||||
register const char *s1;
|
register const char* s1;
|
||||||
|
|
||||||
while (*string) {
|
while (*string)
|
||||||
|
{
|
||||||
for (s1 = brk; *s1 && *s1 != *string; s1++)
|
for (s1 = brk; *s1 && *s1 != *string; s1++)
|
||||||
/* EMPTY */ ;
|
/* EMPTY */;
|
||||||
if (*s1)
|
if (*s1)
|
||||||
return (char *)string;
|
return (char*)string;
|
||||||
string++;
|
string++;
|
||||||
}
|
}
|
||||||
return (char *)NULL;
|
return (char*)NULL;
|
||||||
}
|
}
|
|
@ -4,19 +4,19 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
char *
|
char* strrchr(register const char* s, int c)
|
||||||
strrchr(register const char *s, int c)
|
|
||||||
{
|
{
|
||||||
register const char *result = NULL;
|
register const char* result = NULL;
|
||||||
|
|
||||||
c = (char) c;
|
c = (char)c;
|
||||||
|
|
||||||
do {
|
do
|
||||||
|
{
|
||||||
if (c == *s)
|
if (c == *s)
|
||||||
result = s;
|
result = s;
|
||||||
} while (*s++ != '\0');
|
} while (*s++ != '\0');
|
||||||
|
|
||||||
return (char *)result;
|
return (char*)result;
|
||||||
}
|
}
|
|
@ -4,16 +4,17 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
strspn(const char *string, const char *in)
|
strspn(const char* string, const char* in)
|
||||||
{
|
{
|
||||||
register const char *s1, *s2;
|
register const char *s1, *s2;
|
||||||
|
|
||||||
for (s1 = string; *s1; s1++) {
|
for (s1 = string; *s1; s1++)
|
||||||
|
{
|
||||||
for (s2 = in; *s2 && *s2 != *s1; s2++)
|
for (s2 = in; *s2 && *s2 != *s1; s2++)
|
||||||
/* EMPTY */ ;
|
/* EMPTY */;
|
||||||
if (*s2 == '\0')
|
if (*s2 == '\0')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
|
@ -4,16 +4,16 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
char *
|
char* strstr(register const char* s, register const char* wanted)
|
||||||
strstr(register const char *s, register const char *wanted)
|
|
||||||
{
|
{
|
||||||
register const int len = strlen(wanted);
|
register const int len = strlen(wanted);
|
||||||
|
|
||||||
if (len == 0) return (char *)s;
|
if (len == 0)
|
||||||
|
return (char*)s;
|
||||||
while (*s != *wanted || strncmp(s, wanted, len))
|
while (*s != *wanted || strncmp(s, wanted, len))
|
||||||
if (*s++ == '\0')
|
if (*s++ == '\0')
|
||||||
return (char *)NULL;
|
return (char*)NULL;
|
||||||
return (char *)s;
|
return (char*)s;
|
||||||
}
|
}
|
|
@ -4,23 +4,25 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
char *
|
char* strtok(register char* string, const char* separators)
|
||||||
strtok(register char *string, const char *separators)
|
|
||||||
{
|
{
|
||||||
register char *s1, *s2;
|
register char *s1, *s2;
|
||||||
static char *savestring;
|
static char* savestring;
|
||||||
|
|
||||||
if (string == NULL) {
|
if (string == NULL)
|
||||||
|
{
|
||||||
string = savestring;
|
string = savestring;
|
||||||
if (string == NULL) return (char *)NULL;
|
if (string == NULL)
|
||||||
|
return (char*)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
s1 = string + strspn(string, separators);
|
s1 = string + strspn(string, separators);
|
||||||
if (*s1 == '\0') {
|
if (*s1 == '\0')
|
||||||
|
{
|
||||||
savestring = NULL;
|
savestring = NULL;
|
||||||
return (char *)NULL;
|
return (char*)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
s2 = strpbrk(s1, separators);
|
s2 = strpbrk(s1, separators);
|
|
@ -4,18 +4,21 @@
|
||||||
*/
|
*/
|
||||||
/* $Id$ */
|
/* $Id$ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
strxfrm(register char *s1, register const char *save, register size_t n)
|
strxfrm(register char* s1, register const char* save, register size_t n)
|
||||||
{
|
{
|
||||||
register const char *s2 = save;
|
register const char* s2 = save;
|
||||||
|
|
||||||
while (*s2) {
|
while (*s2)
|
||||||
if (n > 1) {
|
{
|
||||||
|
if (n > 1)
|
||||||
|
{
|
||||||
n--;
|
n--;
|
||||||
*s1++ = *s2++;
|
*s1++ = *s2++;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
s2++;
|
s2++;
|
||||||
}
|
}
|
||||||
if (n > 0)
|
if (n > 0)
|
61
lang/cem/libcc.ansi/core/time/asctime.c
Normal file
61
lang/cem/libcc.ansi/core/time/asctime.c
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* asctime - print a date
|
||||||
|
*/
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include "loc_time.h"
|
||||||
|
|
||||||
|
#define DATE_STR "??? ??? ?? ??:??:?? ????\n"
|
||||||
|
|
||||||
|
static char*
|
||||||
|
two_digits(register char* pb, int i, int nospace)
|
||||||
|
{
|
||||||
|
*pb = (i / 10) % 10 + '0';
|
||||||
|
if (!nospace && *pb == '0')
|
||||||
|
*pb = ' ';
|
||||||
|
pb++;
|
||||||
|
*pb++ = (i % 10) + '0';
|
||||||
|
return ++pb;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char*
|
||||||
|
four_digits(register char* pb, int i)
|
||||||
|
{
|
||||||
|
i %= 10000;
|
||||||
|
*pb++ = (i / 1000) + '0';
|
||||||
|
i %= 1000;
|
||||||
|
*pb++ = (i / 100) + '0';
|
||||||
|
i %= 100;
|
||||||
|
*pb++ = (i / 10) + '0';
|
||||||
|
*pb++ = (i % 10) + '0';
|
||||||
|
return ++pb;
|
||||||
|
}
|
||||||
|
|
||||||
|
char* asctime(const struct tm* timeptr)
|
||||||
|
{
|
||||||
|
static char buf[26];
|
||||||
|
register char* pb = buf;
|
||||||
|
register const char* ps;
|
||||||
|
register int n;
|
||||||
|
|
||||||
|
strcpy(pb, DATE_STR);
|
||||||
|
ps = _days[timeptr->tm_wday];
|
||||||
|
n = ABB_LEN;
|
||||||
|
while (--n >= 0)
|
||||||
|
*pb++ = *ps++;
|
||||||
|
pb++;
|
||||||
|
ps = _months[timeptr->tm_mon];
|
||||||
|
n = ABB_LEN;
|
||||||
|
while (--n >= 0)
|
||||||
|
*pb++ = *ps++;
|
||||||
|
pb++;
|
||||||
|
pb = two_digits(
|
||||||
|
two_digits(
|
||||||
|
two_digits(two_digits(pb, timeptr->tm_mday, 0), timeptr->tm_hour, 1), timeptr->tm_min, 1),
|
||||||
|
timeptr->tm_sec, 1);
|
||||||
|
|
||||||
|
four_digits(pb, timeptr->tm_year + 1900);
|
||||||
|
return buf;
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue