/** * \file except.cpp */ INTERFACE: #include #include #include #include #include "ptree_nodes.h" class Compile_error : public std::runtime_error { public: static bool had_errors; }; #ifdef __GNUC__ /* An attempt to reduce the warnings */ void compile_error(const char*) __attribute__((noreturn)); void compile_error(std::string) __attribute__((noreturn)); void bogus_ptree_error(const char*, Ptree*) __attribute__((noreturn)); void bogus_ptree_error(std::string, Ptree*) __attribute__((noreturn)); #endif IMPLEMENTATION: #include #include #include #include #include "source.h" #ifdef USE_BACKTRACER # include "debug.h" #else # define printBacktrace(x) #endif bool Compile_error::had_errors = 0; void compile_error(const char* str) { throw Compile_error(str); } void compile_error(std::string str) { throw Compile_error(str); } void bogus_ptree_error(const char* str, Ptree* tree) { bogus_ptree_error(std::string(str), tree); } void bogus_ptree_error(std::string str, Ptree* tree) { printBacktrace(std::cerr); std::ostringstream o; if (tree) { o << "Could not understand this ptree: "; tree->Display2(o); } else { o << "Null Ptree encountered\n"; } throw Compile_error(o.str() + str); } void expect_ptree(Ptree* p, const char* str) { if (!p->Eq((char*)str)) bogus_ptree_error(std::string("expected `") + str + "'", p); } void expect_ptree(Ptree* p, char c) { if (!p->Eq(c)) bogus_ptree_error(std::string("expected `") + c + "'", p); } PUBLIC Compile_error::Compile_error(std::string str) : std::runtime_error(str) { } PUBLIC Compile_error::Compile_error(const char* str) : std::runtime_error(str) { } static Ptree* find_leaf(Ptree* tree, char** fn_out, int* fn_length_out, unsigned int* line_out) { if (!tree) return 0; else if (tree->IsLeaf()) if ((*line_out = Source::instance().program()->LineNumber(tree->GetPosition(), *fn_out, *fn_length_out))) return tree; else return 0; else if (Ptree* p = find_leaf(tree->Car(), fn_out, fn_length_out, line_out)) return p; else return find_leaf(tree->Cdr(), fn_out, fn_length_out, line_out); } static void print_location(std::ostream& os, Ptree* tree) { unsigned int line; char* fn; int fn_length; tree = find_leaf(tree, &fn, &fn_length, &line); if (tree) { if (line) { os.write(fn, fn_length); os << ":" << line; } else { os << ""; } } else { os << ""; } } PUBLIC void Compile_error::print(std::ostream& os, Ptree* tree) { print_location(os, tree); os << ": " << what() << "\n"; had_errors = true; } void compile_warning(const char* str, Ptree* tree) { print_location(std::cerr, tree); std::cerr << ": warning: " << str << "\n"; } void compile_warning(std::string str, Ptree* tree) { print_location(std::cerr, tree); std::cerr << ": warning: " << str << "\n"; }