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 <math.h> 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: 70 TInfoSinkBase() : outputStream(4) {} 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<<(long unsigned int n) { append(String(n)); return *this; } 78 TInfoSinkBase& operator<<(float n) { const int size = 40; char buf[size]; 79 snprintf(buf, size, (fabs(n) > 1e-8 && fabs(n) < 1e8) || n == 0.0f ? "%f" : "%g", n); 80 append(buf); 81 return *this; } 82 TInfoSinkBase& operator+(const TPersistString& t) { append(t); return *this; } 83 TInfoSinkBase& operator+(const TString& t) { append(t); return *this; } 84 TInfoSinkBase& operator<<(const TString& t) { append(t); return *this; } 85 TInfoSinkBase& operator+(const char* s) { append(s); return *this; } 86 const char* c_str() const { return sink.c_str(); } 87 void prefix(TPrefixType message) { 88 switch(message) { 89 case EPrefixNone: break; 90 case EPrefixWarning: append("WARNING: "); break; 91 case EPrefixError: append("ERROR: "); break; 92 case EPrefixInternalError: append("INTERNAL ERROR: "); break; 93 case EPrefixUnimplemented: append("UNIMPLEMENTED: "); break; 94 case EPrefixNote: append("NOTE: "); break; 95 default: append("UNKNOWN ERROR: "); break; 96 } 97 } 98 void location(const TSourceLoc& loc) { 99 const int maxSize = 24; 100 char locText[maxSize]; 101 snprintf(locText, maxSize, ":%d", loc.line); 102 append(loc.getStringNameOrNum(false).c_str()); 103 append(locText); 104 append(": "); 105 } 106 void message(TPrefixType message, const char* s) { 107 prefix(message); 108 append(s); 109 append("\n"); 110 } 111 void message(TPrefixType message, const char* s, const TSourceLoc& loc) { 112 prefix(message); 113 location(loc); 114 append(s); 115 append("\n"); 116 } 117 118 void setOutputStream(int output = 4) 119 { 120 outputStream = output; 121 } 122 123 protected: 124 void append(const char* s); 125 126 void append(int count, char c); 127 void append(const TPersistString& t); 128 void append(const TString& t); 129 130 void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2) 131 sink.reserve(sink.capacity() + sink.capacity() / 2); } 132 void appendToStream(const char* s); 133 TPersistString sink; 134 int outputStream; 135 }; 136 137 } // end namespace glslang 138 139 class TInfoSink { 140 public: 141 glslang::TInfoSinkBase info; 142 glslang::TInfoSinkBase debug; 143 }; 144 145 #endif // _INFOSINK_INCLUDED_ 146