diff options
author | David E. O'Brien <obrien@FreeBSD.org> | 2011-03-31 18:34:50 +0000 |
---|---|---|
committer | David E. O'Brien <obrien@FreeBSD.org> | 2011-03-31 18:34:50 +0000 |
commit | 703cb6130cc6bd2fc0b0eba9cf05b5f483673ef4 (patch) | |
tree | 75d1413f2d85aff18799bc1b708f14ace12aaf47 /filecomplete.c | |
parent | 8dfe73baa31e01bec909d4aa794df323b0876a9d (diff) |
Diffstat (limited to 'filecomplete.c')
-rw-r--r-- | filecomplete.c | 107 |
1 files changed, 59 insertions, 48 deletions
diff --git a/filecomplete.c b/filecomplete.c index 78982c37ee4ec..c97b9f206c073 100644 --- a/filecomplete.c +++ b/filecomplete.c @@ -1,4 +1,4 @@ -/* $NetBSD: filecomplete.c,v 1.10 2006/11/09 16:58:38 christos Exp $ */ +/* $NetBSD: filecomplete.c,v 1.19 2010/06/01 18:20:26 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -15,9 +15,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -34,7 +31,7 @@ #include "config.h" #if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: filecomplete.c,v 1.10 2006/11/09 16:58:38 christos Exp $"); +__RCSID("$NetBSD: filecomplete.c,v 1.19 2010/06/01 18:20:26 christos Exp $"); #endif /* not lint && not SCCSID */ #include <sys/types.h> @@ -62,8 +59,8 @@ __RCSID("$NetBSD: filecomplete.c,v 1.10 2006/11/09 16:58:38 christos Exp $"); #include "histedit.h" #include "filecomplete.h" -static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', - '>', '<', '=', ';', '|', '&', '{', '(', '\0' }; +static Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', + '$', '>', '<', '=', ';', '|', '&', '{', '(', '\0' }; /********************************/ @@ -149,20 +146,24 @@ fn_filename_completion_function(const char *text, int state) nptr = realloc(filename, strlen(temp) + 1); if (nptr == NULL) { free(filename); + filename = NULL; return NULL; } filename = nptr; (void)strcpy(filename, temp); len = temp - text; /* including last slash */ + nptr = realloc(dirname, len + 1); if (nptr == NULL) { - free(filename); + free(dirname); + dirname = NULL; return NULL; } dirname = nptr; (void)strncpy(dirname, text, len); dirname[len] = '\0'; } else { + free(filename); if (*text == 0) filename = NULL; else { @@ -170,6 +171,7 @@ fn_filename_completion_function(const char *text, int state) if (filename == NULL) return NULL; } + free(dirname); dirname = NULL; } @@ -179,12 +181,14 @@ fn_filename_completion_function(const char *text, int state) } /* support for ``~user'' syntax */ - free(dirpath); - if (dirname == NULL && (dirname = strdup("./")) == NULL) - return NULL; - - if (*dirname == '~') + free(dirpath); + dirpath = NULL; + if (dirname == NULL) { + if ((dirname = strdup("")) == NULL) + return NULL; + dirpath = strdup("./"); + } else if (*dirname == '~') dirpath = fn_tilde_expand(dirname); else dirpath = strdup(dirname); @@ -211,10 +215,10 @@ fn_filename_completion_function(const char *text, int state) /* otherwise, get first entry where first */ /* filename_len characters are equal */ if (entry->d_name[0] == filename[0] -#if defined(__SVR4) || defined(__linux__) - && strlen(entry->d_name) >= filename_len -#else +#if HAVE_STRUCT_DIRENT_D_NAMLEN && entry->d_namlen >= filename_len +#else + && strlen(entry->d_name) >= filename_len #endif && strncmp(entry->d_name, filename, filename_len) == 0) @@ -223,10 +227,10 @@ fn_filename_completion_function(const char *text, int state) if (entry) { /* match found */ -#if defined(__SVR4) || defined(__linux__) - len = strlen(entry->d_name); -#else +#if HAVE_STRUCT_DIRENT_D_NAMLEN len = entry->d_namlen; +#else + len = strlen(entry->d_name); #endif temp = malloc(strlen(dirname) + len + 1); @@ -248,7 +252,7 @@ append_char_function(const char *name) { struct stat stbuf; char *expname = *name == '~' ? fn_tilde_expand(name) : NULL; - const char *rs = ""; + const char *rs = " "; if (stat(expname ? expname : name, &stbuf) == -1) goto out; @@ -338,9 +342,9 @@ _fn_qsort_string_compare(const void *i1, const void *i2) * 'max' is maximum length of string in 'matches'. */ void -fn_display_match_list (EditLine *el, char **matches, int len, int max) +fn_display_match_list (EditLine *el, char **matches, size_t len, size_t max) { - int i, idx, limit, count; + size_t i, idx, limit, count; int screenwidth = el->el_term.t_size.h; /* @@ -362,9 +366,12 @@ fn_display_match_list (EditLine *el, char **matches, int len, int max) idx = 1; for(; count > 0; count--) { - for(i = 0; i < limit && matches[idx]; i++, idx++) - (void)fprintf(el->el_outfile, "%-*s ", max, - matches[idx]); + int more = limit > 0 && matches[0]; + for(i = 0; more; i++, idx++) { + more = ++i < limit && matches[idx + 1]; + (void)fprintf(el->el_outfile, "%-*s%s", (int)max, + matches[idx], more ? " " : ""); + } (void)fprintf(el->el_outfile, "\n"); } } @@ -385,13 +392,14 @@ int fn_complete(EditLine *el, char *(*complet_func)(const char *, int), char **(*attempted_completion_function)(const char *, int, int), - const char *word_break, const char *special_prefixes, - const char *(*app_func)(const char *), int query_items, + const Char *word_break, const Char *special_prefixes, + const char *(*app_func)(const char *), size_t query_items, int *completion_type, int *over, int *point, int *end) { - const LineInfo *li; - char *temp, **matches; - const char *ctemp; + const TYPE(LineInfo) *li; + Char *temp; + char **matches; + const Char *ctemp; size_t len; int what_to_do = '\t'; int retval = CC_NORM; @@ -409,45 +417,45 @@ fn_complete(EditLine *el, app_func = append_char_function; /* We now look backwards for the start of a filename/variable word */ - li = el_line(el); - ctemp = (const char *) li->cursor; + li = FUN(el,line)(el); + ctemp = li->cursor; while (ctemp > li->buffer - && !strchr(word_break, ctemp[-1]) - && (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) ) + && !Strchr(word_break, ctemp[-1]) + && (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) ) ctemp--; len = li->cursor - ctemp; #if defined(__SSP__) || defined(__SSP_ALL__) - temp = malloc(len + 1); + temp = malloc(sizeof(*temp) * (len + 1)); #else - temp = alloca(len + 1); + temp = alloca(sizeof(*temp) * (len + 1)); #endif - (void)strncpy(temp, ctemp, len); + (void)Strncpy(temp, ctemp, len); temp[len] = '\0'; /* these can be used by function called in completion_matches() */ /* or (*attempted_completion_function)() */ if (point != 0) - *point = li->cursor - li->buffer; + *point = (int)(li->cursor - li->buffer); if (end != NULL) - *end = li->lastchar - li->buffer; + *end = (int)(li->lastchar - li->buffer); if (attempted_completion_function) { - int cur_off = li->cursor - li->buffer; - matches = (*attempted_completion_function) (temp, + int cur_off = (int)(li->cursor - li->buffer); + matches = (*attempted_completion_function) (ct_encode_string(temp, &el->el_scratch), (int)(cur_off - len), cur_off); } else matches = 0; if (!attempted_completion_function || (over != NULL && !*over && !matches)) - matches = completion_matches(temp, complet_func); + matches = completion_matches(ct_encode_string(temp, &el->el_scratch), complet_func); if (over != NULL) *over = 0; if (matches) { int i; - int matches_num, maxlen, match_len, match_display=1; + size_t matches_num, maxlen, match_len, match_display=1; retval = CC_REFRESH; /* @@ -456,7 +464,8 @@ fn_complete(EditLine *el, */ if (matches[0][0] != '\0') { el_deletestr(el, (int) len); - el_insertstr(el, matches[0]); + FUN(el,insertstr)(el, + ct_decode_string(matches[0], &el->el_scratch)); } if (what_to_do == '?') @@ -468,7 +477,9 @@ fn_complete(EditLine *el, * it, unless we do filename completion and the * object is a directory. */ - el_insertstr(el, (*append_char_function)(matches[0])); + FUN(el,insertstr)(el, + ct_decode_string((*app_func)(matches[0]), + &el->el_scratch)); } else if (what_to_do == '!') { display_matches: /* @@ -476,7 +487,7 @@ fn_complete(EditLine *el, * matches. */ - for(i=1, maxlen=0; matches[i]; i++) { + for(i = 1, maxlen = 0; matches[i]; i++) { match_len = strlen(matches[i]); if (match_len > maxlen) maxlen = match_len; @@ -492,7 +503,7 @@ fn_complete(EditLine *el, */ if (matches_num > query_items) { (void)fprintf(el->el_outfile, - "Display all %d possibilities? (y or n) ", + "Display all %zu possibilities? (y or n) ", matches_num); (void)fflush(el->el_outfile); if (getc(stdin) != 'y') @@ -502,7 +513,7 @@ fn_complete(EditLine *el, if (match_display) fn_display_match_list(el, matches, matches_num, - maxlen); + maxlen); retval = CC_REDISPLAY; } else if (matches[0][0]) { /* |