Assume C99 compiler. Drop pre-C99 checks.
Assume and require that all Single Unix Specification v3
specified headers are present.
Remove trio library, libesmtp and KAME get????info.?.
Reshuffle #include "fetchmail.h" where needed.
Drop compatibility cruft for BeOS, Cygwin, EMX.
| MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
| CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
-The m4/gethostbyname_r.m4 and libesmtp/* files functions are (C) by
-Brian Stafford, see the respective file headers for details (LGPL v2.1
-or later).
-
-The KAME/* files are (C) Copyright (C) 1995, 1996, 1997, and 1998 WIDE
-Project, see the respective file headers for details.
+The m4/gethostbyname_r.m4 files functions are (C) by Brian Stafford,
+see the respective file headers for details (LGPL v2.1 or later).
All other code in the distribution incorporates the copy of GPL version 2
below by reference.
+++ /dev/null
-/* $KAME: getnameinfo.c,v 1.72 2005/01/13 04:12:03 itojun Exp $ */
-
-/*
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * 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. Neither the name of the project 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 PROJECT 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 PROJECT 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.
- */
-
-/*
- * Issues to be discussed:
- * - RFC2553 says that we should raise error on short buffer. X/Open says
- * we need to truncate the result. We obey RFC2553 (and X/Open should be
- * modified). ipngwg rough consensus seems to follow RFC2553. RFC3493 says
- * nothing about it, but defines a new error code EAI_OVERFLOW which seems
- * to be intended the code for this case.
- * - What is "local" in NI_NOFQDN? (see comments in the code)
- * - NI_NAMEREQD and NI_NUMERICHOST conflict with each other.
- * - (KAME extension) always attach textual scopeid (fe80::1%lo0), if
- * sin6_scope_id is filled - standardization status?
- * - what should we do if we should do getservbyport("sctp")?
- */
-
-/*
- * Considerations about thread-safeness
- * The code in this file is thread-safe, and so the thread-safeness of
- * getnameinfo() depends on the property of backend functions.
- * - getservbyport() is not thread safe for most systems we are targeting.
- * - getipnodebyaddr() is thread safe. However, many resolver libraries
- * used in the function are not thread safe.
- * - gethostbyaddr() is usually not thread safe.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifndef HAVE_GETNAMEINFO
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <arpa/nameser.h>
-#include <netdb.h>
-#include <resolv.h>
-#include <string.h>
-#include <stddef.h>
-#include <errno.h>
-
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#include "fetchmail.h"
-#include "getaddrinfo.h"
-
-static const struct afd {
- int a_af;
- int a_addrlen;
- int a_socklen;
- int a_off;
- int a_portoff;
-} afdl [] = {
-#ifdef INET6
- {PF_INET6, sizeof(struct in6_addr), sizeof(struct sockaddr_in6),
- offsetof(struct sockaddr_in6, sin6_addr),
- offsetof(struct sockaddr_in6, sin6_port)},
-#endif
- {PF_INET, sizeof(struct in_addr), sizeof(struct sockaddr_in),
- offsetof(struct sockaddr_in, sin_addr),
- offsetof(struct sockaddr_in, sin_port)},
- {0, 0, 0, 0, 0},
-};
-
-#ifdef INET6
-static int ip6_parsenumeric __P((const struct sockaddr *, const char *, char *,
- size_t, int));
-static int ip6_sa2str __P((const struct sockaddr_in6 *, char *, size_t, int));
-#endif
-
-int
-getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
- const struct sockaddr *sa;
-#ifdef HAVE_SOCKLEN_T
- socklen_t salen;
-#else
- unsigned int salen;
-#endif
- char *host;
- size_t hostlen;
- char *serv;
- size_t servlen;
- int flags;
-{
- const struct afd *afd;
- struct servent *sp;
- struct hostent *hp;
- u_short port;
- int family, i;
- const char *addr;
- u_int32_t v4a;
- int h_error;
- char numserv[512];
- char numaddr[512];
-
- if (sa == NULL)
- return EAI_FAIL;
-
-#ifdef HAVE_SA_LEN /*XXX*/
- if (sa->sa_len != salen)
- return EAI_FAIL;
-#endif
-
- family = sa->sa_family;
- for (i = 0; afdl[i].a_af; i++)
- if (afdl[i].a_af == family) {
- afd = &afdl[i];
- goto found;
- }
- return EAI_FAMILY;
-
- found:
- if (salen != afd->a_socklen)
- return EAI_FAIL;
-
- /* network byte order */
- memcpy(&port, (const char *)sa + afd->a_portoff, sizeof(port));
- addr = (const char *)sa + afd->a_off;
-
- if (serv == NULL || servlen == 0) {
- /*
- * do nothing in this case.
- * in case you are wondering if "&&" is more correct than
- * "||" here: RFC3493 says that serv == NULL OR servlen == 0
- * means that the caller does not want the result.
- */
- } else {
- if (flags & NI_NUMERICSERV)
- sp = NULL;
- else {
- sp = getservbyport(port,
- (flags & NI_DGRAM) ? "udp" : "tcp");
- }
- if (sp) {
- if (strlen(sp->s_name) + 1 > servlen)
- return EAI_OVERFLOW;
- strlcpy(serv, sp->s_name, servlen);
- } else {
- snprintf(numserv, sizeof(numserv), "%u", ntohs(port));
- if (strlen(numserv) + 1 > servlen)
- return EAI_OVERFLOW;
- strlcpy(serv, numserv, servlen);
- }
- }
-
- switch (sa->sa_family) {
- case AF_INET:
- v4a = (u_int32_t)
- ntohl(((const struct sockaddr_in *)sa)->sin_addr.s_addr);
- if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a))
- flags |= NI_NUMERICHOST;
- v4a >>= IN_CLASSA_NSHIFT;
- if (v4a == 0)
- flags |= NI_NUMERICHOST;
- break;
-#ifdef INET6
- case AF_INET6:
- {
- const struct sockaddr_in6 *sin6;
- sin6 = (const struct sockaddr_in6 *)sa;
- switch (sin6->sin6_addr.s6_addr[0]) {
- case 0x00:
- if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
- ;
- else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
- ;
- else
- flags |= NI_NUMERICHOST;
- break;
- default:
- if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr))
- flags |= NI_NUMERICHOST;
- else if (IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))
- flags |= NI_NUMERICHOST;
- break;
- }
- }
- break;
-#endif
- }
- if (host == NULL || hostlen == 0) {
- /*
- * do nothing in this case.
- * in case you are wondering if "&&" is more correct than
- * "||" here: RFC3493 says that host == NULL or hostlen == 0
- * means that the caller does not want the result.
- */
- } else if (flags & NI_NUMERICHOST) {
- /* NUMERICHOST and NAMEREQD conflicts with each other */
- if (flags & NI_NAMEREQD)
- return EAI_NONAME;
-
- goto numeric;
- } else {
-#ifdef USE_GETIPNODEBY
- hp = getipnodebyaddr(addr, afd->a_addrlen, afd->a_af, &h_error);
-#else
- hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
-#ifdef HAVE_H_ERRNO
- h_error = h_errno;
-#else
- h_error = EINVAL;
-#endif
-#endif
-
- if (hp) {
-#if 0
- if (flags & NI_NOFQDN) {
- /*
- * According to RFC3493 section 6.2, NI_NOFQDN
- * means "node name portion of the FQDN shall
- * be returned for local hosts." The following
- * code tries to implement it by returning the
- * first label (the part before the first
- * period) of the FQDN. However, it is not
- * clear if this always makes sense, since the
- * given address may be outside of "local
- * hosts." Due to the unclear description, we
- * disable the code in this implementation.
- */
- char *p;
- p = strchr(hp->h_name, '.');
- if (p)
- *p = '\0';
- }
-#endif
- if (strlen(hp->h_name) + 1 > hostlen) {
-#ifdef USE_GETIPNODEBY
- freehostent(hp);
-#endif
- return EAI_OVERFLOW;
- }
- strlcpy(host, hp->h_name, hostlen);
-#ifdef USE_GETIPNODEBY
- freehostent(hp);
-#endif
- } else {
- if (flags & NI_NAMEREQD)
- return EAI_NONAME;
-
- numeric:
- switch(afd->a_af) {
-#ifdef INET6
- case AF_INET6:
- {
- int error;
-
- if ((error = ip6_parsenumeric(sa, addr, host,
- hostlen,
- flags)) != 0)
- return(error);
- break;
- }
-#endif
- default:
-#ifdef HAVE_INET_NTOP
- if (inet_ntop(afd->a_af, addr, host,
- hostlen) == NULL)
- return EAI_SYSTEM;
-#else
- if (afd->a_af == AF_INET) {
- struct in_addr addr_tmp;
- addr_tmp.s_addr = addr;
- strlcpy(host, inet_ntoa(addr_tmp), hostlen);
- }
- else
- return EAI_FAMILY;
-#endif
- break;
- }
- }
- }
- return(0);
-}
-
-#ifdef INET6
-static int
-ip6_parsenumeric(sa, addr, host, hostlen, flags)
- const struct sockaddr *sa;
- const char *addr;
- char *host;
- size_t hostlen;
- int flags;
-{
- int numaddrlen;
- char numaddr[512];
-
- if (inet_ntop(AF_INET6, addr, numaddr, sizeof(numaddr)) == NULL)
- return EAI_SYSTEM;
-
- numaddrlen = strlen(numaddr);
- if (numaddrlen + 1 > hostlen) /* don't forget terminator */
- return EAI_OVERFLOW;
- strlcpy(host, numaddr, hostlen);
-
- if (((const struct sockaddr_in6 *)sa)->sin6_scope_id) {
- char zonebuf[MAXHOSTNAMELEN];
- int zonelen;
-
- zonelen = ip6_sa2str(
- (const struct sockaddr_in6 *)(const void *)sa,
- zonebuf, sizeof(zonebuf), flags);
- if (zonelen < 0)
- return EAI_OVERFLOW;
- if (zonelen + 1 + numaddrlen + 1 > hostlen)
- return EAI_OVERFLOW;
-
- /* construct <numeric-addr><delim><zoneid> */
- memcpy(host + numaddrlen + 1, zonebuf,
- (size_t)zonelen);
- host[numaddrlen] = SCOPE_DELIMITER;
- host[numaddrlen + 1 + zonelen] = '\0';
- }
-
- return 0;
-}
-
-/* ARGSUSED */
-static int
-ip6_sa2str(sa6, buf, bufsiz, flags)
- const struct sockaddr_in6 *sa6;
- char *buf;
- size_t bufsiz;
- int flags;
-{
- unsigned int ifindex;
- const struct in6_addr *a6;
- int n;
-
- ifindex = (unsigned int)sa6->sin6_scope_id;
- a6 = &sa6->sin6_addr;
-
-#ifdef NI_NUMERICSCOPE
- if ((flags & NI_NUMERICSCOPE) != 0) {
- n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
- if (n < 0 || n >= bufsiz)
- return -1;
- else
- return n;
- }
-#endif
-
- /* if_indextoname() does not take buffer size. not a good api... */
- if ((IN6_IS_ADDR_LINKLOCAL(a6) || IN6_IS_ADDR_MC_LINKLOCAL(a6) ||
- IN6_IS_ADDR_MC_NODELOCAL(a6)) && bufsiz >= IF_NAMESIZE) {
- char *p = if_indextoname(ifindex, buf);
- if (p)
- return (strlen(p));
- }
-
- /* last resort */
- n = snprintf(buf, bufsiz, "%u", sa6->sin6_scope_id);
- if (n < 0 || n >= bufsiz)
- return -1;
- else
- return n;
-}
-#endif /* INET6 */
-#endif
SUBDIRS= . po
AUTOMAKE_OPTIONS= 1.11 foreign no-dist-gzip dist-xz subdir-objects
-AM_CPPFLAGS= -I$(srcdir)/libesmtp
ACLOCAL_AMFLAGS= -I m4 -I m4-local
AM_YFLAGS= -d
# listing socket.$(OBJEXT) here is a hack to compile socket.c pretty
TESTS= t.smoke t.validate-xhtml10 t.validate-xhtml t.x509_name_match
LOG_COMPILER= env LC_ALL=C TZ=UTC $(SHELL)
-if NEED_TRIO
-noinst_LIBRARIES+= libtrio.a
-libtrio_a_SOURCES= trio/triostr.c trio/trio.c trio/trionan.c \
- trio/trio.h trio/triop.h trio/triodef.h \
- trio/trionan.h trio/triostr.h
-check_PROGRAMS+= regression
-regression_SOURCES= trio/regression.c
-LDADD+= libtrio.a -lm
-TESTS+= t.regression
-endif
-
fetchmail_SOURCES= fetchmail.h getopt.h \
gettext.h i18n.h kerberos.h fm_md5.h mx.h netrc.h smtp.h \
socket.h tunable.h \
if RPA_ENABLE
fetchmail_SOURCES += rpa.c
endif
-if NEED_GETNAMEINFO
-fetchmail_SOURCES += KAME/getnameinfo.c
-endif
-if NEED_GETADDRINFO
-fetchmail_SOURCES += libesmtp/getaddrinfo.h libesmtp/getaddrinfo.c
-endif
check_PROGRAMS += rfc822 unmime netrc rfc2047e mxget rfc822valid \
x509_name_match
EXTRA_DIST= $(DISTDOCS) $(distdirs) \
fetchmail.spec fetchmail.xpm \
- trio/CHANGES trio/README \
strlcpy.3 bighand.png \
m4/codeset.m4 \
m4/gettext.m4 \
m4/xsize.m4 \
m4-local/ac-archive-license.txt \
m4-local/ac_ma_search_package.m4 \
- $(TESTS) t.rc t.regression \
+ $(TESTS) t.rc \
dist-tools/html2txt \
dist-tools/manServer.pl \
Doxyfile
change. MA = Matthias Andree, ESR = Eric S. Raymond, RF = Rob Funk.)
# ADVANCE WARNING OF FEATURES TO BE REMOVED OR CHANGED IN FUTURE VERSIONS
-(There are no plans to remove features from a 6.4.X release, but they may be
-removed from a 6.5.0 or newer release.)
+(There are no plans to remove features from a 6.5.X release, but they may be
+removed from a 6.6.0 or newer release.)
* Future fetchmail releases may require compilers and operating systems
that adhere to standards issued 2011 or later.
(Currently, C89 and Single Unix Specification V2 should suffice.)
--------------------------------------------------------------------------------
+fetchmail-6.5.0 (not yet released):
+
+## CHANGED REQUIREMENTS
+* fetchmail 6.5.0 is written in C99 and requires a SUSv3 (Single Unix
+ Specification v3, a superset of POSIX.1-2001 aka. IEEE Std 1003.1-2001 with
+ XSI extension) compliant system.
+
+ In particular, older fetchmail versions had workarounds or replacement code
+ for several functions standardized in the Single Unix Specification v3, these
+ have been removed.
+
+ The trio/ library has been removed from the distribution.
+ The libesmtp/getaddrinfo.? library has been removed from the distribution.
+ The KAME/getnameinfo.c file has been removed from the distribution.
+
fetchmail-6.4.0 (not yet released):
# NOTE THAT FETCHMAIL IS NO LONGER PUBLISHED THROUGH IBIBLIO.
* Fetchmail prevents buffer overruns in GSSAPI authentication with user names
beyond c. 6000 characters in length. Reported by Greg Hudson.
+## CHANGED REQUIREMENTS
+* fetchmail 6.4.0 is written in C99 and requires a SUSv3 (Single Unix
+ Specification v3, a superset of POSIX.1-2001 aka. IEEE Std 1003.1-2001 with
+ XSI extension) compliant system. For now, a C89 compiler should also work
+ if the system is SUSv3 compliant.
+
+ In particular, older fetchmail versions had workaround for several functions
+ standardized in the Single Unix Specification v3, these have been removed.
+
+ The trio/ library has been removed from the distribution.
+
## CHANGES
* fetchmail 6.3.X is unsupported.
* fetchmail now configures OpenSSL support by default.
NEXTSTEP, OSF 3.2, IRIX, and Rhapsody once upon a time.
The current maintainer does not have access to these systems, and assumes that
-the system is at least Single-Unix-Specification V2 compatible, yet fetchmaiil
-should be compilable by a C89 compiler. It currently ships with a copy of the
-trio library for systems that lack snprintf().
+the system is at least Single-Unix-Specification V3 compatible, and that
+will also require a C99 compiler.
-Fetchmail should be able to be compiled with C89, C99, C11, C++98, C++03,
+Fetchmail should be able to be compiled with C99, C11, C++98, C++03,
C++11, C++14 compilers, but not C++17 because the "register" keyword is
used in some parts of the code.
-Future fetchmail releases will require modern language features such as
-"long long" and others, so this release is the last to support C89.
-
Further reading
---------------
a list of things that still need doing. If you want to hack on this code,
a list of known bugs and to-do items can be found in the file todo.html.
+
Status, source code
-------------------
* For license terms, see the file COPYING in this directory.
*/
#include "config.h"
+#include "fetchmail.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <strings.h>
#include <sys/types.h>
-#ifdef HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#else
#include <sys/socket.h>
-#endif
#include <netinet/in.h>
-#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
-#endif
#include <netdb.h>
#include "i18n.h"
#include "mx.h"
-#include "fetchmail.h"
-#include "getaddrinfo.h"
#define MX_RETRIES 3
*/
#include "config.h"
+#include "fetchmail.h"
#include "tunable.h"
#include <stdio.h>
#include <ctype.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
#include <string.h>
#include <pwd.h>
#include <errno.h>
-#include "fetchmail.h"
/* Python prettyprinting functions */
AC_CANONICAL_HOST
dnl automake options are in Makefile.am
-AC_PREREQ(2.60)
+AC_PREREQ([2.69])
dnl 2.60 required for AC_USE_SYSTEM_EXTENSIONS
AM_INIT_AUTOMAKE([silent-rules -Wall])
AM_SILENT_RULES
AC_USE_SYSTEM_EXTENSIONS
AC_PROG_AWK
AC_PROG_CC
+AC_PROG_CC_C99
+if [ "$ac_cv_prog_cc_c99" = "no" ] ; then
+ AC_MSG_ERROR([fetchmail requires a C99 capable compiler!])
+fi
AM_PROG_CC_C_O
AC_PROG_INSTALL
AC_PROG_CPP dnl Later checks need this.
+AC_PROG_CPP_WERROR
AM_PROG_AR
AC_PROG_RANLIB
-AM_PROG_CC_C_O
-
-AC_ISC_POSIX
-dnl AC_ISC_POSIX: - XXX FIXME: remove in fetchmail 6.4.
-dnl This macro adds `-lcposix' to output variable `LIBS' if necessary
-dnl for Posix facilities. Sun dropped support for the obsolete
-dnl INTERACTIVE Systems Corporation Unix on 2006-07-23. New programs
-dnl need not use this macro. It is implemented as
-dnl `AC_SEARCH_LIBS([strerror], [cposix])'
dnl check for b0rked Solaris (and other shells) and find one that works
AC_MSG_CHECKING(for a working shell...)
AC_MSG_ERROR(no SUS compliant shell found - on Solaris, install SUNWxcu4)
fi
-
-AC_HEADER_STDC
-AC_HEADER_TIME
AC_TYPE_SIZE_T
AC_TYPE_PID_T
-AC_CHECK_HEADERS([unistd.h termios.h termio.h sgtty.h stdarg.h \
- sys/itimer.h fcntl.h sys/fcntl.h memory.h sys/wait.h \
- arpa/inet.h arpa/nameser.h netinet/in.h net/socket.h netdb.h \
- sys/select.h sys/socket.h sys/time.h langinfo.h])
-if test _$ac_cv_header_stdarg_h != _yes ; then
-AC_MSG_WARN([stdarg.h is not defined. Unsupported configuration, proceed at your own risk.])
-fi
-
AC_TYPE_UINT32_T
+AC_CHECK_HEADERS([sys/itimer.h sys/fcntl.h arpa/nameser.h langinfo.h])
AC_CHECK_HEADERS([resolv.h],,,[
#include <sys/types.h>
AC_CHECK_DECLS([h_errno],,,[
AC_INCLUDES_DEFAULT
- #ifdef HAVE_NETDB_H
#include <netdb.h>
- #endif
])
-AC_C_CONST dnl getopt needs this.
-AC_C_INLINE dnl uid_db.? need this.
-
AM_PROG_LEX
+case "$ac_cv_prog_LEX" in
+ *flex*) ;; # we like that
+ *) AC_MSG_WARN([Fetchmail requires flex to rebuild rcfile_l.*!]) ;;
+esac
AC_PROG_MAKE_SET
AC_PROG_YACC
+case "$ac_cv_prog_YACC" in
+ *bison*) ;; # we like that
+ *) AC_MSG_WARN([Fetchmail requires bison to rebuild rcfile_y.*!]) ;;
+esac
# Check for OS special cases
case $host_os in
AC_CHECK_LIB(socket,socket)
AC_CHECK_LIB(inet,socket))
-# The condition in this test copes with the presence of inet_addr in libc6.
-AC_CHECK_FUNC(inet_addr,
- AC_MSG_RESULT(using libc's inet_addr),
- AC_CHECK_LIB(nsl,inet_addr))
-
-dnl Port hack for Interactive UNIX System V/386 Release 3.2
-AC_CHECK_LIB(cposix, strchr,
- [DEFS="$DEFS -D_SYSV3"
- LIBS="$LIBS -lcposix"])
-
-dnl Port hack for Sparc/NetBSD-1.5
-dnl
-dnl NB: this has been disabled as it causes the unconditional
-dnl addition of libintl to the build, which is both undesired
-dnl and breaks on Solaris/Blastwave.org machines.
-dnl
-dnl AC_CHECK_LIB(intl, gettext,
-dnl [LIBS="$LIBS -lintl"])
-
-AC_REPLACE_FUNCS([strstr strcasecmp memmove stpcpy strlcpy strlcat])
+AC_REPLACE_FUNCS([stpcpy strlcpy strlcat])
AC_CHECK_FUNC(getopt_long, [],
[AC_LIBSOURCES([getopt.c, getopt1.c])
EXTRAOBJ="$EXTRAOBJ getopt.\$(OBJEXT) getopt1.\$(OBJEXT)"])
-AC_FUNC_VPRINTF
-
AC_SUBST(EXTRAOBJ)
-AC_CHECK_FUNCS(tcsetattr stty setsid geteuid seteuid dnl
- strerror syslog snprintf vprintf vsnprintf vsyslog dnl
- atexit inet_aton strftime setrlimit socketpair dnl
- sigaction strdup setlocale)
-
-AC_CHECK_DECLS([strerror,getenv])
-dnl INET6 is used by KAME/getnameinfo
-AC_CACHE_CHECK(for AF_INET6/PF_INET6,ac_cv_inet6,
-AC_COMPILE_IFELSE([
- AC_LANG_PROGRAM([[
- #include <sys/types.h>
- #include <sys/socket.h>
- ]],[[
- int foo = AF_INET6;
- int bar = PF_INET6;
- ]])],
- ac_cv_inet6=yes , ac_cv_inet6=no
-))
-if test "x$ac_cv_inet6" = xyes
-then
- AC_DEFINE(INET6,1,Define to 1 if your system defines AF_INET6 and PF_INET6.)
-fi
+AC_CHECK_FUNCS(vsyslog inet_aton)
# Under Red Hat 4.0 (and many other Linuxes) -lresolv is seriously flaky
# and breaks gethostbyname(2). It's better to use the bind stuff in the C
LIBS=$old_LIBS
done
-dnl Check for usable void pointer type
-AC_MSG_CHECKING(use of void pointer type)
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[char *p;
- void *xmalloc();
- p = (char *) xmalloc(1);
- ]])],[AC_DEFINE(HAVE_VOIDPOINTER,1,[Define if your C compiler allows void * as a function result]) AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)])
-
-dnl Check for ANSI volatile
-AC_C_VOLATILE
-
-dnl Check out the wait reality. We have to assume sys/wait.h is present.
-AC_CHECK_FUNCS(waitpid wait3)
-AC_MSG_CHECKING(for union wait);
-AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <sys/types.h>
-#include <sys/wait.h>]], [[union wait status; int pid; pid = wait (&status);
-#ifdef WEXITSTATUS
-/* Some POSIXoid systems have both the new-style macros and the old
- union wait type, and they do not work together. If union wait
- conflicts with WEXITSTATUS et al, we don't want to use it at all. */
-if (WEXITSTATUS (status) != 0) pid = -1;
-#endif
-#ifdef HAVE_WAITPID
-/* Make sure union wait works with waitpid. */
-pid = waitpid (-1, &status, 0);
-#endif
-]])],[AC_DEFINE(HAVE_UNION_WAIT,1,Define if 'union wait' is the type of the first arg to wait functions.) AC_MSG_RESULT(yes)],[AC_MSG_RESULT(no)])
-
AC_MSG_CHECKING(sys_siglist declaration in signal.h or unistd.h)
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <signal.h>
/* NetBSD declares sys_siglist in <unistd.h>. */
[with_opie=no])
test "$with_opie" = "yes" && AC_DEFINE(OPIE_ENABLE,1,Define if you want OPIE support compiled in)
-dnl Mostly stolen from gnulib's getaddrinfo.m4
-AC_SEARCH_LIBS(getaddrinfo, [nsl socket])
-AC_CACHE_CHECK([for getaddrinfo],[fm_cv_getaddrinfo],[
- AC_TRY_LINK([
-#include <sys/types.h>
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
- ], [getaddrinfo(0, 0, 0, 0);],
- [ fm_cv_getaddrinfo=yes],
- [ fm_cv_getaddrinfo=no ])
-])
-
-if test x"$fm_cv_getaddrinfo" = "xyes"; then
- AC_DEFINE(HAVE_GETADDRINFO, 1,
- [Define to 1 if you have the getaddrinfo function.])
-fi
-
-AC_CACHE_CHECK([for getnameinfo],[fm_cv_getnameinfo],[
- AC_TRY_LINK([
-#include <sys/types.h>
-#ifdef HAVE_SYS_SOCKET_H
-#include <sys/socket.h>
-#endif
-#ifdef HAVE_NETDB_H
-#include <netdb.h>
-#endif
-#ifndef NULL
-#define NULL 0
-#endif
- ], [getnameinfo(NULL,0, NULL,0, NULL, 0, 0);],
- [ fm_cv_getnameinfo=yes],
- [ fm_cv_getnameinfo=no ])
-])
-if test $fm_cv_getnameinfo = yes ; then
- AC_DEFINE(HAVE_GETNAMEINFO,1,[Define to 1 if your system has getnameinfo()])
-fi
-
-AM_CONDITIONAL(NEED_GETADDRINFO, test "$fm_cv_getaddrinfo" != yes)
-AM_CONDITIONAL(NEED_GETNAMEINFO, test "$fm_cv_getnameinfo" != yes)
-
AC_CHECK_FUNCS(inet_ntop)
dnl Check if getaddrinfo is async-signal-safe - most implementations aren't
-if test "$fm_cv_getaddrinfo" = yes ; then
- AC_MSG_CHECKING(if your getaddrinfo is async-signal-safe)
- gai_ts=no
- dnl we have getaddrinfo() - check if the OS is known to have a async-signal-safe implementation
- case $host_os in
- darwin9*) gai_ts=yes ;;
- linux*) gai_ts=yes ;;
- freebsd5.5|freebsd6*|freebsd7*) gai_ts=yes ;;
- solaris2.8|solaris2.9|solaris2.10) gai_ts=yes ;;
- esac
- AC_MSG_RESULT($gai_ts)
- if test $gai_ts = yes ; then
- AC_DEFINE(GETADDRINFO_ASYNCSAFE, 1, [define to 1 if you know your getaddrinfo function is async-signal-safe])
- fi
+
+AC_MSG_CHECKING(if your getaddrinfo is async-signal-safe)
+gai_ts=no
+dnl we have getaddrinfo() - check if the OS is known to have a async-signal-safe/thread-safe implementation
+case $host_os in
+ darwin*) gai_ts=yes ;;
+ linux*) gai_ts=yes ;;
+ freebsd*) gai_ts=yes ;;
+ solaris*) gai_ts=yes ;;
+esac
+AC_MSG_RESULT($gai_ts)
+if test $gai_ts = yes ; then
+ AC_DEFINE(GETADDRINFO_ASYNCSAFE, 1, [define to 1 if you know your getaddrinfo function is async-signal-safe])
fi
# This version of the Kerberos 4 and 5 options addresses the follwing issues:
])
fi])
-dnl ,------------------------------------------------------------------
-dnl Check if we need TRIO
-needtrio=0
-if test "$FORCE_TRIO" = "yes" ; then
- needtrio=1
- ac_cv_func_vsnprintf=no
- ac_cv_func_snprintf=no
-fi
-if test "x$ac_cv_func_snprintf" != "xyes" ; then
- AC_DEFINE(snprintf, trio_snprintf,
- [Define to trio_snprintf if your system lacks snprintf])
- needtrio=1
-fi
-if test "x$ac_cv_func_vsnprintf" != "xyes" ; then
- AC_DEFINE(vsnprintf, trio_vsnprintf,
- [Define to trio_vsnprintf if your system lacks vsnprintf])
- needtrio=1
-fi
-AM_CONDITIONAL(NEED_TRIO, test "$needtrio" = 1)
-
-dnl TRIO IEEE compiler option for Alpha
-dnl
-if test "$needtrio" = 1 ; then
- AC_MSG_CHECKING(for IEEE compilation options)
- AC_CACHE_VAL(ac_cv_ieee_option, [
- AC_TRY_COMPILE(,[
- #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__))) && (defined(VMS) || defined(__VMS)))
- # error "Option needed"
- #endif
- ],ac_cv_ieee_option="/IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE",
- AC_TRY_COMPILE(,[
- #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__))) && !(defined(VMS) || defined(__VMS)) && !defined(_CFE))
- # error "Option needed"
- #endif
- ],ac_cv_ieee_option="-ieee",
- AC_TRY_COMPILE(,[
- #if !(defined(__alpha) && (defined(__GNUC__) && (defined(__osf__) || defined(__linux__))))
- # error "Option needed"
- #endif
- ],ac_cv_ieee_option="-mieee",
- ac_cv_ieee_option="none"
- )
- )
- )
- ])
- AC_MSG_RESULT($ac_cv_ieee_option)
- if test $ac_cv_ieee_option != none; then
- CFLAGS="${CFLAGS} ${ac_cv_ieee_option}"
- fi
-fi
-dnl ----------------------------------------------------------------'
-
AC_CONFIG_FILES([Makefile po/Makefile.in])
AC_OUTPUT
*/
#include "config.h"
+#include "fetchmail.h"
+
#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#include "fetchmail.h"
#include "socket.h"
#include "i18n.h"
*/
#include "config.h"
+#include "fetchmail.h"
#include <stdio.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
-#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
-#endif
-#ifdef HAVE_FCNTL_H
#include <fcntl.h>
-#else /* !HAVE_FCNTL_H */
-#ifdef HAVE_SYS_FCNTL_H
-#include <sys/fcntl.h>
-#endif /* HAVE_SYS_FCNTL_H */
-#endif /* !HAVE_FCNTL_H */
#include <sys/stat.h> /* get umask(2) prototyped */
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
#if defined(QNX)
#include <unix.h>
#endif
-#if !defined(HAVE_SETSID) && defined(SIGTSTP)
-#if defined(HAVE_TERMIOS_H)
-# include <termios.h> /* for TIOCNOTTY under Linux */
-#endif
-
-#if !defined(TIOCNOTTY) && defined(HAVE_SGTTY_H)
-# include <sgtty.h> /* for TIOCNOTTY under NEXTSTEP */
-#endif
-#endif /* !defined(HAVE_SETSID) && defined(SIGTSTP) */
-
/* BSD portability hack */
#if !defined(SIGCHLD) && defined(SIGCLD)
#define SIGCHLD SIGCLD
#endif
-#include "fetchmail.h"
#include "tunable.h"
static RETSIGTYPE
sigchld_handler (int sig)
/* process SIGCHLD to obtain the exit code of the terminating process */
{
-#if defined(HAVE_WAITPID) /* the POSIX way */
int status;
while (waitpid(-1, &status, WNOHANG) > 0)
continue; /* swallow 'em up. */
-#elif defined(HAVE_WAIT3) /* the BSD way */
- pid_t pid;
-#if defined(HAVE_UNION_WAIT) && !defined(__FreeBSD__)
- union wait status;
-#else
- int status;
-#endif
-
- while ((pid = wait3(&status, WNOHANG, 0)) > 0)
- continue; /* swallow 'em up. */
-#else /* Zooks! Nothing to do but wait(), and hope we don't block... */
- int status;
-
- wait(&status);
-#endif
lastsig = SIGCHLD;
(void)sig;
}
*/
{
SIGHANDLERTYPE rethandler;
-#ifdef HAVE_SIGACTION
struct sigaction sa_new, sa_old;
memset (&sa_new, 0, sizeof sa_new);
sigemptyset (&sa_new.sa_mask);
sa_new.sa_handler = handler;
sa_new.sa_flags = 0;
-#ifdef SA_RESTART /* SunOS 4.1 portability hack */
/* system call should restart on all signals except SIGALRM */
if (sig != SIGALRM)
sa_new.sa_flags |= SA_RESTART;
-#endif
-#ifdef SA_NOCLDSTOP /* SunOS 4.1 portability hack */
if (sig == SIGCHLD)
sa_new.sa_flags |= SA_NOCLDSTOP;
-#endif
sigaction(sig, &sa_new, &sa_old);
rethandler = sa_old.sa_handler;
#if defined(SIGPWR)
if (sig == SIGCHLD)
sigaction(SIGPWR, &sa_new, NULL);
#endif
-#else /* HAVE_SIGACTION */
- rethandler = signal(sig, handler);
-#if defined(SIGPWR)
- if (sig == SIGCHLD)
- signal(SIGPWR, handler);
-#endif
- /* system call should restart on all signals except SIGALRM */
- siginterrupt(sig, sig == SIGALRM);
-#endif /* HAVE_SIGACTION */
return rethandler;
}
/* Make ourselves the leader of a new process group with no
controlling terminal */
-#if defined(HAVE_SETSID) /* POSIX */
/* POSIX makes this soooo easy to do */
if (setsid() < 0) {
report(stderr, "setsid (%s)\n", strerror(errno));
return(PS_IOERR);
}
-#elif defined(SIGTSTP) /* BSD */
- /* change process group */
-#ifndef __EMX__
- setpgrp(0, getpid());
-#endif
- /* lose controlling tty */
- if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
- ioctl(fd, TIOCNOTTY, (char *) 0);
- close(fd); /* not checking should be safe, there were no writes */
- }
-#else /* SVR3 and older */
- /* change process group */
-#ifndef __EMX__
- setpgrp();
-#endif
-
- /* lose controlling tty */
- set_signal_handler(SIGHUP, SIG_IGN);
- if ((childpid = fork()) < 0) {
- report(stderr, "fork (%s)\n", strerror(errno));
- return(PS_IOERR);
- }
- else if (childpid > 0) {
- exit(0); /* parent */
- }
-#endif
nottyDetach:
if (dup(logfd) < 0 /* stdout */
|| ((logfd == 0 || logfd >= 3) && dup(logfd) < 0)) { /* stderr */
- report(stderr, "dup (%s)\n", strerror(errno));
+ report(stderr, "dup(): %s\n", strerror(errno));
return(PS_IOERR);
}
-#ifdef HAVE_GETCWD
/* move to root directory, so we don't prevent filesystem unmounts */
- chdir("/");
-#endif
+ if (chdir("/")) {
+ report(stderr, "chdir(\"/\"): %s\n", strerror(errno));
+ return PS_IOERR;
+ }
/* set our umask to something reasonable (we hope) */
#if defined(DEF_UMASK)
*/
#include "config.h"
+#include "fetchmail.h"
+
#include <stdio.h>
#include <setjmp.h>
#include <errno.h>
#include <string.h>
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif /* HAVE_MEMORY_H */
-#if defined(STDC_HEADERS)
#include <stdlib.h>
#include <limits.h>
-#endif
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
#if defined(HAVE_SYS_ITIMER_H)
#include <sys/itimer.h>
#endif
#include <signal.h>
-#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
-#endif
-#ifdef HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#endif
#include <netdb.h>
#ifdef HAVE_PKG_hesiod
#ifdef __cplusplus
#include "i18n.h"
#include "socket.h"
-#include "fetchmail.h"
-#include "getaddrinfo.h"
#include "tunable.h"
#include "sdump.h"
void set_timeout(int timeleft)
/* reset the nonresponse-timeout */
{
-#if !defined(__EMX__) && !defined(__BEOS__)
struct itimerval ntimeout;
if (timeleft == 0)
ntimeout.it_value.tv_sec = timeleft;
ntimeout.it_value.tv_usec = 0;
setitimer(ITIMER_REAL, &ntimeout, (struct itimerval *)NULL);
-#endif
}
static RETSIGTYPE timeout_handler (int signal)
*/
#include "config.h"
+#include "fetchmail.h"
+
#include <stdio.h>
#include <ctype.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
#include <pwd.h>
#include <string.h>
-#ifdef HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#endif
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
-#include "fetchmail.h"
-#include "getaddrinfo.h"
#include "i18n.h"
-#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS) && defined(HAVE_STRFTIME)
+#if defined(ENABLE_NLS)
#include <locale.h>
#endif
-#ifndef HAVE_DECL_GETENV
-extern char *getenv(const char *); /* needed on sysV68 R3V7.1. */
-#endif
-
void envquery(int argc, char **argv)
/* set up basic stuff from the environment (including the rc file name) */
{
static char buf[50];
time(&now);
-#ifdef HAVE_STRFTIME
/*
* Conform to RFC822. We generate a 4-digit year here, avoiding
* Y2K hassles. Max length of this timestamp in an English locale
* weird multibyte i18n characters (such as kanji) from showing up
* in your Received headers.
*/
-#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS)
+#if defined(ENABLE_NLS)
setlocale (LC_TIME, "C");
#endif
strftime(buf, sizeof(buf)-1,
"%a, %d %b %Y %H:%M:%S XXXXX (%Z)", localtime(&now));
-#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS)
+#if defined(ENABLE_NLS)
setlocale (LC_TIME, "");
#endif
memcpy(strstr(buf, "XXXXX"), tzoffset(&now), 5);
-#else
- /*
- * This is really just a portability fallback, as the
- * date format ctime(3) emits is not RFC822
- * conformant.
- */
- strlcpy(buf, ctime(&now), sizeof(buf));
- buf[strlen(buf)-1] = '\0'; /* remove trailing \n */
-#endif /* HAVE_STRFTIME */
return(buf);
}
#include "config.h"
#ifdef ETRN_ENABLE
+#include "fetchmail.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
-#ifdef HAVE_NET_SOCKET_H /* BeOS needs this */
-#include <net/socket.h>
-#endif
#include <netdb.h>
#include <errno.h>
#include <unistd.h>
#include "i18n.h"
-#include "fetchmail.h"
#include "smtp.h"
#include "socket.h"
* For license terms, see the file COPYING in this directory.
*/
#include "config.h"
+#include "fetchmail.h"
#include <stdio.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
#include <fcntl.h>
#include <string.h>
#include <signal.h>
-#if defined(HAVE_SYSLOG)
#include <syslog.h>
-#endif
#include <pwd.h>
#ifdef __FreeBSD__
#include <grp.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef HAVE_SETRLIMIT
#include <sys/resource.h>
-#endif /* HAVE_SETRLIMIT */
#ifdef HAVE_SOCKS
#include <socks.h> /* SOCKSinit() */
#include <langinfo.h>
#endif
-#include "fetchmail.h"
#include "socket.h"
#include "tunable.h"
#include "smtp.h"
}
#endif
-#if defined(HAVE_SETLOCALE) && defined(ENABLE_NLS) && defined(HAVE_STRFTIME)
+#if defined(ENABLE_NLS)
#include <locale.h>
/** returns timestamp in current locale,
* and resets LC_TIME locale to POSIX. */
*/
fm_lock_dispose();
-#ifdef HAVE_GETCWD
/* save the current directory */
if (getcwd (currentwd, sizeof (currentwd)) == NULL) {
report(stderr, GT_("could not get current working directory\n"));
currentwd[0] = 0;
}
-#endif
{
int i;
}
}
-#if defined(HAVE_SYSLOG)
/* logging should be set up early in case we were restarted from exec */
if (run.use_syslog)
{
}
}
else
-#endif
report_init((run.poll_interval == 0 || nodetach) && !run.logfile); /* when changing this, change copy above, too */
#ifdef POP3_ENABLE
/* construct the lockfile */
fm_lock_setup(&run);
-#ifdef HAVE_SETRLIMIT
/*
* Before getting passwords, disable core dumps unless -v -d0 mode is on.
* Core dumps could otherwise contain passwords to be scavenged by a
corelimit.rlim_max = 0;
setrlimit(RLIMIT_CORE, &corelimit);
}
-#endif /* HAVE_SETRLIMIT */
#define NETRC_FILE ".netrc"
/* parse the ~/.netrc file (if present) for future password lookups. */
{
report(stdout, GT_("restarting fetchmail (%s changed)\n"), rcfile);
-#ifdef HAVE_GETCWD
/* restore the startup directory */
if (!currentwd[0] || chdir (currentwd) == -1)
report(stderr, GT_("attempt to re-exec may fail as directory has not been restored\n"));
-#endif
/*
* Matthias Andree: Isn't this prone to introduction of
if (ctl->password)
memset(ctl->password, '\0', strlen(ctl->password));
-#if !defined(HAVE_ATEXIT)
- fm_lock_release();
-#endif
-
if (activecount == 0)
exit(PS_NOMAIL);
else
printf(GT_("Logfile is %s\n"), runp->logfile);
if (strcmp(runp->idfile, IDFILE_NAME))
printf(GT_("Idfile is %s\n"), runp->idfile);
-#if defined(HAVE_SYSLOG)
if (runp->use_syslog)
printf(GT_("Progress messages will be logged via syslog\n"));
-#endif
if (runp->invisible)
printf(GT_("Fetchmail will masquerade and will not generate Received\n"));
if (runp->showdots)
* For license terms, see the file COPYING in this directory.
*/
+/* We need this for HAVE_STDARG_H, etc */
#include "config.h"
struct addrinfo;
#include <sys/types.h>
/* We need this for time_t */
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
+#include <sys/time.h>
+#include <time.h>
-#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
-#endif
-#ifdef HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#endif
#include <netdb.h>
#include <stdio.h>
-/* Import Trio if needed */
-#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF)
-# include "trio/trio.h"
-#endif
-
#include "uid_db.h"
+
#include "fm_strl.h"
/* constants designating the various supported protocols */
#endif
/* error.c: Error reporting */
-#if defined(HAVE_STDARG_H)
void report_init(int foreground);
/** Flush partial message, suppress program name tag for next report printout. */
void report_flush(FILE *fp);
void report_at_line (FILE *fp, int, const char *, unsigned int, const char *, ...)
__attribute__ ((format (printf, 5, 6)))
;
-#else
-void report ();
-void report_build ();
-void report_complete ();
-void report_at_line ();
-#endif
/* driver.c -- main driver loop */
void set_timeout(int);
int num,
flag *suppress_readbody);
int readbody(int sock, struct query *ctl, flag forward, int len);
-#if defined(HAVE_STDARG_H)
void gen_send(int sock, const char *, ... )
__attribute__ ((format (printf, 2, 3)))
;
int gen_transact(int sock, const char *, ... )
__attribute__ ((format (printf, 2, 3)))
;
-#else
-void gen_send();
-int gen_recv();
-void gen_recv_split_init();
-int gen_recv_split();
-int gen_transact();
-#endif
extern struct msgblk msgblk;
/* use these to track what was happening when the nonresponse timer fired */
void release_sink(struct query *);
int close_sink(struct query *, struct msgblk *, flag);
int open_warning_by_mail(struct query *);
-#if defined(HAVE_STDARG_H)
void stuff_warning(const char *,
struct query *,
const char *pfx,
const char *fmt, ...)
__attribute__ ((format (printf, 4, 5)))
;
-#else
-void stuff_warning();
-#endif
void close_warning_by_mail(struct query *, struct msgblk *);
/* rfc822.c: RFC822 header parsing */
void yyerror(const char *);
int yylex(void);
-#ifdef __EMX__
-void itimerthread(void*);
-/* Have to include these first to avoid errors from redefining getcwd
- and chdir. They're re-include protected in EMX, so it's okay, I
- guess. */
-#include <stdlib.h>
-#include <unistd.h>
-/* Redefine getcwd and chdir to get drive-letter support so we can
- find all of our lock files and stuff. */
-#define getcwd _getcwd2
-#define chdir _chdir2
-#endif /* _EMX_ */
-
-#ifdef HAVE_STRERROR
-# if !defined(strerror) && !defined(HAVE_DECL_STRERROR) /* On some systems, strerror is a macro */
-char *strerror (int);
-# endif
-#endif /* HAVE_STRERROR */
-
#define STRING_DISABLED (char *)-1
#define STRING_DUMMY ""
char *stpcpy(char *, const char*);
#endif
-#ifdef __CYGWIN__
-#define ROOT_UID 18
-#else /* !__CYGWIN__ */
#define ROOT_UID 0
-#endif /* __CYGWIN__ */
extern int mailserver_socket_temp;
extern const char *program_name;
* positive integer to a port number. Returns -1 for error. */
int servport(const char *service);
-#ifndef HAVE_GETNAMEINFO
-# define NI_NUMERICHOST 1
-# define NI_NUMERICSERV 2
-# define NI_NOFQDN 4
-# define NI_NAMEREQD 8
-# define NI_DGRAM 16
-#endif
-
int fm_getaddrinfo(const char *node, const char *serv, const struct addrinfo *hints, struct addrinfo **res);
void fm_freeaddrinfo(struct addrinfo *ai);
#define MD5_H
#include "config.h"
+#include "fetchmail.h"
-#include <sys/types.h>
-#include "fetchmail.h"
+#include <sys/types.h>
#if SIZEOF_INT == 4
typedef unsigned int uint32;
{
/* Bottom segment is the short one. */
int len = middle - bottom;
- register int i;
+ int i;
/* Swap it with the top part of the top segment. */
for (i = 0; i < len; i++)
{
/* Top segment is the short one. */
int len = top - middle;
- register int i;
+ int i;
/* Swap it with the bottom part of the bottom segment. */
for (i = 0; i < len; i++)
***********************************************************************/
#include "config.h"
+#include "fetchmail.h"
#include <stdio.h>
#include <signal.h>
#include <fcntl.h>
#include <stdlib.h>
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
-#include "fetchmail.h"
#include "i18n.h"
#define INPUT_BUF_SIZE PASSWORDLEN
-#if defined(HAVE_TERMIOS_H) && defined(HAVE_TCSETATTR)
-# include <termios.h>
-#else
-#if defined(HAVE_TERMIO_H)
-# include <sys/ioctl.h>
-# include <termio.h>
-#else
-#if defined(HAVE_SGTTY_H)
-# include <sgtty.h>
-#endif
-#endif
-#endif
+#include <termios.h>
static int ttyfd;
-#if defined(HAVE_TCSETATTR)
- static struct termios termb;
- static tcflag_t flags;
-#else
-#if defined(HAVE_TERMIO_H)
- static struct termio termb;
- static unsigned short flags;
-#else
-#if defined(HAVE_STTY)
- static struct sgttyb ttyb;
- static int flags;
-#endif
-#endif
-#endif
+static struct termios termb;
+static tcflag_t flags;
static void save_tty_state(void);
static void disable_tty_echo(void);
char *fm_getpassword(char *prompt)
{
-#if !(defined(HAVE_TCSETATTR) || defined(HAVE_TERMIO_H) || defined(HAVE_STTY))
-#if defined(HAVE_GETPASS)
- char *getpass();
- return getpass(prompt);
-#else
- fputs(GT_("ERROR: no support for getpassword() routine\n"),stderr);
- exit(1);
-#endif
-#else
char *p;
int c;
FILE *fi;
fclose(fi); /* not checking should be safe, file mode was "r" */
return(pbuf);
-#endif /* !(defined(HAVE_TCSETATTR) || ... */
}
static void save_tty_state (void)
{
-#if defined(HAVE_TCSETATTR)
tcgetattr(ttyfd, &termb);
flags = termb.c_lflag;
-#else
-#if defined(HAVE_TERMIO_H)
- ioctl(ttyfd, TCGETA, (char *) &termb);
- flags = termb.c_lflag;
-#else /* we HAVE_STTY */
- gtty(ttyfd, &ttyb);
- flags = ttyb.sg_flags;
-#endif
-#endif
}
static void disable_tty_echo(void)
{
/* turn off echo on the tty */
-#if defined(HAVE_TCSETATTR)
termb.c_lflag &= ~ECHO;
tcsetattr(ttyfd, TCSAFLUSH, &termb);
-#else
-#if defined(HAVE_TERMIO_H)
- termb.c_lflag &= ~ECHO;
- ioctl(ttyfd, TCSETA, (char *) &termb);
-#else /* we HAVE_STTY */
- ttyb.sg_flags &= ~ECHO;
- stty(ttyfd, &ttyb);
-#endif
-#endif
}
static void restore_tty_state(void)
{
/* restore previous tty echo state */
-#if defined(HAVE_TCSETATTR)
termb.c_lflag = flags;
tcsetattr(ttyfd, TCSAFLUSH, &termb);
-#else
-#if defined(HAVE_TERMIO_H)
- termb.c_lflag = flags;
- ioctl(ttyfd, TCSETA, (char *) &termb);
-#else /* we HAVE_STTY */
- ttyb.sg_flags = flags;
- stty(ttyfd, &ttyb);
-#endif
-#endif
}
static RETSIGTYPE sigint_handler(int signum)
*/
#include "config.h"
+#include "fetchmail.h"
+
#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#include "fetchmail.h"
#include "socket.h"
#include "i18n.h"
MIT license. Compile with -DMAIN to build the demonstrator.
******************************************************************************/
+#include "fetchmail.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
-#include <fetchmail.h> /* for ROOT_UID */
#ifndef TRUE
#define TRUE 1
}
#endif /* SLEEP_WITH_ALARM */
-#ifdef __EMX__
-/* Various EMX-specific definitions */
-static int itimerflag;
-
-void itimerthread(void* dummy)
-{
- if (outlevel >= O_VERBOSE)
- report(stderr,
- GT_("fetchmail: thread sleeping for %d sec.\n"), poll_interval);
- while(1)
- {
- _sleep2(poll_interval*1000);
- kill((getpid()), SIGALRM);
- }
-}
-#endif
-
int interruptible_idle(int seconds)
/* time for a pause in the action; return TRUE if awakened by signal */
{
int awoken = FALSE;
-#ifndef __EMX__
#ifdef SLEEP_WITH_ALARM /* not normally on */
/*
* We can't use sleep(3) here because we need an alarm(3)
} while (lastsig == SIGCHLD);
}
#endif
-#else /* EMX */
- alarm_latch = FALSE;
- set_signal_handler(SIGALRM, gotsigalrm);
- _beginthread(itimerthread, NULL, 32768, NULL);
- /* see similar code above */
- if (!alarm_latch)
- pause();
- set_signal_handler(SIGALRM, SIG_IGN);
-#endif /* ! EMX */
+
if (lastsig == SIGUSR1 || ((seconds && getuid() == ROOT_UID)
&& lastsig == SIGHUP))
awoken = TRUE;
*/
#include "config.h"
+#include "fetchmail.h"
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <limits.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
#include <string.h>
-#endif
-#if defined(HAVE_UNISTD_H)
+#include <strings.h>
#include <unistd.h>
-#endif
-#include "fetchmail.h"
/** Save string \a str to idlist \a idl with status \a status.
* \return Pointer to the last element of the list to help the quick,
*/
#include "config.h"
+#include "fetchmail.h"
+
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
-#endif
-#include "fetchmail.h"
#include "socket.h"
#include "i18n.h"
#include <stdio.h>
#include <string.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <net/if.h>
#if defined(__FreeBSD__)
-#if defined __FreeBSD_USE_KVM
-#if __FreeBSD_version >= 300001
-#include <net/if_var.h>
-#endif
-#include <kvm.h>
-#include <nlist.h>
-#include <sys/fcntl.h>
-#else
-#include <sys/sysctl.h>
-#include <net/route.h>
-#include <net/if_dl.h>
-#endif
+# if defined __FreeBSD_USE_KVM
+# if __FreeBSD_version >= 300001
+# include <net/if_var.h>
+# endif
+# include <kvm.h>
+# include <nlist.h>
+# include <sys/fcntl.h>
+# else
+# include <sys/sysctl.h>
+# include <net/route.h>
+# include <net/if_dl.h>
+# endif
#endif
#include "socket.h"
#include "i18n.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
#include "fetchmail.h"
#include "socket.h"
#include "kerberos.h"
+++ /dev/null
-/*
- * This file is part of libESMTP, a library for submission of RFC 2822
- * formatted electronic mail messages using the SMTP protocol described
- * in RFC 2821.
- *
- * Copyright (C) 2001,2002 Brian Stafford <brian@stafford.uklinux.net>
- *
- * This 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.
- *
- * This 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 this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* An emulation of the RFC 2553 / Posix getaddrinfo resolver interface.
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifndef HAVE_GETADDRINFO
-
-/* Need to turn off Posix features in glibc to build this */
-#undef _POSIX_C_SOURCE
-#undef _XOPEN_SOURCE
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-
-#include <netdb.h>
-
-#include "gethostbyname.h"
-#include "getaddrinfo.h"
-
-static struct addrinfo *
-dup_addrinfo (struct addrinfo *info, void *addr, size_t addrlen)
-{
- struct addrinfo *ret;
-
- ret = malloc (sizeof (struct addrinfo));
- if (ret == NULL)
- return NULL;
- memcpy (ret, info, sizeof (struct addrinfo));
- ret->ai_addr = malloc (addrlen);
- if (ret->ai_addr == NULL)
- {
- free (ret);
- return NULL;
- }
- memcpy (ret->ai_addr, addr, addrlen);
- ret->ai_addrlen = addrlen;
- return ret;
-}
-
-int
-getaddrinfo (const char *nodename, const char *servname,
- const struct addrinfo *hints, struct addrinfo **res)
-{
- struct hostent *hp;
- struct servent *servent;
- const char *socktype;
- int port;
- struct addrinfo hint, result;
- struct addrinfo *ai, *sai, *eai;
- struct ghbnctx ghbnctx;
- char **addrs;
- int code;
-
- memset (&result, 0, sizeof result);
-
- /* default for hints */
- if (hints == NULL)
- {
- memset (&hint, 0, sizeof hint);
- hint.ai_family = PF_UNSPEC;
- hints = &hint;
- }
-
- if (servname == NULL && nodename == NULL)
- return EAI_NONAME;
-
- if (servname == NULL)
- port = 0;
- else {
- /* check for tcp or udp sockets only */
- if (hints->ai_socktype == SOCK_STREAM)
- socktype = "tcp";
- else if (hints->ai_socktype == SOCK_DGRAM)
- socktype = "udp";
- else
- return EAI_SERVICE;
- result.ai_socktype = hints->ai_socktype;
-
- /* Note: maintain port in host byte order to make debugging easier */
- if (isdigit (*servname))
- port = strtol (servname, NULL, 10);
- else if ((servent = getservbyname (servname, socktype)) != NULL)
- port = ntohs (servent->s_port);
- else
- return EAI_NONAME;
- }
-
- /* if nodename == NULL refer to the local host for a client or any
- for a server */
- if (nodename == NULL)
- {
- struct sockaddr_in sin;
-
- /* check protocol family is PF_UNSPEC or PF_INET - could try harder
- for IPv6 but that's more code than I'm prepared to write */
- if (hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET)
- result.ai_family = AF_INET;
- else
- return EAI_FAMILY;
-
- sin.sin_family = result.ai_family;
- sin.sin_port = htons (port);
- if (hints->ai_flags & AI_PASSIVE)
- sin.sin_addr.s_addr = htonl (INADDR_ANY);
- else
- sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
- /* Duplicate result and addr and return */
- *res = dup_addrinfo (&result, &sin, sizeof sin);
- return (*res == NULL) ? EAI_MEMORY : 0;
- }
-
- /* If AI_NUMERIC is specified, use inet_addr to translate numbers and
- dots notation. */
- if (hints->ai_flags & AI_NUMERICHOST)
- {
- struct sockaddr_in sin;
-
- /* check protocol family is PF_UNSPEC or PF_INET */
- if (hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET)
- result.ai_family = AF_INET;
- else
- return EAI_FAMILY;
-
- sin.sin_family = result.ai_family;
- sin.sin_port = htons (port);
- sin.sin_addr.s_addr = inet_addr (nodename);
- /* Duplicate result and addr and return */
- *res = dup_addrinfo (&result, &sin, sizeof sin);
- return (*res == NULL) ? EAI_MEMORY : 0;
- }
-
- errno = 0;
- hp = gethostbyname_ctx (nodename, &ghbnctx);
- if (hp == NULL)
- {
- if (errno != 0)
- {
- free_ghbnctx (&ghbnctx);
- return EAI_SYSTEM;
- }
- code = h_error_ctx (&ghbnctx);
- switch (code)
- {
- case HOST_NOT_FOUND: code = EAI_NODATA; break;
- case NO_DATA: code = EAI_NODATA; break;
-#if defined(NO_ADDRESS) && NO_ADDRESS != NO_DATA
- case NO_ADDRESS: code = EAI_NODATA; break;
-#endif
- case NO_RECOVERY: code = EAI_FAIL; break;
- case TRY_AGAIN: code = EAI_AGAIN; break;
- default: code = EAI_FAIL; break;
- }
- free_ghbnctx (&ghbnctx);
- return code;
- }
-
- /* Check that the address family is acceptable.
- */
- switch (hp->h_addrtype)
- {
- case AF_INET:
- if (!(hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET))
- goto eai_family;
- break;
-#ifdef USE_IPV6
- case AF_INET6:
- if (!(hints->ai_family == PF_UNSPEC || hints->ai_family == PF_INET6))
- goto eai_family;
- break;
-#endif
- default:
- eai_family:
- free_ghbnctx (&ghbnctx);
- return EAI_FAMILY;
- }
-
- /* For each element pointed to by hp, create an element in the
- result linked list. */
- sai = eai = NULL;
- for (addrs = hp->h_addr_list; *addrs != NULL; addrs++)
- {
- struct sockaddr sa;
- size_t addrlen;
-
- if (hp->h_length < 1)
- continue;
- sa.sa_family = hp->h_addrtype;
- switch (hp->h_addrtype)
- {
- case AF_INET:
- ((struct sockaddr_in *) &sa)->sin_port = htons (port);
- memcpy (&((struct sockaddr_in *) &sa)->sin_addr,
- *addrs, hp->h_length);
- addrlen = sizeof (struct sockaddr_in);
- break;
-#ifdef USE_IPV6
- case AF_INET6:
-# if SIN6_LEN
- ((struct sockaddr_in6 *) &sa)->sin6_len = hp->h_length;
-# endif
- ((struct sockaddr_in6 *) &sa)->sin6_port = htons (port);
- memcpy (&((struct sockaddr_in6 *) &sa)->sin6_addr,
- *addrs, hp->h_length);
- addrlen = sizeof (struct sockaddr_in6);
- break;
-#endif
- default:
- continue;
- }
-
- result.ai_family = hp->h_addrtype;
- ai = dup_addrinfo (&result, &sa, addrlen);
- if (ai == NULL)
- {
- free_ghbnctx (&ghbnctx);
- freeaddrinfo (sai);
- return EAI_MEMORY;
- }
- if (sai == NULL)
- sai = ai;
- else
- eai->ai_next = ai;
- eai = ai;
- }
-
- if (sai == NULL)
- {
- free_ghbnctx (&ghbnctx);
- return EAI_NODATA;
- }
-
- if (hints->ai_flags & AI_CANONNAME)
- {
- sai->ai_canonname = malloc (strlen (hp->h_name) + 1);
- if (sai->ai_canonname == NULL)
- {
- free_ghbnctx (&ghbnctx);
- freeaddrinfo (sai);
- return EAI_MEMORY;
- }
- strcpy (sai->ai_canonname, hp->h_name);
- }
-
- free_ghbnctx (&ghbnctx);
- *res = sai;
- return 0;
-}
-
-void
-freeaddrinfo (struct addrinfo *ai)
-{
- struct addrinfo *next;
-
- while (ai != NULL)
- {
- next = ai->ai_next;
- if (ai->ai_canonname != NULL)
- free (ai->ai_canonname);
- if (ai->ai_addr != NULL)
- free (ai->ai_addr);
- free (ai);
- ai = next;
- }
-}
-
-const char *
-gai_strerror (int ecode)
-{
- static const char *eai_descr[] =
- {
- "no error",
- "address family for nodename not supported", /* EAI_ADDRFAMILY */
- "temporary failure in name resolution", /* EAI_AGAIN */
- "invalid value for ai_flags", /* EAI_BADFLAGS */
- "non-recoverable failure in name resolution", /* EAI_FAIL */
- "ai_family not supported", /* EAI_FAMILY */
- "memory allocation failure", /* EAI_MEMORY */
- "no address associated with nodename", /* EAI_NODATA */
- "nodename nor servname provided, or not known", /* EAI_NONAME */
- "servname not supported for ai_socktype", /* EAI_SERVICE */
- "ai_socktype not supported", /* EAI_SOCKTYPE */
- "system error returned in errno", /* EAI_SYSTEM */
- "argument buffer overflow", /* EAI_OVERFLOW */
- };
-
- if (ecode < 0 || ecode > (int) (sizeof eai_descr/ sizeof eai_descr[0]))
- return "unknown error";
- return eai_descr[ecode];
-}
-
-#endif
+++ /dev/null
-#ifndef _getaddrinfo_h
-#define _getaddrinfo_h
-/*
- * This file is part of libESMTP, a library for submission of RFC 2822
- * formatted electronic mail messages using the SMTP protocol described
- * in RFC 2821.
- *
- * Copyright (C) 2001,2002 Brian Stafford <brian@stafford.uklinux.net>
- *
- * This 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.
- *
- * This 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 this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/* Structure and prototypes aken from RFC 2553 */
-
-#include <config.h>
-#ifndef HAVE_GETADDRINFO
-
-struct addrinfo
- {
- int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */
- int ai_family; /* PF_xxx */
- int ai_socktype; /* SOCK_xxx */
- int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
- size_t ai_addrlen; /* length of ai_addr */
- char *ai_canonname; /* canonical name for nodename */
- struct sockaddr *ai_addr; /* binary address */
- struct addrinfo *ai_next; /* next structure in linked list */
- };
-
-/* Supposed to be defined in <netdb.h> */
-#define AI_PASSIVE 1 /* Socket address is intended for `bind'. */
-#define AI_CANONNAME 2 /* Request for canonical name. */
-#define AI_NUMERICHOST 4 /* Don't use name resolution. */
-
-/* Supposed to be defined in <netdb.h> */
-#define EAI_ADDRFAMILY 1 /* address family for nodename not supported */
-#define EAI_AGAIN 2 /* temporary failure in name resolution */
-#define EAI_BADFLAGS 3 /* invalid value for ai_flags */
-#define EAI_FAIL 4 /* non-recoverable failure in name resolution */
-#define EAI_FAMILY 5 /* ai_family not supported */
-#define EAI_MEMORY 6 /* memory allocation failure */
-#define EAI_NODATA 7 /* no address associated with nodename */
-#define EAI_NONAME 8 /* nodename nor servname provided, or not known */
-#define EAI_SERVICE 9 /* servname not supported for ai_socktype */
-#define EAI_SOCKTYPE 10 /* ai_socktype not supported */
-#define EAI_SYSTEM 11 /* system error returned in errno */
-#define EAI_OVERFLOW 12 /* argument buffer too small */
-
-/* RFC 2553 / Posix resolver */
-int getaddrinfo (const char *nodename, const char *servname,
- const struct addrinfo *hints, struct addrinfo **res);
-
-/* Free addrinfo structure and associated storage */
-void freeaddrinfo (struct addrinfo *ai);
-
-/* Convert error return from getaddrinfo() to string */
-const char *gai_strerror (int code);
-
-#endif
-#endif
* For license terms, see the file COPYING in this directory.
*/
#include "config.h"
+#include "fetchmail.h"
#include <stdio.h>
-#ifdef HAVE_STRING_H
#include <string.h> /* strcat() */
-#endif
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
-#include "fetchmail.h"
#include "i18n.h"
#include "lock.h"
void fm_lock_dispose(void)
/* arrange for a lock to be removed on process exit */
{
-#ifdef HAVE_ATEXIT
atexit(unlockit);
-#endif
}
int fm_lock_state(void)
#include "config.h"
#include "fm_md5.h"
-#ifdef HAVE_STRING_H
+
#include <string.h> /* memmove */
-#endif
#include <inttypes.h>
***********************************************************************/
-#include <stdio.h>
-#include <string.h>
+#include "fm_md5.h"
-#if defined(STDC_HEADERS)
+#include <stdio.h>
#include <string.h>
-#endif
-
-#include "fm_md5.h"
char *
MD5Digest (unsigned const char *s)
+++ /dev/null
-/*
- * Scratch implementation of memmove() in case your C library lacks one.
- *
- * For license terms, see the file COPYING in this directory.
- */
-char *memmove(char *dst, register char *src, register int n)
-{
- register char *svdst;
-
- if ((dst > src) && (dst < src + n))
- {
- src += n;
- for (svdst = dst + n; n-- > 0; )
- *--svdst = *--src;
- }
- else
- {
- for (svdst = dst; n-- > 0; )
- *svdst++ = *src++;
- }
- return dst;
-}
#include "config.h"
-#ifdef HAVE_NETDB_H
#include <netdb.h>
-#endif
struct mxentry
{
#include <stdio.h>
#include <string.h>
#ifdef HAVE_RES_SEARCH
-#ifdef HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#endif
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
-#ifdef __BEOS__
-#include "beos/beos_nameser.h"
-#endif
-
#ifdef HAVE_ARPA_NAMESER_H
#include <arpa/nameser.h>
#endif
*/
#include "config.h"
+#include "fetchmail.h"
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
-#include "fetchmail.h"
#include "netrc.h"
#include "i18n.h"
*/
#include "config.h"
+
#ifdef ODMR_ENABLE
+#include "fetchmail.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
-#ifdef HAVE_STRING_H /* strcat() */
-#include <string.h>
-#endif
-#ifdef HAVE_NET_SOCKET_H /* BeOS needs this */
-#include <net/socket.h>
-#endif
+#include <string.h>
#include <sys/types.h>
-#ifdef HAVE_NET_SELECT_H /* AIX needs this */
-#include <net/select.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H /* AIX 4.1, at least, needs this */
#include <sys/select.h>
-#endif
#include <netdb.h>
#include <errno.h>
#include <unistd.h>
#include "i18n.h"
-#include "fetchmail.h"
#include "sdump.h"
#include "smtp.h"
#include "socket.h"
*/
#include "config.h"
+#include "fetchmail.h"
+
#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#include "fetchmail.h"
#include "socket.h"
#include "i18n.h"
*/
#include "config.h"
+#include "fetchmail.h"
#include <stdio.h>
#include <pwd.h>
#include <string.h>
+#include <strings.h>
#include <errno.h>
-#if defined(STDC_HEADERS)
-#include <stdlib.h>
-#include <limits.h>
-#else
-#include <ctype.h>
-#endif
+#include <stdlib.h>
+#include <limits.h>
#include "getopt.h"
-#include "fetchmail.h"
#include "i18n.h"
enum {
static int xatoi(char *s, int *errflagptr)
/* do safe conversion from string to number */
{
-#if defined (STDC_HEADERS) && defined (LONG_MAX) && defined (INT_MAX)
+#if defined (LONG_MAX) && defined (INT_MAX)
/* parse and convert numbers, but also check for invalid characters in
* numbers
*/
#else
int i;
char *dp;
-# if defined (STDC_HEADERS)
size_t len;
-# else
- int len;
-# endif
/* We do only base 10 conversions here (atoi)! */
#include "config.h"
#ifdef POP2_ENABLE
+#include "fetchmail.h"
#include <stdio.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#ifdef HAVE_STRING_H
#include <string.h>
-#endif
-#include "fetchmail.h"
#include "socket.h"
#include "i18n.h"
#include "config.h"
#ifdef POP3_ENABLE
+#include "fetchmail.h"
#include <stdio.h>
#include <string.h>
+#include <strings.h>
#include <ctype.h>
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
#include <errno.h>
-#include "fetchmail.h"
#include "socket.h"
#include "i18n.h"
#include "uid_db.h"
*/
#include "config.h"
+#include "fetchmail.h"
#include <stdio.h>
#include <sys/types.h>
#include <sys/file.h>
-#if defined(HAVE_SYS_WAIT_H)
#include <sys/wait.h>
-#endif
#include <sys/stat.h>
#include <errno.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
#include <string.h>
-#if defined(__CYGWIN__)
-#include <sys/cygwin.h>
-#endif /* __CYGWIN__ */
-
-#include "fetchmail.h"
#include "i18n.h"
/* parser reads these */
int prc_filecheck(const char *pathname,
const flag securecheck /** shortcuts permission, filetype and uid tests if false */)
{
-#ifndef __EMX__
struct stat statbuf;
errno = 0;
return(PS_IOERR);
}
-#ifndef __BEOS__
-#ifdef __CYGWIN__
- if (cygwin_internal(CW_CHECK_NTSEC, pathname))
-#endif /* __CYGWIN__ */
if (statbuf.st_mode & (S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_IXOTH))
{
fprintf(stderr, GT_("File %s must have no more than -rwx------ (0700) permissions.\n"),
pathname);
return(PS_IOERR);
}
-#endif /* __BEOS__ */
-#ifdef HAVE_GETEUID
if (statbuf.st_uid != geteuid())
-#else
- if (statbuf.st_uid != getuid())
-#endif /* HAVE_GETEUID */
{
fprintf(stderr, GT_("File %s must be owned by you.\n"), pathname);
return(PS_IOERR);
}
-#endif
return(PS_SUCCESS);
}
prc_errflag = 0;
querylist = hosttail = (struct query *)NULL;
+ (void)yytoknum; /* work around compiler warning */
+
errno = 0;
/* Check that the file is secure */
* vprintf(3) is unreliable.
*/
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
+/* make glibc expose vsyslog(3): */
+#define _DEFAULT_SOURCE
+#define _BSD_SOURCE
+
+#include "config.h"
+#include "fetchmail.h"
#include <stdio.h>
#include <errno.h>
#include <string.h>
-#if defined(HAVE_SYSLOG)
#include <syslog.h>
-#endif
#include "i18n.h"
-#include "fetchmail.h"
-#if defined(HAVE_VPRINTF) || defined(HAVE_DOPRNT) || defined(_LIBC) || defined(HAVE_STDARG_H)
-# if HAVE_STDARG_H
-# include <stdarg.h>
-# define VA_START(args, lastarg) va_start(args, lastarg)
-# else
-# include <varargs.h>
-# define VA_START(args, lastarg) va_start(args)
-# endif
-#else
-# define va_alist a1, a2, a3, a4, a5, a6, a7, a8
-# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
-#endif
+#include <stdarg.h>
#define MALLOC(n) xmalloc(n)
#define REALLOC(n,s) xrealloc(n,s)
# define program_name program_invocation_name
# include <errno.h>
-#else
-
-# if !HAVE_STRERROR && !defined(strerror)
-char *strerror (int errnum)
-{
- extern char *sys_errlist[];
- extern int sys_nerr;
-
- if (errnum > 0 && errnum <= sys_nerr)
- return sys_errlist[errnum];
- return GT_("Unknown system error");
-}
-# endif /* HAVE_STRERROR */
#endif /* _LIBC */
/* Print the program name and error message MESSAGE, which is a printf-style
format string with optional args. */
-/* VARARGS */
-void
-#ifdef HAVE_STDARG_H
-report (FILE *errfp, const char *message, ...)
-#else
-report (FILE *errfp, message, va_alist)
- const char *message;
- va_dcl
-#endif
+void report (FILE *errfp, const char *message, ...)
{
-#ifdef VA_START
va_list args;
-#endif
/* If a partially built message exists, print it now so it's not lost. */
if (partial_message_size_used != 0)
report (errfp, GT_("%s (log message incomplete)\n"), partial_message);
}
-#if defined(HAVE_SYSLOG)
if (use_syslog)
{
int priority;
-#ifdef VA_START
- VA_START (args, message);
-#endif
+ va_start(args, message);
priority = (errfp == stderr) ? LOG_ERR : LOG_INFO;
#ifdef HAVE_VSYSLOG
vsyslog (priority, message, args);
#else
{
- char *a1 = va_arg(args, char *);
- char *a2 = va_arg(args, char *);
- char *a3 = va_arg(args, char *);
- char *a4 = va_arg(args, char *);
- char *a5 = va_arg(args, char *);
- char *a6 = va_arg(args, char *);
- char *a7 = va_arg(args, char *);
- char *a8 = va_arg(args, char *);
- syslog (priority, message, a1, a2, a3, a4, a5, a6, a7, a8);
+ char tmpbuf[2048];
+ vsnprintf(tmpbuf, sizeof tmpbuf, message, args);
+ syslog(priority, "%s", tmpbuf);
}
#endif
-#ifdef VA_START
va_end(args);
-#endif
}
else /* i. e. not using syslog */
-#endif
{
if ( *message == '\n' )
{
fprintf (errfp, "%s: ", program_name);
partial_suppress_tag = 0;
-#ifdef VA_START
- VA_START (args, message);
-# if defined(HAVE_VPRINTF) || defined(_LIBC)
+ va_start (args, message);
vfprintf (errfp, message, args);
-# else
- _doprnt (message, args, errfp);
-# endif
va_end (args);
-#else
- fprintf (errfp, message, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif
fflush (errfp);
}
}
use_syslog = FALSE;
break;
-#ifdef HAVE_SYSLOG
case -1: /* syslogd */
unbuffered = FALSE;
use_syslog = TRUE;
break;
-#endif /* HAVE_SYSLOG */
}
}
message exists, then, in an attempt to keep the messages in their proper
sequence, the partial message will be printed as-is (with a trailing
newline) before report() prints its message. */
-/* VARARGS */
static void rep_ensuresize(void) {
/* Make an initial guess for the size of any single message fragment. */
}
}
-#ifdef HAVE_STDARG_H
static void report_vbuild(const char *message, va_list args)
{
int n;
partial_message = (char *)REALLOC (partial_message, partial_message_size);
}
}
-#endif
-void
-#ifdef HAVE_STDARG_H
-report_build (FILE *errfp, const char *message, ...)
-#else
-report_build (FILE *errfp, message, va_alist)
- const char *message;
- va_dcl
-#endif
+void report_build (FILE *errfp, const char *message, ...)
{
-#ifdef VA_START
va_list args;
-#else
- int n;
-#endif
rep_ensuresize();
-#if defined(VA_START)
- VA_START(args, message);
+ va_start(args, message);
report_vbuild(message, args);
va_end(args);
-#else
- for ( ; ; )
- {
- n = snprintf (partial_message + partial_message_size_used,
- partial_message_size - partial_message_size_used,
- message, a1, a2, a3, a4, a5, a6, a7, a8);
-
- /* output error, f. i. EILSEQ */
- if (n < 0) break;
-
- if (n >= 0
- && (unsigned)n < partial_message_size - partial_message_size_used)
- {
- partial_message_size_used += n;
- break;
- }
-
- partial_message_size += 2048;
- partial_message = REALLOC (partial_message, partial_message_size);
- }
-#endif
if (unbuffered && partial_message_size_used != 0)
{
format string with optional args, to the existing report message (which may
be empty.) The completed report message is then printed (and reset to
empty.) */
-/* VARARGS */
-void
-#ifdef HAVE_STDARG_H
-report_complete (FILE *errfp, const char *message, ...)
-#else
-report_complete (FILE *errfp, message, va_alist)
- const char *message;
- va_dcl
-#endif
+void report_complete (FILE *errfp, const char *message, ...)
{
-#ifdef VA_START
va_list args;
-#endif
rep_ensuresize();
-#if defined(VA_START)
- VA_START(args, message);
+ va_start(args, message);
report_vbuild(message, args);
va_end(args);
-#else
- report_build(errfp, message, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif
/* Finally... print it. */
partial_message_size_used = 0;
static int error_one_per_line;
/* If errnum is nonzero, print its corresponding system error message. */
-void
-#ifdef HAVE_STDARG_H
-report_at_line (FILE *errfp, int errnum, const char *file_name,
+void report_at_line (FILE *errfp, int errnum, const char *file_name,
unsigned int line_number, const char *message, ...)
-#else
-report_at_line (FILE *errfp, errnum, file_name, line_number, message, va_alist)
- int errnum;
- const char *file_name;
- unsigned int line_number;
- const char *message;
- va_dcl
-#endif
{
-#ifdef VA_START
va_list args;
-#endif
if (error_one_per_line)
{
if (file_name != NULL)
fprintf (errfp, "%s:%u: ", file_name, line_number);
-#ifdef VA_START
- VA_START (args, message);
-# if defined(HAVE_VPRINTF) || defined(_LIBC)
+ va_start(args, message);
vfprintf (errfp, message, args);
-# else
- _doprnt (message, args, errfp);
-# endif
va_end (args);
-#else
- fprintf (errfp, message, a1, a2, a3, a4, a5, a6, a7, a8);
-#endif
if (errnum)
fprintf (errfp, ": %s", strerror (errnum));
******************************************************************************/
#include "config.h"
+#include "fetchmail.h"
#include <stdio.h>
#include <ctype.h>
#include <strings.h>
#include <stdlib.h>
-#include "fetchmail.h"
#include "sdump.h"
#ifndef MAIN
#include "config.h"
#if defined(POP3_ENABLE) && defined(RPA_ENABLE)
+#include "fetchmail.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include "socket.h"
-#include "fetchmail.h"
#include "fm_md5.h"
#include "i18n.h"
* For license terms, see the file COPYING in this directory.
*/
#include "fetchmail.h"
-#include "getaddrinfo.h"
#include "i18n.h"
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netdb.h>
-#if defined(HAVE_NETINET_IN_H)
#include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
-#endif
#include <sys/socket.h>
int servport(const char *service) {
*/
#include "config.h"
+#include "fetchmail.h"
+
#include <stdio.h>
#include <errno.h>
#include <string.h>
+#include <strings.h>
#include <signal.h>
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif /* HAVE_MEMORY_H */
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
-#if defined(HAVE_STDARG_H)
#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
#include <ctype.h>
#include <langinfo.h>
-#include "fetchmail.h"
-
/* for W* macros after pclose() */
#define _USE_BSD
#include <sys/types.h>
int *good_addresses, int *bad_addresses)
/* open a stream to a local MDA */
{
-#ifdef HAVE_SETEUID
uid_t orig_uid;
-#endif /* HAVE_SETEUID */
struct idlist *idp;
int length = 0, fromlen = 0, nameslen = 0;
char *names = NULL, *before, *after, *from = NULL;
if (outlevel >= O_DEBUG)
report(stdout, GT_("about to deliver with: %s\n"), before);
-#ifdef HAVE_SETEUID
/*
* Arrange to run with user's permissions if we're root.
* This will initialize the ownership of any files the
report(stderr, GT_("Cannot switch effective user id to %ld: %s\n"), (long)ctl->uid, strerror(errno));
return PS_IOERR;
}
-#endif /* HAVE_SETEUID */
sinkfp = popen(before, "w");
free(before);
before = NULL;
-#ifdef HAVE_SETEUID
/* this will fail quietly if we didn't start as root */
if (seteuid(orig_uid)) {
report(stderr, GT_("Cannot switch effective user id back to original %ld: %s\n"), (long)orig_uid, strerror(errno));
return PS_IOERR;
}
-#endif /* HAVE_SETEUID */
if (!sinkfp)
{
/* if rfc2047charset is non-NULL, encode the line (that is assumed to be
* a header line) as per RFC-2047 using rfc2047charset as the character
* set field */
-#if defined(HAVE_STDARG_H)
void stuff_warning(const char *rfc2047charset, struct query *ctl, const char *pfx, const char *fmt, ... )
-#else
-void stuff_warning(rfc2047charset, ctl, pfx, fmt, va_alist)
-const char *charset;
-const char *pfx; /* constant, non-translated prefix (such as "Subject: ") */
-struct query *ctl;
-const char *fmt; /* printf-style format */
-va_dcl
-#endif
{
/* make huge -- i18n can bulk up error messages a lot */
char buf[3*MSGBUFSIZE+4];
* case it was a string constant. We make a virtue of that necessity
* here by supporting stdargs/varargs.
*/
-#if defined(HAVE_STDARG_H)
va_start(ap, fmt) ;
-#else
- va_start(ap);
-#endif
vsnprintf(buf+strlen(buf), sizeof(buf)-strlen(buf)-2, fmt, ap);
va_end(ap);
+#include "fetchmail.h"
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include "ntlm.h"
#include "smbencrypt.h"
#include "smbbyteorder.h"
-#include "fetchmail.h"
char versionString[] ="libntlm version 0.21";
#include <stdio.h>
#include <unistd.h>
#include <string.h>
+#include <strings.h>
#include <signal.h>
#include "socket.h"
#include "smtp.h"
*/
#include "config.h"
+#include "fetchmail.h"
+
#include <stdio.h>
#include <errno.h>
#include <string.h>
+#include <strings.h>
#include <ctype.h> /* isspace() */
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif /* HAVE_MEMORY_H */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
-#ifdef HAVE_ARPA_INET_H
#include <arpa/inet.h>
-#endif
#include <netdb.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
-#if defined(HAVE_STDARG_H)
#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#endif
#include "socket.h"
-#include "fetchmail.h"
-#include "getaddrinfo.h"
#include "i18n.h"
#include "sdump.h"
#include "uid_db.h"
-/* Defines to allow BeOS and Cygwin to play nice... */
-#ifdef __BEOS__
-static char peeked;
-#define fm_close(a) closesocket(a)
-#define fm_write(a,b,c) send(a,b,c,0)
-#define fm_peek(a,b,c) recv(a,b,c,0)
-#define fm_read(a,b,c) recv(a,b,c,0)
-#else
-#define fm_close(a) close(a)
-#define fm_write(a,b,c) write(a,b,c)
-#define fm_peek(a,b,c) recv(a,b,c, MSG_PEEK)
-#ifdef __CYGWIN__
-#define fm_read(a,b,c) cygwin_read(a,b,c)
-static ssize_t cygwin_read(int sock, void *buf, size_t count);
-#else /* ! __CYGWIN__ */
-#define fm_read(a,b,c) read(a,b,c)
-#endif /* __CYGWIN__ */
-#endif
+/* Defines, these used to be used to allow BeOS and Cygwin to play nice...
+ these days, fetchmail requires a conforming system. */
+#define fm_close(a) close(a)
+#define fm_write(a,b,c) write(a,b,c)
+#define fm_peek(a,b,c) recv(a,b,c, MSG_PEEK)
+#define fm_read(a,b,c) read(a,b,c)
/* We need to define h_errno only if it is not already */
#ifndef h_errno
# endif
#endif /* ndef h_errno */
-#ifdef HAVE_SOCKETPAIR
static char *const *parse_plugin(const char *plugin, const char *host, const char *service)
{
char **argvec;
(void) close(fds[0]);
return fds[1];
}
-#endif /* HAVE_SOCKETPAIR */
/** Set socket to SO_KEEPALIVE. \return 0 for success. */
int SockKeepalive(int sock) {
int ord;
char errbuf[8192] = "";
-#ifdef HAVE_SOCKETPAIR
if (plugin)
return handle_plugin(host,service,plugin);
-#endif /* HAVE_SOCKETPAIR */
memset(&req, 0, sizeof(struct addrinfo));
req.ai_socktype = SOCK_STREAM;
}
-#if defined(HAVE_STDARG_H)
int SockPrintf(int sock, const char* format, ...)
{
-#else
-int SockPrintf(sock,format,va_alist)
-int sock;
-char *format;
-va_dcl {
-#endif
-
va_list ap;
char buf[8192];
-#if defined(HAVE_STDARG_H)
va_start(ap, format) ;
-#else
- va_start(ap);
-#endif
vsnprintf(buf, sizeof(buf), format, ap);
va_end(ap);
return SockWrite(sock, buf, strlen(buf));
-
}
#ifdef SSL_ENABLE
if (--len < 1)
return(-1);
-#ifdef __BEOS__
- if (peeked != 0){
- (*bp) = peeked;
- bp++;
- len--;
- peeked = 0;
- }
-#endif
do {
/*
* The reason for these gymnastics is that we want two things:
#endif /* SSL_ENABLE */
{
-#ifdef __BEOS__
- if ((n = fm_read(sock, bp, 1)) <= 0)
-#else
if ((n = fm_peek(sock, bp, len)) <= 0)
-#endif
return (-1);
if ((newline = (char *)memchr(bp, '\n', n)) != NULL)
n = newline - bp + 1;
-#ifndef __BEOS__
if ((n = fm_read(sock, bp, n)) == -1)
return(-1);
-#endif /* __BEOS__ */
}
bp += n;
len -= n;
if (n == -1)
return -1;
-#ifdef __BEOS__
- peeked = ch;
-#endif
return(ch);
}
/* if there's an error closing at this point, not much we can do */
return(fm_close(sock)); /* this is guarded */
}
-
-#ifdef __CYGWIN__
-/*
- * Workaround Microsoft Winsock recv/WSARecv(..., MSG_PEEK) bug.
- * See http://sources.redhat.com/ml/cygwin/2001-08/msg00628.html
- * for more details.
- */
-static ssize_t cygwin_read(int sock, void *buf, size_t count)
-{
- char *bp = (char *)buf;
- size_t n = 0;
-
- if ((n = read(sock, bp, count)) == (size_t)-1)
- return(-1);
-
- if (n != count) {
- size_t n2 = 0;
- if (outlevel >= O_VERBOSE)
- report(stdout, GT_("Cygwin socket read retry\n"));
- n2 = read(sock, bp + n, count - n);
- if (n2 == (size_t)-1 || n + n2 != count) {
- report(stderr, GT_("Cygwin socket read retry failed!\n"));
- return(-1);
- }
- }
-
- return count;
-}
-#endif /* __CYGWIN__ */
struct addrinfo;
#include <config.h>
-#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
-#elif HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#endif
#include <netdb.h>
/** Create a new client socket; returns -1 on error */
Send formatted output to the socket (matches interface of fprintf).
Returns number of bytes successfully written.
*/
-#if defined(HAVE_STDARG_H)
int SockPrintf(int sock, const char *format, ...)
__attribute__ ((format (printf, 2, 3)))
;
-#else
-int SockPrintf();
-#endif
/**
Close a socket previously opened by SockOpen. This allows for some
#include "fetchmail.h"
#include <string.h>
-
-#ifdef HAVE_STRINGS_H
#include <strings.h>
-#endif
/** return true if user allowed opportunistic STARTTLS/STLS */
int maybe_starttls(struct query *ctl) {
+++ /dev/null
-/*
- * scratch implementation of strcasecmp(),
- * in case your C library doesn't have it
- *
- * For license terms, see the file COPYING in this directory.
- */
-#include <ctype.h>
-
-int strcasecmp(char *s1, char *s2)
-{
- while (toupper((unsigned char)*s1) == toupper((unsigned char)*s2++))
- if (*s1++ == '\0')
- return 0;
- return(toupper((unsigned char)*s1) - toupper((unsigned char)*--s2));
-}
-
-int strncasecmp(char *s1, char *s2, register int n)
-{
- while (--n >= 0 && toupper((unsigned char)*s1) == toupper((unsigned char)*s2++))
- if (*s1++ == '\0')
- return 0;
- return(n < 0 ? 0 : toupper((unsigned char)*s1) - toupper((unsigned char)*--s2));
-}
+++ /dev/null
-/*
- * strstr -- locate first occurence of a substring
- *
- * Locates the first occurrence in the string pointed to by S1 of the string
- * pointed to by S2. Returns a pointer to the substring found, or a NULL
- * pointer if not found. If S2 points to a string with zero length, the
- * function returns S1.
- *
- * For license terms, see the file COPYING in this directory.
- */
-
-char *strstr(register char *buf, register char *sub)
-{
- register char *bp;
-
- if (!*sub)
- return buf;
- for (;;)
- {
- if (!*buf)
- break;
- bp = buf;
- for (;;)
- {
- if (!*sub)
- return buf;
- if (*bp++ != *sub++)
- break;
- }
- sub -= (unsigned long) bp;
- sub += (unsigned long) buf;
- buf += 1;
- }
- return 0;
-}
-
+++ /dev/null
-#! /bin/sh
-exec ./regression
*/
#include "config.h"
+#include "fetchmail.h"
#include <stdio.h>
#include <string.h>
+#include <strings.h>
#include <ctype.h>
-#ifdef HAVE_MEMORY_H
-#include <memory.h>
-#endif /* HAVE_MEMORY_H */
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#if defined(HAVE_UNISTD_H)
#include <unistd.h>
-#endif
-#if defined(HAVE_STDARG_H)
#include <stdarg.h>
-#else
-#include <varargs.h>
-#endif
#include <limits.h>
#include <assert.h>
-#ifdef HAVE_NET_SOCKET_H
-#include <net/socket.h>
-#endif
#include <sys/socket.h>
#include <netdb.h>
#include "fm_md5.h"
#include "i18n.h"
#include "socket.h"
-#include "fetchmail.h"
/** Macro to clamp the argument so it is >= INT_MIN. */
#define _FIX_INT_MIN(x) ((x) < INT_MIN ? INT_MIN : (x))
char tag[TAGLEN]; /**< buffer for the tag */
static unsigned int tagnum; /**< local counter for the tag */
/** Macro to generate the tag and store it in #tag. */
-#define GENSYM (sprintf(tag, "A%04u", ++tagnum % TAGMOD), tag)
+#define GENSYM (snprintf(tag, sizeof tag, "A%04u", ++tagnum % TAGMOD), tag)
static const struct method *protocol; /**< description of the protocol used for the current poll */
char shroud[PASSWORDLEN*2+3]; /**< string to shroud in debug output */
}
}
-#if defined(HAVE_STDARG_H)
/** assemble command in printf(3) style and send to the server */
void gen_send(int sock, const char *fmt, ... )
-#else
-void gen_send(sock, fmt, va_alist)
-int sock; /** socket to which server is connected */
-const char *fmt; /** printf-style format */
-va_dcl
-#endif
{
char buf [MSGBUFSIZE+1];
va_list ap;
else
buf[0] = '\0';
-#if defined(HAVE_STDARG_H)
va_start(ap, fmt);
-#else
- va_start(ap);
-#endif
vsnprintf(buf + strlen(buf), sizeof(buf)-2-strlen(buf), fmt, ap);
va_end(ap);
}
/** @} */
-#if defined(HAVE_STDARG_H)
int gen_transact(int sock, const char *fmt, ... )
-#else
-int gen_transact(int sock, fmt, va_alist)
-int sock; /** socket to which server is connected */
-const char *fmt; /** printf-style format */
-va_dcl
-#endif
/** assemble command in printf(3) style, send to server, fetch a response */
{
int ok;
else
buf[0] = '\0';
-#if defined(HAVE_STDARG_H)
va_start(ap, fmt) ;
-#else
- va_start(ap);
-#endif
vsnprintf(buf + strlen(buf), sizeof(buf)-2-strlen(buf), fmt, ap);
va_end(ap);
+++ /dev/null
-CHANGES -- trio
-
-
-The changes listed without a name attributed to them were most likely done by
-Bjorn Reese and/or Daniel Stenberg.
-
-Version 1.14 - 2010/01/26
--------------------------
-* David Byron
- Added trio_xstring_append_max.
-
-* Fixed compilation problem on Cygwin due to lack of long double math
- (reported by Matthias Andree).
-
-* David Boyce
- Added #undef of standard stdio function names before assigning trio functions
- to them.
-
-* Matthias Andree
- Upgraded configure.in to use new macros instead of obsoleted macros.
-
-* Matthias Andree
- Added VPATH to Makefile.in
-
-* Tom Honermann
- Fixed problem with subnormal numbers which caused an infinite loop outputting
- leading spaces.
-
-* Adam McLaurin
- Improved parsing performance by avoiding memset() and memcpy() on character
- arrays.
-
-* Gideon Smeding
- Fixed %u scanning of signed numbers.
-
-* Gideon Smeding
- Fixed group scanning for non-matching input.
-
-* Fixed missing undo of look-ahead reading for scanf functions. This does only
- work for the scanf* and fscanf* functions, not dscanf* and cscanf* functions
- (reported by Gideon Smeding).
-
-* If the format string is empty, scanf does not attempt to read any input.
-
-* Ralf Junker
- Fixed Borland compilation for user-defined specifiers.
-
-
-Version 1.13 - 2008/11/09
--------------------------
-* Ives Aerts
- Added the $<format|skip> format for user-defined specifiers, which is
- compatible with compiler warnings about mismatches between specifiers and
- arguments.
-
-* Added TRIO_DEPRECATED flag (reported by David Boyce)
-
-* Fixed rounding adjustment for long double (reported as bug item #2136686).
-
-* Added Makefile dependency for test target (reported as bug item #2136636).
-
-* David Boyce
- Fixed long long support for MSVC.
-
-* Fixed potential problem with read after buffer end for non-zero terminated
- strings (reported as bug item #1828465).
-
-* Andreas Stricker
- Added WinCE support.
-
-* Fixed number of significant digits for %g.
-
-
-Version 1.12 - 2006/10/22
--------------------------
-* Fixed scanning of floats (reported by Bernd Ahlers).
-
-* Fixed configure.in for GCC on Tru64 and MIPSpro on IRIX (reported by Andreas
- Maus).
-
-* Olli Savia
- Added support for LynxOS.
-
-
-Version 1.11 - 2006/04/08
--------------------------
-* Mark Pickelmann
- Fixed trio_unregister. If the first element was removed, the remaining
- list would be removed as well.
-
-* Fixed unintended formatting of %e that would result in non-zero numbers
- starting with zero (reported by Mark Pickelmann and Gisli Ottarsson).
-
-* Fixed compilation with Sun Workshop 6 (reported by Matthias Andree).
-
-* Fixed accuracy for denormalized numbers (bug item #758327).
-
-* Glen Davidson
- Fixed scanning of floating-point numbers without a decimal-point (bug item
- #1370427).
-
-* David Byron
- Fixed more compiler warnings.
-
-* Fixed compilation of trio_to_long_double and TRIO_FEATURE_FLOAT (reported by
- David Byron).
-
-* Fixed precision of large floating-point numbers (bug item #1314524).
-
-* Karl Bochert
- Fixed trio_fpclassify_and_signbit to only restore the floating-point
- precision.
-
-* Fixed detection of need for ieee option on FreeBSD/Alpha.
-
-* Added TRIO_SNPRINTF_ONLY compilation.
-
-* Fixed trio_to_double by not using strtod() on Tru64/DECC because it does not
- support hex-floats.
-
-* Fixed crash on 64 bits machines related to a previous workaround in version
- 1.9 for uninitialized va_list (reported by Nicolai Tufar, suggestion by
- Douglas Gwyn).
-
-* Patrick Jessee
- Fixed width calculation for %g.
-
-* Added macros for internal features.
-
-* Jon Foster
- Added macros for conditional compilation of many features. Documented all
- the features.
-
-* Karl Bochert
- Fixed problem with Borland C++, which changes the floating-point precision
- for certain math functions (log10() and _fpclass()).
-
-* Karl Bochert
- Fixed compilation warnings on Borland C++.
-
-* Removed any occurrence of #elif because Borland C++ reports wrong line
- numbers when they are present (reported by Karl Bochert).
-
-* David Byron
- Added trio_asprintfv.
-
-* Brian Chapman
- Fixed Mac OS X compilation.
-
-* David Byron
- Fixed several compiler warnings.
-
-* Fixed printing of out-of-range arguments for %hhd and %hd. These arguments
- can be out of range because of default integer promotion.
-
-* Bob Friesenhahn
- Fixed installation of header files.
-
-* Joe Orton
- Added SHELL to Makefile.in to avoid problems with CShells.
-
-* Shaun Tancheff
- Fixed regresion tests for MSVC.
-
-* Craig Berry
- Fixed the VMS C99 workaround.
-
-
-Version 1.10 - 2003/03/06
--------------------------
-* Rearranged some include files to accommodate large file support (reported by
- Albert Chin-A-Young).
-
-* Added support for SunOS 4.1.x lack of strerror, tolower, and toupper
- (reported by Peter McCluskey).
-
-* Fixed pedantic compilation with TRIO_MINIMAL.
-
-* Jose Kahan
- Moved <limits.h> to avoid redefinition problems.
-
-* Fixed hex-float exponents (reported by Matthias Clasen).
-
-* Fixed handling of negative width and precision via paramters (reported by
- Jacob Navia).
-
-* Nigel Hall
- Fixed TRIO_VA_START for VMS.
-
-* Rune Enggaard Lausen
- Fixed compilation for Borland C++ Builder.
-
-* Fixed precision of hex-float numbers (reported by James Antill).
-
-* Fixed plus sign only to be added for signed numbers.
-
-* Fixed printing of integers with value and precision of zero (reported by
- James Antill).
-
-* Fixed %#.o to only print one zero if the value is zero (reported by James
- Antill).
-
-* Rewrote check for IEEE compilation option to remove dependency on additional
- scripts.
-
-* Mehdi Lavasani
- Makefile install target fixed to work with older install programs.
-
-* Collapsed the DECC, MSVC, HP-UX, and AIX code for trio_fpclassify_and_sign()
- with further preprocessing.
-
-
-Version 1.9 - 2002/10/13
-------------------------
-* Fixed trio_fpclassify_and_signbit on AIX 3.2
-
-* Added configure check for -ieee/-mieee compilation option for Alpha machines.
-
-* Craig Berry
- Fixed compilation on VMS.
-
-* Albert Chin-A-Young
- Fixed incorrect conditional expression in trio_isinf.
-
-* Fixed the warnings about uninitialized va_list in the printfv and scanfv
- family without the use of compiler specific pragmas (suggested by Ian
- Pilcher).
-
-* Fixed space flag for floating-point numbers (reported by Ian Main).
-
-
-Version 1.8 - 2002/07/10
-------------------------
-* Fixed infinite loop in multibyte handling (reported by Gisli Ottarsson).
-
-* Added the customizable cprintf/cscanf family which enables to user to specify
- input and output stream functions (suggested by Florian Schulze).
-
-* Fixed trio_isinf by removing the HP-UX workaround, and instead making sure
- that the C99 macro will adhere to the trio return values (reported by Luke
- Dunstan).
-
-* Alexander Lukyanov
- Fixed boundary case for scanning and EOF.
-
-* Jacob Navia
- Enabled the L modifier for formatting.
-
-* Added TRIO_MINIMAL to build trio without the string functions.
-
-* Added the R modifier to print rounded floating-point numbers.
-
-* Added trio_to_long_double and long double scanning (the L modifier).
-
-* Added trio_locale_decimal_point, trio_locale_thousand_separator,
- trio_locale_grouping to overwrite locale settings.
-
-* Rewrote TrioWriteDouble to avoid temporary buffers and thus the danger of
- buffer overflows (for instance %.5000f).
-
-* Improved floating-point formatting accuracy.
-
-* Fixed formatting of non-decimal exponents.
-
-* Fixed thousand separator checking.
-
-* Fixed %f scanning to get a float and %lf to get a double.
-
-* Fixed WIN32 compilation (reported by Emmanuel Mogenet)
-
-* Fixed regression test cases to exclude disabled features.
-
-
-Version 1.7 - 2002/05/07
-------------------------
-* Fixed trio_to_double to handle hex-floats properly.
-
-* Fixed printing of %a-format to be like %e, not like %g.
-
-* Fixed floating-point printing of values beyond the machine accuracy.
-
-* Fixed %f for printing with large precision.
-
-* Fixed the usage of C99 nan(), which caused a crash on OSF/1 (reported by
- Georg Bolz)
-
-* Joe Orton
- Fixed %p on 64-bit platforms.
-
-* Made trio compile with K&R compilers.
-
-* Emmanuel Mogenet
- Fixed bug in trio_asprintf.
-
-* Emmanuel Mogenet
- Various WIN32 fixes.
-
-* Joe Orton
- Fixed trio_isinf() on HP-UX, and added test cases.
-
-* Joe Orton
- Fixed non-portable use of $^ in Makefile.
-
-* Joe Orton
- Added autoconf.
-
-* Alexander Lukyanov
- Fixed a number of bugs in the scanning of EOF and the count specifier.
-
-* Richard Jinks
- Added trio_nzero
-
-* Fixed incorrect handling of return code from TrioReadChar (reported by
- Henrik Löf)
-
-* Fixed parsing of character class expressions.
-
-* Fixed trio_to_double which did not work with long fractions.
-
-* Fixed %f for printing of large numbers.
-
-* Fixed %#s to handle whitespaces as non-printable characters.
-
-* Added trio_isfinite, trio_signbit, and trio_fpclassify.
-
-* Added new test cases.
-
-
-Version 1.6 - 2002/01/13
-------------------------
-* Added dynamic string functions.
-
-* Rewrote and extended documentation in JavaDoc (using Doxygen).
-
-* Moved and renamed strio functions to triostr.
-
-* Robert Collins
- Added definition for Cygwin.
-
-* Markus Henke
- Added long double workaround for the HP C/iX compiler.
-
-* Marc Verwerft
- Improved error handling for dynamically allocated strings.
-
-* John Fotheringham
- Made trionan compile on OpenVMS.
-
-* Added 'd' and 'D' as exponent letters when using TRIO_MICROSOFT.
-
-* Fixed uninitial memory read for the parameter modifiers.
-
-
-Version 1.5 - 2001/09/08
-------------------------
-* Merged with libxml changes.
-
-* Moved NaN and Inf handling to separate file to enable reuse in other
- projects.
-
-* Igor Zlatkovic
- Fixed TrioGenerateNan for MSVC.
-
-* Fixed lots of preprocessor macros and internal data structure names.
-
-
-Version 1.4 - 2001/06/03
-------------------------
-* Added hex-float (%a and %A) for scanning.
-
-* Added wide character arguments (%ls, %ws, %S, %lc, %wc, and %C) for both
- printf and scanf.
-
-* Added mutex callbacks for user-specified specifiers to enable applications to
- add thread-safety. These are registered with trio_register, where the
- namespace is set to either ":enter" to lock a mutex, or ":leave" to unlock a
- mutex.
-
-* Added equivalence class expressions for scanning. For example, %[[=a=]] scans
- for all letters in the same equivalence class as the letter 'a' as defined
- by the locale.
-
-* Changed character class expressions for scanning. The expressions must now
- be embedded withing an extra set of brackets, e.g. %[[:alpha:]]. This was
- done to adhere to the syntax of UNIX98 regular expressions.
-
-* Added the possibility to specify standard support (TRIO_C99 etc.) as compiler
- options.
-
-* Fixed conversion of hex-float in StrToDouble.
-
-* Fixed formatting of hex-float numbers.
-
-* Stan Boehm
- Fixed crash on QNX, which happend because some buffers on the stack were too
- big.
-
-* Fixed default precision for %f and %g (reported by Jose Ortiz)
-
-* Howard Kapustein
- Added the I8, I16, I32, and I64 modifiers.
-
-* Jose Ortiz
- Fixed rounding problem for %e.
-
-* Jose Ortiz
- Fixed various problems with the xlC and Sun C++ compilers.
-
-
-Version 1.3 - 2001/05/16
-------------------------
-* trio's treatment of the field width when the %e code was used was not
- correct (reported by Gisli Ottarsson). It turns out the fraction part should
- be zero-padded by default and the exponent part should be zero-prefixed if
- it is only one digit. At least that's how the GNU and Sun libc's work. The
- trio floating point output looks identical to them now.
-
-* Fixed group scanning with modifiers.
-
-* Fixed compilation for 64-bit Digital Unix.
-
-* Igor Zlatkovic
- Fixed compilation of dprintf, which uses read/write, for MSVC.
-
-* Fixed various compilation problems on Digital Unix (mainly associated with
- va_list).
-
-
-Version 1.2 - 2001/04/11
-------------------------
-* Added autoconf integration. If compiled with HAVE_CONFIG_H the following
- happens. Firstly, <config.h> is included. Secondly, trio will only be
- compiled if WITH_TRIO is defined herein. Thirdly, if TRIO_REPLACE_STDIO is
- defined, only stdio functions that have not been detected by autoconf, i.e.
- those not defined by HAVE_PRINTF or similar, will be replaced by trio
- functions (suggested by Daniel Veillard).
-
-* Fixed '%m.nf' output. Previously trio did not treat the width properly
- in all cases (reported by Gisli Ottarsson).
-
-* Added explicit promotion for the scanfv family.
-
-* Fixed more C++ compilation warnings.
-
-
-Version 1.1 - 2001/02/25
-------------------------
-* Added explicit promotion for the printfv familiy. A float must be specified
- by %hf.
-
-* Fixed positionals for printfv (reported by Gisli Ottarsson).
-
-* Fixed an integer to pointer conversion problem on the SGI MIPS C compiler
- (reported by Gisli Ottarsson).
-
-* Fixed ANSI C++ warnings (type casting, and namespace is a reserved keyword).
-
-* Added \n to all examples in the documentation to prevent confusion.
-
-* Fixed StrSubstringMax
-
-
-Version 1.0 - 2000/12/10
-------------------------
-* Bumped Version number.
-
-
-Version 0.25 - 2000/12/09
--------------------------
-* Wrote more documentation.
-
-* Improved NaN support and added NaN to regression test.
-
-* Fixed C99 support.
-
-* Added missing getter/setter functions.
-
-
-Version 0.24 - 2000/12/02
--------------------------
-* Added callback functionality for the user-defined specifier (<>). All
- the necessary functions are defined in triop.h header file. See the
- documentation for trio_register for further detail.
-
-* Wrote initial documentation on the callback functionality.
-
-* Added the printfv and scanfv family of functions, which takes a pointer
- array rather than variadic arguments. Each pointer in the array must point
- to the associated data (requested by Bruce Korb).
-
-* As indicated in version 0.21 the extension modifiers (<>) have now been
- completely removed.
-
-* Added skipping of thousand-separators in floating-point number scanning.
-
-
-Version 0.23 - 2000/10/21
--------------------------
-* Added width to scanning of floating-point numbers.
-
-* Wrote more documentation on trio_printf.
-
-* Fixed problem with trailing zeroes after decimal-point.
-
-
-Version 0.22 - 2000/08/06
--------------------------
-* Added LC_CTYPE locale dependent character class expressions to scan lists.
- Included are [:alnum:], [:alpha:], [:cntrl:], [:digit:], [:graph:],
- [:lower:], [:print:], [:punct:], [:space:], [:upper:], [:xdigit:]
-
-* Added C escapes to alternative string formatting and scanning.
-
-* Added StrSubstringMax.
-
-* Wrote a little more documentation.
-
-* Fixed scanf return values.
-
-* Fixed a sign error for non-ascii characters.
-
-
-Version 0.21 - 2000/07/19
--------------------------
-* Converted the documentation to TeX. With latex2man the documentation can
- automatically be converted into man pages.
-
-* Added trio_scanf, trio_vscanf, trio_fscanf, and trio_vfscanf.
-
-* Added trio_dprintf, trio_vdprintf, trio_dscanf, and trio_vdscanf. These
- functions can be used to write and read directly to pipes and sockets (the
- assume blocking sockets). Stdio buffering is surpassed, so the functions are
- async-safe. However, reading from stdin (STDIN_FILENO) or writing to stdout
- (STDOUT_FILENO) reintroduces the buffering.
-
-* Paul Janzen
- Added trio_asprintf and trio_vasprintf, which are compatible with the GNU
- and BSD interfaces.
-
-* Added scanlist ranges for group scanning (%[]).
-
-* Added width for scanning (missing for floating-point numbers though).
-
-* Added variable size modifier (&) to handle system defined types of unknown
- size. This modifier makes certain assumptions about the integer sizes, which
- may not be valid on any machine. Consequently, the modifier will remain
- undocumented, as it may be removed later.
-
-* Added \777 and \xFF to alternative string scanning (%#s)
-
-* Added the TRIO_REPLACE_STDIO check in the header.
-
-* Improved performance of the multibyte character parsing.
-
-* Fixed positionals (%n$) which had stopped working.
-
-* Fixed hh and ll modifiers to allow exactly two letters and no more.
-
-* Fixed ANSI C++ warnings. Also fixed the compiler warning about casting
- between integer and pointer (this has been annoying me for ages).
-
-* Fixed snprintf and vsnprintf with zero buffer size.
-
-* Fixed NAN problems (reported by Keith Briggs).
-
-* Fixed parsing of multibyte characters. The format string was not correctly
- advanced in case of a multibyte character.
-
-* Renamed many of the internal functions to have more consistant names.
-
-* Removed the <quote=c> and <fill=c> modifiers. They are not really worth
- including. The other <> modifiers may disappear as well.
-
-
-Version 0.20 - 2000/06/05
--------------------------
-* Added intmax_t and ptrdiff_t support.
-
-* Added support for LC_NUMERIC grouping.
-
-* Added double-dot notation for the conversion base. The style is now
- %width.precision.base, where any argument can be a number, an asterix
- indicating a parameter, or be omitted entirely. For example, %*..2i is
- to specify binary numbers without precision, and with width as a parameter
- on the va_list.
-
-* Added sticky modifier (!), which makes subsequent specifiers of the same
- type reuse the current modifiers. Inspired by a suggestion from Gary Porter.
-
-* Added group scanning (%[]). Scanlist ranges and multibyte sequences are not
- supported yet.
-
-* Added count scanning (%n).
-
-* Changed the number scanning to accept thousand separators and any base.
-
-* Fixed positional for parameters. It is possible to write something like
- %3$*1$.*2$d (which happens to be the same as %*.*d).
-
-* Fixed precision of integers.
-
-* Fixed parameter flags. Before trio could only handle one parameter flag per
- specifier, although two (three with double-dot base) were possible.
-
-* Fixed isinf() for those platforms where it is unimplemented.
-
-
-Version 0.18 - 2000/05/27
--------------------------
-* Rewrote the entire floating-point formatting function (Danny Dulai had
- reported several errors and even supplied some patches, which unfortunately
- were lost due to the refactoring).
-
-* Removed the use of strlen() in the declaration of a stack array. This
- caused problems on some compilers (besides it isn't really ANSI C compliant
- anyways). Using some arbitrarily chosen maximum value; should examine if
- some standard defines an upper limit on the length of decimal-point and
- thousands-separator (sizeof(wchar_t) perhaps?)
-
-* Changed the parsing of the format string to be multibyte aware.
-
-
-Version 0.17 - 2000/05/19
--------------------------
-* Added INF, -INF, and NAN for floating-point numbers.
-
-* Fixed %#.9g -- alternative with precision.
-
-* Ken Gibson
- Fixed printing of negative hex numbers
-
-* Joerg (last name unknown)
- Fixed convertion of non-ASCII characters
-
-
-Version 0.16 - 1999/08/06
--------------------------
-* Changed the constness of the second argument of StrFloat and StrDouble. The
- lack of parameter overloading in C is the reason for the strange use of
- constness in strtof and strtod.
-
-* Cleaned up constness.
-
-
-Version 0.15 - 1999/07/23
--------------------------
-* Fixed the internal representation of numbers from signed to unsigned. Signed
- numbers posed a problem for large unsigned numbers (reported by Tero)
-
-* Fixed a tiny bug in trio_vsprintfcat
-
-* Changed the meaning of the max argument of StrAppendMax to be consistant
- with StrFormatAppendMax. Now it is the maximal size of the entire target
- buffer, not just the appended size. This makes it easier to avoid buffer
- overflows (requested by Tero)
-
-
-Version 0.14 - 1999/05/16
--------------------------
-* Added size_t support (just waiting for a C99 compliant compiler to add
- ptrdiff_t and intmax_t)
-
-* Rewrote TrioOutStreamDouble so it does not use the libc sprintf to emulate
- floating-point anylonger.
-
-* Fixed width, precision, and adjustment for numbers and doubles.
-
-
-Version 0.13 - 1999/05/06
--------------------------
-* Fixed zero padding for %d. Now %d will only zero pad if explicitly requested
- to do so with the 0 flag (reported by Tero).
-
-* Fixed an incorrect while() condition in TrioGetString (reported by Tero).
-
-
-Version 0.12 - 1999/04/19
--------------------------
-* Fixed incorrect zero padding of pointers
-
-* Added StrHash with STRIO_HASH_PLAIN
-
-* Added StrFormatDateMax
-
-
-Version 0.11 - 1999/03/25
--------------------------
-* Made it compile under cygwin
-
-* Fixed a bug were TrioPreprocess would return an error if no formatting chars
- were found (reported by Tero).
-
-
-Version - 1999/03/19
---------------------
-* Added trio_strerror and TRIO_ERROR_NAME.
-
-* Changed the error codes to be positive (as errno)
-
-* Fixed two reads of uninitialized memory reported by Purify
-
-* Added binary specifiers 'b' and 'B' (like SCO.) ThousandSeparator can be
- used to separate nibbles (4 bit)
-
-* Renamed all Internal* functions to Trio*, which seems like a better
- namespace (even though it is of no practical interest because these
- functions are not visible beyond the scope of this file.)
-
-
-Version - 1999/03/12
---------------------
-* Added hex-float format for StrToDouble
-
-* Double references and gaps in the arguments are not allowed (for the %n$
- format) and in both cases an error code is returned.
-
-* Added StrToDouble (and StrToFloat)
-
-
-Version - 1999/03/08
---------------------
-* Added InStream and OutStream to the trio_T structure.
-
-* Started work on TrioScan.
-
-* Return values for errors changed. Two macros to unpack the error code has
- been added to the header.
-
-* Shortshort (hh) flag added.
-
-* %#s also quotes the quote-char now.
-
-* Removed the 'errorInFormat' boolean, which isn't used anymore after the
- functions bail out with an error instead.
-
-
-Version - 1999/03/04
---------------------
-* More than MAX_PARAMETERS parametes will now cause the TrioPreprocess()
- function to return error.
-
-* Unknown flags and/or specifiers cause errors too.
-
-* Added trio_snprintfcat and trio_vsnprintfcat and the defined name
- StrFormatAppendMax. They append a formatted string to the end of a string.
-
-* Define MAX_PARAMETERS to 128 at all times instead of using NL_ARGMAX when
- that exists.
-
-* Added platform fixes for Amiga as suggested by Tero Jänkä <tesaja@utu.fi>
-
-
-Version - 1999/01/31
---------------------
-* vaprintf did add a zero byte even when it had failed.
-
-* Cleaned up the code for locale handling and thousand separator
-
-* Added trio_aprintf() and trio_vaprintf(). They return an allocated string.
-
-* Added thousands separator for numbers
-
-* Added floating point support for *printf
-
-
-Version - 1998/10/20
---------------------
-* StrMatchCase() called StrMatch() instead of itself recursively
-
-* Rewrote the implementation of *printf and *scanf and put all the code in
- this file. Extended qualifiers and qualifiers from other standards were
- added.
-
-* Added StrSpanFunction, StrToLong, and StrToUnsignedLong
-
-
-Version - 1998/05/23
---------------------
-* Made the StrEqual* functions resistant to NULL pointers
-
-* Turns out strdup() is no standard at all, and some platforms (I seem to
- recall HP-UX) has problems with it. Made our own StrDuplicate() instead.
-
-* Added StrFormat() and StrFormatMax() to serve as sprintf() and snprintf()
- respectively.
+++ /dev/null
-FILES
-README
-CHANGES
-Makefile.in
-maketgz
-strio.h
-trio.c
-trio.h
-triodef.h
-trionan.c
-trionan.h
-triop.h
-triostr.c
-triostr.h
-compare.c
-example.c
-regression.c
-configure
-configure.in
-install-sh
-autogen.sh
-doc/doc.h
-doc/doc_dynamic.h
-doc/doc_printf.h
-doc/doc_register.h
-doc/doc_scanf.h
-doc/doc_static.h
-doc/footer.html
-doc/header.html
-doc/trio.cfg
-doc/trio.css
-html/trio.css
-html/*.html
+++ /dev/null
-SHELL = @SHELL@
-CC = @CC@
-CFLAGS = @CFLAGS@ -I. -DDEBUG
-OBJS = triostr.o trio.o trionan.o
-TARGETLIB = libtrio.a
-TARGETINCS = trio.h triop.h triodef.h trionan.h triostr.h
-LDFLAGS = -L. -ltrio -lm
-AR = ar
-RANLIB = @RANLIB@
-ERASE = rm -f
-MKDIR = mkdir -p
-GENDOC = doxygen
-srcdir = @srcdir@
-# VPATH doesn't seem to work with /usr/xpg4/bin/make on Solaris
-# (use /usr/ccs/bin/make), and doesn't work on older Solaris make
-# such as Solaris 2.6.
-VPATH = @srcdir@
-
-# Installation settings
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-prefix = @prefix@
-exec_prefix = @exec_prefix@
-includedir = @includedir@
-libdir = @libdir@
-
-all: $(TARGETLIB) $(TARGET)
-
-.PHONY: all check test install doc clean
-
-$(srcdir)/configure: configure.in
- cd $(srcdir) && autoconf
-
-Makefile: Makefile.in config.status
- CONFIG_COMMANDS= CONFIG_LINKS= CONFIG_HEADERS= \
- CONFIG_FILES=Makefile ./config.status
-
-config.status: configure
- ./config.status --recheck
-
-check: test
-test: regression
- ./regression
-
-install: $(TARGETLIB)
- $(MKDIR) $(libdir)
- $(MKDIR) $(includedir)
- $(INSTALL_DATA) $(TARGETLIB) $(libdir)/$(TARGETLIB)
- for i in $(TARGETINCS);do \
- (set -x;$(INSTALL_DATA) $(srcdir)/$$i $(includedir)); \
- done
-
-regression: regression.o $(TARGETLIB)
- $(CC) $(CFLAGS) regression.o $(LDFLAGS) -o $@
-
-example: example.o $(TARGETLIB)
- $(CC) $(CFLAGS) example.o $(LDFLAGS) -o $@
-
-compare: compare.o $(TARGETLIB)
- $(CC) $(CFLAGS) compare.o $(LDFLAGS) -o $@
-
-userdef: userdef.o $(TARGETLIB)
- $(CC) $(CFLAGS) userdef.o $(LDFLAGS) -o $@
-
-$(TARGETLIB): $(OBJS)
- $(AR) ruv $(TARGETLIB) $(OBJS)
- $(RANLIB) $(TARGETLIB)
-
-doc::
- (cd $(srcdir) && $(GENDOC) doc/trio.cfg)
-
-clean:
- $(ERASE) *~ core core.* regression example $(TOBJS) $(OBJS) $(TARGET) $(TARGETLIB) example.o regression.o
+++ /dev/null
-README -- trio
-
-Trio is a package with portable string functions. Including printf() clones
-and others.
-
- Copyright (C) 1998-2001 by Bjorn Reese and Daniel Stenberg.
-
- Permission to use, copy, modify, and distribute this software for any
- purpose with or without fee is hereby granted, provided that the above
- copyright notice and this permission notice appear in all copies.
-
- 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. THE AUTHORS AND
- CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
-
-Trio is intended to be an integral part of another application, so we
-have not done anything to create a proper installation.
-
-Compile with 'make' (edit the Makefile if you want a release build)
-
-Test the package with 'make test'
-
-Install by copying trio.h, triop.h, and libtrio.a (and man/man?/* if
-you want documentation) to the appropriate directories.
-
-Catch some usage examples in example.c
-
-Send feedback and patches to the mailing list, subscription and other
-information is found here:
-
- http://lists.sourceforge.net/lists/listinfo/ctrio-talk
-
-Enjoy!
-
-Trio web page
-
- http://daniel.haxx.se/trio/
+++ /dev/null
-#!/bin/sh
-autoconf
-rm -rf autom4te.cache
+++ /dev/null
-#include "trio.h"
-
-#define compare(format, value) printf("FORMAT: %s\n", format); printf("TRIO: "); trio_printf(format,value); printf("\nLIBC: "); \
-printf(format,value); printf("\n\n");
-
-int main()
-{
- compare("\"%e\"",2.342E+02);
- compare("\"%10.4e\"",-2.342E-02);
- compare("\"%11.4e\"",-2.342E-02);
- compare("\"%12.4e\"",-2.342E-02);
- compare("\"%13.4e\"",-2.342E-02);
- compare("\"%14.4e\"",-2.342E-02);
- compare("\"%15.4e\"",-2.342E-02);
- compare("\"%16.4e\"",-2.342E-02);
- compare("\"%16.4e\"",-2.342E-22);
- compare("\"%G\"",-2.342E-02);
- compare("\"%G\"",3.1415e-6);
- compare("%016e", 3141.5);
- compare("%16e", 3141.5);
- compare("%-16e", 3141.5);
- compare("%010.3e", 3141.5);
-
- compare("*%5f*", 3.3);
- compare("*%5f*", 3.0);
- compare("*%5f*", .999999E-4);
- compare("*%5f*", .99E-3);
- compare("*%5f*", 3333.0);
-
- compare("*%5g*", 3.3);
- compare("*%5g*", 3.0);
- compare("*%5g*", .999999E-4);
- compare("*%5g*", .99E-3);
- compare("*%5g*", 3333.0);
- compare("*%5g*", 0.01);
-
- compare("*%5.g*", 3.3);
- compare("*%5.g*", 3.0);
- compare("*%5.g*", .999999E-4);
- compare("*%5.g*", 1.0E-4);
- compare("*%5.g*", .99E-3);
- compare("*%5.g*", 3333.0);
- compare("*%5.g*", 0.01);
-
- compare("*%5.2g*", 3.3);
- compare("*%5.2g*", 3.0);
- compare("*%5.2g*", .999999E-4);
- compare("*%5.2g*", .99E-3);
- compare("*%5.2g*", 3333.0);
- compare("*%5.2g*", 0.01);
-
- return 0;
-}
+++ /dev/null
-dnl
-dnl Configuration for trio
-dnl
-
-AC_INIT
-AC_CONFIG_SRCDIR([triodef.h])
-AC_PREREQ(2.55) dnl autoconf 2.55 was released in 2002
-
-AC_PROG_CC
-ifdef([AC_PROG_CC_STDC], [AC_PROG_CC_STDC])
-AC_LANG([C])
-
-AC_PROG_INSTALL
-AC_PROG_RANLIB
-
-dnl
-dnl Alpha floating-point compiler option.
-dnl
-
-AC_MSG_CHECKING(for IEEE compilation options)
-AC_CACHE_VAL(ac_cv_ieee_option, [
- AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[
- #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__))) && (defined(VMS) || defined(__VMS)))
- # error "Option needed"
- typedef int option_needed[-1];
- #endif
- ]]]),
- ac_cv_ieee_option="/IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE",
- AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[
- #if !(defined(__alpha) && (defined(__DECC) || defined(__DECCXX) || (defined(__osf__) && defined(__LANGUAGE_C__) && !defined(__GNUC__))) && !(defined(VMS) || defined(__VMS)) && !defined(_CFE))
- # error "Option needed"
- typedef int option_needed[-1];
- #endif
- ]]]),
- ac_cv_ieee_option="-ieee",
- AC_COMPILE_IFELSE(AC_LANG_PROGRAM(,[[[
- #if !(defined(__alpha) && (defined(__GNUC__) && (defined(__osf__) || defined(__linux__))))
- # error "Option needed"
- typedef int option_needed[-1];
- #endif
- ]]]),
- ac_cv_ieee_option="-mieee",
- ac_cv_ieee_option="none"
- )
- )
- )
-])
-AC_MSG_RESULT($ac_cv_ieee_option)
-if test $ac_cv_ieee_option != none; then
- CFLAGS="${CFLAGS} ${ac_cv_ieee_option}"
-fi
-
-AC_CONFIG_FILES([Makefile])
-AC_OUTPUT
+++ /dev/null
-/*************************************************************************
- *
- * $Id: doc.h,v 1.20 2006/08/18 11:32:08 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/**
-@mainpage
-
-@author Bjørn Reese
-@author Daniel Stenberg
-
-@section intro Introduction
-
-Trio is a fully matured and stable set of printf and string functions
-designed be used by applications with focus on portability or with the
-need for additional features that are not supported by standard stdio
-implementation.
-
-There are several cases where you may want to consider using trio:
-
-@li Portability across heterogeneous platforms.
-@li Embedded systems without stdio support.
-@li Extendability of unsupported features.
-@li Your native version does not do everything you need.
-
-When you write applications that must be portable to a wide range of
-platforms you often have to deal with inadequate implementations of the
-stdio library functions. Most notably is the lack of secure formatting
-functions, such as snprintf, or the lack of parameter reordering commonly
-used for the internationalization of applications, such as the <num>$
-modifier. Sometimes the feature you need is simply not present in stdio.
-So you end up spending much effort on determining which platforms supports
-what, and to write your own versions of various features. This is where
-trio can help you. Trio is a platform-independent implementation of the
-stdio printf and scanf functions and the string library functions.
-
-The functionality described in the stdio standards is a compromise, and
-does unfortunately not include a mechanism to extend the functionality for
-an individual application. Oftentimes an application has the need for an
-extra feature, and the application code can become much more clear and
-readable by using an extension mechanism. Trio supports a range of useful
-extensions such as user-defined specifiers, passing of arguments in arrays,
-localized string scanning, thousand-separators, and arbitrary integer bases.
-
-Trio fully implements the C99 (ISO/IEC 9899:1999) and UNIX98 (the Single
-Unix Specification, Version 2) standards, as well as many features from
-other implemenations, e.g. the GNU libc and BSD4.
-
-@section examples Examples
-
-@subsection ex1 Binary Numbers
-Output an integer as a binary number using a trio extension.
-@verbatim
- trio_printf("%..2i\n", number);
-@endverbatim
-
-@subsection ex2 Thousand-separator
-Output a number with thousand-separator using a trio extension.
-@verbatim
- trio_printf("%'f\n", 12345.6);
-@endverbatim
-The thousand-separator described by the locale is used.
-
-@subsection ex3 Fixed Length Array and Sticky Modifier
-Output an fixed length array of floating-point numbers.
-@verbatim
- double array[] = {1.0, 2.0, 3.0};
- printf("%.2f %.2f %.2f\n", array[0], array[1], array[2]);
-@endverbatim
-The same with two trio extensions (arguments are passed in an array, and
-the first formatting specifier sets the sticky option so we do not have
-to type all the formatting modifiers for the remaining formatting specifiers)
-@verbatim
- trio_printfv("%!.2f %f %f\n", array);
-@endverbatim
-Another, and more powerful, application of being able to pass arguments in
-an array is the creation of the printf/scanf statement at run-time, where
-the formatting string, and thus the argument list, is based on an external
-configuration file.
-
-@subsection ex4 Localized scanning
-Parse a string consisting of one or more upper-case alphabetic characters
-followed by one or more numeric characters.
-@verbatim
- sscanf(buffer, "%[A-Z]%[0-9]", alphabetic, numeric);
-@endverbatim
-The same but with locale using a trio extension.
-@verbatim
- trio_sscanf(buffer, "%[[:upper:]]%[[:digit:]]", alphabetic, numeric);
-@endverbatim
-
-@section legal Legal Issues
-Trio is distributed under the following license, which allows practically
-anybody to use it in almost any kind of software, including proprietary
-software, without difficulty.
-
-"Copyright (C) 1998-2001 Bjorn Reese and Daniel Stenberg.
-
-Permission to use, copy, modify, and distribute this software for any
-purpose with or without fee is hereby granted, provided that the above
-copyright notice and this permission notice appear in all copies.
-
-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. THE AUTHORS AND
-CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER."
-
-@section contribution Contribution
-
-@subsection contribute Contribute
-We appreciate any type of contribution, from ideas over improvements to
-error corrections.
-
-The project space contains references to bug and feature tracking,
-mailing-list, and the CVS repository. We prefer communication via the
-mailing-list, but do not require you to be subscribed, because trio is a
-small project.
-
-The project space is located at http://sourceforge.net/projects/ctrio/
-
-@subsection contributors Contributors
-We have received contributions from the following persons (in alphabetic
-order sorted by surname)
-
-@li Craig Berry
-@li Karl Bochert
-@li Stan Boehm
-@li David Byron
-@li Brian Chapman
-@li Robert Collins
-@li Danny Dulai
-@li Bob Friesenhahn
-@li Jon Foster
-@li John Fotheringham
-@li Markus Henke
-@li Ken Gibson
-@li Paul Janzen
-@li Patrick Jessee
-@li Richard Jinks
-@li Tero Jänkä
-@li Howard Kapustein
-@li Rune Enggaard Lausen
-@li Mehdi Lavasani
-@li Alexander Lukyanov
-@li Andreas Maus
-@li Mikey Menezes
-@li Emmanuel Mogenet
-@li Jacob Navia
-@li Jose Ortiz
-@li Joe Orton
-@li Gisli Ottarsson
-@li Mark Pickelmann
-@li Olli Savia
-@li Shaun Tancheff
-@li Marc Werwerft
-@li Igor Zlatkovic
-
-Please let us know, and accept our apology, if we have omitted anybody.
-
-*/
+++ /dev/null
-/*************************************************************************
- *
- * $Id: doc_dynamic.h,v 1.1 2001/12/27 17:29:20 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/** @addtogroup DynamicStrings Dynamic String Functions.
-Dynamic string functions.
-
-@b SYNOPSIS
-
-@verbatim
-cc ... -ltrio -lm
-
-#include <triostr.h>
-@endverbatim
-
-@b DESCRIPTION
-
-*/
+++ /dev/null
-/*************************************************************************
- *
- * $Id: doc_nan.h,v 1.1 2001/12/30 12:47:41 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/** @addtogroup SpecialQuantities Special Quantifies.
-Functions to detect and fabricate special quantities in floating-point
-numbers.
-
-@b SYNOPSIS
-
-@verbatim
-cc ... -ltrio -lm
-
-#include <trionan.h>
-@endverbatim
-
-@b DESCRIPTION
-
-Certain arithmetical operations does not result in normal numbers. Instead
-they result in special quantities that must be handled differently by the
-floating-point hardware. These includes Infinity and Not-A-Number (NaN).
-
-For example, 0/0 (zero divided by zero) yields NaN. Any operation which
-involves a NaN will result in NaN. Any comparison involving NaN will be
-unsuccessful, even if NaN is compared to NaN.
-
-These special quantities are represented with special bit patterns by the
-floating-point hardware, and this bit patterns depend on the hardware.
-There may even be hardware that does not support special quantities, so
-the functions in this module are not guaranteed to work on all platforms.
-
-The approach used in this module is to (in decreasing order of importance)
-@li Use C99 functionality when available.
-@li Use IEEE 754-1985 bit patterns if possible.
-@li Use platform-specific techniques.
-
-@b NOTES
-
-This module does not depend on the rest of trio, and can thus be reused
-separately. The following files are necessary:
-@li @c triodef.h
-@li @c trionan.h
-@li @c trionan.c
-
-*/
+++ /dev/null
-/*************************************************************************
- *
- * $Id: doc_printf.h,v 1.5 2008/10/12 12:09:51 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/** @addtogroup Printf Formatted Printing Functions.
-Variations of formatted printing functions.
-
-@b SYNOPSIS
-
-@verbatim
-cc ... -ltrio -lm
-
-#include <trio.h>
-@endverbatim
-
-@b DESCRIPTION
-
-This documentation is incomplete.
-The documentation of the printf family in [C99] and [UNIX98] also applies
-to the trio counterparts.
-
-All these functions outputs a string which is formatted according to the
-@p format string and the consecutive arguments. The @p format string is
-described in the Formatting section below.
-
-@ref trio_printf, @ref trio_vprintf, and @ref trio_printfv writes the
-output to the standard output stream (stdout).
-
-@ref trio_fprintf, @ref trio_vfprintf, and @ref trio_fprintfv writes the
-output to a given output stream.
-
-@ref trio_dprintf, @ref trio_vdprintf, and @ref trio_dprintfv writes the
-output to a file descriptor (this includes, for example, sockets).
-
-@ref trio_sprintf, @ref trio_vsprintf, and @ref trio_sprintfv writes the
-output into @p buffer.
-
-@ref trio_snprintf, @ref trio_vsnprintf, and @ref trio_snprintfv writes @p
-max - 1 characters into @p buffer followed by a terminating zero character.
-If @p max is 1, then @p buffer will be an empty string. If @p max is 0,
-then @p buffer is left untouched, and can consequently be NULL. The number
-of characters that would have been written to @p buffer, had there been
-sufficient space, is returned.
-
-@ref trio_snprintfcat appends the formatted text at the end of @p buffer.
-
-@ref trio_asprintf, @ref trio_vasprintf, and @ref trio_asprintfv allocates
-and returns an allocated string in @p buffer containing the formatted text.
-
-@b FORMATTING
-
-The @p format string can contain normal text and conversion indicators.
-The normal text can be any character except the nil character (\000 =
-'\0') and the percent character (\045 = '%'). Conversion indicators
-consists of an indication character (%), followed by zero or more conversion
-modifiers, and exactly one conversion specifier.
-
-@b Modifiers
-
-Some modifiers exhibit the same behaviour for all specifiers, other modifiers
-indicate different behaviours for different specifiers, and other modifiers
-are only applicable to certain specifiers. The relationship is described for
-each modifier. The number 9 is used to denotes an arbitrary integer.
-
-@em Positional ( @c 9$ ) [UNIX98]
-
-Normally the arguments supplied to these functions are interpreted
-incrementially from left to right. Arguments can be referenced specifically in
-the format string. The modifier n$ selects the nth argument. The first
-argument is referred as 1$. If this modifier is used, it must be the first
-modifier after the indication character. n$ can also be used for argument
-width, precision, and base.
-
-The performance penalty of using positionals is almost neglible (contrary to
-most other printf implementations).
-
-@li @em Reference @em Mix.
-Mixing normal and positional specifiers is allowed [TRIO]. For example,
-@verbatim
- trio_printf("%d %3$d %2$d\n", 1, 2, 3);
-@endverbatim
-results in
-@verbatim
- 1 3 2
-@endverbatim
-Arguments for the printf family are passed on the stack. On most platforms it
-is not possible to determine the size of individual stack elements, so it is
-essential that the format string corresponds exactly to the passed arguments.
-If this is not the case, incorrect values may be put into the result.
-
-@li @em Reference @em Gap.
-For the same reason it is also essential that the format string does not
-contain any "gaps" in the positional arguments. For example,
-@verbatim
- trio_printf("%1$d %3$d\n", 1, 2, 3);
-@endverbatim
-is NOT allowed. The format string parser has no knowledge about whether the
-second argument is, say, an integer or a long double (which have different
-sizes).
-@verbatim
-@endverbatim
-[UNIX98] describes this as unspecified behaviour. [TRIO] will detect reference
-gaps and return an error.
-
-@li @em Double @em Reference.
-It is also not allowed to reference an argument twice or more. For example,
-@verbatim
- trio_printf("%1$d %1$lf\n", 1);
-@endverbatim
-is NOT allowed, because it references the first argument as two differently
-sized objects.
-@verbatim
-@endverbatim
-[UNIX98] describes this as unspecified behaviour. [TRIO] will detect double
-references and return an error.
-
-The following two statements are equivalent
-@verbatim
- trio_printf("|%d %s\n|", 42, "meanings");
- |42 meanings|
-
- trio_printf("|%1$d %2$s|\n", 42, "meanings");
- |42 meanings|
-@endverbatim
-
-@em Width ( @c 9 )
-
-Specifies the minimum width of a field. If the fields has less characters than
-specified by the width, the field will be left adjusted and padded by spaces.
-The adjustment and padding can be changed by the Alignment ( @c - ) and
-Padding ( @c 0 ) modifiers.
-
-The width is specified as a number. If an asterix ( @c * ) is used instead, the
-width will be read from the argument list.
-
-Prefixes, such as 0x for hexadecimal integers, are part of width.
-@verbatim
- trio_printf("|%10i|\n", 42);
- | 42|
-@endverbatim
-
-@em Precision ( @c .9 )
-
-The precision has different semantics for the various data types.
-The precision specifies the maximum number of printed characters for strings,
-the number of digits after the decimal-point for floating-point numbers,
-the number of significant digits for the @c g (and @c G) representation of
-floating-point numbers, the minimum number of printed digits for integers.
-@verbatim
- trio_printf("|%10.8i|%.8i|\n", 42, 42);
- | 00000042|00000042|
-@endverbatim
-
-@em Base ( @c ..9 ) [TRIO]
-
-Sets the base that the associated integer must be converted to. The base can
-be between 2 and 36 (both included).
-@verbatim
- trio_printf("|%10.8.2i|%10..2i|%..2i|\n", 42, 42, 42);
- | 00101010| 101010|101010|
-
- trio_printf("|%*.8.*i|\n", 10, 2, 42);
- | 00101010|
-@endverbatim
-
-@em Padding ( @c 0 )
-
-Integer and floating point numbers are prepended by zeros. The number of
-leading zeros are determined by the precision. If precision is not present,
-width is used instead.
-
-@em Short ( @c h )
-
-Integer arguments are read as an ( @c unsigned ) @c short @c int. String
-and character arguments are read as @c char @c * and @c char respectively.
-
-@em Short @em short ( @c hh ) [C99, GNU]
-
-The argument is read as an ( @c unsigned ) @c char.
-
-@em Fixed @em Size ( @c I ) [MSVC]
-
-The argument is read as a fixed sized integer. The modifier is followed by
-a number, which specifies the number of bits in the integer, and can be one
-of the following
-
-@li @c I8
-@li @c I16
-@li @c I32
-@li @c I64 (if 64-bits integers are supported)
-
-Works only for integers (i, u, d, o, x, X)
-
-@em Largest ( @c j ) [C99]
-
-The argument is read as an @c intmax_t / @c uintmax_t, which is defined to
-be the largest signed/unsigned integer.
-
-@em Long ( @c l )
-
-An integral argument is read as an ( @c unsigned ) @c long @c int. A string
-argument is read as a @c wchar_t @c *, and output as a multi-byte character
-sequence.
-
-@em Long @em long ( @c ll ) [C99, UNIX98, GNU]
-
-The argument is read as an ( @c unsigned ) @c long @c long @c int.
-
-@em Long @em double ( @c L ) [C99, UNIX98, GNU]
-
-The argument is read as a @c long @c double.
-
-@em ptrdiff_t ( @c t ) [C99]
-
-The argument is read as a @c ptrdiff_t, which is defined to be the signed
-integer type of the result of subtracting two pointers.
-
-@em Quad ( @c q ) [BSD, GNU]
-
-Corresponds to the long long modifier ( @c ll ).
-
-@em Wide ( @c w ) [MISC]
-
-For a string argument this is equivalent to using the long modifier ( @c l ).
-
-@em size_t ( @c z ) [C99]
-
-The argument is read as a @c size_t, which is defined to be the type
-returned by the @c sizeof operator.
-
-@em size_t ( @c Z ) [GNU]
-
-Corresponds to the size_t modifier ( @c z ).
-
-@em Alternative ( @c # )
-
-Prepend radix indicator for hexadecimal, octal, and binary integer numbers
-and for pointers.
-Always add a decimal-point for floating-point numbers.
-Escape non-printable characters for strings.
-
-@em Spacing ( )
-
-Prepend leading spaces when necessary.
-
-@em Sign ( @c + )
-
-Always prepend a sign to numbers. Normally only the negative sign is prepended
-to a number. With this modifier the positive sign may also be prepended.
-
-@em Alignment ( @c - )
-
-The output will be left-justified in the field specified by the width.
-
-@em Argument ( @c * )
-
-Width, precision, or base is read from the argument list, rather than from
-the formatting string.
-
-@em Quote / @em Grouping ( @c ' ) [MISC]
-
-Groups integers and the integer-part of floating-point numbers according to
-the locale. Quote strings and characters.
-
-@em Sticky ( @c ! ) [TRIO]
-
-The modifiers listed for the current specifier will be reused by subsequent
-specifiers of the same group.
-The following specifier groups exists
-@li Integer ( @c i, @c u, @c d, @c o, @c x, @c X )
-@li Floating-point ( @c f, @c F, @c e, @c E, @c g, @c G, @c a, @c A )
-@li Character ( @c c )
-@li String ( @c s )
-@li Pointer ( @c p )
-@li Count ( @c n )
-@li Errno ( @c m )
-@li Group ( @c [] )
-
-The sticky modifiers are active until superseeded by other sticky modifiers,
-or the end of the format string is reached.
-Local modifiers overrides sticky modifiers for the given specifier only.
-@verbatim
- trio_printf("|%!08#x|%04x|%x|\n", 42, 42, 42);
- |0x00002a|0x2a|0x00002a|
-@endverbatim
-
-@b Specifiers
-
-@em Percent ( @c % )
-
-Produce a percent ( @c % ) character. This is used to quote the indication
-character. No modifiers are allowed.
-The full syntax is @c %%.
-@verbatim
- trio_printf("Percent is %%\n");
- Percent is %
-@endverbatim
-
-@em Hex @em floats ( @c a, @c A ) [C99]
-
-Output a hexadecimal (base 16) representation of a floating point number. The
-number is automatically preceeded by @c 0x ( or @c 0X ). The exponent is
-@c p ( or @c P ).
-@verbatim
- trio_printf("|%a|%A|\n", 3.1415, 3.1415e20);
- |0x3.228bc|0X3.228BCP+14|
-@endverbatim
-
-@em Binary @em numbers ( @c b, @c B ) [MISC - SCO UnixWare 7]
-
-DEPRECATED: Use Base modifier @c %..2i instead.
-
-@em Character ( @c c )
-
-Output a single character.
-
-@li Quote ( @c ' ) [TRIO].
-Quote the character.
-
-@em Decimal ( @c d )
-
-Output a decimal (base 10) representation of a number.
-
-@li Grouping ( @c ' ) [TRIO].
-The number is separated by the locale thousand separator.
-@verbatim
- trio_printf("|%'ld|\n", 1234567);
- |1,234,567|
-@endverbatim
-
-@em Floating-point ( @c e, @c E)
-
-Output a decimal floating-point number.
-The style is @c [-]9.99e[-]9, where
-@li @c [-]9.99 is the mantissa (as described for the @c f, @c F specifier), and
-@li @c e[-]9 is the exponent indicator (either @c e or @c E, depending on the
-floating-point specifier), followed by an optional sign and the exponent
-
-If the precision is wider than the maximum number of digits that can be
-represented by the floating-point unit, then the number will be adequately
-rounded. For example, assuming DBL_DIG is 15
-@verbatim
- trio_printf("|%.18e|\n", (1.0 / 3.0));
- |3.333333333333333000e-01|
-@endverbatim
-
-@em Floating-point ( @c f, @c F )
-
-Output a decimal floating-point number.
-The style is @c [-]9.99, where
-@li @c [-] is an optional sign (either @c + or @c -),
-@li @c 9 is the integer-part (possibly interspersed with thousand-separators),
-@li @c . is the decimal-point (depending on the locale), and
-@li @c 99 is the fractional-part.
-
-If more digits are needed to output the number, than can be represented with
-the accuracy of the floating-point unit, then the number will be adequately
-rounded. For example, assuming that DBL_DIG is 15
-@verbatim
- trio_printf("|%f|\n", (2.0 / 3.0) * 1E18);
- |666666666666666700.000000|
-@endverbatim
-
-The following modifiers holds a special meaning for this specifier
-@li Alternative ( @c # ) [C99].
-Add decimal point.
-@li Grouping ( @c ' ) [TRIO].
-Group integer part of number into thousands (according to locale).
-
-@em Floating-point ( @c g, @c G)
-
-Output a decimal floating-point representation of a number. The format of
-either the @c f, @c F specifier or the @c e, @c E specifier is used, whatever
-produces the shortest result.
-
-@em Integer ( @c i )
-
-Output a signed integer. Default base is 10.
-
-@em Errno ( @c m ) [GNU]
-
-@em Count ( @c n )
-
-Insert into the location pointed to by the argument, the number of octets
-written to the output so far.
-
-@em Octal ( @c o )
-
-Output an octal (base 8) representation of a number.
-
-@em Pointer ( @c p )
-
-Ouput the address of the argument. The address is printed as a hexadecimal
-number. If the argument is the NULL pointer the text @c (nil) will be used
-instead.
-@li Alternative ( @c # ) [TRIO].
-Prepend 0x
-
-@em String ( @c s, @c S )
-
-Output a string. The argument must point to a zero terminated string. If the
-argument is the NULL pointer the text @c (nil) will be used instead.
-@c S is equivalent to @c ls.
-@li Alternative ( @c # ) [TRIO].
-Escape non-printable characters.
-
-Non-printable characters are converted into C escapes, or hexadecimal numbers
-where no C escapes exists for the character. The C escapes, the hexadecimal
-number, and all backslashes are prepended by a backslash ( @c \ ).
-The supported C escapes are
-@li @c \a (\007) = alert
-@li @c \b (\010) = backspace
-@li @c \f (\014) = formfeed
-@li @c \n (\012) = newline
-@li @c \r (\015) = carriage return
-@li @c \t (\011) = horizontal tab
-@li @c \v (\013) = vertical tab
-
-@verbatim
- trio_printf("|One %s Three|One %'s Three|\n", "Two", "Two");
- |One Two Three|One "Two" Three|
-
- trio_printf("|Argument missing %s|\n", NULL);
- |Argument missing (nil)|
-
- trio_printf("|%#s|\n", "\007 \a.");
- |\a \a.|
-@endverbatim
-
-@em Unsigned ( @c u )
-
-Output an unsigned integer. Default base is 10.
-
-@em Hex ( @c x, @c X )
-
-Output a hexadecimal (base 16) representation of a number.
-
-@li Alternative ( @c # ).
-Preceed the number by @c 0x ( or @c 0X ). The two characters are counted
-as part of the width.
-
-@em User-defined ( @c <> )
-
-Invoke user-defined formatting.
-See @ref trio_register for further information.
-
-@b RETURN @b VALUES
-
-All functions returns the number of outputted characters. If an error occured
-then a negative error code is returned [TRIO]. Note that this is a deviation
-from the standard, which simply returns -1 (or EOF) and errno set
-appropriately.
-The error condition can be detected by checking whether the function returns
-a negative number or not, and the number can be parsed with the following
-macros. The error codes are primarily intended as debugging aide for the
-developer.
-
-@li TRIO_EINVAL: Invalid argument.
-@li TRIO_ETOOMANY: Too many arguments.
-@li TRIO_EDBLREF: Double argument reference.
-@li TRIO_EGAP: Argument reference gap.
-@li TRIO_ENOMEM: Out of memory.
-@li TRIO_ERANGE: Invalid range.
-@li TRIO_ERRNO: The error is specified by the errno variable.
-
-Example:
-@verbatim
- int rc;
-
- rc = trio_printf("%r\n", 42);
- if (rc < 0) {
- if (TRIO_ERROR_CODE(rc) != TRIO_EOF) {
- trio_printf("Error: %s at position %d\n",
- TRIO_ERROR_NAME(rc),
- TRIO_ERROR_POSITION(rc));
- }
- }
-@endverbatim
-
-@b SEE @b ALSO
-
-@e trio_scanf, @e trio_register.
-
-@b NOTES
-
-The printfv family uses an array rather than the stack to pass arguments.
-This means that @c short @c int and @c float values will not be handled by
-the default argument promotion in C. Instead, these values must be explicitly
-converted with the Short (h) modifier in both cases.
-
-Example:
-@verbatim
- void *array[2];
- float float_number = 42.0;
- short short_number = 42;
-
- array[0] = &float_number;
- array[1] = &short_number;
-
- trio_printfv("%hf %hd\n", array); /* CORRECT */
- trio_printfv("%f %d\n", array); /* WRONG */
-@endverbatim
-
-@b CONFORMING @b TO
-
-Throughout this document the following abbreviations have been used to
-indicate what standard a feature conforms to. If nothing else is indicated
-ANSI C (C89) is assumed.
-
-@li [C89] ANSI X3.159-1989
-@li [C99] ISO/IEC 9899:1999
-@li [UNIX98] The Single UNIX Specification, Version 2
-@li [BSD] 4.4BSD
-@li [GNU] GNU libc
-@li [MSVC] Microsoft Visual C
-@li [MISC] Other non-standard sources
-@li [TRIO] Extensions specific for this package
-
-*/
+++ /dev/null
-/*************************************************************************
- *
- * $Id: doc_register.h,v 1.3 2008/10/12 12:09:51 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/** @addtogroup UserDefined User-defined Formatted Printing Functions.
-Functions for using customized formatting specifiers.
-
-@b SYNOPSIS
-
-@verbatim
-cc ... -ltrio -lm
-
-#include <trio.h>
-#include <triop.h>
-@endverbatim
-
-@b DESCRIPTION
-
-This documentation is incomplete.
-
-@b User-defined @b Specifier
-
-The user-defined specifier consists of a start character (\074 = '<'), an
-optional namespace string followed by a namespace separator (\072 = ':'),
-a format string, an optional skipping separator (\174 = '|'), and an end
-character (\076 = '>').
-
-The namespace string can consist of alphanumeric characters, and is used to
-define a named reference (see below). The namespace is case-sensitive. If no
-namespace is specified, then we use an unnamed reference (see below).
-
-The format can consist of any character except the end character ('>'), the
-namespace separator (':'), the skipping separator ('|'), and the nil character
-(\000).
-
-Any modifier can be used together with the user-defined specifier.
-
-There are two formats for invoking a user-defined specifier. The first format
-is an extension of the normal printf/scanf formatting. It uses the percent
-character (\045 = '%') followed by optional qualifiers and a specifier. For
-example:
-
-@verbatim
- trio_printf("%<format>\n", my_handle, my_data);
-@endverbatim
-
-Some C compilers can issue a warning if there is a mismatch between specifiers
-and arguments. Unfortunately, these warnings does not work with the first
-format for user-defined specifiers. Therefore the second format has been
-introduced. The second format can only be applied to user-defined specifiers.
-
-The second format starts with a dollar character (\044 = '$') instead of the
-percent character, and is followed by optional qualifiers and the user-defined
-specifier. If the specifier contains a pipe character (\174 = '|'), then
-everything between the pipe character and the end character ('>') is ignored.
-The ignored part can be used to list the normal specifiers that the C compiler
-uses to determine mismatches. For example:
-
-@verbatim
- trio_printf("$<format|%p%p>\n", my_handle, my_data);
-@endverbatim
-
-@b Registering
-
-A user-defined specifier must be registered before it can be used.
-Unregistered user-defined specifiers are ignored. The @ref trio_register
-function is used to register a user-defined specifier. It takes two argument,
-a callback function and a namespace, and it returns a handle. The handle must
-be used to unregister the specifier later.
-
-The following example registers a user-define specifier with the "my_namespace"
-namespace:
-
-@verbatim
- my_handle = trio_register(my_callback, "my_namespace");
-@endverbatim
-
-There can only be one user-defined specifier with a given namespace. There
-can be an unlimited number (subject to maximum length of the namespace) of
-different user-defined specifiers.
-
-Passing NULL as the namespace argument results in an anonymous reference.
-There can be an unlimited number of anonymous references.
-
-@b REFERENCES
-
-There are two ways that a registered callback can be called. Either the
-user-defined specifier must contain the registered namespace in the format
-string, or the handle is passed as an argument to the formatted printing
-function.
-
-If the namespace is used, then a user-defined pointer must be passed as an
-argument:
-
-@verbatim
- trio_printf("%<my_namespace:format>\n", my_data);
-@endverbatim
-
-If the handle is used, then the user-defined specifier must not contain a
-namespace. Instead the handle must be passed as an argument, followed by a
-user-defined pointer:
-
-@verbatim
- trio_printf("%<format>\n", my_handle, my_data);
-@endverbatim
-
-The two examples above are equivalent.
-
-There must be exactly one user-defined pointer per user-defined specifier.
-This pointer can be used within the callback function with the
-@ref trio_get_argument getter function (see below).
-
-The format string is optional. It can be used within the callback function
-with the @ref trio_get_format getter function.
-
-@b Anonymous @b References
-Anonymous references are specified by passing NULL as the namespace.
-
-The handle must be passed as an argument followed by a user-defined pointer.
-No namespace can be specified.
-
-@verbatim
- anon_handle = trio_register(callback, NULL);
- trio_printf("%<format>\n", anon_handle, my_data);
-@endverbatim
-
-@b Restrictions
-
-@li The length of the namespace string cannot exceed 63 characters.
-@li The length of the user-defined format string cannot exceed 255 characters.
-@li User-defined formatting cannot re-define existing specifiers.
-This restriction was imposed because the existing formatting specifiers have
-a well-defined behaviour, and any re-definition would apply globally to an
-application (imagine a third-party library changing the behaviour of a
-specifier that is crusial to your application).
-
-@b CALLBACK @b FUNCTION
-
-The callback function will be called if a matching user-defined specifier
-is found within the formatting string. The callback function takes one input
-parameter, an opaque reference which is needed by the private functions. It
-returns an @c int, which is currently ignored. The prototype is
-
-@verbatim
- int (*trio_callback_t)(void *ref);
-@endverbatim
-
-See the Example section for full examples.
-
-@b PRINTING @b FUNCTIONS
-
-The following printing functions must only be used inside a callback function.
-These functions will print to the same output medium as the printf function
-which invoked the callback function. For example, if the user-defined
-specifier is used in an sprintf function, then these print functions will
-output their result to the same string.
-
-@b Elementary @b Printing
-
-There are a number of function to print elementary data types.
-
-@li @ref trio_print_int Print a signed integer. For example:
-@verbatim
- trio_print_int(42);
-@endverbatim
-@li @ref trio_print_uint Print an unsigned integer.
-@li @ref trio_print_double Print a floating-point number.
-@li @ref trio_print_string Print a string. For example:
-@verbatim
- trio_print_string("Hello World");
- trio_print_string(trio_get_format());
-@endverbatim
-@li @ref trio_print_pointer Print a pointer.
-
-@b Formatted @b Printing
-
-The functions @ref trio_print_ref, @ref trio_vprint_ref, and
-@ref trio_printv_ref outputs a formatted string just like its printf
-equivalents.
-
-@verbatim
- trio_print_ref(ref, "There are %d towels\n", 42);
- trio_print_ref(ref, "%<recursive>\n", recursive_writer, trio_get_argument(ref));
-@endverbatim
-
-@b GETTER @b AND @b SETTER @b FUNCTIONS
-
-The following getter and setter functions must only be used inside a callback
-function. They can either operate on the modifiers or on special data.
-
-@b Modifiers
-
-The value of a modifier, or a boolean indication of its presence or absence,
-can be found or set with the getter and setter functions.
-The generic prototypes of the these getter and setter functions are
-
-@verbatim
- int trio_get_???(void *ref);
- void trio_set_???(void *ref, int);
-@endverbatim
-
-where @c ??? refers to a modifier. For example, to get the width of the
-user-defined specifier use
-
-@verbatim
- int width = trio_get_width(ref);
-@endverbatim
-
-@b Special @b Data
-
-Consider the following user-defined specifier, in its two possible referencing
-presentations.
-
-@verbatim
- trio_printf("%<format>\n", namespace_writer, argument);
- trio_printf("%<namespace:format>\n", argument);
-@endverbatim
-
-@ref trio_get_format will get the @p format string, and
-@ref trio_get_argument} will get the @p argument parameter.
-There are no associated setter functions.
-
-@b EXAMPLES
-
-The following examples show various types of user-defined specifiers. Although
-each specifier is demonstrated in isolation, they can all co-exist within the
-same application.
-
-@b Time @b Example
-
-Print the time in the format "HOUR:MINUTE:SECOND" if "time" is specified inside
-the user-defined specifier.
-
-@verbatim
- static int time_print(void *ref)
- {
- const char *format;
- time_t *data;
- char buffer[256];
-
- format = trio_get_format(ref);
- if ((format) && (strcmp(format, "time") == 0)) {
- data = trio_get_argument(ref);
- if (data == NULL)
- return -1;
- strftime(buffer, sizeof(buffer), "%H:%M:%S", localtime(data));
- trio_print_string(ref, buffer);
- }
- return 0;
- }
-@endverbatim
-
-@verbatim
- int main(void)
- {
- void *handle;
- time_t now = time(NULL);
-
- handle = trio_register(time_print, "my_time");
-
- trio_printf("%<time>\n", handle, &now);
- trio_printf("%<my_time:time>\n", &now);
-
- trio_unregister(handle);
- return 0;
- }
-@endverbatim
-
-@b Complex @b Numbers @b Example
-
-Consider a complex number consisting of a real part, re, and an imaginary part,
-im.
-
-@verbatim
- struct Complex {
- double re;
- double im;
- };
-@endverbatim
-
-This example can print such a complex number in one of two formats.
-The default format is "re + i im". If the alternative modifier is used, then
-the format is "r exp(i theta)", where r is the length of the complex vector
-(re, im) and theta is its angle.
-
-@verbatim
- static int complex_print(void *ref)
- {
- struct Complex *data;
- const char *format;
-
- data = (struct Complex *)trio_get_argument(ref);
- if (data) {
- format = trio_get_format(ref);
-
- if (trio_get_alternative(ref)) {
- double r, theta;
-
- r = sqrt(pow(data->re, 2) + pow(data->im, 2));
- theta = acos(data->re / r);
- trio_print_ref(ref, "%#f exp(i %#f)", r, theta);
-
- } else {
- trio_print_ref(ref, "%#f + i %#f", data->re, data->im);
- }
- }
- return 0;
- }
-@endverbatim
-
-@verbatim
- int main(void)
- {
- void *handle;
-
- handle = trio_register(complex_print, "complex");
-
- /* Normal format. With handle and the with namespace */
- trio_printf("%<>\n", handle, &complex);
- trio_printf("%<complex:>\n", &complex);
- /* In exponential notation */
- trio_printf("%#<>\n", handle, &complex);
- trio_printf("%#<complex:unused data>\n", &complex);
-
- trio_unregister(handle);
- return 0;
- }
-@endverbatim
-
-@b RETURN @b VALUES
-
-@ref trio_register returns a handle, or NULL if an error occured.
-
-@b SEE @b ALSO
-
-@ref trio_printf
-
-@b NOTES
-
-User-defined specifiers, @ref trio_register, and @ref trio_unregister are
-not thread-safe. In multi-threaded applications they must be guarded by
-mutexes. Trio provides two special callback functions, called ":enter" and
-":leave", which are invoked every time a thread-unsafe operation is attempted.
-As the thread model is determined by the application, these callback functions
-must be implemented by the application.
-
-The following callback functions are for demonstration-purposes only.
-Replace their bodies with locking and unlocking of a mutex to achieve
-thread-safety.
-@verbatim
- static int enter_region(void *ref)
- {
- fprintf(stderr, "Enter Region\n");
- return 1;
- }
-
- static int leave_region(void *ref)
- {
- fprintf(stderr, "Leave Region\n");
- return 1;
- }
-@endverbatim
-These two callbacks must be registered before other callbacks are registered.
-@verbatim
- trio_register(enter_region, ":enter");
- trio_register(leave_region, ":leave");
-
- another_handle = trio_register(another_callback, NULL);
-@endverbatim
-
-*/
+++ /dev/null
-/*************************************************************************
- *
- * $Id: doc_scanf.h,v 1.1 2001/12/27 17:29:20 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/** @addtogroup Scanf Formatted Scanning Functions.
-Variations of formatted scanning functions.
-
-@b SYNOPSIS
-
-@verbatim
-cc ... -ltrio -lm
-
-#include <trio.h>
-@endverbatim
-
-@b DESCRIPTION
-
-This documentation is incomplete.
-The documentation of the scanf family in [C99] and [UNIX98] also applies
-to the trio counterparts.
-
-@b SCANNING
-
-The scanning is controlled by the format string.
-The format string can contain normal text and conversion indicators.
-The normal text can be any character except the nil character
-(\000) and the percent character (\045 = '\%').
-Conversion indicators consists of an indication character (%), followed by
-zero or more conversion modifiers, and exactly one conversion specifier.
-
-@b Modifiers
-
-@em Positional ( @c 9$ ) [UNIX98]
-
-See @ref trio_printf.
-
-@b Specifiers
-
-@em Percent ( @c % )
-
-@em Character ( @c c )
-
-@em Decimal ( @c d )
-
-@em Floating-point ( @c a, @c A, @c e, @c E, @c f, @c F, @c g, @c G )
-
-@em Integer ( @c i )
-
-@em Count ( @c n )
-
-@em Octal ( @c o )
-
-@em Pointer ( @c p )
-
-@em String ( @c s )
-
-@em Unsigned ( @c u )
-
-@em Hex ( @c x, @c X )
-
-@em Scanlist ( @c [] )
-
-Scanlist Exclusion (@c ^ )
-
-Scanlist Range ( @c - ) [TRIO]
-
-@li Only increasing ranges, i.e. @c [a-b], but not @c [b-a].
-@li Transitive ranges, ie. @c [a-b-c] equals @c [a-c].
-@li Trailing minus, ie. @c [a-] is interpreted as an @c a and a @c -.
-@li Duplicates are ignored.
-
-Scanlist Equivalence Class Expression ( @c [= @c =] ) [TRIO]
-
-Locale dependent (LC_COLLATE).
-Only one expression can appear inside the delimiters.
-@li @c [=a=] All letters in the same equivalence class as the letter @c a.
-@verbatim
- trio_scanf("%[[=a=]b]\n", buffer);
- trio_scanf("%[[=a=][=b=]]\n", buffer);
-@endverbatim
-
-Scanlist Character Class Expression ( @c [: @c :]) [TRIO]
-Locale dependent (LC_CTYPE).
-Only one expression can appear inside the delimiters.
-@li @c [:alnum:] Same as @c [:alpha:] and @c [:digit:]
-@li @c [:alpha:] Same as @c [:lower:] and @c [:upper:]
-@li @c [:cntrl:] Control characters
-@li @c [:digit:] Decimal digits
-@li @c [:graph:] Printable characters except space
-@li @c [:lower:] Lower case alphabetic letters
-@li @c [:print:] Printable characters
-@li @c [:punct:] Punctuation
-@li @c [:space:] Whitespace characters
-@li @c [:upper:] Upper case alphabetic letters
-@li @c [:xdigit:] Hexadecimal digits
-@verbatim
- trio_scanf("%[[:alnum:]]\n", buffer);
- trio_scanf("%[[:alpha:][:digit:]]\n", buffer);
-@endverbatim
-
-@b RETURN @b VALUES
-
-@b SEE @b ALSO
-
-@ref trio_printf
-
-*/
+++ /dev/null
-/*************************************************************************
- *
- * $Id: doc_static.h,v 1.1 2001/12/27 17:29:20 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/** @addtogroup StaticStrings Static String Functions.
-Replacements for the standard C string functions.
-
-@b SYNOPSIS
-
-@verbatim
-cc ... -ltrio -lm
-
-#include <triostr.h>
-@endverbatim
-
-@b DESCRIPTION
-
-This package renames, fixes, and extends the standard C string handling
-functions.
-
-@b Naming
-
-Renaming is done to provide more clear names, to provide a consistant naming
-and argument policy, and to hide portability issues.
-
-@li All functions starts with "trio_".
-@li Target is always the first argument, if present, except where the target
-is optional, such as @ref trio_to_double.
-@li Functions requiring a size for target includes "_max" in its name, and
-the size is always the second argument.
-@li Functions performing case-sensitive operations includes "_case" in its
-name.
-
-@b Fixing
-
-Fixing is done to avoid subtle error conditions.
-For example, @c strncpy does not terminate the result with a zero if the
-source string is bigger than the maximal length, so technically the result
-is not a C string anymore. @ref trio_copy_max makes sure that the result
-is zero terminated.
-
-@b Extending
-
-Extending is done to provide a richer set of fundamental functions.
-This includes functionality such as wildcard matching ( @c trio_match )
-and calculation of hash values ( @c trio_hash ).
-
-*/
+++ /dev/null
-<HR>
-<center class="copyright">Copyright (C) 2001 - 2006 Bjørn Reese and Daniel Stenberg.</center>
-</body>
-</html>
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
- <meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
- <title>TRIO</title>
- <link href="trio.css" rel="stylesheet" type="text/css">
-</head>
-<body>
+++ /dev/null
-# Doxyfile 1.2.12
-
-# This file describes the settings to be used by the documentation system
-# doxygen (www.doxygen.org) for a project
-#
-# All text after a hash (#) is considered a comment and will be ignored
-# The format is:
-# TAG = value [value, ...]
-# For lists items can also be appended using:
-# TAG += value [value, ...]
-# Values that contain spaces should be placed between quotes (" ")
-
-#---------------------------------------------------------------------------
-# General configuration options
-#---------------------------------------------------------------------------
-
-# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
-# by quotes) that should identify the project.
-
-PROJECT_NAME = TRIO
-
-# The PROJECT_NUMBER tag can be used to enter a project or revision number.
-# This could be handy for archiving the generated documentation or
-# if some version control system is used.
-
-PROJECT_NUMBER =
-
-# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
-# base path where the generated documentation will be put.
-# If a relative path is entered, it will be relative to the location
-# where doxygen was started. If left blank the current directory will be used.
-
-OUTPUT_DIRECTORY =
-
-# The OUTPUT_LANGUAGE tag is used to specify the language in which all
-# documentation generated by doxygen is written. Doxygen will use this
-# information to generate all constant output in the proper language.
-# The default language is English, other supported languages are:
-# Brazilian, Chinese, Croatian, Czech, Danish, Dutch, Finnish, French,
-# German, Hungarian, Italian, Japanese, Korean, Norwegian, Polish,
-# Portuguese, Romanian, Russian, Slovak, Slovene, Spanish and Swedish.
-
-OUTPUT_LANGUAGE = English
-
-# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
-# documentation are documented, even if no documentation was available.
-# Private class members and static file members will be hidden unless
-# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
-
-EXTRACT_ALL = NO
-
-# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
-# will be included in the documentation.
-
-EXTRACT_PRIVATE = NO
-
-# If the EXTRACT_STATIC tag is set to YES all static members of a file
-# will be included in the documentation.
-
-EXTRACT_STATIC = NO
-
-# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
-# undocumented members of documented classes, files or namespaces.
-# If set to NO (the default) these members will be included in the
-# various overviews, but no documentation section is generated.
-# This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_MEMBERS = YES
-
-# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
-# undocumented classes that are normally visible in the class hierarchy.
-# If set to NO (the default) these class will be included in the various
-# overviews. This option has no effect if EXTRACT_ALL is enabled.
-
-HIDE_UNDOC_CLASSES = YES
-
-# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
-# include brief member descriptions after the members that are listed in
-# the file and class documentation (similar to JavaDoc).
-# Set to NO to disable this.
-
-BRIEF_MEMBER_DESC = YES
-
-# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
-# the brief description of a member or function before the detailed description.
-# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
-# brief descriptions will be completely suppressed.
-
-REPEAT_BRIEF = YES
-
-# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
-# Doxygen will generate a detailed section even if there is only a brief
-# description.
-
-ALWAYS_DETAILED_SEC = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
-# path before files name in the file list and in the header files. If set
-# to NO the shortest path that makes the file name unique will be used.
-
-FULL_PATH_NAMES = NO
-
-# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
-# can be used to strip a user defined part of the path. Stripping is
-# only done if one of the specified strings matches the left-hand part of
-# the path. It is allowed to use relative paths in the argument list.
-
-STRIP_FROM_PATH =
-
-# The INTERNAL_DOCS tag determines if documentation
-# that is typed after a \internal command is included. If the tag is set
-# to NO (the default) then the documentation will be excluded.
-# Set it to YES to include the internal documentation.
-
-INTERNAL_DOCS = NO
-
-# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
-# doxygen to hide any special comment blocks from generated source code
-# fragments. Normal C and C++ comments will always remain visible.
-
-STRIP_CODE_COMMENTS = YES
-
-# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
-# file names in lower case letters. If set to YES upper case letters are also
-# allowed. This is useful if you have classes or files whose names only differ
-# in case and if your file system supports case sensitive file names. Windows
-# users are adviced to set this option to NO.
-
-CASE_SENSE_NAMES = NO
-
-# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
-# (but less readable) file names. This can be useful is your file systems
-# doesn't support long names like on DOS, Mac, or CD-ROM.
-
-SHORT_NAMES = NO
-
-# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
-# will show members with their full class and namespace scopes in the
-# documentation. If set to YES the scope will be hidden.
-
-HIDE_SCOPE_NAMES = NO
-
-# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
-# will generate a verbatim copy of the header file for each class for
-# which an include is specified. Set to NO to disable this.
-
-VERBATIM_HEADERS = NO
-
-# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
-# will put list of the files that are included by a file in the documentation
-# of that file.
-
-SHOW_INCLUDE_FILES = NO
-
-# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
-# will interpret the first line (until the first dot) of a JavaDoc-style
-# comment as the brief description. If set to NO, the JavaDoc
-# comments will behave just like the Qt-style comments (thus requiring an
-# explict @brief command for a brief description.
-
-JAVADOC_AUTOBRIEF = YES
-
-# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
-# member inherits the documentation from any documented member that it
-# reimplements.
-
-INHERIT_DOCS = YES
-
-# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
-# is inserted in the documentation for inline members.
-
-INLINE_INFO = YES
-
-# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
-# will sort the (detailed) documentation of file and class members
-# alphabetically by member name. If set to NO the members will appear in
-# declaration order.
-
-SORT_MEMBER_DOCS = YES
-
-# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
-# tag is set to YES, then doxygen will reuse the documentation of the first
-# member in the group (if any) for the other members of the group. By default
-# all members of a group must be documented explicitly.
-
-DISTRIBUTE_GROUP_DOC = NO
-
-# The TAB_SIZE tag can be used to set the number of spaces in a tab.
-# Doxygen uses this value to replace tabs by spaces in code fragments.
-
-TAB_SIZE = 8
-
-# The GENERATE_TODOLIST tag can be used to enable (YES) or
-# disable (NO) the todo list. This list is created by putting \todo
-# commands in the documentation.
-
-GENERATE_TODOLIST = YES
-
-# The GENERATE_TESTLIST tag can be used to enable (YES) or
-# disable (NO) the test list. This list is created by putting \test
-# commands in the documentation.
-
-GENERATE_TESTLIST = YES
-
-# The GENERATE_BUGLIST tag can be used to enable (YES) or
-# disable (NO) the bug list. This list is created by putting \bug
-# commands in the documentation.
-
-GENERATE_BUGLIST = YES
-
-# This tag can be used to specify a number of aliases that acts
-# as commands in the documentation. An alias has the form "name=value".
-# For example adding "sideeffect=\par Side Effects:\n" will allow you to
-# put the command \sideeffect (or @sideeffect) in the documentation, which
-# will result in a user defined paragraph with heading "Side Effects:".
-# You can put \n's in the value part of an alias to insert newlines.
-
-ALIASES =
-
-# The ENABLED_SECTIONS tag can be used to enable conditional
-# documentation sections, marked by \if sectionname ... \endif.
-
-ENABLED_SECTIONS =
-
-# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
-# the initial value of a variable or define consist of for it to appear in
-# the documentation. If the initializer consists of more lines than specified
-# here it will be hidden. Use a value of 0 to hide initializers completely.
-# The appearance of the initializer of individual variables and defines in the
-# documentation can be controlled using \showinitializer or \hideinitializer
-# command in the documentation regardless of this setting.
-
-MAX_INITIALIZER_LINES = 30
-
-# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
-# only. Doxygen will then generate output that is more tailored for C.
-# For instance some of the names that are used will be different. The list
-# of all members will be omitted, etc.
-
-OPTIMIZE_OUTPUT_FOR_C = YES
-
-# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
-# at the bottom of the documentation of classes and structs. If set to YES the
-# list will mention the files that were used to generate the documentation.
-
-SHOW_USED_FILES = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to warning and progress messages
-#---------------------------------------------------------------------------
-
-# The QUIET tag can be used to turn on/off the messages that are generated
-# by doxygen. Possible values are YES and NO. If left blank NO is used.
-
-QUIET = NO
-
-# The WARNINGS tag can be used to turn on/off the warning messages that are
-# generated by doxygen. Possible values are YES and NO. If left blank
-# NO is used.
-
-WARNINGS = YES
-
-# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
-# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
-# automatically be disabled.
-
-WARN_IF_UNDOCUMENTED = YES
-
-# The WARN_FORMAT tag determines the format of the warning messages that
-# doxygen can produce. The string should contain the $file, $line, and $text
-# tags, which will be replaced by the file and line number from which the
-# warning originated and the warning text.
-
-WARN_FORMAT =
-
-# The WARN_LOGFILE tag can be used to specify a file to which warning
-# and error messages should be written. If left blank the output is written
-# to stderr.
-
-WARN_LOGFILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the input files
-#---------------------------------------------------------------------------
-
-# The INPUT tag can be used to specify the files and/or directories that contain
-# documented source files. You may enter file names like "myfile.cpp" or
-# directories like "/usr/src/myproject". Separate the files or directories
-# with spaces.
-
-INPUT = . doc
-
-# If the value of the INPUT tag contains directories, you can use the
-# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank file matching one of the following patterns are included:
-# *.c *.cc *.cxx *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp
-# *.h++ *.idl
-
-FILE_PATTERNS = *.h *.c
-
-# The RECURSIVE tag can be used to turn specify whether or not subdirectories
-# should be searched for input files as well. Possible values are YES and NO.
-# If left blank NO is used.
-
-RECURSIVE = NO
-
-# The EXCLUDE tag can be used to specify files and/or directories that should
-# excluded from the INPUT source files. This way you can easily exclude a
-# subdirectory from a directory tree whose root is specified with the INPUT tag.
-
-EXCLUDE =
-
-# If the value of the INPUT tag contains directories, you can use the
-# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
-# certain files from those directories.
-
-EXCLUDE_PATTERNS =
-
-# The EXAMPLE_PATH tag can be used to specify one or more files or
-# directories that contain example code fragments that are included (see
-# the \include command).
-
-EXAMPLE_PATH = doc
-
-# If the value of the EXAMPLE_PATH tag contains directories, you can use the
-# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
-# and *.h) to filter out the source-files in the directories. If left
-# blank all files are included.
-
-EXAMPLE_PATTERNS =
-
-# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
-# searched for input files to be used with the \include or \dontinclude
-# commands irrespective of the value of the RECURSIVE tag.
-# Possible values are YES and NO. If left blank NO is used.
-
-EXAMPLE_RECURSIVE = NO
-
-# The IMAGE_PATH tag can be used to specify one or more files or
-# directories that contain image that are included in the documentation (see
-# the \image command).
-
-IMAGE_PATH =
-
-# The INPUT_FILTER tag can be used to specify a program that doxygen should
-# invoke to filter for each input file. Doxygen will invoke the filter program
-# by executing (via popen()) the command <filter> <input-file>, where <filter>
-# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
-# input file. Doxygen will then use the output that the filter program writes
-# to standard output.
-
-INPUT_FILTER =
-
-# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
-# INPUT_FILTER) will be used to filter the input files when producing source
-# files to browse.
-
-FILTER_SOURCE_FILES = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to source browsing
-#---------------------------------------------------------------------------
-
-# If the SOURCE_BROWSER tag is set to YES then a list of source files will
-# be generated. Documented entities will be cross-referenced with these sources.
-
-SOURCE_BROWSER = NO
-
-# Setting the INLINE_SOURCES tag to YES will include the body
-# of functions and classes directly in the documentation.
-
-INLINE_SOURCES = NO
-
-# If the REFERENCED_BY_RELATION tag is set to YES (the default)
-# then for each documented function all documented
-# functions referencing it will be listed.
-
-REFERENCED_BY_RELATION = YES
-
-# If the REFERENCES_RELATION tag is set to YES (the default)
-# then for each documented function all documented entities
-# called/used by that function will be listed.
-
-REFERENCES_RELATION = YES
-
-#---------------------------------------------------------------------------
-# configuration options related to the alphabetical class index
-#---------------------------------------------------------------------------
-
-# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
-# of all compounds will be generated. Enable this if the project
-# contains a lot of classes, structs, unions or interfaces.
-
-ALPHABETICAL_INDEX = NO
-
-# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
-# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
-# in which this list will be split (can be a number in the range [1..20])
-
-COLS_IN_ALPHA_INDEX = 5
-
-# In case all classes in a project start with a common prefix, all
-# classes will be put under the same header in the alphabetical index.
-# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
-# should be ignored while generating the index headers.
-
-IGNORE_PREFIX =
-
-#---------------------------------------------------------------------------
-# configuration options related to the HTML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
-# generate HTML output.
-
-GENERATE_HTML = YES
-
-# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `html' will be used as the default path.
-
-HTML_OUTPUT =
-
-# The HTML_HEADER tag can be used to specify a personal HTML header for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard header.
-
-HTML_HEADER = doc/header.html
-
-# The HTML_FOOTER tag can be used to specify a personal HTML footer for
-# each generated HTML page. If it is left blank doxygen will generate a
-# standard footer.
-
-HTML_FOOTER = doc/footer.html
-
-# The HTML_STYLESHEET tag can be used to specify a user defined cascading
-# style sheet that is used by each HTML page. It can be used to
-# fine-tune the look of the HTML output. If the tag is left blank doxygen
-# will generate a default style sheet
-
-HTML_STYLESHEET = doc/trio.css
-
-# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
-# files or namespaces will be aligned in HTML using tables. If set to
-# NO a bullet list will be used.
-
-HTML_ALIGN_MEMBERS = YES
-
-# If the GENERATE_HTMLHELP tag is set to YES, additional index files
-# will be generated that can be used as input for tools like the
-# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
-# of the generated HTML documentation.
-
-GENERATE_HTMLHELP = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
-# controls if a separate .chi index file is generated (YES) or that
-# it should be included in the master .chm file (NO).
-
-GENERATE_CHI = NO
-
-# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
-# controls whether a binary table of contents is generated (YES) or a
-# normal table of contents (NO) in the .chm file.
-
-BINARY_TOC = NO
-
-# The TOC_EXPAND flag can be set to YES to add extra items for group members
-# to the contents of the Html help documentation and to the tree view.
-
-TOC_EXPAND = NO
-
-# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
-# top of each HTML page. The value NO (the default) enables the index and
-# the value YES disables it.
-
-DISABLE_INDEX = NO
-
-# This tag can be used to set the number of enum values (range [1..20])
-# that doxygen will group on one line in the generated HTML documentation.
-
-ENUM_VALUES_PER_LINE = 4
-
-# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
-# generated containing a tree-like index structure (just like the one that
-# is generated for HTML Help). For this to work a browser that supports
-# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+,
-# or Internet explorer 4.0+). Note that for large projects the tree generation
-# can take a very long time. In such cases it is better to disable this feature.
-# Windows users are probably better off using the HTML help feature.
-
-GENERATE_TREEVIEW = NO
-
-# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
-# used to set the initial width (in pixels) of the frame in which the tree
-# is shown.
-
-TREEVIEW_WIDTH = 250
-
-#---------------------------------------------------------------------------
-# configuration options related to the LaTeX output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
-# generate Latex output.
-
-GENERATE_LATEX = NO
-
-# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `latex' will be used as the default path.
-
-LATEX_OUTPUT =
-
-# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
-# LaTeX documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_LATEX = NO
-
-# The PAPER_TYPE tag can be used to set the paper type that is used
-# by the printer. Possible values are: a4, a4wide, letter, legal and
-# executive. If left blank a4wide will be used.
-
-PAPER_TYPE = a4wide
-
-# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
-# packages that should be included in the LaTeX output.
-
-EXTRA_PACKAGES =
-
-# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
-# the generated latex document. The header should contain everything until
-# the first chapter. If it is left blank doxygen will generate a
-# standard header. Notice: only use this tag if you know what you are doing!
-
-LATEX_HEADER =
-
-# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
-# is prepared for conversion to pdf (using ps2pdf). The pdf file will
-# contain links (just like the HTML output) instead of page references
-# This makes the output suitable for online browsing using a pdf viewer.
-
-PDF_HYPERLINKS = NO
-
-# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
-# plain latex in the generated Makefile. Set this option to YES to get a
-# higher quality PDF documentation.
-
-USE_PDFLATEX = NO
-
-# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
-# command to the generated LaTeX files. This will instruct LaTeX to keep
-# running if errors occur, instead of asking the user for help.
-# This option is also used when generating formulas in HTML.
-
-LATEX_BATCHMODE = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the RTF output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
-# The RTF output is optimised for Word 97 and may not look very pretty with
-# other RTF readers or editors.
-
-GENERATE_RTF = NO
-
-# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `rtf' will be used as the default path.
-
-RTF_OUTPUT =
-
-# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
-# RTF documents. This may be useful for small projects and may help to
-# save some trees in general.
-
-COMPACT_RTF = NO
-
-# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
-# will contain hyperlink fields. The RTF file will
-# contain links (just like the HTML output) instead of page references.
-# This makes the output suitable for online browsing using WORD or other
-# programs which support those fields.
-# Note: wordpad (write) and others do not support links.
-
-RTF_HYPERLINKS = NO
-
-# Load stylesheet definitions from file. Syntax is similar to doxygen's
-# config file, i.e. a series of assigments. You only have to provide
-# replacements, missing definitions are set to their default value.
-
-RTF_STYLESHEET_FILE =
-
-# Set optional variables used in the generation of an rtf document.
-# Syntax is similar to doxygen's config file.
-
-RTF_EXTENSIONS_FILE =
-
-#---------------------------------------------------------------------------
-# configuration options related to the man page output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
-# generate man pages
-
-GENERATE_MAN = NO
-
-# The MAN_OUTPUT tag is used to specify where the man pages will be put.
-# If a relative path is entered the value of OUTPUT_DIRECTORY will be
-# put in front of it. If left blank `man' will be used as the default path.
-
-MAN_OUTPUT =
-
-# The MAN_EXTENSION tag determines the extension that is added to
-# the generated man pages (default is the subroutine's section .3)
-
-MAN_EXTENSION =
-
-# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
-# then it will generate one additional man file for each entity
-# documented in the real man page(s). These additional files
-# only source the real man page, but without them the man command
-# would be unable to find the correct page. The default is NO.
-
-MAN_LINKS = NO
-
-#---------------------------------------------------------------------------
-# configuration options related to the XML output
-#---------------------------------------------------------------------------
-
-# If the GENERATE_XML tag is set to YES Doxygen will
-# generate an XML file that captures the structure of
-# the code including all documentation. Note that this
-# feature is still experimental and incomplete at the
-# moment.
-
-GENERATE_XML = NO
-
-#---------------------------------------------------------------------------
-# Configuration options related to the preprocessor
-#---------------------------------------------------------------------------
-
-# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
-# evaluate all C-preprocessor directives found in the sources and include
-# files.
-
-ENABLE_PREPROCESSING = YES
-
-# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
-# names in the source code. If set to NO (the default) only conditional
-# compilation will be performed. Macro expansion can be done in a controlled
-# way by setting EXPAND_ONLY_PREDEF to YES.
-
-MACRO_EXPANSION = YES
-
-# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
-# then the macro expansion is limited to the macros specified with the
-# PREDEFINED and EXPAND_AS_PREDEFINED tags.
-
-EXPAND_ONLY_PREDEF = YES
-
-# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
-# in the INCLUDE_PATH (see below) will be search if a #include is found.
-
-SEARCH_INCLUDES = YES
-
-# The INCLUDE_PATH tag can be used to specify one or more directories that
-# contain include files that are not input files but should be processed by
-# the preprocessor.
-
-INCLUDE_PATH =
-
-# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
-# patterns (like *.h and *.hpp) to filter out the header-files in the
-# directories. If left blank, the patterns specified with FILE_PATTERNS will
-# be used.
-
-INCLUDE_FILE_PATTERNS =
-
-# The PREDEFINED tag can be used to specify one or more macro names that
-# are defined before the preprocessor is started (similar to the -D option of
-# gcc). The argument of the tag is a list of macros of the form: name
-# or name=definition (no spaces). If the definition and the = are
-# omitted =1 is assumed.
-
-PREDEFINED = __STDC__=1 TRIO_DOCUMENTATION= TRIO_PUBLIC= TRIO_PRIVATE=static TRIO_CONST=const TRIO_VOLATILE=volatile TRIO_SIGNED=signed TRIO_INLINE=inline TRIO_NOARGS=void TRIO_ARGS1(z,a)=(a) TRIO_ARGS2(z,a,b)=(a,b) TRIO_ARGS3(z,a,b,c)=(a,b,c) TRIO_ARGS4(z,a,b,c,d)=(a,b,c,d) TRIO_ARGS5(z,a,b,c,d,e)=(a,b,c,d,e) TRIO_ARGS6(z,a,b,c,d,e,f)=(a,b,c,d,e,f) TRIO_VARGS2(z,a,b)=(a,b) TRIO_VARGS3(z,a,b,c)=(a,b,c) TRIO_VARGS4(z,a,b,c,d)=(a,b,c,d) TRIO_VARGS5(z,a,b,c,d,e)=(a,b,c,d,e)
-
-# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
-# this tag can be used to specify a list of macro names that should be expanded.
-# The macro definition that is found in the sources will be used.
-# Use the PREDEFINED tag if you want to use a different macro definition.
-
-EXPAND_AS_DEFINED =
-
-# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
-# doxygen's preprocessor will remove all function-like macros that are alone
-# on a line and do not end with a semicolon. Such function macros are typically
-# used for boiler-plate code, and will confuse the parser if not removed.
-
-SKIP_FUNCTION_MACROS = YES
-
-#---------------------------------------------------------------------------
-# Configuration::addtions related to external references
-#---------------------------------------------------------------------------
-
-# The TAGFILES tag can be used to specify one or more tagfiles.
-
-TAGFILES =
-
-# When a file name is specified after GENERATE_TAGFILE, doxygen will create
-# a tag file that is based on the input files it reads.
-
-GENERATE_TAGFILE =
-
-# If the ALLEXTERNALS tag is set to YES all external classes will be listed
-# in the class index. If set to NO only the inherited external classes
-# will be listed.
-
-ALLEXTERNALS = NO
-
-# The PERL_PATH should be the absolute path and name of the perl script
-# interpreter (i.e. the result of `which perl').
-
-PERL_PATH =
-
-#---------------------------------------------------------------------------
-# Configuration options related to the dot tool
-#---------------------------------------------------------------------------
-
-# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
-# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or
-# super classes. Setting the tag to NO turns the diagrams off. Note that this
-# option is superceded by the HAVE_DOT option below. This is only a fallback. It is
-# recommended to install and use dot, since it yield more powerful graphs.
-
-CLASS_DIAGRAMS = YES
-
-# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
-# available from the path. This tool is part of Graphviz, a graph visualization
-# toolkit from AT&T and Lucent Bell Labs. The other options in this section
-# have no effect if this option is set to NO (the default)
-
-HAVE_DOT = NO
-
-# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect inheritance relations. Setting this tag to YES will force the
-# the CLASS_DIAGRAMS tag to NO.
-
-CLASS_GRAPH = YES
-
-# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
-# will generate a graph for each documented class showing the direct and
-# indirect implementation dependencies (inheritance, containment, and
-# class references variables) of the class with other documented classes.
-
-COLLABORATION_GRAPH = YES
-
-# If set to YES, the inheritance and collaboration graphs will show the
-# relations between templates and their instances.
-
-TEMPLATE_RELATIONS = YES
-
-# If set to YES, the inheritance and collaboration graphs will hide
-# inheritance and usage relations if the target is undocumented
-# or is not a class.
-
-HIDE_UNDOC_RELATIONS = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
-# tags are set to YES then doxygen will generate a graph for each documented
-# file showing the direct and indirect include dependencies of the file with
-# other documented files.
-
-INCLUDE_GRAPH = YES
-
-# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
-# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
-# documented header file showing the documented files that directly or
-# indirectly include this file.
-
-INCLUDED_BY_GRAPH = YES
-
-# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
-# will graphical hierarchy of all classes instead of a textual one.
-
-GRAPHICAL_HIERARCHY = YES
-
-# The tag DOT_PATH can be used to specify the path where the dot tool can be
-# found. If left blank, it is assumed the dot tool can be found on the path.
-
-DOT_PATH =
-
-# The DOTFILE_DIRS tag can be used to specify one or more directories that
-# contain dot files that are included in the documentation (see the
-# \dotfile command).
-
-DOTFILE_DIRS =
-
-# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_WIDTH = 1024
-
-# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
-# (in pixels) of the graphs generated by dot. If a graph becomes larger than
-# this value, doxygen will try to truncate the graph, so that it fits within
-# the specified constraint. Beware that most browsers cannot cope with very
-# large images.
-
-MAX_DOT_GRAPH_HEIGHT = 1024
-
-# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
-# generate a legend page explaining the meaning of the various boxes and
-# arrows in the dot generated graphs.
-
-GENERATE_LEGEND = YES
-
-# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
-# remove the intermedate dot files that are used to generate
-# the various graphs.
-
-DOT_CLEANUP = YES
-
-#---------------------------------------------------------------------------
-# Configuration::addtions related to the search engine
-#---------------------------------------------------------------------------
-
-# The SEARCHENGINE tag specifies whether or not a search engine should be
-# used. If set to NO the values of all tags below this one will be ignored.
-
-SEARCHENGINE = NO
-
-# The CGI_NAME tag should be the name of the CGI script that
-# starts the search engine (doxysearch) with the correct parameters.
-# A script with this name will be generated by doxygen.
-
-CGI_NAME =
-
-# The CGI_URL tag should be the absolute URL to the directory where the
-# cgi binaries are located. See the documentation of your http daemon for
-# details.
-
-CGI_URL =
-
-# The DOC_URL tag should be the absolute URL to the directory where the
-# documentation is located. If left blank the absolute path to the
-# documentation, with file:// prepended to it, will be used.
-
-DOC_URL =
-
-# The DOC_ABSPATH tag should be the absolute path to the directory where the
-# documentation is located. If left blank the directory on the local machine
-# will be used.
-
-DOC_ABSPATH =
-
-# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
-# is installed.
-
-BIN_ABSPATH =
-
-# The EXT_DOC_PATHS tag can be used to specify one or more paths to
-# documentation generated for other projects. This allows doxysearch to search
-# the documentation for these projects as well.
-
-EXT_DOC_PATHS =
+++ /dev/null
-/* HTML tags */
-
-BODY {
- background-color: white;
- color: darkblue;
-}
-
-TD { color: darkblue; }
-
-H1 { text-align: center; }
-
-H3 { font-style: italic; }
-
-HR {
- width: 85%;
- align: center;
-}
-
-.copyright { color: darkblue; }
-
-/* Links */
-
-:link { color: blue; }
-
-:visited { color: purple; }
-
-:active { color: red; }
-
-.el:link { font-style: italic; }
-
-/* Examples */
-
-DIV.fragment {
- color: maroon;
-}
+++ /dev/null
-/*************************************************************************
- * For testing purposes
- */
-
-#include <stdarg.h>
-#include <limits.h>
-#include <math.h>
-#include <unistd.h>
-/* #include <nan.h> */
-#include <wchar.h>
-#include "strio.h"
-#include "trio.h"
-#undef printf
-
-#if !defined(USE_LONGLONG)
-# if defined(__GNUC__) && !defined(__STRICT_ANSI__)
-# define USE_LONGLONG
-# elif defined(__SUNPRO_C)
-# define USE_LONGLONG
-# endif
-#endif
-
-#if defined(USE_LONGLONG)
-# define LONGLONG long long
-#else
-# define LONGLONG long
-#endif
-
-#if defined(TRIO_C99)
-# define LONGEST intmax_t
-#else
-# define LONGEST LONGLONG
-#endif
-
-static const char rcsid[] = "@(#)$Id: example.c,v 1.9 2001/11/25 13:47:38 breese Exp $";
-
-/*************************************************************************
- *
- */
-void Dump(char *buffer, int rc)
-{
- if (rc < 0)
- {
- printf("Err = %d (%s), Pos = %d\n",
- TRIO_ERROR_CODE(rc),
- TRIO_ERROR_NAME(rc),
- TRIO_ERROR_POSITION(rc));
- }
- else
- printf("buffer[% 3d] = \"%s\"\n", rc, buffer);
-}
-
-/*************************************************************************
- *
- */
-int main(void)
-{
- char buffer[512];
- int rc;
- LONGLONG int dummy;
- char *fool;
- int num;
- int num2;
- int count;
- double dnum;
- char *end;
- char text[256];
- char ch;
- int nerrors = 0;
- void *p1;
- char *p2;
-
- printf("%s\n", rcsid);
-
-/* printf("%d %u %d %u\n", */
-/* INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
-/* trio_printf("%d %u %d %u\n", */
-/* INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
-/* printf("%d %u\n", INT_MIN, INT_MIN); */
-/* trio_printf("%d %u\n", INT_MIN, INT_MIN); */
-
-/* printf("%ld %lu %ld %lu\n", */
-/* INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
-/* trio_printf("%ld %lu %ld %lu\n", */
-/* INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
-/* printf("%ld %lu\n", INT_MIN, INT_MIN); */
-/* trio_printf("%ld %lu\n", INT_MIN, INT_MIN); */
-
-/* printf("%lld %llu %lld %llu\n", */
-/* INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
-/* trio_printf("%lld %llu %lld %llu\n", */
-/* INT_MAX, INT_MAX, UINT_MAX, UINT_MAX); */
-/* printf("%lld %llu\n", INT_MIN, INT_MIN); */
-/* trio_printf("%lld %llu\n", INT_MIN, INT_MIN); */
-
-/* return 0; */
-
-
-/* dnum = StrToDouble("3.14e+44", (const char **)&end); */
-/* printf("double = %e (%s)\n", dnum, end); */
-/* dnum = StrToDouble("0xA3.14p44", (const char **)&end); */
-/* printf("double = %e (%s)\n", dnum, end); */
-
- /* trio_printf("%.*stext\n", 0, "-----"); */ /* fails */
-
-/* trio_printf("%Zd\n", (size_t)sizeof(char)); */
-
-/* rc = StrFormat(buffer, "%a", 3.14e+44); */
-/* Dump(buffer, rc); */
-
- /* rc = StrFormat(buffer, "Filled string: %-16<fill=_>s", "test"); */
-
-/* errno = EINTR; */
-/* rc = StrFormat(buffer, "Error: %m"); */
-
-/* rc = StrFormat(buffer, "Count %lln", &dummy); */
-/* printf("dummy = %lld\n", dummy); */
-
-/* rc = StrFormat(buffer, "Char %<quote='>c", 'X'); */
-
-/* rc = StrFormatMax(buffer, 20, "Here goes %-20<adjust=_>s", "test"); */
-
-/* rc = StrFormat(buffer, "Hex-float %a", 3.1415); */
-/* Dump(buffer, rc); */
-/* rc = StrFormat(buffer, "Hex-float %A", 3.1415e20); */
-/* Dump(buffer, rc); */
-/* rc = StrFormat(buffer, "Double %#g", 3.1415e20); */
-/* Dump(buffer, rc); */
-/* rc = StrFormat(buffer, "Double %.3f", 3.1415); */
-/* Dump(buffer, rc); */
-/* rc = StrFormat(buffer, "Double %+e", 3.1415); */
-/* Dump(buffer, rc); */
-
-/* printf("'%.2f'\n", 99.99999); */
-/* trio_printf("'%.2f'\n", 99.99999); */
-/* printf("'%f'\n", 0.0); */
-/* trio_printf("'%f'\n", 0.0); */
-/* printf("'%f'\n", 3141.0); */
-/* trio_printf("'%f'\n", 3141.0); */
-/* printf("'%#f'\n", 3141.0); */
-/* trio_printf("'%#f'\n", 3141.0); */
-/* printf("'%'f'\n", 31415.2); */
-/* trio_printf("'%'f'\n", 31415.2); */
-/* printf("'%-16e'\n", 3141.5); */
-/* trio_printf("'%-16e'\n", 3141.5); */
-/* printf("'%#f'\n", 3141.0); */
-/* trio_printf("'%#f'\n", 3141.0); */
-/* printf("'%f'\n", 3141.5); */
-/* trio_printf("'%f'\n", 3141.5); */
-/* printf("'%#.6g'\n", 3141.5); */
-/* trio_printf("'%#.6g'\n", 3141.5); */
-
-/* printf("'%20e'\n", 314.5); */
-/* trio_printf("'%20e'\n", 314.5); */
-
-/* printf("'%-16e'\n", 3141.5); */
-/* trio_printf("'%-16e'\n", 3141.5); */
-
-/* printf("'%#.4g'\n", 314151.5); */
-/* trio_printf("'%#.4g'\n", 314151.5); */
-
-/* printf("'%#.4g'\n", 0.0); */
-/* trio_printf("'%#.4g'\n", 0.0); */
-
-/* printf("'%#.4g'\n", 11.0); */
-/* trio_printf("'%#.4g'\n", 11.0); */
-
-/* printf("%f\n", HUGE_VAL); */
-/* trio_printf("%f\n", HUGE_VAL); */
-/* printf("%f\n", -HUGE_VAL); */
-/* trio_printf("%f\n", -HUGE_VAL); */
-/* #define NAN (cos(HUGE_VAL)) */
-/* printf("%f\n", NAN); */
-/* trio_printf("%f\n", NAN); */
-
-/* printf("'%+06d'\n", 1234); */
-/* trio_printf("'%+06d'\n", 1234); */
-/* printf("'%-#6.3x'\n", 12); */
-/* trio_printf("'%-#06.3x'\n", 12); */
-/* printf("'%+6d'\n", 1234); */
-/* trio_printf("'%+6d'\n", 1234); */
-/* printf("'%-08d'\n", 12); */
-/* trio_printf("'%-08d'\n", 12); */
-/* printf("'%08.6d'\n", 12); */
-/* trio_printf("'%08.6d'\n", 12); */
-/* printf("'%4d'\n", 123456); */
-/* trio_printf("'%4d'\n", 123456); */
-/* printf("'%.4d'\n", 12); */
-/* trio_printf("'%.4d'\n", 12); */
-
-/* trio_printf("%!#08x %04x %..10x\n", 42, 42, 42); */
-/* trio_printf("%*.*.*i\n", 8, 4, 2, 23); */
-/* trio_printf("%8.4.2i %<base=2>08i %.8.2i %..2i\n", 23, 23, 23, 23); */
-
-/* trio_printf("%8i\n", 42); */
-/* trio_printf("%.7i\n", 42); */
-/* trio_printf("%..2i\n", 42); */
-/* trio_printf("%8.7i\n", 42); */
-/* trio_printf("%8..2i\n", 42); */
-/* trio_printf("%8.7.2i\n", 42); */
-/* trio_printf("%*.*.*i\n", 8, 7, 2, 42); */
-
-/* { */
-/* LONGLONG ll = 1234567890; */
-/* rc = trio_printf("%&i %d\n", sizeof(ll), ll, 42); */
-/* Dump(buffer, rc); */
-/* } */
-/* { */
-/* char ch = 12; */
-/* rc = trio_printf("%&i %d\n", sizeof(ch), ch, 42); */
-/* Dump(buffer, rc); */
-/* } */
-/* { */
-/* pid_t pid = 99; */
-/* rc = trio_printf("%&i %d\n", sizeof(pid), pid, 42); */
-/* Dump(buffer, rc); */
-/* } */
-
-/* rc = trio_printf("%*.*.*i\n", 6, 4, 10, 12); */
-/* Dump(buffer, rc); */
-/* rc = trio_printf("%1$0*3$.*2$d\n", 3141, 6, 10); */
-/* Dump(buffer, rc); */
-
-/* rc = trio_asprintf(&end, "%s%n", "0123456789", &num); */
-/* printf("%d %d '%s'\n", rc, num, end); */
-/* if (end) */
-/* free(end); */
-
-/* trio_printf("%016e\n", 3141.5); */
-/* trio_printf("%'f\n", 424242.42); */
-/* trio_printf("%#.4f\n", 0.0); */
-/* trio_printf("%'d\n", 424242); */
-
-/* rc = trio_sprintf(buffer, "%4$d %3$*8$d %2$.*7$d %1$*6$.*5$d\n", */
-/* 123, */
-/* 1234, */
-/* 12345, */
-/* 123456, */
-/* 5, 6, 7, 8 */
-/* ); */
-/* Dump(buffer, rc); */
-/* rc = trio_sprintf(buffer, "%2$s %1$#s", "111", "222"); */
-/* Dump(buffer, rc); */
-
-/* trio_printf(" %x %!#x %g %09x %x\n", 123456, 123456, 123456.0, 123456, 123456); */
-/* trio_printf("%!'i %f %i\n", 12345, 12345.0, 12345); */
-/* trio_printf("%!<base=2>i %i\n", 23, 23); */
-
-/* rc = trio_sprintf(buffer, "%I32d", 12345); */
-/* Dump(buffer, rc); */
-/* rc = trio_sprintf(buffer, "%I32I8d", 12345); */
-/* Dump(buffer, rc); */
-
-/* rc = trio_sprintf(buffer, "*%5f*", 3.3); */
-/* Dump(buffer, rc); */
-
-/* { */
-/* wchar_t *wstring = L"some data"; */
-/* wchar_t wbuffer[512]; */
-
-/* rc = trio_sprintf(buffer, "%ls", wstring); */
-/* Dump(buffer, rc); */
-
-/* rc = trio_sscanf(buffer, "%ls", wbuffer); */
-/* Dump(buffer, rc); */
-/* rc = trio_sprintf(buffer, "%ls", wbuffer); */
-/* Dump(buffer, rc); */
-/* } */
-
- /* rc = StrFormat(buffer, "\040-\040\040-\n"); */
-
-/* rc = StrFormat(buffer, "%.*s@%s", 3, "Daniel", "Fool"); */
-/* rc = StrFormatAppendMax(buffer, 512, " %s is a doh", "Simpson"); */
-
-/* rc = StrFormat(buffer, "hello %1$d %1$d", 31, 32); */
-/* Dump(buffer, rc); */
-/* rc = StrFormat(buffer, "%2$d %3$d", 31, 32, 33); */
-/* Dump(buffer, rc); */
-
-/* rc = trio_sprintf(buffer, "%d say %g hey %s", 42, 3.14, "text"); */
-/* Dump(buffer, rc); */
-/* trio_sscanf(buffer, "%d %*s %e hey %s", &num, &dnum, text); */
-/* printf("num = %d, dnum = %e, text = \"%s\"\n", num, dnum, text); */
-
-/* rc = trio_sprintf(buffer, "%g", HUGE_VAL); */
-/* Dump(buffer, rc); */
-/* trio_sscanf(buffer, "%f", &dnum); */
-/* printf("dnum = %e\n", dnum); */
-
-/* rc = trio_sprintf(buffer, "%g", -HUGE_VAL); */
-/* Dump(buffer, rc); */
-/* trio_sscanf(buffer, "%f", &dnum); */
-/* printf("dnum = %e\n", dnum); */
-
-/* #if defined(NAN) */
-/* rc = trio_sprintf(buffer, "%g", NAN); */
-/* Dump(buffer, rc); */
-/* if ((rc = trio_sscanf(buffer, "%f", &dnum)) < 0) */
-/* Dump(buffer, rc); */
-/* else */
-/* printf("dnum = %e\n", dnum); */
-/* #endif */
-
-/* rc = trio_sprintf(buffer, "%*d", 6, 1234); */
-/* Dump(buffer, rc); */
-
-/* rc = trio_sprintf(buffer, "'%!08.6d' '%!d' '%d'", 4, 6, 8); */
-/* Dump(buffer, rc); */
-
-/* rc = trio_sprintf(buffer, "%0g", 0.123); */
-/* Dump(buffer, rc); */
-
-/* { */
-/* void *argarray[4]; */
-/* int value = 42; */
-/* double number = 123.456; */
-/* float small_number = 123.456; */
-
-/* argarray[0] = &value; */
-/* argarray[1] = "my string"; */
-/* rc = trio_sprintfv(buffer, "%d %s", argarray); */
-/* Dump(buffer, rc); */
-/* rc = trio_snprintfv(buffer, 8, "%d %s", argarray); */
-/* Dump(buffer, rc); */
-
-/* argarray[0] = # */
-/* argarray[1] = text; */
-/* rc = trio_sscanfv(buffer, "%d %s", argarray); */
-/* Dump(buffer, rc); */
-/* printf("num = %d text = \"%s\"\n", num, text); */
-
-/* argarray[0] = &number; */
-/* argarray[1] = &small_number; */
-/* rc = trio_sprintfv(buffer, "%f %hf", argarray); */
-/* Dump(buffer, rc); */
-/* printf("number = %f small_number = \"%f\"\n", number, small_number); */
-/* } */
-
- rc = trio_sprintf(buffer, "abcba");
- Dump(buffer, rc);
- trio_sscanf(buffer, "%[ab]", text);
- printf("text = \"%s\"\n", text);
- trio_sscanf(buffer, "%*[ab]c%[^\n]", text);
- printf("text = \"%s\"\n", text);
-
- trio_sprintf(buffer, "aabcdba aaa");
- rc = trio_sscanf(buffer, "%s", text);
- Dump(buffer, rc);
- printf("text = \"%s\"\n", text);
- rc = trio_sscanf(buffer, "%*1[aA]%[a-c]", text);
- Dump(buffer, rc);
- printf("text = \"%s\"\n", text);
-
- rc = trio_sprintf(buffer, "10021");
- rc = trio_sscanf(buffer, "%b%n%d", &num, &count, &num2);
- Dump(buffer, rc);
- printf("num = %d %d %d\n", num, num2, count);
-
-/* rc = trio_sprintf(buffer, "%'d", 10000); */
-/* rc = trio_sscanf(buffer, "%'d", &num); */
-/* Dump(buffer, rc); */
-/* printf("num = %d\n", num); */
-
-/* rc = trio_dprintf(STDOUT_FILENO, "%s\n", "hello there"); */
-/* Dump(buffer, rc); */
-/* rc = trio_dscanf(STDIN_FILENO, "%s", buffer); */
-/* Dump(buffer, rc); */
-
-/* rc = trio_scanf("%s", buffer); */
-/* Dump(buffer, rc); */
-
-/* rc = trio_sprintf(buffer, "Ttext"); */
-/* Dump(buffer, rc); */
-/* trio_sscanf(buffer, "%*[Tt]e%c", &ch); */
-/* printf("ch = %c\n", ch); */
-
-/* printf("%p\n", &main); */
-/* rc = trio_sprintf(buffer, "%p %p", &main, NULL); */
-/* Dump(buffer, rc); */
-/* trio_sscanf(buffer, "%p %p", &p1, &p2); */
-/* printf("pointer = %p %p\n", p1, p2); */
-
-/* rc = trio_sprintf(buffer, "%@.@.@i", 8, 7, 2, 42); */
-/* Dump(buffer, rc); */
-/* trio_sprintf(buffer, "abcdefghijklmnopqrstuvwxyz"); */
-/* rc = trio_sscanf(buffer, "%100s", text); */
-/* Dump(text, rc); */
-/* rc = trio_sscanf(buffer, "%@s", 100, text); */
-/* Dump(text, rc); */
-
-/* rc = trio_sprintf(buffer, "%..2i", 42); */
-/* Dump(buffer, rc); */
-/* rc = trio_sscanf(buffer, "%..2i", &num); */
-/* printf("%d\n", num); */
-/* rc = trio_sscanf(buffer, "%..@i", 2, &num); */
-/* printf("%d\n", num); */
-
-/* { */
-/* int num1, num2, num3, num4; */
-
-/* rc = trio_sprintf(buffer, "123_456 [12%%-34%%]"); */
-/* Dump(buffer, rc); */
-/* rc = trio_sscanf(buffer, "%5i%*1s%5i%*1s%5i%*2s%5i", */
-/* &num1, &num2, &num3, &num4); */
-/* Dump(buffer, rc); */
-/* printf("%d %d %d %d %d\n", rc, num1, num2, num3, num4); */
-/* rc = trio_sscanf(buffer, "%d_%d [%d%%-%d%%]", */
-/* &num1, &num2, &num3, &num4); */
-/* Dump(buffer, rc); */
-/* printf("%d %d %d %d %d\n", rc, num1, num2, num3, num4); */
-/* } */
-
-/* rc = trio_sprintf(buffer, "01 3456789"); */
-/* Dump(buffer, rc); */
-/* memset(&text, 0, sizeof(text)); */
-/* rc = trio_sscanf(buffer, "%4c", &text); */
-/* Dump(text, rc); */
-/* memset(&text, 0, sizeof(text)); */
-/* rc = sscanf(buffer, "%4c", &text); */
-/* Dump(text, rc); */
-
-/* rc = trio_sprintf(buffer, "12345 6"); */
-/* Dump(buffer, rc); */
-/* rc = trio_sscanf(buffer, "%2d", &num); */
-/* Dump(buffer, rc); */
-/* printf("%d\n", num); */
-/* rc = sscanf(buffer, "%2d", &num); */
-/* Dump(buffer, rc); */
-/* printf("%d\n", num); */
-
-/* rc = trio_sprintf(buffer, "aa\\x0abb"); */
-/* Dump(buffer, rc); */
-/* rc = trio_sscanf(buffer, "aa%#sbb", &text); */
-/* Dump(text, rc); */
-
-/* rc = trio_sscanf("0 ", "%f", &dnum, text); */
-/* printf("%d %f\n", rc, dnum); */
-/* rc = sscanf("0 ", "%f %s", &dnum, text); */
-/* printf("%d %f\n", rc, dnum); */
-
-/* rc = trio_sscanf("lære", "%[:alpha:]", text); */
-/* Dump(text, rc); */
-
-/* rc = trio_sscanf("-0.123e3", "%8e", &dnum); */
-/* printf("%d %f\n", rc, dnum); */
-
-/* rc = trio_sscanf("123,456.78", "%'f", &dnum); */
-/* printf("%d %f\n", rc, dnum); */
-
- return 0;
-}
+++ /dev/null
-#!/bin/sh
-#
-# install - install a program, script, or datafile
-# This comes from X11R5 (mit/util/scripts/install.sh).
-#
-# Copyright 1991 by the Massachusetts Institute of Technology
-#
-# Permission to use, copy, modify, distribute, and sell this software and its
-# documentation for any purpose is hereby granted without fee, provided that
-# the above copyright notice appear in all copies and that both that
-# copyright notice and this permission notice appear in supporting
-# documentation, and that the name of M.I.T. not be used in advertising or
-# publicity pertaining to distribution of the software without specific,
-# written prior permission. M.I.T. makes no representations about the
-# suitability of this software for any purpose. It is provided "as is"
-# without express or implied warranty.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch. It can only install one file at a time, a restriction
-# shared with many OS's install programs.
-
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-transformbasename=""
-transform_arg=""
-instcmd="$mvprog"
-chmodcmd="$chmodprog 0755"
-chowncmd=""
-chgrpcmd=""
-stripcmd=""
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=""
-dst=""
-dir_arg=""
-
-while [ x"$1" != x ]; do
- case $1 in
- -c) instcmd="$cpprog"
- shift
- continue;;
-
- -d) dir_arg=true
- shift
- continue;;
-
- -m) chmodcmd="$chmodprog $2"
- shift
- shift
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd="$stripprog"
- shift
- continue;;
-
- -t=*) transformarg=`echo $1 | sed 's/-t=//'`
- shift
- continue;;
-
- -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
- shift
- continue;;
-
- *) if [ x"$src" = x ]
- then
- src=$1
- else
- # this colon is to work around a 386BSD /bin/sh bug
- :
- dst=$1
- fi
- shift
- continue;;
- esac
-done
-
-if [ x"$src" = x ]
-then
- echo "install: no input file specified"
- exit 1
-else
- true
-fi
-
-if [ x"$dir_arg" != x ]; then
- dst=$src
- src=""
-
- if [ -d $dst ]; then
- instcmd=:
- else
- instcmd=mkdir
- fi
-else
-
-# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
-# might cause directories to be created, which would be especially bad
-# if $src (and thus $dsttmp) contains '*'.
-
- if [ -f $src -o -d $src ]
- then
- true
- else
- echo "install: $src does not exist"
- exit 1
- fi
-
- if [ x"$dst" = x ]
- then
- echo "install: no destination specified"
- exit 1
- else
- true
- fi
-
-# If destination is a directory, append the input filename; if your system
-# does not like double slashes in filenames, you may need to add some logic
-
- if [ -d $dst ]
- then
- dst="$dst"/`basename $src`
- else
- true
- fi
-fi
-
-## this sed command emulates the dirname command
-dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
-
-# Make sure that the destination directory exists.
-# this part is taken from Noah Friedman's mkinstalldirs script
-
-# Skip lots of stat calls in the usual case.
-if [ ! -d "$dstdir" ]; then
-defaultIFS='
-'
-IFS="${IFS-${defaultIFS}}"
-
-oIFS="${IFS}"
-# Some sh's can't handle IFS=/ for some reason.
-IFS='%'
-set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
-IFS="${oIFS}"
-
-pathcomp=''
-
-while [ $# -ne 0 ] ; do
- pathcomp="${pathcomp}${1}"
- shift
-
- if [ ! -d "${pathcomp}" ] ;
- then
- $mkdirprog "${pathcomp}"
- else
- true
- fi
-
- pathcomp="${pathcomp}/"
-done
-fi
-
-if [ x"$dir_arg" != x ]
-then
- $doit $instcmd $dst &&
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
-else
-
-# If we're going to rename the final executable, determine the name now.
-
- if [ x"$transformarg" = x ]
- then
- dstfile=`basename $dst`
- else
- dstfile=`basename $dst $transformbasename |
- sed $transformarg`$transformbasename
- fi
-
-# don't allow the sed command to completely eliminate the filename
-
- if [ x"$dstfile" = x ]
- then
- dstfile=`basename $dst`
- else
- true
- fi
-
-# Make a temp file name in the proper directory.
-
- dsttmp=$dstdir/#inst.$$#
-
-# Move or copy the file name to the temp name
-
- $doit $instcmd $src $dsttmp &&
-
- trap "rm -f ${dsttmp}" 0 &&
-
-# and set any options; do chmod last to preserve setuid bits
-
-# If any of these fail, we abort the whole thing. If we want to
-# ignore errors from any of these, just make sure not to ignore
-# errors from the above "$doit $instcmd $src $dsttmp" command.
-
- if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
- if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
- if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
- if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
-
-# Now rename the file to the real destination.
-
- $doit $rmcmd -f $dstdir/$dstfile &&
- $doit $mvcmd $dsttmp $dstdir/$dstfile
-
-fi &&
-
-
-exit 0
+++ /dev/null
-#! /bin/sh
-# Script to build archives with
-#
-
-echo "Version number?"
-read version
-
-# get current dir
-dir=`pwd`
-
-# Get basename
-orig=`basename $dir`
-
-# Get the left part of the dash (-)
-new=`echo $orig | cut -d- -f1`
-
-# Build new directory name
-n=$new-$version;
-
-# Tell the world what we're doing
-echo "creates $n.tar.gz";
-
-if [ -r $n ]; then
- echo "Directory already exists!"
- exit
-fi
-
-# Create the new dir
-mkdir $n
-
-# Copy all relevant files, with path and permissions!
-tar -cf - `cat FILES` | (cd $n; tar -xBpf -) || exit 1
-
-(cd $n && sh autogen.sh) || exit 1
-
-# Make a tar archive of it all
-tar -cvf $n.tar $n
-
-# gzip the archive
-gzip $n.tar
-
-# Make it world readable
-chmod a+r $n.tar.gz ;
-
-# Delete the temp dir
-rm -rf $n
+++ /dev/null
-/*************************************************************************
- * Regression test
- */
-
-#include "triodef.h"
-#if defined(TRIO_COMPILER_ANCIENT)
-# include <varargs.h>
-#else
-# include <stdarg.h>
-#endif
-#include <math.h>
-#include <limits.h>
-#include <float.h>
-#include <errno.h>
-
-#include "trio.h"
-#include "triop.h"
-#if defined(TRIO_EMBED_NAN)
-# define TRIO_PUBLIC_NAN static
-# define TRIO_FUNC_NINF
-# define TRIO_FUNC_PINF
-# define TRIO_FUNC_NAN
-# define TRIO_FUNC_ISINF
-# define TRIO_FUNC_ISNAN
-# if TRIO_FEATURE_FLOAT
-# define TRIO_FUNC_NZERO
-# endif
-#endif
-#include "trionan.h"
-#if defined(TRIO_EMBED_STRING)
-# define TRIO_PUBLIC_STRING static
-# define TRIO_FUNC_EQUAL_CASE
-#endif
-#include "triostr.h"
-#undef printf
-
-#if TRIO_FEATURE_WIDECHAR
-# include <wchar.h>
-#endif
-
-#define QUOTE(x) #x
-
-#define DOUBLE_EQUAL(x,y) (((x)>(y)-DBL_EPSILON) && ((x)<(y)+DBL_EPSILON))
-#define FLOAT_EQUAL(x,y) (((x)>(y)-FLT_EPSILON) && ((x)<(y)+FLT_EPSILON))
-
-static TRIO_CONST char rcsid[] = "@(#)$Id: regression.c,v 1.67 2010/01/26 13:02:02 breese Exp $";
-
-#if defined(TRIO_EMBED_NAN)
-# include "trionan.c"
-#endif
-#if defined(TRIO_EMBED_STRING)
-# include "triostr.c"
-#endif
-
-/*************************************************************************
- *
- */
-static void
-Dump
-TRIO_ARGS2((buffer, rc),
- char *buffer,
- int rc)
-{
- if (rc < 0)
- {
- printf("Err = %d (%s), Pos = %d\n",
- TRIO_ERROR_CODE(rc),
- TRIO_ERROR_NAME(rc),
- TRIO_ERROR_POSITION(rc));
- }
- else if (buffer)
- printf("buffer[% 3d] = \"%s\"\n", rc, buffer);
-}
-
-/*************************************************************************
- *
- */
-static void
-Report0
-TRIO_ARGS2((file, line),
- TRIO_CONST char *file,
- int line)
-{
- printf("Verification failed in %s:%d.\n", file, line);
-}
-
-/*************************************************************************
- *
- */
-static void
-Report
-TRIO_ARGS4((file, line, expected, got),
- TRIO_CONST char *file,
- int line,
- TRIO_CONST char *expected,
- TRIO_CONST char *got)
-{
- Report0(file, line);
- printf(" Expected \"%s\"\n", expected);
- printf(" Got \"%s\"\n", got);
-}
-
-/*************************************************************************
- *
- */
-int
-Verify
-TRIO_VARGS5((file, line, result, fmt, va_alist),
- TRIO_CONST char *file,
- int line,
- TRIO_CONST char *result,
- TRIO_CONST char *fmt,
- TRIO_VA_DECL)
-{
- int rc;
- va_list args;
- char buffer[4096];
-
- TRIO_VA_START(args, fmt);
- rc = trio_vsnprintf(buffer, sizeof(buffer), fmt, args);
- if (rc < 0)
- Dump(buffer, rc);
- TRIO_VA_END(args);
-
- if (!trio_equal_case(result, buffer))
- {
- Report(file, line, result, buffer);
- return 1;
- }
- return 0;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyReturnValues(TRIO_NOARGS)
-{
- int nerrors = 0;
- int rc;
- int count;
- char *expected;
- char buffer[4096];
- char result[4096];
-
- rc = trio_sprintf(buffer, "%s%n", "0123456789", &count);
- trio_sprintf(result, "%d %d %s", rc, count, buffer);
- expected = "10 10 0123456789";
- if (!trio_equal_case(result, expected))
- {
- nerrors++;
- Report(__FILE__, __LINE__, expected, result);
- }
-
- rc = trio_snprintf(buffer, sizeof(buffer), "%s%n", "0123456789", &count);
- trio_sprintf(result, "%d %d %s", rc, count, buffer);
- expected = "10 10 0123456789";
- if (!trio_equal_case(result, expected))
- {
- nerrors++;
- Report(__FILE__, __LINE__, expected, result);
- }
-
- rc = trio_snprintf(buffer, 4, "%s%n", "0123456789", &count);
- trio_sprintf(result, "%d %d %s", rc, count, buffer);
- expected = "10 3 012";
- if (!trio_equal_case(result, expected))
- {
- nerrors++;
- Report(__FILE__, __LINE__, expected, result);
- }
-
- /* The output buffer contains the empty string */
- rc = trio_snprintf(buffer, 1, "%s%n", "0123456789", &count);
- trio_sprintf(result, "%d %d %s", rc, count, buffer);
- expected = "10 0 ";
- if (!trio_equal_case(result, expected))
- {
- nerrors++;
- Report(__FILE__, __LINE__, expected, result);
- }
-
- /* The output buffer should be left untouched when max size is 0 */
- trio_sprintf(buffer, "DO NOT TOUCH");
- rc = trio_snprintf(buffer, 0, "%s%n", "0123456789", &count);
- trio_sprintf(result, "%d %d %s", rc, count, buffer);
- expected = "10 0 DO NOT TOUCH";
- if (!trio_equal_case(result, expected))
- {
- nerrors++;
- Report(__FILE__, __LINE__, expected, result);
- }
-
- return nerrors;
-}
-
-/*************************************************************************
- *
- */
-#define TEST_STRING "0123456789"
-
-int
-VerifyAllocate(TRIO_NOARGS)
-{
- int nerrors = 0;
-#if TRIO_FEATURE_DYNAMICSTRING
- int rc;
- char *string;
- int count;
- int test_size = sizeof(TEST_STRING) - 1;
-
- /* Allocate a string with the result */
- rc = trio_asprintf(&string, "%s%n", TEST_STRING, &count);
- if (rc < 0)
- {
- nerrors++;
- Dump(string, rc);
- }
- else if (count != test_size)
- {
- nerrors++;
- printf("Validation failed in %s:%d\n", __FILE__, __LINE__);
- printf(" Expected %%n = %d\n", test_size);
- printf(" Got %%n = %d\n", count);
- }
- else if (!trio_equal_case(string, TEST_STRING))
- {
- nerrors++;
- Report(__FILE__, __LINE__, TEST_STRING, string);
- }
- if (string)
- free(string);
-#endif
-
- return nerrors;
-}
-
-
-/*************************************************************************
- *
- */
-int
-VerifyFormattingStrings(TRIO_NOARGS)
-{
- int nerrors = 0;
-
- /* Normal text */
- nerrors += Verify(__FILE__, __LINE__, "Hello world",
- "Hello world");
- /* String */
- nerrors += Verify(__FILE__, __LINE__, "Hello world",
- "%s", "Hello world");
-
- return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyFormattingIntegers(TRIO_NOARGS)
-{
- int nerrors = 0;
- char buffer[256];
-
- /* Integer */
- nerrors += Verify(__FILE__, __LINE__, "Number 42",
- "Number %d", 42);
- nerrors += Verify(__FILE__, __LINE__, "Number -42",
- "Number %d", -42);
- nerrors += Verify(__FILE__, __LINE__, "Number 42",
- "Number %ld", 42L);
- nerrors += Verify(__FILE__, __LINE__, "Number -42",
- "Number %ld", -42L);
- /* Integer width */
- nerrors += Verify(__FILE__, __LINE__, " 1234",
- "%6d", 1234);
- nerrors += Verify(__FILE__, __LINE__, " 1234",
- "%*d", 6, 1234);
- /* Integer width overrun */
- nerrors += Verify(__FILE__, __LINE__, "123456",
- "%4d", 123456);
- /* Integer precision */
- nerrors += Verify(__FILE__, __LINE__, "0012",
- "%.4d", 12);
- nerrors += Verify(__FILE__, __LINE__, "0012",
- "%.*d", 4, 12);
- nerrors += Verify(__FILE__, __LINE__, " 0012",
- "%6.*d", 4, 12);
- nerrors += Verify(__FILE__, __LINE__, " 0012",
- "%*.*d", 6, 4, 12);
- nerrors += Verify(__FILE__, __LINE__, " 0012",
- "%*.*.*d", 6, 4, 2, 12);
- nerrors += Verify(__FILE__, __LINE__, " 0012",
- "%*.*.*i", 6, 4, 10, 12);
- /* Integer sign, zero-padding, and width */
- nerrors += Verify(__FILE__, __LINE__, "+01234",
- "%+06d", 1234);
- nerrors += Verify(__FILE__, __LINE__, " 01234",
- "% 06d", 1234);
- nerrors += Verify(__FILE__, __LINE__, "+01234",
- "% +06d", 1234);
- /* Integer adjust, zero-padding, and width */
- nerrors += Verify(__FILE__, __LINE__, "12 ",
- "%-08d", 12);
- /* Integer zero-padding, width, and precision */
- nerrors += Verify(__FILE__, __LINE__, " 000012",
- "%08.6d", 12);
- /* Integer base */
- nerrors += Verify(__FILE__, __LINE__, "42",
- "%u", 42);
- nerrors += Verify(__FILE__, __LINE__, "-1",
- "%d", -1);
- nerrors += Verify(__FILE__, __LINE__, "52",
- "%o", 42);
- nerrors += Verify(__FILE__, __LINE__, "052",
- "%#o", 42);
- nerrors += Verify(__FILE__, __LINE__, "0",
- "%#o", 0);
- nerrors += Verify(__FILE__, __LINE__, "2a",
- "%x", 42);
- nerrors += Verify(__FILE__, __LINE__, "2A",
- "%X", 42);
- nerrors += Verify(__FILE__, __LINE__, "0x2a",
- "%#x", 42);
- nerrors += Verify(__FILE__, __LINE__, "0X2A",
- "%#X", 42);
- nerrors += Verify(__FILE__, __LINE__, "0x00c ",
- "%-#6.3x", 12);
- nerrors += Verify(__FILE__, __LINE__, "",
- "%.d", 0);
- nerrors += Verify(__FILE__, __LINE__, "",
- "%#.d", 0);
- nerrors += Verify(__FILE__, __LINE__, "42",
- "%.d", 42);
- nerrors += Verify(__FILE__, __LINE__, "",
- "%.o", 0);
- nerrors += Verify(__FILE__, __LINE__, " 0000",
- "%8.4o", 0);
- nerrors += Verify(__FILE__, __LINE__, " 0",
- "%8o", 0);
- nerrors += Verify(__FILE__, __LINE__, "00000000",
- "%08o", 0);
- nerrors += Verify(__FILE__, __LINE__, "0",
- "%#.o", 0);
- nerrors += Verify(__FILE__, __LINE__, "52",
- "%.o", 42);
- nerrors += Verify(__FILE__, __LINE__, "",
- "%.x", 0);
- nerrors += Verify(__FILE__, __LINE__, "",
- "%#.x", 0);
- nerrors += Verify(__FILE__, __LINE__, "2a",
- "%.x", 42);
- sprintf(buffer, "%u", UINT_MAX);
- nerrors += Verify(__FILE__, __LINE__, buffer,
- "%u", -1);
- sprintf(buffer, "%x", UINT_MAX);
- nerrors += Verify(__FILE__, __LINE__, buffer,
- "%x", -1);
-
- return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyFormattingFloats(TRIO_NOARGS)
-{
- int nerrors = 0;
-
-#if TRIO_FEATURE_FLOAT
- /* Double */
- nerrors += Verify(__FILE__, __LINE__, "3141.000000",
- "%f", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, "3141.500000",
- "%f", 3141.5);
- nerrors += Verify(__FILE__, __LINE__, "3.141000e+03",
- "%e", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, " -2.3420e-02",
- "%16.4e", -2.342E-02);
- nerrors += Verify(__FILE__, __LINE__, " -2.3420e-22",
- "%16.4e", -2.342E-22);
- nerrors += Verify(__FILE__, __LINE__, " 2.3420e-02",
- "% 16.4e", 2.342E-02);
- nerrors += Verify(__FILE__, __LINE__, " 2.3420e-02",
- "% 1.4e", 2.342E-02);
- nerrors += Verify(__FILE__, __LINE__, "3.141000E-44",
- "%E", 3.141e-44);
- nerrors += Verify(__FILE__, __LINE__, "0",
- "%g", 0.0);
- nerrors += Verify(__FILE__, __LINE__, "-0",
- "%g", trio_nzero());
- nerrors += Verify(__FILE__, __LINE__, "3141.5",
- "%g", 3141.5);
- nerrors += Verify(__FILE__, __LINE__, "3.1415E-06",
- "%G", 3.1415e-6);
- nerrors += Verify(__FILE__, __LINE__, "+3141.000000",
- "%+f", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, "-3141.000000",
- "%+f", -3141.0);
- nerrors += Verify(__FILE__, __LINE__, "0.333333",
- "%f", 1.0/3.0);
- nerrors += Verify(__FILE__, __LINE__, "0.666667",
- "%f", 2.0/3.0);
- /* Beyond accuracy */
- nerrors += Verify(__FILE__, __LINE__, "0.000000",
- "%f", 1.234567890123456789e-20);
-# if defined(TRIO_BREESE)
- nerrors += Verify(__FILE__, __LINE__, "1.3999999999999999111821580299875",
- "%.32g", 1.4);
- nerrors += Verify(__FILE__, __LINE__, "1.39999999999999991118215802998748",
- "%.32f", 1.4);
- nerrors += Verify(__FILE__, __LINE__, "1.3999999999999999111821580300",
- "%.28f", 1.4);
- nerrors += Verify(__FILE__, __LINE__, "1.399999999999999911182158",
- "%.24f", 1.4);
- nerrors += Verify(__FILE__, __LINE__, "1.39999999999999991",
- "%.17f", 1.4);
- nerrors += Verify(__FILE__, __LINE__, "1.40000000000000",
- "%.14f", 1.4);
- nerrors += Verify(__FILE__, __LINE__, "39413.800000000002910383045673370361",
- "%.30f", 39413.80);
-# endif
- /* 2^-1 + 2^-15 */
- nerrors += Verify(__FILE__, __LINE__, "0.500030517578125",
- "%.*g", DBL_DIG + 10, 0.500030517578125);
- /* Double decimal point */
- nerrors += Verify(__FILE__, __LINE__, "3141",
- "%.0f", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, "3142",
- "%.0f", 3141.5);
- nerrors += Verify(__FILE__, __LINE__, "3141",
- "%.f", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, "12",
- "%.f", 12.34);
- nerrors += Verify(__FILE__, __LINE__, "3141.000",
- "%.3f", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, "3141.000000",
- "%#f", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, "0.0000",
- "%#.4f", 0.0);
- nerrors += Verify(__FILE__, __LINE__, "0.000",
- "%#.4g", 0.0);
- nerrors += Verify(__FILE__, __LINE__, "0.001000",
- "%#.4g", 1e-3);
- nerrors += Verify(__FILE__, __LINE__, "3141.0000",
- "%#.4f", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, "3141.",
- "%#.0f", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, "3141.",
- "%#.f", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, "11.0000",
- "%#.4f", 11.0);
- nerrors += Verify(__FILE__, __LINE__, "100.00",
- "%.2f", 99.9999);
- nerrors += Verify(__FILE__, __LINE__, "3e+03",
- "%.e", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, "3.e+03",
- "%#.e", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, "1.23457e+06",
- "%g", 1234567.0);
- nerrors += Verify(__FILE__, __LINE__, "1e+02",
- "%.2g", 99.9999);
- nerrors += Verify(__FILE__, __LINE__, "1.0e+02",
- "%#.2g", 99.9999);
- nerrors += Verify(__FILE__, __LINE__, "0.123",
- "%0g", 0.123);
- nerrors += Verify(__FILE__, __LINE__, "1.00e+00",
- "%.2e", 0.9999);
- nerrors += Verify(__FILE__, __LINE__, "1",
- "%.2g", 0.9999);
- nerrors += Verify(__FILE__, __LINE__, "2",
- "%.0g", 1.5);
- nerrors += Verify(__FILE__, __LINE__, "2",
- "%.g", 1.5);
- nerrors += Verify(__FILE__, __LINE__, "0.01",
- "%.2g", 0.01);
- nerrors += Verify(__FILE__, __LINE__, "0.010",
- "%#.2g", 0.01);
- nerrors += Verify(__FILE__, __LINE__, "1e-04",
- "%5.g", 0.999999e-4);
- /* Double width and precision */
- nerrors += Verify(__FILE__, __LINE__, " 1e-05",
- "%11.5g", 1e-5);
- nerrors += Verify(__FILE__, __LINE__, " 0.0001",
- "%11.5g", 1e-4);
- nerrors += Verify(__FILE__, __LINE__, " 0.001",
- "%11.5g", 1e-3);
- nerrors += Verify(__FILE__, __LINE__, " 0.01",
- "%11.5g", 1e-2);
- nerrors += Verify(__FILE__, __LINE__, " 0.1",
- "%11.5g", 1e-1);
- nerrors += Verify(__FILE__, __LINE__, " 1",
- "%11.5g", 1e0);
- nerrors += Verify(__FILE__, __LINE__, " 10",
- "%11.5g", 1e1);
- nerrors += Verify(__FILE__, __LINE__, " 100",
- "%11.5g", 1e2);
- nerrors += Verify(__FILE__, __LINE__, " 1000",
- "%11.5g", 1e3);
- nerrors += Verify(__FILE__, __LINE__, " 10000",
- "%11.5g", 1e4);
- nerrors += Verify(__FILE__, __LINE__, " 1e+05",
- "%11.5g", 1e5);
- nerrors += Verify(__FILE__, __LINE__, " 9.9e-05",
- "%11.2g", 0.99e-4);
- nerrors += Verify(__FILE__, __LINE__, " 0.00099",
- "%11.2g", 0.99e-3);
- nerrors += Verify(__FILE__, __LINE__, " 0.0099",
- "%11.2g", 0.99e-2);
- nerrors += Verify(__FILE__, __LINE__, " 0.099",
- "%11.2g", 0.99e-1);
- nerrors += Verify(__FILE__, __LINE__, " 0.99",
- "%11.2g", 0.99e0);
- nerrors += Verify(__FILE__, __LINE__, " 9.9",
- "%11.2g", 0.99e1);
- nerrors += Verify(__FILE__, __LINE__, " 99",
- "%11.2g", 0.99e2);
- nerrors += Verify(__FILE__, __LINE__, " 9.9e+02",
- "%11.2g", 0.99e3);
- nerrors += Verify(__FILE__, __LINE__, " 9.9e+03",
- "%11.2g", 0.99e4);
- nerrors += Verify(__FILE__, __LINE__, " 9.9e+04",
- "%11.2g", 0.99e5);
- /* Double width, precision, and alternative */
- nerrors += Verify(__FILE__, __LINE__, " 1.0000e-05",
- "%#11.5g", 1e-5);
- nerrors += Verify(__FILE__, __LINE__, " 0.00010000",
- "%#11.5g", 1e-4);
- nerrors += Verify(__FILE__, __LINE__, " 0.0010000",
- "%#11.5g", 1e-3);
- nerrors += Verify(__FILE__, __LINE__, " 0.0010000",
- "%#11.5g", 0.999999e-3);
- nerrors += Verify(__FILE__, __LINE__, " 0.010000",
- "%#11.5g", 1e-2);
- nerrors += Verify(__FILE__, __LINE__, " 0.010000",
- "%#11.5g", 0.999999e-2);
- nerrors += Verify(__FILE__, __LINE__, " 0.10000",
- "%#11.5g", 1e-1);
- nerrors += Verify(__FILE__, __LINE__, " 0.10000",
- "%#11.5g", 0.999999e-1);
- nerrors += Verify(__FILE__, __LINE__, " 1.0000",
- "%#11.5g", 1e0);
- nerrors += Verify(__FILE__, __LINE__, " 1.0000",
- "%#11.5g", 0.999999e0);
- nerrors += Verify(__FILE__, __LINE__, " 10.000",
- "%#11.5g", 1e1);
- nerrors += Verify(__FILE__, __LINE__, " 100.00",
- "%#11.5g", 1e2);
- nerrors += Verify(__FILE__, __LINE__, " 1000.0",
- "%#11.5g", 1e3);
- nerrors += Verify(__FILE__, __LINE__, " 10000.",
- "%#11.5g", 1e4);
- nerrors += Verify(__FILE__, __LINE__, " 1.0000e+05",
- "%#11.5g", 1e5);
- nerrors += Verify(__FILE__, __LINE__, " 9.9e-05",
- "%#11.2g", 0.99e-4);
- nerrors += Verify(__FILE__, __LINE__, " 0.00099",
- "%#11.2g", 0.99e-3);
- nerrors += Verify(__FILE__, __LINE__, " 0.0099",
- "%#11.2g", 0.99e-2);
- nerrors += Verify(__FILE__, __LINE__, " 0.099",
- "%#11.2g", 0.99e-1);
- nerrors += Verify(__FILE__, __LINE__, " 0.99",
- "%#11.2g", 0.99e0);
- nerrors += Verify(__FILE__, __LINE__, " 9.9",
- "%#11.2g", 0.99e1);
- nerrors += Verify(__FILE__, __LINE__, " 99.",
- "%#11.2g", 0.99e2);
- nerrors += Verify(__FILE__, __LINE__, " 9.9e+02",
- "%#11.2g", 0.99e3);
- nerrors += Verify(__FILE__, __LINE__, " 9.9e+03",
- "%#11.2g", 0.99e4);
- nerrors += Verify(__FILE__, __LINE__, " 9.9e+04",
- "%#11.2g", 0.99e5);
- /* Double width, precision, and zero padding */
- nerrors += Verify(__FILE__, __LINE__, "00003.141500e+03",
- "%016e", 3141.5);
- nerrors += Verify(__FILE__, __LINE__, " 3.141500e+03",
- "%16e", 3141.5);
- nerrors += Verify(__FILE__, __LINE__, "3.141500e+03 ",
- "%-16e", 3141.5);
- nerrors += Verify(__FILE__, __LINE__, "03.142e+03",
- "%010.3e", 3141.5);
-#if !defined(TRIO_COMPILER_ANCIENT)
- /* Long double */
- nerrors += Verify(__FILE__, __LINE__, "1.400000",
- "%Lf", 1.4L);
-#endif
-
- /* Special cases */
- nerrors += Verify(__FILE__, __LINE__, "1.00",
- "%.2f", 0.999);
- nerrors += Verify(__FILE__, __LINE__, "100",
- "%.0f", 99.9);
- nerrors += Verify(__FILE__, __LINE__, "inf",
- "%f", trio_pinf());
- nerrors += Verify(__FILE__, __LINE__, "-inf",
- "%f", trio_ninf());
- nerrors += Verify(__FILE__, __LINE__, "INF",
- "%F", trio_pinf());
- nerrors += Verify(__FILE__, __LINE__, "-INF",
- "%F", trio_ninf());
- /* May fail if NaN is unsupported */
- nerrors += Verify(__FILE__, __LINE__, "nan",
- "%f", trio_nan());
- nerrors += Verify(__FILE__, __LINE__, "NAN",
- "%F", trio_nan());
-
-# if TRIO_FEATURE_HEXFLOAT
- nerrors += Verify(__FILE__, __LINE__, "0x2.ap+4",
- "%a", 42.0);
- nerrors += Verify(__FILE__, __LINE__, "-0x2.ap+4",
- "%a", -42.0);
- nerrors += Verify(__FILE__, __LINE__, "0x1.8p+0",
- "%a", 1.5);
- nerrors += Verify(__FILE__, __LINE__, "0x1.6666666666666p+0",
- "%a", 1.4);
- nerrors += Verify(__FILE__, __LINE__, "0xc.45p+8",
- "%a", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, "0XC.45P+8",
- "%A", 3141.0);
- nerrors += Verify(__FILE__, __LINE__, "0xb.351c434a98fa8p-148",
- "%a", 3.141e-44);
-# endif
-
-#endif /* TRIO_FEATURE_FLOAT */
-
- return nerrors;
-}
-
-/*************************************************************************
- *
- */
-#if TRIO_EXTENSION
-int number_writer(void *ref)
-{
- const char *format;
- int *data;
-
- format = trio_get_format(ref);
- if ((format) && trio_equal(format, "integer"))
- {
- data = trio_get_argument(ref);
- if (data)
- {
- trio_print_int(ref, *data);
- }
- }
- return 0;
-}
-
-#endif
-
-int
-VerifyFormattingUserDefined(TRIO_NOARGS)
-{
- int nerrors = 0;
-#if TRIO_EXTENSION
- void *number_handle;
- int integer = 123;
-
- number_handle = trio_register(number_writer, "number");
-
- /* Old style */
- nerrors += Verify(__FILE__, __LINE__, "123",
- "%<number:integer>", &integer);
-
- /* New style */
- nerrors += Verify(__FILE__, __LINE__, "123",
- "$<number:integer|%p>", &integer);
- nerrors += Verify(__FILE__, __LINE__, "123",
- "$<integer|%p%p>", number_handle, &integer);
- nerrors += Verify(__FILE__, __LINE__, "$<integer|123",
- "$<integer|%d", 123);
- nerrors += Verify(__FILE__, __LINE__, "$integer|123>",
- "$integer|%d>", 123);
-
- trio_unregister(number_handle);
-#endif
-
- return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyFormattingRegression(TRIO_NOARGS)
-{
- int nerrors = 0;
-
-#if TRIO_FEATURE_FLOAT
- /* 0.6 was formatted as 0.600000e+00 */
- nerrors += Verify(__FILE__, __LINE__, "5.000000e-01",
- "%e", 0.5);
- nerrors += Verify(__FILE__, __LINE__, "6.000000e-01",
- "%e", 0.6);
-#endif
-
- return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyFormatting(TRIO_NOARGS)
-{
- int nerrors = 0;
-#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
- char buffer[256];
-#endif
-
- nerrors += VerifyFormattingStrings();
- nerrors += VerifyFormattingIntegers();
- nerrors += VerifyFormattingFloats();
- nerrors += VerifyFormattingRegression();
- nerrors += VerifyFormattingUserDefined();
-
- /* Pointer */
- if (sizeof(void *) == 4)
- {
- nerrors += Verify(__FILE__, __LINE__, "Pointer 0x01234567",
- "Pointer %p", 0x1234567);
- }
-#if defined(TRIO_COMPILER_SUPPORTS_LL)
- else if (sizeof(void *) == 8)
- {
- nerrors += Verify(__FILE__, __LINE__, "Pointer 0x0123456789012345",
- "Pointer %p", 0x123456789012345LL);
- }
-#endif
- /* Nil pointer */
- nerrors += Verify(__FILE__, __LINE__, "Pointer (nil)",
- "Pointer %p", NULL);
-
- /* Char width alignment */
- nerrors += Verify(__FILE__, __LINE__, "Char X .",
- "Char %-4c.", 'X');
- /* String width / precision */
- nerrors += Verify(__FILE__, __LINE__, " testing",
- "%8s", "testing");
- nerrors += Verify(__FILE__, __LINE__, "testing ",
- "%-8s", "testing");
- nerrors += Verify(__FILE__, __LINE__, " testing",
- "%*s", 8, "testing");
- nerrors += Verify(__FILE__, __LINE__, "testing ",
- "%*s", -8, "testing");
- nerrors += Verify(__FILE__, __LINE__, "test",
- "%.4s", "testing");
- nerrors += Verify(__FILE__, __LINE__, "test",
- "%.*s", 4, "testing");
- nerrors += Verify(__FILE__, __LINE__, "testing",
- "%.*s", -4, "testing");
-#if TRIO_FEATURE_POSITIONAL
- /* Positional */
- nerrors += Verify(__FILE__, __LINE__, "222 111",
- "%2$s %1$s", "111", "222");
- nerrors += Verify(__FILE__, __LINE__, "123456 12345 0001234 00123",
- "%4$d %3$*8$d %2$.*7$d %1$*6$.*5$d",
- 123, 1234, 12345, 123456, 5, 6, 7, 8);
-#endif
-
-#if TRIO_FEATURE_SIZE_T_UPPER
- nerrors += Verify(__FILE__, __LINE__, "256",
- "%Zd", sizeof(buffer));
-#endif
-
-#if TRIO_FEATURE_ERRNO
- errno = EINTR;
-# if defined(TRIO_PLATFORM_LYNX)
-# if defined(PREDEF_STANDARD_POSIX_1996)
- nerrors += Verify(__FILE__, __LINE__, "Interrupted system call ",
- "%m");
-# else
- nerrors += Verify(__FILE__, __LINE__, "System call interrupted",
- "%m");
-# endif
-# else
- nerrors += Verify(__FILE__, __LINE__, "Interrupted system call",
- "%m");
-# endif
-#endif
-
-#if TRIO_FEATURE_QUAD
-# if defined(TRIO_COMPILER_SUPPORTS_LL)
- /* This may fail if the preprocessor does not recognize LL */
- nerrors += Verify(__FILE__, __LINE__, "42",
- "%qd", 42LL);
-# endif
-#endif
-
-#if TRIO_FEATURE_SIZE_T
- nerrors += Verify(__FILE__, __LINE__, "256",
- "%zd", sizeof(buffer));
-#endif
-#if TRIO_FEATURE_PTRDIFF_T
- nerrors += Verify(__FILE__, __LINE__, "42",
- "%td", 42);
-#endif
-#if TRIO_FEATURE_INTMAX_T
-# if defined(TRIO_COMPILER_SUPPORTS_LL)
- /* Some compilers may not handle the LL suffix correctly */
- nerrors += Verify(__FILE__, __LINE__, "42",
- "%jd", 42LL);
-# endif
-#endif
-
-#if TRIO_FEATURE_WIDECHAR
- nerrors += Verify(__FILE__, __LINE__, "Hello World",
- "%ls", L"Hello World");
- nerrors += Verify(__FILE__, __LINE__, "\\aHello World",
- "%#ls", L"\aHello World");
- nerrors += Verify(__FILE__, __LINE__, "A",
- "%lc", L'A');
- nerrors += Verify(__FILE__, __LINE__, "\\a",
- "%#lc", L'\a');
-#endif
-
-#if TRIO_FEATURE_FIXED_SIZE
- nerrors += Verify(__FILE__, __LINE__, "42",
- "%I8d", 42);
- nerrors += Verify(__FILE__, __LINE__, "ffffffff",
- "%I16x", -1);
-#endif
-
-#if TRIO_EXTENSION
- nerrors += Verify(__FILE__, __LINE__, " 42 86",
- "%!4d %d", 42, 86);
- nerrors += Verify(__FILE__, __LINE__, "0042 0086",
- "%!04d %d", 42, 86);
- nerrors += Verify(__FILE__, __LINE__, "42",
- "%&d", sizeof(long), 42L);
- /* Non-printable string */
- nerrors += Verify(__FILE__, __LINE__, "NonPrintable \\x01 \\a \\\\",
- "NonPrintable %#s", "\01 \07 \\");
- nerrors += Verify(__FILE__, __LINE__, "\\a \\b \\t \\n \\v \\f \\r",
- "%#s", "\007 \010 \011 \012 \013 \014 \015");
- /* Quote flag */
- nerrors += Verify(__FILE__, __LINE__, "Another \"quoted\" string",
- "Another %'s string", "quoted");
- /* Integer base */
- nerrors += Verify(__FILE__, __LINE__, "Number 42 == 1120 (base 3)",
- "Number %d == %..3i (base 3)", 42, 42);
- /* Integer base (specifier base must be used instead of base modifier) */
- nerrors += Verify(__FILE__, __LINE__, "42",
- "%..3d", 42);
- nerrors += Verify(__FILE__, __LINE__, "52",
- "%..3o", 42);
- nerrors += Verify(__FILE__, __LINE__, "2a",
- "%..3x", 42);
- /* Integer thousand separator */
- nerrors += Verify(__FILE__, __LINE__, "Number 100",
- "Number %'d", 100);
- nerrors += Verify(__FILE__, __LINE__, "Number 1,000,000",
- "Number %'d", 1000000);
-# if TRIO_FEATURE_FLOAT
- /* Float thousand separator */
- nerrors += Verify(__FILE__, __LINE__, "31,415.200000",
- "%'f", 31415.2);
- nerrors += Verify(__FILE__, __LINE__, "1,000,000.000000",
- "%'f", 1000000.0);
- /* Rounding modifier */
- nerrors += Verify(__FILE__, __LINE__, "1.4",
- "%.32Rf", 1.4);
- nerrors += Verify(__FILE__, __LINE__, "1.4",
- "%.17Rf", 1.4);
- nerrors += Verify(__FILE__, __LINE__, "39413.8",
- "%.30Rf", 39413.80);
-# if !defined(TRIO_COMPILER_ANCIENT)
- /* Long double */
- nerrors += Verify(__FILE__, __LINE__, "1.4",
- "%RLf", 1.4L);
- nerrors += Verify(__FILE__, __LINE__, "1.4",
- "%.30RLf", 1.4L);
-# endif
-# endif
-#endif
-
-#if defined(TRIO_BREESE)
- /*
- * These results depends on issues beyond our control. For example,
- * the accuracy of floating-point numbers depends on the underlying
- * floating-point hardware (e.g. whether IEEE 754 double or extended-
- * double format is used).
- *
- * These tests are therefore not part of the normal regression test,
- * but we keep them here for development purposes.
- */
- nerrors += Verify(__FILE__, __LINE__, "123456789012345680868.000000",
- "%f", 1.234567890123456789e20);
- nerrors += Verify(__FILE__, __LINE__, "1.23456789012345677901e-20",
- "%.20e", 1.2345678901234567e-20);
- nerrors += Verify(__FILE__, __LINE__, "0.666666666666666629659233",
- "%.*g", DBL_DIG + 10, 2.0/3.0);
- nerrors += Verify(__FILE__, __LINE__, "123456789012345700000",
- "%Rf", 1.234567890123456789e20);
-# if !defined(TRIO_COMPILER_ANCIENT)
- nerrors += Verify(__FILE__, __LINE__, "0.666666666666666667",
- "%RLf", (2.0L/3.0L));
- nerrors += Verify(__FILE__, __LINE__, "0.666666666666666667",
- "%.30RLf", (2.0L/3.0L));
-# endif
-#endif
-
- return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyErrors(TRIO_NOARGS)
-{
- char buffer[512];
- int rc;
- int nerrors = 0;
-
- /* Error: Invalid argument 1 */
- rc = trio_snprintf(buffer, sizeof(buffer), "%d %r", 42, "text");
-#if TRIO_FEATURE_ERRORCODE
-# if TRIO_FEATURE_STRERR
- trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
- TRIO_ERROR_CODE(rc),
- TRIO_ERROR_NAME(rc),
- TRIO_ERROR_POSITION(rc));
- nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 5",
- "%s", buffer);
-# else
- trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
- TRIO_ERROR_CODE(rc),
- TRIO_ERROR_POSITION(rc));
- nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 5",
- "%s", buffer);
-# endif
-#else
- nerrors += (rc != -1);
-#endif
-
- /* Error: Invalid argument 2 */
- rc = trio_snprintf(buffer, sizeof(buffer), "%#");
-#if TRIO_FEATURE_ERRORCODE
-# if TRIO_FEATURE_STRERR
- trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
- TRIO_ERROR_CODE(rc),
- TRIO_ERROR_NAME(rc),
- TRIO_ERROR_POSITION(rc));
- nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 3",
- "%s", buffer);
-# else
- trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
- TRIO_ERROR_CODE(rc),
- TRIO_ERROR_POSITION(rc));
- nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 3",
- "%s", buffer);
-# endif
-#else
- nerrors += (rc != -1);
-#endif
-
- /* Error: Invalid argument 3 */
- rc = trio_snprintf(buffer, sizeof(buffer), "%hhhd", 42);
-#if TRIO_FEATURE_ERRORCODE
-# if TRIO_FEATURE_STRERR
- trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
- TRIO_ERROR_CODE(rc),
- TRIO_ERROR_NAME(rc),
- TRIO_ERROR_POSITION(rc));
- nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 4",
- "%s", buffer);
-# else
- trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
- TRIO_ERROR_CODE(rc),
- TRIO_ERROR_POSITION(rc));
- nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 4",
- "%s", buffer);
-# endif
-#else
- nerrors += (rc != -1);
-#endif
-
- /* Error: Double reference */
- rc = trio_snprintf(buffer, sizeof(buffer), "hello %1$d %1$d", 31, 32);
-#if TRIO_FEATURE_ERRORCODE
-# if TRIO_FEATURE_STRERR
- trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
- TRIO_ERROR_CODE(rc),
- TRIO_ERROR_NAME(rc),
- TRIO_ERROR_POSITION(rc));
-# if TRIO_UNIX98
- nerrors += Verify(__FILE__, __LINE__, "Err = 4 (Double reference), Pos = 0",
- "%s", buffer);
-# else
- nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 9",
- "%s", buffer);
-# endif
-# else
- trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
- TRIO_ERROR_CODE(rc),
- TRIO_ERROR_POSITION(rc));
-# if TRIO_UNIX98
- nerrors += Verify(__FILE__, __LINE__, "Err = 4, Pos = 0",
- "%s", buffer);
-# else
- nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 9",
- "%s", buffer);
-# endif
-# endif
-#else
- nerrors += (rc != -1);
-#endif
-
- /* Error: Reference gap */
- rc = trio_snprintf(buffer, sizeof(buffer), "%3$d %1$d", 31, 32, 33);
-#if TRIO_FEATURE_ERRORCODE
-# if TRIO_FEATURE_STRERR
- trio_snprintf(buffer, sizeof(buffer), "Err = %d (%s), Pos = %d",
- TRIO_ERROR_CODE(rc),
- TRIO_ERROR_NAME(rc),
- TRIO_ERROR_POSITION(rc));
-# if TRIO_UNIX98
- nerrors += Verify(__FILE__, __LINE__, "Err = 5 (Reference gap), Pos = 1",
- "%s", buffer);
-# else
- nerrors += Verify(__FILE__, __LINE__, "Err = 2 (Invalid argument), Pos = 3",
- "%s", buffer);
-# endif
-# else
- trio_snprintf(buffer, sizeof(buffer), "Err = %d, Pos = %d",
- TRIO_ERROR_CODE(rc),
- TRIO_ERROR_POSITION(rc));
-# if TRIO_UNIX98
- nerrors += Verify(__FILE__, __LINE__, "Err = 5, Pos = 1",
- "%s", buffer);
-# else
- nerrors += Verify(__FILE__, __LINE__, "Err = 2, Pos = 3",
- "%s", buffer);
-# endif
-# endif
-#else
- nerrors += (rc != -1);
-#endif
-
- return nerrors;
-}
-
-/*************************************************************************
- *
- */
-#if TRIO_FEATURE_SCANF
-int
-VerifyScanningOneInteger
-TRIO_ARGS5((file, line, expected, format, original),
- TRIO_CONST char *file,
- int line,
- TRIO_CONST char *expected,
- TRIO_CONST char *format,
- int original)
-{
- int number;
- char data[512];
-
- trio_snprintf(data, sizeof(data), format, original);
- trio_sscanf(data, format, &number);
- return Verify(file, line, expected, format, number);
-}
-
-int
-VerifyScanningIntegers(TRIO_NOARGS)
-{
- int nerrors = 0;
-
- nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
- "%i", 42);
- nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
- "%d", 42);
- nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "-42",
- "%d", -42);
- nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "2147483647",
- "%d", 2147483647);
- nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "42",
- "%u", 42);
- nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "2a",
- "%x", 42);
- nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "52",
- "%o", 42);
- nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "101010",
- "%..2i", 42);
- nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "0x2a",
- "%#x", 42);
- nerrors += VerifyScanningOneInteger(__FILE__, __LINE__, "052",
- "%#o", 42);
-
- return nerrors;
-}
-#endif
-
-/*************************************************************************
- *
- */
-#if TRIO_FEATURE_SCANF
-int
-VerifyScanningOneFloat
-TRIO_ARGS5((file, line, expected, format, original),
- TRIO_CONST char *file,
- int line,
- TRIO_CONST char *expected,
- TRIO_CONST char *format,
- double original)
-{
- float number;
- char data[512];
-
- trio_snprintf(data, sizeof(data), format, original);
- trio_sscanf(data, format, &number);
- return Verify(file, line, expected, format, number);
-}
-
-int
-VerifyScanningOneDouble
-TRIO_ARGS5((file, line, expected, format, original),
- TRIO_CONST char *file,
- int line,
- TRIO_CONST char *expected,
- TRIO_CONST char *format,
- double original)
-{
- double number;
- char data[512];
-
- trio_snprintf(data, sizeof(data), format, original);
- trio_sscanf(data, format, &number);
- return Verify(file, line, expected, format, number);
-}
-
-int
-VerifyScanningFloats(TRIO_NOARGS)
-{
- int nerrors = 0;
-
-#if TRIO_FEATURE_FLOAT
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "42.000000",
- "%f", 42.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "-42.000000",
- "%f", -42.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "4.200000e+01",
- "%e", 42.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "4.200000E+01",
- "%E", 42.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "42",
- "%g", 42.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e+06",
- "%g", 1234567.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e-06",
- "%g", 1.234567e-6);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457E+06",
- "%G", 1234567.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234567e+06",
- "%12e", 1234567.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234500e+00",
- "%6e", 1234567.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.234567e+06",
- "%.6e", 1234567.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.2345670000e+06",
- "%.10e", 1234567.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1.23457e+06",
- "%.6g", 1234567.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "1234567",
- "%.10g", 1234567.0);
-# if TRIO_FEATURE_HEXFLOAT
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0x2.ap+4",
- "%a", 42.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0x1.2d687p+20",
- "%a", 1234567.0);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "0X1.2D687P+20",
- "%A", 1234567.0);
-# endif
- nerrors += VerifyScanningOneDouble(__FILE__, __LINE__, "1.79769e+308",
- "%lg", 1.79769e+308);
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "nan",
- "%f", trio_nan());
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "NAN",
- "%F", trio_nan());
- nerrors += VerifyScanningOneFloat(__FILE__, __LINE__, "-inf",
- "%f", trio_ninf());
-#endif
-
- return nerrors;
-}
-#endif
-
-/*************************************************************************
- *
- */
-#if TRIO_FEATURE_SCANF
-int
-VerifyScanningOneString
-TRIO_ARGS5((file, line, expected, format, original),
- TRIO_CONST char *file,
- int line,
- TRIO_CONST char *expected,
- TRIO_CONST char *format,
- char *original)
-{
- char string[512];
- char data[512];
-
- trio_snprintf(data, sizeof(data), "%s", original);
- string[0] = 0;
- trio_sscanf(data, format, string);
- return Verify(file, line, expected, "%s", string);
-}
-
-int
-VerifyScanningStrings(TRIO_NOARGS)
-{
- int nerrors = 0;
-
- nerrors += VerifyScanningOneString(__FILE__, __LINE__, "",
- "hello", "hello");
- nerrors += VerifyScanningOneString(__FILE__, __LINE__, "",
- "", "");
- nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
- "%s", "hello");
- nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
- "%s", "hello world");
- nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello world",
- "%[^\n]", "hello world");
- nerrors += VerifyScanningOneString(__FILE__, __LINE__, "(nil)",
- "%s", NULL);
- nerrors += VerifyScanningOneString(__FILE__, __LINE__, "hello",
- "%20s", "hello");
- nerrors += VerifyScanningOneString(__FILE__, __LINE__, "he",
- "%2s", "hello");
- nerrors += VerifyScanningOneString(__FILE__, __LINE__, "ab",
- "%[ab]", "abcba");
- nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
- "%[abc]", "abcba");
- nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
- "%[a-c]", "abcba");
-#if TRIO_EXTENSION
- nerrors += VerifyScanningOneString(__FILE__, __LINE__, "abcba",
- "%[[:alpha:]]", "abcba");
-#endif
- nerrors += VerifyScanningOneString(__FILE__, __LINE__, "ba",
- "%*[ab]c%[^\n]", "abcba");
-
- return nerrors;
-}
-#endif
-
-/*************************************************************************
- *
- */
-#if TRIO_FEATURE_SCANF
-int
-VerifyScanningRegression(TRIO_NOARGS)
-{
- int nerrors = 0;
- int rc;
-#if TRIO_FEATURE_FLOAT
- int offset;
- double dnumber;
-# if defined(TRIO_BREESE)
- trio_long_double_t ldnumber;
-# endif
-#endif
- long lnumber;
- int number;
- char ch;
- char buffer[4096];
- FILE *stream;
-
-#if TRIO_FEATURE_FLOAT
- rc = trio_sscanf("1.5", "%lf%n", &dnumber, &offset);
- nerrors += Verify(__FILE__, __LINE__, "1 3 1.500000",
- "%d %d %f", rc, offset, dnumber);
-#endif
- rc = trio_sscanf("q 123", "%c%ld", &ch, &lnumber);
- nerrors += Verify(__FILE__, __LINE__, "q 123",
- "%c %ld", ch, lnumber);
- rc = trio_sscanf("abc", "%*s%n", &number);
- nerrors += Verify(__FILE__, __LINE__, "0 3",
- "%d %d", rc, number);
- rc = trio_sscanf("abc def", "%*s%n", &number);
- nerrors += Verify(__FILE__, __LINE__, "0 3",
- "%d %d", rc, number);
-#if TRIO_FEATURE_FLOAT
- rc = trio_sscanf("0.141882295971771490", "%lf", &dnumber);
- /* FIXME: Verify */
-#endif
- number = 33;
- rc = trio_sscanf("total 1", "total %d", &number);
- nerrors += Verify(__FILE__, __LINE__, "1 1",
- "%d %d", rc, number);
-#if defined(TRIO_BREESE)
-# if TRIO_FEATURE_FLOAT
- nerrors += Verify(__FILE__, __LINE__, "1 0.141882295971771488",
- "%d %.18f", rc, dnumber);
- rc = trio_sscanf("0.141882295971771490", "%Lf", &ldnumber);
- nerrors += Verify(__FILE__, __LINE__, "1 0.141882295971771490",
- "%d %.18Lf", rc, ldnumber);
-# endif
-#endif
-#if TRIO_FEATURE_FLOAT
- rc = trio_sscanf("1.e-6", "%lg", &dnumber);
- nerrors += Verify(__FILE__, __LINE__, "1e-06",
- "%g", dnumber);
- rc = trio_sscanf("1e-6", "%lg", &dnumber);
- nerrors += Verify(__FILE__, __LINE__, "1e-06",
- "%g", dnumber);
-#endif
-
- /* Do not overwrite result on matching error */
- ch = 'a';
- rc = trio_sscanf("0123456789", "%1[c]", &ch);
- nerrors += Verify(__FILE__, __LINE__, "a",
- "%c", ch);
-
- /* Scan plus prefix for unsigned integer */
- rc = trio_sscanf("+42", "%u", &number);
- nerrors += Verify(__FILE__, __LINE__, "1 42",
- "%d %u", rc, number);
-
- /* Scan minus prefix even for unsigned integer */
- rc = trio_sscanf("-42", "%u", &number);
- sprintf(buffer, "1 %u", -42U);
- nerrors += Verify(__FILE__, __LINE__, buffer,
- "%d %u", rc, number);
-
- /* A scangroup match failure should not bind its argument,
- * i.e., it shouldn't match the empty string. */
- sprintf(buffer, "SPQR");
- rc = trio_sscanf("asdf", "%[c]", buffer);
- nerrors += Verify(__FILE__, __LINE__, "0 SPQR",
- "%d %s", rc, buffer);
-
- /* Even whitespace scanning shouldn't try to read past EOF */
- stream = tmpfile();
- trio_fprintf(stream, "");
- rewind(stream);
- rc = trio_fscanf(stream, " ");
- nerrors += Verify(__FILE__, __LINE__, "0",
- "%d", rc);
- fclose(stream);
-
- /* Idem, after a succesfull read */
- stream = tmpfile();
- trio_fprintf(stream, "123");
- rewind(stream);
- rc = trio_fscanf(stream, "%i ", &number);
- nerrors += Verify(__FILE__, __LINE__, "1 123",
- "%d %i", rc, number);
- fclose(stream);
-
- /* The scanner should unget its read-ahead char */
- stream = tmpfile();
- trio_fprintf(stream, "123");
- rewind(stream);
- trio_fscanf(stream, "%*c");
- trio_fscanf(stream, "%c", &ch);
- nerrors += Verify(__FILE__, __LINE__, "2",
- "%c", ch);
- fclose(stream);
-
- return nerrors;
-}
-#endif
-
-/*************************************************************************
- *
- */
-int
-VerifyScanning(TRIO_NOARGS)
-{
- int nerrors = 0;
-#if TRIO_FEATURE_SCANF
- nerrors += VerifyScanningIntegers();
- nerrors += VerifyScanningFloats();
- nerrors += VerifyScanningStrings();
- nerrors += VerifyScanningRegression();
-#endif
- return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyStrings(TRIO_NOARGS)
-{
- int nerrors = 0;
-#if !defined(TRIO_MINIMAL)
- char buffer[512];
-#if TRIO_FEATURE_FLOAT
- double dnumber;
- float fnumber;
-#endif
- char *end;
-
- /* Comparison */
- trio_copy(buffer, "Find me now");
- if (trio_length(buffer) != sizeof("Find me now") - 1) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (!trio_equal(buffer, "Find me now")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (!trio_equal_case(buffer, "Find me now")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (trio_equal_case(buffer, "FIND ME NOW")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (!trio_equal_max(buffer, sizeof("Find me") - 1, "Find ME")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (!trio_contains(buffer, "me")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (trio_contains(buffer, "and me")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (trio_substring(buffer, "me") == NULL) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (trio_substring_max(buffer, 4, "me") != NULL) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (!trio_match(buffer, "* me *")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (trio_match_case(buffer, "* ME *")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (trio_index(buffer, 'n') == NULL) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (trio_index(buffer, '_') != NULL) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (trio_index_last(buffer, 'n') == NULL) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
-
- /* Append */
- trio_copy(buffer, "Find me now");
- if (!trio_append(buffer, " and again")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (!trio_equal(buffer, "Find me now and again")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (!trio_append_max(buffer, 0, "should not appear")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (!trio_equal(buffer, "Find me now and again")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
-
- /* To upper/lower */
- trio_copy(buffer, "Find me now");
- trio_upper(buffer);
- if (!trio_equal_case(buffer, "FIND ME NOW")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- trio_lower(buffer);
- if (!trio_equal_case(buffer, "find me now")) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
-
-#if TRIO_FEATURE_FLOAT
- /* Double conversion */
- trio_copy(buffer, "3.1415");
- dnumber = trio_to_double(buffer, NULL);
- if (!DOUBLE_EQUAL(dnumber, 3.1415)) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- fnumber = trio_to_float(buffer, NULL);
- if (!FLOAT_EQUAL(fnumber, 3.1415)) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
-#endif
-
- /* Long conversion */
- trio_copy(buffer, "3.1415");
- if (trio_to_long(buffer, NULL, 10) != 3L) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- if (trio_to_long(buffer, NULL, 4) != 3L) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
- trio_to_long(buffer, &end, 2);
- if (end != buffer) {
- nerrors++;
- Report0(__FILE__, __LINE__);
- }
-
-#endif /* !defined(TRIO_MINIMAL) */
- return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyDynamicStrings(TRIO_NOARGS)
-{
- int nerrors = 0;
-#if !defined(TRIO_MINIMAL)
- trio_string_t *string;
- const char no_terminate[5] = { 'h', 'e', 'l', 'l', 'o' };
-
- string = trio_xstring_duplicate("Find me now");
- if (string == NULL) {
- nerrors++;
- goto error;
- }
- if (!trio_xstring_equal(string, "FIND ME NOW"))
- nerrors++;
- if (!trio_xstring_append(string, " and again") ||
- !trio_xstring_equal(string, "FIND ME NOW AND AGAIN"))
- nerrors++;
- if (!trio_xstring_contains(string, "me"))
- nerrors++;
- if (trio_xstring_contains(string, "ME"))
- nerrors++;
- if (!trio_xstring_match(string, "* me *"))
- nerrors++;
- if (trio_xstring_match_case(string, "* ME *"))
- nerrors++;
- if (!trio_xstring_append_max(string, no_terminate, 5) ||
- !trio_xstring_equal(string, "FIND ME NOW AND AGAINhello"))
- nerrors++;
-
- error:
- if (string)
- trio_string_destroy(string);
-
-#endif /* !defined(TRIO_MINIMAL) */
- return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-VerifyNaN(TRIO_NOARGS)
-{
- double ninf_number = trio_ninf();
- double pinf_number = trio_pinf();
- double nan_number = trio_nan();
- int nerrors = 0;
-
- nerrors += Verify(__FILE__, __LINE__, "-1",
- "%d", trio_isinf(ninf_number));
- nerrors += Verify(__FILE__, __LINE__, "0",
- "%d", trio_isinf(42.0));
- nerrors += Verify(__FILE__, __LINE__, "1",
- "%d", trio_isinf(pinf_number));
- nerrors += Verify(__FILE__, __LINE__, "1",
- "%d", trio_isnan(nan_number));
- nerrors += Verify(__FILE__, __LINE__, "0",
- "%d", trio_isnan(42.0));
-
- return nerrors;
-}
-
-/*************************************************************************
- *
- */
-int
-main(TRIO_NOARGS)
-{
- int nerrors = 0;
-
- printf("%s\n", rcsid);
-
-#if TRIO_EXTENSION
- /* Override system locale settings */
- trio_locale_set_decimal_point(".");
- trio_locale_set_thousand_separator(",");
- trio_locale_set_grouping("\3");
-#endif
-
- printf("Verifying strings\n");
- nerrors += VerifyStrings();
-
- printf("Verifying dynamic strings\n");
- nerrors += VerifyDynamicStrings();
-
- printf("Verifying special quantities\n");
- nerrors += VerifyNaN();
-
- printf("Verifying formatting\n");
- nerrors += VerifyFormatting();
-
- printf("Verifying scanning\n");
- nerrors += VerifyScanning();
-
- printf("Verifying return values\n");
- nerrors += VerifyErrors();
- nerrors += VerifyReturnValues();
-
- printf("Verifying allocation\n");
- nerrors += VerifyAllocate();
-
- if (nerrors == 0)
- printf("Regression test succeeded\n");
- else
- printf("Regression test failed in %d instance(s)\n", nerrors);
-
- return nerrors ? 1 : 0;
-}
+++ /dev/null
-/*************************************************************************
- *
- * $Id: strio.h,v 1.11 2001/12/27 17:29:20 breese Exp $
- *
- * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************
- *
- * This maintains backwards compatibility with the strio functions.
- *
- ************************************************************************/
-
-#ifndef TRIO_STRIO_H
-#define TRIO_STRIO_H
-
-#if !(defined(DEBUG) || defined(NDEBUG))
-# define NDEBUG
-#endif
-#include "triostr.h"
-
-enum {
- STRIO_HASH_NONE = TRIO_HASH_NONE,
- STRIO_HASH_PLAIN = TRIO_HASH_PLAIN,
- STRIO_HASH_TWOSIGNED = TRIO_HASH_TWOSIGNED
-};
-
-#define StrAlloc(n) trio_create(n)
-#define StrAppend(x,y) ((void)trio_append((x),(y)),(x))
-#define StrAppendMax(x,n,y) ((void)trio_append_max((x),(n),(y)),(x))
-#define StrContains(x,y) trio_contains((x),(y))
-#define StrCopy(x,y) ((void)trio_copy((x),(y)),(x))
-#define StrCopyMax(x,n,y) ((void)trio_copy_max((x),(n),(y)),(x))
-#define StrDuplicate(x) trio_duplicate(x)
-#define StrDuplicateMax(x,n) trio_duplicate((x),(n))
-#define StrEqual(x,y) trio_equal((x),(y))
-#define StrEqualCase(x,y) trio_equal_case((x),(y))
-#define StrEqualCaseMax(x,n,y) trio_equal_case_max((x),(n),(y))
-#define StrEqualLocale(x,y) trio_equal_locale((x),(y))
-#define StrEqualMax(x,n,y) trio_equal_max((x),(n),(y))
-#define StrError(n) trio_error(n)
-#define StrFree(x) trio_destroy(x)
-#define StrFormat trio_sprintf
-#define StrFormatAlloc trio_aprintf
-#define StrFormatAppendMax trio_snprintfcat
-#define StrFormatDateMax(x,n,y,t) trio_format_date_max((x),(n),(y),(t))
-#define StrFormatMax trio_snprintf
-#define StrHash(x,n) trio_hash((x),(n))
-#define StrIndex(x,y) trio_index((x),(y))
-#define StrIndexLast(x,y) trio_index_last((x),(y))
-#define StrLength(x) trio_length((x))
-#define StrMatch(x,y) trio_match((x),(y))
-#define StrMatchCase(x,y) trio_match_case((x),(y))
-#define StrScan trio_sscanf
-#define StrSpanFunction(x,f) trio_span_function((x),(f))
-#define StrSubstring(x,y) trio_substring((x),(y))
-#define StrSubstringMax(x,n,y) trio_substring_max((x),(n),(y))
-#define StrToDouble(x,y) trio_to_double((x),(y))
-#define StrToFloat(x,y) trio_to_float((x),(y))
-#define StrTokenize(x,y) trio_tokenize((x),(y))
-#define StrToLong(x,y,n) trio_to_long((x),(y),(n))
-#define StrToUnsignedLong(x,y,n) trio_to_unsigned_long((x),(n),(y))
-#define StrToUpper(x) trio_upper(x)
-
-#endif /* TRIO_STRIO_H */
+++ /dev/null
-/*************************************************************************
- *
- * $Id: trio.c,v 1.129 2009/09/20 11:37:15 breese Exp $
- *
- * Copyright (C) 1998, 2009 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- *************************************************************************
- *
- * A note to trio contributors:
- *
- * Avoid heap allocation at all costs to ensure that the trio functions
- * are async-safe. The exceptions are the printf/fprintf functions, which
- * uses fputc, and the asprintf functions and the <alloc> modifier, which
- * by design are required to allocate form the heap.
- *
- ************************************************************************/
-
-/*
- * TODO:
- * - Scan is probably too permissive about its modifiers.
- * - C escapes in %#[] ?
- * - Multibyte characters (done for format parsing, except scan groups)
- * - Complex numbers? (C99 _Complex)
- * - Boolean values? (C99 _Bool)
- * - C99 NaN(n-char-sequence) missing. The n-char-sequence can be used
- * to print the mantissa, e.g. NaN(0xc000000000000000)
- * - Should we support the GNU %a alloc modifier? GNU has an ugly hack
- * for %a, because C99 used %a for other purposes. If specified as
- * %as or %a[ it is interpreted as the alloc modifier, otherwise as
- * the C99 hex-float. This means that you cannot scan %as as a hex-float
- * immediately followed by an 's'.
- * - Scanning of collating symbols.
- */
-
-/*************************************************************************
- * Trio include files
- */
-#include "triodef.h"
-#include "trio.h"
-#include "triop.h"
-
-#if defined(TRIO_EMBED_NAN)
-# define TRIO_PUBLIC_NAN static
-# if TRIO_FEATURE_FLOAT
-# define TRIO_FUNC_NAN
-# define TRIO_FUNC_NINF
-# define TRIO_FUNC_PINF
-# define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT
-# define TRIO_FUNC_ISINF
-# endif
-#endif
-#include "trionan.h"
-
-#if defined(TRIO_EMBED_STRING)
-# define TRIO_PUBLIC_STRING static
-# define TRIO_FUNC_LENGTH
-# define TRIO_FUNC_LENGTH_MAX
-# define TRIO_FUNC_TO_LONG
-# if TRIO_FEATURE_LOCALE
-# define TRIO_FUNC_COPY_MAX
-# endif
-# if TRIO_FEATURE_DYNAMICSTRING
-# define TRIO_FUNC_XSTRING_DUPLICATE
-# endif
-# if TRIO_EXTENSION && TRIO_FEATURE_SCANF
-# define TRIO_FUNC_EQUAL_LOCALE
-# endif
-# if TRIO_FEATURE_ERRNO
-# define TRIO_FUNC_ERROR
-# endif
-# if TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF
-# define TRIO_FUNC_TO_DOUBLE
-# endif
-# if TRIO_FEATURE_DYNAMICSTRING
-# define TRIO_FUNC_STRING_EXTRACT
-# endif
-# if TRIO_FEATURE_DYNAMICSTRING
-# define TRIO_FUNC_STRING_TERMINATE
-# endif
-# if TRIO_FEATURE_USER_DEFINED
-# define TRIO_FUNC_DUPLICATE
-# endif
-# if TRIO_FEATURE_DYNAMICSTRING
-# define TRIO_FUNC_STRING_DESTROY
-# endif
-# if TRIO_FEATURE_USER_DEFINED
-# define TRIO_FUNC_DESTROY
-# endif
-# if TRIO_FEATURE_USER_DEFINED || (TRIO_FEATURE_FLOAT && TRIO_FEATURE_SCANF)
-# define TRIO_FUNC_EQUAL
-# endif
-# if TRIO_FEATURE_USER_DEFINED || TRIO_FEATURE_SCANF
-# define TRIO_FUNC_EQUAL_CASE
-# endif
-# if (TRIO_EXTENSION && TRIO_FEATURE_SCANF)
-# define TRIO_FUNC_EQUAL_MAX
-# endif
-# if TRIO_FEATURE_SCANF
-# define TRIO_FUNC_TO_UPPER
-# endif
-# if TRIO_FEATURE_DYNAMICSTRING
-# define TRIO_FUNC_XSTRING_APPEND_CHAR
-# endif
-#endif
-#include "triostr.h"
-
-/**************************************************************************
- *
- * Definitions
- *
- *************************************************************************/
-
-#include <limits.h>
-#if TRIO_FEATURE_FLOAT
-# include <math.h>
-# include <float.h>
-#endif
-
-#if defined(__STDC_ISO_10646__) || defined(MB_LEN_MAX) || defined(USE_MULTIBYTE) || TRIO_FEATURE_WIDECHAR
-# if !defined(TRIO_PLATFORM_WINCE)
-# define TRIO_COMPILER_SUPPORTS_MULTIBYTE
-# if !defined(MB_LEN_MAX)
-# define MB_LEN_MAX 6
-# endif
-# endif
-#endif
-
-#if (TRIO_COMPILER_VISUALC - 0 >= 1100) || defined(TRIO_COMPILER_BORLAND)
-# define TRIO_COMPILER_SUPPORTS_VISUALC_INT
-#endif
-
-#if TRIO_FEATURE_FLOAT
-# if defined(PREDEF_STANDARD_C99) \
- || defined(PREDEF_STANDARD_UNIX03)
-# if !defined(HAVE_FLOORL) && !defined(TRIO_NO_FLOORL)
-# define HAVE_FLOORL
-# endif
-# if !defined(HAVE_CEILL) && !defined(TRIO_NO_CEILL)
-# define HAVE_CEILL
-# endif
-# if !defined(HAVE_POWL) && !defined(TRIO_NO_POWL)
-# define HAVE_POWL
-# endif
-# if !defined(HAVE_FMODL) && !defined(TRIO_NO_FMODL)
-# define HAVE_FMODL
-# endif
-# if !defined(HAVE_LOG10L) && !defined(TRIO_NO_LOG10L)
-# define HAVE_LOG10L
-# endif
-# endif
-# if defined(TRIO_COMPILER_VISUALC)
-# if defined(floorl)
-# define HAVE_FLOORL
-# endif
-# if defined(ceill)
-# define HAVE_CEILL
-# endif
-# if defined(powl)
-# define HAVE_POWL
-# endif
-# if defined(fmodl)
-# define HAVE_FMODL
-# endif
-# if defined(log10l)
-# define HAVE_LOG10L
-# endif
-# endif
-#endif
-
-/*************************************************************************
- * Generic definitions
- */
-
-#if !(defined(DEBUG) || defined(NDEBUG))
-# define NDEBUG
-#endif
-
-#include <assert.h>
-#include <ctype.h>
-#if defined(PREDEF_STANDARD_C99) && !defined(isascii)
-# define isascii(x) ((x) & 0x7F)
-#endif
-#if defined(TRIO_COMPILER_ANCIENT)
-# include <varargs.h>
-#else
-# include <stdarg.h>
-#endif
-#include <stddef.h>
-#if defined(TRIO_PLATFORM_WINCE)
-extern int errno;
-#else
-# include <errno.h>
-#endif
-
-#ifndef NULL
-# define NULL 0
-#endif
-#define NIL ((char)0)
-#ifndef FALSE
-# define FALSE (1 == 0)
-# define TRUE (! FALSE)
-#endif
-#define BOOLEAN_T int
-
-/* mincore() can be used for debugging purposes */
-#define VALID(x) (NULL != (x))
-
-#if TRIO_FEATURE_ERRORCODE
- /*
- * Encode the error code and the position. This is decoded
- * with TRIO_ERROR_CODE and TRIO_ERROR_POSITION.
- */
-# define TRIO_ERROR_RETURN(x,y) (- ((x) + ((y) << 8)))
-#else
-# define TRIO_ERROR_RETURN(x,y) (-1)
-#endif
-
-typedef unsigned long trio_flags_t;
-
-
-/*************************************************************************
- * Platform specific definitions
- */
-#if defined(TRIO_PLATFORM_UNIX)
-# include <unistd.h>
-# include <signal.h>
-# include <locale.h>
-# if !defined(TRIO_FEATURE_LOCALE)
-# define USE_LOCALE
-# endif
-#endif /* TRIO_PLATFORM_UNIX */
-#if defined(TRIO_PLATFORM_VMS)
-# include <unistd.h>
-#endif
-#if defined(TRIO_PLATFORM_WIN32)
-# if defined(TRIO_PLATFORM_WINCE)
-int read(int handle, char *buffer, unsigned int length);
-int write(int handle, const char *buffer, unsigned int length);
-# else
-# include <io.h>
-# define read _read
-# define write _write
-# endif
-#endif /* TRIO_PLATFORM_WIN32 */
-
-#if TRIO_FEATURE_WIDECHAR
-# if defined(PREDEF_STANDARD_C94)
-# include <wchar.h>
-# include <wctype.h>
-typedef wchar_t trio_wchar_t;
-typedef wint_t trio_wint_t;
-# else
-typedef char trio_wchar_t;
-typedef int trio_wint_t;
-# define WCONST(x) L ## x
-# define WEOF EOF
-# define iswalnum(x) isalnum(x)
-# define iswalpha(x) isalpha(x)
-# define iswcntrl(x) iscntrl(x)
-# define iswdigit(x) isdigit(x)
-# define iswgraph(x) isgraph(x)
-# define iswlower(x) islower(x)
-# define iswprint(x) isprint(x)
-# define iswpunct(x) ispunct(x)
-# define iswspace(x) isspace(x)
-# define iswupper(x) isupper(x)
-# define iswxdigit(x) isxdigit(x)
-# endif
-#endif
-
-
-/*************************************************************************
- * Compiler dependent definitions
- */
-
-/* Support for long long */
-#ifndef __cplusplus
-# if !defined(USE_LONGLONG)
-# if defined(TRIO_COMPILER_GCC) && !defined(__STRICT_ANSI__)
-# define USE_LONGLONG
-# else
-# if defined(TRIO_COMPILER_SUNPRO)
-# define USE_LONGLONG
-# else
-# if defined(TRIO_COMPILER_MSVC) && (_MSC_VER >= 1400)
-# define USE_LONGLONG
-# else
-# if defined(_LONG_LONG) || defined(_LONGLONG)
-# define USE_LONGLONG
-# endif
-# endif
-# endif
-# endif
-# endif
-#endif
-
-/* The extra long numbers */
-#if defined(USE_LONGLONG)
-typedef signed long long int trio_longlong_t;
-typedef unsigned long long int trio_ulonglong_t;
-#else
-# if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT)
-typedef signed __int64 trio_longlong_t;
-typedef unsigned __int64 trio_ulonglong_t;
-# else
-typedef TRIO_SIGNED long int trio_longlong_t;
-typedef unsigned long int trio_ulonglong_t;
-# endif
-#endif
-
-/* Maximal and fixed integer types */
-#if defined(PREDEF_STANDARD_C99)
-# include <stdint.h>
-typedef intmax_t trio_intmax_t;
-typedef uintmax_t trio_uintmax_t;
-typedef int8_t trio_int8_t;
-typedef int16_t trio_int16_t;
-typedef int32_t trio_int32_t;
-typedef int64_t trio_int64_t;
-#else
-# if defined(PREDEF_STANDARD_UNIX98)
-# include <inttypes.h>
-typedef intmax_t trio_intmax_t;
-typedef uintmax_t trio_uintmax_t;
-typedef int8_t trio_int8_t;
-typedef int16_t trio_int16_t;
-typedef int32_t trio_int32_t;
-typedef int64_t trio_int64_t;
-# else
-# if defined(TRIO_COMPILER_SUPPORTS_VISUALC_INT)
-typedef trio_longlong_t trio_intmax_t;
-typedef trio_ulonglong_t trio_uintmax_t;
-typedef __int8 trio_int8_t;
-typedef __int16 trio_int16_t;
-typedef __int32 trio_int32_t;
-typedef __int64 trio_int64_t;
-# else
-typedef trio_longlong_t trio_intmax_t;
-typedef trio_ulonglong_t trio_uintmax_t;
-# if defined(TRIO_INT8_T)
-typedef TRIO_INT8_T trio_int8_t;
-# else
-typedef TRIO_SIGNED char trio_int8_t;
-# endif
-# if defined(TRIO_INT16_T)
-typedef TRIO_INT16_T trio_int16_t;
-# else
-typedef TRIO_SIGNED short trio_int16_t;
-# endif
-# if defined(TRIO_INT32_T)
-typedef TRIO_INT32_T trio_int32_t;
-# else
-typedef TRIO_SIGNED int trio_int32_t;
-# endif
-# if defined(TRIO_INT64_T)
-typedef TRIO_INT64_T trio_int64_t;
-# else
-typedef trio_longlong_t trio_int64_t;
-# endif
-# endif
-# endif
-#endif
-
-#if defined(HAVE_FLOORL)
-# define trio_floor(x) floorl((x))
-#else
-# define trio_floor(x) floor((double)(x))
-#endif
-
-#if defined(HAVE_CEILL)
-# define trio_ceil(x) ceill((x))
-#else
-# define trio_ceil(x) ceil((double)(x))
-#endif
-
-#if defined(HAVE_FMODL)
-# define trio_fmod(x,y) fmodl((x),(y))
-#else
-# define trio_fmod(x,y) fmod((double)(x),(double)(y))
-#endif
-
-#if defined(HAVE_POWL)
-# define trio_pow(x,y) powl((x),(y))
-#else
-# define trio_pow(x,y) pow((double)(x),(double)(y))
-#endif
-
-#if defined(HAVE_LOG10L)
-# define trio_log10(x) log10l((x))
-#else
-# define trio_log10(x) log10((double)(x))
-#endif
-
-#if TRIO_FEATURE_FLOAT
-# define TRIO_FABS(x) (((x) < 0.0) ? -(x) : (x))
-#endif
-
-/*************************************************************************
- * Internal Definitions
- */
-
-#if TRIO_FEATURE_FLOAT
-
-# if !defined(DECIMAL_DIG)
-# define DECIMAL_DIG DBL_DIG
-# endif
-
-/* Long double sizes */
-# ifdef LDBL_DIG
-# define MAX_MANTISSA_DIGITS LDBL_DIG
-# define MAX_EXPONENT_DIGITS 4
-# define MAX_DOUBLE_DIGITS LDBL_MAX_10_EXP
-# else
-# define MAX_MANTISSA_DIGITS DECIMAL_DIG
-# define MAX_EXPONENT_DIGITS 3
-# define MAX_DOUBLE_DIGITS DBL_MAX_10_EXP
-# endif
-
-# if defined(TRIO_COMPILER_ANCIENT) || !defined(LDBL_DIG)
-# undef LDBL_DIG
-# undef LDBL_MANT_DIG
-# undef LDBL_EPSILON
-# define LDBL_DIG DBL_DIG
-# define LDBL_MANT_DIG DBL_MANT_DIG
-# define LDBL_EPSILON DBL_EPSILON
-# endif
-
-#endif /* TRIO_FEATURE_FLOAT */
-
-/* The maximal number of digits is for base 2 */
-#define MAX_CHARS_IN(x) (sizeof(x) * CHAR_BIT)
-/* The width of a pointer. The number of bits in a hex digit is 4 */
-#define POINTER_WIDTH ((sizeof("0x") - 1) + sizeof(trio_pointer_t) * CHAR_BIT / 4)
-
-#if TRIO_FEATURE_FLOAT
-/* Infinite and Not-A-Number for floating-point */
-# define INFINITE_LOWER "inf"
-# define INFINITE_UPPER "INF"
-# define LONG_INFINITE_LOWER "infinite"
-# define LONG_INFINITE_UPPER "INFINITE"
-# define NAN_LOWER "nan"
-# define NAN_UPPER "NAN"
-#endif
-
-/* Various constants */
-enum {
- TYPE_PRINT = 1,
-#if TRIO_FEATURE_SCANF
- TYPE_SCAN = 2,
-#endif
-
- /* Flags. FLAGS_LAST must be less than ULONG_MAX */
- FLAGS_NEW = 0,
- FLAGS_STICKY = 1,
- FLAGS_SPACE = 2 * FLAGS_STICKY,
- FLAGS_SHOWSIGN = 2 * FLAGS_SPACE,
- FLAGS_LEFTADJUST = 2 * FLAGS_SHOWSIGN,
- FLAGS_ALTERNATIVE = 2 * FLAGS_LEFTADJUST,
- FLAGS_SHORT = 2 * FLAGS_ALTERNATIVE,
- FLAGS_SHORTSHORT = 2 * FLAGS_SHORT,
- FLAGS_LONG = 2 * FLAGS_SHORTSHORT,
- FLAGS_QUAD = 2 * FLAGS_LONG,
- FLAGS_LONGDOUBLE = 2 * FLAGS_QUAD,
- FLAGS_SIZE_T = 2 * FLAGS_LONGDOUBLE,
- FLAGS_PTRDIFF_T = 2 * FLAGS_SIZE_T,
- FLAGS_INTMAX_T = 2 * FLAGS_PTRDIFF_T,
- FLAGS_NILPADDING = 2 * FLAGS_INTMAX_T,
- FLAGS_UNSIGNED = 2 * FLAGS_NILPADDING,
- FLAGS_UPPER = 2 * FLAGS_UNSIGNED,
- FLAGS_WIDTH = 2 * FLAGS_UPPER,
- FLAGS_WIDTH_PARAMETER = 2 * FLAGS_WIDTH,
- FLAGS_PRECISION = 2 * FLAGS_WIDTH_PARAMETER,
- FLAGS_PRECISION_PARAMETER = 2 * FLAGS_PRECISION,
- FLAGS_BASE = 2 * FLAGS_PRECISION_PARAMETER,
- FLAGS_BASE_PARAMETER = 2 * FLAGS_BASE,
- FLAGS_FLOAT_E = 2 * FLAGS_BASE_PARAMETER,
- FLAGS_FLOAT_G = 2 * FLAGS_FLOAT_E,
- FLAGS_QUOTE = 2 * FLAGS_FLOAT_G,
- FLAGS_WIDECHAR = 2 * FLAGS_QUOTE,
- FLAGS_IGNORE = 2 * FLAGS_WIDECHAR,
- FLAGS_IGNORE_PARAMETER = 2 * FLAGS_IGNORE,
- FLAGS_VARSIZE_PARAMETER = 2 * FLAGS_IGNORE_PARAMETER,
- FLAGS_FIXED_SIZE = 2 * FLAGS_VARSIZE_PARAMETER,
- FLAGS_LAST = FLAGS_FIXED_SIZE,
- /* Reused flags */
- FLAGS_EXCLUDE = FLAGS_SHORT,
- FLAGS_USER_DEFINED = FLAGS_IGNORE,
- FLAGS_USER_DEFINED_PARAMETER = FLAGS_IGNORE_PARAMETER,
- FLAGS_ROUNDING = FLAGS_INTMAX_T,
- /* Compounded flags */
- FLAGS_ALL_VARSIZES = FLAGS_LONG | FLAGS_QUAD | FLAGS_INTMAX_T | FLAGS_PTRDIFF_T | FLAGS_SIZE_T,
- FLAGS_ALL_SIZES = FLAGS_ALL_VARSIZES | FLAGS_SHORTSHORT | FLAGS_SHORT,
-
- NO_POSITION = -1,
- NO_WIDTH = 0,
- NO_PRECISION = -1,
- NO_SIZE = -1,
-
- /* Do not change these */
- NO_BASE = -1,
- MIN_BASE = 2,
- MAX_BASE = 36,
- BASE_BINARY = 2,
- BASE_OCTAL = 8,
- BASE_DECIMAL = 10,
- BASE_HEX = 16,
-
- /* Maximal number of allowed parameters */
- MAX_PARAMETERS = 64,
- /* Maximal number of characters in class */
- MAX_CHARACTER_CLASS = UCHAR_MAX + 1,
-
-#if TRIO_FEATURE_USER_DEFINED
- /* Maximal string lengths for user-defined specifiers */
- MAX_USER_NAME = 64,
- MAX_USER_DATA = 256,
-#endif
-
- /* Maximal length of locale separator strings */
- MAX_LOCALE_SEPARATOR_LENGTH = MB_LEN_MAX,
- /* Maximal number of integers in grouping */
- MAX_LOCALE_GROUPS = 64
-};
-
-#define NO_GROUPING ((int)CHAR_MAX)
-
-/* Fundamental formatting parameter types */
-#define FORMAT_SENTINEL -1 /* marks end of parameters array */
-#define FORMAT_UNKNOWN 0
-#define FORMAT_INT 1
-#define FORMAT_DOUBLE 2
-#define FORMAT_CHAR 3
-#define FORMAT_STRING 4
-#define FORMAT_POINTER 5
-#define FORMAT_COUNT 6
-#define FORMAT_PARAMETER 7
-#define FORMAT_GROUP 8
-#define FORMAT_ERRNO 9
-#define FORMAT_USER_DEFINED 10
-
-/* Character constants */
-#define CHAR_IDENTIFIER '%'
-#define CHAR_ALT_IDENTIFIER '$'
-#define CHAR_BACKSLASH '\\'
-#define CHAR_QUOTE '\"'
-#define CHAR_ADJUST ' '
-
-#if TRIO_EXTENSION
-/* Character class expressions */
-# define CLASS_ALNUM "[:alnum:]"
-# define CLASS_ALPHA "[:alpha:]"
-# define CLASS_BLANK "[:blank:]"
-# define CLASS_CNTRL "[:cntrl:]"
-# define CLASS_DIGIT "[:digit:]"
-# define CLASS_GRAPH "[:graph:]"
-# define CLASS_LOWER "[:lower:]"
-# define CLASS_PRINT "[:print:]"
-# define CLASS_PUNCT "[:punct:]"
-# define CLASS_SPACE "[:space:]"
-# define CLASS_UPPER "[:upper:]"
-# define CLASS_XDIGIT "[:xdigit:]"
-#endif
-
-/*
- * SPECIFIERS:
- *
- *
- * a Hex-float
- * A Hex-float
- * c Character
- * C Widechar character (wint_t)
- * d Decimal
- * e Float
- * E Float
- * F Float
- * F Float
- * g Float
- * G Float
- * i Integer
- * m Error message
- * n Count
- * o Octal
- * p Pointer
- * s String
- * S Widechar string (wchar_t *)
- * u Unsigned
- * x Hex
- * X Hex
- * [] Group
- * <> User-defined
- *
- * Reserved:
- *
- * D Binary Coded Decimal %D(length,precision) (OS/390)
- */
-#define SPECIFIER_CHAR 'c'
-#define SPECIFIER_STRING 's'
-#define SPECIFIER_DECIMAL 'd'
-#define SPECIFIER_INTEGER 'i'
-#define SPECIFIER_UNSIGNED 'u'
-#define SPECIFIER_OCTAL 'o'
-#define SPECIFIER_HEX 'x'
-#define SPECIFIER_HEX_UPPER 'X'
-#if TRIO_FEATURE_FLOAT
-# define SPECIFIER_FLOAT_E 'e'
-# define SPECIFIER_FLOAT_E_UPPER 'E'
-# define SPECIFIER_FLOAT_F 'f'
-# define SPECIFIER_FLOAT_F_UPPER 'F'
-# define SPECIFIER_FLOAT_G 'g'
-# define SPECIFIER_FLOAT_G_UPPER 'G'
-#endif
-#define SPECIFIER_POINTER 'p'
-#if TRIO_FEATURE_SCANF
-# define SPECIFIER_GROUP '['
-# define SPECIFIER_UNGROUP ']'
-#endif
-#define SPECIFIER_COUNT 'n'
-#if TRIO_UNIX98
-# define SPECIFIER_CHAR_UPPER 'C'
-# define SPECIFIER_STRING_UPPER 'S'
-#endif
-#define SPECIFIER_HEXFLOAT 'a'
-#define SPECIFIER_HEXFLOAT_UPPER 'A'
-#define SPECIFIER_ERRNO 'm'
-#if TRIO_FEATURE_BINARY
-# define SPECIFIER_BINARY 'b'
-# define SPECIFIER_BINARY_UPPER 'B'
-#endif
-#if TRIO_FEATURE_USER_DEFINED
-# define SPECIFIER_USER_DEFINED_BEGIN '<'
-# define SPECIFIER_USER_DEFINED_END '>'
-# define SPECIFIER_USER_DEFINED_SEPARATOR ':'
-# define SPECIFIER_USER_DEFINED_EXTRA '|'
-#endif
-
-/*
- * QUALIFIERS:
- *
- *
- * Numbers = d,i,o,u,x,X
- * Float = a,A,e,E,f,F,g,G
- * String = s
- * Char = c
- *
- *
- * 9$ Position
- * Use the 9th parameter. 9 can be any number between 1 and
- * the maximal argument
- *
- * 9 Width
- * Set width to 9. 9 can be any number, but must not be postfixed
- * by '$'
- *
- * h Short
- * Numbers:
- * (unsigned) short int
- *
- * hh Short short
- * Numbers:
- * (unsigned) char
- *
- * l Long
- * Numbers:
- * (unsigned) long int
- * String:
- * as the S specifier
- * Char:
- * as the C specifier
- *
- * ll Long Long
- * Numbers:
- * (unsigned) long long int
- *
- * L Long Double
- * Float
- * long double
- *
- * # Alternative
- * Float:
- * Decimal-point is always present
- * String:
- * non-printable characters are handled as \number
- *
- * Spacing
- *
- * + Sign
- *
- * - Alignment
- *
- * . Precision
- *
- * * Parameter
- * print: use parameter
- * scan: no parameter (ignore)
- *
- * q Quad
- *
- * Z size_t
- *
- * w Widechar
- *
- * ' Thousands/quote
- * Numbers:
- * Integer part grouped in thousands
- * Binary numbers:
- * Number grouped in nibbles (4 bits)
- * String:
- * Quoted string
- *
- * j intmax_t
- * t prtdiff_t
- * z size_t
- *
- * ! Sticky
- * @ Parameter (for both print and scan)
- *
- * I n-bit Integer
- * Numbers:
- * The following options exists
- * I8 = 8-bit integer
- * I16 = 16-bit integer
- * I32 = 32-bit integer
- * I64 = 64-bit integer
- */
-#define QUALIFIER_POSITION '$'
-#define QUALIFIER_SHORT 'h'
-#define QUALIFIER_LONG 'l'
-#define QUALIFIER_LONG_UPPER 'L'
-#define QUALIFIER_ALTERNATIVE '#'
-#define QUALIFIER_SPACE ' '
-#define QUALIFIER_PLUS '+'
-#define QUALIFIER_MINUS '-'
-#define QUALIFIER_DOT '.'
-#define QUALIFIER_STAR '*'
-#define QUALIFIER_CIRCUMFLEX '^' /* For scanlists */
-#define QUALIFIER_SIZE_T 'z'
-#define QUALIFIER_PTRDIFF_T 't'
-#define QUALIFIER_INTMAX_T 'j'
-#define QUALIFIER_QUAD 'q'
-#define QUALIFIER_SIZE_T_UPPER 'Z'
-#if TRIO_MISC
-# define QUALIFIER_WIDECHAR 'w'
-#endif
-#define QUALIFIER_FIXED_SIZE 'I'
-#define QUALIFIER_QUOTE '\''
-#define QUALIFIER_STICKY '!'
-#define QUALIFIER_VARSIZE '&' /* This should remain undocumented */
-#define QUALIFIER_ROUNDING_UPPER 'R'
-#if TRIO_EXTENSION
-# define QUALIFIER_PARAM '@' /* Experimental */
-# define QUALIFIER_COLON ':' /* For scanlists */
-# define QUALIFIER_EQUAL '=' /* For scanlists */
-#endif
-
-
-/*************************************************************************
- *
- * Internal Structures
- *
- *************************************************************************/
-
-/* Parameters */
-typedef struct {
- /* An indication of which entry in the data union is used */
- int type;
- /* The flags */
- trio_flags_t flags;
- /* The width qualifier */
- int width;
- /* The precision qualifier */
- int precision;
- /* The base qualifier */
- int base;
- /* Base from specifier */
- int baseSpecifier;
- /* The size for the variable size qualifier */
- int varsize;
- /* Offset of the first character of the specifier */
- int beginOffset;
- /* Offset of the first character after the specifier */
- int endOffset;
- /* Position in the argument list that this parameter refers to */
- int position;
- /* The data from the argument list */
- union {
- char *string;
-#if TRIO_FEATURE_WIDECHAR
- trio_wchar_t *wstring;
-#endif
- trio_pointer_t pointer;
- union {
- trio_intmax_t as_signed;
- trio_uintmax_t as_unsigned;
- } number;
-#if TRIO_FEATURE_FLOAT
- double doubleNumber;
- double *doublePointer;
- trio_long_double_t longdoubleNumber;
- trio_long_double_t *longdoublePointer;
-#endif
- int errorNumber;
- } data;
-#if TRIO_FEATURE_USER_DEFINED
- /* For the user-defined specifier */
- union {
- char namespace[MAX_USER_NAME];
- int handler; /* if flags & FLAGS_USER_DEFINED_PARAMETER */
- } user_defined;
- char user_data[MAX_USER_DATA];
-#endif
-} trio_parameter_t;
-
-/* Container for customized functions */
-typedef struct {
- union {
- trio_outstream_t out;
- trio_instream_t in;
- } stream;
- trio_pointer_t closure;
-} trio_custom_t;
-
-/* General trio "class" */
-typedef struct _trio_class_t {
- /*
- * The function to write characters to a stream.
- */
- void (*OutStream) TRIO_PROTO((struct _trio_class_t *, int));
- /*
- * The function to read characters from a stream.
- */
- void (*InStream) TRIO_PROTO((struct _trio_class_t *, int *));
- /*
- * The function to undo read characters from a stream.
- */
- void (*UndoStream) TRIO_PROTO((struct _trio_class_t *));
- /*
- * The current location in the stream.
- */
- trio_pointer_t location;
- /*
- * The character currently being processed.
- */
- int current;
- /*
- * The number of characters that would have been written/read
- * if there had been sufficient space.
- */
- int processed;
- union {
- /*
- * The number of characters that are actually written. Processed and
- * committed will only differ for the *nprintf functions.
- */
- int committed;
- /*
- * The number of look-ahead characters read.
- */
- int cached;
- } actually;
- /*
- * The upper limit of characters that may be written/read.
- */
- int max;
- /*
- * The last output error that was detected.
- */
- int error;
-} trio_class_t;
-
-/* References (for user-defined callbacks) */
-typedef struct _trio_reference_t {
- trio_class_t *data;
- trio_parameter_t *parameter;
-} trio_reference_t;
-
-#if TRIO_FEATURE_USER_DEFINED
-/* Registered entries (for user-defined callbacks) */
-typedef struct _trio_userdef_t {
- struct _trio_userdef_t *next;
- trio_callback_t callback;
- char *name;
-} trio_userdef_t;
-#endif
-
-/*************************************************************************
- *
- * Internal Variables
- *
- *************************************************************************/
-
-static TRIO_CONST char rcsid[] = "@(#)$Id: trio.c,v 1.129 2009/09/20 11:37:15 breese Exp $";
-
-#if TRIO_FEATURE_FLOAT
-/*
- * Need this to workaround a parser bug in HP C/iX compiler that fails
- * to resolves macro definitions that includes type 'long double',
- * e.g: va_arg(arg_ptr, long double)
- */
-# if defined(TRIO_PLATFORM_MPEIX)
-static TRIO_CONST trio_long_double_t ___dummy_long_double = 0;
-# endif
-#endif
-
-static TRIO_CONST char internalNullString[] = "(nil)";
-
-#if defined(USE_LOCALE)
-static struct lconv *internalLocaleValues = NULL;
-#endif
-
-/*
- * UNIX98 says "in a locale where the radix character is not defined,
- * the radix character defaults to a period (.)"
- */
-#if TRIO_FEATURE_FLOAT || TRIO_FEATURE_LOCALE || defined(USE_LOCALE)
-static int internalDecimalPointLength = 1;
-static char internalDecimalPoint = '.';
-static char internalDecimalPointString[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ".";
-#endif
-#if TRIO_FEATURE_QUOTE || TRIO_FEATURE_LOCALE || TRIO_EXTENSION
-static int internalThousandSeparatorLength = 1;
-static char internalThousandSeparator[MAX_LOCALE_SEPARATOR_LENGTH + 1] = ",";
-static char internalGrouping[MAX_LOCALE_GROUPS] = { (char)NO_GROUPING };
-#endif
-
-static TRIO_CONST char internalDigitsLower[] = "0123456789abcdefghijklmnopqrstuvwxyz";
-static TRIO_CONST char internalDigitsUpper[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-#if TRIO_FEATURE_SCANF
-static BOOLEAN_T internalDigitsUnconverted = TRUE;
-static int internalDigitArray[128];
-# if TRIO_EXTENSION
-static BOOLEAN_T internalCollationUnconverted = TRUE;
-static char internalCollationArray[MAX_CHARACTER_CLASS][MAX_CHARACTER_CLASS];
-# endif
-#endif
-
-#if TRIO_FEATURE_USER_DEFINED
-static TRIO_VOLATILE trio_callback_t internalEnterCriticalRegion = NULL;
-static TRIO_VOLATILE trio_callback_t internalLeaveCriticalRegion = NULL;
-static trio_userdef_t *internalUserDef = NULL;
-#endif
-
-
-/*************************************************************************
- *
- * Internal Functions
- *
- ************************************************************************/
-
-#if defined(TRIO_EMBED_NAN)
-# include "trionan.c"
-#endif
-
-#if defined(TRIO_EMBED_STRING)
-# include "triostr.c"
-#endif
-
-/*************************************************************************
- * TrioInitializeParameter
- *
- * Description:
- * Initialize a trio_parameter_t struct.
- */
-TRIO_PRIVATE void
-TrioInitializeParameter
-TRIO_ARGS1((parameter),
- trio_parameter_t *parameter)
-{
- parameter->type = FORMAT_UNKNOWN;
- parameter->flags = 0;
- parameter->width = 0;
- parameter->precision = 0;
- parameter->base = 0;
- parameter->baseSpecifier = 0;
- parameter->varsize = 0;
- parameter->beginOffset = 0;
- parameter->endOffset = 0;
- parameter->position = 0;
- parameter->data.pointer = 0;
-#if TRIO_FEATURE_USER_DEFINED
- parameter->user_defined.handler = 0;
- parameter->user_data[0] = 0;
-#endif
-}
-
-/*************************************************************************
- * TrioCopyParameter
- *
- * Description:
- * Copies one trio_parameter_t struct to another.
- */
-TRIO_PRIVATE void
-TrioCopyParameter
-TRIO_ARGS2((target, source),
- trio_parameter_t *target,
- TRIO_CONST trio_parameter_t *source)
-{
-#if TRIO_FEATURE_USER_DEFINED
- size_t i;
-#endif
-
- target->type = source->type;
- target->flags = source->flags;
- target->width = source->width;
- target->precision = source->precision;
- target->base = source->base;
- target->baseSpecifier = source->baseSpecifier;
- target->varsize = source->varsize;
- target->beginOffset = source->beginOffset;
- target->endOffset = source->endOffset;
- target->position = source->position;
- target->data = source->data;
-
-#if TRIO_FEATURE_USER_DEFINED
- target->user_defined = source->user_defined;
-
- for (i = 0U; i < sizeof(target->user_data); ++i)
- {
- if ((target->user_data[i] = source->user_data[i]) == NIL)
- break;
- }
-#endif
-}
-
-/*************************************************************************
- * TrioIsQualifier
- *
- * Description:
- * Remember to add all new qualifiers to this function.
- * QUALIFIER_POSITION must not be added.
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioIsQualifier
-TRIO_ARGS1((character),
- TRIO_CONST char character)
-{
- /* QUALIFIER_POSITION is not included */
- switch (character)
- {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case QUALIFIER_PLUS:
- case QUALIFIER_MINUS:
- case QUALIFIER_SPACE:
- case QUALIFIER_DOT:
- case QUALIFIER_STAR:
- case QUALIFIER_ALTERNATIVE:
- case QUALIFIER_SHORT:
- case QUALIFIER_LONG:
- case QUALIFIER_CIRCUMFLEX:
- case QUALIFIER_LONG_UPPER:
- case QUALIFIER_SIZE_T:
- case QUALIFIER_PTRDIFF_T:
- case QUALIFIER_INTMAX_T:
- case QUALIFIER_QUAD:
- case QUALIFIER_SIZE_T_UPPER:
-#if defined(QUALIFIER_WIDECHAR)
- case QUALIFIER_WIDECHAR:
-#endif
- case QUALIFIER_QUOTE:
- case QUALIFIER_STICKY:
- case QUALIFIER_VARSIZE:
-#if defined(QUALIFIER_PARAM)
- case QUALIFIER_PARAM:
-#endif
- case QUALIFIER_FIXED_SIZE:
- case QUALIFIER_ROUNDING_UPPER:
- return TRUE;
- default:
- return FALSE;
- }
-}
-
-/*************************************************************************
- * TrioSetLocale
- */
-#if defined(USE_LOCALE)
-TRIO_PRIVATE void
-TrioSetLocale(TRIO_NOARGS)
-{
- internalLocaleValues = (struct lconv *)localeconv();
- if (internalLocaleValues)
- {
- if ((internalLocaleValues->decimal_point) &&
- (internalLocaleValues->decimal_point[0] != NIL))
- {
- internalDecimalPointLength = trio_length(internalLocaleValues->decimal_point);
- if (internalDecimalPointLength == 1)
- {
- internalDecimalPoint = internalLocaleValues->decimal_point[0];
- }
- else
- {
- internalDecimalPoint = NIL;
- trio_copy_max(internalDecimalPointString,
- sizeof(internalDecimalPointString),
- internalLocaleValues->decimal_point);
- }
- }
-# if TRIO_EXTENSION
- if ((internalLocaleValues->thousands_sep) &&
- (internalLocaleValues->thousands_sep[0] != NIL))
- {
- trio_copy_max(internalThousandSeparator,
- sizeof(internalThousandSeparator),
- internalLocaleValues->thousands_sep);
- internalThousandSeparatorLength = trio_length(internalThousandSeparator);
- }
-# endif
-# if TRIO_EXTENSION
- if ((internalLocaleValues->grouping) &&
- (internalLocaleValues->grouping[0] != NIL))
- {
- trio_copy_max(internalGrouping,
- sizeof(internalGrouping),
- internalLocaleValues->grouping);
- }
-# endif
- }
-}
-#endif /* defined(USE_LOCALE) */
-
-#if TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE
-TRIO_PRIVATE int
-TrioCalcThousandSeparatorLength
-TRIO_ARGS1((digits),
- int digits)
-{
- int count = 0;
- int step = NO_GROUPING;
- char *groupingPointer = internalGrouping;
-
- while (digits > 0)
- {
- if (*groupingPointer == CHAR_MAX)
- {
- /* Disable grouping */
- break; /* while */
- }
- else if (*groupingPointer == 0)
- {
- /* Repeat last group */
- if (step == NO_GROUPING)
- {
- /* Error in locale */
- break; /* while */
- }
- }
- else
- {
- step = *groupingPointer++;
- }
- if (digits > step)
- count += internalThousandSeparatorLength;
- digits -= step;
- }
- return count;
-}
-#endif /* TRIO_FEATURE_FLOAT && TRIO_FEATURE_QUOTE */
-
-#if TRIO_FEATURE_QUOTE
-TRIO_PRIVATE BOOLEAN_T
-TrioFollowedBySeparator
-TRIO_ARGS1((position),
- int position)
-{
- int step = 0;
- char *groupingPointer = internalGrouping;
-
- position--;
- if (position == 0)
- return FALSE;
- while (position > 0)
- {
- if (*groupingPointer == CHAR_MAX)
- {
- /* Disable grouping */
- break; /* while */
- }
- else if (*groupingPointer != 0)
- {
- step = *groupingPointer++;
- }
- if (step == 0)
- break;
- position -= step;
- }
- return (position == 0);
-}
-#endif /* TRIO_FEATURE_QUOTE */
-
-/*************************************************************************
- * TrioGetPosition
- *
- * Get the %n$ position.
- */
-TRIO_PRIVATE int
-TrioGetPosition
-TRIO_ARGS2((format, offsetPointer),
- TRIO_CONST char *format,
- int *offsetPointer)
-{
-#if TRIO_FEATURE_POSITIONAL
- char *tmpformat;
- int number = 0;
- int offset = *offsetPointer;
-
- number = (int)trio_to_long(&format[offset], &tmpformat, BASE_DECIMAL);
- offset = (int)(tmpformat - format);
- if ((number != 0) && (QUALIFIER_POSITION == format[offset++]))
- {
- *offsetPointer = offset;
- /*
- * number is decreased by 1, because n$ starts from 1, whereas
- * the array it is indexing starts from 0.
- */
- return number - 1;
- }
-#endif
- return NO_POSITION;
-}
-
-/*************************************************************************
- * TrioFindNamespace
- *
- * Find registered user-defined specifier.
- * The prev argument is used for optimization only.
- */
-#if TRIO_FEATURE_USER_DEFINED
-TRIO_PRIVATE trio_userdef_t *
-TrioFindNamespace
-TRIO_ARGS2((name, prev),
- TRIO_CONST char *name,
- trio_userdef_t **prev)
-{
- trio_userdef_t *def;
-
- if (internalEnterCriticalRegion)
- (void)internalEnterCriticalRegion(NULL);
-
- for (def = internalUserDef; def; def = def->next)
- {
- /* Case-sensitive string comparison */
- if (trio_equal_case(def->name, name))
- break;
-
- if (prev)
- *prev = def;
- }
-
- if (internalLeaveCriticalRegion)
- (void)internalLeaveCriticalRegion(NULL);
-
- return def;
-}
-#endif
-
-/*************************************************************************
- * TrioPower
- *
- * Description:
- * Calculate pow(base, exponent), where number and exponent are integers.
- */
-#if TRIO_FEATURE_FLOAT
-TRIO_PRIVATE trio_long_double_t
-TrioPower
-TRIO_ARGS2((number, exponent),
- int number,
- int exponent)
-{
- trio_long_double_t result;
-
- if (number == 10)
- {
- switch (exponent)
- {
- /* Speed up calculation of common cases */
- case 0:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E-1);
- break;
- case 1:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+0);
- break;
- case 2:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+1);
- break;
- case 3:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+2);
- break;
- case 4:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+3);
- break;
- case 5:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+4);
- break;
- case 6:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+5);
- break;
- case 7:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+6);
- break;
- case 8:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+7);
- break;
- case 9:
- result = (trio_long_double_t)number * TRIO_SUFFIX_LONG(1E+8);
- break;
- default:
- result = trio_pow((trio_long_double_t)number,
- (trio_long_double_t)exponent);
- break;
- }
- }
- else
- {
- return trio_pow((trio_long_double_t)number,
- (trio_long_double_t)exponent);
- }
- return result;
-}
-#endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * TrioLogarithm
- */
-#if TRIO_FEATURE_FLOAT
-TRIO_PRIVATE trio_long_double_t
-TrioLogarithm
-TRIO_ARGS2((number, base),
- trio_long_double_t number,
- int base)
-{
- trio_long_double_t result;
-
- if (number <= 0.0)
- {
- /* xlC crashes on log(0) */
- result = (number == 0.0) ? trio_ninf() : trio_nan();
- }
- else
- {
- if (base == 10)
- {
- result = trio_log10(number);
- }
- else
- {
- result = trio_log10(number) / trio_log10((double)base);
- }
- }
- return result;
-}
-#endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * TrioLogarithmBase
- */
-#if TRIO_FEATURE_FLOAT
-TRIO_PRIVATE double
-TrioLogarithmBase
-TRIO_ARGS1((base),
- int base)
-{
- switch (base)
- {
- case BASE_BINARY : return 1.0;
- case BASE_OCTAL : return 3.0;
- case BASE_DECIMAL: return 3.321928094887362345;
- case BASE_HEX : return 4.0;
- default : return TrioLogarithm((double)base, 2);
- }
-}
-#endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * TrioParseQualifiers
- *
- * Description:
- * Parse the qualifiers of a potential conversion specifier
- */
-TRIO_PRIVATE int
-TrioParseQualifiers
-TRIO_ARGS4((type, format, offset, parameter),
- int type,
- TRIO_CONST char *format,
- int offset,
- trio_parameter_t *parameter)
-{
- char ch;
- int dots = 0; /* Count number of dots in modifier part */
- char *tmpformat;
-
- parameter->beginOffset = offset - 1;
- parameter->flags = FLAGS_NEW;
- parameter->position = TrioGetPosition(format, &offset);
-
- /* Default values */
- parameter->width = NO_WIDTH;
- parameter->precision = NO_PRECISION;
- parameter->base = NO_BASE;
- parameter->varsize = NO_SIZE;
-
- while (TrioIsQualifier(format[offset]))
- {
- ch = format[offset++];
-
- switch (ch)
- {
- case QUALIFIER_SPACE:
- parameter->flags |= FLAGS_SPACE;
- break;
-
- case QUALIFIER_PLUS:
- parameter->flags |= FLAGS_SHOWSIGN;
- break;
-
- case QUALIFIER_MINUS:
- parameter->flags |= FLAGS_LEFTADJUST;
- parameter->flags &= ~FLAGS_NILPADDING;
- break;
-
- case QUALIFIER_ALTERNATIVE:
- parameter->flags |= FLAGS_ALTERNATIVE;
- break;
-
- case QUALIFIER_DOT:
- if (dots == 0) /* Precision */
- {
- dots++;
-
- /* Skip if no precision */
- if (QUALIFIER_DOT == format[offset])
- break;
-
- /* After the first dot we have the precision */
- parameter->flags |= FLAGS_PRECISION;
- if ((QUALIFIER_STAR == format[offset])
-#if defined(QUALIFIER_PARAM)
- || (QUALIFIER_PARAM == format[offset])
-#endif
- )
- {
- offset++;
- parameter->flags |= FLAGS_PRECISION_PARAMETER;
- parameter->precision = TrioGetPosition(format, &offset);
- }
- else
- {
- parameter->precision = trio_to_long(&format[offset],
- &tmpformat,
- BASE_DECIMAL);
- offset = (int)(tmpformat - format);
- }
- }
- else if (dots == 1) /* Base */
- {
- dots++;
-
- /* After the second dot we have the base */
- parameter->flags |= FLAGS_BASE;
- if ((QUALIFIER_STAR == format[offset])
-#if defined(QUALIFIER_PARAM)
- || (QUALIFIER_PARAM == format[offset])
-#endif
- )
- {
- offset++;
- parameter->flags |= FLAGS_BASE_PARAMETER;
- parameter->base = TrioGetPosition(format, &offset);
- }
- else
- {
- parameter->base = trio_to_long(&format[offset],
- &tmpformat,
- BASE_DECIMAL);
- if (parameter->base > MAX_BASE)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
- offset = (int)(tmpformat - format);
- }
- }
- else
- {
- return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
- }
- break; /* QUALIFIER_DOT */
-
-#if defined(QUALIFIER_PARAM)
- case QUALIFIER_PARAM:
- parameter->type = TYPE_PRINT;
- /* FALLTHROUGH */
-#endif
- case QUALIFIER_STAR:
- /* This has different meanings for print and scan */
- if (TYPE_PRINT == type)
- {
- /* Read with from parameter */
- int width = TrioGetPosition(format, &offset);
- parameter->flags |= (FLAGS_WIDTH | FLAGS_WIDTH_PARAMETER);
- if (NO_POSITION != width)
- parameter->width = width;
- /* else keep parameter->width = NO_WIDTH which != NO_POSITION */
- }
-#if TRIO_FEATURE_SCANF
- else
- {
- /* Scan, but do not store result */
- parameter->flags |= FLAGS_IGNORE;
- }
-#endif
- break; /* QUALIFIER_STAR */
-
- case '0':
- if (! (parameter->flags & FLAGS_LEFTADJUST))
- parameter->flags |= FLAGS_NILPADDING;
- /* FALLTHROUGH */
- case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- parameter->flags |= FLAGS_WIDTH;
- /*
- * &format[offset - 1] is used to "rewind" the read
- * character from format
- */
- parameter->width = trio_to_long(&format[offset - 1],
- &tmpformat,
- BASE_DECIMAL);
- offset = (int)(tmpformat - format);
- break;
-
- case QUALIFIER_SHORT:
- if (parameter->flags & FLAGS_SHORTSHORT)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
- else if (parameter->flags & FLAGS_SHORT)
- parameter->flags |= FLAGS_SHORTSHORT;
- else
- parameter->flags |= FLAGS_SHORT;
- break;
-
- case QUALIFIER_LONG:
- if (parameter->flags & FLAGS_QUAD)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
- else if (parameter->flags & FLAGS_LONG)
- parameter->flags |= FLAGS_QUAD;
- else
- parameter->flags |= FLAGS_LONG;
- break;
-
-#if TRIO_FEATURE_LONGDOUBLE
- case QUALIFIER_LONG_UPPER:
- parameter->flags |= FLAGS_LONGDOUBLE;
- break;
-#endif
-
-#if TRIO_FEATURE_SIZE_T
- case QUALIFIER_SIZE_T:
- parameter->flags |= FLAGS_SIZE_T;
- /* Modify flags for later truncation of number */
- if (sizeof(size_t) == sizeof(trio_ulonglong_t))
- parameter->flags |= FLAGS_QUAD;
- else if (sizeof(size_t) == sizeof(long))
- parameter->flags |= FLAGS_LONG;
- break;
-#endif
-
-#if TRIO_FEATURE_PTRDIFF_T
- case QUALIFIER_PTRDIFF_T:
- parameter->flags |= FLAGS_PTRDIFF_T;
- if (sizeof(ptrdiff_t) == sizeof(trio_ulonglong_t))
- parameter->flags |= FLAGS_QUAD;
- else if (sizeof(ptrdiff_t) == sizeof(long))
- parameter->flags |= FLAGS_LONG;
- break;
-#endif
-
-#if TRIO_FEATURE_INTMAX_T
- case QUALIFIER_INTMAX_T:
- parameter->flags |= FLAGS_INTMAX_T;
- if (sizeof(trio_intmax_t) == sizeof(trio_ulonglong_t))
- parameter->flags |= FLAGS_QUAD;
- else if (sizeof(trio_intmax_t) == sizeof(long))
- parameter->flags |= FLAGS_LONG;
- break;
-#endif
-
-#if TRIO_FEATURE_QUAD
- case QUALIFIER_QUAD:
- parameter->flags |= FLAGS_QUAD;
- break;
-#endif
-
-#if TRIO_FEATURE_FIXED_SIZE
- case QUALIFIER_FIXED_SIZE:
- if (parameter->flags & FLAGS_FIXED_SIZE)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-
- if (parameter->flags & (FLAGS_ALL_SIZES |
- FLAGS_LONGDOUBLE |
- FLAGS_WIDECHAR |
- FLAGS_VARSIZE_PARAMETER))
- return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-
- if ((format[offset] == '6') &&
- (format[offset + 1] == '4'))
- {
- parameter->varsize = sizeof(trio_int64_t);
- offset += 2;
- }
- else if ((format[offset] == '3') &&
- (format[offset + 1] == '2'))
- {
- parameter->varsize = sizeof(trio_int32_t);
- offset += 2;
- }
- else if ((format[offset] == '1') &&
- (format[offset + 1] == '6'))
- {
- parameter->varsize = sizeof(trio_int16_t);
- offset += 2;
- }
- else if (format[offset] == '8')
- {
- parameter->varsize = sizeof(trio_int8_t);
- offset++;
- }
- else
- return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
-
- parameter->flags |= FLAGS_FIXED_SIZE;
- break;
-#endif /* TRIO_FEATURE_FIXED_SIZE */
-
-#if defined(QUALIFIER_WIDECHAR)
- case QUALIFIER_WIDECHAR:
- parameter->flags |= FLAGS_WIDECHAR;
- break;
-#endif
-
-#if TRIO_FEATURE_SIZE_T_UPPER
- case QUALIFIER_SIZE_T_UPPER:
- break;
-#endif
-
-#if TRIO_FEATURE_QUOTE
- case QUALIFIER_QUOTE:
- parameter->flags |= FLAGS_QUOTE;
- break;
-#endif
-
-#if TRIO_FEATURE_STICKY
- case QUALIFIER_STICKY:
- parameter->flags |= FLAGS_STICKY;
- break;
-#endif
-
-#if TRIO_FEATURE_VARSIZE
- case QUALIFIER_VARSIZE:
- parameter->flags |= FLAGS_VARSIZE_PARAMETER;
- break;
-#endif
-
-#if TRIO_FEATURE_ROUNDING
- case QUALIFIER_ROUNDING_UPPER:
- parameter->flags |= FLAGS_ROUNDING;
- break;
-#endif
-
- default:
- /* Bail out completely to make the error more obvious */
- return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
- }
- } /* while qualifier */
-
- parameter->endOffset = offset;
-
- return 0;
-}
-
-/*************************************************************************
- * TrioParseSpecifier
- *
- * Description:
- * Parse the specifier part of a potential conversion specifier
- */
-TRIO_PRIVATE int
-TrioParseSpecifier
-TRIO_ARGS4((type, format, offset, parameter),
- int type,
- TRIO_CONST char *format,
- int offset,
- trio_parameter_t *parameter)
-{
- parameter->baseSpecifier = NO_BASE;
-
- switch (format[offset++])
- {
-#if defined(SPECIFIER_CHAR_UPPER)
- case SPECIFIER_CHAR_UPPER:
- parameter->flags |= FLAGS_WIDECHAR;
- /* FALLTHROUGH */
-#endif
- case SPECIFIER_CHAR:
- if (parameter->flags & FLAGS_LONG)
- parameter->flags |= FLAGS_WIDECHAR;
- else if (parameter->flags & FLAGS_SHORT)
- parameter->flags &= ~FLAGS_WIDECHAR;
- parameter->type = FORMAT_CHAR;
- break;
-
-#if defined(SPECIFIER_STRING_UPPER)
- case SPECIFIER_STRING_UPPER:
- parameter->flags |= FLAGS_WIDECHAR;
- /* FALLTHROUGH */
-#endif
- case SPECIFIER_STRING:
- if (parameter->flags & FLAGS_LONG)
- parameter->flags |= FLAGS_WIDECHAR;
- else if (parameter->flags & FLAGS_SHORT)
- parameter->flags &= ~FLAGS_WIDECHAR;
- parameter->type = FORMAT_STRING;
- break;
-
-#if defined(SPECIFIER_GROUP)
- case SPECIFIER_GROUP:
- if (TYPE_SCAN == type)
- {
- int depth = 1;
- parameter->type = FORMAT_GROUP;
- if (format[offset] == QUALIFIER_CIRCUMFLEX)
- offset++;
- if (format[offset] == SPECIFIER_UNGROUP)
- offset++;
- if (format[offset] == QUALIFIER_MINUS)
- offset++;
- /* Skip nested brackets */
- while (format[offset] != NIL)
- {
- if (format[offset] == SPECIFIER_GROUP)
- {
- depth++;
- }
- else if (format[offset] == SPECIFIER_UNGROUP)
- {
- if (--depth <= 0)
- {
- offset++;
- break;
- }
- }
- offset++;
- }
- }
- break;
-#endif /* defined(SPECIFIER_GROUP) */
-
- case SPECIFIER_INTEGER:
- parameter->type = FORMAT_INT;
- break;
-
- case SPECIFIER_UNSIGNED:
- parameter->flags |= FLAGS_UNSIGNED;
- parameter->type = FORMAT_INT;
- break;
-
- case SPECIFIER_DECIMAL:
- parameter->baseSpecifier = BASE_DECIMAL;
- parameter->type = FORMAT_INT;
- break;
-
- case SPECIFIER_OCTAL:
- parameter->flags |= FLAGS_UNSIGNED;
- parameter->baseSpecifier = BASE_OCTAL;
- parameter->type = FORMAT_INT;
- break;
-
-#if TRIO_FEATURE_BINARY
- case SPECIFIER_BINARY_UPPER:
- parameter->flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
- case SPECIFIER_BINARY:
- parameter->flags |= FLAGS_NILPADDING;
- parameter->baseSpecifier = BASE_BINARY;
- parameter->type = FORMAT_INT;
- break;
-#endif
-
- case SPECIFIER_HEX_UPPER:
- parameter->flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
- case SPECIFIER_HEX:
- parameter->flags |= FLAGS_UNSIGNED;
- parameter->baseSpecifier = BASE_HEX;
- parameter->type = FORMAT_INT;
- break;
-
-#if defined(SPECIFIER_FLOAT_E)
-# if defined(SPECIFIER_FLOAT_E_UPPER)
- case SPECIFIER_FLOAT_E_UPPER:
- parameter->flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
-# endif
- case SPECIFIER_FLOAT_E:
- parameter->flags |= FLAGS_FLOAT_E;
- parameter->type = FORMAT_DOUBLE;
- break;
-#endif
-
-#if defined(SPECIFIER_FLOAT_G)
-# if defined(SPECIFIER_FLOAT_G_UPPER)
- case SPECIFIER_FLOAT_G_UPPER:
- parameter->flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
-# endif
- case SPECIFIER_FLOAT_G:
- parameter->flags |= FLAGS_FLOAT_G;
- parameter->type = FORMAT_DOUBLE;
- break;
-#endif
-
-#if defined(SPECIFIER_FLOAT_F)
-# if defined(SPECIFIER_FLOAT_F_UPPER)
- case SPECIFIER_FLOAT_F_UPPER:
- parameter->flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
-# endif
- case SPECIFIER_FLOAT_F:
- parameter->type = FORMAT_DOUBLE;
- break;
-#endif
-
-#if defined(TRIO_COMPILER_VISUALC)
-# pragma warning( push )
-# pragma warning( disable : 4127 ) /* Conditional expression is constant */
-#endif
- case SPECIFIER_POINTER:
- if (sizeof(trio_pointer_t) == sizeof(trio_ulonglong_t))
- parameter->flags |= FLAGS_QUAD;
- else if (sizeof(trio_pointer_t) == sizeof(long))
- parameter->flags |= FLAGS_LONG;
- parameter->type = FORMAT_POINTER;
- break;
-#if defined(TRIO_COMPILER_VISUALC)
-# pragma warning( pop )
-#endif
-
- case SPECIFIER_COUNT:
- parameter->type = FORMAT_COUNT;
- break;
-
-#if TRIO_FEATURE_HEXFLOAT
- case SPECIFIER_HEXFLOAT_UPPER:
- parameter->flags |= FLAGS_UPPER;
- /* FALLTHROUGH */
- case SPECIFIER_HEXFLOAT:
- parameter->baseSpecifier = BASE_HEX;
- parameter->type = FORMAT_DOUBLE;
- break;
-#endif
-
-#if TRIO_FEATURE_ERRNO
- case SPECIFIER_ERRNO:
- parameter->type = FORMAT_ERRNO;
- break;
-#endif
-
-#if TRIO_FEATURE_USER_DEFINED
- case SPECIFIER_USER_DEFINED_BEGIN:
- {
- unsigned int max;
- int without_namespace = TRUE;
- char* tmpformat = (char *)&format[offset];
- int ch;
-
- parameter->type = FORMAT_USER_DEFINED;
- parameter->user_defined.namespace[0] = NIL;
-
- while ((ch = format[offset]) != NIL)
- {
- offset++;
- if ((ch == SPECIFIER_USER_DEFINED_END) || (ch == SPECIFIER_USER_DEFINED_EXTRA))
- {
- if (without_namespace)
- /* No namespace, handler will be passed as an argument */
- parameter->flags |= FLAGS_USER_DEFINED_PARAMETER;
-
- /* Copy the user data */
- max = (unsigned int)(&format[offset] - tmpformat);
- if (max > MAX_USER_DATA)
- max = MAX_USER_DATA;
- trio_copy_max(parameter->user_data, max, tmpformat);
-
- /* Skip extra data (which is only there to keep the compiler happy) */
- while ((ch != NIL) && (ch != SPECIFIER_USER_DEFINED_END))
- ch = format[offset++];
-
- break; /* while */
- }
-
- if (ch == SPECIFIER_USER_DEFINED_SEPARATOR)
- {
- without_namespace = FALSE;
- /* Copy the namespace for later looking-up */
- max = (int)(&format[offset] - tmpformat);
- if (max > MAX_USER_NAME)
- max = MAX_USER_NAME;
- trio_copy_max(parameter->user_defined.namespace, max, tmpformat);
- tmpformat = (char *)&format[offset];
- }
- }
-
- if (ch != SPECIFIER_USER_DEFINED_END)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
- }
- break;
-#endif /* TRIO_FEATURE_USER_DEFINED */
-
- default:
- /* Bail out completely to make the error more obvious */
- return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
- }
-
- parameter->endOffset = offset;
-
- return 0;
-}
-
-/*************************************************************************
- * TrioParse
- *
- * Description:
- * Parse the format string
- */
-TRIO_PRIVATE int
-TrioParse
-TRIO_ARGS5((type, format, parameters, arglist, argarray),
- int type,
- TRIO_CONST char *format,
- trio_parameter_t *parameters,
- va_list arglist,
- trio_pointer_t *argarray)
-{
- /* Count the number of times a parameter is referenced */
- unsigned short usedEntries[MAX_PARAMETERS];
- /* Parameter counters */
- int parameterPosition;
- int maxParam = -1;
- /* Utility variables */
- int offset; /* Offset into formatting string */
- BOOLEAN_T positional; /* Does the specifier have a positional? */
-#if TRIO_FEATURE_STICKY
- BOOLEAN_T gotSticky = FALSE; /* Are there any sticky modifiers at all? */
-#endif
- /*
- * indices specifies the order in which the parameters must be
- * read from the va_args (this is necessary to handle positionals)
- */
- int indices[MAX_PARAMETERS];
- int pos = 0;
- /* Various variables */
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- int charlen;
-#endif
- int save_errno;
- int i = -1;
- int num;
- trio_parameter_t workParameter;
- int status;
-
- /*
- * The 'parameters' array is not initialized, but we need to
- * know which entries we have used.
- */
- memset(usedEntries, 0, sizeof(usedEntries));
-
- save_errno = errno;
- offset = 0;
- parameterPosition = 0;
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- (void)mblen(NULL, 0);
-#endif
-
- while (format[offset])
- {
- TrioInitializeParameter(&workParameter);
-
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- if (! isascii(format[offset]))
- {
- /*
- * Multibyte characters cannot be legal specifiers or
- * modifiers, so we skip over them.
- */
- charlen = mblen(&format[offset], MB_LEN_MAX);
- offset += (charlen > 0) ? charlen : 1;
- continue; /* while */
- }
-#endif /* TRIO_COMPILER_SUPPORTS_MULTIBYTE */
-
- switch(format[offset++]) {
-
- case CHAR_IDENTIFIER:
- {
- if (CHAR_IDENTIFIER == format[offset])
- {
- /* skip double "%" */
- offset++;
- continue; /* while */
- }
-
- status = TrioParseQualifiers(type, format, offset, &workParameter);
- if (status < 0)
- return status; /* Return qualifier syntax error */
-
- status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter);
- if (status < 0)
- return status; /* Return specifier syntax error */
- }
- break;
-
-#if TRIO_EXTENSION
- case CHAR_ALT_IDENTIFIER:
- {
- status = TrioParseQualifiers(type, format, offset, &workParameter);
- if (status < 0)
- continue; /* False alert, not a user defined specifier */
-
- status = TrioParseSpecifier(type, format, workParameter.endOffset, &workParameter);
- if ((status < 0) || (FORMAT_USER_DEFINED != workParameter.type))
- continue; /* False alert, not a user defined specifier */
- }
- break;
-#endif
-
- default:
- continue; /* while */
- }
-
- /* now handle the parsed conversion specification */
- positional = (NO_POSITION != workParameter.position);
-
- /*
- * Parameters only need the type and value. The value is
- * read later.
- */
- if (workParameter.flags & FLAGS_WIDTH_PARAMETER)
- {
- if (workParameter.width == NO_WIDTH)
- {
- workParameter.width = parameterPosition++;
- }
- else
- {
- if (! positional)
- workParameter.position = workParameter.width + 1;
- }
-
- usedEntries[workParameter.width] += 1;
- if (workParameter.width > maxParam)
- maxParam = workParameter.width;
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].flags = 0;
- indices[workParameter.width] = pos;
- workParameter.width = pos++;
- }
- if (workParameter.flags & FLAGS_PRECISION_PARAMETER)
- {
- if (workParameter.precision == NO_PRECISION)
- {
- workParameter.precision = parameterPosition++;
- }
- else
- {
- if (! positional)
- workParameter.position = workParameter.precision + 1;
- }
-
- usedEntries[workParameter.precision] += 1;
- if (workParameter.precision > maxParam)
- maxParam = workParameter.precision;
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].flags = 0;
- indices[workParameter.precision] = pos;
- workParameter.precision = pos++;
- }
- if (workParameter.flags & FLAGS_BASE_PARAMETER)
- {
- if (workParameter.base == NO_BASE)
- {
- workParameter.base = parameterPosition++;
- }
- else
- {
- if (! positional)
- workParameter.position = workParameter.base + 1;
- }
-
- usedEntries[workParameter.base] += 1;
- if (workParameter.base > maxParam)
- maxParam = workParameter.base;
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].flags = 0;
- indices[workParameter.base] = pos;
- workParameter.base = pos++;
- }
-#if TRIO_FEATURE_VARSIZE
- if (workParameter.flags & FLAGS_VARSIZE_PARAMETER)
- {
- workParameter.varsize = parameterPosition++;
-
- usedEntries[workParameter.varsize] += 1;
- if (workParameter.varsize > maxParam)
- maxParam = workParameter.varsize;
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].flags = 0;
- indices[workParameter.varsize] = pos;
- workParameter.varsize = pos++;
- }
-#endif
-#if TRIO_FEATURE_USER_DEFINED
- if (workParameter.flags & FLAGS_USER_DEFINED_PARAMETER)
- {
- workParameter.user_defined.handler = parameterPosition++;
-
- usedEntries[workParameter.user_defined.handler] += 1;
- if (workParameter.user_defined.handler > maxParam)
- maxParam = workParameter.user_defined.handler;
- parameters[pos].type = FORMAT_PARAMETER;
- parameters[pos].flags = FLAGS_USER_DEFINED;
- indices[workParameter.user_defined.handler] = pos;
- workParameter.user_defined.handler = pos++;
- }
-#endif
-
- if (NO_POSITION == workParameter.position)
- {
- workParameter.position = parameterPosition++;
- }
-
- if (workParameter.position > maxParam)
- maxParam = workParameter.position;
-
- if (workParameter.position >= MAX_PARAMETERS)
- {
- /* Bail out completely to make the error more obvious */
- return TRIO_ERROR_RETURN(TRIO_ETOOMANY, offset);
- }
-
- indices[workParameter.position] = pos;
-
- /* Count the number of times this entry has been used */
- usedEntries[workParameter.position] += 1;
-
- /* Find last sticky parameters */
-#if TRIO_FEATURE_STICKY
- if (workParameter.flags & FLAGS_STICKY)
- {
- gotSticky = TRUE;
- }
- else if (gotSticky)
- {
- for (i = pos - 1; i >= 0; i--)
- {
- if (parameters[i].type == FORMAT_PARAMETER)
- continue;
- if ((parameters[i].flags & FLAGS_STICKY) &&
- (parameters[i].type == workParameter.type))
- {
- /* Do not overwrite current qualifiers */
- workParameter.flags |= (parameters[i].flags & (unsigned long)~FLAGS_STICKY);
- if (workParameter.width == NO_WIDTH)
- workParameter.width = parameters[i].width;
- if (workParameter.precision == NO_PRECISION)
- workParameter.precision = parameters[i].precision;
- if (workParameter.base == NO_BASE)
- workParameter.base = parameters[i].base;
- break;
- }
- }
- }
-#endif
-
- if (workParameter.base == NO_BASE)
- workParameter.base = BASE_DECIMAL;
-
- offset = workParameter.endOffset;
-
- TrioCopyParameter(¶meters[pos++], &workParameter);
- } /* while format characters left */
-
- parameters[pos].type = FORMAT_SENTINEL; /* end parameter array with sentinel */
- parameters[pos].beginOffset = offset;
-
- for (num = 0; num <= maxParam; num++)
- {
- if (usedEntries[num] != 1)
- {
- if (usedEntries[num] == 0) /* gap detected */
- return TRIO_ERROR_RETURN(TRIO_EGAP, num);
- else /* double references detected */
- return TRIO_ERROR_RETURN(TRIO_EDBLREF, num);
- }
-
- i = indices[num];
-
- /*
- * FORMAT_PARAMETERS are only present if they must be read,
- * so it makes no sense to check the ignore flag (besides,
- * the flags variable is not set for that particular type)
- */
- if ((parameters[i].type != FORMAT_PARAMETER) &&
- (parameters[i].flags & FLAGS_IGNORE))
- continue; /* for all arguments */
-
- /*
- * The stack arguments are read according to ANSI C89
- * default argument promotions:
- *
- * char = int
- * short = int
- * unsigned char = unsigned int
- * unsigned short = unsigned int
- * float = double
- *
- * In addition to the ANSI C89 these types are read (the
- * default argument promotions of C99 has not been
- * considered yet)
- *
- * long long
- * long double
- * size_t
- * ptrdiff_t
- * intmax_t
- */
- switch (parameters[i].type)
- {
- case FORMAT_GROUP:
- case FORMAT_STRING:
-#if TRIO_FEATURE_WIDECHAR
- if (parameters[i].flags & FLAGS_WIDECHAR)
- {
- parameters[i].data.wstring = (argarray == NULL)
- ? va_arg(arglist, trio_wchar_t *)
- : (trio_wchar_t *)(argarray[num]);
- }
- else
-#endif
- {
- parameters[i].data.string = (argarray == NULL)
- ? va_arg(arglist, char *)
- : (char *)(argarray[num]);
- }
- break;
-
-#if TRIO_FEATURE_USER_DEFINED
- case FORMAT_USER_DEFINED:
-#endif
- case FORMAT_POINTER:
- case FORMAT_COUNT:
- case FORMAT_UNKNOWN:
- parameters[i].data.pointer = (argarray == NULL)
- ? va_arg(arglist, trio_pointer_t )
- : argarray[num];
- break;
-
- case FORMAT_CHAR:
- case FORMAT_INT:
-#if TRIO_FEATURE_SCANF
- if (TYPE_SCAN == type)
- {
- if (argarray == NULL)
- parameters[i].data.pointer =
- (trio_pointer_t)va_arg(arglist, trio_pointer_t);
- else
- {
- if (parameters[i].type == FORMAT_CHAR)
- parameters[i].data.pointer =
- (trio_pointer_t)((char *)argarray[num]);
- else if (parameters[i].flags & FLAGS_SHORT)
- parameters[i].data.pointer =
- (trio_pointer_t)((short *)argarray[num]);
- else
- parameters[i].data.pointer =
- (trio_pointer_t)((int *)argarray[num]);
- }
- }
- else
-#endif /* TRIO_FEATURE_SCANF */
- {
-#if TRIO_FEATURE_VARSIZE || TRIO_FEATURE_FIXED_SIZE
- if (parameters[i].flags
- & (FLAGS_VARSIZE_PARAMETER | FLAGS_FIXED_SIZE))
- {
- int varsize;
- if (parameters[i].flags & FLAGS_VARSIZE_PARAMETER)
- {
- /*
- * Variable sizes are mapped onto the fixed sizes, in
- * accordance with integer promotion.
- *
- * Please note that this may not be portable, as we
- * only guess the size, not the layout of the numbers.
- * For example, if int is little-endian, and long is
- * big-endian, then this will fail.
- */
- varsize = (int)parameters[parameters[i].varsize].data.number.as_unsigned;
- }
- else
- {
- /* Used for the I<bits> modifiers */
- varsize = parameters[i].varsize;
- }
- parameters[i].flags &= ~FLAGS_ALL_VARSIZES;
-
- if (varsize <= (int)sizeof(int))
- ;
- else if (varsize <= (int)sizeof(long))
- parameters[i].flags |= FLAGS_LONG;
-#if TRIO_FEATURE_INTMAX_T
- else if (varsize <= (int)sizeof(trio_longlong_t))
- parameters[i].flags |= FLAGS_QUAD;
- else
- parameters[i].flags |= FLAGS_INTMAX_T;
-#else
- else
- parameters[i].flags |= FLAGS_QUAD;
-#endif
- }
-#endif /* TRIO_FEATURE_VARSIZE */
-#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
- if (parameters[i].flags & FLAGS_SIZE_T)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(arglist, size_t)
- : (trio_uintmax_t)(*((size_t *)argarray[num]));
- else
-#endif
-#if TRIO_FEATURE_PTRDIFF_T
- if (parameters[i].flags & FLAGS_PTRDIFF_T)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(arglist, ptrdiff_t)
- : (trio_uintmax_t)(*((ptrdiff_t *)argarray[num]));
- else
-#endif
-#if TRIO_FEATURE_INTMAX_T
- if (parameters[i].flags & FLAGS_INTMAX_T)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(arglist, trio_intmax_t)
- : (trio_uintmax_t)(*((trio_intmax_t *)argarray[num]));
- else
-#endif
- if (parameters[i].flags & FLAGS_QUAD)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(arglist, trio_ulonglong_t)
- : (trio_uintmax_t)(*((trio_ulonglong_t *)argarray[num]));
- else if (parameters[i].flags & FLAGS_LONG)
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(arglist, long)
- : (trio_uintmax_t)(*((long *)argarray[num]));
- else
- {
- if (argarray == NULL)
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)va_arg(arglist, int);
- else
- {
- if (parameters[i].type == FORMAT_CHAR)
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((char *)argarray[num]));
- else if (parameters[i].flags & FLAGS_SHORT)
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((short *)argarray[num]));
- else
- parameters[i].data.number.as_unsigned = (trio_uintmax_t)(*((int *)argarray[num]));
- }
- }
- }
- break;
-
- case FORMAT_PARAMETER:
- /*
- * The parameter for the user-defined specifier is a pointer,
- * whereas the rest (width, precision, base) uses an integer.
- */
- if (parameters[i].flags & FLAGS_USER_DEFINED)
- parameters[i].data.pointer = (argarray == NULL)
- ? va_arg(arglist, trio_pointer_t )
- : argarray[num];
- else
- parameters[i].data.number.as_unsigned = (argarray == NULL)
- ? (trio_uintmax_t)va_arg(arglist, int)
- : (trio_uintmax_t)(*((int *)argarray[num]));
- break;
-
-#if TRIO_FEATURE_FLOAT
- case FORMAT_DOUBLE:
-# if TRIO_FEATURE_SCANF
- if (TYPE_SCAN == type)
- {
- if (parameters[i].flags & FLAGS_LONGDOUBLE)
- parameters[i].data.longdoublePointer = (argarray == NULL)
- ? va_arg(arglist, trio_long_double_t *)
- : (trio_long_double_t *)argarray[num];
- else
- {
- if (parameters[i].flags & FLAGS_LONG)
- parameters[i].data.doublePointer = (argarray == NULL)
- ? va_arg(arglist, double *)
- : (double *)argarray[num];
- else
- parameters[i].data.doublePointer = (argarray == NULL)
- ? (double *)va_arg(arglist, float *)
- : (double *)((float *)argarray[num]);
- }
- }
- else
-# endif /* TRIO_FEATURE_SCANF */
- {
- if (parameters[i].flags & FLAGS_LONGDOUBLE)
- parameters[i].data.longdoubleNumber = (argarray == NULL)
- ? va_arg(arglist, trio_long_double_t)
- : (trio_long_double_t)(*((trio_long_double_t *)argarray[num]));
- else
- {
- if (argarray == NULL)
- parameters[i].data.longdoubleNumber =
- (trio_long_double_t)va_arg(arglist, double);
- else
- {
- if (parameters[i].flags & FLAGS_SHORT)
- parameters[i].data.longdoubleNumber =
- (trio_long_double_t)(*((float *)argarray[num]));
- else
- parameters[i].data.longdoubleNumber =
- (trio_long_double_t)(*((double *)argarray[num]));
- }
- }
- }
- break;
-#endif /* TRIO_FEATURE_FLOAT */
-
-#if TRIO_FEATURE_ERRNO
- case FORMAT_ERRNO:
- parameters[i].data.errorNumber = save_errno;
- break;
-#endif
-
- default:
- break;
- }
- } /* for all specifiers */
- return num;
-}
-
-
-/*************************************************************************
- *
- * FORMATTING
- *
- ************************************************************************/
-
-
-/*************************************************************************
- * TrioWriteNumber
- *
- * Description:
- * Output a number.
- * The complexity of this function is a result of the complexity
- * of the dependencies of the flags.
- */
-TRIO_PRIVATE void
-TrioWriteNumber
-TRIO_ARGS6((self, number, flags, width, precision, base),
- trio_class_t *self,
- trio_uintmax_t number,
- trio_flags_t flags,
- int width,
- int precision,
- int base)
-{
- BOOLEAN_T isNegative;
- BOOLEAN_T isNumberZero;
- BOOLEAN_T isPrecisionZero;
- BOOLEAN_T ignoreNumber;
- char buffer[MAX_CHARS_IN(trio_uintmax_t) * (1 + MAX_LOCALE_SEPARATOR_LENGTH) + 1];
- char *bufferend;
- char *pointer;
- TRIO_CONST char *digits;
- int i;
-#if TRIO_FEATURE_QUOTE
- int length;
- char *p;
-#endif
- int count;
- int digitOffset;
-
- assert(VALID(self));
- assert(VALID(self->OutStream));
- assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
-
- digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
- if (base == NO_BASE)
- base = BASE_DECIMAL;
-
- isNumberZero = (number == 0);
- isPrecisionZero = (precision == 0);
- ignoreNumber = (isNumberZero
- && isPrecisionZero
- && !((flags & FLAGS_ALTERNATIVE) && (base == BASE_OCTAL)));
-
- if (flags & FLAGS_UNSIGNED)
- {
- isNegative = FALSE;
- flags &= ~FLAGS_SHOWSIGN;
- }
- else
- {
- isNegative = ((trio_intmax_t)number < 0);
- if (isNegative)
- number = -((trio_intmax_t)number);
- }
-
- if (flags & FLAGS_QUAD)
- number &= (trio_ulonglong_t)-1;
- else if (flags & FLAGS_LONG)
- number &= (unsigned long)-1;
- else
- number &= (unsigned int)-1;
-
- /* Build number */
- pointer = bufferend = &buffer[sizeof(buffer) - 1];
- *pointer-- = NIL;
- for (i = 1; i < (int)sizeof(buffer); i++)
- {
- digitOffset = number % base;
- *pointer-- = digits[digitOffset];
- number /= base;
- if (number == 0)
- break;
-
-#if TRIO_FEATURE_QUOTE
- if ((flags & FLAGS_QUOTE) && TrioFollowedBySeparator(i + 1))
- {
- /*
- * We are building the number from the least significant
- * to the most significant digit, so we have to copy the
- * thousand separator backwards
- */
- length = internalThousandSeparatorLength;
- if (((int)(pointer - buffer) - length) > 0)
- {
- p = &internalThousandSeparator[length - 1];
- while (length-- > 0)
- *pointer-- = *p--;
- }
- }
-#endif
- }
-
- if (! ignoreNumber)
- {
- /* Adjust width */
- width -= (bufferend - pointer) - 1;
- }
-
- /* Adjust precision */
- if (NO_PRECISION != precision)
- {
- precision -= (bufferend - pointer) - 1;
- if (precision < 0)
- precision = 0;
- flags |= FLAGS_NILPADDING;
- }
-
- /* Calculate padding */
- count = (! ((flags & FLAGS_LEFTADJUST) || (precision == NO_PRECISION)))
- ? precision
- : 0;
-
- /* Adjust width further */
- if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
- width--;
- if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero)
- {
- switch (base)
- {
- case BASE_BINARY:
- case BASE_HEX:
- width -= 2;
- break;
- case BASE_OCTAL:
- if (!(flags & FLAGS_NILPADDING) || (count == 0))
- width--;
- break;
- default:
- break;
- }
- }
-
- /* Output prefixes spaces if needed */
- if (! ((flags & FLAGS_LEFTADJUST) ||
- ((flags & FLAGS_NILPADDING) && (precision == NO_PRECISION))))
- {
- while (width-- > count)
- self->OutStream(self, CHAR_ADJUST);
- }
-
- /* width has been adjusted for signs and alternatives */
- if (isNegative)
- self->OutStream(self, '-');
- else if (flags & FLAGS_SHOWSIGN)
- self->OutStream(self, '+');
- else if (flags & FLAGS_SPACE)
- self->OutStream(self, ' ');
-
- /* Prefix is not written when the value is zero */
- if ((flags & FLAGS_ALTERNATIVE) && !isNumberZero)
- {
- switch (base)
- {
- case BASE_BINARY:
- self->OutStream(self, '0');
- self->OutStream(self, (flags & FLAGS_UPPER) ? 'B' : 'b');
- break;
-
- case BASE_OCTAL:
- if (!(flags & FLAGS_NILPADDING) || (count == 0))
- self->OutStream(self, '0');
- break;
-
- case BASE_HEX:
- self->OutStream(self, '0');
- self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
- break;
-
- default:
- break;
- } /* switch base */
- }
-
- /* Output prefixed zero padding if needed */
- if (flags & FLAGS_NILPADDING)
- {
- if (precision == NO_PRECISION)
- precision = width;
- while (precision-- > 0)
- {
- self->OutStream(self, '0');
- width--;
- }
- }
-
- if (! ignoreNumber)
- {
- /* Output the number itself */
- while (*(++pointer))
- {
- self->OutStream(self, *pointer);
- }
- }
-
- /* Output trailing spaces if needed */
- if (flags & FLAGS_LEFTADJUST)
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
-}
-
-/*************************************************************************
- * TrioWriteStringCharacter
- *
- * Description:
- * Output a single character of a string
- */
-TRIO_PRIVATE void
-TrioWriteStringCharacter
-TRIO_ARGS3((self, ch, flags),
- trio_class_t *self,
- int ch,
- trio_flags_t flags)
-{
- if (flags & FLAGS_ALTERNATIVE)
- {
- if (! isprint(ch))
- {
- /*
- * Non-printable characters are converted to C escapes or
- * \number, if no C escape exists.
- */
- self->OutStream(self, CHAR_BACKSLASH);
- switch (ch)
- {
- case '\007': self->OutStream(self, 'a'); break;
- case '\b': self->OutStream(self, 'b'); break;
- case '\f': self->OutStream(self, 'f'); break;
- case '\n': self->OutStream(self, 'n'); break;
- case '\r': self->OutStream(self, 'r'); break;
- case '\t': self->OutStream(self, 't'); break;
- case '\v': self->OutStream(self, 'v'); break;
- case '\\': self->OutStream(self, '\\'); break;
- default:
- self->OutStream(self, 'x');
- TrioWriteNumber(self, (trio_uintmax_t)ch,
- FLAGS_UNSIGNED | FLAGS_NILPADDING,
- 2, 2, BASE_HEX);
- break;
- }
- }
- else if (ch == CHAR_BACKSLASH)
- {
- self->OutStream(self, CHAR_BACKSLASH);
- self->OutStream(self, CHAR_BACKSLASH);
- }
- else
- {
- self->OutStream(self, ch);
- }
- }
- else
- {
- self->OutStream(self, ch);
- }
-}
-
-/*************************************************************************
- * TrioWriteString
- *
- * Description:
- * Output a string
- */
-TRIO_PRIVATE void
-TrioWriteString
-TRIO_ARGS5((self, string, flags, width, precision),
- trio_class_t *self,
- TRIO_CONST char *string,
- trio_flags_t flags,
- int width,
- int precision)
-{
- int length;
- int ch;
-
- assert(VALID(self));
- assert(VALID(self->OutStream));
-
- if (string == NULL)
- {
- string = internalNullString;
- length = sizeof(internalNullString) - 1;
-#if TRIO_FEATURE_QUOTE
- /* Disable quoting for the null pointer */
- flags &= (~FLAGS_QUOTE);
-#endif
- width = 0;
- }
- else
- {
- if (precision == 0)
- {
- length = trio_length(string);
- }
- else
- {
- length = trio_length_max(string, precision);
- }
- }
- if ((NO_PRECISION != precision) &&
- (precision < length))
- {
- length = precision;
- }
- width -= length;
-
-#if TRIO_FEATURE_QUOTE
- if (flags & FLAGS_QUOTE)
- self->OutStream(self, CHAR_QUOTE);
-#endif
-
- if (! (flags & FLAGS_LEFTADJUST))
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
-
- while (length-- > 0)
- {
- /* The ctype parameters must be an unsigned char (or EOF) */
- ch = (int)((unsigned char)(*string++));
- TrioWriteStringCharacter(self, ch, flags);
- }
-
- if (flags & FLAGS_LEFTADJUST)
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
-#if TRIO_FEATURE_QUOTE
- if (flags & FLAGS_QUOTE)
- self->OutStream(self, CHAR_QUOTE);
-#endif
-}
-
-/*************************************************************************
- * TrioWriteWideStringCharacter
- *
- * Description:
- * Output a wide string as a multi-byte sequence
- */
-#if TRIO_FEATURE_WIDECHAR
-TRIO_PRIVATE int
-TrioWriteWideStringCharacter
-TRIO_ARGS4((self, wch, flags, width),
- trio_class_t *self,
- trio_wchar_t wch,
- trio_flags_t flags,
- int width)
-{
- int size;
- int i;
- int ch;
- char *string;
- char buffer[MB_LEN_MAX + 1];
-
- if (width == NO_WIDTH)
- width = sizeof(buffer);
-
- size = wctomb(buffer, wch);
- if ((size <= 0) || (size > width) || (buffer[0] == NIL))
- return 0;
-
- string = buffer;
- i = size;
- while ((width >= i) && (width-- > 0) && (i-- > 0))
- {
- /* The ctype parameters must be an unsigned char (or EOF) */
- ch = (int)((unsigned char)(*string++));
- TrioWriteStringCharacter(self, ch, flags);
- }
- return size;
-}
-#endif /* TRIO_FEATURE_WIDECHAR */
-
-/*************************************************************************
- * TrioWriteWideString
- *
- * Description:
- * Output a wide character string as a multi-byte string
- */
-#if TRIO_FEATURE_WIDECHAR
-TRIO_PRIVATE void
-TrioWriteWideString
-TRIO_ARGS5((self, wstring, flags, width, precision),
- trio_class_t *self,
- TRIO_CONST trio_wchar_t *wstring,
- trio_flags_t flags,
- int width,
- int precision)
-{
- int length;
- int size;
-
- assert(VALID(self));
- assert(VALID(self->OutStream));
-
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- /* Required by TrioWriteWideStringCharacter */
- (void)mblen(NULL, 0);
-#endif
-
- if (wstring == NULL)
- {
- TrioWriteString(self, NULL, flags, width, precision);
- return;
- }
-
- if (NO_PRECISION == precision)
- {
- length = INT_MAX;
- }
- else
- {
- length = precision;
- width -= length;
- }
-
-#if TRIO_FEATURE_QUOTE
- if (flags & FLAGS_QUOTE)
- self->OutStream(self, CHAR_QUOTE);
-#endif
-
- if (! (flags & FLAGS_LEFTADJUST))
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
-
- while (length > 0)
- {
- size = TrioWriteWideStringCharacter(self, *wstring++, flags, length);
- if (size == 0)
- break; /* while */
- length -= size;
- }
-
- if (flags & FLAGS_LEFTADJUST)
- {
- while (width-- > 0)
- self->OutStream(self, CHAR_ADJUST);
- }
-#if TRIO_FEATURE_QUOTE
- if (flags & FLAGS_QUOTE)
- self->OutStream(self, CHAR_QUOTE);
-#endif
-}
-#endif /* TRIO_FEATURE_WIDECHAR */
-
-/*************************************************************************
- * TrioWriteDouble
- *
- * http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_211.htm
- *
- * "5.2.4.2.2 paragraph #4
- *
- * The accuracy [...] is implementation defined, as is the accuracy
- * of the conversion between floating-point internal representations
- * and string representations performed by the libray routine in
- * <stdio.h>"
- */
-/* FIXME: handle all instances of constant long-double number (L)
- * and *l() math functions.
- */
-#if TRIO_FEATURE_FLOAT
-TRIO_PRIVATE void
-TrioWriteDouble
-TRIO_ARGS6((self, number, flags, width, precision, base),
- trio_class_t *self,
- trio_long_double_t number,
- trio_flags_t flags,
- int width,
- int precision,
- int base)
-{
- trio_long_double_t integerNumber;
- trio_long_double_t fractionNumber;
- trio_long_double_t workNumber;
- int integerDigits;
- int fractionDigits;
- int exponentDigits;
- int workDigits;
- int baseDigits;
- int integerThreshold;
- int fractionThreshold;
- int expectedWidth;
- int exponent = 0;
- unsigned int uExponent = 0;
- int exponentBase;
- trio_long_double_t dblBase;
- trio_long_double_t dblFractionBase;
- trio_long_double_t integerAdjust;
- trio_long_double_t fractionAdjust;
- trio_long_double_t workFractionNumber;
- trio_long_double_t workFractionAdjust;
- int fractionDigitsInspect;
- BOOLEAN_T isNegative;
- BOOLEAN_T isExponentNegative = FALSE;
- BOOLEAN_T requireTwoDigitExponent;
- BOOLEAN_T isHex;
- TRIO_CONST char *digits;
-# if TRIO_FEATURE_QUOTE
- char *groupingPointer;
-# endif
- int i;
- int offset;
- BOOLEAN_T hasOnlyZeroes;
- int leadingFractionZeroes = -1;
- register int trailingZeroes;
- BOOLEAN_T keepTrailingZeroes;
- BOOLEAN_T keepDecimalPoint;
- trio_long_double_t epsilon;
- BOOLEAN_T adjustNumber = FALSE;
-
- assert(VALID(self));
- assert(VALID(self->OutStream));
- assert(((base >= MIN_BASE) && (base <= MAX_BASE)) || (base == NO_BASE));
-
- /* Determine sign and look for special quantities */
- switch (trio_fpclassify_and_signbit(number, &isNegative))
- {
- case TRIO_FP_NAN:
- TrioWriteString(self,
- (flags & FLAGS_UPPER)
- ? NAN_UPPER
- : NAN_LOWER,
- flags, width, precision);
- return;
-
- case TRIO_FP_INFINITE:
- if (isNegative)
- {
- /* Negative infinity */
- TrioWriteString(self,
- (flags & FLAGS_UPPER)
- ? "-" INFINITE_UPPER
- : "-" INFINITE_LOWER,
- flags, width, precision);
- return;
- }
- else
- {
- /* Positive infinity */
- TrioWriteString(self,
- (flags & FLAGS_UPPER)
- ? INFINITE_UPPER
- : INFINITE_LOWER,
- flags, width, precision);
- return;
- }
-
- default:
- /* Finitude */
- break;
- }
-
- /* Normal numbers */
- if (flags & FLAGS_LONGDOUBLE)
- {
- baseDigits = (base == 10)
- ? LDBL_DIG
- : (int)trio_floor(LDBL_MANT_DIG / TrioLogarithmBase(base));
- epsilon = LDBL_EPSILON;
- }
- else if (flags & FLAGS_SHORT)
- {
- baseDigits = (base == BASE_DECIMAL)
- ? FLT_DIG
- : (int)trio_floor(FLT_MANT_DIG / TrioLogarithmBase(base));
- epsilon = FLT_EPSILON;
- }
- else
- {
- baseDigits = (base == BASE_DECIMAL)
- ? DBL_DIG
- : (int)trio_floor(DBL_MANT_DIG / TrioLogarithmBase(base));
- epsilon = DBL_EPSILON;
- }
-
- digits = (flags & FLAGS_UPPER) ? internalDigitsUpper : internalDigitsLower;
- isHex = (base == BASE_HEX);
- if (base == NO_BASE)
- base = BASE_DECIMAL;
- dblBase = (trio_long_double_t)base;
- keepTrailingZeroes = !( (flags & FLAGS_ROUNDING) ||
- ( (flags & FLAGS_FLOAT_G) &&
- !(flags & FLAGS_ALTERNATIVE) ) );
-
-# if TRIO_FEATURE_ROUNDING
- if (flags & FLAGS_ROUNDING)
- {
- precision = baseDigits;
- }
-# endif
-
- if (precision == NO_PRECISION)
- {
- if (isHex)
- {
- keepTrailingZeroes = FALSE;
- precision = FLT_MANT_DIG;
- }
- else
- {
- precision = FLT_DIG;
- }
- }
-
- if (isNegative)
- {
- number = -number;
- }
-
- if (isHex)
- {
- flags |= FLAGS_FLOAT_E;
- }
-
- reprocess:
-
- if (flags & FLAGS_FLOAT_G)
- {
- if (precision == 0)
- precision = 1;
-
- if ( (number < TRIO_SUFFIX_LONG(1.0E-4)) ||
- (number >= TrioPower(base, (trio_long_double_t)precision)) )
- {
- /* Use scientific notation */
- flags |= FLAGS_FLOAT_E;
- }
- else if (number < 1.0)
- {
- /*
- * Use normal notation. If the integer part of the number is
- * zero, then adjust the precision to include leading fractional
- * zeros.
- */
- workNumber = TrioLogarithm(number, base);
- workNumber = TRIO_FABS(workNumber);
- if (workNumber - trio_floor(workNumber) < epsilon)
- workNumber--;
- leadingFractionZeroes = (int)trio_floor(workNumber);
- }
- }
-
- if (flags & FLAGS_FLOAT_E)
- {
- /* Scale the number */
- workNumber = TrioLogarithm(number, base);
- if (trio_isinf(workNumber) == -1)
- {
- exponent = 0;
- /* Undo setting */
- if (flags & FLAGS_FLOAT_G)
- flags &= ~FLAGS_FLOAT_E;
- }
- else
- {
- exponent = (int)trio_floor(workNumber);
- workNumber = number;
- /*
- * The expression A * 10^-B is equivalent to A / 10^B but the former
- * usually gives better accuracy.
- */
- workNumber *= TrioPower(dblBase, (trio_long_double_t)-exponent);
- if (trio_isinf(workNumber)) {
- /*
- * Scaling is done it two steps to avoid problems with subnormal
- * numbers.
- */
- workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent / 2));
- workNumber /= TrioPower(dblBase, (trio_long_double_t)(exponent - (exponent / 2)));
- }
- number = workNumber;
- isExponentNegative = (exponent < 0);
- uExponent = (isExponentNegative) ? -exponent : exponent;
- if (isHex)
- uExponent *= 4; /* log16(2) */
-#if TRIO_FEATURE_QUOTE
- /* No thousand separators */
- flags &= ~FLAGS_QUOTE;
-#endif
- }
- }
-
- integerNumber = trio_floor(number);
- fractionNumber = number - integerNumber;
-
- /*
- * Truncated number.
- *
- * Precision is number of significant digits for FLOAT_G and number of
- * fractional digits for others.
- */
- integerDigits = 1;
- if (integerNumber > epsilon)
- {
- integerDigits += (int)TrioLogarithm(integerNumber, base);
- }
-
- fractionDigits = precision;
- if (flags & FLAGS_FLOAT_G)
- {
- if (leadingFractionZeroes > 0)
- {
- fractionDigits += leadingFractionZeroes;
- }
- if ((integerNumber > epsilon) || (number <= epsilon))
- {
- fractionDigits -= integerDigits;
- }
- }
-
- dblFractionBase = TrioPower(base, fractionDigits);
-
- if (integerNumber < 1.0)
- {
- workNumber = number * dblFractionBase + TRIO_SUFFIX_LONG(0.5);
- if (trio_floor(number * dblFractionBase) != trio_floor(workNumber))
- {
- adjustNumber = TRUE;
- /* Remove a leading fraction zero if fraction is rounded up */
- if ((int)TrioLogarithm(number * dblFractionBase, base) != (int)TrioLogarithm(workNumber, base))
- {
- --leadingFractionZeroes;
- }
- }
- workNumber /= dblFractionBase;
- }
- else
- {
- workNumber = number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase;
- adjustNumber = (trio_floor(number) != trio_floor(workNumber));
- }
- if (adjustNumber)
- {
- if ((flags & FLAGS_FLOAT_G) && !(flags & FLAGS_FLOAT_E))
- {
- /* The adjustment may require a change to scientific notation */
- if ( (workNumber < TRIO_SUFFIX_LONG(1.0E-4)) ||
- (workNumber >= TrioPower(base, (trio_long_double_t)precision)) )
- {
- /* Use scientific notation */
- flags |= FLAGS_FLOAT_E;
- goto reprocess;
- }
- }
-
- if (flags & FLAGS_FLOAT_E)
- {
- workDigits = 1 + TrioLogarithm(trio_floor(workNumber), base);
- if (integerDigits == workDigits)
- {
- /* Adjust if the same number of digits are used */
- number += TRIO_SUFFIX_LONG(0.5) / dblFractionBase;
- integerNumber = trio_floor(number);
- fractionNumber = number - integerNumber;
- }
- else
- {
- /* Adjust if number was rounded up one digit (ie. 0.99 to 1.00) */
- exponent++;
- isExponentNegative = (exponent < 0);
- uExponent = (isExponentNegative) ? -exponent : exponent;
- if (isHex)
- uExponent *= 4; /* log16(2) */
- workNumber = (number + TRIO_SUFFIX_LONG(0.5) / dblFractionBase) / dblBase;
- integerNumber = trio_floor(workNumber);
- fractionNumber = workNumber - integerNumber;
- }
- }
- else
- {
- if (workNumber > 1.0)
- {
- /* Adjust if number was rounded up one digit (ie. 99 to 100) */
- integerNumber = trio_floor(workNumber);
- fractionNumber = 0.0;
- integerDigits = (integerNumber > epsilon)
- ? 1 + (int)TrioLogarithm(integerNumber, base)
- : 1;
- if (flags & FLAGS_FLOAT_G)
- {
- if (flags & FLAGS_ALTERNATIVE)
- {
- if ((integerNumber > epsilon) || (number <= epsilon))
- {
- fractionDigits -= integerDigits;
- }
- }
- else
- {
- fractionDigits = 0;
- }
- }
- }
- else
- {
- integerNumber = trio_floor(workNumber);
- fractionNumber = workNumber - integerNumber;
- if (flags & FLAGS_FLOAT_G)
- {
- if (flags & FLAGS_ALTERNATIVE)
- {
- fractionDigits = precision;
- if (leadingFractionZeroes > 0)
- {
- fractionDigits += leadingFractionZeroes;
- }
- if ((integerNumber > epsilon) || (number <= epsilon))
- {
- fractionDigits -= integerDigits;
- }
- }
- }
- }
- }
- }
-
- /* Estimate accuracy */
- integerAdjust = fractionAdjust = TRIO_SUFFIX_LONG(0.5);
-# if TRIO_FEATURE_ROUNDING
- if (flags & FLAGS_ROUNDING)
- {
- if (integerDigits > baseDigits)
- {
- integerThreshold = baseDigits;
- fractionDigits = 0;
- dblFractionBase = 1.0;
- fractionThreshold = 0;
- precision = 0; /* Disable decimal-point */
- integerAdjust = TrioPower(base, integerDigits - integerThreshold - 1);
- fractionAdjust = 0.0;
- }
- else
- {
- integerThreshold = integerDigits;
- fractionThreshold = fractionDigits - integerThreshold;
- fractionAdjust = 1.0;
- }
- }
- else
-# endif
- {
- integerThreshold = INT_MAX;
- fractionThreshold = INT_MAX;
- }
-
- /*
- * Calculate expected width.
- * sign + integer part + thousands separators + decimal point
- * + fraction + exponent
- */
- fractionAdjust /= dblFractionBase;
- hasOnlyZeroes = (trio_floor((fractionNumber + fractionAdjust) *
- dblFractionBase) < epsilon);
- keepDecimalPoint = ( (flags & FLAGS_ALTERNATIVE) ||
- !((precision == 0) ||
- (!keepTrailingZeroes && hasOnlyZeroes)) );
-
- expectedWidth = integerDigits + fractionDigits;
-
- if (!keepTrailingZeroes)
- {
- trailingZeroes = 0;
- workFractionNumber = fractionNumber;
- workFractionAdjust = fractionAdjust;
- fractionDigitsInspect = fractionDigits;
-
- if (integerDigits > integerThreshold)
- {
- fractionDigitsInspect = 0;
- }
- else if (fractionThreshold <= fractionDigits)
- {
- fractionDigitsInspect = fractionThreshold + 1;
- }
-
- trailingZeroes = fractionDigits - fractionDigitsInspect;
- for (i = 0; i < fractionDigitsInspect; i++)
- {
- workFractionNumber *= dblBase;
- workFractionAdjust *= dblBase;
- workNumber = trio_floor(workFractionNumber + workFractionAdjust);
- workFractionNumber -= workNumber;
- offset = (int)trio_fmod(workNumber, dblBase);
- if (offset == 0)
- {
- trailingZeroes++;
- }
- else
- {
- trailingZeroes = 0;
- }
- }
- expectedWidth -= trailingZeroes;
- }
-
- if (keepDecimalPoint)
- {
- expectedWidth += internalDecimalPointLength;
- }
-
-#if TRIO_FEATURE_QUOTE
- if (flags & FLAGS_QUOTE)
- {
- expectedWidth += TrioCalcThousandSeparatorLength(integerDigits);
- }
-#endif
-
- if (isNegative || (flags & FLAGS_SHOWSIGN) || (flags & FLAGS_SPACE))
- {
- expectedWidth += sizeof("-") - 1;
- }
-
- exponentDigits = 0;
- if (flags & FLAGS_FLOAT_E)
- {
- exponentDigits = (uExponent == 0)
- ? 1
- : (int)trio_ceil(TrioLogarithm((double)(uExponent + 1),
- (isHex) ? 10 : base));
- }
- requireTwoDigitExponent = ((base == BASE_DECIMAL) && (exponentDigits == 1));
- if (exponentDigits > 0)
- {
- expectedWidth += exponentDigits;
- expectedWidth += (requireTwoDigitExponent
- ? sizeof("E+0") - 1
- : sizeof("E+") - 1);
- }
-
- if (isHex)
- {
- expectedWidth += sizeof("0X") - 1;
- }
-
- /* Output prefixing */
- if (flags & FLAGS_NILPADDING)
- {
- /* Leading zeros must be after sign */
- if (isNegative)
- self->OutStream(self, '-');
- else if (flags & FLAGS_SHOWSIGN)
- self->OutStream(self, '+');
- else if (flags & FLAGS_SPACE)
- self->OutStream(self, ' ');
- if (isHex)
- {
- self->OutStream(self, '0');
- self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
- }
- if (!(flags & FLAGS_LEFTADJUST))
- {
- for (i = expectedWidth; i < width; i++)
- {
- self->OutStream(self, '0');
- }
- }
- }
- else
- {
- /* Leading spaces must be before sign */
- if (!(flags & FLAGS_LEFTADJUST))
- {
- for (i = expectedWidth; i < width; i++)
- {
- self->OutStream(self, CHAR_ADJUST);
- }
- }
- if (isNegative)
- self->OutStream(self, '-');
- else if (flags & FLAGS_SHOWSIGN)
- self->OutStream(self, '+');
- else if (flags & FLAGS_SPACE)
- self->OutStream(self, ' ');
- if (isHex)
- {
- self->OutStream(self, '0');
- self->OutStream(self, (flags & FLAGS_UPPER) ? 'X' : 'x');
- }
- }
-
- /* Output the integer part and thousand separators */
- for (i = 0; i < integerDigits; i++)
- {
- workNumber = trio_floor(((integerNumber + integerAdjust)
- / TrioPower(base, integerDigits - i - 1)));
- if (i > integerThreshold)
- {
- /* Beyond accuracy */
- self->OutStream(self, digits[0]);
- }
- else
- {
- self->OutStream(self, digits[(int)trio_fmod(workNumber, dblBase)]);
- }
-
-#if TRIO_FEATURE_QUOTE
- if (((flags & (FLAGS_FLOAT_E | FLAGS_QUOTE)) == FLAGS_QUOTE)
- && TrioFollowedBySeparator(integerDigits - i))
- {
- for (groupingPointer = internalThousandSeparator;
- *groupingPointer != NIL;
- groupingPointer++)
- {
- self->OutStream(self, *groupingPointer);
- }
- }
-#endif
- }
-
- /* Insert decimal point and build the fraction part */
- trailingZeroes = 0;
-
- if (keepDecimalPoint)
- {
- if (internalDecimalPoint)
- {
- self->OutStream(self, internalDecimalPoint);
- }
- else
- {
- for (i = 0; i < internalDecimalPointLength; i++)
- {
- self->OutStream(self, internalDecimalPointString[i]);
- }
- }
- }
-
- for (i = 0; i < fractionDigits; i++)
- {
- if ((integerDigits > integerThreshold) || (i > fractionThreshold))
- {
- /* Beyond accuracy */
- trailingZeroes++;
- }
- else
- {
- fractionNumber *= dblBase;
- fractionAdjust *= dblBase;
- workNumber = trio_floor(fractionNumber + fractionAdjust);
- if (workNumber > fractionNumber)
- {
- /* fractionNumber should never become negative */
- fractionNumber = 0.0;
- fractionAdjust = 0.0;
- }
- else
- {
- fractionNumber -= workNumber;
- }
- offset = (int)trio_fmod(workNumber, dblBase);
- if (offset == 0)
- {
- trailingZeroes++;
- }
- else
- {
- while (trailingZeroes > 0)
- {
- /* Not trailing zeroes after all */
- self->OutStream(self, digits[0]);
- trailingZeroes--;
- }
- self->OutStream(self, digits[offset]);
- }
- }
- }
-
- if (keepTrailingZeroes)
- {
- while (trailingZeroes > 0)
- {
- self->OutStream(self, digits[0]);
- trailingZeroes--;
- }
- }
-
- /* Output exponent */
- if (exponentDigits > 0)
- {
- self->OutStream(self,
- isHex
- ? ((flags & FLAGS_UPPER) ? 'P' : 'p')
- : ((flags & FLAGS_UPPER) ? 'E' : 'e'));
- self->OutStream(self, (isExponentNegative) ? '-' : '+');
-
- /* The exponent must contain at least two digits */
- if (requireTwoDigitExponent)
- self->OutStream(self, '0');
-
- if (isHex)
- base = 10;
- exponentBase = (int)TrioPower(base, exponentDigits - 1);
- for (i = 0; i < exponentDigits; i++)
- {
- self->OutStream(self, digits[(uExponent / exponentBase) % base]);
- exponentBase /= base;
- }
- }
- /* Output trailing spaces */
- if (flags & FLAGS_LEFTADJUST)
- {
- for (i = expectedWidth; i < width; i++)
- {
- self->OutStream(self, CHAR_ADJUST);
- }
- }
-}
-#endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * TrioFormatProcess
- *
- * Description:
- * This is the main engine for formatting output
- */
-TRIO_PRIVATE int
-TrioFormatProcess
-TRIO_ARGS3((data, format, parameters),
- trio_class_t *data,
- TRIO_CONST char *format,
- trio_parameter_t *parameters)
-{
- int i;
-#if TRIO_FEATURE_ERRNO
- TRIO_CONST char *string;
-#endif
- trio_pointer_t pointer;
- trio_flags_t flags;
- int width;
- int precision;
- int base;
- int offset;
-
- offset = 0;
- i = 0;
-
- for (;;)
- {
- /* Skip the parameter entries */
- while (parameters[i].type == FORMAT_PARAMETER)
- i++;
-
- /* Copy non conversion-specifier part of format string */
- while (offset < parameters[i].beginOffset)
- {
- if (CHAR_IDENTIFIER == format[offset] && CHAR_IDENTIFIER == format[offset + 1])
- {
- data->OutStream(data, CHAR_IDENTIFIER);
- offset += 2;
- }
- else
- {
- data->OutStream(data, format[offset++]);
- }
- }
-
- /* Abort if we reached end of format string */
- if (parameters[i].type == FORMAT_SENTINEL)
- break;
-
- /* Ouput parameter */
- flags = parameters[i].flags;
-
- /* Find width */
- width = parameters[i].width;
- if (flags & FLAGS_WIDTH_PARAMETER)
- {
- /* Get width from parameter list */
- width = (int)parameters[width].data.number.as_signed;
- if (width < 0)
- {
- /*
- * A negative width is the same as the - flag and
- * a positive width.
- */
- flags |= FLAGS_LEFTADJUST;
- flags &= ~FLAGS_NILPADDING;
- width = -width;
- }
- }
-
- /* Find precision */
- if (flags & FLAGS_PRECISION)
- {
- precision = parameters[i].precision;
- if (flags & FLAGS_PRECISION_PARAMETER)
- {
- /* Get precision from parameter list */
- precision = (int)parameters[precision].data.number.as_signed;
- if (precision < 0)
- {
- /*
- * A negative precision is the same as no
- * precision
- */
- precision = NO_PRECISION;
- }
- }
- }
- else
- {
- precision = NO_PRECISION;
- }
-
- /* Find base */
- if (NO_BASE != parameters[i].baseSpecifier)
- {
- /* Base from specifier has priority */
- base = parameters[i].baseSpecifier;
- }
- else if (flags & FLAGS_BASE_PARAMETER)
- {
- /* Get base from parameter list */
- base = parameters[i].base;
- base = (int)parameters[base].data.number.as_signed;
- }
- else
- {
- /* Use base from format string */
- base = parameters[i].base;
- }
-
- switch (parameters[i].type)
- {
- case FORMAT_CHAR:
-#if TRIO_FEATURE_QUOTE
- if (flags & FLAGS_QUOTE)
- data->OutStream(data, CHAR_QUOTE);
-#endif
- if (! (flags & FLAGS_LEFTADJUST))
- {
- while (--width > 0)
- data->OutStream(data, CHAR_ADJUST);
- }
-#if TRIO_FEATURE_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- TrioWriteWideStringCharacter(data,
- (trio_wchar_t)parameters[i].data.number.as_signed,
- flags,
- NO_WIDTH);
- }
- else
-#endif
- {
- TrioWriteStringCharacter(data,
- (int)parameters[i].data.number.as_signed,
- flags);
- }
-
- if (flags & FLAGS_LEFTADJUST)
- {
- while(--width > 0)
- data->OutStream(data, CHAR_ADJUST);
- }
-#if TRIO_FEATURE_QUOTE
- if (flags & FLAGS_QUOTE)
- data->OutStream(data, CHAR_QUOTE);
-#endif
-
- break; /* FORMAT_CHAR */
-
- case FORMAT_INT:
- TrioWriteNumber(data,
- parameters[i].data.number.as_unsigned,
- flags,
- width,
- precision,
- base);
-
- break; /* FORMAT_INT */
-
-#if TRIO_FEATURE_FLOAT
- case FORMAT_DOUBLE:
- TrioWriteDouble(data,
- parameters[i].data.longdoubleNumber,
- flags,
- width,
- precision,
- base);
- break; /* FORMAT_DOUBLE */
-#endif
-
- case FORMAT_STRING:
-#if TRIO_FEATURE_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- TrioWriteWideString(data,
- parameters[i].data.wstring,
- flags,
- width,
- precision);
- }
- else
-#endif
- {
- TrioWriteString(data,
- parameters[i].data.string,
- flags,
- width,
- precision);
- }
- break; /* FORMAT_STRING */
-
- case FORMAT_POINTER:
- {
- trio_reference_t reference;
-
- reference.data = data;
- reference.parameter = ¶meters[i];
- trio_print_pointer(&reference, parameters[i].data.pointer);
- }
- break; /* FORMAT_POINTER */
-
- case FORMAT_COUNT:
- pointer = parameters[i].data.pointer;
- if (NULL != pointer)
- {
- /*
- * C99 paragraph 7.19.6.1.8 says "the number of
- * characters written to the output stream so far by
- * this call", which is data->actually.committed
- */
-#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
- if (flags & FLAGS_SIZE_T)
- *(size_t *)pointer = (size_t)data->actually.committed;
- else
-#endif
-#if TRIO_FEATURE_PTRDIFF_T
- if (flags & FLAGS_PTRDIFF_T)
- *(ptrdiff_t *)pointer = (ptrdiff_t)data->actually.committed;
- else
-#endif
-#if TRIO_FEATURE_INTMAX_T
- if (flags & FLAGS_INTMAX_T)
- *(trio_intmax_t *)pointer = (trio_intmax_t)data->actually.committed;
- else
-#endif
- if (flags & FLAGS_QUAD)
- {
- *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)data->actually.committed;
- }
- else if (flags & FLAGS_LONG)
- {
- *(long int *)pointer = (long int)data->actually.committed;
- }
- else if (flags & FLAGS_SHORT)
- {
- *(short int *)pointer = (short int)data->actually.committed;
- }
- else
- {
- *(int *)pointer = (int)data->actually.committed;
- }
- }
- break; /* FORMAT_COUNT */
-
- case FORMAT_PARAMETER:
- break; /* FORMAT_PARAMETER */
-
-#if TRIO_FEATURE_ERRNO
- case FORMAT_ERRNO:
- string = trio_error(parameters[i].data.errorNumber);
- if (string)
- {
- TrioWriteString(data,
- string,
- flags,
- width,
- precision);
- }
- else
- {
- data->OutStream(data, '#');
- TrioWriteNumber(data,
- (trio_uintmax_t)parameters[i].data.errorNumber,
- flags,
- width,
- precision,
- BASE_DECIMAL);
- }
- break; /* FORMAT_ERRNO */
-#endif /* TRIO_FEATURE_ERRNO */
-
-#if TRIO_FEATURE_USER_DEFINED
- case FORMAT_USER_DEFINED:
- {
- trio_reference_t reference;
- trio_userdef_t *def = NULL;
-
- if (parameters[i].flags & FLAGS_USER_DEFINED_PARAMETER)
- {
- /* Use handle */
- if ((i > 0) ||
- (parameters[i - 1].type == FORMAT_PARAMETER))
- def = (trio_userdef_t *)parameters[i - 1].data.pointer;
- }
- else
- {
- /* Look up namespace */
- def = TrioFindNamespace(parameters[i].user_defined.namespace, NULL);
- }
- if (def)
- {
- reference.data = data;
- reference.parameter = ¶meters[i];
- def->callback(&reference);
- }
- }
- break;
-#endif /* TRIO_FEATURE_USER_DEFINED */
-
- default:
- break;
- } /* switch parameter type */
-
- /* Prepare for next */
- offset = parameters[i].endOffset;
- i++;
- }
-
- return data->processed;
-}
-
-/*************************************************************************
- * TrioFormatRef
- */
-#if TRIO_EXTENSION
-TRIO_PRIVATE int
-TrioFormatRef
-TRIO_ARGS4((reference, format, arglist, argarray),
- trio_reference_t *reference,
- TRIO_CONST char *format,
- va_list arglist,
- trio_pointer_t *argarray)
-{
- int status;
- trio_parameter_t parameters[MAX_PARAMETERS];
-
- status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);
- if (status < 0)
- return status;
-
- status = TrioFormatProcess(reference->data, format, parameters);
- if (reference->data->error != 0)
- {
- status = reference->data->error;
- }
- return status;
-}
-#endif /* TRIO_EXTENSION */
-
-/*************************************************************************
- * TrioFormat
- */
-TRIO_PRIVATE int
-TrioFormat
-TRIO_ARGS6((destination, destinationSize, OutStream, format, arglist, argarray),
- trio_pointer_t destination,
- size_t destinationSize,
- void (*OutStream) TRIO_PROTO((trio_class_t *, int)),
- TRIO_CONST char *format,
- va_list arglist,
- trio_pointer_t *argarray)
-{
- int status;
- trio_class_t data;
- trio_parameter_t parameters[MAX_PARAMETERS];
-
- assert(VALID(OutStream));
- assert(VALID(format));
-
- memset(&data, 0, sizeof(data));
- data.OutStream = OutStream;
- data.location = destination;
- data.max = destinationSize;
- data.error = 0;
-
-#if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-#endif
-
- status = TrioParse(TYPE_PRINT, format, parameters, arglist, argarray);
- if (status < 0)
- return status;
-
- status = TrioFormatProcess(&data, format, parameters);
- if (data.error != 0)
- {
- status = data.error;
- }
- return status;
-}
-
-/*************************************************************************
- * TrioOutStreamFile
- */
-#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO
-TRIO_PRIVATE void
-TrioOutStreamFile
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- FILE *file;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- file = (FILE *)self->location;
- self->processed++;
- if (fputc(output, file) == EOF)
- {
- self->error = TRIO_ERROR_RETURN(TRIO_EOF, 0);
- }
- else
- {
- self->actually.committed++;
- }
-}
-#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */
-
-/*************************************************************************
- * TrioOutStreamFileDescriptor
- */
-#if TRIO_FEATURE_FD
-TRIO_PRIVATE void
-TrioOutStreamFileDescriptor
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- int fd;
- char ch;
-
- assert(VALID(self));
-
- fd = *((int *)self->location);
- ch = (char)output;
- self->processed++;
- if (write(fd, &ch, sizeof(char)) == -1)
- {
- self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);
- }
- else
- {
- self->actually.committed++;
- }
-}
-#endif /* TRIO_FEATURE_FD */
-
-/*************************************************************************
- * TrioOutStreamCustom
- */
-#if TRIO_FEATURE_CLOSURE
-TRIO_PRIVATE void
-TrioOutStreamCustom
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- int status;
- trio_custom_t *data;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- data = (trio_custom_t *)self->location;
- if (data->stream.out)
- {
- status = (data->stream.out)(data->closure, output);
- if (status >= 0)
- {
- self->actually.committed++;
- }
- else
- {
- if (self->error == 0)
- {
- self->error = TRIO_ERROR_RETURN(TRIO_ECUSTOM, -status);
- }
- }
- }
- self->processed++;
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-/*************************************************************************
- * TrioOutStreamString
- */
-TRIO_PRIVATE void
-TrioOutStreamString
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- char **buffer;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- buffer = (char **)self->location;
- **buffer = (char)output;
- (*buffer)++;
- self->processed++;
- self->actually.committed++;
-}
-
-/*************************************************************************
- * TrioOutStreamStringMax
- */
-TRIO_PRIVATE void
-TrioOutStreamStringMax
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- char **buffer;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- buffer = (char **)self->location;
-
- if (self->processed < self->max)
- {
- **buffer = (char)output;
- (*buffer)++;
- self->actually.committed++;
- }
- self->processed++;
-}
-
-/*************************************************************************
- * TrioOutStreamStringDynamic
- */
-#if TRIO_FEATURE_DYNAMICSTRING
-TRIO_PRIVATE void
-TrioOutStreamStringDynamic
-TRIO_ARGS2((self, output),
- trio_class_t *self,
- int output)
-{
- assert(VALID(self));
- assert(VALID(self->location));
-
- if (self->error == 0)
- {
- trio_xstring_append_char((trio_string_t *)self->location,
- (char)output);
- self->actually.committed++;
- }
- /* The processed variable must always be increased */
- self->processed++;
-}
-#endif /* TRIO_FEATURE_DYNAMICSTRING */
-
-/*************************************************************************
- *
- * Formatted printing functions
- *
- ************************************************************************/
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_printf.h"
-#endif
-/** @addtogroup Printf
- @{
-*/
-
-/*************************************************************************
- * printf
- */
-
-/**
- Print to standard output stream.
-
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-#if TRIO_FEATURE_STDIO
-TRIO_PUBLIC int
-trio_printf
-TRIO_VARGS2((format, va_alist),
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-#endif /* TRIO_FEATURE_STDIO */
-
-/**
- Print to standard output stream.
-
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-#if TRIO_FEATURE_STDIO
-TRIO_PUBLIC int
-trio_vprintf
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(format));
-
- return TrioFormat(stdout, 0, TrioOutStreamFile, format, args, NULL);
-}
-#endif /* TRIO_FEATURE_STDIO */
-
-/**
- Print to standard output stream.
-
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-#if TRIO_FEATURE_STDIO
-TRIO_PUBLIC int
-trio_printfv
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- trio_pointer_t * args)
-{
- static va_list unused;
-
- assert(VALID(format));
-
- return TrioFormat(stdout, 0, TrioOutStreamFile, format, unused, args);
-}
-#endif /* TRIO_FEATURE_STDIO */
-
-/*************************************************************************
- * fprintf
- */
-
-/**
- Print to file.
-
- @param file File pointer.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-#if TRIO_FEATURE_FILE
-TRIO_PUBLIC int
-trio_fprintf
-TRIO_VARGS3((file, format, va_alist),
- FILE *file,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(file));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-#endif /* TRIO_FEATURE_FILE */
-
-/**
- Print to file.
-
- @param file File pointer.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-#if TRIO_FEATURE_FILE
-TRIO_PUBLIC int
-trio_vfprintf
-TRIO_ARGS3((file, format, args),
- FILE *file,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(file));
- assert(VALID(format));
-
- return TrioFormat(file, 0, TrioOutStreamFile, format, args, NULL);
-}
-#endif /* TRIO_FEATURE_FILE */
-
-/**
- Print to file.
-
- @param file File pointer.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-#if TRIO_FEATURE_FILE
-TRIO_PUBLIC int
-trio_fprintfv
-TRIO_ARGS3((file, format, args),
- FILE *file,
- TRIO_CONST char *format,
- trio_pointer_t * args)
-{
- static va_list unused;
-
- assert(VALID(file));
- assert(VALID(format));
-
- return TrioFormat(file, 0, TrioOutStreamFile, format, unused, args);
-}
-#endif /* TRIO_FEATURE_FILE */
-
-/*************************************************************************
- * dprintf
- */
-
-/**
- Print to file descriptor.
-
- @param fd File descriptor.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-#if TRIO_FEATURE_FD
-TRIO_PUBLIC int
-trio_dprintf
-TRIO_VARGS3((fd, format, va_alist),
- int fd,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-#endif /* TRIO_FEATURE_FD */
-
-/**
- Print to file descriptor.
-
- @param fd File descriptor.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-#if TRIO_FEATURE_FD
-TRIO_PUBLIC int
-trio_vdprintf
-TRIO_ARGS3((fd, format, args),
- int fd,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(format));
-
- return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, args, NULL);
-}
-#endif /* TRIO_FEATURE_FD */
-
-/**
- Print to file descriptor.
-
- @param fd File descriptor.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-#if TRIO_FEATURE_FD
-TRIO_PUBLIC int
-trio_dprintfv
-TRIO_ARGS3((fd, format, args),
- int fd,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- static va_list unused;
-
- assert(VALID(format));
-
- return TrioFormat(&fd, 0, TrioOutStreamFileDescriptor, format, unused, args);
-}
-#endif /* TRIO_FEATURE_FD */
-
-/*************************************************************************
- * cprintf
- */
-#if TRIO_FEATURE_CLOSURE
-TRIO_PUBLIC int
-trio_cprintf
-TRIO_VARGS4((stream, closure, format, va_alist),
- trio_outstream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- data.stream.out = stream;
- data.closure = closure;
- status = TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-#if TRIO_FEATURE_CLOSURE
-TRIO_PUBLIC int
-trio_vcprintf
-TRIO_ARGS4((stream, closure, format, args),
- trio_outstream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- va_list args)
-{
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- data.stream.out = stream;
- data.closure = closure;
- return TrioFormat(&data, 0, TrioOutStreamCustom, format, args, NULL);
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-#if TRIO_FEATURE_CLOSURE
-TRIO_PUBLIC int
-trio_cprintfv
-TRIO_ARGS4((stream, closure, format, args),
- trio_outstream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- void **args)
-{
- static va_list unused;
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- data.stream.out = stream;
- data.closure = closure;
- return TrioFormat(&data, 0, TrioOutStreamCustom, format, unused, args);
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-/*************************************************************************
- * sprintf
- */
-
-/**
- Print to string.
-
- @param buffer Output string.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_sprintf
-TRIO_VARGS3((buffer, format, va_alist),
- char *buffer,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL);
- *buffer = NIL; /* Terminate with NIL character */
- TRIO_VA_END(args);
- return status;
-}
-
-/**
- Print to string.
-
- @param buffer Output string.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vsprintf
-TRIO_ARGS3((buffer, format, args),
- char *buffer,
- TRIO_CONST char *format,
- va_list args)
-{
- int status;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, args, NULL);
- *buffer = NIL;
- return status;
-}
-
-/**
- Print to string.
-
- @param buffer Output string.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_sprintfv
-TRIO_ARGS3((buffer, format, args),
- char *buffer,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- static va_list unused;
- int status;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- status = TrioFormat(&buffer, 0, TrioOutStreamString, format, unused, args);
- *buffer = NIL;
- return status;
-}
-
-/*************************************************************************
- * snprintf
- */
-
-/**
- Print at most @p max characters to string.
-
- @param buffer Output string.
- @param max Maximum number of characters to print.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_snprintf
-TRIO_VARGS4((buffer, max, format, va_alist),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(buffer) || (max == 0));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, args, NULL);
- if (max > 0)
- *buffer = NIL;
- TRIO_VA_END(args);
- return status;
-}
-
-/**
- Print at most @p max characters to string.
-
- @param buffer Output string.
- @param max Maximum number of characters to print.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_vsnprintf
-TRIO_ARGS4((buffer, max, format, args),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- va_list args)
-{
- int status;
-
- assert(VALID(buffer) || (max == 0));
- assert(VALID(format));
-
- status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, args, NULL);
- if (max > 0)
- *buffer = NIL;
- return status;
-}
-
-/**
- Print at most @p max characters to string.
-
- @param buffer Output string.
- @param max Maximum number of characters to print.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-TRIO_PUBLIC int
-trio_snprintfv
-TRIO_ARGS4((buffer, max, format, args),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- static va_list unused;
- int status;
-
- assert(VALID(buffer) || (max == 0));
- assert(VALID(format));
-
- status = TrioFormat(&buffer, max > 0 ? max - 1 : 0,
- TrioOutStreamStringMax, format, unused, args);
- if (max > 0)
- *buffer = NIL;
- return status;
-}
-
-/*************************************************************************
- * snprintfcat
- * Appends the new string to the buffer string overwriting the '\0'
- * character at the end of buffer.
- */
-#if TRIO_EXTENSION
-TRIO_PUBLIC int
-trio_snprintfcat
-TRIO_VARGS4((buffer, max, format, va_alist),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
- size_t buf_len;
-
- TRIO_VA_START(args, format);
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- buf_len = trio_length(buffer);
- buffer = &buffer[buf_len];
-
- status = TrioFormat(&buffer, max - 1 - buf_len,
- TrioOutStreamStringMax, format, args, NULL);
- TRIO_VA_END(args);
- *buffer = NIL;
- return status;
-}
-#endif
-
-#if TRIO_EXTENSION
-TRIO_PUBLIC int
-trio_vsnprintfcat
-TRIO_ARGS4((buffer, max, format, args),
- char *buffer,
- size_t max,
- TRIO_CONST char *format,
- va_list args)
-{
- int status;
- size_t buf_len;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- buf_len = trio_length(buffer);
- buffer = &buffer[buf_len];
- status = TrioFormat(&buffer, max - 1 - buf_len,
- TrioOutStreamStringMax, format, args, NULL);
- *buffer = NIL;
- return status;
-}
-#endif
-
-/*************************************************************************
- * trio_aprintf
- */
-
-#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING
-TRIO_PUBLIC char *
-trio_aprintf
-TRIO_VARGS2((format, va_alist),
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- va_list args;
- trio_string_t *info;
- char *result = NULL;
-
- assert(VALID(format));
-
- info = trio_xstring_duplicate("");
- if (info)
- {
- TRIO_VA_START(args, format);
- (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, args, NULL);
- TRIO_VA_END(args);
-
- trio_string_terminate(info);
- result = trio_string_extract(info);
- trio_string_destroy(info);
- }
- return result;
-}
-#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */
-
-#if TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING
-TRIO_PUBLIC char *
-trio_vaprintf
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- va_list args)
-{
- trio_string_t *info;
- char *result = NULL;
-
- assert(VALID(format));
-
- info = trio_xstring_duplicate("");
- if (info)
- {
- (void)TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, args, NULL);
- trio_string_terminate(info);
- result = trio_string_extract(info);
- trio_string_destroy(info);
- }
- return result;
-}
-#endif /* TRIO_DEPRECATED && TRIO_FEATURE_DYNAMICSTRING */
-
-/**
- Allocate and print to string.
- The memory allocated and returned by @p result must be freed by the
- calling application.
-
- @param result Output string.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of printed characters.
- */
-#if TRIO_FEATURE_DYNAMICSTRING
-TRIO_PUBLIC int
-trio_asprintf
-TRIO_VARGS3((result, format, va_alist),
- char **result,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- va_list args;
- int status;
- trio_string_t *info;
-
- assert(VALID(format));
-
- *result = NULL;
-
- info = trio_xstring_duplicate("");
- if (info == NULL)
- {
- status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
- }
- else
- {
- TRIO_VA_START(args, format);
- status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, args, NULL);
- TRIO_VA_END(args);
- if (status >= 0)
- {
- trio_string_terminate(info);
- *result = trio_string_extract(info);
- }
- trio_string_destroy(info);
- }
- return status;
-}
-#endif /* TRIO_FEATURE_DYNAMICSTRING */
-
-/**
- Allocate and print to string.
- The memory allocated and returned by @p result must be freed by the
- calling application.
-
- @param result Output string.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-#if TRIO_FEATURE_DYNAMICSTRING
-TRIO_PUBLIC int
-trio_vasprintf
-TRIO_ARGS3((result, format, args),
- char **result,
- TRIO_CONST char *format,
- va_list args)
-{
- int status;
- trio_string_t *info;
-
- assert(VALID(format));
-
- *result = NULL;
-
- info = trio_xstring_duplicate("");
- if (info == NULL)
- {
- status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
- }
- else
- {
- status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, args, NULL);
- if (status >= 0)
- {
- trio_string_terminate(info);
- *result = trio_string_extract(info);
- }
- trio_string_destroy(info);
- }
- return status;
-}
-#endif /* TRIO_FEATURE_DYNAMICSTRING */
-
-/**
- Allocate and print to string.
- The memory allocated and returned by @p result must be freed by the
- calling application.
-
- @param result Output string.
- @param format Formatting string.
- @param args Arguments.
- @return Number of printed characters.
- */
-#if TRIO_FEATURE_DYNAMICSTRING
-TRIO_PUBLIC int
-trio_asprintfv
-TRIO_ARGS3((result, format, args),
- char **result,
- TRIO_CONST char *format,
- trio_pointer_t * args)
-{
- static va_list unused;
- int status;
- trio_string_t *info;
-
- assert(VALID(format));
-
- *result = NULL;
-
- info = trio_xstring_duplicate("");
- if (info == NULL)
- {
- status = TRIO_ERROR_RETURN(TRIO_ENOMEM, 0);
- }
- else
- {
- status = TrioFormat(info, 0, TrioOutStreamStringDynamic,
- format, unused, args);
- if (status >= 0)
- {
- trio_string_terminate(info);
- *result = trio_string_extract(info);
- }
- trio_string_destroy(info);
- }
- return status;
-}
-#endif /* TRIO_FEATURE_DYNAMICSTRING */
-
-/** @} End of Printf documentation module */
-
-/*************************************************************************
- *
- * CALLBACK
- *
- ************************************************************************/
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_register.h"
-#endif
-/**
- @addtogroup UserDefined
- @{
-*/
-
-#if TRIO_FEATURE_USER_DEFINED
-
-/*************************************************************************
- * trio_register
- */
-
-/**
- Register new user-defined specifier.
-
- @param callback
- @param name
- @return Handle.
- */
-TRIO_PUBLIC trio_pointer_t
-trio_register
-TRIO_ARGS2((callback, name),
- trio_callback_t callback,
- TRIO_CONST char *name)
-{
- trio_userdef_t *def;
- trio_userdef_t *prev = NULL;
-
- if (callback == NULL)
- return NULL;
-
- if (name)
- {
- /* Handle built-in namespaces */
- if (name[0] == ':')
- {
- if (trio_equal(name, ":enter"))
- {
- internalEnterCriticalRegion = callback;
- }
- else if (trio_equal(name, ":leave"))
- {
- internalLeaveCriticalRegion = callback;
- }
- return NULL;
- }
-
- /* Bail out if namespace is too long */
- if (trio_length(name) >= MAX_USER_NAME)
- return NULL;
-
- /* Bail out if namespace already is registered */
- def = TrioFindNamespace(name, &prev);
- if (def)
- return NULL;
- }
-
- def = (trio_userdef_t *)TRIO_MALLOC(sizeof(trio_userdef_t));
- if (def)
- {
- if (internalEnterCriticalRegion)
- (void)internalEnterCriticalRegion(NULL);
-
- if (name)
- {
- /* Link into internal list */
- if (prev == NULL)
- internalUserDef = def;
- else
- prev->next = def;
- }
- /* Initialize */
- def->callback = callback;
- def->name = (name == NULL)
- ? NULL
- : trio_duplicate(name);
- def->next = NULL;
-
- if (internalLeaveCriticalRegion)
- (void)internalLeaveCriticalRegion(NULL);
- }
- return (trio_pointer_t)def;
-}
-
-/**
- Unregister an existing user-defined specifier.
-
- @param handle
- */
-void
-trio_unregister
-TRIO_ARGS1((handle),
- trio_pointer_t handle)
-{
- trio_userdef_t *self = (trio_userdef_t *)handle;
- trio_userdef_t *def;
- trio_userdef_t *prev = NULL;
-
- assert(VALID(self));
-
- if (self->name)
- {
- def = TrioFindNamespace(self->name, &prev);
- if (def)
- {
- if (internalEnterCriticalRegion)
- (void)internalEnterCriticalRegion(NULL);
-
- if (prev == NULL)
- internalUserDef = internalUserDef->next;
- else
- prev->next = def->next;
-
- if (internalLeaveCriticalRegion)
- (void)internalLeaveCriticalRegion(NULL);
- }
- trio_destroy(self->name);
- }
- TRIO_FREE(self);
-}
-
-/*************************************************************************
- * trio_get_format [public]
- */
-TRIO_CONST char *
-trio_get_format
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
-#if TRIO_FEATURE_USER_DEFINED
- assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
-#endif
-
- return (((trio_reference_t *)ref)->parameter->user_data);
-}
-
-/*************************************************************************
- * trio_get_argument [public]
- */
-TRIO_CONST trio_pointer_t
-trio_get_argument
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
-#if TRIO_FEATURE_USER_DEFINED
- assert(((trio_reference_t *)ref)->parameter->type == FORMAT_USER_DEFINED);
-#endif
-
- return ((trio_reference_t *)ref)->parameter->data.pointer;
-}
-
-/*************************************************************************
- * trio_get_width / trio_set_width [public]
- */
-int
-trio_get_width
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return ((trio_reference_t *)ref)->parameter->width;
-}
-
-void
-trio_set_width
-TRIO_ARGS2((ref, width),
- trio_pointer_t ref,
- int width)
-{
- ((trio_reference_t *)ref)->parameter->width = width;
-}
-
-/*************************************************************************
- * trio_get_precision / trio_set_precision [public]
- */
-int
-trio_get_precision
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->precision);
-}
-
-void
-trio_set_precision
-TRIO_ARGS2((ref, precision),
- trio_pointer_t ref,
- int precision)
-{
- ((trio_reference_t *)ref)->parameter->precision = precision;
-}
-
-/*************************************************************************
- * trio_get_base / trio_set_base [public]
- */
-int
-trio_get_base
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->base);
-}
-
-void
-trio_set_base
-TRIO_ARGS2((ref, base),
- trio_pointer_t ref,
- int base)
-{
- ((trio_reference_t *)ref)->parameter->base = base;
-}
-
-/*************************************************************************
- * trio_get_long / trio_set_long [public]
- */
-int
-trio_get_long
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONG)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_long
-TRIO_ARGS2((ref, is_long),
- trio_pointer_t ref,
- int is_long)
-{
- if (is_long)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONG;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONG;
-}
-
-/*************************************************************************
- * trio_get_longlong / trio_set_longlong [public]
- */
-int
-trio_get_longlong
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUAD)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_longlong
-TRIO_ARGS2((ref, is_longlong),
- trio_pointer_t ref,
- int is_longlong)
-{
- if (is_longlong)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUAD;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUAD;
-}
-
-/*************************************************************************
- * trio_get_longdouble / trio_set_longdouble [public]
- */
-# if TRIO_FEATURE_FLOAT
-int
-trio_get_longdouble
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LONGDOUBLE)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_longdouble
-TRIO_ARGS2((ref, is_longdouble),
- trio_pointer_t ref,
- int is_longdouble)
-{
- if (is_longdouble)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LONGDOUBLE;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LONGDOUBLE;
-}
-# endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * trio_get_short / trio_set_short [public]
- */
-int
-trio_get_short
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORT)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_short
-TRIO_ARGS2((ref, is_short),
- trio_pointer_t ref,
- int is_short)
-{
- if (is_short)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORT;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORT;
-}
-
-/*************************************************************************
- * trio_get_shortshort / trio_set_shortshort [public]
- */
-int
-trio_get_shortshort
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHORTSHORT)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_shortshort
-TRIO_ARGS2((ref, is_shortshort),
- trio_pointer_t ref,
- int is_shortshort)
-{
- if (is_shortshort)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHORTSHORT;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHORTSHORT;
-}
-
-/*************************************************************************
- * trio_get_alternative / trio_set_alternative [public]
- */
-int
-trio_get_alternative
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_ALTERNATIVE)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_alternative
-TRIO_ARGS2((ref, is_alternative),
- trio_pointer_t ref,
- int is_alternative)
-{
- if (is_alternative)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_ALTERNATIVE;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_ALTERNATIVE;
-}
-
-/*************************************************************************
- * trio_get_alignment / trio_set_alignment [public]
- */
-int
-trio_get_alignment
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_LEFTADJUST)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_alignment
-TRIO_ARGS2((ref, is_leftaligned),
- trio_pointer_t ref,
- int is_leftaligned)
-{
- if (is_leftaligned)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_LEFTADJUST;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_LEFTADJUST;
-}
-
-/*************************************************************************
- * trio_get_spacing /trio_set_spacing [public]
- */
-int
-trio_get_spacing
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SPACE)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_spacing
-TRIO_ARGS2((ref, is_space),
- trio_pointer_t ref,
- int is_space)
-{
- if (is_space)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SPACE;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SPACE;
-}
-
-/*************************************************************************
- * trio_get_sign / trio_set_sign [public]
- */
-int
-trio_get_sign
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SHOWSIGN)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_sign
-TRIO_ARGS2((ref, is_sign),
- trio_pointer_t ref,
- int is_sign)
-{
- if (is_sign)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SHOWSIGN;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SHOWSIGN;
-}
-
-/*************************************************************************
- * trio_get_padding / trio_set_padding [public]
- */
-int
-trio_get_padding
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_NILPADDING)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_padding
-TRIO_ARGS2((ref, is_padding),
- trio_pointer_t ref,
- int is_padding)
-{
- if (is_padding)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_NILPADDING;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_NILPADDING;
-}
-
-/*************************************************************************
- * trio_get_quote / trio_set_quote [public]
- */
-# if TRIO_FEATURE_QUOTE
-int
-trio_get_quote
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_QUOTE)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_quote
-TRIO_ARGS2((ref, is_quote),
- trio_pointer_t ref,
- int is_quote)
-{
- if (is_quote)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_QUOTE;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_QUOTE;
-}
-#endif /* TRIO_FEATURE_QUOTE */
-
-/*************************************************************************
- * trio_get_upper / trio_set_upper [public]
- */
-int
-trio_get_upper
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_UPPER)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_upper
-TRIO_ARGS2((ref, is_upper),
- trio_pointer_t ref,
- int is_upper)
-{
- if (is_upper)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_UPPER;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_UPPER;
-}
-
-/*************************************************************************
- * trio_get_largest / trio_set_largest [public]
- */
-#if TRIO_FEATURE_INTMAX_T
-int
-trio_get_largest
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_INTMAX_T)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_largest
-TRIO_ARGS2((ref, is_largest),
- trio_pointer_t ref,
- int is_largest)
-{
- if (is_largest)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_INTMAX_T;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_INTMAX_T;
-}
-#endif /* TRIO_FEATURE_INTMAX_T */
-
-/*************************************************************************
- * trio_get_ptrdiff / trio_set_ptrdiff [public]
- */
-#if TRIO_FEATURE_PTRDIFF_T
-int
-trio_get_ptrdiff
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_PTRDIFF_T)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_ptrdiff
-TRIO_ARGS2((ref, is_ptrdiff),
- trio_pointer_t ref,
- int is_ptrdiff)
-{
- if (is_ptrdiff)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_PTRDIFF_T;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_PTRDIFF_T;
-}
-#endif /* TRIO_FEATURE_PTRDIFF_T */
-
-/*************************************************************************
- * trio_get_size / trio_set_size [public]
- */
-#if TRIO_FEATURE_SIZE_T
-int
-trio_get_size
-TRIO_ARGS1((ref),
- trio_pointer_t ref)
-{
- return (((trio_reference_t *)ref)->parameter->flags & FLAGS_SIZE_T)
- ? TRUE
- : FALSE;
-}
-
-void
-trio_set_size
-TRIO_ARGS2((ref, is_size),
- trio_pointer_t ref,
- int is_size)
-{
- if (is_size)
- ((trio_reference_t *)ref)->parameter->flags |= FLAGS_SIZE_T;
- else
- ((trio_reference_t *)ref)->parameter->flags &= ~FLAGS_SIZE_T;
-}
-#endif /* TRIO_FEATURE_SIZE_T */
-
-/*************************************************************************
- * trio_print_int [public]
- */
-void
-trio_print_int
-TRIO_ARGS2((ref, number),
- trio_pointer_t ref,
- int number)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
-
- TrioWriteNumber(self->data,
- (trio_uintmax_t)number,
- self->parameter->flags,
- self->parameter->width,
- self->parameter->precision,
- self->parameter->base);
-}
-
-/*************************************************************************
- * trio_print_uint [public]
- */
-void
-trio_print_uint
-TRIO_ARGS2((ref, number),
- trio_pointer_t ref,
- unsigned int number)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
-
- TrioWriteNumber(self->data,
- (trio_uintmax_t)number,
- self->parameter->flags | FLAGS_UNSIGNED,
- self->parameter->width,
- self->parameter->precision,
- self->parameter->base);
-}
-
-/*************************************************************************
- * trio_print_double [public]
- */
-#if TRIO_FEATURE_FLOAT
-void
-trio_print_double
-TRIO_ARGS2((ref, number),
- trio_pointer_t ref,
- double number)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
-
- TrioWriteDouble(self->data,
- number,
- self->parameter->flags,
- self->parameter->width,
- self->parameter->precision,
- self->parameter->base);
-}
-#endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * trio_print_string [public]
- */
-void
-trio_print_string
-TRIO_ARGS2((ref, string),
- trio_pointer_t ref,
- TRIO_CONST char *string)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
-
- TrioWriteString(self->data,
- string,
- self->parameter->flags,
- self->parameter->width,
- self->parameter->precision);
-}
-
-/*************************************************************************
- * trio_print_ref [public]
- */
-int
-trio_print_ref
-TRIO_VARGS3((ref, format, va_alist),
- trio_pointer_t ref,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list arglist;
-
- assert(VALID(format));
-
- TRIO_VA_START(arglist, format);
- status = TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL);
- TRIO_VA_END(arglist);
- return status;
-}
-
-/*************************************************************************
- * trio_vprint_ref [public]
- */
-int
-trio_vprint_ref
-TRIO_ARGS3((ref, format, arglist),
- trio_pointer_t ref,
- TRIO_CONST char *format,
- va_list arglist)
-{
- assert(VALID(format));
-
- return TrioFormatRef((trio_reference_t *)ref, format, arglist, NULL);
-}
-
-/*************************************************************************
- * trio_printv_ref [public]
- */
-int
-trio_printv_ref
-TRIO_ARGS3((ref, format, argarray),
- trio_pointer_t ref,
- TRIO_CONST char *format,
- trio_pointer_t *argarray)
-{
- static va_list unused;
-
- assert(VALID(format));
-
- return TrioFormatRef((trio_reference_t *)ref, format, unused, argarray);
-}
-
-#endif
-
-/*************************************************************************
- * trio_print_pointer [public]
- */
-void
-trio_print_pointer
-TRIO_ARGS2((ref, pointer),
- trio_pointer_t ref,
- trio_pointer_t pointer)
-{
- trio_reference_t *self = (trio_reference_t *)ref;
- trio_flags_t flags;
- trio_uintmax_t number;
-
- if (NULL == pointer)
- {
- TRIO_CONST char *string = internalNullString;
- while (*string)
- self->data->OutStream(self->data, *string++);
- }
- else
- {
- /*
- * The subtraction of the null pointer is a workaround
- * to avoid a compiler warning. The performance overhead
- * is negligible (and likely to be removed by an
- * optimizing compiler). The (char *) casting is done
- * to please ANSI C++.
- */
- number = (trio_uintmax_t)((char *)pointer - (char *)0);
- /* Shrink to size of pointer */
- number &= (trio_uintmax_t)-1;
- flags = self->parameter->flags;
- flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE |
- FLAGS_NILPADDING);
- TrioWriteNumber(self->data,
- number,
- flags,
- POINTER_WIDTH,
- NO_PRECISION,
- BASE_HEX);
- }
-}
-
-/** @} End of UserDefined documentation module */
-
-/*************************************************************************
- *
- * LOCALES
- *
- ************************************************************************/
-
-/*************************************************************************
- * trio_locale_set_decimal_point
- *
- * Decimal point can only be one character. The input argument is a
- * string to enable multibyte characters. At most MB_LEN_MAX characters
- * will be used.
- */
-#if TRIO_FEATURE_LOCALE
-TRIO_PUBLIC void
-trio_locale_set_decimal_point
-TRIO_ARGS1((decimalPoint),
- char *decimalPoint)
-{
-#if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-#endif
- internalDecimalPointLength = trio_length(decimalPoint);
- if (internalDecimalPointLength == 1)
- {
- internalDecimalPoint = *decimalPoint;
- }
- else
- {
- internalDecimalPoint = NIL;
- trio_copy_max(internalDecimalPointString,
- sizeof(internalDecimalPointString),
- decimalPoint);
- }
-}
-#endif
-
-/*************************************************************************
- * trio_locale_set_thousand_separator
- *
- * See trio_locale_set_decimal_point
- */
-#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION
-TRIO_PUBLIC void
-trio_locale_set_thousand_separator
-TRIO_ARGS1((thousandSeparator),
- char *thousandSeparator)
-{
-# if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-# endif
- trio_copy_max(internalThousandSeparator,
- sizeof(internalThousandSeparator),
- thousandSeparator);
- internalThousandSeparatorLength = trio_length(internalThousandSeparator);
-}
-#endif
-
-/*************************************************************************
- * trio_locale_set_grouping
- *
- * Array of bytes. Reversed order.
- *
- * CHAR_MAX : No further grouping
- * 0 : Repeat last group for the remaining digits (not necessary
- * as C strings are zero-terminated)
- * n : Set current group to n
- *
- * Same order as the grouping attribute in LC_NUMERIC.
- */
-#if TRIO_FEATURE_LOCALE || TRIO_EXTENSION
-TRIO_PUBLIC void
-trio_locale_set_grouping
-TRIO_ARGS1((grouping),
- char *grouping)
-{
-# if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-# endif
- trio_copy_max(internalGrouping,
- sizeof(internalGrouping),
- grouping);
-}
-#endif
-
-
-/*************************************************************************
- *
- * SCANNING
- *
- ************************************************************************/
-
-#if TRIO_FEATURE_SCANF
-
-/*************************************************************************
- * TrioSkipWhitespaces
- */
-TRIO_PRIVATE int
-TrioSkipWhitespaces
-TRIO_ARGS1((self),
- trio_class_t *self)
-{
- int ch;
-
- ch = self->current;
- while (isspace(ch))
- {
- self->InStream(self, &ch);
- }
- return ch;
-}
-
-/*************************************************************************
- * TrioGetCollation
- */
-#if TRIO_EXTENSION
-TRIO_PRIVATE void
-TrioGetCollation(TRIO_NOARGS)
-{
- int i;
- int j;
- int k;
- char first[2];
- char second[2];
-
- /* This is computationally expensive */
- first[1] = NIL;
- second[1] = NIL;
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- {
- k = 0;
- first[0] = (char)i;
- for (j = 0; j < MAX_CHARACTER_CLASS; j++)
- {
- second[0] = (char)j;
- if (trio_equal_locale(first, second))
- internalCollationArray[i][k++] = (char)j;
- }
- internalCollationArray[i][k] = NIL;
- }
-}
-#endif
-
-/*************************************************************************
- * TrioGetCharacterClass
- *
- * FIXME:
- * multibyte
- */
-TRIO_PRIVATE int
-TrioGetCharacterClass
-TRIO_ARGS4((format, offsetPointer, flagsPointer, characterclass),
- TRIO_CONST char *format,
- int *offsetPointer,
- trio_flags_t *flagsPointer,
- int *characterclass)
-{
- int offset = *offsetPointer;
- int i;
- char ch;
- char range_begin;
- char range_end;
-
- *flagsPointer &= ~FLAGS_EXCLUDE;
-
- if (format[offset] == QUALIFIER_CIRCUMFLEX)
- {
- *flagsPointer |= FLAGS_EXCLUDE;
- offset++;
- }
- /*
- * If the ungroup character is at the beginning of the scanlist,
- * it will be part of the class, and a second ungroup character
- * must follow to end the group.
- */
- if (format[offset] == SPECIFIER_UNGROUP)
- {
- characterclass[(int)SPECIFIER_UNGROUP]++;
- offset++;
- }
- /*
- * Minus is used to specify ranges. To include minus in the class,
- * it must be at the beginning of the list
- */
- if (format[offset] == QUALIFIER_MINUS)
- {
- characterclass[(int)QUALIFIER_MINUS]++;
- offset++;
- }
- /* Collect characters */
- for (ch = format[offset];
- (ch != SPECIFIER_UNGROUP) && (ch != NIL);
- ch = format[++offset])
- {
- switch (ch)
- {
- case QUALIFIER_MINUS: /* Scanlist ranges */
-
- /*
- * Both C99 and UNIX98 describes ranges as implementation-
- * defined.
- *
- * We support the following behaviour (although this may
- * change as we become wiser)
- * - only increasing ranges, ie. [a-b] but not [b-a]
- * - transitive ranges, ie. [a-b-c] == [a-c]
- * - trailing minus, ie. [a-] is interpreted as an 'a'
- * and a '-'
- * - duplicates (although we can easily convert these
- * into errors)
- */
- range_begin = format[offset - 1];
- range_end = format[++offset];
- if (range_end == SPECIFIER_UNGROUP)
- {
- /* Trailing minus is included */
- characterclass[(int)ch]++;
- ch = range_end;
- break; /* for */
- }
- if (range_end == NIL)
- return TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
- if (range_begin > range_end)
- return TRIO_ERROR_RETURN(TRIO_ERANGE, offset);
-
- for (i = (int)range_begin; i <= (int)range_end; i++)
- characterclass[i]++;
-
- ch = range_end;
- break;
-
-#if TRIO_EXTENSION
-
- case SPECIFIER_GROUP:
-
- switch (format[offset + 1])
- {
- case QUALIFIER_DOT: /* Collating symbol */
- /*
- * FIXME: This will be easier to implement when multibyte
- * characters have been implemented. Until now, we ignore
- * this feature.
- */
- for (i = offset + 2; ; i++)
- {
- if (format[i] == NIL)
- /* Error in syntax */
- return -1;
- else if (format[i] == QUALIFIER_DOT)
- break; /* for */
- }
- if (format[++i] != SPECIFIER_UNGROUP)
- return -1;
-
- offset = i;
- break;
-
- case QUALIFIER_EQUAL: /* Equivalence class expressions */
- {
- unsigned int j;
- unsigned int k;
-
- if (internalCollationUnconverted)
- {
- /* Lazy evaluation of collation array */
- TrioGetCollation();
- internalCollationUnconverted = FALSE;
- }
- for (i = offset + 2; ; i++)
- {
- if (format[i] == NIL)
- /* Error in syntax */
- return -1;
- else if (format[i] == QUALIFIER_EQUAL)
- break; /* for */
- else
- {
- /* Mark any equivalent character */
- k = (unsigned int)format[i];
- for (j = 0; internalCollationArray[k][j] != NIL; j++)
- characterclass[(int)internalCollationArray[k][j]]++;
- }
- }
- if (format[++i] != SPECIFIER_UNGROUP)
- return -1;
-
- offset = i;
- }
- break;
-
- case QUALIFIER_COLON: /* Character class expressions */
-
- if (trio_equal_max(CLASS_ALNUM, sizeof(CLASS_ALNUM) - 1,
- &format[offset]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isalnum(i))
- characterclass[i]++;
- offset += sizeof(CLASS_ALNUM) - 1;
- }
- else if (trio_equal_max(CLASS_ALPHA, sizeof(CLASS_ALPHA) - 1,
- &format[offset]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isalpha(i))
- characterclass[i]++;
- offset += sizeof(CLASS_ALPHA) - 1;
- }
- else if (trio_equal_max(CLASS_CNTRL, sizeof(CLASS_CNTRL) - 1,
- &format[offset]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (iscntrl(i))
- characterclass[i]++;
- offset += sizeof(CLASS_CNTRL) - 1;
- }
- else if (trio_equal_max(CLASS_DIGIT, sizeof(CLASS_DIGIT) - 1,
- &format[offset]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isdigit(i))
- characterclass[i]++;
- offset += sizeof(CLASS_DIGIT) - 1;
- }
- else if (trio_equal_max(CLASS_GRAPH, sizeof(CLASS_GRAPH) - 1,
- &format[offset]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isgraph(i))
- characterclass[i]++;
- offset += sizeof(CLASS_GRAPH) - 1;
- }
- else if (trio_equal_max(CLASS_LOWER, sizeof(CLASS_LOWER) - 1,
- &format[offset]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (islower(i))
- characterclass[i]++;
- offset += sizeof(CLASS_LOWER) - 1;
- }
- else if (trio_equal_max(CLASS_PRINT, sizeof(CLASS_PRINT) - 1,
- &format[offset]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isprint(i))
- characterclass[i]++;
- offset += sizeof(CLASS_PRINT) - 1;
- }
- else if (trio_equal_max(CLASS_PUNCT, sizeof(CLASS_PUNCT) - 1,
- &format[offset]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (ispunct(i))
- characterclass[i]++;
- offset += sizeof(CLASS_PUNCT) - 1;
- }
- else if (trio_equal_max(CLASS_SPACE, sizeof(CLASS_SPACE) - 1,
- &format[offset]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isspace(i))
- characterclass[i]++;
- offset += sizeof(CLASS_SPACE) - 1;
- }
- else if (trio_equal_max(CLASS_UPPER, sizeof(CLASS_UPPER) - 1,
- &format[offset]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isupper(i))
- characterclass[i]++;
- offset += sizeof(CLASS_UPPER) - 1;
- }
- else if (trio_equal_max(CLASS_XDIGIT, sizeof(CLASS_XDIGIT) - 1,
- &format[offset]))
- {
- for (i = 0; i < MAX_CHARACTER_CLASS; i++)
- if (isxdigit(i))
- characterclass[i]++;
- offset += sizeof(CLASS_XDIGIT) - 1;
- }
- else
- {
- characterclass[(int)ch]++;
- }
- break;
-
- default:
- characterclass[(int)ch]++;
- break;
- }
- break;
-
-#endif /* TRIO_EXTENSION */
-
- default:
- characterclass[(int)ch]++;
- break;
- }
- }
- return 0;
-}
-
-/*************************************************************************
- * TrioReadNumber
- *
- * We implement our own number conversion in preference of strtol and
- * strtoul, because we must handle 'long long' and thousand separators.
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadNumber
-TRIO_ARGS5((self, target, flags, width, base),
- trio_class_t *self,
- trio_uintmax_t *target,
- trio_flags_t flags,
- int width,
- int base)
-{
- trio_uintmax_t number = 0;
- int digit;
- int count;
- BOOLEAN_T isNegative = FALSE;
- BOOLEAN_T gotNumber = FALSE;
- int j;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
- assert((base >= MIN_BASE && base <= MAX_BASE) || (base == NO_BASE));
-
- if (internalDigitsUnconverted)
- {
- /* Lazy evaluation of digits array */
- memset(internalDigitArray, -1, sizeof(internalDigitArray));
- for (j = 0; j < (int)sizeof(internalDigitsLower) - 1; j++)
- {
- internalDigitArray[(int)internalDigitsLower[j]] = j;
- internalDigitArray[(int)internalDigitsUpper[j]] = j;
- }
- internalDigitsUnconverted = FALSE;
- }
-
- TrioSkipWhitespaces(self);
-
- /* Leading sign */
- if (self->current == '+')
- {
- self->InStream(self, NULL);
- }
- else if (self->current == '-')
- {
- self->InStream(self, NULL);
- isNegative = TRUE;
- }
-
- count = self->processed;
-
- if (flags & FLAGS_ALTERNATIVE)
- {
- switch (base)
- {
- case NO_BASE:
- case BASE_OCTAL:
- case BASE_HEX:
- case BASE_BINARY:
- if (self->current == '0')
- {
- self->InStream(self, NULL);
- if (self->current)
- {
- if ((base == BASE_HEX) &&
- (trio_to_upper(self->current) == 'X'))
- {
- self->InStream(self, NULL);
- }
- else if ((base == BASE_BINARY) &&
- (trio_to_upper(self->current) == 'B'))
- {
- self->InStream(self, NULL);
- }
- }
- }
- else
- return FALSE;
- break;
- default:
- break;
- }
- }
-
- while (((width == NO_WIDTH) || (self->processed - count < width)) &&
- (! ((self->current == EOF) || isspace(self->current))))
- {
- if (isascii(self->current))
- {
- digit = internalDigitArray[self->current];
- /* Abort if digit is not allowed in the specified base */
- if ((digit == -1) || (digit >= base))
- break;
- }
-#if TRIO_FEATURE_QUOTE
- else if (flags & FLAGS_QUOTE)
- {
- /* Compare with thousands separator */
- for (j = 0; internalThousandSeparator[j] && self->current; j++)
- {
- if (internalThousandSeparator[j] != self->current)
- break;
-
- self->InStream(self, NULL);
- }
- if (internalThousandSeparator[j])
- break; /* Mismatch */
- else
- continue; /* Match */
- }
-#endif
- else
- break;
-
- number *= base;
- number += digit;
- gotNumber = TRUE; /* we need at least one digit */
-
- self->InStream(self, NULL);
- }
-
- /* Was anything read at all? */
- if (!gotNumber)
- return FALSE;
-
- if (target)
- *target = (isNegative) ? (trio_uintmax_t)(-((trio_intmax_t)number)) : number;
- return TRUE;
-}
-
-/*************************************************************************
- * TrioReadChar
- */
-TRIO_PRIVATE int
-TrioReadChar
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- char *target,
- trio_flags_t flags,
- int width)
-{
- int i;
- char ch;
- trio_uintmax_t number;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- for (i = 0;
- (self->current != EOF) && (i < width);
- i++)
- {
- ch = (char)self->current;
- self->InStream(self, NULL);
- if ((flags & FLAGS_ALTERNATIVE) && (ch == CHAR_BACKSLASH))
- {
- switch (self->current)
- {
- case '\\': ch = '\\'; break;
- case 'a': ch = '\007'; break;
- case 'b': ch = '\b'; break;
- case 'f': ch = '\f'; break;
- case 'n': ch = '\n'; break;
- case 'r': ch = '\r'; break;
- case 't': ch = '\t'; break;
- case 'v': ch = '\v'; break;
- default:
- if (isdigit(self->current))
- {
- /* Read octal number */
- if (!TrioReadNumber(self, &number, 0, 3, BASE_OCTAL))
- return 0;
- ch = (char)number;
- }
- else if (trio_to_upper(self->current) == 'X')
- {
- /* Read hexadecimal number */
- self->InStream(self, NULL);
- if (!TrioReadNumber(self, &number, 0, 2, BASE_HEX))
- return 0;
- ch = (char)number;
- }
- else
- {
- ch = (char)self->current;
- }
- break;
- }
- }
-
- if (target)
- target[i] = ch;
- }
- return i + 1;
-}
-
-/*************************************************************************
- * TrioReadString
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadString
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- char *target,
- trio_flags_t flags,
- int width)
-{
- int i;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- TrioSkipWhitespaces(self);
-
- /*
- * Continue until end of string is reached, a whitespace is encountered,
- * or width is exceeded
- */
- for (i = 0;
- ((width == NO_WIDTH) || (i < width)) &&
- (! ((self->current == EOF) || isspace(self->current)));
- i++)
- {
- if (TrioReadChar(self, (target ? &target[i] : 0), flags, 1) == 0)
- break; /* for */
- }
- if (target)
- target[i] = NIL;
- return TRUE;
-}
-
-/*************************************************************************
- * TrioReadWideChar
- */
-#if TRIO_FEATURE_WIDECHAR
-TRIO_PRIVATE int
-TrioReadWideChar
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- trio_wchar_t *target,
- trio_flags_t flags,
- int width)
-{
- int i;
- int j;
- int size;
- int amount = 0;
- trio_wchar_t wch;
- char buffer[MB_LEN_MAX + 1];
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- for (i = 0;
- (self->current != EOF) && (i < width);
- i++)
- {
- if (isascii(self->current))
- {
- if (TrioReadChar(self, buffer, flags, 1) == 0)
- return 0;
- buffer[1] = NIL;
- }
- else
- {
- /*
- * Collect a multibyte character, by enlarging buffer until
- * it contains a fully legal multibyte character, or the
- * buffer is full.
- */
- j = 0;
- do
- {
- buffer[j++] = (char)self->current;
- buffer[j] = NIL;
- self->InStream(self, NULL);
- }
- while ((j < (int)sizeof(buffer)) && (mblen(buffer, (size_t)j) != j));
- }
- if (target)
- {
- size = mbtowc(&wch, buffer, sizeof(buffer));
- if (size > 0)
- target[i] = wch;
- }
- amount += size;
- self->InStream(self, NULL);
- }
- return amount;
-}
-#endif /* TRIO_FEATURE_WIDECHAR */
-
-/*************************************************************************
- * TrioReadWideString
- */
-#if TRIO_FEATURE_WIDECHAR
-TRIO_PRIVATE BOOLEAN_T
-TrioReadWideString
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- trio_wchar_t *target,
- trio_flags_t flags,
- int width)
-{
- int i;
- int size;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- TrioSkipWhitespaces(self);
-
-#if defined(TRIO_COMPILER_SUPPORTS_MULTIBYTE)
- /* Required by TrioReadWideChar */
- (void)mblen(NULL, 0);
-#endif
-
- /*
- * Continue until end of string is reached, a whitespace is encountered,
- * or width is exceeded
- */
- for (i = 0;
- ((width == NO_WIDTH) || (i < width)) &&
- (! ((self->current == EOF) || isspace(self->current)));
- )
- {
- size = TrioReadWideChar(self, &target[i], flags, 1);
- if (size == 0)
- break; /* for */
-
- i += size;
- }
- if (target)
- target[i] = WCONST('\0');
- return TRUE;
-}
-#endif /* TRIO_FEATURE_WIDECHAR */
-
-/*************************************************************************
- * TrioReadGroup
- *
- * Reads non-empty character groups.
- *
- * FIXME: characterclass does not work with multibyte characters
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadGroup
-TRIO_ARGS5((self, target, characterclass, flags, width),
- trio_class_t *self,
- char *target,
- int *characterclass,
- trio_flags_t flags,
- int width)
-{
- int ch;
- int i;
-
- assert(VALID(self));
- assert(VALID(self->InStream));
-
- ch = self->current;
- for (i = 0;
- ((width == NO_WIDTH) || (i < width)) &&
- (! ((ch == EOF) ||
- (((flags & FLAGS_EXCLUDE) != 0) ^ (characterclass[ch] == 0))));
- i++)
- {
- if (target)
- target[i] = (char)ch;
- self->InStream(self, &ch);
- }
-
- if (i == 0)
- return FALSE;
-
- /* Terminate the string if input saved */
- if (target)
- target[i] = NIL;
- return TRUE;
-}
-
-/*************************************************************************
- * TrioReadDouble
- *
- * FIXME:
- * add long double
- * handle base
- */
-#if TRIO_FEATURE_FLOAT
-TRIO_PRIVATE BOOLEAN_T
-TrioReadDouble
-TRIO_ARGS4((self, target, flags, width),
- trio_class_t *self,
- trio_pointer_t target,
- trio_flags_t flags,
- int width)
-{
- int ch;
- char doubleString[512];
- int offset = 0;
- int start;
-# if TRIO_FEATURE_QUOTE
- int j;
-# endif
- BOOLEAN_T isHex = FALSE;
- trio_long_double_t infinity;
-
- doubleString[0] = 0;
-
- if ((width == NO_WIDTH) || (width > (int)sizeof(doubleString) - 1))
- width = sizeof(doubleString) - 1;
-
- TrioSkipWhitespaces(self);
-
- /*
- * Read entire double number from stream. trio_to_double requires
- * a string as input, but InStream can be anything, so we have to
- * collect all characters.
- */
- ch = self->current;
- if ((ch == '+') || (ch == '-'))
- {
- doubleString[offset++] = (char)ch;
- self->InStream(self, &ch);
- width--;
- }
-
- start = offset;
- switch (ch)
- {
- case 'n':
- case 'N':
- /* Not-a-number */
- if (offset != 0)
- break;
- /* FALLTHROUGH */
- case 'i':
- case 'I':
- /* Infinity */
- while (isalpha(ch) && (offset - start < width))
- {
- doubleString[offset++] = (char)ch;
- self->InStream(self, &ch);
- }
- doubleString[offset] = NIL;
-
- /* Case insensitive string comparison */
- if (trio_equal(&doubleString[start], INFINITE_UPPER) ||
- trio_equal(&doubleString[start], LONG_INFINITE_UPPER))
- {
- infinity = ((start == 1) && (doubleString[0] == '-'))
- ? trio_ninf()
- : trio_pinf();
- if (flags & FLAGS_LONGDOUBLE)
- {
- *((trio_long_double_t *)target) = infinity;
- }
- else if (flags & FLAGS_LONG)
- {
- *((double *)target) = infinity;
- }
- else
- {
- *((float *)target) = infinity;
- }
- return TRUE;
- }
- if (trio_equal(doubleString, NAN_UPPER))
- {
- /* NaN must not have a preceeding + nor - */
- if (flags & FLAGS_LONGDOUBLE)
- {
- *((trio_long_double_t *)target) = trio_nan();
- }
- else if (flags & FLAGS_LONG)
- {
- *((double *)target) = trio_nan();
- }
- else
- {
- *((float *)target) = trio_nan();
- }
- return TRUE;
- }
- return FALSE;
-
- case '0':
- doubleString[offset++] = (char)ch;
- self->InStream(self, &ch);
- if (trio_to_upper(ch) == 'X')
- {
- isHex = TRUE;
- doubleString[offset++] = (char)ch;
- self->InStream(self, &ch);
- }
- break;
-
- default:
- break;
- }
-
- while ((ch != EOF) && (offset - start < width))
- {
- /* Integer part */
- if (isHex ? isxdigit(ch) : isdigit(ch))
- {
- doubleString[offset++] = (char)ch;
- self->InStream(self, &ch);
- }
-# if TRIO_FEATURE_QUOTE
- else if (flags & FLAGS_QUOTE)
- {
- /* Compare with thousands separator */
- for (j = 0; internalThousandSeparator[j] && self->current; j++)
- {
- if (internalThousandSeparator[j] != self->current)
- break;
-
- self->InStream(self, &ch);
- }
- if (internalThousandSeparator[j])
- break; /* Mismatch */
- else
- continue; /* Match */
- }
-# endif
- else
- break; /* while */
- }
- if (ch == '.')
- {
- /* Decimal part */
- doubleString[offset++] = (char)ch;
- self->InStream(self, &ch);
- while ((isHex ? isxdigit(ch) : isdigit(ch)) &&
- (offset - start < width))
- {
- doubleString[offset++] = (char)ch;
- self->InStream(self, &ch);
- }
- }
- if (isHex ? (trio_to_upper(ch) == 'P') : (trio_to_upper(ch) == 'E'))
- {
- /* Exponent */
- doubleString[offset++] = (char)ch;
- self->InStream(self, &ch);
- if ((ch == '+') || (ch == '-'))
- {
- doubleString[offset++] = (char)ch;
- self->InStream(self, &ch);
- }
- while (isdigit(ch) && (offset - start < width))
- {
- doubleString[offset++] = (char)ch;
- self->InStream(self, &ch);
- }
- }
-
- if ((offset == start) || (*doubleString == NIL))
- return FALSE;
-
- doubleString[offset] = 0;
-
- if (flags & FLAGS_LONGDOUBLE)
- {
- *((trio_long_double_t *)target) = trio_to_long_double(doubleString, NULL);
- }
- else if (flags & FLAGS_LONG)
- {
- *((double *)target) = trio_to_double(doubleString, NULL);
- }
- else
- {
- *((float *)target) = trio_to_float(doubleString, NULL);
- }
- return TRUE;
-}
-#endif /* TRIO_FEATURE_FLOAT */
-
-/*************************************************************************
- * TrioReadPointer
- */
-TRIO_PRIVATE BOOLEAN_T
-TrioReadPointer
-TRIO_ARGS3((self, target, flags),
- trio_class_t *self,
- trio_pointer_t *target,
- trio_flags_t flags)
-{
- trio_uintmax_t number;
- char buffer[sizeof(internalNullString)];
-
- flags |= (FLAGS_UNSIGNED | FLAGS_ALTERNATIVE | FLAGS_NILPADDING);
-
- if (TrioReadNumber(self,
- &number,
- flags,
- POINTER_WIDTH,
- BASE_HEX))
- {
- if (target)
- {
-#if defined(TRIO_COMPILER_GCC) || defined(TRIO_COMPILER_MIPSPRO)
- /*
- * The strange assignment of number is a workaround for a compiler
- * warning
- */
- *target = &((char *)0)[number];
-#else
- *target = (trio_pointer_t)number;
-#endif
- }
- return TRUE;
- }
- else if (TrioReadString(self,
- (flags & FLAGS_IGNORE)
- ? NULL
- : buffer,
- 0,
- sizeof(internalNullString) - 1))
- {
- if (trio_equal_case(buffer, internalNullString))
- {
- if (target)
- *target = NULL;
- return TRUE;
- }
- }
- return FALSE;
-}
-
-/*************************************************************************
- * TrioScanProcess
- */
-TRIO_PRIVATE int
-TrioScanProcess
-TRIO_ARGS3((data, format, parameters),
- trio_class_t *data,
- TRIO_CONST char *format,
- trio_parameter_t *parameters)
-{
- int status;
- int assignment;
- int ch;
- int offset; /* Offset of format string */
- int i; /* Offset of current parameter */
- trio_flags_t flags;
- int width;
- int base;
- trio_pointer_t pointer;
-
- /* Return on empty format string */
- if (format[0] == NIL)
- return 0;
-
- status = 0;
- assignment = 0;
- i = 0;
- offset = 0;
- data->InStream(data, &ch);
-
- for (;;)
- {
- /* Skip the parameter entries */
- while (parameters[i].type == FORMAT_PARAMETER)
- {
- assert(i <= MAX_PARAMETERS);
- i++;
- }
-
- /* Compare non conversion-specifier part of format string */
- while (offset < parameters[i].beginOffset)
- {
- if ((CHAR_IDENTIFIER == format[offset]) &&
- (CHAR_IDENTIFIER == format[offset + 1]))
- {
- /* Two % in format matches one % in input stream */
- if (CHAR_IDENTIFIER == ch)
- {
- data->InStream(data, &ch);
- offset += 2;
- continue; /* while format chars left */
- }
- else
- {
- status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
- goto end;
- }
- }
- else /* Not an % identifier */
- {
- if (isspace((int)format[offset]))
- {
- /* Whitespaces may match any amount of whitespaces */
- ch = TrioSkipWhitespaces(data);
- }
- else if (ch == format[offset])
- {
- data->InStream(data, &ch);
- }
- else
- {
- status = assignment;
- goto end;
- }
-
- offset++;
- }
- }
-
- if (parameters[i].type == FORMAT_SENTINEL)
- break;
-
- if ((EOF == ch) && (parameters[i].type != FORMAT_COUNT))
- {
- status = (assignment > 0) ? assignment : EOF;
- goto end;
- }
-
- flags = parameters[i].flags;
-
- /* Find width */
- width = parameters[i].width;
- if (flags & FLAGS_WIDTH_PARAMETER)
- {
- /* Get width from parameter list */
- width = (int)parameters[width].data.number.as_signed;
- }
-
- /* Find base */
- if (NO_BASE != parameters[i].baseSpecifier)
- {
- /* Base from specifier has priority */
- base = parameters[i].baseSpecifier;
- }
- else if (flags & FLAGS_BASE_PARAMETER)
- {
- /* Get base from parameter list */
- base = parameters[i].base;
- base = (int)parameters[base].data.number.as_signed;
- }
- else
- {
- /* Use base from format string */
- base = parameters[i].base;
- }
-
- switch (parameters[i].type)
- {
- case FORMAT_INT:
- {
- trio_uintmax_t number;
-
- if (0 == base)
- base = BASE_DECIMAL;
-
- if (!TrioReadNumber(data,
- &number,
- flags,
- width,
- base))
- {
- status = assignment;
- goto end;
- }
-
- if (!(flags & FLAGS_IGNORE))
- {
- assignment++;
-
- pointer = parameters[i].data.pointer;
-#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
- if (flags & FLAGS_SIZE_T)
- *(size_t *)pointer = (size_t)number;
- else
-#endif
-#if TRIO_FEATURE_PTRDIFF_T
- if (flags & FLAGS_PTRDIFF_T)
- *(ptrdiff_t *)pointer = (ptrdiff_t)number;
- else
-#endif
-#if TRIO_FEATURE_INTMAX_T
- if (flags & FLAGS_INTMAX_T)
- *(trio_intmax_t *)pointer = (trio_intmax_t)number;
- else
-#endif
- if (flags & FLAGS_QUAD)
- *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)number;
- else if (flags & FLAGS_LONG)
- *(long int *)pointer = (long int)number;
- else if (flags & FLAGS_SHORT)
- *(short int *)pointer = (short int)number;
- else
- *(int *)pointer = (int)number;
- }
- }
- break; /* FORMAT_INT */
-
- case FORMAT_STRING:
-#if TRIO_FEATURE_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- if (!TrioReadWideString(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.wstring,
- flags,
- width))
- {
- status = assignment;
- goto end;
- }
- }
- else
-#endif
- {
- if (!TrioReadString(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.string,
- flags,
- width))
- {
- status = assignment;
- goto end;
- }
- }
- if (!(flags & FLAGS_IGNORE))
- assignment++;
- break; /* FORMAT_STRING */
-
-#if TRIO_FEATURE_FLOAT
- case FORMAT_DOUBLE:
- {
- if (flags & FLAGS_IGNORE)
- {
- pointer = NULL;
- }
- else
- {
- pointer = (flags & FLAGS_LONGDOUBLE)
- ? (trio_pointer_t)parameters[i].data.longdoublePointer
- : (trio_pointer_t)parameters[i].data.doublePointer;
- }
- if (!TrioReadDouble(data, pointer, flags, width))
- {
- status = assignment;
- goto end;
- }
- if (!(flags & FLAGS_IGNORE))
- {
- assignment++;
- }
- break; /* FORMAT_DOUBLE */
- }
-#endif
-
- case FORMAT_GROUP:
- {
- int characterclass[MAX_CHARACTER_CLASS + 1];
-
- /* Skip over modifiers */
- while (format[offset] != SPECIFIER_GROUP)
- {
- offset++;
- }
- /* Skip over group specifier */
- offset++;
-
- memset(characterclass, 0, sizeof(characterclass));
- status = TrioGetCharacterClass(format,
- &offset,
- &flags,
- characterclass);
- if (status < 0)
- goto end;
-
- if (!TrioReadGroup(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.string,
- characterclass,
- flags,
- parameters[i].width))
- {
- status = assignment;
- goto end;
- }
- if (!(flags & FLAGS_IGNORE))
- assignment++;
- }
- break; /* FORMAT_GROUP */
-
- case FORMAT_COUNT:
- pointer = parameters[i].data.pointer;
- if (NULL != pointer)
- {
- int count = data->processed;
- if (ch != EOF)
- count--; /* a character is read, but is not consumed yet */
-#if TRIO_FEATURE_SIZE_T || TRIO_FEATURE_SIZE_T_UPPER
- if (flags & FLAGS_SIZE_T)
- *(size_t *)pointer = (size_t)count;
- else
-#endif
-#if TRIO_FEATURE_PTRDIFF_T
- if (flags & FLAGS_PTRDIFF_T)
- *(ptrdiff_t *)pointer = (ptrdiff_t)count;
- else
-#endif
-#if TRIO_FEATURE_INTMAX_T
- if (flags & FLAGS_INTMAX_T)
- *(trio_intmax_t *)pointer = (trio_intmax_t)count;
- else
-#endif
- if (flags & FLAGS_QUAD)
- {
- *(trio_ulonglong_t *)pointer = (trio_ulonglong_t)count;
- }
- else if (flags & FLAGS_LONG)
- {
- *(long int *)pointer = (long int)count;
- }
- else if (flags & FLAGS_SHORT)
- {
- *(short int *)pointer = (short int)count;
- }
- else
- {
- *(int *)pointer = (int)count;
- }
- }
- break; /* FORMAT_COUNT */
-
- case FORMAT_CHAR:
-#if TRIO_FEATURE_WIDECHAR
- if (flags & FLAGS_WIDECHAR)
- {
- if (TrioReadWideChar(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.wstring,
- flags,
- (width == NO_WIDTH) ? 1 : width) == 0)
- {
- status = assignment;
- goto end;
- }
- }
- else
-#endif
- {
- if (TrioReadChar(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : parameters[i].data.string,
- flags,
- (width == NO_WIDTH) ? 1 : width) == 0)
- {
- status = assignment;
- goto end;
- }
- }
- if (!(flags & FLAGS_IGNORE))
- assignment++;
- break; /* FORMAT_CHAR */
-
- case FORMAT_POINTER:
- if (!TrioReadPointer(data,
- (flags & FLAGS_IGNORE)
- ? NULL
- : (trio_pointer_t *)parameters[i].data.pointer,
- flags))
- {
- status = assignment;
- goto end;
- }
- if (!(flags & FLAGS_IGNORE))
- assignment++;
- break; /* FORMAT_POINTER */
-
- case FORMAT_PARAMETER:
- break; /* FORMAT_PARAMETER */
-
- default:
- status = TRIO_ERROR_RETURN(TRIO_EINVAL, offset);
- goto end;
- }
-
- ch = data->current;
- offset = parameters[i].endOffset;
- i++;
- }
-
- status = assignment;
- end:
- if (data->UndoStream)
- data->UndoStream(data);
- return status;
-}
-
-/*************************************************************************
- * TrioScan
- */
-TRIO_PRIVATE int
-TrioScan
-TRIO_ARGS7((source, sourceSize, InStream, UndoStream, format, arglist, argarray),
- trio_pointer_t source,
- size_t sourceSize,
- void (*InStream) TRIO_PROTO((trio_class_t *, int *)),
- void (*UndoStream) TRIO_PROTO((trio_class_t *)),
- TRIO_CONST char *format,
- va_list arglist,
- trio_pointer_t *argarray)
-{
- int status;
- trio_parameter_t parameters[MAX_PARAMETERS];
- trio_class_t data;
-
- assert(VALID(InStream));
- assert(VALID(format));
-
- memset(&data, 0, sizeof(data));
- data.InStream = InStream;
- data.UndoStream = UndoStream;
- data.location = (trio_pointer_t)source;
- data.max = sourceSize;
- data.error = 0;
-
-#if defined(USE_LOCALE)
- if (NULL == internalLocaleValues)
- {
- TrioSetLocale();
- }
-#endif
-
- status = TrioParse(TYPE_SCAN, format, parameters, arglist, argarray);
- if (status < 0)
- return status;
-
- status = TrioScanProcess(&data, format, parameters);
- if (data.error != 0)
- {
- status = data.error;
- }
- return status;
-}
-
-/*************************************************************************
- * TrioInStreamFile
- */
-#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO
-TRIO_PRIVATE void
-TrioInStreamFile
-TRIO_ARGS2((self, intPointer),
- trio_class_t *self,
- int *intPointer)
-{
- FILE *file = (FILE *)self->location;
-
- assert(VALID(self));
- assert(VALID(file));
-
- self->actually.cached = 0;
-
- /* The initial value of self->current is zero */
- if (self->current == EOF)
- {
- self->error = (ferror(file))
- ? TRIO_ERROR_RETURN(TRIO_ERRNO, 0)
- : TRIO_ERROR_RETURN(TRIO_EOF, 0);
- }
- else
- {
- self->processed++;
- self->actually.cached++;
- }
-
- self->current = fgetc(file);
-
- if (VALID(intPointer))
- {
- *intPointer = self->current;
- }
-}
-#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */
-
-/*************************************************************************
- * TrioUndoStreamFile
- */
-#if TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO
-TRIO_PRIVATE void
-TrioUndoStreamFile
-TRIO_ARGS1((self),
- trio_class_t *self)
-{
- FILE *file = (FILE *)self->location;
-
- assert(VALID(self));
- assert(VALID(file));
-
- if (self->actually.cached > 0)
- {
- assert(self->actually.cached == 1);
-
- self->current = ungetc(self->current, file);
- self->actually.cached = 0;
- }
-}
-#endif /* TRIO_FEATURE_FILE || TRIO_FEATURE_STDIO */
-
-/*************************************************************************
- * TrioInStreamFileDescriptor
- */
-#if TRIO_FEATURE_FD
-TRIO_PRIVATE void
-TrioInStreamFileDescriptor
-TRIO_ARGS2((self, intPointer),
- trio_class_t *self,
- int *intPointer)
-{
- int fd = *((int *)self->location);
- int size;
- unsigned char input;
-
- assert(VALID(self));
-
- self->actually.cached = 0;
-
- size = read(fd, &input, sizeof(char));
- if (size == -1)
- {
- self->error = TRIO_ERROR_RETURN(TRIO_ERRNO, 0);
- self->current = EOF;
- }
- else
- {
- self->current = (size == 0) ? EOF : input;
- }
- if (self->current != EOF)
- {
- self->actually.cached++;
- self->processed++;
- }
-
- if (VALID(intPointer))
- {
- *intPointer = self->current;
- }
-}
-#endif /* TRIO_FEATURE_FD */
-
-/*************************************************************************
- * TrioInStreamCustom
- */
-#if TRIO_FEATURE_CLOSURE
-TRIO_PRIVATE void
-TrioInStreamCustom
-TRIO_ARGS2((self, intPointer),
- trio_class_t *self,
- int *intPointer)
-{
- trio_custom_t *data;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- self->actually.cached = 0;
-
- data = (trio_custom_t *)self->location;
-
- self->current = (data->stream.in == NULL)
- ? NIL
- : (data->stream.in)(data->closure);
-
- if (self->current == NIL)
- {
- self->current = EOF;
- }
- else
- {
- self->processed++;
- self->actually.cached++;
- }
-
- if (VALID(intPointer))
- {
- *intPointer = self->current;
- }
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-/*************************************************************************
- * TrioInStreamString
- */
-TRIO_PRIVATE void
-TrioInStreamString
-TRIO_ARGS2((self, intPointer),
- trio_class_t *self,
- int *intPointer)
-{
- unsigned char **buffer;
-
- assert(VALID(self));
- assert(VALID(self->location));
-
- self->actually.cached = 0;
-
- buffer = (unsigned char **)self->location;
- self->current = (*buffer)[0];
- if (self->current == NIL)
- {
- self->current = EOF;
- }
- else
- {
- (*buffer)++;
- self->processed++;
- self->actually.cached++;
- }
-
- if (VALID(intPointer))
- {
- *intPointer = self->current;
- }
-}
-
-/*************************************************************************
- *
- * Formatted scanning functions
- *
- ************************************************************************/
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_scanf.h"
-#endif
-/** @addtogroup Scanf
- @{
-*/
-
-/*************************************************************************
- * scanf
- */
-
-/**
- Scan characters from standard input stream.
-
- @param format Formatting string.
- @param ... Arguments.
- @return Number of scanned characters.
- */
-#if TRIO_FEATURE_STDIO
-TRIO_PUBLIC int
-trio_scanf
-TRIO_VARGS2((format, va_alist),
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioScan((trio_pointer_t)stdin, 0,
- TrioInStreamFile,
- TrioUndoStreamFile,
- format, args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-#endif /* TRIO_FEATURE_STDIO */
-
-/**
- Scan characters from standard input stream.
-
- @param format Formatting string.
- @param args Arguments.
- @return Number of scanned characters.
- */
-#if TRIO_FEATURE_STDIO
-TRIO_PUBLIC int
-trio_vscanf
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)stdin, 0,
- TrioInStreamFile,
- TrioUndoStreamFile,
- format, args, NULL);
-}
-#endif /* TRIO_FEATURE_STDIO */
-
-/**
- Scan characters from standard input stream.
-
- @param format Formatting string.
- @param args Arguments.
- @return Number of scanned characters.
- */
-#if TRIO_FEATURE_STDIO
-TRIO_PUBLIC int
-trio_scanfv
-TRIO_ARGS2((format, args),
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- static va_list unused;
-
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)stdin, 0,
- TrioInStreamFile,
- TrioUndoStreamFile,
- format, unused, args);
-}
-#endif /* TRIO_FEATURE_STDIO */
-
-/*************************************************************************
- * fscanf
- */
-
-/**
- Scan characters from file.
-
- @param file File pointer.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of scanned characters.
- */
-#if TRIO_FEATURE_FILE
-TRIO_PUBLIC int
-trio_fscanf
-TRIO_VARGS3((file, format, va_alist),
- FILE *file,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(file));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioScan((trio_pointer_t)file, 0,
- TrioInStreamFile,
- TrioUndoStreamFile,
- format, args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-#endif /* TRIO_FEATURE_FILE */
-
-/**
- Scan characters from file.
-
- @param file File pointer.
- @param format Formatting string.
- @param args Arguments.
- @return Number of scanned characters.
- */
-#if TRIO_FEATURE_FILE
-TRIO_PUBLIC int
-trio_vfscanf
-TRIO_ARGS3((file, format, args),
- FILE *file,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(file));
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)file, 0,
- TrioInStreamFile,
- TrioUndoStreamFile,
- format, args, NULL);
-}
-#endif /* TRIO_FEATURE_FILE */
-
-/**
- Scan characters from file.
-
- @param file File pointer.
- @param format Formatting string.
- @param args Arguments.
- @return Number of scanned characters.
- */
-#if TRIO_FEATURE_FILE
-TRIO_PUBLIC int
-trio_fscanfv
-TRIO_ARGS3((file, format, args),
- FILE *file,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- static va_list unused;
-
- assert(VALID(file));
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)file, 0,
- TrioInStreamFile,
- TrioUndoStreamFile,
- format, unused, args);
-}
-#endif /* TRIO_FEATURE_FILE */
-
-/*************************************************************************
- * dscanf
- */
-
-/**
- Scan characters from file descriptor.
-
- @param fd File descriptor.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of scanned characters.
- */
-#if TRIO_FEATURE_FD
-TRIO_PUBLIC int
-trio_dscanf
-TRIO_VARGS3((fd, format, va_alist),
- int fd,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioScan((trio_pointer_t)&fd, 0,
- TrioInStreamFileDescriptor,
- NULL,
- format, args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-#endif /* TRIO_FEATURE_FD */
-
-/**
- Scan characters from file descriptor.
-
- @param fd File descriptor.
- @param format Formatting string.
- @param args Arguments.
- @return Number of scanned characters.
- */
-#if TRIO_FEATURE_FD
-TRIO_PUBLIC int
-trio_vdscanf
-TRIO_ARGS3((fd, format, args),
- int fd,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)&fd, 0,
- TrioInStreamFileDescriptor,
- NULL,
- format, args, NULL);
-}
-#endif /* TRIO_FEATURE_FD */
-
-/**
- Scan characters from file descriptor.
-
- @param fd File descriptor.
- @param format Formatting string.
- @param args Arguments.
- @return Number of scanned characters.
- */
-#if TRIO_FEATURE_FD
-TRIO_PUBLIC int
-trio_dscanfv
-TRIO_ARGS3((fd, format, args),
- int fd,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- static va_list unused;
-
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)&fd, 0,
- TrioInStreamFileDescriptor,
- NULL,
- format, unused, args);
-}
-#endif /* TRIO_FEATURE_FD */
-
-/*************************************************************************
- * cscanf
- */
-#if TRIO_FEATURE_CLOSURE
-TRIO_PUBLIC int
-trio_cscanf
-TRIO_VARGS4((stream, closure, format, va_alist),
- trio_instream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- data.stream.in = stream;
- data.closure = closure;
- status = TrioScan(&data, 0, TrioInStreamCustom, NULL, format, args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-#if TRIO_FEATURE_CLOSURE
-TRIO_PUBLIC int
-trio_vcscanf
-TRIO_ARGS4((stream, closure, format, args),
- trio_instream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- va_list args)
-{
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- data.stream.in = stream;
- data.closure = closure;
- return TrioScan(&data, 0, TrioInStreamCustom, NULL, format, args, NULL);
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-#if TRIO_FEATURE_CLOSURE
-TRIO_PUBLIC int
-trio_cscanfv
-TRIO_ARGS4((stream, closure, format, args),
- trio_instream_t stream,
- trio_pointer_t closure,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- static va_list unused;
- trio_custom_t data;
-
- assert(VALID(stream));
- assert(VALID(format));
-
- data.stream.in = stream;
- data.closure = closure;
- return TrioScan(&data, 0, TrioInStreamCustom, NULL, format, unused, args);
-}
-#endif /* TRIO_FEATURE_CLOSURE */
-
-/*************************************************************************
- * sscanf
- */
-
-/**
- Scan characters from string.
-
- @param buffer Input string.
- @param format Formatting string.
- @param ... Arguments.
- @return Number of scanned characters.
- */
-TRIO_PUBLIC int
-trio_sscanf
-TRIO_VARGS3((buffer, format, va_alist),
- TRIO_CONST char *buffer,
- TRIO_CONST char *format,
- TRIO_VA_DECL)
-{
- int status;
- va_list args;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- TRIO_VA_START(args, format);
- status = TrioScan((trio_pointer_t)&buffer, 0,
- TrioInStreamString,
- NULL,
- format, args, NULL);
- TRIO_VA_END(args);
- return status;
-}
-
-/**
- Scan characters from string.
-
- @param buffer Input string.
- @param format Formatting string.
- @param args Arguments.
- @return Number of scanned characters.
- */
-TRIO_PUBLIC int
-trio_vsscanf
-TRIO_ARGS3((buffer, format, args),
- TRIO_CONST char *buffer,
- TRIO_CONST char *format,
- va_list args)
-{
- assert(VALID(buffer));
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)&buffer, 0,
- TrioInStreamString,
- NULL,
- format, args, NULL);
-}
-
-/**
- Scan characters from string.
-
- @param buffer Input string.
- @param format Formatting string.
- @param args Arguments.
- @return Number of scanned characters.
- */
-TRIO_PUBLIC int
-trio_sscanfv
-TRIO_ARGS3((buffer, format, args),
- TRIO_CONST char *buffer,
- TRIO_CONST char *format,
- trio_pointer_t *args)
-{
- static va_list unused;
-
- assert(VALID(buffer));
- assert(VALID(format));
-
- return TrioScan((trio_pointer_t)&buffer, 0,
- TrioInStreamString,
- NULL,
- format, unused, args);
-}
-
-#endif /* TRIO_FEATURE_SCANF */
-
-/** @} End of Scanf documentation module */
-
-/*************************************************************************
- * trio_strerror
- */
-TRIO_PUBLIC TRIO_CONST char *
-trio_strerror
-TRIO_ARGS1((errorcode),
- int errorcode)
-{
-#if TRIO_FEATURE_STRERR
- /* Textual versions of the error codes */
- switch (TRIO_ERROR_CODE(errorcode))
- {
- case TRIO_EOF:
- return "End of file";
- case TRIO_EINVAL:
- return "Invalid argument";
- case TRIO_ETOOMANY:
- return "Too many arguments";
- case TRIO_EDBLREF:
- return "Double reference";
- case TRIO_EGAP:
- return "Reference gap";
- case TRIO_ENOMEM:
- return "Out of memory";
- case TRIO_ERANGE:
- return "Invalid range";
- case TRIO_ECUSTOM:
- return "Custom error";
- default:
- return "Unknown";
- }
-#else
- return "Unknown";
-#endif
-}
+++ /dev/null
-/*************************************************************************
- *
- * $Id: trio.h,v 1.19 2009/09/13 10:12:22 breese Exp $
- *
- * Copyright (C) 1998 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- *************************************************************************
- *
- * http://ctrio.sourceforge.net/
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIO_H
-#define TRIO_TRIO_H
-
-#if !defined(WITHOUT_TRIO)
-
-#if WANT_FETCHMAIL_CONFIG_H_FOR_TRIO - 0
-/* if used as part of fetchmail, do not include config.h, as that would break
- * the regression test. */
-
-/*
- * Use autoconf defines if present. Packages using trio must define
- * HAVE_CONFIG_H as a compiler option themselves.
- */
-#if defined(HAVE_CONFIG_H)
-# include <config.h>
-#endif
-#endif
-
-#include "triop.h"
-
-#include <stdio.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Error codes.
- *
- * Remember to add a textual description to trio_strerror.
- */
-enum {
- TRIO_EOF = 1,
- TRIO_EINVAL = 2,
- TRIO_ETOOMANY = 3,
- TRIO_EDBLREF = 4,
- TRIO_EGAP = 5,
- TRIO_ENOMEM = 6,
- TRIO_ERANGE = 7,
- TRIO_ERRNO = 8,
- TRIO_ECUSTOM = 9
-};
-
-/* Error macros */
-#define TRIO_ERROR_CODE(x) ((-(x)) & 0x00FF)
-#define TRIO_ERROR_POSITION(x) ((-(x)) >> 8)
-#define TRIO_ERROR_NAME(x) trio_strerror(x)
-
-typedef int (*trio_outstream_t) TRIO_PROTO((trio_pointer_t, int));
-typedef int (*trio_instream_t) TRIO_PROTO((trio_pointer_t));
-
-TRIO_CONST char *trio_strerror TRIO_PROTO((int));
-
-/*************************************************************************
- * Print Functions
- */
-
-int trio_printf TRIO_PROTO((TRIO_CONST char *format, ...));
-int trio_vprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
-int trio_printfv TRIO_PROTO((TRIO_CONST char *format, void **args));
-
-int trio_fprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
-int trio_vfprintf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
-int trio_fprintfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
-
-int trio_dprintf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
-int trio_vdprintf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
-int trio_dprintfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
-
-int trio_cprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, ...));
-int trio_vcprintf TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, va_list args));
-int trio_cprintfv TRIO_PROTO((trio_outstream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, void **args));
-
-int trio_sprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, ...));
-int trio_vsprintf TRIO_PROTO((char *buffer, TRIO_CONST char *format, va_list args));
-int trio_sprintfv TRIO_PROTO((char *buffer, TRIO_CONST char *format, void **args));
-
-int trio_snprintf TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
-int trio_vsnprintf TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
- va_list args));
-int trio_snprintfv TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
- void **args));
-
-int trio_snprintfcat TRIO_PROTO((char *buffer, size_t max, TRIO_CONST char *format, ...));
-int trio_vsnprintfcat TRIO_PROTO((char *buffer, size_t bufferSize, TRIO_CONST char *format,
- va_list args));
-
-#if defined(TRIO_DEPRECATED)
-char *trio_aprintf TRIO_PROTO((TRIO_CONST char *format, ...));
-char *trio_vaprintf TRIO_PROTO((TRIO_CONST char *format, va_list args));
-#endif
-
-int trio_asprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, ...));
-int trio_vasprintf TRIO_PROTO((char **ret, TRIO_CONST char *format, va_list args));
-int trio_asprintfv TRIO_PROTO((char **result, TRIO_CONST char *format, trio_pointer_t * args));
-
-/*************************************************************************
- * Scan Functions
- */
-int trio_scanf TRIO_PROTO((TRIO_CONST char *format, ...));
-int trio_vscanf TRIO_PROTO((TRIO_CONST char *format, va_list args));
-int trio_scanfv TRIO_PROTO((TRIO_CONST char *format, void **args));
-
-int trio_fscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, ...));
-int trio_vfscanf TRIO_PROTO((FILE *file, TRIO_CONST char *format, va_list args));
-int trio_fscanfv TRIO_PROTO((FILE *file, TRIO_CONST char *format, void **args));
-
-int trio_dscanf TRIO_PROTO((int fd, TRIO_CONST char *format, ...));
-int trio_vdscanf TRIO_PROTO((int fd, TRIO_CONST char *format, va_list args));
-int trio_dscanfv TRIO_PROTO((int fd, TRIO_CONST char *format, void **args));
-
-int trio_cscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, ...));
-int trio_vcscanf TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, va_list args));
-int trio_cscanfv TRIO_PROTO((trio_instream_t stream, trio_pointer_t closure,
- TRIO_CONST char *format, void **args));
-
-int trio_sscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, ...));
-int trio_vsscanf TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, va_list args));
-int trio_sscanfv TRIO_PROTO((TRIO_CONST char *buffer, TRIO_CONST char *format, void **args));
-
-/*************************************************************************
- * Locale Functions
- */
-void trio_locale_set_decimal_point TRIO_PROTO((char *decimalPoint));
-void trio_locale_set_thousand_separator TRIO_PROTO((char *thousandSeparator));
-void trio_locale_set_grouping TRIO_PROTO((char *grouping));
-
-/*************************************************************************
- * Renaming
- */
-#ifdef TRIO_REPLACE_STDIO
-/* Replace the <stdio.h> functions */
-#ifndef HAVE_PRINTF
-# undef printf
-# define printf trio_printf
-#endif
-#ifndef HAVE_VPRINTF
-# undef vprintf
-# define vprintf trio_vprintf
-#endif
-#ifndef HAVE_FPRINTF
-# undef fprintf
-# define fprintf trio_fprintf
-#endif
-#ifndef HAVE_VFPRINTF
-# undef vfprintf
-# define vfprintf trio_vfprintf
-#endif
-#ifndef HAVE_SPRINTF
-# undef sprintf
-# define sprintf trio_sprintf
-#endif
-#ifndef HAVE_VSPRINTF
-# undef vsprintf
-# define vsprintf trio_vsprintf
-#endif
-#ifndef HAVE_SNPRINTF
-# undef snprintf
-# define snprintf trio_snprintf
-#endif
-#ifndef HAVE_VSNPRINTF
-# undef vsnprintf
-# define vsnprintf trio_vsnprintf
-#endif
-#ifndef HAVE_SCANF
-# undef scanf
-# define scanf trio_scanf
-#endif
-#ifndef HAVE_VSCANF
-# undef vscanf
-# define vscanf trio_vscanf
-#endif
-#ifndef HAVE_FSCANF
-# undef fscanf
-# define fscanf trio_fscanf
-#endif
-#ifndef HAVE_VFSCANF
-# undef vfscanf
-# define vfscanf trio_vfscanf
-#endif
-#ifndef HAVE_SSCANF
-# undef sscanf
-# define sscanf trio_sscanf
-#endif
-#ifndef HAVE_VSSCANF
-# undef vsscanf
-# define vsscanf trio_vsscanf
-#endif
-/* These aren't stdio functions, but we make them look similar */
-#undef dprintf
-#define dprintf trio_dprintf
-#undef vdprintf
-#define vdprintf trio_vdprintf
-#undef aprintf
-#define aprintf trio_aprintf
-#undef vaprintf
-#define vaprintf trio_vaprintf
-#undef asprintf
-#define asprintf trio_asprintf
-#undef vasprintf
-#define vasprintf trio_vasprintf
-#undef dscanf
-#define dscanf trio_dscanf
-#undef vdscanf
-#define vdscanf trio_vdscanf
-#endif
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* WITHOUT_TRIO */
-
-#endif /* TRIO_TRIO_H */
+++ /dev/null
-/*************************************************************************
- *
- * $Id: triodef.h,v 1.35 2009/09/20 11:37:14 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIODEF_H
-#define TRIO_TRIODEF_H
-
-/*************************************************************************
- * Compiler support detection
- */
-
-#if defined(__GNUC__)
-# define TRIO_COMPILER_GCC
-#endif
-
-#if defined(__SUNPRO_CC)
-# define TRIO_COMPILER_SUNPRO __SUNPRO_CC
-#else
-# if defined(__SUNPRO_C)
-# define TRIO_COMPILER_SUNPRO __SUNPRO_C
-# endif
-#endif
-
-#if defined(__xlC__) || defined(__IBMC__) || defined(__IBMCPP__)
-# define TRIO_COMPILER_XLC
-#else
-# if defined(_AIX) && !defined(__GNUC__)
-# define TRIO_COMPILER_XLC /* Workaround for old xlc */
-# endif
-#endif
-
-#if defined(__DECC) || defined(__DECCXX)
-# define TRIO_COMPILER_DECC
-#else
-# if defined(__osf__) && defined(__LANGUAGE_C__) && !defined(__GNUC__)
-# define TRIO_COMPILER_DECC /* Workaround for old DEC C compilers */
-# endif
-#endif
-
-#if defined(__HP_aCC) || defined(__HP_cc)
-# define TRIO_COMPILER_HP
-#endif
-
-#if defined(sgi) || defined(__sgi)
-# define TRIO_COMPILER_MIPSPRO
-#endif
-
-#if defined(_MSC_VER)
-# define TRIO_COMPILER_MSVC
-#endif
-
-#if defined(__BORLANDC__)
-# define TRIO_COMPILER_BCB
-#endif
-
-/*************************************************************************
- * Platform support detection
- */
-
-#if defined(VMS) || defined(__VMS)
-# define TRIO_PLATFORM_VMS
-#endif
-
-#if defined(unix) || defined(__unix) || defined(__unix__)
-# define TRIO_PLATFORM_UNIX
-#endif
-
-#if defined(TRIO_COMPILER_XLC) || defined(_AIX)
-# define TRIO_PLATFORM_UNIX
-#endif
-
-#if defined(TRIO_COMPILER_DECC) || defined(__osf___)
-# if !defined(TRIO_PLATFORM_VMS)
-# define TRIO_PLATFORM_UNIX
-# endif
-#endif
-
-#if defined(__NetBSD__)
-# define TRIO_PLATFORM_UNIX
-#endif
-
-#if defined(__Lynx__)
-# define TRIO_PLATFORM_UNIX
-# define TRIO_PLATFORM_LYNX
-#endif
-
-#if defined(__APPLE__) && defined(__MACH__)
-# define TRIO_PLATFORM_UNIX
-#endif
-
-#if defined(__QNX__)
-# define TRIO_PLATFORM_UNIX
-# define TRIO_PLATFORM_QNX
-#endif
-
-#if defined(__CYGWIN__)
-# define TRIO_PLATFORM_UNIX
-#endif
-
-#if defined(AMIGA) && defined(TRIO_COMPILER_GCC)
-# define TRIO_PLATFORM_UNIX
-#endif
-
-#if defined(TRIO_COMPILER_MSVC) || defined(WIN32) || defined(_WIN32)
-# define TRIO_PLATFORM_WIN32
-#endif
-
-#if defined(_WIN32_WCE)
-# define TRIO_PLATFORM_WINCE
-#endif
-
-#if defined(mpeix) || defined(__mpexl)
-# define TRIO_PLATFORM_MPEIX
-#endif
-
-#if defined(_AIX)
-# define TRIO_PLATFORM_AIX
-#endif
-
-#if defined(__hpux)
-# define TRIO_PLATFORM_HPUX
-#endif
-
-#if defined(sun) || defined(__sun__)
-# if defined(__SVR4) || defined(__svr4__)
-# define TRIO_PLATFORM_SOLARIS
-# else
-# define TRIO_PLATFORM_SUNOS
-# endif
-#endif
-
-/*************************************************************************
- * Standards support detection
- */
-
-#if defined(__STDC__) \
- || defined(_MSC_EXTENSIONS) \
- || defined(TRIO_COMPILER_BCB)
-# define PREDEF_STANDARD_C89
-#endif
-#if defined(__STDC_VERSION__)
-# define PREDEF_STANDARD_C90
-#endif
-#if (__STDC_VERSION__ - 0 >= 199409L)
-# define PREDEF_STANDARD_C94
-#endif
-#if (__STDC_VERSION__ - 0 >= 199901L)
-# define PREDEF_STANDARD_C99
-#endif
-#if defined(TRIO_COMPILER_SUNPRO) && (TRIO_COMPILER_SUNPRO >= 0x420)
-# if !defined(PREDEF_STANDARD_C94)
-# define PREDEF_STANDARD_C94
-# endif
-#endif
-
-#if defined(__cplusplus)
-# define PREDEF_STANDARD_CXX
-#endif
-#if __cplusplus - 0 >= 199711L
-# define PREDEF_STANDARD_CXX89
-#endif
-
-#if defined(TRIO_PLATFORM_UNIX)
-# include <unistd.h>
-#endif
-
-#if defined(_POSIX_VERSION)
-# define PREDEF_STANDARD_POSIX _POSIX_VERSION
-# if (_POSIX_VERSION >= 199506L)
-# define PREDEF_STANDARD_POSIX_1996
-# endif
-#endif
-
-#if (_XOPEN_VERSION - 0 >= 3) || defined(_XOPEN_XPG3)
-# define PREDEF_STANDARD_XPG3
-#endif
-#if (_XOPEN_VERSION - 0 >= 4) || defined(_XOPEN_XPG4)
-# define PREDEF_STANDARD_XPG4
-#endif
-#if (_XOPEN_VERSION - 0 > 4) \
- || (defined(_XOPEN_UNIX) && (_XOPEN_VERSION - 0 == 4))
-# define PREDEF_STANDARD_UNIX95
-#endif
-#if (_XOPEN_VERSION - 0 >= 500)
-# define PREDEF_STANDARD_UNIX98
-#endif
-#if (_XOPEN_VERSION - 0 >= 600)
-# define PREDEF_STANDARD_UNIX03
-#endif
-
-/*************************************************************************
- * Generic defines
- */
-
-#if !defined(TRIO_PUBLIC)
-# define TRIO_PUBLIC
-#endif
-#if !defined(TRIO_PRIVATE)
-# define TRIO_PRIVATE static
-#endif
-
-#if !(defined(PREDEF_STANDARD_C89) || defined(PREDEF_STANDARD_CXX))
-# define TRIO_COMPILER_ANCIENT
-#endif
-
-#if defined(TRIO_COMPILER_ANCIENT)
-# define TRIO_CONST
-# define TRIO_VOLATILE
-# define TRIO_SIGNED
-typedef double trio_long_double_t;
-typedef char * trio_pointer_t;
-# define TRIO_SUFFIX_LONG(x) x
-# define TRIO_PROTO(x) ()
-# define TRIO_NOARGS
-# define TRIO_ARGS1(list,a1) list a1;
-# define TRIO_ARGS2(list,a1,a2) list a1; a2;
-# define TRIO_ARGS3(list,a1,a2,a3) list a1; a2; a3;
-# define TRIO_ARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4;
-# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5;
-# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) list a1; a2; a3; a4; a5; a6;
-# define TRIO_ARGS7(list,a1,a2,a3,a4,a5,a6,a7) list a1; a2; a3; a4; a5; a6; a7;
-# define TRIO_VARGS2(list,a1,a2) list a1; a2
-# define TRIO_VARGS3(list,a1,a2,a3) list a1; a2; a3
-# define TRIO_VARGS4(list,a1,a2,a3,a4) list a1; a2; a3; a4
-# define TRIO_VARGS5(list,a1,a2,a3,a4,a5) list a1; a2; a3; a4; a5
-# define TRIO_VA_DECL va_dcl
-# define TRIO_VA_START(x,y) va_start(x)
-# define TRIO_VA_END(x) va_end(x)
-#else /* ANSI C */
-# define TRIO_CONST const
-# define TRIO_VOLATILE volatile
-# define TRIO_SIGNED signed
-typedef long double trio_long_double_t;
-typedef void * trio_pointer_t;
-# define TRIO_SUFFIX_LONG(x) x ## L
-# define TRIO_PROTO(x) x
-# define TRIO_NOARGS void
-# define TRIO_ARGS1(list,a1) (a1)
-# define TRIO_ARGS2(list,a1,a2) (a1,a2)
-# define TRIO_ARGS3(list,a1,a2,a3) (a1,a2,a3)
-# define TRIO_ARGS4(list,a1,a2,a3,a4) (a1,a2,a3,a4)
-# define TRIO_ARGS5(list,a1,a2,a3,a4,a5) (a1,a2,a3,a4,a5)
-# define TRIO_ARGS6(list,a1,a2,a3,a4,a5,a6) (a1,a2,a3,a4,a5,a6)
-# define TRIO_ARGS7(list,a1,a2,a3,a4,a5,a6,a7) (a1,a2,a3,a4,a5,a6,a7)
-# define TRIO_VARGS2 TRIO_ARGS2
-# define TRIO_VARGS3 TRIO_ARGS3
-# define TRIO_VARGS4 TRIO_ARGS4
-# define TRIO_VARGS5 TRIO_ARGS5
-# define TRIO_VA_DECL ...
-# define TRIO_VA_START(x,y) va_start(x,y)
-# define TRIO_VA_END(x) va_end(x)
-#endif
-
-#if defined(PREDEF_STANDARD_C99) || defined(PREDEF_STANDARD_CXX)
-# define TRIO_INLINE inline
-#else
-# if defined(TRIO_COMPILER_GCC)
-# define TRIO_INLINE __inline__
-# endif
-# if defined(TRIO_COMPILER_MSVC)
-# define TRIO_INLINE _inline
-# endif
-# if defined(TRIO_COMPILER_BCB)
-# define TRIO_INLINE __inline
-# endif
-#endif
-#if !defined(TRIO_INLINE)
-# define TRIO_INLINE
-#endif
-
-/*************************************************************************
- * Workarounds
- */
-
-#if defined(TRIO_PLATFORM_VMS)
-/*
- * Computations done with constants at compile time can trigger these
- * even when compiling with IEEE enabled.
- */
-# pragma message disable (UNDERFLOW, FLOATOVERFL)
-
-# if (__CRTL_VER < 80210001)
-/*
- * Although the compiler supports C99 language constructs, the C
- * run-time library does not contain all C99 functions.
- */
-# if defined(PREDEF_STANDARD_C99)
-# undef PREDEF_STANDARD_C99
-# endif
-# endif
-#endif
-
-/*
- * Not all preprocessors supports the LL token.
- */
-#if defined(TRIO_COMPILER_MSVC) || defined(TRIO_COMPILER_BCB)
-#else
-# define TRIO_COMPILER_SUPPORTS_LL
-#endif
-
-#if defined(__CYGWIN__)
-/*
- * Cygwin defines the macros for hosted C99, but does not support certain
- * long double math functions.
- */
-# include <cygwin/version.h>
-# define TRIO_CYGWIN_VERSION_API CYGWIN_VERSION_API_MAJOR * 1000 + \
- CYGWIN_VERSION_API_MINOR
-/*
- * Please change the version number below when the Cygwin API supports
- * long double math functions (powl, fmodl, etc.)
- */
-# if TRIO_CYGWIN_VERSION_API < 99999999
-# define TRIO_NO_FLOORL 1
-# define TRIO_NO_CEILL 1
-# define TRIO_NO_POWL 1
-# define TRIO_NO_FMODL 1
-# define TRIO_NO_LOG10L 1
-# endif
-#endif
-
-#endif /* TRIO_TRIODEF_H */
+++ /dev/null
-/*************************************************************************
- *
- * $Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************
- *
- * Functions to handle special quantities in floating-point numbers
- * (that is, NaNs and infinity). They provide the capability to detect
- * and fabricate special quantities.
- *
- * Although written to be as portable as possible, it can never be
- * guaranteed to work on all platforms, as not all hardware supports
- * special quantities.
- *
- * The approach used here (approximately) is to:
- *
- * 1. Use C99 functionality when available.
- * 2. Use IEEE 754 bit-patterns if possible.
- * 3. Use platform-specific techniques.
- *
- ************************************************************************/
-
-/*************************************************************************
- * Include files
- */
-#include "triodef.h"
-#include "trionan.h"
-
-#include <math.h>
-#include <string.h>
-#include <limits.h>
-#if !defined(TRIO_PLATFORM_SYMBIAN)
-# include <float.h>
-#endif
-#if defined(TRIO_PLATFORM_UNIX)
-# include <signal.h>
-#endif
-#if defined(TRIO_COMPILER_DECC)
-# include <fp_class.h>
-#endif
-#include <assert.h>
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_nan.h"
-#endif
-/** @addtogroup SpecialQuantities
- @{
-*/
-
-/*************************************************************************
- * Definitions
- */
-
-#if !defined(TRIO_PUBLIC_NAN)
-# define TRIO_PUBLIC_NAN TRIO_PUBLIC
-#endif
-#if !defined(TRIO_PRIVATE_NAN)
-# define TRIO_PRIVATE_NAN TRIO_PRIVATE
-#endif
-
-#define TRIO_TRUE (1 == 1)
-#define TRIO_FALSE (0 == 1)
-
-/*
- * We must enable IEEE floating-point on Alpha
- */
-#if defined(__alpha) && !defined(_IEEE_FP)
-# if defined(TRIO_COMPILER_DECC)
-# if defined(TRIO_PLATFORM_VMS)
-# error "Must be compiled with option /IEEE_MODE=UNDERFLOW_TO_ZERO/FLOAT=IEEE"
-# else
-# if !defined(_CFE)
-# error "Must be compiled with option -ieee"
-# endif
-# endif
-# else
-# if defined(TRIO_COMPILER_GCC)
-# error "Must be compiled with option -mieee"
-# endif
-# endif
-#endif /* __alpha && ! _IEEE_FP */
-
-/*
- * In ANSI/IEEE 754-1985 64-bits double format numbers have the
- * following properties (amoungst others)
- *
- * o FLT_RADIX == 2: binary encoding
- * o DBL_MAX_EXP == 1024: 11 bits exponent, where one bit is used
- * to indicate special numbers (e.g. NaN and Infinity), so the
- * maximum exponent is 10 bits wide (2^10 == 1024).
- * o DBL_MANT_DIG == 53: The mantissa is 52 bits wide, but because
- * numbers are normalized the initial binary 1 is represented
- * implicitly (the so-called "hidden bit"), which leaves us with
- * the ability to represent 53 bits wide mantissa.
- */
-#if defined(__STDC_IEC_559__)
-# define TRIO_IEEE_754
-#else
-# if (FLT_RADIX - 0 == 2) && (DBL_MAX_EXP - 0 == 1024) && (DBL_MANT_DIG - 0 == 53)
-# define TRIO_IEEE_754
-# endif
-#endif
-
-/*
- * Determine which fpclassify_and_sign() function to use.
- */
-#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
-# if defined(PREDEF_STANDARD_C99) && defined(fpclassify)
-# define TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT
-# else
-# if defined(TRIO_COMPILER_DECC)
-# define TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT
-# else
-# if defined(TRIO_COMPILER_VISUALC) || defined(TRIO_COMPILER_BORLAND)
-# define TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT
-# else
-# if defined(TRIO_COMPILER_HP) && defined(FP_PLUS_NORM)
-# define TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT
-# else
-# if defined(TRIO_COMPILER_XLC) && defined(FP_PLUS_NORM)
-# define TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT
-# else
-# define TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT
-# endif
-# endif
-# endif
-# endif
-# endif
-#endif
-
-/*
- * Determine how to generate negative zero.
- */
-#if defined(TRIO_FUNC_NZERO)
-# if defined(TRIO_IEEE_754)
-# define TRIO_NZERO_IEEE_754
-# else
-# define TRIO_NZERO_FALLBACK
-# endif
-#endif
-
-/*
- * Determine how to generate positive infinity.
- */
-#if defined(TRIO_FUNC_PINF)
-# if defined(INFINITY) && defined(__STDC_IEC_559__)
-# define TRIO_PINF_C99_MACRO
-# else
-# if defined(TRIO_IEEE_754)
-# define TRIO_PINF_IEEE_754
-# else
-# define TRIO_PINF_FALLBACK
-# endif
-# endif
-#endif
-
-/*
- * Determine how to generate NaN.
- */
-#if defined(TRIO_FUNC_NAN)
-# if defined(PREDEF_STANDARD_C99) && !defined(TRIO_COMPILER_DECC)
-# define TRIO_NAN_C99_FUNCTION
-# else
-# if defined(NAN) && defined(__STDC_IEC_559__)
-# define TRIO_NAN_C99_MACRO
-# else
-# if defined(TRIO_IEEE_754)
-# define TRIO_NAN_IEEE_754
-# else
-# define TRIO_NAN_FALLBACK
-# endif
-# endif
-# endif
-#endif
-
-/*
- * Resolve internal dependencies.
- */
-#if defined(TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT)
-# define TRIO_FUNC_INTERNAL_ISNAN
-# define TRIO_FUNC_INTERNAL_ISINF
-# if defined(TRIO_IEEE_754)
-# define TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY
-# define TRIO_FUNC_INTERNAL_IS_NEGATIVE
-# endif
-#endif
-
-#if defined(TRIO_NZERO_IEEE_754) \
- || defined(TRIO_PINF_IEEE_754) \
- || defined(TRIO_NAN_IEEE_754)
-# define TRIO_FUNC_INTERNAL_MAKE_DOUBLE
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_ISNAN)
-# if defined(PREDEF_STANDARD_XPG3)
-# define TRIO_INTERNAL_ISNAN_XPG3
-# else
-# if defined(TRIO_IEEE_754)
-# define TRIO_INTERNAL_ISNAN_IEEE_754
-# else
-# define TRIO_INTERNAL_ISNAN_FALLBACK
-# endif
-# endif
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_ISINF)
-# if defined(TRIO_IEEE_754)
-# define TRIO_INTERNAL_ISINF_IEEE_754
-# else
-# define TRIO_INTERNAL_ISINF_FALLBACK
-# endif
-#endif
-
-/*************************************************************************
- * Constants
- */
-
-#if !defined(TRIO_EMBED_NAN)
-static TRIO_CONST char rcsid[] = "@(#)$Id: trionan.c,v 1.33 2005/05/29 11:57:25 breese Exp $";
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE) \
- || defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY) \
- || defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
-/*
- * Endian-agnostic indexing macro.
- *
- * The value of internalEndianMagic, when converted into a 64-bit
- * integer, becomes 0x0706050403020100 (we could have used a 64-bit
- * integer value instead of a double, but not all platforms supports
- * that type). The value is automatically encoded with the correct
- * endianess by the compiler, which means that we can support any
- * kind of endianess. The individual bytes are then used as an index
- * for the IEEE 754 bit-patterns and masks.
- */
-#define TRIO_DOUBLE_INDEX(x) (((unsigned char *)&internalEndianMagic)[7-(x)])
-static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)
-/* Mask for the exponent */
-static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {
- 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/* Mask for the mantissa */
-static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = {
- 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
-};
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
-/* Mask for the sign bit */
-static TRIO_CONST unsigned char ieee_754_sign_mask[] = {
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-#endif
-
-#if defined(TRIO_NZERO_IEEE_754)
-/* Bit-pattern for negative zero */
-static TRIO_CONST unsigned char ieee_754_negzero_array[] = {
- 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-#endif
-
-#if defined(TRIO_PINF_IEEE_754)
-/* Bit-pattern for infinity */
-static TRIO_CONST unsigned char ieee_754_infinity_array[] = {
- 0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-#endif
-
-#if defined(TRIO_NAN_IEEE_754)
-/* Bit-pattern for quiet NaN */
-static TRIO_CONST unsigned char ieee_754_qnan_array[] = {
- 0x7F, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-#endif
-
-
-/*************************************************************************
- * Internal functions
- */
-
-/*
- * internal_make_double
- */
-#if defined(TRIO_FUNC_INTERNAL_MAKE_DOUBLE)
-
-TRIO_PRIVATE_NAN double
-internal_make_double
-TRIO_ARGS1((values),
- TRIO_CONST unsigned char *values)
-{
- TRIO_VOLATILE double result;
- int i;
-
- for (i = 0; i < (int)sizeof(double); i++) {
- ((TRIO_VOLATILE unsigned char *)&result)[TRIO_DOUBLE_INDEX(i)] = values[i];
- }
- return result;
-}
-
-#endif
-
-/*
- * internal_is_special_quantity
- */
-#if defined(TRIO_FUNC_INTERNAL_IS_SPECIAL_QUANTITY)
-
-TRIO_PRIVATE_NAN int
-internal_is_special_quantity
-TRIO_ARGS2((number, has_mantissa),
- double number,
- int *has_mantissa)
-{
- unsigned int i;
- unsigned char current;
- int is_special_quantity = TRIO_TRUE;
-
- *has_mantissa = 0;
-
- for (i = 0; i < (unsigned int)sizeof(double); i++) {
- current = ((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)];
- is_special_quantity
- &= ((current & ieee_754_exponent_mask[i]) == ieee_754_exponent_mask[i]);
- *has_mantissa |= (current & ieee_754_mantissa_mask[i]);
- }
- return is_special_quantity;
-}
-
-#endif
-
-/*
- * internal_is_negative
- */
-#if defined(TRIO_FUNC_INTERNAL_IS_NEGATIVE)
-
-TRIO_PRIVATE_NAN int
-internal_is_negative
-TRIO_ARGS1((number),
- double number)
-{
- unsigned int i;
- int is_negative = TRIO_FALSE;
-
- for (i = 0; i < (unsigned int)sizeof(double); i++) {
- is_negative |= (((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)]
- & ieee_754_sign_mask[i]);
- }
- return is_negative;
-}
-
-#endif
-
-#if defined(TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT)
-
-TRIO_PRIVATE_NAN TRIO_INLINE int
-c99_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
- double number,
- int *is_negative)
-{
- *is_negative = signbit(number);
- switch (fpclassify(number)) {
- case FP_NAN:
- return TRIO_FP_NAN;
- case FP_INFINITE:
- return TRIO_FP_INFINITE;
- case FP_SUBNORMAL:
- return TRIO_FP_SUBNORMAL;
- case FP_ZERO:
- return TRIO_FP_ZERO;
- default:
- return TRIO_FP_NORMAL;
- }
-}
-
-#endif /* TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT */
-
-#if defined(TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT)
-
-TRIO_PRIVATE_NAN TRIO_INLINE int
-decc_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
- double number,
- int *is_negative)
-{
- switch (fp_class(number)) {
- case FP_QNAN:
- case FP_SNAN:
- *is_negative = TRIO_FALSE; /* NaN has no sign */
- return TRIO_FP_NAN;
- case FP_POS_INF:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_INFINITE;
- case FP_NEG_INF:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_INFINITE;
- case FP_POS_DENORM:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_SUBNORMAL;
- case FP_NEG_DENORM:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_SUBNORMAL;
- case FP_POS_ZERO:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_ZERO;
- case FP_NEG_ZERO:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_ZERO;
- case FP_POS_NORM:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_NORMAL;
- case FP_NEG_NORM:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_NORMAL;
- default:
- *is_negative = (number < 0.0);
- return TRIO_FP_NORMAL;
- }
-}
-
-#endif /* TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT */
-
-#if defined(TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT)
-
-TRIO_PRIVATE_NAN int
-ms_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
- double number,
- int *is_negative)
-{
- int result;
-# if defined(TRIO_COMPILER_BORLAND)
- /*
- * The floating-point precision may be changed by the Borland _fpclass()
- * function, so we have to save and restore the floating-point control mask.
- */
- unsigned int mask;
- /* Remember the old mask */
- mask = _control87(0, 0);
-# endif
-
- switch (_fpclass(number)) {
- case _FPCLASS_QNAN:
- case _FPCLASS_SNAN:
- *is_negative = TRIO_FALSE; /* NaN has no sign */
- result = TRIO_FP_NAN;
- break;
- case _FPCLASS_PINF:
- *is_negative = TRIO_FALSE;
- result = TRIO_FP_INFINITE;
- break;
- case _FPCLASS_NINF:
- *is_negative = TRIO_TRUE;
- result = TRIO_FP_INFINITE;
- break;
- case _FPCLASS_PD:
- *is_negative = TRIO_FALSE;
- result = TRIO_FP_SUBNORMAL;
- break;
- case _FPCLASS_ND:
- *is_negative = TRIO_TRUE;
- result = TRIO_FP_SUBNORMAL;
- break;
- case _FPCLASS_PZ:
- *is_negative = TRIO_FALSE;
- result = TRIO_FP_ZERO;
- break;
- case _FPCLASS_NZ:
- *is_negative = TRIO_TRUE;
- result = TRIO_FP_ZERO;
- break;
- case _FPCLASS_PN:
- *is_negative = TRIO_FALSE;
- result = TRIO_FP_NORMAL;
- break;
- case _FPCLASS_NN:
- *is_negative = TRIO_TRUE;
- result = TRIO_FP_NORMAL;
- break;
- default:
- *is_negative = (number < 0.0);
- result = TRIO_FP_NORMAL;
- break;
- }
-
-# if defined(TRIO_COMPILER_BORLAND)
- /* Restore the old precision */
- (void)_control87(mask, MCW_PC);
-# endif
-
- return result;
-}
-
-#endif /* TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT */
-
-#if defined(TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT)
-
-TRIO_PRIVATE_NAN TRIO_INLINE int
-hp_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
- double number,
- int *is_negative)
-{
- /*
- * HP-UX 9.x and 10.x have an fpclassify() function, that is different
- * from the C99 fpclassify() macro supported on HP-UX 11.x.
- */
- switch (fpclassify(number)) {
- case FP_QNAN:
- case FP_SNAN:
- *is_negative = TRIO_FALSE; /* NaN has no sign */
- return TRIO_FP_NAN;
- case FP_PLUS_INF:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_INFINITE;
- case FP_MINUS_INF:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_INFINITE;
- case FP_PLUS_DENORM:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_SUBNORMAL;
- case FP_MINUS_DENORM:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_SUBNORMAL;
- case FP_PLUS_ZERO:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_ZERO;
- case FP_MINUS_ZERO:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_ZERO;
- case FP_PLUS_NORM:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_NORMAL;
- case FP_MINUS_NORM:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_NORMAL;
- default:
- *is_negative = (number < 0.0);
- return TRIO_FP_NORMAL;
- }
-}
-
-#endif /* TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT */
-
-#if defined(TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT)
-
-TRIO_PRIVATE_NAN TRIO_INLINE int
-xlc_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
- double number,
- int *is_negative)
-{
- /*
- * AIX has class() for C, and _class() for C++
- */
-# if defined(__cplusplus)
-# define AIX_CLASS(n) _class(n)
-# else
-# define AIX_CLASS(n) class(n)
-# endif
-
- switch (AIX_CLASS(number)) {
- case FP_QNAN:
- case FP_SNAN:
- *is_negative = TRIO_FALSE; /* NaN has no sign */
- return TRIO_FP_NAN;
- case FP_PLUS_INF:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_INFINITE;
- case FP_MINUS_INF:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_INFINITE;
- case FP_PLUS_DENORM:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_SUBNORMAL;
- case FP_MINUS_DENORM:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_SUBNORMAL;
- case FP_PLUS_ZERO:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_ZERO;
- case FP_MINUS_ZERO:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_ZERO;
- case FP_PLUS_NORM:
- *is_negative = TRIO_FALSE;
- return TRIO_FP_NORMAL;
- case FP_MINUS_NORM:
- *is_negative = TRIO_TRUE;
- return TRIO_FP_NORMAL;
- default:
- *is_negative = (number < 0.0);
- return TRIO_FP_NORMAL;
- }
-}
-
-#endif /* TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT */
-
-#if defined(TRIO_FUNC_INTERNAL_ISNAN)
-
-TRIO_PRIVATE_NAN TRIO_INLINE int
-internal_isnan
-TRIO_ARGS1((number),
- double number)
-{
-# if defined(TRIO_INTERNAL_ISNAN_XPG3) || defined(TRIO_PLATFORM_SYMBIAN)
- /*
- * XPG3 defines isnan() as a function.
- */
- return isnan(number);
-
-# endif
-
-# if defined(TRIO_INTERNAL_ISNAN_IEEE_754)
-
- /*
- * Examine IEEE 754 bit-pattern. A NaN must have a special exponent
- * pattern, and a non-empty mantissa.
- */
- int has_mantissa;
- int is_special_quantity;
-
- is_special_quantity = internal_is_special_quantity(number, &has_mantissa);
-
- return (is_special_quantity && has_mantissa);
-
-# endif
-
-# if defined(TRIO_INTERNAL_ISNAN_FALLBACK)
-
- /*
- * Fallback solution
- */
- int status;
- double integral, fraction;
-
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
-
- status = (/*
- * NaN is the only number which does not compare to itself
- */
- ((TRIO_VOLATILE double)number != (TRIO_VOLATILE double)number) ||
- /*
- * Fallback solution if NaN compares to NaN
- */
- ((number != 0.0) &&
- (fraction = modf(number, &integral),
- integral == fraction)));
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
- return status;
-
-# endif
-}
-
-#endif /* TRIO_FUNC_INTERNAL_ISNAN */
-
-#if defined(TRIO_FUNC_INTERNAL_ISINF)
-
-TRIO_PRIVATE_NAN TRIO_INLINE int
-internal_isinf
-TRIO_ARGS1((number),
- double number)
-{
-# if defined(TRIO_PLATFORM_SYMBIAN)
-
- return isinf(number);
-
-# endif
-
-# if defined(TRIO_INTERNAL_ISINF_IEEE_754)
- /*
- * Examine IEEE 754 bit-pattern. Infinity must have a special exponent
- * pattern, and an empty mantissa.
- */
- int has_mantissa;
- int is_special_quantity;
-
- is_special_quantity = internal_is_special_quantity(number, &has_mantissa);
-
- return (is_special_quantity && !has_mantissa)
- ? ((number < 0.0) ? -1 : 1)
- : 0;
-
-# endif
-
-# if defined(TRIO_INTERNAL_ISINF_FALLBACK)
-
- /*
- * Fallback solution.
- */
- int status;
-
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
-
- double infinity = trio_pinf();
-
- status = ((number == infinity)
- ? 1
- : ((number == -infinity) ? -1 : 0));
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
- return status;
-
-# endif
-}
-
-#endif /* TRIO_FUNC_INTERNAL_ISINF */
-
-/*************************************************************************
- * Public functions
- */
-
-#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
-
-TRIO_PUBLIC_NAN int
-trio_fpclassify_and_signbit
-TRIO_ARGS2((number, is_negative),
- double number,
- int *is_negative)
-{
- /* The TRIO_FUNC_xxx_FPCLASSIFY_AND_SIGNBIT macros are mutually exclusive */
-
-#if defined(TRIO_FUNC_C99_FPCLASSIFY_AND_SIGNBIT)
-
- return c99_fpclassify_and_signbit(number, is_negative);
-
-#endif
-
-#if defined(TRIO_FUNC_DECC_FPCLASSIFY_AND_SIGNBIT)
-
- return decc_fpclassify_and_signbit(number, is_negative);
-
-#endif
-
-#if defined(TRIO_FUNC_MS_FPCLASSIFY_AND_SIGNBIT)
-
- return ms_fpclassify_and_signbit(number, is_negative);
-
-#endif
-
-#if defined(TRIO_FUNC_HP_FPCLASSIFY_AND_SIGNBIT)
-
- return hp_fpclassify_and_signbit(number, is_negative);
-
-#endif
-
-#if defined(TRIO_FUNC_XLC_FPCLASSIFY_AND_SIGNBIT)
-
- return xlc_fpclassify_and_signbit(number, is_negative);
-
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_FPCLASSIFY_AND_SIGNBIT)
-
- /*
- * Fallback solution.
- */
- int rc;
-
- if (number == 0.0) {
- /*
- * In IEEE 754 the sign of zero is ignored in comparisons, so we
- * have to handle this as a special case by examining the sign bit
- * directly.
- */
-# if defined(TRIO_IEEE_754)
- *is_negative = internal_is_negative(number);
-# else
- *is_negative = TRIO_FALSE; /* FIXME */
-# endif
- return TRIO_FP_ZERO;
- }
- if (internal_isnan(number)) {
- *is_negative = TRIO_FALSE;
- return TRIO_FP_NAN;
- }
- rc = internal_isinf(number);
- if (rc != 0) {
- *is_negative = (rc == -1);
- return TRIO_FP_INFINITE;
- }
- if ((number > 0.0) && (number < DBL_MIN)) {
- *is_negative = TRIO_FALSE;
- return TRIO_FP_SUBNORMAL;
- }
- if ((number < 0.0) && (number > -DBL_MIN)) {
- *is_negative = TRIO_TRUE;
- return TRIO_FP_SUBNORMAL;
- }
- *is_negative = (number < 0.0);
- return TRIO_FP_NORMAL;
-
-#endif
-}
-
-#endif
-
-/**
- Check for NaN.
-
- @param number An arbitrary floating-point number.
- @return Boolean value indicating whether or not the number is a NaN.
-*/
-#if defined(TRIO_FUNC_ISNAN)
-
-TRIO_PUBLIC_NAN int
-trio_isnan
-TRIO_ARGS1((number),
- double number)
-{
- int dummy;
-
- return (trio_fpclassify_and_signbit(number, &dummy) == TRIO_FP_NAN);
-}
-
-#endif
-
-/**
- Check for infinity.
-
- @param number An arbitrary floating-point number.
- @return 1 if positive infinity, -1 if negative infinity, 0 otherwise.
-*/
-#if defined(TRIO_FUNC_ISINF)
-
-TRIO_PUBLIC_NAN int
-trio_isinf
-TRIO_ARGS1((number),
- double number)
-{
- int is_negative;
-
- if (trio_fpclassify_and_signbit(number, &is_negative) == TRIO_FP_INFINITE)
- {
- return (is_negative) ? -1 : 1;
- }
- else
- {
- return 0;
- }
-}
-
-#endif
-
-/**
- Check for finity.
-
- @param number An arbitrary floating-point number.
- @return Boolean value indicating whether or not the number is a finite.
-*/
-#if defined(TRIO_FUNC_ISFINITE)
-
-TRIO_PUBLIC_NAN int
-trio_isfinite
-TRIO_ARGS1((number),
- double number)
-{
- int dummy;
-
- switch (trio_fpclassify_and_signbit(number, &dummy))
- {
- case TRIO_FP_INFINITE:
- case TRIO_FP_NAN:
- return 0;
- default:
- return 1;
- }
-}
-
-#endif
-
-/**
- Examine the sign of a number.
-
- @param number An arbitrary floating-point number.
- @return Boolean value indicating whether or not the number has the
- sign bit set (i.e. is negative).
-*/
-#if defined(TRIO_FUNC_SIGNBIT)
-
-TRIO_PUBLIC_NAN int
-trio_signbit
-TRIO_ARGS1((number),
- double number)
-{
- int is_negative;
-
- (void)trio_fpclassify_and_signbit(number, &is_negative);
- return is_negative;
-}
-
-#endif
-
-/**
- Examine the class of a number.
-
- @param number An arbitrary floating-point number.
- @return Enumerable value indicating the class of @p number
-*/
-#if defined(TRIO_FUNC_FPCLASSIFY)
-
-TRIO_PUBLIC_NAN int
-trio_fpclassify
-TRIO_ARGS1((number),
- double number)
-{
- int dummy;
-
- return trio_fpclassify_and_signbit(number, &dummy);
-}
-
-#endif
-
-/**
- Generate negative zero.
-
- @return Floating-point representation of negative zero.
-*/
-#if defined(TRIO_FUNC_NZERO)
-
-TRIO_PUBLIC_NAN double
-trio_nzero(TRIO_NOARGS)
-{
-# if defined(TRIO_NZERO_IEEE_754)
-
- return internal_make_double(ieee_754_negzero_array);
-
-# endif
-
-# if defined(TRIO_NZERO_FALLBACK)
-
- TRIO_VOLATILE double zero = 0.0;
-
- return -zero;
-
-# endif
-}
-
-#endif
-
-/**
- Generate positive infinity.
-
- @return Floating-point representation of positive infinity.
-*/
-#if defined(TRIO_FUNC_PINF)
-
-TRIO_PUBLIC_NAN double
-trio_pinf(TRIO_NOARGS)
-{
- /* Cache the result */
- static double pinf_value = 0.0;
-
- if (pinf_value == 0.0) {
-
-# if defined(TRIO_PINF_C99_MACRO)
-
- pinf_value = (double)INFINITY;
-
-# endif
-
-# if defined(TRIO_PINF_IEEE_754)
-
- pinf_value = internal_make_double(ieee_754_infinity_array);
-
-# endif
-
-# if defined(TRIO_PINF_FALLBACK)
- /*
- * If HUGE_VAL is different from DBL_MAX, then HUGE_VAL is used
- * as infinity. Otherwise we have to resort to an overflow
- * operation to generate infinity.
- */
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
-
- pinf_value = HUGE_VAL;
- if (HUGE_VAL == DBL_MAX) {
- /* Force overflow */
- pinf_value += HUGE_VAL;
- }
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
-# endif
- }
- return pinf_value;
-}
-
-#endif
-
-/**
- Generate negative infinity.
-
- @return Floating-point value of negative infinity.
-*/
-#if defined(TRIO_FUNC_NINF)
-
-TRIO_PUBLIC_NAN double
-trio_ninf(TRIO_NOARGS)
-{
- static double ninf_value = 0.0;
-
- if (ninf_value == 0.0) {
- /*
- * Negative infinity is calculated by negating positive infinity,
- * which can be done because it is legal to do calculations on
- * infinity (for example, 1 / infinity == 0).
- */
- ninf_value = -trio_pinf();
- }
- return ninf_value;
-}
-
-#endif
-
-/**
- Generate NaN.
-
- @return Floating-point representation of NaN.
-*/
-#if defined(TRIO_FUNC_NAN)
-
-TRIO_PUBLIC_NAN double
-trio_nan(TRIO_NOARGS)
-{
- /* Cache the result */
- static double nan_value = 0.0;
-
- if (nan_value == 0.0) {
-
-# if defined(TRIO_NAN_C99_FUNCTION) || defined(TRIO_PLATFORM_SYMBIAN)
-
- nan_value = nan("");
-
-# endif
-
-# if defined(TRIO_NAN_C99_MACRO)
-
- nan_value = (double)NAN;
-
-# endif
-
-# if defined(TRIO_NAN_IEEE_754)
-
- nan_value = internal_make_double(ieee_754_qnan_array);
-
-# endif
-
-# if defined(TRIO_NAN_FALLBACK)
- /*
- * There are several ways to generate NaN. The one used here is
- * to divide infinity by infinity. I would have preferred to add
- * negative infinity to positive infinity, but that yields wrong
- * result (infinity) on FreeBSD.
- *
- * This may fail if the hardware does not support NaN, or if
- * the Invalid Operation floating-point exception is unmasked.
- */
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler)(int) = signal(SIGFPE, SIG_IGN);
-# endif
-
- nan_value = trio_pinf() / trio_pinf();
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
-# endif
- }
- return nan_value;
-}
-
-#endif
-
-/** @} SpecialQuantities */
-
-/*************************************************************************
- * For test purposes.
- *
- * Add the following compiler option to include this test code.
- *
- * Unix : -DSTANDALONE
- * VMS : /DEFINE=(STANDALONE)
- */
-#if defined(STANDALONE)
-# include <stdio.h>
-
-static TRIO_CONST char *
-getClassification
-TRIO_ARGS1((type),
- int type)
-{
- switch (type) {
- case TRIO_FP_INFINITE:
- return "FP_INFINITE";
- case TRIO_FP_NAN:
- return "FP_NAN";
- case TRIO_FP_NORMAL:
- return "FP_NORMAL";
- case TRIO_FP_SUBNORMAL:
- return "FP_SUBNORMAL";
- case TRIO_FP_ZERO:
- return "FP_ZERO";
- default:
- return "FP_UNKNOWN";
- }
-}
-
-static void
-print_class
-TRIO_ARGS2((prefix, number),
- TRIO_CONST char *prefix,
- double number)
-{
- printf("%-6s: %s %-15s %g\n",
- prefix,
- trio_signbit(number) ? "-" : "+",
- getClassification(trio_fpclassify(number)),
- number);
-}
-
-int main(TRIO_NOARGS)
-{
- double my_nan;
- double my_pinf;
- double my_ninf;
-# if defined(TRIO_PLATFORM_UNIX)
- void (*signal_handler) TRIO_PROTO((int));
-# endif
-
- my_nan = trio_nan();
- my_pinf = trio_pinf();
- my_ninf = trio_ninf();
-
- print_class("Nan", my_nan);
- print_class("PInf", my_pinf);
- print_class("NInf", my_ninf);
- print_class("PZero", 0.0);
- print_class("NZero", -0.0);
- print_class("PNorm", 1.0);
- print_class("NNorm", -1.0);
- print_class("PSub", 1.01e-307 - 1.00e-307);
- print_class("NSub", 1.00e-307 - 1.01e-307);
-
- printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
- my_nan,
- ((unsigned char *)&my_nan)[0],
- ((unsigned char *)&my_nan)[1],
- ((unsigned char *)&my_nan)[2],
- ((unsigned char *)&my_nan)[3],
- ((unsigned char *)&my_nan)[4],
- ((unsigned char *)&my_nan)[5],
- ((unsigned char *)&my_nan)[6],
- ((unsigned char *)&my_nan)[7],
- trio_isnan(my_nan), trio_isinf(my_nan), trio_isfinite(my_nan));
- printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
- my_pinf,
- ((unsigned char *)&my_pinf)[0],
- ((unsigned char *)&my_pinf)[1],
- ((unsigned char *)&my_pinf)[2],
- ((unsigned char *)&my_pinf)[3],
- ((unsigned char *)&my_pinf)[4],
- ((unsigned char *)&my_pinf)[5],
- ((unsigned char *)&my_pinf)[6],
- ((unsigned char *)&my_pinf)[7],
- trio_isnan(my_pinf), trio_isinf(my_pinf), trio_isfinite(my_pinf));
- printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
- my_ninf,
- ((unsigned char *)&my_ninf)[0],
- ((unsigned char *)&my_ninf)[1],
- ((unsigned char *)&my_ninf)[2],
- ((unsigned char *)&my_ninf)[3],
- ((unsigned char *)&my_ninf)[4],
- ((unsigned char *)&my_ninf)[5],
- ((unsigned char *)&my_ninf)[6],
- ((unsigned char *)&my_ninf)[7],
- trio_isnan(my_ninf), trio_isinf(my_ninf), trio_isfinite(my_ninf));
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal_handler = signal(SIGFPE, SIG_IGN);
-# endif
-
- my_pinf = DBL_MAX + DBL_MAX;
- my_ninf = -my_pinf;
- my_nan = my_pinf / my_pinf;
-
-# if defined(TRIO_PLATFORM_UNIX)
- signal(SIGFPE, signal_handler);
-# endif
-
- printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
- my_nan,
- ((unsigned char *)&my_nan)[0],
- ((unsigned char *)&my_nan)[1],
- ((unsigned char *)&my_nan)[2],
- ((unsigned char *)&my_nan)[3],
- ((unsigned char *)&my_nan)[4],
- ((unsigned char *)&my_nan)[5],
- ((unsigned char *)&my_nan)[6],
- ((unsigned char *)&my_nan)[7],
- trio_isnan(my_nan), trio_isinf(my_nan), trio_isfinite(my_nan));
- printf("PInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
- my_pinf,
- ((unsigned char *)&my_pinf)[0],
- ((unsigned char *)&my_pinf)[1],
- ((unsigned char *)&my_pinf)[2],
- ((unsigned char *)&my_pinf)[3],
- ((unsigned char *)&my_pinf)[4],
- ((unsigned char *)&my_pinf)[5],
- ((unsigned char *)&my_pinf)[6],
- ((unsigned char *)&my_pinf)[7],
- trio_isnan(my_pinf), trio_isinf(my_pinf), trio_isfinite(my_pinf));
- printf("NInf: %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d, %2d)\n",
- my_ninf,
- ((unsigned char *)&my_ninf)[0],
- ((unsigned char *)&my_ninf)[1],
- ((unsigned char *)&my_ninf)[2],
- ((unsigned char *)&my_ninf)[3],
- ((unsigned char *)&my_ninf)[4],
- ((unsigned char *)&my_ninf)[5],
- ((unsigned char *)&my_ninf)[6],
- ((unsigned char *)&my_ninf)[7],
- trio_isnan(my_ninf), trio_isinf(my_ninf), trio_isfinite(my_ninf));
-
- return 0;
-}
-#endif
+++ /dev/null
-/*************************************************************************
- *
- * $Id: trionan.h,v 1.9 2005/03/27 18:52:45 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese <breese@users.sourceforge.net>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIONAN_H
-#define TRIO_TRIONAN_H
-
-#include "triodef.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if !defined(TRIO_PUBLIC_NAN)
-# if !defined(TRIO_PUBLIC)
-# define TRIO_PUBLIC
-# endif
-# define TRIO_PUBLIC_NAN TRIO_PUBLIC
-#endif
-
-enum {
- TRIO_FP_INFINITE,
- TRIO_FP_NAN,
- TRIO_FP_NORMAL,
- TRIO_FP_SUBNORMAL,
- TRIO_FP_ZERO
-};
-
-/*************************************************************************
- * Dependencies
- */
-
-#if defined(TRIO_EMBED_NAN)
-
-/*
- * The application that trionan is embedded in must define which functions
- * it uses.
- *
- * The following resolves internal dependencies.
- */
-
-# if defined(TRIO_FUNC_ISNAN) \
- || defined(TRIO_FUNC_ISINF)
-# if !defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
-# define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT
-# endif
-# endif
-
-# if defined(TRIO_FUNC_NAN)
-# if !defined(TRIO_FUNC_PINF)
-# define TRIO_FUNC_PINF
-# endif
-# endif
-
-# if defined(TRIO_FUNC_NINF)
-# if !defined(TRIO_FUNC_PINF)
-# define TRIO_FUNC_PINF
-# endif
-# endif
-
-#else
-
-/*
- * When trionan is not embedded all all functions are defined.
- */
-
-# define TRIO_FUNC_NAN
-# define TRIO_FUNC_PINF
-# define TRIO_FUNC_NINF
-# define TRIO_FUNC_NZERO
-# define TRIO_FUNC_ISNAN
-# define TRIO_FUNC_ISINF
-# define TRIO_FUNC_ISFINITE
-# define TRIO_FUNC_SIGNBIT
-# define TRIO_FUNC_FPCLASSIFY
-# define TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT
-
-#endif
-
-/*************************************************************************
- * Functions
- */
-
-/*
- * Return NaN (Not-a-Number).
- */
-#if defined(TRIO_FUNC_NAN)
-TRIO_PUBLIC_NAN double
-trio_nan
-TRIO_PROTO((void));
-#endif
-
-/*
- * Return positive infinity.
- */
-#if defined(TRIO_FUNC_PINF)
-TRIO_PUBLIC_NAN double
-trio_pinf
-TRIO_PROTO((void));
-#endif
-
-/*
- * Return negative infinity.
- */
-#if defined(TRIO_FUNC_NINF)
-TRIO_PUBLIC_NAN double
-trio_ninf
-TRIO_PROTO((void));
-#endif
-
-/*
- * Return negative zero.
- */
-#if defined(TRIO_FUNC_NZERO)
-TRIO_PUBLIC_NAN double
-trio_nzero
-TRIO_PROTO((TRIO_NOARGS));
-#endif
-
-/*
- * If number is a NaN return non-zero, otherwise return zero.
- */
-#if defined(TRIO_FUNC_ISNAN)
-TRIO_PUBLIC_NAN int
-trio_isnan
-TRIO_PROTO((double number));
-#endif
-
-/*
- * If number is positive infinity return 1, if number is negative
- * infinity return -1, otherwise return 0.
- */
-#if defined(TRIO_FUNC_ISINF)
-TRIO_PUBLIC_NAN int
-trio_isinf
-TRIO_PROTO((double number));
-#endif
-
-/*
- * If number is finite return non-zero, otherwise return zero.
- */
-#if defined(TRIO_FUNC_ISFINITE)
-TRIO_PUBLIC_NAN int
-trio_isfinite
-TRIO_PROTO((double number));
-#endif
-
-#if defined(TRIO_FUNC_SIGNBIT)
-TRIO_PUBLIC_NAN int
-trio_signbit
-TRIO_PROTO((double number));
-#endif
-
-#if defined(TRIO_FUNC_FPCLASSIFY)
-TRIO_PUBLIC_NAN int
-trio_fpclassify
-TRIO_PROTO((double number));
-#endif
-
-#if defined(TRIO_FUNC_FPCLASSIFY_AND_SIGNBIT)
-TRIO_PUBLIC_NAN int
-trio_fpclassify_and_signbit
-TRIO_PROTO((double number, int *is_negative));
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TRIO_TRIONAN_H */
+++ /dev/null
-/*************************************************************************
- *
- * $Id: triop.h,v 1.18 2009/07/05 10:14:07 breese Exp $
- *
- * Copyright (C) 2000 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************
- *
- * Private functions, types, etc. used for callback functions.
- *
- * The ref pointer is an opaque type and should remain as such.
- * Private data must only be accessible through the getter and
- * setter functions.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIOP_H
-#define TRIO_TRIOP_H
-
-#include "triodef.h"
-
-#include <stdlib.h>
-#if defined(TRIO_COMPILER_ANCIENT)
-# include <varargs.h>
-#else
-# include <stdarg.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*************************************************************************
- * Supported standards
- */
-
-/*
- * TRIO_C99 (=0 or =1)
- *
- * Define this to 0 to disable C99 format specifier extensions, or
- * define to 1 to enable them. The format specifiers that are
- * disabled by this switch are labelled with [C99] in the format
- * specifier documentation.
- */
-#if !defined(TRIO_C99)
-# define TRIO_C99 1
-#endif
-
-/*
- * TRIO_BSD (=0 or =1)
- *
- * Define this to 0 to disable BSD format specifier extensions, or
- * define to 1 to enable them. The format specifiers that are
- * disabled by this switch are labelled with [BSD] in the format
- * specifier documentation.
- */
-#if !defined(TRIO_BSD)
-# define TRIO_BSD 1
-#endif
-
-/*
- * TRIO_GNU (=0 or =1)
- *
- * Define this to 0 to disable GNU format specifier extensions, or
- * define to 1 to enable them. The format specifiers that are
- * disabled by this switch are labelled with [GNU] in the format
- * specifier documentation.
- */
-#if !defined(TRIO_GNU)
-# define TRIO_GNU 1
-#endif
-
-/*
- * TRIO_MISC (=0 or =1)
- *
- * Define this to 0 to disable miscellaneous format specifier
- * extensions, or define to 1 to enable them. The format specifiers
- * that are disabled by this switch are labelled with [MISC] in the
- * format specifier documentation.
- */
-#if !defined(TRIO_MISC)
-# define TRIO_MISC 1
-#endif
-
-/*
- * TRIO_UNIX98 (=0 or =1)
- *
- * Define this to 0 to disable UNIX98 format specifier extensions,
- * or define to 1 to enable them. The format specifiers that are
- * disabled by this switch are labelled with [UNIX98] in the format
- * specifier documentation.
- */
-#if !defined(TRIO_UNIX98)
-# define TRIO_UNIX98 1
-#endif
-
-/*
- * TRIO_MICROSOFT (=0 or =1)
- *
- * Define this to 0 to disable Microsoft Visual C format specifier
- * extensions, or define to 1 to enable them. The format specifiers
- * that are disabled by this switch are labelled with [MSVC] in the
- * format specifier documentation.
- */
-#if !defined(TRIO_MICROSOFT)
-# define TRIO_MICROSOFT 1
-#endif
-
-/*
- * TRIO_EXTENSION (=0 or =1)
- *
- * Define this to 0 to disable Trio-specific extensions, or define
- * to 1 to enable them. This has two effects: it controls whether
- * or not the Trio user-defined formating mechanism
- * (trio_register() etc) is supported, and it enables or disables
- * Trio's own format specifier extensions. The format specifiers
- * that are disabled by this switch are labelled with [TRIO] in
- * the format specifier documentation.
- */
-#if !defined(TRIO_EXTENSION)
-# define TRIO_EXTENSION 1
-#endif
-
-/*
- * TRIO_DEPRECATED (=0 or =1)
- *
- * Define this to 0 to disable deprecated functionality, or define
- * to 1 to enable them.
- */
-#if !defined(TRIO_DEPRECATED)
-# define TRIO_DEPRECATED 1
-#endif
-
-/*************************************************************************
- * Features
- */
-
-#if defined(TRIO_SNPRINTF_ONLY)
-# define TRIO_FEATURE_SCANF 0
-# define TRIO_FEATURE_FILE 0
-# define TRIO_FEATURE_STDIO 0
-# define TRIO_FEATURE_FD 0
-# define TRIO_FEATURE_DYNAMICSTRING 0
-# define TRIO_FEATURE_CLOSURE 0
-# define TRIO_FEATURE_STRERR 0
-# define TRIO_FEATURE_LOCALE 0
-# define TRIO_EMBED_NAN 1
-# define TRIO_EMBED_STRING 1
-#endif
-
-/*
- * TRIO_FEATURE_SCANF (=0 or =1)
- *
- * Define this to 0 to disable all the scanf() variants, or define to 1
- * to enable them.
- */
-#if !defined(TRIO_FEATURE_SCANF)
-# define TRIO_FEATURE_SCANF 1
-#endif
-
-/*
- * TRIO_FEATURE_FILE (=0 or =1)
- *
- * Define this to 0 to disable compilation of the trio_fprintf() and
- * trio_fscanf() family of functions, or define to 1 to enable them.
- *
- * This may be useful on an embedded platform with no filesystem.
- * Note that trio_printf() uses fwrite to write to stdout, so if you
- * do not have an implementation of fwrite() at all then you must also
- * define TRIO_FEATURE_STDIO to 0.
- */
-#if !defined(TRIO_FEATURE_FILE)
-# define TRIO_FEATURE_FILE 1
-#endif
-
-/*
- * TRIO_FEATURE_STDIO (=0 or =1)
- *
- * Define this to 0 to disable compilation of the trio_printf() and
- * trio_scanf() family of functions, or define to 1 to enable them.
- *
- * This may be useful on an embedded platform with no standard I/O.
- */
-#if !defined(TRIO_FEATURE_STDIO)
-# define TRIO_FEATURE_STDIO 1
-#endif
-
-/*
- * TRIO_FEATURE_FD (=0 or =1)
- *
- * Define this to 0 to disable compilation of the trio_dprintf() and
- * trio_dscanf() family of functions, or define to 1 to enable them.
- *
- * This may be useful on an embedded platform with no filesystem, or on
- * a platform that supports file I/O using FILE* but not using raw file
- * descriptors.
- */
-#if !defined(TRIO_FEATURE_FD)
-# define TRIO_FEATURE_FD 1
-#endif
-
-/*
- * TRIO_FEATURE_DYNAMICSTRING (=0 or =1)
- *
- * Define this to 0 to disable compilation of the trio_aprintf()
- * family of functions, or define to 1 to enable them.
- *
- * If you define both this and TRIO_MINIMAL to 0, then Trio will never
- * call malloc or free.
- */
-#if !defined(TRIO_FEATURE_DYNAMICSTRING)
-# define TRIO_FEATURE_DYNAMICSTRING 1
-#endif
-
-/*
- * TRIO_FEATURE_CLOSURE (=0 or =1)
- *
- * Define this to 0 to disable compilation of the trio_cprintf() and
- * trio_cscanf() family of functions, or define to 1 to enable them.
- *
- * These functions are rarely needed. This saves a (small) amount of code.
- */
-#if !defined(TRIO_FEATURE_CLOSURE)
-# define TRIO_FEATURE_CLOSURE 1
-#endif
-
-/*
- * TRIO_FEATURE_ERRORCODE (=0 or =1)
- *
- * Define this to 0 to return -1 from the print and scan function on
- * error, or define to 1 to return a negative number with debugging
- * information as part of the return code.
- *
- * If enabled, the return code will be a negative number, which encodes
- * an error code and an error location. These can be decoded with the
- * TRIO_ERROR_CODE and TRIO_ERROR_POSITION macros.
- */
-#if defined(TRIO_ERRORS)
-# define TRIO_FEATURE_ERRORCODE TRIO_ERRORS
-#endif
-#if !defined(TRIO_FEATURE_ERRORCODE)
-# define TRIO_FEATURE_ERRORCODE 1
-#endif
-
-/*
- * TRIO_FEATURE_STRERR (=0 or =1)
- *
- * Define this to 0 if you do not use trio_strerror(), or define to 1 if
- * you do use it.
- *
- * This saves a (small) amount of code.
- */
-#if !defined(TRIO_FEATURE_STRERR)
-# define TRIO_FEATURE_STRERR 1
-#endif
-
-/*
- * TRIO_FEATURE_FLOAT (=0 or =1)
- *
- * Define this to 0 to disable all floating-point support, or define
- * to 1 to enable it.
- *
- * This is useful in restricted embedded platforms that do not support
- * floating-point. Obviously you cannot use floating-point format
- * specifiers if you define this.
- *
- * Do not compile trionan.c if you disable this.
- */
-#if !defined(TRIO_FEATURE_FLOAT)
-# define TRIO_FEATURE_FLOAT 1
-#endif
-
-/*
- * TRIO_FEATURE_LOCALE (=0 or =1)
- *
- * Define this to 0 to disable customized locale support, or define
- * to 1 to enable it.
- *
- * This saves a (small) amount of code.
- */
-#if !defined(TRIO_FEATURE_LOCALE)
-# define TRIO_FEATURE_LOCALE 1
-#endif
-
-/*
- * TRIO_MINIMAL
- *
- * Define this to disable building the public trionan.h and triostr.h.
- * If you define this, then you must not compile trionan.c and triostr.c
- * separately.
- */
-#if defined(TRIO_MINIMAL)
-# if !defined(TRIO_EMBED_NAN)
-# define TRIO_EMBED_NAN
-# endif
-# if !defined(TRIO_EMBED_STRING)
-# define TRIO_EMBED_STRING
-# endif
-#endif
-
-/* Does not work yet. Do not enable */
-#ifndef TRIO_FEATURE_WIDECHAR
-# define TRIO_FEATURE_WIDECHAR 0
-#endif
-
-/*************************************************************************
- * Mapping standards to internal features
- */
-
-#if !defined(TRIO_FEATURE_HEXFLOAT)
-# define TRIO_FEATURE_HEXFLOAT (TRIO_C99 && TRIO_FEATURE_FLOAT)
-#endif
-
-#if !defined(TRIO_FEATURE_LONGDOUBLE)
-# define TRIO_FEATURE_LONGDOUBLE TRIO_FEATURE_FLOAT
-#endif
-
-#if !defined(TRIO_FEATURE_ERRNO)
-# define TRIO_FEATURE_ERRNO TRIO_GNU
-#endif
-
-#if !defined(TRIO_FEATURE_QUAD)
-# define TRIO_FEATURE_QUAD (TRIO_BSD || TRIO_GNU)
-#endif
-
-#if !defined(TRIO_FEATURE_SIZE_T)
-# define TRIO_FEATURE_SIZE_T TRIO_C99
-#endif
-
-#if !defined(TRIO_FEATURE_SIZE_T_UPPER)
-# define TRIO_FEATURE_SIZE_T_UPPER TRIO_GNU
-#endif
-
-#if !defined(TRIO_FEATURE_PTRDIFF_T)
-# define TRIO_FEATURE_PTRDIFF_T TRIO_C99
-#endif
-
-#if !defined(TRIO_FEATURE_INTMAX_T)
-# define TRIO_FEATURE_INTMAX_T TRIO_C99
-#endif
-
-#if !defined(TRIO_FEATURE_FIXED_SIZE)
-# define TRIO_FEATURE_FIXED_SIZE TRIO_MICROSOFT
-#endif
-
-#if !defined(TRIO_FEATURE_POSITIONAL)
-# define TRIO_FEATURE_POSITIONAL TRIO_UNIX98
-#endif
-
-#if !defined(TRIO_FEATURE_USER_DEFINED)
-# define TRIO_FEATURE_USER_DEFINED TRIO_EXTENSION
-#endif
-
-#if !defined(TRIO_FEATURE_BINARY)
-# define TRIO_FEATURE_BINARY TRIO_EXTENSION
-#endif
-
-#if !defined(TRIO_FEATURE_QUOTE)
-# define TRIO_FEATURE_QUOTE TRIO_EXTENSION
-#endif
-
-#if !defined(TRIO_FEATURE_STICKY)
-# define TRIO_FEATURE_STICKY TRIO_EXTENSION
-#endif
-
-#if !defined(TRIO_FEATURE_VARSIZE)
-# define TRIO_FEATURE_VARSIZE TRIO_EXTENSION
-#endif
-
-#if !defined(TRIO_FEATURE_ROUNDING)
-# define TRIO_FEATURE_ROUNDING TRIO_EXTENSION
-#endif
-
-/*************************************************************************
- * Memory handling
- */
-#ifndef TRIO_MALLOC
-# define TRIO_MALLOC(n) malloc(n)
-#endif
-#ifndef TRIO_REALLOC
-# define TRIO_REALLOC(x,n) realloc((x),(n))
-#endif
-#ifndef TRIO_FREE
-# define TRIO_FREE(x) free(x)
-#endif
-
-
-/*************************************************************************
- * User-defined specifiers
- */
-
-typedef int (*trio_callback_t) TRIO_PROTO((trio_pointer_t));
-
-trio_pointer_t trio_register TRIO_PROTO((trio_callback_t callback, const char *name));
-void trio_unregister TRIO_PROTO((trio_pointer_t handle));
-
-TRIO_CONST char *trio_get_format TRIO_PROTO((trio_pointer_t ref));
-TRIO_CONST trio_pointer_t trio_get_argument TRIO_PROTO((trio_pointer_t ref));
-
-/* Modifiers */
-int trio_get_width TRIO_PROTO((trio_pointer_t ref));
-void trio_set_width TRIO_PROTO((trio_pointer_t ref, int width));
-int trio_get_precision TRIO_PROTO((trio_pointer_t ref));
-void trio_set_precision TRIO_PROTO((trio_pointer_t ref, int precision));
-int trio_get_base TRIO_PROTO((trio_pointer_t ref));
-void trio_set_base TRIO_PROTO((trio_pointer_t ref, int base));
-int trio_get_padding TRIO_PROTO((trio_pointer_t ref));
-void trio_set_padding TRIO_PROTO((trio_pointer_t ref, int is_padding));
-int trio_get_short TRIO_PROTO((trio_pointer_t ref)); /* h */
-void trio_set_shortshort TRIO_PROTO((trio_pointer_t ref, int is_shortshort));
-int trio_get_shortshort TRIO_PROTO((trio_pointer_t ref)); /* hh */
-void trio_set_short TRIO_PROTO((trio_pointer_t ref, int is_short));
-int trio_get_long TRIO_PROTO((trio_pointer_t ref)); /* l */
-void trio_set_long TRIO_PROTO((trio_pointer_t ref, int is_long));
-int trio_get_longlong TRIO_PROTO((trio_pointer_t ref)); /* ll */
-void trio_set_longlong TRIO_PROTO((trio_pointer_t ref, int is_longlong));
-int trio_get_longdouble TRIO_PROTO((trio_pointer_t ref)); /* L */
-void trio_set_longdouble TRIO_PROTO((trio_pointer_t ref, int is_longdouble));
-int trio_get_alternative TRIO_PROTO((trio_pointer_t ref)); /* # */
-void trio_set_alternative TRIO_PROTO((trio_pointer_t ref, int is_alternative));
-int trio_get_alignment TRIO_PROTO((trio_pointer_t ref)); /* - */
-void trio_set_alignment TRIO_PROTO((trio_pointer_t ref, int is_leftaligned));
-int trio_get_spacing TRIO_PROTO((trio_pointer_t ref)); /* (space) */
-void trio_set_spacing TRIO_PROTO((trio_pointer_t ref, int is_space));
-int trio_get_sign TRIO_PROTO((trio_pointer_t ref)); /* + */
-void trio_set_sign TRIO_PROTO((trio_pointer_t ref, int is_showsign));
-#if TRIO_FEATURE_QUOTE
-int trio_get_quote TRIO_PROTO((trio_pointer_t ref)); /* ' */
-void trio_set_quote TRIO_PROTO((trio_pointer_t ref, int is_quote));
-#endif
-int trio_get_upper TRIO_PROTO((trio_pointer_t ref));
-void trio_set_upper TRIO_PROTO((trio_pointer_t ref, int is_upper));
-#if TRIO_FEATURE_INTMAX_T
-int trio_get_largest TRIO_PROTO((trio_pointer_t ref)); /* j */
-void trio_set_largest TRIO_PROTO((trio_pointer_t ref, int is_largest));
-#endif
-#if TRIO_FEATURE_PTRDIFF_T
-int trio_get_ptrdiff TRIO_PROTO((trio_pointer_t ref)); /* t */
-void trio_set_ptrdiff TRIO_PROTO((trio_pointer_t ref, int is_ptrdiff));
-#endif
-#if TRIO_FEATURE_SIZE_T
-int trio_get_size TRIO_PROTO((trio_pointer_t ref)); /* z / Z */
-void trio_set_size TRIO_PROTO((trio_pointer_t ref, int is_size));
-#endif
-
-/* Printing */
-int trio_print_ref TRIO_PROTO((trio_pointer_t ref, const char *format, ...));
-int trio_vprint_ref TRIO_PROTO((trio_pointer_t ref, const char *format, va_list args));
-int trio_printv_ref TRIO_PROTO((trio_pointer_t ref, const char *format, trio_pointer_t *args));
-
-void trio_print_int TRIO_PROTO((trio_pointer_t ref, int number));
-void trio_print_uint TRIO_PROTO((trio_pointer_t ref, unsigned int number));
-/* void trio_print_long TRIO_PROTO((trio_pointer_t ref, long number)); */
-/* void trio_print_ulong TRIO_PROTO((trio_pointer_t ref, unsigned long number)); */
-void trio_print_double TRIO_PROTO((trio_pointer_t ref, double number));
-void trio_print_string TRIO_PROTO((trio_pointer_t ref, TRIO_CONST char *string));
-void trio_print_pointer TRIO_PROTO((trio_pointer_t ref, trio_pointer_t pointer));
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* TRIO_TRIOP_H */
+++ /dev/null
-/*************************************************************************
- *
- * $Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-/*************************************************************************
- * Include files
- */
-
-#if defined(HAVE_CONFIG_H)
-# include <config.h>
-#endif
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include "triodef.h"
-#include "triostr.h"
-#if defined(TRIO_FUNC_TO_LONG_DOUBLE)
-# define USE_MATH
-#endif
-#if defined(USE_MATH)
-# include <math.h>
-#endif
-
-/*************************************************************************
- * Definitions
- */
-
-#if !defined(TRIO_PUBLIC_STRING)
-# define TRIO_PUBLIC_STRING TRIO_PUBLIC
-#endif
-#if !defined(TRIO_PRIVATE_STRING)
-# define TRIO_PRIVATE_STRING TRIO_PRIVATE
-#endif
-
-#if !defined(NULL)
-# define NULL 0
-#endif
-#if !defined(NIL)
-# define NIL ((char)0)
-#endif
-#if !defined(FALSE)
-# define FALSE (1 == 0)
-# define TRUE (! FALSE)
-#endif
-#if !defined(BOOLEAN_T)
-# define BOOLEAN_T int
-#endif
-
-#if defined(USE_MATH)
-# if defined(PREDEF_STANDARD_C99)
-# if defined(TRIO_COMPILER_DECC)
-# if (TRIO_COMPILER_DECC - 0 > 80000000)
-/*
- * The OSF/1 runtime that comes with the DECC compiler does not support
- * hexfloats conversion.
- */
-# define USE_STRTOD
-# define USE_STRTOF
-# endif
-# else
-# define USE_STRTOD
-# define USE_STRTOF
-# endif
-# else
-# if defined(TRIO_COMPILER_VISUALC)
-# define USE_STRTOD
-# endif
-#endif
-#endif
-
-#if defined(TRIO_PLATFORM_UNIX)
-# if defined(PREDEF_STANDARD_UNIX95)
-# define USE_STRCASECMP
-# define USE_STRNCASECMP
-# endif
-# if defined(TRIO_PLATFORM_SUNOS)
-# define USE_SYS_ERRLIST
-# else
-# define USE_STRERROR
-# endif
-# if defined(TRIO_PLATFORM_QNX)
-# define strcasecmp(x,y) stricmp(x,y)
-# define strncasecmp(x,y,n) strnicmp(x,y,n)
-# endif
-#endif
-
-#if defined(TRIO_PLATFORM_WIN32)
-# define USE_STRCASECMP
-# if defined(TRIO_PLATFORM_WINCE)
-# define strcasecmp(x,y) _stricmp(x,y)
-# else
-# define strcasecmp(x,y) strcmpi(x,y)
-# endif
-#endif
-
-#if !defined(HAVE_CONFIG_H)
-# if !(defined(TRIO_PLATFORM_SUNOS))
-# define HAVE_TOLOWER
-# define HAVE_TOUPPER
-# endif
-#endif
-
-#if defined(USE_MATH) && !defined(TRIO_NO_POWL)
-# if !defined(HAVE_POWL)
-# if defined(PREDEF_STANDARD_C99) \
- || defined(PREDEF_STANDARD_UNIX03)
-# define HAVE_POWL
-# else
-# if defined(TRIO_COMPILER_VISUALC)
-# if defined(powl)
-# define HAVE_POWL
-# endif
-# endif
-# endif
-# endif
-#endif
-
-#if defined(HAVE_POWL)
-# define trio_powl(x,y) powl((x),(y))
-#else
-# define trio_powl(x,y) pow((double)(x),(double)(y))
-#endif
-
-#if defined(TRIO_FUNC_TO_UPPER) \
- || (defined(TRIO_FUNC_EQUAL) && !defined(USE_STRCASECMP)) \
- || (defined(TRIO_FUNC_EQUAL_MAX) && !defined(USE_STRNCASECMP)) \
- || defined(TRIO_FUNC_MATCH) \
- || defined(TRIO_FUNC_TO_LONG_DOUBLE) \
- || defined(TRIO_FUNC_UPPER)
-# define TRIO_FUNC_INTERNAL_TO_UPPER
-#endif
-
-/*************************************************************************
- * Structures
- */
-
-struct _trio_string_t
-{
- char *content;
- size_t length;
- size_t allocated;
-};
-
-/*************************************************************************
- * Constants
- */
-
-#if !defined(TRIO_EMBED_STRING)
-static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $";
-#endif
-
-/*************************************************************************
- * Static String Functions
- */
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_static.h"
-#endif
-/** @addtogroup StaticStrings
- @{
-*/
-
-/*
- * internal_duplicate_max
- */
-#if defined(TRIO_FUNC_DUPLICATE) \
- || defined(TRIO_FUNC_DUPLICATE_MAX) \
- || defined(TRIO_FUNC_STRING_DUPLICATE) \
- || defined(TRIO_FUNC_XSTRING_DUPLICATE)
-
-TRIO_PRIVATE_STRING char *
-internal_duplicate_max
-TRIO_ARGS2((source, size),
- TRIO_CONST char *source,
- size_t size)
-{
- char *target;
-
- assert(source);
-
- /* Make room for string plus a terminating zero */
- size++;
- target = trio_create(size);
- if (target)
- {
- trio_copy_max(target, size, source);
- }
- return target;
-}
-
-#endif
-
-/*
- * internal_string_alloc
- */
-#if defined(TRIO_FUNC_STRING_CREATE) \
- || defined(TRIO_FUNC_STRING_DUPLICATE) \
- || defined(TRIO_FUNC_XSTRING_DUPLICATE)
-
-TRIO_PRIVATE_STRING trio_string_t *
-internal_string_alloc(TRIO_NOARGS)
-{
- trio_string_t *self;
-
- self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
- if (self)
- {
- self->content = NULL;
- self->length = 0;
- self->allocated = 0;
- }
- return self;
-}
-
-#endif
-
-/*
- * internal_string_grow
- *
- * The size of the string will be increased by 'delta' characters. If
- * 'delta' is zero, the size will be doubled.
- */
-#if defined(TRIO_FUNC_STRING_CREATE) \
- || defined(TRIO_FUNC_STRING_APPEND) \
- || defined(TRIO_FUNC_XSTRING_APPEND) \
- || defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
-
-TRIO_PRIVATE_STRING BOOLEAN_T
-internal_string_grow
-TRIO_ARGS2((self, delta),
- trio_string_t *self,
- size_t delta)
-{
- BOOLEAN_T status = FALSE;
- char *new_content;
- size_t new_size;
-
- new_size = (delta == 0)
- ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
- : self->allocated + delta;
-
- new_content = (char *)TRIO_REALLOC(self->content, new_size);
- if (new_content)
- {
- self->content = new_content;
- self->allocated = new_size;
- status = TRUE;
- }
- return status;
-}
-
-#endif
-
-/*
- * internal_string_grow_to
- *
- * The size of the string will be increased to 'length' plus one characters.
- * If 'length' is less than the original size, the original size will be
- * used (that is, the size of the string is never decreased).
- */
-#if defined(TRIO_FUNC_STRING_APPEND) \
- || defined(TRIO_FUNC_XSTRING_APPEND) \
- || defined(TRIO_FUNC_XSTRING_APPEND_MAX)
-
-TRIO_PRIVATE_STRING BOOLEAN_T
-internal_string_grow_to
-TRIO_ARGS2((self, length),
- trio_string_t *self,
- size_t length)
-{
- length++; /* Room for terminating zero */
- return (self->allocated < length)
- ? internal_string_grow(self, length - self->allocated)
- : TRUE;
-}
-
-#endif
-
-#if defined(TRIO_FUNC_INTERNAL_TO_UPPER)
-
-TRIO_PRIVATE_STRING TRIO_INLINE int
-internal_to_upper
-TRIO_ARGS1((source),
- int source)
-{
-# if defined(HAVE_TOUPPER)
-
- return toupper(source);
-
-# else
-
- /* Does not handle locales or non-contiguous alphabetic characters */
- return ((source >= (int)'a') && (source <= (int)'z'))
- ? source - 'a' + 'A'
- : source;
-
-# endif
-}
-
-#endif
-
-
-/**
- Create new string.
-
- @param size Size of new string.
- @return Pointer to string, or NULL if allocation failed.
-*/
-#if defined(TRIO_FUNC_CREATE)
-
-TRIO_PUBLIC_STRING char *
-trio_create
-TRIO_ARGS1((size),
- size_t size)
-{
- return (char *)TRIO_MALLOC(size);
-}
-
-#endif
-
-/**
- Destroy string.
-
- @param string String to be freed.
-*/
-#if defined(TRIO_FUNC_DESTROY)
-
-TRIO_PUBLIC_STRING void
-trio_destroy
-TRIO_ARGS1((string),
- char *string)
-{
- if (string)
- {
- TRIO_FREE(string);
- }
-}
-
-#endif
-
-/**
- Count the number of characters in a string.
-
- @param string String to measure.
- @return Number of characters in @p string.
-*/
-#if defined(TRIO_FUNC_LENGTH)
-
-TRIO_PUBLIC_STRING size_t
-trio_length
-TRIO_ARGS1((string),
- TRIO_CONST char *string)
-{
- return strlen(string);
-}
-
-#endif
-
-/**
- Count at most @p max characters in a string.
-
- @param string String to measure.
- @param max Maximum number of characters to count.
- @return The maximum value of @p max and number of characters in @p string.
-*/
-#if defined(TRIO_FUNC_LENGTH_MAX)
-
-TRIO_PUBLIC_STRING size_t
-trio_length_max
-TRIO_ARGS2((string, max),
- TRIO_CONST char *string,
- size_t max)
-{
- size_t i;
-
- for (i = 0; i < max; ++i)
- {
- if (string[i] == 0)
- break;
- }
- return i;
-}
-
-#endif
-
-/**
- Append @p source at the end of @p target.
-
- @param target Target string.
- @param source Source string.
- @return Boolean value indicating success or failure.
-
- @pre @p target must point to a memory chunk with sufficient room to
- contain the @p target string and @p source string.
- @pre No boundary checking is performed, so insufficient memory will
- result in a buffer overrun.
- @post @p target will be zero terminated.
-*/
-#if defined(TRIO_FUNC_APPEND)
-
-TRIO_PUBLIC_STRING int
-trio_append
-TRIO_ARGS2((target, source),
- char *target,
- TRIO_CONST char *source)
-{
- assert(target);
- assert(source);
-
- return (strcat(target, source) != NULL);
-}
-
-#endif
-
-/**
- Append at most @p max characters from @p source to @p target.
-
- @param target Target string.
- @param max Maximum number of characters to append.
- @param source Source string.
- @return Boolean value indicating success or failure.
-
- @pre @p target must point to a memory chuck with sufficient room to
- contain the @p target string and the @p source string (at most @p max
- characters).
- @pre No boundary checking is performed, so insufficient memory will
- result in a buffer overrun.
- @post @p target will be zero terminated.
-*/
-#if defined(TRIO_FUNC_APPEND_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_append_max
-TRIO_ARGS3((target, max, source),
- char *target,
- size_t max,
- TRIO_CONST char *source)
-{
- size_t length;
-
- assert(target);
- assert(source);
-
- length = trio_length(target);
-
- if (max > length)
- {
- strncat(target, source, max - length - 1);
- }
- return TRUE;
-}
-
-#endif
-
-/**
- Determine if a string contains a substring.
-
- @param string String to be searched.
- @param substring String to be found.
- @return Boolean value indicating success or failure.
-*/
-#if defined(TRIO_FUNC_CONTAINS)
-
-TRIO_PUBLIC_STRING int
-trio_contains
-TRIO_ARGS2((string, substring),
- TRIO_CONST char *string,
- TRIO_CONST char *substring)
-{
- assert(string);
- assert(substring);
-
- return (0 != strstr(string, substring));
-}
-
-#endif
-
-/**
- Copy @p source to @p target.
-
- @param target Target string.
- @param source Source string.
- @return Boolean value indicating success or failure.
-
- @pre @p target must point to a memory chunk with sufficient room to
- contain the @p source string.
- @pre No boundary checking is performed, so insufficient memory will
- result in a buffer overrun.
- @post @p target will be zero terminated.
-*/
-#if defined(TRIO_FUNC_COPY)
-
-TRIO_PUBLIC_STRING int
-trio_copy
-TRIO_ARGS2((target, source),
- char *target,
- TRIO_CONST char *source)
-{
- assert(target);
- assert(source);
-
- (void)strcpy(target, source);
- return TRUE;
-}
-
-#endif
-
-/**
- Copy at most @p max - 1 characters from @p source to @p target.
-
- @param target Target string.
- @param max Maximum number of characters to append (one of which is
- a NUL terminator). In other words @p source must point to at least
- @p max - 1 bytes, but @p target must point to at least @p max
- bytes.
- @param source Source string.
- @return Boolean value indicating success or failure.
-
- @pre @p target must point to a memory chunk with sufficient room to
- contain the @p source string and a NUL terminator (at most @p max
- bytes total).
- @pre No boundary checking is performed, so insufficient memory will
- result in a buffer overrun.
- @post @p target will be zero terminated.
-*/
-#if defined(TRIO_FUNC_COPY_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_copy_max
-TRIO_ARGS3((target, max, source),
- char *target,
- size_t max,
- TRIO_CONST char *source)
-{
- assert(target);
- assert(source);
- assert(max > 0); /* Includes != 0 */
-
- (void)strncpy(target, source, max - 1);
- target[max - 1] = (char)0;
- return TRUE;
-}
-
-#endif
-
-/**
- Duplicate @p source.
-
- @param source Source string.
- @return A copy of the @p source string.
-
- @post @p target will be zero terminated.
-*/
-#if defined(TRIO_FUNC_DUPLICATE)
-
-TRIO_PUBLIC_STRING char *
-trio_duplicate
-TRIO_ARGS1((source),
- TRIO_CONST char *source)
-{
- return internal_duplicate_max(source, trio_length(source));
-}
-
-#endif
-
-/**
- Duplicate at most @p max characters of @p source.
-
- @param source Source string.
- @param max Maximum number of characters to duplicate.
- @return A copy of the @p source string.
-
- @post @p target will be zero terminated.
-*/
-#if defined(TRIO_FUNC_DUPLICATE_MAX)
-
-TRIO_PUBLIC_STRING char *
-trio_duplicate_max
-TRIO_ARGS2((source, max),
- TRIO_CONST char *source,
- size_t max)
-{
- size_t length;
-
- assert(source);
- assert(max > 0);
-
- length = trio_length(source);
- if (length > max)
- {
- length = max;
- }
- return internal_duplicate_max(source, length);
-}
-
-#endif
-
-/**
- Compare if two strings are equal.
-
- @param first First string.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Case-insensitive comparison.
-*/
-#if defined(TRIO_FUNC_EQUAL)
-
-TRIO_PUBLIC_STRING int
-trio_equal
-TRIO_ARGS2((first, second),
- TRIO_CONST char *first,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
- if ((first != NULL) && (second != NULL))
- {
-# if defined(USE_STRCASECMP)
- return (0 == strcasecmp(first, second));
-# else
- while ((*first != NIL) && (*second != NIL))
- {
- if (internal_to_upper(*first) != internal_to_upper(*second))
- {
- break;
- }
- first++;
- second++;
- }
- return ((*first == NIL) && (*second == NIL));
-# endif
- }
- return FALSE;
-}
-
-#endif
-
-/**
- Compare if two strings are equal.
-
- @param first First string.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Case-sensitive comparison.
-*/
-#if defined(TRIO_FUNC_EQUAL_CASE)
-
-TRIO_PUBLIC_STRING int
-trio_equal_case
-TRIO_ARGS2((first, second),
- TRIO_CONST char *first,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
- if ((first != NULL) && (second != NULL))
- {
- return (0 == strcmp(first, second));
- }
- return FALSE;
-}
-
-#endif
-
-/**
- Compare if two strings up until the first @p max characters are equal.
-
- @param first First string.
- @param max Maximum number of characters to compare.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Case-sensitive comparison.
-*/
-#if defined(TRIO_FUNC_EQUAL_CASE_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_equal_case_max
-TRIO_ARGS3((first, max, second),
- TRIO_CONST char *first,
- size_t max,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
- if ((first != NULL) && (second != NULL))
- {
- return (0 == strncmp(first, second, max));
- }
- return FALSE;
-}
-
-#endif
-
-/**
- Compare if two strings are equal.
-
- @param first First string.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Collating characters are considered equal.
-*/
-#if defined(TRIO_FUNC_EQUAL_LOCALE)
-
-TRIO_PUBLIC_STRING int
-trio_equal_locale
-TRIO_ARGS2((first, second),
- TRIO_CONST char *first,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
-# if defined(LC_COLLATE)
- return (strcoll(first, second) == 0);
-# else
- return trio_equal(first, second);
-# endif
-}
-
-#endif
-
-/**
- Compare if two strings up until the first @p max characters are equal.
-
- @param first First string.
- @param max Maximum number of characters to compare.
- @param second Second string.
- @return Boolean indicating whether the two strings are equal or not.
-
- Case-insensitive comparison.
-*/
-#if defined(TRIO_FUNC_EQUAL_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_equal_max
-TRIO_ARGS3((first, max, second),
- TRIO_CONST char *first,
- size_t max,
- TRIO_CONST char *second)
-{
- assert(first);
- assert(second);
-
- if ((first != NULL) && (second != NULL))
- {
-# if defined(USE_STRNCASECMP)
- return (0 == strncasecmp(first, second, max));
-# else
- /* Not adequately tested yet */
- size_t cnt = 0;
- while ((*first != NIL) && (*second != NIL) && (cnt <= max))
- {
- if (internal_to_upper(*first) != internal_to_upper(*second))
- {
- break;
- }
- first++;
- second++;
- cnt++;
- }
- return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
-# endif
- }
- return FALSE;
-}
-
-#endif
-
-/**
- Provide a textual description of an error code (errno).
-
- @param error_number Error number.
- @return Textual description of @p error_number.
-*/
-#if defined(TRIO_FUNC_ERROR)
-
-TRIO_PUBLIC_STRING TRIO_CONST char *
-trio_error
-TRIO_ARGS1((error_number),
- int error_number)
-{
-# if defined(USE_STRERROR)
-
- return strerror(error_number);
-
-# else
-# if defined(USE_SYS_ERRLIST)
-
- extern char *sys_errlist[];
- extern int sys_nerr;
-
- return ((error_number < 0) || (error_number >= sys_nerr))
- ? "unknown"
- : sys_errlist[error_number];
-
-# else
-
- return "unknown";
-
-# endif
-# endif
-}
-
-#endif
-
-/**
- Format the date/time according to @p format.
-
- @param target Target string.
- @param max Maximum number of characters to format.
- @param format Formatting string.
- @param datetime Date/time structure.
- @return Number of formatted characters.
-
- The formatting string accepts the same specifiers as the standard C
- function strftime.
-*/
-#if defined(TRIO_FUNC_FORMAT_DATE_MAX)
-
-TRIO_PUBLIC_STRING size_t
-trio_format_date_max
-TRIO_ARGS4((target, max, format, datetime),
- char *target,
- size_t max,
- TRIO_CONST char *format,
- TRIO_CONST struct tm *datetime)
-{
- assert(target);
- assert(format);
- assert(datetime);
- assert(max > 0);
-
- return strftime(target, max, format, datetime);
-}
-
-#endif
-
-/**
- Calculate a hash value for a string.
-
- @param string String to be calculated on.
- @param type Hash function.
- @return Calculated hash value.
-
- @p type can be one of the following
- @li @c TRIO_HASH_PLAIN Plain hash function.
-*/
-#if defined(TRIO_FUNC_HASH)
-
-TRIO_PUBLIC_STRING unsigned long
-trio_hash
-TRIO_ARGS2((string, type),
- TRIO_CONST char *string,
- int type)
-{
- unsigned long value = 0L;
- char ch;
-
- assert(string);
-
- switch (type)
- {
- case TRIO_HASH_PLAIN:
- while ( (ch = *string++) != NIL )
- {
- value *= 31;
- value += (unsigned long)ch;
- }
- break;
- default:
- assert(FALSE);
- break;
- }
- return value;
-}
-
-#endif
-
-/**
- Find first occurrence of a character in a string.
-
- @param string String to be searched.
- @param character Character to be found.
- @return A pointer to the found character, or NULL if character was not found.
- */
-#if defined(TRIO_FUNC_INDEX)
-
-TRIO_PUBLIC_STRING char *
-trio_index
-TRIO_ARGS2((string, character),
- TRIO_CONST char *string,
- int character)
-{
- assert(string);
-
- return strchr(string, character);
-}
-
-#endif
-
-/**
- Find last occurrence of a character in a string.
-
- @param string String to be searched.
- @param character Character to be found.
- @return A pointer to the found character, or NULL if character was not found.
- */
-#if defined(TRIO_FUNC_INDEX_LAST)
-
-TRIO_PUBLIC_STRING char *
-trio_index_last
-TRIO_ARGS2((string, character),
- TRIO_CONST char *string,
- int character)
-{
- assert(string);
-
- return strchr(string, character);
-}
-
-#endif
-
-/**
- Convert the alphabetic letters in the string to lower-case.
-
- @param target String to be converted.
- @return Number of processed characters (converted or not).
-*/
-#if defined(TRIO_FUNC_LOWER)
-
-TRIO_PUBLIC_STRING int
-trio_lower
-TRIO_ARGS1((target),
- char *target)
-{
- assert(target);
-
- return trio_span_function(target, target, trio_to_lower);
-}
-
-#endif
-
-/**
- Compare two strings using wildcards.
-
- @param string String to be searched.
- @param pattern Pattern, including wildcards, to search for.
- @return Boolean value indicating success or failure.
-
- Case-insensitive comparison.
-
- The following wildcards can be used
- @li @c * Match any number of characters.
- @li @c ? Match a single character.
-*/
-#if defined(TRIO_FUNC_MATCH)
-
-TRIO_PUBLIC_STRING int
-trio_match
-TRIO_ARGS2((string, pattern),
- TRIO_CONST char *string,
- TRIO_CONST char *pattern)
-{
- assert(string);
- assert(pattern);
-
- for (; ('*' != *pattern); ++pattern, ++string)
- {
- if (NIL == *string)
- {
- return (NIL == *pattern);
- }
- if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern))
- && ('?' != *pattern))
- {
- return FALSE;
- }
- }
- /* two-line patch to prevent *too* much recursiveness: */
- while ('*' == pattern[1])
- pattern++;
-
- do
- {
- if ( trio_match(string, &pattern[1]) )
- {
- return TRUE;
- }
- }
- while (*string++);
-
- return FALSE;
-}
-
-#endif
-
-/**
- Compare two strings using wildcards.
-
- @param string String to be searched.
- @param pattern Pattern, including wildcards, to search for.
- @return Boolean value indicating success or failure.
-
- Case-sensitive comparison.
-
- The following wildcards can be used
- @li @c * Match any number of characters.
- @li @c ? Match a single character.
-*/
-#if defined(TRIO_FUNC_MATCH_CASE)
-
-TRIO_PUBLIC_STRING int
-trio_match_case
-TRIO_ARGS2((string, pattern),
- TRIO_CONST char *string,
- TRIO_CONST char *pattern)
-{
- assert(string);
- assert(pattern);
-
- for (; ('*' != *pattern); ++pattern, ++string)
- {
- if (NIL == *string)
- {
- return (NIL == *pattern);
- }
- if ((*string != *pattern)
- && ('?' != *pattern))
- {
- return FALSE;
- }
- }
- /* two-line patch to prevent *too* much recursiveness: */
- while ('*' == pattern[1])
- pattern++;
-
- do
- {
- if ( trio_match_case(string, &pattern[1]) )
- {
- return TRUE;
- }
- }
- while (*string++);
-
- return FALSE;
-}
-
-#endif
-
-/**
- Execute a function on each character in string.
-
- @param target Target string.
- @param source Source string.
- @param Function Function to be executed.
- @return Number of processed characters.
-*/
-#if defined(TRIO_FUNC_SPAN_FUNCTION)
-
-TRIO_PUBLIC_STRING size_t
-trio_span_function
-TRIO_ARGS3((target, source, Function),
- char *target,
- TRIO_CONST char *source,
- int (*Function) TRIO_PROTO((int)))
-{
- size_t count = 0;
-
- assert(target);
- assert(source);
- assert(Function);
-
- while (*source != NIL)
- {
- *target++ = Function(*source++);
- count++;
- }
- return count;
-}
-
-#endif
-
-/**
- Search for a substring in a string.
-
- @param string String to be searched.
- @param substring String to be found.
- @return Pointer to first occurrence of @p substring in @p string, or NULL
- if no match was found.
-*/
-#if defined(TRIO_FUNC_SUBSTRING)
-
-TRIO_PUBLIC_STRING char *
-trio_substring
-TRIO_ARGS2((string, substring),
- TRIO_CONST char *string,
- TRIO_CONST char *substring)
-{
- assert(string);
- assert(substring);
-
- return strstr(string, substring);
-}
-
-#endif
-
-/**
- Search for a substring in the first @p max characters of a string.
-
- @param string String to be searched.
- @param max Maximum characters to be searched.
- @param substring String to be found.
- @return Pointer to first occurrence of @p substring in @p string, or NULL
- if no match was found.
-*/
-#if defined(TRIO_FUNC_SUBSTRING_MAX)
-
-TRIO_PUBLIC_STRING char *
-trio_substring_max
-TRIO_ARGS3((string, max, substring),
- TRIO_CONST char *string,
- size_t max,
- TRIO_CONST char *substring)
-{
- size_t count;
- size_t size;
- char *result = NULL;
-
- assert(string);
- assert(substring);
-
- size = trio_length(substring);
- if (size <= max)
- {
- for (count = 0; count <= max - size; count++)
- {
- if (trio_equal_max(substring, size, &string[count]))
- {
- result = (char *)&string[count];
- break;
- }
- }
- }
- return result;
-}
-
-#endif
-
-/**
- Tokenize string.
-
- @param string String to be tokenized.
- @param delimiters String containing list of delimiting characters.
- @return Start of new token.
-
- @warning @p string will be destroyed.
-*/
-#if defined(TRIO_FUNC_TOKENIZE)
-
-TRIO_PUBLIC_STRING char *
-trio_tokenize
-TRIO_ARGS2((string, delimiters),
- char *string,
- TRIO_CONST char *delimiters)
-{
- assert(delimiters);
-
- return strtok(string, delimiters);
-}
-
-#endif
-
-/**
- Convert string to floating-point number.
-
- @param source String to be converted.
- @param endp Pointer to end of the converted string.
- @return A floating-point number.
-
- The following Extended Backus-Naur form is used
- @verbatim
- double ::= [ <sign> ]
- ( <number> |
- <number> <decimal_point> <number> |
- <decimal_point> <number> )
- [ <exponential> [ <sign> ] <number> ]
- number ::= 1*( <digit> )
- digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
- exponential ::= ( 'e' | 'E' )
- sign ::= ( '-' | '+' )
- decimal_point ::= '.'
- @endverbatim
-*/
-#if defined(TRIO_FUNC_TO_LONG_DOUBLE)
-
-/* FIXME: Add EBNF for hex-floats */
-TRIO_PUBLIC_STRING trio_long_double_t
-trio_to_long_double
-TRIO_ARGS2((source, endp),
- TRIO_CONST char *source,
- char **endp)
-{
-# if defined(USE_STRTOLD)
- return strtold(source, endp);
-# else
- int isNegative = FALSE;
- int isExponentNegative = FALSE;
- trio_long_double_t integer = 0.0;
- trio_long_double_t fraction = 0.0;
- unsigned long exponent = 0;
- trio_long_double_t base;
- trio_long_double_t fracdiv = 1.0;
- trio_long_double_t value = 0.0;
-
- /* First try hex-floats */
- if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
- {
- base = 16.0;
- source += 2;
- while (isxdigit((int)*source))
- {
- integer *= base;
- integer += (isdigit((int)*source)
- ? (*source - '0')
- : 10 + (internal_to_upper((int)*source) - 'A'));
- source++;
- }
- if (*source == '.')
- {
- source++;
- while (isxdigit((int)*source))
- {
- fracdiv /= base;
- fraction += fracdiv * (isdigit((int)*source)
- ? (*source - '0')
- : 10 + (internal_to_upper((int)*source) - 'A'));
- source++;
- }
- if ((*source == 'p') || (*source == 'P'))
- {
- source++;
- if ((*source == '+') || (*source == '-'))
- {
- isExponentNegative = (*source == '-');
- source++;
- }
- while (isdigit((int)*source))
- {
- exponent *= 10;
- exponent += (*source - '0');
- source++;
- }
- }
- }
- /* For later use with exponent */
- base = 2.0;
- }
- else /* Then try normal decimal floats */
- {
- base = 10.0;
- isNegative = (*source == '-');
- /* Skip sign */
- if ((*source == '+') || (*source == '-'))
- source++;
-
- /* Integer part */
- while (isdigit((int)*source))
- {
- integer *= base;
- integer += (*source - '0');
- source++;
- }
-
- if (*source == '.')
- {
- source++; /* skip decimal point */
- while (isdigit((int)*source))
- {
- fracdiv /= base;
- fraction += (*source - '0') * fracdiv;
- source++;
- }
- }
- if ((*source == 'e')
- || (*source == 'E')
-# if TRIO_MICROSOFT
- || (*source == 'd')
- || (*source == 'D')
-# endif
- )
- {
- source++; /* Skip exponential indicator */
- isExponentNegative = (*source == '-');
- if ((*source == '+') || (*source == '-'))
- source++;
- while (isdigit((int)*source))
- {
- exponent *= (int)base;
- exponent += (*source - '0');
- source++;
- }
- }
- }
-
- value = integer + fraction;
- if (exponent != 0)
- {
- if (isExponentNegative)
- value /= trio_powl(base, (trio_long_double_t)exponent);
- else
- value *= trio_powl(base, (trio_long_double_t)exponent);
- }
- if (isNegative)
- value = -value;
-
- if (endp)
- *endp = (char *)source;
- return value;
-# endif
-}
-
-#endif
-
-/**
- Convert string to floating-point number.
-
- @param source String to be converted.
- @param endp Pointer to end of the converted string.
- @return A floating-point number.
-
- See @ref trio_to_long_double.
-*/
-#if defined(TRIO_FUNC_TO_DOUBLE)
-
-TRIO_PUBLIC_STRING double
-trio_to_double
-TRIO_ARGS2((source, endp),
- TRIO_CONST char *source,
- char **endp)
-{
-#if defined(USE_STRTOD)
- return strtod(source, endp);
-#else
- return (double)trio_to_long_double(source, endp);
-#endif
-}
-
-#endif
-
-/**
- Convert string to floating-point number.
-
- @param source String to be converted.
- @param endp Pointer to end of the converted string.
- @return A floating-point number.
-
- See @ref trio_to_long_double.
-*/
-#if defined(TRIO_FUNC_TO_FLOAT)
-
-TRIO_PUBLIC_STRING float
-trio_to_float
-TRIO_ARGS2((source, endp),
- TRIO_CONST char *source,
- char **endp)
-{
-# if defined(USE_STRTOF)
- return strtof(source, endp);
-# else
- return (float)trio_to_long_double(source, endp);
-# endif
-}
-
-#endif
-
-/**
- Convert string to signed integer.
-
- @param string String to be converted.
- @param endp Pointer to end of converted string.
- @param base Radix number of number.
-*/
-#if defined(TRIO_FUNC_TO_LONG)
-
-TRIO_PUBLIC_STRING long
-trio_to_long
-TRIO_ARGS3((string, endp, base),
- TRIO_CONST char *string,
- char **endp,
- int base)
-{
- assert(string);
- assert((base >= 2) && (base <= 36));
-
- return strtol(string, endp, base);
-}
-
-#endif
-
-/**
- Convert one alphabetic letter to lower-case.
-
- @param source The letter to be converted.
- @return The converted letter.
-*/
-#if defined(TRIO_FUNC_TO_LOWER)
-
-TRIO_PUBLIC_STRING int
-trio_to_lower
-TRIO_ARGS1((source),
- int source)
-{
-# if defined(HAVE_TOLOWER)
-
- return tolower(source);
-
-# else
-
- /* Does not handle locales or non-contiguous alphabetic characters */
- return ((source >= (int)'A') && (source <= (int)'Z'))
- ? source - 'A' + 'a'
- : source;
-
-# endif
-}
-
-#endif
-
-/**
- Convert string to unsigned integer.
-
- @param string String to be converted.
- @param endp Pointer to end of converted string.
- @param base Radix number of number.
-*/
-#if defined(TRIO_FUNC_TO_UNSIGNED_LONG)
-
-TRIO_PUBLIC_STRING unsigned long
-trio_to_unsigned_long
-TRIO_ARGS3((string, endp, base),
- TRIO_CONST char *string,
- char **endp,
- int base)
-{
- assert(string);
- assert((base >= 2) && (base <= 36));
-
- return strtoul(string, endp, base);
-}
-
-#endif
-
-/**
- Convert one alphabetic letter to upper-case.
-
- @param source The letter to be converted.
- @return The converted letter.
-*/
-#if defined(TRIO_FUNC_TO_UPPER)
-
-TRIO_PUBLIC_STRING int
-trio_to_upper
-TRIO_ARGS1((source),
- int source)
-{
- return internal_to_upper(source);
-}
-
-#endif
-
-/**
- Convert the alphabetic letters in the string to upper-case.
-
- @param target The string to be converted.
- @return The number of processed characters (converted or not).
-*/
-#if defined(TRIO_FUNC_UPPER)
-
-TRIO_PUBLIC_STRING int
-trio_upper
-TRIO_ARGS1((target),
- char *target)
-{
- assert(target);
-
- return trio_span_function(target, target, internal_to_upper);
-}
-
-#endif
-
-/** @} End of StaticStrings */
-
-
-/*************************************************************************
- * Dynamic String Functions
- */
-
-#if defined(TRIO_DOCUMENTATION)
-# include "doc/doc_dynamic.h"
-#endif
-/** @addtogroup DynamicStrings
- @{
-*/
-
-/**
- Create a new dynamic string.
-
- @param initial_size Initial size of the buffer.
- @return Newly allocated dynamic string, or NULL if memory allocation failed.
-*/
-#if defined(TRIO_FUNC_STRING_CREATE)
-
-TRIO_PUBLIC_STRING trio_string_t *
-trio_string_create
-TRIO_ARGS1((initial_size),
- int initial_size)
-{
- trio_string_t *self;
-
- self = internal_string_alloc();
- if (self)
- {
- if (internal_string_grow(self,
- (size_t)((initial_size > 0) ? initial_size : 1)))
- {
- self->content[0] = (char)0;
- self->allocated = initial_size;
- }
- else
- {
- trio_string_destroy(self);
- self = NULL;
- }
- }
- return self;
-}
-
-#endif
-
-/**
- Deallocate the dynamic string and its contents.
-
- @param self Dynamic string
-*/
-#if defined(TRIO_FUNC_STRING_DESTROY)
-
-TRIO_PUBLIC_STRING void
-trio_string_destroy
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- if (self)
- {
- trio_destroy(self->content);
- TRIO_FREE(self);
- }
-}
-
-#endif
-
-/**
- Get a pointer to the content.
-
- @param self Dynamic string.
- @param offset Offset into content.
- @return Pointer to the content.
-
- @p Offset can be zero, positive, or negative. If @p offset is zero,
- then the start of the content will be returned. If @p offset is positive,
- then a pointer to @p offset number of characters from the beginning of the
- content is returned. If @p offset is negative, then a pointer to @p offset
- number of characters from the ending of the string, starting at the
- terminating zero, is returned.
-*/
-#if defined(TRIO_FUNC_STRING_GET)
-
-TRIO_PUBLIC_STRING char *
-trio_string_get
-TRIO_ARGS2((self, offset),
- trio_string_t *self,
- int offset)
-{
- char *result = NULL;
-
- assert(self);
-
- if (self->content != NULL)
- {
- if (self->length == 0)
- {
- (void)trio_string_length(self);
- }
- if (offset >= 0)
- {
- if (offset > (int)self->length)
- {
- offset = self->length;
- }
- }
- else
- {
- offset += self->length + 1;
- if (offset < 0)
- {
- offset = 0;
- }
- }
- result = &(self->content[offset]);
- }
- return result;
-}
-
-#endif
-
-/**
- Extract the content.
-
- @param self Dynamic String
- @return Content of dynamic string.
-
- The content is removed from the dynamic string. This enables destruction
- of the dynamic string without deallocation of the content.
-*/
-#if defined(TRIO_FUNC_STRING_EXTRACT)
-
-TRIO_PUBLIC_STRING char *
-trio_string_extract
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- char *result;
-
- assert(self);
-
- result = self->content;
- /* FIXME: Allocate new empty buffer? */
- self->content = NULL;
- self->length = self->allocated = 0;
- return result;
-}
-
-#endif
-
-/**
- Set the content of the dynamic string.
-
- @param self Dynamic String
- @param buffer The new content.
-
- Sets the content of the dynamic string to a copy @p buffer.
- An existing content will be deallocated first, if necessary.
-
- @remark
- This function will make a copy of @p buffer.
- You are responsible for deallocating @p buffer yourself.
-*/
-#if defined(TRIO_FUNC_XSTRING_SET)
-
-TRIO_PUBLIC_STRING void
-trio_xstring_set
-TRIO_ARGS2((self, buffer),
- trio_string_t *self,
- char *buffer)
-{
- assert(self);
-
- trio_destroy(self->content);
- self->content = trio_duplicate(buffer);
-}
-
-#endif
-
-/*
- * trio_string_size
- */
-#if defined(TRIO_FUNC_STRING_SIZE)
-
-TRIO_PUBLIC_STRING int
-trio_string_size
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- return self->allocated;
-}
-
-#endif
-
-/*
- * trio_string_terminate
- */
-#if defined(TRIO_FUNC_STRING_TERMINATE)
-
-TRIO_PUBLIC_STRING void
-trio_string_terminate
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- trio_xstring_append_char(self, 0);
-}
-
-#endif
-
-/**
- Append the second string to the first.
-
- @param self Dynamic string to be modified.
- @param other Dynamic string to copy from.
- @return Boolean value indicating success or failure.
-*/
-#if defined(TRIO_FUNC_STRING_APPEND)
-
-TRIO_PUBLIC_STRING int
-trio_string_append
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- size_t length;
-
- assert(self);
- assert(other);
-
- length = self->length + other->length;
- if (!internal_string_grow_to(self, length))
- goto error;
- trio_copy(&self->content[self->length], other->content);
- self->length = length;
- return TRUE;
-
- error:
- return FALSE;
-}
-
-#endif
-
-
-/*
- * trio_xstring_append
- */
-#if defined(TRIO_FUNC_XSTRING_APPEND)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_append
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- size_t length;
-
- assert(self);
- assert(other);
-
- length = self->length + trio_length(other);
- if (!internal_string_grow_to(self, length))
- goto error;
- trio_copy(&self->content[self->length], other);
- self->length = length;
- return TRUE;
-
- error:
- return FALSE;
-}
-
-#endif
-
-/*
- * trio_xstring_append_char
- */
-#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_append_char
-TRIO_ARGS2((self, character),
- trio_string_t *self,
- char character)
-{
- assert(self);
-
- if ((int)self->length >= trio_string_size(self))
- {
- if (!internal_string_grow(self, 0))
- goto error;
- }
- self->content[self->length] = character;
- self->length++;
- return TRUE;
-
- error:
- return FALSE;
-}
-
-#endif
-
-/*
- * trio_xstring_append_max
- */
-#if defined(TRIO_FUNC_XSTRING_APPEND_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_append_max
-TRIO_ARGS3((self, other, max),
- trio_string_t *self,
- TRIO_CONST char *other,
- size_t max)
-{
- size_t length;
-
- assert(self);
- assert(other);
-
- length = self->length + trio_length_max(other, max);
- if (!internal_string_grow_to(self, length))
- goto error;
-
- /*
- * Pass max + 1 since trio_copy_max copies one character less than
- * this from the source to make room for a terminating zero.
- */
- trio_copy_max(&self->content[self->length], max + 1, other);
- self->length = length;
- return TRUE;
-
- error:
- return FALSE;
-}
-
-#endif
-
-/**
- Search for the first occurrence of second parameter in the first.
-
- @param self Dynamic string to be modified.
- @param other Dynamic string to copy from.
- @return Boolean value indicating success or failure.
-*/
-#if defined(TRIO_FUNC_STRING_CONTAINS)
-
-TRIO_PUBLIC_STRING int
-trio_string_contains
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_contains(self->content, other->content);
-}
-
-#endif
-
-/*
- * trio_xstring_contains
- */
-#if defined(TRIO_FUNC_XSTRING_CONTAINS)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_contains
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_contains(self->content, other);
-}
-
-#endif
-
-/*
- * trio_string_copy
- */
-#if defined(TRIO_FUNC_STRING_COPY)
-
-TRIO_PUBLIC_STRING int
-trio_string_copy
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- self->length = 0;
- return trio_string_append(self, other);
-}
-
-#endif
-
-
-/*
- * trio_xstring_copy
- */
-#if defined(TRIO_FUNC_XSTRING_COPY)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_copy
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- self->length = 0;
- return trio_xstring_append(self, other);
-}
-
-#endif
-
-/*
- * trio_string_duplicate
- */
-#if defined(TRIO_FUNC_STRING_DUPLICATE)
-
-TRIO_PUBLIC_STRING trio_string_t *
-trio_string_duplicate
-TRIO_ARGS1((other),
- trio_string_t *other)
-{
- trio_string_t *self;
-
- assert(other);
-
- self = internal_string_alloc();
- if (self)
- {
- self->content = internal_duplicate_max(other->content, other->length);
- if (self->content)
- {
- self->length = other->length;
- self->allocated = self->length + 1;
- }
- else
- {
- self->length = self->allocated = 0;
- }
- }
- return self;
-}
-
-#endif
-
-/*
- * trio_xstring_duplicate
- */
-#if defined(TRIO_FUNC_XSTRING_DUPLICATE)
-
-TRIO_PUBLIC_STRING trio_string_t *
-trio_xstring_duplicate
-TRIO_ARGS1((other),
- TRIO_CONST char *other)
-{
- trio_string_t *self;
-
- assert(other);
-
- self = internal_string_alloc();
- if (self)
- {
- self->content = internal_duplicate_max(other, trio_length(other));
- if (self->content)
- {
- self->length = trio_length(self->content);
- self->allocated = self->length + 1;
- }
- else
- {
- self->length = self->allocated = 0;
- }
- }
- return self;
-}
-
-#endif
-
-/*
- * trio_string_equal
- */
-#if defined(TRIO_FUNC_STRING_EQUAL)
-
-TRIO_PUBLIC_STRING int
-trio_string_equal
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal(self->content, other->content);
-}
-
-#endif
-
-
-/*
- * trio_xstring_equal
- */
-#if defined(TRIO_FUNC_XSTRING_EQUAL)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_equal
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal(self->content, other);
-}
-
-#endif
-
-/*
- * trio_string_equal_max
- */
-#if defined(TRIO_FUNC_STRING_EQUAL_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_string_equal_max
-TRIO_ARGS3((self, max, other),
- trio_string_t *self,
- size_t max,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_max(self->content, max, other->content);
-}
-#endif
-
-/*
- * trio_xstring_equal_max
- */
-#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_equal_max
-TRIO_ARGS3((self, max, other),
- trio_string_t *self,
- size_t max,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_max(self->content, max, other);
-}
-
-#endif
-
-/*
- * trio_string_equal_case
- */
-#if defined(TRIO_FUNC_STRING_EQUAL_CASE)
-
-TRIO_PUBLIC_STRING int
-trio_string_equal_case
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_case(self->content, other->content);
-}
-
-#endif
-
-/*
- * trio_xstring_equal_case
- */
-#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_equal_case
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_case(self->content, other);
-}
-
-#endif
-
-/*
- * trio_string_equal_case_max
- */
-#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_string_equal_case_max
-TRIO_ARGS3((self, max, other),
- trio_string_t *self,
- size_t max,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_case_max(self->content, max, other->content);
-}
-
-#endif
-
-/*
- * trio_xstring_equal_case_max
- */
-#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_equal_case_max
-TRIO_ARGS3((self, max, other),
- trio_string_t *self,
- size_t max,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_equal_case_max(self->content, max, other);
-}
-
-#endif
-
-/*
- * trio_string_format_data_max
- */
-#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX)
-
-TRIO_PUBLIC_STRING size_t
-trio_string_format_date_max
-TRIO_ARGS4((self, max, format, datetime),
- trio_string_t *self,
- size_t max,
- TRIO_CONST char *format,
- TRIO_CONST struct tm *datetime)
-{
- assert(self);
-
- return trio_format_date_max(self->content, max, format, datetime);
-}
-
-#endif
-
-/*
- * trio_string_index
- */
-#if defined(TRIO_FUNC_STRING_INDEX)
-
-TRIO_PUBLIC_STRING char *
-trio_string_index
-TRIO_ARGS2((self, character),
- trio_string_t *self,
- int character)
-{
- assert(self);
-
- return trio_index(self->content, character);
-}
-
-#endif
-
-/*
- * trio_string_index_last
- */
-#if defined(TRIO_FUNC_STRING_INDEX_LAST)
-
-TRIO_PUBLIC_STRING char *
-trio_string_index_last
-TRIO_ARGS2((self, character),
- trio_string_t *self,
- int character)
-{
- assert(self);
-
- return trio_index_last(self->content, character);
-}
-
-#endif
-
-/*
- * trio_string_length
- */
-#if defined(TRIO_FUNC_STRING_LENGTH)
-
-TRIO_PUBLIC_STRING int
-trio_string_length
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- if (self->length == 0)
- {
- self->length = trio_length(self->content);
- }
- return self->length;
-}
-
-#endif
-
-/*
- * trio_string_lower
- */
-#if defined(TRIO_FUNC_STRING_LOWER)
-
-TRIO_PUBLIC_STRING int
-trio_string_lower
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- return trio_lower(self->content);
-}
-
-#endif
-
-/*
- * trio_string_match
- */
-#if defined(TRIO_FUNC_STRING_MATCH)
-
-TRIO_PUBLIC_STRING int
-trio_string_match
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_match(self->content, other->content);
-}
-
-#endif
-
-/*
- * trio_xstring_match
- */
-#if defined(TRIO_FUNC_XSTRING_MATCH)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_match
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_match(self->content, other);
-}
-
-#endif
-
-/*
- * trio_string_match_case
- */
-#if defined(TRIO_FUNC_STRING_MATCH_CASE)
-
-TRIO_PUBLIC_STRING int
-trio_string_match_case
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_match_case(self->content, other->content);
-}
-
-#endif
-
-/*
- * trio_xstring_match_case
- */
-#if defined(TRIO_FUNC_XSTRING_MATCH_CASE)
-
-TRIO_PUBLIC_STRING int
-trio_xstring_match_case
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_match_case(self->content, other);
-}
-
-#endif
-
-/*
- * trio_string_substring
- */
-#if defined(TRIO_FUNC_STRING_SUBSTRING)
-
-TRIO_PUBLIC_STRING char *
-trio_string_substring
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- trio_string_t *other)
-{
- assert(self);
- assert(other);
-
- return trio_substring(self->content, other->content);
-}
-
-#endif
-
-/*
- * trio_xstring_substring
- */
-#if defined(TRIO_FUNC_XSTRING_SUBSTRING)
-
-TRIO_PUBLIC_STRING char *
-trio_xstring_substring
-TRIO_ARGS2((self, other),
- trio_string_t *self,
- TRIO_CONST char *other)
-{
- assert(self);
- assert(other);
-
- return trio_substring(self->content, other);
-}
-
-#endif
-
-/*
- * trio_string_upper
- */
-#if defined(TRIO_FUNC_STRING_UPPER)
-
-TRIO_PUBLIC_STRING int
-trio_string_upper
-TRIO_ARGS1((self),
- trio_string_t *self)
-{
- assert(self);
-
- return trio_upper(self->content);
-}
-
-#endif
-
-/** @} End of DynamicStrings */
+++ /dev/null
-/*************************************************************************
- *
- * $Id: triostr.h,v 1.18 2010/01/26 13:02:02 breese Exp $
- *
- * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * 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. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- ************************************************************************/
-
-#ifndef TRIO_TRIOSTR_H
-#define TRIO_TRIOSTR_H
-
-/*
- * Documentation is located in triostr.c
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include "triodef.h"
-#include "triop.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum {
- TRIO_HASH_NONE = 0,
- TRIO_HASH_PLAIN,
- TRIO_HASH_TWOSIGNED
-};
-
-#if !defined(TRIO_PUBLIC_STRING)
-# if !defined(TRIO_PUBLIC)
-# define TRIO_PUBLIC
-# endif
-# define TRIO_PUBLIC_STRING TRIO_PUBLIC
-#endif
-
-/*************************************************************************
- * Dependencies
- */
-
-#if defined(TRIO_EMBED_STRING)
-
-/*
- * The application that triostr is embedded in must define which functions
- * it uses.
- *
- * The following resolves internal dependencies.
- */
-
-# if defined(TRIO_FUNC_XSTRING_SET)
-# if !defined(TRIO_FUNC_DUPLICATE)
-# define TRIO_FUNC_DUPLICATE
-# endif
-# endif
-
-# if defined(TRIO_FUNC_DUPLICATE) \
- || defined(TRIO_FUNC_DUPLICATE_MAX) \
- || defined(TRIO_FUNC_STRING_DUPLICATE) \
- || defined(TRIO_FUNC_XSTRING_DUPLICATE)
-# if !defined(TRIO_FUNC_CREATE)
-# define TRIO_FUNC_CREATE
-# endif
-# if !defined(TRIO_FUNC_COPY_MAX)
-# define TRIO_FUNC_COPY_MAX
-# endif
-# endif
-
-# if defined(TRIO_FUNC_STRING_CREATE)
-# if !defined(TRIO_FUNC_STRING_DESTROY)
-# define TRIO_FUNC_STRING_DESTROY
-# endif
-# endif
-
-# if defined(TRIO_FUNC_STRING_DESTROY) \
- || defined(TRIO_FUNC_XSTRING_SET)
-# if !defined(TRIO_FUNC_DESTROY)
-# define TRIO_FUNC_DESTROY
-# endif
-# endif
-
-# if defined(TRIO_FUNC_EQUAL_LOCALE) \
- || defined(TRIO_FUNC_STRING_EQUAL) \
- || defined(TRIO_FUNC_XSTRING_EQUAL)
-# if !defined(TRIO_FUNC_EQUAL)
-# define TRIO_FUNC_EQUAL
-# endif
-# endif
-
-# if defined(TRIO_FUNC_EQUAL_CASE) \
- || defined(TRIO_FUNC_STRING_EQUAL_CASE) \
- || defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
-# if !defined(TRIO_FUNC_EQUAL_CASE)
-# define TRIO_FUNC_EQUAL_CASE
-# endif
-# endif
-
-# if defined(TRIO_FUNC_SUBSTRING_MAX) \
- || defined(TRIO_FUNC_STRING_EQUAL_MAX) \
- || defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
-# if !defined(TRIO_FUNC_EQUAL_MAX)
-# define TRIO_FUNC_EQUAL_MAX
-# endif
-# endif
-
-# if defined(TRIO_FUNC_TO_DOUBLE) \
- || defined(TRIO_FUNC_TO_FLOAT)
-# if !defined(TRIO_FUNC_TO_LONG_DOUBLE)
-# define TRIO_FUNC_TO_LONG_DOUBLE
-# endif
-# endif
-
-# if defined(TRIO_FUNC_STRING_TERMINATE)
-# if !defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
-# define TRIO_FUNC_XSTRING_APPEND_CHAR
-# endif
-# endif
-
-# if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
-# if !defined(TRIO_FUNC_STRING_SIZE)
-# define TRIO_FUNC_STRING_SIZE
-# endif
-# endif
-
-#else
-
-/*
- * When triostr is not embedded all functions are defined.
- */
-
-# define TRIO_FUNC_APPEND
-# define TRIO_FUNC_APPEND_MAX
-# define TRIO_FUNC_CONTAINS
-# define TRIO_FUNC_COPY
-# define TRIO_FUNC_COPY_MAX
-# define TRIO_FUNC_CREATE
-# define TRIO_FUNC_DESTROY
-# define TRIO_FUNC_DUPLICATE
-# define TRIO_FUNC_DUPLICATE_MAX
-# define TRIO_FUNC_EQUAL
-# define TRIO_FUNC_EQUAL_CASE
-# define TRIO_FUNC_EQUAL_CASE_MAX
-# define TRIO_FUNC_EQUAL_LOCALE
-# define TRIO_FUNC_EQUAL_MAX
-# define TRIO_FUNC_ERROR
-# if !defined(TRIO_PLATFORM_WINCE)
-# define TRIO_FUNC_FORMAT_DATE_MAX
-# endif
-# define TRIO_FUNC_HASH
-# define TRIO_FUNC_INDEX
-# define TRIO_FUNC_INDEX_LAST
-# define TRIO_FUNC_LENGTH
-# define TRIO_FUNC_LENGTH_MAX
-# define TRIO_FUNC_LOWER
-# define TRIO_FUNC_MATCH
-# define TRIO_FUNC_MATCH_CASE
-# define TRIO_FUNC_SPAN_FUNCTION
-# define TRIO_FUNC_SUBSTRING
-# define TRIO_FUNC_SUBSTRING_MAX
-# define TRIO_FUNC_TO_DOUBLE
-# define TRIO_FUNC_TO_FLOAT
-# define TRIO_FUNC_TO_LONG
-# define TRIO_FUNC_TO_LONG_DOUBLE
-# define TRIO_FUNC_TO_LOWER
-# define TRIO_FUNC_TO_UNSIGNED_LONG
-# define TRIO_FUNC_TO_UPPER
-# define TRIO_FUNC_TOKENIZE
-# define TRIO_FUNC_UPPER
-
-# define TRIO_FUNC_STRING_APPEND
-# define TRIO_FUNC_STRING_CONTAINS
-# define TRIO_FUNC_STRING_COPY
-# define TRIO_FUNC_STRING_CREATE
-# define TRIO_FUNC_STRING_DESTROY
-# define TRIO_FUNC_STRING_DUPLICATE
-# define TRIO_FUNC_STRING_EQUAL
-# define TRIO_FUNC_STRING_EQUAL_CASE
-# define TRIO_FUNC_STRING_EQUAL_CASE_MAX
-# define TRIO_FUNC_STRING_EQUAL_MAX
-# define TRIO_FUNC_STRING_EXTRACT
-# if !defined(TRIO_PLATFORM_WINCE)
-# define TRIO_FUNC_STRING_FORMAT_DATE_MAX
-# endif
-# define TRIO_FUNC_STRING_GET
-# define TRIO_FUNC_STRING_INDEX
-# define TRIO_FUNC_STRING_INDEX_LAST
-# define TRIO_FUNC_STRING_LENGTH
-# define TRIO_FUNC_STRING_LOWER
-# define TRIO_FUNC_STRING_MATCH
-# define TRIO_FUNC_STRING_MATCH_CASE
-# define TRIO_FUNC_STRING_SIZE
-# define TRIO_FUNC_STRING_SUBSTRING
-# define TRIO_FUNC_STRING_TERMINATE
-# define TRIO_FUNC_STRING_UPPER
-
-# define TRIO_FUNC_XSTRING_APPEND
-# define TRIO_FUNC_XSTRING_APPEND_CHAR
-# define TRIO_FUNC_XSTRING_APPEND_MAX
-# define TRIO_FUNC_XSTRING_CONTAINS
-# define TRIO_FUNC_XSTRING_COPY
-# define TRIO_FUNC_XSTRING_DUPLICATE
-# define TRIO_FUNC_XSTRING_EQUAL
-# define TRIO_FUNC_XSTRING_EQUAL_CASE
-# define TRIO_FUNC_XSTRING_EQUAL_CASE_MAX
-# define TRIO_FUNC_XSTRING_EQUAL_MAX
-# define TRIO_FUNC_XSTRING_MATCH
-# define TRIO_FUNC_XSTRING_MATCH_CASE
-# define TRIO_FUNC_XSTRING_SET
-# define TRIO_FUNC_XSTRING_SUBSTRING
-
-#endif
-
-
-/*************************************************************************
- * String functions
- */
-
-#if defined(TRIO_FUNC_APPEND)
-TRIO_PUBLIC_STRING int
-trio_append
-TRIO_PROTO((char *target, TRIO_CONST char *source));
-#endif
-
-#if defined(TRIO_FUNC_APPEND_MAX)
-TRIO_PUBLIC_STRING int
-trio_append_max
-TRIO_PROTO((char *target, size_t max, TRIO_CONST char *source));
-#endif
-
-#if defined(TRIO_FUNC_CONTAINS)
-TRIO_PUBLIC_STRING int
-trio_contains
-TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring));
-#endif
-
-#if defined(TRIO_FUNC_COPY)
-TRIO_PUBLIC_STRING int
-trio_copy
-TRIO_PROTO((char *target, TRIO_CONST char *source));
-#endif
-
-#if defined(TRIO_FUNC_COPY_MAX)
-TRIO_PUBLIC_STRING int
-trio_copy_max
-TRIO_PROTO((char *target, size_t max, TRIO_CONST char *source));
-#endif
-
-#if defined(TRIO_FUNC_CREATE)
-TRIO_PUBLIC_STRING char *
-trio_create
-TRIO_PROTO((size_t size));
-#endif
-
-#if defined(TRIO_FUNC_DESTROY)
-TRIO_PUBLIC_STRING void
-trio_destroy
-TRIO_PROTO((char *string));
-#endif
-
-#if defined(TRIO_FUNC_DUPLICATE)
-TRIO_PUBLIC_STRING char *
-trio_duplicate
-TRIO_PROTO((TRIO_CONST char *source));
-#endif
-
-#if defined(TRIO_FUNC_DUPLICATE_MAX)
-TRIO_PUBLIC_STRING char *
-trio_duplicate_max
-TRIO_PROTO((TRIO_CONST char *source, size_t max));
-#endif
-
-#if defined(TRIO_FUNC_EQUAL)
-TRIO_PUBLIC_STRING int
-trio_equal
-TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second));
-#endif
-
-#if defined(TRIO_FUNC_EQUAL_CASE)
-TRIO_PUBLIC_STRING int
-trio_equal_case
-TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second));
-#endif
-
-#if defined(TRIO_FUNC_EQUAL_CASE_MAX)
-TRIO_PUBLIC_STRING int
-trio_equal_case_max
-TRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second));
-#endif
-
-#if defined(TRIO_FUNC_EQUAL_LOCALE)
-TRIO_PUBLIC_STRING int
-trio_equal_locale
-TRIO_PROTO((TRIO_CONST char *first, TRIO_CONST char *second));
-#endif
-
-#if defined(TRIO_FUNC_EQUAL_MAX)
-TRIO_PUBLIC_STRING int
-trio_equal_max
-TRIO_PROTO((TRIO_CONST char *first, size_t max, TRIO_CONST char *second));
-#endif
-
-#if defined(TRIO_FUNC_ERROR)
-TRIO_PUBLIC_STRING TRIO_CONST char *
-trio_error
-TRIO_PROTO((int));
-#endif
-
-#if defined(TRIO_FUNC_FORMAT_DATE_MAX)
-TRIO_PUBLIC_STRING size_t
-trio_format_date_max
-TRIO_PROTO((char *target, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime));
-#endif
-
-#if defined(TRIO_FUNC_HASH)
-TRIO_PUBLIC_STRING unsigned long
-trio_hash
-TRIO_PROTO((TRIO_CONST char *string, int type));
-#endif
-
-#if defined(TRIO_FUNC_INDEX)
-TRIO_PUBLIC_STRING char *
-trio_index
-TRIO_PROTO((TRIO_CONST char *string, int character));
-#endif
-
-#if defined(TRIO_FUNC_INDEX_LAST)
-TRIO_PUBLIC_STRING char *
-trio_index_last
-TRIO_PROTO((TRIO_CONST char *string, int character));
-#endif
-
-#if defined(TRIO_FUNC_LENGTH)
-TRIO_PUBLIC_STRING size_t
-trio_length
-TRIO_PROTO((TRIO_CONST char *string));
-#endif
-
-#if defined(TRIO_FUNC_LENGTH_MAX)
-TRIO_PUBLIC_STRING size_t
-trio_length_max
-TRIO_PROTO((TRIO_CONST char *string, size_t max));
-#endif
-
-#if defined(TRIO_FUNC_LOWER)
-TRIO_PUBLIC_STRING int
-trio_lower
-TRIO_PROTO((char *target));
-#endif
-
-#if defined(TRIO_FUNC_MATCH)
-TRIO_PUBLIC_STRING int
-trio_match
-TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern));
-#endif
-
-#if defined(TRIO_FUNC_MATCH_CASE)
-TRIO_PUBLIC_STRING int
-trio_match_case
-TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *pattern));
-#endif
-
-#if defined(TRIO_FUNC_SPAN_FUNCTION)
-TRIO_PUBLIC_STRING size_t
-trio_span_function
-TRIO_PROTO((char *target, TRIO_CONST char *source, int (*Function) TRIO_PROTO((int))));
-#endif
-
-#if defined(TRIO_FUNC_SUBSTRING)
-TRIO_PUBLIC_STRING char *
-trio_substring
-TRIO_PROTO((TRIO_CONST char *string, TRIO_CONST char *substring));
-#endif
-
-#if defined(TRIO_FUNC_SUBSTRING_MAX)
-TRIO_PUBLIC_STRING char *
-trio_substring_max
-TRIO_PROTO((TRIO_CONST char *string, size_t max, TRIO_CONST char *substring));
-#endif
-
-#if defined(TRIO_FUNC_TO_DOUBLE)
-TRIO_PUBLIC_STRING double
-trio_to_double
-TRIO_PROTO((TRIO_CONST char *source, char **endp));
-#endif
-
-#if defined(TRIO_FUNC_TO_FLOAT)
-TRIO_PUBLIC_STRING float
-trio_to_float
-TRIO_PROTO((TRIO_CONST char *source, char **endp));
-#endif
-
-#if defined(TRIO_FUNC_TO_LONG)
-TRIO_PUBLIC_STRING long
-trio_to_long
-TRIO_PROTO((TRIO_CONST char *source, char **endp, int base));
-#endif
-
-#if defined(TRIO_FUNC_TO_LOWER)
-TRIO_PUBLIC_STRING int
-trio_to_lower
-TRIO_PROTO((int source));
-#endif
-
-#if defined(TRIO_FUNC_TO_LONG_DOUBLE)
-TRIO_PUBLIC_STRING trio_long_double_t
-trio_to_long_double
-TRIO_PROTO((TRIO_CONST char *source, char **endp));
-#endif
-
-#if defined(TRIO_FUNC_TO_UNSIGNED_LONG)
-TRIO_PUBLIC_STRING unsigned long
-trio_to_unsigned_long
-TRIO_PROTO((TRIO_CONST char *source, char **endp, int base));
-#endif
-
-#if defined(TRIO_FUNC_TO_UPPER)
-TRIO_PUBLIC_STRING int
-trio_to_upper
-TRIO_PROTO((int source));
-#endif
-
-#if defined(TRIO_FUNC_TOKENIZE)
-TRIO_PUBLIC_STRING char *
-trio_tokenize
-TRIO_PROTO((char *string, TRIO_CONST char *delimiters));
-#endif
-
-#if defined(TRIO_FUNC_UPPER)
-TRIO_PUBLIC_STRING int
-trio_upper
-TRIO_PROTO((char *target));
-#endif
-
-/*************************************************************************
- * Dynamic string functions
- */
-
-/*
- * Opaque type for dynamic strings
- */
-
-typedef struct _trio_string_t trio_string_t;
-
-#if defined(TRIO_FUNC_STRING_APPEND)
-TRIO_PUBLIC_STRING int
-trio_string_append
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_CONTAINS)
-TRIO_PUBLIC_STRING int
-trio_string_contains
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_COPY)
-TRIO_PUBLIC_STRING int
-trio_string_copy
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_CREATE)
-TRIO_PUBLIC_STRING trio_string_t *
-trio_string_create
-TRIO_PROTO((int initial_size));
-#endif
-
-#if defined(TRIO_FUNC_STRING_DESTROY)
-TRIO_PUBLIC_STRING void
-trio_string_destroy
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_STRING_DUPLICATE)
-TRIO_PUBLIC_STRING trio_string_t *
-trio_string_duplicate
-TRIO_PROTO((trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_EQUAL)
-TRIO_PUBLIC_STRING int
-trio_string_equal
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_EQUAL_MAX)
-TRIO_PUBLIC_STRING int
-trio_string_equal_max
-TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *second));
-#endif
-
-#if defined(TRIO_FUNC_STRING_EQUAL_CASE)
-TRIO_PUBLIC_STRING int
-trio_string_equal_case
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX)
-TRIO_PUBLIC_STRING int
-trio_string_equal_case_max
-TRIO_PROTO((trio_string_t *self, size_t max, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_EXTRACT)
-TRIO_PUBLIC_STRING char *
-trio_string_extract
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX)
-TRIO_PUBLIC_STRING size_t
-trio_string_format_date_max
-TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *format, TRIO_CONST struct tm *datetime));
-#endif
-
-#if defined(TRIO_FUNC_STRING_GET)
-TRIO_PUBLIC_STRING char *
-trio_string_get
-TRIO_PROTO((trio_string_t *self, int offset));
-#endif
-
-#if defined(TRIO_FUNC_STRING_INDEX)
-TRIO_PUBLIC_STRING char *
-trio_string_index
-TRIO_PROTO((trio_string_t *self, int character));
-#endif
-
-#if defined(TRIO_FUNC_STRING_INDEX_LAST)
-TRIO_PUBLIC_STRING char *
-trio_string_index_last
-TRIO_PROTO((trio_string_t *self, int character));
-#endif
-
-#if defined(TRIO_FUNC_STRING_LENGTH)
-TRIO_PUBLIC_STRING int
-trio_string_length
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_STRING_LOWER)
-TRIO_PUBLIC_STRING int
-trio_string_lower
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_STRING_MATCH)
-TRIO_PUBLIC_STRING int
-trio_string_match
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_MATCH_CASE)
-TRIO_PUBLIC_STRING int
-trio_string_match_case
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_SIZE)
-TRIO_PUBLIC_STRING int
-trio_string_size
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_STRING_SUBSTRING)
-TRIO_PUBLIC_STRING char *
-trio_string_substring
-TRIO_PROTO((trio_string_t *self, trio_string_t *other));
-#endif
-
-#if defined(TRIO_FUNC_STRING_TERMINATE)
-TRIO_PUBLIC_STRING void
-trio_string_terminate
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_STRING_UPPER)
-TRIO_PUBLIC_STRING int
-trio_string_upper
-TRIO_PROTO((trio_string_t *self));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_APPEND)
-TRIO_PUBLIC_STRING int
-trio_xstring_append
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
-TRIO_PUBLIC_STRING int
-trio_xstring_append_char
-TRIO_PROTO((trio_string_t *self, char character));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_APPEND_MAX)
-TRIO_PUBLIC_STRING int
-trio_xstring_append_max
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other, size_t max));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_CONTAINS)
-TRIO_PUBLIC_STRING int
-trio_xstring_contains
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_COPY)
-TRIO_PUBLIC_STRING int
-trio_xstring_copy
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_DUPLICATE)
-TRIO_PUBLIC_STRING trio_string_t *
-trio_xstring_duplicate
-TRIO_PROTO((TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_EQUAL)
-TRIO_PUBLIC_STRING int
-trio_xstring_equal
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
-TRIO_PUBLIC_STRING int
-trio_xstring_equal_max
-TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
-TRIO_PUBLIC_STRING int
-trio_xstring_equal_case
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX)
-TRIO_PUBLIC_STRING int
-trio_xstring_equal_case_max
-TRIO_PROTO((trio_string_t *self, size_t max, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_MATCH)
-TRIO_PUBLIC_STRING int
-trio_xstring_match
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_MATCH_CASE)
-TRIO_PUBLIC_STRING int
-trio_xstring_match_case
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_SET)
-TRIO_PUBLIC_STRING void
-trio_xstring_set
-TRIO_PROTO((trio_string_t *self, char *buffer));
-#endif
-
-#if defined(TRIO_FUNC_XSTRING_SUBSTRING)
-TRIO_PUBLIC_STRING char *
-trio_xstring_substring
-TRIO_PROTO((trio_string_t *self, TRIO_CONST char *other));
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* TRIO_TRIOSTR_H */
*/
#include "config.h"
+#include "fetchmail.h"
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <limits.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
#include <string.h>
-#endif
-#if defined(HAVE_UNISTD_H)
+#include <strings.h>
#include <unistd.h>
-#endif
-#include "fetchmail.h"
#include "i18n.h"
#include "sdump.h"
6.3.17 release, including the OpenSSL exemption.
*/
+/* Have Solaris expose ffs() from strings.h: */
+#define __EXTENSIONS__
+
#include "fetchmail.h"
/* includes */
* For license terms, see the file COPYING in this directory.
*/
+#include "fetchmail.h"
#include "config.h"
#include <string.h>
+#include <strings.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
-#include "fetchmail.h"
#include "i18n.h"
static unsigned char unhex(unsigned char c)
*/
#include "config.h"
+#include "fetchmail.h"
+
#include "xmalloc.h"
#include <sys/types.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
-#if defined(STDC_HEADERS)
#include <stdlib.h>
-#endif
-#include "fetchmail.h"
#include "i18n.h"
XMALLOCTYPE *
return p;
}
-#if !defined(HAVE_STRDUP)
-char *strdup(const char *s)
-{
- char *p;
- p = (char *) malloc(strlen(s)+1);
- if (p)
- strcpy(p,s);
- return p;
-}
-#endif /* !HAVE_STRDUP */
-
char *xstrndup(const char *s, size_t len)
{
char *p;
#endif
/* xmalloc.c */
-#if defined(HAVE_VOIDPOINTER) || defined(__cplusplus)
#define XMALLOCTYPE void
-#else
-#define XMALLOCTYPE char
-#endif
/** Allocate \a n characters of memory, abort program on failure. */
XMALLOCTYPE *xmalloc(size_t n);
/** Reallocate \a n characters of memory, abort program on failure. */
-XMALLOCTYPE *xrealloc(/*@null@*/ void *, size_t n);
+XMALLOCTYPE *xrealloc(/*@null@*/ XMALLOCTYPE *, size_t n);
/** Free memory at position \a p and set pointer \a p to NULL afterwards. */
#define xfree(p) { if (p) { free(p); } (p) = 0; }