Merge pull request #106 from davidgiven/dtrg-libc

Refactor the libc
This commit is contained in:
David Given 2018-06-23 23:28:21 +02:00 committed by GitHub
commit 91a978fa95
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
379 changed files with 6483 additions and 8742 deletions

View file

@ -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",
} }

View file

@ -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

View file

@ -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

View file

@ -1 +0,0 @@
assert.c

View file

@ -1,2 +0,0 @@
clean:
rm -f assert.o OLIST

View file

@ -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();
}

View file

@ -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 }
} }

View 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.

View file

@ -0,0 +1,6 @@
#include <ctype.h>
int tolower(int c)
{
return isupper(c) ? c - 'A' + 'a' : c;
}

View file

@ -0,0 +1,6 @@
#include <ctype.h>
int toupper(int c)
{
return islower(c) ? c - 'a' + 'A' : c;
}

View 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]);

View 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);
}

View file

@ -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];
} }

View file

@ -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 = "";

View 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;
}
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View file

@ -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

View 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View 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);
}

View 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();
}

View 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;
}

View file

@ -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

View file

@ -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 */

View file

@ -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;
} }

View file

@ -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);
} }

View 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;
}

View 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;
}

View 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;
}

View file

@ -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);
} }

View file

@ -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;
} }

View file

@ -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

View file

@ -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');
} }

View file

@ -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');
} }

View 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;
}

View file

@ -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;
} }

View 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

View 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

View 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

View file

@ -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);
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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);
} }

View file

@ -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;
} }

View file

@ -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);
} }

View file

@ -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;
} }

View file

@ -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;

View file

@ -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)

View 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;
}

View 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

View 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);
}

View file

@ -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;
} }

View file

@ -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;

View 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;
}

View file

@ -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;
} }
} }

View file

@ -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++;
} }
} }

View file

@ -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++;
} }
} }

View file

@ -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;
} }
} }

View file

@ -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;
} }

View file

@ -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;
} }

View 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;
}

View file

@ -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;
} }
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;

View 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;
}

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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;
} }

View file

@ -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);

View file

@ -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)

View 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