3 ** History and file completion functions for editline library.
8 #if defined(NEED_STRDUP)
10 ** Return an allocated copy of a string.
18 if ((new = NEW(char, strlen(p
) + 1)) != NULL
)
22 #endif /* defined(NEED_STRDUP) */
25 ** strcmp-like sorting predicate for qsort.
35 v1
= (CONST
char **)p1
;
36 v2
= (CONST
char **)p2
;
37 return strcmp(*v1
, *v2
);
41 ** Fill in *avp with an array of names that match file, up to its length.
45 FindMatches(dir
, file
, avp
)
58 if ((dp
= opendir(dir
)) == NULL
)
64 while ((ep
= readdir(dp
)) != NULL
) {
66 if (p
[0] == '.' && (p
[1] == '\0' || (p
[1] == '.' && p
[2] == '\0')))
68 if (len
&& strncmp(p
, file
, len
) != 0)
71 if ((ac
% MEM_INC
) == 0) {
72 if ((new = NEW(char*, ac
+ MEM_INC
)) == NULL
)
75 COPYFROMTO(new, av
, ac
* sizeof (char **));
81 if ((av
[ac
] = strdup(p
)) == NULL
) {
89 /* Clean up and return. */
92 qsort(av
, ac
, sizeof (char **), compare
);
97 ** Split a pathname into allocated directory and trailing filename parts.
100 SplitPath(path
, dirpart
, filepart
)
105 static char DOT
[] = ".";
109 if ((fpart
= strrchr(path
, '/')) == NULL
) {
110 if ((dpart
= strdup(DOT
)) == NULL
)
112 if ((fpart
= strdup(path
)) == NULL
) {
118 if ((dpart
= strdup(path
)) == NULL
)
120 dpart
[fpart
- path
] = '\0';
121 if ((fpart
= strdup(++fpart
)) == NULL
) {
132 ** Attempt to complete the pathname, returning an allocated copy.
133 ** Fill in *unique if we completed it, or set it to 0 if ambiguous.
136 rl_complete(pathname
, unique
)
151 if (SplitPath(pathname
, &dir
, &file
) < 0)
153 if ((ac
= FindMatches(dir
, file
, &av
)) == 0) {
162 /* Exactly one match -- finish it off. */
164 j
= strlen(av
[0]) - len
+ 2;
165 if ((p
= NEW(char, j
+ 1)) != NULL
) {
166 COPYFROMTO(p
, av
[0] + len
, j
);
167 if ((new = NEW(char, strlen(dir
) + strlen(av
[0]) + 2)) != NULL
) {
168 (void)strcpy(new, dir
);
169 (void)strcat(new, "/");
170 (void)strcat(new, av
[0]);
171 rl_add_slash(new, p
);
179 /* Find largest matching substring. */
180 for (i
= len
, end
= strlen(av
[0]); i
< end
; i
++)
181 for (j
= 1; j
< ac
; j
++)
182 if (av
[0][i
] != av
[j
][i
])
187 if ((p
= NEW(char, j
)) != NULL
) {
188 COPYFROMTO(p
, av
[0] + len
, j
);
195 /* Clean up and return. */
198 for (i
= 0; i
< ac
; i
++)
205 ** Return all possible completions.
208 rl_list_possib(pathname
, avp
)
216 if (SplitPath(pathname
, &dir
, &file
) < 0)
218 ac
= FindMatches(dir
, file
, avp
);