Exemple #1
0
_RWSTD_EXPORT int
__rw_get_num (void *pval, const char *buf, int type, int flags,
              const char *groups, _RWSTD_SIZE_T ngroups,
              const char *grouping, _RWSTD_SIZE_T ngroupings)
{
    // 22.2.2.1.2, p3: Stage 1
    int err = 0;   // errno value, ERANGE, or 0

    _RWSTD_ASSERT (0 != buf);
    _RWSTD_ASSERT ('+' == *buf || '-' == *buf);

    if (!(type & __rw_facet::_C_floating)) {

        //////////////////////////////////////////////////////////////
        // integral parsing (including void*)

        int base = unsigned (flags) >> _RWSTD_IOS_BASEOFF;

        if (!base)
            base = 10;

        union {
#ifdef _RWSTD_LONG_LONG

            _RWSTD_LONG_LONG           ll;
            unsigned _RWSTD_LONG_LONG ull;

#endif   // _RWSTD_LONG_LONG

            long           l;
            unsigned long ul;
        } val;

        if (1 == base) {
            // treat numeric (i.e., non-Roman) input in base-1 as decimal
            const UChar digit = __rw_digit_map [UChar (buf [1])];

            if (digit < 10) {
                val.ul = _RW::__rw_strtoul (buf, &err, 10);
            }
            else {
                _RWSTD_ASSERT ('+' == *buf);

                val.ul = __rw_get_roman (buf + 1);
            }

            val.l = _RWSTD_STATIC_CAST (long, val.ul);
        }
        else if (__rw_facet::_C_ullong == type) {
Exemple #2
0
_RWSTD_SIZE_T gslice::next_ind ()
{
    _RWSTD_SIZE_T __n = _C_length.size ();

    while (__n && _C_r_length [__n - 1] == _C_length [__n - 1] - 1)
        --__n;

    if (0 == __n) {
        _C_reset    = true;
        _C_r_length = 0;
        return _C_start;
    }
     
    if (_C_reset) {
        _C_reset = false;
        return _C_start;
    }

    _RWSTD_ASSERT (0 < __n);

    ++_C_r_length [__n - 1];

    if (__n < _C_r_length.size ())
        ::memset (&_C_r_length [__n], 0,
                  (_C_r_length.size () - __n) * sizeof _C_r_length [__n]);
    else
        __n = _C_r_length.size ();

    _RWSTD_SIZE_T __inx = _C_start;
    for (_RWSTD_SIZE_T __i = 0; __i != __n; ++__i)
        __inx += _C_r_length [__i] * _C_stride [__i];

    return __inx;
}
Exemple #3
0
/* virtual */ strstreambuf::int_type
strstreambuf::underflow ()
{
    _RWSTD_ASSERT (_C_is_valid ());

    if (gptr () < egptr ()) {
        // read position is available (see 27.5.1, p3, bullet 4)

        // D.7.1.3, p9, bullet 1
        return traits_type::to_int_type (*gptr ());
    }

    if (pptr () > egptr ()) {

        // D.7.1.3, p9, bullet 2
        if (gptr ())
            setg (eback (), gptr (), pptr ());
        else
            setg (pbase (), pbase (), pptr ());

        return traits_type::to_int_type (*gptr ());
    }

    // D.7.1.3, p10
    return traits_type::eof ();
}
Exemple #4
0
_RWSTD_EXPORT void*
__rw_fopen (const char *fname, int openmode, long prot)
{
    if (openmode & _RWSTD_IOS_STDIO) {

        // convert the iostream open mode to the C stdio file open mode
        const char* const fmode = __rw_stdio_mode (openmode);

        _RWSTD_ASSERT (0 != fmode);

        // fmode is the empty string on failure
        if ('\0' == *fmode)
            return 0;

        FILE *file;

        if (fname) {
            // open the named file using C stdio
            file = fopen (fname, fmode);
        }
        else {
            // FIXME: check openmode to make sure it's valid for "w+"

            // extension: create a temporary file for update ("w+")
            // that will be automatically deleted when all references
            // to the file are closed
            file = tmpfile ();
        }

        if (0 == file)
            return 0;

        return _RWSTD_STATIC_CAST (void*, file);
    }

    // convert the iostream open mode to the POSIX file access mode
    const int fdmode = __rw_io_mode (openmode);

    if (fdmode < 0)
        return 0;

    int fd;

    if (fname) {
        // open the named file
        fd = open (fname, fdmode, prot);
    }
    else {
        // extension: create a temporary file that will be deleted
        // when the last file descriptor that refers to it is closed
        fd = __rw_mkstemp (fdmode, prot);
    }

    if (fd < 0)
        return 0;

    return _RWSTD_REINTERPRET_CAST (void*, fd + 1);
}
Exemple #5
0
/* virtual */ strstreambuf::pos_type
strstreambuf::seekpos (pos_type sp, ios::openmode which)
{
    _RWSTD_ASSERT (_C_is_valid ());

    // call seekoff() defined by strstreambuf, and
    // not an overridden() virtual if one exists
    return strstreambuf::seekoff (sp - pos_type (), ios::beg, which);
}
Exemple #6
0
/* virtual */
strstreambuf::~strstreambuf ()
{
    _RWSTD_ASSERT (_C_is_valid ());

    if (   _C_buffer && _C_state & _C_allocated
        && !(_C_state & _C_frozen)) {
        if (_C_pfree)
            _C_pfree (_C_buffer);
        else
            delete[] _C_buffer;
    }
}
Exemple #7
0
static const void*
__rw_get_numpunct (const __rw_facet *pfacet, int flags)
{
    const int   member = flags & ~(__rw_mon | __rw_wide | __rw_intl);
    const bool  winx   = !!(flags & __rw_wide);   // wide or narrow index
    const void *pdata  = pfacet->_C_data ();      // mapped locale database

    if (pdata) {

        const __rw_punct_t* const pun =
            _RWSTD_STATIC_CAST (const __rw_punct_t*, pdata);

        const __rw_num_t *num;
    
        switch (member) {

        case __rw_dp: return pun->decimal_point (winx);
        case __rw_ts: return pun->thousands_sep (winx);
        case __rw_gr: return pun->grouping ();

        case __rw_tn:
            num = _RWSTD_STATIC_CAST (const __rw_num_t*, pun->get_ext ());
            _RWSTD_ASSERT (num);
            return num->truename (winx);

        case __rw_fn:
            num = _RWSTD_STATIC_CAST (const __rw_num_t*, pun->get_ext ());
            _RWSTD_ASSERT (num);
            return num->falsename (winx);

        default: _RWSTD_ASSERT (!"bad discriminant");
        }

        return 0;
    }
    else if (0 == __rw_access::_C_get_name (*pfacet)) {   // "C" locale
Exemple #8
0
std::money_base::pattern
set_pattern (const char *format)
{
    std::money_base::pattern pat;

    for (unsigned i = 0; i != sizeof pat.field / sizeof *pat.field; ++i) {
        switch (format [i]) {
        case '\0': case '@': pat.field [i] = std::money_base::none; break;
        case '\1': case ' ': pat.field [i] = std::money_base::space; break;
        case '\2': case '$': pat.field [i] = std::money_base::symbol; break;
        case '\3': case '-': pat.field [i] = std::money_base::sign; break;
        case '\4': case '1': pat.field [i] = std::money_base::value; break;
        default:
            _RWSTD_ASSERT (!!"bad format specifier");
        }
    }

    return pat;
}
Exemple #9
0
_RWSTD_EXPORT _RWSTD_SIZE_T
__rw_rand (_RWSTD_SIZE_T limit)
{
    _RWSTD_ASSERT (0 != limit);

#ifdef _RWSTD_NO_TLS

    _RWSTD_MT_STATIC_GUARD (_RandGuardT);

#endif   // _RWSTD_NO_TLS

    if (0 == __rw_inx [0] && 0 == __rw_inx [1])
        __rw_seed (161803398U);

    __rw_table [++__rw_inx [0] %= __rw_table_size] -=
        __rw_table [++__rw_inx [1] %= __rw_table_size];

    return __rw_table [__rw_inx [0]] % limit;

}
Exemple #10
0
/* virtual */ strstreambuf::int_type
strstreambuf::pbackfail (int_type c)
{
    _RWSTD_ASSERT (_C_is_valid ());

    typedef traits_type Traits;

    if (eback () < gptr ()) {

        // putback position is available (see 27.5.1, p3, bullet 3)

        if (Traits::eq_int_type (c, Traits::eof ())) {

            // D.7.1.3, p6, bullet 3

            gbump (-1);
            return Traits::not_eof (c);
        }

        if (Traits::eq_int_type (Traits::to_int_type (*(gptr () - 1)), c)) {

            // D.7.1.3, p6, bullet 1

            gbump (-1);
            return c;
        }

        if (!(_C_state & _C_constant)) {

            // D.7.1.3, p6, bullet 2

            gbump (-1);
            Traits::assign (*gptr (), Traits::to_char_type (c));
            return c;
        }
    }

    // D.7.1.3, p7
    return Traits::eof ();
}
Exemple #11
0
// one-time initializer for the classic wide_tab
static void
__rw_init_classic_wide_tab ()
{
#  ifdef _RWSTDDEBUG

    static int init;

    // paranoid check: verify that one-time initialization works
    _RWSTD_ASSERT (0 == init);

    ++init;

#  endif   // _RWSTDDEBUG

    // init the classic wide tab
    wchar_t wc_array [_STD::ctype<char>::table_size];

    for (wchar_t wc = 0; wc < _STD::ctype<char>::table_size; ++wc)
        wc_array [wc] = wc;

    __rw_get_mask (0, wc_array, wc_array + _STD::ctype<char>::table_size,
                   __rw_all, __rw_classic_wide_tab, false, false, "C");
}
Exemple #12
0
/* virtual */ strstreambuf::int_type
strstreambuf::overflow (int_type c)
{
    _RWSTD_ASSERT (_C_is_valid ());

    if (!_C_is_out () || !(_C_state & _C_dynamic))
        return traits_type::eof ();
    
    if (_C_is_eof (c))
        return traits_type::not_eof (c);
    
    // reallocate space if necessary
    if (!(pptr () < epptr ())) {

        const streamsize new_size =
            _C_bufsize ? _C_bufsize * 2 : _C_alsize ? _C_alsize : 128;

        // take care to avoid calling the overridden setbuf(), if any
        if (!strstreambuf::setbuf (0, new_size))
            return traits_type::eof ();
    }

    return sputc (traits_type::to_char_type (c));
}
Exemple #13
0
/* virtual */ streambuf*
strstreambuf::setbuf (char_type* buf, streamsize bufsize)
{
    _RWSTD_ASSERT (_C_is_valid ());

    if (   !(_C_state & _C_dynamic) || (_C_state & _C_frozen)
        || (!buf && !bufsize)) {
        // lwg issue 66
        return 0;
    }

    // determine the existing (possibly disjoint) sequences
    // in the (possibly two distinct) buffer(s) and copy
    // them into the new buffer

    // [.....]  [.....]          or [....[.]...]
    // ^     ^  ^     ^             ^          ^
    // |     |  |     |             |          |
    // |     |  |     +- xend       |          +- xend, gap_beg, gap_end
    // |     |  +------- gap_end    +------------ xbeg
    // |     +---------- gap_beg
    // +---------------- xbeg

    const char_type* const xbeg =
        eback () && eback () < pbase () ? eback () : pbase ();

    const char_type* const xend =
        epptr () && epptr () < egptr () ? egptr () : epptr ();

    const char_type *gap_beg = pptr () < eback ()
        ? pptr () : egptr () < pbase () ? egptr () : pbase ();

    const char_type *gap_end = pptr () < eback ()
        ? eback () : egptr () < pbase () ? egptr () : pbase ();

    // if gap_end is before gap_beg, set both so as to make the gap zero size
    if (gap_end <= gap_beg)
        gap_beg = gap_end = xend;

    // compute the cumulative size of both sequences minus the gap
    const streamsize slen = streamsize ((xend - xbeg) - (gap_end - gap_beg));

    if (bufsize < slen || !_C_is_out ())
        return 0;   // failure

    const bool free_old_buf = _C_own_buf ();
    
    if (!buf) {
        _TRY {
            // allocate a new buffer
            buf = _C_palloc ?
                  _RWSTD_STATIC_CAST (char_type*, _C_palloc (bufsize))
                : new char [bufsize];
        }
        _CATCH (...) {
            // catch all exceptions, indicate failure by returning 0
        }

        if (!buf)
            return 0;

        _C_own_buf (true);
    }
Exemple #14
0
/* static */ __rw_locale* __rw_locale::
_C_get_body (__rw_locale      *one,
             __rw_locale      *other,
             const char       *locname,
             int               cat,
             const __rw_facet *pfacet)
{
    __rw_chararray realname;

    // see if `locname' contains embedded "LC_XXX=..." sequences
    if (locname && !strncmp (locname, "LC_", 3)) {

        // convert a combined locale name (consisting of a sequence
        // of `sep'-separated LC_XXX=<name> substrings) to a normalized
        // form in the expected (internal) format and order

        const char *pcatnames [__rw_n_cats] = { 0 };

        // try the libc "native" separator first, semicolon next
        const char *sep = strchr (locname, *_RWSTD_CAT_SEP);
        if (!sep)
            sep = ";";

        for (const char *s = locname; *s; ) {

            const char *next = strchr (s, *sep);
            if (!next)
                next = s + strlen (s);

            const char* const endcat = strchr (s, '=');
            if (!endcat)
                return 0;   // error: missing `=' after LC_XXX

            // go through the LC_XXX category names, trying to find
            // a match; if found, remember its position (duplicates
            // are not allowed)

            for (_RWSTD_SIZE_T i = 0; i != __rw_n_cats; ++i) {
                if (!strncmp (__rw_cats [i].name, s, endcat - s)) {
                    if (pcatnames [i])
                        return 0;    // error: duplicate LC_XXX

                    pcatnames [i] = endcat + 1;
                    break;
                }
            }

            s = *next ? next + 1 : next;
        }

        // compose a normalized locale name out of category names
        _RWSTD_SIZE_T size = 0;
        for (_RWSTD_SIZE_T i = 0; i != __rw_n_cats; ++i) {

            if (!pcatnames [i]) {
                // use "C" for missing LC_XXX values
                pcatnames [i] = "C";
            }

            const char *endcat = strchr (pcatnames [i], *sep);

            if (!endcat)
                endcat = pcatnames [i] + strlen (pcatnames [i]);

            const _RWSTD_SIZE_T catsize = endcat - pcatnames [i];

            // append name followed by the libc "native" separator
            realname.append (pcatnames [i], catsize);
            realname.append (_RWSTD_CAT_SEP, 1);

            size += catsize;
        }

        locname = realname.data ();
    }
    else if (locname && *locname == *_RWSTD_CAT_SEP) {
        // advance past the leading category separator if present
        ++locname;
    }

    if (!one && !other && !locname && _STD::locale::none == cat && !pfacet) {
        // implements default ctor: locale::locale () throw ()
        __rw_locale* const global = __rw_locale::_C_manage (0, 0);

        _RWSTD_ASSERT (0 != global);

        return global;
    }

    if (one && !other && !locname && _STD::locale::none == cat && !pfacet) {
        // copy ctor: locale::locale (const locale&)
        // or combining ctor: locale::locale (const locale&, Facet*)
        // (in the second case with Facet* being 0)
        // body may or may not be globally managed
        // or locale::operator=(const locale&)
        _RWSTD_ATOMIC_PREINCREMENT (one->_C_ref, false);
        return one;
    }

    if (!one && !other && locname && _STD::locale::none == cat && !pfacet) {
        // ctor: locale::locale (const char*)
        // if successful, body is globally managed
         __rw_locale* const plocale = __rw_locale::_C_manage (0, locname);

         _RWSTD_ASSERT (!plocale || plocale->_C_is_managed (_STD::locale::none));

        return plocale;
    }

    if (one && !other && !locname && _STD::locale::none == cat && pfacet) {
        // template ctor: locale::locale (const locale&, Facet*)
        // with `pfacet' being installed (e.g., adding or replacing
        // an existing one)
        // template <class Facet> locale::combine(const locale&) is
        // trivially implemented inline in terms of the template ctor
        __rw_locale* const plocale = one->_C_combine (pfacet);

        _RWSTD_ASSERT (0 != plocale);

        return plocale;
    }

    if (one && !other && locname && !pfacet) {
        // combining ctor: locale (const locale&, const char*, category)

        // construct a temporary locale from locale name `locname'
        const _STD::locale tmp (locname);

        // construct a locale combined from `one' and the temporary
        __rw_locale* const plocale = one->_C_combine (*tmp._C_body, cat);

        return plocale;
    }

    if (one && other && !locname && !pfacet) {
        // combining ctor: locale (const locale&, const locale&, category)
        return one->_C_combine (*other, cat);
    }

    _RWSTD_ASSERT (!"logic error: bad combination of arguments");

    return 0;
}
Exemple #15
0
void __rw_locale::
_C_construct (const __rw_locale &rhs, const __rw_facet *pfacet)
{
    // called from ctor only, members are not initialized
    _C_ref = 1;

    // copy standard facets from other locale
#if defined (__i386__) || !defined (__GNUG__) || __GNUG__ < 3

    memcpy (_C_std_facets, rhs._C_std_facets,
            _C_n_std_facets * sizeof *_C_std_facets);

#else   // !i86  || !gcc 3.x

    // Working around a bug (most probably) identical to the one described 
    // and fixed in __rw_locale::__rw_locale, but related to the use of
    // memcpy.

    for(_RWSTD_SIZE_T i = 0; i != _C_n_std_facets; i++)
        _C_std_facets [i] = rhs._C_std_facets [i];

#endif   // i86/gcc 3.x

    _RWSTD_ASSERT (!pfacet || pfacet->_C_pid);

    // get facet's index into one of the facet arrays
    _RWSTD_SIZE_T inx = pfacet
        ? rhs._C_get_facet_inx (*pfacet->_C_pid) : (_RWSTD_SIZE_T)(-1);

    // extend size if facet isn't installed in `rhs'
    _C_n_usr_facets =   rhs._C_n_usr_facets
                      + (inx > rhs._C_n_usr_facets + _C_n_std_facets);

    // allocate a buffer for user facets if necesary
    _C_usr_facets = _C_n_usr_facets ? new __rw_facet* [_C_n_usr_facets] : 0;

    // copy facets from other locale
    memcpy (_C_usr_facets, rhs._C_usr_facets,
            rhs._C_n_usr_facets * sizeof *_C_usr_facets);

    _RWSTD_ASSERT (rhs._C_name);

    _C_name = 0;

    // copy facet bits from `rhs' and adjust below as necessary
    _C_std_facet_bits    = rhs._C_std_facet_bits;
    _C_byname_facet_bits = rhs._C_byname_facet_bits;

    if (pfacet) {
        __rw_facet* const pf = _RWSTD_CONST_CAST (__rw_facet*, pfacet);
        // overwrite an existing pointer or add a new one
        if (inx < _C_n_std_facets) {
            _C_std_facets [inx] = pf;

            const _RWSTD_SIZE_T facet_bit = 1UL << inx;

            // set or clear a corresponding bit based on whether
            // the facet is one of the standard facets or not
            // (user-defined objects even if they are of standard
            // facet types, are not considered standard facets)
            if (pf->_C_type > 0)
                _C_std_facet_bits |= facet_bit;
            else
                _C_std_facet_bits &= ~facet_bit;

            // ditto for named facet bitmap
            if (pf->_C_type & 1)   // even types are _byname
                _C_byname_facet_bits &= ~facet_bit;
            else
                _C_byname_facet_bits |= facet_bit;

            // construct a new name
            // _C_name =
            //     _C_make_name (_C_namebuf, sizeof _C_namebuf, rhs, *pfacet);
        }
        else if ((_RWSTD_SIZE_T)(-1) == inx)
            _C_usr_facets [_C_n_usr_facets - 1] = pf;
        else
            _C_usr_facets [inx - _C_n_std_facets] = pf;
    }

    if (!_C_name) {
        // simply copy name from `rhs'
        const _RWSTD_SIZE_T size = strlen (rhs._C_name) + 1;
        char* const name = size <= sizeof _C_namebuf
            ? _C_namebuf : new char [size];

        memcpy (name, rhs._C_name, size);
        _C_name = name;
    }

    // increment reference counts for facets (including the newly added one)
    for (inx = 0; inx != _C_n_std_facets; ++inx) {
        if (_C_std_facets [inx])
            _RWSTD_ATOMIC_PREINCREMENT (_C_std_facets [inx]->_C_ref,
                                        _C_std_facets [inx]->_C_mutex);
    }
    
    for (inx = 0; inx != _C_n_usr_facets; ++inx) {
        _RWSTD_ATOMIC_PREINCREMENT (_C_usr_facets [inx]->_C_ref,
                                    _C_usr_facets [inx]->_C_mutex);
    }
}
Exemple #16
0
void do_test (int             line,     // line number of test case
              const char     *src,      // source sequence
              std::size_t     resoff,   // offset of result
              ForwardIterator dummy_iter,
              const T*,
              const char*     predname)
{
    static const char* const itname = type_name (dummy_iter, (T*)0);

    const std::size_t nsrc = std::strlen (src);

    if (std::size_t (-1) == resoff)
        resoff = nsrc;

    // have the UserClass default ctor initialize objects from `src'
    xinit_begin = src;
    UserClass::gen_     = xinit;

    UserClass* const xsrc = new UserClass [nsrc];

    const ForwardIterator first =
        make_iter (xsrc, xsrc, xsrc + nsrc, dummy_iter);

    const ForwardIterator last =
        make_iter (xsrc + nsrc, xsrc, xsrc + nsrc, dummy_iter);

    // reset predicate counters
    UserClass::n_total_op_eq_                  = 0;
    EqualityPredicate<T, T>::funcalls_ = 0;

    // construct a predicate object
    const EqualityPredicate<T, T> pred (0, 0);

    const ForwardIterator res = predname ?
          std::adjacent_find (first, last, pred)
        : std::adjacent_find (first, last);

    // silence a bogus EDG eccp remark #550-D:
    // variable "res" was set but never used
    _RWSTD_UNUSED (res);

    const std::size_t n_total_pred = predname ?
          EqualityPredicate<T, T>::funcalls_
        : UserClass::n_total_op_eq_;

    // verify that the returned iterator is set as expected
    int success = res.cur_ == first.cur_ + resoff;
    rw_assert (success, 0, line, 
               "line %d: adjacent_find<%s>(it = \"%s\", ...)"
               " == (it + %zu), got (it + %td)",
               __LINE__, itname, src,
               resoff, res.cur_ - first.cur_);

    // verify the number of applications of the predicate (lwg issue 240):
    // Complexity: For a nonempty range, exactly
    //             min((i - first) + 1, (last - first) - 1)
    // applications of the corresponding predicate, where i is
    // adjacent_find's return value.

    // compute the expected number of invocations of the predicate
    std::size_t n_expect_pred = 0;

    if (nsrc) {
        // test iterators are guaranteed to be in range
        _RWSTD_ASSERT (first.cur_ <= res.cur_ && res.cur_ <= last.cur_);

        n_expect_pred = std::size_t (res.cur_ - first.cur_) + 1;
        const std::size_t tmp = std::size_t (last.cur_ - first.cur_) - 1;
        if (tmp < n_expect_pred)
            n_expect_pred = tmp;
    }

    success = std::size_t (n_expect_pred) == n_total_pred;
    rw_assert (success, 0, line, 
               "line %d: adjacent_find<%s>(\"%s\", ...) "
               "invoked %s %zu times, expected %td",
               __LINE__, itname, src,
               predname ? predname : "operator==()", 
               n_total_pred, n_expect_pred);
}
Exemple #17
0
_RW::__rw_locale* __rw_locale::
_C_combine (const __rw_facet *pfacet) const
{
    _RWSTD_ASSERT (pfacet);

    // template ctor: locale::locale (const locale&, Facet*)
    // with `facet' being installed (e.g., adding or replacing
    // an existing one)

    // verify that Facet::id has been initialized
    _RWSTD_ASSERT (pfacet->_C_pid);
    _RWSTD_ASSERT (*pfacet->_C_pid);

    // get the locale name ("C" if it's NUL)
    const char* const one_locname = _C_name ? _C_name : "C";

    // get the name of the locale `*pfacet' belongs to
    const char* const facet_locname =
        pfacet->_C_name ? pfacet->_C_name : "C";

    // get the locale::category that `*pfacet' belongs to
    const int facet_cat =
        _C_LC2category (__rw_get_cat (int (*pfacet->_C_pid)));

    bool managed = false;

    if (pfacet->_C_type && !_C_n_usr_facets) {

        // facet is one of the (perhaps byname) standard facets

        // compute the number of the bit in _C_std_facet_bits or
        //_C_byname_facet_bits corresponding to the facet being
        // used (i.e., `*pfacet')
        const _RWSTD_SIZE_T facet_bit =
            (_RWSTD_SIZE_T)1U << (*pfacet->_C_pid - 1U);

        // a locale object is globally managed if all its facets are objects
        // of standard facet types (ordinary or byname) that were constructed
        // by the library and within each locale category all facets belong
        // to the same facet
        // managed locales have names that completely describe their facets
        // and from which they can be unambiguously and fully constructed
        //
        // note that in the code snippet below, x0 is not a managed locale
        // (its name is "*"), but y0 is a managed locale (on SunOS, its name
        // is "/de_DE/de_DE/de_DE/de_DE/de_DE/en_US"); x1 is the same as x0
        // and y1 is the same as de:
        //
        //   locale de ("de_DE");
        //   locale en ("en_US");
        //   locale x0 = de.combine<messages<char> >(en);
        //   locale y0 = x0.combine<messages<wchar_t> >(en);
        //   locale x1 = y0.combine<messages<wchar_t> >(de);
        //   locale y1 = x1.combine<messages<char> >(de);
        //   assert (de == y1);
        //   assert (x0 == x1);

        if (__rw_locale::_C_all == (_C_std_facet_bits | facet_bit)) {

            // compute the bitmask corresponding to all the facets in
            // the same category as the one to which `*pfacet' belongs
            const int cat_bits = _C_LC2facet_bits (facet_cat);

            // get the index into the _C_std_facets array for `pfacet'
            const _RWSTD_SIZE_T facet_inx =
                _C_get_facet_inx (*pfacet->_C_pid);

            managed = true;

            // iterate over all facets that belong the same category
            // as `*pfacet' and compare the name of each with the name
            // of `*pfacet' to determine if they all have the same name
            // _byname facets that are not installed yet (i.e., whose
            // pointers are 0 come from a locale whose name is given
            // by the name of the whole locale
            for (_RWSTD_SIZE_T i = 0; i != _C_n_std_facets; ++i) {

                // skip facets from other categories
                if (!((1 << i) & cat_bits))
                    continue;

                // skip the facet being replaced
                if (facet_inx == i)
                    continue;

                const char* const ones_facet_locname =
                      _C_std_facets [i] ? _C_std_facets [i]->_C_name
                    ? _C_std_facets [i]->_C_name : "C" : one_locname;

                if (strcmp (facet_locname, ones_facet_locname)) {
                    managed = false;
                    break;
                }
            }
        }
    }

    __rw_locale *plocale;

    if (managed) {

        __rw_chararray locname;
        __rw_combine_names (locname, one_locname, facet_locname, facet_cat);

        plocale = __rw_locale::_C_manage (0, locname.data ());

        _RWSTD_ASSERT (0 != plocale);
        _RWSTD_ASSERT (plocale->_C_is_managed (_STD::locale::none));
    }
    else {
        plocale = new __rw_locale (*this, pfacet);
        
        _RWSTD_ASSERT (0 != plocale);
        _RWSTD_ASSERT (!plocale->_C_is_managed (_STD::locale::none));
    }

    return plocale;
}
void do_test (int         line,     // line number of test case
              const char *src,      // source sequence
              std::size_t resoff,   // offset of result
              ForwardIterator    dummy_iter,
              const T*,
              const char* predicate)
{
    static const char* const itname = type_name (dummy_iter, (T*)0);

   #ifdef __SYMBIAN32__
     const size_t nsrc = strlen (src);
   #else  
    const std::size_t nsrc = std::strlen (src);
   #endif //__SYMBIAN32__
     
    if (std::size_t (-1) == resoff)
        resoff = nsrc;

    // have the X default ctor initialize objects from `src'
    xinit_begin = src;
    #ifndef __SYMBIAN32__
     X::gen_     = xinit;
    #else
     gen_     = xinit;
    #endif 

    X* const xsrc = new X [nsrc];

    const ForwardIterator first =
        make_iter (xsrc, xsrc, xsrc + nsrc, dummy_iter);

    const ForwardIterator last =
        make_iter (xsrc + nsrc, xsrc, xsrc + nsrc, dummy_iter);

    // compute the number of invocations of the predicate
    #ifndef __SYMBIAN32__
     std::size_t n_total_pred = X::n_total_op_eq_;
    #else
    std::size_t n_total_pred = n_total_op_eq_;
    #endif 
    const ForwardIterator res =
        predicate ? std::adjacent_find (first, last, std::equal_to<X>())
                  : std::adjacent_find (first, last);

    // silence a bogus EDG eccp remark #550-D:
    // variable "res" was set but never used
    _RWSTD_UNUSED (res);
    
    #ifndef __SYMBIAN32__
    n_total_pred =X::n_total_op_eq_ - n_total_pred;
    #else
    n_total_pred = n_total_op_eq_ - n_total_pred;
    #endif
    // verify that the returned iterator is set as expected
    int success = res.cur_ == first.cur_ + resoff;
    
    if(!success)
      {
        failures++;
       std_log(LOG_FILENAME_LINE,"Reason: Failing as expected iterator is not returned"); 
      }
       
   
    rw_assert (success, 0, line, 
               "line %d: adjacent_find<%s>(it = \"%s\", ...)"
               " == (it + %zu), got (it + %td)",
               __LINE__, itname, src,
               resoff, res.cur_ - first.cur_);

    // verify the number of applications of the predicate (lwg issue 240):
    // Complexity: For a nonempty range, exactly
    //             min((i - first) + 1, (last - first) - 1)
    // applications of the corresponding predicate, where i is
    // adjacent_find's return value.

    // compute the expected number of invocations of the predicate
    std::size_t n_expect_pred = 0;

    if (nsrc) {
        // test iterators are guaranteed to be in range
        _RWSTD_ASSERT (first.cur_ <= res.cur_ && res.cur_ <= last.cur_);

        n_expect_pred = std::size_t (res.cur_ - first.cur_) + 1;
        const std::size_t tmp = std::size_t (last.cur_ - first.cur_) - 1;
        if (tmp < n_expect_pred)
            n_expect_pred = tmp;
    }

    success = std::size_t (n_expect_pred) == n_total_pred;
    
    if(!success)
     {
       failures ++;
       std_log(LOG_FILENAME_LINE,"Reason: Failing as iteratoris not in range");
      }
    rw_assert (success, 0, line, 
               "line %d: adjacent_find<%s>(\"%s\", ...) "
               "invoked %s %zu times, expected %td",
               __LINE__, itname, src,
               predicate ? predicate : "operator==()", 
               n_total_pred, n_expect_pred);
}
Exemple #19
0
void __rw_locale::
_C_construct (const __rw_locale &one, const __rw_locale &other, int cat)
{
    // category must be valid at this point (checked by caller)
    _RWSTD_ASSERT (_C_check_category (cat));

    // called from ctor only, members are not initialized
    _C_ref = 1;

    // size is the same as that of `one'
    _C_n_usr_facets = one._C_n_usr_facets;

    // allocate only if internal buffer is insufficient
    _C_usr_facets = _C_n_usr_facets ?  new __rw_facet* [_C_n_usr_facets] : 0;

    // copy standard facets to `one' from `other'
    memcpy (_C_std_facets, one._C_std_facets,
            _C_n_std_facets * sizeof *_C_std_facets);

    // copy user-defined facets (if any)
    memcpy (_C_usr_facets, one._C_usr_facets,
            _C_n_usr_facets * sizeof *_C_usr_facets);

    // compute and assign facet bitmaps
    const int bits = _C_LC2facet_bits (cat);

    _C_std_facet_bits    =   one._C_std_facet_bits & ~bits
                           | other._C_std_facet_bits & bits;

    _C_byname_facet_bits =   one._C_byname_facet_bits & ~bits
                           | other._C_byname_facet_bits & bits;

    for (_RWSTD_SIZE_T i = 0; i != _C_n_std_facets; ++i) {

        // each facet is stored at an index equal to its (id - 1)
        // convert an LC_XXX constant to a locale::category value
        const int c = _C_LC2category (__rw_get_cat (int (i) + 1));

        if (cat & c) {
            // assign/overwrite corresponding facets
            _C_std_facets [i] = other._C_std_facets [i];
        }

        if (_C_std_facets [i]) {
            // bump up the facet's reference count of *this' facet
            _RWSTD_ATOMIC_PREINCREMENT (_C_std_facets [i]->_C_ref,
                                        _C_std_facets [i]->_C_mutex);
        }
    }

    // increment the ref count of user-defined facets (if any)
    for (_RWSTD_SIZE_T j = 0; j != _C_n_usr_facets; ++j) {

        _RWSTD_ASSERT (_C_usr_facets [j]);

        _RWSTD_ATOMIC_PREINCREMENT (_C_usr_facets [j]->_C_ref,
                                    _C_usr_facets [j]->_C_mutex);
    }

    __rw_chararray locname;

    __rw_combine_names (locname, one._C_name, other._C_name, cat);

    if (locname.size () >= one._C_namebuf_size)
        _C_name = locname.release ();
    else {
        _C_name = _C_namebuf;
        memcpy (_C_namebuf, locname.data (), locname.size () + 1);
    }
}
Exemple #20
0
void exception_loop (int              line /* line number in caller*/,
                     MemberFunction   mfun /* deque member function */,
                     const char      *fcall /* function call string */,
                     int              exceptions /* enabled exceptions */,
                     Deque           &deq /* container to call function on */,
                     const Deque::iterator &it /* iterator into container */,
                     int              n /* number of elements or offset */,
                     const UserClass *x /* pointer to an element or 0 */,
                     const Iterator  &first /* beginning of range */,
                     const Iterator  &last /* end of range to insert */,
                     int             *n_copy /* number of copy ctors */,
                     int             *n_asgn /* number of assignments */)
{
    std::size_t throw_after = 0;

    // get the initial size of the container and its begin() iterator
    // to detect illegal changes after an exception (i.e., violations
    // if the strong exception guarantee)
    const std::size_t           size  = deq.size ();
    const Deque::const_iterator begin = deq.begin ();
    const Deque::const_iterator end   = deq.end ();

#ifdef DEFINE_REPLACEMENT_NEW_AND_DELETE

    rwt_free_store* const pst = rwt_get_free_store (0);

#endif   // DEFINE_REPLACEMENT_NEW_AND_DELETE

    // repeatedly call the specified member function until it returns
    // without throwing an exception
    for ( ; ; ) {

        // detect objects constructed but not destroyed after an exception
        std::size_t x_count = UserClass::count_;

        _RWSTD_ASSERT (n_copy);
        _RWSTD_ASSERT (n_asgn);

        *n_copy = UserClass::n_total_copy_ctor_;
        *n_asgn = UserClass::n_total_op_assign_;

#ifndef _RWSTD_NO_EXCEPTIONS

        // iterate for `n=throw_after' starting at the next call to operator
        // new, forcing each call to throw an exception, until the insertion
        // finally succeeds (i.e, no exception is thrown)

#  ifdef DEFINE_REPLACEMENT_NEW_AND_DELETE

        if (exceptions & NewThrows) {
            *pst->throw_at_calls_ [0] = pst->new_calls_ [0] + throw_after + 1;
        }

#  endif   // DEFINE_REPLACEMENT_NEW_AND_DELETE

        if (exceptions & CopyCtorThrows) {
            UserClass::copy_ctor_throw_count_ =
                UserClass::n_total_copy_ctor_ + throw_after;
        }

        if (exceptions & AssignmentThrows) {
            UserClass::op_assign_throw_count_ =
                UserClass::n_total_op_assign_ + throw_after;
        }

#endif   // _RWSTD_NO_EXCEPTIONS

        _TRY {

            switch (mfun) {
            case Assign_n:
                _RWSTD_ASSERT (x);
                deq.assign (n, *x);
                break;
            case AssignRange:
                deq.assign (first, last);
                break;

            case Erase_1:
                deq.erase (it);
                break;
            case EraseRange: {
                const Deque::iterator erase_end (it + n);
                deq.erase (it, erase_end);
                break;
            }

            case Insert_1:
                _RWSTD_ASSERT (x);
                deq.insert (it, *x);
                break;
            case Insert_n:
                _RWSTD_ASSERT (x);
                deq.insert (it, n, *x);
                break;
            case InsertRange:
                deq.insert (it, first, last);
                break;
            }
        }
        _CATCH (...) {

            // verify that an exception thrown from the member function
            // didn't cause a change in the state of the container

            rw_assert (deq.size () == size, 0, line,
                       "line %d: %s: size unexpectedly changed "
                       "from %zu to %zu after an exception",
                       __LINE__, fcall, size, deq.size ());
            
            rw_assert (deq.begin () == begin, 0, line,
                       "line %d: %s: begin() unexpectedly "
                       "changed after an exception by %td",
                       __LINE__, fcall, deq.begin () - begin);

            rw_assert (deq.end () == end, 0, line,
                       "line %d: %s: end() unexpectedly "
                       "changed after an exception by %td",
                       __LINE__, fcall, deq.end () - end);
            

            // count the number of objects to detect leaks
            x_count = UserClass::count_ - x_count;
            rw_assert (x_count == deq.size () - size, 0, line,
                       "line %d: %s: leaked %zu objects after an exception",
                       __LINE__, fcall, x_count - (deq.size () - size));
            
            if (exceptions) {

                // increment to allow this call to operator new to succeed
                // and force the next one to fail, and try to insert again
                ++throw_after;
            }
            else
                break;

            continue;
        }

        // count the number of objects to detect leaks
        x_count = UserClass::count_ - x_count;
        rw_assert (x_count == deq.size () - size, 0, line,
                   "line %d: %s: leaked %zu objects "
                   "after a successful insertion",
                   __LINE__, fcall, x_count - (deq.size () - size));

        break;
    }
Exemple #21
0
/* virtual */ strstreambuf::pos_type
strstreambuf::seekoff (off_type off, ios::seekdir way, ios::openmode which)
{
    _RWSTD_ASSERT (_C_is_valid ());

    // should implicitly hold as long as ios::seekdir is an enum
    _RWSTD_ASSERT (ios::beg == way || ios::cur == way || ios::end == way);
    _RWSTD_ASSERT (_C_is_valid ());

    // determine seekable area - D.7.1, p4
    char* const seeklo = eback ();
    char* const seekhi = epptr () ? epptr () : egptr ();

    const char* const xnext = which & ios::in ? gptr () : pptr ();
    const char* const xbeg  = which & ios::in ? eback () : pbase ();

    // D.7.1.3, p13
    if (!xnext)
        return pos_type (off_type (-1));

    off_type saved_off = off;

    // compute new offset - D.7.1.3, p13, table 105
    if (ios::cur == way)
        off += off_type (xnext - xbeg);
    else if (ios::end == way)
        off += off_type (seekhi - xbeg);

    // test conditions in D.7.1.3, p13, table 105, row 4
    if (off < seeklo - xbeg || off > seekhi - xbeg)
        off = -1;   // failure
    else if (which & ios::in) {   // position input sequence

        // fail if `way' is `cur', otherwise position output sequence first
        if (   which & ios::out
            && (   way == ios::cur
                || pos_type (-1) == seekoff (saved_off, way, ios::out)))
            return pos_type (off_type (-1));

        // adjust input sequence as necessary to maintain invariant
        if (off <= egptr () - eback ())
            setg (eback (), eback () + off, egptr ());
        else if (off <= pptr () - egptr ())   // advance egptr()
            setg (eback (), eback () + off, pptr ());
        else   // advance egptr() even further
            setg (eback (), eback () + off, epptr ());
    }
    else if (which & ios::out) {   // position output sequence
        if (seeklo + off < pbase ()) {
            // adjust beginning of output sequence, then increment pptr()
            setp (seeklo, epptr ());
            pbump (off);
        }
        else {
            // reset pptr() first, then increment it by offset
            setp (pbase (), epptr ());
            pbump (off - (pbase () - seeklo));
        }
    }
    else
        off = -1;   // failure

    _RWSTD_ASSERT (_C_is_valid ());

    return pos_type (off);
}
Exemple #22
0
void run_test (intT, thr_args_base::tag_t tag)
{
    static const char* const tname = rw_any_t (intT ()).type_name ();

    if (!rw_enabled (tname)) {
        rw_note (0, 0, 0, "%s test disabled", tname);
        return;
    }

#ifdef _RWSTD_REENTRANT

    static const char* const fun = "__rw_atomic_exchange";

    rw_info (0, 0, 0, "__rw::%s (%s&, %2$s): %d iterations in %d threads",
             fun, tname, rw_opt_nloops, rw_opt_nthreads);

    rw_thread_t tid [MAX_THREADS];

    typedef thr_args<intT> Args;

    Args::nthreads_   = unsigned (rw_opt_nthreads);
    Args::type_tag_   = tag;
    Args::nincr_      = unsigned (rw_opt_nloops);
    Args::shared_ [0] = intT (1);
    Args::shared_ [1] = intT (1);

    _RWSTD_ASSERT (Args::nthreads_ < sizeof tid / sizeof *tid);

    Args args [sizeof tid / sizeof *tid];

    for (unsigned long i = 0; i != Args::nthreads_; ++i) {

        args [i].threadno_ = i;
        args [i].niter_    = 0;
        args [i].nxchg_    = 0;

        rw_fatal (0 == rw_thread_create (tid + i, 0, thread_routine, args + i),
                  0, __LINE__, "thread_create() failed");
    }
            
    for (unsigned long i = 0; i != Args::nthreads_; ++i) {

        rw_error (0 == rw_thread_join (tid [i], 0), 0, __LINE__,
                  "thread_join() failed");

        if (args [i].niter_) {
            // compute the percantage of thread iterations that resulted
            // in increments of one of the shared variables
            const unsigned long incrpcnt =
                (100U * Args::nincr_) / args [i].niter_;

            printf ("thread %lu performed %lu exchanges in %lu iterations "
                    "(%lu%% increments)\n",
                    args [i].threadno_, args [i].nxchg_,
                    args [i].niter_, incrpcnt);
        }
    }

    // compute the expected result, "skipping" zeros by incrementing
    // expect twice when it overflows and wraps around to 0 (zero is
    // used as the lock variable in thread_routine() above)
    intT expect = intT (1);

    const unsigned long nincr = (Args::nthreads_ * Args::nincr_) / 2U;
        
    for (unsigned long i = 0; i != nincr; ++i) {
        if (intT () == ++expect)
            ++expect;
    }

    // verify that the final value of the variables shared among all
    // threads equals the number of increments performed by the threads
    rw_assert (Args::shared_ [0] == expect, 0, __LINE__,
               "1. %s (%s&, %2$s); %s == %s failed",
               fun, tname, TOSTR (Args::shared_ [0]), TOSTR (expect));

    rw_assert (Args::shared_ [1] == expect, 0, __LINE__,
               "2. %s (%s&, %2$s); %s == %s failed",
               fun, tname, TOSTR (Args::shared_ [1]), TOSTR (expect));

#else   // if !defined (_RWSTD_REENTRANT)

    _RWSTD_UNUSED (tag);

#endif   // _RWSTD_REENTRANT
}
Exemple #23
0
__rw_locale* __rw_locale::
_C_combine (const __rw_locale &other, int cat)
{
    // convert a possible LC_XXX constant to a locale::category value
    cat = _C_LC2category (cat);

    // verify that the category argument is valid
    if (!_C_check_category (cat))
        return 0;


    // combining ctor: locale (const locale&, const locale&, cat)

    if (this == &other || _STD::locale::none == cat) {
        // same as copy ctor (copying all facets from `*this')
        // body may or may not be globally managed
        _RWSTD_ATOMIC_PREINCREMENT (_C_ref, false);

        return this;
    }

#if 0   // disabled

    // 22.1.1.2, p14: only facets that implement categories in `cat' are
    // to be copied from `other', i.e., not necessarily user-defined facets

    if (_RWSTD_LC_ALL == cat || _STD::locale::all == cat) {
        // same as copy ctor (copying all facets from `other')
        // body may or may not be globally managed
        _RWSTD_ATOMIC_PREINCREMENT (other._C_ref, false);
        return &other;
    }

#endif   // 0/1

    if (   _C_is_managed (_STD::locale::all & ~cat)
        && other._C_is_managed (cat)) {
        
        // determine new locale name from `*this' and `other's, taking all of
        // this's category names except for those given by `cat', which come
        // from `other'

        const char *name_1 = _C_name;
        const char *name_2 = other._C_name;

        if (0 == strcmp (name_1, name_2)) {
            // if locale names are the same, return a globally managed body
            __rw_locale* const plocale = __rw_locale::_C_manage (0, name_1);

            _RWSTD_ASSERT (0 != plocale);
            _RWSTD_ASSERT (plocale->_C_is_managed (_STD::locale::none));

            return plocale;
        }

        __rw_chararray locname;

        // compose the new name
        __rw_combine_names (locname, name_1, name_2, cat);

        // return a globally managed body
        __rw_locale* const plocale =
            __rw_locale::_C_manage (0, locname.data ());

        _RWSTD_ASSERT (0 != plocale);
        _RWSTD_ASSERT (plocale->_C_is_managed (_STD::locale::none));

        return plocale;
    }

    // one or both locales are not globally managed (one or more of
    // their facets are of use-defined types, possibly derived from
    // the standard facets), and thus the combined locale cannot be
    // globally managed either
    __rw_locale *plocale = new __rw_locale (*this, other, cat);

    _RWSTD_ASSERT (!plocale->_C_is_managed (_STD::locale::none));

    return plocale;
}