#pragma once
#include <iostream>
#include <sstream>
#include <cstdarg>
#include <windows.h>
//usage:
// DEBUGOUT("HI %s", username);
// DEBUGOUT << "HI " << username;
//results:
// C:/users/dev/code/mpd/file_ptr.h(9): HI smith
// C:/users/dev/code/mpd/file_ptr.h(10): HI smith
//double click a line to be taken directly to that line of code
__declspec( dllimport) void __stdcall OutputDebugStringA( _In_opt_ const char * lpOutputString) ;
struct DebugOutBuffer {
DebugOutBuffer( const char * file, int line, bool enabled)
{ if ( enabled) ss<< file<< '(' << line<< "): " ; else ss.setstate ( std:: ios_base :: badbit ) ; }
~DebugOutBuffer( )
{ if ( ss) { ss<< '\n ' ; OutputDebugStringW( ss.str ( ) .c_str ( ) ) ; } }
operator std:: wostream & ( ) { return ss; }
template < class T> std:: wostream & operator<< ( T&& t) { return ss << t; }
DebugOutBuffer& operator( ) ( _In_z_ const char * text)
{ if ( ss) ss<< text; return * this ; }
template < class T, class enabled= typename std:: enable_if < ! std:: is_same < T,va_list > :: value > :: type >
DebugOutBuffer& operator( ) ( _In_z_ _Printf_format_string_ const char * format, T, ...)
{
if ( ! ss) return * this ;
va_list arglist;
va_start ( arglist, format) ;
operator( ) ( format, arglist) ;
va_end ( arglist) ;
return * this ;
}
DebugOutBuffer& operator( ) ( _In_z_ _Printf_format_string_ const char * format, va_list args)
{
if ( ! ss) return * this ;
char buffer[ 1024 ] ;
va_list arglist;
va_start ( arglist, format) ;
vsnprintf( buffer, 1024 , format, args) ;
buffer[ 1023 ] = '\0 ' ;
ss<< buffer;
return * this ;
}
DebugOutBuffer& operator( ) ( _In_z_ const wchar_t * text)
{ if ( ss) ss<< text; return * this ; }
template < class T, class enabled= typename std:: enable_if < ! std:: is_same < T,va_list > :: value > :: type >
DebugOutBuffer& operator( ) ( _In_z_ _Printf_format_string_ const wchar_t * format, T, ...)
{
if ( ! ss) return * this ;
va_list arglist;
va_start ( arglist, format) ;
operator( ) ( format, arglist) ;
va_end ( arglist) ;
return * this ;
}
DebugOutBuffer& operator( ) ( _In_z_ _Printf_format_string_ const wchar_t * format, va_list args)
{
if ( ! ss) return * this ;
wchar_t buffer[ 1024 ] ;
va_list arglist;
va_start ( arglist, format) ;
_vsnwprintf( buffer, 1024 , format, args) ;
buffer[ 1023 ] = '\0 ' ;
ss<< buffer;
return * this ;
}
private :
std:: wostringstream ss;
} ;
#define DEBUGOUT DebugOutBuffer(__FILE__, __LINE__, true)
I3ByYWdtYSBvbmNlCiNpbmNsdWRlIDxpb3N0cmVhbT4gCiNpbmNsdWRlIDxzc3RyZWFtPgojaW5jbHVkZSA8Y3N0ZGFyZz4KI2luY2x1ZGUgPHdpbmRvd3MuaD4KCi8vdXNhZ2U6IAovLyAgIERFQlVHT1VUKCJISSAlcyIsIHVzZXJuYW1lKTsKLy8gICBERUJVR09VVCA8PCAiSEkgIiA8PCB1c2VybmFtZTsKLy9yZXN1bHRzOgovLyAgIEM6L3VzZXJzL2Rldi9jb2RlL21wZC9maWxlX3B0ci5oKDkpOiBISSBzbWl0aAovLyAgIEM6L3VzZXJzL2Rldi9jb2RlL21wZC9maWxlX3B0ci5oKDEwKTogSEkgc21pdGgKLy9kb3VibGUgY2xpY2sgYSBsaW5lIHRvIGJlIHRha2VuIGRpcmVjdGx5IHRvIHRoYXQgbGluZSBvZiBjb2RlCgpfX2RlY2xzcGVjKGRsbGltcG9ydCkgdm9pZCBfX3N0ZGNhbGwgT3V0cHV0RGVidWdTdHJpbmdBKF9Jbl9vcHRfIGNvbnN0IGNoYXIqIGxwT3V0cHV0U3RyaW5nKTsKc3RydWN0IERlYnVnT3V0QnVmZmVyIHsKICAgIERlYnVnT3V0QnVmZmVyKGNvbnN0IGNoYXIqIGZpbGUsIGludCBsaW5lLCBib29sIGVuYWJsZWQpIAogICAge2lmIChlbmFibGVkKSBzczw8ZmlsZTw8JygnPDxsaW5lPDwiKTogIjsgZWxzZSBzcy5zZXRzdGF0ZShzdGQ6Omlvc19iYXNlOjpiYWRiaXQpOyB9CiAgICB+RGVidWdPdXRCdWZmZXIoKQogICAge2lmIChzcykge3NzPDwnXG4nOyBPdXRwdXREZWJ1Z1N0cmluZ1coc3Muc3RyKCkuY19zdHIoKSk7fX0KICAgIAogICAgb3BlcmF0b3Igc3RkOjp3b3N0cmVhbSYoKSB7cmV0dXJuIHNzO30KICAgIHRlbXBsYXRlPGNsYXNzIFQ+IHN0ZDo6d29zdHJlYW0mIG9wZXJhdG9yPDwoVCYmIHQpIHtyZXR1cm4gc3MgPDwgdDt9CgogICAgRGVidWdPdXRCdWZmZXImIG9wZXJhdG9yKCkoX0luX3pfIGNvbnN0IGNoYXIqIHRleHQpIAogICAge2lmIChzcykgc3M8PHRleHQ7IHJldHVybiAqdGhpczt9CiAgICB0ZW1wbGF0ZTxjbGFzcyBULCBjbGFzcyBlbmFibGVkPXR5cGVuYW1lIHN0ZDo6ZW5hYmxlX2lmPCFzdGQ6OmlzX3NhbWU8VCx2YV9saXN0Pjo6dmFsdWU+Ojp0eXBlPgogICAgRGVidWdPdXRCdWZmZXImIG9wZXJhdG9yKCkoX0luX3pfIF9QcmludGZfZm9ybWF0X3N0cmluZ18gY29uc3QgY2hhciogZm9ybWF0LCBULCAuLi4pIAogICAgeyAKICAgICAgICBpZiAoIXNzKSByZXR1cm4gKnRoaXM7CiAgICAgICAgdmFfbGlzdCBhcmdsaXN0OwogICAgICAgIHZhX3N0YXJ0KGFyZ2xpc3QsIGZvcm1hdCk7CiAgICAgICAgb3BlcmF0b3IoKShmb3JtYXQsIGFyZ2xpc3QpOwogICAgICAgIHZhX2VuZChhcmdsaXN0KTsKICAgICAgICByZXR1cm4gKnRoaXM7CiAgICB9CiAgICBEZWJ1Z091dEJ1ZmZlciYgb3BlcmF0b3IoKShfSW5fel8gX1ByaW50Zl9mb3JtYXRfc3RyaW5nXyBjb25zdCBjaGFyKiBmb3JtYXQsIHZhX2xpc3QgYXJncykgCiAgICB7IAogICAgICAgIGlmICghc3MpIHJldHVybiAqdGhpczsKICAgICAgICBjaGFyIGJ1ZmZlclsxMDI0XTsKICAgICAgICB2YV9saXN0IGFyZ2xpc3Q7CiAgICAgICAgdmFfc3RhcnQoYXJnbGlzdCwgZm9ybWF0KTsKICAgICAgICB2c25wcmludGYoYnVmZmVyLCAxMDI0LCBmb3JtYXQsIGFyZ3MpOwogICAgICAgIGJ1ZmZlclsxMDIzXSA9ICdcMCc7CiAgICAgICAgc3M8PGJ1ZmZlcjsKICAgICAgICByZXR1cm4gKnRoaXM7CiAgICB9CiAgICBEZWJ1Z091dEJ1ZmZlciYgb3BlcmF0b3IoKShfSW5fel8gY29uc3Qgd2NoYXJfdCogdGV4dCkgCiAgICB7aWYgKHNzKSBzczw8dGV4dDsgcmV0dXJuICp0aGlzO30KICAgIHRlbXBsYXRlPGNsYXNzIFQsIGNsYXNzIGVuYWJsZWQ9dHlwZW5hbWUgc3RkOjplbmFibGVfaWY8IXN0ZDo6aXNfc2FtZTxULHZhX2xpc3Q+Ojp2YWx1ZT46OnR5cGU+CiAgICBEZWJ1Z091dEJ1ZmZlciYgb3BlcmF0b3IoKShfSW5fel8gX1ByaW50Zl9mb3JtYXRfc3RyaW5nXyBjb25zdCB3Y2hhcl90KiBmb3JtYXQsIFQsIC4uLikgCiAgICB7IAogICAgICAgIGlmICghc3MpIHJldHVybiAqdGhpczsKICAgICAgICB2YV9saXN0IGFyZ2xpc3Q7CiAgICAgICAgdmFfc3RhcnQoYXJnbGlzdCwgZm9ybWF0KTsKICAgICAgICBvcGVyYXRvcigpKGZvcm1hdCwgYXJnbGlzdCk7CiAgICAgICAgdmFfZW5kKGFyZ2xpc3QpOwogICAgICAgIHJldHVybiAqdGhpczsKICAgIH0KICAgIERlYnVnT3V0QnVmZmVyJiBvcGVyYXRvcigpKF9Jbl96XyBfUHJpbnRmX2Zvcm1hdF9zdHJpbmdfIGNvbnN0IHdjaGFyX3QqIGZvcm1hdCwgdmFfbGlzdCBhcmdzKSAKICAgIHsgCiAgICAgICAgaWYgKCFzcykgcmV0dXJuICp0aGlzOwogICAgICAgIHdjaGFyX3QgYnVmZmVyWzEwMjRdOwogICAgICAgIHZhX2xpc3QgYXJnbGlzdDsKICAgICAgICB2YV9zdGFydChhcmdsaXN0LCBmb3JtYXQpOwogICAgICAgIF92c253cHJpbnRmKGJ1ZmZlciwgMTAyNCwgZm9ybWF0LCBhcmdzKTsKICAgICAgICBidWZmZXJbMTAyM10gPSAnXDAnOwogICAgICAgIHNzPDxidWZmZXI7CiAgICAgICAgcmV0dXJuICp0aGlzOwogICAgfQpwcml2YXRlOgogICAgc3RkOjp3b3N0cmluZ3N0cmVhbSBzczsKfTsKI2RlZmluZSBERUJVR09VVCBEZWJ1Z091dEJ1ZmZlcihfX0ZJTEVfXywgX19MSU5FX18sIHRydWUpIA==