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