Add -e for exact searches (no fuzzy matches).

Only exact matches (or synonyms) are returned for simple searches.
This commit is contained in:
Peter
2017-07-28 11:27:19 +02:00
parent 586215fda7
commit e85927e562
11 changed files with 43 additions and 6 deletions

View File

@@ -147,6 +147,7 @@ if (BUILD_TESTS)
add_sdcv_shell_test(t_only_data_dir) add_sdcv_shell_test(t_only_data_dir)
add_sdcv_shell_test(t_synonyms) add_sdcv_shell_test(t_synonyms)
add_sdcv_shell_test(t_json) add_sdcv_shell_test(t_json)
add_sdcv_shell_test(t_exact)
add_sdcv_shell_test(t_interactive) add_sdcv_shell_test(t_interactive)
add_sdcv_shell_test(t_utf8output) add_sdcv_shell_test(t_utf8output)
add_sdcv_shell_test(t_utf8input) add_sdcv_shell_test(t_utf8input)

View File

@@ -350,7 +350,7 @@ bool Library::process_phrase(const char *loc_str, IReadLine &io, bool force)
break; break;
case qtSIMPLE: case qtSIMPLE:
SimpleLookup(get_impl(str), res_list); SimpleLookup(get_impl(str), res_list);
if (res_list.empty()) if (res_list.empty() && fuzzy_)
LookupWithFuzzy(get_impl(str), res_list); LookupWithFuzzy(get_impl(str), res_list);
break; break;
case qtDATA: case qtDATA:

View File

