| // |
| // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions |
| // are met: |
| // |
| // Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // |
| // Redistributions in binary form must reproduce the above |
| // copyright notice, this list of conditions and the following |
| // disclaimer in the documentation and/or other materials provided |
| // with the distribution. |
| // |
| // Neither the name of 3Dlabs Inc. Ltd. nor the names of its |
| // contributors may be used to endorse or promote products derived |
| // from this software without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
| // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
| // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
| // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, |
| // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
| // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
| // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| // POSSIBILITY OF SUCH DAMAGE. |
| // |
| |
| #ifndef _INFOSINK_INCLUDED_ |
| #define _INFOSINK_INCLUDED_ |
| |
| #include "../Include/Common.h" |
| #include <cmath> |
| |
| namespace glslang { |
| |
| // |
| // TPrefixType is used to centralize how info log messages start. |
| // See below. |
| // |
| enum TPrefixType { |
| EPrefixNone, |
| EPrefixWarning, |
| EPrefixError, |
| EPrefixInternalError, |
| EPrefixUnimplemented, |
| EPrefixNote |
| }; |
| |
| enum TOutputStream { |
| ENull = 0, |
| EDebugger = 0x01, |
| EStdOut = 0x02, |
| EString = 0x04, |
| }; |
| // |
| // Encapsulate info logs for all objects that have them. |
| // |
| // The methods are a general set of tools for getting a variety of |
| // messages and types inserted into the log. |
| // |
| class TInfoSinkBase { |
| public: |
| TInfoSinkBase() : outputStream(4) {} |
| void erase() { sink.erase(); } |
| TInfoSinkBase& operator<<(const TPersistString& t) { append(t); return *this; } |
| TInfoSinkBase& operator<<(char c) { append(1, c); return *this; } |
| TInfoSinkBase& operator<<(const char* s) { append(s); return *this; } |
| TInfoSinkBase& operator<<(int n) { append(String(n)); return *this; } |
| TInfoSinkBase& operator<<(unsigned int n) { append(String(n)); return *this; } |
| TInfoSinkBase& operator<<(float n) { const int size = 40; char buf[size]; |
| snprintf(buf, size, (fabs(n) > 1e-8 && fabs(n) < 1e8) || n == 0.0f ? "%f" : "%g", n); |
| append(buf); |
| return *this; } |
| TInfoSinkBase& operator+(const TPersistString& t) { append(t); return *this; } |
| TInfoSinkBase& operator+(const TString& t) { append(t); return *this; } |
| TInfoSinkBase& operator<<(const TString& t) { append(t); return *this; } |
| TInfoSinkBase& operator+(const char* s) { append(s); return *this; } |
| const char* c_str() const { return sink.c_str(); } |
| void prefix(TPrefixType message) { |
| switch(message) { |
| case EPrefixNone: break; |
| case EPrefixWarning: append("WARNING: "); break; |
| case EPrefixError: append("ERROR: "); break; |
| case EPrefixInternalError: append("INTERNAL ERROR: "); break; |
| case EPrefixUnimplemented: append("UNIMPLEMENTED: "); break; |
| case EPrefixNote: append("NOTE: "); break; |
| default: append("UNKNOWN ERROR: "); break; |
| } |
| } |
| void location(const TSourceLoc& loc) { |
| const int maxSize = 24; |
| char locText[maxSize]; |
| snprintf(locText, maxSize, ":%d", loc.line); |
| append(loc.getStringNameOrNum(false).c_str()); |
| append(locText); |
| append(": "); |
| } |
| void message(TPrefixType message, const char* s) { |
| prefix(message); |
| append(s); |
| append("\n"); |
| } |
| void message(TPrefixType message, const char* s, const TSourceLoc& loc) { |
| prefix(message); |
| location(loc); |
| append(s); |
| append("\n"); |
| } |
| |
| void setOutputStream(int output = 4) |
| { |
| outputStream = output; |
| } |
| |
| protected: |
| void append(const char* s); |
| |
| void append(int count, char c); |
| void append(const TPersistString& t); |
| void append(const TString& t); |
| |
| void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2) |
| sink.reserve(sink.capacity() + sink.capacity() / 2); } |
| void appendToStream(const char* s); |
| TPersistString sink; |
| int outputStream; |
| }; |
| |
| } // end namespace glslang |
| |
| class TInfoSink { |
| public: |
| glslang::TInfoSinkBase info; |
| glslang::TInfoSinkBase debug; |
| }; |
| |
| #endif // _INFOSINK_INCLUDED_ |