From f96e90ef35f2810b8b56868468d683c8f9290b1f Mon Sep 17 00:00:00 2001 From: Marco Trevisan (Treviño) Date: Feb 23 2018 05:02:24 +0000 Subject: [PATCH 1/11] locate: add --transliterate support using iconv to match accented When enabled all search parameters and paths are transliterated and used for matching. --- diff --git a/AUTHORS b/AUTHORS index ade5106..8457862 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1 +1,2 @@ Miloslav Trmac +Marco Trevisan diff --git a/configure.ac b/configure.ac index 2c587ad..162f55c 100644 --- a/configure.ac +++ b/configure.ac @@ -39,6 +39,15 @@ gl_INIT AM_GNU_GETTEXT([external], [need-ngettext]) AM_GNU_GETTEXT_VERSION([0.18.2]) +AC_ARG_ENABLE(iconv, + AC_HELP_STRING([--disable-iconv], + [disable iconv support]),, + enable_iconv=yes) + +if test x$enable_iconv = xyes; then + AM_ICONV +fi + # Checks for header files. # Checks for types. diff --git a/src/locate.c b/src/locate.c index 87f2c15..f7ca9d6 100644 --- a/src/locate.c +++ b/src/locate.c @@ -22,6 +22,10 @@ Author: Miloslav Trmac */ #include #include #include +#if HAVE_ICONV +#include +#include +#endif #include #include #include @@ -60,6 +64,9 @@ static struct string_list conf_dbpath; /* = { 0, }; */ /* Ignore case when matching patterns */ static bool conf_ignore_case; /* = false; */ +/* Ignore accents when matching patterns */ +static bool conf_transliterate; /* = false; */ + /* Return only files that match all patterns */ static bool conf_match_all_patterns; /* = false; */ @@ -108,6 +115,11 @@ static bool conf_quiet; /* = false; */ /* Output only statistics */ static bool conf_statistics; /* = false; */ +#if HAVE_ICONV +/* Iconv context for transliterate conversion */ +static iconv_t iconv_context; /* = NULL; */ +#endif + /* String utilities */ /* Convert SRC to upper-case wide string in OBSTACK; @@ -163,6 +175,34 @@ uppercase_string (struct obstack *obstack, const char *src) return res; } +#if HAVE_ICONV +static char * +transliterate_string (const char *str) +{ + size_t len; + size_t retlen; + size_t outlen; + char *inbuf; + char *outptr; + char outbuf[PATH_MAX * 2]; + + inbuf = (char *) str; + outptr = outbuf; + len = strlen (str); + + outlen = sizeof (outbuf) - 1; + retlen = iconv (iconv_context, &inbuf, &len, &outptr, &outlen); + + if (retlen == (size_t) -1) + { + error (0, errno, _("Impossible to transliterate string %s"), str); + return NULL; + } + + return strndup (outbuf, sizeof (outbuf) - 1 - outlen); +} +#endif + /* Write STRING to stdout, replace unprintable characters with '?' */ static void write_quoted (const char *string) @@ -418,6 +458,7 @@ static int handle_path (const char *path, int *visible) { const char *s, *matching; + char *transliterated = NULL; /* Statistics */ if (conf_statistics != false) @@ -431,8 +472,17 @@ handle_path (const char *path, int *visible) matching = s + 1; else matching = path; +#if HAVE_ICONV + if (conf_transliterate != false) + { + transliterated = transliterate_string (matching); + matching = transliterated; + } +#endif if (!string_matches_pattern (matching)) goto done; + free(transliterated); + transliterated = NULL; /* Visible? */ if (*visible == -1) *visible = check_directory_perms (path) == 0; @@ -458,6 +508,7 @@ handle_path (const char *path, int *visible) if (conf_output_limit_set != false && matches_found == conf_output_limit) return -1; done: + free(transliterated); return 0; } @@ -632,6 +683,10 @@ help (void) " -h, --help print this help\n" " -i, --ignore-case ignore case distinctions when matching " "patterns\n" +#if HAVE_ICONV + " -t, --transliterate ignore accents using iconv " + "transliteration when matching patterns\n" +#endif " -l, --limit, -n LIMIT limit output (or counting) to LIMIT " "entries\n" " -m, --mmap ignored, for backward compatibility\n" @@ -669,6 +724,7 @@ parse_options (int argc, char *argv[]) { "follow", no_argument, NULL, 'L' }, { "help", no_argument, NULL, 'h' }, { "ignore-case", no_argument, NULL, 'i' }, + { "transliterate", no_argument, NULL, 't' }, { "limit", required_argument, NULL, 'l' }, { "mmap", no_argument, NULL, 'm' }, { "quiet", no_argument, NULL, 'q' }, @@ -691,7 +747,7 @@ parse_options (int argc, char *argv[]) { int opt, idx; - opt = getopt_long (argc, argv, "0AHPLSVbcd:ehil:mn:qr:sw", options, &idx); + opt = getopt_long (argc, argv, "0AHPLSVbcd:ehitl:mn:qr:sw", options, &idx); switch (opt) { case -1: @@ -772,6 +828,10 @@ parse_options (int argc, char *argv[]) conf_ignore_case = true; break; + case 't': + conf_transliterate = true; + break; + case 'l': case 'n': { char *end; @@ -822,6 +882,19 @@ parse_options (int argc, char *argv[]) error (EXIT_FAILURE, 0, _("non-option arguments are not allowed with --%s"), conf_statistics != false ? "statistics" : "regexp"); + if (conf_transliterate != false) + { +#if HAVE_ICONV + iconv_context = iconv_open ("ASCII//TRANSLIT", nl_langinfo (CODESET)); + if (iconv_context == (iconv_t) -1) + error (EXIT_FAILURE, errno, _("can not do transliteration between " \ + "these locales: `%s' and `ASCII'"), + nl_langinfo (CODESET)); +#else + error (EXIT_FAILURE, errno, _("transliteration support is not supported" \ + "by this build of %s"), program_name); +#endif + } } /* Parse arguments in ARGC, ARGV. Exit on error. */ @@ -836,6 +909,13 @@ parse_arguments (int argc, char *argv[]) error (EXIT_FAILURE, 0, _("no pattern to search for specified")); conf_patterns.entries = xnrealloc (conf_patterns.entries, conf_patterns.len, sizeof (*conf_patterns.entries)); +#if HAVE_ICONV + if (conf_transliterate != false) + { + for (i = 0; i < conf_patterns.len; i++) + conf_patterns.entries[i] = transliterate_string (conf_patterns.entries[i]); + } +#endif if (conf_match_regexp != false) { int cflags; @@ -1042,6 +1122,10 @@ main (int argc, char *argv[]) handle_dbpath_entry (conf_dbpath.entries[i]); } done: +#if HAVE_ICONV + if (conf_transliterate != false && iconv_context) + iconv_close (iconv_context); +#endif if (conf_output_count != false) printf ("%ju\n", matches_found); if (conf_statistics != false || matches_found != 0) From 11a579c1ebbd88d61790ea16698bcf338706cbfe Mon Sep 17 00:00:00 2001 From: Marco Trevisan (Treviño) Date: Feb 23 2018 05:02:33 +0000 Subject: [PATCH 2/11] doc: add -t / --transliterate to man page --- diff --git a/doc/locate.1.in b/doc/locate.1.in index b8d2826..9c2e629 100644 --- a/doc/locate.1.in +++ b/doc/locate.1.in @@ -126,6 +126,10 @@ and exit successfully. Ignore case distinctions when matching patterns. .TP +\fB\-t\fR, \fB\-\-transliterate\fR +Ignore accents using iconv transliteration when matching patterns. + +.TP \fB\-l\fR, \fB\-\-limit\fR, \fB\-n\fR \fILIMIT\fR Exit successfully after finding .I LIMIT @@ -267,4 +271,5 @@ but it is added to other databases in this implementation and \fBslocate\fR. Miloslav Trmac .SH SEE ALSO -.BR updatedb (8) +.BR updatedb (8), +.BR iconv (1), From c84e4a786e07f518710aed135349df82b11313fa Mon Sep 17 00:00:00 2001 From: Marco Trevisan (Treviño) Date: Feb 23 2018 05:06:57 +0000 Subject: [PATCH 3/11] locate: only add and check transliterated patterns if needed There's no need to check transliterated strings all the times if the targets don't need transliteration. --- diff --git a/src/locate.c b/src/locate.c index f7ca9d6..ecd26bf 100644 --- a/src/locate.c +++ b/src/locate.c @@ -199,6 +199,9 @@ transliterate_string (const char *str) return NULL; } + if (retlen == 0) + return NULL; + return strndup (outbuf, sizeof (outbuf) - 1 - outlen); } #endif @@ -458,7 +461,6 @@ static int handle_path (const char *path, int *visible) { const char *s, *matching; - char *transliterated = NULL; /* Statistics */ if (conf_statistics != false) @@ -472,17 +474,29 @@ handle_path (const char *path, int *visible) matching = s + 1; else matching = path; -#if HAVE_ICONV - if (conf_transliterate != false) + if (!string_matches_pattern (matching)) +#if !HAVE_ICONV + goto done; +#else { - transliterated = transliterate_string (matching); - matching = transliterated; + bool matched; + + matched = false; + if (conf_transliterate != false) + { + char *transliterated; + + transliterated = transliterate_string (matching); + if (transliterated) + { + matched = string_matches_pattern (transliterated); + free (transliterated); + } + } + if (!matched) + goto done; } #endif - if (!string_matches_pattern (matching)) - goto done; - free(transliterated); - transliterated = NULL; /* Visible? */ if (*visible == -1) *visible = check_directory_perms (path) == 0; @@ -508,7 +522,6 @@ handle_path (const char *path, int *visible) if (conf_output_limit_set != false && matches_found == conf_output_limit) return -1; done: - free(transliterated); return 0; } @@ -907,15 +920,23 @@ parse_arguments (int argc, char *argv[]) string_list_append (&conf_patterns, argv[i]); if (conf_statistics == false && conf_patterns.len == 0) error (EXIT_FAILURE, 0, _("no pattern to search for specified")); - conf_patterns.entries = xnrealloc (conf_patterns.entries, conf_patterns.len, - sizeof (*conf_patterns.entries)); #if HAVE_ICONV if (conf_transliterate != false) { - for (i = 0; i < conf_patterns.len; i++) - conf_patterns.entries[i] = transliterate_string (conf_patterns.entries[i]); + size_t patterns_len = conf_patterns.len; + char *transliterated; + + for (i = 0; i < patterns_len; i++) + { + transliterated = transliterate_string (conf_patterns.entries[i]); + + if (transliterated) + string_list_append (&conf_patterns, transliterated); + } } #endif + conf_patterns.entries = xnrealloc (conf_patterns.entries, conf_patterns.len, + sizeof (*conf_patterns.entries)); if (conf_match_regexp != false) { int cflags; From 20454fab283dbfc37ed245d0739656db0f549bc5 Mon Sep 17 00:00:00 2001 From: Marco Trevisan (Treviño) Date: Feb 23 2018 05:07:05 +0000 Subject: [PATCH 4/11] locate: ignore transliterated strings only with replacement chars --- diff --git a/src/locate.c b/src/locate.c index ecd26bf..0775773 100644 --- a/src/locate.c +++ b/src/locate.c @@ -180,8 +180,10 @@ static char * transliterate_string (const char *str) { size_t len; - size_t retlen; + size_t conversions; size_t outlen; + size_t transliterated_len; + size_t i; char *inbuf; char *outptr; char outbuf[PATH_MAX * 2]; @@ -191,18 +193,27 @@ transliterate_string (const char *str) len = strlen (str); outlen = sizeof (outbuf) - 1; - retlen = iconv (iconv_context, &inbuf, &len, &outptr, &outlen); + conversions = iconv (iconv_context, &inbuf, &len, &outptr, &outlen); + transliterated_len = sizeof (outbuf) - 1 - outlen; - if (retlen == (size_t) -1) + if (conversions == (size_t) -1) { error (0, errno, _("Impossible to transliterate string %s"), str); return NULL; } - if (retlen == 0) - return NULL; + if (transliterated_len == conversions) + { + bool found_valid = false; + + for (i = 0; i < transliterated_len && !found_valid; ++i) + found_valid = outbuf[i] != '?'; + + if (!found_valid) + return NULL; + } - return strndup (outbuf, sizeof (outbuf) - 1 - outlen); + return strndup (outbuf, transliterated_len); } #endif From 89d267c6a25c06535b8431e40fc9b28ca5ec025e Mon Sep 17 00:00:00 2001 From: Marco Trevisan (Treviño) Date: Feb 23 2018 05:07:05 +0000 Subject: [PATCH 5/11] locate: transliterate strings by char and do it on valid results only To avoid false positives and not to break regex (in advanced mode when a '?' is present, we had to escape it otherwise). --- diff --git a/src/locate.c b/src/locate.c index 0775773..29f046e 100644 --- a/src/locate.c +++ b/src/locate.c @@ -179,41 +179,63 @@ uppercase_string (struct obstack *obstack, const char *src) static char * transliterate_string (const char *str) { - size_t len; - size_t conversions; - size_t outlen; - size_t transliterated_len; - size_t i; + size_t strrlen; + size_t inlen; + size_t outleft; + size_t transliteratedlen; + bool changed; + char outbuf[PATH_MAX * 2]; char *inbuf; char *outptr; - char outbuf[PATH_MAX * 2]; + changed = false; inbuf = (char *) str; + inlen = 1; outptr = outbuf; - len = strlen (str); + strrlen = strlen (str); + outleft = sizeof (outbuf) - 1; + transliteratedlen = 0; - outlen = sizeof (outbuf) - 1; - conversions = iconv (iconv_context, &inbuf, &len, &outptr, &outlen); - transliterated_len = sizeof (outbuf) - 1 - outlen; - - if (conversions == (size_t) -1) + while (inbuf < str + strrlen) { - error (0, errno, _("Impossible to transliterate string %s"), str); - return NULL; - } + size_t convertedlen; + size_t conversions; + size_t symbollen; - if (transliterated_len == conversions) - { - bool found_valid = false; + symbollen = inlen; + conversions = iconv (iconv_context, &inbuf, &inlen, &outptr, &outleft); + convertedlen = (outptr - outbuf) - transliteratedlen; - for (i = 0; i < transliterated_len && !found_valid; ++i) - found_valid = outbuf[i] != '?'; + if (conversions == (size_t) -1) + { + if (errno == EILSEQ || errno == EINVAL) + { + inlen += 1; + continue; + } - if (!found_valid) - return NULL; + error (0, errno, _("Impossible to transliterate string %s"), str); + return NULL; + } + else if (conversions == 1 && convertedlen == 1 && outptr[-1] == '?') + { + /* Transliteration is not possible for this symbol, so we just + reuse it as it is. */ + memcpy (outptr - 1, inbuf - symbollen, symbollen); + convertedlen = symbollen; + outptr += symbollen - 1; + outleft -= symbollen - 1; + } + else if (conversions > 0) + changed = true; + transliteratedlen += convertedlen; + inlen = 1; } - return strndup (outbuf, transliterated_len); + if (changed != true) + return NULL; + + return strndup (outbuf, transliteratedlen); } #endif From a6c0fb80d2f4be47a880123d0ad630581469da0e Mon Sep 17 00:00:00 2001 From: Marco Trevisan (Treviño) Date: Feb 23 2018 05:07:05 +0000 Subject: [PATCH 6/11] locate: don't even try to transliterate ascii strings This improves performances a lot, basically there's now almost no timing difference between using -t parameter or not --- diff --git a/src/locate.c b/src/locate.c index 29f046e..cd0e897 100644 --- a/src/locate.c +++ b/src/locate.c @@ -183,19 +183,33 @@ transliterate_string (const char *str) size_t inlen; size_t outleft; size_t transliteratedlen; + size_t i; bool changed; + bool needsconversion; char outbuf[PATH_MAX * 2]; char *inbuf; char *outptr; + needsconversion = false; changed = false; inbuf = (char *) str; inlen = 1; outptr = outbuf; - strrlen = strlen (str); + strrlen = 0; outleft = sizeof (outbuf) - 1; transliteratedlen = 0; + for (i = 0; str[i]; i++) + { + if (str[i] & 0x80) + needsconversion = true; + + ++strrlen; + } + + if (needsconversion != true) + return NULL; + while (inbuf < str + strrlen) { size_t convertedlen; From 9c1c52fea3182117c6c9b5372439abc3830d709e Mon Sep 17 00:00:00 2001 From: Marco Trevisan (Treviño) Date: Feb 23 2018 13:58:04 +0000 Subject: [PATCH 7/11] locate: take in account inlen value when transliterating string We don't want to pass to iconv a buffer with a size that might overflow the actual string length. --- diff --git a/src/locate.c b/src/locate.c index cd0e897..5442a88 100644 --- a/src/locate.c +++ b/src/locate.c @@ -210,7 +210,7 @@ transliterate_string (const char *str) if (needsconversion != true) return NULL; - while (inbuf < str + strrlen) + while (inbuf + inlen <= str + strrlen) { size_t convertedlen; size_t conversions; From 15d7fdfd1a25ca08518e2e656e4a7844feb378cd Mon Sep 17 00:00:00 2001 From: Marco Trevisan (Treviño) Date: Feb 23 2018 15:00:01 +0000 Subject: [PATCH 8/11] locate: only allocate memory if needed in transliteration We can be sure that the transliterated string will be long at least like the input source plus an extra computed on the number of chars that might be converted, as there' s no transliteration that takes so much space. --- diff --git a/src/locate.c b/src/locate.c index 5442a88..54f7c14 100644 --- a/src/locate.c +++ b/src/locate.c @@ -183,33 +183,35 @@ transliterate_string (const char *str) size_t inlen; size_t outleft; size_t transliteratedlen; + size_t nonasciibytes; size_t i; bool changed; - bool needsconversion; - char outbuf[PATH_MAX * 2]; char *inbuf; + char *outbuf; char *outptr; - needsconversion = false; changed = false; - inbuf = (char *) str; - inlen = 1; - outptr = outbuf; + nonasciibytes = 0; strrlen = 0; - outleft = sizeof (outbuf) - 1; - transliteratedlen = 0; for (i = 0; str[i]; i++) { if (str[i] & 0x80) - needsconversion = true; + ++nonasciibytes; ++strrlen; } - if (needsconversion != true) + if (nonasciibytes < 1) return NULL; + inbuf = (char *) str; + inlen = 1; + transliteratedlen = 0; + outleft = strrlen + (nonasciibytes * 5); + outbuf = xmalloc (outleft); + outptr = outbuf; + while (inbuf + inlen <= str + strrlen) { size_t convertedlen; @@ -227,9 +229,9 @@ transliterate_string (const char *str) inlen += 1; continue; } - error (0, errno, _("Impossible to transliterate string %s"), str); - return NULL; + changed = false; + break; } else if (conversions == 1 && convertedlen == 1 && outptr[-1] == '?') { @@ -241,15 +243,21 @@ transliterate_string (const char *str) outleft -= symbollen - 1; } else if (conversions > 0) - changed = true; + { + changed = true; + } transliteratedlen += convertedlen; inlen = 1; } if (changed != true) - return NULL; + { + free (outbuf); + return NULL; + } - return strndup (outbuf, transliteratedlen); + outbuf[transliteratedlen] = '\0'; + return outbuf; } #endif From 5fc996c39f9b1ed0c9bada1b9e60b0a7ee623803 Mon Sep 17 00:00:00 2001 From: Marco Trevisan (Treviño) Date: Feb 23 2018 22:31:44 +0000 Subject: [PATCH 9/11] locate: allocate less space for transliterated, realloc if needed In case we don't have enough space for the transliterated string we can just reallocate some space for it, so far this is just needed when chars such as `㎯' are found as they use 4 bytes, but the transliteration is 7 bytes. As we can't make assumptions about what will be the maximum transliteration length, we can just repeatedly reallocate if needed. --- diff --git a/src/locate.c b/src/locate.c index 54f7c14..de7fcd6 100644 --- a/src/locate.c +++ b/src/locate.c @@ -197,7 +197,7 @@ transliterate_string (const char *str) for (i = 0; str[i]; i++) { if (str[i] & 0x80) - ++nonasciibytes; + ++nonasciibytes; ++strrlen; } @@ -208,7 +208,7 @@ transliterate_string (const char *str) inbuf = (char *) str; inlen = 1; transliteratedlen = 0; - outleft = strrlen + (nonasciibytes * 5); + outleft = strrlen + nonasciibytes; outbuf = xmalloc (outleft); outptr = outbuf; @@ -217,10 +217,12 @@ transliterate_string (const char *str) size_t convertedlen; size_t conversions; size_t symbollen; + size_t outidx; symbollen = inlen; conversions = iconv (iconv_context, &inbuf, &inlen, &outptr, &outleft); - convertedlen = (outptr - outbuf) - transliteratedlen; + outidx = outptr - outbuf; + convertedlen = outidx - transliteratedlen; if (conversions == (size_t) -1) { @@ -229,6 +231,13 @@ transliterate_string (const char *str) inlen += 1; continue; } + else if (errno == E2BIG) + { + outleft += 5; + outbuf = xrealloc (outbuf, outidx + outleft); + outptr = outbuf + outidx; + continue; + } error (0, errno, _("Impossible to transliterate string %s"), str); changed = false; break; From 1359fb07f35c1d0e08b12070da0e3aa8faa0065a Mon Sep 17 00:00:00 2001 From: Marco Trevisan (Treviño) Date: Feb 23 2018 22:39:05 +0000 Subject: [PATCH 10/11] locate: escape transliterated meta chars if regex is enabled As per C-translit.h many chars could generate combinations where regex meta chars are used. For example: ⓪, ﬩,{ → ㎯, ﹙∗ In such case, we need to escape the regex properly. --- diff --git a/src/locate.c b/src/locate.c index de7fcd6..df18a0d 100644 --- a/src/locate.c +++ b/src/locate.c @@ -51,6 +51,9 @@ Author: Miloslav Trmac */ #include "db.h" #include "lib.h" +#define BASIC_REGEX_META_CHARS ".^$*[]\\-" +#define EXTENDED_REGEX_META_CHARS BASIC_REGEX_META_CHARS "{}|+?()" + /* Check file existence before reporting them */ static bool conf_check_existence; /* = false; */ @@ -176,6 +179,69 @@ uppercase_string (struct obstack *obstack, const char *src) } #if HAVE_ICONV +static bool +char_needs_escape (const char c) +{ + if (conf_match_regexp_basic != false && + strchr (BASIC_REGEX_META_CHARS, c) != NULL) + return true; + + if (conf_match_regexp_basic != true && + strchr (EXTENDED_REGEX_META_CHARS, c) != NULL) + return true; + + return false; +} + +static char * +escape_regex (const char *str, size_t len, size_t *escaped_len) +{ + size_t i, j; + size_t newlen; + bool foundmeta; + char *outbuf; + + if (escaped_len) + *escaped_len = 0; + + if (conf_match_regexp != true) + return NULL; + + foundmeta = false; + newlen = 0; + + for (i = 0; str[i] && i < len; ++i) + { + if (char_needs_escape (str[i])) + { + foundmeta = true; + ++newlen; + } + ++newlen; + } + + if (foundmeta != true || newlen == 0) + return NULL; + + outbuf = xmalloc (newlen + 1); + outbuf[newlen] = '\0'; + + for (i = 0, j = 0; i < len && j < newlen; ++i) + { + if (char_needs_escape (str[i])) + outbuf[j++] = '\\'; + outbuf[j++] = str[i]; + } + + if (escaped_len) + *escaped_len = newlen; + + return outbuf; +} + +/* Use iconv to transliterate the string into ASCII chars, when possible. + If a transliteration does not exist, we just use the actual symbol + not to loose precision. */ static char * transliterate_string (const char *str) { @@ -253,6 +319,32 @@ transliterate_string (const char *str) } else if (conversions > 0) { + if (conf_match_regexp != false && convertedlen > 0) + { + char *converted; + char *escaped; + size_t escaped_len; + + converted = outptr - convertedlen; + escaped = escape_regex (converted, convertedlen, &escaped_len); + + if (escaped) + { + if (escaped_len > outleft) + { + outleft += (escaped_len - outleft); + outbuf = xrealloc (outbuf, outidx + outleft); + outptr = outbuf + outidx; + converted = outptr - convertedlen; + } + memcpy (converted, escaped, escaped_len); + free (escaped); + + outptr += (escaped_len - convertedlen); + outleft -= (escaped_len - convertedlen); + convertedlen = escaped_len; + } + } changed = true; } transliteratedlen += convertedlen; From 444ab882f9b7add5c8cadc7de78b3895464cd7ef Mon Sep 17 00:00:00 2001 From: Marco Trevisan (Treviño) Date: Mar 01 2018 05:31:03 +0000 Subject: [PATCH 11/11] locate: update test to match new help --- diff --git a/src/locate.c b/src/locate.c index df18a0d..52b9de4 100644 --- a/src/locate.c +++ b/src/locate.c @@ -329,7 +329,7 @@ transliterate_string (const char *str) escaped = escape_regex (converted, convertedlen, &escaped_len); if (escaped) - { + { if (escaped_len > outleft) { outleft += (escaped_len - outleft); @@ -343,7 +343,7 @@ transliterate_string (const char *str) outptr += (escaped_len - convertedlen); outleft -= (escaped_len - convertedlen); convertedlen = escaped_len; - } + } } changed = true; } @@ -854,7 +854,8 @@ help (void) "patterns\n" #if HAVE_ICONV " -t, --transliterate ignore accents using iconv " - "transliteration when matching patterns\n" + "transliteration when\n" + " matching patterns\n" #endif " -l, --limit, -n LIMIT limit output (or counting) to LIMIT " "entries\n" diff --git a/tests/locate.at b/tests/locate.at index 4f718ef..e89a56b 100644 --- a/tests/locate.at +++ b/tests/locate.at @@ -233,6 +233,8 @@ Search for entries in a mlocate database. existence (default) -h, --help print this help -i, --ignore-case ignore case distinctions when matching patterns + -t, --transliterate ignore accents using iconv transliteration when + matching patterns -l, --limit, -n LIMIT limit output (or counting) to LIMIT entries -m, --mmap ignored, for backward compatibility -P, --nofollow, -H don't follow trailing symbolic links when checking file