1
 
/*      Copyright (C) 2004 Garrett A. Kajmowicz
 
3
 
        This file is part of the uClibc++ Library.
 
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.
 
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.
 
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
 
20
 
#include <basic_definitions>
 
26
 
#ifndef __STD_HEADER_OSTREAM_HELPERS
 
27
 
#define __STD_HEADER_OSTREAM_HELPERS 1
 
29
 
#pragma GCC visibility push(default)
 
33
 
        /* We are making the following template class for serveral reasons.  Firstly,
 
34
 
         * we want to keep the main ostream code neat and tidy.  Secondly, we want it
 
35
 
         * to be easy to do partial specialization of the ostream 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
 
47
 
        template <class traits, class charT, class dataType> class _UCXXEXPORT __ostream_printout{
 
49
 
                static void printout(basic_ostream<charT,traits>& stream, const dataType n);
 
52
 
        template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, signed long int>{
 
54
 
                static void printout(basic_ostream<char, traits >& stream, const signed long int n)
 
57
 
                        const char * c_ld = "%ld";
 
58
 
                        const char * c_lo = "%lo";
 
59
 
                        const char * c_lX = "%lX";
 
60
 
                        const char * c_lx = "%lx";
 
61
 
                        const char * c_hashlo = "%#lo";
 
62
 
                        const char * c_hashlX = "%#lX";
 
63
 
                        const char * c_hashlx = "%#lx";
 
65
 
                        const char * formatString=0;
 
67
 
                        if( stream.flags() & ios_base::dec){
 
69
 
                        }else if( stream.flags() & ios_base::oct){
 
70
 
                                if( stream.flags() & ios_base::showbase){
 
71
 
                                        formatString = c_hashlo;
 
75
 
                        }else if (stream.flags() & ios_base::hex){
 
76
 
                                if(stream.flags() & ios_base::showbase){
 
77
 
                                        if(stream.flags() & ios_base::uppercase){
 
78
 
                                                formatString = c_hashlX;
 
80
 
                                                formatString = c_hashlx;
 
83
 
                                        if(stream.flags() & ios_base::uppercase){
 
91
 
                        stream.printout(buffer, snprintf(buffer, 20, formatString, n) );
 
93
 
                        if(stream.flags() & ios_base::unitbuf){
 
100
 
        template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, unsigned long int>{
 
102
 
                static void printout(basic_ostream<char, traits >& stream, const unsigned long int n)
 
105
 
                        const char * c_lo = "%lo";
 
106
 
                        const char * c_lu = "%lu";
 
107
 
                        const char * c_lX = "%lX";
 
108
 
                        const char * c_lx = "%lx";
 
109
 
                        const char * c_hashlo = "%#lo";
 
110
 
                        const char * c_hashlX = "%#lX";
 
111
 
                        const char * c_hashlx = "%#lx";
 
112
 
                        const char * formatString=0;
 
114
 
                        if( stream.flags() & ios_base::dec){
 
116
 
                        }else if( stream.flags() & ios_base::oct){
 
117
 
                                if( stream.flags() & ios_base::showbase){
 
118
 
                                        formatString = c_hashlo;
 
122
 
                        }else if (stream.flags() & ios_base::hex){
 
123
 
                                if(stream.flags() & ios_base::showbase){
 
124
 
                                        if(stream.flags() & ios_base::uppercase){
 
125
 
                                                formatString = c_hashlX;
 
127
 
                                                formatString = c_hashlx;
 
130
 
                                        if(stream.flags() & ios_base::uppercase){
 
138
 
                        stream.printout(buffer, snprintf(buffer, 20, formatString, n));
 
139
 
                        if(stream.flags() & ios_base::unitbuf){
 
145
 
#ifndef __STRICT_ANSI__
 
147
 
        template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, signed long long int>{
 
149
 
                static void printout(basic_ostream<char, traits >& stream, const signed long long int n)
 
152
 
                        const char * lld = "%lld";
 
153
 
                        const char * llo = "%llo";
 
154
 
                        const char * llX = "%llX";
 
155
 
                        const char * llx = "%llx";
 
156
 
                        const char * hashllo = "%#llo";
 
157
 
                        const char * hashllX = "%#llX";
 
158
 
                        const char * hashllx = "%#llx";
 
159
 
                        const char * formatString=0;
 
161
 
                        if( stream.flags() & ios_base::dec){
 
163
 
                        }else if( stream.flags() & ios_base::oct){
 
164
 
                                if( stream.flags() & ios_base::showbase){
 
165
 
                                        formatString = hashllo;
 
169
 
                        }else if (stream.flags() & ios_base::hex){
 
170
 
                                if(stream.flags() & ios_base::showbase){
 
171
 
                                        if(stream.flags() & ios_base::uppercase){
 
172
 
                                                formatString = hashllX;
 
174
 
                                                formatString = hashllx;
 
177
 
                                        if(stream.flags() & ios_base::uppercase){
 
185
 
                        stream.printout(buffer, snprintf(buffer, 27, formatString, n) );
 
187
 
                        if(stream.flags() & ios_base::unitbuf){
 
193
 
        template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, unsigned long long int>{
 
195
 
                static void printout(basic_ostream<char, traits >& stream, const unsigned long long int n)
 
198
 
                        const char * llo = "%llo";
 
199
 
                        const char * llu = "%llu";
 
200
 
                        const char * llX = "%llX";
 
201
 
                        const char * llx = "%llx";
 
202
 
                        const char * hashllo = "%#llo";
 
203
 
                        const char * hashllX = "%#llX";
 
204
 
                        const char * hashllx = "%#llx";
 
205
 
                        const char * formatString=0;
 
207
 
                        if( stream.flags() & ios_base::dec){
 
209
 
                        }else if( stream.flags() & ios_base::oct){
 
210
 
                                if( stream.flags() & ios_base::showbase){
 
211
 
                                        formatString = hashllo;
 
215
 
                        }else if (stream.flags() & ios_base::hex){
 
216
 
                                if(stream.flags() & ios_base::showbase){
 
217
 
                                        if(stream.flags() & ios_base::uppercase){
 
218
 
                                                formatString = hashllX;
 
220
 
                                                formatString = hashllx;
 
223
 
                                        if(stream.flags() & ios_base::uppercase){
 
231
 
                        stream.printout(buffer, snprintf(buffer, 27, formatString, n) );
 
233
 
                        if(stream.flags() & ios_base::unitbuf){
 
240
 
#endif  //__STRICT_ANSI__
 
242
 
        template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, float>{
 
244
 
                static void printout(basic_ostream<char, traits >& stream, const float f)
 
249
 
                        //length = snprintf(buffer, 32, "%*.*f",static_cast<int>(stream.width()),static_cast<int>(stream.precision()), f);
 
250
 
                        length = strlen(dtostrf(f, static_cast<int>(stream.width()), static_cast<int>(stream.precision()), buffer));
 
252
 
                        stream.printout(buffer, length);
 
253
 
                        if(stream.flags() & ios_base::unitbuf){
 
259
 
        template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, double>{
 
261
 
                static void printout(basic_ostream<char, traits >& stream, const double f)
 
265
 
                        if(stream.flags() & ios_base::scientific){
 
266
 
                                if(stream.flags() & ios_base::uppercase){
 
267
 
#if defined( __AVR__ )
 
268
 
                                        length = strlen(dtostre(f, buffer, static_cast<int>(stream.precision()),  0x04 ));
 
270
 
                                        length = snprintf(buffer, 32, "%*.*E", static_cast<int>(stream.width()),static_cast<int>(stream.precision()), f);
 
273
 
#if defined( __AVR__ )
 
274
 
                                        length = strlen(dtostre(f, buffer, static_cast<int>(stream.precision()), 0));
 
276
 
                                        length = snprintf(buffer, 32, "%*.*e", static_cast<int>(stream.width()),static_cast<int>(stream.precision()), f);
 
279
 
                        } else if(stream.flags() & ios_base::fixed){
 
280
 
#if defined( __AVR__ )
 
281
 
                                length = strlen(dtostrf(f, static_cast<int>(stream.width()), static_cast<int>(stream.precision()), buffer));
 
283
 
                                length = snprintf(buffer, 32, "%*.*f",static_cast<int>(stream.width()),static_cast<int>(stream.precision()), f);
 
286
 
#if defined( __AVR__ )
 
287
 
                                length = strlen(dtostrf(f, static_cast<int>(stream.width()), static_cast<int>(stream.precision()), buffer));
 
289
 
                                length = snprintf(buffer, 32, "%*.*g",static_cast<int>(stream.width()),static_cast<int>(stream.precision()), f);
 
292
 
                        stream.printout(buffer, length);
 
293
 
                        if(stream.flags() & ios_base::unitbuf){
 
299
 
        template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, long double>{
 
301
 
                static void printout(basic_ostream<char, traits >& stream, const long double f)
 
305
 
                        if(stream.flags() & ios_base::scientific){
 
306
 
                                if(stream.flags() & ios_base::uppercase){
 
307
 
                                        length = snprintf(buffer, 32, "%*.*LE", static_cast<int>(stream.width()), static_cast<int>(stream.precision()), f);
 
309
 
                                        length = snprintf(buffer, 32, "%*.*Le", static_cast<int>(stream.width()), static_cast<int>(stream.precision()), f);
 
311
 
                        } else if(stream.flags() & ios_base::fixed){
 
312
 
                                length = snprintf(buffer, 32, "%*.*Lf", static_cast<int>(stream.width()), static_cast<int>(stream.precision()), f);
 
314
 
                                length = snprintf(buffer, 32, "%*.*Lg", static_cast<int>(stream.width()), static_cast<int>(stream.precision()), f);
 
316
 
                        stream.printout(buffer, length);
 
317
 
                        if(stream.flags() & ios_base::unitbuf){
 
324
 
#ifdef __UCLIBCXX_HAS_WCHAR__
 
325
 
        template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, signed long int>{
 
327
 
                static void printout(basic_ostream<wchar_t, traits >& stream, const signed long int n)
 
330
 
                        if( stream.flags() & ios_base::dec){
 
331
 
                                stream.printout(buffer, swprintf(buffer, 20, L"%ld", n));
 
332
 
                        }else if( stream.flags() & ios_base::oct){
 
333
 
                                if( stream.flags() & ios_base::showbase){
 
334
 
                                        stream.printout(buffer, swprintf(buffer, 20, L"%#lo", n));
 
336
 
                                        stream.printout(buffer, swprintf(buffer, 20, L"%lo", n) );
 
338
 
                        }else if (stream.flags() & ios_base::hex){
 
339
 
                                if(stream.flags() & ios_base::showbase){
 
340
 
                                        if(stream.flags() & ios_base::uppercase){
 
341
 
                                                stream.printout(buffer, swprintf(buffer, 20, L"%#lX", n) );
 
343
 
                                                stream.printout(buffer, swprintf(buffer, 20, L"%#lx", n) );
 
346
 
                                        if(stream.flags() & ios_base::uppercase){
 
347
 
                                                stream.printout(buffer, swprintf(buffer, 20, L"%lX", n) );
 
349
 
                                                stream.printout(buffer, swprintf(buffer, 20, L"%lx", n) );
 
353
 
                        if(stream.flags() & ios_base::unitbuf){
 
359
 
        template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, unsigned long int>{
 
361
 
                static void printout(basic_ostream<wchar_t, traits >& stream, const unsigned long int n)
 
364
 
                        if( stream.flags() & ios_base::dec){
 
365
 
                                stream.printout(buffer, swprintf(buffer, 20, L"%lu", n));
 
366
 
                        }else if( stream.flags() & ios_base::oct){
 
367
 
                                if( stream.flags() & ios_base::showbase){
 
368
 
                                        stream.printout(buffer, swprintf(buffer, 20, L"%#lo", n));
 
370
 
                                        stream.printout(buffer, swprintf(buffer, 20, L"%lo", n) );
 
372
 
                        }else if (stream.flags() & ios_base::hex){
 
373
 
                                if(stream.flags() & ios_base::showbase){
 
374
 
                                        if(stream.flags() & ios_base::uppercase){
 
375
 
                                                stream.printout(buffer, swprintf(buffer, 20, L"%#lX", n) );
 
377
 
                                                stream.printout(buffer, swprintf(buffer, 20, L"%#lx", n) );
 
380
 
                                        if(stream.flags() & ios_base::uppercase){
 
381
 
                                                stream.printout(buffer, swprintf(buffer, 20, L"%lX", n) );
 
383
 
                                                stream.printout(buffer, swprintf(buffer, 20, L"%lx", n) );
 
387
 
                        if(stream.flags() & ios_base::unitbuf){
 
393
 
#ifndef __STRICT_ANSI__
 
395
 
        template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, signed long long int>{
 
397
 
                static void printout(basic_ostream<wchar_t, traits >& stream, const signed long long int n)
 
400
 
                        if( stream.flags() & ios_base::dec){
 
401
 
                                stream.printout(buffer, swprintf(buffer, 27, L"%lld", n));
 
402
 
                        }else if( stream.flags() & ios_base::oct){
 
403
 
                                if( stream.flags() & ios_base::showbase){
 
404
 
                                        stream.printout(buffer, swprintf(buffer, 27, L"%#llo", n));
 
406
 
                                        stream.printout(buffer, swprintf(buffer, 27, L"%llo", n) );
 
408
 
                        }else if (stream.flags() & ios_base::hex){
 
409
 
                                if(stream.flags() & ios_base::showbase){
 
410
 
                                        if(stream.flags() & ios_base::uppercase){
 
411
 
                                                stream.printout(buffer, swprintf(buffer, 27, L"%#llX", n) );
 
413
 
                                                stream.printout(buffer, swprintf(buffer, 27, L"%#llx", n) );
 
416
 
                                        if(stream.flags() & ios_base::uppercase){
 
417
 
                                                stream.printout(buffer, swprintf(buffer, 27, L"%llX", n) );
 
419
 
                                                stream.printout(buffer, swprintf(buffer, 27, L"%llx", n) );
 
423
 
                        if(stream.flags() & ios_base::unitbuf){
 
429
 
        template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, unsigned long long int>{
 
431
 
                static void printout(basic_ostream<wchar_t, traits >& stream, const unsigned long long int n)
 
434
 
                        if( stream.flags() & ios_base::dec){
 
435
 
                                stream.printout(buffer, swprintf(buffer, 27, L"%llu", n));
 
436
 
                        }else if( stream.flags() & ios_base::oct){
 
437
 
                                if( stream.flags() & ios_base::showbase){
 
438
 
                                        stream.printout(buffer, swprintf(buffer, 27, L"%#llo", n));
 
440
 
                                        stream.printout(buffer, swprintf(buffer, 27, L"%llo", n) );
 
442
 
                        }else if (stream.flags() & ios_base::hex){
 
443
 
                                if(stream.flags() & ios_base::showbase){
 
444
 
                                        if(stream.flags() & ios_base::uppercase){
 
445
 
                                                stream.printout(buffer, swprintf(buffer, 27, L"%#llX", n) );
 
447
 
                                                stream.printout(buffer, swprintf(buffer, 27, L"%#llx", n) );
 
450
 
                                        if(stream.flags() & ios_base::uppercase){
 
451
 
                                                stream.printout(buffer, swprintf(buffer, 27, L"%llX", n) );
 
453
 
                                                stream.printout(buffer, swprintf(buffer, 27, L"%llx", n) );
 
457
 
                        if(stream.flags() & ios_base::unitbuf){
 
464
 
#endif  //__STRICT_ANSI__
 
466
 
        template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, double>{
 
468
 
                static void printout(basic_ostream<wchar_t, traits >& stream, const double f)
 
471
 
                        wchar_t format_string[32];
 
472
 
                        if(stream.flags() & ios_base::scientific){
 
473
 
                                if(stream.flags() & ios_base::uppercase){
 
474
 
                                        swprintf(format_string, 32, L"%%%u.%uE", static_cast<int>(stream.width()), static_cast<unsigned int>(stream.precision()));
 
476
 
                                        swprintf(format_string, 32, L"%%%u.%ue", static_cast<int>(stream.width()), static_cast<unsigned int>(stream.precision()));
 
478
 
                        } else if(stream.flags() & ios_base::fixed){
 
479
 
                                swprintf(format_string, 32, L"%%%u.%uf", static_cast<int>(stream.width()), static_cast<unsigned int>(stream.precision()));
 
481
 
                                swprintf(format_string, 32, L"%%%u.%ug", static_cast<int>(stream.width()), static_cast<unsigned int>(stream.precision()));
 
483
 
                        stream.printout(buffer, swprintf(buffer, 32, format_string, f) );
 
484
 
                        if(stream.flags() & ios_base::unitbuf){
 
490
 
        template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, long double>{
 
492
 
                static void printout(basic_ostream<wchar_t, traits >& stream, const long double f)
 
495
 
                        wchar_t format_string[32];
 
496
 
                        if(stream.flags() & ios_base::scientific){
 
497
 
                                if(stream.flags() & ios_base::uppercase){
 
498
 
                                        swprintf(format_string, 32, L"%%%u.%uLE", static_cast<unsigned int>(stream.width()), static_cast<unsigned int>(stream.precision()));
 
500
 
                                        swprintf(format_string, 32, L"%%%u.%uLe", static_cast<unsigned int>(stream.width()), static_cast<unsigned int>(stream.precision()));
 
502
 
                        } else if(stream.flags() & ios_base::fixed){
 
503
 
                                swprintf(format_string, 32, L"%%%u.%uLf", static_cast<unsigned int>(stream.width()), static_cast<unsigned int>(stream.precision()));
 
505
 
                                swprintf(format_string, 32, L"%%%u.%uLg", static_cast<unsigned int>(stream.width()), static_cast<unsigned int>(stream.precision()));
 
507
 
                        stream.printout(buffer, swprintf(buffer, 32, format_string, f) );
 
508
 
                        if(stream.flags() & ios_base::unitbuf){
 
514
 
#endif //__UCLIBCXX_HAS_WCHAR__
 
518
 
#pragma GCC visibility pop