From 44c1aeef226542d692f0002b5cca5a3c30935d18 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Sat, 10 Sep 2016 10:43:19 -0700 Subject: 3315 --- html/003trace.cc.html | 164 ++++++++++++++++++++++++++------------------------ 1 file changed, 85 insertions(+), 79 deletions(-) (limited to 'html/003trace.cc.html') diff --git a/html/003trace.cc.html b/html/003trace.cc.html index 9011e3eb..0e35ce97 100644 --- a/html/003trace.cc.html +++ b/html/003trace.cc.html @@ -110,9 +110,6 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color //: programmers form a mental model, rather than as production of a program." //: -- Peter Naur (http://alistair.cockburn.us/ASD+book+extract%3A+%22Naur,+Ehn,+Musashi%22) -:(before "int main") -// End Tracing // hack to ensure most code in this layer comes before anything else - :(before "End Types") struct trace_line { int depth; // optional field just to help browse traces later @@ -123,15 +120,18 @@ body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color }; :(before "End Globals") -const int Max_depth = 9999; -const int Error_depth = 0; // definitely always print errors -const int App_depth = 2; // temporarily where all mu code will trace to -:(before "End Tracing") bool Hide_errors = false; :(before "End Setup") Hide_errors = false; -:(before "End Tracing") +:(before "End Types") +// Pre-define some global constants that trace_stream needs to know about. +// Since they're in the Types section, they'll be included in any cleaved +// compilation units. So no extern linkage. +const int Max_depth = 9999; +const int Error_depth = 0; // definitely always print errors +const int App_depth = 2; // temporarily where all mu code will trace to + struct trace_stream { vector<trace_line> past_lines; // accumulator for current line @@ -157,41 +157,52 @@ Hide_errors = false;} // be sure to call this before messing with curr_stream or curr_label - void newline() { - if (!curr_stream) return; - string curr_contents = curr_stream->str(); - if (curr_contents.empty()) return; - past_lines.push_back(trace_line(curr_depth, trim(curr_label), curr_contents)); // preserve indent in contents - if (!Hide_errors && curr_label == "error") - cerr << curr_label << ": " << curr_contents << '\n'; - delete curr_stream; - curr_stream = NULL; - curr_label.clear(); - curr_depth = Max_depth; - } - + void newline(); // useful for debugging - string readable_contents(string label) { // empty label = show everything - ostringstream output; - label = trim(label); - for (vector<trace_line>::iterator p = past_lines.begin(); p != past_lines.end(); ++p) - if (label.empty() || label == p->label) { - output << std::setw(4) << p->depth << ' ' << p->label << ": " << p->contents << '\n'; - } - return output.str(); - } + string readable_contents(string label); // empty label = show everything }; -^L +:(code) +void trace_stream::newline() { + if (!curr_stream) return; + string curr_contents = curr_stream->str(); + if (curr_contents.empty()) return; + past_lines.push_back(trace_line(curr_depth, trim(curr_label), curr_contents)); // preserve indent in contents + if (!Hide_errors && curr_label == "error") + cerr << curr_label << ": " << curr_contents << '\n'; + delete curr_stream; + curr_stream = NULL; + curr_label.clear(); + curr_depth = Max_depth; +} + +string trace_stream::readable_contents(string label) { + ostringstream output; + label = trim(label); + for (vector<trace_line>::iterator p = past_lines.begin(); p != past_lines.end(); ++p) + if (label.empty() || label == p->label) { + output << std::setw(4) << p->depth << ' ' << p->label << ": " << p->contents << '\n'; + } + return output.str(); +} +:(before "End Globals") trace_stream* Trace_stream = NULL; int Trace_errors = 0; // used only when Trace_stream is NULL +:(before "End Includes") +#define CLEAR_TRACE delete Trace_stream, Trace_stream = new trace_stream; + // Top-level helper. IMPORTANT: can't nest #define trace(...) !Trace_stream ? cerr /*print nothing*/ : Trace_stream->stream(__VA_ARGS__) +// Just for debugging; 'git log' should never show any calls to 'dbg'. +#define dbg trace(0, "a") +#define DUMP(label) if (Trace_stream) cerr << Trace_stream->readable_contents(label); + // Errors are a special layer. #define raise (!Trace_stream ? (tb_shutdown(),++Trace_errors,cerr) /*do print*/ : Trace_stream->stream(Error_depth, "error")) + // Inside tests, fail any tests that displayed (unexpected) errors. // Expected errors in tests should always be hidden and silently checked for. :(before "End Test Teardown") @@ -200,37 +211,35 @@ trace_stream* Trace_stream = NULL; } -// Just for debugging. -#define dbg trace(0, "a") - :(before "End Types") struct end {}; -:(before "End Tracing") +:(code) ostream& operator<<(ostream& os, unused end) { if (Trace_stream) Trace_stream->newline(); return os; } -#define CLEAR_TRACE delete Trace_stream, Trace_stream = new trace_stream; - -#define DUMP(label) if (Trace_stream) cerr << Trace_stream->readable_contents(label); - +:(before "End Globals") bool Save_trace = false; // Trace_stream is a resource, lease_tracer uses RAII to manage it. +:(before "End Types") struct lease_tracer { - lease_tracer() { Trace_stream = new trace_stream; } - ~lease_tracer() { - if (!Trace_stream) return; // in case tests close Trace_stream - if (Save_trace) { - ofstream fout("last_trace"); - fout << Trace_stream->readable_contents(""); - fout.close(); - } - delete Trace_stream, Trace_stream = NULL; - } + lease_tracer(); + ~lease_tracer(); }; - +:(code) +lease_tracer::lease_tracer() { Trace_stream = new trace_stream; } +lease_tracer::~lease_tracer() { + if (!Trace_stream) return; // in case tests close Trace_stream + if (Save_trace) { + ofstream fout("last_trace"); + fout << Trace_stream->readable_contents(""); + fout.close(); + } + delete Trace_stream, Trace_stream = NULL; +} +:(before "End Includes") #define START_TRACING_UNTIL_END_OF_SCOPE lease_tracer leased_tracer; :(before "End Test Setup") START_TRACING_UNTIL_END_OF_SCOPE @@ -238,8 +247,31 @@ START_TRACING_UNTIL_END_OF_SCOPE :(before "End Includes") #define CHECK_TRACE_CONTENTS(...) check_trace_contents(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) -:(before "End Tracing") +#define CHECK_TRACE_CONTAINS_ERROR() CHECK(trace_count("error") > 0) +#define CHECK_TRACE_DOESNT_CONTAIN_ERROR() \ + if (Passed && trace_count("error") > 0) { \ + ++Num_failures; \ + cerr << "\nF - " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): unexpected errors\n"; \ + DUMP("error"); \ + Passed = false; \ + return; \ + } + +#define CHECK_TRACE_COUNT(label, count) \ + if (Passed && trace_count(label) != (count)) { \ + ++Num_failures; \ + cerr << "\nF - " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): trace_count of " << label << " should be " << count << '\n'; \ + cerr << " got " << trace_count(label) << '\n'; /* multiple eval */ \ + DUMP(label); \ + Passed = false; \ + return; /* Currently we stop at the very first failure. */ \ + } + +#define CHECK_TRACE_DOESNT_CONTAIN(...) CHECK(trace_doesnt_contain(__VA_ARGS__)) + +:(code) bool check_trace_contents(string FUNCTION, string FILE, int LINE, string expected) { + if (!Passed) return false; if (!Trace_stream) return false; vector<string> expected_lines = split(expected, "^D"); int curr_expected_line = 0; @@ -292,8 +324,6 @@ START_TRACING_UNTIL_END_OF_SCOPE return false; } -^L - int trace_count(string label) { return trace_count(label, ""); } @@ -322,26 +352,6 @@ START_TRACING_UNTIL_END_OF_SCOPE return result; } -#define CHECK_TRACE_CONTAINS_ERROR() CHECK(trace_count("error") > 0) -#define CHECK_TRACE_DOESNT_CONTAIN_ERROR() \ - if (trace_count("error") > 0) { \ - ++Num_failures; \ - cerr << "\nF - " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): unexpected errors\n"; \ - DUMP("error"); \ - Passed = false; \ - return; \ - } - -#define CHECK_TRACE_COUNT(label, count) \ - if (trace_count(label) != (count)) { \ - ++Num_failures; \ - cerr << "\nF - " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): trace_count of " << label << " should be " << count << '\n'; \ - cerr << " got " << trace_count(label) << '\n'; /* multiple eval */ \ - DUMP(label); \ - Passed = false; \ - return; /* Currently we stop at the very first failure. */ \ - } - bool trace_doesnt_contain(string label, string line) { return trace_count(label, line) == 0; } @@ -351,10 +361,6 @@ START_TRACING_UNTIL_END_OF_SCOPE return trace_doesnt_contain(tmp.at(0), tmp.at(1)); } -#define CHECK_TRACE_DOESNT_CONTAIN(...) CHECK(trace_doesnt_contain(__VA_ARGS__)) - -^L - vector<string> split(string s, string delim) { vector<string> result; size_t begin=0, end=s.find(delim); @@ -419,8 +425,8 @@ string trim(const str //: Errors will be depth 0. //: Mu 'applications' will be able to use depths 1-100 as they like. //: Primitive statements will occupy 101-9989 -const int Initial_callstack_depth = 101; -const int Max_callstack_depth = 9989; +extern const int Initial_callstack_depth = 101; +extern const int Max_callstack_depth = 9989; //: Finally, details of primitive mu statements will occupy depth 9990-9999 (more on that later as well) //: //: This framework should help us hide some details at each level, mixing -- cgit 1.4.1-2-gfad0