/elec/propeller-clock

To get this branch, use:
bzr branch http://bzr.ed.am/elec/propeller-clock

« back to all changes in this revision

Viewing changes to src/utility/istream_helpers

  • Committer: edam
  • Date: 2012-02-25 01:31:43 UTC
  • Revision ID: tim@ed.am-20120225013143-9fet2y2d3fjlrwez
added ulibc

Show diffs side-by-side

added added

removed removed

 
1
/*      Copyright (C) 2004 Garrett A. Kajmowicz
 
2
 
 
3
        This file is part of the uClibc++ Library.
 
4
 
 
5
        This library is free software; you can redistribute it and/or
 
6
        modify it under the terms of the GNU Lesser General Public
 
7
        License as published by the Free Software Foundation; either
 
8
        version 2.1 of the License, or (at your option) any later version.
 
9
 
 
10
        This library is distributed in the hope that it will be useful,
 
11
        but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
        Lesser General Public License for more details.
 
14
 
 
15
        You should have received a copy of the GNU Lesser General Public
 
16
        License along with this library; if not, write to the Free Software
 
17
        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
*/
 
19
 
 
20
#include <ios>
 
21
#include <cctype>
 
22
 
 
23
#include <string>
 
24
 
 
25
#ifndef __STD_HEADER_ISTREAM_HELPERS
 
26
#define __STD_HEADER_ISTREAM_HELPERS 1
 
27
 
 
28
#pragma GCC visibility push(default)
 
