int main(int argc, char** argv) { /* If there's an argument, load that. Otherwise, load ourself. */ char const* lib = (argc > 1 ? argv[1] : argv[0]); /* First, get the list of functions that we should run. */ unique_ptr<char[]> real_symbol_cmd(new char[std::strlen(symbol_cmd) - 2 + std::strlen(lib) + 1]); std::sprintf(real_symbol_cmd.get(), symbol_cmd, lib); auto cmd_pipe = make_unique(popen(real_symbol_cmd.get(), "r"), &pclose); /* Then, build the test suites. */ char line[256]; TestSuite root; auto self = make_unique(dlopen(lib, RTLD_LAZY | RTLD_GLOBAL), &dlclose); if (!self) throw runtime_error(string("Could not dlopen() ") + lib); auto state_ptr = static_cast<DTest::State**>(dlsym(self.get(), "_dtest")); if (state_ptr) *state_ptr = &DTest::state; _dtest = &DTest::state; while (std::fgets(line, 255, cmd_pipe.get())) { char* space; for (space = line; *space != 0 && *space != ' '; ++space); if (space == 0) throw runtime_error(string("Invalid line: ") + line); *space = 0; char* i; for (i = space + 1; *i != 0 && *i != '\n'; ++i); *i = 0; root.add_test(space + 1, dltestsym(self.get(), line)); } /* And run the test suites. */ cout<<"Running tests..."<<endl; if (root.run()) return 0; return 1; }