Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
_punct.cc
Go to the documentation of this file.
1
30#include <streambuf>
31#include <loc/_ctype.h>
32
33
35
36
38template <class _CharT, class _InputIter>
39_InputIter __rw_match_name (_InputIter __it, _InputIter __end,
40 const _CharT* const *__names,
41 const _RWSTD_SIZE_T *__sizes,
42 _RWSTD_SIZE_T __count,
43 _RWSTD_SIZE_T &__inx,
44 int &__err,
45 _STD::ios_base *__flags)
46{
47 const _RWSTD_SIZE_T __badval = _RWSTD_SIZE_MAX;
48
49 // make sure there are enough bits for all `count' `names'
50 _RWSTD_ASSERT (__count <= sizeof (_RWSTD_SIZE_T) * _RWSTD_CHAR_BIT);
51
52 // on input, `err' contains the maximum allowed number of matches
53 const _RWSTD_SIZE_T __matchmax = (_RWSTD_SIZE_T)__err;
54
55 __err = 0;
56
57 _RWSTD_SIZE_T __bits = ~0UL; // a bit for each `name'
58 _RWSTD_SIZE_T __nmatch = __count; // total number of positive matches
59 _RWSTD_SIZE_T __pos = 0; // position within input
60 _RWSTD_SIZE_T __num = __inx; // input as a number
61
62 __inx = __badval; // invalidate
63
64 const _STD::ctype<_CharT> *__ctp = __flags ?
65 &_RWSTD_USE_FACET (_STD::ctype<_CharT>, __flags->getloc ()) : 0;
66
67 _CharT __ch;
68
69 for (; (__bits || __num != __badval) && !__err; ++__it, ++__pos) {
70
71 if (__it == __end) {
72 __err |= _RWSTD_IOS_EOFBIT;
73 __ch = _CharT ();
74 }
75 else
76 __ch = *__it;
77
78 if (__ctp && __num != __badval) {
79 if (__ctp->is (_STD::ctype_base::digit, __ch))
80 __num = __num * 10 + __ctp->narrow (__ch, '0') - '0';
81 else
82 __num = __badval;
83 }
84
85 // iterate over all names, clear bits of those that do not match
86 for (_RWSTD_SIZE_T __k = 0; __k != __count; ++__k) {
87
88 typedef _STD::char_traits<_CharT> _Traits;
89
90 const _RWSTD_SIZE_T __mask =
91 _RWSTD_STATIC_CAST (_RWSTD_SIZE_T, 1UL) << __k;
92
93 if (__bits & __mask) {
94 // `name' is still in the set, see if the next char matches
95 // (case insensitive comparison done if `ctp' is nonzero)
96 if ( __pos < __sizes [__k]
97 && !__err
98 && (__ctp ?
99 _Traits::eq ((__ctp->toupper)(__names [__k][__pos]),
100 (__ctp->toupper)(__ch))
101 : _Traits::eq (__names [__k][__pos], __ch))) {
102
103 // next character on `name' mactches input
104 if (__badval == __inx) {
105 // no prior match, remember this one
106 __inx = __k;
107 }
108 else if ( __k != __inx
109 && __sizes [__k] == __sizes [__inx]
110 && __pos + 1 == __sizes [__inx]) {
111
112 // this match is a duplicate of the last best one
113 // remove this match from the set
114 __bits &= ~__mask;
115 --__nmatch;
116 }
117 else if ( __sizes [__k] < __sizes [__inx]
118 || __pos >= __sizes [__inx]) {
119 // this match is either shorter than the last one
120 // or the last one will be eliminated
121 __inx = __k;
122 }
123 }
124 else {
125 if (1 == __nmatch) {
126 if (__badval == __inx && __badval == __num)
127 return __it;
128 goto __endloop;
129 }
130
131 if (__inx == __k) {
132 // if this `name' is the current shortest match...
133 if (__err && __pos == __sizes [__k]) {
134 // ...and we're at eof, return successfully
135 return __it;
136 }
137 // otherwise forget the match
138 __inx = __badval;
139 }
140
141 // clear the bit for the `name' that failed to match
142 // and decrement the numeber of matches
143 __bits &= ~__mask;
144 --__nmatch;
145 }
146 }
147 }
148
149 if (1 == __nmatch && __pos + 1 == __sizes [__inx])
150 return ++__it;
151 }
152
153__endloop:
154
155 if (__matchmax < __nmatch || __pos < __sizes [__inx])
156 __inx = __badval;
157
158 if (__ctp && __badval == __inx && !__err && __num != __badval) {
159
160 // if symbolic matching fails, fall back on numeric parsing
161 for ( ; ; ) {
162 if (++__it == __end) {
163 __err |= _RWSTD_IOS_EOFBIT;
164 break;
165 }
166
167 __ch = *__it;
168
169 if (__ctp->is (_STD::ctype_base::digit, __ch))
170 __num = __num * 10 + __ctp->narrow (__ch, '0') - '0';
171 else
172 break;
173 }
174
175 __inx = __count + __num;
176 }
177
178 return __it;
179}
180
181
182} // namespace __rw
#define _RWSTD_USE_FACET(type, arg)
Definition _defs.h:949
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _EXPORT
Definition _defs.h:498
#define _RWSTD_IOS_EOFBIT
Definition _defs.h:809
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108