From 25768c6b8049663baefcc7fd43a02d56a159ee8d Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Tue, 12 Jan 2021 03:35:55 +0100 Subject: [PATCH 1/4] Handle "rest" arguments the glib way Ensures the "stop parsing" token (--) is handled properly. --- src/sdcv.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/sdcv.cpp b/src/sdcv.cpp index ca222b8..3d21156 100644 --- a/src/sdcv.cpp +++ b/src/sdcv.cpp @@ -83,6 +83,7 @@ try { glib::CharStr opt_data_dir; gboolean only_data_dir = FALSE; gboolean colorize = FALSE; + glib::StrArr word_list; const GOptionEntry entries[] = { { "version", 'v', 0, G_OPTION_ARG_NONE, &show_version, @@ -109,11 +110,13 @@ try { _("only use the dictionaries in data-dir, do not search in user and system directories"), nullptr }, { "color", 'c', 0, G_OPTION_ARG_NONE, &colorize, _("colorize the output"), nullptr }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, get_addr(word_list), + _("search terms"), _(" words") }, {}, }; glib::Error error; - GOptionContext *context = g_option_context_new(_(" words")); + GOptionContext *context = g_option_context_new(nullptr); g_option_context_set_help_enabled(context, TRUE); g_option_context_add_main_entries(context, entries, nullptr); const gboolean parse_res = g_option_context_parse(context, &argc, &argv, get_addr(error)); @@ -210,12 +213,14 @@ try { lib.load(dicts_dir_list, order_list, disable_list); std::unique_ptr io(create_readline_object()); - if (optind < argc) { + if (word_list != nullptr) { search_result rval = SEARCH_SUCCESS; - for (int i = optind; i < argc; ++i) - if ((rval = lib.process_phrase(argv[i], *io, non_interactive)) != SEARCH_SUCCESS) { + gchar **p = get_impl(word_list); + while (*p) { + if ((rval = lib.process_phrase(*p++, *io, non_interactive)) != SEARCH_SUCCESS) { return rval; } + } } else if (!non_interactive) { std::string phrase; From 8f096629ec00a9b4eb8fea3a3a0e5710256bd052 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Tue, 12 Jan 2021 04:16:03 +0100 Subject: [PATCH 2/4] Unbreak tests glib already runs the argument through g_locale_to_utf8 with G_OPTION_REMAINING --- src/libwrapper.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libwrapper.cpp b/src/libwrapper.cpp index f900edc..0cd047c 100644 --- a/src/libwrapper.cpp +++ b/src/libwrapper.cpp @@ -332,10 +332,17 @@ search_result Library::process_phrase(const char *loc_str, IReadLine &io, bool f glib::Error err; search_result rval = SEARCH_SUCCESS; glib::CharStr str; - if (!utf8_input_) - str.reset(g_locale_to_utf8(loc_str, -1, &bytes_read, &bytes_written, get_addr(err))); - else + // Glib already runs CLI arguments through g_locale_to_utf8 + if (g_get_charset(nullptr)) { + // Current locale is UTF-8 str.reset(g_strdup(loc_str)); + } else { + if (!utf8_input_) { + str.reset(g_strdup(loc_str)); + } else { + str.reset(g_locale_from_utf8(loc_str, -1, &bytes_read, &bytes_written, get_addr(err))); + } + } if (nullptr == get_impl(str)) { fprintf(stderr, _("Can not convert %s to utf8.\n"), loc_str); From 070a9fb0bd6f78f63776b2fa27d9b8612f7f8bbb Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Tue, 12 Jan 2021 04:37:07 +0100 Subject: [PATCH 3/4] Oh, well, dirty hackery it is, then. the previous approachonly works as long as locales are actually sane (i.e., the test only passes if you *actually* have the ru_RU.KOI8-R locale built, which the CI doesn't). --- src/libwrapper.cpp | 13 +++---------- src/sdcv.cpp | 16 ++++++++-------- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/src/libwrapper.cpp b/src/libwrapper.cpp index 0cd047c..f900edc 100644 --- a/src/libwrapper.cpp +++ b/src/libwrapper.cpp @@ -332,17 +332,10 @@ search_result Library::process_phrase(const char *loc_str, IReadLine &io, bool f glib::Error err; search_result rval = SEARCH_SUCCESS; glib::CharStr str; - // Glib already runs CLI arguments through g_locale_to_utf8 - if (g_get_charset(nullptr)) { - // Current locale is UTF-8 + if (!utf8_input_) + str.reset(g_locale_to_utf8(loc_str, -1, &bytes_read, &bytes_written, get_addr(err))); + else str.reset(g_strdup(loc_str)); - } else { - if (!utf8_input_) { - str.reset(g_strdup(loc_str)); - } else { - str.reset(g_locale_from_utf8(loc_str, -1, &bytes_read, &bytes_written, get_addr(err))); - } - } if (nullptr == get_impl(str)) { fprintf(stderr, _("Can not convert %s to utf8.\n"), loc_str); diff --git a/src/sdcv.cpp b/src/sdcv.cpp index 3d21156..77de38b 100644 --- a/src/sdcv.cpp +++ b/src/sdcv.cpp @@ -83,7 +83,6 @@ try { glib::CharStr opt_data_dir; gboolean only_data_dir = FALSE; gboolean colorize = FALSE; - glib::StrArr word_list; const GOptionEntry entries[] = { { "version", 'v', 0, G_OPTION_ARG_NONE, &show_version, @@ -110,13 +109,11 @@ try { _("only use the dictionaries in data-dir, do not search in user and system directories"), nullptr }, { "color", 'c', 0, G_OPTION_ARG_NONE, &colorize, _("colorize the output"), nullptr }, - { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, get_addr(word_list), - _("search terms"), _(" words") }, {}, }; glib::Error error; - GOptionContext *context = g_option_context_new(nullptr); + GOptionContext *context = g_option_context_new(_(" words")); g_option_context_set_help_enabled(context, TRUE); g_option_context_add_main_entries(context, entries, nullptr); const gboolean parse_res = g_option_context_parse(context, &argc, &argv, get_addr(error)); @@ -213,11 +210,14 @@ try { lib.load(dicts_dir_list, order_list, disable_list); std::unique_ptr io(create_readline_object()); - if (word_list != nullptr) { + if (argc > 1) { search_result rval = SEARCH_SUCCESS; - gchar **p = get_impl(word_list); - while (*p) { - if ((rval = lib.process_phrase(*p++, *io, non_interactive)) != SEARCH_SUCCESS) { + for (int i = 1; i < argc; i++) { + // Skip the GNU "stop option parsing" token ("--"), because glib won't do it for us without G_OPTION_REMAINING + if (strcmp(argv[i], "--") == 0) { + continue; + } + if ((rval = lib.process_phrase(argv[i], *io, non_interactive)) != SEARCH_SUCCESS) { return rval; } } From 3b26731b0277d595c6308432133a123acfd91dd6 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Thu, 14 Jan 2021 19:26:06 +0100 Subject: [PATCH 4/4] Making glib thinks it's a filename instead of a string prevents the initial UTF-8 conversion At least on POSIX. Windows is another kettle of fish. But then it was probably already broken there. --- src/sdcv.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/sdcv.cpp b/src/sdcv.cpp index 77de38b..60a21ad 100644 --- a/src/sdcv.cpp +++ b/src/sdcv.cpp @@ -83,6 +83,7 @@ try { glib::CharStr opt_data_dir; gboolean only_data_dir = FALSE; gboolean colorize = FALSE; + glib::StrArr word_list; const GOptionEntry entries[] = { { "version", 'v', 0, G_OPTION_ARG_NONE, &show_version, @@ -109,11 +110,13 @@ try { _("only use the dictionaries in data-dir, do not search in user and system directories"), nullptr }, { "color", 'c', 0, G_OPTION_ARG_NONE, &colorize, _("colorize the output"), nullptr }, + { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, get_addr(word_list), + _("search terms"), _(" words") }, {}, }; glib::Error error; - GOptionContext *context = g_option_context_new(_(" words")); + GOptionContext *context = g_option_context_new(nullptr); g_option_context_set_help_enabled(context, TRUE); g_option_context_add_main_entries(context, entries, nullptr); const gboolean parse_res = g_option_context_parse(context, &argc, &argv, get_addr(error)); @@ -210,14 +213,11 @@ try { lib.load(dicts_dir_list, order_list, disable_list); std::unique_ptr io(create_readline_object()); - if (argc > 1) { + if (word_list != nullptr) { search_result rval = SEARCH_SUCCESS; - for (int i = 1; i < argc; i++) { - // Skip the GNU "stop option parsing" token ("--"), because glib won't do it for us without G_OPTION_REMAINING - if (strcmp(argv[i], "--") == 0) { - continue; - } - if ((rval = lib.process_phrase(argv[i], *io, non_interactive)) != SEARCH_SUCCESS) { + gchar **p = get_impl(word_list); + while (*p) { + if ((rval = lib.process_phrase(*p++, *io, non_interactive)) != SEARCH_SUCCESS) { return rval; } }