X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=fish%2Fdestpaths.c;h=5ed93ec78f2eafebdc86b45df7146633dc064f2c;hp=02e9f223950913c68053933eff02a6973b6afaed;hb=21bd2db7cf259a17cc3922409937b849e4b83c0f;hpb=9a8889e4d0c532b9f77af3a9cc7aae06adebfb83 diff --git a/fish/destpaths.c b/fish/destpaths.c index 02e9f22..5ed93ec 100644 --- a/fish/destpaths.c +++ b/fish/destpaths.c @@ -31,6 +31,7 @@ #include "fish.h" +#ifdef HAVE_LIBREADLINE // From gnulib's xalloc.h: /* Return 1 if an array of N objects, each of size S, cannot exist due to size arithmetic overflow. S must be positive and N must be @@ -46,6 +47,7 @@ branch when S is known to be 1. */ # define xalloc_oversized(n, s) \ ((size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) < (n)) +#endif /* Readline completion for paths on the guest filesystem, also for * devices and LVM names. @@ -58,6 +60,7 @@ struct word { int is_dir; }; +#ifdef HAVE_LIBREADLINE static void free_words (struct word *words, size_t nr_words) { @@ -69,6 +72,15 @@ free_words (struct word *words, size_t nr_words) free (words); } +static int +compare_words (const void *vp1, const void *vp2) +{ + const struct word *w1 = (const struct word *) vp1; + const struct word *w2 = (const struct word *) vp2; + return strcmp (w1->name, w2->name); +} +#endif + char * complete_dest_paths_generator (const char *text, int state) { @@ -166,8 +178,8 @@ complete_dest_paths_generator (const char *text, int state) for (i = 0; i < dirents->len; ++i) { int err; - if (strcmp (dirents->val[i].name, ".") != 0 && - strcmp (dirents->val[i].name, "..") != 0) { + if (STRNEQ (dirents->val[i].name, ".") && + STRNEQ (dirents->val[i].name, "..")) { if (STREQ (dir, "/")) err = asprintf (&p, "/%s", dirents->val[i].name); else @@ -208,6 +220,9 @@ complete_dest_paths_generator (const char *text, int state) /* This inhibits ordinary (local filename) completion. */ rl_attempted_completion_over = 1; + /* Sort the words so the list is stable over multiple calls. */ + qsort (words, nr_words, sizeof (struct word), compare_words); + /* Complete the string. */ while (index < nr_words) { struct word *word; @@ -215,7 +230,20 @@ complete_dest_paths_generator (const char *text, int state) word = &words[index]; index++; - if (strncasecmp (word->name, text, len) == 0) { + /* Whether we should match case insensitively here or not is + * determined by the value of the completion-ignore-case readline + * variable. Default to case insensitive. (See: RHBZ#582993). + */ + char *cic_var = rl_variable_value ("completion-ignore-case"); + int cic = 1; + if (cic_var && STREQ (cic_var, "off")) + cic = 0; + + int matches = + cic ? STRCASEEQLEN (word->name, text, len) + : STREQLEN (word->name, text, len); + + if (matches) { if (word->is_dir) rl_completion_append_character = '/';