diff --git a/Doc/APCS_HowTo b/Doc/APCS_HowTo index 6bc2984667dea42419e5d0db09cdc905ffb19d6a..88f5561bdc34c6e2b4012cb5c822b43dfb14437e 100644 --- a/Doc/APCS_HowTo +++ b/Doc/APCS_HowTo @@ -15,4 +15,4 @@ To make Shared C Library compatible with 32-bit RISC OS, build with APCS = APCS- An APCS-32 Shared C Library will NOT run 26-bit programs, even on a 26-bit system; an APCS-R Shared C Library must be used. In a build using APCS-32, the SCL must be forced to APCS-R - pass the option SCL_APCS="-APCS 3/26bit" -in the components file to acheive this. +in the components file to achieve this. diff --git a/Makefile b/Makefile index 6383555798c164b727a5058203c278c75d22052e..b3e9aadcb1349b2af8590b4f885788be097f367e 100644 --- a/Makefile +++ b/Makefile @@ -181,6 +181,7 @@ HEADERS =\ CLIB:h.stdlib \ CLIB:h.string \ CLIB:h.swis \ + CLIB:h.tgmath \ CLIB:h.time \ CLIB:h.varargs \ RISC_OSLib:h.akbd \ @@ -278,7 +279,7 @@ ANSI_OBJS =\ o.alloc o.armprof o.armsys o.clib o.ctype o.error o.fpprintf \ o.kernel o.locale o.math o.memcpset o.overmgr o.printf o.scanf \ o.signal o.sort o.stdio o.stdlib o.string o.swiv o.time o.fenv \ - o.longlong + o.longlong o.mathl RM_OBJS =\ rm_o.k_modbody \ @@ -587,17 +588,17 @@ rm_o.k_stub2_rm: kernel.s.k_stub2_rm rm_o_rl.rl_stub_rm: rlib.s.rl_stub_rm ${OBJASM} ${ALFLAGS} -from rlib.s.rl_stub_rm -to $@ -lib.stubs: o.cl_stub_r o.k_stub2_r o.cl_stub2_r - ${LIBFILE} ${LIBFLAGS} $@ o.cl_stub_r o.k_stub2_r o.cl_stub2_r +lib.stubs: o.cl_stub_r o.k_stub2_r o.cl_stub2_r o.mathl + ${LIBFILE} ${LIBFLAGS} $@ o.cl_stub_r o.k_stub2_r o.cl_stub2_r o.mathl -lib.rstubs: o_rl.rl_stub_r o.k_stub2_r o.cl_stub2_r - ${LIBFILE} ${LIBFLAGS} $@ o_rl.rl_stub_r o.k_stub2_r o.cl_stub2_r +lib.rstubs: o_rl.rl_stub_r o.k_stub2_r o.cl_stub2_r o.mathl + ${LIBFILE} ${LIBFLAGS} $@ o_rl.rl_stub_r o.k_stub2_r o.cl_stub2_r o.mathl -lib.romcstubs: rm_o.cl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm - ${LIBFILE} ${LIBFLAGS} $@ rm_o.cl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm +lib.romcstubs: rm_o.cl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm o.mathl + ${LIBFILE} ${LIBFLAGS} $@ rm_o.cl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm o.mathl -lib.romstubs: rm_o_rl.rl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm - ${LIBFILE} ${LIBFLAGS} $@ rm_o_rl.rl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm +lib.romstubs: rm_o_rl.rl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm o.mathl + ${LIBFILE} ${LIBFLAGS} $@ rm_o_rl.rl_stub_rm rm_o.k_stub2_rm rm_o.cl_stub2_rm o.mathl lib.romastubs: rlib.s.rl_stub_a ${OBJASM} ${AFLAGS} -from rlib.s.rl_stub_a -to $@ @@ -648,6 +649,7 @@ CLIB:h.stdint: clib.h.stdint; ${CP} clib.h.stdint $@ ${CPFLAGS} CLIB:h.stdio: clib.h.stdio; ${CP} clib.h.stdio $@ ${CPFLAGS} CLIB:h.stdlib: clib.h.stdlib; ${CP} clib.h.stdlib $@ ${CPFLAGS} CLIB:h.string: clib.h.string; ${CP} clib.h.string $@ ${CPFLAGS} +CLIB:h.tgmath: clib.h.tgmath; ${CP} clib.h.tgmath $@ ${CPFLAGS} CLIB:h.time: clib.h.time; ${CP} clib.h.time $@ ${CPFLAGS} CLIB:h.varargs: clib.h.varargs; ${CP} clib.h.varargs $@ ${CPFLAGS} diff --git a/VersionASM b/VersionASM index bee29ec5425ca49e26377168fe187c9bb1b1564c..8ac6c0bbd52479e771e7713d83c096aa3bbd19ee 100644 --- a/VersionASM +++ b/VersionASM @@ -11,13 +11,13 @@ GBLS Module_HelpVersion GBLS Module_ComponentName GBLS Module_ComponentPath -Module_MajorVersion SETS "5.45" -Module_Version SETA 545 +Module_MajorVersion SETS "5.46" +Module_Version SETA 546 Module_MinorVersion SETS "" -Module_Date SETS "17 Jan 2003" -Module_ApplicationDate SETS "17-Jan-03" +Module_Date SETS "15 Apr 2003" +Module_ApplicationDate SETS "15-Apr-03" Module_ComponentName SETS "RISC_OSLib" Module_ComponentPath SETS "RiscOS/Sources/Lib/RISC_OSLib" -Module_FullVersion SETS "5.45" -Module_HelpVersion SETS "5.45 (17 Jan 2003)" +Module_FullVersion SETS "5.46" +Module_HelpVersion SETS "5.46 (15 Apr 2003)" END diff --git a/VersionNum b/VersionNum index 56c0684b750737eeea1055126021a0ccca6e1fe8..fc0b5cd8c3c009094b0fdc406d7ad38ebd237b85 100644 --- a/VersionNum +++ b/VersionNum @@ -1,23 +1,23 @@ -/* (5.45) +/* (5.46) * * This file is automatically maintained by srccommit, do not edit manually. * Last processed by srccommit version: 1.68. * */ -#define Module_MajorVersion_CMHG 5.45 +#define Module_MajorVersion_CMHG 5.46 #define Module_MinorVersion_CMHG -#define Module_Date_CMHG 17 Jan 2003 +#define Module_Date_CMHG 15 Apr 2003 -#define Module_MajorVersion "5.45" -#define Module_Version 545 +#define Module_MajorVersion "5.46" +#define Module_Version 546 #define Module_MinorVersion "" -#define Module_Date "17 Jan 2003" +#define Module_Date "15 Apr 2003" -#define Module_ApplicationDate "17-Jan-03" +#define Module_ApplicationDate "15-Apr-03" #define Module_ComponentName "RISC_OSLib" #define Module_ComponentPath "RiscOS/Sources/Lib/RISC_OSLib" -#define Module_FullVersion "5.45" -#define Module_HelpVersion "5.45 (17 Jan 2003)" -#define Module_LibraryVersionInfo "5:45" +#define Module_FullVersion "5.46" +#define Module_HelpVersion "5.46 (15 Apr 2003)" +#define Module_LibraryVersionInfo "5:46" diff --git a/c/armsys b/c/armsys index 68d4ffc30016b0efe95059c571db10be8af8b890..b37a21e7d8fa81a5c6143c3b70ec19ad38bf319f 100644 --- a/c/armsys +++ b/c/armsys @@ -40,6 +40,7 @@ extern int main(int argc, char **argv); /* the point of it all */ extern FILEHANDLE __dup(int new, int old); extern void _ctype_init(void); extern int _fprintf_lf(FILE *fp, const char *fmt, ...); +extern int _sprintf(char *buff, const char *fmt, ...); extern int _sprintf_lf(char *buff, const char *fmt, ...); extern _kernel_oserror *_kernel_peek_last_oserror(void); @@ -160,22 +161,25 @@ time_t time(time_t *timer) */ int _desktop_task() { - int h = 0; + _kernel_swi_regs r; if (_kernel_processor_mode() & 0xF) return 0; - _swix(TaskWindow_TaskInfo, _IN(0)|_OUT(0), 0, &h); - if (h) return 0; - _swix(Wimp_ReadSysInfo, _IN(0)|_OUT(0), 3, &h); - if (h == 0) return 0; - _swix(Wimp_ReadSysInfo, _IN(0)|_OUT(0), 5, &h); - return h; + r.r[0] = 0; + if (_kernel_swi(TaskWindow_TaskInfo, &r, &r) || r.r[0]) + return 0; + r.r[0] = 3; + _kernel_swi(Wimp_ReadSysInfo, &r, &r); + if (r.r[0] == 0) return 0; + r.r[0] = 5; + _kernel_swi(Wimp_ReadSysInfo, &r, &r); + return r.r[0]; } static int _desktop_report(const char *s, const char *but) { + _kernel_swi_regs r; _kernel_oserror err, *e; - const char *n = NULL; char *p, *end; - int flags, r, h = _desktop_task(); + int flags, h = _desktop_task(); if (h == 0) return 0; flags = 0x102; /* New error, cancel button */ @@ -210,17 +214,26 @@ static int _desktop_report(const char *s, const char *but) e = &err; } - _swix(TaskManager_TaskNameFromHandle, _IN(0)|_OUT(0), h, &n); - - r = 0; - _swix(Wimp_ReportError, _INR(0,5)|_OUT(1), e, flags, n, NULL, 1, but, &r); - return r; + r.r[0] = h; + if (_kernel_swi(TaskManager_TaskNameFromHandle, &r, &r) == 0) + r.r[2] = r.r[0]; + else + r.r[2] = 0; + r.r[0] = (int) e; + r.r[1] = flags; + r.r[3] = 0; + r.r[4] = 1; + r.r[5] = (int) but; + if (_kernel_swi(Wimp_ReportError, &r, &r) == 0) + return r.r[1]; + else + return 0; } -bool _sys__assert(const char *s, const char *expr, const char *file, int line) +bool _sys__assert(const char *s, const char *expr, const char *func, const char *file, int line) { char buffer[252]; - int len, exprlen, filelen; + int len, funclen, exprlen, filelen; if (!istty(stderr->__file)) return false; @@ -228,29 +241,39 @@ bool _sys__assert(const char *s, const char *expr, const char *file, int line) if (strlen(s) > 200) return false; /* Be safe */ - len = sprintf(buffer, s, "", "", line); + len = func ? _sprintf(buffer, s, "", "", "", line) + : _sprintf(buffer, s, "", "", line); + funclen = func ? strlen(func) : 0; exprlen = strlen(expr); filelen = strlen(file); - if (len + exprlen + filelen < 251) + if (len + funclen + exprlen + filelen < 251) { - sprintf(buffer, s, expr, file, line); + func ? _sprintf(buffer, s, expr, func, file, line) + : _sprintf(buffer, s, expr, file, line); } else { char expr2[200]; + char func2[50]; char file2[100]; #define min(a,b) a<b?a:b exprlen = min(exprlen, 199); + funclen = min(funclen, 49); filelen = min(filelen, 99); - filelen = min(filelen, 251-len-exprlen); + filelen = min(filelen, 251-len-funclen-exprlen); if (filelen < 0) filelen = 0; - exprlen = min(exprlen, 251-len-filelen); + funclen = min(funclen, 251-len-exprlen-filelen); + if (funclen < 0) funclen = 0; + exprlen = min(exprlen, 251-len-funclen-filelen); memcpy(expr2, expr, exprlen); + memcpy(func2, func, funclen); memcpy(file2, file, filelen); expr2[exprlen]='\0'; + func2[funclen]='\0'; file2[filelen]='\0'; - sprintf(buffer, s, expr2, file2, line); + func ? _sprintf(buffer, s, expr2, func2, file2, line) + : _sprintf(buffer, s, expr2, file2, line); } return _desktop_report(buffer, NULL); } diff --git a/c/error b/c/error index 00c3eac4c08d0325410e65205a4bcb1f8d1249e7..f90a9b555b07dd3e306003b54d47d867dad83e99 100644 --- a/c/error +++ b/c/error @@ -47,14 +47,27 @@ void _sysdie(const char *s) } /* from <assert.h> */ -void __assert(char *expr, char *file, int line) +void __assert(const char *expr, const char *file, int line) { const char *s; s = _kernel_getmessage("*** assertion failed: %s, file %s, line %d", "C34"); - if (!_sys__assert(s, expr, file, line)) + if (!_sys__assert(s, expr, NULL, file, line)) { _fprintf_lf(stderr, s, expr, file, line); - fputc('\n', stderr); + fputc('\n', stderr); + } + abort(); +} + +void __assert2(const char *expr, const char *func, const char *file, int line) +{ + const char *s; + s = _kernel_getmessage_def("*** assertion failed: %s, function %s, file %s, line %d", "C73"); + + if (!_sys__assert(s, expr, func, file, line)) { + _fprintf_lf(stderr, s, expr, func, file, line); + fputc('\n', stderr); + } abort(); } diff --git a/c/math b/c/math index b9715256288bc6c2d0c5a8f2a4edd0cc13bc6914..ede25d33347c4cca1e5923f283ebcf11c4b07703 100644 --- a/c/math +++ b/c/math @@ -35,6 +35,7 @@ #include "hostsys.h" #include <limits.h> +#include <float.h> #include <errno.h> /* This file contains code for most of the math routines from <math.h> */ @@ -63,7 +64,7 @@ double frexp(double d, int *lvn) int n; if (d==0.0) { *lvn = 0; - return 0.0; + return d; } d1.d = d; if ((n = d1.i.x - 0x3fe) == -0x3fe) @@ -73,8 +74,9 @@ double frexp(double d, int *lvn) /* suitable nonzero bit appears to go in the implicit-bit place in the */ /* fractional result. For each bit shifted I need to adjust the final */ /* exponent that will be returned. */ -/* I have already tested to see if d was zero so the fllowing loop MUST */ +/* I have already tested to see if d was zero so the following loop MUST */ /* terminate. */ + n++; do { flag = d1.i.mhi & 0x00080000; d1.i.mhi = (d1.i.mhi << 1) | (d1.i.mlo >> 31); @@ -82,11 +84,46 @@ double frexp(double d, int *lvn) n--; } while (flag==0); } + else if (n == 0x401) + { +/* Here d1 has 0x7ff in its exponent field - it's a NaN or infinity */ + *lvn = (d1.i.mhi || d1.i.mlo) ? FP_ILOGBNAN : INT_MAX; + return d1.d; + } *lvn = n; d1.i.x = 0x3fe; return d1.d; } +float frexpf(float s, int *lvn) +{ + fp_number_single s1; + int n; + if (s==0.0F) + { *lvn = 0; + return s; + } + s1.s = s; + if ((n = s1.i.x - 0x7e) == -0x7e) + { int flag; + n++; + do + { flag = s1.i.m & 0x00400000; + s1.i.m = s1.i.m << 1; + n--; + } while (flag==0); + } + else if (n == 0x81) + { +/* Here d1 has 0xff in its exponent field - it's a NaN or infinity */ + *lvn = (s1.i.m) ? FP_ILOGBNAN : INT_MAX; + return s1.s; + } + *lvn = n; + s1.i.x = 0x7e; + return s1.s; +} + #else /* DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS */ double frexp(double d, int *lvn) @@ -94,7 +131,7 @@ double frexp(double d, int *lvn) fp_number d1; if (d==0.0) { *lvn = 0; - return 0.0; + return d; } d1.d = d; *lvn = d1.i.x - 0x3fe; @@ -102,29 +139,246 @@ double frexp(double d, int *lvn) return d1.d; } +float frexpf(float s, int *lvn) +{ + fp_number_single s1; + int n; + if (s==0.0F) + { *lvn = 0; + return s; + } + s1.s = s; + *lvn = s1.i.x - 0x7e; + s1.i.x = 0x7e; + return s1.s; +} + #endif /* DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS */ -double ldexp(double d, int n) +double scalbln(double d, long int n) { - fp_number d1; - int nx; - if (d==0.0) return 0.0; /* special case */ - d1.d = d; - nx = (int) d1.i.x + n; - if (nx >= 0x7ff) - { errno = ERANGE; - return HUGE_VAL; /* overflow yields 'infinity' */ + fp_number x; + long int exponent; + if (n == 0 || d == 0.0) return d; + x.d = d; + exponent = x.i.x; + if (exponent == 0x7ff) return d; /* NaN or infinite */ +#ifndef DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS + if (exponent == 0) /* starting subnormal */ + { int flag; + exponent++; + do + { flag = x.i.mhi & 0x00080000; + x.i.mhi = (x.i.mhi << 1) | (x.i.mlo >> 31); + x.i.mlo = x.i.mlo << 1; + exponent--; + } while (flag==0); } -/* Maybe I should be prepared to generate un-normalized numbers here, or */ -/* even deal with input d un-normalized and n positive yielding a proper */ -/* result. All that seems like a lot of work and so I will not even try */ -/* in this version of the code! */ - else if (nx <= 0) return 0.0; /* deal with underflow */ - d1.i.x = nx; - return (d1.d); +#endif + if (n > 0x1000 || exponent + n >= 0x7ff) /* overflow */ + { errno = ERANGE; + return x.i.s ? -HUGE_VAL : HUGE_VAL; + } + if (n < -0x1000 || exponent + n <= -53) /* total underflow */ + { x.i.x = x.i.mhi = x.i.mlo = 0; + errno = ERANGE; + return x.d; + } + if (exponent + n <= 0) /* subnormal result */ + { unsigned round = 0, hi; + n = 1 - (exponent + n); + hi = 0x00100000 | x.i.mhi; + + if (n >= 32) + { round = x.i.mlo; + x.i.mlo = hi; + hi = 0; + n -= 32; + } + if (n > 0) + { round = (x.i.mlo << (32-n)) | (round != 0); + x.i.mlo = (hi << (32-n)) | (x.i.mlo >> n); + hi = hi >> n; + } + x.i.mhi = hi; + x.i.x = 0; + /* perform round-to-nearest; to even in tie cases */ + if (round > 0x80000000 || + (round == 0x80000000 && (x.i.mlo & 1))) + if (++x.i.mlo == 0) + if (++x.i.mhi == 0) + x.i.x = 1; + + if (round != 0) errno = ERANGE; /* only if inexact */ + + return x.d; + } + /* normal result */ + x.i.x = (int) (exponent + n); + return x.d; } +float scalblnf(float s, long int n) +{ + fp_number_single x; + long int exponent; + if (n == 0 || s == 0.0F) return s; + x.s = s; + exponent = x.i.x; + if (exponent == 0xff) return s; /* NaN or infinite */ +#ifndef DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS + if (exponent == 0) /* starting subnormal */ + { int flag; + exponent++; + do + { flag = x.i.m & 0x00400000; + x.i.m = x.i.m << 1; + exponent--; + } while (flag==0); + } +#endif + if (n > 0x1000 || exponent + n >= 0xff) /* overflow */ + { errno = ERANGE; + return x.i.s ? -HUGE_VALF : HUGE_VALF; + } + if (n < -0x1000 || exponent + n <= -24) /* total underflow */ + { x.i.x = x.i.m = 0; + errno = ERANGE; + return x.s; + } + if (exponent + n <= 0) /* subnormal result */ + { unsigned round, m; + n = 1 - (exponent + n); + m = 0x00800000 | x.i.m; + + round = m << (32-n); + x.i.m = m >> n; + x.i.x = 0; + /* perform round-to-nearest; to even in tie cases */ + if (round > 0x80000000 || + (round == 0x80000000 && (x.i.m & 1))) + if (++x.i.m == 0) + x.i.x = 1; + + if (round != 0) errno = ERANGE; /* only if inexact */ + + return x.s; + } + /* normal result */ + x.i.x = (int) (exponent + n); + return x.s; +} + +double scalbn(double x, int n) +{ + return scalbln(x, n); +} + +float scalbnf(float x, int n) +{ + return scalblnf(x, n); +} + +double ldexp(double x, int n) +{ + return scalbn(x, n); +} +float ldexpf(float x, int n) +{ + return scalbnf(x, n); +} + +int ilogb(double d) +{ + fp_number x; + int exponent; + + if (d == 0.0) + { errno = ERANGE; + return FP_ILOGB0; + } + + x.d = d; + exponent = x.i.x; +#ifndef DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS + if (exponent == 0) + { int flag; + exponent = 1; + do + { flag = x.i.mhi & 0x00080000; + x.i.mhi = (x.i.mhi << 1) | (x.i.mlo >> 31); + x.i.mlo = x.i.mlo << 1; + exponent--; + } while (flag==0); + } + else if (exponent == 0x7ff) + { if (x.i.mhi || x.i.mlo) + return FP_ILOGBNAN; + else + return INT_MAX; + } +#endif + return exponent - 0x3ff; +} + +int ilogbf(float s) +{ + fp_number_single x; + int exponent; + + if (s == 0.0F) + { errno = ERANGE; + return FP_ILOGB0; + } + + x.s = s; + exponent = x.i.x; +#ifndef DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS + if (exponent == 0) + { int flag; + exponent = 1; + do + { flag = x.i.m & 0x00400000; + x.i.m = x.i.m << 1; + exponent--; + } while (flag==0); + } + else if (exponent == 0xff) + { if (x.i.m) + return FP_ILOGBNAN; + else + return INT_MAX; + } +#endif + return exponent - 0x7f; +} + +double logb(double d) +{ + int x = ilogb(d); + + switch (x) + { + case FP_ILOGB0: return -HUGE_VAL; + case FP_ILOGBNAN: return d; + case INT_MAX: return INFINITY; + default: return x; + } +} + +float logbf(float s) +{ + int x = ilogbf(s); + + switch (x) + { + case FP_ILOGB0: return -HUGE_VALF; + case FP_ILOGBNAN: return s; + case INT_MAX: return INFINITY; + default: return x; + } +} #define _exp_arg_limit 709.78271289338397 @@ -595,11 +849,15 @@ double pow(double x, double y) double atan2(double y, double x) { - if (x==0.0 && y==0.0) - { errno = EDOM; - return -HUGE_VAL; - } - if (fabs(x) < fabs(y)) + if (isunordered(y, x)) return y+x; + + if (y==0.0 || (isinf(x) && isfinite(y))) + return signbit(x) ? copysign(_pi_, y) : y; + + if (isinf(x)) /* y must also be infinite, from above */ + return copysign(x > 0 ? _pi_4 : 3*_pi_4, y); + + if (fabs(x) < fabs(y)) /* handles infinite y, finite x */ { if (fabs(x / y)<1.0e-20) { if (y<0.0) return - _pi_2; else return _pi_2; @@ -613,6 +871,30 @@ double atan2(double y, double x) return y; } +float atan2f(float y, float x) +{ + if (isunordered(y, x)) return y+x; + + if (y==0.0F || (isinf(x) && isfinite(y))) + return signbit(x) ? copysignf((float)_pi_, y) : y; + + if (isinf(x)) /* y must also be infinite, from above */ + return copysignf(x > 0 ? (float)_pi_4 : (float)(3*_pi_4), y); + + if (fabsf(x) < fabsf(y)) /* handles infinite y, finite x */ + { if (fabsf(x / y)<1.0e-12F) + { if (y<0.0F) return (float) - _pi_2; + else return (float) _pi_2; + } + } + y = atanf(y / x); + if (x<0.0F) + { if (y>0.0F) y -= (float) _pi_; + else y += (float) _pi_; + } + return y; +} + #ifndef HOST_HAS_TRIG double hypot(double x, double y) { @@ -701,8 +983,9 @@ double sinh(double x) { int sign; double y; - if (x<0.0) y = -x, sign = 1; else y = x, sign = 0; - if (y>1.0) + if (x==0) return x; + if (isless(x,0.0)) y = -x, sign = 1; else y = x, sign = 0; + if (isgreater(y,1.0)) { /* _sinh_lnv is REQUIRED to read in as a number with the lower part of */ /* its floating point representation zero. */ @@ -711,7 +994,8 @@ double sinh(double x) #define _sinh_v2m1 0.13830277879601902638e-4 /* (v/2) - 1 */ double w = y - _sinh_lnv, z, r; if (w>_exp_arg_limit) - { errno = ERANGE; + { if (isinf(x)) return x; + errno = ERANGE; if (sign) return -HUGE_VAL; else return HUGE_VAL; } @@ -721,7 +1005,7 @@ double sinh(double x) if (sign) return -r; else return r; } - else if (y<=1.0e-10) return x; + else if (!isgreater(y,1.0e-10)) return x; else { #define _sinh_p0 -0.35181283430177117881e6 @@ -743,12 +1027,12 @@ double sinh(double x) double cosh(double x) { - if (x<0.0) x = -x; - if (x>1.0) - { - x = x - _sinh_lnv; + x = fabs(x); + if (isgreater(x,1.0)) + { x = x - _sinh_lnv; if (x>_exp_arg_limit) - { errno = ERANGE; + { if (isinf(x)) return x; + errno = ERANGE; return HUGE_VAL; } x = exp(x); /* the range check above ensures that this does */ @@ -768,11 +1052,11 @@ double tanh(double x) /* The first two exits avoid premature overflow as well as needless use */ /* of the exp() function. */ int sign; - if (x>27.0) return 1.0; /* here exp(2x) dominates 1.0 */ - else if (x<-27.0) return -1.0; - if (x<0.0) x = -x, sign = 1; + if (isgreater(x,27.0)) return 1.0; /* here exp(2x) dominates 1.0 */ + else if (isless(x,-27.0)) return -1.0; + if (isless(x,0.0)) x = -x, sign = 1; else sign = 0; - if (x>0.549306144334054846) /* ln(3)/2 is crossover point */ + if (isgreater(x,0.549306144334054846)) /* ln(3)/2 is crossover point */ { x = exp(2.0*x); x = 1.0 - 2.0/(x + 1.0); if (sign) return -x; @@ -785,7 +1069,7 @@ double tanh(double x) #define _tanh_q1 0.22337720718962312926e4 #define _tanh_q2 0.11274474380534949335e3 #define _tanh_q3 1.0 - if (x>1.0e-10) + if (isgreater(x,1.0e-10)) { double y = x*x; /* minimax rational approximation */ y = (((_tanh_p2*y + _tanh_p1)*y + _tanh_p0)*y) / @@ -796,6 +1080,100 @@ double tanh(double x) else return x; } +/* Simple forms for now */ +float coshf(float x) +{ + return (float)cosh(x); +} + +float sinhf(float x) +{ + return (float)sinh(x); +} + +float tanhf(float x) +{ + return (float)tanh(x); +} + +double asinh(double x) +{ + if (isless(x, 0.0)) + return -asinh(-x); + + if (x == 0) return x; // asinh(ą0) returns ą0 + + return log(x+hypot(x,1.0)); +} + +double acosh(double x) +{ + if (isless(x, 1.0)) + { errno = EDOM; + return NAN; + } + + // acosh(0) = 2.0*log(sqrt(1)+sqrt(0)) = 2.0*log(1) = +0 + return 2.0*log(sqrt((x+1)*0.5)+sqrt((x-1)*0.5)); +} + +double atanh(double x) +{ + if (isless(x, 0.0)) + return -atanh(-x); + + if (x == 0) return x; // atanh(ą0) returns ą0 + if (isgreater(x, 1.0)) + { errno = EDOM; + return NAN; + } + if (x == 1) // atanh(ą1) returns ąinf + { errno = ERANGE; + return HUGE_VAL; + } + + return 0.5*log((1+x)/(1-x)); +} + +float asinhf(float x) +{ + if (isless(x, 0.0F)) + return -asinhf(-x); + + if (x == 0) return x; // asinhf(ą0) returns ą0 + + return (float) log(x+hypot(x,1.0)); +} + +float acoshf(float x) +{ + if (isless(x, 1.0F)) + { errno = EDOM; + return NAN; + } + + // acoshf(0) = 2.0*log(sqrt(1)+sqrt(0)) = 2.0*log(1) = +0 + return (float) (2.0*log(sqrt((x+1.0)*0.5)+sqrt((x-1.0)*0.5))); +} + +float atanhf(float x) +{ + if (isless(x, 0.0F)) + return -atanhf(-x); + + if (x == 0) return x; // atanhf(ą0) returns ą0 + if (isgreater(x, 1.0)) + { errno = EDOM; + return NAN; + } + if (x == 1) // atanhf(ą1) returns ąinf + { errno = ERANGE; + return HUGE_VALF; + } + + return (float) (0.5*log((1.0+x)/(1.0-x))); +} + double fmod(double x, double y) { /* floating point remainder of (x/y) for integral quotient. Remainder */ @@ -823,6 +1201,34 @@ double fmod(double x, double y) return r; } +float fmodf(float x, float y) +{ +/* floating point remainder of (x/y) for integral quotient. Remainder */ +/* has same sign as x. */ + float q, r; + if (y==0.0F) + { + errno = EDOM; + return -HUGE_VALF; + } + if (x==0.0F) return x; + if (y < 0.0F) y = -y; + r = modff(x/y, &q); + r = x - q * y; +/* The next few lines are an ultra-cautious scheme to ensure that the */ +/* result is less than fabs(y) in value and that it has the sign of x. */ + if (x > 0.0F) + { while (r >= y) r -= y; + while (r < 0.0F) r += y; + } + else + { while (r <= -y) r += y; + while (r > 0.0F) r -= y; + } + return r; +} + +#if 0 double (floor)(double d) { /* round x down to an integer towards minus infinity. */ @@ -855,7 +1261,7 @@ double (ceil)(double d) /* round x up to an integer towards plus infinity. */ fp_number x; int exponent, mask, exact; - if (d == 0.0) return 0.0; + if (d == 0.0) return d; x.d = d; /* pun on union type */ if ((exponent = x.i.x - 0x3ff) < 0) { if (x.i.s) return 0.0; @@ -876,10 +1282,11 @@ double (ceil)(double d) if (exact!=0 && x.i.s==0) return x.d + 1.0; else return x.d; } +#endif -/*double (ceil)(double x) { return ceil(x); }*/ +double (ceil)(double x) { return ceil(x); } float (ceilf)(float x) { return ceilf(x); } -/*double (floor)(double x) { return floor(x); }*/ +double (floor)(double x) { return floor(x); } float (floorf)(float x) { return floorf(x); } double (rint)(double x) { return rint(x); } float (rintf)(float x) { return rintf(x); } @@ -889,11 +1296,11 @@ double (trunc)(double x) { return trunc(x); } float (truncf)(float x) { return truncf(x); } double (atan)(double x) { return atan(x); } -/*float (atanf)(float x) { return atanf(x); }*/ +float (atanf)(float x) { return atanf(x); } double (sin)(double x) { return sin(x); } -/*float (sinf)(float x) { return sinf(x); }*/ +float (sinf)(float x) { return sinf(x); } double (cos)(double x) { return cos(x); } -/*float (cosf)(float x) { return cosf(x); }*/ +float (cosf)(float x) { return cosf(x); } double modf(double value, double *iptr) { @@ -901,17 +1308,17 @@ double modf(double value, double *iptr) fp_number x; int exponent, mask; if (value == 0.0) - { *iptr = 0.0; - return 0.0; + { *iptr = value; + return value; } x.d = value; if ((exponent = x.i.x - 0x3ff) < 0) - { *iptr = 0.0; + { *iptr = copysign(0.0, value); return value; } else if (exponent >= 52) { *iptr = value; - return 0.0; + return copysign(0.0, value); } if (exponent >= 20) { mask = ((unsigned) 0xffffffff) >> (exponent - 20); @@ -926,6 +1333,30 @@ double modf(double value, double *iptr) return value - x.d; } +float modff(float value, float *iptr) +{ +/* splits value into integral part & fraction (both same sign) */ + fp_number_single x; + int exponent, mask; + if (value == 0.0F) + { *iptr = value; + return value; + } + x.s = value; + if ((exponent = x.i.x - 0xff) < 0) + { *iptr = copysignf(0.0F, value); + return value; + } + else if (exponent >= 23) + { *iptr = value; + return copysignf(0.0F, value); + } + mask = 0x7fffff >> exponent; + x.i.m &= ~mask; + *iptr = x.s; + return value - x.s; +} + double nan(const char *s) { return (double) NAN; @@ -952,6 +1383,331 @@ float fdimf(float x, float y) return x - y; /* Will return NaN for NaN input */ } +#define _sqrt2pi 2.50662827463100050242 + +/* + * Gamma functions computed using Lanczos' approximation. + * Double version uses coefficients computed as per Spouge (1994) + * to achieve (theoretically) < 1 ulp error. + * Float version uses original Lanczos coefficients. + * + * Lanczos' approximation: + * + * G(x+1) = (x+a)^(x+.5)* e^-(x+a) * sqrt(2*pi) * + * [ c0 + c1/(x+1) + c2/(x+3).. + cn/(x+n) ] (x > 0) + * + * + * Spouge's coefficients: + * c0 = 1 + * c[k] = (-1)^(k-1) * e^(a-k) * (a-k)^(k-0.5) ( 1 <= k < ceil(a) ) + * ------------------------------------ + * sqrt(2*pi) * (k-1)! + * + * giving relative error < sqrt(a) * (2*pi)^-(a+0.5) / (a+x) + * + * Useful relations: gamma(x+1) = x*gamma(x) + * gamma(1-x) = pi / (gamma(x)*sin(pi*x)) + * gamma(n+1) = n! + */ + +#define _lgamma_c1 166599025.853949811570 // actually c[k]*sqrt(2*pi) +#define _lgamma_c2 -981939810.195007931170 +#define _lgamma_c3 2548964102.46316408700 +#define _lgamma_c4 -3836248618.43839895348 +#define _lgamma_c5 3709080184.61731236844 +#define _lgamma_c6 -2412708472.49486138749 +#define _lgamma_c7 1075449464.75190680642 +#define _lgamma_c8 -328534715.011179056348 +#define _lgamma_c9 67752870.4715251633277 +#define _lgamma_c10 -9145761.20044444915581 +#define _lgamma_c11 768402.637723269577278 +#define _lgamma_c12 -37175.9448951564986832 +#define _lgamma_c13 917.944248521710658895 +#define _lgamma_c14 -9.51510944794615044564 +#define _lgamma_c15 0.0294177178100457006509 +#define _lgamma_c16 -1.37185031730621246722e-5 +#define _lgamma_c17 1.72316912091954830013e-10 +#define _lgamma_c18 -2.50065513100139951901e-20 + +static inline double _gamma_sum(double x) +{ + /* Do it like this to avoid using client static data for an array */ + return _sqrt2pi + + _lgamma_c1 / (x + 1) + + _lgamma_c2 / (x + 2) + + _lgamma_c3 / (x + 3) + + _lgamma_c4 / (x + 4) + + _lgamma_c5 / (x + 5) + + _lgamma_c6 / (x + 6) + + _lgamma_c7 / (x + 7) + + _lgamma_c8 / (x + 8) + + _lgamma_c9 / (x + 9) + + _lgamma_c10 / (x + 10) + + _lgamma_c11 / (x + 11) + + _lgamma_c12 / (x + 12) + + _lgamma_c13 / (x + 13) + + _lgamma_c14 / (x + 14) + + _lgamma_c15 / (x + 15) + + _lgamma_c16 / (x + 16) + + _lgamma_c17 / (x + 17) + + _lgamma_c18 / (x + 18); +} + +#define _lgammaf_c0 1.000000000190015 +#define _lgammaf_c1 76.18009172947146 +#define _lgammaf_c2 -86.50532032941677 +#define _lgammaf_c3 24.01409824083091 +#define _lgammaf_c4 -1.231739572450155 +#define _lgammaf_c5 1.208650973866179e-3 +#define _lgammaf_c6 -5.395239384953e-6 + +static inline double _gammaf_sum(double x) +{ + return _lgammaf_c0 + + _lgammaf_c1 / (x + 1) + + _lgammaf_c2 / (x + 2) + + _lgammaf_c3 / (x + 3) + + _lgammaf_c4 / (x + 4) + + _lgammaf_c5 / (x + 5) + + _lgammaf_c6 / (x + 6); +} + +double lgamma(double x) +{ + if (isinf(x)) return INFINITY; + if (isnan(x)) return x; + + if (x < 1) + { + if (floor(x) == x) + { errno = ERANGE; + return HUGE_VAL; + } + + return log(fabs((1-x)*_pi_/sin(_pi_*x)))-lgamma(2-x); + } + + if (x == 1 || x == 2) return +0; + + return (x+0.5)*log(x+18.5) - (x+18.5) + log(_gamma_sum(x) / x); +} + +float lgammaf(float x) +{ + if (isinf(x)) return INFINITY; + if (isnan(x)) return x; + + if (x < 1) + { + if (floorf(x) == x) + { errno = ERANGE; + return HUGE_VALF; + } + + return (float) log(fabs((1.0-x)*_pi_/sin(_pi_*x)))-lgammaf(2-x); + } + + if (x == 1 || x == 2) return +0; + + return (float) ((x+0.5)*log(x+5.5) - (x+5.5) + log(_sqrt2pi * _gammaf_sum(x) / x)); +} + +double tgamma(double x) +{ + if (isinf(x)) + { if (x > 0) + return x; + else + { errno = ERANGE; + return NAN; + } + } + if (isnan(x)) return x; + + if (x == 0) + { errno = ERANGE; + return copysign(HUGE_VAL, x); + } + + if (floor(x) == x) + { + if (x < 0) + { errno = EDOM; + return NAN; + } + else if (x <= 171) + { double r = 1; + for (int n = (int) x - 1; n > 1; n--) + r *= n; + return r; + } + } + + if (x < 1) + return (1-x)*_pi_/(sin(_pi_*x)*tgamma(2-x)); + + return exp(lgamma(x)); +} + +float tgammaf(float x) +{ + if (isinf(x)) + { if (x > 0) + return x; + else + { errno = ERANGE; + return NAN; + } + } + if (isnan(x)) return x; + + if (x == 0) + { errno = ERANGE; + return copysignf(HUGE_VALF, x); + } + + if (floorf(x) == x) + { + if (x < 0) + { errno = EDOM; + return NAN; + } + else if (x <= 35) + { + float r = 1; + for (int n = (int) x - 1; n > 1; n--) + r *= n; + return r; + } + } + + if (x < 1) + return (float) ((1.0-x)*_pi_/(sin(_pi_*x)*tgammaf(2-x))); + + return expf(lgammaf(x)); +} + +/* Error function algorithms derived from "Numerical recipes in C" */ + +#define _log_sqrt_pi 0.5723649429247000870717137 // == lgamma(0.5) + +/* Series calculation for incomplete gamma function P(0.5,x); good for */ +/* x <= 1.5. */ +static double gser05(double x, double epsilon) +{ + double sum,del,ap; + + ap = 0.5; + del = sum = 2; + for (;;) + { ++ap; + del *= x/ap; + sum += del; + if (fabs(del) < fabs(sum)*epsilon) + return sum*exp(-x+0.5*log(x)-_log_sqrt_pi); + } +} + +/* Continued fraction calculation for incomplete gamma function */ +/* 1 - P(0.5,x); good for x >= 1.5. */ +static double gcf05(double x, double epsilon) +{ + double an,b,c,d,del,h; + #define FPMIN 1e-300 + + b = x+0.5; + c = 1/FPMIN; + d = 1/b; + h = d; + for (int i=1; ; i++) + { an = i*(0.5-i); + b += 2; + d = an*d+b; + if (fabs(d) < FPMIN) d = FPMIN; + c = b + an/c; + if (fabs(c) < FPMIN) c = FPMIN; + d = 1/d; + del = d*c; + h *= del; + if (fabs(del-1) < epsilon) break; + } + return exp(-x+0.5*log(x)-_log_sqrt_pi)*h; +} + +static double gammp05(double x, double epsilon) +{ + if (isunordered(x, 1.5)) + return x; + else if (isless(x, 1.5)) + return gser05(x,epsilon); + else + return 1 - gcf05(x,epsilon); +} + +static double gammq05(double x, double epsilon) +{ + if (isunordered(x, 1.5)) + return x; + else if (isless(x, 1.5)) + return 1 - gser05(x,epsilon); + else + return gcf05(x,epsilon); +} + +double erf(double x) +{ + if (x == 0) return x; + if (isless(x, 0.0)) return -erf(-x); + if (isgreater(x, 1e100)) return 1.0; + + return gammp05(x*x, 3*DBL_EPSILON); +} + +double erfc(double x) +{ + if (isgreater(fabs(x), 1e100)) return isless(x, 0.0) ? 2 : 0; + + return isless(x, 0.0) ? 1+gammp05(x*x, 3*DBL_EPSILON) + : gammq05(x*x, 3*DBL_EPSILON); +} + +float erff(float x) +{ + if (x == 0) return x; + if (isless(x, 0.0)) return -erff(-x); + if (isgreater(x, 1e15F)) return 1.0F; + + return (float) gammp05((double) x*x, 3.0*FLT_EPSILON); +} + +#define _erfcf_c0 -1.26551223 +#define _erfcf_c1 1.00002368 +#define _erfcf_c2 0.37409196 +#define _erfcf_c3 0.09678418 +#define _erfcf_c4 -0.18628806 +#define _erfcf_c5 0.27886807 +#define _erfcf_c6 -1.13520398 +#define _erfcf_c7 1.48851586 +#define _erfcf_c8 -0.82215223 +#define _erfcf_c9 0.17087277 + +float erfcf(float x) +{ + double t,r; + + if (isgreater(fabsf(x), 1e15F)) return isless(x, 0.0F) ? 2 : 0; + + t = 1/(1+0.5*fabsf(x)); + + r = (((((((((_erfcf_c9) * t + _erfcf_c8) * t + _erfcf_c7) * t + + _erfcf_c6) * t + _erfcf_c5) * t + _erfcf_c4) * t + + _erfcf_c3) * t + _erfcf_c2) * t + _erfcf_c1) * t + + _erfcf_c0; + + r = t*exp(r - (double)x*x); + return (float) (isless(x, 0.0F) ? 2-r : r); +} + #endif /* NO_FLOATING_POINT */ /* end of math.c */ diff --git a/c/stdio b/c/stdio index bad330c437bedfbd5c259a388dc50a09f85e0829..26bb4c763ead8bff39d001782338032a99fecf10 100644 --- a/c/stdio +++ b/c/stdio @@ -94,10 +94,32 @@ typedef struct __extradata { int __buflim; /* used size of buffer */ int __savedicnt; /* after unget contains old icnt */ int __savedocnt; /* after unget contains old ocnt */ +#ifdef SUPPORT_WIDE + int __orientation; + mbstate_t __mbstate; /* must be stored in fpos_t */ +#endif } _extradata, *_extradatap; static _extradatap _extra; +#ifdef SUPPORT_WIDE +#define O_NONE 0 +#define O_BYTE (-1) +#define O_WIDE (+1) +#define ORIENTATION(stream) ((stream)->__extrap->__orientation) +#define BYTEORIENT(stream) (ORIENTATION(stream) == 0 ? \ + ORIENTATION(stream) = O_BYTE : \ + ORIENTATION(stream)) +#define ENSUREBYTE(stream,e) do { if (BYTEORIENT(stream) != O_BYTE) return e; } while (0) +#define WIDEORIENT(stream) (ORIENTATION(stream) == 0 ? \ + ORIENTATION(stream) = O_WIDE : \ + ORIENTATION(stream)) +#define ENSUREWIDE(stream,e) do { if (WIDEORIENT(stream) != O_WIDE) return e; } while (0) +#else +#define BYTEORIENT(stream) +#define ENSUREBYTE(stream,e) +#endif + #define EXTENT(stream) ((stream)->__extrap->__extent > (stream)->__ptr \ ? (stream)->__extrap->__extent : (stream)->__ptr) @@ -222,6 +244,7 @@ int __backspace(FILE *stream) int ungetc(int c,FILE *stream) { /* made into a fn to evaluate each arg once. */ + ENSUREBYTE(stream, EOF); if (c==EOF || (stream->__flag & (_IOUNGET+_IONOREADS))) return EOF; /* put char into unget buffer */ stream->__extrap->__lilbuf[1] = c; @@ -808,6 +831,7 @@ size_t fread(void *ptr, size_t itemsize, size_t count, FILE *stream) * is concerned and that the number of WHOLE items read is returned. */ dbmsg("fread %d\n", count); + ENSUREBYTE(stream, 0); return itemsize == 0 ? 0 /* slight ansi irrationality */ : _read(ptr, itemsize*count, stream) / itemsize; } @@ -917,6 +941,7 @@ size_t fwrite(const void *ptr, size_t itemsize, size_t count, FILE *stream) /* The comments made about fread apply here too */ dbmsg_noNL("fwrite %d ", count); dbmsg("itemsize %d (decimal)\n", itemsize); + ENSUREBYTE(fwrite, 0); return itemsize == 0 ? count : _write(ptr, itemsize*count, stream) / itemsize; } diff --git a/c/stdlib b/c/stdlib index 2bdac5ade4c6305a03a49b04f65985012e7410bb..256ad21ffa77601197cd6512d553d6973557cb55 100644 --- a/c/stdlib +++ b/c/stdlib @@ -154,23 +154,27 @@ void exit(int n) _exit(n); } +void _Exit(int n) +{ +/* Is this the best way of doing this? abort() probably shouldn't be calling + * atexit functions either... + */ + while (exit_s.number_of_exit_functions!=0) { + int flags = _exitvector[exit_s.number_of_exit_functions].i; + if ((flags & 3) != 0) { ++exit_s.number_of_exit_functions; break; }; + } + _exit(n); +} + void abort() { raise(SIGABRT); exit(1); } -int abs(int x) -{ - if (x<0) return (-x); - else return x; -} +int (abs)(int x) { return abs(x); } -long int labs(long int x) -{ - if (x<0) return (-x); - else return x; -} +long int (labs)(long int x) { return labs(x); } #if 0 /* Compiler generates poo code at the minute - in machine code for now */ diff --git a/c/string b/c/string index 24fd608e5ca3c2237dae7237ad7e0fc66223636e..bf3e024140d5dc3fd46d2f633cf8db2fce6f1de3 100644 --- a/c/string +++ b/c/string @@ -349,15 +349,17 @@ size_t strxfrm(char *s1, const char *s2, size_t n) int strcoll(const char *a, const char *b) { - int ret; + _kernel_swi_regs r; if (strcoll_territory == 0) return strcmp(a, b); /* C locale */ - if (_swix(Territory_Collate, _INR(0,3)|_OUT(0), - strcoll_territory, a, b, 0, - &ret)) + r.r[0] = strcoll_territory; + r.r[1] = (int) a; + r.r[2] = (int) b; + r.r[3] = 0; + if (_kernel_swi(Territory_Collate, &r, &r)) return 0; - return ret; + return r.r[0]; } void _set_strcoll(int territory) diff --git a/clib/Resources/UK/Messages b/clib/Resources/UK/Messages index 03504967685be7a2bb281db99a3885088401330c..ee7f547977694c26c7669ab1391a78bcc4cd4f9d 100644 --- a/clib/Resources/UK/Messages +++ b/clib/Resources/UK/Messages @@ -74,3 +74,6 @@ C70:unknown error #{DictTokens} C71:Calling standard APCS-A no longer supported by C library C72:Application is not 32-bit compatible + +#{Default} +C73:*** assertion failed: %s, function %s, file %s, line %d diff --git a/clib/h/assert b/clib/h/assert index ed1b5e1242d90e28234cc7761b77c68aaae868e8..00d464e4dc51ea32ab3e559e859380979613b9ab 100644 --- a/clib/h/assert +++ b/clib/h/assert @@ -14,19 +14,20 @@ */ #pragma force_top_level -/* assert.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.2 */ +/* assert.h: ISO 'C' (9899:1999) library header, section 7.2 */ /* Copyright (C) Codemist Ltd. */ /* Copyright (C) Acorn Computers Ltd. 1991, 1992 */ -/* version 2.00 */ +/* version 2.01 */ /* * The assert macro puts diagnostics into programs. When it is executed, * if its argument expression is false, it writes information about the * call that failed (including the text of the argument, the name of the - * source file, and the source line number - the latter are respectively - * the values of the preprocessing macros __FILE__ and __LINE__) on the + * source file, the source line number, and the name of the enclosing + * function - the latter are respectively the values of the preprocessing + * macros __FILE__ and __LINE__ and of the identifier __func__) on the * standard error stream. It then calls the abort function. - * If its argument expression is true, the assert macro returns no value. + * The assert macro returns no value. */ /* @@ -38,9 +39,11 @@ #ifndef __assert_h # define __assert_h #ifdef __cplusplus - extern "C" void __assert(char *, char *, int); + extern "C" void __assert(const char *, const char *, int); + extern "C" void __assert2(const char *, const char *, const char *, int); #else - extern void __assert(char *, char *, int); + extern void __assert(const char *, const char *, int); + extern void __assert2(const char *, const char *, const char *, int); #endif #else # undef assert @@ -49,7 +52,13 @@ #ifdef NDEBUG # define assert(ignore) ((void)0) #else -# define assert(e) ((e) ? (void)0 : __assert(#e, __FILE__, __LINE__)) +# define assert(e) ((e) ? (void)0 : __assert(#e, __FILE__, __LINE__)) +# ifdef __STDC_VERSION__ +# if __STDC_VERSION__ >= 199901 +# undef assert +# define assert(e) ((e) ? (void)0 : __assert2(#e, __func__, __FILE__, __LINE__)) +# endif +# endif #endif /* end of assert.h */ diff --git a/clib/h/ctype b/clib/h/ctype index 3a79b1f5b02ed34f3c5e5e78345b8d340ca663f9..1a3cddc2389679b0661c70900c8a84396d1370c8 100644 --- a/clib/h/ctype +++ b/clib/h/ctype @@ -15,7 +15,7 @@ #pragma force_top_level #pragma include_only_once -/* ctype.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.3 */ +/* ctype.h: ISO 'C' (9899:1999) library header, section 7.4 */ /* Copyright (C) Codemist Ltd. */ /* Copyright (C) Acorn Computers Ltd. 1991, 1992 */ /* version 2.00 */ @@ -89,27 +89,27 @@ extern unsigned char __ctype[]; /* non-0 iff c is a digit, in 'a'..'f', or in 'A'..'F' */ #ifndef __cplusplus -extern int (isalnum)(int c); -extern int (isalpha)(int c); -extern int (iscntrl)(int c); -extern int (isdigit)(int c); -extern int (isgraph)(int c); -extern int (islower)(int c); -extern int (isprint)(int c); -extern int (ispunct)(int c); -extern int (isspace)(int c); -extern int (isupper)(int c); -extern int (isxdigit)(int c); +int (isalnum)(int c); +int (isalpha)(int c); +int (iscntrl)(int c); +int (isdigit)(int c); +int (isgraph)(int c); +int (islower)(int c); +int (isprint)(int c); +int (ispunct)(int c); +int (isspace)(int c); +int (isupper)(int c); +int (isxdigit)(int c); #endif #ifdef __cplusplus extern "C" { #endif -extern int tolower(int c); +int tolower(int c); /* if c is an upper-case letter then return the corresponding */ /* lower-case letter, otherwise return c. */ -extern int toupper(int c); +int toupper(int c); /* if c is an lower-case letter then return the corresponding */ /* upper-case letter, otherwise return c. */ #ifdef __cplusplus diff --git a/clib/h/errno b/clib/h/errno index 5a43702b031c8466705c6f10af27d6a3c9476c46..ff628b613b79f119aa78bdfe33287efdbcc544d5 100644 --- a/clib/h/errno +++ b/clib/h/errno @@ -15,7 +15,7 @@ #pragma force_top_level #pragma include_only_once -/* errno.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.1.3 */ +/* errno.h: ISO 'C' (9899:1999) library header, section 7.5 */ /* Copyright (C) Codemist Ltd. */ /* Copyright (C) Acorn Computers Ltd. 1991, 1992 */ /* version 2.00 */ diff --git a/clib/h/float b/clib/h/float index abb3081bc88327ae58cadd329508ac78eb93a027..a764343968853c649a89680f38d92a691b72325e 100644 --- a/clib/h/float +++ b/clib/h/float @@ -15,7 +15,7 @@ #pragma force_top_level #pragma include_only_once -/* float.h: ISO 'C' (9899 Dec 99) library header, section 5.2.4.2 */ +/* float.h: ISO 'C' (9899 Dec 99) library header, section 5.2.4.2.2 */ /* Copyright (C) Codemist Ltd, 1988 */ /* Copyright (C) Acorn Computers Ltd. 1991, 1992 */ /* version 3.00 */ @@ -50,7 +50,7 @@ * range of the double type, evaluate long double operations and * constants to the range and precision of the long double type; * 2 : evaluate all operations and constants to the range and precision - * of the lang double type; + * of the long double type; * ? : all other negative values are implementation defined. */ @@ -84,6 +84,8 @@ #define DBL_MAX_EXP 1024 #define LDBL_MAX_EXP 1024 /* maximum integer such that FLT_RADIX raised to that power minus 1 is a */ + /* representable finite floating-point number. */ + #define FLT_MAX_10_EXP 38 #define DBL_MAX_10_EXP 308 #define LDBL_MAX_10_EXP 308 diff --git a/clib/h/inttypes b/clib/h/inttypes index d32a13bafc7d471c5250436fcc7f078cafb9579b..024a817b5fc7ffda88caada4d14f8a0b36f650a0 100644 --- a/clib/h/inttypes +++ b/clib/h/inttypes @@ -200,21 +200,21 @@ typedef struct imaxdiv_t { intmax_t quot, rem; } imaxdiv_t; /* type of the value returned by the imaxdiv function. */ -extern intmax_t imaxabs(intmax_t /*j*/); +intmax_t imaxabs(intmax_t /*j*/); /* * computes the absolute value of an integer j. If the result cannot be * represented, the behaviour is undefined. * Returns: the absolute value. */ -extern imaxdiv_t imaxdiv(intmax_t /*numer*/, intmax_t /*denom*/); +imaxdiv_t imaxdiv(intmax_t /*numer*/, intmax_t /*denom*/); /* * computes numer / denom and numer % denom in a single operation. * Returns: a structure of type imaxdiv_t, comprising both the quotient and * the remainder. */ -extern intmax_t strtoimax(const char * restrict /*nptr*/, - char ** restrict /*endptr*/, int /*base*/); +intmax_t strtoimax(const char * restrict /*nptr*/, + char ** restrict /*endptr*/, int /*base*/); /* * equivalent to the strtoll function, except that the initial portion of the * string is converted to intmax_t representation. @@ -224,8 +224,8 @@ extern intmax_t strtoimax(const char * restrict /*nptr*/, * (according to the sign of the value), and the value of the * macro ERANGE is stored in errno. */ -extern uintmax_t strtoumax(const char * restrict /*nptr*/, - char ** restrict /*endptr*/, int /*base*/); +uintmax_t strtoumax(const char * restrict /*nptr*/, + char ** restrict /*endptr*/, int /*base*/); /* * equivalent to the strtoull function, except that the initial portion of * the string is converted to uintmax_t representation. diff --git a/clib/h/locale b/clib/h/locale index 8a1d674a4e885938666aa109fef9614948cde83a..1e9db56874c6d2bb0df2f897ab585de6afd31d5b 100644 --- a/clib/h/locale +++ b/clib/h/locale @@ -15,7 +15,7 @@ #pragma force_top_level #pragma include_only_once -/* locale.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.3 */ +/* locale.h: ISO 'C' (9899:1999) library header, section 7.11 */ /* Copyright (C) Codemist Ltd. */ /* Copyright (C) Acorn Computers Ltd. 1991, 1992 */ /* version 2.00 */ diff --git a/clib/h/math b/clib/h/math index e01bb281dcce2c25d6bebf0908f12e45da11fafa..09093cc58aa23fcc0e017606d07162b86c082171 100644 --- a/clib/h/math +++ b/clib/h/math @@ -15,10 +15,10 @@ #pragma force_top_level #pragma include_only_once -/* math.h: ISO 'C' (9899:1999) library header, section 7.22 */ +/* math.h: ISO 'C' (9899:1999) library header, section 7.12 */ /* Copyright (C) Codemist Ltd. */ /* Copyright (C) Acorn Computers Ltd. 1991 */ -/* version 0.04 */ +/* version 0.05 */ #ifndef __math_h #define __math_h @@ -37,6 +37,10 @@ extern const double HUGE_VAL; #endif #endif +#ifndef HUGE_VALL +#define HUGE_VALL ((long double) HUGE_VAL) +#endif + #ifndef __cplusplus #ifndef HUGE_VALF # define HUGE_VALF INFINITY @@ -55,14 +59,17 @@ extern const double HUGE_VAL; /* the mutually exclusive kinds of floating-point values for fpclassify() */ #endif +#define FP_ILOGB0 (-0x7fffffff) /* -INT_MAX */ +#define FP_ILOGBNAN (~0x7fffffff) /* INT_MIN */ + /* integer constant expressions whose values are returned by ilogb(x) if */ + /* x is zero or NaN, respectively. */ + #define MATH_ERRNO 1 #define MATH_ERREXCEPT 2 #define math_errhandling MATH_ERRNO /* <math.h> functions just set errno - no exceptions are raised */ -/*#pragma no_side_effects*/ - #ifdef __cplusplus extern "C" { #endif @@ -73,16 +80,16 @@ extern "C" { #pragma no_side_effects #pragma force_fpargs_in_regs -extern int __fpclassifyf(float); -extern int __fpclassifyd(double); -extern int __signbitf(float); -extern int __signbitd(double); +__caller_narrow int __fpclassifyf(float); +int __fpclassifyd(double); +__caller_narrow int __signbitf(float); +int __signbitd(double); #pragma no_force_fpargs_in_regs #pragma side_effects #ifdef __cplusplus -#define __classmacro(fn,r) (sizeof(r) == 4 ? __##fn##f(r) : \ - __##fn##d(r)) +#define __classmacro(fn,r) (sizeof(r) == 4 ? __##fn##f((float)(r)) : \ + __##fn##d((double)(r))) #else #define __assertfp(r) ___assert(___typeof(r) == 0x002 ||\ ___typeof(r) == 0x202 ||\ @@ -90,8 +97,8 @@ extern int __signbitd(double); "Illegal type used with classification macro") #define __classmacro(fn,r) (__assertfp(r),\ - ___typeof(r) == 0x402 ? __##fn##f(r) : \ - __##fn##d(r)) + ___typeof(r) == 0x402 ? __##fn##f((float)(r)) : \ + __##fn##d((double)(r))) #endif #define fpclassify(r) __classmacro(fpclassify,(r)) @@ -109,232 +116,369 @@ extern int __signbitd(double); #endif -extern double acos(double /*x*/); +double acos(double /*x*/); +float acosf(float /*x*/); +long double acosl(long double /*x*/); /* computes the principal value of the arc cosine of x */ /* a domain error occurs for arguments not in the range -1 to 1 */ /* Returns: the arc cosine in the range 0 to Pi. */ -extern double asin(double /*x*/); +double asin(double /*x*/); +float asinf(float /*x*/); +long double asinl(long double /*x*/); /* computes the principal value of the arc sine of x */ /* a domain error occurs for arguments not in the range -1 to 1 */ /* and -HUGE_VAL is returned. */ /* Returns: the arc sine in the range -Pi/2 to Pi/2. */ -extern double atan(double /*x*/); +double atan(double /*x*/); +float atanf(float /*x*/); +long double atanl(long double /*x*/); /* computes the principal value of the arc tangent of x */ /* Returns: the arc tangent in the range -Pi/2 to Pi/2. */ -extern double atan2(double /*x*/, double /*y*/); +double atan2(double /*y*/, double /*x*/); +float atan2f(float /*y*/, float /*x*/); +long double atan2l(long double /*y*/, long double /*x*/); /* computes the principal value of the arc tangent of y/x, using the */ /* signs of both arguments to determine the quadrant of the return value */ - /* a domain error occurs if both args are zero, and -HUGE_VAL returned. */ /* Returns: the arc tangent of y/x, in the range -Pi to Pi. */ - -extern double __d_atan(double); -#define atan(x) __d_atan(x) -#ifndef __cplusplus -extern __caller_narrow float __r_atan(float); -#define atanf(x) __r_atan(x) -#endif - -extern double cos(double /*x*/); +double cos(double /*x*/); +float cosf(float /*x*/); +long double cosl(long double /*x*/); /* computes the cosine of x (measured in radians). A large magnitude */ /* argument may yield a result with little or no significance */ /* Returns: the cosine value. */ -extern double sin(double /*x*/); +double sin(double /*x*/); +float sinf(float /*x*/); +long double sinl(long double /*x*/); /* computes the sine of x (measured in radians). A large magnitude */ /* argument may yield a result with little or no significance */ /* Returns: the sine value. */ - -extern double __d_cos(double); -extern double __d_sin(double); -#define cos(x) __d_cos(x) -#define sin(x) __d_sin(x) -#ifndef __cplusplus -extern __caller_narrow float __r_sin(float); -extern __caller_narrow float __r_cos(float); -#define sinf(x) __r_sin(x) -#define cosf(x) __r_cos(x) -#endif - -extern double tan(double /*x*/); +double tan(double /*x*/); +float tanf(float /*x*/); +long double tanl(long double /*x*/); /* computes the tangent of x (measured in radians). A large magnitude */ /* argument may yield a result with little or no significance */ /* Returns: the tangent value. */ /* if range error; returns HUGE_VAL. */ -extern double cosh(double /*x*/); +double acosh(double /*x*/); +float acoshf(float /*x*/); +long double acoshl(long double /*x*/); + /* computes the (non-negative) arc hyperbolic cosine of x. */ + /* A domain error occurs for arguments less than 1. */ + /* Returns: arcosh x in the interval [0,+inf] */ +double asinh(double /*x*/); +float asinhf(float /*x*/); +long double asinhl(long double /*x*/); + /* computes the arc hyperbolic sine of x. */ + /* Returns: arsinh x */ +double atanh(double /*x*/); +float atanhf(float /*x*/); +long double atanhl(long double /*x*/); + /* computes the arc hyperbolic tangent of x. A domain error occurs */ + /* for arguments not in the interval [-1,+1]. A range error occurs */ + /* if the argument equals -1 or +1. */ + /* Returns: artanh x */ +double cosh(double /*x*/); +float coshf(float /*x*/); +long double coshl(long double /*x*/); /* computes the hyperbolic cosine of x. A range error occurs if the */ /* magnitude of x is too large. */ /* Returns: the hyperbolic cosine value. */ /* if range error; returns HUGE_VAL. */ -extern double sinh(double /*x*/); +double sinh(double /*x*/); +float sinhf(float /*x*/); +long double sinhl(long double /*x*/); /* computes the hyperbolic sine of x. A range error occurs if the */ /* magnitude of x is too large. */ /* Returns: the hyperbolic sine value. */ /* if range error; returns -HUGE_VAL or HUGE_VAL depending */ /* on the sign of the argument */ -extern double tanh(double /*x*/); +double tanh(double /*x*/); +float tanhf(float /*x*/); +long double tanhl(long double /*x*/); /* computes the hyperbolic tangent of x. */ /* Returns: the hyperbolic tangent value. */ -extern double exp(double /*x*/); - /* computes the exponential function of x. A range error occurs if the */ +double exp(double /*x*/); +float expf(float /*x*/); +long double expl(long double /*x*/); + /* computes the base-e exponential of x. A range error occurs if the */ + /* magnitude of x is too large. */ + /* Returns: e^x */ + /* if underflow range error; 0 is returned. */ + /* if overflow range error; HUGE_VAL is returned. */ +double exp2(double /*x*/); +float exp2f(float /*x*/); +long double exp2l(long double /*x*/); + /* computes the base-2 exponential of x. A range error occurs if the */ /* magnitude of x is too large. */ - /* Returns: the exponential value. */ + /* Returns: 2^x */ /* if underflow range error; 0 is returned. */ /* if overflow range error; HUGE_VAL is returned. */ -extern double frexp(double /*value*/, int * /*exp*/); +double expm1(double /*x*/); +float expm1f(float /*x*/); +long double expm1l(long double /*x*/); + /* computes the base-e exponential of x, minus 1. A range error occurs if */ + /* the magnitude of x is too large. */ + /* Returns: e^x - 1 */ +double frexp(double /*value*/, int * /*exp*/); +float frexpf(float /*value*/, int * /*exp*/); +long double frexpl(long double /*value*/, int * /*exp*/); /* breaks a floating-point number into a normalised fraction and an */ /* integral power of 2. It stores the integer in the int object pointed */ /* to by exp. */ /* Returns: the value x, such that x is a double with magnitude in the */ /* interval 0.5 to 1.0 or zero, and value equals x times 2 raised to the */ /* power *exp. If value is zero, both parts of the result are zero. */ -extern double ldexp(double /*x*/, int /*exp*/); +int ilogb(double /*x*/); +int ilogbf(float /*x*/); +int ilogbl(long double /*x*/); + /* extracts the exponent of x as a signed int value. If x is zero it */ + /* computes the value FP_ILOGB0; if x is infinite it computes the value */ + /* INT_MAX; if x is a NaN it computes the value FP_ILOGBNAN; otherwise it */ + /* is equivalent to calling the corresponding logb function and casting */ + /* the returned value to type int. A range error occurs if x is 0. */ + /* Returns: the exponent of x as a signed int value. */ +double ldexp(double /*x*/, int /*exp*/); +float ldexpf(float /*x*/, int /*exp*/); +long double ldexpl(long double /*x*/, int /*exp*/); /* multiplies a floating-point number by an integral power of 2. */ /* A range error may occur. */ /* Returns: the value of x times 2 raised to the power of exp. */ /* if range error; HUGE_VAL is returned. */ -extern double log(double /*x*/); - /* computes the natural logarithm of x. A domain error occurs if the */ - /* argument is negative, and -HUGE_VAL is returned. A range error occurs */ - /* if the argument is zero. */ +double log(double /*x*/); +float logf(float /*x*/); +long double logl(long double /*x*/); + /* computes the base-e (natural) logarithm of x. A domain error occurs if */ + /* the argument is negative, and -HUGE_VAL is returned. A range error */ + /* occurs if the argument is zero. */ /* Returns: the natural logarithm. */ /* if range error; -HUGE_VAL is returned. */ -extern double log10(double /*x*/); - /* computes the base-ten logarithm of x. A domain error occurs if the */ - /* argument is negative. A range error occurs if the argument is zero. */ +double log10(double /*x*/); +float log10f(float /*x*/); +long double log10l(long double /*x*/); + /* computes the base-ten (common) logarithm of x. A domain error occurs if */ + /* the argument is negative. A range error occurs if the argument is zero. */ /* Returns: the base-ten logarithm. */ -extern double modf(double /*value*/, double * /*iptr*/); +double log1p(double /*x*/); +float log1pf(float /*x*/); +long double log1pl(long double /*x*/); + /* computes the base-e (natural) logarithm of 1 plus the argument. A */ + /* domain error occurs if the argument is less than -1. A range error */ + /* occurs if the argument equals -1. */ + /* Returns: the natural logarithm of (1+x). */ +double log2(double /*x*/); +float log2f(float /*x*/); +long double log2l(long double /*x*/); + /* computes the base-two logarithm of x. A domain error occurs if the */ + /* argument is negative. A range error occurs if the argument is zero. */ + /* Returns: the base-two logarithm. */ +double logb(double /*x*/); +float logbf(float /*x*/); +long double logbl(long double /*x*/); + /* extracts the exponent of x, as a signed integer value in floating- */ + /* point format. If x is subnormal it is treated as though it were */ + /* normalised; thus, for positive finite x, */ + /* 1 <= x * FLT_RADIX ^ -logb(x) < FLT_RADIX */ + /* A domain error occurs if the argument is zero. */ + /* Returns: the signed exponent of x */ +double modf(double /*value*/, double * /*iptr*/); +float modff(float /*value*/, float * /*iptr*/); +long double modfl(long double /*value*/, long double * /*iptr*/); /* breaks the argument value into integral and fraction parts, each of */ /* which has the same sign as the argument. It stores the integral part */ /* as a double in the object pointed to by iptr. */ /* Returns: the signed fractional part of value. */ - -extern double hypot(double /*x*/, double /*y*/); -extern float hypotf(float /*x*/, float /*y*/); +double scalbn(double /*x*/, int /*n*/); +float scalbnf(float /*x*/, int /*n*/); +long double scalbnl(long double /*x*/, int /*n*/); +double scalbln(double /*x*/, long int /*n*/); +float scalblnf(float /*x*/, long int /*n*/); +long double scalblnl(long double /*x*/, long int /*n*/); + /* computes x * FLT_RADIX^n efficiently. A range error may occur. */ + /* Returns: x * FLT_RADIX^n */ + +double cbrt(double /*x*/); +float cbrtf(float /*x*/); +long double cbrtl(long double /*x*/); + /* computes the real cube root of x. */ + /* Returns: x^(1/3) */ +#pragma no_side_effects +double fabs(double /*x*/); +float fabsf(float /*x*/); +long double fabsl(long double /*x*/); + /* computes the absolute value of the floating-point number x. */ + /* Returns: the absolute value of x. */ +#pragma side_effects +double hypot(double /*x*/, double /*y*/); +float hypotf(float /*x*/, float /*y*/); +long double hypotl(long double /*x*/, long double /*y*/); /* computes the square root of the sum of the squares of x and y, without */ - /* undue overflow or underflow. A ronge error may occur. */ + /* undue overflow or underflow. A range error may occur. */ /* Returns: sqrt(x^2 + y^2) */ -extern double pow(double /*x*/, double /*y*/); +double pow(double /*x*/, double /*y*/); +float powf(float /*x*/, float /*y*/); +long double powl(long double /*x*/, long double /*y*/); /* computes x raised to the power of y. A domain error occurs if x is */ /* zero and y is less than or equal to zero, or if x is negative and y */ /* is not an integer, and -HUGE_VAL returned. A range error may occur. */ /* Returns: the value of x raised to the power of y. */ /* if underflow range error; 0 is returned. */ /* if overflow range error; HUGE_VAL is returned. */ -extern double sqrt(double /*x*/); +double sqrt(double /*x*/); +float sqrtf(float /*x*/); +long double sqrtl(long double /*x*/); /* computes the non-negative square root of x. A domain error occurs */ /* if the argument is negative, and -HUGE_VAL returned. */ /* Returns: the value of the square root. */ -extern double fabs(double /*x*/); -extern float fabsf(float /*x*/); - /* computes the absolute value of the floating-point number x. */ - /* Returns: the absolute value of x. */ -extern double ceil(double /*x*/); -extern float ceilf(float /*x*/); +double erf(double /*x*/); +float erff(float /*x*/); +long double erfl(long double /*x*/); + /* computes the error function of x. */ + /* Returns: erf x = 2/sqrt(pi) * integral[0,x] (e^(-t^2)) dt */ +double erfc(double /*x*/); +float erfcf(float /*x*/); +long double erfcl(long double /*x*/); + /* computes the complementary error function of x. A range error occurs */ + /* if x is too large. + /* Returns: erfc x = 1 - erf x */ + /* = 2/sqrt(pi) * integral[x,inf] (e^(-t^2)) dt */ +double lgamma(double /*x*/); +float lgammaf(float /*x*/); +long double lgammal(long double /*x*/); + /* computes the natural logarithm of the absolute value of gamma of x. */ + /* A range error occurs if x is too large. A range error occurs if x is */ + /* a negative integer or zero. */ + /* Returns: log |Gamma(x)| */ +double tgamma(double /*x*/); +float tgammaf(float /*x*/); +long double tgammal(long double /*x*/); + /* computes the gamma function of x. A domain error occurs if x is a */ + /* negative integer or if the result cannot be represented when x is */ + /* zero. A range error may occur if the magnitude of x is too large or */ + /* too small. */ + /* Returns: Gamma(x) */ + +#pragma no_side_effects +double ceil(double /*x*/); +float ceilf(float /*x*/); +long double ceill(long double /*x*/); /* computes the smallest integer not less than x. */ /* Returns: the smallest integer not less than x, expressed as a double. */ -extern double floor(double /*x*/); -extern float floorf(float /*x*/); +double floor(double /*x*/); +float floorf(float /*x*/); +long double floorl(long double /*x*/); /* computes the largest integer not greater than x. */ /* Returns: the largest integer not greater than x, expressed as a double */ -extern double nearbyint(double /*x*/); -extern float nearbyintf(float /*x*/); +double nearbyint(double /*x*/); +float nearbyintf(float /*x*/); +long double nearbyintl(long double /*x*/); /* rounds its argument to an integer value, using the current rounding */ /* direction. Does not raise the inexact exception. */ /* Returns: the rounded integer value. */ -extern double rint(double /*x*/); -extern float rintf(float /*x*/); +double rint(double /*x*/); +float rintf(float /*x*/); +long double rintl(long double /*x*/); /* rounds its argument to an integer value, using the current rounding */ /* direction. Raises "inexact" if the result differs from the argument. */ /* Returns: the rounded integer value. */ -extern long int lrint(double /*x*/); -extern long int lrintf(float /*x*/); +#pragma side_effects +long int lrint(double /*x*/); +long int lrintf(float /*x*/); +long int lrintl(long double /*x*/); /* rounds its argument to an integer value, using the current rounding */ /* direction. Raises "inexact" if the result differs from the argument. */ /* Returns: the rounded integer value. */ -extern double round(double /*x*/); -extern float roundf(float /*x*/); +#pragma no_side_effects +double round(double /*x*/); +float roundf(float /*x*/); +long double roundl(long double /*x*/); /* rounds its argument to the nearest integer value, rounding halfway */ /* cases away from zero. */ /* Returns: the rounded integer value. */ -extern long int lround(double /*x*/); -extern long int lroundf(float /*x*/); +#pragma side_effects +long int lround(double /*x*/); +long int lroundf(float /*x*/); +long int lroundl(long double /*x*/); /* rounds its argument to the nearest integer value, rounding halfway */ /* cases away from zero. */ /* Returns: the rounded integer value. */ -extern double trunc(double /*x*/); -extern float truncf(float /*x*/); +#pragma no_side_effects +double trunc(double /*x*/); +float truncf(float /*x*/); +long double truncl(long double /*x*/); /* rounds its argument to the integer value, nearest to but no larger in */ /* magnitude than the argument. */ /* Returns: the truncated integer value. */ -extern double fmod(double /*x*/, double /*y*/); +#pragma side_effects +double fmod(double /*x*/, double /*y*/); +float fmodf(float /*x*/, float /*y*/); +long double fmodl(long double /*x*/, long double /*y*/); /* computes the floating-point remainder of x/y. */ /* Returns: the value x - i * y, for some integer i such that, if y is */ /* nonzero, the result has the same sign as x and magnitude */ /* less than the magnitude of y. If y is zero, a domain error */ /* occurs and -HUGE_VAL is returned. */ -extern double remainder(double /*x*/, double /*y*/); -extern float remainderf(float /*x*/, float /*y*/); +double remainder(double /*x*/, double /*y*/); +float remainderf(float /*x*/, float /*y*/); +long double remainderl(long double /*x*/, long double /*y*/); /* computes the remainder x REM y required by IEEE 754 */ /* Returns: x REM y */ -extern double __d_abs(double); -extern double __d_floor(double); -extern double __d_ceil(double); -extern double __d_trunc(double); -extern double __d_rint(double); -extern long int __d_lrint(double); -extern float __r_abs(float); -#define fabs(x) __d_abs(x) -#define floor(x) __d_floor(x) -#define ceil(x) __d_ceil(x) -#define trunc(x) __d_trunc(x) -#define rint(x) __d_rint(x) -#define lrint(x) __d_lrint(x) -#ifndef __cplusplus -extern __caller_narrow float __r_floor(float); -extern __caller_narrow float __r_ceil(float); -extern __caller_narrow float __r_trunc(float); -extern __caller_narrow float __r_rint(float); -extern __caller_narrow long int __r_lrint(float); -#define fabsf(x) __r_abs(x) -#define floorf(x) __r_floor(x) -#define ceilf(x) __r_ceil(x) -#define truncf(x) __r_trunc(x) -#define rintf(x) __r_rint(x) -#define lrintf(x) __r_lrint(x) -#endif - +#pragma no_side_effects #ifndef __cplusplus #pragma force_fpargs_in_regs -extern double copysign(double /*x*/, double /*y*/); -extern float copysignf(float /*x*/, float /*y*/); +double copysign(double /*x*/, double /*y*/); +__caller_narrow float copysignf(float /*x*/, float /*y*/); +long double copysignl(long double /*x*/, long double /*y*/); #pragma no_force_fpargs_in_regs /* produce a value with the magnitude of x and the sign of y. They */ /* produce a NaN (with the sign of y) if x is a NaN. */ /* Returns: a value with the magnitude of x and the sign of y. */ #endif -extern double nan(const char * /*tagp*/); -extern float nanf(const char * /*tagp*/); +double nan(const char * /*tagp*/); +float nanf(const char * /*tagp*/); +long double nanl(const char * /*tagp*/); /* Returns: a quiet NaN, with content indicated through tagp. */ -extern double nextafter(double /*x*/, double /*y*/); -extern float nextafterf(float /*x*/, float /*y*/); +#pragma side_effects +double nextafter(double /*x*/, double /*y*/); +float nextafterf(float /*x*/, float /*y*/); +long double nextafterl(long double /*x*/, long double /*y*/); /* Returns: the next representable value in the specified format after */ /* x in the direction of y */ -extern double fdim(double /*x*/, double /*y*/); -extern float fdimf(float /*x*/, float /*y*/); +double nexttoward(double /*x*/, long double /*y*/); +float nexttowardf(float /*x*/, long double /*y*/); +long double nexttowardl(long double /*x*/, long double /*y*/); + /* equivalent to the nextafter functions except that the second parameter */ + /* has type long double. */ +double fdim(double /*x*/, double /*y*/); +float fdimf(float /*x*/, float /*y*/); +long double fdiml(long double /*x*/, long double /*y*/); /* determine the positive difference between their arguments: */ /* { x-y if x > y */ /* { +0 if x <= y */ /* A range error may occur. */ /* Returns: the positive difference value. */ -extern double fmax(double /*x*/, double /*y*/); -extern float fmaxf(float /*x*/, float /*y*/); +#pragma no_side_effects +double fmax(double /*x*/, double /*y*/); +float fmaxf(float /*x*/, float /*y*/); +long double fmaxl(long double /*x*/, long double /*y*/); /* Returns: the maximum numeric value of their arguments. */ -extern double fmin(double /*x*/, double /*y*/); -extern float fminf(float /*x*/, float /*y*/); +double fmin(double /*x*/, double /*y*/); +float fminf(float /*x*/, float /*y*/); +long double fminl(long double /*x*/, long double /*y*/); /* Returns: the minimum numeric value of their arguments. */ +#pragma side_effects + +double fma(double /*x*/, double /*y*/, double /*z*/); +float fmaf(float /*x*/, float /*y*/, float /*z*/); +long double fmal(long double /*x*/, long double /*y*/, long double /*z*/); + /* computes (x*y)+z, rounded as one ternary operation: it computes */ + /* the value (as if) to infinite precision and rounds once to the result */ + /* format, according to the rounding mode characterised by the value of */ + /* FLT_ROUNDS. */ + /* Returns: (x*y)+z, rounded as one ternary operation. */ #ifndef __cplusplus #define isgreater(x,y) ((x) __greater (y)) @@ -349,12 +493,50 @@ extern float fminf(float /*x*/, float /*y*/); /* "invalid" floating-point exception. */ #endif +/* Some functions can be safely inlined - appropriate macros defined here */ +double __d_atan(double); +double __d_cos(double); +double __d_sin(double); +double __d_abs(double); +double __d_floor(double); +double __d_ceil(double); +double __d_trunc(double); +double __d_rint(double); +long int __d_lrint(double); +float __r_abs(float); +#define atan(x) __d_atan(x) +#define cos(x) __d_cos(x) +#define sin(x) __d_sin(x) +#define fabs(x) ((void) sizeof fabs(x), __abs (double) (x)) +#define floor(x) __d_floor(x) +#define ceil(x) __d_ceil(x) +#define trunc(x) __d_trunc(x) +#define rint(x) __d_rint(x) +#define lrint(x) __d_lrint(x) +#ifndef __cplusplus +__caller_narrow float __r_atan(float); +__caller_narrow float __r_sin(float); +__caller_narrow float __r_cos(float); +__caller_narrow float __r_floor(float); +__caller_narrow float __r_ceil(float); +__caller_narrow float __r_trunc(float); +__caller_narrow float __r_rint(float); +__caller_narrow long int __r_lrint(float); +#define atanf(x) __r_atan(x) +#define sinf(x) __r_sin(x) +#define cosf(x) __r_cos(x) +#define fabsf(x) ((void) sizeof fabsf(x), __abs (float) (x)) +#define floorf(x) __r_floor(x) +#define ceilf(x) __r_ceil(x) +#define truncf(x) __r_trunc(x) +#define rintf(x) __r_rint(x) +#define lrintf(x) __r_lrint(x) +#endif + #ifdef __cplusplus } #endif -#pragma side_effects - #endif /* end of math.h */ diff --git a/clib/h/setjmp b/clib/h/setjmp index 2388f48b311a8916fd7e0981fa2f732b74c25f40..1110dd586db831262593486b9b4c74fdbad514a2 100644 --- a/clib/h/setjmp +++ b/clib/h/setjmp @@ -15,7 +15,7 @@ #pragma force_top_level #pragma include_only_once -/* setjmp.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.6 */ +/* setjmp.h: ISO 'C' (9899:1999) library header, section 7.13 */ /* Copyright (C) A.C. Norman and A. Mycroft */ /* Copyright (C) Acorn Computers Ltd. 1991, 1992 */ /* version 2.00 */ @@ -49,7 +49,7 @@ typedef int jmp_buf[22]; /* size suitable for the ARM */ #ifdef __cplusplus extern "C" { #endif -extern int setjmp(jmp_buf /*env*/); +int setjmp(jmp_buf /*env*/); /* Saves its calling environment in its jmp_buf argument, for later use * by the longjmp function. * Returns: If the return is from a direct invocation, the setjmp function @@ -57,7 +57,7 @@ extern int setjmp(jmp_buf /*env*/); * function, the setjmp function returns a non zero value. */ -extern void longjmp(jmp_buf /*env*/, int /*val*/); +void longjmp(jmp_buf /*env*/, int /*val*/); /* Restores the environment saved by the most recent call to setjmp in the * same invocation of the program, with the corresponding jmp_buf argument. * If there has been no such call, or if the function containing the call diff --git a/clib/h/signal b/clib/h/signal index 85d55937ff197dfd2a7c58a77d093ea6467415c9..7c8a56591c2ea221b2fc2412e94ff1def5a343f3 100644 --- a/clib/h/signal +++ b/clib/h/signal @@ -15,7 +15,7 @@ #pragma force_top_level #pragma include_only_once -/* signal.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.7 */ +/* signal.h: ISO 'C' (9899:1999) library header, section 7.14 */ /* Copyright (C) Codemist Ltd. */ /* Copyright (C) Acorn Computers Ltd. 1991, 1992 */ /* version 2.00 */ @@ -36,9 +36,9 @@ typedef int sig_atomic_t; #ifdef __cplusplus extern "C" { #endif -extern void __SIG_DFL(int); -extern void __SIG_ERR(int); -extern void __SIG_IGN(int); +void __SIG_DFL(int); +void __SIG_ERR(int); +void __SIG_IGN(int); /* * Each of the following macros expand to a constant expression with a * distinct value and has the same type as the second argument to, and the @@ -69,7 +69,7 @@ extern void __SIG_IGN(int); #define SIGUSR2 9 #define SIGOSERROR 10 -extern void (*signal (int /*sig*/, void (* /*func*/ )(int)))(int); +void (*signal (int /*sig*/, void (* /*func*/ )(int)))(int); /* * Chooses one of three ways in which receipt of the signal number sig is to * be subsequently handled. If the value of func is SIG_DFL, default @@ -102,7 +102,7 @@ extern void (*signal (int /*sig*/, void (* /*func*/ )(int)))(int); * integer expression errno is set to indicate the error. */ -extern int raise(int /*sig*/); +int raise(int /*sig*/); /* sends the signal sig to the executing program. */ /* Returns: zero if successful, non-zero if unsuccessful. */ #ifdef __cplusplus diff --git a/clib/h/stddef b/clib/h/stddef index d2e8015e2b2b70f42356324217b9beb478c3c3c7..26683611034abc51f51ce70bea351ab052f470ce 100644 --- a/clib/h/stddef +++ b/clib/h/stddef @@ -15,7 +15,7 @@ #pragma force_top_level #pragma include_only_once -/* stddef.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.1.4 */ +/* stddef.h: ISO 'C' (9899:1999) library header, section 7.17 */ /* Copyright (C) Codemist Ltd. */ /* Copyright (C) Acorn Computers Ltd. 1991, 1992 */ /* version 2.01 */ diff --git a/clib/h/stdio b/clib/h/stdio index 180623ddb2873f31db6cf9eb4bce7b263ddc8a71..a1ed212bb1480ee25c4c22a3bdc7dbf96505f392 100644 --- a/clib/h/stdio +++ b/clib/h/stdio @@ -15,19 +15,16 @@ #pragma force_top_level #pragma include_only_once -/* stdio.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.9 */ +/* stdio.h: ISO 'C' (9899:1999) library header, section 7.19 */ /* Copyright (C) Codemist Ltd. */ /* Copyright (C) Acorn Computers Ltd., 1990, 1992 */ -/* version 3.00 */ - -/* AM July-88 changes to all prototypes so that */ -/* #define mode 3; #include <stdio.h> can work as ANSI require. */ +/* version 3.01 */ /* - * stdio.h declares two types, several macros, and many functions for + * stdio.h declares three types, several macros, and many functions for * performing input and output. For a discussion on Streams and Files - * refer to sections 4.9.2 and 4.9.3 in the above ANSI draft, or to a - * modern textbook on C. + * refer to sections 7.19.2 and 7.19.3 in the above ISO standard, or + * to a modern textbook on C. */ #ifndef __stdio_h @@ -152,7 +149,7 @@ extern FILE __iob[]; /* pointer to a FILE object associated with standard error stream */ #endif -extern int remove(const char * /*filename*/); +int remove(const char * /*filename*/); /* * causes the file whose name is the string pointed to by filename to be * removed. Subsequent attempts to open the file will fail, unless it is @@ -161,7 +158,7 @@ extern int remove(const char * /*filename*/); * fails). * Returns: zero if the operation succeeds, nonzero if it fails. */ -extern int rename(const char * /*old*/, const char * /*new*/); +int rename(const char * /*old*/, const char * /*new*/); /* * causes the file whose name is the string pointed to by old to be * henceforth known by the name given by the string pointed to by new. The @@ -173,14 +170,14 @@ extern int rename(const char * /*old*/, const char * /*new*/); * case if the file existed previously it is still known by its * original name. */ -extern FILE *tmpfile(void); +FILE *tmpfile(void); /* * creates a temporary binary file that will be automatically removed when * it is closed or at program termination. The file is opened for update. * Returns: a pointer to the stream of the file that it created. If the file * cannot be created, a null pointer is returned. */ -extern char *tmpnam(char * /*s*/); +char *tmpnam(char * /*s*/); /* * generates a string that is not the same as the name of an existing file. * The tmpnam function generates a different string each time it is called, @@ -198,7 +195,7 @@ extern char *tmpnam(char * /*s*/); * the argument as its value. */ -extern int fclose(FILE * /*stream*/); +int fclose(FILE * /*stream*/); /* * causes the stream pointed to by stream to be flushed and the associated * file to be closed. Any unwritten buffered data for the stream are @@ -208,7 +205,7 @@ extern int fclose(FILE * /*stream*/); * Returns: zero if the stream was succesfully closed, or nonzero if any * errors were detected or if the stream was already closed. */ -extern int fflush(FILE * /*stream*/); +int fflush(FILE * /*stream*/); /* * If the stream points to an output or update stream in which the most * recent operation was output, the fflush function causes any unwritten @@ -218,7 +215,7 @@ extern int fflush(FILE * /*stream*/); * on the stream. * Returns: nonzero if a write error occurs. */ -extern FILE *fopen(const char * /*filename*/, const char * /*mode*/); +FILE *fopen(const char * /*filename*/, const char * /*mode*/); /* * opens the file whose name is the string pointed to by filename, and * associates a stream with it. @@ -261,8 +258,8 @@ extern FILE *fopen(const char * /*filename*/, const char * /*mode*/); * Returns: a pointer to the object controlling the stream. If the open * operation fails, fopen returns a null pointer. */ -extern FILE *freopen(const char * /*filename*/, const char * /*mode*/, - FILE * /*stream*/); +FILE *freopen(const char * /*filename*/, const char * /*mode*/, + FILE * /*stream*/); /* * opens the file whose name is the string pointed to by filename and * associates the stream pointed to by stream with it. The mode argument is @@ -273,15 +270,14 @@ extern FILE *freopen(const char * /*filename*/, const char * /*mode*/, * Returns: a null pointer if the operation fails. Otherwise, freopen * returns the value of the stream. */ -extern void setbuf(FILE * /*stream*/, char * /*buf*/); +void setbuf(FILE * /*stream*/, char * /*buf*/); /* * Except that it returns no value, the setbuf function is equivalent to the * setvbuf function invoked with the values _IOFBF for mode and BUFSIZ for * size, or (if buf is a null pointer), with the value _IONBF for mode. * Returns: no value. */ -extern int setvbuf(FILE * /*stream*/, char * /*buf*/, - int /*mode*/, size_t /*size*/); +int setvbuf(FILE * /*stream*/, char * /*buf*/, int /*mode*/, size_t /*size*/); /* * may be used after the stream pointed to by stream has been associated * with an open file but before it is read or written. The argument mode @@ -301,7 +297,7 @@ extern int setvbuf(FILE * /*stream*/, char * /*buf*/, */ #pragma -v1 /* hint to the compiler to check f/s/printf format */ -extern int fprintf(FILE * /*stream*/, const char * /*format*/, ...); +int fprintf(FILE * /*stream*/, const char * /*format*/, ...); /* * writes output to the stream pointed to by stream, under control of the * string pointed to by format that specifies how subsequent arguments are @@ -322,14 +318,14 @@ extern int fprintf(FILE * /*stream*/, const char * /*format*/, ...); * Returns: the number of characters transmitted, or a negative value if an * output error occurred. */ -extern int printf(const char * /*format*/, ...); +int printf(const char * /*format*/, ...); /* * is equivalent to fprintf with the argument stdout interposed before the * arguments to printf. * Returns: the number of characters transmitted, or a negative value if an * output error occurred. */ -extern int snprintf(char * /*s*/, size_t /*n*/, const char * /*format*/, ...); +int snprintf(char * /*s*/, size_t /*n*/, const char * /*format*/, ...); /* * is equivalent to fprintf, except that the argument s specifies an array * into which the generated output is to be written, rather than to a @@ -343,7 +339,7 @@ extern int snprintf(char * /*s*/, size_t /*n*/, const char * /*format*/, ...); * written if and only if the returned value is nonnegative and * less than n. */ -extern int sprintf(char * /*s*/, const char * /*format*/, ...); +int sprintf(char * /*s*/, const char * /*format*/, ...); /* * is equivalent to fprintf, except that the argument s specifies an array * into which the generated output is to be written, rather than to a @@ -353,7 +349,7 @@ extern int sprintf(char * /*s*/, const char * /*format*/, ...); * terminating null character. */ #pragma -v2 /* hint to the compiler to check f/s/scanf format */ -extern int fscanf(FILE * /*stream*/, const char * /*format*/, ...); +int fscanf(FILE * /*stream*/, const char * /*format*/, ...); /* * reads input from the stream pointed to by stream, under control of the * string pointed to by format that specifies the admissible input sequences @@ -386,7 +382,7 @@ extern int fscanf(FILE * /*stream*/, const char * /*format*/, ...); * even zero, in the event of an early conflict between an input * character and the format. */ -extern int scanf(const char * /*format*/, ...); +int scanf(const char * /*format*/, ...); /* * is equivalent to fscanf with the argument stdin interposed before the * arguments to scanf. @@ -395,7 +391,7 @@ extern int scanf(const char * /*format*/, ...); * input items assigned, which can be fewer than provided for, or * even zero, in the event of an early matching failure. */ -extern int sscanf(const char * /*s*/, const char * /*format*/, ...); +int sscanf(const char * /*s*/, const char * /*format*/, ...); /* * is equivalent to fscanf except that the argument s specifies a string * from which the input is to be obtained, rather than from a stream. @@ -407,8 +403,7 @@ extern int sscanf(const char * /*s*/, const char * /*format*/, ...); * even zero, in the event of an early matching failure. */ #pragma -v0 /* back to default */ -extern int vfprintf(FILE * /*stream*/, - const char * /*format*/, __va_list /*arg*/); +int vfprintf(FILE * /*stream*/, const char * /*format*/, __va_list /*arg*/); /* * is equivalent to fprintf, with the variable argument list replaced by * arg, which has been initialised by the va_start macro (and possibly @@ -417,8 +412,7 @@ extern int vfprintf(FILE * /*stream*/, * Returns: the number of characters transmitted, or a negative value if an * output error occurred. */ -extern int vfscanf(FILE * /*stream*/, - const char * /*format*/, __va_list /*arg*/); +int vfscanf(FILE * /*stream*/, const char * /*format*/, __va_list /*arg*/); /* * is equivalent to fscanf, with the variable argument list replaced by * arg, which has been initialised by the va_start macro (and possibly @@ -429,7 +423,7 @@ extern int vfscanf(FILE * /*stream*/, * of input items assigned, which can be fewer than provided for, * or even zero, in the event of an early matching failure. */ -extern int vprintf(const char * /*format*/, __va_list /*arg*/); +int vprintf(const char * /*format*/, __va_list /*arg*/); /* * is equivalent to printf, with the variable argument list replaced by arg, * which has been initialised by the va_start macro (and possibly subsequent @@ -437,7 +431,7 @@ extern int vprintf(const char * /*format*/, __va_list /*arg*/); * Returns: the number of characters transmitted, or a negative value if an * output error occurred. */ -extern int vscanf(const char * /*format*/, __va_list /*arg*/); +int vscanf(const char * /*format*/, __va_list /*arg*/); /* * is equivalent to scanf, with the variable argument list replaced by arg, * which has been initialised by the va_start macro (and possibly subsequent @@ -447,8 +441,8 @@ extern int vscanf(const char * /*format*/, __va_list /*arg*/); * input items assigned, which can be fewer than provided for, or * even zero, in the event of an early matching failure. */ -extern int vsnprintf(char * /*s*/, size_t /*n*/, - const char * /*format*/, __va_list /*arg*/); +int vsnprintf(char * /*s*/, size_t /*n*/, + const char * /*format*/, __va_list /*arg*/); /* * is equivalent to snprintf, with the variable argument list replaced by * arg, which has been initialised by the va_start macro (and possibly @@ -460,7 +454,7 @@ extern int vsnprintf(char * /*s*/, size_t /*n*/, * written if and only if the returned value is nonnegative and * less than n. */ -extern int vsprintf(char * /*s*/, const char * /*format*/, __va_list /*arg*/); +int vsprintf(char * /*s*/, const char * /*format*/, __va_list /*arg*/); /* * is equivalent to sprintf, with the variable argument list replaced by * arg, which has been initialised by the va_start macro (and possibly @@ -469,8 +463,7 @@ extern int vsprintf(char * /*s*/, const char * /*format*/, __va_list /*arg*/); * Returns: the number of characters written in the array, not counting the * terminating null character. */ -extern int vsscanf(const char * /*s*/, - const char * /*format*/, __va_list /*arg*/); +int vsscanf(const char * /*s*/, const char * /*format*/, __va_list /*arg*/); /* * is equivalent to sscanf, with the variable argument list replaced by arg, * which has been initialised by the va_start macro (and possibly subsequent @@ -481,7 +474,7 @@ extern int vsscanf(const char * /*s*/, * even zero, in the event of an early matching failure. */ -extern int fgetc(FILE * /*stream*/); +int fgetc(FILE * /*stream*/); /* * obtains the next character (if present) as an unsigned char converted to * an int, from the input stream pointed to by stream, and advances the @@ -491,7 +484,7 @@ extern int fgetc(FILE * /*stream*/); * set and fgetc returns EOF. If a read error occurs, the error * indicator is set and fgetc returns EOF. */ -extern char *fgets(char * /*s*/, int /*n*/, FILE * /*stream*/); +char *fgets(char * /*s*/, int /*n*/, FILE * /*stream*/); /* * reads at most one less than the number of characters specified by n from * the stream pointed to by stream into the array pointed to by s. No @@ -504,7 +497,7 @@ extern char *fgets(char * /*s*/, int /*n*/, FILE * /*stream*/); * during the operation, the array contents are indeterminate and a * null pointer is returned. */ -extern int fputc(int /*c*/, FILE * /*stream*/); +int fputc(int /*c*/, FILE * /*stream*/); /* * writes the character specified by c (converted to an unsigned char) to * the output stream pointed to by stream, at the position indicated by the @@ -514,14 +507,14 @@ extern int fputc(int /*c*/, FILE * /*stream*/); * Returns: the character written. If a write error occurs, the error * indicator is set and fputc returns EOF. */ -extern int fputs(const char * /*s*/, FILE * /*stream*/); +int fputs(const char * /*s*/, FILE * /*stream*/); /* * writes the string pointed to by s to the stream pointed to by stream. * The terminating null character is not written. * Returns: EOF if a write error occurs; otherwise it returns a nonnegative * value. */ -extern int __filbuf(FILE * /*stream*/); +int __filbuf(FILE * /*stream*/); /* * SYSTEM USE ONLY, called by getc to refill buffer and or sort out flags. * Returns: first character put into buffer or EOF on error. @@ -529,7 +522,7 @@ extern int __filbuf(FILE * /*stream*/); #define getc(p) \ (--((p)->__icnt) >= 0 ? *((p)->__ptr)++ : __filbuf(p)) #ifndef __cplusplus -extern int (getc)(FILE * /*stream*/); +int (getc)(FILE * /*stream*/); #endif /* * is equivalent to fgetc except that it may be (and is under @@ -543,7 +536,7 @@ extern int (getc)(FILE * /*stream*/); */ #define getchar() getc(stdin) #ifndef __cplusplus -extern int (getchar)(void); +int (getchar)(void); #endif /* * is equivalent to getc with the argument stdin. @@ -552,7 +545,7 @@ extern int (getchar)(void); * set and getchar returns EOF. If a read error occurs, the error * indicator is set and getchar returns EOF. */ -extern char *gets(char * /*s*/); +char *gets(char * /*s*/); /* * reads characters from the input stream pointed to by stdin into the array * pointed to by s, until end-of-file is encountered or a new-line character @@ -564,7 +557,7 @@ extern char *gets(char * /*s*/); * during the operation, the array contents are indeterminate and a * null pointer is returned. */ -extern int __flsbuf(int /*c*/, FILE * /*stream*/); +int __flsbuf(int /*c*/, FILE * /*stream*/); /* * SYSTEM USE ONLY, called by putc to flush buffer and or sort out flags. * Returns: character put into buffer or EOF on error. @@ -572,7 +565,7 @@ extern int __flsbuf(int /*c*/, FILE * /*stream*/); #define putc(ch, p) \ (--((p)->__ocnt) >= 0 ? (*((p)->__ptr)++ = (ch)) : __flsbuf(ch,p)) #ifndef __cplusplus -extern int (putc)(int /*c*/, FILE * /*stream*/); +int (putc)(int /*c*/, FILE * /*stream*/); #endif /* * is equivalent to fputc except that it may be (and is under @@ -584,14 +577,14 @@ extern int (putc)(int /*c*/, FILE * /*stream*/); */ #define putchar(ch) putc(ch, stdout) #ifndef __cplusplus -extern int (putchar)(int /*c*/); +int (putchar)(int /*c*/); #endif /* * is equivalent to putc with the second argument stdout. * Returns: the character written. If a write error occurs, the error * indicator is set and putc returns EOF. */ -extern int puts(const char * /*s*/); +int puts(const char * /*s*/); /* * writes the string pointed to by s to the stream pointed to by stdout, and * appends a new-line character to the output. The terminating null @@ -599,7 +592,7 @@ extern int puts(const char * /*s*/); * Returns: EOF if a write error occurs; otherwise it returns a nonnegative * value. */ -extern int ungetc(int /*c*/, FILE * /*stream*/); +int ungetc(int /*c*/, FILE * /*stream*/); /* * pushes the character specified by c (converted to an unsigned char) back * onto the input stream pointed to by stream. The character will be @@ -625,8 +618,8 @@ extern int ungetc(int /*c*/, FILE * /*stream*/); * operation fails. */ -extern size_t fread(void * /*ptr*/, - size_t /*size*/, size_t /*nmemb*/, FILE * /*stream*/); +size_t fread(void * /*ptr*/, + size_t /*size*/, size_t /*nmemb*/, FILE * /*stream*/); /* * reads into the array pointed to by ptr, up to nmemb members whose size is * specified by size, from the stream pointed to by stream. The file @@ -640,8 +633,8 @@ extern size_t fread(void * /*ptr*/, * nmemb is zero, fread returns zero and the contents of the array * and the state of the stream remain unchanged. */ -extern size_t fwrite(const void * /*ptr*/, - size_t /*size*/, size_t /*nmemb*/, FILE * /*stream*/); +size_t fwrite(const void * /*ptr*/, + size_t /*size*/, size_t /*nmemb*/, FILE * /*stream*/); /* * writes, from the array pointed to by ptr up to nmemb members whose size * is specified by size, to the stream pointed to by stream. The file @@ -652,7 +645,7 @@ extern size_t fwrite(const void * /*ptr*/, * than nmemb only if a write error is encountered. */ -extern int fgetpos(FILE * /*stream*/, fpos_t * /*pos*/); +int fgetpos(FILE * /*stream*/, fpos_t * /*pos*/); /* * stores the current value of the file position indicator for the stream * pointed to by stream in the object pointed to by pos. The value stored @@ -663,7 +656,7 @@ extern int fgetpos(FILE * /*stream*/, fpos_t * /*pos*/); * integer expression errno is set to an implementation-defined * nonzero value (under RISCOS/Arthur/Brazil fgetpos cannot fail). */ -extern int fseek(FILE * /*stream*/, long int /*offset*/, int /*whence*/); +int fseek(FILE * /*stream*/, long int /*offset*/, int /*whence*/); /* * sets the file position indicator for the stream pointed to by stream. * For a binary stream, the new position is at the signed number of @@ -680,7 +673,7 @@ extern int fseek(FILE * /*stream*/, long int /*offset*/, int /*whence*/); * the next operation on an update stream may be either input or output. * Returns: nonzero only for a request that cannot be satisfied. */ -extern int fsetpos(FILE * /*stream*/, const fpos_t * /*pos*/); +int fsetpos(FILE * /*stream*/, const fpos_t * /*pos*/); /* * sets the file position indicator for the stream pointed to by stream * according to the value of the object pointed to by pos, which shall be a @@ -694,7 +687,7 @@ extern int fsetpos(FILE * /*stream*/, const fpos_t * /*pos*/); * nonzero value (under RISCOS/Arthur/Brazil the value that of EDOM * in math.h). */ -extern long int ftell(FILE * /*stream*/); +long int ftell(FILE * /*stream*/); /* * obtains the current value of the file position indicator for the stream * pointed to by stream. For a binary stream, the value is the number of @@ -709,7 +702,7 @@ extern long int ftell(FILE * /*stream*/); * expression errno to an implementation-defined nonzero value * (under RISCOS/Arthur/Brazil ftell cannot fail). */ -extern void rewind(FILE * /*stream*/); +void rewind(FILE * /*stream*/); /* * sets the file position indicator for the stream pointed to by stream to * the beginning of the file. It is equivalent to @@ -718,7 +711,7 @@ extern void rewind(FILE * /*stream*/); * Returns: no value. */ -extern void clearerr(FILE * /*stream*/); +void clearerr(FILE * /*stream*/); /* * clears the end-of-file and error indicators for the stream pointed to by * stream. These indicators are cleared only when the file is opened or by @@ -728,7 +721,7 @@ extern void clearerr(FILE * /*stream*/); #define feof(stream) ((stream)->__flag & _IOEOF) #ifndef __cplusplus -extern int (feof)(FILE * /*stream*/); +int (feof)(FILE * /*stream*/); #endif /* * tests the end-of-file indicator for the stream pointed to by stream. @@ -736,13 +729,13 @@ extern int (feof)(FILE * /*stream*/); */ #define ferror(stream) ((stream)->__flag & _IOERR) #ifndef __cplusplus -extern int (ferror)(FILE * /*stream*/); +int (ferror)(FILE * /*stream*/); #endif /* * tests the error indicator for the stream pointed to by stream. * Returns: nonzero iff the error indicator is set for stream. */ -extern void perror(const char * /*s*/); +void perror(const char * /*s*/); /* * maps the error number in the integer expression errno to an error * message. It writes a sequence of characters to the standard error stream diff --git a/clib/h/stdlib b/clib/h/stdlib index 9d7948358ad3b38d4a837261541ecc4a25116119..2f96be2dd2189abc57e17aa584e674204b92ddfc 100644 --- a/clib/h/stdlib +++ b/clib/h/stdlib @@ -18,7 +18,7 @@ /* stdlib.h: ISO 'C' (9899:1999) library header, section 7.20 */ /* Copyright (C) Codemist Ltd. */ /* Copyright (C) Acorn Computers Ltd., 1990, 1992 */ -/* version 2.01 */ +/* version 2.03 */ /* * stdlib.h declares four types, several general purpose functions, @@ -91,19 +91,19 @@ typedef struct lldiv_t { long long int quot, rem; } lldiv_t; #ifdef __cplusplus extern "C" { #endif -extern double atof(const char * /*nptr*/); +double atof(const char * /*nptr*/); /* * converts the initial part of the string pointed to by nptr to double * representation. * Returns: the converted value. */ -extern int atoi(const char * /*nptr*/); +int atoi(const char * /*nptr*/); /* * converts the initial part of the string pointed to by nptr to int * representation. * Returns: the converted value. */ -extern long int atol(const char * /*nptr*/); +long int atol(const char * /*nptr*/); /* * converts the initial part of the string pointed to by nptr to long int * representation. @@ -111,7 +111,7 @@ extern long int atol(const char * /*nptr*/); */ #ifdef __STDC_VERSION__ #if __STDC_VERSION__ >= 199901 -extern long long int atoll(const char * /*nptr*/); +long long int atoll(const char * /*nptr*/); /* * converts the initial part of the string pointed to by nptr to long long * int representation. @@ -120,7 +120,7 @@ extern long long int atoll(const char * /*nptr*/); #endif #endif -extern double strtod(const char * /*nptr*/, char ** /*endptr*/); +double strtod(const char * /*nptr*/, char ** /*endptr*/); /* * converts the initial part of the string pointed to by nptr to double * representation. First it decomposes the input string into three parts: @@ -140,7 +140,7 @@ extern double strtod(const char * /*nptr*/, char ** /*endptr*/); * underflow, zero is returned and the value of the macro ERANGE is * stored in errno. */ -extern long int strtol(const char * /*nptr*/, char **/*endptr*/, int /*base*/); +long int strtol(const char * /*nptr*/, char **/*endptr*/, int /*base*/); /* * converts the initial part of the string pointed to by nptr to long int * representation. First it decomposes the input string into three parts: @@ -169,8 +169,8 @@ extern long int strtol(const char * /*nptr*/, char **/*endptr*/, int /*base*/); * (according to the sign of the value), and the value of the * macro ERANGE is stored in errno. */ -extern unsigned long int strtoul(const char * /*nptr*/, - char ** /*endptr*/, int /*base*/); +unsigned long int strtoul(const char * /*nptr*/, + char ** /*endptr*/, int /*base*/); /* * converts the initial part of the string pointed to by nptr to unsigned * long int representation. First it decomposes the input string into three @@ -200,8 +200,8 @@ extern unsigned long int strtoul(const char * /*nptr*/, */ #ifdef __STDC_VERSION__ #if __STDC_VERSION__ >= 199901 -extern long long int strtoll(const char * restrict /*nptr*/, - char ** restrict /*endptr*/, int /*base*/); +long long int strtoll(const char * restrict /*nptr*/, + char ** restrict /*endptr*/, int /*base*/); /* * converts the initial part of the string pointed to by nptr to long long * int representation. First it decomposes the input string into three parts: @@ -230,9 +230,9 @@ extern long long int strtoll(const char * restrict /*nptr*/, * (according to the sign of the value), and the value of the * macro ERANGE is stored in errno. */ -extern unsigned long long int strtoull(const char * restrict /*nptr*/, - char ** restrict /*endptr*/, - int /*base*/); +unsigned long long int strtoull(const char * restrict /*nptr*/, + char ** restrict /*endptr*/, + int /*base*/); /* * converts the initial part of the string pointed to by nptr to unsigned * long long int representation. First it decomposes the input string into @@ -263,7 +263,7 @@ extern unsigned long long int strtoull(const char * restrict /*nptr*/, #endif #endif -extern int rand(void); +int rand(void); /* * Computes a sequence of pseudo-random integers in the range 0 to RAND_MAX. * Uses an additive generator (Mitchell & Moore) of the form: @@ -273,7 +273,7 @@ extern int rand(void); * conjectured to be good. Empirical testing since 1958 has shown no flaws. * Returns: a pseudo-random integer. */ -extern void srand(unsigned int /*seed*/); +void srand(unsigned int /*seed*/); /* * uses its argument as a seed for a new sequence of pseudo-random numbers * to be returned by subsequent calls to rand. If srand is then called with @@ -282,7 +282,7 @@ extern void srand(unsigned int /*seed*/); * sequence is generated as when srand is first called with a seed value * of 1. */ -extern int _ANSI_rand(void); +int _ANSI_rand(void); /* * The ANSI-defined 16-bit random number generator which computes * a sequence of pseudo-random integers in the range 0 to _ANSI_RAND_MAX. @@ -290,7 +290,7 @@ extern int _ANSI_rand(void); * *** NOT AVAILABLE IN THE SHARED C LIBRARY *** * Returns: a pseudo-random integer. */ -extern void _ANSI_srand(unsigned int /*seed*/); +void _ANSI_srand(unsigned int /*seed*/); /* * Uses its argument as a seed for a new sequence of pseudo-random numbers * to be returned by subsequent calls to _ANSI_rand. If _ANSI_srand is then @@ -307,19 +307,19 @@ extern void _ANSI_srand(unsigned int /*seed*/); typedef char *malloc_t; -extern char *calloc(size_t /*nmemb*/, size_t /*size*/); -extern void free(void * /*ptr*/); -extern char *malloc(size_t /*size*/); -extern char *realloc(void * /*ptr*/, size_t /*size*/); +char *calloc(size_t /*nmemb*/, size_t /*size*/); +void free(void * /*ptr*/); +char *malloc(size_t /*size*/); +char *realloc(void * /*ptr*/, size_t /*size*/); #endif #else -extern void *calloc(size_t /*nmemb*/, size_t /*size*/); +void *calloc(size_t /*nmemb*/, size_t /*size*/); /* * allocates space for an array of nmemb objects, each of whose size is * 'size'. The space is initialised to all bits zero. * Returns: either a null pointer or a pointer to the allocated space. */ -extern void free(void * /*ptr*/); +void free(void * /*ptr*/); /* * causes the space pointed to by ptr to be deallocated (i.e., made * available for further allocation). If ptr is a null pointer, no action @@ -327,13 +327,13 @@ extern void free(void * /*ptr*/); * calloc, malloc or realloc or if the space has been deallocated by a call * to free or realloc, the behaviour is undefined. */ -extern void *malloc(size_t /*size*/); +void *malloc(size_t /*size*/); /* * allocates space for an object whose size is specified by 'size' and whose * value is indeterminate. * Returns: either a null pointer or a pointer to the allocated space. */ -extern void *realloc(void * /*ptr*/, size_t /*size*/); +void *realloc(void * /*ptr*/, size_t /*size*/); /* * changes the size of the object pointed to by ptr to the size specified by * size. The contents of the object shall be unchanged up to the lesser of @@ -351,17 +351,17 @@ extern void *realloc(void * /*ptr*/, size_t /*size*/); */ #endif -extern void abort(void); +void abort(void); /* * causes abnormal program termination to occur, unless the signal SIGABRT * is being caught and the signal handler does not return. Whether open * output streams are flushed or open streams are closed or temporary files - * removed is implementation-defined (under Arthur/Brazil all these occur). + * removed is implementation-defined (under RISC OS all these occur). * An implementation-defined form of the status 'unsuccessful termination' - * (1 under Arthur/Brazil) is returned to the host environment by means - * of a call to raise(SIGABRT). + * (1 under RISC OS) is returned to the host environment by means of a call + * to raise(SIGABRT). */ -extern int atexit(void (* /*func*/)(void)); +int atexit(void (* /*func*/)(void)); /* * registers the function pointed to by func, to be called without its * arguments at normal program termination. It is possible to register at @@ -369,7 +369,7 @@ extern int atexit(void (* /*func*/)(void)); * Returns: zero if the registration succeeds, nonzero if it fails. */ -extern void exit(int status); +void exit(int /*status*/); /* * causes normal program termination to occur. If more than one call to the * exit function is executed by a program, the behaviour is undefined. @@ -379,14 +379,26 @@ extern void exit(int status); * and all files created by the tmpfile function are removed. * Finally, control is returned to the host environment. If the value of * status is zero or EXIT_SUCCESS, an implementation-defined form of the - * status 'successful termination' (0 under Arthur/Brazil) is returned. If - * the value of status is EXIT_FAILURE, an implementation-defined form of - * the status 'unsuccessful termination' (1 under Arthur/Brazil) is - * returned. Otherwise the status returned is implementation-defined (the - * value of status is returned under Arthur/Brazil). + * status 'successful termination' (0 under RISC OS) is returned. If the + * value of status is EXIT_FAILURE, an implementation-defined form of the + * status 'unsuccessful termination' (1 under RISC OS) is returned. + * Otherwise the status returned is implementation-defined (the value of + * status is returned under RISC OS). */ -extern char *getenv(const char * /*name*/); +void _Exit(int /*status*/); + /* + * causes normal program termination to occur and control to be returned to + * the host environment. No functions registered by the atexit function or + * signal handlers registered by the signal function are called. + * The status returned to the host environment is determined in the same + * way as for the exit function. + * Whether open streams with unwritten buffered data are flushed, open + * streams are closed or temporary files are removed is implementation- + * defined (under RISC OS all these occur). + */ + +char *getenv(const char * /*name*/); /* * searches the environment list, provided by the host environment, for a * string that matches the string pointed to by name. The set of environment @@ -398,14 +410,14 @@ extern char *getenv(const char * /*name*/); * If the specified name cannot be found, a null pointer is * returned. */ -extern int system(const char * /*string*/); +int system(const char * /*string*/); /* * passes the string pointed to by string to the host environment to be * executed by a command processor in an implementation-defined manner. * A null pointer may be used for string, to inquire whether a command * processor exists. * - * Under Arthur/Brazil care must be taken when executing a command, that the + * Under RISC OS care must be taken when executing a command, that the * command does not overwrite the calling program. The string 'chain:' or * 'call:' may immediately precede the actual command. The effect of 'call:' * is the same as if 'call:' were not present, which is to attempt to return @@ -415,12 +427,12 @@ extern int system(const char * /*string*/); * Returns: If the argument is a null pointer, the system function returns * non-zero only if a command processor is available. If the * argument is not a null pointer, the system function returns an - * implementation-defined value (under Arthur/Brazil 0 is returned + * implementation-defined value (under RISC OS 0 is returned * for success, -2 for failure to invoke the command and any other * value is the return code from the executed command). */ -extern void *bsearch(const void * /*key*/, const void * /*base*/, +void *bsearch(const void * /*key*/, const void * /*base*/, size_t /*nmemb*/, size_t /*size*/, int (* /*compar*/)(const void *, const void *)); /* @@ -437,7 +449,7 @@ extern void *bsearch(const void * /*key*/, const void * /*base*/, * if no match is found. If two members compare as equal, which * member is matched is unspecified. */ -extern void qsort(void * /*base*/, size_t /*nmemb*/, size_t /*size*/, +void qsort(void * /*base*/, size_t /*nmemb*/, size_t /*size*/, int (* /*compar*/)(const void *, const void *)); /* * sorts an array of nmemb objects, the initial member of which is pointed @@ -451,25 +463,25 @@ extern void qsort(void * /*base*/, size_t /*nmemb*/, size_t /*size*/, * sorted array is unspecified. */ -extern int abs(int /*j*/); +int abs(int /*j*/); /* * computes the absolute value of an integer j. If the result cannot be * represented, the behaviour is undefined. * Returns: the absolute value. */ -extern div_t div(int /*numer*/, int /*denom*/); +div_t div(int /*numer*/, int /*denom*/); /* * computes numer / denom and numer % denom in a single operation. * Returns: a structure of type div_t, comprising both the quotient and the * remainder. */ -extern long int labs(long int /*j*/); +long int labs(long int /*j*/); /* * computes the absolute value of an integer j. If the result cannot be * represented, the behaviour is undefined. * Returns: the absolute value. */ -extern ldiv_t ldiv(long int /*numer*/, long int /*denom*/); +ldiv_t ldiv(long int /*numer*/, long int /*denom*/); /* * computes numer / denom and numer % denom in a single operation. * Returns: a structure of type ldiv_t, comprising both the quotient and the @@ -477,13 +489,13 @@ extern ldiv_t ldiv(long int /*numer*/, long int /*denom*/); */ #ifdef __STDC_VERSION__ #if __STDC_VERSION__ >= 199901 -extern long long int llabs(long long int /*j*/); +long long int llabs(long long int /*j*/); /* * computes the absolute value of an integer j. If the result cannot be * represented, the behaviour is undefined. * Returns: the absolute value. */ -extern lldiv_t lldiv(long long int /*numer*/, long long int /*denom*/); +lldiv_t lldiv(long long int /*numer*/, long long int /*denom*/); /* * computes numer / denom and numer % denom in a single operation. * Returns: a structure of type lldiv_t, comprising both the quotient and the @@ -492,6 +504,12 @@ extern lldiv_t lldiv(long long int /*numer*/, long long int /*denom*/); #endif #endif +#ifndef __cplusplus +/* the sizeof expression performs the necessary type-checking */ +#define abs(j) ((void) sizeof abs(j), __abs (int) (j)) +#define labs(j) ((void) sizeof labs(j), __abs (long int) (j)) +#endif + /* * Multibyte Character Functions. * The behaviour of the multibyte character functions is affected by the @@ -504,7 +522,7 @@ extern lldiv_t lldiv(long long int /*numer*/, long long int /*denom*/); * otherwise. After the LC_CTYPE category is changed, the shift state of these * functions is indeterminate. */ -extern int mblen(const char * /*s*/, size_t /*n*/); +int mblen(const char * /*s*/, size_t /*n*/); /* * If s is not a null pointer, the mblen function determines the number of * bytes compromising the multibyte character pointed to by s. Except that @@ -519,7 +537,7 @@ extern int mblen(const char * /*s*/, size_t /*n*/); * valid multibyte character), or returns -1 (they do not form a * valid multibyte character). */ -extern int mbtowc(wchar_t * /*pwc*/, const char * /*s*/, size_t /*n*/); +int mbtowc(wchar_t * /*pwc*/, const char * /*s*/, size_t /*n*/); /* * If s is not a null pointer, the mbtowc function determines the number of * bytes that compromise the multibyte character pointed to by s. It then @@ -537,7 +555,7 @@ extern int mbtowc(wchar_t * /*pwc*/, const char * /*s*/, size_t /*n*/); * fewer bytes form a valid multibyte character), or returns -1 * (they do not form a valid multibyte character). */ -extern int wctomb(char * /*s*/, wchar_t /*wchar*/); +int wctomb(char * /*s*/, wchar_t /*wchar*/); /* * determines the number of bytes need to represent the multibyte character * corresponding to the code whose value is wchar (including any change in @@ -559,7 +577,7 @@ extern int wctomb(char * /*s*/, wchar_t /*wchar*/); * The behaviour of the multibyte string functions is affected by the LC_CTYPE * category of the current locale. */ -extern size_t mbstowcs(wchar_t * /*pwcs*/, const char * /*s*/, size_t /*n*/); +size_t mbstowcs(wchar_t * /*pwcs*/, const char * /*s*/, size_t /*n*/); /* * converts a sequence of multibyte character that begins in the initial * shift state from the array pointed to by s into a sequence of @@ -576,7 +594,7 @@ extern size_t mbstowcs(wchar_t * /*pwcs*/, const char * /*s*/, size_t /*n*/); * returns the number of array elements modified, not including * a terminating zero code, if any. */ -extern size_t wcstombs(char * /*s*/, const wchar_t * /*pwcs*/, size_t /*n*/); +size_t wcstombs(char * /*s*/, const wchar_t * /*pwcs*/, size_t /*n*/); /* * converts a sequence of codes that correspond to multibyte characters * from the array pointed to by pwcs into a sequence of multibyte diff --git a/clib/h/string b/clib/h/string index 0826b382d0f7d94c3f15b0d025fa6f02f3cabffc..27a25678f5385121579e241d63791a4d74a0fff5 100644 --- a/clib/h/string +++ b/clib/h/string @@ -15,7 +15,7 @@ #pragma force_top_level #pragma include_only_once -/* string.h: ANSI 'C' (X3J11 Oct 88) library header, section 4.11 */ +/* string.h: ISO 'C' (9899:1999) library header, section 7.21 */ /* Copyright (C) Codemist Ltd. */ /* Copyright (C) Acorn Computers Ltd. 1991, 1992 */ /* version 2.00 */ @@ -44,14 +44,14 @@ typedef unsigned int size_t; /* from <stddef.h> */ #ifdef __cplusplus extern "C" { #endif -extern char *strcpy(char * /*s1*/, const char * /*s2*/); +char *strcpy(char * /*s1*/, const char * /*s2*/); /* * copies the string pointed to by s2 (including the terminating nul * character) into the array pointed to by s1. If copying takes place * between objects that overlap, the behaviour is undefined. * Returns: the value of s1. */ -extern char *strncpy(char * /*s1*/, const char * /*s2*/, size_t /*n*/); +char *strncpy(char * /*s1*/, const char * /*s2*/, size_t /*n*/); /* * copies not more than n characters (characters that follow a null * character are not copied) from the array pointed to by s2 into the array @@ -60,14 +60,14 @@ extern char *strncpy(char * /*s1*/, const char * /*s2*/, size_t /*n*/); * Returns: the value of s1. */ -extern char *strcat(char * /*s1*/, const char * /*s2*/); +char *strcat(char * /*s1*/, const char * /*s2*/); /* * appends a copy of the string pointed to by s2 (including the terminating * null character) to the end of the string pointed to by s1. The initial * character of s2 overwrites the null character at the end of s1. * Returns: the value of s1. */ -extern char *strncat(char * /*s1*/, const char * /*s2*/, size_t /*n*/); +char *strncat(char * /*s1*/, const char * /*s2*/, size_t /*n*/); /* * appends not more than n characters (a null character and characters that * follow it are not appended) from the array pointed to by s2 to the end of @@ -84,7 +84,7 @@ extern char *strncat(char * /*s1*/, const char * /*s2*/, size_t /*n*/); * objects being compared. */ -extern int memcmp(const void * /*s1*/, const void * /*s2*/, size_t /*n*/); +int memcmp(const void * /*s1*/, const void * /*s2*/, size_t /*n*/); /* * compares the first n characters of the object pointed to by s1 to the * first n characters of the object pointed to by s2. @@ -92,14 +92,14 @@ extern int memcmp(const void * /*s1*/, const void * /*s2*/, size_t /*n*/); * as the object pointed to by s1 is greater than, equal to, or * less than the object pointed to by s2. */ -extern int strcmp(const char * /*s1*/, const char * /*s2*/); +int strcmp(const char * /*s1*/, const char * /*s2*/); /* * compares the string pointed to by s1 to the string pointed to by s2. * Returns: an integer greater than, equal to, or less than zero, according * as the string pointed to by s1 is greater than, equal to, or * less than the string pointed to by s2. */ -extern int strncmp(const char * /*s1*/, const char * /*s2*/, size_t /*n*/); +int strncmp(const char * /*s1*/, const char * /*s2*/, size_t /*n*/); /* * compares not more than n characters (characters that follow a null * character are not compared) from the array pointed to by s1 to the array @@ -108,7 +108,7 @@ extern int strncmp(const char * /*s1*/, const char * /*s2*/, size_t /*n*/); * as the string pointed to by s1 is greater than, equal to, or * less than the string pointed to by s2. */ -extern int strcoll(const char * /*s1*/, const char * /*s2*/); +int strcoll(const char * /*s1*/, const char * /*s2*/); /* * compares the string pointed to by s1 to the string pointed to by s2, both * interpreted as appropriate to the LC_COLLATE category of the current @@ -119,7 +119,7 @@ extern int strcoll(const char * /*s1*/, const char * /*s2*/); * as appropriate to the current locale. */ -extern size_t strxfrm(char * /*s1*/, const char * /*s2*/, size_t /*n*/); +size_t strxfrm(char * /*s1*/, const char * /*s2*/, size_t /*n*/); /* * transforms the string pointed to by s2 and places the resulting string * into the array pointed to by s1. The transformation function is such that @@ -136,28 +136,28 @@ extern size_t strxfrm(char * /*s1*/, const char * /*s2*/, size_t /*n*/); * indeterminate. */ -extern char *strchr(const char * /*s*/, int /*c*/); +char *strchr(const char * /*s*/, int /*c*/); /* * locates the first occurence of c (converted to an char) in the string * pointed to by s (including the terminating null character). * Returns: a pointer to the located character, or a null pointer if the * character does not occur in the string. */ -extern size_t strcspn(const char * /*s1*/, const char * /*s2*/); +size_t strcspn(const char * /*s1*/, const char * /*s2*/); /* * computes the length of the initial segment of the string pointed to by s1 * which consists entirely of characters not from the string pointed to by * s2. The terminating null character is not considered part of s2. * Returns: the length of the segment. */ -extern char *strpbrk(const char * /*s1*/, const char * /*s2*/); +char *strpbrk(const char * /*s1*/, const char * /*s2*/); /* * locates the first occurence in the string pointed to by s1 of any * character from the string pointed to by s2. * Returns: returns a pointer to the character, or a null pointer if no * character form s2 occurs in s1. */ -extern char *strrchr(const char * /*s*/, int /*c*/); +char *strrchr(const char * /*s*/, int /*c*/); /* * locates the last occurence of c (converted to a char) in the string * pointed to by s. The terminating null character is considered part of @@ -165,13 +165,13 @@ extern char *strrchr(const char * /*s*/, int /*c*/); * Returns: returns a pointer to the character, or a null pointer if c does * not occur in the string. */ -extern size_t strspn(const char * /*s1*/, const char * /*s2*/); +size_t strspn(const char * /*s1*/, const char * /*s2*/); /* * computes the length of the initial segment of the string pointed to by s1 * which consists entirely of characters from the string pointed to by S2 * Returns: the length of the segment. */ -extern char *strstr(const char * /*s1*/, const char * /*s2*/); +char *strstr(const char * /*s1*/, const char * /*s2*/); /* * locates the first occurence in the string pointed to by s1 of the * sequence of characters (excluding the terminating null character) in the @@ -179,7 +179,7 @@ extern char *strstr(const char * /*s1*/, const char * /*s2*/); * Returns: a pointer to the located string, or a null pointer if the string * is not found. */ -extern char *strtok(char * /*s1*/, const char * /*s2*/); +char *strtok(char * /*s1*/, const char * /*s2*/); /* * A sequence of calls to the strtok function breaks the string pointed to * by s1 into a sequence of tokens, each of which is delimited by a @@ -206,14 +206,14 @@ extern char *strtok(char * /*s1*/, const char * /*s2*/); * there is no token. */ -extern void *memcpy(void * /*s1*/, const void * /*s2*/, size_t /*n*/); +void *memcpy(void * /*s1*/, const void * /*s2*/, size_t /*n*/); /* * copies n characters from the object pointed to by s2 into the object * pointed to by s1. If copying takes place between objects that overlap, * the behaviour is undefined. * Returns: the value of s1. */ -extern void *memmove(void * /*s1*/, const void * /*s2*/, size_t /*n*/); +void *memmove(void * /*s1*/, const void * /*s2*/, size_t /*n*/); /* * copies n characters from the object pointed to by s2 into the object * pointed to by s1. Copying takes place as if the n characters from the @@ -223,7 +223,7 @@ extern void *memmove(void * /*s1*/, const void * /*s2*/, size_t /*n*/); * object pointed to by s1. * Returns: the value of s1. */ -extern void *memchr(const void * /*s*/, int /*c*/, size_t /*n*/); +void *memchr(const void * /*s*/, int /*c*/, size_t /*n*/); /* * locates the first occurence of c (converted to an unsigned char) in the * initial n characters (each interpreted as unsigned char) of the object @@ -231,14 +231,14 @@ extern void *memchr(const void * /*s*/, int /*c*/, size_t /*n*/); * Returns: a pointer to the located character, or a null pointer if the * character does not occur in the object. */ -extern void *memset(void * /*s*/, int /*c*/, size_t /*n*/); +void *memset(void * /*s*/, int /*c*/, size_t /*n*/); /* * copies the value of c (converted to an unsigned char) into each of the * first n charactes of the object pointed to by s. * Returns: the value of s. */ -extern char *strerror(int /*errnum*/); +char *strerror(int /*errnum*/); /* * maps the error number in errnum to an error message string. * Returns: a pointer to the string, the contents of which are @@ -253,7 +253,7 @@ extern char *strerror(int /*errnum*/); * modified by the program, but may be overwritten by a subsequent * call to the strerror function. */ -extern size_t strlen(const char * /*s*/); +size_t strlen(const char * /*s*/); /* * computes the length of the string pointed to by s. * Returns: the number of characters that precede the terminating null diff --git a/clib/h/tgmath b/clib/h/tgmath new file mode 100644 index 0000000000000000000000000000000000000000..f0ae59022a4fd951ef1f687c6c5d234908e4bdf7 --- /dev/null +++ b/clib/h/tgmath @@ -0,0 +1,175 @@ +/* Copyright 2003 Tematic Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma force_top_level +#pragma include_only_once + +/* tgmath.h: ISO 'C' (9899:1999) library header, section 7.22 */ +/* Copyright (C) Acorn Computers Ltd. 2002 */ +/* version 1.00 */ + +/* + * tgmath.h includes the headers <math.h> and <complex.h> and defines + * several type-generic macros. + */ +#ifndef __tgmath_h +#define __tgmath_h + +#include <math.h> + +#define _TG(o, ...) (___select(0, o##f, o, o##l, __VA_ARGS__))(__VA_ARGS__) +#define _TG1(o, x,...) (___select(0, o##f, o, o##l, x))(x,__VA_ARGS__) +#define _TG2(o, x,y,...) (___select(0, o##f, o, o##l, x,y))(x,y,__VA_ARGS__) + +#define _TGx(f,d,l, ...) (___select(0, f, d, l, __VA_ARGS__))(__VA_ARGS__) + +/* Type-generic macros for functions with both real and complex forms */ +#undef acos +#undef asin +#undef atan +#undef acosh +#undef asinh +#undef atanh +#undef cos +#undef sin +#undef tan +#undef cosh +#undef sinh +#undef tanh +#undef exp +#undef log +#undef pow +#undef sqrt +#undef fabs + +#define acos(x) _TG(acos, x) +#define asin(x) _TG(asin, x) +#define atan(x) _TG(atan, x) +#define acosh(x) _TG(acosh, x) +#define asinh(x) _TG(asinh, x) +#define atanh(x) _TG(atanh, x) +#define cos(x) _TG(cos, x) +#define sin(x) _TG(sin, x) +#define tan(x) _TG(tan, x) +#define cosh(x) _TG(cosh, x) +#define sinh(x) _TG(sinh, x) +#define tanh(x) _TG(tanh, x) +#define exp(x) _TG(exp, x) +#define log(x) _TG(log, x) +#define pow(x) _TG(pow, x) +#define sqrt(x) _TG(sqrt, x) +#define fabs(x) _TG(fabs, x) + +/* Type-generic macros for real-only functions */ +#undef atan2 +#undef cbrt +#undef ceil +#undef copysign +#undef erf +#undef erfc +#undef expm1 +#undef fdim +#undef floor +#undef fma +#undef fmax +#undef fmin +#undef fmod +#undef frexp +#undef hypot +#undef ilogb +#undef ldexp +#undef lgamma +#undef llrint +#undef llround +#undef log10 +#undef log1p +#undef log2 +#undef logb +#undef lrint +#undef lround +#undef nearbyint +#undef nextafter +#undef nexttoward +#undef remainder +#undef remquo +#undef rint +#undef round +#undef scalbn +#undef scalbln +#undef tgamma +#undef trunc + +#define atan2(y,x) _TG(atan2, y,x) +#define cbrt(x) _TG(cbrt, x) +#define ceil(x) _TG(ceil, x) +#define copysign(x,y) _TG(copysign, x,y) +#define erf(x) _TG(erf, x) +#define erfc(x) _TG(erfc, x) +#define expm1(x) _TG(expm1, x) +#define fdim(x,y) _TG(fdim, x,y) +#define floor(x) _TG(floor, x) +#define fma(x,y,z) _TG(fma, x,y,z) +#define fmax(x,y) _TG(fmax, x,y) +#define fmin(x,y) _TG(fmin, x,y) +#define fmod(x,y) _TG(fmod, x,y) +#define frexp(v,e) _TG1(frexp, v,e) +#define hypot(x,y) _TG(hypot, x,y) +#define ilogb(x) _TG(ilogb, x) +#define ldexp(x,e) _TG1(ldexp, x,e) +#define lgamma(x) _TG(lgamma, x) +#define llrint(x) _TG(llrint, x) +#define llround(x) _TG(llround, x) +#define log10(x) _TG(log10, x) +#define log1p(x) _TG(log1p, x) +#define log2(x) _TG(log2, x) +#define logb(x) _TG(logb, x) +#define lrint(x) _TG(lrint, x) +#define lround(x) _TG(lround, x) +#define nearbyint(x) _TG(nearbyint, x) +#define nextafter(x,y) _TG(nextafter, x,y) +#define nexttoward(x,y) _TG1(nexttoward, x,y) +#define remainder(x,y) _TG(remainder, x,y) +#define remquo(x,y,q) _TG2(remquo, x,y,q) +#define rint(x) _TG(rint, x) +#define round(x) _TG(round, x) +#define scalbn(x,n) _TG1(scalbn, x,n) +#define scalbln(x,n) _TG1(scalbln, x,n) +#define tgamma(x) _TG(tgamma, x) +#define trunc(x) _TG(trunc, x) + +/* Ensure inlining still happens, unless requested otherwise */ +#ifndef __TGMATH_NO_INLINING +#undef atan +#undef cos +#undef sin +#undef fabs +#undef floor +#undef ceil +#undef trunc +#undef rint +#undef lrint +#define atan(x) _TGx(__r_atan, __d_atan, atanl, x) +#define cos(x) _TGx(__r_cos, __d_cos, cosl, x) +#define sin(x) _TGx(__r_sin, __d_sin, sinl, x) +#define fabs(x) (___select(0, __abs (x), __abs (double) (x), __abs (x), x)) +#define floor(x) _TGx(__r_floor, __d_floor, floorl, x) +#define ceil(x) _TGx(__r_ceil, __d_ceil, ceill, x) +#define trunc(x) _TGx(__r_trunc, __d_trunc, truncl, x) +#define rint(x) _TGx(__r_rint, __d_rint, rintl, x) +#define lrint(x) _TGx(__r_lrint, __d_lrint, lrintl, x) +#endif + +#endif + +/* end of tgmath.h */ diff --git a/clib/h/time b/clib/h/time index ee770e0a2492c457295ca5bc4875d4fc36cab03b..4dbbcd898d90df8839c99884f997d0df612fc6d3 100644 --- a/clib/h/time +++ b/clib/h/time @@ -74,7 +74,7 @@ struct tm { #ifdef __cplusplus extern "C" { #endif -extern clock_t clock(void); +clock_t clock(void); /* determines the processor time used. * Returns: the implementation's best approximation to the processor time * used by the program since program invocation. The time in @@ -82,12 +82,12 @@ extern clock_t clock(void); * CLK_TCK. The value (clock_t)-1 is returned if the processor time * used is not available. */ -extern double difftime(time_t /*time1*/, time_t /*time0*/); +double difftime(time_t /*time1*/, time_t /*time0*/); /* * computes the difference between two calendar times: time1 - time0. * Returns: the difference expressed in seconds as a double. */ -extern time_t mktime(struct tm * /*timeptr*/); +time_t mktime(struct tm * /*timeptr*/); /* * converts the broken-down time, expressed as local time, in the structure * pointed to by timeptr into a calendar time value with the same encoding @@ -103,7 +103,7 @@ extern time_t mktime(struct tm * /*timeptr*/); * If the calendar time cannot be represented, the function returns * the value (time_t)-1. */ -extern time_t time(time_t * /*timer*/); +time_t time(time_t * /*timer*/); /* * determines the current calendar time. The encoding of the value is * unspecified. @@ -113,33 +113,33 @@ extern time_t time(time_t * /*timer*/); * is also assigned to the object it points to. */ -extern char *asctime(const struct tm * /*timeptr*/); +char *asctime(const struct tm * /*timeptr*/); /* * converts the broken-down time in the structure pointed to by timeptr into * a string in the form Sun Sep 16 01:03:52 1973\n\0. * Returns: a pointer to the string containing the date and time. */ -extern char *ctime(const time_t * /*timer*/); +char *ctime(const time_t * /*timer*/); /* * converts the calendar time pointed to by timer to local time in the form * of a string. It is equivalent to asctime(localtime(timer)); * Returns: the pointer returned by the asctime function with that * broken-down time as argument. */ -extern struct tm *gmtime(const time_t * /*timer*/); +struct tm *gmtime(const time_t * /*timer*/); /* * converts the calendar time pointed to by timer into a broken-down time, * expressed as Greenwich Mean Time (GMT). * Returns: a pointer to that object or a null pointer if GMT not available. */ -extern struct tm *localtime(const time_t * /*timer*/); +struct tm *localtime(const time_t * /*timer*/); /* * converts the calendar time pointed to by timer into a broken-down time, * expressed a local time. * Returns: a pointer to that object. */ -extern size_t strftime(char * /*s*/, size_t /*maxsize*/, - const char * /*format*/, const struct tm * /*timeptr*/); +size_t strftime(char * /*s*/, size_t /*maxsize*/, + const char * /*format*/, const struct tm * /*timeptr*/); /* * places characters into the array pointed to by s as controlled by the * string pointed to by format. The format string consists of zero or more diff --git a/clib/s/cl_body b/clib/s/cl_body index 24dfdb08b2cb801d5e7d42c5f2ef680b3c23b734..00bc5ecb400f43893f07bf66ff5227bc1f1b9474 100644 --- a/clib/s/cl_body +++ b/clib/s/cl_body @@ -57,6 +57,12 @@ $Label MOV r1, #0 WFS r1 MEND + MACRO +$Label CheckFPInterrupts $nocheck + ; Sets r1 to the current fp flags. + RFS r1 + MEND + MACRO $Label ReEnableFPInterrupts $nocheck ; Reinstates the exception mask state which prevailed before the call @@ -152,6 +158,8 @@ $Label EXPORT copysignf EXPORT nextafter EXPORT nextafterf + EXPORT nexttoward + EXPORT nexttowardf EXPORT |__rt_stkovf_split_small| EXPORT |__rt_stkovf_split_big| @@ -175,6 +183,8 @@ $Label EXPORT fmax EXPORT fmaxf + EXPORT fmaf + EXPORT nearbyint EXPORT nearbyintf EXPORT round @@ -184,14 +194,31 @@ $Label EXPORT remainder EXPORT remainderf EXPORT exp + EXPORT expf + EXPORT expm1 + EXPORT expm1f + EXPORT exp2 + EXPORT exp2f EXPORT log10 + EXPORT log10f EXPORT log + EXPORT logf + EXPORT log1p + EXPORT log1pf + EXPORT log2 + EXPORT log2f EXPORT sqrt EXPORT sqrtf + EXPORT cbrt + EXPORT cbrtf EXPORT tan + EXPORT tanf EXPORT asin + EXPORT asinf EXPORT acos + EXPORT acosf EXPORT pow + EXPORT powf EXPORT hypot EXPORT hypotf @@ -852,6 +879,7 @@ chunks_deallocated |_osbyte| B |_kernel_osbyte| + LTORG ; double _ldfp(void *x) converts packed decimal at x to a double @@ -951,6 +979,8 @@ copysignf ; Back to normal calling conventions +nexttoward + NOP nextafter [ :LNOT:FloatingPointArgsInRegs STMFD sp!, {r0-r3} @@ -1166,7 +1196,6 @@ fminf Return ,LinkNotStacked,VC B fcmpnan - [ {FALSE} fmaf [ :LNOT:FloatingPointArgsInRegs STMFD sp!, {r0-r3} @@ -1180,7 +1209,6 @@ fmaf MUFE f0, f0, f1 ; totally accurate result ADFS f0, f0, f2 Return ,LinkNotStacked - ] nearbyint [ :LNOT:FloatingPointArgsInRegs @@ -1292,7 +1320,9 @@ exp | DisableFPInterrupts ] +exp_common EXPD f0, f0 +exp_exit ReEnableFPInterrupts TST r1, #&0F Return ,LinkNotStacked, EQ @@ -1300,6 +1330,52 @@ exp BNE underflow_error B huge_error +expf + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + DisableFPInterrupts + LDFD f0, [sp], #8 + | + DisableFPInterrupts + ] + MVFS f0, f0 +expf_common + EXPS f0, f0 +expf_exit + ReEnableFPInterrupts + TST r1, #&0F + Return ,LinkNotStacked, EQ + TST r1, #8 + BNE underflow_error + B huge_errorf + +; Mickey-mouse implementations, but they are still better than the user +; doing it, because of intermediate extended precision. +expm1 + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + DisableFPInterrupts + LDFD f0, [sp], #8 + | + DisableFPInterrupts + ] + EXPE f0, f0 + SUFD f0, f0, #1 + B exp_exit + +expm1f + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + DisableFPInterrupts + LDFD f0, [sp], #8 + | + DisableFPInterrupts + ] + MVFS f0, f0 + EXPE f0, f0 + SUFS f0, f0, #1 + B expf_exit + ldfp_overflow LDR r0, [r0, #0] CMPS r0, #0 @@ -1323,6 +1399,13 @@ huge_val DCD &7FEFFFFF ; put constant where it is easy to find DCD &FFFFFFFF +huge_negative_resultf + MOV r0, #ERANGE + LDFS f0, negative_huge_valf + B Set_errno +negative_huge_valf + DCD &FF800000 + huge_errorf MOV r0, #ERANGE LDFS f0, huge_valf @@ -1340,8 +1423,6 @@ negative_errorf MOV r0, #EDOM LDFS f0, negative_huge_valf ; @@@@!!!! B Set_errno -negative_huge_valf - DCD &FF800000 ; put constant where it is easy to find underflow_error MOV r0, #ERANGE @@ -1353,31 +1434,221 @@ log10 STMFD sp!, {r0, r1} LDFD f0, [sp], #8 ] - CMFE f0, #0 + CMF f0, #0 BEQ huge_negative_result BMI negative_error LOGD f0, f0 Return ,LinkNotStacked +log10f + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + LDFD f0, [sp], #8 + ] + MVFS f0, f0 + CMF f0, #0 + BEQ huge_negative_resultf + BMI negative_errorf + LOGGTS f0, f0 + Return ,LinkNotStacked + log [ :LNOT: FloatingPointArgsInRegs STMFD sp!, {r0, r1} LDFD f0, [sp], #8 ] - CMFE f0, #0 + CMF f0, #0 + BEQ huge_negative_result + BMI negative_error + LGNGTD f0, f0 + Return ,LinkNotStacked + +logf + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + LDFD f0, [sp], #8 + ] + MVFS f0, f0 + CMF f0, #0 + BEQ huge_negative_resultf + BMI negative_errorf + LGNGTS f0, f0 + Return ,LinkNotStacked + +; Mickey-mouse implementations, but they are still better than the user +; doing it, because of intermediate extended precision. +log1p + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + LDFD f0, [sp], #8 + ] + CNF f0, #1 BEQ huge_negative_result BMI negative_error - LGND f0, f0 + ADFGTE f0, f0, #1 + LGNGTD f0, f0 Return ,LinkNotStacked +log1pf + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + LDFD f0, [sp], #8 + ] + MVFS f0, f0 + CNF f0, #1 + BEQ huge_negative_result + BMI negative_error + ADFGTE f0, f0, #1 + LGNGTS f0, f0 + Return ,LinkNotStacked + +log2 + [ FloatingPointArgsInRegs + STFD f0, [sp, #-8]! + LDMFD sp!, {r0, r1} + | + STMFD sp!, {r0, r1} + LDFD f0, [sp], #8 + ] + ; Now argument is in both {r0,r1} and f0 + CMF f0, #0 + BEQ huge_negative_result + BMI negative_error + Return ,LinkNotStacked,VS + ; Argument is strictly positive and finite + MOVS r2, r0, LSR #20 ; r2 = exponent field + BNE %FT30 + ; Subnormal case - normalise + MOV r2, #1 +10 ADDS r1, r1, r1 + ADCS r0, r0, r0 + SUB r2, r2, #1 + TST r0, #&00100000 + BEQ %BT10 +30 ORRS r3, r1, r0, LSL #12 ; EQ if exact power of 2 + ; If exact, just convert exponent field to FP, else + ; compute log2(e)*log(x) + BEQ log2_exact + LDFE f1, log2_e + LGNE f0, f0 + MUFD f0, f0, f1 + Return ,LinkNotStacked +log2_exact + SUB r2, r2, #&400 + ADD r2, r2, #1 + TEQ r2, #&400 ; EQ if infinity + FLTNED f0, r2 + Return ,LinkNotStacked + +log2f + [ :LNOT:FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + LDFD f0, [sp], #8 + ] + MVFS f0, f0 + STFS f0, [sp, #-4]! + LDR r0, [sp], #4 + ; Now argument is in both r0 and f0 + CMF f0, #0 + BEQ huge_negative_result + BMI negative_error + Return ,LinkNotStacked,VS + ; Argument is strictly positive and finite + MOVS r2, r0, LSR #23 ; r2 = exponent field + MOV r0, r0, LSL #9 ; r0 = fraction + BNE %FT30 + ; Subnormal case - normalise + MOV r2, #1 +10 ADDS r0, r0, r0 + SUB r2, r2, #1 + BCC %BT10 +30 TEQ r0, #0 ; EQ if exact power of 2 + ; If exact, just convert exponent field to FP, else + ; compute log2(e)*log(x) + BEQ log2f_exact + LDFE f1, log2_e + LGNE f0, f0 + MUFS f0, f0, f1 + Return ,LinkNotStacked +log2f_exact + SUB r2, r2, #&400 + ADD r2, r2, #1 + TEQ r2, #&400 ; EQ if infinity + FLTNES f0, r2 + Return ,LinkNotStacked + +log2_e DCD &00003FFF, &B8AA3B29, &5C17F0BC +loge_2 DCD &00003FFE, &B17217F7, &D1CF79AC + + IMPORT scalbln +exp2 + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + DisableFPInterrupts + LDFD f0, [sp], #8 + | + DisableFPInterrupts + ] + FIX r0, f0 + CheckFPInterrupts + ANDS r1, r1, #&1F ; inexact or invalid? + BNE exp2_inexact + ; exp2 of an integer - can create an exact result using scalbn + ReEnableFPInterrupts nocheck + [ FloatingPointArgsInRegs + MVFD f0, #1 + | + MOV r2, r0 + ADR r3, D_one + LDMIA r3, {r0,r1} + ] + B scalbln +exp2_inexact + LDFE f1, loge_2 + MUFE f0, f0, f1 + B exp_common + + IMPORT scalblnf +exp2f + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + DisableFPInterrupts + LDFD f0, [sp], #8 + | + DisableFPInterrupts + ] + MVFS f0, f0 + FIX r0, f0 + CheckFPInterrupts + ANDS r1, r1, #&1F ; inexact or invalid? + BNE exp2f_inexact + ; exp2f of an integer - can create an exact result using scalbn + ReEnableFPInterrupts nocheck + [ FloatingPointArgsInRegs + MVFS f0, #1 + | + MOV r2, r0 + ADR r3, D_one + LDMIA r3, {r0,r1} + ] + B scalblnf +exp2f_inexact + LDFE f1, loge_2 + MUFE f0, f0, f1 + B expf_common + +D_one DCFD 1 +OneThird + DCD &00003FFD, &AAAAAAAA, &AAAAAAAB + sqrt [ :LNOT: FloatingPointArgsInRegs STMFD sp!, {r0, r1} LDFD f0, [sp], #8 ] - CMFE f0, #0 + CMF f0, #0 BMI negative_error - SQTD f0, f0 + SQTGED f0, f0 Return ,LinkNotStacked sqrtf @@ -1386,9 +1657,36 @@ sqrtf LDFD f0, [sp], #8 ] MVFS f0, f0 - CMFE f0, #0 + CMF f0, #0 BMI negative_errorf - SQTS f0, f0 + SQTGES f0, f0 + Return ,LinkNotStacked + +cbrt + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + LDFD f0, [sp], #8 + ] + CMF f0, #0 + Return ,LinkNotStacked,EQ + LDFVCE f1, OneThird + ABSVCE f0, f0 + POWVCD f0, f0, f1 + MNFMID f0, f0 + Return ,LinkNotStacked + +cbrtf + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + LDFD f0, [sp], #8 + ] + MVFS f0, f0 + CMF f0, #0 + Return ,LinkNotStacked,EQ + LDFVCE f1, OneThird + ABSVCE f0, f0 + POWVCS f0, f0, f1 + MNFMIS f0, f0 Return ,LinkNotStacked tan @@ -1405,7 +1703,6 @@ tan Return ,LinkNotStacked, EQ B huge_error - [ {FALSE} tanf [ :LNOT: FloatingPointArgsInRegs STMFD sp!, {r0, r1} @@ -1420,7 +1717,6 @@ tanf TST r1, #&07 Return ,LinkNotStacked, EQ B huge_errorf - ] asin [ :LNOT: FloatingPointArgsInRegs @@ -1439,6 +1735,24 @@ asin Return ,LinkNotStacked, EQ B negative_error +asinf + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + DisableFPInterrupts + LDFD f0, [sp], #8 + | + DisableFPInterrupts + ] + MVFS f0, f0 + ASNS f0, f0 + ReEnableFPInterrupts + ; A range error is not possible; any error must be a domain error. + ; (And the only plausible error flag is IVO, but I don't check). + ; Dunno what result is sensible. + TST r1, #&07 + Return ,LinkNotStacked, EQ + B negative_errorf + acos [ :LNOT: FloatingPointArgsInRegs @@ -1457,6 +1771,24 @@ acos Return ,LinkNotStacked, EQ B negative_error +acosf + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1} + DisableFPInterrupts + LDFD f0, [sp], #8 + | + DisableFPInterrupts + ] + MVFS f0, f0 + ACSS f0, f0 + ReEnableFPInterrupts + ; A range error is not possible; any error must be a domain error. + ; (And the only plausible error flag is IVO, but I don't check). + ; Dunno what result is sensible. + TST r1, #&07 + Return ,LinkNotStacked, EQ + B negative_errorf + pow [ :LNOT: FloatingPointArgsInRegs @@ -1470,6 +1802,7 @@ pow CMFE f0, #0 BEQ POWFirstArgZero POWD f0, f0, f1 +POWCommonExit ReEnableFPInterrupts ; Plausibly, there may have been either an overflow or IVO error. ; I assume that the former is always a range error, and the latter @@ -1484,6 +1817,22 @@ pow BNE underflow_error B huge_error +powf + [ :LNOT: FloatingPointArgsInRegs + STMFD sp!, {r0, r1, r2, r3} + DisableFPInterrupts + LDFD f0, [sp], #8 + LDFD f1, [sp], #8 + | + DisableFPInterrupts + ] + MVFS f0, f0 + MVFS f1, f1 + CMFE f0, #0 + BEQ POWFirstArgZero + POWS f0, f0, f1 + B POWCommonExit + POWFirstArgZero CMFE f1, #0 MVFEQD f0, #1 ; return 1.0 if both args 0.0 @@ -1502,7 +1851,8 @@ hypot LDFD f0, [sp], #8 LDFD f1, [sp], #8 ] - LDFS f3, infinity + ADRL r0, infinity + LDFS f3, [r0] CMF f0, f1 BVS hypot_nan MVFMID f2, f0 @@ -1538,7 +1888,8 @@ hypotf ] ABSS f0, f0 ABSS f1, f1 - LDFS f3, infinity + ADRL r0, infinity + LDFS f3, [r0] CMF f0, f1 BVS hypot_nan MVFMIS f2, f0 diff --git a/clib/s/cl_entry2 b/clib/s/cl_entry2 index 924e0ef16b3c344445797473ce8c808c2e8f7012..5238709331a45c257d36751a9836e135de82b4f2 100644 --- a/clib/s/cl_entry2 +++ b/clib/s/cl_entry2 @@ -85,4 +85,59 @@ Entry strtoimax, imported, , unveneered Entry strtoumax, imported, , unveneered + Entry __assert2, imported, , unveneered + Entry _Exit, imported, , unveneered + + Entry acosf, , , unveneered + Entry asinf, , , unveneered + Entry atanf, imported, , unveneered + Entry atan2f, imported, , unveneered + Entry cosf, imported, , unveneered + Entry sinf, imported, , unveneered + Entry tanf, , , unveneered + Entry acosh, imported, , unveneered + Entry acoshf, imported, , unveneered + Entry asinh, imported, , unveneered + Entry asinhf, imported, , unveneered + Entry atanh, imported, , unveneered + Entry atanhf, imported, , unveneered + Entry expf, , , unveneered + Entry exp2, , , unveneered + Entry exp2f, , , unveneered + Entry expm1, , , unveneered + Entry expm1f, , , unveneered + Entry frexpf, imported, , unveneered + Entry ilogb, imported, , unveneered + Entry ilogbf, imported, , unveneered + Entry ldexpf, imported, , unveneered + Entry logf, , , unveneered + Entry log10f, , , unveneered + Entry log1p, , , unveneered + Entry log1pf, , , unveneered + Entry log2, , , unveneered + Entry log2f, , , unveneered + Entry logb, imported, , unveneered + Entry logbf, imported, , unveneered + Entry modff, imported, , unveneered + Entry fmodf, imported, , unveneered + Entry scalbn, imported, , unveneered + Entry scalbnf, imported, , unveneered + Entry scalbln, imported, , unveneered + Entry scalblnf, imported, , unveneered + Entry cbrt, , , unveneered + Entry cbrtf, , , unveneered + Entry powf, , , unveneered + Entry sqrtf, , , unveneered + Entry erf, imported, , unveneered + Entry erff, imported, , unveneered + Entry erfc, imported, , unveneered + Entry erfcf, imported, , unveneered + Entry lgamma, imported, , unveneered + Entry lgammaf, imported, , unveneered + Entry tgamma, imported, , unveneered + Entry tgammaf, imported, , unveneered + Entry nexttoward, , , unveneered + Entry nexttowardf, , , unveneered + Entry fmaf, , , unveneered + END diff --git a/clib/s/cl_stub b/clib/s/cl_stub index 8e459555b492e9159b6e2dacba62418154647486..c1030c3fcbf90f17efb58db8d31ddda7f831cb5b 100644 --- a/clib/s/cl_stub +++ b/clib/s/cl_stub @@ -79,6 +79,11 @@ SharedLibrary SETL {TRUE} |_kernel_entrypoint| SWI GetEnv + [ APCS_Type <> "APCS-R" :LAND: Code_Destination = "RAM" + MOV sp, r1 + BL EnsureCLib +; SWIVS GenerateError + ] MOV r2, r1 LDR r1, =|Image$$RW$$Limit| MOV r3, #-1 @@ -185,6 +190,10 @@ LookupError ; Note that finalise always discards the RMA (whether fatal or not) ; so initialise always acquires it. Is this reasonable? STMFD sp!, {r14} + [ APCS_Type <> "APCS-R" :LAND: Code_Destination = "RAM" + BL EnsureCLib +; LDMVSFD sp!, {pc} + ] MOV r9, r0 ; save 'copy statics' flag ; [ Code_Destination = "RAM" ; Old versions of RelocCode would "return" the last field of the @@ -305,6 +314,43 @@ LookupError LDMIA sp!, {pc} ] + [ APCS_Type <> "APCS-R" :LAND: Code_Destination = "RAM" +EnsureCLib + STMFD sp!, {r0,lr} +; ADR r0, RMEnsure1 +; SWI CLI + ADR r0, RMEnsure2 + SWI CLI +; ADRVC r0, RMEnsure3 +; SWIVC CLI + ADRVC r0, RMEnsure4 + SWIVC CLI +; ADRVC r0, RMEnsure5 +; SWIVC CLI + ADRVC r0, RMEnsure6 + SWIVC CLI +; ADRVC r0, RMEnsure7 +; SWIVC CLI + STRVS r0, [sp] + LDMFD sp!, {r0,pc} + +;RMEnsure1 +; = "RMEnsure UtilityModule 3.10", 0 +RMEnsure2 + = "RMEnsure UtilityModule 3.70 RMEnsure CallASWI 0.02 RMLoad System:Modules.CallASWI", 0 +;RMEnsure3 +; = "RMEnsure UtilityModule 3.70 RMEnsure CallASWI 0.02", 0 +RMEnsure4 + = "RMEnsure FPEmulator 4.03 RMLoad System:Modules.FPEmulator", 0 +;RMEnsure5 +; = "RMEnsure FPEmulator 4.03", 0 +RMEnsure6 + = "RMEnsure SharedCLibrary 5.17 RMLoad System:Modules.CLib", 0 +;RMEnsure7 +; = "RMEnsure SharedCLibrary 5.34", 0 + ALIGN + ] + EXPORT |_clib_initialisemodule| |_clib_initialisemodule| STMFD sp!, {r14} diff --git a/h/hostsys b/h/hostsys index 603ab2dbd7c55f374ef322141052dd01ec8e0c64..e8c990414b03ade2307f0bdae9c4bd86f44ef789 100644 --- a/h/hostsys +++ b/h/hostsys @@ -100,8 +100,8 @@ extern void *_sys_alloc(size_t n); extern void _init_user_alloc(void); extern void _terminate_user_alloc(void); extern void _sys_msg(const char *); -extern bool _sys__assert(const char *fmt, - const char *expr, const char *file, int line); +extern bool _sys__assert(const char *fmt, const char *expr, + const char *func, const char *file, int line); extern void _exit(int n); extern void _terminate_getenv(void); @@ -153,7 +153,7 @@ extern struct _svcwto _io_emsg; /* beware only 64 bytes thereof */ /* For the current ARM floating point system that Acorn use the first */ /* word of a floating point value is the one containing the exponent. */ # undef OTHER_WORD_ORDER_FOR_FP_NUMBERS -# define DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS 1 +/*# define DO_NOT_SUPPORT_UNNORMALIZED_NUMBERS 1*/ # endif # endif #endif @@ -350,9 +350,11 @@ extern FILE *_fopen_string_file(const char *data, int length); #ifdef DEFAULT_TEXT extern char *_kernel_getmessage(char *msg, char *tag); extern char *_kernel_getmessage2(char *msg, char *tag, char *dst, size_t len); +#define _kernel_getmessage_def(msg, tag) _kernel_getmessage(msg, tag) #else extern char *_kernel_getmessage(char *tag); extern char *_kernel_getmessage2(char *tag, char *dst, size_t len); +extern char *_kernel_getmessage_def(char *msg, char *tag); #define _kernel_getmessage(msg, tag) _kernel_getmessage(tag) #define _kernel_getmessage2(msg, tag, dst, len) _kernel_getmessage2(tag, dst, len) #endif diff --git a/kernel/s/k_body b/kernel/s/k_body index 850546d3ebe4d7aaf9d1ac6f46d2a79e723ff315..f0ad3470877e61dc42ace91c69a5049dd426d0f4 100644 --- a/kernel/s/k_body +++ b/kernel/s/k_body @@ -3150,6 +3150,7 @@ dividebyzero EXPORT |_kernel_copyerror| EXPORT |_kernel_getmessage| + EXPORT |_kernel_getmessage_def| EXPORT |_kernel_getmessage2| [ SharedLibrary ; Only works with module for the moment @@ -3197,15 +3198,14 @@ n_module_lookupname EQU 18 ; Return: ; R0 = Message ; + [ :DEF:DEFAULT_TEXT |_kernel_getmessage| + ] +|_kernel_getmessage_def| FunctionEntry "r0-r7,r12" BL open_messagefile MOV r0, r1 - [ :DEF:DEFAULT_TEXT LDR r1, [sp, #4] - | - LDR r1, [sp] - ] MOV r2, #0 MOV r4, #0 MOV r5, #0 @@ -3215,6 +3215,20 @@ n_module_lookupname EQU 18 STRVC r2, [sp] Return "r0-r7,r12" + [ :LNOT::DEF:DEFAULT_TEXT +; On entry: +; R0 = Message tag +; +; Return: +; R0 = Message +; +|_kernel_getmessage| + FunctionEntry "r1" + MOV r1, r0 + BL |_kernel_getmessage_def| + Return "r1" + ] + ; On entry: ; [ DEFAULT_TEXT ; R0 = Message to use if failed to get message from message file @@ -3292,6 +3306,7 @@ open_messagefile Return ,LinkNotStacked |_kernel_getmessage| +|_kernel_getmessage_def| |_kernel_getmessage2| Return ,LinkNotStacked diff --git a/rlib/c/txt1 b/rlib/c/txt1 index a07972d0a5cb8f7c0851af3887296d012003c5de..02cb06bfdffb1a353fd33f0a586ac2985cba7205 100644 --- a/rlib/c/txt1 +++ b/rlib/c/txt1 @@ -267,8 +267,6 @@ static int txt1__min(int a, int b) {return(a < b ? a : b);} static int txt1__max(int a, int b) {return(a > b ? a : b);} -static int txt1__abs(int a) {return(a < 0 ? -a : a);} - /* -------- checking and debugging. -------- */ #if TRACE @@ -1405,7 +1403,7 @@ of the succuessor line rather than the end of the previous one. */ txt1__horizmeasure(t, x, t->w->caretx + t->w->caretoffsetx, &at); if ( 0 == (txt_DISPLAY & t->charoptionset) - || (txt1__abs(by) < (3 * t->w->limy) / (4 * t->w->linesep))) { + || (abs(by) < (3 * t->w->limy) / (4 * t->w->linesep))) { /* could end up doing on-screen block copies */ tracef0("movevertical is near.\n"); txt1_dosetdot(t, txt1__bufindextoindex(t, at)); @@ -1476,7 +1474,7 @@ void txt1_domovehorizontal(txt t, int by) caret = 0 != (txt_CARET & t->charoptionset); t->charoptionset &= ~txt_CARET; spacewidth = txt1__spacewidth(t); - for (i = 1; i <= txt1__abs(by); i++) { + for (i = 1; i <= abs(by); i++) { if (((t->w->caretoffsetx > 0) || ((t->w->caretoffsetx == 0) && (by > 0))) && ((t->gapend == txt1__termchbi(t)) || (t->buf[t->gapend] == '\n')) && (t->w->caretoffsetx + t->w->caretx + by*spacewidth <= t->w->limx) @@ -2440,7 +2438,7 @@ void txt1__updatescrollbar(txt t) offset = (first * 100) / max; }; /* try not to keep fiddling the size by small amounts. */ - if (t->w->isize != 0 && txt1__abs(size - t->w->isize) < 3) { + if (t->w->isize != 0 && abs(size - t->w->isize) < 3) { size = t->w->isize; }; if (size != t->w->isize || offset != t->w->ioffset) { @@ -3376,7 +3374,7 @@ a move or replace. */ tracef3("limy=%i lastvisy=%i linesep=%i\n", t->w->limy, t->w->lastvisy, t->w->linesep); if (by == 0) return; - byy = txt1__abs(by) * t->w->linesep; + byy = abs(by) * t->w->linesep; /* >>>> replaced by stuff below if ((by > 0) && (t->w->lastvis.pos == txt1__termchbi(t))) { diff --git a/rlib/c/txtar b/rlib/c/txtar index d5c4d4e149b203d62f121ae200e4715dc58baa73..46507ccf0dd2006c0c83e652f33c73a12371beb4 100644 --- a/rlib/c/txtar +++ b/rlib/c/txtar @@ -216,8 +216,6 @@ static int txtar__max(int a, int b) {return(a > b ? a : b);} static int txtar__min(int a, int b) {return(a < b ? a : b);} -static int txtar__abs(int a) {return(a < 0 ? -a : a);} - static void txtar__setmode(txtar__sysdata *s) { txt t = s->t; #ifdef BIG_WINDOWS @@ -2466,8 +2464,8 @@ drag event. */ m = 0; }; - if ((txtar__abs(s->prevmousex - e->data.but.m.x) <= 2 * wimpt_dx()) - && (txtar__abs(s->prevmousey - e->data.but.m.y) <= 2 * wimpt_dy()) + if ((abs(s->prevmousex - e->data.but.m.x) <= 2 * wimpt_dx()) + && (abs(s->prevmousey - e->data.but.m.y) <= 2 * wimpt_dy()) && (mousetime - s->prevmousetime < 100)) { tracef0("mouse exact multi-click.\n"); m |= txt_MEXACT; diff --git a/s/mathl b/s/mathl new file mode 100644 index 0000000000000000000000000000000000000000..8977503be93190a9e8054860fa4823ef725e6d24 --- /dev/null +++ b/s/mathl @@ -0,0 +1,93 @@ +; Copyright 2003 Tematic Ltd +; +; Licensed under the Apache License, Version 2.0 (the "License"); +; you may not use this file except in compliance with the License. +; You may obtain a copy of the License at +; +; http://www.apache.org/licenses/LICENSE-2.0 +; +; Unless required by applicable law or agreed to in writing, software +; distributed under the License is distributed on an "AS IS" BASIS, +; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +; See the License for the specific language governing permissions and +; limitations under the License. +; +; As long double is the same as double, all the long double <math.h> functions +; can just bounce to the double ones. These bounces are included in ANSILib +; and the stubs as is - the Shared C Library doesn't contain or export them. + + AREA |C$$code|, CODE, READONLY + + MACRO + DoL $func + EXPORT $func.l + IMPORT $func +$func.l B $func + MEND + + DoL acos + DoL asin + DoL atan + DoL atan2 + DoL cos + DoL sin + DoL tan + + DoL acosh + DoL asinh + DoL atanh + DoL cosh + DoL sinh + DoL tanh + + DoL exp + DoL exp2 + DoL expm1 + DoL frexp + DoL ilogb + DoL ldexp + DoL log + DoL log10 + DoL log1p + DoL log2 + DoL logb + DoL modf + DoL scalbn + DoL scalbln + + DoL cbrt + DoL fabs + DoL hypot + DoL pow + DoL sqrt + + DoL erf + DoL erfc + DoL lgamma + DoL tgamma + + DoL ceil + DoL floor + DoL nearbyint + DoL rint + DoL lrint + DoL round + DoL lround + DoL trunc + + DoL fmod + DoL remainder +; DoL remquo + + DoL copysign + DoL nan + DoL nextafter + DoL nexttoward + + DoL fdim + DoL fmax + DoL fmin + +; DoL fma + + END