1 // 2 // Copyright (C) 2002-2005 3Dlabs Inc. Ltd. 3 // All rights reserved. 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions 7 // are met: 8 // 9 // Redistributions of source code must retain the above copyright 10 // notice, this list of conditions and the following disclaimer. 11 // 12 // Redistributions in binary form must reproduce the above 13 // copyright notice, this list of conditions and the following 14 // disclaimer in the documentation and/or other materials provided 15 // with the distribution. 16 // 17 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its 18 // contributors may be used to endorse or promote products derived 19 // from this software without specific prior written permission. 20 // 21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 24 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 29 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 31 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 // POSSIBILITY OF SUCH DAMAGE. 33 // 34 35 #ifndef _INFOSINK_INCLUDED_ 36 #define _INFOSINK_INCLUDED_ 37 38 #include "../Include/Common.h" 39 #include <cmath> 40 41 namespace glslang { 42 43 // 44 // TPrefixType is used to centralize how info log messages start. 45 // See below. 46 // 47 enum TPrefixType { 48 EPrefixNone, 49 EPrefixWarning, 50 EPrefixError, 51 EPrefixInternalError, 52 EPrefixUnimplemented, 53 EPrefixNote 54 }; 55 56 enum TOutputStream { 57 ENull = 0, 58 EDebugger = 0x01, 59 EStdOut = 0x02, 60 EString = 0x04, 61 }; 62 // 63 // Encapsulate info logs for all objects that have them. 64 // 65 // The methods are a general set of tools for getting a variety of 66 // messages and types inserted into the log. 67 // 68 class TInfoSinkBase { 69 public: TInfoSinkBase()70 TInfoSinkBase() : outputStream(4) {} erase()71 void erase() { sink.erase(); } 72 TInfoSinkBase& operator<<(const TPersistString& t) { append(t); return *this; } 73 TInfoSinkBase& operator<<(char c) { append(1, c); return *this; } 74 TInfoSinkBase& operator<<(const char* s) { append(s); return *this; } 75 TInfoSinkBase& operator<<(int n) { append(String(n)); return *this; } 76 TInfoSinkBase& operator<<(unsigned int n) { append(String(n)); return *this; } 77 TInfoSinkBase& operator<<(float n) { const int size = 40; char buf[size]; 78 snprintf(buf, size, (fabs(n) > 1e-8 && fabs(n) < 1e8) || n == 0.0f ? "%f" : "%g", n); 79 append(buf); 80 return *this; } 81 TInfoSinkBase& operator+(const TPersistString& t) { append(t); return *this; } 82 TInfoSinkBase& operator+(const TString& t) { append(t); return *this; } 83 TInfoSinkBase& operator<<(const TString& t) { append(t); return *this; } 84 TInfoSinkBase& operator+(const char* s) { append(s); return *this; } c_str()85 const char* c_str() const { return sink.c_str(); } prefix(TPrefixType message)86 void prefix(TPrefixType message) { 87 switch(message) { 88 case EPrefixNone: break; 89 case EPrefixWarning: append("WARNING: "); break; 90 case EPrefixError: append("ERROR: "); break; 91 case EPrefixInternalError: append("INTERNAL ERROR: "); break; 92 case EPrefixUnimplemented: append("UNIMPLEMENTED: "); break; 93 case EPrefixNote: append("NOTE: "); break; 94 default: append("UNKNOWN ERROR: "); break; 95 } 96 } location(const TSourceLoc & loc)97 void location(const TSourceLoc& loc) { 98 const int maxSize = 24; 99 char locText[maxSize]; 100 snprintf(locText, maxSize, ":%d", loc.line); 101 append(loc.getStringNameOrNum(false).c_str()); 102 append(locText); 103 append(": "); 104 } message(TPrefixType message,const char * s)105 void message(TPrefixType message, const char* s) { 106 prefix(message); 107 append(s); 108 append("\n"); 109 } message(TPrefixType message,const char * s,const TSourceLoc & loc)110 void message(TPrefixType message, const char* s, const TSourceLoc& loc) { 111 prefix(message); 112 location(loc); 113 append(s); 114 append("\n"); 115 } 116 117 void setOutputStream(int output = 4) 118 { 119 outputStream = output; 120 } 121 122 protected: 123 void append(const char* s); 124 125 void append(int count, char c); 126 void append(const TPersistString& t); 127 void append(const TString& t); 128 checkMem(size_t growth)129 void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2) 130 sink.reserve(sink.capacity() + sink.capacity() / 2); } 131 void appendToStream(const char* s); 132 TPersistString sink; 133 int outputStream; 134 }; 135 136 } // end namespace glslang 137 138 class TInfoSink { 139 public: 140 glslang::TInfoSinkBase info; 141 glslang::TInfoSinkBase debug; 142 }; 143 144 #endif // _INFOSINK_INCLUDED_ 145