From 766b82d71b6aeffb8f5ad4fd97ed76d78685b65d Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Sat, 2 Nov 2013 07:52:45 -0700 Subject: [PATCH] Fix some edge-cases in the thesarus code Handle missing parts-of-speach and trailing pipes on lines. --- aegisub/libaegisub/common/thesaurus.cpp | 44 ++++++++++++------- .../libaegisub/include/libaegisub/thesaurus.h | 5 +-- aegisub/src/subs_edit_ctrl.cpp | 5 +-- aegisub/src/thesaurus.cpp | 6 +-- aegisub/src/thesaurus.h | 3 +- 5 files changed, 37 insertions(+), 26 deletions(-) diff --git a/aegisub/libaegisub/common/thesaurus.cpp b/aegisub/libaegisub/common/thesaurus.cpp index 0c66368c5..8767eb83d 100644 --- a/aegisub/libaegisub/common/thesaurus.cpp +++ b/aegisub/libaegisub/common/thesaurus.cpp @@ -55,15 +55,15 @@ Thesaurus::Thesaurus(agi::fs::path const& dat_path, agi::fs::path const& idx_pat Thesaurus::~Thesaurus() { } -void Thesaurus::Lookup(std::string const& word, std::vector *out) { - out->clear(); - if (!dat.get()) return; +std::vector Thesaurus::Lookup(std::string const& word) { + std::vector out; + if (!dat.get()) return out; - std::map::const_iterator it = offsets.find(word); - if (it == offsets.end()) return; + auto it = offsets.find(word); + if (it == offsets.end()) return out; dat->seekg(it->second, std::ios::beg); - if (!dat->good()) return; + if (!dat->good()) return out; // First line is the word and meaning count std::string temp; @@ -71,22 +71,36 @@ void Thesaurus::Lookup(std::string const& word, std::vector *out) { std::vector header; std::string converted(conv->Convert(temp)); boost::split(header, converted, _1 == '|'); - if (header.size() != 2) return; + if (header.size() != 2) return out; int meanings = atoi(header[1].c_str()); - out->resize(meanings); + out.reserve(meanings); for (int i = 0; i < meanings; ++i) { - std::vector line; getline(*dat, temp); - std::string converted(conv->Convert(temp)); + auto converted = conv->Convert(temp); + std::vector line; boost::split(line, converted, _1 == '|'); - // The "definition" is just the part of speech plus the word it's - // giving synonyms for (which may not be the passed word) - (*out)[i].first = line[0] + ' ' + line[1]; - (*out)[i].second.reserve(line.size() - 2); - copy(line.begin() + 2, line.end(), back_inserter((*out)[i].second)); + if (line.size() < 2) + continue; + + Entry e; + // The "definition" is just the part of speech (which may be empty) + // plus the word it's giving synonyms for (which may not be the passed word) + if (!line[0].empty()) + e.first = line[0] + ' '; + e.first += line[1]; + e.second.reserve(line.size() - 2); + + for (size_t i = 2; i < line.size(); ++i) { + if (line[i].size()) + e.second.emplace_back(std::move(line[i])); + } + + out.emplace_back(std::move(e)); } + + return out; } } diff --git a/aegisub/libaegisub/include/libaegisub/thesaurus.h b/aegisub/libaegisub/include/libaegisub/thesaurus.h index 88b2c4360..5bdded31e 100644 --- a/aegisub/libaegisub/include/libaegisub/thesaurus.h +++ b/aegisub/libaegisub/include/libaegisub/thesaurus.h @@ -38,7 +38,7 @@ class Thesaurus { public: /// A pair of a word and synonyms for that word - typedef std::pair > Entry; + typedef std::pair> Entry; /// Constructor /// @param dat_path Path to data file @@ -48,8 +48,7 @@ public: /// Look up synonyms for a word /// @param word Word to look up - /// @param[out] out Vector to fill with word/synonym lists - void Lookup(std::string const& word, std::vector *out); + std::vector Lookup(std::string const& word); }; } diff --git a/aegisub/src/subs_edit_ctrl.cpp b/aegisub/src/subs_edit_ctrl.cpp index aeae928ba..196c1720f 100644 --- a/aegisub/src/subs_edit_ctrl.cpp +++ b/aegisub/src/subs_edit_ctrl.cpp @@ -387,8 +387,7 @@ void SubsTextEditCtrl::AddThesaurusEntries(wxMenu &menu) { if (!thesaurus) thesaurus = agi::util::make_unique(); - std::vector results; - thesaurus->Lookup(currentWord, &results); + auto results = thesaurus->Lookup(currentWord); thesSugs.clear(); @@ -398,7 +397,7 @@ void SubsTextEditCtrl::AddThesaurusEntries(wxMenu &menu) { int curThesEntry = 0; for (auto const& result : results) { // Single word, insert directly - if (result.second.size() == 1) { + if (result.second.empty()) { thesMenu->Append(EDIT_MENU_THESAURUS_SUGS+curThesEntry, to_wx(result.first)); thesSugs.push_back(result.first); ++curThesEntry; diff --git a/aegisub/src/thesaurus.cpp b/aegisub/src/thesaurus.cpp index fe5c9d1e0..72ea78b57 100644 --- a/aegisub/src/thesaurus.cpp +++ b/aegisub/src/thesaurus.cpp @@ -44,10 +44,10 @@ Thesaurus::~Thesaurus() { // Explicit empty destructor needed for scoped_ptr with incomplete types } -void Thesaurus::Lookup(std::string word, std::vector *result) { - if (!impl.get()) return; +std::vector Thesaurus::Lookup(std::string word) { + if (!impl.get()) return std::vector(); boost::to_lower(word); - impl->Lookup(word, result); + return impl->Lookup(word); } std::vector Thesaurus::GetLanguageList() const { diff --git a/aegisub/src/thesaurus.h b/aegisub/src/thesaurus.h index 84dc91cee..4485c5daa 100644 --- a/aegisub/src/thesaurus.h +++ b/aegisub/src/thesaurus.h @@ -53,8 +53,7 @@ public: /// Get a list of synonyms for a word, grouped by possible meanings of the word /// @param word Word to get synonyms for - /// @param[out] result Output list - void Lookup(std::string word, std::vector *result); + std::vector Lookup(std::string word); /// Get a list of language codes which thesauri are available for std::vector GetLanguageList() const;