diff --git a/doc/glmark2.1.in b/doc/glmark2.1.in index 529cafe5..cd8399e0 100644 --- a/doc/glmark2.1.in +++ b/doc/glmark2.1.in @@ -55,7 +55,7 @@ Run in fullscreen mode (equivalent to --size -1x-1) The types of results to report for each benchmark, as a ':' separated list [fps,cpu,shader] .TP \fB\-\-results-file\fR RESULTS-FILE -The file to save the results to, in the format determined by the file extension +The file to save the results to, in the format determined by the file extension [csv] .TP \fB\-\-winsys-options\fR OPTS A list of 'opt=value' pairs for window system specific options, separated by ':' diff --git a/src/options.cpp b/src/options.cpp index 41072eb0..f01aa708 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -223,7 +223,7 @@ Options::print_help() " --results RESULTS The types of results to report for each benchmark,\n" " as a ':' separated list [fps,cpu,shader]\n" " --results-file F The file to save the results to, in the format determined\n" - " by the file extension\n" + " by the file extension [csv]\n" " --winsys-options O A list of 'opt=value' pairs for window system specific\n" " options, separated by ':'\n" " -l, --list-scenes Display information about the available scenes\n" diff --git a/src/results-file.cpp b/src/results-file.cpp index a23819d3..f0777619 100644 --- a/src/results-file.cpp +++ b/src/results-file.cpp @@ -24,6 +24,7 @@ #include "log.h" #include +#include namespace { @@ -45,6 +46,64 @@ class NullResultsFile : public ResultsFile } }; +std::string escape_csv_text(const std::string &str) +{ + std::stringstream ss; + + for (auto c : str) + { + switch (c) + { + case '"': ss << "\"\""; break; + default: ss << c; break; + } + } + + return ss.str(); +} + +class CSVResultsFile : public ResultsFile +{ +public: + CSVResultsFile(std::ofstream &&fs) : fs{std::move(fs)} {} + + std::string type() override { return "CSV"; } + + void begin() override {} + void end() override {} + + void begin_info() override + { + first_field = true; + } + + void end_info() override + { + fs << std::endl; + } + + void begin_benchmark() override + { + first_field = true; + } + + void end_benchmark() override + { + fs << std::endl; + } + + void add_field(const std::string &name, const std::string &value) override + { + static_cast(name); + fs << (first_field ? "\"" : ",\"") << escape_csv_text(value) << "\""; + first_field = false; + } + +private: + std::ofstream fs; + bool first_field = true; +}; + std::string get_file_extension(const std::string &str) { auto i = str.rfind('.'); @@ -81,9 +140,20 @@ bool ResultsFile::init(const std::string &file) return false; } - Log::error("Results file type %s is not supported\n", file.c_str()); + if (ext == ".csv") + { + ResultsFile::singleton = std::make_unique(std::move(fs)); + } + else + { + Log::error("Results file type %s is not supported\n", file.c_str()); + return false; + } + + Log::debug("Writing results to %s file %s\n", + ResultsFile::get().type().c_str(), file.c_str()); - return false; + return true; } ResultsFile& ResultsFile::get()