Repository: wolfpld/tracy
File: capture/src/capture.cpp (C++)

Code before:
                tracy::MemSizeToString( netTotal ),
                tracy::MemSizeToString( tracy::memUsage ),
                tracy::TimeToString( worker.GetLastTime() ) );
            fflush( stdout );
        }

        std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
        if( seconds != -1 )
        {
            const auto dur = std::chrono::high_resolution_clock::now() - t0;
            if( std::chrono::duration_cast<std::chrono::seconds>(dur).count() >= seconds )
            {
                disconnect = true;
            }
        }
    }
    const auto t1 = std::chrono::high_resolution_clock::now();

    const char *ansiReset = isTTY ? "\033[0m" : "";
    const char *ansiBold = isTTY ? "\033[1m" : "";
    const char *ansiBlack = isTTY ? "\033[30m" : "";
    const char *ansiRed = isTTY ? "\033[31m" : "";
    const char *ansiGreen = isTTY ? "\033[32m" : "";
    const char *ansiYellow = isTTY ? "\033[33m" : "";
    const char *ansiMagenta = isTTY ? "\033[35m" : "";
    const char *ansiCyan = isTTY ? "\033[36m" : "";

    const auto& failure = worker.GetFailureType();
    if( failure != tracy::Worker::Failure::None )
    {
        printf( "\n%s%sInstrumentation failure: %s%s", ansiRed, ansiBold, tracy::Worker::GetFailureString( failure ), ansiReset );
        auto& fd = worker.GetFailureData();
        if( !fd.message.empty() )
        {
            printf( "\nContext: %s", fd.message.c_str() );
        }
        if( fd.callstack != 0 )
        {
            printf( "\n%sFailure callstack:%s\n" , ansiBold, ansiReset);
            auto& cs = worker.GetCallstack( fd.callstack );
            int fidx = 0;
            int bidx = 0;
            for( auto& entry : cs )
            {
                auto frameData = worker.GetCallstackFrame( entry );
                if( !frameData )
                {
                    printf( "%3i. %p\n", fidx++, (void*)worker.GetCanonicalPointer( entry ) );
                }
                else
                {

Review comment (refactor):
Please move this code earlier (e.g. next to the `isTTY` initialization). Then please use these variables in the `if (isTTY) {` block, to improve readability. Maybe an alternate way of encoding colors would be better here? Something like:

```c++
#define AnsiRed "\033[31m"
...
const char *ansiRed = isTTY ? AnsiRed : "";
...
printf( AnsiRed "error" ... );
```

Of course the `%s` indirection would need to stay below, as it is dynamic, but in the code above the check is at entry into the block, so colors are always used there.

Code after:
        if( handshake == tracy::HandshakeNotAvailable )
        {
            printf( "\nThe client you are trying to connect to is no longer able to sent profiling data,\nbecause another server was already connected to it.\nYou can do the following:\n\n  1. Restart the client application.\n  2. Rebuild the client application with on-demand mode enabled.\n" );
            return 2;
        }
        if( handshake == tracy::HandshakeDropped )
        {
            printf( "\nThe client you are trying to connect to has disconnected during the initial\nconnection handshake. Please check your network configuration.\n" );
            return 3;
        }
    }
    while( !worker.HasData() ) std::this_thread::sleep_for( std::chrono::milliseconds( 100 ) );
    printf( "\nQueue delay: %s\nTimer resolution: %s\n", tracy::TimeToString( worker.GetDelay() ), tracy::TimeToString( worker.GetResolution() ) );

#ifdef _WIN32
    signal( SIGINT, SigInt );
#else
    struct sigaction sigint, oldsigint;
    memset( &sigint, 0, sizeof( sigint ) );
    sigint.sa_handler = SigInt;
    sigaction( SIGINT, &sigint, &oldsigint );
#endif

    auto& lock = worker.GetMbpsDataLock();

    const auto t0 = std::chrono::high_resolution_clock::now();
    while( worker.IsConnected() )
    {
        // Relaxed order is sufficient here because `s_disconnect` is only ever
        // set by this thread or by the SigInt handler, and that handler does
        // nothing else than storing `s_disconnect`.
        if( s_disconnect.load( std::memory_order_relaxed ) )
        {
            worker.Disconnect();
            // Relaxed order is sufficient because only this thread ever reads
            // this value.
            s_disconnect.store(false, std::memory_order_relaxed );
            break;
        }

        lock.lock();
        const auto mbps = worker.GetMbpsData().back();
        const auto compRatio = worker.GetCompRatio();
        const auto netTotal = worker.GetDataTransferred();
        lock.unlock();

        // Output progress info only if destination is a TTY to avoid bloating
        // log files (so this is not just about usage of ANSI color codes).
        if( IsStdoutATerminal() )
        {
            const char* unit = "Mbps";