blob: 1b1996203f0182ab32af525ba55104e57c30ca8b [file] [log] [blame]
/************************************************************************
*
* fmt_bits.cpp - definitions of snprintfa helpers
*
* $Id$
*
************************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*
* Copyright 2005-2008 Rogue Wave Software. Inc.
*
**************************************************************************/
// expand _TEST_EXPORT macros
#define _RWSTD_TEST_SRC
#include "fmt_defs.h"
#include <rw_printf.h>
#include <ctype.h> // for isalnum(), ...
#include <errno.h> // for errno, errno constants
#include <locale.h>
#include <signal.h> // for signal constant
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // memcpy(), memmove(), strcat(), ...
#ifndef _RWSTD_NO_WCHAR_H
# include <wchar.h>
#endif // _RWSTD_NO_WCHAR_H
#ifndef _RWSTD_NO_WCTYPE_H
# include <wctype.h> // for iswalpha(), ...
#endif // _RWSTD_NO_WCTYPE_H
#ifdef _WIN32
# include <windows.h> // for FormatMessage()
#endif // _WIN32
#include <ios>
#include <iostream>
#include <locale>
/**************************************************************************/
struct Bitnames
{
const char *longname;
const char *name;
int bits;
};
#define BITNAME(qual, name) { #qual "::" #name, #name, qual::name }
static int
_rw_bmpfmt (const FmtSpec &spec, Buffer &buf,
const Bitnames bmap[],
size_t size,
int bits)
{
RW_ASSERT (0 != buf.pbuf);
char buffer [1024];
*buffer = '\0';
// string to use when no bits are set
const char* all_clear = "0";
for (size_t i = 0; i != size; ++i) {
if (bmap [i].bits) {
if ((bits & bmap [i].bits) == bmap [i].bits) {
const char* const name = spec.fl_pound ?
bmap [i].longname : bmap [i].name;
strcat (*buffer ? strcat (buffer, " | ") : buffer, name);
bits &= ~bmap [i].bits;
}
}
else {
// save the name of the constant to use for 0
all_clear = spec.fl_pound ? bmap [i].longname : bmap [i].name;
}
}
size_t buffersize;
if ('\0' == *buffer) {
// no constant matched, format teh value either as a number
// or, when 0, using the all_clear name (see above)
if (bits)
sprintf (buffer, "%#x", bits);
else
strcpy (buffer, all_clear);
buffersize = strlen (buffer);
}
else if (bits) {
buffersize = strlen (buffer);
// verify that buffer wasn't overflowed
RW_ASSERT (buffersize <= sizeof buffer);
char bitstr [32];
const int n = sprintf (bitstr, "%#x | ", bits);
RW_ASSERT (0 < n);
memmove (buffer + n, buffer, buffersize);
memcpy (buffer, bitstr, size_t (n));
buffersize += n;
}
else {
buffersize = strlen (buffer);
}
// verify that buffer wasn't overflowed
RW_ASSERT (buffersize <= sizeof buffer);
// NUL-terminate string so that it can be appended to using
// the %{+} directive, taking care not to make the NUL a part
// of the formatted string
FmtSpec newspec (spec);
newspec.fl_pound = 0;
const int len = _rw_fmtstr (newspec, buf, buffer, buffersize + 1);
--buf.endoff;
return 0 < len ? len - 1 : len;
}
/********************************************************************/
/* extern */ int
_rw_fmtflags (const FmtSpec &spec, Buffer &buf, int bits)
{
static const Bitnames names [] = {
BITNAME (std::ios, adjustfield),
BITNAME (std::ios, basefield),
BITNAME (std::ios, boolalpha),
BITNAME (std::ios, dec),
BITNAME (std::ios, fixed),
BITNAME (std::ios, hex),
BITNAME (std::ios, internal),
BITNAME (std::ios, left),
BITNAME (std::ios, oct),
BITNAME (std::ios, right),
BITNAME (std::ios, scientific),
BITNAME (std::ios, showbase),
BITNAME (std::ios, showpoint),
BITNAME (std::ios, showpos),
BITNAME (std::ios, skipws),
BITNAME (std::ios, unitbuf),
BITNAME (std::ios, uppercase),
#ifndef _RWSTD_NO_EXT_BIN_IO
// extension: produce binary output (similar to oct, dec, and hex)
BITNAME (std::ios, bin),
#endif // _RWSTD_NO_EXT_BIN_IO
#ifndef _RWSTD_NO_EXT_REENTRANT_IO
// extension: allow unsychronized access to stream and/or its buffer
BITNAME (std::ios, nolock),
BITNAME (std::ios, nolockbuf),
#endif // _RWSTD_NO_EXT_REENTRANT_IO
{ "std::ios::fmtflags(0)", "fmtflags(0)", std::ios::fmtflags () }
};
static const size_t count = sizeof names / sizeof *names;
const int base = (bits >> _RWSTD_IOS_BASEOFF) & _RWSTD_IOS_BASEMASK;
// zero out bits representingthe numeric base
bits &= ~(_RWSTD_IOS_BASEMASK << _RWSTD_IOS_BASEOFF);
int len = _rw_bmpfmt (spec, buf, names, count, bits);
if (0 < len && base && base != 8 && base != 10 && base != 16) {
// for numeric bases other than those required by the standard,
// use the text "base (%d)" to show the extended numeric base
#ifndef _RWSTD_NO_EXT_BIN_IO
if (bits & std::ios::bin)
return len;
#endif // _RWSTD_NO_EXT_BIN_IO
const int n = rw_asnprintf (buf.pbuf, buf.pbufsize,
"%{+} | %{?}std::ios::%{;}base(%d)",
spec.fl_pound, base);
if (0 < n) {
// adjust length and the end offset after appending above
len += n;
buf.endoff += n;
}
else {
// error (most likely ENOMEM)
len = n;
}
}
return len;
}
/********************************************************************/
/* extern */ int
_rw_fmtiostate (const FmtSpec &spec, Buffer &buf, int bits)
{
static const Bitnames names [] = {
BITNAME (std::ios, goodbit),
BITNAME (std::ios, badbit),
BITNAME (std::ios, eofbit),
BITNAME (std::ios, failbit)
};
static const size_t count = sizeof names / sizeof *names;
return _rw_bmpfmt (spec, buf, names, count, bits);
}
/********************************************************************/
/* extern */ int
_rw_fmtopenmode (const FmtSpec &spec, Buffer &buf, int bits)
{
static const Bitnames names [] = {
#ifndef _RWSTD_NO_EXTENSIONS
{ "std::ios::nocreate", "nocreate", std::ios::nocreate },
{ "std::ios::noreplace", "noreplace", std::ios::noreplace },
#else // if defined (_RWSTD_NO_EXTENSIONS)
{ "__rw:::__rw_nocreate", "__rw_nocreate", _RW::__rw_nocreate },
{ "__rw::__rw_noreplace", "__rw_noreplace", _RW::__rw_noreplace },
#endif // _RWSTD_NO_EXTENSIONS
#ifndef _RWSTD_NO_EXT_STDIO
{ "std::ios::stdio", "stdio", std::ios::stdio },
{ "std::ios::native", "native", std::ios::native },
#else // if defined (_RWSTD_NO_EXT_STDIO)
{ "__rw::__rw_stdio", "__rw_stdio", _RW::__rw_stdio },
{ "__rw::__rw_native", "__rw_native", _RW::__rw_native },
#endif // _RWSTD_NO_EXT_STDIO
BITNAME (std::ios, app),
BITNAME (std::ios, binary),
BITNAME (std::ios, in),
BITNAME (std::ios, out),
BITNAME (std::ios, trunc),
BITNAME (std::ios, ate),
{ "std::ios::openmode(0)", "openmode(0)", std::ios::openmode () }
};
static const size_t count = sizeof names / sizeof *names;
return _rw_bmpfmt (spec, buf, names, count, bits);
}
/********************************************************************/
/* extern */ int
_rw_fmtseekdir (const FmtSpec &spec, Buffer &buf, int bits)
{
static const Bitnames names [] = {
BITNAME (std::ios, beg),
BITNAME (std::ios, cur),
BITNAME (std::ios, end)
};
static const size_t count = sizeof names / sizeof *names;
return _rw_bmpfmt (spec, buf, names, count, bits);
}
/********************************************************************/
/* extern */ int
_rw_fmtevent (const FmtSpec& spec, Buffer &buf, int event)
{
const char* const str =
std::ios::copyfmt_event == event ? "copyfmt_event"
: std::ios::imbue_event == event ? "imbue_event"
: std::ios::erase_event == event ? "erase_event"
: 0;
// NUL-terminate before appending below
FmtSpec newspec (spec);
newspec.fl_pound = 0;
int len = _rw_fmtstr (newspec, buf, "", 1);
if (1 == len) {
// back up before the terminating NUL
buf.endoff -= 1;
// append name of event
len = rw_asnprintf (buf.pbuf, buf.pbufsize,
"%{+}%{?}std::ios::%{;}%{?}%s%{:}event(%d)%{;}",
spec.fl_pound, 0 != str, str, event);
if (0 < len)
buf.endoff += len;
}
return len;
}
/********************************************************************/
/* extern */ int
_rw_fmtlc (const FmtSpec &spec, Buffer &buf, int val)
{
const char *str = 0;
switch (val) {
case LC_ALL: str = "LC_ALL"; break;
case LC_COLLATE: str = "LC_COLLATE"; break;
case LC_CTYPE: str = "LC_CTYPE"; break;
case LC_MONETARY: str = "LC_MONETARY"; break;
case LC_NUMERIC: str = "LC_NUMERIC"; break;
case LC_TIME: str = "LC_TIME"; break;
#ifdef LC_MESSAGES
case LC_MESSAGES: str = "LC_MESSAGES"; break;
#endif // LC_MESSAGES
}
if (str) {
// NUL-terminate before appending below
FmtSpec newspec (spec);
newspec.fl_pound = 0;
int len = _rw_fmtstr (newspec, buf, "", 1);
if (1 == len) {
// back up before the terminating NUL
buf.endoff -= 1;
len = rw_asnprintf (buf.pbuf, buf.pbufsize, "%{+}%s", str);
if (0 < len)
buf.endoff += len;
}
return len;
}
static const Bitnames names [] = {
BITNAME (std::locale, all),
BITNAME (std::locale, none),
BITNAME (std::locale, collate),
BITNAME (std::locale, ctype),
BITNAME (std::locale, monetary),
BITNAME (std::locale, numeric),
BITNAME (std::locale, messages),
BITNAME (std::locale, time)
};
static const size_t count = sizeof names / sizeof *names;
return _rw_bmpfmt (spec, buf, names, count, val);
}
/********************************************************************/
/* extern */ int
_rw_fmtmonpat (const FmtSpec &spec, Buffer &buf, const char pat [4])
{
static const char qual[] = "std::money_base::";
char buffer [256];
buffer [0] = '\0';
for (int i = 0; i != 4; ++i) {
switch (pat [i]) {
case std::money_base::symbol:
if (spec.fl_pound)
strcat (buffer, qual);
strcat (buffer, "symbol ");
break;
case std::money_base::sign:
if (spec.fl_pound)
strcat (buffer, qual);
strcat (buffer, "sign ");
break;
case std::money_base::none:
if (spec.fl_pound)
strcat (buffer, qual);
strcat (buffer, "none ");
break;
case std::money_base::value:
if (spec.fl_pound)
strcat (buffer, qual);
strcat (buffer, "value ");
break;
case std::money_base::space:
if (spec.fl_pound)
strcat (buffer, qual);
strcat (buffer, "space ");
break;
default:
sprintf (buffer + strlen (buffer), "\\%03o", pat [i]);
break;
}
}
FmtSpec newspec (spec);
newspec.fl_pound = 0;
return _rw_fmtstr (newspec, buf, buffer, _RWSTD_SIZE_MAX);
}
/********************************************************************/
/* extern */ int
_rw_fmtsignal (const FmtSpec &spec, Buffer &buf, int val)
{
static const struct {
int val;
const char* str;
} names[] = {
#undef SIGNAL
#define SIGNAL(val) { val, #val }
#ifdef SIGABRT
SIGNAL (SIGABRT),
#endif // SIGABRT
#ifdef SIGALRM
SIGNAL (SIGALRM),
#endif // SIGALRM
#ifdef SIGBUS
SIGNAL (SIGBUS),
#endif // SIGBUS
#ifdef SIGCANCEL
SIGNAL (SIGCANCEL),
#endif // SIGCANCEL
#ifdef SIGCHLD
SIGNAL (SIGCHLD),
#endif // SIGCHLD
#ifdef SIGCKPT
SIGNAL (SIGCKPT),
#endif // SIGCKPT
#ifdef SIGCLD
SIGNAL (SIGCLD),
#endif // SIGCLD
#ifdef SIGCONT
SIGNAL (SIGCONT),
#endif // SIGCONT
#ifdef SIGDIL
SIGNAL (SIGDIL),
#endif // SIGDIL
#ifdef SIGEMT
SIGNAL (SIGEMT),
#endif // SIGEMT
#ifdef SIGFPE
SIGNAL (SIGFPE),
#endif // SIGFPE
#ifdef SIGFREEZE
SIGNAL (SIGFREEZE),
#endif // SIGFREEZE
#ifdef SIGGFAULT
SIGNAL (SIGGFAULT),
#endif // SIGGFAULT
#ifdef SIGHUP
SIGNAL (SIGHUP),
#endif // SIGHUP
#ifdef SIGILL
SIGNAL (SIGILL),
#endif // SIGILL
#ifdef SIGINFO
SIGNAL (SIGINFO),
#endif // SIGINFO
#ifdef SIGINT
SIGNAL (SIGINT),
#endif // SIGINT
#ifdef SIGIO
SIGNAL (SIGIO),
#endif // SIGIO
#ifdef SIGIOT
SIGNAL (SIGIOT),
#endif // SIGIOT
#ifdef SIGK32
SIGNAL (SIGK32),
#endif // SIGK32
#ifdef SIGKILL
SIGNAL (SIGKILL),
#endif // SIGKILL
#ifdef SIGLOST
SIGNAL (SIGLOST),
#endif // SIGLOST
#ifdef SIGLWP
SIGNAL (SIGLWP),
#endif // SIGLWP
#ifdef SIGPIPE
SIGNAL (SIGPIPE),
#endif // SIGPIPE
#ifdef SIGPOLL
SIGNAL (SIGPOLL),
#endif // SIGPOLL
#ifdef SIGPROF
SIGNAL (SIGPROF),
#endif // SIGPROF
#ifdef SIGPTINTR
SIGNAL (SIGPTINTR),
#endif // SIGPTINTR
#ifdef SIGPTRESCHED
SIGNAL (SIGPTRESCHED),
#endif // SIGPTRESCHED
#ifdef SIGPWR
SIGNAL (SIGPWR),
#endif // SIGPWR
#ifdef SIGQUIT
SIGNAL (SIGQUIT),
#endif // SIGQUIT
#ifdef SIGRESTART
SIGNAL (SIGRESTART),
#endif // SIGRESTART
#ifdef SIGRESV
SIGNAL (SIGRESV),
#endif // SIGRESV
#ifdef SIGSEGV
SIGNAL (SIGSEGV),
#endif // SIGSEGV
#ifdef SIGSTKFLT
SIGNAL (SIGSTKFLT),
#endif // SIGSTKFLT
#ifdef SIGSTOP
SIGNAL (SIGSTOP),
#endif // SIGSTOP
#ifdef SIGSYS
SIGNAL (SIGSYS),
#endif // SIGSYS
#ifdef SIGTERM
SIGNAL (SIGTERM),
#endif // SIGTERM
#ifdef SIGTHAW
SIGNAL (SIGTHAW),
#endif // SIGTHAW
#ifdef SIGTRAP
SIGNAL (SIGTRAP),
#endif // SIGTRAP
#ifdef SIGTSTP
SIGNAL (SIGTSTP),
#endif // SIGTSTP
#ifdef SIGTTIN
SIGNAL (SIGTTIN),
#endif // SIGTTIN
#ifdef SIGTTOU
SIGNAL (SIGTTOU),
#endif // SIGTTOU
#ifdef SIGUNUSED
SIGNAL (SIGUNUSED),
#endif // SIGUNUSED
#ifdef SIGURG
SIGNAL (SIGURG),
#endif // SIGURG
#ifdef SIGUSR1
SIGNAL (SIGUSR1),
#endif // SIGUSR1
#ifdef SIGUSR2
SIGNAL (SIGUSR2),
#endif // SIGUSR2
#ifdef SIGVTALRM
SIGNAL (SIGVTALRM),
#endif // SIGVTALRM
#ifdef SIGWAITING
SIGNAL (SIGWAITING),
#endif // SIGWAITING
#ifdef SIGWINCH
SIGNAL (SIGWINCH),
#endif // SIGWINCH
#ifdef SIGWINDOW
SIGNAL (SIGWINDOW),
#endif // SIGWINDOW
#ifdef SIGXCPU
SIGNAL (SIGXCPU),
#endif // SIGXCPU
#ifdef SIGXFSZ
SIGNAL (SIGXFSZ),
#endif // SIGXFSZ
#ifdef SIGXRES
SIGNAL (SIGXRES),
#endif // SIGXRES
{ -1, 0 }
};
const char *name = 0;
for (size_t i = 0; i != sizeof names / sizeof *names; ++i) {
if (names [i].val == val) {
name = names [i].str;
break;
}
}
char smallbuf [32];
if (0 == name) {
sprintf (smallbuf, "SIG#%d", val);
name = smallbuf;
}
FmtSpec newspec (spec);
newspec.fl_pound = 0;
return _rw_fmtstr (newspec, buf, name, _RWSTD_SIZE_MAX);
}
/********************************************************************/
/* extern */ int
_rw_fmterrno (const FmtSpec &spec, Buffer &buf, int val)
{
static const struct {
int val;
const char* str;
} names[] = {
#undef ERRNO
#define ERRNO(val) { val, #val }
#ifdef EPERM
ERRNO (EPERM),
#endif // EPERM
#ifdef ENOENT
ERRNO (ENOENT),
#endif // ENOENT
#ifdef ESRCH
ERRNO (ESRCH),
#endif // ESRCH
#ifdef EINTR
ERRNO (EINTR),
#endif // EINTR
#ifdef EIO
ERRNO (EIO),
#endif // EIO
#ifdef ENXIO
ERRNO (ENXIO),
#endif // ENXIO
#ifdef E2BIG
ERRNO (E2BIG),
#endif // E2BIG
#ifdef ENOEXEC
ERRNO (ENOEXEC),
#endif // ENOEXEC
#ifdef EBADF
ERRNO (EBADF),
#endif // EBADF
#ifdef ECHILD
ERRNO (ECHILD),
#endif // ECHILD
#ifdef EAGAIN
ERRNO (EAGAIN),
#endif // EAGAIN
#ifdef ENOMEM
ERRNO (ENOMEM),
#endif // ENOMEM
#ifdef EACCES
ERRNO (EACCES),
#endif // EACCES
#ifdef EFAULT
ERRNO (EFAULT),
#endif // EFAULT
#ifdef ENOTBLK
ERRNO (ENOTBLK),
#endif // ENOTBLK
#ifdef EBUSY
ERRNO (EBUSY),
#endif // EBUSY
#ifdef EEXIST
ERRNO (EEXIST),
#endif // EEXIST
#ifdef EXDEV
ERRNO (EXDEV),
#endif // EXDEV
#ifdef ENODEV
ERRNO (ENODEV),
#endif // ENODEV
#ifdef ENOTDIR
ERRNO (ENOTDIR),
#endif // ENOTDIR
#ifdef EISDIR
ERRNO (EISDIR),
#endif // EISDIR
#ifdef EINVAL
ERRNO (EINVAL),
#endif // EINVAL
#ifdef ENFILE
ERRNO (ENFILE),
#endif // ENFILE
#ifdef EMFILE
ERRNO (EMFILE),
#endif // EMFILE
#ifdef ENOTTY
ERRNO (ENOTTY),
#endif // ENOTTY
#ifdef ETXTBSY
ERRNO (ETXTBSY),
#endif // ETXTBSY
#ifdef EFBIG
ERRNO (EFBIG),
#endif // EFBIG
#ifdef ENOSPC
ERRNO (ENOSPC),
#endif // ENOSPC
#ifdef ESPIPE
ERRNO (ESPIPE),
#endif // ESPIPE
#ifdef EROFS
ERRNO (EROFS),
#endif // EROFS
#ifdef EMLINK
ERRNO (EMLINK),
#endif // EMLINK
#ifdef EPIPE
ERRNO (EPIPE),
#endif // EPIPE
#ifdef EDOM
ERRNO (EDOM),
#endif // EDOM
#ifdef ERANGE
ERRNO (ERANGE),
#endif // ERANGE
#ifdef ENOMSG
ERRNO (ENOMSG),
#endif // ENOMSG
#ifdef EIDRM
ERRNO (EIDRM),
#endif // EIDRM
#ifdef ECHRNG
ERRNO (ECHRNG),
#endif // ECHRNG
#ifdef EL2NSYNC
ERRNO (EL2NSYNC),
#endif // EL2NSYNC
#ifdef EL3HLT
ERRNO (EL3HLT),
#endif // EL3HLT
#ifdef EL3RST
ERRNO (EL3RST),
#endif // EL3RST
#ifdef ELNRNG
ERRNO (ELNRNG),
#endif // ELNRNG
#ifdef EUNATCH
ERRNO (EUNATCH),
#endif // EUNATCH
#ifdef ENOCSI
ERRNO (ENOCSI),
#endif // ENOCSI
#ifdef EL2HLT
ERRNO (EL2HLT),
#endif // EL2HLT
#ifdef EDEADLK
ERRNO (EDEADLK),
#endif // EDEADLK
#ifdef ENOLCK
ERRNO (ENOLCK),
#endif // ENOLCK
#ifdef ECANCELED
ERRNO (ECANCELED),
#endif // ECANCELED
#ifdef ENOTSUP
ERRNO (ENOTSUP),
#endif // ENOTSUP
#ifdef EDQUOT
ERRNO (EDQUOT),
#endif // EDQUOT
#ifdef EBADE
ERRNO (EBADE),
#endif // EBADE
#ifdef EBADR
ERRNO (EBADR),
#endif // EBADR
#ifdef EXFULL
ERRNO (EXFULL),
#endif // EXFULL
#ifdef ENOANO
ERRNO (ENOANO),
#endif // ENOANO
#ifdef EBADRQC
ERRNO (EBADRQC),
#endif // EBADRQC
#ifdef EBADSLT
ERRNO (EBADSLT),
#endif // EBADSLT
#ifdef EDEADLOCK
ERRNO (EDEADLOCK),
#endif // EDEADLOCK
#ifdef EBFONT
ERRNO (EBFONT),
#endif // EBFONT
#ifdef EOWNERDEAD
ERRNO (EOWNERDEAD),
#endif // EOWNERDEAD
#ifdef ENOTRECOVERABLE
ERRNO (ENOTRECOVERABLE),
#endif // ENOTRECOVERABLE
#ifdef ENOSTR
ERRNO (ENOSTR),
#endif // ENOSTR
#ifdef ENODATA
ERRNO (ENODATA),
#endif // ENODATA
#ifdef ETIME
ERRNO (ETIME),
#endif // ETIME
#ifdef ENOSR
ERRNO (ENOSR),
#endif // ENOSR
#ifdef ENONET
ERRNO (ENONET),
#endif // ENONET
#ifdef ENOPKG
ERRNO (ENOPKG),
#endif // ENOPKG
#ifdef EREMOTE
ERRNO (EREMOTE),
#endif // EREMOTE
#ifdef ENOLINK
ERRNO (ENOLINK),
#endif // ENOLINK
#ifdef EADV
ERRNO (EADV),
#endif // EADV
#ifdef ESRMNT
ERRNO (ESRMNT),
#endif // ESRMNT
#ifdef ECOMM
ERRNO (ECOMM),
#endif // ECOMM
#ifdef ELOCKUNMAPPED
ERRNO (ELOCKUNMAPPED),
#endif // ELOCKUNMAPPED
#ifdef ENOTACTIVE
ERRNO (ENOTACTIVE),
#endif // ENOTACTIVE
#ifdef EMULTIHOP
ERRNO (EMULTIHOP),
#endif // EMULTIHOP
#ifdef EBADMSG
ERRNO (EBADMSG),
#endif // EBADMSG
#ifdef ENAMETOOLONG
ERRNO (ENAMETOOLONG),
#endif // ENAMETOOLONG
#ifdef EOVERFLOW
ERRNO (EOVERFLOW),
#endif // EOVERFLOW
#ifdef ENOTUNIQ
ERRNO (ENOTUNIQ),
#endif // ENOTUNIQ
#ifdef EBADFD
ERRNO (EBADFD),
#endif // EBADFD
#ifdef EREMCHG
ERRNO (EREMCHG),
#endif // EREMCHG
#ifdef ELIBACC
ERRNO (ELIBACC),
#endif // ELIBACC
#ifdef ELIBBAD
ERRNO (ELIBBAD),
#endif // ELIBBAD
#ifdef ELIBSCN
ERRNO (ELIBSCN),
#endif // ELIBSCN
#ifdef ELIBMAX
ERRNO (ELIBMAX),
#endif // ELIBMAX
#ifdef ELIBEXEC
ERRNO (ELIBEXEC),
#endif // ELIBEXEC
#ifdef EILSEQ
ERRNO (EILSEQ),
#endif // EILSEQ
#ifdef ENOSYS
ERRNO (ENOSYS),
#endif // ENOSYS
#ifdef ELOOP
ERRNO (ELOOP),
#endif // ELOOP
#ifdef ERESTART
ERRNO (ERESTART),
#endif // ERESTART
#ifdef ESTRPIPE
ERRNO (ESTRPIPE),
#endif // ESTRPIPE
#ifdef ENOTEMPTY
ERRNO (ENOTEMPTY),
#endif // ENOTEMPTY
#ifdef EUSERS
ERRNO (EUSERS),
#endif // EUSERS
#ifdef ENOTSOCK
ERRNO (ENOTSOCK),
#endif // ENOTSOCK
#ifdef EDESTADDRREQ
ERRNO (EDESTADDRREQ),
#endif // EDESTADDRREQ
#ifdef EMSGSIZE
ERRNO (EMSGSIZE),
#endif // EMSGSIZE
#ifdef EPROTOTYPE
ERRNO (EPROTOTYPE),
#endif // EPROTOTYPE
#ifdef ENOPROTOOPT
ERRNO (ENOPROTOOPT),
#endif // ENOPROTOOPT
#ifdef EPROTONOSUPPORT
ERRNO (EPROTONOSUPPORT),
#endif // EPROTONOSUPPORT
#ifdef ESOCKTNOSUPPORT
ERRNO (ESOCKTNOSUPPORT),
#endif // ESOCKTNOSUPPORT
#ifdef EOPNOTSUPP
ERRNO (EOPNOTSUPP),
#endif // EOPNOTSUPP
#ifdef EPFNOSUPPORT
ERRNO (EPFNOSUPPORT),
#endif // EPFNOSUPPORT
#ifdef EAFNOSUPPORT
ERRNO (EAFNOSUPPORT),
#endif // EAFNOSUPPORT
#ifdef EADDRINUSE
ERRNO (EADDRINUSE),
#endif // EADDRINUSE
#ifdef EADDRNOTAVAIL
ERRNO (EADDRNOTAVAIL),
#endif // EADDRNOTAVAIL
#ifdef ENETDOWN
ERRNO (ENETDOWN),
#endif // ENETDOWN
#ifdef ENETUNREACH
ERRNO (ENETUNREACH),
#endif // ENETUNREACH
#ifdef ENETRESET
ERRNO (ENETRESET),
#endif // ENETRESET
#ifdef ECONNABORTED
ERRNO (ECONNABORTED),
#endif // ECONNABORTED
#ifdef ECONNRESET
ERRNO (ECONNRESET),
#endif // ECONNRESET
#ifdef ENOBUFS
ERRNO (ENOBUFS),
#endif // ENOBUFS
#ifdef EISCONN
ERRNO (EISCONN),
#endif // EISCONN
#ifdef ENOTCONN
ERRNO (ENOTCONN),
#endif // ENOTCONN
#ifdef ESHUTDOWN
ERRNO (ESHUTDOWN),
#endif // ESHUTDOWN
#ifdef ETOOMANYREFS
ERRNO (ETOOMANYREFS),
#endif // ETOOMANYREFS
#ifdef ETIMEDOUT
ERRNO (ETIMEDOUT),
#endif // ETIMEDOUT
#ifdef ECONNREFUSED
ERRNO (ECONNREFUSED),
#endif // ECONNREFUSED
#ifdef EHOSTDOWN
ERRNO (EHOSTDOWN),
#endif // EHOSTDOWN
#ifdef EHOSTUNREACH
ERRNO (EHOSTUNREACH),
#endif // EHOSTUNREACH
#ifdef EWOULDBLOCK
ERRNO (EWOULDBLOCK),
#endif // EWOULDBLOCK
#ifdef EALREADY
ERRNO (EALREADY),
#endif // EALREADY
#ifdef EINPROGRESS
ERRNO (EINPROGRESS),
#endif // EINPROGRESS
#ifdef ESTALE
ERRNO (ESTALE),
#endif // ESTALE
{ -1, 0 }
};
const char* str = strerror (val);
char smallbuf [32];
if (spec.fl_pound || 0 == str) {
const char *name = 0;
for (size_t i = 0; i != sizeof names / sizeof *names; ++i) {
if (names [i].val == val) {
name = names [i].str;
break;
}
}
if (0 == name) {
sprintf (smallbuf, "E#%d", val);
str = smallbuf;
}
else
str = name;
}
FmtSpec newspec (spec);
newspec.width = 0;
newspec.fl_pound = 0;
return _rw_fmtstr (newspec, buf, str, _RWSTD_SIZE_MAX);
}
/********************************************************************/
/* extern */ int
_rw_fmtlasterror (const FmtSpec &spec, Buffer &buf, int val)
{
#ifdef _WIN32
LPVOID pmsg;
FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM
| FORMAT_MESSAGE_IGNORE_INSERTS,
0, (DWORD)val,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR)&pmsg,
0, 0);
FmtSpec newspec (spec);
newspec.width = 0;
newspec.fl_pound = 0;
const int result = _rw_fmtstr (newspec, buf,
_RWSTD_STATIC_CAST (const char*, pmsg),
_RWSTD_SIZE_MAX);
LocalFree (pmsg);
return result;
#else // if !defined (_WIN32)
return _rw_fmterrno (spec, buf, val);
#endif // _WIN32
}
/********************************************************************/
/* extern */ int
_rw_fmtmask (const FmtSpec &spec, Buffer &buf, int bits)
{
static const Bitnames names [] = {
BITNAME (std::ctype_base, alnum),
BITNAME (std::ctype_base, alpha),
BITNAME (std::ctype_base, cntrl),
BITNAME (std::ctype_base, digit),
BITNAME (std::ctype_base, graph),
BITNAME (std::ctype_base, lower),
BITNAME (std::ctype_base, print),
BITNAME (std::ctype_base, punct),
BITNAME (std::ctype_base, space),
BITNAME (std::ctype_base, upper),
BITNAME (std::ctype_base, xdigit)
};
static const size_t count = sizeof names / sizeof *names;
return _rw_bmpfmt (spec, buf, names, count, bits);
}
/********************************************************************/
/* extern */ int
_rw_fmtcharmask (const FmtSpec &spec, Buffer &buf, int c)
{
enum {
bit_alnum = 1,
bit_alpha = 1 << 1,
bit_cntrl = 1 << 2,
bit_digit = 1 << 3,
bit_graph = 1 << 4,
bit_lower = 1 << 5,
bit_print = 1 << 6,
bit_punct = 1 << 7,
bit_space = 1 << 8,
bit_upper = 1 << 9,
bit_xdigit = 1 << 10
};
int mask = 0;
if (spec.fl_pound) {
#ifndef _RWSTD_NO_WCHAR_H
mask |= iswalnum (c) ? bit_alnum : 0;
mask |= iswalpha (c) ? bit_alpha : 0;
mask |= iswcntrl (c) ? bit_cntrl : 0;
mask |= iswdigit (c) ? bit_digit : 0;
mask |= iswgraph (c) ? bit_graph : 0;
mask |= iswlower (c) ? bit_lower : 0;
mask |= iswprint (c) ? bit_print : 0;
mask |= iswpunct (c) ? bit_punct : 0;
mask |= iswspace (c) ? bit_space : 0;
mask |= iswupper (c) ? bit_upper : 0;
mask |= iswxdigit (c) ? bit_xdigit : 0;
#endif // _RWSTD_NO_WCHAR_H
}
else {
const unsigned char uc = c;
mask |= isalnum (uc) ? bit_alnum : 0;
mask |= isalpha (uc) ? bit_alpha : 0;
mask |= iscntrl (uc) ? bit_cntrl : 0;
mask |= isdigit (uc) ? bit_digit : 0;
mask |= isgraph (uc) ? bit_graph : 0;
mask |= islower (uc) ? bit_lower : 0;
mask |= isprint (uc) ? bit_print : 0;
mask |= ispunct (uc) ? bit_punct : 0;
mask |= isspace (uc) ? bit_space : 0;
mask |= isupper (uc) ? bit_upper : 0;
mask |= isxdigit (uc) ? bit_xdigit : 0;
}
char mask_str [80];
char *str = mask_str;
str [0] = '\0';
#define APPEND(bit) \
if (mask & bit_ ## bit) \
strcat (strcat (str, #bit), "|"); \
else (void)0
APPEND (alnum);
APPEND (alpha);
APPEND (cntrl);
APPEND (digit);
APPEND (graph);
APPEND (lower);
APPEND (print);
APPEND (punct);
APPEND (space);
APPEND (upper);
APPEND (xdigit);
if (str == mask_str)
*str = '\0';
else
str [-1] = '\0';
FmtSpec newspec (spec);
newspec.fl_pound = 0;
return _rw_fmtstr (newspec, buf, str, _RWSTD_SIZE_MAX);
}
/********************************************************************/
/* extern */ int
_rw_fmtbits (const FmtSpec &spec, Buffer &buf,
const void *pelems, size_t elemsize)
{
const size_t nbits = spec.prec;
char bitbuf [256];
char *pbits = nbits < sizeof bitbuf ? bitbuf : new char [nbits + 1];
for (size_t bitno = 0; bitno != nbits; ++bitno) {
if (bitno && 0 == (bitno % (elemsize * _RWSTD_CHAR_BIT)))
pelems = _RWSTD_STATIC_CAST (const UChar*, pelems) + elemsize;
size_t bit = 1 << (bitno & (_RWSTD_CHAR_BIT * elemsize - 1));
switch (elemsize) {
case _RWSTD_CHAR_SIZE:
bit = *_RWSTD_STATIC_CAST (const UChar*, pelems) & bit;
break;
#if _RWSTD_CHAR_SIZE < _RWSTD_SHRT_SIZE
case _RWSTD_SHRT_SIZE:
bit = *_RWSTD_STATIC_CAST (const UShrt*, pelems) & bit;
break;
#endif // sizeof (char) < sizeof (short)
#if _RWSTD_SHRT_SIZE < _RWSTD_INT_SIZE
case _RWSTD_INT_SIZE:
bit = *_RWSTD_STATIC_CAST (const UInt*, pelems) & bit;
break;
#endif // sizeof (short) < sizeof (int)
#if _RWSTD_INT_SIZE < _RWSTD_LONG_SIZE
case _RWSTD_LONG_SIZE:
bit = *_RWSTD_STATIC_CAST (const ULong*, pelems) & bit;
break;
#endif // sizeof (int) < sizeof (long)
#if _RWSTD_LONG_SIZE < _RWSTD_LLONG_SIZE
case _RWSTD_LLONG_SIZE:
bit = *_RWSTD_STATIC_CAST (const ULLong*, pelems) & bit;
break;
#endif // sizeof (long) < sizeof (long long)
default:
RW_ASSERT (!"logic error: bad element size");
}
pbits [bitno] = bit ? '1' : '0';
}
const int res = _rw_fmtstr (spec, buf, pbits, nbits);
if (pbits != bitbuf)
delete[] pbits;
return res;
}