summaryrefslogtreecommitdiff
path: root/missing
diff options
context:
space:
mode:
Diffstat (limited to 'missing')
-rw-r--r--missing/acosh.c19
-rw-r--r--missing/alloca.c7
-rw-r--r--missing/cbrt.c10
-rw-r--r--missing/close.c67
-rw-r--r--missing/crypt.c52
-rw-r--r--missing/dup2.c5
-rw-r--r--missing/erf.c12
-rw-r--r--missing/finite.c3
-rw-r--r--missing/flock.c14
-rw-r--r--missing/hypot.c3
-rw-r--r--missing/isinf.c17
-rw-r--r--missing/isnan.c8
-rw-r--r--missing/langinfo.c147
-rw-r--r--missing/lgamma_r.c68
-rw-r--r--missing/memcmp.c9
-rw-r--r--missing/memmove.c17
-rw-r--r--missing/os2.c25
-rw-r--r--missing/signbit.c19
-rw-r--r--missing/strcasecmp.c16
-rw-r--r--missing/strchr.c18
-rw-r--r--missing/strerror.c3
-rw-r--r--missing/strftime.c903
-rw-r--r--missing/strlcat.c73
-rw-r--r--missing/strlcpy.c69
-rw-r--r--missing/strncasecmp.c21
-rw-r--r--missing/strstr.c11
-rw-r--r--missing/strtod.c271
-rw-r--r--missing/strtol.c9
-rw-r--r--missing/strtoul.c184
-rw-r--r--missing/tgamma.c92
-rw-r--r--missing/vsnprintf.c1135
-rw-r--r--missing/x68.c40
32 files changed, 674 insertions, 2673 deletions
diff --git a/missing/acosh.c b/missing/acosh.c
index a4443e191f..c6695b599e 100644
--- a/missing/acosh.c
+++ b/missing/acosh.c
@@ -3,7 +3,6 @@
acosh.c -
$Author$
- $Date$
created at: Fri Apr 12 00:34:17 JST 2002
public domain rewrite of acosh(3), asinh(3) and atanh(3)
@@ -13,6 +12,7 @@
#include <errno.h>
#include <float.h>
#include <math.h>
+#include "ruby.h"
/* DBL_MANT_DIG must be less than 4 times of bits of int */
#ifndef DBL_MANT_DIG
@@ -33,8 +33,7 @@
#ifndef HAVE_ACOSH
double
-acosh(x)
- double x;
+acosh(double x)
{
if (x < 1)
x = -1; /* NaN */
@@ -50,8 +49,7 @@ acosh(x)
#ifndef HAVE_ASINH
double
-asinh(x)
- double x;
+asinh(double x)
{
int neg = x < 0;
double z = fabs(x);
@@ -74,8 +72,7 @@ asinh(x)
#ifndef HAVE_ATANH
double
-atanh(x)
- double x;
+atanh(double x)
{
int neg = x < 0;
double z = fabs(x);
@@ -83,6 +80,14 @@ atanh(x)
if (z < SMALL_CRITERIA) return x;
z = log(z > 1 ? -1 : (1 + z) / (1 - z)) / 2;
if (neg) z = -z;
+ if (isinf(z))
+#if defined(ERANGE)
+ errno = ERANGE;
+#elif defined(EDOM)
+ errno = EDOM;
+#else
+ ;
+#endif
return z;
}
#endif
diff --git a/missing/alloca.c b/missing/alloca.c
index 39697f114a..d23917f3f7 100644
--- a/missing/alloca.c
+++ b/missing/alloca.c
@@ -29,7 +29,9 @@
static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
#endif
-#include "config.h"
+#include "ruby/config.h"
+#ifdef C_ALLOCA
+
#ifdef emacs
#ifdef static
/* actually, only want this if static is defined as ""
@@ -52,7 +54,7 @@ typedef char *pointer; /* generic pointer type */
#define NULL 0 /* null pointer constant */
-#ifdef RUBY_LIB
+#ifdef RUBY_LIB_PREFIX
#define xmalloc ruby_xmalloc
#define xfree ruby_xfree
#endif
@@ -192,3 +194,4 @@ alloca (size) /* returns pointer to storage */
}
}
+#endif
diff --git a/missing/cbrt.c b/missing/cbrt.c
new file mode 100644
index 0000000000..54db2703a0
--- /dev/null
+++ b/missing/cbrt.c
@@ -0,0 +1,10 @@
+#include <math.h>
+
+double cbrt(double x)
+{
+ if (x < 0)
+ return -pow(-x, 1/3.0);
+ else
+ return pow(x, 1/3.0);
+}
+
diff --git a/missing/close.c b/missing/close.c
new file mode 100644
index 0000000000..d87f9e3164
--- /dev/null
+++ b/missing/close.c
@@ -0,0 +1,67 @@
+/* Ignore ECONNRESET of FreeBSD */
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+int
+ruby_getpeername(int s, struct sockaddr * name,
+ socklen_t * namelen)
+{
+ int err = errno;
+ errno = 0;
+ s = getpeername(s, name, namelen);
+ if (errno == ECONNRESET) {
+ errno = 0;
+ s = 0;
+ }
+ else if (errno == 0)
+ errno = err;
+ return s;
+}
+
+int
+ruby_getsockname(int s, struct sockaddr * name,
+ socklen_t * namelen)
+{
+ int err = errno;
+ errno = 0;
+ s = getsockname(s, name, namelen);
+ if (errno == ECONNRESET) {
+ errno = 0;
+ s = 0;
+ }
+ else if (errno == 0)
+ errno = err;
+ return s;
+}
+
+int
+ruby_shutdown(int s, int how)
+{
+ int err = errno;
+ errno = 0;
+ s = shutdown(s, how);
+ if (errno == ECONNRESET) {
+ errno = 0;
+ s = 0;
+ }
+ else if (errno == 0)
+ errno = err;
+ return s;
+}
+
+int
+ruby_close(int s)
+{
+ int err = errno;
+ errno = 0;
+ s = close(s);
+ if (errno == ECONNRESET) {
+ errno = 0;
+ s = 0;
+ }
+ else if (errno == 0)
+ errno = err;
+ return s;
+}
diff --git a/missing/crypt.c b/missing/crypt.c
index 486df5050b..d5a9281f77 100644
--- a/missing/crypt.c
+++ b/missing/crypt.c
@@ -107,13 +107,15 @@ static char sccsid[] = "@(#)crypt.c 8.1 (Berkeley) 6/4/93";
#define LARGEDATA
#endif
+int des_setkey(), des_cipher();
+
/* compile with "-DSTATIC=int" when profiling */
#ifndef STATIC
#define STATIC static
#endif
-STATIC init_des(), init_perm(), permute();
+STATIC void init_des(), init_perm(), permute();
#ifdef DEBUG
-STATIC prtab();
+STATIC void prtab();
#endif
/* ==================================== */
@@ -255,10 +257,10 @@ typedef union {
*/
#define TO_SIX_BIT(rslt, src) { \
C_block cvt; \
- cvt.b[0] = src; src >>= 6; \
- cvt.b[1] = src; src >>= 6; \
- cvt.b[2] = src; src >>= 6; \
- cvt.b[3] = src; \
+ cvt.b[0] = (unsigned char)src; src >>= 6; \
+ cvt.b[1] = (unsigned char)src; src >>= 6; \
+ cvt.b[2] = (unsigned char)src; src >>= 6; \
+ cvt.b[3] = (unsigned char)src; \
rslt = (cvt.b32.i0 & 0x3f3f3f3fL) << 2; \
}
@@ -299,7 +301,7 @@ typedef union {
#define PERM3264(d,d0,d1,cpp,p) \
{ C_block tblk; permute(cpp,&tblk,p,4); LOAD (d,d0,d1,tblk); }
-STATIC
+STATIC void
permute(cp, out, p, chars_in)
unsigned char *cp;
C_block *out;
@@ -377,46 +379,62 @@ static unsigned char PC2[] = { /* permuted choice table 2 */
};
static unsigned char S[8][64] = { /* 48->32 bit substitution tables */
+ {
/* S[1] */
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
+ },
+ {
/* S[2] */
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
+ },
+ {
/* S[3] */
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
+ },
+ {
/* S[4] */
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
+ },
+ {
/* S[5] */
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
+ },
+ {
/* S[6] */
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
+ },
+ {
/* S[7] */
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
+ },
+ {
/* S[8] */
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11,
+ },
};
static unsigned char P32Tr[] = { /* 32-bit permutation function */
@@ -580,6 +598,7 @@ static C_block KS[KS_SIZE];
/*
* Set up the key schedule from the key.
*/
+int
des_setkey(key)
register const char *key;
{
@@ -614,6 +633,7 @@ des_setkey(key)
* NOTE: the performance of this routine is critically dependent on your
* compiler and machine architecture.
*/
+int
des_cipher(in, out, salt, num_iter)
const char *in;
char *out;
@@ -660,13 +680,13 @@ des_cipher(in, out, salt, num_iter)
if (num_iter >= 0)
{ /* encryption */
kp = &KS[0];
- ks_inc = sizeof(*kp);
+ ks_inc = (int)sizeof(*kp);
}
else
{ /* decryption */
num_iter = -num_iter;
kp = &KS[KS_SIZE-1];
- ks_inc = -sizeof(*kp);
+ ks_inc = -(int)sizeof(*kp);
}
while (--num_iter >= 0) {
@@ -734,7 +754,7 @@ des_cipher(in, out, salt, num_iter)
* Initialize various tables. This need only be done once. It could even be
* done at compile time, if the compiler were capable of that sort of thing.
*/
-STATIC
+STATIC void
init_des()
{
register int i, j;
@@ -764,7 +784,7 @@ init_des()
k = (k|07) - (k&07);
k++;
}
- perm[i] = k;
+ perm[i] = (unsigned char)k;
}
#ifdef DEBUG
prtab("pc1tab", perm, 8);
@@ -811,7 +831,7 @@ init_des()
k = (k|07) - (k&07);
k++;
}
- perm[i*8+j] = k;
+ perm[i*8+j] = (unsigned char)k;
}
}
#ifdef DEBUG
@@ -857,7 +877,7 @@ init_des()
for (i = 0; i < 32; i++)
tmp32[i] = 0;
for (i = 0; i < 4; i++)
- tmp32[4 * tableno + i] = (k >> i) & 01;
+ tmp32[4 * tableno + i] = (unsigned char)(k >> i) & 01;
k = 0;
for (i = 24; --i >= 0; )
k = (k<<1) | tmp32[perm[i]-1];
@@ -878,7 +898,7 @@ init_des()
*
* "perm" must be all-zeroes on entry to this routine.
*/
-STATIC
+STATIC void
init_perm(perm, p, chars_in, chars_out)
C_block perm[64/CHUNKBITS][1<<CHUNKBITS];
unsigned char p[64];
@@ -902,6 +922,7 @@ init_perm(perm, p, chars_in, chars_out)
/*
* "setkey" routine (for backwards compatibility)
*/
+int
setkey(key)
register const char *key;
{
@@ -922,6 +943,7 @@ setkey(key)
/*
* "encrypt" routine (for backwards compatibility)
*/
+int
encrypt(block, flag)
register char *block;
int flag;
@@ -950,7 +972,7 @@ encrypt(block, flag)
}
#ifdef DEBUG
-STATIC
+STATIC void
prtab(s, t, num_rows)
char *s;
unsigned char *t;
diff --git a/missing/dup2.c b/missing/dup2.c
index e7cc46f4c1..7554084c5d 100644
--- a/missing/dup2.c
+++ b/missing/dup2.c
@@ -11,7 +11,7 @@
* Return fd2 if all went well; return BADEXIT otherwise.
*/
-#include "config.h"
+#include "ruby/config.h"
#if defined(HAVE_FCNTL)
# include <fcntl.h>
@@ -24,8 +24,7 @@
#define BADEXIT -1
int
-dup2(fd1, fd2)
-int fd1, fd2;
+dup2(int fd1, int fd2)
{
#if defined(HAVE_FCNTL) && defined(F_DUPFD)
if (fd1 != fd2) {
diff --git a/missing/erf.c b/missing/erf.c
index d9e7469024..fe65b9a479 100644
--- a/missing/erf.c
+++ b/missing/erf.c
@@ -25,8 +25,7 @@ static double q_gamma(double, double, double);
/* Incomplete gamma function
1 / Gamma(a) * Int_0^x exp(-t) t^(a-1) dt */
-static double p_gamma(a, x, loggamma_a)
- double a, x, loggamma_a;
+static double p_gamma(double a, double x, double loggamma_a)
{
int k;
double result, term, previous;
@@ -45,8 +44,7 @@ static double p_gamma(a, x, loggamma_a)
/* Incomplete gamma function
1 / Gamma(a) * Int_x^inf exp(-t) t^(a-1) dt */
-static double q_gamma(a, x, loggamma_a)
- double a, x, loggamma_a;
+static double q_gamma(double a, double x, double loggamma_a)
{
int k;
double result, w, temp, previous;
@@ -69,8 +67,7 @@ static double q_gamma(a, x, loggamma_a)
#define LOG_PI_OVER_2 0.572364942924700087071713675675 /* log_e(PI)/2 */
-double erf(x)
- double x;
+double erf(double x)
{
if (!finite(x)) {
if (isnan(x)) return x; /* erf(NaN) = NaN */
@@ -80,8 +77,7 @@ double erf(x)
else return - p_gamma(0.5, x * x, LOG_PI_OVER_2);
}
-double erfc(x)
- double x;
+double erfc(double x)
{
if (!finite(x)) {
if (isnan(x)) return x; /* erfc(NaN) = NaN */
diff --git a/missing/finite.c b/missing/finite.c
index f91035a8cd..8d0b7af262 100644
--- a/missing/finite.c
+++ b/missing/finite.c
@@ -1,8 +1,7 @@
/* public domain rewrite of finite(3) */
int
-finite(n)
- double n;
+finite(double n)
{
return !isnan(n) && !isinf(n);
}
diff --git a/missing/flock.c b/missing/flock.c
index 5f6b41c357..b02f8bf832 100644
--- a/missing/flock.c
+++ b/missing/flock.c
@@ -1,4 +1,4 @@
-#include "config.h"
+#include "ruby/config.h"
#if defined _WIN32
#elif defined HAVE_FCNTL && defined HAVE_FCNTL_H
@@ -24,9 +24,7 @@
#include <errno.h>
int
-flock(fd, operation)
- int fd;
- int operation;
+flock(int fd, int operation)
{
struct flock lock;
@@ -91,9 +89,7 @@ flock(fd, operation)
# endif
int
-flock(fd, operation)
- int fd;
- int operation;
+flock(int fd, int operation)
{
switch (operation) {
@@ -125,9 +121,7 @@ flock(fd, operation)
}
#else
int
-flock(fd, operation)
- int fd;
- int operation;
+flock(int fd, int operation)
{
rb_notimplement();
return -1;
diff --git a/missing/hypot.c b/missing/hypot.c
index aad5259e92..5a663553cf 100644
--- a/missing/hypot.c
+++ b/missing/hypot.c
@@ -2,8 +2,7 @@
#include <math.h>
-double hypot(x,y)
- double x, y;
+double hypot(double x, double y)
{
if (x < 0) x = -x;
if (y < 0) y = -y;
diff --git a/missing/isinf.c b/missing/isinf.c
index c9e49c6795..4aef51b213 100644
--- a/missing/isinf.c
+++ b/missing/isinf.c
@@ -6,8 +6,7 @@
#include <nan.h>
int
-isinf(n)
- double n;
+isinf(double n)
{
if (IsNANorINF(n) && IsINF(n)) {
return 1;
@@ -19,7 +18,7 @@ isinf(n)
#else
-#include "config.h"
+#include "ruby/config.h"
#if defined(HAVE_FINITE) && defined(HAVE_ISNAN)
@@ -35,8 +34,7 @@ isinf(n)
*/
#ifndef isinf
int
-isinf(n)
- double n;
+isinf(double n)
{
return (!finite(n) && !isnan(n));
}
@@ -50,13 +48,12 @@ isinf(n)
# include <strings.h>
#endif
-static double zero() { return 0.0; }
-static double one() { return 1.0; }
-static double inf() { return one() / zero(); }
+static double zero(void) { return 0.0; }
+static double one (void) { return 1.0; }
+static double inf (void) { return one() / zero(); }
int
-isinf(n)
- double n;
+isinf(double n)
{
static double pinf = 0.0;
static double ninf = 0.0;
diff --git a/missing/isnan.c b/missing/isnan.c
index 459048e936..a8733978ad 100644
--- a/missing/isnan.c
+++ b/missing/isnan.c
@@ -1,17 +1,15 @@
/* public domain rewrite of isnan(3) */
-static int double_ne();
+static int double_ne(double n1, double n2);
int
-isnan(n)
- double n;
+isnan(double n)
{
return double_ne(n, n);
}
static int
-double_ne(n1, n2)
- double n1, n2;
+double_ne(double n1, double n2)
{
return n1 != n2;
}
diff --git a/missing/langinfo.c b/missing/langinfo.c
new file mode 100644
index 0000000000..6373afd0f5
--- /dev/null
+++ b/missing/langinfo.c
@@ -0,0 +1,147 @@
+/* -*- c-file-style: "gnu" -*- */
+/*
+ * This is a quick-and-dirty emulator of the nl_langinfo(CODESET)
+ * function defined in the Single Unix Specification for those systems
+ * (FreeBSD, etc.) that don't have one yet. It behaves as if it had
+ * been called after setlocale(LC_CTYPE, ""), that is it looks at
+ * the locale environment variables.
+ *
+ * http://www.opengroup.org/onlinepubs/7908799/xsh/langinfo.h.html
+ *
+ * Please extend it as needed and suggest improvements to the author.
+ * This emulator will hopefully become redundant soon as
+ * nl_langinfo(CODESET) becomes more widely implemented.
+ *
+ * Since the proposed Li18nux encoding name registry is still not mature,
+ * the output follows the MIME registry where possible:
+ *
+ * http://www.iana.org/assignments/character-sets
+ *
+ * A possible autoconf test for the availability of nl_langinfo(CODESET)
+ * can be found in
+ *
+ * http://www.cl.cam.ac.uk/~mgk25/unicode.html#activate
+ *
+ * Markus.Kuhn@cl.cam.ac.uk -- 2002-03-11
+ * Permission to use, copy, modify, and distribute this software
+ * for any purpose and without fee is hereby granted. The author
+ * disclaims all warranties with regard to this software.
+ *
+ * Latest version:
+ *
+ * http://www.cl.cam.ac.uk/~mgk25/ucs/langinfo.c
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#if defined _WIN32 || defined __CYGWIN__
+#include <windows.h>
+#if defined _WIN32
+#define strncasecmp strnicmp
+#endif
+#endif
+#ifdef HAVE_LANGINFO_H
+#include "langinfo.h"
+#endif
+
+#define C_CODESET "US-ASCII" /* Return this as the encoding of the
+ * C/POSIX locale. Could as well one day
+ * become "UTF-8". */
+
+#if defined _WIN32 || defined __CYGWIN__
+#define JA_CODESET "Windows-31J"
+#else
+#define JA_CODESET "EUC-JP"
+#endif
+
+#define digit(x) ((x) >= '0' && (x) <= '9')
+#define strstart(s, n) (strncasecmp(s, n, strlen(n)) == 0)
+
+static char buf[16];
+
+const char *
+nl_langinfo_codeset(void)
+{
+ const char *l, *p;
+ int n;
+
+ if (((l = getenv("LC_ALL")) && *l) ||
+ ((l = getenv("LC_CTYPE")) && *l) ||
+ ((l = getenv("LANG")) && *l)) {
+ /* check standardized locales */
+ if (!strcmp(l, "C") || !strcmp(l, "POSIX"))
+ return C_CODESET;
+ /* check for encoding name fragment */
+ p = strchr(l, '.');
+ if (!p++) p = l;
+ if (strstart(p, "UTF"))
+ return "UTF-8";
+ if ((n = 5, strstart(p, "8859-")) || (n = 9, strstart(p, "ISO-8859-"))) {
+ if (digit(p[n])) {
+ p += n;
+ memcpy(buf, "ISO-8859-\0\0", 12);
+ buf[9] = *p++;
+ if (digit(*p)) buf[10] = *p++;
+ return buf;
+ }
+ }
+ if (strstart(p, "KOI8-R")) return "KOI8-R";
+ if (strstart(p, "KOI8-U")) return "KOI8-U";
+ if (strstart(p, "620")) return "TIS-620";
+ if (strstart(p, "2312")) return "GB2312";
+ if (strstart(p, "HKSCS")) return "Big5HKSCS"; /* no MIME charset */
+ if (strstart(p, "BIG5")) return "Big5";
+ if (strstart(p, "GBK")) return "GBK"; /* no MIME charset */
+ if (strstart(p, "18030")) return "GB18030"; /* no MIME charset */
+ if (strstart(p, "Shift_JIS") || strstart(p, "SJIS")) return "Windows-31J";
+ /* check for conclusive modifier */
+ if (strstart(p, "euro")) return "ISO-8859-15";
+ /* check for language (and perhaps country) codes */
+ if (strstart(l, "zh_TW")) return "Big5";
+ if (strstart(l, "zh_HK")) return "Big5HKSCS"; /* no MIME charset */
+ if (strstart(l, "zh")) return "GB2312";
+ if (strstart(l, "ja")) return JA_CODESET;
+ if (strstart(l, "ko")) return "EUC-KR";
+ if (strstart(l, "ru")) return "KOI8-R";
+ if (strstart(l, "uk")) return "KOI8-U";
+ if (strstart(l, "pl") || strstart(l, "hr") ||
+ strstart(l, "hu") || strstart(l, "cs") ||
+ strstart(l, "sk") || strstart(l, "sl")) return "ISO-8859-2";
+ if (strstart(l, "eo") || strstart(l, "mt")) return "ISO-8859-3";
+ if (strstart(l, "el")) return "ISO-8859-7";
+ if (strstart(l, "he")) return "ISO-8859-8";
+ if (strstart(l, "tr")) return "ISO-8859-9";
+ if (strstart(l, "th")) return "TIS-620"; /* or ISO-8859-11 */
+ if (strstart(l, "lt")) return "ISO-8859-13";
+ if (strstart(l, "cy")) return "ISO-8859-14";
+ if (strstart(l, "ro")) return "ISO-8859-2"; /* or ISO-8859-16 */
+ if (strstart(l, "am") || strstart(l, "vi")) return "UTF-8";
+ /* Send me further rules if you like, but don't forget that we are
+ * *only* interested in locale naming conventions on platforms
+ * that do not already provide an nl_langinfo(CODESET) implementation. */
+ }
+ return NULL;
+}
+
+#ifdef HAVE_LANGINFO_H
+char *nl_langinfo(nl_item item)
+{
+ const char *codeset;
+ if (item != CODESET)
+ return NULL;
+ codeset = nl_langinfo_codeset();
+ if (!codeset) codeset = C_CODESET;
+ return (char *)codeset;
+}
+#endif
+
+/* For a demo, compile with "gcc -W -Wall -o langinfo -D TEST langinfo.c" */
+
+#ifdef TEST
+#include <stdio.h>
+int main()
+{
+ printf("%s\n", nl_langinfo(CODESET));
+ return 0;
+}
+#endif
diff --git a/missing/lgamma_r.c b/missing/lgamma_r.c
new file mode 100644
index 0000000000..ba8535b18a
--- /dev/null
+++ b/missing/lgamma_r.c
@@ -0,0 +1,68 @@
+/* lgamma_r.c - public domain implementation of function lgamma_r(3m)
+
+lgamma_r() is based on gamma(). modified by Tanaka Akira.
+
+reference - Haruhiko Okumura: C-gengo niyoru saishin algorithm jiten
+ (New Algorithm handbook in C language) (Gijyutsu hyouron
+ sha, Tokyo, 1991) [in Japanese]
+ http://oku.edu.mie-u.ac.jp/~okumura/algo/
+*/
+
+/***********************************************************
+ gamma.c -- Gamma function
+***********************************************************/
+#include <math.h>
+#include <errno.h>
+#define PI 3.14159265358979324 /* $\pi$ */
+#define LOG_2PI 1.83787706640934548 /* $\log 2\pi$ */
+#define LOG_PI 1.14472988584940017 /* $\log_e \pi$ */
+#define N 8
+
+#define B0 1 /* Bernoulli numbers */
+#define B1 (-1.0 / 2.0)
+#define B2 ( 1.0 / 6.0)
+#define B4 (-1.0 / 30.0)
+#define B6 ( 1.0 / 42.0)
+#define B8 (-1.0 / 30.0)
+#define B10 ( 5.0 / 66.0)
+#define B12 (-691.0 / 2730.0)
+#define B14 ( 7.0 / 6.0)
+#define B16 (-3617.0 / 510.0)
+
+static double
+loggamma(double x) /* the natural logarithm of the Gamma function. */
+{
+ double v, w;
+
+ if (x == 1.0 || x == 2.0) return 0.0;
+
+ v = 1;
+ while (x < N) { v *= x; x++; }
+ w = 1 / (x * x);
+ return ((((((((B16 / (16 * 15)) * w + (B14 / (14 * 13))) * w
+ + (B12 / (12 * 11))) * w + (B10 / (10 * 9))) * w
+ + (B8 / ( 8 * 7))) * w + (B6 / ( 6 * 5))) * w
+ + (B4 / ( 4 * 3))) * w + (B2 / ( 2 * 1))) / x
+ + 0.5 * LOG_2PI - log(v) - x + (x - 0.5) * log(x);
+}
+
+/* the natural logarithm of the absolute value of the Gamma function */
+double
+lgamma_r(double x, int *signp)
+{
+ if (x <= 0) {
+ double i, f, s;
+ f = modf(-x, &i);
+ if (f == 0.0) { /* pole error */
+ *signp = 1;
+ errno = ERANGE;
+ return HUGE_VAL;
+ }
+ *signp = (fmod(i, 2.0) != 0.0) ? 1 : -1;
+ s = sin(PI * f);
+ if (s < 0) s = -s;
+ return LOG_PI - log(s) - loggamma(1 - x);
+ }
+ *signp = 1;
+ return loggamma(x);
+}
diff --git a/missing/memcmp.c b/missing/memcmp.c
index 9edc9c13b9..5b3ad3817a 100644
--- a/missing/memcmp.c
+++ b/missing/memcmp.c
@@ -1,16 +1,15 @@
/* public domain rewrite of memcmp(3) */
+#include <stddef.h>
+
int
-memcmp(s1,s2,len)
- char *s1;
- char *s2;
- register int len;
+memcmp(const void *s1, const void *s2, size_t len)
{
register unsigned char *a = (unsigned char*)s1;
register unsigned char *b = (unsigned char*)s2;
register int tmp;
- while (len--) {
+ for (; len; --len) {
if (tmp = *a++ - *b++)
return tmp;
}
diff --git a/missing/memmove.c b/missing/memmove.c
index c9d67d8b45..19c5f18847 100644
--- a/missing/memmove.c
+++ b/missing/memmove.c
@@ -1,22 +1,21 @@
/* public domain rewrite of memcmp(3) */
+#include <stddef.h>
+
void *
-memmove (d, s, n)
- void *d, *s;
- int n;
+memmove(void *d, const void *s, size_t n)
{
- char *dst = d;
- char *src = s;
- void *ret = dst;
+ char *dst = (char *)d;
+ const char *src = (const char *)s;
if (src < dst) {
src += n;
dst += n;
- while (n--)
+ for (; n; --n)
*--dst = *--src;
}
else if (dst < src)
- while (n--)
+ for (; n; --n)
*dst++ = *src++;
- return ret;
+ return d;
}
diff --git a/missing/os2.c b/missing/os2.c
index fe7238aad1..3448cdc281 100644
--- a/missing/os2.c
+++ b/missing/os2.c
@@ -17,11 +17,36 @@ chown(char *path, int owner, int group)
return 0;
}
+#if 0
int
link(char *from, char *to)
{
return -1;
}
+#endif
+
+#if defined(EMX_REPLACE_GETCWD) && (EMX_REPLACE_GETCWD) \
+ || defined(EMX_REPLACE_CHDIR) && (EMX_REPLACE_CHDIR)
+#include <unistd.h>
+
+#if defined(EMX_REPLACE_GETCWD) && (EMX_REPLACE_GETCWD)
+/* to handle the drive letter and DBCS characters within a given path */
+char *
+getcwd(char *path, size_t len)
+{
+ return _getcwd2(path, (int)len);
+}
+#endif
+
+#if defined(EMX_REPLACE_CHDIR) && (EMX_REPLACE_CHDIR)
+/* to handle the drive letter and DBCS characters within a given path */
+int
+chdir(__const__ char *path)
+{
+ return _chdir2(path);
+}
+#endif
+#endif
typedef char* CHARP;
diff --git a/missing/signbit.c b/missing/signbit.c
new file mode 100644
index 0000000000..2f7ce8c601
--- /dev/null
+++ b/missing/signbit.c
@@ -0,0 +1,19 @@
+#include <limits.h>
+#include "ruby.h"
+
+int
+signbit(double x)
+{
+ enum {double_per_long = sizeof(double) / sizeof(long)};
+ enum {long_msb = sizeof(long) * CHAR_BIT - 1};
+ union {double d; unsigned long i[double_per_long];} u;
+ unsigned long l;
+
+ u.d = x;
+#ifdef WORDS_BIGENDIAN
+ l = u.i[0];
+#else
+ l = u.i[double_per_long - 1];
+#endif
+ return (int)(l >> long_msb);
+}
diff --git a/missing/strcasecmp.c b/missing/strcasecmp.c
deleted file mode 100644
index fddb8385be..0000000000
--- a/missing/strcasecmp.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* public domain rewrite of strcasecmp(3) */
-
-#include <ctype.h>
-
-int
-strcasecmp(p1, p2)
- char *p1, *p2;
-{
- while (*p1 && *p2) {
- if (toupper(*p1) != toupper(*p2))
- return toupper(*p1) - toupper(*p2);
- p1++;
- p2++;
- }
- return strlen(p1) - strlen(p2);
-}
diff --git a/missing/strchr.c b/missing/strchr.c
index 886d70ede6..bebd7ba578 100644
--- a/missing/strchr.c
+++ b/missing/strchr.c
@@ -1,32 +1,28 @@
/* public domain rewrite of strchr(3) and strrchr(3) */
char *
-strchr(s, c)
- char *s;
- int c;
+strchr(const char *s, int c)
{
- if (c == 0) return s + strlen(s);
+ if (c == 0) return (char *)s + strlen(s);
while (*s) {
if (*s == c)
- return s;
+ return (char *)s;
s++;
}
return 0;
}
char *
-strrchr(s, c)
- char *s;
- int c;
+strrchr(const char *s, int c)
{
- char *save;
+ const char *save;
- if (c == 0) return s + strlen(s);
+ if (c == 0) return (char *)s + strlen(s);
save = 0;
while (*s) {
if (*s == c)
save = s;
s++;
}
- return save;
+ return (char *)save;
}
diff --git a/missing/strerror.c b/missing/strerror.c
index c1bf6feff8..023935a1ff 100644
--- a/missing/strerror.c
+++ b/missing/strerror.c
@@ -6,8 +6,7 @@ extern char *sys_errlist[];
static char msg[50];
char *
-strerror(error)
- int error;
+strerror(int error)
{
if (error <= sys_nerr && error > 0) {
return sys_errlist[error];
diff --git a/missing/strftime.c b/missing/strftime.c
deleted file mode 100644
index caa5eb8719..0000000000
--- a/missing/strftime.c
+++ /dev/null
@@ -1,903 +0,0 @@
-/*
- * strftime.c
- *
- * Public-domain implementation of ANSI C library routine.
- *
- * It's written in old-style C for maximal portability.
- * However, since I'm used to prototypes, I've included them too.
- *
- * If you want stuff in the System V ascftime routine, add the SYSV_EXT define.
- * For extensions from SunOS, add SUNOS_EXT.
- * For stuff needed to implement the P1003.2 date command, add POSIX2_DATE.
- * For VMS dates, add VMS_EXT.
- * For a an RFC822 time format, add MAILHEADER_EXT.
- * For ISO week years, add ISO_DATE_EXT.
- * For complete POSIX semantics, add POSIX_SEMANTICS.
- *
- * The code for %c, %x, and %X now follows the 1003.2 specification for
- * the POSIX locale.
- * This version ignores LOCALE information.
- * It also doesn't worry about multi-byte characters.
- * So there.
- *
- * This file is also shipped with GAWK (GNU Awk), gawk specific bits of
- * code are included if GAWK is defined.
- *
- * Arnold Robbins
- * January, February, March, 1991
- * Updated March, April 1992
- * Updated April, 1993
- * Updated February, 1994
- * Updated May, 1994
- * Updated January, 1995
- * Updated September, 1995
- * Updated January, 1996
- *
- * Fixes from ado@elsie.nci.nih.gov
- * February 1991, May 1992
- * Fixes from Tor Lillqvist tml@tik.vtt.fi
- * May, 1993
- * Further fixes from ado@elsie.nci.nih.gov
- * February 1994
- * %z code from chip@chinacat.unicom.com
- * Applied September 1995
- * %V code fixed (again) and %G, %g added,
- * January 1996
- */
-
-#include "config.h"
-
-#ifndef GAWK
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <time.h>
-#endif
-#if defined(TM_IN_SYS_TIME) || !defined(GAWK) && !defined(_WIN32_WCE)
-#include <sys/types.h>
-#include <sys/time.h>
-#endif
-
-/* defaults: season to taste */
-#define SYSV_EXT 1 /* stuff in System V ascftime routine */
-#define SUNOS_EXT 1 /* stuff in SunOS strftime routine */
-#define POSIX2_DATE 1 /* stuff in Posix 1003.2 date command */
-#define VMS_EXT 1 /* include %v for VMS date format */
-#define MAILHEADER_EXT 1 /* add %z for HHMM format */
-#define ISO_DATE_EXT 1 /* %G and %g for year of ISO week */
-#ifndef GAWK
-#define POSIX_SEMANTICS 1 /* call tzset() if TZ changes */
-#endif
-
-#if defined(ISO_DATE_EXT)
-#if ! defined(POSIX2_DATE)
-#define POSIX2_DATE 1
-#endif
-#endif
-
-#if defined(POSIX2_DATE)
-#if ! defined(SYSV_EXT)
-#define SYSV_EXT 1
-#endif
-#if ! defined(SUNOS_EXT)
-#define SUNOS_EXT 1
-#endif
-#endif
-
-#if defined(POSIX2_DATE)
-#define adddecl(stuff) stuff
-#else
-#define adddecl(stuff)
-#endif
-
-#undef strchr /* avoid AIX weirdness */
-
-#ifndef __STDC__
-#define const /**/
-extern void tzset();
-static int weeknumber();
-adddecl(static int iso8601wknum();)
-#else
-extern void tzset(void);
-static int weeknumber(const struct tm *timeptr, int firstweekday);
-adddecl(static int iso8601wknum(const struct tm *timeptr);)
-#endif
-
-#ifdef STDC_HEADERS
-#include <stdlib.h>
-#include <string.h>
-#else
-extern void *malloc();
-extern void *realloc();
-extern char *getenv();
-extern char *strchr();
-#endif
-
-#define range(low, item, hi) max(low, min(item, hi))
-
-#ifdef __CYGWIN__
-#define DLL_IMPORT __declspec(dllimport)
-#endif
-#ifdef __WIN32__
-#define DLL_IMPORT __declspec(dllimport)
-#endif
-#if !defined(OS2) && !defined(MSDOS) && defined(HAVE_TZNAME)
-extern DLL_IMPORT char *tzname[2];
-#ifdef HAVE_DAYLIGHT
-extern DLL_IMPORT int daylight;
-#endif
-#ifdef HAVE_VAR_TIMEZONE
-extern DLL_IMPORT TYPEOF_VAR_TIMEZONE timezone;
-#endif
-#ifdef HAVE_VAR_ALTZONE
-extern DLL_IMPORT TYPEOF_VAR_ALTZONE altzone;
-#endif
-#endif
-
-#undef min /* just in case */
-
-/* min --- return minimum of two numbers */
-
-#ifndef __STDC__
-static inline int
-min(a, b)
-int a, b;
-#else
-static inline int
-min(int a, int b)
-#endif
-{
- return (a < b ? a : b);
-}
-
-#undef max /* also, just in case */
-
-/* max --- return maximum of two numbers */
-
-#ifndef __STDC__
-static inline int
-max(a, b)
-int a, b;
-#else
-static inline int
-max(int a, int b)
-#endif
-{
- return (a > b ? a : b);
-}
-
-/* strftime --- produce formatted time */
-
-#ifndef __STDC__
-size_t
-strftime(s, maxsize, format, timeptr)
-char *s;
-size_t maxsize;
-const char *format;
-const struct tm *timeptr;
-#else
-size_t
-strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
-#endif
-{
- char *endp = s + maxsize;
- char *start = s;
- auto char tbuf[100];
- long off;
- int i, w;
- long y;
- static short first = 1;
-#ifdef POSIX_SEMANTICS
- static char *savetz = NULL;
- static int savetzlen = 0;
- char *tz;
-#endif /* POSIX_SEMANTICS */
-#ifndef HAVE_TM_ZONE
-#ifndef HAVE_TM_NAME
- struct timeval tv;
- struct timezone zone;
-#endif /* HAVE_TM_NAME */
-#endif /* HAVE_TM_ZONE */
-
- /* various tables, useful in North America */
- static const char *days_a[] = {
- "Sun", "Mon", "Tue", "Wed",
- "Thu", "Fri", "Sat",
- };
- static const char *days_l[] = {
- "Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday",
- };
- static const char *months_a[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
- };
- static const char *months_l[] = {
- "January", "February", "March", "April",
- "May", "June", "July", "August", "September",
- "October", "November", "December",
- };
- static const char *ampm[] = { "AM", "PM", };
-
- if (s == NULL || format == NULL || timeptr == NULL || maxsize == 0)
- return 0;
-
- /* quick check if we even need to bother */
- if (strchr(format, '%') == NULL && strlen(format) + 1 >= maxsize)
- return 0;
-
-#ifndef POSIX_SEMANTICS
- if (first) {
- tzset();
- first = 0;
- }
-#else /* POSIX_SEMANTICS */
- tz = getenv("TZ");
- if (first) {
- if (tz != NULL) {
- int tzlen = strlen(tz);
-
- savetz = (char *) malloc(tzlen + 1);
- if (savetz != NULL) {
- savetzlen = tzlen + 1;
- strcpy(savetz, tz);
- }
- }
- tzset();
- first = 0;
- }
- /* if we have a saved TZ, and it is different, recapture and reset */
- if (tz && savetz && (tz[0] != savetz[0] || strcmp(tz, savetz) != 0)) {
- i = strlen(tz) + 1;
- if (i > savetzlen) {
- savetz = (char *) realloc(savetz, i);
- if (savetz) {
- savetzlen = i;
- strcpy(savetz, tz);
- }
- } else
- strcpy(savetz, tz);
- tzset();
- }
-#endif /* POSIX_SEMANTICS */
-
- for (; *format && s < endp - 1; format++) {
- tbuf[0] = '\0';
- if (*format != '%') {
- *s++ = *format;
- continue;
- }
- again:
- switch (*++format) {
- case '\0':
- *s++ = '%';
- goto out;
-
- case '%':
- *s++ = '%';
- continue;
-
- case 'a': /* abbreviated weekday name */
- if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
- strcpy(tbuf, "?");
- else
- strcpy(tbuf, days_a[timeptr->tm_wday]);
- break;
-
- case 'A': /* full weekday name */
- if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
- strcpy(tbuf, "?");
- else
- strcpy(tbuf, days_l[timeptr->tm_wday]);
- break;
-
-#ifdef SYSV_EXT
- case 'h': /* abbreviated month name */
-#endif
- case 'b': /* abbreviated month name */
- if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
- strcpy(tbuf, "?");
- else
- strcpy(tbuf, months_a[timeptr->tm_mon]);
- break;
-
- case 'B': /* full month name */
- if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
- strcpy(tbuf, "?");
- else
- strcpy(tbuf, months_l[timeptr->tm_mon]);
- break;
-
- case 'c': /* appropriate date and time representation */
- strftime(tbuf, sizeof tbuf, "%a %b %e %H:%M:%S %Y", timeptr);
- break;
-
- case 'd': /* day of the month, 01 - 31 */
- i = range(1, timeptr->tm_mday, 31);
- sprintf(tbuf, "%02d", i);
- break;
-
- case 'H': /* hour, 24-hour clock, 00 - 23 */
- i = range(0, timeptr->tm_hour, 23);
- sprintf(tbuf, "%02d", i);
- break;
-
- case 'I': /* hour, 12-hour clock, 01 - 12 */
- i = range(0, timeptr->tm_hour, 23);
- if (i == 0)
- i = 12;
- else if (i > 12)
- i -= 12;
- sprintf(tbuf, "%02d", i);
- break;
-
- case 'j': /* day of the year, 001 - 366 */
- sprintf(tbuf, "%03d", timeptr->tm_yday + 1);
- break;
-
- case 'm': /* month, 01 - 12 */
- i = range(0, timeptr->tm_mon, 11);
- sprintf(tbuf, "%02d", i + 1);
- break;
-
- case 'M': /* minute, 00 - 59 */
- i = range(0, timeptr->tm_min, 59);
- sprintf(tbuf, "%02d", i);
- break;
-
- case 'p': /* am or pm based on 12-hour clock */
- i = range(0, timeptr->tm_hour, 23);
- if (i < 12)
- strcpy(tbuf, ampm[0]);
- else
- strcpy(tbuf, ampm[1]);
- break;
-
- case 'S': /* second, 00 - 60 */
- i = range(0, timeptr->tm_sec, 60);
- sprintf(tbuf, "%02d", i);
- break;
-
- case 'U': /* week of year, Sunday is first day of week */
- sprintf(tbuf, "%02d", weeknumber(timeptr, 0));
- break;
-
- case 'w': /* weekday, Sunday == 0, 0 - 6 */
- i = range(0, timeptr->tm_wday, 6);
- sprintf(tbuf, "%d", i);
- break;
-
- case 'W': /* week of year, Monday is first day of week */
- sprintf(tbuf, "%02d", weeknumber(timeptr, 1));
- break;
-
- case 'x': /* appropriate date representation */
- strftime(tbuf, sizeof tbuf, "%m/%d/%y", timeptr);
- break;
-
- case 'X': /* appropriate time representation */
- strftime(tbuf, sizeof tbuf, "%H:%M:%S", timeptr);
- break;
-
- case 'y': /* year without a century, 00 - 99 */
- i = timeptr->tm_year % 100;
- sprintf(tbuf, "%02d", i);
- break;
-
- case 'Y': /* year with century */
- sprintf(tbuf, "%ld", 1900L + timeptr->tm_year);
- break;
-
-#ifdef MAILHEADER_EXT
- /*
- * From: Chip Rosenthal <chip@chinacat.unicom.com>
- * Date: Sun, 19 Mar 1995 00:33:29 -0600 (CST)
- *
- * Warning: the %z [code] is implemented by inspecting the
- * timezone name conditional compile settings, and
- * inferring a method to get timezone offsets. I've tried
- * this code on a couple of machines, but I don't doubt
- * there is some system out there that won't like it.
- * Maybe the easiest thing to do would be to bracket this
- * with an #ifdef that can turn it off. The %z feature
- * would be an admittedly obscure one that most folks can
- * live without, but it would be a great help to those of
- * us that muck around with various message processors.
- */
- case 'z': /* time zone offset east of GMT e.g. -0600 */
-#ifdef HAVE_TM_NAME
- /*
- * Systems with tm_name probably have tm_tzadj as
- * secs west of GMT. Convert to mins east of GMT.
- */
- off = -timeptr->tm_tzadj / 60;
-#else /* !HAVE_TM_NAME */
-#ifdef HAVE_TM_ZONE
- /*
- * Systems with tm_zone probably have tm_gmtoff as
- * secs east of GMT. Convert to mins east of GMT.
- */
- off = timeptr->tm_gmtoff / 60;
-#else /* !HAVE_TM_ZONE */
-#ifdef HAVE_GETTIMEOFDAY
- gettimeofday(&tv, &zone);
- off = -zone.tz_minuteswest;
-#else
-#if HAVE_VAR_TIMEZONE
-#if HAVE_VAR_ALTZONE
- off = -(daylight ? timezone : altzone) / 60;
-#else
- off = -timezone / 60;
-#endif
-#endif
-#endif
-#endif /* !HAVE_TM_ZONE */
-#endif /* !HAVE_TM_NAME */
- if (off < 0) {
- tbuf[0] = '-';
- off = -off;
- } else {
- tbuf[0] = '+';
- }
- sprintf(tbuf+1, "%02u%02u", (unsigned)off/60, (unsigned)off%60);
- break;
-#endif /* MAILHEADER_EXT */
-
- case 'Z': /* time zone name or abbrevation */
-#ifdef HAVE_TZNAME
- i = (daylight && timeptr->tm_isdst > 0); /* 0 or 1 */
- strcpy(tbuf, tzname[i]);
-#else
-#ifdef HAVE_TM_ZONE
- strcpy(tbuf, timeptr->tm_zone);
-#else
-#ifdef HAVE_TM_NAME
- strcpy(tbuf, timeptr->tm_name);
-#else
-#ifdef HAVE_TIMEZONE
- gettimeofday(& tv, & zone);
-#ifdef TIMEZONE_VOID
- strcpy(tbuf, timezone());
-#else
- strcpy(tbuf, timezone(zone.tz_minuteswest,
- timeptr->tm_isdst > 0));
-#endif /* TIMEZONE_VOID */
-#endif /* HAVE_TIMEZONE */
-#endif /* HAVE_TM_NAME */
-#endif /* HAVE_TM_ZONE */
-#endif /* HAVE_TZNAME */
- break;
-
-#ifdef SYSV_EXT
- case 'n': /* same as \n */
- tbuf[0] = '\n';
- tbuf[1] = '\0';
- break;
-
- case 't': /* same as \t */
- tbuf[0] = '\t';
- tbuf[1] = '\0';
- break;
-
- case 'D': /* date as %m/%d/%y */
- strftime(tbuf, sizeof tbuf, "%m/%d/%y", timeptr);
- break;
-
- case 'e': /* day of month, blank padded */
- sprintf(tbuf, "%2d", range(1, timeptr->tm_mday, 31));
- break;
-
- case 'r': /* time as %I:%M:%S %p */
- strftime(tbuf, sizeof tbuf, "%I:%M:%S %p", timeptr);
- break;
-
- case 'R': /* time as %H:%M */
- strftime(tbuf, sizeof tbuf, "%H:%M", timeptr);
- break;
-
- case 'T': /* time as %H:%M:%S */
- strftime(tbuf, sizeof tbuf, "%H:%M:%S", timeptr);
- break;
-#endif
-
-#ifdef SUNOS_EXT
- case 'k': /* hour, 24-hour clock, blank pad */
- sprintf(tbuf, "%2d", range(0, timeptr->tm_hour, 23));
- break;
-
- case 'l': /* hour, 12-hour clock, 1 - 12, blank pad */
- i = range(0, timeptr->tm_hour, 23);
- if (i == 0)
- i = 12;
- else if (i > 12)
- i -= 12;
- sprintf(tbuf, "%2d", i);
- break;
-#endif
-
-
-#ifdef VMS_EXT
- case 'v': /* date as dd-bbb-YYYY */
- sprintf(tbuf, "%2d-%3.3s-%4ld",
- range(1, timeptr->tm_mday, 31),
- months_a[range(0, timeptr->tm_mon, 11)],
- timeptr->tm_year + 1900L);
- for (i = 3; i < 6; i++)
- if (islower(tbuf[i]))
- tbuf[i] = toupper(tbuf[i]);
- break;
-#endif
-
-
-#ifdef POSIX2_DATE
- case 'C':
- sprintf(tbuf, "%02ld", (timeptr->tm_year + 1900L) / 100);
- break;
-
-
- case 'E':
- case 'O':
- /* POSIX locale extensions, ignored for now */
- goto again;
-
- case 'V': /* week of year according ISO 8601 */
- sprintf(tbuf, "%02d", iso8601wknum(timeptr));
- break;
-
- case 'u':
- /* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */
- sprintf(tbuf, "%d", timeptr->tm_wday == 0 ? 7 :
- timeptr->tm_wday);
- break;
-#endif /* POSIX2_DATE */
-
-#ifdef ISO_DATE_EXT
- case 'G':
- case 'g':
- /*
- * Year of ISO week.
- *
- * If it's December but the ISO week number is one,
- * that week is in next year.
- * If it's January but the ISO week number is 52 or
- * 53, that week is in last year.
- * Otherwise, it's this year.
- */
- w = iso8601wknum(timeptr);
- if (timeptr->tm_mon == 11 && w == 1)
- y = 1900L + timeptr->tm_year + 1;
- else if (timeptr->tm_mon == 0 && w >= 52)
- y = 1900L + timeptr->tm_year - 1;
- else
- y = 1900L + timeptr->tm_year;
-
- if (*format == 'G')
- sprintf(tbuf, "%ld", y);
- else
- sprintf(tbuf, "%02ld", y % 100);
- break;
-#endif /* ISO_DATE_EXT */
- default:
- tbuf[0] = '%';
- tbuf[1] = *format;
- tbuf[2] = '\0';
- break;
- }
- i = strlen(tbuf);
- if (i) {
- if (s + i < endp - 1) {
- strcpy(s, tbuf);
- s += i;
- } else
- return 0;
- }
- }
-out:
- if (s < endp && *format == '\0') {
- *s = '\0';
- return (s - start);
- } else
- return 0;
-}
-
-/* isleap --- is a year a leap year? */
-
-#ifndef __STDC__
-static int
-isleap(year)
-long year;
-#else
-static int
-isleap(long year)
-#endif
-{
- return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
-}
-
-
-#ifdef POSIX2_DATE
-/* iso8601wknum --- compute week number according to ISO 8601 */
-
-#ifndef __STDC__
-static int
-iso8601wknum(timeptr)
-const struct tm *timeptr;
-#else
-static int
-iso8601wknum(const struct tm *timeptr)
-#endif
-{
- /*
- * From 1003.2:
- * If the week (Monday to Sunday) containing January 1
- * has four or more days in the new year, then it is week 1;
- * otherwise it is the highest numbered week of the previous
- * year (52 or 53), and the next week is week 1.
- *
- * ADR: This means if Jan 1 was Monday through Thursday,
- * it was week 1, otherwise week 52 or 53.
- *
- * XPG4 erroneously included POSIX.2 rationale text in the
- * main body of the standard. Thus it requires week 53.
- */
-
- int weeknum, jan1day;
-
- /* get week number, Monday as first day of the week */
- weeknum = weeknumber(timeptr, 1);
-
- /*
- * With thanks and tip of the hatlo to tml@tik.vtt.fi
- *
- * What day of the week does January 1 fall on?
- * We know that
- * (timeptr->tm_yday - jan1.tm_yday) MOD 7 ==
- * (timeptr->tm_wday - jan1.tm_wday) MOD 7
- * and that
- * jan1.tm_yday == 0
- * and that
- * timeptr->tm_wday MOD 7 == timeptr->tm_wday
- * from which it follows that. . .
- */
- jan1day = timeptr->tm_wday - (timeptr->tm_yday % 7);
- if (jan1day < 0)
- jan1day += 7;
-
- /*
- * If Jan 1 was a Monday through Thursday, it was in
- * week 1. Otherwise it was last year's highest week, which is
- * this year's week 0.
- *
- * What does that mean?
- * If Jan 1 was Monday, the week number is exactly right, it can
- * never be 0.
- * If it was Tuesday through Thursday, the weeknumber is one
- * less than it should be, so we add one.
- * Otherwise, Friday, Saturday or Sunday, the week number is
- * OK, but if it is 0, it needs to be 52 or 53.
- */
- switch (jan1day) {
- case 1: /* Monday */
- break;
- case 2: /* Tuesday */
- case 3: /* Wednesday */
- case 4: /* Thursday */
- weeknum++;
- break;
- case 5: /* Friday */
- case 6: /* Saturday */
- case 0: /* Sunday */
- if (weeknum == 0) {
-#ifdef USE_BROKEN_XPG4
- /* XPG4 (as of March 1994) says 53 unconditionally */
- weeknum = 53;
-#else
- /* get week number of last week of last year */
- struct tm dec31ly; /* 12/31 last year */
- dec31ly = *timeptr;
- dec31ly.tm_year--;
- dec31ly.tm_mon = 11;
- dec31ly.tm_mday = 31;
- dec31ly.tm_wday = (jan1day == 0) ? 6 : jan1day - 1;
- dec31ly.tm_yday = 364 + isleap(dec31ly.tm_year + 1900L);
- weeknum = iso8601wknum(& dec31ly);
-#endif
- }
- break;
- }
-
- if (timeptr->tm_mon == 11) {
- /*
- * The last week of the year
- * can be in week 1 of next year.
- * Sigh.
- *
- * This can only happen if
- * M T W
- * 29 30 31
- * 30 31
- * 31
- */
- int wday, mday;
-
- wday = timeptr->tm_wday;
- mday = timeptr->tm_mday;
- if ( (wday == 1 && (mday >= 29 && mday <= 31))
- || (wday == 2 && (mday == 30 || mday == 31))
- || (wday == 3 && mday == 31))
- weeknum = 1;
- }
-
- return weeknum;
-}
-#endif
-
-/* weeknumber --- figure how many weeks into the year */
-
-/* With thanks and tip of the hatlo to ado@elsie.nci.nih.gov */
-
-#ifndef __STDC__
-static int
-weeknumber(timeptr, firstweekday)
-const struct tm *timeptr;
-int firstweekday;
-#else
-static int
-weeknumber(const struct tm *timeptr, int firstweekday)
-#endif
-{
- int wday = timeptr->tm_wday;
- int ret;
-
- if (firstweekday == 1) {
- if (wday == 0) /* sunday */
- wday = 6;
- else
- wday--;
- }
- ret = ((timeptr->tm_yday + 7 - wday) / 7);
- if (ret < 0)
- ret = 0;
- return ret;
-}
-
-#if 0
-/* ADR --- I'm loathe to mess with ado's code ... */
-
-Date: Wed, 24 Apr 91 20:54:08 MDT
-From: Michal Jaegermann <audfax!emory!vm.ucs.UAlberta.CA!NTOMCZAK>
-To: arnold@audiofax.com
-
-Hi Arnold,
-in a process of fixing of strftime() in libraries on Atari ST I grabbed
-some pieces of code from your own strftime. When doing that it came
-to mind that your weeknumber() function compiles a little bit nicer
-in the following form:
-/*
- * firstweekday is 0 if starting in Sunday, non-zero if in Monday
- */
-{
- return (timeptr->tm_yday - timeptr->tm_wday +
- (firstweekday ? (timeptr->tm_wday ? 8 : 1) : 7)) / 7;
-}
-How nicer it depends on a compiler, of course, but always a tiny bit.
-
- Cheers,
- Michal
- ntomczak@vm.ucs.ualberta.ca
-#endif
-
-#ifdef TEST_STRFTIME
-
-/*
- * NAME:
- * tst
- *
- * SYNOPSIS:
- * tst
- *
- * DESCRIPTION:
- * "tst" is a test driver for the function "strftime".
- *
- * OPTIONS:
- * None.
- *
- * AUTHOR:
- * Karl Vogel
- * Control Data Systems, Inc.
- * vogelke@c-17igp.wpafb.af.mil
- *
- * BUGS:
- * None noticed yet.
- *
- * COMPILE:
- * cc -o tst -DTEST_STRFTIME strftime.c
- */
-
-/* ADR: I reformatted this to my liking, and deleted some unneeded code. */
-
-#ifndef NULL
-#include <stdio.h>
-#endif
-#include <sys/time.h>
-#include <string.h>
-
-#define MAXTIME 132
-
-/*
- * Array of time formats.
- */
-
-static char *array[] =
-{
- "(%%A) full weekday name, var length (Sunday..Saturday) %A",
- "(%%B) full month name, var length (January..December) %B",
- "(%%C) Century %C",
- "(%%D) date (%%m/%%d/%%y) %D",
- "(%%E) Locale extensions (ignored) %E",
- "(%%H) hour (24-hour clock, 00..23) %H",
- "(%%I) hour (12-hour clock, 01..12) %I",
- "(%%M) minute (00..59) %M",
- "(%%O) Locale extensions (ignored) %O",
- "(%%R) time, 24-hour (%%H:%%M) %R",
- "(%%S) second (00..60) %S",
- "(%%T) time, 24-hour (%%H:%%M:%%S) %T",
- "(%%U) week of year, Sunday as first day of week (00..53) %U",
- "(%%V) week of year according to ISO 8601 %V",
- "(%%W) week of year, Monday as first day of week (00..53) %W",
- "(%%X) appropriate locale time representation (%H:%M:%S) %X",
- "(%%Y) year with century (1970...) %Y",
- "(%%Z) timezone (EDT), or blank if timezone not determinable %Z",
- "(%%a) locale's abbreviated weekday name (Sun..Sat) %a",
- "(%%b) locale's abbreviated month name (Jan..Dec) %b",
- "(%%c) full date (Sat Nov 4 12:02:33 1989)%n%t%t%t %c",
- "(%%d) day of the month (01..31) %d",
- "(%%e) day of the month, blank-padded ( 1..31) %e",
- "(%%h) should be same as (%%b) %h",
- "(%%j) day of the year (001..366) %j",
- "(%%k) hour, 24-hour clock, blank pad ( 0..23) %k",
- "(%%l) hour, 12-hour clock, blank pad ( 0..12) %l",
- "(%%m) month (01..12) %m",
- "(%%p) locale's AM or PM based on 12-hour clock %p",
- "(%%r) time, 12-hour (same as %%I:%%M:%%S %%p) %r",
- "(%%u) ISO 8601: Weekday as decimal number [1 (Monday) - 7] %u",
- "(%%v) VMS date (dd-bbb-YYYY) %v",
- "(%%w) day of week (0..6, Sunday == 0) %w",
- "(%%x) appropriate locale date representation %x",
- "(%%y) last two digits of year (00..99) %y",
- "(%%z) timezone offset east of GMT as HHMM (e.g. -0500) %z",
- (char *) NULL
-};
-
-/* main routine. */
-
-int
-main(argc, argv)
-int argc;
-char **argv;
-{
- long time();
-
- char *next;
- char string[MAXTIME];
-
- int k;
- int length;
-
- struct tm *tm;
-
- long clock;
-
- /* Call the function. */
-
- clock = time((long *) 0);
- tm = localtime(&clock);
-
- for (k = 0; next = array[k]; k++) {
- length = strftime(string, MAXTIME, next, tm);
- printf("%s\n", string);
- }
-
- exit(0);
-}
-#endif /* TEST_STRFTIME */
diff --git a/missing/strlcat.c b/missing/strlcat.c
new file mode 100644
index 0000000000..b309648155
--- /dev/null
+++ b/missing/strlcat.c
@@ -0,0 +1,73 @@
+/* $OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$OpenBSD: strlcat.c,v 1.8 2001/05/13 15:40:15 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Appends src to string dst of size siz (unlike strncat, siz is the
+ * full size of dst, not space left). At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
+ * Returns strlen(src) + MIN(siz, strlen(initial dst)).
+ * If retval >= siz, truncation occurred.
+ */
+size_t
+strlcat(dst, src, siz)
+ char *dst;
+ const char *src;
+ size_t siz;
+{
+ register char *d = dst;
+ register const char *s = src;
+ register size_t n = siz;
+ size_t dlen;
+
+ /* Find the end of dst and adjust bytes left but don't go past end */
+ while (n-- != 0 && *d != '\0')
+ d++;
+ dlen = d - dst;
+ n = siz - dlen;
+
+ if (n == 0)
+ return(dlen + strlen(s));
+ while (*s != '\0') {
+ if (n != 1) {
+ *d++ = *s;
+ n--;
+ }
+ s++;
+ }
+ *d = '\0';
+
+ return(dlen + (s - src)); /* count does not include NUL */
+}
diff --git a/missing/strlcpy.c b/missing/strlcpy.c
new file mode 100644
index 0000000000..5f586964b7
--- /dev/null
+++ b/missing/strlcpy.c
@@ -0,0 +1,69 @@
+/* $OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $ */
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$OpenBSD: strlcpy.c,v 1.5 2001/05/13 15:40:16 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <sys/types.h>
+#include <string.h>
+
+/*
+ * Copy src to string dst of size siz. At most siz-1 characters
+ * will be copied. Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+strlcpy(dst, src, siz)
+ char *dst;
+ const char *src;
+ size_t siz;
+{
+ register char *d = dst;
+ register const char *s = src;
+ register size_t n = siz;
+
+ /* Copy as many bytes as will fit */
+ if (n != 0 && --n != 0) {
+ do {
+ if ((*d++ = *s++) == 0)
+ break;
+ } while (--n != 0);
+ }
+
+ /* Not enough room in dst, add NUL and traverse rest of src */
+ if (n == 0) {
+ if (siz != 0)
+ *d = '\0'; /* NUL-terminate dst */
+ while (*s++)
+ ;
+ }
+
+ return(s - src - 1); /* count does not include NUL */
+}
diff --git a/missing/strncasecmp.c b/missing/strncasecmp.c
deleted file mode 100644
index a4cc5828b8..0000000000
--- a/missing/strncasecmp.c
+++ /dev/null
@@ -1,21 +0,0 @@
-/* public domain rewrite of strncasecmp(3) */
-
-#include <ctype.h>
-
-int
-strncasecmp(p1, p2, len)
- char *p1;
- char *p2;
- int len;
-{
- while (len != 0) {
- if (toupper(*p1) != toupper(*p2)) {
- return toupper(*p1) - toupper(*p2);
- }
- if (*p1 == '\0') {
- return 0;
- }
- len--; p1++; p2++;
- }
- return 0;
-}
diff --git a/missing/strstr.c b/missing/strstr.c
index 1673518f06..2e9c282fb1 100644
--- a/missing/strstr.c
+++ b/missing/strstr.c
@@ -1,20 +1,19 @@
/* public domain rewrite of strstr(3) */
char *
-strstr(haystack, needle)
- char *haystack, *needle;
+strstr(const char *haystack, const char *needle)
{
- char *hend;
- char *a, *b;
+ const char *hend;
+ const char *a, *b;
- if (*needle == 0) return haystack;
+ if (*needle == 0) return (char *)haystack;
hend = haystack + strlen(haystack) - strlen(needle) + 1;
while (haystack < hend) {
if (*haystack == *needle) {
a = haystack;
b = needle;
for (;;) {
- if (*b == 0) return haystack;
+ if (*b == 0) return (char *)haystack;
if (*a++ != *b++) {
break;
}
diff --git a/missing/strtod.c b/missing/strtod.c
deleted file mode 100644
index fdccd48081..0000000000
--- a/missing/strtod.c
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * strtod.c --
- *
- * Source code for the "strtod" library procedure.
- *
- * Copyright (c) 1988-1993 The Regents of the University of California.
- * Copyright (c) 1994 Sun Microsystems, Inc.
- *
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The University of California
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- *
- * RCS: @(#) $Id$
- */
-
-#include "config.h"
-#ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-#include <ctype.h>
-#include <errno.h>
-extern int errno;
-
-#ifndef __STDC__
-# ifdef __GNUC__
-# define const __const__
-# else
-# define const
-# endif
-#endif
-
-#ifndef TRUE
-#define TRUE 1
-#define FALSE 0
-#endif
-#ifndef NULL
-#define NULL 0
-#endif
-
-static int maxExponent = 511; /* Largest possible base 10 exponent. Any
- * exponent larger than this will already
- * produce underflow or overflow, so there's
- * no need to worry about additional digits.
- */
-static double powersOf10[] = { /* Table giving binary powers of 10. Entry */
- 10., /* is 10^2^i. Used to convert decimal */
- 100., /* exponents into floating-point numbers. */
- 1.0e4,
- 1.0e8,
- 1.0e16,
- 1.0e32,
- 1.0e64,
- 1.0e128,
- 1.0e256
-};
-
-/*
- *----------------------------------------------------------------------
- *
- * strtod --
- *
- * This procedure converts a floating-point number from an ASCII
- * decimal representation to internal double-precision format.
- *
- * Results:
- * The return value is the double-precision floating-point
- * representation of the characters in string. If endPtr isn't
- * NULL, then *endPtr is filled in with the address of the
- * next character after the last one that was part of the
- * floating-point number.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-double
-strtod(string, endPtr)
- const char *string; /* A decimal ASCII floating-point number,
- * optionally preceded by white space.
- * Must have form "-I.FE-X", where I is the
- * integer part of the mantissa, F is the
- * fractional part of the mantissa, and X
- * is the exponent. Either of the signs
- * may be "+", "-", or omitted. Either I
- * or F may be omitted, or both. The decimal
- * point isn't necessary unless F is present.
- * The "E" may actually be an "e". E and X
- * may both be omitted (but not just one).
- */
- char **endPtr; /* If non-NULL, store terminating character's
- * address here. */
-{
- int sign, expSign = FALSE;
- double fraction, dblExp, *d;
- register const char *p;
- register int c;
- int exp = 0; /* Exponent read from "EX" field. */
- int fracExp = 0; /* Exponent that derives from the fractional
- * part. Under normal circumstatnces, it is
- * the negative of the number of digits in F.
- * However, if I is very long, the last digits
- * of I get dropped (otherwise a long I with a
- * large negative exponent could cause an
- * unnecessary overflow on I alone). In this
- * case, fracExp is incremented one for each
- * dropped digit. */
- int mantSize; /* Number of digits in mantissa. */
- int decPt; /* Number of mantissa digits BEFORE decimal
- * point. */
- const char *pExp; /* Temporarily holds location of exponent
- * in string. */
-
- /*
- * Strip off leading blanks and check for a sign.
- */
-
- p = string;
- while (isspace(*p)) {
- p += 1;
- }
- if (*p == '-') {
- sign = TRUE;
- p += 1;
- } else {
- if (*p == '+') {
- p += 1;
- }
- sign = FALSE;
- }
-
- /*
- * Count the number of digits in the mantissa (including the decimal
- * point), and also locate the decimal point.
- */
-
- decPt = -1;
- for (mantSize = 0; ; mantSize += 1)
- {
- c = *p;
- if (!isdigit(c)) {
- if ((c != '.') || (decPt >= 0)) {
- break;
- }
- decPt = mantSize;
- }
- p += 1;
- }
-
- /*
- * Now suck up the digits in the mantissa. Use two integers to
- * collect 9 digits each (this is faster than using floating-point).
- * If the mantissa has more than 18 digits, ignore the extras, since
- * they can't affect the value anyway.
- */
-
- pExp = p;
- p -= mantSize;
- if (decPt < 0) {
- decPt = mantSize;
- } else {
- mantSize -= 1; /* One of the digits was the point. */
- }
- if (mantSize > 18) {
- fracExp = decPt - 18;
- mantSize = 18;
- } else {
- fracExp = decPt - mantSize;
- }
- if (mantSize == 0) {
- fraction = 0.0;
- p = string;
- goto done;
- } else {
- int frac1, frac2;
- frac1 = 0;
- for ( ; mantSize > 9; mantSize -= 1)
- {
- c = *p;
- p += 1;
- if (c == '.') {
- c = *p;
- p += 1;
- }
- frac1 = 10*frac1 + (c - '0');
- }
- frac2 = 0;
- for (; mantSize > 0; mantSize -= 1)
- {
- c = *p;
- p += 1;
- if (c == '.') {
- c = *p;
- p += 1;
- }
- frac2 = 10*frac2 + (c - '0');
- }
- fraction = (1.0e9 * frac1) + frac2;
- }
-
- /*
- * Skim off the exponent.
- */
-
- p = pExp;
- if ((*p == 'E') || (*p == 'e')) {
- p += 1;
- if (*p == '-') {
- expSign = TRUE;
- p += 1;
- } else {
- if (*p == '+') {
- p += 1;
- }
- expSign = FALSE;
- }
- while (isdigit(*p)) {
- exp = exp * 10 + (*p - '0');
- p += 1;
- }
- }
- if (expSign) {
- exp = fracExp - exp;
- } else {
- exp = fracExp + exp;
- }
-
- /*
- * Generate a floating-point number that represents the exponent.
- * Do this by processing the exponent one bit at a time to combine
- * many powers of 2 of 10. Then combine the exponent with the
- * fraction.
- */
-
- if (exp < 0) {
- expSign = TRUE;
- exp = -exp;
- } else {
- expSign = FALSE;
- }
- if (exp > maxExponent) {
- exp = maxExponent;
- errno = ERANGE;
- }
- dblExp = 1.0;
- for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
- if (exp & 01) {
- dblExp *= *d;
- }
- }
- if (expSign) {
- fraction /= dblExp;
- } else {
- fraction *= dblExp;
- }
-
-done:
- if (endPtr != NULL) {
- *endPtr = (char *) p;
- }
-
- if (sign) {
- return -fraction;
- }
- return fraction;
-}
diff --git a/missing/strtol.c b/missing/strtol.c
index e94aa54ca0..da6636f316 100644
--- a/missing/strtol.c
+++ b/missing/strtol.c
@@ -3,13 +3,10 @@
#include <ctype.h>
long
-strtol(nptr, endptr, base)
- char *nptr;
- char **endptr;
- int base;
+strtol(const char *nptr, char **endptr, int base)
{
long result;
- char *p = nptr;
+ const char *p = nptr;
while (isspace(*p)) {
p++;
@@ -23,7 +20,7 @@ strtol(nptr, endptr, base)
result = strtoul(p, endptr, base);
}
if (endptr != 0 && *endptr == p) {
- *endptr = nptr;
+ *endptr = (char *)nptr;
}
return result;
}
diff --git a/missing/strtoul.c b/missing/strtoul.c
deleted file mode 100644
index f16f2ad9cf..0000000000
--- a/missing/strtoul.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
- * strtoul.c --
- *
- * Source code for the "strtoul" library procedure.
- *
- * Copyright 1988 Regents of the University of California
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that the above copyright
- * notice appear in all copies. The University of California
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
-#include <ctype.h>
-
-/*
- * The table below is used to convert from ASCII digits to a
- * numerical equivalent. It maps from '0' through 'z' to integers
- * (100 for non-digit characters).
- */
-
-static char cvtIn[] = {
- 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, /* '0' - '9' */
- 100, 100, 100, 100, 100, 100, 100, /* punctuation */
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'A' - 'Z' */
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35,
- 100, 100, 100, 100, 100, 100, /* punctuation */
- 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, /* 'a' - 'z' */
- 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
- 30, 31, 32, 33, 34, 35};
-
-/*
- *----------------------------------------------------------------------
- *
- * strtoul --
- *
- * Convert an ASCII string into an integer.
- *
- * Results:
- * The return value is the integer equivalent of string. If endPtr
- * is non-NULL, then *endPtr is filled in with the character
- * after the last one that was part of the integer. If string
- * doesn't contain a valid integer value, then zero is returned
- * and *endPtr is set to string.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
-unsigned long int
-strtoul(string, endPtr, base)
- char *string; /* String of ASCII digits, possibly
- * preceded by white space. For bases
- * greater than 10, either lower- or
- * upper-case digits may be used.
- */
- char **endPtr; /* Where to store address of terminating
- * character, or NULL. */
- int base; /* Base for conversion. Must be less
- * than 37. If 0, then the base is chosen
- * from the leading characters of string:
- * "0x" means hex, "0" means octal, anything
- * else means decimal.
- */
-{
- register char *p;
- register unsigned long int result = 0;
- register unsigned digit;
- int anyDigits = 0;
-
- /*
- * Skip any leading blanks.
- */
-
- p = string;
- while (isspace(*p)) {
- p += 1;
- }
-
- /*
- * If no base was provided, pick one from the leading characters
- * of the string.
- */
-
- if (base == 0)
- {
- if (*p == '0') {
- p += 1;
- if (*p == 'x') {
- p += 1;
- base = 16;
- } else {
-
- /*
- * Must set anyDigits here, otherwise "0" produces a
- * "no digits" error.
- */
-
- anyDigits = 1;
- base = 8;
- }
- }
- else base = 10;
- } else if (base == 16) {
-
- /*
- * Skip a leading "0x" from hex numbers.
- */
-
- if ((p[0] == '0') && (p[1] == 'x')) {
- p += 2;
- }
- }
-
- /*
- * Sorry this code is so messy, but speed seems important. Do
- * different things for base 8, 10, 16, and other.
- */
-
- if (base == 8) {
- for ( ; ; p += 1) {
- digit = *p - '0';
- if (digit > 7) {
- break;
- }
- result = (result << 3) + digit;
- anyDigits = 1;
- }
- } else if (base == 10) {
- for ( ; ; p += 1) {
- digit = *p - '0';
- if (digit > 9) {
- break;
- }
- result = (10*result) + digit;
- anyDigits = 1;
- }
- } else if (base == 16) {
- for ( ; ; p += 1) {
- digit = *p - '0';
- if (digit > ('z' - '0')) {
- break;
- }
- digit = cvtIn[digit];
- if (digit > 15) {
- break;
- }
- result = (result << 4) + digit;
- anyDigits = 1;
- }
- } else {
- for ( ; ; p += 1) {
- digit = *p - '0';
- if (digit > ('z' - '0')) {
- break;
- }
- digit = cvtIn[digit];
- if (digit >= base) {
- break;
- }
- result = result*base + digit;
- anyDigits = 1;
- }
- }
-
- /*
- * See if there were any digits at all.
- */
-
- if (!anyDigits) {
- p = string;
- }
-
- if (endPtr != 0) {
- *endPtr = p;
- }
-
- return result;
-}
diff --git a/missing/tgamma.c b/missing/tgamma.c
new file mode 100644
index 0000000000..5e306fbb43
--- /dev/null
+++ b/missing/tgamma.c
@@ -0,0 +1,92 @@
+/* tgamma.c - public domain implementation of function tgamma(3m)
+
+reference - Haruhiko Okumura: C-gengo niyoru saishin algorithm jiten
+ (New Algorithm handbook in C language) (Gijyutsu hyouron
+ sha, Tokyo, 1991) [in Japanese]
+ http://oku.edu.mie-u.ac.jp/~okumura/algo/
+*/
+
+/***********************************************************
+ gamma.c -- Gamma function
+***********************************************************/
+#include "ruby/config.h"
+#include <math.h>
+#include <errno.h>
+
+#ifdef HAVE_LGAMMA_R
+
+double tgamma(double x)
+{
+ int sign;
+ double d;
+ if (x == 0.0) { /* Pole Error */
+ errno = ERANGE;
+ return 1/x < 0 ? -HUGE_VAL : HUGE_VAL;
+ }
+ if (x < 0) {
+ static double zero = 0.0;
+ double i, f;
+ f = modf(-x, &i);
+ if (f == 0.0) { /* Domain Error */
+ errno = EDOM;
+ return zero/zero;
+ }
+ }
+ d = lgamma_r(x, &sign);
+ return sign * exp(d);
+}
+
+#else
+
+#include <errno.h>
+#define PI 3.14159265358979324 /* $\pi$ */
+#define LOG_2PI 1.83787706640934548 /* $\log 2\pi$ */
+#define N 8
+
+#define B0 1 /* Bernoulli numbers */
+#define B1 (-1.0 / 2.0)
+#define B2 ( 1.0 / 6.0)
+#define B4 (-1.0 / 30.0)
+#define B6 ( 1.0 / 42.0)
+#define B8 (-1.0 / 30.0)
+#define B10 ( 5.0 / 66.0)
+#define B12 (-691.0 / 2730.0)
+#define B14 ( 7.0 / 6.0)
+#define B16 (-3617.0 / 510.0)
+
+static double
+loggamma(double x) /* the natural logarithm of the Gamma function. */
+{
+ double v, w;
+
+ v = 1;
+ while (x < N) { v *= x; x++; }
+ w = 1 / (x * x);
+ return ((((((((B16 / (16 * 15)) * w + (B14 / (14 * 13))) * w
+ + (B12 / (12 * 11))) * w + (B10 / (10 * 9))) * w
+ + (B8 / ( 8 * 7))) * w + (B6 / ( 6 * 5))) * w
+ + (B4 / ( 4 * 3))) * w + (B2 / ( 2 * 1))) / x
+ + 0.5 * LOG_2PI - log(v) - x + (x - 0.5) * log(x);
+}
+
+double tgamma(double x) /* Gamma function */
+{
+ if (x == 0.0) { /* Pole Error */
+ errno = ERANGE;
+ return 1/x < 0 ? -HUGE_VAL : HUGE_VAL;
+ }
+ if (x < 0) {
+ int sign;
+ static double zero = 0.0;
+ double i, f;
+ f = modf(-x, &i);
+ if (f == 0.0) { /* Domain Error */
+ errno = EDOM;
+ return zero/zero;
+ }
+ sign = (fmod(i, 2.0) != 0.0) ? 1 : -1;
+ return sign * PI / (sin(PI * f) * exp(loggamma(1 - x)));
+ }
+ return exp(loggamma(x));
+}
+#endif
diff --git a/missing/vsnprintf.c b/missing/vsnprintf.c
deleted file mode 100644
index 6afdfa189f..0000000000
--- a/missing/vsnprintf.c
+++ /dev/null
@@ -1,1135 +0,0 @@
-/*-
- * Copyright (c) 1990, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Chris Torek.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * IMPORTANT NOTE:
- * --------------
- * From ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
- * paragraph 3 above is now null and void.
- */
-
-/* SNPRINTF.C
- * fjc 7-31-97 Modified by Mib Software to be a standalone snprintf.c module.
- * http://www.mibsoftware.com
- * Mib Software does not warrant this software any differently than the
- * University of California, Berkeley as described above. All warranties
- * are disclaimed. Use this software at your own risk.
- *
- * All code referencing FILE * functions was eliminated, since it could
- * never be called. All header files and necessary files are collapsed
- * into one file, internal functions are declared static. This should
- * allow inclusion into libraries with less chance of namespace collisions.
- *
- * snprintf should be the only externally visible item.
- *
- * As of 7-31-97 FLOATING_POINT is NOT provided. The code is somewhat
- * non-portable, so it is disabled.
- */
-
-/* Define FLOATING_POINT to get floating point. */
-/*
-#define FLOATING_POINT
-*/
-
-#include <sys/types.h>
-#define u_long unsigned long
-#define u_short unsigned short
-#define u_int unsigned int
-
-#undef __P
-#if defined(__STDC__)
-# include <stdarg.h>
-# if !defined(__P)
-# define __P(x) x
-# endif
-#else
-# define __P(x) ()
-# if !defined(const)
-# define const
-# endif
-# include <varargs.h>
-#endif
-#ifndef _BSD_VA_LIST_
-#define _BSD_VA_LIST_ va_list
-#endif
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# ifndef LONG_MAX
-# ifdef HAVE_LIMITS_H
-# include <limits.h>
-# else
- /* assuming 32bit(2's compliment) long */
-# define LONG_MAX 2147483647
-# endif
-# endif
-#endif
-
-#if defined(__hpux) && !defined(__GNUC__) && !defined(__STDC__)
-#define const
-#endif
-
-#if defined(sgi)
-#undef __const
-#define __const
-#endif /* People who don't like const sys_error */
-
-#include <stddef.h>
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/*
- * NB: to fit things in six character monocase externals, the stdio
- * code uses the prefix `__s' for stdio objects, typically followed
- * by a three-character attempt at a mnemonic.
- */
-
-/* stdio buffers */
-struct __sbuf {
- unsigned char *_base;
- int _size;
-};
-
-
-/*
- * stdio state variables.
- *
- * The following always hold:
- *
- * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),
- * _lbfsize is -_bf._size, else _lbfsize is 0
- * if _flags&__SRD, _w is 0
- * if _flags&__SWR, _r is 0
- *
- * This ensures that the getc and putc macros (or inline functions) never
- * try to write or read from a file that is in `read' or `write' mode.
- * (Moreover, they can, and do, automatically switch from read mode to
- * write mode, and back, on "r+" and "w+" files.)
- *
- * _lbfsize is used only to make the inline line-buffered output stream
- * code as compact as possible.
- *
- * _ub, _up, and _ur are used when ungetc() pushes back more characters
- * than fit in the current _bf, or when ungetc() pushes back a character
- * that does not match the previous one in _bf. When this happens,
- * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff
- * _ub._base!=NULL) and _up and _ur save the current values of _p and _r.
- *
- * NB: see WARNING above before changing the layout of this structure!
- */
-typedef struct __sFILE {
- unsigned char *_p; /* current position in (some) buffer */
- int _r; /* read space left for getc() */
- int _w; /* write space left for putc() */
- short _flags; /* flags, below; this FILE is free if 0 */
- short _file; /* fileno, if Unix descriptor, else -1 */
- struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */
- int _lbfsize; /* 0 or -_bf._size, for inline putc */
-} FILE;
-
-
-#define __SLBF 0x0001 /* line buffered */
-#define __SNBF 0x0002 /* unbuffered */
-#define __SRD 0x0004 /* OK to read */
-#define __SWR 0x0008 /* OK to write */
- /* RD and WR are never simultaneously asserted */
-#define __SRW 0x0010 /* open for reading & writing */
-#define __SEOF 0x0020 /* found EOF */
-#define __SERR 0x0040 /* found error */
-#define __SMBF 0x0080 /* _buf is from malloc */
-#define __SAPP 0x0100 /* fdopen()ed in append mode */
-#define __SSTR 0x0200 /* this is an sprintf/snprintf string */
-#define __SOPT 0x0400 /* do fseek() optimisation */
-#define __SNPT 0x0800 /* do not do fseek() optimisation */
-#define __SOFF 0x1000 /* set iff _offset is in fact correct */
-#define __SMOD 0x2000 /* true => fgetln modified _p text */
-
-
-#define EOF (-1)
-
-
-#define __sfeof(p) (((p)->_flags & __SEOF) != 0)
-#define __sferror(p) (((p)->_flags & __SERR) != 0)
-#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
-#define __sfileno(p) ((p)->_file)
-
-#define feof(p) __sfeof(p)
-#define ferror(p) __sferror(p)
-#define clearerr(p) __sclearerr(p)
-
-#ifndef _ANSI_SOURCE
-#define fileno(p) __sfileno(p)
-#endif
-
-
-#if defined(__hpux) && !defined(__GNUC__) || defined(__DECC)
-#include <string.h>
-#endif
-
-/*
- * I/O descriptors for __sfvwrite().
- */
-struct __siov {
- void *iov_base;
- size_t iov_len;
-};
-struct __suio {
- struct __siov *uio_iov;
- int uio_iovcnt;
- int uio_resid;
-};
-
-/*
- * Write some memory regions. Return zero on success, EOF on error.
- *
- * This routine is large and unsightly, but most of the ugliness due
- * to the three different kinds of output buffering is handled here.
- */
-static BSD__sfvwrite(fp, uio)
- register FILE *fp;
- register struct __suio *uio;
-{
- register size_t len;
- register char *p;
- register struct __siov *iov;
- register int w;
-
- if ((len = uio->uio_resid) == 0)
- return (0);
-#ifndef __hpux
-#define MIN(a, b) ((a) < (b) ? (a) : (b))
-#endif
-#define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n))
-
- iov = uio->uio_iov;
- p = iov->iov_base;
- len = iov->iov_len;
- iov++;
-#define GETIOV(extra_work) \
- while (len == 0) { \
- extra_work; \
- p = iov->iov_base; \
- len = iov->iov_len; \
- iov++; \
- }
- if (fp->_flags & __SNBF) {
- /* fjc 7-31-97 Will never happen. We are working with
- strings only
- */
- } else if ((fp->_flags & __SLBF) == 0) {
- /*
- * Fully buffered: fill partially full buffer, if any,
- * and then flush. If there is no partial buffer, write
- * one _bf._size byte chunk directly (without copying).
- *
- * String output is a special case: write as many bytes
- * as fit, but pretend we wrote everything. This makes
- * snprintf() return the number of bytes needed, rather
- * than the number used, and avoids its write function
- * (so that the write function can be invalid).
- */
- do {
- GETIOV(;);
- w = fp->_w;
- if (fp->_flags & __SSTR) {
- if (len < w)
- w = len;
- COPY(w); /* copy MIN(fp->_w,len), */
- fp->_w -= w;
- fp->_p += w;
- w = len; /* but pretend copied all */
- } else {
- /* fjc 7-31-97 Will never happen. We are working with
- strings only
- */
- }
- p += w;
- len -= w;
- } while ((uio->uio_resid -= w) != 0);
- } else {
- /* fjc 7-31-97 Will never happen. We are working with
- strings only
- */
- }
- return (0);
-
-err:
- fp->_flags |= __SERR;
- return (EOF);
-}
-
-/*
- * Actual printf innards.
- *
- * This code is large and complicated...
- */
-
-#if !defined(__CYGWIN32__) && defined(__hpux) && !defined(__GNUC__)
-#include <stdlib.h>
-#endif
-
-/*
- * Flush out all the vectors defined by the given uio,
- * then reset it so that it can be reused.
- */
-static int
-BSD__sprint(fp, uio)
- FILE *fp;
- register struct __suio *uio;
-{
- register int err;
-
- if (uio->uio_resid == 0) {
- uio->uio_iovcnt = 0;
- return (0);
- }
- err = BSD__sfvwrite(fp, uio);
- uio->uio_resid = 0;
- uio->uio_iovcnt = 0;
- return (err);
-}
-
-
-/*
- * Helper function for `fprintf to unbuffered unix file': creates a
- * temporary buffer. We only work on write-only files; this avoids
- * worries about ungetc buffers and so forth.
- */
-static int
-BSD__sbprintf(fp, fmt, ap)
- register FILE *fp;
- const char *fmt;
- va_list ap;
-{
-/* We don't support files. */
- return 0;
-}
-
-
-/*
- * Macros for converting digits to letters and vice versa
- */
-#define to_digit(c) ((c) - '0')
-#define is_digit(c) ((unsigned)to_digit(c) <= 9)
-#define to_char(n) ((n) + '0')
-
-/*
- * Convert an unsigned long to ASCII for printf purposes, returning
- * a pointer to the first character of the string representation.
- * Octal numbers can be forced to have a leading zero; hex numbers
- * use the given digits.
- */
-static char *
-BSD__ultoa(val, endp, base, octzero, xdigs)
- register u_long val;
- char *endp;
- int base, octzero;
- char *xdigs;
-{
- register char *cp = endp;
- register long sval;
-
- /*
- * Handle the three cases separately, in the hope of getting
- * better/faster code.
- */
- switch (base) {
- case 10:
- if (val < 10) { /* many numbers are 1 digit */
- *--cp = to_char(val);
- return (cp);
- }
- /*
- * On many machines, unsigned arithmetic is harder than
- * signed arithmetic, so we do at most one unsigned mod and
- * divide; this is sufficient to reduce the range of
- * the incoming value to where signed arithmetic works.
- */
- if (val > LONG_MAX) {
- *--cp = to_char(val % 10);
- sval = val / 10;
- } else
- sval = val;
- do {
- *--cp = to_char(sval % 10);
- sval /= 10;
- } while (sval != 0);
- break;
-
- case 8:
- do {
- *--cp = to_char(val & 7);
- val >>= 3;
- } while (val);
- if (octzero && *cp != '0')
- *--cp = '0';
- break;
-
- case 16:
- do {
- *--cp = xdigs[val & 15];
- val >>= 4;
- } while (val);
- break;
-
- default: /* oops */
- /*
- abort();
- */
- break; /* fjc 7-31-97. Don't reference abort() here */
- }
- return (cp);
-}
-
-#ifdef FLOATING_POINT
-#include <math.h>
-/* #include "floatio.h" */
-
-#ifndef MAXEXP
-# define MAXEXP 1024
-#endif
-
-#ifndef MAXFRACT
-# define MAXFRACT 64
-#endif
-
-#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */
-#define DEFPREC 6
-
-static char *cvt __P((double, int, int, char *, int *, int, int *));
-static int exponent __P((char *, int, int));
-
-#else /* no FLOATING_POINT */
-
-#define BUF 68
-
-#endif /* FLOATING_POINT */
-
-
-/*
- * Flags used during conversion.
- */
-#define ALT 0x001 /* alternate form */
-#define HEXPREFIX 0x002 /* add 0x or 0X prefix */
-#define LADJUST 0x004 /* left adjustment */
-#define LONGDBL 0x008 /* long double; unimplemented */
-#define LONGINT 0x010 /* long integer */
-
-#ifdef _HAVE_SANE_QUAD_
-#define QUADINT 0x020 /* quad integer */
-#endif /* _HAVE_SANE_QUAD_ */
-
-#define SHORTINT 0x040 /* short integer */
-#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */
-#define FPT 0x100 /* Floating point number */
-static int
-BSD_vfprintf(fp, fmt0, ap)
- FILE *fp;
- const char *fmt0;
- va_list ap;
-{
- register char *fmt; /* format string */
- register int ch; /* character from fmt */
- register int n; /* handy integer (short term usage) */
- register char *cp; /* handy char pointer (short term usage) */
- register struct __siov *iovp;/* for PRINT macro */
- register int flags; /* flags as above */
- int ret; /* return value accumulator */
- int width; /* width from format (%8d), or 0 */
- int prec; /* precision from format (%.3d), or -1 */
- char sign; /* sign prefix (' ', '+', '-', or \0) */
-#ifdef FLOATING_POINT
- char softsign; /* temporary negative sign for floats */
- double _double; /* double precision arguments %[eEfgG] */
- int expt; /* integer value of exponent */
- int expsize; /* character count for expstr */
- int ndig; /* actual number of digits returned by cvt */
- char expstr[7]; /* buffer for exponent string */
-#endif
- u_long ulval; /* integer arguments %[diouxX] */
-#ifdef _HAVE_SANE_QUAD_
- u_quad_t uqval; /* %q integers */
-#endif /* _HAVE_SANE_QUAD_ */
- int base; /* base for [diouxX] conversion */
- int dprec; /* a copy of prec if [diouxX], 0 otherwise */
- int fieldsz; /* field size expanded by sign, etc */
- int realsz; /* field size expanded by dprec */
- int size; /* size of converted field or string */
- char *xdigs; /* digits for [xX] conversion */
-#define NIOV 8
- struct __suio uio; /* output information: summary */
- struct __siov iov[NIOV];/* ... and individual io vectors */
- char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */
- char ox[2]; /* space for 0x hex-prefix */
-
- /*
- * Choose PADSIZE to trade efficiency vs. size. If larger printf
- * fields occur frequently, increase PADSIZE and make the initialisers
- * below longer.
- */
-#define PADSIZE 16 /* pad chunk size */
- static char blanks[PADSIZE] =
- {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '};
- static char zeroes[PADSIZE] =
- {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'};
-
- /*
- * BEWARE, these `goto error' on error, and PAD uses `n'.
- */
-#define PRINT(ptr, len) { \
- iovp->iov_base = (ptr); \
- iovp->iov_len = (len); \
- uio.uio_resid += (len); \
- iovp++; \
- if (++uio.uio_iovcnt >= NIOV) { \
- if (BSD__sprint(fp, &uio)) \
- goto error; \
- iovp = iov; \
- } \
-}
-#define PAD(howmany, with) { \
- if ((n = (howmany)) > 0) { \
- while (n > PADSIZE) { \
- PRINT(with, PADSIZE); \
- n -= PADSIZE; \
- } \
- PRINT(with, n); \
- } \
-}
-#define FLUSH() { \
- if (uio.uio_resid && BSD__sprint(fp, &uio)) \
- goto error; \
- uio.uio_iovcnt = 0; \
- iovp = iov; \
-}
-
- /*
- * To extend shorts properly, we need both signed and unsigned
- * argument extraction methods.
- */
-#define SARG() \
- (flags&LONGINT ? va_arg(ap, long) : \
- flags&SHORTINT ? (long)(short)va_arg(ap, int) : \
- (long)va_arg(ap, int))
-#define UARG() \
- (flags&LONGINT ? va_arg(ap, u_long) : \
- flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \
- (u_long)va_arg(ap, u_int))
-
- /* optimise fprintf(stderr) (and other unbuffered Unix files) */
- if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
- fp->_file >= 0)
- return (BSD__sbprintf(fp, fmt0, ap));
-
- fmt = (char *)fmt0;
- uio.uio_iov = iovp = iov;
- uio.uio_resid = 0;
- uio.uio_iovcnt = 0;
- ret = 0;
-
- /*
- * Scan the format for conversions (`%' character).
- */
- for (;;) {
- for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
- /* void */;
- if ((n = fmt - cp) != 0) {
- PRINT(cp, n);
- ret += n;
- }
- if (ch == '\0')
- goto done;
- fmt++; /* skip over '%' */
-
- flags = 0;
- dprec = 0;
- width = 0;
- prec = -1;
- sign = '\0';
-
-rflag: ch = *fmt++;
-reswitch: switch (ch) {
- case ' ':
- /*
- * ``If the space and + flags both appear, the space
- * flag will be ignored.''
- * -- ANSI X3J11
- */
- if (!sign)
- sign = ' ';
- goto rflag;
- case '#':
- flags |= ALT;
- goto rflag;
- case '*':
- /*
- * ``A negative field width argument is taken as a
- * - flag followed by a positive field width.''
- * -- ANSI X3J11
- * They don't exclude field widths read from args.
- */
- if ((width = va_arg(ap, int)) >= 0)
- goto rflag;
- width = -width;
- /* FALLTHROUGH */
- case '-':
- flags |= LADJUST;
- goto rflag;
- case '+':
- sign = '+';
- goto rflag;
- case '.':
- if ((ch = *fmt++) == '*') {
- n = va_arg(ap, int);
- prec = n < 0 ? -1 : n;
- goto rflag;
- }
- n = 0;
- while (is_digit(ch)) {
- n = 10 * n + to_digit(ch);
- ch = *fmt++;
- }
- prec = n < 0 ? -1 : n;
- goto reswitch;
- case '0':
- /*
- * ``Note that 0 is taken as a flag, not as the
- * beginning of a field width.''
- * -- ANSI X3J11
- */
- flags |= ZEROPAD;
- goto rflag;
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- n = 0;
- do {
- n = 10 * n + to_digit(ch);
- ch = *fmt++;
- } while (is_digit(ch));
- width = n;
- goto reswitch;
-#ifdef FLOATING_POINT
- case 'L':
- flags |= LONGDBL;
- goto rflag;
-#endif
- case 'h':
- flags |= SHORTINT;
- goto rflag;
- case 'l':
- flags |= LONGINT;
- goto rflag;
-#ifdef _HAVE_SANE_QUAD_
- case 'q':
- flags |= QUADINT;
- goto rflag;
-#endif /* _HAVE_SANE_QUAD_ */
- case 'c':
- *(cp = buf) = va_arg(ap, int);
- size = 1;
- sign = '\0';
- break;
- case 'D':
- flags |= LONGINT;
- /*FALLTHROUGH*/
- case 'd':
- case 'i':
-#ifdef _HAVE_SANE_QUAD_
- if (flags & QUADINT) {
- uqval = va_arg(ap, quad_t);
- if ((quad_t)uqval < 0) {
- uqval = -uqval;
- sign = '-';
- }
- } else {
-#else /* _HAVE_SANE_QUAD_ */
- {
-#endif /* _HAVE_SANE_QUAD_ */
- ulval = SARG();
- if ((long)ulval < 0) {
- ulval = -ulval;
- sign = '-';
- }
- }
- base = 10;
- goto number;
-#ifdef FLOATING_POINT
- case 'e': /* anomalous precision */
- case 'E':
- prec = (prec == -1) ?
- DEFPREC + 1 : prec + 1;
- /* FALLTHROUGH */
- goto fp_begin;
- case 'f': /* always print trailing zeroes */
- if (prec != 0)
- flags |= ALT;
- case 'g':
- case 'G':
- if (prec == -1)
- prec = DEFPREC;
-fp_begin: _double = va_arg(ap, double);
- /* do this before tricky precision changes */
- if (isinf(_double)) {
- if (_double < 0)
- sign = '-';
- cp = "Inf";
- size = 3;
- break;
- }
- if (isnan(_double)) {
- cp = "NaN";
- size = 3;
- break;
- }
- flags |= FPT;
- cp = cvt(_double, prec, flags, &softsign,
- &expt, ch, &ndig);
- if (ch == 'g' || ch == 'G') {
- if (expt <= -4 || expt > prec)
- ch = (ch == 'g') ? 'e' : 'E';
- else
- ch = 'g';
- }
- if (ch <= 'e') { /* 'e' or 'E' fmt */
- --expt;
- expsize = exponent(expstr, expt, ch);
- size = expsize + ndig;
- if (ndig > 1 || flags & ALT)
- ++size;
- } else if (ch == 'f') { /* f fmt */
- if (expt > 0) {
- size = expt;
- if (prec || flags & ALT)
- size += prec + 1;
- } else /* "0.X" */
- size = prec + 2;
- } else if (expt >= ndig) { /* fixed g fmt */
- size = expt;
- if (flags & ALT)
- ++size;
- } else
- size = ndig + (expt > 0 ?
- 1 : 2 - expt);
-
- if (softsign)
- sign = '-';
- break;
-#endif /* FLOATING_POINT */
- case 'n':
-#ifdef _HAVE_SANE_QUAD_
- if (flags & QUADINT)
- *va_arg(ap, quad_t *) = ret;
- else if (flags & LONGINT)
-#else /* _HAVE_SANE_QUAD_ */
- if (flags & LONGINT)
-#endif /* _HAVE_SANE_QUAD_ */
- *va_arg(ap, long *) = ret;
- else if (flags & SHORTINT)
- *va_arg(ap, short *) = ret;
- else
- *va_arg(ap, int *) = ret;
- continue; /* no output */
- case 'O':
- flags |= LONGINT;
- /*FALLTHROUGH*/
- case 'o':
-#ifdef _HAVE_SANE_QUAD_
- if (flags & QUADINT)
- uqval = va_arg(ap, u_quad_t);
- else
-#endif /* _HAVE_SANE_QUAD_ */
- ulval = UARG();
- base = 8;
- goto nosign;
- case 'p':
- /*
- * ``The argument shall be a pointer to void. The
- * value of the pointer is converted to a sequence
- * of printable characters, in an implementation-
- * defined manner.''
- * -- ANSI X3J11
- */
-#ifdef _HAVE_LLP64_
- uqval = (u_long)va_arg(ap, void *);
- flags = (flags) | QUADINT | HEXPREFIX;
-#else
- ulval = (u_long)va_arg(ap, void *);
-#ifdef _HAVE_SANE_QUAD_
- flags = (flags & ~QUADINT) | HEXPREFIX;
-#else /* _HAVE_SANE_QUAD_ */
- flags = (flags) | HEXPREFIX;
-#endif /* _HAVE_SANE_QUAD_ */
-#endif
- base = 16;
- xdigs = "0123456789abcdef";
- ch = 'x';
- goto nosign;
- case 's':
- if ((cp = va_arg(ap, char *)) == NULL)
- cp = "(null)";
- if (prec >= 0) {
- /*
- * can't use strlen; can only look for the
- * NUL in the first `prec' characters, and
- * strlen() will go further.
- */
- char *p = (char *)memchr(cp, 0, prec);
-
- if (p != NULL) {
- size = p - cp;
- if (size > prec)
- size = prec;
- } else
- size = prec;
- } else
- size = strlen(cp);
- sign = '\0';
- break;
- case 'U':
- flags |= LONGINT;
- /*FALLTHROUGH*/
- case 'u':
-#ifdef _HAVE_SANE_QUAD_
- if (flags & QUADINT)
- uqval = va_arg(ap, u_quad_t);
- else
-#endif /* _HAVE_SANE_QUAD_ */
- ulval = UARG();
- base = 10;
- goto nosign;
- case 'X':
- xdigs = "0123456789ABCDEF";
- goto hex;
- case 'x':
- xdigs = "0123456789abcdef";
-hex:
-#ifdef _HAVE_SANE_QUAD_
- if (flags & QUADINT)
- uqval = va_arg(ap, u_quad_t);
- else
-#endif /* _HAVE_SANE_QUAD_ */
- ulval = UARG();
- base = 16;
- /* leading 0x/X only if non-zero */
- if (flags & ALT &&
-#ifdef _HAVE_SANE_QUAD_
- (flags & QUADINT ? uqval != 0 : ulval != 0))
-#else /* _HAVE_SANE_QUAD_ */
- ulval != 0)
-#endif /* _HAVE_SANE_QUAD_ */
- flags |= HEXPREFIX;
-
- /* unsigned conversions */
-nosign: sign = '\0';
- /*
- * ``... diouXx conversions ... if a precision is
- * specified, the 0 flag will be ignored.''
- * -- ANSI X3J11
- */
-number: if ((dprec = prec) >= 0)
- flags &= ~ZEROPAD;
-
- /*
- * ``The result of converting a zero value with an
- * explicit precision of zero is no characters.''
- * -- ANSI X3J11
- */
- cp = buf + BUF;
-#ifdef _HAVE_SANE_QUAD_
- if (flags & QUADINT) {
- if (uqval != 0 || prec != 0)
- cp = __uqtoa(uqval, cp, base,
- flags & ALT, xdigs);
- } else {
-#else /* _HAVE_SANE_QUAD_ */
- {
-#endif /* _HAVE_SANE_QUAD_ */
- if (ulval != 0 || prec != 0)
- cp = BSD__ultoa(ulval, cp, base,
- flags & ALT, xdigs);
- }
- size = buf + BUF - cp;
- break;
- default: /* "%?" prints ?, unless ? is NUL */
- if (ch == '\0')
- goto done;
- /* pretend it was %c with argument ch */
- cp = buf;
- *cp = ch;
- size = 1;
- sign = '\0';
- break;
- }
-
- /*
- * All reasonable formats wind up here. At this point, `cp'
- * points to a string which (if not flags&LADJUST) should be
- * padded out to `width' places. If flags&ZEROPAD, it should
- * first be prefixed by any sign or other prefix; otherwise,
- * it should be blank padded before the prefix is emitted.
- * After any left-hand padding and prefixing, emit zeroes
- * required by a decimal [diouxX] precision, then print the
- * string proper, then emit zeroes required by any leftover
- * floating precision; finally, if LADJUST, pad with blanks.
- *
- * Compute actual size, so we know how much to pad.
- * fieldsz excludes decimal prec; realsz includes it.
- */
- fieldsz = size;
- if (sign)
- fieldsz++;
- else if (flags & HEXPREFIX)
- fieldsz += 2;
- realsz = dprec > fieldsz ? dprec : fieldsz;
-
- /* right-adjusting blank padding */
- if ((flags & (LADJUST|ZEROPAD)) == 0)
- PAD(width - realsz, blanks);
-
- /* prefix */
- if (sign) {
- PRINT(&sign, 1);
- } else if (flags & HEXPREFIX) {
- ox[0] = '0';
- ox[1] = ch;
- PRINT(ox, 2);
- }
-
- /* right-adjusting zero padding */
- if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD)
- PAD(width - realsz, zeroes);
-
- /* leading zeroes from decimal precision */
- PAD(dprec - fieldsz, zeroes);
-
- /* the string or number proper */
-#ifdef FLOATING_POINT
- if ((flags & FPT) == 0) {
- PRINT(cp, size);
- } else { /* glue together f_p fragments */
- if (ch >= 'f') { /* 'f' or 'g' */
- if (_double == 0) {
- /* kludge for __dtoa irregularity */
- if (prec == 0 ||
- (flags & ALT) == 0) {
- PRINT("0", 1);
- } else {
- PRINT("0.", 2);
- PAD(ndig - 1, zeroes);
- }
- } else if (expt <= 0) {
- PRINT("0.", 2);
- PAD(-expt, zeroes);
- PRINT(cp, ndig);
- } else if (expt >= ndig) {
- PRINT(cp, ndig);
- PAD(expt - ndig, zeroes);
- if (flags & ALT)
- PRINT(".", 1);
- } else {
- PRINT(cp, expt);
- cp += expt;
- PRINT(".", 1);
- PRINT(cp, ndig-expt);
- }
- } else { /* 'e' or 'E' */
- if (ndig > 1 || flags & ALT) {
- ox[0] = *cp++;
- ox[1] = '.';
- PRINT(ox, 2);
- if (_double || flags & ALT == 0) {
- PRINT(cp, ndig-1);
- } else /* 0.[0..] */
- /* __dtoa irregularity */
- PAD(ndig - 1, zeroes);
- } else /* XeYYY */
- PRINT(cp, 1);
- PRINT(expstr, expsize);
- }
- }
-#else
- PRINT(cp, size);
-#endif
- /* left-adjusting padding (always blank) */
- if (flags & LADJUST)
- PAD(width - realsz, blanks);
-
- /* finally, adjust ret */
- ret += width > realsz ? width : realsz;
-
- FLUSH(); /* copy out the I/O vectors */
- }
-done:
- FLUSH();
-error:
- return (__sferror(fp) ? EOF : ret);
- /* NOTREACHED */
-}
-
-#ifdef FLOATING_POINT
-
-extern char *BSD__dtoa __P((double, int, int, int *, int *, char **));
-
-static char *
-cvt(value, ndigits, flags, sign, decpt, ch, length)
- double value;
- int ndigits, flags, *decpt, ch, *length;
- char *sign;
-{
- int mode, dsgn;
- char *digits, *bp, *rve;
-
- if (ch == 'f')
- mode = 3;
- else {
- mode = 2;
- }
- if (value < 0) {
- value = -value;
- *sign = '-';
- } else if (value == 0.0 && 1.0/value < 0) {
- *sign = '-';
- } else {
- *sign = '\000';
- }
- digits = BSD__dtoa(value, mode, ndigits, decpt, &dsgn, &rve);
- if (flags & ALT) { /* Print trailing zeros */
- bp = digits + ndigits;
- if (ch == 'f') {
- if (*digits == '0' && value)
- *decpt = -ndigits + 1;
- bp += *decpt;
- }
- if (value == 0) /* kludge for __dtoa irregularity */
- rve = bp;
- while (rve < bp)
- *rve++ = '0';
- }
- *length = rve - digits;
- return (digits);
-}
-
-static int
-exponent(p0, exp, fmtch)
- char *p0;
- int exp, fmtch;
-{
- register char *p, *t;
- char expbuf[MAXEXP];
-
- p = p0;
- *p++ = fmtch;
- if (exp < 0) {
- exp = -exp;
- *p++ = '-';
- }
- else
- *p++ = '+';
- t = expbuf + MAXEXP;
- if (exp > 9) {
- do {
- *--t = to_char(exp % 10);
- } while ((exp /= 10) > 9);
- *--t = to_char(exp);
- for (; t < expbuf + MAXEXP; *p++ = *t++);
- }
- else {
- *p++ = '0';
- *p++ = to_char(exp);
- }
- return (p - p0);
-}
-#endif /* FLOATING_POINT */
-
-int
-vsnprintf(str, n, fmt, ap)
- char *str;
- size_t n;
- const char *fmt;
- _BSD_VA_LIST_ ap;
-{
- int ret;
- FILE f;
-
- if ((int)n < 1)
- return (EOF);
- f._flags = __SWR | __SSTR;
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._w = n - 1;
- ret = BSD_vfprintf(&f, fmt, ap);
- *f._p = 0;
- return (ret);
-}
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-
-#if defined(__STDC__)
-# include <stdarg.h>
-#else
-# include <varargs.h>
-#endif
-
-int
-#if defined(__STDC__)
-snprintf(char *str, size_t n, char const *fmt, ...)
-#else
-snprintf(str, n, fmt, va_alist)
-char *str, *fmt;
-size_t n;
-va_dcl
-#endif
-{
- int ret;
- va_list ap;
- FILE f;
-
- if ((int)n < 1)
- return (EOF);
-
-#if defined(__STDC__)
- va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
- f._flags = __SWR | __SSTR;
- f._bf._base = f._p = (unsigned char *)str;
- f._bf._size = f._w = n - 1;
- ret = BSD_vfprintf(&f, fmt, ap);
- *f._p = 0;
- va_end(ap);
- return (ret);
-}
diff --git a/missing/x68.c b/missing/x68.c
deleted file mode 100644
index 8d00d50041..0000000000
--- a/missing/x68.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/* x68 compatibility functions -- follows Ruby's license */
-
-#include "config.h"
-
-#if !HAVE_SELECT
-#include "x68/select.c"
-#endif
-#if MISSING__DTOS18
-#include "x68/_dtos18.c"
-#endif
-#if MISSING_FCONVERT
-#include "x68/_round.c"
-#include "x68/fconvert.c"
-#endif
-
-/* missing some basic syscalls */
-int
-link(const char *src, const char *dst)
-{
- return symlink(src, dst);
-}
-
-#ifndef HAVE_GETTIMEOFDAY
-#include <time.h>
-#include <sys/time.h>
-
-struct timezone {
- int tz_minuteswest;
- int tz_dsttime;
-};
-
-int
-gettimeofday(struct timeval *tv, struct timezone *tz)
-{
- tv->tv_sec = (long)time((time_t*)0);
- tv->tv_usec = 0;
-
- return 0;
-}
-#endif