aboutsummaryrefslogtreecommitdiffstats
path: root/missing_d
diff options
context:
space:
mode:
Diffstat (limited to 'missing_d')
-rw-r--r--missing_d/ChangeLog62
-rw-r--r--missing_d/README14
-rw-r--r--missing_d/getaddrinfo.c112
-rw-r--r--missing_d/getaddrinfo.h26
-rw-r--r--missing_d/memmove.c262
-rw-r--r--missing_d/mktime.c2
-rw-r--r--missing_d/snprintf.c197
-rw-r--r--missing_d/snprintf.c.save136
-rw-r--r--missing_d/strncasecmp.c177
-rw-r--r--missing_d/strtod.c2
10 files changed, 761 insertions, 229 deletions
diff --git a/missing_d/ChangeLog b/missing_d/ChangeLog
index 72c2f71e..261df786 100644
--- a/missing_d/ChangeLog
+++ b/missing_d/ChangeLog
@@ -1,3 +1,65 @@
+Mon Oct 22 08:49:05 2007 Arnold D. Robbins <arnold@skeeve.com>
+
+ * Release 3.1.6: Release tar file made.
+
+Sun Oct 14 19:37:33 2007 Arnold D. Robbins <arnold@skeeve.com>
+
+ * snprintf.c (safe_tmpfile): If have `atexit', add call to a function
+ that closes the open fp and unlinks the file. Needed mainly for
+ PC which can't do Unix-style unlink-after-open.
+
+Tue Oct 2 22:12:13 2007 Arnold D. Robbins <arnold@skeeve.com>
+
+ * snprintf.c (safe_tmpfile): Add use of TMPDIR and TEMP environment
+ variables for systems that may not have a /tmp. For MS systems
+ do unlink at close. Thanks to Eli Zaretskii and Scott Deifik
+ for motivating me to do the right thing.
+
+Fri Apr 13 06:05:05 2007 Arnold D. Robbins <arnold@skeeve.com>
+
+ * getaddrinfo.c: Add test for HAVE_SOCKETS with error message
+ if not. Thanks to Pat Rankin.
+
+Sun Apr 8 16:15:27 2007 Arnold D. Robbins <arnold@skeeve.com>
+
+ * getaddrinfo.c: Add include of <netinet/in.h>, and <arpa/inet.h>.
+
+Fri Apr 6 13:23:04 2007 Arnold D. Robbins <arnold@skeeve.com>
+
+ * memmove.c.BSD, strncasecmp.c.BSD: Removed so that they won't make
+ their way into a tarball; these were the original versions from BSD
+ that were in use until the Savannah CVS archive went into place; see
+ the entry from August 25, 2006.
+
+Thu Apr 5 17:01:15 2007 Arnold D. Robbins <arnold@skeeve.com>
+
+ * sprintf.c (snprintf): Fix typo and call vsnprintf
+ instead of calling self recursively. Thanks to Pat Rankin.
+
+Tue Feb 27 20:58:01 2007 Arnold D. Robbins <arnold@skeeve.com>
+
+ * snprintf.c: Change names from gawk_xxx to real xxx.
+
+Mon Jan 15 14:34:30 2007 Arnold D. Robbins <arnold@skeeve.com>
+
+ * getaddrinfo.h, getaddrinfo.c: New files, based on
+ submission by Jan Pazdziora <jpazdziora@redhat.com>.
+
+Fri Sep 15 15:05:09 2006 Arnold D. Robbins <arnold@skeeve.com>
+
+ * strncasecmp.c, memmove.c: Corrected the FSF's address.
+
+Fri Aug 25 13:21:57 2006 Arnold D. Robbins <arnold@skeeve.com>
+
+ * README: New file.
+ * strncasecmp.c, memmove.c: Replaced with versions
+ from GLIBC, hacked unmercifully to work standalone.
+
+Fri Oct 21 11:18:10 2005 Arnold D. Robbins <arnold@skeeve.com>
+
+ * strtod.c (gawk_strtod): Made check for locale's decimal
+ point conditional also upon do_posix.
+
Tue Jul 26 21:46:16 2005 Arnold D. Robbins <arnold@skeeve.com>
* Release 3.1.5: Release tar file made.
diff --git a/missing_d/README b/missing_d/README
new file mode 100644
index 00000000..735889d8
--- /dev/null
+++ b/missing_d/README
@@ -0,0 +1,14 @@
+Fri Aug 25 13:23:06 IDT 2006
+============================
+
+The files memmove.c, mktime.c, snprintf.c, strerror.c, strftime.c,
+strncasecmp.c, and system.c are copyright by the Free Software
+Foundation. They are licensed under the GPL or the LGPL. See the
+COPYING.LIB file in this directory and the COPYING file in the parent
+directory for licensing information.
+
+All other files are public domain.
+
+Arnold Robbins
+arnold@skeeve.com
+
diff --git a/missing_d/getaddrinfo.c b/missing_d/getaddrinfo.c
new file mode 100644
index 00000000..677f27d0
--- /dev/null
+++ b/missing_d/getaddrinfo.c
@@ -0,0 +1,112 @@
+#ifndef HAVE_SOCKETS
+#error getaddrinfo.c included by mistake! no socket support!
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+
+#include "getaddrinfo.h"
+
+void
+freeaddrinfo(struct addrinfo *res)
+{
+ if (res->ai_addr != NULL)
+ free(res->ai_addr);
+ free(res);
+}
+
+int
+getaddrinfo(const char *hostname, const char *portname,
+ struct addrinfo *hints, struct addrinfo **res)
+{
+ struct addrinfo *out;
+ if (res == NULL)
+ return -1;
+
+ out = (struct addrinfo *) malloc(sizeof(*out));
+ if (out == NULL) {
+ *res = NULL;
+ return -1;
+ }
+ memset(out, '\0', sizeof(*out));
+
+ out->ai_addr = (struct sockaddr *) malloc(sizeof(struct sockaddr_in));
+ if (out->ai_addr == NULL) {
+ free(out);
+ *res = NULL;
+ return -1;
+ }
+
+ out->ai_socktype = SOCK_STREAM;
+ if (hints != NULL) {
+ if (hints->ai_socktype)
+ out->ai_socktype = hints->ai_socktype;
+ if (hints->ai_protocol)
+ out->ai_protocol = hints->ai_protocol;
+ }
+
+ if (out->ai_protocol == 0) {
+ switch (out->ai_socktype) {
+ case SOCK_STREAM:
+ out->ai_protocol = IPPROTO_TCP;
+ break;
+ case SOCK_DGRAM:
+ out->ai_protocol = IPPROTO_UDP;
+ break;
+ case SOCK_RAW:
+ out->ai_protocol = IPPROTO_RAW;
+ break;
+ }
+ }
+
+ out->ai_addrlen = sizeof(struct sockaddr_in);
+ memset(out->ai_addr, '\0', sizeof(struct sockaddr_in));
+
+ if (hostname != NULL) {
+ struct hostent *he;
+ he = gethostbyname(hostname);
+ if (he != NULL && he->h_addr_list != NULL) {
+ ((struct sockaddr_in *)out->ai_addr)->sin_addr.s_addr
+ = ((struct in_addr *)he->h_addr_list[0])->s_addr;
+ } else {
+ freeaddrinfo(out);
+ return -1;
+ }
+ } else {
+ if (!(out->ai_flags & AI_PASSIVE))
+ ((struct sockaddr_in *)out->ai_addr)->sin_addr.s_addr
+ = htonl(INADDR_ANY);
+ }
+ ((struct sockaddr_in *)out->ai_addr)->sin_family = AF_INET;
+ out->ai_family = AF_INET;
+
+ if (portname != NULL && *portname) {
+ long portnum;
+ char *end;
+ portnum = strtol(portname, &end, 10);
+ if (*end == '\0' && portnum > 0 && portnum < 65536) {
+ ((struct sockaddr_in *)out->ai_addr)->sin_port
+ = htons(portnum);
+ } else {
+ struct servent *se;
+ se = getservbyname(portname, NULL);
+ if (se != NULL) {
+ ((struct sockaddr_in *)out->ai_addr)->sin_port
+ = se->s_port;
+ }
+ }
+ }
+
+ *res = out;
+
+ return 0;
+}
+#endif
diff --git a/missing_d/getaddrinfo.h b/missing_d/getaddrinfo.h
new file mode 100644
index 00000000..2d369213
--- /dev/null
+++ b/missing_d/getaddrinfo.h
@@ -0,0 +1,26 @@
+#ifndef AI_ADDRCONFIG
+#define AI_ADDRCONFIG 0
+#endif /* AI_ADDRCONFIG */
+#ifndef AI_PASSIVE
+#define AI_PASSIVE 1
+#endif /* AI_PASSIVE */
+
+#define addrinfo xaddrinfo
+#define freeaddrinfo xfreeaddrinfo
+#define getaddrinfo xgetaddrinfo
+
+struct addrinfo
+{
+ int ai_flags;
+ int ai_socktype;
+ int ai_family;
+ int ai_protocol;
+ socklen_t ai_addrlen;
+ struct sockaddr * ai_addr;
+ struct xaddrinfo * ai_next;
+};
+
+void freeaddrinfo(struct xaddrinfo * res);
+
+int getaddrinfo(const char * hostname, const char * portname,
+ struct xaddrinfo * hints, struct xaddrinfo ** res);
diff --git a/missing_d/memmove.c b/missing_d/memmove.c
index 928b812e..a28a32d1 100644
--- a/missing_d/memmove.c
+++ b/missing_d/memmove.c
@@ -1,149 +1,139 @@
-/*-
- * 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. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. 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.
- */
+/* Copy memory to memory until the specified number of bytes
+ has been copied. Overlap is handled correctly.
+ Copyright (C) 1991, 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Torbjorn Granlund (tege@sics.se).
-#if 0
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
-#include <sys/cdefs.h>
-#include <string.h>
-#endif
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301 USA */
/*
- * sizeof(word) MUST BE A POWER OF TWO
- * SO THAT wmask BELOW IS ALL ONES
+ * August 2006. For Gawk: Borrowed from GLIBC and hacked unmercifully.
+ * DON'T steal this for your own code, got straight to the GLIBC
+ * source for the original versions.
*/
-typedef int word; /* "word" used for optimal copy speed */
-#define wsize sizeof(word)
-#define wmask (wsize - 1)
-/* ADR: 1/2004. For gawk, we need memmove(). */
-#define MEMMOVE 1
+/* This stuff from libc/sysdeps/generic/memcopy.h */
+typedef unsigned char byte;
+
+/* Copy exactly NBYTES bytes from SRC_BP to DST_BP,
+ without any assumptions about alignment of the pointers. */
+#define BYTE_COPY_FWD(dst_bp, src_bp, nbytes) \
+ do \
+ { \
+ size_t __nbytes = (nbytes); \
+ while (__nbytes > 0) \
+ { \
+ byte __x = ((byte *) src_bp)[0]; \
+ src_bp += 1; \
+ __nbytes -= 1; \
+ ((byte *) dst_bp)[0] = __x; \
+ dst_bp += 1; \
+ } \
+ } while (0)
+
+/* Copy exactly NBYTES_TO_COPY bytes from SRC_END_PTR to DST_END_PTR,
+ beginning at the bytes right before the pointers and continuing towards
+ smaller addresses. Don't assume anything about alignment of the
+ pointers. */
+#define BYTE_COPY_BWD(dst_ep, src_ep, nbytes) \
+ do \
+ { \
+ size_t __nbytes = (nbytes); \
+ while (__nbytes > 0) \
+ { \
+ byte __x; \
+ src_ep -= 1; \
+ __x = ((byte *) src_ep)[0]; \
+ dst_ep -= 1; \
+ __nbytes -= 1; \
+ ((byte *) dst_ep)[0] = __x; \
+ } \
+ } while (0)
+
+/* end of stuff from memcopy.h */
-/*
- * Copy a block of memory, handling overlap.
- * This is the routine that actually implements
- * (the portable versions of) bcopy, memcpy, and memmove.
- */
-#ifdef MEMCOPY
-void *
-memcpy(dst0, src0, length)
-#else
-#ifdef MEMMOVE
void *
-memmove(dst0, src0, length)
-#else
-void
-bcopy(src0, dst0, length)
-#endif
-#endif
- void *dst0;
- const void *src0;
- register size_t length;
+memmove (dest, src, len)
+ void *dest;
+ const void *src;
+ size_t len;
{
- register char *dst = dst0;
- register const char *src = src0;
- register size_t t;
-
- if (length == 0 || dst == src) /* nothing to do */
- goto done;
-
- /*
- * Macros: loop-t-times; and loop-t-times, t>0
- */
-#define TLOOP(s) if (t) TLOOP1(s)
-#define TLOOP1(s) do { s; } while (--t)
-
- if ((unsigned long)dst < (unsigned long)src) {
- /*
- * Copy forward.
- */
- t = (int)src; /* only need low bits */
- if ((t | (int)dst) & wmask) {
- /*
- * Try to align operands. This cannot be done
- * unless the low bits match.
- */
- if ((t ^ (int)dst) & wmask || length < wsize)
- t = length;
- else
- t = wsize - (t & wmask);
- length -= t;
- TLOOP1(*dst++ = *src++);
- }
- /*
- * Copy whole words, then mop up any trailing bytes.
- */
- t = length / wsize;
- TLOOP(*(word *)dst = *(word *)src; src += wsize; dst += wsize);
- t = length & wmask;
- TLOOP(*dst++ = *src++);
- } else {
- /*
- * Copy backwards. Otherwise essentially the same.
- * Alignment works as before, except that it takes
- * (t&wmask) bytes to align, not wsize-(t&wmask).
- */
- src += length;
- dst += length;
- t = (int)src;
- if ((t | (int)dst) & wmask) {
- if ((t ^ (int)dst) & wmask || length <= wsize)
- t = length;
- else
- t &= wmask;
- length -= t;
- TLOOP1(*--dst = *--src);
- }
- t = length / wsize;
- TLOOP(src -= wsize; dst -= wsize; *(word *)dst = *(word *)src);
- t = length & wmask;
- TLOOP(*--dst = *--src);
+ unsigned long int dstp = (long int) dest;
+ unsigned long int srcp = (long int) src;
+
+ /* This test makes the forward copying code be used whenever possible.
+ Reduces the working set. */
+ if (dstp - srcp >= len) /* *Unsigned* compare! */
+ {
+ /* Copy from the beginning to the end. */
+#if 0 /* screw all this */
+ /* If there not too few bytes to copy, use word copy. */
+ if (len >= OP_T_THRES)
+ {
+ /* Copy just a few bytes to make DSTP aligned. */
+ len -= (-dstp) % OPSIZ;
+ BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
+
+ /* Copy whole pages from SRCP to DSTP by virtual address
+ manipulation, as much as possible. */
+
+ PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
+
+ /* Copy from SRCP to DSTP taking advantage of the known
+ alignment of DSTP. Number of bytes remaining is put
+ in the third argument, i.e. in LEN. This number may
+ vary from machine to machine. */
+
+ WORD_COPY_FWD (dstp, srcp, len, len);
+
+ /* Fall out and copy the tail. */
+ }
+
+ /* There are just a few bytes to copy. Use byte memory operations. */
+#endif
+ BYTE_COPY_FWD (dstp, srcp, len);
+ }
+ else
+ {
+ /* Copy from the end to the beginning. */
+ srcp += len;
+ dstp += len;
+
+#if 0 /* ditto */
+ /* If there not too few bytes to copy, use word copy. */
+ if (len >= OP_T_THRES)
+ {
+ /* Copy just a few bytes to make DSTP aligned. */
+ len -= dstp % OPSIZ;
+ BYTE_COPY_BWD (dstp, srcp, dstp % OPSIZ);
+
+ /* Copy from SRCP to DSTP taking advantage of the known
+ alignment of DSTP. Number of bytes remaining is put
+ in the third argument, i.e. in LEN. This number may
+ vary from machine to machine. */
+
+ WORD_COPY_BWD (dstp, srcp, len, len);
+
+ /* Fall out and copy the tail. */
}
-done:
-#if defined(MEMCOPY) || defined(MEMMOVE)
- return (dst0);
-#else
- return;
#endif
+ /* There are just a few bytes to copy. Use byte memory operations. */
+ BYTE_COPY_BWD (dstp, srcp, len);
+ }
+
+ return (dest);
}
-#undef wsize
-#undef wmask
-#undef MEMMOVE
-#undef TLOOP
-#undef TLOOP1
diff --git a/missing_d/mktime.c b/missing_d/mktime.c
index 217dfafb..d394ef17 100644
--- a/missing_d/mktime.c
+++ b/missing_d/mktime.c
@@ -4,7 +4,7 @@
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
- published by the Free Software Foundation; either version 2 of the
+ published by the Free Software Foundation; either version 3 of the
License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
diff --git a/missing_d/snprintf.c b/missing_d/snprintf.c
new file mode 100644
index 00000000..df7f1da7
--- /dev/null
+++ b/missing_d/snprintf.c
@@ -0,0 +1,197 @@
+/*
+ * snprintf.c - Implement snprintf and vsnprintf on platforms that need them.
+ */
+
+/*
+ * Copyright (C) 2006, 2007 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* If using in a multi-threaded context, then SNPRINTF_REENTRANT must be
+ defined. But in that case, performance will be much worse, since a
+ temporary file is created and closed for each call to snprintf. */
+
+#if defined(HAVE_MKSTEMP)
+/* If mkstemp is available, use it instead of tmpfile(), since some older
+ implementations of tmpfile() were not secure. */
+
+static char *tmpfilename = NULL;
+static FILE *safe_f = NULL;
+
+#ifdef HAVE_ATEXIT
+static void close_safe_f()
+{
+ if (safe_f != NULL) {
+ fclose(safe_f);
+ safe_f = NULL;
+ }
+ if (tmpfilename != NULL) {
+ unlink(tmpfilename);
+ free(tmpfilename);
+ tmpfilename = NULL;
+ }
+}
+#endif
+
+static FILE *
+safe_tmpfile (void)
+{
+ static short first = TRUE;
+ static const char template[] = "snprintfXXXXXX";
+ int fd;
+ static char *tmpdir = NULL;
+ static int len = 0;
+
+ if (first) {
+ first = FALSE;
+ /*
+ * First try Unix stanadard env var, then Windows var,
+ * then fall back to /tmp.
+ */
+ if ((tmpdir = getenv("TMPDIR")) != NULL && *tmpdir != '\0')
+ ; /* got it */
+ else if ((tmpdir = getenv("TEMP")) != NULL && *tmpdir != '\0')
+ ; /* got it */
+ else
+ tmpdir = "/tmp";
+
+ len = strlen(tmpdir) + 1 + strlen(template) + 1;
+#ifdef HAVE_ATEXIT
+ atexit(close_safe_f);
+#endif /* HAVE_ATEXIT */
+ }
+
+ if ((tmpfilename = (char *) malloc(len)) == NULL)
+ return NULL;
+ else
+ sprintf(tmpfilename, "%s/%s", tmpdir, template);
+
+ if ((fd = mkstemp (tmpfilename)) < 0)
+ return NULL;
+
+#if ! defined(DJGPP) && ! defined(MSDOS) && ! defined(_MSC_VER) \
+ && ! defined(_WIN32) && ! defined(__CRTRSXNT__) && ! defined(__EMX__) \
+ && ! defined(__MINGW32__) && ! defined(__WIN32__)
+ /* If not MS, unlink after opening. */
+ unlink (tmpfilename);
+ free(tmpfilename);
+ tmpfilename = NULL;
+#endif
+
+ if ((safe_f = fdopen (fd, "w+b")) == NULL) {
+ close (fd);
+ return NULL;
+ }
+ /* setvbuf(f,NULL,_IOFBF,4*BUFSIZ); */
+ return safe_f;
+}
+
+#elif defined(HAVE_TMPFILE)
+#define safe_tmpfile tmpfile
+#else
+#error Neither mkstemp() nor tmpfile() is available on this platform.
+#endif
+
+int
+vsnprintf (char *restrict buf, size_t len,
+ const char *restrict fmt, va_list args)
+{
+ int actual;
+ int nread;
+ size_t cnt = 0;
+#ifndef SNPRINTF_REENTRANT
+ static
+#endif
+ FILE *fp;
+
+ if ((buf == NULL) || (len < 1))
+ return -1;
+
+ buf[0] = '\0'; /* in case the caller does not check the return code! */
+
+#ifdef SNPRINTF_REENTRANT
+ if ((fp = safe_tmpfile ()) == NULL)
+ return -1;
+#else
+ if ((fp == NULL) && ((fp = safe_tmpfile ()) == NULL))
+ return -1;
+ rewind (fp);
+#endif
+ actual = vfprintf (fp, fmt, args);
+ rewind (fp);
+ if (actual < 0) {
+#ifdef SNPRINTF_REENTRANT
+ fclose (fp);
+ if (tmpfilename != NULL) {
+ unlink(tmpfilename);
+ free(tmpfilename);
+ tmpfilename = NULL;
+ }
+#endif
+ return -1;
+ }
+ else if ((size_t) actual < len)
+ len = actual;
+ else
+ --len;
+ while (cnt < len && (nread = fread (buf + cnt, 1, len - cnt, fp)) > 0)
+ cnt += nread;
+ buf[cnt] = '\0';
+#ifdef SNPRINTF_REENTRANT
+ fclose (fp);
+ if (tmpfilename != NULL) {
+ unlink(tmpfilename);
+ free(tmpfilename);
+ tmpfilename = NULL;
+ }
+#endif
+ if (cnt < len)
+ return -1;
+
+ return actual;
+}
+
+int
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+snprintf (char *restrict buf, size_t len, const char *restrict fmt, ...)
+#else
+snprintf (va_alist)
+ va_dcl
+#endif
+{
+ int rv;
+ va_list args;
+
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ va_start (args, fmt);
+#else
+ char *buf;
+ size_t len;
+ char *fmt;
+
+ va_start (args);
+ buf = va_arg (args, char *);
+ len = va_arg (args, size_t);
+ fmt = va_arg (args, char *);
+#endif
+ rv = vsnprintf (buf, len, fmt, args);
+ va_end (args);
+ return rv;
+}
diff --git a/missing_d/snprintf.c.save b/missing_d/snprintf.c.save
new file mode 100644
index 00000000..9f59e73e
--- /dev/null
+++ b/missing_d/snprintf.c.save
@@ -0,0 +1,136 @@
+/*
+ * snprintf.c - Implement snprintf and vsnprintf on platforms that need them.
+ */
+
+/*
+ * Copyright (C) 2006 the Free Software Foundation, Inc.
+ *
+ * This file is part of GAWK, the GNU implementation of the
+ * AWK Programming Language.
+ *
+ * GAWK is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GAWK is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+
+/* If using in a multi-threaded context, then SNPRINTF_REENTRANT must be
+ defined. But in that case, performance will be much worse, since a
+ temporary file is created and closed for each call to snprintf. */
+
+#if defined(HAVE_MKSTEMP)
+/* If mkstemp is available, use it instead of tmpfile(), since some older
+ implementations of tmpfile() were not secure. */
+
+static FILE *
+safe_tmpfile (void)
+{
+ static const char template[] = "/tmp/snprintfXXXXXX";
+ FILE *f;
+ int fd;
+ char t[sizeof (template)];
+
+ strcpy (t, template);
+ if ((fd = mkstemp (t)) < 0)
+ return NULL;
+ unlink (t);
+ if ((f = fdopen (fd, "w+b")) == NULL) {
+ close (fd);
+ return NULL;
+ }
+ /* setvbuf(f,NULL,_IOFBF,4*BUFSIZ); */
+ return f;
+}
+
+#elif defined(HAVE_TMPFILE)
+#define safe_tmpfile tmpfile
+#else
+#error Neither mkstemp() nor tmpfile() is available on this platform.
+#endif
+
+int
+vsnprintf (char *restrict buf, size_t len,
+ const char *restrict fmt, va_list args)
+{
+ int actual;
+ int nread;
+ size_t cnt = 0;
+#ifndef SNPRINTF_REENTRANT
+ static
+#endif
+ FILE *fp;
+
+ if ((buf == NULL) || (len < 1))
+ return -1;
+
+ buf[0] = '\0'; /* in case the caller does not check the return code! */
+
+#ifdef SNPRINTF_REENTRANT
+ if ((fp = safe_tmpfile ()) == NULL)
+ return -1;
+#else
+ if ((fp == NULL) && ((fp = safe_tmpfile ()) == NULL))
+ return -1;
+ rewind (fp);
+#endif
+ actual = vfprintf (fp, fmt, args);
+ rewind (fp);
+ if (actual < 0) {
+#ifdef SNPRINTF_REENTRANT
+ fclose (fp);
+#endif
+ return -1;
+ }
+ else if ((size_t) actual < len)
+ len = actual;
+ else
+ --len;
+ while (cnt < len && (nread = fread (buf + cnt, 1, len - cnt, fp)) > 0)
+ cnt += nread;
+ buf[cnt] = '\0';
+#ifdef SNPRINTF_REENTRANT
+ fclose (fp);
+#endif
+ if (cnt < len)
+ return -1;
+
+ return actual;
+}
+
+int
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+snprintf (char *restrict buf, size_t len, const char *restrict fmt, ...)
+#else
+snprintf (va_alist)
+ va_dcl
+#endif
+{
+ int rv;
+ va_list args;
+
+#if defined(HAVE_STDARG_H) && defined(__STDC__) && __STDC__
+ va_start (args, fmt);
+#else
+ char *buf;
+ size_t len;
+ char *fmt;
+
+ va_start (args);
+ buf = va_arg (args, char *);
+ len = va_arg (args, size_t);
+ fmt = va_arg (args, char *);
+#endif
+ rv = vsnprintf (buf, len, fmt, args);
+ va_end (args);
+ return rv;
+}
diff --git a/missing_d/strncasecmp.c b/missing_d/strncasecmp.c
index 9d17c648..74872356 100644
--- a/missing_d/strncasecmp.c
+++ b/missing_d/strncasecmp.c
@@ -1,102 +1,97 @@
-/*
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University 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 WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
+/* Copyright (C) 1991,1992,1995,1996,1997,2001,2002, 2004
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301 USA */
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strcasecmp.c 5.6 (Berkeley) 6/27/88";
-#endif /* LIBC_SCCS and not lint */
-
-#ifdef atarist
-#include <sys/types.h>
-#else
-#define u_char unsigned char
-#endif
-
-/* This rather ugly macro is for VMS C */
-#ifdef C
-#undef C
-#endif
-#define C(c) ((u_char)c)
/*
- * This array is designed for mapping upper and lower case letter
- * together for a case independent comparison. The mappings are
- * based upon ascii character sequences.
+ * August 2006. For Gawk: Borrowed from GLIBC to replace BSD licensed version.
+ * DON'T steal this for your own code, just go to the GLIBC sources.
+ * This version hacked unmercifully.
*/
-static u_char charmap[] = {
- '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
- '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
- '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
- '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
- '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
- '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
- '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
- '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
- '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
- '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
- '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
- '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
- '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
- '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
- '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
- '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
- C('\200'), C('\201'), C('\202'), C('\203'), C('\204'), C('\205'), C('\206'), C('\207'),
- C('\210'), C('\211'), C('\212'), C('\213'), C('\214'), C('\215'), C('\216'), C('\217'),
- C('\220'), C('\221'), C('\222'), C('\223'), C('\224'), C('\225'), C('\226'), C('\227'),
- C('\230'), C('\231'), C('\232'), C('\233'), C('\234'), C('\235'), C('\236'), C('\237'),
- C('\240'), C('\241'), C('\242'), C('\243'), C('\244'), C('\245'), C('\246'), C('\247'),
- C('\250'), C('\251'), C('\252'), C('\253'), C('\254'), C('\255'), C('\256'), C('\257'),
- C('\260'), C('\261'), C('\262'), C('\263'), C('\264'), C('\265'), C('\266'), C('\267'),
- C('\270'), C('\271'), C('\272'), C('\273'), C('\274'), C('\275'), C('\276'), C('\277'),
- C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'),
- C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'),
- C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\327'),
- C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\337'),
- C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'),
- C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'),
- C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\367'),
- C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\377'),
-};
-
-#undef C
+
+/* Compare S1 and S2, ignoring case, returning less than, equal to or
+ greater than zero if S1 is lexicographically less than,
+ equal to or greater than S2. */
int
-strcasecmp(s1, s2)
- const char *s1, *s2;
+strcasecmp (s1, s2)
+ const char *s1;
+ const char *s2;
{
- register u_char *cm = charmap,
- *us1 = (u_char *)s1,
- *us2 = (u_char *)s2;
-
- while (cm[*us1] == cm[*us2++])
- if (*us1++ == '\0')
- return(0);
- return(cm[*us1] - cm[*--us2]);
+ const unsigned char *p1 = (const unsigned char *) s1;
+ const unsigned char *p2 = (const unsigned char *) s2;
+ int result;
+
+ if (p1 == p2)
+ return 0;
+
+ while ((result = tolower (*p1) - tolower (*p2++)) == 0)
+ if (*p1++ == '\0')
+ break;
+
+ return result;
}
+/* Compare at most N characters of two strings without taking care for
+ the case.
+ Copyright (C) 1992, 1996, 1997, 2001, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/*
+ * August 2006, for gawk, same comment applies. See strncase.c
+ * in the GLIBC sources.
+ */
+
+
+/* Compare no more than N characters of S1 and S2,
+ ignoring case, returning less than, equal to or
+ greater than zero if S1 is lexicographically less
+ than, equal to or greater than S2. */
int
-strncasecmp(s1, s2, n)
- const char *s1, *s2;
- register size_t n;
+strncasecmp (s1, s2, n)
+ const char *s1;
+ const char *s2;
+ size_t n;
{
- register u_char *cm = charmap,
- *us1 = (u_char *)s1,
- *us2 = (u_char *)s2;
-
- while ((long)(--n) >= 0 && cm[*us1] == cm[*us2++])
- if (*us1++ == '\0')
- return(0);
- return((long)n < 0 ? 0 : cm[*us1] - cm[*--us2]);
+ const unsigned char *p1 = (const unsigned char *) s1;
+ const unsigned char *p2 = (const unsigned char *) s2;
+ int result;
+
+ if (p1 == p2 || n == 0)
+ return 0;
+
+ while ((result = tolower (*p1) - tolower (*p2++)) == 0)
+ if (*p1++ == '\0' || --n == 0)
+ break;
+
+ return result;
}
diff --git a/missing_d/strtod.c b/missing_d/strtod.c
index 5ebc8c6e..c4f9d2bd 100644
--- a/missing_d/strtod.c
+++ b/missing_d/strtod.c
@@ -70,7 +70,7 @@ register const char **ptr;
if (
#if defined(HAVE_LOCALE_H)
- loc.decimal_point != NULL
+ loc.decimal_point != NULL && do_posix
? *s == loc.decimal_point[0]
: *s == '.'
#else