diff --git a/capture/build/win32/capture.vcxproj b/capture/build/win32/capture.vcxproj index daf60a5c..bcf4ac8b 100644 --- a/capture/build/win32/capture.vcxproj +++ b/capture/build/win32/capture.vcxproj @@ -134,6 +134,7 @@ + @@ -156,6 +157,7 @@ + diff --git a/capture/build/win32/capture.vcxproj.filters b/capture/build/win32/capture.vcxproj.filters index cc3623ff..4eeef4e9 100644 --- a/capture/build/win32/capture.vcxproj.filters +++ b/capture/build/win32/capture.vcxproj.filters @@ -36,6 +36,9 @@ common + + server + @@ -104,5 +107,8 @@ common + + server + \ No newline at end of file diff --git a/capture/src/capture.cpp b/capture/src/capture.cpp index 1c32366d..6f0dc96b 100644 --- a/capture/src/capture.cpp +++ b/capture/src/capture.cpp @@ -13,6 +13,7 @@ #include "../../common/TracyProtocol.hpp" #include "../../server/TracyFileWrite.hpp" #include "../../server/TracyMemory.hpp" +#include "../../server/TracyPrint.hpp" #include "../../server/TracyWorker.hpp" #include "getopt.h" @@ -26,87 +27,6 @@ void SigInt( int ) } #endif -static const char* TimeToString( int64_t ns ) -{ - enum { Pool = 8 }; - static char bufpool[Pool][64]; - static int bufsel = 0; - char* buf = bufpool[bufsel]; - bufsel = ( bufsel + 1 ) % Pool; - - const char* sign = ""; - if( ns < 0 ) - { - sign = "-"; - ns = -ns; - } - - if( ns < 1000 ) - { - sprintf( buf, "%s%" PRIi64 " ns", sign, ns ); - } - else if( ns < 1000ll * 1000 ) - { - sprintf( buf, "%s%.2f us", sign, ns / 1000. ); - } - else if( ns < 1000ll * 1000 * 1000 ) - { - sprintf( buf, "%s%.2f ms", sign, ns / ( 1000. * 1000. ) ); - } - else if( ns < 1000ll * 1000 * 1000 * 60 ) - { - sprintf( buf, "%s%.2f s", sign, ns / ( 1000. * 1000. * 1000. ) ); - } - else - { - const auto m = int64_t( ns / ( 1000ll * 1000 * 1000 * 60 ) ); - const auto s = int64_t( ns - m * ( 1000ll * 1000 * 1000 * 60 ) ); - sprintf( buf, "%s%" PRIi64 ":%04.1f", sign, m, s / ( 1000. * 1000. * 1000. ) ); - } - return buf; -} - -static const char* RealToString( double val, bool separator ) -{ - enum { Pool = 8 }; - static char bufpool[Pool][64]; - static int bufsel = 0; - char* buf = bufpool[bufsel]; - bufsel = ( bufsel + 1 ) % Pool; - - sprintf( buf, "%f", val ); - auto ptr = buf; - if( *ptr == '-' ) ptr++; - - const auto vbegin = ptr; - - if( separator ) - { - while( *ptr != '\0' && *ptr != ',' && *ptr != '.' ) ptr++; - auto end = ptr; - while( *end != '\0' ) end++; - auto sz = end - ptr; - - while( ptr - vbegin > 3 ) - { - ptr -= 3; - memmove( ptr+1, ptr, sz ); - *ptr = ','; - sz += 4; - } - } - - while( *ptr != '\0' && *ptr != ',' && *ptr != '.' ) ptr++; - - if( *ptr == '\0' ) return buf; - while( *ptr != '\0' ) ptr++; - ptr--; - while( *ptr == '0' && *ptr != ',' && *ptr != '.' ) ptr--; - if( *ptr != '.' && *ptr != ',' ) ptr++; - *ptr = '\0'; - return buf; -} - void Usage() { @@ -169,7 +89,7 @@ int main( int argc, char** argv ) } } while( !worker.HasData() ) std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); - printf( "\nQueue delay: %s\nTimer resolution: %s\n", TimeToString( worker.GetDelay() ), TimeToString( worker.GetResolution() ) ); + printf( "\nQueue delay: %s\nTimer resolution: %s\n", tracy::TimeToString( worker.GetDelay() ), tracy::TimeToString( worker.GetResolution() ) ); #ifndef _MSC_VER struct sigaction sigint; @@ -203,7 +123,7 @@ int main( int argc, char** argv ) { printf( "\33[2K\r\033[36;1m%7.2f Mbps", mbps ); } - printf( " \033[0m /\033[36;1m%5.1f%% \033[0m=\033[33;1m%7.2f Mbps \033[0m| Mem: \033[31;1m%.2f MB\033[0m | \033[33mTime: %s\033[0m", compRatio * 100.f, mbps / compRatio, tracy::memUsage.load( std::memory_order_relaxed ) / ( 1024.f * 1024.f ), TimeToString( worker.GetLastTime() - worker.GetTimeBegin() ) ); + printf( " \033[0m /\033[36;1m%5.1f%% \033[0m=\033[33;1m%7.2f Mbps \033[0m| Mem: \033[31;1m%.2f MB\033[0m | \033[33mTime: %s\033[0m", compRatio * 100.f, mbps / compRatio, tracy::memUsage.load( std::memory_order_relaxed ) / ( 1024.f * 1024.f ), tracy::TimeToString( worker.GetLastTime() - worker.GetTimeBegin() ) ); fflush( stdout ); std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) ); @@ -215,7 +135,7 @@ int main( int argc, char** argv ) printf( "\n\033[31;1mInstrumentation failure: %s\033[0m", tracy::Worker::GetFailureString( failure ) ); } - printf( "\nFrames: %" PRIu64 "\nTime span: %s\nZones: %s\nSaving trace...", worker.GetFrameCount( *worker.GetFramesBase() ), TimeToString( worker.GetLastTime() - worker.GetTimeBegin() ), RealToString( worker.GetZoneCount(), true ) ); + printf( "\nFrames: %" PRIu64 "\nTime span: %s\nZones: %s\nSaving trace...", worker.GetFrameCount( *worker.GetFramesBase() ), tracy::TimeToString( worker.GetLastTime() - worker.GetTimeBegin() ), tracy::RealToString( worker.GetZoneCount(), true ) ); fflush( stdout ); auto f = std::unique_ptr( tracy::FileWrite::Open( output ) ); if( f ) diff --git a/profiler/build/win32/Tracy.vcxproj b/profiler/build/win32/Tracy.vcxproj index 3a811396..e539a607 100644 --- a/profiler/build/win32/Tracy.vcxproj +++ b/profiler/build/win32/Tracy.vcxproj @@ -113,6 +113,7 @@ + @@ -163,6 +164,7 @@ + diff --git a/profiler/build/win32/Tracy.vcxproj.filters b/profiler/build/win32/Tracy.vcxproj.filters index ec971086..d7908bb6 100644 --- a/profiler/build/win32/Tracy.vcxproj.filters +++ b/profiler/build/win32/Tracy.vcxproj.filters @@ -96,6 +96,9 @@ server + + server + @@ -263,6 +266,9 @@ server + + server + diff --git a/server/TracyPrint.cpp b/server/TracyPrint.cpp new file mode 100644 index 00000000..c9411e45 --- /dev/null +++ b/server/TracyPrint.cpp @@ -0,0 +1,327 @@ +#include +#include +#include +#include +#include +#include + +#include "TracyPrint.hpp" + +namespace tracy +{ + +static const char* IntTable100 = + "00010203040506070809" + "10111213141516171819" + "20212223242526272829" + "30313233343536373839" + "40414243444546474849" + "50515253545556575859" + "60616263646566676869" + "70717273747576777879" + "80818283848586878889" + "90919293949596979899"; + +static inline void PrintTinyInt( char*& buf, uint64_t v ) +{ + if( v >= 10 ) + { + *buf++ = '0' + v/10; + } + *buf++ = '0' + v%10; +} + +static inline void PrintTinyInt0( char*& buf, uint64_t v ) +{ + if( v >= 10 ) + { + *buf++ = '0' + v/10; + } + else + { + *buf++ = '0'; + } + *buf++ = '0' + v%10; +} + +static inline void PrintSmallInt( char*& buf, uint64_t v ) +{ + if( v >= 100 ) + { + memcpy( buf, IntTable100 + v/10*2, 2 ); + buf += 2; + } + else if( v >= 10 ) + { + *buf++ = '0' + v/10; + } + *buf++ = '0' + v%10; +} + +static inline void PrintFrac00( char*& buf, uint64_t v ) +{ + *buf++ = '.'; + v += 5; + if( v/10%10 == 0 ) + { + *buf++ = '0' + v/100; + } + else + { + memcpy( buf, IntTable100 + v/10*2, 2 ); + buf += 2; + } +} + +static inline void PrintFrac0( char*& buf, uint64_t v ) +{ + *buf++ = '.'; + *buf++ = '0' + (v+50)/100; +} + +static inline void PrintSmallIntFrac( char*& buf, uint64_t v ) +{ + uint64_t in = v / 1000; + uint64_t fr = v % 1000; + if( fr >= 995 ) + { + PrintSmallInt( buf, in+1 ); + } + else + { + PrintSmallInt( buf, in ); + if( fr > 5 ) + { + PrintFrac00( buf, fr ); + } + } +} + +static inline void PrintSecondsFrac( char*& buf, uint64_t v ) +{ + uint64_t in = v / 1000; + uint64_t fr = v % 1000; + if( fr >= 950 ) + { + PrintTinyInt0( buf, in+1 ); + } + else + { + PrintTinyInt0( buf, in ); + if( fr > 50 ) + { + PrintFrac0( buf, fr ); + } + } +} + +const char* TimeToString( int64_t _ns ) +{ + enum { Pool = 8 }; + static char bufpool[Pool][64]; + static int bufsel = 0; + char* buf = bufpool[bufsel]; + char* bufstart = buf; + bufsel = ( bufsel + 1 ) % Pool; + + uint64_t ns; + if( _ns < 0 ) + { + *buf = '-'; + buf++; + ns = -_ns; + } + else + { + ns = _ns; + } + + if( ns < 1000 ) + { + PrintSmallInt( buf, ns ); + memcpy( buf, " ns", 4 ); + } + else if( ns < 1000ll * 1000 ) + { + PrintSmallIntFrac( buf, ns ); +#ifdef TRACY_EXTENDED_FONT + memcpy( buf, " \xce\xbcs", 5 ); +#else + memcpy( buf, " us", 4 ); +#endif + } + else if( ns < 1000ll * 1000 * 1000 ) + { + PrintSmallIntFrac( buf, ns / 1000 ); + memcpy( buf, " ms", 4 ); + } + else if( ns < 1000ll * 1000 * 1000 * 60 ) + { + PrintSmallIntFrac( buf, ns / ( 1000ll * 1000 ) ); + memcpy( buf, " s", 3 ); + } + else if( ns < 1000ll * 1000 * 1000 * 60 * 60 ) + { + const auto m = int64_t( ns / ( 1000ll * 1000 * 1000 * 60 ) ); + const auto s = int64_t( ns - m * ( 1000ll * 1000 * 1000 * 60 ) ) / ( 1000ll * 1000 ); + PrintTinyInt( buf, m ); + *buf++ = ':'; + PrintSecondsFrac( buf, s ); + *buf++ = '\0'; + } + else if( ns < 1000ll * 1000 * 1000 * 60 * 60 * 24 ) + { + const auto h = int64_t( ns / ( 1000ll * 1000 * 1000 * 60 * 60 ) ); + const auto m = int64_t( ns / ( 1000ll * 1000 * 1000 * 60 ) - h * 60 ); + const auto s = int64_t( ns / ( 1000ll * 1000 * 1000 ) - h * ( 60 * 60 ) - m * 60 ); + PrintTinyInt( buf, h ); + *buf++ = ':'; + PrintTinyInt0( buf, m ); + *buf++ = ':'; + PrintTinyInt0( buf, s ); + *buf++ = '\0'; + } + else + { + const auto d = int64_t( ns / ( 1000ll * 1000 * 1000 * 60 * 60 * 24 ) ); + const auto h = int64_t( ns / ( 1000ll * 1000 * 1000 * 60 * 60 ) - d * 24 ); + const auto m = int64_t( ns / ( 1000ll * 1000 * 1000 * 60 ) - d * ( 60 * 24 ) - h * 60 ); + const auto s = int64_t( ns / ( 1000ll * 1000 * 1000 ) - d * ( 60 * 60 * 24 ) - h * ( 60 * 60 ) - m * 60 ); + if( d < 1000 ) + { + PrintSmallInt( buf, d ); + *buf++ = 'd'; + } + else + { + buf += sprintf( buf, "%" PRIi64 "d", d ); + } + PrintTinyInt0( buf, h ); + *buf++ = ':'; + PrintTinyInt0( buf, m ); + *buf++ = ':'; + PrintTinyInt0( buf, s ); + *buf++ = '\0'; + } + return bufstart; +} + +const char* RealToString( double val, bool separator ) +{ + enum { Pool = 8 }; + static char bufpool[Pool][64]; + static int bufsel = 0; + char* buf = bufpool[bufsel]; + bufsel = ( bufsel + 1 ) % Pool; + + sprintf( buf, "%f", val ); + auto ptr = buf; + if( *ptr == '-' ) ptr++; + + const auto vbegin = ptr; + + if( separator ) + { + while( *ptr != '\0' && *ptr != ',' && *ptr != '.' ) ptr++; + auto end = ptr; + while( *end != '\0' ) end++; + auto sz = end - ptr; + + while( ptr - vbegin > 3 ) + { + ptr -= 3; + memmove( ptr+1, ptr, sz ); + *ptr = ','; + sz += 4; + } + } + + while( *ptr != '\0' && *ptr != ',' && *ptr != '.' ) ptr++; + + if( *ptr == '\0' ) return buf; + while( *ptr != '\0' ) ptr++; + ptr--; + while( *ptr == '0' ) ptr--; + if( *ptr != '.' && *ptr != ',' ) ptr++; + *ptr = '\0'; + return buf; +} + +const char* MemSizeToString( int64_t val ) +{ + enum { Pool = 8 }; + static char bufpool[Pool][64]; + static int bufsel = 0; + char* buf = bufpool[bufsel]; + bufsel = ( bufsel + 1 ) % Pool; + + const auto aval = abs( val ); + + if( aval < 10000ll ) + { + sprintf( buf, "%" PRIi64 " bytes", val ); + return buf; + } + + enum class Unit + { + Kilobyte, + Megabyte, + Gigabyte, + Terabyte + }; + Unit unit; + + if( aval < 10000ll * 1024 ) + { + sprintf( buf, "%.2f", val / 1024. ); + unit = Unit::Kilobyte; + } + else if( aval < 10000ll * 1024 * 1024 ) + { + sprintf( buf, "%.2f", val / ( 1024. * 1024 ) ); + unit = Unit::Megabyte; + } + else if( aval < 10000ll * 1024 * 1024 * 1024 ) + { + sprintf( buf, "%.2f", val / ( 1024. * 1024 * 1024 ) ); + unit = Unit::Gigabyte; + } + else + { + sprintf( buf, "%.2f", val / ( 1024. * 1024 * 1024 * 1024 ) ); + unit = Unit::Terabyte; + } + + auto ptr = buf; + while( *ptr ) ptr++; + ptr--; + while( ptr >= buf && *ptr == '0' ) ptr--; + if( *ptr != '.' ) ptr++; + + *ptr++ = ' '; + switch( unit ) + { + case Unit::Kilobyte: + *ptr++ = 'K'; + break; + case Unit::Megabyte: + *ptr++ = 'M'; + break; + case Unit::Gigabyte: + *ptr++ = 'G'; + break; + case Unit::Terabyte: + *ptr++ = 'T'; + break; + default: + assert( false ); + break; + } + *ptr++ = 'B'; + *ptr++ = '\0'; + + return buf; +} + +} diff --git a/server/TracyPrint.hpp b/server/TracyPrint.hpp new file mode 100644 index 00000000..5f132d02 --- /dev/null +++ b/server/TracyPrint.hpp @@ -0,0 +1,13 @@ +#ifndef __TRACYPRINT_HPP__ +#define __TRACYPRINT_HPP__ + +namespace tracy +{ + +const char* TimeToString( int64_t ns ); +const char* RealToString( double val, bool separator ); +const char* MemSizeToString( int64_t val ); + +} + +#endif diff --git a/server/TracyView.cpp b/server/TracyView.cpp index fc17b834..5dec5994 100644 --- a/server/TracyView.cpp +++ b/server/TracyView.cpp @@ -23,6 +23,7 @@ #include "TracyFilesystem.hpp" #include "TracyImGui.hpp" #include "TracyPopcnt.hpp" +#include "TracyPrint.hpp" #include "TracyView.hpp" #include "../imguicolortextedit/TextEditor.h" @@ -58,319 +59,6 @@ static const char* s_tracyStackFrames[] = { nullptr }; -static const char* IntTable100 = -"00010203040506070809" -"10111213141516171819" -"20212223242526272829" -"30313233343536373839" -"40414243444546474849" -"50515253545556575859" -"60616263646566676869" -"70717273747576777879" -"80818283848586878889" -"90919293949596979899"; - -static inline void PrintTinyInt( char*& buf, uint64_t v ) -{ - if( v >= 10 ) - { - *buf++ = '0' + v/10; - } - *buf++ = '0' + v%10; -} - -static inline void PrintTinyInt0( char*& buf, uint64_t v ) -{ - if( v >= 10 ) - { - *buf++ = '0' + v/10; - } - else - { - *buf++ = '0'; - } - *buf++ = '0' + v%10; -} - -static inline void PrintSmallInt( char*& buf, uint64_t v ) -{ - if( v >= 100 ) - { - memcpy( buf, IntTable100 + v/10*2, 2 ); - buf += 2; - } - else if( v >= 10 ) - { - *buf++ = '0' + v/10; - } - *buf++ = '0' + v%10; -} - -static inline void PrintFrac00( char*& buf, uint64_t v ) -{ - *buf++ = '.'; - v += 5; - if( v/10%10 == 0 ) - { - *buf++ = '0' + v/100; - } - else - { - memcpy( buf, IntTable100 + v/10*2, 2 ); - buf += 2; - } -} - -static inline void PrintFrac0( char*& buf, uint64_t v ) -{ - *buf++ = '.'; - *buf++ = '0' + (v+50)/100; -} - -static inline void PrintSmallIntFrac( char*& buf, uint64_t v ) -{ - uint64_t in = v / 1000; - uint64_t fr = v % 1000; - if( fr >= 995 ) - { - PrintSmallInt( buf, in+1 ); - } - else - { - PrintSmallInt( buf, in ); - if( fr > 5 ) - { - PrintFrac00( buf, fr ); - } - } -} - -static inline void PrintSecondsFrac( char*& buf, uint64_t v ) -{ - uint64_t in = v / 1000; - uint64_t fr = v % 1000; - if( fr >= 950 ) - { - PrintTinyInt0( buf, in+1 ); - } - else - { - PrintTinyInt0( buf, in ); - if( fr > 50 ) - { - PrintFrac0( buf, fr ); - } - } -} - -static const char* TimeToString( int64_t _ns ) -{ - enum { Pool = 8 }; - static char bufpool[Pool][64]; - static int bufsel = 0; - char* buf = bufpool[bufsel]; - char* bufstart = buf; - bufsel = ( bufsel + 1 ) % Pool; - - uint64_t ns; - if( _ns < 0 ) - { - *buf = '-'; - buf++; - ns = -_ns; - } - else - { - ns = _ns; - } - - if( ns < 1000 ) - { - PrintSmallInt( buf, ns ); - memcpy( buf, " ns", 4 ); - } - else if( ns < 1000ll * 1000 ) - { - PrintSmallIntFrac( buf, ns ); -#ifdef TRACY_EXTENDED_FONT - memcpy( buf, " \xce\xbcs", 5 ); -#else - memcpy( buf, " us", 4 ); -#endif - } - else if( ns < 1000ll * 1000 * 1000 ) - { - PrintSmallIntFrac( buf, ns / 1000 ); - memcpy( buf, " ms", 4 ); - } - else if( ns < 1000ll * 1000 * 1000 * 60 ) - { - PrintSmallIntFrac( buf, ns / ( 1000ll * 1000 ) ); - memcpy( buf, " s", 3 ); - } - else if( ns < 1000ll * 1000 * 1000 * 60 * 60 ) - { - const auto m = int64_t( ns / ( 1000ll * 1000 * 1000 * 60 ) ); - const auto s = int64_t( ns - m * ( 1000ll * 1000 * 1000 * 60 ) ) / ( 1000ll * 1000 ); - PrintTinyInt( buf, m ); - *buf++ = ':'; - PrintSecondsFrac( buf, s ); - *buf++ = '\0'; - } - else if( ns < 1000ll * 1000 * 1000 * 60 * 60 * 24 ) - { - const auto h = int64_t( ns / ( 1000ll * 1000 * 1000 * 60 * 60 ) ); - const auto m = int64_t( ns / ( 1000ll * 1000 * 1000 * 60 ) - h * 60 ); - const auto s = int64_t( ns / ( 1000ll * 1000 * 1000 ) - h * ( 60 * 60 ) - m * 60 ); - PrintTinyInt( buf, h ); - *buf++ = ':'; - PrintTinyInt0( buf, m ); - *buf++ = ':'; - PrintTinyInt0( buf, s ); - *buf++ = '\0'; - } - else - { - const auto d = int64_t( ns / ( 1000ll * 1000 * 1000 * 60 * 60 * 24 ) ); - const auto h = int64_t( ns / ( 1000ll * 1000 * 1000 * 60 * 60 ) - d * 24 ); - const auto m = int64_t( ns / ( 1000ll * 1000 * 1000 * 60 ) - d * ( 60 * 24 ) - h * 60 ); - const auto s = int64_t( ns / ( 1000ll * 1000 * 1000 ) - d * ( 60 * 60 * 24 ) - h * ( 60 * 60 ) - m * 60 ); - if( d < 1000 ) - { - PrintSmallInt( buf, d ); - *buf++ = 'd'; - } - else - { - buf += sprintf( buf, "%" PRIi64 "d", d ); - } - PrintTinyInt0( buf, h ); - *buf++ = ':'; - PrintTinyInt0( buf, m ); - *buf++ = ':'; - PrintTinyInt0( buf, s ); - *buf++ = '\0'; - } - return bufstart; -} - -static const char* RealToString( double val, bool separator ) -{ - enum { Pool = 8 }; - static char bufpool[Pool][64]; - static int bufsel = 0; - char* buf = bufpool[bufsel]; - bufsel = ( bufsel + 1 ) % Pool; - - sprintf( buf, "%f", val ); - auto ptr = buf; - if( *ptr == '-' ) ptr++; - - const auto vbegin = ptr; - - if( separator ) - { - while( *ptr != '\0' && *ptr != ',' && *ptr != '.' ) ptr++; - auto end = ptr; - while( *end != '\0' ) end++; - auto sz = end - ptr; - - while( ptr - vbegin > 3 ) - { - ptr -= 3; - memmove( ptr+1, ptr, sz ); - *ptr = ','; - sz += 4; - } - } - - while( *ptr != '\0' && *ptr != ',' && *ptr != '.' ) ptr++; - - if( *ptr == '\0' ) return buf; - while( *ptr != '\0' ) ptr++; - ptr--; - while( *ptr == '0' ) ptr--; - if( *ptr != '.' && *ptr != ',' ) ptr++; - *ptr = '\0'; - return buf; -} - -static const char* MemSizeToString( int64_t val ) -{ - enum { Pool = 8 }; - static char bufpool[Pool][64]; - static int bufsel = 0; - char* buf = bufpool[bufsel]; - bufsel = ( bufsel + 1 ) % Pool; - - const auto aval = abs( val ); - - if( aval < 10000ll ) - { - sprintf( buf, "%" PRIi64 " bytes", val ); - return buf; - } - - enum class Unit - { - Kilobyte, - Megabyte, - Gigabyte, - Terabyte - }; - Unit unit; - - if( aval < 10000ll * 1024 ) - { - sprintf( buf, "%.2f", val / 1024. ); - unit = Unit::Kilobyte; - } - else if( aval < 10000ll * 1024 * 1024 ) - { - sprintf( buf, "%.2f", val / ( 1024. * 1024 ) ); - unit = Unit::Megabyte; - } - else if( aval < 10000ll * 1024 * 1024 * 1024 ) - { - sprintf( buf, "%.2f", val / ( 1024. * 1024 * 1024 ) ); - unit = Unit::Gigabyte; - } - else - { - sprintf( buf, "%.2f", val / ( 1024. * 1024 * 1024 * 1024 ) ); - unit = Unit::Terabyte; - } - - auto ptr = buf; - while( *ptr ) ptr++; - ptr--; - while( ptr >= buf && *ptr == '0' ) ptr--; - if( *ptr != '.' ) ptr++; - - *ptr++ = ' '; - switch( unit ) - { - case Unit::Kilobyte: - *ptr++ = 'K'; - break; - case Unit::Megabyte: - *ptr++ = 'M'; - break; - case Unit::Gigabyte: - *ptr++ = 'G'; - break; - case Unit::Terabyte: - *ptr++ = 'T'; - break; - default: - assert( false ); - break; - } - *ptr++ = 'B'; - *ptr++ = '\0'; - - return buf; -} static void SetButtonHighlightColor() {