#include <iostream>
#include <list>
using namespace std;
struct stack_frame {
const char *funName;
const char *fileName;
int line;
stack_frame(const char* func, const char* file, int ln)
: funName(func), fileName(file), line(ln) {}
};
thread_local list<stack_frame> *frames = 0;
struct entry_exit {
bool delFrames;
entry_exit(const char* func, const char* file, int ln) {
if (!frames) {
frames = new list<stack_frame>();
delFrames = true;
} else {
delFrames = false;
}
frames->push_back(stack_frame(func, file, ln));
}
~entry_exit() {
frames->pop_back();
if (delFrames) {
delete frames;
frames = 0;
}
}
};
void show_stack() {
for (list<stack_frame>::const_iterator i = frames->begin() ; i != frames->end() ; ++i) {
cerr << i->funName << " - " << i->fileName << " (" << i->line << ")" << endl;
}
}
#define FUNCTION_ENTRY entry_exit _entry_exit_(__func__, __FILE__, __LINE__);
void foo() {
FUNCTION_ENTRY;
show_stack();
}
void bar() {
FUNCTION_ENTRY;
foo();
}
void baz() {
FUNCTION_ENTRY;
bar();
}
int main() {
baz();
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bGlzdD4KCnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgpzdHJ1Y3Qgc3RhY2tfZnJhbWUgewogICAgY29uc3QgY2hhciAqZnVuTmFtZTsKICAgIGNvbnN0IGNoYXIgKmZpbGVOYW1lOwogICAgaW50IGxpbmU7CiAgICBzdGFja19mcmFtZShjb25zdCBjaGFyKiBmdW5jLCBjb25zdCBjaGFyKiBmaWxlLCBpbnQgbG4pCiAgICA6IGZ1bk5hbWUoZnVuYyksIGZpbGVOYW1lKGZpbGUpLCBsaW5lKGxuKSB7fQp9OwoKdGhyZWFkX2xvY2FsIGxpc3Q8c3RhY2tfZnJhbWU+ICpmcmFtZXMgPSAwOwoKc3RydWN0IGVudHJ5X2V4aXQgewogICAgYm9vbCBkZWxGcmFtZXM7CiAgICBlbnRyeV9leGl0KGNvbnN0IGNoYXIqIGZ1bmMsIGNvbnN0IGNoYXIqIGZpbGUsIGludCBsbikgewogICAgICAgIGlmICghZnJhbWVzKSB7CiAgICAgICAgICAgIGZyYW1lcyA9IG5ldyBsaXN0PHN0YWNrX2ZyYW1lPigpOwogICAgICAgICAgICBkZWxGcmFtZXMgPSB0cnVlOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGRlbEZyYW1lcyA9IGZhbHNlOwogICAgICAgIH0KICAgICAgICBmcmFtZXMtPnB1c2hfYmFjayhzdGFja19mcmFtZShmdW5jLCBmaWxlLCBsbikpOwogICAgfQogICAgfmVudHJ5X2V4aXQoKSB7CiAgICAgICAgZnJhbWVzLT5wb3BfYmFjaygpOwogICAgICAgIGlmIChkZWxGcmFtZXMpIHsKICAgICAgICAgICAgZGVsZXRlIGZyYW1lczsKICAgICAgICAgICAgZnJhbWVzID0gMDsKICAgICAgICB9CiAgICB9Cn07Cgp2b2lkIHNob3dfc3RhY2soKSB7CiAgICBmb3IgKGxpc3Q8c3RhY2tfZnJhbWU+Ojpjb25zdF9pdGVyYXRvciBpID0gZnJhbWVzLT5iZWdpbigpIDsgaSAhPSBmcmFtZXMtPmVuZCgpIDsgKytpKSB7CiAgICAgICAgY2VyciA8PCBpLT5mdW5OYW1lIDw8ICIgLSAiIDw8IGktPmZpbGVOYW1lIDw8ICIgKCIgPDwgaS0+bGluZSA8PCAiKSIgPDwgZW5kbDsKICAgIH0KfQoKI2RlZmluZSBGVU5DVElPTl9FTlRSWSBlbnRyeV9leGl0IF9lbnRyeV9leGl0XyhfX2Z1bmNfXywgX19GSUxFX18sIF9fTElORV9fKTsKCnZvaWQgZm9vKCkgewogICAgRlVOQ1RJT05fRU5UUlk7CiAgICBzaG93X3N0YWNrKCk7Cn0Kdm9pZCBiYXIoKSB7CiAgICBGVU5DVElPTl9FTlRSWTsKICAgIGZvbygpOwp9CnZvaWQgYmF6KCkgewogICAgRlVOQ1RJT05fRU5UUlk7CiAgICBiYXIoKTsKfQoKaW50IG1haW4oKSB7CgliYXooKTsKCXJldHVybiAwOwp9