cprintf_formats.hh revision 1762
11689SN/A/* 22325SN/A * Copyright (c) 2003-2005 The Regents of The University of Michigan 31689SN/A * All rights reserved. 41689SN/A * 51689SN/A * Redistribution and use in source and binary forms, with or without 61689SN/A * modification, are permitted provided that the following conditions are 71689SN/A * met: redistributions of source code must retain the above copyright 81689SN/A * notice, this list of conditions and the following disclaimer; 91689SN/A * redistributions in binary form must reproduce the above copyright 101689SN/A * notice, this list of conditions and the following disclaimer in the 111689SN/A * documentation and/or other materials provided with the distribution; 121689SN/A * neither the name of the copyright holders nor the names of its 131689SN/A * contributors may be used to endorse or promote products derived from 141689SN/A * this software without specific prior written permission. 151689SN/A * 161689SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171689SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181689SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191689SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201689SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211689SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221689SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231689SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241689SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251689SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261689SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 272665Ssaidi@eecs.umich.edu */ 282665Ssaidi@eecs.umich.edu 292756Sksewell@umich.edu#ifndef __CPRINTF_FORMATS_HH__ 301689SN/A#define __CPRINTF_FORMATS_HH__ 311689SN/A 321858SN/Astruct Format 332733Sktlim@umich.edu{ 341858SN/A bool alternate_form; 354762Snate@binkert.org bool flush_left; 364762Snate@binkert.org bool print_sign; 374762Snate@binkert.org bool blank_space; 384762Snate@binkert.org bool fill_zero; 394762Snate@binkert.org bool uppercase; 404762Snate@binkert.org enum { dec, hex, oct } base; 414762Snate@binkert.org enum { none, string, integer, character, floating } format; 424762Snate@binkert.org enum { best, fixed, scientific } float_format; 434762Snate@binkert.org int precision; 441858SN/A int width; 452356SN/A 461060SN/A Format() { clear(); } 471060SN/A 481060SN/A void clear() 491060SN/A { 501060SN/A alternate_form = false; 512794Sktlim@umich.edu flush_left = false; 522794Sktlim@umich.edu print_sign = false; 532794Sktlim@umich.edu blank_space = false; 542794Sktlim@umich.edu fill_zero = false; 555529Snate@binkert.org uppercase = false; 565529Snate@binkert.org base = dec; 572669Sktlim@umich.edu format = none; 581060SN/A precision = -1; 595529Snate@binkert.org width = 0; 602292SN/A } 611060SN/A}; 621060SN/A 631060SN/Atemplate <typename T> 642292SN/Ainline void 652733Sktlim@umich.edu_format_char(std::ostream &out, const T &data, Format &fmt) 662292SN/A{ 672292SN/A using namespace std; 682292SN/A 692292SN/A out << data; 701060SN/A} 711755SN/A 721060SN/Atemplate <typename T> 731060SN/Ainline void 741060SN/A_format_integer(std::ostream &out, const T &data, Format &fmt) 751060SN/A{ 761060SN/A using namespace std; 771060SN/A 781755SN/A switch (fmt.base) { 791060SN/A case Format::hex: 801060SN/A out.setf(ios::hex, ios::basefield); 811060SN/A break; 821060SN/A 831060SN/A case Format::oct: 841060SN/A out.setf(ios::oct, ios::basefield); 855336Shines@cs.fsu.edu break; 861060SN/A 874873Sstever@eecs.umich.edu case Format::dec: 881060SN/A out.setf(ios::dec, ios::basefield); 891060SN/A break; 901060SN/A } 912829Sksewell@umich.edu 923221Sktlim@umich.edu if (fmt.alternate_form) { 932829Sksewell@umich.edu if (!fmt.fill_zero) 942829Sksewell@umich.edu out.setf(ios::showbase); 952829Sksewell@umich.edu else { 962829Sksewell@umich.edu switch (fmt.base) { 972829Sksewell@umich.edu case Format::hex: 982829Sksewell@umich.edu out << "0x"; 992829Sksewell@umich.edu fmt.width -= 2; 1002829Sksewell@umich.edu break; 1012829Sksewell@umich.edu case Format::oct: 1022829Sksewell@umich.edu out << "0"; 1032829Sksewell@umich.edu fmt.width -= 1; 1042829Sksewell@umich.edu break; 1052829Sksewell@umich.edu case Format::dec: 1062829Sksewell@umich.edu break; 1072829Sksewell@umich.edu } 1082829Sksewell@umich.edu } 1092829Sksewell@umich.edu } 1102829Sksewell@umich.edu 1112829Sksewell@umich.edu if (fmt.fill_zero) 1122829Sksewell@umich.edu out.fill('0'); 1132829Sksewell@umich.edu 1145336Shines@cs.fsu.edu if (fmt.width > 0) 1152829Sksewell@umich.edu out.width(fmt.width); 1164873Sstever@eecs.umich.edu 1172829Sksewell@umich.edu if (fmt.flush_left && !fmt.fill_zero) 1182829Sksewell@umich.edu out.setf(ios::left); 1192829Sksewell@umich.edu 1202875Sksewell@umich.edu if (fmt.print_sign) 1213859Sbinkertn@umich.edu out.setf(ios::showpos); 1222875Sksewell@umich.edu 1232875Sksewell@umich.edu if (fmt.uppercase) 1242875Sksewell@umich.edu out.setf(ios::uppercase); 1252875Sksewell@umich.edu 1262875Sksewell@umich.edu out << data; 1272875Sksewell@umich.edu} 1283859Sbinkertn@umich.edu 1292875Sksewell@umich.edutemplate <typename T> 1302875Sksewell@umich.eduinline void 1312875Sksewell@umich.edu_format_float(std::ostream &out, const T &data, Format &fmt) 1323859Sbinkertn@umich.edu{ 1332875Sksewell@umich.edu using namespace std; 1342875Sksewell@umich.edu 1352875Sksewell@umich.edu switch (fmt.float_format) { 1362875Sksewell@umich.edu case Format::scientific: 1372875Sksewell@umich.edu if (fmt.precision != -1) { 1382875Sksewell@umich.edu if (fmt.width > 0) 1392875Sksewell@umich.edu out.width(fmt.width); 1403221Sktlim@umich.edu 1413221Sktlim@umich.edu if (fmt.precision == 0) 1422875Sksewell@umich.edu fmt.precision = 1; 1432875Sksewell@umich.edu else 1442875Sksewell@umich.edu out.setf(ios::scientific); 1452875Sksewell@umich.edu 1465336Shines@cs.fsu.edu out.precision(fmt.precision); 1472875Sksewell@umich.edu } else 1484873Sstever@eecs.umich.edu if (fmt.width > 0) 1492875Sksewell@umich.edu out.width(fmt.width); 1502875Sksewell@umich.edu 1512875Sksewell@umich.edu if (fmt.uppercase) 1525529Snate@binkert.org out.setf(ios::uppercase); 1532733Sktlim@umich.edu break; 1543781Sgblack@eecs.umich.edu 1553781Sgblack@eecs.umich.edu case Format::fixed: 1561060SN/A if (fmt.precision != -1) { 1572292SN/A if (fmt.width > 0) 1584329Sktlim@umich.edu out.width(fmt.width); 1594329Sktlim@umich.edu 1604329Sktlim@umich.edu out.setf(ios::fixed); 1614329Sktlim@umich.edu out.precision(fmt.precision); 1624329Sktlim@umich.edu } else 1631060SN/A if (fmt.width > 0) 1644329Sktlim@umich.edu out.width(fmt.width); 1654329Sktlim@umich.edu 1661060SN/A break; 1675529Snate@binkert.org 1682292SN/A default: 1692292SN/A if (fmt.precision != -1) 1701060SN/A out.precision(fmt.precision); 1714329Sktlim@umich.edu 1724329Sktlim@umich.edu if (fmt.width > 0) 1732292SN/A out.width(fmt.width); 1745529Snate@binkert.org 1751060SN/A break; 1765529Snate@binkert.org } 1772292SN/A 1782292SN/A out << data; 1792292SN/A} 1802292SN/A 1811060SN/Atemplate <typename T> 1822873Sktlim@umich.eduinline void 1832873Sktlim@umich.edu_format_string(std::ostream &out, const T &data, Format &fmt) 1842873Sktlim@umich.edu{ 1852873Sktlim@umich.edu using namespace std; 1862873Sktlim@umich.edu 1872873Sktlim@umich.edu#if defined(__GNUC__) && (__GNUC__ < 3) || 1 1882873Sktlim@umich.edu if (fmt.width > 0) { 1892873Sktlim@umich.edu std::stringstream foo; 1901060SN/A foo << data; 1911060SN/A int flen = foo.str().size(); 1921858SN/A 1932292SN/A if (fmt.width > flen) { 1941060SN/A char *spaces = new char[fmt.width - flen + 1]; 1951060SN/A memset(spaces, ' ', fmt.width - flen); 1962843Sktlim@umich.edu spaces[fmt.width - flen] = 0; 1975529Snate@binkert.org 1982316SN/A if (fmt.flush_left) 1991060SN/A out << foo.str() << spaces; 2003221Sktlim@umich.edu else 2013221Sktlim@umich.edu out << spaces << foo.str(); 2023221Sktlim@umich.edu 2033221Sktlim@umich.edu delete [] spaces; 2043221Sktlim@umich.edu } else 2051681SN/A out << data; 2064598Sbinkertn@umich.edu } else 2072794Sktlim@umich.edu out << data; 2082316SN/A#else 2092316SN/A if (fmt.width > 0) 2102316SN/A out.width(fmt.width); 2112316SN/A if (fmt.flush_left) 2122316SN/A out.setf(ios::left); 2134598Sbinkertn@umich.edu 2144598Sbinkertn@umich.edu out << data; 2154598Sbinkertn@umich.edu#endif 2162794Sktlim@umich.edu} 2172316SN/A 2181858SN/A///////////////////////////////////////////////////////////////////////////// 2192292SN/A// 2202292SN/A// The code below controls the actual usage of formats for various types 2211681SN/A// 2221681SN/A 2232325SN/A// 2242325SN/A// character formats 2252325SN/A// 2261060SN/Atemplate <typename T> 2272292SN/Ainline void 2282292SN/Aformat_char(std::ostream &out, const T &data, Format &fmt) 2292292SN/A{ out << "<bad arg type for char format>"; } 2302292SN/A 2312292SN/Ainline void 2322292SN/Aformat_char(std::ostream &out, char data, Format &fmt) 2331060SN/A{ _format_char(out, data, fmt); } 2341060SN/A 2351060SN/Ainline void 2361060SN/Aformat_char(std::ostream &out, unsigned char data, Format &fmt) 2371060SN/A{ _format_char(out, data, fmt); } 2381060SN/A 2391060SN/Ainline void 2401060SN/Aformat_char(std::ostream &out, signed char data, Format &fmt) 2411060SN/A{ _format_char(out, data, fmt); } 2421060SN/A 2431060SN/Ainline void 2442292SN/Aformat_char(std::ostream &out, short data, Format &fmt) 2451060SN/A{ _format_char(out, (char)data, fmt); } 2461060SN/A 2471060SN/Ainline void 2481060SN/Aformat_char(std::ostream &out, unsigned short data, Format &fmt) 2491060SN/A{ _format_char(out, (char)data, fmt); } 2501060SN/A 2511060SN/Ainline void 2521060SN/Aformat_char(std::ostream &out, int data, Format &fmt) 2532292SN/A{ _format_char(out, (char)data, fmt); } 2542292SN/A 2552292SN/Ainline void 2562292SN/Aformat_char(std::ostream &out, unsigned int data, Format &fmt) 2572292SN/A{ _format_char(out, (char)data, fmt); } 2582307SN/A 2592831Sksewell@umich.eduinline void 2602831Sksewell@umich.eduformat_char(std::ostream &out, long data, Format &fmt) 2612831Sksewell@umich.edu{ _format_char(out, (char)data, fmt); } 2622831Sksewell@umich.edu 2632831Sksewell@umich.eduinline void 2642831Sksewell@umich.eduformat_char(std::ostream &out, unsigned long data, Format &fmt) 2652292SN/A{ _format_char(out, (char)data, fmt); } 2662307SN/A 2672292SN/Ainline void 2682292SN/Aformat_char(std::ostream &out, long long data, Format &fmt) 2692316SN/A{ _format_char(out, (char)data, fmt); } 2702292SN/A 2712292SN/Ainline void 2722292SN/Aformat_char(std::ostream &out, unsigned long long data, Format &fmt) 2732292SN/A{ _format_char(out, (char)data, fmt); } 2742292SN/A 2752292SN/A// 2761060SN/A// integer formats 2772292SN/A// 2782292SN/Atemplate <typename T> 2791060SN/Ainline void 2802292SN/Aformat_integer(std::ostream &out, const T &data, Format &fmt) 2812307SN/A{ _format_integer(out, data, fmt); } 2822292SN/Ainline void 2832292SN/Aformat_integer(std::ostream &out, char data, Format &fmt) 2842292SN/A{ _format_integer(out, data, fmt); } 2852325SN/Ainline void 2862292SN/Aformat_integer(std::ostream &out, unsigned char data, Format &fmt) 2872292SN/A{ _format_integer(out, data, fmt); } 2882292SN/Ainline void 2892325SN/Aformat_integer(std::ostream &out, signed char data, Format &fmt) 2902292SN/A{ _format_integer(out, data, fmt); } 2912292SN/A#if 0 2922292SN/Ainline void 2932292SN/Aformat_integer(std::ostream &out, short data, Format &fmt) 2942292SN/A{ _format_integer(out, data, fmt); } 2952292SN/Ainline void 2962292SN/Aformat_integer(std::ostream &out, unsigned short data, Format &fmt) 2972292SN/A{ _format_integer(out, data, fmt); } 2982292SN/Ainline void 2992292SN/Aformat_integer(std::ostream &out, int data, Format &fmt) 3002292SN/A{ _format_integer(out, data, fmt); } 3012325SN/Ainline void 3022292SN/Aformat_integer(std::ostream &out, unsigned int data, Format &fmt) 3032292SN/A{ _format_integer(out, data, fmt); } 3042292SN/Ainline void 3052325SN/Aformat_integer(std::ostream &out, long data, Format &fmt) 3062292SN/A{ _format_integer(out, data, fmt); } 3072292SN/Ainline void 3082292SN/Aformat_integer(std::ostream &out, unsigned long data, Format &fmt) 3092292SN/A{ _format_integer(out, data, fmt); } 3102292SN/Ainline void 3112292SN/Aformat_integer(std::ostream &out, long long data, Format &fmt) 3122292SN/A{ _format_integer(out, data, fmt); } 3132292SN/Ainline void 3143221Sktlim@umich.eduformat_integer(std::ostream &out, unsigned long long data, Format &fmt) 3153221Sktlim@umich.edu{ _format_integer(out, data, fmt); } 3163221Sktlim@umich.edu#endif 3172292SN/A 3182292SN/A// 3192292SN/A// floating point formats 3202292SN/A// 3212292SN/Atemplate <typename T> 3222292SN/Ainline void 3232292SN/Aformat_float(std::ostream &out, const T &data, Format &fmt) 3242292SN/A{ out << "<bad arg type for float format>"; } 3252292SN/A 3261060SN/Ainline void 3272292SN/Aformat_float(std::ostream &out, float data, Format &fmt) 3281060SN/A{ _format_float(out, data, fmt); } 3291060SN/A 3302292SN/Ainline void 3312292SN/Aformat_float(std::ostream &out, double data, Format &fmt) 3322292SN/A{ _format_float(out, data, fmt); } 3332829Sksewell@umich.edu 3342829Sksewell@umich.edu// 3353093Sksewell@umich.edu// string formats 3363093Sksewell@umich.edu// 3373093Sksewell@umich.edutemplate <typename T> 3383093Sksewell@umich.eduinline void 3393093Sksewell@umich.eduformat_string(std::ostream &out, const T &data, Format &fmt) 3402292SN/A{ _format_string(out, data, fmt); } 3411060SN/A 3421060SN/Ainline void 3431060SN/Aformat_string(std::ostream &out, const std::stringstream &data, Format &fmt) 3441755SN/A{ _format_string(out, data.str(), fmt); } 3451060SN/A 3461060SN/A#endif // __CPRINTF_FORMATS_HH__ 3471060SN/A