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