• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "SourcePos.h"
2 
3 #include <stdarg.h>
4 #include <cstdio>
5 #include <set>
6 #include <cstdio>
7 
8 using namespace std;
9 
10 const SourcePos GENERATED_POS("<generated>", -1);
11 
12 // ErrorPos
13 // =============================================================================
14 struct ErrorPos
15 {
16     string file;
17     int line;
18     string error;
19 
20     ErrorPos();
21     ErrorPos(const ErrorPos& that);
22     ErrorPos(const string& file, int line, const string& error);
23     ~ErrorPos();
24     bool operator<(const ErrorPos& rhs) const;
25     bool operator==(const ErrorPos& rhs) const;
26     ErrorPos& operator=(const ErrorPos& rhs);
27 
28     void Print(FILE* to) const;
29 };
30 
31 static set<ErrorPos> g_errors;
32 
ErrorPos()33 ErrorPos::ErrorPos()
34 {
35 }
36 
ErrorPos(const ErrorPos & that)37 ErrorPos::ErrorPos(const ErrorPos& that)
38     :file(that.file),
39      line(that.line),
40      error(that.error)
41 {
42 }
43 
ErrorPos(const string & f,int l,const string & e)44 ErrorPos::ErrorPos(const string& f, int l, const string& e)
45     :file(f),
46      line(l),
47      error(e)
48 {
49 }
50 
~ErrorPos()51 ErrorPos::~ErrorPos()
52 {
53 }
54 
55 bool
operator <(const ErrorPos & rhs) const56 ErrorPos::operator<(const ErrorPos& rhs) const
57 {
58     if (this->file < rhs.file) return true;
59     if (this->file == rhs.file) {
60         if (this->line < rhs.line) return true;
61         if (this->line == rhs.line) {
62             if (this->error < rhs.error) return true;
63         }
64     }
65     return false;
66 }
67 
68 bool
operator ==(const ErrorPos & rhs) const69 ErrorPos::operator==(const ErrorPos& rhs) const
70 {
71     return this->file == rhs.file
72             && this->line == rhs.line
73             && this->error == rhs.error;
74 }
75 
76 ErrorPos&
operator =(const ErrorPos & rhs)77 ErrorPos::operator=(const ErrorPos& rhs)
78 {
79     this->file = rhs.file;
80     this->line = rhs.line;
81     this->error = rhs.error;
82     return *this;
83 }
84 
85 void
Print(FILE * to) const86 ErrorPos::Print(FILE* to) const
87 {
88     if (this->line >= 0) {
89         fprintf(to, "%s:%d: %s\n", this->file.c_str(), this->line, this->error.c_str());
90     } else {
91         fprintf(to, "%s: %s\n", this->file.c_str(), this->error.c_str());
92     }
93 }
94 
95 // SourcePos
96 // =============================================================================
SourcePos(const string & f,int l)97 SourcePos::SourcePos(const string& f, int l)
98     : file(f), line(l)
99 {
100 }
101 
SourcePos(const SourcePos & that)102 SourcePos::SourcePos(const SourcePos& that)
103     : file(that.file), line(that.line)
104 {
105 }
106 
SourcePos()107 SourcePos::SourcePos()
108     : file("???", 0)
109 {
110 }
111 
~SourcePos()112 SourcePos::~SourcePos()
113 {
114 }
115 
116 string
ToString() const117 SourcePos::ToString() const
118 {
119     char buf[1024];
120     if (this->line >= 0) {
121         snprintf(buf, sizeof(buf)-1, "%s:%d", this->file.c_str(), this->line);
122     } else {
123         snprintf(buf, sizeof(buf)-1, "%s:", this->file.c_str());
124     }
125     buf[sizeof(buf)-1] = '\0';
126     return string(buf);
127 }
128 
129 int
Error(const char * fmt,...) const130 SourcePos::Error(const char* fmt, ...) const
131 {
132     int retval=0;
133     char buf[1024];
134     va_list ap;
135     va_start(ap, fmt);
136     retval = vsnprintf(buf, sizeof(buf), fmt, ap);
137     va_end(ap);
138     char* p = buf + retval - 1;
139     while (p > buf && *p == '\n') {
140         *p = '\0';
141         p--;
142     }
143     ErrorPos err(this->file, this->line, string(buf));
144     if (g_errors.find(err) == g_errors.end()) {
145         err.Print(stderr);
146         g_errors.insert(err);
147     }
148     return retval;
149 }
150 
151 bool
HasErrors()152 SourcePos::HasErrors()
153 {
154     return g_errors.size() > 0;
155 }
156 
157 void
PrintErrors(FILE * to)158 SourcePos::PrintErrors(FILE* to)
159 {
160     set<ErrorPos>::const_iterator it;
161     for (it=g_errors.begin(); it!=g_errors.end(); it++) {
162         it->Print(to);
163     }
164 }
165 
166 
167 
168 
169