• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
fractionalPart(float f)15 inline 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 //
24 enum 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 //
39 class TInfoSinkBase {
40 public:
TInfoSinkBase()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 
erase()94     void erase() { sink.clear(); }
size()95     int size() { return static_cast<int>(sink.size()); }
96 
str()97     const TPersistString& str() const { return sink; }
c_str()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 
105 private:
106     TPersistString sink;
107 };
108 
109 class TInfoSink {
110 public:
111     TInfoSinkBase info;
112     TInfoSinkBase debug;
113     TInfoSinkBase obj;
114 };
115 
116 #endif // _INFOSINK_INCLUDED_
117