henesyinit from p9fd787fda5 years agoHistory
187 lines · 3.1 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <bio.h>#include <regexp.h> char	digit[] = "0123456789";char	*suffix = "";char	*stem = "x";char	suff[] = "aa";char	name[200];Biobuf	bout;Biobuf	*output = &bout; extern int nextfile(void);extern int matchfile(Resub*);extern void openf(void);extern char *fold(char*,int);extern void usage(void);extern void badexp(void); voidmain(int argc, char *argv[]){	Reprog *exp;	char *pattern = 0;	int n = 1000;	char *line;	int xflag = 0;	int iflag = 0;	Biobuf bin;	Biobuf *b = &bin;	char buf[256]; 	ARGBEGIN {	case 'n':		n=atoi(EARGF(usage()));		break;	case 'e':		pattern = strdup(EARGF(usage()));		break;	case 'f':		stem = strdup(EARGF(usage()));		break;	case 's':		suffix = strdup(EARGF(usage()));		break;	case 'x':		xflag++;		break;	case 'i':		iflag++;		break;	default:		usage();		break; 	} ARGEND; 	if(argc < 0 || argc > 1)		usage(); 	if(argc != 0) {		b = Bopen(argv[0], OREAD);		if(b == nil) {			fprint(2, "split: can't open %s: %r\n", argv[0]);			exits("open");		}	} else		Binit(b, 0, OREAD); 	if(pattern) {		if(!(exp = regcomp(iflag? fold(pattern,strlen(pattern)): pattern)))			badexp();		while((line=Brdline(b,'\n')) != 0) {			Resub match[2];			memset(match, 0, sizeof match);			line[Blinelen(b)-1] = 0;			if(regexec(exp,iflag?fold(line,Blinelen(b)-1):line,match,2)) {				if(matchfile(match) && xflag)					continue;			} else if(output == 0)				nextfile();	/* at most once */			Bwrite(output, line, Blinelen(b)-1);			Bputc(output, '\n');		}	} else {		int linecnt = n; 		while((line=Brdline(b,'\n')) != 0) {			if(++linecnt > n) {				nextfile();				linecnt = 1;			}			Bwrite(output, line, Blinelen(b));		} 		/*		 * in case we didn't end with a newline, tack whatever's 		 * left onto the last file		 */		while((n = Bread(b, buf, sizeof(buf))) > 0)			Bwrite(output, buf, n);	}	if(b != nil)		Bterm(b);	exits(0);} intnextfile(void){	static canopen = 1;	if(suff[0] > 'z') {		if(canopen)			fprint(2, "split: file %szz not split\n",stem);		canopen = 0;	} else {		strcpy(name, stem);		strcat(name, suff);		if(++suff[1] > 'z') 			suff[1] = 'a', ++suff[0];		openf();	}	return canopen;} intmatchfile(Resub *match){	if(match[1].sp) {		int len = match[1].ep - match[1].sp;		strncpy(name, match[1].sp, len);		strcpy(name+len, suffix);		openf();		return 1;	} 	return nextfile();} voidopenf(void){	static int fd = 0;	Bflush(output);	Bterm(output);	if(fd > 0)		close(fd);	fd = create(name,OWRITE,0666);	if(fd < 0) {		fprint(2, "grep: can't create %s: %r\n", name);		exits("create");	}	Binit(output, fd, OWRITE);} char *fold(char *s, int n){	static char *fline;	static int linesize = 0;	char *t; 	if(linesize < n+1){		fline = realloc(fline,n+1);		linesize = n+1;	}	for(t=fline; *t++ = tolower(*s++); )		continue;		/* we assume the 'A'-'Z' only appear as themselves		 * in a utf encoding.		 */	return fline;} voidusage(void){	fprint(2, "usage: split [-n num] [-e exp] [-f stem] [-s suff] [-x] [-i] [file]\n");	exits("usage");} voidbadexp(void){	fprint(2, "split: bad regular expression\n");	exits("bad regular expression");}