blob: 2940b6e4aab4edde41670e0035b85b2cfd5a74e7 [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) {
16 return fmodf(f, 1.0f);
17}
18
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000019//
20// TPrefixType is used to centralize how info log messages start.
21// See below.
22//
23enum TPrefixType {
24 EPrefixNone,
25 EPrefixWarning,
26 EPrefixError,
27 EPrefixInternalError,
28 EPrefixUnimplemented,
29 EPrefixNote
30};
31
32enum TOutputStream {
33 ENull = 0,
alokp@chromium.org0270ef12010-04-07 19:57:20 +000034 EStdOut = 0x01,
35 EString = 0x02,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000036};
37//
38// Encapsulate info logs for all objects that have them.
39//
40// The methods are a general set of tools for getting a variety of
41// messages and types inserted into the log.
42//
43class TInfoSinkBase {
44public:
alokp@chromium.org0270ef12010-04-07 19:57:20 +000045 TInfoSinkBase() : outputStream(EString) {}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000046 void erase() { sink.erase(); }
47 TInfoSinkBase& operator<<(const TPersistString& t) { append(t); return *this; }
48 TInfoSinkBase& operator<<(char c) { append(1, c); return *this; }
49 TInfoSinkBase& operator<<(const char* s) { append(s); return *this; }
50 TInfoSinkBase& operator<<(int n) { append(String(n)); return *this; }
51 TInfoSinkBase& operator<<(const unsigned int n) { append(String(n)); return *this; }
alokp@chromium.orgb892fc62010-05-06 19:10:34 +000052 TInfoSinkBase& operator<<(float n) {
53 char buf[40];
54 // Make sure that at least one decimal point is written. If a number
55 // does not have a fractional part, %g does not written the decimal
56 // portion which gets interpreted as integer by the compiler.
57 const char* format = fractionalPart(n) == 0.0f ? "%.1f" : "%.8g";
58 sprintf(buf, format, n);
59 append(buf);
60 return *this;
61 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000062 TInfoSinkBase& operator+(const TPersistString& t) { append(t); return *this; }
63 TInfoSinkBase& operator+(const TString& t) { append(t); return *this; }
64 TInfoSinkBase& operator<<(const TString& t) { append(t); return *this; }
65 TInfoSinkBase& operator+(const char* s) { append(s); return *this; }
66 const char* c_str() const { return sink.c_str(); }
67 void prefix(TPrefixType message) {
68 switch(message) {
69 case EPrefixNone: break;
70 case EPrefixWarning: append("WARNING: "); break;
71 case EPrefixError: append("ERROR: "); break;
72 case EPrefixInternalError: append("INTERNAL ERROR: "); break;
73 case EPrefixUnimplemented: append("UNIMPLEMENTED: "); break;
74 case EPrefixNote: append("NOTE: "); break;
75 default: append("UNKOWN ERROR: "); break;
76 }
77 }
78 void location(TSourceLoc loc) {
79 append(FormatSourceLoc(loc).c_str());
80 append(": ");
81 }
82 void message(TPrefixType message, const char* s) {
83 prefix(message);
84 append(s);
85 append("\n");
86 }
87 void message(TPrefixType message, const char* s, TSourceLoc loc) {
88 prefix(message);
89 location(loc);
90 append(s);
91 append("\n");
92 }
93
94 void setOutputStream(int output = 4)
95 {
96 outputStream = output;
97 }
98
99protected:
100 void append(const char *s);
101
102 void append(int count, char c);
103 void append(const TPersistString& t);
104 void append(const TString& t);
105
106 void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2)
107 sink.reserve(sink.capacity() + sink.capacity() / 2); }
108 void appendToStream(const char* s);
109 TPersistString sink;
110 int outputStream;
111};
112
113class TInfoSink {
114public:
115 TInfoSinkBase info;
116 TInfoSinkBase debug;
117 TInfoSinkBase obj;
118};
119
120#endif // _INFOSINK_INCLUDED_