1// 2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 3// Use of this source code is governed by a BSD-style license that can be 4// found in the LICENSE file. 5// 6 7#ifndef _INFOSINK_INCLUDED_ 8#define _INFOSINK_INCLUDED_ 9 10#include <math.h> 11#include <stdlib.h> 12#include "compiler/translator/Common.h" 13 14// Returns the fractional part of the given floating-point number. 15inline float fractionalPart(float f) { 16 float intPart = 0.0f; 17 return modff(f, &intPart); 18} 19 20// 21// TPrefixType is used to centralize how info log messages start. 22// See below. 23// 24enum TPrefixType { 25 EPrefixNone, 26 EPrefixWarning, 27 EPrefixError, 28 EPrefixInternalError, 29 EPrefixUnimplemented, 30 EPrefixNote 31}; 32 33// 34// Encapsulate info logs for all objects that have them. 35// 36// The methods are a general set of tools for getting a variety of 37// messages and types inserted into the log. 38// 39class TInfoSinkBase { 40public: 41 TInfoSinkBase() {} 42 43 template <typename T> 44 TInfoSinkBase& operator<<(const T& t) { 45 TPersistStringStream stream; 46 stream << t; 47 sink.append(stream.str()); 48 return *this; 49 } 50 // Override << operator for specific types. It is faster to append strings 51 // and characters directly to the sink. 52 TInfoSinkBase& operator<<(char c) { 53 sink.append(1, c); 54 return *this; 55 } 56 TInfoSinkBase& operator<<(const char* str) { 57 sink.append(str); 58 return *this; 59 } 60 TInfoSinkBase& operator<<(const TPersistString& str) { 61 sink.append(str); 62 return *this; 63 } 64 TInfoSinkBase& operator<<(const TString& str) { 65 sink.append(str.c_str()); 66 return *this; 67 } 68 // Make sure floats are written with correct precision. 69 TInfoSinkBase& operator<<(float f) { 70 // Make sure that at least one decimal point is written. If a number 71 // does not have a fractional part, the default precision format does 72 // not write the decimal portion which gets interpreted as integer by 73 // the compiler. 74 TPersistStringStream stream; 75 if (fractionalPart(f) == 0.0f) { 76 stream.precision(1); 77 stream << std::showpoint << std::fixed << f; 78 } else { 79 stream.unsetf(std::ios::fixed); 80 stream.unsetf(std::ios::scientific); 81 stream.precision(8); 82 stream << f; 83 } 84 sink.append(stream.str()); 85 return *this; 86 } 87 // Write boolean values as their names instead of integral value. 88 TInfoSinkBase& operator<<(bool b) { 89 const char* str = b ? "true" : "false"; 90 sink.append(str); 91 return *this; 92 } 93 94 void erase() { sink.clear(); } 95 int size() { return static_cast<int>(sink.size()); } 96 97 const TPersistString& str() const { return sink; } 98 const char* c_str() const { return sink.c_str(); } 99 100 void prefix(TPrefixType p); 101 void location(int file, int line); 102 void location(const TSourceLoc& loc); 103 void message(TPrefixType p, const TSourceLoc& loc, const char* m); 104 105private: 106 TPersistString sink; 107}; 108 109class TInfoSink { 110public: 111 TInfoSinkBase info; 112 TInfoSinkBase debug; 113 TInfoSinkBase obj; 114}; 115 116#endif // _INFOSINK_INCLUDED_ 117