29
 
 
30
namespace std{
 
31
 
 
32
 
 
33
        /* We are making the following template class for serveral reasons.  Firstly,
 
34
         * we want to keep the main istream code neat and tidy.  Secondly, we want it
 
35
         * to be easy to do partial specialization of the istream code so that it can
 
36
         * be expanded and put into the library.  This will allow us to make application
 
37
         * code smaller at the expense of increased library size.  This is a fair
 
38
         * trade-off when there are multiple applications being compiled.  Also, this
 
39
         * feature will be used optionally via configuration options.  It will also
 
40
         * allow us to keep the code bases in sync, dramatically simplifying the
 
41
         * maintenance required.  We specialized for char because wchar and others
 
42
         * require different scanf functions
 
43
         */
 
44
 
 
45
        template <class C, class traits> _UCXXEXPORT 
 
46
                basic_string<C, traits> _readToken(basic_istream<C, traits>& stream)
 
47
        {
 
48
                basic_string<C, traits> temp;
 
49
                typename traits::int_type c;
 
50
                while(true){
 
51
                        c = stream.rdbuf()->sgetc();
 
52
                        if(c != traits::eof() && isspace(c) == false){
 
53
                                stream.rdbuf()->sbumpc();
 
54
                                temp.append(1, traits::to_char_type(c));
 
55
                        }else{
 
56
                                break;
 
57
                        }
 
58
                }
 
59
                if (temp.size() == 0)
 
60
                        stream.setstate(ios_base::eofbit|ios_base::failbit);
 
61
 
 
62
                return temp;
 
63
        }
 
64
 
 
65
        template <class C, class traits> _UCXXEXPORT 
 
66
                basic_string<C, traits> _readTokenDecimal(basic_istream<C, traits>& stream)
 
67
        {
 
68
                basic_string<C, traits> temp;
 
69
                typename traits::int_type c;
 
70
                while(true){
 
71
                        c = stream.rdbuf()->sgetc();
 
72
                        if(c != traits::eof() && isspace(c) == false && (
 
73
                                isdigit(c) ||
 
74
                                c == '.' ||
 
75
                                c == ',' ||
 
76
                                ((c == '-' || c == '+') && temp.size() == 0) )
 
77
                        ){
 
78
                                stream.rdbuf()->sbumpc();
 
79
                                temp.append(1, traits::to_char_type(c));
 
80
                        }else{
 
81
                                break;
 
82
                        }
 
83
                }
 
84
                if (temp.size() == 0)
 
85
                        stream.setstate(ios_base::eofbit|ios_base::failbit);
 
86
 
 
87
                return temp;
 
88
        }
 
89
 
 
90
#ifdef __UCLIBCXX_EXPAND_ISTREAM_CHAR__
 
91
 
 
92
        template <> _UCXXEXPORT string _readToken<char, char_traits<char> >(istream & stream);
 
93
 
 
94
#endif
 
95
 
 
96
 
 
97
        template <class traits, class charT, class dataType> class _UCXXEXPORT __istream_readin{
 
98
        public:
 
99
                static void readin(basic_istream<charT,traits>& stream, dataType & var);
 
100
        };
 
101
 
 
102
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, bool>{
 
103
        public:
 
104
                inline static void readin(basic_istream<char, traits >& stream, bool & var)
 
105
                {
 
106
                        basic_string<char, traits > temp;
 
107
                        temp = _readToken( stream);
 
108
                        if(temp == "true" || temp == "True" || temp == "TRUE" || temp == "1"){
 
109
                                var = true;
 
110
                        }else{
 
111
                                var = false;
 
112
                        }
 
113
                }
 
114
        };
 
115
 
 
116
 
 
117
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, short>{
 
118
        public:
 
119
                inline static void readin(basic_istream<char, traits >& stream, short & var)
 
120
                {
 
121
                        basic_string<char, traits > temp;
 
122
 
 
123
                        if(stream.flags() & ios_base::dec){
 
124
                                temp = _readTokenDecimal( stream);
 
125
                                sscanf(temp.c_str(), "%hd", &var );
 
126
                        }else{
 
127
                                temp = _readToken( stream);
 
128
                                if( stream.flags() & ios_base::oct){
 
129
                                        sscanf(temp.c_str(), "%ho", (unsigned short int *)(&var) );
 
130
                                }else if(stream.flags() & ios_base::hex){
 
131
                                        if(stream.flags() & ios_base::uppercase){
 
132
                                                sscanf(temp.c_str(), "%hX", (unsigned short int *)(&var) );
 
133
                                        }else{
 
134
                                                sscanf(temp.c_str(), "%hx", (unsigned short int *)(&var) );
 
135
                                        }
 
136
                                }else{
 
137
                                        sscanf(temp.c_str(), "%hi", &var);
 
138
                
 
139
                                }
 
140
                        }
 
141
                }
 
142
        };
 
143
 
 
144
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned short>{
 
145
        public:
 
146
                inline static void readin(basic_istream<char, traits >& stream, unsigned short & var)
 
147
                {
 
148
                        basic_string<char, traits > temp;
 
149
 
 
150
                        if(stream.flags() & ios_base::dec){
 
151
                                temp = _readTokenDecimal( stream);
 
152
                                sscanf(temp.c_str(), "%hu", &var );
 
153
                        }else{
 
154
                                temp = _readToken( stream);
 
155
                                if( stream.flags() & ios_base::oct){
 
156
                                        sscanf(temp.c_str(), "%ho", &var);
 
157
                                }else if(stream.flags() & ios_base::hex){
 
158
                                        if(stream.flags() & ios_base::uppercase){
 
159
                                                sscanf(temp.c_str(), "%hX", &var );
 
160
                                        }else{
 
161
                                                sscanf(temp.c_str(), "%hx", &var);
 
162
                                        }
 
163
                                }else{
 
164
                                        sscanf(temp.c_str(), "%hi", (signed short int*)(&var) );
 
165
                                }
 
166
                        }
 
167
                }
 
168
        };
 
169
 
 
170
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, int>{
 
171
        public:
 
172
                inline static void readin(basic_istream<char, traits >& stream, int & var)
 
173
                {
 
174
                        basic_string<char, traits > temp;
 
175
 
 
176
                        if(stream.flags() & ios_base::dec){
 
177
                                temp = _readTokenDecimal( stream);
 
178
                                sscanf(temp.c_str(), "%d", &var );
 
179
                        }else{
 
180
                                temp = _readToken( stream);
 
181
                                if( stream.flags() & ios_base::oct){
 
182
                                        sscanf(temp.c_str(), "%o", (unsigned int *)(&var) );
 
183
                                }else if(stream.flags() & ios_base::hex){
 
184
                                        if(stream.flags() & ios_base::uppercase){
 
185
                                                sscanf(temp.c_str(), "%X", (unsigned int *)(&var) );
 
186
                                        }else{
 
187
                                                sscanf(temp.c_str(), "%x", (unsigned int *)(&var) );
 
188
                                        }
 
189
                                }else{
 
190
                                        sscanf(temp.c_str(), "%i", &var);
 
191
                                }
 
192
                        }
 
193
                }
 
194
        };
 
195
 
 
196
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned int>{
 
197
        public:
 
198
                inline static void readin(basic_istream<char, traits >& stream, unsigned int & var)
 
199
                {
 
200
                        basic_string<char, traits > temp;
 
201
 
 
202
                        if(stream.flags() & ios_base::dec){
 
203
                                temp = _readTokenDecimal( stream);
 
204
                                sscanf(temp.c_str(), "%u", &var );
 
205
                        }else{
 
206
                                temp = _readToken( stream);
 
207
                                if( stream.flags() & ios_base::oct){
 
208
                                        sscanf(temp.c_str(), "%o", (unsigned int *)(&var) );
 
209
                                }else if(stream.flags() & ios_base::hex){
 
210
                                        if(stream.flags() & ios_base::uppercase){
 
211
                                                sscanf(temp.c_str(), "%X", (unsigned int *)(&var) );
 
212
                                        }else{
 
213
                                                sscanf(temp.c_str(), "%x", (unsigned int *)(&var) );
 
214
                                        }
 
215
                                }else{
 
216
                                        sscanf(temp.c_str(), "%i", (int *)(&var) );
 
217
                                }
 
218
                        }       
 
219
 
 
220
                }
 
221
        };
 
222
 
 
223
 
 
224
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, long int>{
 
225
        public:
 
226
                inline static void readin(basic_istream<char, traits >& stream, long int & var)
 
227
                {
 
228
                        basic_string<char, traits > temp;
 
229
 
 
230
                        if(stream.flags() & ios_base::dec){
 
231
                                temp = _readTokenDecimal( stream);
 
232
                                sscanf(temp.c_str(), "%ld", &var );
 
233
                        }else{
 
234
                                temp = _readToken( stream);
 
235
                                if( stream.flags() & ios_base::oct){
 
236
                                        sscanf(temp.c_str(), "%lo", (unsigned long int *)(&var) );
 
237
                                }else if(stream.flags() & ios_base::hex){
 
238
                                        if(stream.flags() & ios_base::uppercase){
 
239
                                                sscanf(temp.c_str(), "%lX", (unsigned long int *)(&var) );
 
240
                                        }else{
 
241
                                                sscanf(temp.c_str(), "%lx", (unsigned long int *)(&var) );
 
242
                                        }
 
243
                                }else{
 
244
                                        sscanf(temp.c_str(), "%li", (long int *)(&var) );
 
245
                                }
 
246
                        }
 
247
 
 
248
                }
 
249
        };
 
250
 
 
251
 
 
252
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, unsigned long int>{
 
253
        public:
 
254
                inline static void readin(basic_istream<char, traits >& stream, unsigned long int & var)
 
255
                {
 
256
                        basic_string<char, traits > temp;
 
257
 
 
258
                        if(stream.flags() & ios_base::dec){
 
259
                                temp = _readTokenDecimal( stream);
 
260
                                sscanf(temp.c_str(), "%lu", &var );
 
261
                        }else{
 
262
                                temp = _readToken( stream);
 
263
                                if( stream.flags() & ios_base::oct){
 
264
                                        sscanf(temp.c_str(), "%lo", &var );
 
265
                                }else if(stream.flags() & ios_base::hex){
 
266
                                        if(stream.flags() & ios_base::uppercase){
 
267
                                                sscanf(temp.c_str(), "%lX", &var );
 
268
                                        }else{
 
269
                                                sscanf(temp.c_str(), "%lx", &var);
 
270
                                        }
 
271
                                }else{
 
272
                                        sscanf(temp.c_str(), "%li", (long int *)(&var) );
 
273
                                }
 
274
                        }
 
275
                }
 
276
        };
 
277
 
 
278
 
 
279
#ifdef __UCLIBCXX_HAS_FLOATS__
 
280
 
 
281
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, float>{
 
282
        public:
 
283
                inline static void readin(basic_istream<char, traits >& stream, float & var)
 
284
                {
 
285
                        basic_string<char, traits > temp;
 
286
                        temp = _readTokenDecimal( stream);
 
287
#if defined (__AVR__) 
 
288
                        var = strtod(temp.c_str(), NULL);
 
289
#else
 
290
                        sscanf(temp.c_str(), "%g", &var);
 
291
#endif
 
292
                        
 
293
                }
 
294
        };
 
295
 
 
296
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, double>{
 
297
        public:
 
298
                inline static void readin(basic_istream<char, traits >& stream, double & var)
 
299
                {
 
300
                        basic_string<char, traits > temp;
 
301
                        temp = _readTokenDecimal( stream);
 
302
#if defined (__AVR__)
 
303
                        var = strtod(temp.c_str(), NULL);
 
304
#else                   
 
305
                        sscanf(temp.c_str(), "%lg", &var);
 
306
#endif                  
 
307
                }
 
308
        };
 
309
 
 
310
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, long double>{
 
311
        public:
 
312
                inline static void readin(basic_istream<char, traits >& stream, long double & var)
 
313
                {
 
314
                        basic_string<char, traits > temp;
 
315
                        temp = _readTokenDecimal( stream);
 
316
#if defined (__AVR__)
 
317
                        var = strtod(temp.c_str(), NULL);
 
318
#else                   
 
319
                        sscanf(temp.c_str(), "%Lg", &var);
 
320
#endif                  
 
321
                }
 
322
        };
 
323
 
 
324
#endif  // ifdef __UCLIBCXX_HAS_FLOATS__
 
325
 
 
326
        template <class traits> class _UCXXEXPORT __istream_readin<traits, char, void*>{
 
327
        public:
 
328
                inline static void readin(basic_istream<char, traits >& stream, void* & var)
 
329
                {
 
330
                        basic_string<char, traits > temp;
 
331
                        temp = _readToken( stream);
 
332
                        sscanf(temp.c_str(), "%p", &var);
 
333
                }
 
334
        };
 
335
 
 
336
 
 
337
        template<class charT, class traits> void __skipws(basic_istream<charT,traits>& is){
 
338
                const typename basic_istream<charT,traits>::int_type eof = traits::eof();
 
339
                typename basic_istream<charT,traits>::int_type c;
 
340
                //While the next character normally read doesn't equal eof
 
341
                //and that character is a space, advance to the next read position
 
342
                //Thus itterating through all whitespace until we get to the meaty stuff
 
343
                while (
 
344
                        !traits::eq_int_type((c = is.rdbuf()->sgetc()), eof)
 
345
                        && isspace(c)
 
346
                      )
 
347
                {
 
348
                        is.rdbuf()->sbumpc();
 
349
                }
 
350
                if(traits::eq_int_type(c, eof)){
 
351
                        is.setstate(ios_base::eofbit);
 
352
                }
 
353
        }
 
354
}
 
355
 
 
356
#pragma GCC visibility pop
 
357
 
 
358
#endif
 
359
 
 
360
 
 
361