Edinburgh Speech Tools
2.4-release
Loading...
Searching...
No Matches
el_complete.c
1
/****************************************************************************/
2
/* */
3
/* Copyright 1992 Simmule Turner and Rich Salz. All rights reserved. */
4
/* */
5
/* This software is not subject to any license of the American Telephone */
6
/* and Telegraph Company or of the Regents of the University of California. */
7
/* */
8
/* Permission is granted to anyone to use this software for any purpose on */
9
/* any computer system, and to alter it and redistribute it freely, subject */
10
/* to the following restrictions: */
11
/* 1. The authors are not responsible for the consequences of use of this */
12
/* software, no matter how awful, even if they arise from flaws in it. */
13
/* 2. The origin of this software must not be misrepresented, either by */
14
/* explicit claim or by omission. Since few users ever read sources, */
15
/* credits must appear in the documentation. */
16
/* 3. Altered versions must be plainly marked as such, and must not be */
17
/* misrepresented as being the original software. Since few users */
18
/* ever read sources, credits must appear in the documentation. */
19
/* 4. This notice may not be removed or altered. */
20
/* */
21
/****************************************************************************/
22
/* */
23
/* This is a line-editing library, it can be linked into almost any */
24
/* program to provide command-line editing and recall. */
25
/* */
26
/* Posted to comp.sources.misc Sun, 2 Aug 1992 03:05:27 GMT */
27
/* by rsalz@osf.org (Rich $alz) */
28
/* */
29
/****************************************************************************/
30
/* */
31
/* The version contained here has some modifications by awb@cstr.ed.ac.uk */
32
/* (Alan W Black) in order to integrate it with the Edinburgh Speech Tools */
33
/* library and Scheme-in-one-defun in particular. All modifications to */
34
/* to this work are continued with the same copyright above. That is */
35
/* This version editline does not have the the "no commercial use" */
36
/* restriction that some of the rest of the EST library may have */
37
/* awb Dec 30 1998 */
38
/* */
39
/****************************************************************************/
40
/* $Revision: 1.3 $
41
**
42
** History and file completion functions for editline library.
43
*/
44
#include "editline.h"
45
46
47
#if defined(NEED_STRDUP)
48
/*
49
** Return an allocated copy of a string.
50
*/
51
char
*
strdup
(
char
*p)
52
{
53
char
*
new
;
54
55
if
((
new
= NEW(
char
,
strlen
(p) + 1)) != NULL)
56
(
void
)
strcpy
(
new
, p);
57
return
new
;
58
}
59
#endif
/* defined(NEED_STRDUP) */
60
61
/*
62
** strcmp-like sorting predicate for qsort.
63
*/
64
STATIC
int
compare(CONST
void
*
p1
,CONST
void
*
p2
)
65
{
66
CONST
char
**
v1
;
67
CONST
char
**
v2
;
68
69
v1
= (CONST
char
**)
p1
;
70
v2
= (CONST
char
**)
p2
;
71
return
strcmp
(*
v1
, *
v2
);
72
}
73
74
/*
75
** Fill in *avp with an array of names that match file, up to its length.
76
** Ignore . and .. .
77
*/
78
STATIC
int
FindMatches(
char
*
dir
,
char
*
file
,
char
***
avp
)
79
{
80
#if !defined(SYSTEM_IS_WIN32)
81
char
**
av
;
82
char
**
neww
;
83
char
*p;
84
DIR
*
dp
;
85
DIRENTRY
*
ep
;
86
ESIZE_T
ac
;
87
ESIZE_T
len
;
88
89
if
((
dp
=
opendir
(
dir
)) == NULL)
90
return
0;
91
92
av
= NULL;
93
ac
= 0;
94
len
=
strlen
(
file
);
95
while
((
ep
=
readdir
(
dp
)) != NULL) {
96
p =
ep
->d_name;
97
if
(p[0] ==
'.'
&& (p[1] ==
'\0'
|| (p[1] ==
'.'
&& p[2] ==
'\0'
)))
98
continue
;
99
if
(
len
&&
strncmp
(p,
file
,
len
) != 0)
100
continue
;
101
102
if
((
ac
% MEM_INC) == 0) {
103
if
((
neww
= NEW(
char
*,
ac
+ MEM_INC)) == NULL)
104
break
;
105
if
(
ac
) {
106
COPYFROMTO(
neww
,
av
,
ac
*
sizeof
(
char
**));
107
DISPOSE(
av
);
108
}
109
*
avp
=
av
=
neww
;
110
}
111
112
if
((
av
[
ac
] = STRDUP(p)) == NULL) {
113
if
(
ac
== 0)
114
DISPOSE(
av
);
115
break
;
116
}
117
ac
++;
118
}
119
120
/* Clean up and return. */
121
(
void
)
closedir
(
dp
);
122
if
(
ac
)
123
qsort(
av
,
ac
,
sizeof
(
char
**), compare);
124
return
ac
;
125
#else
126
*
avp
=NULL;
127
return
0;
128
#endif
129
}
130
131
/*
132
** Split a pathname into allocated directory and trailing filename parts.
133
*/
134
STATIC
int
SplitPath(
char
*path,
char
**
dirpart
,
char
**
filepart
)
135
{
136
static
char
DOT
[] =
"."
;
137
char
*
dpart
;
138
char
*
fpart
;
139
140
if
((
fpart
=
strrchr
(path,
'/'
)) == NULL) {
141
if
((
dpart
= STRDUP(
DOT
)) == NULL)
142
return
-1;
143
if
((
fpart
= STRDUP(path)) == NULL) {
144
DISPOSE(
dpart
);
145
return
-1;
146
}
147
}
148
else
{
149
if
((
dpart
= STRDUP(path)) == NULL)
150
return
-1;
151
dpart
[
fpart
- path] =
'\0'
;
152
if
((
fpart
= STRDUP(++
fpart
)) == NULL) {
153
DISPOSE(
dpart
);
154
return
-1;
155
}
156
if
(
dpart
[0] ==
'\0'
)
/* special case for root */
157
{
158
dpart
[0] =
'/'
;
159
dpart
[1] =
'\0'
;
160
}
161
}
162
*
dirpart
=
dpart
;
163
*
filepart
=
fpart
;
164
return
0;
165
}
166
167
/*
168
** Attempt to complete the pathname, returning an allocated copy.
169
** Fill in *unique if we completed it, or set it to 0 if ambiguous.
170
*/
171
char
*rl_complete(
char
*
pathname
,
int
*
unique
)
172
{
173
char
**
av
;
174
char
*
dir
;
175
char
*
file
;
176
char
*
neww
;
177
char
*p;
178
ESIZE_T
ac
;
179
ESIZE_T end;
180
ESIZE_T i;
181
ESIZE_T
j
;
182
ESIZE_T
len
;
183
184
if
(SplitPath(
pathname
, &
dir
, &
file
) < 0)
185
return
NULL;
186
if
((
ac
= FindMatches(
dir
,
file
, &
av
)) == 0) {
187
DISPOSE(
dir
);
188
DISPOSE(
file
);
189
return
NULL;
190
}
191
192
p = NULL;
193
len
=
strlen
(
file
);
194
if
(
ac
== 1) {
195
/* Exactly one match -- finish it off. */
196
*
unique
= 1;
197
j
=
strlen
(
av
[0]) -
len
+ 2;
198
if
((p = NEW(
char
,
j
+ 1)) != NULL) {
199
COPYFROMTO(p,
av
[0] +
len
,
j
);
200
if
((
neww
= NEW(
char
,
strlen
(
dir
) +
strlen
(
av
[0]) + 2)) != NULL) {
201
(
void
)
strcpy
(
neww
,
dir
);
202
(
void
)
strcat
(
neww
,
"/"
);
203
(
void
)
strcat
(
neww
,
av
[0]);
204
rl_add_slash(
neww
, p);
205
DISPOSE(
neww
);
206
}
207
}
208
}
209
else
{
210
*
unique
= 0;
211
if
(
len
) {
212
/* Find largest matching substring. */
213
for
(i =
len
, end =
strlen
(
av
[0]); i < end; i++)
214
for
(
j
= 1;
j
<
ac
;
j
++)
215
if
(
av
[0][i] !=
av
[
j
][i])
216
goto
breakout
;
217
breakout
:
218
if
(i >
len
) {
219
j
= i -
len
+ 1;
220
if
((p = NEW(
char
,
j
)) != NULL) {
221
COPYFROMTO(p,
av
[0] +
len
,
j
);
222
p[
j
- 1] =
'\0'
;
223
}
224
}
225
}
226
}
227
228
/* Clean up and return. */
229
DISPOSE(
dir
);
230
DISPOSE(
file
);
231
for
(i = 0; i <
ac
; i++)
232
DISPOSE(
av
[i]);
233
DISPOSE(
av
);
234
return
p;
235
}
236
237
/*
238
** Return all possible completions.
239
*/
240
int
rl_list_possib(
char
*
pathname
,
char
***
avp
)
241
{
242
char
*
dir
;
243
char
*
file
, *path, *
tt
;
244
int
ac
,i;
245
246
if
(SplitPath(
pathname
, &
dir
, &
file
) < 0)
247
return
0;
248
ac
= FindMatches(
dir
,
file
,
avp
);
249
/* Identify directories with trailing / */
250
for
(i = 0; i <
ac
; i++)
251
{
252
path = walloc(
char
,
strlen
(
dir
)+
strlen
((*
avp
)[i])+3);
253
sprintf
(path,
"%s/%s"
,
dir
,(*
avp
)[i]);
254
if
(el_is_directory(path))
255
{
256
tt
= walloc(
char
,
strlen
((*
avp
)[i])+2);
257
sprintf
(
tt
,
"%s/"
,(*
avp
)[i]);
258
wfree((*
avp
)[i]);
259
(*avp)[i] =
tt
;
260
}
261
wfree(path);
262
}
263
DISPOSE(
dir
);
264
DISPOSE(
file
);
265
return
ac
;
266
}
EST_Hash_Pair
Definition
EST_THash.h:75
siod
el_complete.c
Generated on Wed Jan 29 2025 14:56:50 for Edinburgh Speech Tools by
1.9.8