| /************************************************************************ |
| * |
| * 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; |
| } |