Home | History | Annotate | Download | only in Include
      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