diff --git a/src/citeme.cpp b/src/citeme.cpp index 41ac87f5bb..b8a1d656d9 100644 --- a/src/citeme.cpp +++ b/src/citeme.cpp @@ -15,6 +15,8 @@ #include "comm.h" #include "universe.h" +#include + using namespace LAMMPS_NS; static const char cite_separator[] = @@ -26,6 +28,9 @@ static const char cite_nagline[] = static const char cite_file[] = "The {} {} lists these citations in " "BibTeX format.\n\n"; +// define hash function +static std::hash get_hash; + /* ---------------------------------------------------------------------- */ CiteMe::CiteMe(LAMMPS *lmp, int _screen, int _logfile, const char *_file) @@ -68,14 +73,16 @@ CiteMe::~CiteMe() process an added citation so it will be shown only once and as requested ------------------------------------------------------------------------- */ -void CiteMe::add(const char *ref) +void CiteMe::add(const std::string &reference) { if (comm->me != 0) return; - if (cs->find(ref) != cs->end()) return; - cs->insert(ref); + + std::size_t crc = get_hash(reference); + if (cs->find(crc) != cs->end()) return; + cs->insert(crc); if (fp) { - fputs(ref,fp); + fputs(reference.c_str(),fp); fflush(fp); } @@ -93,7 +100,6 @@ void CiteMe::add(const char *ref) if (logfile_flag == VERBOSE) logbuffer += "\n"; } - std::string reference = ref; std::size_t found = reference.find_first_of("\n"); std::string header = reference.substr(0,found+1); if (screen_flag == VERBOSE) scrbuffer += "- " + reference; diff --git a/src/citeme.h b/src/citeme.h index dd54268a3b..df87f1f9e5 100644 --- a/src/citeme.h +++ b/src/citeme.h @@ -23,8 +23,8 @@ class CiteMe : protected Pointers { public: CiteMe(class LAMMPS *, int, int, const char *); virtual ~CiteMe(); - void add(const char *); // register publication for output - void flush(); // flush buffers to screen and logfile + void add(const std::string &); // register publication for output + void flush(); // flush buffers to screen and logfile enum {VERBOSE, TERSE}; private: @@ -34,7 +34,7 @@ class CiteMe : protected Pointers { int logfile_flag; // determine whether verbose or terse output std::string scrbuffer; // output buffer for screen std::string logbuffer; // output buffer for logfile - typedef std::set citeset; + typedef std::set citeset; citeset *cs; // registered set of publications }; } diff --git a/unittest/commands/test_simple_commands.cpp b/unittest/commands/test_simple_commands.cpp index 644f7071ad..4fce58c668 100644 --- a/unittest/commands/test_simple_commands.cpp +++ b/unittest/commands/test_simple_commands.cpp @@ -13,6 +13,7 @@ #include "lammps.h" +#include "citeme.h" #include "force.h" #include "info.h" #include "input.h" @@ -368,6 +369,51 @@ TEST_F(SimpleCommandsTest, Shell) ASSERT_THAT(other_var, StrEq("2")); } +TEST_F(SimpleCommandsTest, CiteMe) +{ + ASSERT_EQ(lmp->citeme, nullptr); + + lmp->citeme = new LAMMPS_NS::CiteMe(lmp, CiteMe::TERSE, CiteMe::TERSE, nullptr); + + ::testing::internal::CaptureStdout(); + lmp->citeme->add("test citation one:\n 1\n"); + lmp->citeme->add("test citation two:\n 2\n"); + lmp->citeme->add("test citation one:\n 1\n"); + lmp->citeme->flush(); + std::string text = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << text; + + // find the two unique citations, but not the third + ASSERT_THAT(text, MatchesRegex(".*one.*two.*")); + ASSERT_THAT(text, Not(MatchesRegex(".*one.*two.*one.*"))); + + ::testing::internal::CaptureStdout(); + lmp->citeme->add("test citation one:\n 0\n"); + lmp->citeme->add("test citation two:\n 2\n"); + lmp->citeme->add("test citation three:\n 3\n"); + lmp->citeme->flush(); + + text = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << text; + + // find the forth (only differs in long citation) and sixth added citation + ASSERT_THAT(text, MatchesRegex(".*one.*three.*")); + ASSERT_THAT(text, Not(MatchesRegex(".*two.*"))); + + ::testing::internal::CaptureStdout(); + lmp->citeme->add("test citation one:\n 1\n"); + lmp->citeme->add("test citation two:\n 2\n"); + lmp->citeme->add("test citation one:\n 0\n"); + lmp->citeme->add("test citation two:\n 2\n"); + lmp->citeme->add("test citation three:\n 3\n"); + lmp->citeme->flush(); + + text = ::testing::internal::GetCapturedStdout(); + if (verbose) std::cout << text; + + // no new citation. no CITE-CITE-CITE- lines + ASSERT_THAT(text, Not(MatchesRegex(".*CITE-CITE-CITE-CITE.*"))); +} } // namespace LAMMPS_NS int main(int argc, char **argv)