diff options
author | Baptiste Daroussin <bapt@FreeBSD.org> | 2021-03-22 14:34:14 +0000 |
---|---|---|
committer | Baptiste Daroussin <bapt@FreeBSD.org> | 2021-03-22 14:34:14 +0000 |
commit | f9a159da2a292968cd5c37b56a6c43b6af8c5eed (patch) | |
tree | 6068c188fd0adbf0cfbc185d62250f6bd08960db /contrib/libedit/filecomplete.c | |
parent | a0409676120c1e558d0ade943019934e0f15118d (diff) | |
parent | 881fcf9c3caf82a2f97a17b6ca91eb0b1b0320cd (diff) |
Diffstat (limited to 'contrib/libedit/filecomplete.c')
-rw-r--r-- | contrib/libedit/filecomplete.c | 221 |
1 files changed, 113 insertions, 108 deletions
diff --git a/contrib/libedit/filecomplete.c b/contrib/libedit/filecomplete.c index 662a0bb85d0b..61579024926c 100644 --- a/contrib/libedit/filecomplete.c +++ b/contrib/libedit/filecomplete.c @@ -1,4 +1,4 @@ -/* $NetBSD: filecomplete.c,v 1.58 2019/09/08 05:50:58 abhinav Exp $ */ +/* $NetBSD: filecomplete.c,v 1.64 2020/01/05 07:12:05 abhinav Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include "config.h" #if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: filecomplete.c,v 1.58 2019/09/08 05:50:58 abhinav Exp $"); +__RCSID("$NetBSD: filecomplete.c,v 1.64 2020/01/05 07:12:05 abhinav Exp $"); #endif /* not lint && not SCCSID */ #include <sys/types.h> @@ -86,8 +86,7 @@ fn_tilde_expand(const char *txt) temp = el_calloc(len, sizeof(*temp)); if (temp == NULL) return NULL; - (void)strncpy(temp, txt + 1, len - 2); - temp[len - 2] = '\0'; + (void)strlcpy(temp, txt + 1, len - 1); } if (temp[0] == 0) { #ifdef HAVE_GETPW_R_POSIX @@ -354,8 +353,7 @@ fn_filename_completion_function(const char *text, int state) return NULL; } dirname = nptr; - (void)strncpy(dirname, text, len); - dirname[len] = '\0'; + (void)strlcpy(dirname, text, len + 1); } else { el_free(filename); if (*text == 0) @@ -509,8 +507,7 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int)) el_free(match_list); return NULL; } - (void)strncpy(retstr, match_list[1], max_equal); - retstr[max_equal] = '\0'; + (void)strlcpy(retstr, match_list[1], max_equal + 1); match_list[0] = retstr; /* add NULL as last pointer to the array */ @@ -586,10 +583,12 @@ fn_display_match_list(EditLine * el, char **matches, size_t num, size_t width, static wchar_t * find_word_to_complete(const wchar_t * cursor, const wchar_t * buffer, - const wchar_t * word_break, const wchar_t * special_prefixes, size_t * length) + const wchar_t * word_break, const wchar_t * special_prefixes, size_t * length, + int do_unescape) { /* We now look backwards for the start of a filename/variable word */ const wchar_t *ctemp = cursor; + wchar_t *temp; size_t len; /* if the cursor is placed at a slash or a quote, we need to find the @@ -614,12 +613,8 @@ find_word_to_complete(const wchar_t * cursor, const wchar_t * buffer, if (ctemp - buffer >= 2 && ctemp[-2] == '\\') { ctemp -= 2; continue; - } else if (ctemp - buffer >= 2 && - (ctemp[-2] == '\'' || ctemp[-2] == '"')) { - ctemp--; - continue; - } else - break; + } + break; } if (special_prefixes && wcschr(special_prefixes, ctemp[-1])) break; @@ -632,10 +627,16 @@ find_word_to_complete(const wchar_t * cursor, const wchar_t * buffer, ctemp++; } *length = len; - wchar_t *unescaped_word = unescape_string(ctemp, len); - if (unescaped_word == NULL) - return NULL; - return unescaped_word; + if (do_unescape) { + wchar_t *unescaped_word = unescape_string(ctemp, len); + if (unescaped_word == NULL) + return NULL; + return unescaped_word; + } + temp = el_malloc((len + 1) * sizeof(*temp)); + (void) wcsncpy(temp, ctemp, len); + temp[len] = '\0'; + return temp; } /* @@ -665,6 +666,7 @@ fn_complete(EditLine *el, size_t len; int what_to_do = '\t'; int retval = CC_NORM; + int do_unescape = attempted_completion_function == NULL? 1: 0; if (el->el_state.lastcmd == el->el_state.thiscmd) what_to_do = '?'; @@ -680,7 +682,7 @@ fn_complete(EditLine *el, li = el_wline(el); temp = find_word_to_complete(li->cursor, - li->buffer, word_break, special_prefixes, &len); + li->buffer, word_break, special_prefixes, &len, do_unescape); if (temp == NULL) goto out; @@ -706,107 +708,110 @@ fn_complete(EditLine *el, if (over != NULL) *over = 0; - if (matches) { - int i; - size_t matches_num, maxlen, match_len, match_display=1; - int single_match = matches[2] == NULL && - (matches[1] == NULL || strcmp(matches[0], matches[1]) == 0); - - retval = CC_REFRESH; - - if (matches[0][0] != '\0') { - el_deletestr(el, (int)len); - if (!attempted_completion_function) - completion = escape_filename(el, matches[0], - single_match, app_func); - else - completion = strdup(matches[0]); - if (completion == NULL) - goto out; - if (single_match) { - /* We found exact match. Add a space after it, - * unless we do filename completion and the - * object is a directory. Also do necessary - * escape quoting - */ - el_winsertstr(el, - ct_decode_string(completion, &el->el_scratch)); - } else { - /* Only replace the completed string with - * common part of possible matches if there is - * possible completion. - */ - el_winsertstr(el, - ct_decode_string(completion, &el->el_scratch)); - } - free(completion); - } + if (matches == NULL) { + goto out; + } + int i; + size_t matches_num, maxlen, match_len, match_display=1; + int single_match = matches[2] == NULL && + (matches[1] == NULL || strcmp(matches[0], matches[1]) == 0); + + retval = CC_REFRESH; + + if (matches[0][0] != '\0') { + el_deletestr(el, (int)len); + if (!attempted_completion_function) + completion = escape_filename(el, matches[0], + single_match, app_func); + else + completion = strdup(matches[0]); + if (completion == NULL) + goto out; + /* + * Replace the completed string with the common part of + * all possible matches if there is a possible completion. + */ + el_winsertstr(el, + ct_decode_string(completion, &el->el_scratch)); - if (!single_match && (what_to_do == '!' || what_to_do == '?')) { + if (single_match && attempted_completion_function) { /* - * More than one match and requested to list possible - * matches. + * We found an exact match. Add a space after + * it, unless we do filename completion and the + * object is a directory. Also do necessary + * escape quoting */ + el_winsertstr(el, ct_decode_string( + (*app_func)(completion), &el->el_scratch)); + } + free(completion); + } - for(i = 1, maxlen = 0; matches[i]; i++) { - match_len = strlen(matches[i]); - if (match_len > maxlen) - maxlen = match_len; - } - /* matches[1] through matches[i-1] are available */ - matches_num = (size_t)(i - 1); - /* newline to get on next line from command line */ - (void)fprintf(el->el_outfile, "\n"); + if (!single_match && (what_to_do == '!' || what_to_do == '?')) { + /* + * More than one match and requested to list possible + * matches. + */ - /* - * If there are too many items, ask user for display - * confirmation. - */ - if (matches_num > query_items) { - (void)fprintf(el->el_outfile, - "Display all %zu possibilities? (y or n) ", - matches_num); - (void)fflush(el->el_outfile); - if (getc(stdin) != 'y') - match_display = 0; - (void)fprintf(el->el_outfile, "\n"); - } + for(i = 1, maxlen = 0; matches[i]; i++) { + match_len = strlen(matches[i]); + if (match_len > maxlen) + maxlen = match_len; + } + /* matches[1] through matches[i-1] are available */ + matches_num = (size_t)(i - 1); - if (match_display) { - /* - * Interface of this function requires the - * strings be matches[1..num-1] for compat. - * We have matches_num strings not counting - * the prefix in matches[0], so we need to - * add 1 to matches_num for the call. - */ - fn_display_match_list(el, matches, - matches_num+1, maxlen, app_func); - } - retval = CC_REDISPLAY; - } else if (matches[0][0]) { + /* newline to get on next line from command line */ + (void)fprintf(el->el_outfile, "\n"); + + /* + * If there are too many items, ask user for display + * confirmation. + */ + if (matches_num > query_items) { + (void)fprintf(el->el_outfile, + "Display all %zu possibilities? (y or n) ", + matches_num); + (void)fflush(el->el_outfile); + if (getc(stdin) != 'y') + match_display = 0; + (void)fprintf(el->el_outfile, "\n"); + } + + if (match_display) { /* - * There was some common match, but the name was - * not complete enough. Next tab will print possible - * completions. + * Interface of this function requires the + * strings be matches[1..num-1] for compat. + * We have matches_num strings not counting + * the prefix in matches[0], so we need to + * add 1 to matches_num for the call. */ - el_beep(el); - } else { - /* lcd is not a valid object - further specification */ - /* is needed */ - el_beep(el); - retval = CC_NORM; + fn_display_match_list(el, matches, + matches_num+1, maxlen, app_func); } - - /* free elements of array and the array itself */ - for (i = 0; matches[i]; i++) - el_free(matches[i]); - el_free(matches); - matches = NULL; + retval = CC_REDISPLAY; + } else if (matches[0][0]) { + /* + * There was some common match, but the name was + * not complete enough. Next tab will print possible + * completions. + */ + el_beep(el); + } else { + /* lcd is not a valid object - further specification */ + /* is needed */ + el_beep(el); + retval = CC_NORM; } + /* free elements of array and the array itself */ + for (i = 0; matches[i]; i++) + el_free(matches[i]); + el_free(matches); + matches = NULL; + out: el_free(temp); return retval; |