blob: e2a921c060c559c64f9b2c329ed88c9a148ec352 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001#include "SourcePos.h"
2
3#include <stdarg.h>
4#include <vector>
5
6using namespace std;
7
8
9// ErrorPos
10// =============================================================================
11struct ErrorPos
12{
13 String8 file;
14 int line;
15 String8 error;
16 bool fatal;
17
18 ErrorPos();
19 ErrorPos(const ErrorPos& that);
20 ErrorPos(const String8& file, int line, const String8& error, bool fatal);
21 ~ErrorPos();
22 bool operator<(const ErrorPos& rhs) const;
23 bool operator==(const ErrorPos& rhs) const;
24 ErrorPos& operator=(const ErrorPos& rhs);
25
26 void print(FILE* to) const;
27};
28
29static vector<ErrorPos> g_errors;
30
31ErrorPos::ErrorPos()
32 :line(-1), fatal(false)
33{
34}
35
36ErrorPos::ErrorPos(const ErrorPos& that)
37 :file(that.file),
38 line(that.line),
39 error(that.error),
40 fatal(that.fatal)
41{
42}
43
44ErrorPos::ErrorPos(const String8& f, int l, const String8& e, bool fat)
45 :file(f),
46 line(l),
47 error(e),
48 fatal(fat)
49{
50}
51
52ErrorPos::~ErrorPos()
53{
54}
55
56bool
57ErrorPos::operator<(const ErrorPos& rhs) const
58{
59 if (this->file < rhs.file) return true;
60 if (this->file == rhs.file) {
61 if (this->line < rhs.line) return true;
62 if (this->line == rhs.line) {
63 if (this->error < rhs.error) return true;
64 }
65 }
66 return false;
67}
68
69bool
70ErrorPos::operator==(const ErrorPos& rhs) const
71{
72 return this->file == rhs.file
73 && this->line == rhs.line
74 && this->error == rhs.error;
75}
76
77ErrorPos&
78ErrorPos::operator=(const ErrorPos& rhs)
79{
80 this->file = rhs.file;
81 this->line = rhs.line;
82 this->error = rhs.error;
83 return *this;
84}
85
86void
87ErrorPos::print(FILE* to) const
88{
Marco Nelissendd931862009-07-13 13:02:33 -070089 const char* type = fatal ? "error:" : "warning:";
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090
91 if (this->line >= 0) {
92 fprintf(to, "%s:%d: %s %s\n", this->file.string(), this->line, type, this->error.string());
93 } else {
94 fprintf(to, "%s: %s %s\n", this->file.string(), type, this->error.string());
95 }
96}
97
98// SourcePos
99// =============================================================================
100SourcePos::SourcePos(const String8& f, int l)
101 : file(f), line(l)
102{
103}
104
105SourcePos::SourcePos(const SourcePos& that)
106 : file(that.file), line(that.line)
107{
108}
109
110SourcePos::SourcePos()
111 : file("???", 0), line(-1)
112{
113}
114
115SourcePos::~SourcePos()
116{
117}
118
119int
120SourcePos::error(const char* fmt, ...) const
121{
122 int retval=0;
123 char buf[1024];
124 va_list ap;
125 va_start(ap, fmt);
126 retval = vsnprintf(buf, sizeof(buf), fmt, ap);
127 va_end(ap);
128 char* p = buf + retval - 1;
129 while (p > buf && *p == '\n') {
130 *p = '\0';
131 p--;
132 }
133 g_errors.push_back(ErrorPos(this->file, this->line, String8(buf), true));
134 return retval;
135}
136
137int
138SourcePos::warning(const char* fmt, ...) const
139{
140 int retval=0;
141 char buf[1024];
142 va_list ap;
143 va_start(ap, fmt);
144 retval = vsnprintf(buf, sizeof(buf), fmt, ap);
145 va_end(ap);
146 char* p = buf + retval - 1;
147 while (p > buf && *p == '\n') {
148 *p = '\0';
149 p--;
150 }
151 ErrorPos(this->file, this->line, String8(buf), false).print(stderr);
152 return retval;
153}
154
155bool
156SourcePos::hasErrors()
157{
158 return g_errors.size() > 0;
159}
160
161void
162SourcePos::printErrors(FILE* to)
163{
164 vector<ErrorPos>::const_iterator it;
165 for (it=g_errors.begin(); it!=g_errors.end(); it++) {
166 it->print(to);
167 }
168}
169
170
171