6 longestprefixlength(char *a, char *b, int n)
12 w = chartorune(&ra, a);
23 freecompletion(Completion *c)
32 strpcmp(const void *va, const void *vb)
42 complete(char *dir, char *s)
44 long i, l, n, nfile, len, nbytes;
51 if(strchr(s, '/') != nil){
52 werrstr("slash character in name argument to complete()");
56 fd = open(dir, OREAD);
60 n = dirreadall(fd, &dirp);
66 /* find longest string, for allocation */
69 l = strlen(dirp[i].name) + 1 + 1; /* +1 for / +1 for \0 */
74 name = malloc(n*sizeof(char*));
75 mode = malloc(n*sizeof(ulong));
76 c = malloc(sizeof(Completion) + len);
77 if(name == nil || mode == nil || c == nil)
79 memset(c, 0, sizeof(Completion));
81 /* find the matches */
86 if(strncmp(s, dirp[i].name, len) == 0){
87 name[nfile] = dirp[i].name;
88 mode[nfile] = dirp[i].mode;
89 if(minlen > strlen(dirp[i].name))
90 minlen = strlen(dirp[i].name);
95 /* report interesting results */
96 /* trim length back to longest common initial string */
97 for(i=1; i<nfile; i++)
98 minlen = longestprefixlength(name[0], name[i], minlen);
100 /* build the answer */
101 c->complete = (nfile == 1);
102 c->advance = c->complete || (minlen > len);
103 c->string = (char*)(c+1);
104 memmove(c->string, name[0]+len, minlen-len);
106 c->string[minlen++ - len] = (mode[0]&DMDIR)? '/' : ' ';
107 c->string[minlen - len] = '\0';
110 /* no match, so return all possible strings */
112 name[i] = dirp[i].name;
113 mode[i] = dirp[i].mode;
119 /* attach list of names */
120 nbytes = nfile * sizeof(char*);
121 for(i=0; i<nfile; i++)
122 nbytes += strlen(name[i]) + 1 + 1;
123 c->filename = malloc(nbytes);
124 if(c->filename == nil)
126 p = (char*)(c->filename + nfile);
127 for(i=0; i<nfile; i++){
136 qsort(c->filename, c->nfile, sizeof(c->filename[0]), strpcmp);