blob: 6ddf6b07a3adc04e4e2960080db1501242dff4f8 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
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
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000010#include <math.h>
11
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000012#include "compiler/Common.h"
13
alokp@chromium.orgb892fc62010-05-06 19:10:34 +000014// Returns the fractional part of the given floating-point number.
15inline float fractionalPart(float f) {
alokp@chromium.org92984ef2010-05-06 22:49:37 +000016 float intPart = 0.0f;
17 return modff(f, &intPart);
alokp@chromium.orgb892fc62010-05-06 19:10:34 +000018}
19
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000020//
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
33enum TOutputStream {
34 ENull = 0,
alokp@chromium.org0270ef12010-04-07 19:57:20 +000035 EStdOut = 0x01,
36 EString = 0x02,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000037};
38//
39// Encapsulate info logs for all objects that have them.
40//
41// The methods are a general set of tools for getting a variety of
42// messages and types inserted into the log.
43//
44class TInfoSinkBase {
45public:
alokp@chromium.org0270ef12010-04-07 19:57:20 +000046 TInfoSinkBase() : outputStream(EString) {}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000047 void erase() { sink.erase(); }
48 TInfoSinkBase& operator<<(const TPersistString& t) { append(t); return *this; }
49 TInfoSinkBase& operator<<(char c) { append(1, c); return *this; }
50 TInfoSinkBase& operator<<(const char* s) { append(s); return *this; }
51 TInfoSinkBase& operator<<(int n) { append(String(n)); return *this; }
52 TInfoSinkBase& operator<<(const unsigned int n) { append(String(n)); return *this; }
alokp@chromium.orgb892fc62010-05-06 19:10:34 +000053 TInfoSinkBase& operator<<(float n) {
54 char buf[40];
55 // Make sure that at least one decimal point is written. If a number
56 // does not have a fractional part, %g does not written the decimal
57 // portion which gets interpreted as integer by the compiler.
58 const char* format = fractionalPart(n) == 0.0f ? "%.1f" : "%.8g";
59 sprintf(buf, format, n);
60 append(buf);
61 return *this;
62 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000063 TInfoSinkBase& operator+(const TPersistString& t) { append(t); return *this; }
64 TInfoSinkBase& operator+(const TString& t) { append(t); return *this; }
65 TInfoSinkBase& operator<<(const TString& t) { append(t); return *this; }
66 TInfoSinkBase& operator+(const char* s) { append(s); return *this; }
67 const char* c_str() const { return sink.c_str(); }
68 void prefix(TPrefixType message) {
69 switch(message) {
70 case EPrefixNone: break;
71 case EPrefixWarning: append("WARNING: "); break;
72 case EPrefixError: append("ERROR: "); break;
73 case EPrefixInternalError: append("INTERNAL ERROR: "); break;
74 case EPrefixUnimplemented: append("UNIMPLEMENTED: "); break;
75 case EPrefixNote: append("NOTE: "); break;
76 default: append("UNKOWN ERROR: "); break;
77 }
78 }
79 void location(TSourceLoc loc) {
80 append(FormatSourceLoc(loc).c_str());
81 append(": ");
82 }
83 void message(TPrefixType message, const char* s) {
84 prefix(message);
85 append(s);
86 append("\n");
87 }
88 void message(TPrefixType message, const char* s, TSourceLoc loc) {
89 prefix(message);
90 location(loc);
91 append(s);
92 append("\n");
93 }
94
95 void setOutputStream(int output = 4)
96 {
97 outputStream = output;
98 }
99
100protected:
101 void append(const char *s);
102
103 void append(int count, char c);
104 void append(const TPersistString& t);
105 void append(const TString& t);
106
107 void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2)
108 sink.reserve(sink.capacity() + sink.capacity() / 2); }
109 void appendToStream(const char* s);
110 TPersistString sink;
111 int outputStream;
112};
113
114class TInfoSink {
115public:
116 TInfoSinkBase info;
117 TInfoSinkBase debug;
118 TInfoSinkBase obj;
119};
120
121#endif // _INFOSINK_INCLUDED_