/*************************************************************************** * * _punct.cc * * $Id: _punct.cc 597438 2007-11-22 15:44:53Z faridz $ * *************************************************************************** * * 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 1994-2006 Rogue Wave Software. * **************************************************************************/ #include #include _RWSTD_NAMESPACE (__rw) { _EXPORT template _InputIter __rw_match_name (_InputIter __it, _InputIter __end, const _CharT* const *__names, const _RWSTD_SIZE_T *__sizes, _RWSTD_SIZE_T __count, _RWSTD_SIZE_T &__inx, int &__err, _STD::ios_base *__flags) { const _RWSTD_SIZE_T __badval = _RWSTD_SIZE_MAX; // make sure there are enough bits for all `count' `names' _RWSTD_ASSERT (__count <= sizeof (_RWSTD_SIZE_T) * _RWSTD_CHAR_BIT); // on input, `err' contains the maximum allowed number of matches const _RWSTD_SIZE_T __matchmax = (_RWSTD_SIZE_T)__err; __err = 0; _RWSTD_SIZE_T __bits = ~0UL; // a bit for each `name' _RWSTD_SIZE_T __nmatch = __count; // total number of positive matches _RWSTD_SIZE_T __pos = 0; // position within input _RWSTD_SIZE_T __num = __inx; // input as a number __inx = __badval; // invalidate const _STD::ctype<_CharT> *__ctp = __flags ? &_RWSTD_USE_FACET (_STD::ctype<_CharT>, __flags->getloc ()) : 0; _CharT __ch; for (; (__bits || __num != __badval) && !__err; ++__it, ++__pos) { if (__it == __end) { __err |= _RWSTD_IOS_EOFBIT; __ch = _CharT (); } else __ch = *__it; if (__ctp && __num != __badval) { if (__ctp->is (_STD::ctype_base::digit, __ch)) __num = __num * 10 + __ctp->narrow (__ch, '0') - '0'; else __num = __badval; } // iterate over all names, clear bits of those that do not match for (_RWSTD_SIZE_T __k = 0; __k != __count; ++__k) { typedef _STD::char_traits<_CharT> _Traits; const _RWSTD_SIZE_T __mask = _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, 1UL) << __k; if (__bits & __mask) { // `name' is still in the set, see if the next char matches // (case insensitive comparison done if `ctp' is nonzero) if ( __pos < __sizes [__k] && !__err && (__ctp ? _Traits::eq ((__ctp->toupper)(__names [__k][__pos]), (__ctp->toupper)(__ch)) : _Traits::eq (__names [__k][__pos], __ch))) { // next character on `name' mactches input if (__badval == __inx) { // no prior match, remember this one __inx = __k; } else if ( __k != __inx && __sizes [__k] == __sizes [__inx] && __pos + 1 == __sizes [__inx]) { // this match is a duplicate of the last best one // remove this match from the set __bits &= ~__mask; --__nmatch; } else if ( __sizes [__k] < __sizes [__inx] || __pos >= __sizes [__inx]) { // this match is either shorter than the last one // or the last one will be eliminated __inx = __k; } } else { if (1 == __nmatch) { if (__badval == __inx && __badval == __num) return __it; goto __endloop; } if (__inx == __k) { // if this `name' is the current shortest match... if (__err && __pos == __sizes [__k]) { // ...and we're at eof, return successfully return __it; } // otherwise forget the match __inx = __badval; } // clear the bit for the `name' that failed to match // and decrement the numeber of matches __bits &= ~__mask; --__nmatch; } } } if (1 == __nmatch && __pos + 1 == __sizes [__inx]) return ++__it; } __endloop: if (__matchmax < __nmatch || __pos < __sizes [__inx]) __inx = __badval; if (__ctp && __badval == __inx && !__err && __num != __badval) { // if symbolic matching fails, fall back on numeric parsing for ( ; ; ) { if (++__it == __end) { __err |= _RWSTD_IOS_EOFBIT; break; } __ch = *__it; if (__ctp->is (_STD::ctype_base::digit, __ch)) __num = __num * 10 + __ctp->narrow (__ch, '0') - '0'; else break; } __inx = __count + __num; } return __it; } } // namespace __rw