• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "SourcePos.h"
2 
3 #include <stdarg.h>
4 #include <vector>
5 
6 using namespace std;
7 
8 
9 // ErrorPos
10 // =============================================================================
11 struct 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 
29 static vector<ErrorPos> g_errors;
30 
ErrorPos()31 ErrorPos::ErrorPos()
32     :line(-1), fatal(false)
33 {
34 }
35 
ErrorPos(const ErrorPos & that)36 ErrorPos::ErrorPos(const ErrorPos& that)
37     :file(that.file),
38      line(that.line),
39      error(that.error),
40      fatal(that.fatal)
41 {
42 }
43 
ErrorPos(const String8 & f,int l,const String8 & e,bool fat)44 ErrorPos::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 
~ErrorPos()52 ErrorPos::~ErrorPos()
53 {
54 }
55 
56 bool
operator <(const ErrorPos & rhs) const57 ErrorPos::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 
69 bool
operator ==(const ErrorPos & rhs) const70 ErrorPos::operator==(const ErrorPos& rhs) const
71 {
72     return this->file == rhs.file
73             && this->line == rhs.line
74             && this->error == rhs.error;
75 }
76 
77 ErrorPos&
operator =(const ErrorPos & rhs)78 ErrorPos::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 
86 void
print(FILE * to) const87 ErrorPos::print(FILE* to) const
88 {
89     const char* type = fatal ? "error:" : "warning:";
90 
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 // =============================================================================
SourcePos(const String8 & f,int l)100 SourcePos::SourcePos(const String8& f, int l)
101     : file(f), line(l)
102 {
103 }
104 
SourcePos(const SourcePos & that)105 SourcePos::SourcePos(const SourcePos& that)
106     : file(that.file), line(that.line)
107 {
108 }
109 
SourcePos()110 SourcePos::SourcePos()
111     : file("???", 0), line(-1)
112 {
113 }
114 
~SourcePos()115 SourcePos::~SourcePos()
116 {
117 }
118 
119 int
error(const char * fmt,...) const120 SourcePos::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 
137 int
warning(const char * fmt,...) const138 SourcePos::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 
155 bool
hasErrors()156 SourcePos::hasErrors()
157 {
158     return g_errors.size() > 0;
159 }
160 
161 void
printErrors(FILE * to)162 SourcePos::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 
172