19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "SourcePos.h"
29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdarg.h>
49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <vector>
59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace std;
79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// ErrorPos
109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// =============================================================================
119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct ErrorPos
129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String8 file;
149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int line;
159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    String8 error;
169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool fatal;
179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ErrorPos();
199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ErrorPos(const ErrorPos& that);
209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ErrorPos(const String8& file, int line, const String8& error, bool fatal);
219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ~ErrorPos();
229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool operator<(const ErrorPos& rhs) const;
239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    bool operator==(const ErrorPos& rhs) const;
249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ErrorPos& operator=(const ErrorPos& rhs);
259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    void print(FILE* to) const;
279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project};
289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic vector<ErrorPos> g_errors;
309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectErrorPos::ErrorPos()
329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    :line(-1), fatal(false)
339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectErrorPos::ErrorPos(const ErrorPos& that)
379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    :file(that.file),
389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     line(that.line),
399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     error(that.error),
409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     fatal(that.fatal)
419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectErrorPos::ErrorPos(const String8& f, int l, const String8& e, bool fat)
459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    :file(f),
469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     line(l),
479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     error(e),
489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project     fatal(fat)
499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectErrorPos::~ErrorPos()
539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool
579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectErrorPos::operator<(const ErrorPos& rhs) const
589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (this->file < rhs.file) return true;
609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (this->file == rhs.file) {
619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (this->line < rhs.line) return true;
629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        if (this->line == rhs.line) {
639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            if (this->error < rhs.error) return true;
649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        }
659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return false;
679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool
709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectErrorPos::operator==(const ErrorPos& rhs) const
719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return this->file == rhs.file
739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            && this->line == rhs.line
749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project            && this->error == rhs.error;
759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectErrorPos&
789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectErrorPos::operator=(const ErrorPos& rhs)
799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    this->file = rhs.file;
819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    this->line = rhs.line;
829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    this->error = rhs.error;
839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return *this;
849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid
879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectErrorPos::print(FILE* to) const
889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
89dd931864209eac0b4182d7a0d1ca965fcc3b8c03Marco Nelissen    const char* type = fatal ? "error:" : "warning:";
909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    if (this->line >= 0) {
929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(to, "%s:%d: %s %s\n", this->file.string(), this->line, type, this->error.string());
939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    } else {
949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        fprintf(to, "%s: %s %s\n", this->file.string(), type, this->error.string());
959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// SourcePos
999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// =============================================================================
1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSourcePos::SourcePos(const String8& f, int l)
1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : file(f), line(l)
1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSourcePos::SourcePos(const SourcePos& that)
1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : file(that.file), line(that.line)
1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSourcePos::SourcePos()
1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    : file("???", 0), line(-1)
1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSourcePos::~SourcePos()
1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint
1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSourcePos::error(const char* fmt, ...) const
1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int retval=0;
1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buf[1024];
1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    va_list ap;
1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    va_start(ap, fmt);
1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    retval = vsnprintf(buf, sizeof(buf), fmt, ap);
1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    va_end(ap);
1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* p = buf + retval - 1;
1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (p > buf && *p == '\n') {
1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *p = '\0';
1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p--;
1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    g_errors.push_back(ErrorPos(this->file, this->line, String8(buf), true));
1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return retval;
1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint
1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSourcePos::warning(const char* fmt, ...) const
1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    int retval=0;
1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char buf[1024];
1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    va_list ap;
1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    va_start(ap, fmt);
1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    retval = vsnprintf(buf, sizeof(buf), fmt, ap);
1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    va_end(ap);
1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    char* p = buf + retval - 1;
1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    while (p > buf && *p == '\n') {
1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        *p = '\0';
1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        p--;
1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    ErrorPos(this->file, this->line, String8(buf), false).print(stderr);
1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return retval;
1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool
1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSourcePos::hasErrors()
1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    return g_errors.size() > 0;
1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid
1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectSourcePos::printErrors(FILE* to)
1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{
1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    vector<ErrorPos>::const_iterator it;
1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    for (it=g_errors.begin(); it!=g_errors.end(); it++) {
1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project        it->print(to);
1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project    }
1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}
1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project
172