aboutsummaryrefslogtreecommitdiff
path: root/src/libcomplete
diff options
context:
space:
mode:
authorrsc <devnull@localhost>2004-02-29 22:10:26 +0000
committerrsc <devnull@localhost>2004-02-29 22:10:26 +0000
commit5a8e63b2f016735364d17866d5e2bcb35d20c78b (patch)
treed5d0ce11e087efaf81c77311bac9d30aed41783d /src/libcomplete
parentd51419bf4397cf13d0c50bf84c125477c6bed307 (diff)
downloadplan9port-5a8e63b2f016735364d17866d5e2bcb35d20c78b.tar.gz
plan9port-5a8e63b2f016735364d17866d5e2bcb35d20c78b.tar.bz2
plan9port-5a8e63b2f016735364d17866d5e2bcb35d20c78b.zip
Fighting the good fight.
Move libfmt, libutf into subdirectories of lib9. Add poll-based socket i/o to libthread, so that we can avoid using multiple procs when possible, thus removing dependence on crappy pthreads implementations. Convert samterm, acme to the single-proc libthread. Bring libcomplete, acme up-to-date w.r.t. Plan 9 distribution.
Diffstat (limited to 'src/libcomplete')
-rw-r--r--src/libcomplete/complete.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/src/libcomplete/complete.c b/src/libcomplete/complete.c
index 3a06447a..6c7c7e67 100644
--- a/src/libcomplete/complete.c
+++ b/src/libcomplete/complete.c
@@ -41,7 +41,7 @@ strpcmp(const void *va, const void *vb)
Completion*
complete(char *dir, char *s)
{
- long i, l, n, nmatch, len, nbytes;
+ long i, l, n, nfile, len, nbytes;
int fd, minlen;
Dir *dirp;
char **name, *p;
@@ -58,8 +58,10 @@ complete(char *dir, char *s)
return nil;
n = dirreadall(fd, &dirp);
- if(n <= 0)
+ if(n <= 0){
+ close(fd);
return nil;
+ }
/* find longest string, for allocation */
len = 0;
@@ -78,49 +80,51 @@ complete(char *dir, char *s)
/* find the matches */
len = strlen(s);
- nmatch = 0;
+ nfile = 0;
minlen = 1000000;
for(i=0; i<n; i++)
if(strncmp(s, dirp[i].name, len) == 0){
- name[nmatch] = dirp[i].name;
- mode[nmatch] = dirp[i].mode;
+ name[nfile] = dirp[i].name;
+ mode[nfile] = dirp[i].mode;
if(minlen > strlen(dirp[i].name))
minlen = strlen(dirp[i].name);
- nmatch++;
+ nfile++;
}
- if(nmatch > 0) {
+ if(nfile > 0) {
/* report interesting results */
/* trim length back to longest common initial string */
- for(i=1; i<nmatch; i++)
+ for(i=1; i<nfile; i++)
minlen = longestprefixlength(name[0], name[i], minlen);
/* build the answer */
- c->complete = (nmatch == 1);
+ c->complete = (nfile == 1);
c->advance = c->complete || (minlen > len);
c->string = (char*)(c+1);
memmove(c->string, name[0]+len, minlen-len);
if(c->complete)
c->string[minlen++ - len] = (mode[0]&DMDIR)? '/' : ' ';
c->string[minlen - len] = '\0';
+ c->nmatch = nfile;
} else {
/* no match, so return all possible strings */
for(i=0; i<n; i++){
name[i] = dirp[i].name;
mode[i] = dirp[i].mode;
}
- nmatch = n;
+ nfile = n;
+ c->nmatch = 0;
}
/* attach list of names */
- nbytes = nmatch * sizeof(char*);
- for(i=0; i<nmatch; i++)
+ nbytes = nfile * sizeof(char*);
+ for(i=0; i<nfile; i++)
nbytes += strlen(name[i]) + 1 + 1;
c->filename = malloc(nbytes);
if(c->filename == nil)
goto Return;
- p = (char*)(c->filename + nmatch);
- for(i=0; i<nmatch; i++){
+ p = (char*)(c->filename + nfile);
+ for(i=0; i<nfile; i++){
c->filename[i] = p;
strcpy(p, name[i]);
p += strlen(p);
@@ -128,12 +132,13 @@ complete(char *dir, char *s)
*p++ = '/';
*p++ = '\0';
}
- c->nfile = nmatch;
+ c->nfile = nfile;
qsort(c->filename, c->nfile, sizeof(c->filename[0]), strpcmp);
Return:
free(name);
free(mode);
free(dirp);
+ close(fd);
return c;
}