// Minimal stand-in for the not-yet-built server: dlopen()s a compiled // template .so and calls its exported render entry point directly, the // way a persistent content-provider process would (no process spawn per // request, no re-parsing the .jet source - both the compile step AND // the shared-object load happen once, ahead of time). #include "Global.h" #include "MString.h" #include "Exception.h" #include #include #include typedef void (*RenderFn)(jet::Global &, coreutils::MString &); int main(int argc, char **argv, char **envp) { if (argc < 3) { std::cerr << "usage: host_test " << std::endl; return 1; } void *handle = dlopen(argv[1], RTLD_NOW); if (!handle) { std::cerr << "dlopen failed: " << dlerror() << std::endl; return 1; } dlerror(); RenderFn render = (RenderFn)dlsym(handle, argv[2]); const char *err = dlerror(); if (err) { std::cerr << "dlsym failed: " << err << std::endl; return 1; } // Simulate the host calling the SAME module twice, for two different // "requests", to prove the .so is reusable across calls without being // reloaded - the actual point of a persistent content provider. for (int i = 0; i < 2; ++i) { jet::Global global(envp); coreutils::MString out; try { render(global, out); global.outputHeaders(); std::cout << "--- render call " << i << " ---" << std::endl; std::cout << out; } catch (coreutils::Exception &e) { std::cout << "render call " << i << " threw: " << e.text << std::endl; } } dlclose(handle); return 0; }