X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;ds=sidebyside;f=retrace.cpp;h=412c73b8061e6ecd975ecc32581250dcb7fe8440;hb=e181b99a776865a5aca43a64cf6afbaa371583ab;hp=07ee5b56b5dc98936be7b4f80ed3befdb6963ff3;hpb=8d53812c37b72d4cc4346b4548a940d0210815df;p=apitrace diff --git a/retrace.cpp b/retrace.cpp index 07ee5b5..412c73b 100644 --- a/retrace.cpp +++ b/retrace.cpp @@ -36,29 +36,81 @@ namespace retrace { int verbosity = 0; -void ignore(Trace::Call &call) { +static bool call_dumped = false; + + +static void dumpCall(trace::Call &call) { + if (verbosity >= 0 && !call_dumped) { + std::cout << call; + std::cout.flush(); + call_dumped = true; + } +} + + +std::ostream &warning(trace::Call &call) { + dumpCall(call); + + std::cerr << call.no << ": "; + std::cerr << "warning: "; + + return std::cerr; +} + + +void ignore(trace::Call &call) { (void)call; } -void retrace_unknown(Trace::Call &call) { - if (verbosity >= 0) { - std::cerr << call.no << ": warning: unknown call " << call.name() << "\n"; +void unsupported(trace::Call &call) { + warning(call) << "unsupported " << call.name() << " call\n"; +} + +inline void Retracer::addCallback(const Entry *entry) { + assert(entry->name); + assert(entry->callback); + map[entry->name] = entry->callback; +} + + +void Retracer::addCallbacks(const Entry *entries) { + while (entries->name && entries->callback) { + addCallback(entries++); } } -void dispatch(Trace::Call &call, const Entry *entries, unsigned num_entries) -{ - /* TODO: do a bisection instead of a linear search */ - const char *name = call.name(); - for (unsigned i = 0; i < num_entries; ++i) { - if (strcmp(name, entries[i].name) == 0) { - entries[i].callback(call); - return; +void Retracer::retrace(trace::Call &call) { + call_dumped = false; + + if (verbosity >= 1) { + dumpCall(call); + } + + Callback callback = 0; + + trace::Id id = call.sig->id; + if (id >= callbacks.size()) { + callbacks.resize(id + 1); + callback = 0; + } else { + callback = callbacks[id]; + } + + if (!callback) { + Map::const_iterator it = map.find(call.name()); + if (it == map.end()) { + callback = &unsupported; + } else { + callback = it->second; } + callbacks[id] = callback; } - retrace_unknown(call); + assert(callback); + assert(callbacks[id] == callback); + + callback(call); }