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",
"osx386",
"osxppc",
--"qemuppc",
-- --"qemuppc",
"pc86",
"rpi",
"pdpv7",
@ -22,7 +22,7 @@ vars.plats_with_tests = {
"linux68k",
"linux386",
"linuxppc",
--"qemuppc",
-- --"qemuppc",
"pc86",
}

View file

@ -1,6 +1,11 @@
#!/bin/sh
echo ""
if [ "$1" = "" ]; then
echo "No tests."
exit 0
fi
succeeding="$(find "$@" -size 0)"
notsucceeding="$(find "$@" ! -size 0)"
if [ "$notsucceeding" != "" ]; then

View file

@ -16,6 +16,6 @@ typedef struct{
int strlength;
} String;
String *_newstr() ;
extern String *_newstr(char* str);
#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 {
name = "ctype_tab",
srcs = { "./ctype/char.tab" }
srcs = { "./core/ctype/char.tab" }
}
normalrule {
name = "ctype_files",
ins = { "./ctype/genfiles" },
ins = { "./core/ctype/genfiles" },
outleaves = {
"isalnum.c",
"isalpha.c",
@ -33,31 +33,31 @@ for _, plat in ipairs(vars.plats) do
srcs = {
"+ctype_files",
"+ctype_tab",
"./ctype/*.c",
"./errno/*.c",
"./locale/*.c",
"./malloc/*.c",
"./math/*.c", -- hypot.c
"./math/*.e",
"./misc/environ.c", -- don't build everything here as it's all obsolete
"./setjmp/*.c",
"./setjmp/*.e",
"./signal/*.c",
"./assert/*.c",
"./stdio/*.c",
"./stdlib/*.c",
"./string/*.c",
"./time/*.c",
"./core/ctype/*.c",
"./core/errno/*.c",
"./core/locale/*.c",
"./core/math/*.c",
"./core/math/*.e",
"./core/misc/*.c",
"./core/setjmp/*.c",
"./core/setjmp/*.e",
"./core/stdlib/*.c",
"./core/string/*.c",
"./core/time/*.c",
"./sys/exit/*.c",
"./sys/malloc/*.c",
"./sys/misc/*.c",
"./sys/stdio/*.c",
},
hdrs = {}, -- must be empty
deps = {
"lang/cem/libcc.ansi/headers+pkg",
"plat/"..plat.."/include+pkg",
"./malloc/malloc.h",
"./math/localmath.h",
"./stdio/loc_incl.h",
"./stdlib/ext_fmt.h",
"./time/loc_time.h",
"./core/math/localmath.h",
"./core/stdlib/ext_fmt.h",
"./core/time/loc_time.h",
"./sys/malloc/malloc.h",
"./sys/stdio/loc_incl.h",
},
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

@ -10,8 +10,7 @@
* 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.
*/
char *
strerror(register int errnum)
char* strerror(register int errnum)
{
extern const char* _sys_errlist[];
extern const int _sys_nerr;

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

@ -8,8 +8,11 @@
#include <math.h>
#include <errno.h>
#include <ack/config.h>
#include "localmath.h"
#if ACKCONF_WANT_FLOAT
static double
asin_acos(double x, int cosfl)
{
@ -32,17 +35,21 @@ asin_acos(double x, int cosfl)
1.0
};
if (__IsNan(x)) {
if (__IsNan(x))
{
errno = EDOM;
return x;
}
if (negative) {
if (negative)
{
x = -x;
}
if (x > 0.5) {
if (x > 0.5)
{
i = 1;
if (x > 1) {
if (x > 1)
{
errno = EDOM;
return 0;
}
@ -50,22 +57,28 @@ asin_acos(double x, int cosfl)
x = -sqrt(g);
x += x;
}
else {
else
{
/* ??? avoid underflow ??? */
i = 0;
g = x * x;
}
x += x * g * POLYNOM4(g, p) / POLYNOM5(g, q);
if (cosfl) {
if (! negative) x = -x;
if (cosfl)
{
if (!negative)
x = -x;
}
if ((cosfl == 0) == (i == 1)) {
if ((cosfl == 0) == (i == 1))
{
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;
}
if (! cosfl && negative) x = -x;
if (!cosfl && negative)
x = -x;
return x;
}
@ -80,3 +93,5 @@ acos(double x)
{
return asin_acos(x, 1);
}
#endif

View file

@ -9,8 +9,11 @@
#include <float.h>
#include <math.h>
#include <errno.h>
#include <ack/config.h>
#include "localmath.h"
#if ACKCONF_WANT_FLOAT
double
atan(double x)
{
@ -43,30 +46,38 @@ atan(double x)
int n;
double g;
if (__IsNan(x)) {
if (__IsNan(x))
{
errno = EDOM;
return x;
}
if (neg) {
if (neg)
{
x = -x;
}
if (x > 1.0) {
if (x > 1.0)
{
x = 1.0 / x;
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;
x = (((0.73205080756887729353*x-0.5)-0.5)+x)/
(1.73205080756887729353+x);
x = (((0.73205080756887729353 * x - 0.5) - 0.5) + x) / (1.73205080756887729353 + x);
}
/* ??? avoid underflow ??? */
g = x * x;
x += x * g * POLYNOM3(g, p) / POLYNOM4(g, q);
if (n > 1) x = -x;
if (n > 1)
x = -x;
x += a[n];
return neg ? -x : x;
}
#endif

View file

@ -8,35 +8,47 @@
#include <math.h>
#include <errno.h>
#include <ack/config.h>
#include "localmath.h"
#if ACKCONF_WANT_FLOAT
double
atan2(double y, double x)
{
double absx, absy, val;
if (x == 0 && y == 0) {
if (x == 0 && y == 0)
{
errno = EDOM;
return 0;
}
absy = y < 0 ? -y : y;
absx = x < 0 ? -x : x;
if (absy - absx == absy) {
if (absy - absx == absy)
{
/* x negligible compared to y */
return y < 0 ? -M_PI_2 : M_PI_2;
}
if (absx - absy == absx) {
if (absx - absy == absx)
{
/* y negligible compared to x */
val = 0.0;
}
else val = atan(y/x);
if (x > 0) {
else
val = atan(y / x);
if (x > 0)
{
/* first or fourth quadrant; already correct */
return val;
}
if (y < 0) {
if (y < 0)
{
/* third quadrant */
return val - M_PI;
}
return val + M_PI;
}
#endif

View file

@ -7,6 +7,9 @@
/* $Id$ */
#include <math.h>
#include <ack/config.h>
#if ACKCONF_WANT_FLOAT
double
ceil(double x)
@ -18,3 +21,6 @@ ceil(double x)
fractional part
*/
}
#endif

View file

@ -9,8 +9,10 @@
#include <math.h>
#include <float.h>
#include <errno.h>
#include <ack/config.h>
#include "localmath.h"
#if ACKCONF_WANT_FLOAT
double
exp(double x)
@ -36,20 +38,24 @@ exp(double x)
int n;
int negative = x < 0;
if (__IsNan(x)) {
if (__IsNan(x))
{
errno = EDOM;
return x;
}
if (x < M_LN_MIN_D) {
if (x < M_LN_MIN_D)
{
errno = ERANGE;
return 0.0;
}
if (x > M_LN_MAX_D) {
if (x > M_LN_MAX_D)
{
errno = ERANGE;
return HUGE_VAL;
}
if (negative) x = -x;
if (negative)
x = -x;
/* ??? avoid underflow ??? */
@ -61,7 +67,8 @@ exp(double x)
g = ((x1 - xn * 0.693359375) + x2) - xn * (-2.1219444005469058277e-4);
}
if (negative) {
if (negative)
{
g = -g;
n = -n;
}
@ -70,3 +77,6 @@ exp(double x)
n += 1;
return (ldexp(0.5 + x / (POLYNOM3(xn, q) - x), n));
}
#endif

View file

@ -5,9 +5,15 @@
* Author: Ceriel J.H. Jacobs
*/
/* $Id$ */
#include <ack/config.h>
#if ACKCONF_WANT_FLOAT
double
fabs(double x)
{
return x < 0 ? -x : x;
}
#endif

View file

@ -7,6 +7,9 @@
/* $Id$ */
#include <math.h>
#include <ack/config.h>
#if ACKCONF_WANT_FLOAT
double
floor(double x)
@ -18,3 +21,6 @@ floor(double x)
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$ */
#include <ack/config.h>
mes 2,_EM_WSIZE,_EM_PSIZE
#if ACKCONF_WANT_FLOAT
exp $frexp
pro $frexp,0
lal 0
@ -16,3 +20,5 @@
sti _EM_WSIZE
ret _EM_DSIZE
end
#endif

View file

@ -7,5 +7,11 @@
/* $Id$ */
#include <math.h>
#include <ack/config.h>
#if ACKCONF_WANT_FLOAT
double __huge_val = 1.0e+1000; /* This will generate a warning */
#endif

View file

@ -6,6 +6,9 @@
*/
#include <math.h>
#include <ack/config.h>
#if ACKCONF_WANT_FLOAT
/* $Id$ */
@ -14,20 +17,25 @@ hypot(double x,double y)
{
/* Computes sqrt(x*x+y*y), avoiding overflow */
if (x < 0) x = -x;
if (y < 0) y = -y;
if (x > y) {
if (x < 0)
x = -x;
if (y < 0)
y = -y;
if (x > y)
{
double t = y;
y = x;
x = t;
}
/* 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;
return y * sqrt(x * x + 1.0);
}
struct complex {
struct complex
{
double r, i;
};
@ -36,3 +44,6 @@ cabs(struct complex p_compl)
{
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

@ -7,6 +7,9 @@
#include <math.h>
#include <float.h>
#include <errno.h>
#include <ack/config.h>
#if ACKCONF_WANT_FLOAT
double
ldexp(double fl, int exp)
@ -14,38 +17,48 @@ ldexp(double fl, int exp)
int sign = 1;
int currexp;
if (__IsNan(fl)) {
if (__IsNan(fl))
{
errno = EDOM;
return fl;
}
if (fl == 0.0) return 0.0;
if (fl<0) {
if (fl == 0.0)
return 0.0;
if (fl < 0)
{
fl = -fl;
sign = -1;
}
if (fl > DBL_MAX) { /* for infinity */
if (fl > DBL_MAX)
{ /* for infinity */
errno = ERANGE;
return sign * fl;
}
fl = frexp(fl, &currexp);
exp += currexp;
if (exp > 0) {
if (exp > DBL_MAX_EXP) {
if (exp > 0)
{
if (exp > DBL_MAX_EXP)
{
errno = ERANGE;
return sign * HUGE_VAL;
}
while (exp>30) {
while (exp > 30)
{
fl *= (double)(1L << 30);
exp -= 30;
}
fl *= (double)(1L << exp);
}
else {
else
{
/* number need not be normalized */
if (exp < DBL_MIN_EXP - DBL_MANT_DIG) {
if (exp < DBL_MIN_EXP - DBL_MANT_DIG)
{
return 0.0;
}
while (exp<-30) {
while (exp < -30)
{
fl /= (double)(1L << 30);
exp += 30;
}
@ -53,3 +66,6 @@ ldexp(double fl, int exp)
}
return sign * fl;
}
#endif

View file

@ -9,8 +9,11 @@
#include <math.h>
#include <float.h>
#include <errno.h>
#include <ack/config.h>
#include "localmath.h"
#if ACKCONF_WANT_FLOAT
double
log(double x)
{
@ -33,35 +36,46 @@ log(double x)
double znum, zden, z, w;
int exponent;
if (__IsNan(x)) {
if (__IsNan(x))
{
errno = EDOM;
return x;
}
if (x < 0) {
if (x < 0)
{
errno = EDOM;
return -HUGE_VAL;
}
else if (x == 0) {
else if (x == 0)
{
errno = ERANGE;
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);
if (x > M_1_SQRT2) {
if (x > M_1_SQRT2)
{
znum = (x - 0.5) - 0.5;
zden = x * 0.5 + 0.5;
}
else {
else
{
znum = x - 0.5;
zden = znum * 0.5 + 0.5;
exponent--;
}
z = znum/zden; w = z * z;
z = znum / zden;
w = z * z;
x = z + z * w * (POLYNOM2(w, a) / POLYNOM3(w, b));
z = exponent;
x += z * (-2.121944400546905827679e-4);
return x + z * 0.693359375;
}
#endif

View file

@ -8,23 +8,32 @@
#include <math.h>
#include <errno.h>
#include <ack/config.h>
#include "localmath.h"
#if ACKCONF_WANT_FLOAT
double
log10(double x)
{
if (__IsNan(x)) {
if (__IsNan(x))
{
errno = EDOM;
return x;
}
if (x < 0) {
if (x < 0)
{
errno = EDOM;
return -HUGE_VAL;
}
else if (x == 0) {
else if (x == 0)
{
errno = ERANGE;
return -HUGE_VAL;
}
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".
*/
/* $Id$ */
#include <ack/config.h>
mes 2,_EM_WSIZE,_EM_PSIZE
#if ACKCONF_WANT_FLOAT
exp $modf
pro $modf,0
lal 0
@ -20,3 +23,4 @@
sti _EM_DSIZE
ret _EM_DSIZE
end
#endif

View file

@ -10,6 +10,9 @@
#include <float.h>
#include <errno.h>
#include <limits.h>
#include <ack/config.h>
#if ACKCONF_WANT_FLOAT
double
pow(double x, double y)
@ -19,82 +22,107 @@ pow(double x, double y)
int ex, newexp;
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;
return 0;
}
if (y == 0) return 1.0;
if (y == 0)
return 1.0;
if (y < 0) {
if (y < 0)
{
y = -y;
negexp = 1;
}
else negexp = 0;
else
negexp = 0;
y_fractpart = modf(y, &y_intpart);
if (y_fractpart != 0) {
if (x < 0) {
if (y_fractpart != 0)
{
if (x < 0)
{
errno = EDOM;
return 0;
}
}
negx = 0;
if (x < 0) {
if (x < 0)
{
x = -x;
negx = 1;
}
if (y_intpart > ULONG_MAX) {
if (negx && modf(y_intpart/2.0, &y_fractpart) == 0) {
if (y_intpart > ULONG_MAX)
{
if (negx && modf(y_intpart / 2.0, &y_fractpart) == 0)
{
negx = 0;
}
x = log(x);
/* Beware of overflow in the multiplication */
if (x > 1.0 && y > DBL_MAX/x) {
if (x > 1.0 && y > DBL_MAX / x)
{
errno = ERANGE;
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);
}
if (y_fractpart != 0) {
if (y_fractpart != 0)
{
fp = exp(y_fractpart * log(x));
}
else fp = 1.0;
else
fp = 1.0;
yi = y_intpart;
if (! (yi & 1)) negx = 0;
if (!(yi & 1))
negx = 0;
x = frexp(x, &ex);
newexp = 0;
for (;;) {
if (yi & 1) {
for (;;)
{
if (yi & 1)
{
fp *= x;
newexp += ex;
}
yi >>= 1;
if (yi == 0) break;
if (yi == 0)
break;
x *= x;
ex <<= 1;
if (x < 0.5) {
if (x < 0.5)
{
x += x;
ex -= 1;
}
}
if (negexp) {
if (negexp)
{
fp = 1.0 / fp;
newexp = -newexp;
}
if (negx) {
if (negx)
{
return -ldexp(fp, newexp);
}
return ldexp(fp, newexp);
}
#endif

View file

@ -9,8 +9,11 @@
#include <math.h>
#include <float.h>
#include <errno.h>
#include <ack/config.h>
#include "localmath.h"
#if ACKCONF_WANT_FLOAT
static double
sinus(double x, int cos_flag)
{
@ -33,25 +36,30 @@ sinus(double x, int cos_flag)
double y;
int neg = 1;
if (__IsNan(x)) {
if (__IsNan(x))
{
errno = EDOM;
return x;
}
if (x < 0) {
if (x < 0)
{
x = -x;
neg = -1;
}
if (cos_flag) {
if (cos_flag)
{
neg = 1;
y = M_PI_2 + x;
}
else y = x;
else
y = x;
/* ??? avoid loss of significance, if y is too large, error ??? */
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.
Here we used 12 bits of the mantissa for a1.
@ -63,8 +71,10 @@ sinus(double x, int cos_flag)
double x1, x2;
modf(y, &y);
if (modf(0.5*y, &x1)) neg = -neg;
if (cos_flag) y -= 0.5;
if (modf(0.5 * y, &x1))
neg = -neg;
if (cos_flag)
y -= 0.5;
x2 = modf(x, &x1);
x = x1 - y * A1;
x += x2;
@ -73,7 +83,8 @@ sinus(double x, int cos_flag)
#undef A2
}
if (x < 0) {
if (x < 0)
{
neg = -neg;
x = -x;
}
@ -94,6 +105,10 @@ sin(double x)
double
cos(double x)
{
if (x < 0) x = -x;
if (x < 0)
x = -x;
return sinus(x, 1);
}
#endif

View file

@ -9,8 +9,11 @@
#include <math.h>
#include <float.h>
#include <errno.h>
#include <ack/config.h>
#include "localmath.h"
#if ACKCONF_WANT_FLOAT
static double
sinh_cosh(double x, int cosh_flag)
{
@ -34,32 +37,38 @@ sinh_cosh(double x, int cosh_flag)
int negative = x < 0;
double y = negative ? -x : x;
if (__IsNan(x)) {
if (__IsNan(x))
{
errno = EDOM;
return x;
}
if (! cosh_flag && y <= 1.0) {
if (!cosh_flag && y <= 1.0)
{
/* ??? check for underflow ??? */
y = y * y;
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
#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 += VD2M1 * x;
}
else {
else
{
errno = ERANGE;
x = HUGE_VAL;
}
}
else {
else
{
double z = exp(y);
x = 0.5 * (z + (cosh_flag ? 1.0 : -1.0) / z);
@ -76,6 +85,10 @@ sinh(double x)
double
cosh(double x)
{
if (x < 0) x = -x;
if (x < 0)
x = -x;
return sinh_cosh(x, 1);
}
#endif

View file

@ -9,6 +9,9 @@
#include <math.h>
#include <float.h>
#include <errno.h>
#include <ack/config.h>
#if ACKCONF_WANT_FLOAT
#define NITER 5
@ -18,26 +21,35 @@ sqrt(double x)
int exponent;
double val;
if (__IsNan(x)) {
if (__IsNan(x))
{
errno = EDOM;
return x;
}
if (x <= 0) {
if (x < 0) errno = EDOM;
if (x <= 0)
{
if (x < 0)
errno = EDOM;
return 0;
}
if (x > DBL_MAX) return x; /* for infinity */
if (x > DBL_MAX)
return x; /* for infinity */
val = frexp(x, &exponent);
if (exponent & 1) {
if (exponent & 1)
{
exponent--;
val *= 2;
}
val = ldexp(val + 1.0, exponent / 2 - 1);
/* 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;
}
return val;
}
#endif

View file

@ -9,8 +9,11 @@
#include <math.h>
#include <float.h>
#include <errno.h>
#include <ack/config.h>
#include "localmath.h"
#if ACKCONF_WANT_FLOAT
double
tan(double x)
{
@ -36,17 +39,20 @@ tan(double x)
0.49819433993786512270e-6
};
if (__IsNan(x)) {
if (__IsNan(x))
{
errno = EDOM;
return x;
}
if (negative) x = -x;
if (negative)
x = -x;
/* ??? avoid loss of significance, error if x is too large ??? */
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.
Here we used 12 bits of the mantissa for a1.
@ -58,7 +64,8 @@ tan(double x)
double x1, x2;
modf(y, &y);
if (modf(0.5*y, &x1)) invert = 1;
if (modf(0.5 * y, &x1))
invert = 1;
x2 = modf(x, &x1);
x = x1 - y * A1;
x += x2;
@ -71,6 +78,10 @@ tan(double x)
y = x * x;
x += x * y * POLYNOM2(y, p + 1);
y = POLYNOM4(y, q);
if (negative) x = -x;
if (negative)
x = -x;
return invert ? -y / x : x / y;
}
#endif

View file

@ -9,8 +9,11 @@
#include <float.h>
#include <math.h>
#include <errno.h>
#include <ack/config.h>
#include "localmath.h"
#if ACKCONF_WANT_FLOAT
double
tanh(double x)
{
@ -32,24 +35,32 @@ tanh(double x)
};
int negative = x < 0;
if (__IsNan(x)) {
if (__IsNan(x))
{
errno = EDOM;
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;
}
#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 += x;
}
else {
else
{
/* ??? avoid underflow ??? */
double g = x * x;
x += x * g * POLYNOM2(g, p) / POLYNOM3(g, q);
}
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$ */
#if defined(_POSIX_SOURCE)
#include <stdlib.h>
#include <sys/types.h>
#endif
#include <signal.h>
int
raise(int sig)
#if ACKCONF_WANT_EMULATED_RAISE
int raise(int sig)
{
if (sig < 0 || sig > _NSIG)
return -1;
return kill(getpid(), sig);
}
#endif

View file

@ -16,23 +16,24 @@
int _sigprocmask(int, sigset_t*, sigset_t*);
static void
__testsigset(void) {
__testsigset(void)
{
/* 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 sizeof(sigset_t) <= sizeof(long):
break;
}
}
void
__newsigset(sigset_t *p)
void __newsigset(sigset_t* p)
{
/* The SIG_SETMASK is not significant */
_sigprocmask(SIG_SETMASK, NULL, p);
}
void
__oldsigset(sigset_t *p)
void __oldsigset(sigset_t* p)
{
_sigprocmask(SIG_SETMASK, p, NULL);
}

View file

@ -5,10 +5,10 @@
#include <stdio.h>
int
fgetpos(FILE *stream, fpos_t *pos)
int fgetpos(FILE* stream, fpos_t* pos)
{
*pos = ftell(stream);
if (*pos == -1) return -1;
if (*pos == -1)
return -1;
return 0;
}

View file

@ -5,8 +5,7 @@
#include <stdio.h>
int
fsetpos(FILE *stream, fpos_t *pos)
int fsetpos(FILE* stream, fpos_t* pos)
{
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

@ -4,10 +4,8 @@
/* $Id$ */
#include <stdio.h>
#include "loc_incl.h"
void
rewind(FILE *stream)
void rewind(FILE* stream)
{
(void)fseek(stream, 0L, SEEK_SET);
clearerr(stream);

View file

@ -6,8 +6,7 @@
#include <stdlib.h>
int
abs(register int i)
int abs(register int i)
{
return i >= 0 ? i : -i;
}

View file

@ -6,9 +6,11 @@
#include <stdlib.h>
#include <errno.h>
#include <ack/config.h>
double
(atof)(const char *nptr)
#if ACKCONF_WANT_FLOAT
double(atof)(const char* nptr)
{
double d;
int e = errno;
@ -17,3 +19,5 @@ double
errno = e;
return d;
}
#endif

View file

@ -9,19 +9,22 @@
/* We do not use strtol here for backwards compatibility in behaviour on
overflow.
*/
int
atoi(register const char *nptr)
int atoi(register const char* nptr)
{
int total = 0;
int minus = 0;
while (isspace(*nptr)) nptr++;
if (*nptr == '+') nptr++;
else if (*nptr == '-') {
while (isspace(*nptr))
nptr++;
if (*nptr == '+')
nptr++;
else if (*nptr == '-')
{
minus = 1;
nptr++;
}
while (isdigit(*nptr)) {
while (isdigit(*nptr))
{
total *= 10;
total += (*nptr++ - '0');
}

View file

@ -9,19 +9,22 @@
/* We do not use strtol here for backwards compatibility in behaviour on
overflow.
*/
long
atol(register const char *nptr)
long atol(register const char* nptr)
{
long total = 0;
int minus = 0;
while (isspace(*nptr)) nptr++;
if (*nptr == '+') nptr++;
else if (*nptr == '-') {
while (isspace(*nptr))
nptr++;
if (*nptr == '+')
nptr++;
else if (*nptr == '-')
{
minus = 1;
nptr++;
}
while (isdigit(*nptr)) {
while (isdigit(*nptr))
{
total *= 10;
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

@ -6,15 +6,15 @@
#include <stdlib.h>
div_t
div(register int numer, register int denom)
div_t div(register int numer, register int denom)
{
div_t r;
r.quot = numer / denom; /* might trap if denom == 0 */
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.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

@ -39,13 +39,14 @@ char* _findenv(register const char* name, int* offset)
if (!environ)
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))
if (*(C = *P + len) == '=') {
if (*(C = *P + len) == '=')
{
*offset = P - environ;
return (char*)(++C);
}
return (NULL);
}

View file

@ -6,8 +6,7 @@
#include <stdlib.h>
long
labs(register long l)
long labs(register long l)
{
return l >= 0 ? l : -l;
}

View file

@ -14,7 +14,8 @@ ldiv(register long numer, register long denom)
r.quot = numer / denom; /* might trap if denom == 0 */
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.rem -= denom;
}

View file

@ -9,10 +9,11 @@
#define CHAR_SHIFT 8
int
(mblen)(const char *s, size_t n)
int(mblen)(const char* s, size_t n)
{
if (s == (const char *)NULL) return 0; /* no state dependent codings */
if (n <= 0) return 0;
if (s == (const char*)NULL)
return 0; /* no state dependent codings */
if (n <= 0)
return 0;
return (*s != 0);
}

View file

@ -11,10 +11,10 @@ mbstowcs(register wchar_t *pwcs, register const char *s, size_t n)
{
register int i = n;
while (--i >= 0) {
while (--i >= 0)
{
if (!(*pwcs++ = *s++))
return n - i - 1;
}
return n - i;
}

View file

@ -7,11 +7,13 @@
#include <stdlib.h>
#include <limits.h>
int
mbtowc(wchar_t *pwc, register const char *s, size_t n)
int mbtowc(wchar_t* pwc, register const char* s, size_t n)
{
if (s == (const char *)NULL) return 0;
if (n <= 0) return 0;
if (pwc) *pwc = *s;
if (s == (const char*)NULL)
return 0;
if (n <= 0)
return 0;
if (pwc)
*pwc = *s;
return (*s != 0);
}

View file

@ -12,8 +12,7 @@
extern char** environ;
int
putenv(char *name)
int putenv(char* name)
{
register char** v = environ;
register char* r;
@ -23,20 +22,27 @@ putenv(char *name)
* last non-null entry is environ[size - 2].
*/
if (!name) return 0;
if (r = strchr(name, '=')) {
if (!name)
return 0;
if (r = strchr(name, '='))
{
register const char *p, *q;
*r = '\0';
if (v != NULL) {
while ((p = *v) != NULL) {
if (v != NULL)
{
while ((p = *v) != NULL)
{
q = name;
while (*q && (*q++ == *p++))
/* EMPTY */;
if (*q || (*p != '=')) {
if (*q || (*p != '='))
{
v++;
} else {
}
else
{
/* The name was already in the
* environment.
*/
@ -50,12 +56,14 @@ putenv(char *name)
v = environ;
}
if (!size) {
if (!size)
{
register char** p;
register int i = 0;
if (v)
do {
do
{
i++;
} while (*v++);
if (!(v = malloc(rounded(i) * sizeof(char**))))
@ -63,9 +71,12 @@ putenv(char *name)
size = i;
p = environ;
environ = v;
while (*v++ = *p++); /* copy the environment */
while (*v++ = *p++)
; /* copy the environment */
v = environ;
} else if (!(size % ENTRY_INC)) {
}
else if (!(size % ENTRY_INC))
{
if (!(v = realloc(environ, rounded(size) * sizeof(char**))))
return 1;
environ = v;

View file

@ -11,12 +11,12 @@ static int (*qcompar)(const char *, const char *);
static void qexchange(char*, char*, size_t);
static void q3exchange(char*, char*, char*, size_t);
void
qsort(void *base, size_t nel, size_t width,
void qsort(void* base, size_t nel, size_t width,
int (*compar)(const void*, const void*))
{
/* when nel is 0, the expression '(nel - 1) * width' is wrong */
if (!nel) return;
if (!nel)
return;
qcompar = (int (*)(const char*, const char*))compar;
qsort1(base, (char*)base + (nel - 1) * width, width);
}
@ -28,8 +28,10 @@ qsort1(char *a1, char *a2, register size_t width)
register char *lefteq, *righteq;
int cmp;
for (;;) {
if (a2 <= a1) return;
for (;;)
{
if (a2 <= a1)
return;
left = a1;
right = a2;
lefteq = righteq = a1 + width * (((a2 - a1) + width) / (2 * width));
@ -42,12 +44,15 @@ qsort1(char *a1, char *a2, register size_t width)
up right of it.
*/
again:
while (left < lefteq && (cmp = (*qcompar)(left, lefteq)) <= 0) {
if (cmp < 0) {
while (left < lefteq && (cmp = (*qcompar)(left, lefteq)) <= 0)
{
if (cmp < 0)
{
/* leave it where it is */
left += width;
}
else {
else
{
/* equal, so exchange with the element to
the left of the "equal"-interval.
*/
@ -55,11 +60,14 @@ again:
qexchange(left, lefteq, width);
}
}
while (right > righteq) {
if ((cmp = (*qcompar)(right, righteq)) < 0) {
while (right > righteq)
{
if ((cmp = (*qcompar)(right, righteq)) < 0)
{
/* smaller, should go to left part
*/
if (left < lefteq) {
if (left < lefteq)
{
/* yes, we had a larger one at the
left, so we can just exchange
*/
@ -80,16 +88,19 @@ again:
lefteq += width;
left = lefteq;
}
else if (cmp == 0) {
else if (cmp == 0)
{
/* equal, so exchange with the element to
the right of the "equal-interval"
*/
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,
so move the "equal-interval" one place to the
left, and the larger element to the right
@ -117,7 +128,8 @@ qexchange(register char *p, register char *q,
{
register int c;
while (n-- > 0) {
while (n-- > 0)
{
c = *p;
*p++ = *q;
*q++ = c;
@ -130,7 +142,8 @@ q3exchange(register char *p, register char *q, register char *r,
{
register int c;
while (n-- > 0) {
while (n-- > 0)
{
c = *p;
*p++ = *r;
*r++ = *q;

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

@ -13,7 +13,8 @@ wcstombs(register char *s, register const wchar_t *pwcs, size_t n)
{
register int i = n;
while (--i >= 0) {
while (--i >= 0)
{
if (!(*s++ = *pwcs++))
break;
}

View file

@ -7,10 +7,10 @@
#include <stdlib.h>
#include <limits.h>
int
wctomb(char *s, wchar_t wchar)
int wctomb(char* s, wchar_t wchar)
{
if (!s) return 0; /* no state dependent codings */
if (!s)
return 0; /* no state dependent codings */
*s = wchar;
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

@ -6,15 +6,17 @@
#include <string.h>
int
memcmp(const void *s1, const void *s2, size_t n)
int memcmp(const void* s1, const void* s2, size_t n)
{
register const unsigned char *p1 = s1, *p2 = s2;
if (n) {
if (n)
{
n++;
while (--n > 0) {
if (*p1++ == *p2++) continue;
while (--n > 0)
{
if (*p1++ == *p2++)
continue;
return *--p1 - *--p2;
}
}

View file

@ -6,16 +6,16 @@
#include <string.h>
void *
memcpy(void *s1, const void *s2, register size_t n)
void* memcpy(void* s1, const void* s2, register size_t n)
{
register char* p1 = s1;
register const char* p2 = s2;
if (n) {
if (n)
{
n++;
while (--n > 0) {
while (--n > 0)
{
*p1++ = *p2++;
}
}

View file

@ -6,24 +6,29 @@
#include <string.h>
void *
memmove(void *s1, const void *s2, register size_t n)
void* memmove(void* s1, const void* s2, register size_t n)
{
register char* p1 = s1;
register const char* p2 = s2;
if (n>0) {
if (p2 <= p1 && p2 + n > p1) {
if (n > 0)
{
if (p2 <= p1 && p2 + n > p1)
{
/* overlap, copy backwards */
p1 += n;
p2 += n;
n++;
while (--n > 0) {
while (--n > 0)
{
*--p1 = *--p2;
}
} else {
}
else
{
n++;
while (--n > 0) {
while (--n > 0)
{
*p1++ = *p2++;
}
}

View file

@ -6,14 +6,15 @@
#include <string.h>
void *
memset(void *s, register int c, register size_t n)
void* memset(void* s, register int c, register size_t n)
{
register char* s1 = s;
if (n>0) {
if (n > 0)
{
n++;
while (--n > 0) {
while (--n > 0)
{
*s1++ = c;
}
}

View file

@ -6,8 +6,7 @@
#include <string.h>
char *
strcat(char *ret, register const char *s2)
char* strcat(char* ret, register const char* s2)
{
register char* s1 = ret;

View file

@ -6,13 +6,14 @@
#include <string.h>
char *
strchr(register const char *s, register int c)
char* strchr(register const char* s, register int c)
{
c = (char)c;
while (c != *s) {
if (*s++ == '\0') return NULL;
while (c != *s)
{
if (*s++ == '\0')
return NULL;
}
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

@ -7,11 +7,12 @@
#include <string.h>
#include <locale.h>
int
strcoll(register const char *s1, register const char *s2)
int strcoll(register const char* s1, register const char* s2)
{
while (*s1 == *s2++)
{
if (*s1++ == '\0')
{
while (*s1 == *s2++) {
if (*s1++ == '\0') {
return 0;
}
}

View file

@ -6,8 +6,7 @@
#include <string.h>
char *
strcpy(char *ret, register const char *s2)
char* strcpy(char* ret, register const char* s2)
{
register char* s1 = ret;

View file

@ -11,7 +11,8 @@ strcspn(const char *string, const char *notin)
{
register const char *s1, *s2;
for (s1 = string; *s1; s1++) {
for (s1 = string; *s1; s1++)
{
for (s2 = notin; *s2 != *s1 && *s2; s2++)
/* EMPTY */;
if (*s2)

View file

@ -7,8 +7,7 @@
#include <stdlib.h>
#include <string.h>
char*
strdup(const char *s)
char* strdup(const char* s)
{
int len = strlen(s);
char* p = malloc(len + 1);

View file

@ -6,20 +6,24 @@
#include <string.h>
char *
strncat(char *ret, register const char *s2, size_t n)
char* strncat(char* ret, register const char* s2, size_t n)
{
register char* s1 = ret;
if (n > 0) {
if (n > 0)
{
while (*s1++)
/* EMPTY */;
s1--;
while (*s1++ = *s2++) {
if (--n > 0) continue;
while (*s1++ = *s2++)
{
if (--n > 0)
continue;
*s1 = '\0';
break;
}
return ret;
} else return s1;
}
else
return s1;
}

View file

@ -6,19 +6,23 @@
#include <string.h>
int
strncmp(register const char *s1, register const char *s2, register size_t n)
int strncmp(register const char* s1, register const char* s2, register size_t n)
{
if (n)
{
do
{
if (n) {
do {
if (*s1 != *s2++)
break;
if (*s1++ == '\0')
return 0;
} while (--n > 0);
if (n > 0) {
if (*s1 == '\0') return -1;
if (*--s2 == '\0') return 1;
if (n > 0)
{
if (*s1 == '\0')
return -1;
if (*--s2 == '\0')
return 1;
return (unsigned char)*s1 - (unsigned char)*s2;
}
}

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

@ -6,12 +6,12 @@
#include <string.h>
char *
strpbrk(register const char *string, register const char *brk)
char* strpbrk(register const char* string, register const char* brk)
{
register const char* s1;
while (*string) {
while (*string)
{
for (s1 = brk; *s1 && *s1 != *string; s1++)
/* EMPTY */;
if (*s1)

View file

@ -6,14 +6,14 @@
#include <string.h>
char *
strrchr(register const char *s, int c)
char* strrchr(register const char* s, int c)
{
register const char* result = NULL;
c = (char)c;
do {
do
{
if (c == *s)
result = s;
} while (*s++ != '\0');

View file

@ -11,7 +11,8 @@ strspn(const char *string, const char *in)
{
register const char *s1, *s2;
for (s1 = string; *s1; s1++) {
for (s1 = string; *s1; s1++)
{
for (s2 = in; *s2 && *s2 != *s1; s2++)
/* EMPTY */;
if (*s2 == '\0')

View file

@ -6,12 +6,12 @@
#include <string.h>
char *
strstr(register const char *s, register const char *wanted)
char* strstr(register const char* s, register const char* 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))
if (*s++ == '\0')
return (char*)NULL;

View file

@ -6,19 +6,21 @@
#include <string.h>
char *
strtok(register char *string, const char *separators)
char* strtok(register char* string, const char* separators)
{
register char *s1, *s2;
static char* savestring;
if (string == NULL) {
if (string == NULL)
{
string = savestring;
if (string == NULL) return (char *)NULL;
if (string == NULL)
return (char*)NULL;
}
s1 = string + strspn(string, separators);
if (*s1 == '\0') {
if (*s1 == '\0')
{
savestring = NULL;
return (char*)NULL;
}

View file

@ -11,11 +11,14 @@ strxfrm(register char *s1, register const char *save, register size_t n)
{
register const char* s2 = save;
while (*s2) {
if (n > 1) {
while (*s2)
{
if (n > 1)
{
n--;
*s1++ = *s2++;
} else
}
else
s2++;
}
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