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

📄 list.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <regexp.h>#include <libsec.h>#include <String.h>#include <bio.h>#include "dat.h"int debug;enum{	Tregexp=	(1<<0),		/* ~ */	Texact=		(1<<1),		/* = */};typedef struct Pattern Pattern;struct Pattern{	Pattern	*next;	int	type;	char	*arg;	int	bang;};String	*patternpath;Pattern	*patterns;String	*mbox;static voidusage(void){	fprint(2, "usage: %s add|check patternfile [addressfile ...]\n", argv0);	exits("usage");}/* *  convert string to lower case */static voidmklower(char *p){	int c;	for(; *p; p++){		c = *p;		if(c <= 'Z' && c >= 'A')			*p = c - 'A' + 'a';	}}/* *  simplify an address, reduce to a domain */static String*simplify(char *addr){	int dots;	char *p, *at;	String *s;	mklower(addr);	at = strchr(addr, '@');	if(at == nil){		/* local address, make it an exact match */		s = s_copy("=");		s_append(s, addr);		return s;	}	/* copy up to the '@' sign */	at++;	s = s_copy("~");	for(p = addr; p < at; p++){		if(strchr(".*+?(|)\\[]^$", *p))			s_putc(s, '\\');		s_putc(s, *p);	}	/* just any address matching the two most significant domain elements */	s_append(s, "(.*\\.)?");	p = addr+strlen(addr);	dots = 0;	for(; p > at; p--){		if(*p != '.')			continue;		if(dots++ > 0){			p++;			break;		}	}	for(; *p; p++){		if(strchr(".*+?(|)\\[]^$", *p) != 0)			s_putc(s, '\\');		s_putc(s, *p);	}	s_terminate(s);	return s;}/* *  link patterns in order */static intnewpattern(int type, char *arg, int bang){	Pattern *p;	static Pattern *last;	mklower(arg);	p = mallocz(sizeof *p, 1);	if(p == nil)		return -1;	if(type == Tregexp){		p->arg = malloc(strlen(arg)+3);		if(p->arg == nil){			free(p);			return -1;		}		p->arg[0] = 0;		strcat(p->arg, "^");		strcat(p->arg, arg);		strcat(p->arg, "$");	} else {		p->arg = strdup(arg);		if(p->arg == nil){			free(p);			return -1;		}	}	p->type = type;	p->bang = bang;	if(last == nil)		patterns = p;	else		last->next = p;	last = p;	return 0;}/* *  patterns are either *	~ regular expression *	= exact match string * *  all comparisons are case insensitive */static intreadpatterns(char *path){	Biobuf *b;	char *p;	char *token[2];	int n;	int bang;	b = Bopen(path, OREAD);	if(b == nil)		return -1;	while((p = Brdline(b, '\n')) != nil){		p[Blinelen(b)-1] = 0;		n = tokenize(p, token, 2);		if(n == 0)			continue;		mklower(token[0]);		p = token[0];		if(*p == '!'){			p++;			bang = 1;		} else			bang = 0;		if(*p == '='){			if(newpattern(Texact, p+1, bang) < 0)				return -1;		} else if(*p == '~'){			if(newpattern(Tregexp, p+1, bang) < 0)				return -1;		} else if(strcmp(token[0], "#include") == 0 && n == 2)			readpatterns(token[1]);	}	Bterm(b);	return 0;}/* fuck, shit, bugger, damn */void regerror(char*){}/* *  check lower case version of address agains patterns */static Pattern*checkaddr(char *arg){	Pattern *p;	Reprog *rp;	String *s;	s = s_copy(arg);	mklower(s_to_c(s));	for(p = patterns; p != nil; p = p->next)		switch(p->type){		case Texact:			if(strcmp(p->arg, s_to_c(s)) == 0){				free(s);				return p;			}			break;		case Tregexp:			rp = regcomp(p->arg);			if(rp == nil)				continue;			if(regexec(rp, s_to_c(s), nil, 0)){				free(rp);				free(s);				return p;			}			free(rp);			break;		}	s_free(s);	return 0;}static char*check(int argc, char **argv){	int i;	Addr *a;	Pattern *p;	int matchedbang;	matchedbang = 0;	for(i = 0; i < argc; i++){		a = readaddrs(argv[i], nil);		for(; a != nil; a = a->next){			p = checkaddr(a->val);			if(p == nil)				continue;			if(p->bang)				matchedbang = 1;			else				return nil;		}	}	if(matchedbang)		return "!match";	else		return "no match";}/* *  add anything that isn't already matched, all matches are lower case */static char*add(char *pp, int argc, char **argv){	int fd, i;	String *s;	char *cp;	Addr *a;	a = nil;	for(i = 0; i < argc; i++)		a = readaddrs(argv[i], a);	fd = open(pp, OWRITE);	seek(fd, 0, 2);	for(; a != nil; a = a->next){		if(checkaddr(a->val))			continue;		s = simplify(a->val);		cp = s_to_c(s);		fprint(fd, "%q\t%q\n", cp, a->val);		if(*cp == '=')			newpattern(Texact, cp+1, 0);		else if(*cp == '~')			newpattern(Tregexp, cp+1, 0);		s_free(s);	}	close(fd);	return nil;	}voidmain(int argc, char **argv){	char *patternpath;	ARGBEGIN {	case 'd':		debug++;		break;	} ARGEND;	quotefmtinstall();	if(argc < 3)		usage();	patternpath = argv[1];	readpatterns(patternpath);	if(strcmp(argv[0], "add") == 0)		exits(add(patternpath, argc-2, argv+2));	else if(strcmp(argv[0], "check") == 0)		exits(check(argc-2, argv+2));	else		usage();}

⌨️ 快捷键说明

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