cprintf_formats.hh revision 448
16899SN/A/* 26899SN/A * Copyright (c) 2003 The Regents of The University of Michigan 36899SN/A * All rights reserved. 46899SN/A * 56899SN/A * Redistribution and use in source and binary forms, with or without 66899SN/A * modification, are permitted provided that the following conditions are 76899SN/A * met: redistributions of source code must retain the above copyright 86899SN/A * notice, this list of conditions and the following disclaimer; 96899SN/A * redistributions in binary form must reproduce the above copyright 106899SN/A * notice, this list of conditions and the following disclaimer in the 116899SN/A * documentation and/or other materials provided with the distribution; 126899SN/A * neither the name of the copyright holders nor the names of its 136899SN/A * contributors may be used to endorse or promote products derived from 146899SN/A * this software without specific prior written permission. 156899SN/A * 166899SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 176899SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 186899SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 196899SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 206899SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 216899SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 226899SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 236899SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 246899SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 256899SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 266899SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 276899SN/A */ 286899SN/A 296899SN/A#ifndef __CPRINTF_FORMATS_HH__ 307053SN/A#define __CPRINTF_FORMATS_HH__ 317053SN/A 326899SN/Astruct Format 337055SN/A{ 347055SN/A bool alternate_form; 357632SBrad.Beckmann@amd.com bool flush_left; 367053SN/A bool print_sign; 3714184Sgabeblack@google.com bool blank_space; 3814184Sgabeblack@google.com bool fill_zero; 397053SN/A bool uppercase; 406899SN/A enum { dec, hex, oct } base; 416899SN/A enum { none, string, integer, character, floating } format; 426899SN/A enum { best, fixed, scientific } float_format; 437053SN/A int precision; 446899SN/A int width; 457053SN/A 467053SN/A Format() { clear(); } 477053SN/A 4811025Snilay@cs.wisc.edu void clear() 498932SBrad.Beckmann@amd.com { 506899SN/A alternate_form = false; 517053SN/A flush_left = false; 5210302Snilay@cs.wisc.edu print_sign = false; 5311025Snilay@cs.wisc.edu blank_space = false; 5411025Snilay@cs.wisc.edu fill_zero = false; 556899SN/A uppercase = false; 567055SN/A base = dec; 576899SN/A format = none; 587053SN/A precision = -1; 598184Ssomayeh@cs.wisc.edu width = 0; 607053SN/A } 617053SN/A}; 627053SN/A 636899SN/Atemplate <typename T> 647053SN/Ainline void 657053SN/A_format_char(std::ostream &out, const T& data, Format &fmt) 666899SN/A{ 677053SN/A using namespace std; 686899SN/A 697053SN/A out << data; 709208Snilay@cs.wisc.edu} 717053SN/A 727053SN/Atemplate <typename T> 7311025Snilay@cs.wisc.eduinline void 7411025Snilay@cs.wisc.edu_format_integer(std::ostream &out, const T& data, Format &fmt) 758164Snilay@cs.wisc.edu{ 768932SBrad.Beckmann@amd.com using namespace std; 778932SBrad.Beckmann@amd.com 787053SN/A switch (fmt.base) { 796899SN/A case Format::hex: 806899SN/A out.setf(ios::hex, ios::basefield); 817055SN/A break; 827055SN/A 836899SN/A case Format::oct: 847053SN/A out.setf(ios::oct, ios::basefield); 857055SN/A break; 867053SN/A 876899SN/A case Format::dec: 886899SN/A out.setf(ios::dec, ios::basefield); 897053SN/A break; 90 } 91 92 if (fmt.alternate_form) { 93 if (!fmt.fill_zero) 94 out.setf(ios::showbase); 95 else { 96 switch (fmt.base) { 97 case Format::hex: 98 out << "0x"; 99 fmt.width -= 2; 100 break; 101 case Format::oct: 102 out << "0"; 103 fmt.width -= 1; 104 break; 105 case Format::dec: 106 break; 107 } 108 } 109 } 110 111 if (fmt.fill_zero) 112 out.fill('0'); 113 114 if (fmt.width > 0) 115 out.width(fmt.width); 116 117 if (fmt.flush_left && !fmt.fill_zero) 118 out.setf(ios::left); 119 120 if (fmt.print_sign) 121 out.setf(ios::showpos); 122 123 if (fmt.uppercase) 124 out.setf(ios::uppercase); 125 126 out << data; 127} 128 129template <typename T> 130inline void 131_format_float(std::ostream &out, const T& data, Format &fmt) 132{ 133 using namespace std; 134 135 switch (fmt.float_format) { 136 case Format::scientific: 137 if (fmt.precision != -1) { 138 if (fmt.width > 0) 139 out.width(fmt.width); 140 141 if (fmt.precision == 0) 142 fmt.precision = 1; 143 else 144 out.setf(ios::scientific); 145 146 out.precision(fmt.precision); 147 } else 148 if (fmt.width > 0) 149 out.width(fmt.width); 150 151 if (fmt.uppercase) 152 out.setf(ios::uppercase); 153 break; 154 155 case Format::fixed: 156 if (fmt.precision != -1) { 157 if (fmt.width > 0) 158 out.width(fmt.width); 159 160 out.setf(ios::fixed); 161 out.precision(fmt.precision); 162 } else 163 if (fmt.width > 0) 164 out.width(fmt.width); 165 166 break; 167 168 default: 169 if (fmt.precision != -1) 170 out.precision(fmt.precision); 171 172 if (fmt.width > 0) 173 out.width(fmt.width); 174 175 break; 176 } 177 178 out << data; 179} 180 181template <typename T> 182inline void 183_format_string(std::ostream &out, const T& data, Format &fmt) 184{ 185 using namespace std; 186 187#if defined(__GNUC__) && (__GNUC__ < 3) || 1 188 if (fmt.width > 0) { 189 std::stringstream foo; 190 foo << data; 191 int flen = foo.str().size(); 192 193 if (fmt.width > flen) { 194 char *spaces = new char[fmt.width - flen + 1]; 195 memset(spaces, ' ', fmt.width - flen); 196 spaces[fmt.width - flen] = 0; 197 198 if (fmt.flush_left) 199 out << foo.str() << spaces; 200 else 201 out << spaces << foo.str(); 202 203 delete [] spaces; 204 } else 205 out << data; 206 } else 207 out << data; 208#else 209 if (fmt.width > 0) 210 out.width(fmt.width); 211 if (fmt.flush_left) 212 out.setf(ios::left); 213 214 out << data; 215#endif 216} 217 218///////////////////////////////////////////////////////////////////////////// 219// 220// The code below controls the actual usage of formats for various types 221// 222 223// 224// character formats 225// 226template <typename T> 227inline void 228format_char(std::ostream &out, const T& data, Format &fmt) 229{ out << "<bad arg type for char format>"; } 230 231inline void 232format_char(std::ostream &out, char data, Format &fmt) 233{ _format_char(out, data, fmt); } 234 235inline void 236format_char(std::ostream &out, unsigned char data, Format &fmt) 237{ _format_char(out, data, fmt); } 238 239inline void 240format_char(std::ostream &out, signed char data, Format &fmt) 241{ _format_char(out, data, fmt); } 242 243inline void 244format_char(std::ostream &out, short data, Format &fmt) 245{ _format_char(out, (char)data, fmt); } 246 247inline void 248format_char(std::ostream &out, unsigned short data, Format &fmt) 249{ _format_char(out, (char)data, fmt); } 250 251inline void 252format_char(std::ostream &out, int data, Format &fmt) 253{ _format_char(out, (char)data, fmt); } 254 255inline void 256format_char(std::ostream &out, unsigned int data, Format &fmt) 257{ _format_char(out, (char)data, fmt); } 258 259inline void 260format_char(std::ostream &out, long data, Format &fmt) 261{ _format_char(out, (char)data, fmt); } 262 263inline void 264format_char(std::ostream &out, unsigned long data, Format &fmt) 265{ _format_char(out, (char)data, fmt); } 266 267inline void 268format_char(std::ostream &out, long long data, Format &fmt) 269{ _format_char(out, (char)data, fmt); } 270 271inline void 272format_char(std::ostream &out, unsigned long long data, Format &fmt) 273{ _format_char(out, (char)data, fmt); } 274 275// 276// integer formats 277// 278template <typename T> 279inline void 280format_integer(std::ostream &out, const T &data, Format &fmt) 281{ _format_integer(out, data, fmt); } 282 283#if 0 284inline void 285format_integer(std::ostream &out, char data, Format &fmt) 286{ _format_integer(out, data, fmt); } 287inline void 288format_integer(std::ostream &out, unsigned char data, Format &fmt) 289{ _format_integer(out, data, fmt); } 290inline void 291format_integer(std::ostream &out, signed char data, Format &fmt) 292{ _format_integer(out, data, fmt); } 293inline void 294format_integer(std::ostream &out, short data, Format &fmt) 295{ _format_integer(out, data, fmt); } 296inline void 297format_integer(std::ostream &out, unsigned short data, Format &fmt) 298{ _format_integer(out, data, fmt); } 299inline void 300format_integer(std::ostream &out, int data, Format &fmt) 301{ _format_integer(out, data, fmt); } 302inline void 303format_integer(std::ostream &out, unsigned int data, Format &fmt) 304{ _format_integer(out, data, fmt); } 305inline void 306format_integer(std::ostream &out, long data, Format &fmt) 307{ _format_integer(out, data, fmt); } 308inline void 309format_integer(std::ostream &out, unsigned long data, Format &fmt) 310{ _format_integer(out, data, fmt); } 311inline void 312format_integer(std::ostream &out, long long data, Format &fmt) 313{ _format_integer(out, data, fmt); } 314inline void 315format_integer(std::ostream &out, unsigned long long data, Format &fmt) 316{ _format_integer(out, data, fmt); } 317#endif 318 319// 320// floating point formats 321// 322template <typename T> 323inline void 324format_float(std::ostream &out, const T& data, Format &fmt) 325{ out << "<bad arg type for float format>"; } 326 327inline void 328format_float(std::ostream &out, float data, Format &fmt) 329{ _format_float(out, data, fmt); } 330 331inline void 332format_float(std::ostream &out, double data, Format &fmt) 333{ _format_float(out, data, fmt); } 334 335// 336// string formats 337// 338template <typename T> 339inline void 340format_string(std::ostream &out, const T& data, Format &fmt) 341{ _format_string(out, data, fmt); } 342 343inline void 344format_string(std::ostream &out, const std::stringstream& data, Format &fmt) 345{ _format_string(out, data.str(), fmt); } 346 347#endif // __CPRINTF_FORMATS_HH__ 348