From 7a219c68bae6dbe214aec69a051015e851e32400 Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Thu, 12 Oct 2017 23:55:19 -0700 Subject: 4054 --- html/subx/003trace.cc.html | 232 ++++++++++++++++++++++----------------------- 1 file changed, 116 insertions(+), 116 deletions(-) (limited to 'html/subx/003trace.cc.html') diff --git a/html/subx/003trace.cc.html b/html/subx/003trace.cc.html index 9fca7be6..81d543b6 100644 --- a/html/subx/003trace.cc.html +++ b/html/subx/003trace.cc.html @@ -130,89 +130,89 @@ if ('onhashchange' in window) { 69 70 :(before "End Types") 71 struct trace_line { - 72 int depth; // optional field just to help browse traces later - 73 string label; - 74 string contents; - 75 trace_line(string l, string c) :depth(0), label(l), contents(c) {} - 76 trace_line(int d, string l, string c) :depth(d), label(l), contents(c) {} + 72 int depth; // optional field just to help browse traces later + 73 string label; + 74 string contents; + 75 trace_line(string l, string c) :depth(0), label(l), contents(c) {} + 76 trace_line(int d, string l, string c) :depth(d), label(l), contents(c) {} 77 }; 78 79 :(before "End Globals") 80 bool Hide_errors = false; - 81 bool Dump_trace = false; - 82 string Dump_label = ""; + 81 bool Dump_trace = false; + 82 string Dump_label = ""; 83 :(before "End Reset") 84 Hide_errors = false; - 85 Dump_trace = false; - 86 Dump_label = ""; + 85 Dump_trace = false; + 86 Dump_label = ""; 87 88 :(before "End Types") 89 // Pre-define some global constants that trace_stream needs to know about. 90 // Since they're in the Types section, they'll be included in any cleaved 91 // compilation units. So no extern linkage. - 92 const int Max_depth = 9999; - 93 const int Error_depth = 0; // definitely always print errors + 92 const int Max_depth = 9999; + 93 const int Error_depth = 0; // definitely always print errors 94 95 struct trace_stream { - 96 vector<trace_line> past_lines; + 96 vector<trace_line> past_lines; 97 // accumulator for current line - 98 ostringstream* curr_stream; - 99 string curr_label; -100 int curr_depth; -101 int callstack_depth; -102 int collect_depth; -103 ofstream null_stream; // never opens a file, so writes silently fail -104 trace_stream() :curr_stream(NULL), curr_depth(Max_depth), callstack_depth(0), collect_depth(Max_depth) {} -105 ~trace_stream() { if (curr_stream) delete curr_stream; } + 98 ostringstream* curr_stream; + 99 string curr_label; +100 int curr_depth; +101 int callstack_depth; +102 int collect_depth; +103 ofstream null_stream; // never opens a file, so writes silently fail +104 trace_stream() :curr_stream(NULL), curr_depth(Max_depth), callstack_depth(0), collect_depth(Max_depth) {} +105 ~trace_stream() { if (curr_stream) delete curr_stream; } 106 -107 ostream& stream(string label) { -108 ¦ return stream(Max_depth, label); +107 ostream& stream(string label) { +108 ¦ return stream(Max_depth, label); 109 } 110 -111 ostream& stream(int depth, string label) { -112 ¦ if (depth > collect_depth) return null_stream; -113 ¦ curr_stream = new ostringstream; -114 ¦ curr_label = label; -115 ¦ curr_depth = depth; +111 ostream& stream(int depth, string label) { +112 ¦ if (depth > collect_depth) return null_stream; +113 ¦ curr_stream = new ostringstream; +114 ¦ curr_label = label; +115 ¦ curr_depth = depth; 116 ¦ return *curr_stream; 117 } 118 119 // be sure to call this before messing with curr_stream or curr_label -120 void newline(); +120 void newline(); 121 // useful for debugging -122 string readable_contents(string label); // empty label = show everything +122 string readable_contents(string label); // empty label = show everything 123 }; 124 125 :(code) -126 void trace_stream::newline() { +126 void trace_stream::newline() { 127 if (!curr_stream) return; -128 string curr_contents = curr_stream->str(); +128 string curr_contents = curr_stream->str(); 129 if (!curr_contents.empty()) { -130 ¦ past_lines.push_back(trace_line(curr_depth, trim(curr_label), curr_contents)); // preserve indent in contents -131 ¦ if ((!Hide_errors && curr_label == "error") -132 ¦ ¦ ¦ || Dump_trace -133 ¦ ¦ ¦ || (!Dump_label.empty() && curr_label == Dump_label)) -134 ¦ ¦ cerr << curr_label << ": " << curr_contents << '\n'; +130 ¦ past_lines.push_back(trace_line(curr_depth, trim(curr_label), curr_contents)); // preserve indent in contents +131 ¦ if ((!Hide_errors && curr_label == "error") +132 ¦ ¦ ¦ || Dump_trace +133 ¦ ¦ ¦ || (!Dump_label.empty() && curr_label == Dump_label)) +134 ¦ ¦ cerr << curr_label << ": " << curr_contents << '\n'; 135 } -136 delete curr_stream; -137 curr_stream = NULL; -138 curr_label.clear(); -139 curr_depth = Max_depth; +136 delete curr_stream; +137 curr_stream = NULL; +138 curr_label.clear(); +139 curr_depth = Max_depth; 140 } 141 -142 string trace_stream::readable_contents(string label) { +142 string trace_stream::readable_contents(string label) { 143 ostringstream output; -144 label = trim(label); -145 for (vector<trace_line>::iterator p = past_lines.begin(); p != past_lines.end(); ++p) -146 ¦ if (label.empty() || label == p->label) { -147 ¦ ¦ output << std::setw(4) << p->depth << ' ' << p->label << ": " << p->contents << '\n'; +144 label = trim(label); +145 for (vector<trace_line>::iterator p = past_lines.begin(); p != past_lines.end(); ++p) +146 ¦ if (label.empty() || label == p->label) { +147 ¦ ¦ output << std::setw(4) << p->depth << ' ' << p->label << ": " << p->contents << '\n'; 148 ¦ } 149 return output.str(); 150 } 151 152 :(before "End Globals") -153 trace_stream* Trace_stream = NULL; -154 int Trace_errors = 0; // used only when Trace_stream is NULL +153 trace_stream* Trace_stream = NULL; +154 int Trace_errors = 0; // used only when Trace_stream is NULL 155 156 :(before "End Includes") 157 #define CLEAR_TRACE delete Trace_stream, Trace_stream = new trace_stream; @@ -233,46 +233,46 @@ if ('onhashchange' in window) { 172 // Inside tests, fail any tests that displayed (unexpected) errors. 173 // Expected errors in tests should always be hidden and silently checked for. 174 :(before "End Test Teardown") -175 if (Passed && !Hide_errors && trace_contains_errors()) { -176 Passed = false; +175 if (Passed && !Hide_errors && trace_contains_errors()) { +176 Passed = false; 177 } 178 :(code) -179 bool trace_contains_errors() { -180 return Trace_errors > 0 || trace_count("error") > 0; +179 bool trace_contains_errors() { +180 return Trace_errors > 0 || trace_count("error") > 0; 181 } 182 183 :(before "End Types") -184 struct end {}; +184 struct end {}; 185 :(code) -186 ostream& operator<<(ostream& os, unused end) { -187 if (Trace_stream) Trace_stream->newline(); +186 ostream& operator<<(ostream& os, unused end) { +187 if (Trace_stream) Trace_stream->newline(); 188 return os; 189 } 190 191 :(before "End Globals") -192 bool Save_trace = false; +192 bool Save_trace = false; 193 194 // Trace_stream is a resource, lease_tracer uses RAII to manage it. 195 :(before "End Types") 196 struct lease_tracer { 197 lease_tracer(); -198 ~lease_tracer(); +198 ~lease_tracer(); 199 }; 200 :(code) -201 lease_tracer::lease_tracer() { Trace_stream = new trace_stream; } -202 lease_tracer::~lease_tracer() { +201 lease_tracer::lease_tracer() { Trace_stream = new trace_stream; } +202 lease_tracer::~lease_tracer() { 203 if (!Trace_stream) return; // in case tests close Trace_stream -204 if (Save_trace) { +204 if (Save_trace) { 205 ¦ ofstream fout("last_trace"); -206 ¦ fout << Trace_stream->readable_contents(""); +206 ¦ fout << Trace_stream->readable_contents(""); 207 ¦ fout.close(); 208 } -209 delete Trace_stream, Trace_stream = NULL; +209 delete Trace_stream, Trace_stream = NULL; 210 } 211 :(before "End Includes") 212 #define START_TRACING_UNTIL_END_OF_SCOPE lease_tracer leased_tracer; 213 :(before "End Test Setup") -214 START_TRACING_UNTIL_END_OF_SCOPE +214 START_TRACING_UNTIL_END_OF_SCOPE 215 216 :(before "End Includes") 217 #define CHECK_TRACE_CONTENTS(...) check_trace_contents(__FUNCTION__, __FILE__, __LINE__, __VA_ARGS__) @@ -282,143 +282,143 @@ if ('onhashchange' in window) { 221 if (Passed && trace_contains_errors()) { \ 222 ¦ cerr << "\nF - " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): unexpected errors\n"; \ 223 ¦ DUMP("error"); \ -224 ¦ Passed = false; \ +224 ¦ Passed = false; \ 225 ¦ return; \ 226 } 227 228 #define CHECK_TRACE_COUNT(label, count) \ 229 if (Passed && trace_count(label) != (count)) { \ -230 ¦ cerr << "\nF - " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): trace_count of " << label << " should be " << count << '\n'; \ +230 ¦ cerr << "\nF - " << __FUNCTION__ << "(" << __FILE__ << ":" << __LINE__ << "): trace_count of " << label << " should be " << count << '\n'; \ 231 ¦ cerr << " got " << trace_count(label) << '\n'; /* multiple eval */ \ 232 ¦ DUMP(label); \ -233 ¦ Passed = false; \ +233 ¦ Passed = false; \ 234 ¦ return; /* Currently we stop at the very first failure. */ \ 235 } 236 237 #define CHECK_TRACE_DOESNT_CONTAIN(...) CHECK(trace_doesnt_contain(__VA_ARGS__)) 238 239 :(code) -240 bool check_trace_contents(string FUNCTION, string FILE, int LINE, string expected) { +240 bool check_trace_contents(string FUNCTION, string FILE, int LINE, string expected) { 241 if (!Passed) return false; 242 if (!Trace_stream) return false; -243 vector<string> expected_lines = split(expected, "^D"); +243 vector<string> expected_lines = split(expected, "^D"); 244 int curr_expected_line = 0; -245 while (curr_expected_line < SIZE(expected_lines) && expected_lines.at(curr_expected_line).empty()) +245 while (curr_expected_line < SIZE(expected_lines) && expected_lines.at(curr_expected_line).empty()) 246 ¦ ++curr_expected_line; -247 if (curr_expected_line == SIZE(expected_lines)) return true; -248 string label, contents; -249 split_label_contents(expected_lines.at(curr_expected_line), &label, &contents); -250 for (vector<trace_line>::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { -251 ¦ if (label != p->label) continue; -252 ¦ if (contents != trim(p->contents)) continue; +247 if (curr_expected_line == SIZE(expected_lines)) return true; +248 string label, contents; +249 split_label_contents(expected_lines.at(curr_expected_line), &label, &contents); +250 for (vector<trace_line>::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { +251 ¦ if (label != p->label) continue; +252 ¦ if (contents != trim(p->contents)) continue; 253 ¦ ++curr_expected_line; -254 ¦ while (curr_expected_line < SIZE(expected_lines) && expected_lines.at(curr_expected_line).empty()) +254 ¦ while (curr_expected_line < SIZE(expected_lines) && expected_lines.at(curr_expected_line).empty()) 255 ¦ ¦ ++curr_expected_line; -256 ¦ if (curr_expected_line == SIZE(expected_lines)) return true; -257 ¦ split_label_contents(expected_lines.at(curr_expected_line), &label, &contents); +256 ¦ if (curr_expected_line == SIZE(expected_lines)) return true; +257 ¦ split_label_contents(expected_lines.at(curr_expected_line), &label, &contents); 258 } 259 -260 if (line_exists_anywhere(label, contents)) { -261 ¦ cerr << "\nF - " << FUNCTION << "(" << FILE << ":" << LINE << "): line [" << label << ": " << contents << "] out of order in trace:\n"; -262 ¦ DUMP(""); +260 if (line_exists_anywhere(label, contents)) { +261 ¦ cerr << "\nF - " << FUNCTION << "(" << FILE << ":" << LINE << "): line [" << label << ": " << contents << "] out of order in trace:\n"; +262 ¦ DUMP(""); 263 } 264 else { -265 ¦ cerr << "\nF - " << FUNCTION << "(" << FILE << ":" << LINE << "): missing [" << contents << "] in trace:\n"; -266 ¦ DUMP(label); +265 ¦ cerr << "\nF - " << FUNCTION << "(" << FILE << ":" << LINE << "): missing [" << contents << "] in trace:\n"; +266 ¦ DUMP(label); 267 } -268 Passed = false; +268 Passed = false; 269 return false; 270 } 271 -272 void split_label_contents(const string& s, string* label, string* contents) { +272 void split_label_contents(const string& s, string* label, string* contents) { 273 static const string delim(": "); 274 size_t pos = s.find(delim); 275 if (pos == string::npos) { 276 ¦ *label = ""; -277 ¦ *contents = trim(s); +277 ¦ *contents = trim(s); 278 } 279 else { -280 ¦ *label = trim(s.substr(0, pos)); -281 ¦ *contents = trim(s.substr(pos+SIZE(delim))); +280 ¦ *label = trim(s.substr(0, pos)); +281 ¦ *contents = trim(s.substr(pos+SIZE(delim))); 282 } 283 } 284 -285 bool line_exists_anywhere(const string& label, const string& contents) { -286 for (vector<trace_line>::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { -287 ¦ if (label != p->label) continue; -288 ¦ if (contents == trim(p->contents)) return true; +285 bool line_exists_anywhere(const string& label, const string& contents) { +286 for (vector<trace_line>::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { +287 ¦ if (label != p->label) continue; +288 ¦ if (contents == trim(p->contents)) return true; 289 } 290 return false; 291 } 292 -293 int trace_count(string label) { -294 return trace_count(label, ""); +293 int trace_count(string label) { +294 return trace_count(label, ""); 295 } 296 -297 int trace_count(string label, string line) { +297 int trace_count(string label, string line) { 298 if (!Trace_stream) return 0; 299 long result = 0; -300 for (vector<trace_line>::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { -301 ¦ if (label == p->label) { -302 ¦ ¦ if (line == "" || trim(line) == trim(p->contents)) +300 for (vector<trace_line>::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { +301 ¦ if (label == p->label) { +302 ¦ ¦ if (line == "" || trim(line) == trim(p->contents)) 303 ¦ ¦ ¦ ++result; 304 ¦ } 305 } 306 return result; 307 } 308 -309 int trace_count_prefix(string label, string prefix) { +309 int trace_count_prefix(string label, string prefix) { 310 if (!Trace_stream) return 0; 311 long result = 0; -312 for (vector<trace_line>::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { -313 ¦ if (label == p->label) { -314 ¦ ¦ if (starts_with(trim(p->contents), trim(prefix))) +312 for (vector<trace_line>::iterator p = Trace_stream->past_lines.begin(); p != Trace_stream->past_lines.end(); ++p) { +313 ¦ if (label == p->label) { +314 ¦ ¦ if (starts_with(trim(p->contents), trim(prefix))) 315 ¦ ¦ ¦ ++result; 316 ¦ } 317 } 318 return result; 319 } 320 -321 bool trace_doesnt_contain(string label, string line) { -322 return trace_count(label, line) == 0; +321 bool trace_doesnt_contain(string label, string line) { +322 return trace_count(label, line) == 0; 323 } 324 325 bool trace_doesnt_contain(string expected) { -326 vector<string> tmp = split_first(expected, ": "); +326 vector<string> tmp = split_first(expected, ": "); 327 return trace_doesnt_contain(tmp.at(0), tmp.at(1)); 328 } 329 -330 vector<string> split(string s, string delim) { +330 vector<string> split(string s, string delim) { 331 vector<string> result; 332 size_t begin=0, end=s.find(delim); 333 while (true) { -334 ¦ if (end == string::npos) { +334 ¦ if (end == string::npos) { 335 ¦ ¦ result.push_back(string(s, begin, string::npos)); 336 ¦ ¦ break; 337 ¦ } 338 ¦ result.push_back(string(s, begin, end-begin)); 339 ¦ begin = end+SIZE(delim); -340 ¦ end = s.find(delim, begin); +340 ¦ end = s.find(delim, begin); 341 } 342 return result; 343 } 344 -345 vector<string> split_first(string s, string delim) { +345 vector<string> split_first(string s, string delim) { 346 vector<string> result; 347 size_t end=s.find(delim); -348 result.push_back(string(s, 0, end)); -349 if (end != string::npos) +348 result.push_back(string(s, 0, end)); +349 if (end != string::npos) 350 ¦ result.push_back(string(s, end+SIZE(delim), string::npos)); 351 return result; 352 } 353 -354 string trim(const string& s) { +354 string trim(const string& s) { 355 string::const_iterator first = s.begin(); -356 while (first != s.end() && isspace(*first)) +356 while (first != s.end() && isspace(*first)) 357 ¦ ++first; -358 if (first == s.end()) return ""; +358 if (first == s.end()) return ""; 359 -360 string::const_iterator last = --s.end(); +360 string::const_iterator last = --s.end(); 361 while (last != s.begin() && isspace(*last)) 362 ¦ --last; 363 ++last; @@ -450,8 +450,8 @@ if ('onhashchange' in window) { 389 //: Errors will be depth 0. 390 //: Mu 'applications' will be able to use depths 1-100 as they like. 391 //: Primitive statements will occupy 101-9989 -392 extern const int Initial_callstack_depth = 101; -393 extern const int Max_callstack_depth = 9989; +392 extern const int Initial_callstack_depth = 101; +393 extern const int Max_callstack_depth = 9989; 394 //: Finally, details of primitive Mu statements will occupy depth 9990-9999 395 //: (more on that later as well) 396 //: -- cgit 1.4.1-2-gfad0