Home | History | Annotate | Download | only in localize
      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 
     33 ErrorPos::ErrorPos()
     34 {
     35 }
     36 
     37 ErrorPos::ErrorPos(const ErrorPos& that)
     38     :file(that.file),
     39      line(that.line),
     40      error(that.error)
     41 {
     42 }
     43 
     44 ErrorPos::ErrorPos(const string& f, int l, const string& e)
     45     :file(f),
     46      line(l),
     47      error(e)
     48 {
     49 }
     50 
     51 ErrorPos::~ErrorPos()
     52 {
     53 }
     54 
     55 bool
     56 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
     69 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&
     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
     86 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 // =============================================================================
     97 SourcePos::SourcePos(const string& f, int l)
     98     : file(f), line(l)
     99 {
    100 }
    101 
    102 SourcePos::SourcePos(const SourcePos& that)
    103     : file(that.file), line(that.line)
    104 {
    105 }
    106 
    107 SourcePos::SourcePos()
    108     : file("???", 0)
    109 {
    110 }
    111 
    112 SourcePos::~SourcePos()
    113 {
    114 }
    115 
    116 string
    117 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
    130 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
    152 SourcePos::HasErrors()
    153 {
    154     return g_errors.size() > 0;
    155 }
    156 
    157 void
    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