1d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Copyright 2016 The SwiftShader Authors. All Rights Reserved. 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Licensed under the Apache License, Version 2.0 (the "License"); 4d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// you may not use this file except in compliance with the License. 5d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// You may obtain a copy of the License at 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 7d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// http://www.apache.org/licenses/LICENSE-2.0 8d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// 9d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// Unless required by applicable law or agreed to in writing, software 10d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// distributed under the License is distributed on an "AS IS" BASIS, 11d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// See the License for the specific language governing permissions and 13d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens// limitations under the License. 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef _INFOSINK_INCLUDED_ 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#define _INFOSINK_INCLUDED_ 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include <math.h> 19cc863da574ed5079b055574127fe5788a9a0fc33Nicolas Capens#include "Common.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Returns the fractional part of the given floating-point number. 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumaninline float fractionalPart(float f) { 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman float intPart = 0.0f; 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return modff(f, &intPart); 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// TPrefixType is used to centralize how info log messages start. 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// See below. 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanenum TPrefixType { 32d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens EPrefixNone, 33d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens EPrefixWarning, 34d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens EPrefixError, 35d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens EPrefixInternalError, 36d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens EPrefixUnimplemented, 37d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens EPrefixNote 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// Encapsulate info logs for all objects that have them. 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The methods are a general set of tools for getting a variety of 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// messages and types inserted into the log. 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TInfoSinkBase { 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 48d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TInfoSinkBase() {} 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 50d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens template <typename T> 51d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TInfoSinkBase& operator<<(const T& t) { 52d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TPersistStringStream stream; 53d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens stream << t; 54d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sink.append(stream.str()); 55d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return *this; 56d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 57d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // Override << operator for specific types. It is faster to append strings 58d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // and characters directly to the sink. 59d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TInfoSinkBase& operator<<(char c) { 60d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sink.append(1, c); 61d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return *this; 62d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 63d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TInfoSinkBase& operator<<(const char* str) { 64d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sink.append(str); 65d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return *this; 66d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 67d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TInfoSinkBase& operator<<(const TPersistString& str) { 68d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sink.append(str); 69d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return *this; 70d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 71d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TInfoSinkBase& operator<<(const TString& str) { 72d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sink.append(str.c_str()); 73d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return *this; 74d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 75d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // Make sure floats are written with correct precision. 76d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TInfoSinkBase& operator<<(float f) { 77d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // Make sure that at least one decimal point is written. If a number 78d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // does not have a fractional part, the default precision format does 79d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // not write the decimal portion which gets interpreted as integer by 80d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // the compiler. 81d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TPersistStringStream stream; 82d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens if (fractionalPart(f) == 0.0f) { 83d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens stream.precision(1); 84d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens stream << std::showpoint << std::fixed << f; 85d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } else { 86d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens stream.unsetf(std::ios::fixed); 87d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens stream.unsetf(std::ios::scientific); 88d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens stream.precision(8); 89d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens stream << f; 90d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 91d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sink.append(stream.str()); 92d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return *this; 93d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 94d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens // Write boolean values as their names instead of integral value. 95d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TInfoSinkBase& operator<<(bool b) { 96d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens const char* str = b ? "true" : "false"; 97d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens sink.append(str); 98d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens return *this; 99d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens } 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 101d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void erase() { sink.clear(); } 102d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens int size() { return static_cast<int>(sink.size()); } 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 104d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens const TPersistString& str() const { return sink; } 105d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens const char* c_str() const { return sink.c_str(); } 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 107d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void prefix(TPrefixType message); 108d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void location(const TSourceLoc& loc); 109d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void message(TPrefixType message, const char* s); 110d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens void message(TPrefixType message, const char* s, TSourceLoc loc); 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate: 113d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TPersistString sink; 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass TInfoSink { 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanpublic: 118d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TInfoSinkBase info; 119d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TInfoSinkBase debug; 120d999309b36cb3dceadd38217b322f0e96a06b202Nicolas Capens TInfoSinkBase obj; 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif // _INFOSINK_INCLUDED_ 124