Skip to content

Instantly share code, notes, and snippets.

@AlekSi
Created January 15, 2009 11:50
Show Gist options
  • Save AlekSi/47374 to your computer and use it in GitHub Desktop.
Save AlekSi/47374 to your computer and use it in GitHub Desktop.
SConsole SNAB::snabDebug( SConsole::Debug );
SConsole SNAB::snabWarning( SConsole::Warning );
SConsole SNAB::snabError( SConsole::Error );
SConsole::SConsole(MsgType type) : m_stream(0), m_file(0), m_type(type)
{
static bool release = false;
static bool noDebug = false;
#ifdef RELEASE_SNAB2
release = true;
#endif
#ifdef SNAB2_NO_DEBUG
noDebug = true;
#endif
if( release || ( noDebug && (m_type == Debug) ) )
{
m_file = new QFile("/dev/null");
m_file->open( IO_WriteOnly );
m_stream = new QTextStream( m_file );
} else {
m_stream = new QTextStream( stderr, IO_WriteOnly );
}
}
SConsole::~SConsole()
{
m_stream->device()->flush();
delete m_stream;
delete m_file;
}
SConsole& SConsole::operator<<(SConsoleModifiers t)
{
switch (t)
{
case sEndl:
*m_stream << endl;
// проваливаемся дальше
case sFlush:
*m_stream << flush;
break;
case sDec:
*m_stream << dec;
break;
case sBin:
*m_stream << bin;
break;
case sHex:
*m_stream << hex;
break;
}
return *this;
}
void SConsole::operator()(const char* str, ...)
{
const int size = 8*1024 -1;
char buf[size+1] = {0};
va_list ap;
va_start(ap, str);
vsnprintf(buf, size, str, ap);
va_end(ap);
this->operator<<(buf);
}
QString SConsole::prefix() const
{
switch(m_type)
{
case Debug:
return "D: ";
case Warning:
return "*W* ";
case Error:
return "*ERR* ";
default:
return "?!. ";
}
}
namespace SNAB
{
enum SConsoleModifiers
{
sEndl, /*!< Перевод строки*/
sFlush, /*!< Сброс буфера в консоль*/
sDec, /*!< Десятичный режим вывода чисел*/
sBin, /*!< Двоичный режим вывода чисел*/
sHex /*!< Шестнадцатиричный режим вывода чисел*/
};
class SConsole
{
public:
enum MsgType
{
Debug, /*!< Отладочное сообщение*/
Warning, /*!< Предупреждающее сообщение*/
Error /*!< Ошибка*/
};
SConsole(MsgType type);
~SConsole();
// printf-like
void operator()(const char* str, ...);
// наши модификаторы
SConsole& operator<<(SConsoleModifiers t);
// стандартные типы
inline SConsole& operator<<(bool t) { *m_stream << (t ? "true" : "false"); return *this; }
inline SConsole& operator<<(char t) { *m_stream << t; return *this; }
inline SConsole& operator<<(signed short t) { *m_stream << t; return *this; }
inline SConsole& operator<<(unsigned short t) { *m_stream << t; return *this; }
inline SConsole& operator<<(signed int t) { *m_stream << t; return *this; }
inline SConsole& operator<<(unsigned int t) { *m_stream << t; return *this; }
inline SConsole& operator<<(signed long t) { *m_stream << t; return *this; }
inline SConsole& operator<<(unsigned long t) { *m_stream << t; return *this; }
inline SConsole& operator<<(signed long long t) { *m_stream << QString::number(t); return *this; }
inline SConsole& operator<<(unsigned long long t) { *m_stream << QString::number(t); return *this; }
inline SConsole& operator<<(float t) { *m_stream << t; return *this; }
inline SConsole& operator<<(double t) { *m_stream << t; return *this; }
// строки
inline SConsole& operator<<(const char* t) { *m_stream << L8B(t); return *this; }
inline SConsole& operator<<(const QString& t) { *m_stream << t; return *this; }
inline SConsole& operator<<(const QChar& t) { *m_stream << t; return *this; }
// QStringList
SConsole& operator<<( const QStringList& t )
{
QStringList::const_iterator it = t.begin();
*m_stream << "[ ";
if ( it != t.end() )
{
while( true )
{
*this << *it;
++it;
if( it == t.end() )
break;
*m_stream << ", ";
}
}
*m_stream << " ](" << t.size() << ")";
return *this;
}
// ассоциативный массив
template < class T1, class T2 >
SConsole& operator<<( const QMap<T1,T2>& t )
{
typename QMap<T1,T2>::const_iterator it = t.begin();
*m_stream << "[ ";
if ( it != t.end() )
{
while( true )
{
*m_stream << it.key() << " => \"" << it.data() << "\"";
++it;
if( it == t.end() )
break;
*m_stream << ", ";
}
}
*m_stream << " ](" << t.size() << ")";
return *this;
}
// вектор, список и другие QTL- и STL-контейнеры
template < class T, template < class > class L >
SConsole& operator<<( const L<T>& t )
{
typename L<T>::const_iterator it = t.begin();
*m_stream << "[ ";
if ( it != t.end() )
{
while( true )
{
*this << *it;
++it;
if( it == t.end() )
break;
*m_stream << ", ";
}
}
*m_stream << " ](" << t.size() << ")";
return *this;
}
// QVariant
inline SConsole& operator<<(const QVariant& t) { *m_stream << t.toString() << "(" << QVariant::typeToName( t.type() ) << ")"; return *this; }
/*! Возвращает префикс сообщения, который зависит от типа, переданого в конструктор. */
QString prefix() const;
private:
QTextStream* m_stream;
QFile* m_file;
MsgType m_type;
};
extern SConsole snabDebug;
extern SConsole snabWarning;
extern SConsole snabError;
} // namespace
#define sDebug ( SNAB::snabDebug << SNAB::snabDebug.prefix() << "\t " << __FILE__ << "\t " << __LINE__ << "\t " << QTime::currentTime().toString("hh:mm:ss") << " " ), SNAB::snabDebug
#define sWarning ( SNAB::snabWarning << SNAB::snabWarning.prefix() << "\t " << __FILE__ << "\t " << __LINE__ << "\t " << QTime::currentTime().toString("hh:mm:ss") << " " ), SNAB::snabWarning
#define sError ( SNAB::snabError << SNAB::snabError.prefix() << "\t " << __FILE__ << "\t " << __LINE__ << "\t " << QTime::currentTime().toString("hh:mm:ss") << " " ), SNAB::snabError
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment