#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");}
#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);
void
main(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);
}
int
nextfile(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;
}
int
matchfile(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();
}
void
openf(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;
}
void
usage(void)
{
fprint(2, "usage: split [-n num] [-e exp] [-f stem] [-s suff] [-x] [-i] [file]\n");
exits("usage");
}
void
badexp(void)
{
fprint(2, "split: bad regular expression\n");
exits("bad regular expression");
}