1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "SourcePos.h"
2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdarg.h>
4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <vector>
5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiusing namespace std;
7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// ErrorPos
10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// =============================================================================
11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistruct ErrorPos
12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
13a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    enum Level {
14a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski        NOTE,
15a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski        WARNING,
16a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski        ERROR
17a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    };
18a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski
19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    String8 file;
20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    int line;
21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    String8 error;
22a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    Level level;
23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ErrorPos();
25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ErrorPos(const ErrorPos& that);
26a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    ErrorPos(const String8& file, int line, const String8& error, Level level);
27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    ErrorPos& operator=(const ErrorPos& rhs);
28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    void print(FILE* to) const;
30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski};
31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatic vector<ErrorPos> g_errors;
33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
34282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiErrorPos::ErrorPos()
35a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    :line(-1), level(NOTE)
36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
39282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiErrorPos::ErrorPos(const ErrorPos& that)
40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    :file(that.file),
41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     line(that.line),
42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     error(that.error),
43a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski     level(that.level)
44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
47a01a9374fd386f3a8773528d7a49bc5315492dffAdam LesinskiErrorPos::ErrorPos(const String8& f, int l, const String8& e, Level lev)
48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    :file(f),
49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     line(l),
50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski     error(e),
51a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski     level(lev)
52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
55282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiErrorPos&
56282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiErrorPos::operator=(const ErrorPos& rhs)
57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    this->file = rhs.file;
59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    this->line = rhs.line;
60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    this->error = rhs.error;
61a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    this->level = rhs.level;
62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return *this;
63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid
66282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiErrorPos::print(FILE* to) const
67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
68a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    const char* type = "";
69a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    switch (level) {
70a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    case NOTE:
71a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski        type = "note: ";
72a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski        break;
73a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    case WARNING:
74a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski        type = "warning: ";
75a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski        break;
76a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    case ERROR:
77a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski        type = "error: ";
78a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski        break;
79a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    }
80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
81a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    if (!this->file.isEmpty()) {
82a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski        if (this->line >= 0) {
83a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski            fprintf(to, "%s:%d: %s%s\n", this->file.string(), this->line, type, this->error.string());
84a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski        } else {
85a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski            fprintf(to, "%s: %s%s\n", this->file.string(), type, this->error.string());
86a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski        }
87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    } else {
88a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski        fprintf(to, "%s%s\n", type, this->error.string());
89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// SourcePos
93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// =============================================================================
94282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiSourcePos::SourcePos(const String8& f, int l)
95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    : file(f), line(l)
96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
99282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiSourcePos::SourcePos(const SourcePos& that)
100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    : file(that.file), line(that.line)
101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
104282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiSourcePos::SourcePos()
105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    : file("???", 0), line(-1)
106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
109282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiSourcePos::~SourcePos()
110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
113a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinskivoid
114282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiSourcePos::error(const char* fmt, ...) const
115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    va_list ap;
117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    va_start(ap, fmt);
118a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    String8 msg = String8::formatV(fmt, ap);
119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    va_end(ap);
120a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    g_errors.push_back(ErrorPos(this->file, this->line, msg, ErrorPos::ERROR));
121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
123a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinskivoid
124282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiSourcePos::warning(const char* fmt, ...) const
125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    va_list ap;
127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    va_start(ap, fmt);
128a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    String8 msg = String8::formatV(fmt, ap);
129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    va_end(ap);
130a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    ErrorPos(this->file, this->line, msg, ErrorPos::WARNING).print(stderr);
131a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski}
132a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski
133a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinskivoid
134a01a9374fd386f3a8773528d7a49bc5315492dffAdam LesinskiSourcePos::printf(const char* fmt, ...) const
135a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski{
136a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    va_list ap;
137a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    va_start(ap, fmt);
138a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    String8 msg = String8::formatV(fmt, ap);
139a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    va_end(ap);
140a01a9374fd386f3a8773528d7a49bc5315492dffAdam Lesinski    ErrorPos(this->file, this->line, msg, ErrorPos::NOTE).print(stderr);
141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool
144de7de47fef1dcaa26d553665d89e4d3792325c3fAdam LesinskiSourcePos::operator<(const SourcePos& rhs) const
145de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski{
146de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski    return (file < rhs.file) || (line < rhs.line);
147de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski}
148de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinski
149de7de47fef1dcaa26d553665d89e4d3792325c3fAdam Lesinskibool
150282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiSourcePos::hasErrors()
151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    return g_errors.size() > 0;
153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid
156282e181b58cf72b6ca770dc7ca5f91f135444502Adam LesinskiSourcePos::printErrors(FILE* to)
157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{
158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    vector<ErrorPos>::const_iterator it;
159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    for (it=g_errors.begin(); it!=g_errors.end(); it++) {
160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski        it->print(to);
161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski    }
162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski}
163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski
166