⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 complete.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include "complete.h"static intlongestprefixlength(char *a, char *b, int n){	int i, w;	Rune ra, rb;	for(i=0; i<n; i+=w){		w = chartorune(&ra, a);		chartorune(&rb, b);		if(ra != rb)			break;		a += w;		b += w;	}	return i;}voidfreecompletion(Completion *c){	if(c){		free(c->filename);		free(c);	}}static intstrpcmp(const void *va, const void *vb){	char *a, *b;	a = *(char**)va;	b = *(char**)vb;	return strcmp(a, b);}Completion*complete(char *dir, char *s){	long i, l, n, nfile, len, nbytes;	int fd, minlen;	Dir *dirp;	char **name, *p;	ulong* mode;	Completion *c;	if(strchr(s, '/') != nil){		werrstr("slash character in name argument to complete()");		return nil;	}	fd = open(dir, OREAD);	if(fd < 0)		return nil;	n = dirreadall(fd, &dirp);	if(n <= 0){		close(fd);		return nil;	}	/* find longest string, for allocation */	len = 0;	for(i=0; i<n; i++){		l = strlen(dirp[i].name) + 1 + 1; /* +1 for /   +1 for \0 */		if(l > len)			len = l;	}	name = malloc(n*sizeof(char*));	mode = malloc(n*sizeof(ulong));	c = malloc(sizeof(Completion) + len);	if(name == nil || mode == nil || c == nil)		goto Return;	memset(c, 0, sizeof(Completion));	/* find the matches */	len = strlen(s);	nfile = 0;	minlen = 1000000;	for(i=0; i<n; i++)		if(strncmp(s, dirp[i].name, len) == 0){			name[nfile] = dirp[i].name;			mode[nfile] = dirp[i].mode;			if(minlen > strlen(dirp[i].name))				minlen = strlen(dirp[i].name);			nfile++;		}	if(nfile > 0) {		/* report interesting results */		/* trim length back to longest common initial string */		for(i=1; i<nfile; i++)			minlen = longestprefixlength(name[0], name[i], minlen);		/* build the answer */		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;		}		nfile = n;		c->nmatch = 0;	}	/* attach list of names */	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 + nfile);	for(i=0; i<nfile; i++){		c->filename[i] = p;		strcpy(p, name[i]);		p += strlen(p);		if(mode[i] & DMDIR)			*p++ = '/';		*p++ = '\0';	}	c->nfile = nfile;	qsort(c->filename, c->nfile, sizeof(c->filename[0]), strpcmp);  Return:	free(name);	free(mode);	free(dirp);	close(fd);	return c;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -