4b61ec36e3
Stubbed out more of STL.
538 lines
16 KiB
Plaintext
538 lines
16 KiB
Plaintext
/* Copyright (C) 2004 Garrett A. Kajmowicz
|
|
|
|
This file is part of the uClibc++ Library.
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include <basic_definitions>
|
|
#include <cstddef>
|
|
#include <ios>
|
|
#include <cctype>
|
|
#include <string>
|
|
#include <stdio.h>
|
|
|
|
#ifndef __STD_HEADER_OSTREAM_HELPERS
|
|
#define __STD_HEADER_OSTREAM_HELPERS 1
|
|
|
|
#pragma GCC visibility push(default)
|
|
|
|
namespace std{
|
|
|
|
/* We are making the following template class for serveral reasons. Firstly,
|
|
* we want to keep the main ostream code neat and tidy. Secondly, we want it
|
|
* to be easy to do partial specialization of the ostream code so that it can
|
|
* be expanded and put into the library. This will allow us to make application
|
|
* code smaller at the expense of increased library size. This is a fair
|
|
* trade-off when there are multiple applications being compiled. Also, this
|
|
* feature will be used optionally via configuration options. It will also
|
|
* allow us to keep the code bases in sync, dramatically simplifying the
|
|
* maintenance required. We specialized for char because wchar and others
|
|
* require different scanf functions
|
|
*/
|
|
|
|
|
|
|
|
template <class traits, class charT, class dataType> class _UCXXEXPORT __ostream_printout{
|
|
public:
|
|
static void printout(basic_ostream<charT,traits>& stream, const dataType n);
|
|
};
|
|
|
|
template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, signed long int>{
|
|
public:
|
|
static void printout(basic_ostream<char, traits >& stream, const signed long int n)
|
|
{
|
|
char buffer[20];
|
|
const char * c_ld = "%ld";
|
|
const char * c_lo = "%lo";
|
|
const char * c_lX = "%lX";
|
|
const char * c_lx = "%lx";
|
|
const char * c_hashlo = "%#lo";
|
|
const char * c_hashlX = "%#lX";
|
|
const char * c_hashlx = "%#lx";
|
|
|
|
const char * formatString=0;
|
|
|
|
if( stream.flags() & ios_base::dec){
|
|
formatString = c_ld;
|
|
}else if( stream.flags() & ios_base::oct){
|
|
if( stream.flags() & ios_base::showbase){
|
|
formatString = c_hashlo;
|
|
}else{
|
|
formatString = c_lo;
|
|
}
|
|
}else if (stream.flags() & ios_base::hex){
|
|
if(stream.flags() & ios_base::showbase){
|
|
if(stream.flags() & ios_base::uppercase){
|
|
formatString = c_hashlX;
|
|
}else{
|
|
formatString = c_hashlx;
|
|
}
|
|
}else{
|
|
if(stream.flags() & ios_base::uppercase){
|
|
formatString = c_lX;
|
|
}else{
|
|
formatString = c_lx;
|
|
}
|
|
}
|
|
}
|
|
|
|
stream.write(buffer, snprintf(buffer, 20, formatString, n) );
|
|
|
|
if(stream.flags() & ios_base::unitbuf){
|
|
stream.flush();
|
|
}
|
|
|
|
}
|
|
};
|
|
|
|
template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, unsigned long int>{
|
|
public:
|
|
static void printout(basic_ostream<char, traits >& stream, const unsigned long int n)
|
|
{
|
|
char buffer[20];
|
|
const char * c_lo = "%lo";
|
|
const char * c_lu = "%lu";
|
|
const char * c_lX = "%lX";
|
|
const char * c_lx = "%lx";
|
|
const char * c_hashlo = "%#lo";
|
|
const char * c_hashlX = "%#lX";
|
|
const char * c_hashlx = "%#lx";
|
|
const char * formatString=0;
|
|
|
|
if( stream.flags() & ios_base::dec){
|
|
formatString = c_lu;
|
|
}else if( stream.flags() & ios_base::oct){
|
|
if( stream.flags() & ios_base::showbase){
|
|
formatString = c_hashlo;
|
|
}else{
|
|
formatString = c_lo;
|
|
}
|
|
}else if (stream.flags() & ios_base::hex){
|
|
if(stream.flags() & ios_base::showbase){
|
|
if(stream.flags() & ios_base::uppercase){
|
|
formatString = c_hashlX;
|
|
}else{
|
|
formatString = c_hashlx;
|
|
}
|
|
}else{
|
|
if(stream.flags() & ios_base::uppercase){
|
|
formatString = c_lX;
|
|
}else{
|
|
formatString = c_lx;
|
|
}
|
|
}
|
|
}
|
|
|
|
stream.write(buffer, snprintf(buffer, 20, formatString, n));
|
|
if(stream.flags() & ios_base::unitbuf){
|
|
stream.flush();
|
|
}
|
|
}
|
|
};
|
|
|
|
#ifndef __STRICT_ANSI__
|
|
|
|
template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, signed long long int>{
|
|
public:
|
|
static void printout(basic_ostream<char, traits >& stream, const signed long long int n)
|
|
{
|
|
char buffer[28];
|
|
const char * lld = "%lld";
|
|
const char * llo = "%llo";
|
|
const char * llX = "%llX";
|
|
const char * llx = "%llx";
|
|
const char * hashllo = "%#llo";
|
|
const char * hashllX = "%#llX";
|
|
const char * hashllx = "%#llx";
|
|
const char * formatString=0;
|
|
|
|
if( stream.flags() & ios_base::dec){
|
|
formatString = lld;
|
|
}else if( stream.flags() & ios_base::oct){
|
|
if( stream.flags() & ios_base::showbase){
|
|
formatString = hashllo;
|
|
}else{
|
|
formatString = llo;
|
|
}
|
|
}else if (stream.flags() & ios_base::hex){
|
|
if(stream.flags() & ios_base::showbase){
|
|
if(stream.flags() & ios_base::uppercase){
|
|
formatString = hashllX;
|
|
}else{
|
|
formatString = hashllx;
|
|
}
|
|
}else{
|
|
if(stream.flags() & ios_base::uppercase){
|
|
formatString = llX;
|
|
}else{
|
|
formatString = llx;
|
|
}
|
|
}
|
|
}
|
|
|
|
stream.write(buffer, snprintf(buffer, 27, formatString, n) );
|
|
|
|
if(stream.flags() & ios_base::unitbuf){
|
|
stream.flush();
|
|
}
|
|
}
|
|
};
|
|
|
|
template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, unsigned long long int>{
|
|
public:
|
|
static void printout(basic_ostream<char, traits >& stream, const unsigned long long int n)
|
|
{
|
|
char buffer[28];
|
|
const char * llo = "%llo";
|
|
const char * llu = "%llu";
|
|
const char * llX = "%llX";
|
|
const char * llx = "%llx";
|
|
const char * hashllo = "%#llo";
|
|
const char * hashllX = "%#llX";
|
|
const char * hashllx = "%#llx";
|
|
const char * formatString=0;
|
|
|
|
if( stream.flags() & ios_base::dec){
|
|
formatString = llu;
|
|
}else if( stream.flags() & ios_base::oct){
|
|
if( stream.flags() & ios_base::showbase){
|
|
formatString = hashllo;
|
|
}else{
|
|
formatString = llo;
|
|
}
|
|
}else if (stream.flags() & ios_base::hex){
|
|
if(stream.flags() & ios_base::showbase){
|
|
if(stream.flags() & ios_base::uppercase){
|
|
formatString = hashllX;
|
|
}else{
|
|
formatString = hashllx;
|
|
}
|
|
}else{
|
|
if(stream.flags() & ios_base::uppercase){
|
|
formatString = llX;
|
|
}else{
|
|
formatString = llx;
|
|
}
|
|
}
|
|
}
|
|
|
|
stream.write(buffer, snprintf(buffer, 27, formatString, n) );
|
|
|
|
if(stream.flags() & ios_base::unitbuf){
|
|
stream.flush();
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
#endif //__STRICT_ANSI__
|
|
|
|
template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, double>{
|
|
public:
|
|
static void printout(basic_ostream<char, traits >& stream, double f)
|
|
{
|
|
char buffer[32];
|
|
int length;
|
|
|
|
#ifdef __AVR__
|
|
// this is lifted from the Arduino Print class
|
|
char *ptr=buffer;
|
|
|
|
// Handle negative numbers
|
|
if (f < 0.0)
|
|
{
|
|
*ptr++='-';
|
|
f = -f;
|
|
}
|
|
|
|
int digits=stream.precision();
|
|
|
|
// Round correctly so that print(1.999, 2) prints as "2.00"
|
|
double rounding = 0.5;
|
|
for (uint8_t i=0; i<digits; ++i)
|
|
rounding /= 10.0;
|
|
|
|
f += rounding;
|
|
|
|
// Extract the integer part of the number and print it
|
|
unsigned long int_part = (unsigned long)f;
|
|
double remainder = f - (double)int_part;
|
|
|
|
ltoa(int_part,ptr,10);
|
|
while(*ptr) ptr++;
|
|
|
|
// Print the decimal point, but only if there are digits beyond
|
|
if (digits > 0)
|
|
*ptr++='.';
|
|
|
|
// Extract digits from the remainder one at a time
|
|
while (digits-- > 0)
|
|
{
|
|
remainder *= 10.0;
|
|
int toPrint = int(remainder);
|
|
itoa(toPrint,ptr,10);
|
|
while(*ptr) ptr++;
|
|
remainder -= toPrint;
|
|
}
|
|
|
|
length=ptr-buffer;
|
|
|
|
#else
|
|
if(stream.flags() & ios_base::scientific){
|
|
if(stream.flags() & ios_base::uppercase){
|
|
length = snprintf(buffer, 32, "%*.*E", static_cast<int>(stream.width()),static_cast<int>(stream.precision()), f);
|
|
}else{
|
|
length = snprintf(buffer, 32, "%*.*e", static_cast<int>(stream.width()),static_cast<int>(stream.precision()), f);
|
|
}
|
|
} else if(stream.flags() & ios_base::fixed){
|
|
length = snprintf(buffer, 32, "%*.*f",static_cast<int>(stream.width()),static_cast<int>(stream.precision()), f);
|
|
} else {
|
|
length = snprintf(buffer, 32, "%*.*g",static_cast<int>(stream.width()),static_cast<int>(stream.precision()), f);
|
|
}
|
|
#endif
|
|
stream.write(buffer, length);
|
|
if(stream.flags() & ios_base::unitbuf){
|
|
stream.flush();
|
|
}
|
|
}
|
|
};
|
|
|
|
template <class traits> class _UCXXEXPORT __ostream_printout<traits, char, long double>{
|
|
public:
|
|
static void printout(basic_ostream<char, traits >& stream, const long double f)
|
|
{
|
|
char buffer[32];
|
|
int length;
|
|
if(stream.flags() & ios_base::scientific){
|
|
if(stream.flags() & ios_base::uppercase){
|
|
length = snprintf(buffer, 32, "%*.*LE", static_cast<int>(stream.width()), static_cast<int>(stream.precision()), f);
|
|
}else{
|
|
length = snprintf(buffer, 32, "%*.*Le", static_cast<int>(stream.width()), static_cast<int>(stream.precision()), f);
|
|
}
|
|
} else if(stream.flags() & ios_base::fixed){
|
|
length = snprintf(buffer, 32, "%*.*Lf", static_cast<int>(stream.width()), static_cast<int>(stream.precision()), f);
|
|
} else {
|
|
length = snprintf(buffer, 32, "%*.*Lg", static_cast<int>(stream.width()), static_cast<int>(stream.precision()), f);
|
|
}
|
|
stream.write(buffer, length);
|
|
if(stream.flags() & ios_base::unitbuf){
|
|
stream.flush();
|
|
}
|
|
|
|
}
|
|
};
|
|
|
|
#ifdef __UCLIBCXX_HAS_WCHAR__
|
|
template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, signed long int>{
|
|
public:
|
|
static void printout(basic_ostream<wchar_t, traits >& stream, const signed long int n)
|
|
{
|
|
wchar_t buffer[20];
|
|
if( stream.flags() & ios_base::dec){
|
|
stream.write(buffer, swprintf(buffer, 20, L"%ld", n));
|
|
}else if( stream.flags() & ios_base::oct){
|
|
if( stream.flags() & ios_base::showbase){
|
|
stream.write(buffer, swprintf(buffer, 20, L"%#lo", n));
|
|
}else{
|
|
stream.write(buffer, swprintf(buffer, 20, L"%lo", n) );
|
|
}
|
|
}else if (stream.flags() & ios_base::hex){
|
|
if(stream.flags() & ios_base::showbase){
|
|
if(stream.flags() & ios_base::uppercase){
|
|
stream.write(buffer, swprintf(buffer, 20, L"%#lX", n) );
|
|
}else{
|
|
stream.write(buffer, swprintf(buffer, 20, L"%#lx", n) );
|
|
}
|
|
}else{
|
|
if(stream.flags() & ios_base::uppercase){
|
|
stream.write(buffer, swprintf(buffer, 20, L"%lX", n) );
|
|
}else{
|
|
stream.write(buffer, swprintf(buffer, 20, L"%lx", n) );
|
|
}
|
|
}
|
|
}
|
|
if(stream.flags() & ios_base::unitbuf){
|
|
stream.flush();
|
|
}
|
|
}
|
|
};
|
|
|
|
template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, unsigned long int>{
|
|
public:
|
|
static void printout(basic_ostream<wchar_t, traits >& stream, const unsigned long int n)
|
|
{
|
|
wchar_t buffer[20];
|
|
if( stream.flags() & ios_base::dec){
|
|
stream.write(buffer, swprintf(buffer, 20, L"%lu", n));
|
|
}else if( stream.flags() & ios_base::oct){
|
|
if( stream.flags() & ios_base::showbase){
|
|
stream.write(buffer, swprintf(buffer, 20, L"%#lo", n));
|
|
}else{
|
|
stream.write(buffer, swprintf(buffer, 20, L"%lo", n) );
|
|
}
|
|
}else if (stream.flags() & ios_base::hex){
|
|
if(stream.flags() & ios_base::showbase){
|
|
if(stream.flags() & ios_base::uppercase){
|
|
stream.write(buffer, swprintf(buffer, 20, L"%#lX", n) );
|
|
}else{
|
|
stream.write(buffer, swprintf(buffer, 20, L"%#lx", n) );
|
|
}
|
|
}else{
|
|
if(stream.flags() & ios_base::uppercase){
|
|
stream.write(buffer, swprintf(buffer, 20, L"%lX", n) );
|
|
}else{
|
|
stream.write(buffer, swprintf(buffer, 20, L"%lx", n) );
|
|
}
|
|
}
|
|
}
|
|
if(stream.flags() & ios_base::unitbuf){
|
|
stream.flush();
|
|
}
|
|
}
|
|
};
|
|
|
|
#ifndef __STRICT_ANSI__
|
|
|
|
template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, signed long long int>{
|
|
public:
|
|
static void printout(basic_ostream<wchar_t, traits >& stream, const signed long long int n)
|
|
{
|
|
wchar_t buffer[28];
|
|
if( stream.flags() & ios_base::dec){
|
|
stream.write(buffer, swprintf(buffer, 27, L"%lld", n));
|
|
}else if( stream.flags() & ios_base::oct){
|
|
if( stream.flags() & ios_base::showbase){
|
|
stream.write(buffer, swprintf(buffer, 27, L"%#llo", n));
|
|
}else{
|
|
stream.write(buffer, swprintf(buffer, 27, L"%llo", n) );
|
|
}
|
|
}else if (stream.flags() & ios_base::hex){
|
|
if(stream.flags() & ios_base::showbase){
|
|
if(stream.flags() & ios_base::uppercase){
|
|
stream.write(buffer, swprintf(buffer, 27, L"%#llX", n) );
|
|
}else{
|
|
stream.write(buffer, swprintf(buffer, 27, L"%#llx", n) );
|
|
}
|
|
}else{
|
|
if(stream.flags() & ios_base::uppercase){
|
|
stream.write(buffer, swprintf(buffer, 27, L"%llX", n) );
|
|
}else{
|
|
stream.write(buffer, swprintf(buffer, 27, L"%llx", n) );
|
|
}
|
|
}
|
|
}
|
|
if(stream.flags() & ios_base::unitbuf){
|
|
stream.flush();
|
|
}
|
|
}
|
|
};
|
|
|
|
template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, unsigned long long int>{
|
|
public:
|
|
static void printout(basic_ostream<wchar_t, traits >& stream, const unsigned long long int n)
|
|
{
|
|
wchar_t buffer[28];
|
|
if( stream.flags() & ios_base::dec){
|
|
stream.write(buffer, swprintf(buffer, 27, L"%llu", n));
|
|
}else if( stream.flags() & ios_base::oct){
|
|
if( stream.flags() & ios_base::showbase){
|
|
stream.write(buffer, swprintf(buffer, 27, L"%#llo", n));
|
|
}else{
|
|
stream.write(buffer, swprintf(buffer, 27, L"%llo", n) );
|
|
}
|
|
}else if (stream.flags() & ios_base::hex){
|
|
if(stream.flags() & ios_base::showbase){
|
|
if(stream.flags() & ios_base::uppercase){
|
|
stream.write(buffer, swprintf(buffer, 27, L"%#llX", n) );
|
|
}else{
|
|
stream.write(buffer, swprintf(buffer, 27, L"%#llx", n) );
|
|
}
|
|
}else{
|
|
if(stream.flags() & ios_base::uppercase){
|
|
stream.write(buffer, swprintf(buffer, 27, L"%llX", n) );
|
|
}else{
|
|
stream.write(buffer, swprintf(buffer, 27, L"%llx", n) );
|
|
}
|
|
}
|
|
}
|
|
if(stream.flags() & ios_base::unitbuf){
|
|
stream.flush();
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
#endif //__STRICT_ANSI__
|
|
|
|
template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, double>{
|
|
public:
|
|
static void printout(basic_ostream<wchar_t, traits >& stream, const double f)
|
|
{
|
|
wchar_t buffer[32];
|
|
wchar_t format_string[32];
|
|
if(stream.flags() & ios_base::scientific){
|
|
if(stream.flags() & ios_base::uppercase){
|
|
swprintf(format_string, 32, L"%%%u.%uE", static_cast<int>(stream.width()), static_cast<unsigned int>(stream.precision()));
|
|
}else{
|
|
swprintf(format_string, 32, L"%%%u.%ue", static_cast<int>(stream.width()), static_cast<unsigned int>(stream.precision()));
|
|
}
|
|
} else if(stream.flags() & ios_base::fixed){
|
|
swprintf(format_string, 32, L"%%%u.%uf", static_cast<int>(stream.width()), static_cast<unsigned int>(stream.precision()));
|
|
} else {
|
|
swprintf(format_string, 32, L"%%%u.%ug", static_cast<int>(stream.width()), static_cast<unsigned int>(stream.precision()));
|
|
}
|
|
stream.write(buffer, swprintf(buffer, 32, format_string, f) );
|
|
if(stream.flags() & ios_base::unitbuf){
|
|
stream.flush();
|
|
}
|
|
}
|
|
};
|
|
|
|
template <class traits> class _UCXXEXPORT __ostream_printout<traits, wchar_t, long double>{
|
|
public:
|
|
static void printout(basic_ostream<wchar_t, traits >& stream, const long double f)
|
|
{
|
|
wchar_t buffer[32];
|
|
wchar_t format_string[32];
|
|
if(stream.flags() & ios_base::scientific){
|
|
if(stream.flags() & ios_base::uppercase){
|
|
swprintf(format_string, 32, L"%%%u.%uLE", static_cast<unsigned int>(stream.width()), static_cast<unsigned int>(stream.precision()));
|
|
}else{
|
|
swprintf(format_string, 32, L"%%%u.%uLe", static_cast<unsigned int>(stream.width()), static_cast<unsigned int>(stream.precision()));
|
|
}
|
|
} else if(stream.flags() & ios_base::fixed){
|
|
swprintf(format_string, 32, L"%%%u.%uLf", static_cast<unsigned int>(stream.width()), static_cast<unsigned int>(stream.precision()));
|
|
} else {
|
|
swprintf(format_string, 32, L"%%%u.%uLg", static_cast<unsigned int>(stream.width()), static_cast<unsigned int>(stream.precision()));
|
|
}
|
|
stream.write(buffer, swprintf(buffer, 32, format_string, f) );
|
|
if(stream.flags() & ios_base::unitbuf){
|
|
stream.flush();
|
|
}
|
|
}
|
|
};
|
|
|
|
#endif //__UCLIBCXX_HAS_WCHAR__
|
|
|
|
}
|
|
|
|
#pragma GCC visibility pop
|
|
|
|
#endif
|
|
|
|
|
|
|