@@ -25,9 +25,10 @@ typedef std::vector<TSearchResult> TSearchResultList;
//of it //of it
class Library : public Libs { class Library : public Libs {
public: public:
Library(bool uinput, bool uoutput, bool colorize_output, bool use_json) Library(bool uinput, bool uoutput, bool colorize_output, bool use_json, bool no_fuzzy)
: utf8_input_(uinput), utf8_output_(uoutput), colorize_output_(colorize_output), json_(use_json) { : utf8_input_(uinput), utf8_output_(uoutput), colorize_output_(colorize_output), json_(use_json) {
setVerbose(!use_json); setVerbose(!use_json);
setFuzzy(!no_fuzzy);
} }
bool process_phrase(const char *loc_str, IReadLine &io, bool force = false); bool process_phrase(const char *loc_str, IReadLine &io, bool force = false);

View File

@@ -76,6 +76,7 @@ int main(int argc, char *argv[]) try {
glib::StrArr use_dict_list; glib::StrArr use_dict_list;
gboolean non_interactive = FALSE; gboolean non_interactive = FALSE;
gboolean json_output = FALSE; gboolean json_output = FALSE;
gboolean no_fuzzy = FALSE;
gboolean utf8_output = FALSE; gboolean utf8_output = FALSE;
gboolean utf8_input = FALSE; gboolean utf8_input = FALSE;
glib::CharStr opt_data_dir; glib::CharStr opt_data_dir;
@@ -94,6 +95,8 @@ int main(int argc, char *argv[]) try {
_("for use in scripts"), nullptr }, _("for use in scripts"), nullptr },
{ "json-output", 'j', 0, G_OPTION_ARG_NONE, &json_output, { "json-output", 'j', 0, G_OPTION_ARG_NONE, &json_output,
_("print the result formatted as JSON."), nullptr }, _("print the result formatted as JSON."), nullptr },
{ "exact-search", 'e', 0, G_OPTION_ARG_NONE, &no_fuzzy,
_("do not fuzzy-search for similar words, only return exact matches."), nullptr },
{ "utf8-output", '0', 0, G_OPTION_ARG_NONE, &utf8_output, { "utf8-output", '0', 0, G_OPTION_ARG_NONE, &utf8_output,
_("output must be in utf8"), nullptr }, _("output must be in utf8"), nullptr },
{ "utf8-input", '1', 0, G_OPTION_ARG_NONE, &utf8_input, { "utf8-input", '1', 0, G_OPTION_ARG_NONE, &utf8_input,
@@ -199,7 +202,7 @@ int main(int argc, char *argv[]) try {
fprintf(stderr, _("g_mkdir failed: %s\n"), strerror(errno)); fprintf(stderr, _("g_mkdir failed: %s\n"), strerror(errno));
} }
Library lib(utf8_input, utf8_output, colorize, json_output); Library lib(utf8_input, utf8_output, colorize, json_output, no_fuzzy);
lib.load(dicts_dir_list, order_list, disable_list); lib.load(dicts_dir_list, order_list, disable_list);
std::unique_ptr<IReadLine> io(create_readline_object()); std::unique_ptr<IReadLine> io(create_readline_object());

View File

@@ -1404,7 +1404,7 @@ bool Libs::LookupSimilarWord(const gchar* sWord, glong & iWordIndex, int iLib)
bool Libs::SimpleLookupWord(const gchar* sWord, glong & iWordIndex, int iLib) bool Libs::SimpleLookupWord(const gchar* sWord, glong & iWordIndex, int iLib)
{ {
bool bFound = oLib[iLib]->Lookup(sWord, iWordIndex); bool bFound = oLib[iLib]->Lookup(sWord, iWordIndex);
if (!bFound) if (!bFound && fuzzy_)
bFound = LookupSimilarWord(sWord, iWordIndex, iLib); bFound = LookupSimilarWord(sWord, iWordIndex, iLib);
return bFound; return bFound;
} }

View File

@@ -145,6 +145,7 @@ public:
iMaxFuzzyDistance = MAX_FUZZY_DISTANCE; //need to read from cfg. iMaxFuzzyDistance = MAX_FUZZY_DISTANCE; //need to read from cfg.
} }
void setVerbose(bool verbose) { verbose_ = verbose; } void setVerbose(bool verbose) { verbose_ = verbose; }
void setFuzzy(bool fuzzy) { fuzzy_ = fuzzy; }
~Libs(); ~Libs();
Libs(const Libs&) = delete; Libs(const Libs&) = delete;
Libs& operator=(const Libs&) = delete; Libs& operator=(const Libs&) = delete;
@@ -178,6 +179,8 @@ public:
bool LookupWithFuzzy(const gchar *sWord, gchar *reslist[], gint reslist_size); bool LookupWithFuzzy(const gchar *sWord, gchar *reslist[], gint reslist_size);
gint LookupWithRule(const gchar *sWord, gchar *reslist[]); gint LookupWithRule(const gchar *sWord, gchar *reslist[]);
bool LookupData(const gchar *sWord, std::vector<gchar *> *reslist); bool LookupData(const gchar *sWord, std::vector<gchar *> *reslist);
protected:
bool fuzzy_;
private: private:
std::vector<Dict *> oLib; // word Libs. std::vector<Dict *> oLib; // word Libs.
int iMaxFuzzyDistance; int iMaxFuzzyDistance;

View File

@@ -1,7 +1,7 @@
StarDict's dict ifo file StarDict's dict ifo file
version=2.4.2 version=2.4.2
bookname=Test synonyms bookname=Test synonyms
wordcount=1 wordcount=2
synwordcount=2 synwordcount=2
idxfilesize=13 idxfilesize=32
sametypesequence=m sametypesequence=m

View File

@@ -15,4 +15,9 @@
<![CDATA[result of test]]> <![CDATA[result of test]]>
</definition> </definition>
</article> </article>
<article><key>testawordy</key>
<definition type="m">
<![CDATA[word that ends in y to test with fuzzy search in -ied]]>
</definition>
</article>
</stardict> </stardict>

24
tests/t_exact Executable file
View File

@@ -0,0 +1,24 @@
#!/bin/sh
set -e
SDCV="$1"
TEST_DIR="$2"
unset SDCV_PAGER
test_word() {
WORD=$1
EXPECTED=$2
TAG=$3
RES=$($SDCV -e -n --data-dir "$TEST_DIR" -u "Test synonyms" $WORD | grep "$TAG")
if [ "$EXPECTED" != "$RES" ]; then
echo "synonym for $WORD should be '$EXPECTED' but was '$RES'"
exit 1
fi
}
test_word testawordies "Nothing similar to testawordies, sorry :(" "Nothing similar"
test_word testawordy "word that ends in y to test with fuzzy search in -ied" "fuzzy"
exit 0