|
|
researchv10 Norman
#include <fio.h>
#include <regexp.h>
#include <string.h>
#include <libc.h>
enum { nofile = -1, stdin, stdout, stderr };
char digit[] = "0123456789";
char *suffix = "";
char *stem = "x";
char suff[] = "aa";
char name[200];
int output = nofile;
char *fold(), *slashfix();
main(argc, argv)
char **argv;
{
regexp *exp = 0;
char *pattern = 0;
register n = 1000;
char *line;
int xflag = 0;
int iflag = 0;
for( ; argc>1 && argv[1][0]=='-'; ++argv, --argc) {
if(strchr(digit, argv[1][1])) {
if((n=atoi(&argv[1][1])) <= 0) {
Fprint(stderr,"split: n not positive\n");
exit(1);
}
} else switch(argv[1][1]) {
default:
usage();
case 'n':
if(++argv, --argc<=1)
usage();
n=atoi(argv[1]);
break;
case 'e':
if(++argv, --argc<=1)
usage();
pattern = slashfix(argv[1]);
break;
case 'f':
if(++argv, --argc<=1)
usage();
stem = strdup(argv[1]);
break;
case 's':
if(++argv, --argc<=1)
usage();
suffix = strdup(argv[1]);
break;
case 'x':
xflag++;
break;
case 'y':
Fprint(stderr,"split: -y obsolete; -i assumed\n");
case 'i':
iflag++;
break;
}
}
if(argc > 2)
usage();
if(argc > 1) {
close(stdin);
if(open(argv[1], 0) != stdin) {
Fprint(stderr,"split: cannot open %s\n",argv[1]);
exit(1);
}
}
if(pattern) {
if(!(exp = regcomp(iflag? fold(pattern): pattern)))
badexp();
while((line=Frdline(stdin)) != 0) {
regsubexp match[2];
if(regexec(exp,iflag?fold(line):line,match,2)) {
if(matchfile(match) && xflag)
continue;
} else if(output == nofile)
nextfile(); /* at most once */
Fwrite(output, line, FIOLINELEN(stdin));
Fputc(output, '\n');
}
} else {
register linecnt = n;
while((line=Frdline(stdin)) != 0) {
if(++linecnt > n) {
nextfile();
linecnt = 1;
}
Fwrite(output, line, FIOLINELEN(stdin));
Fputc(output, '\n');
}
}
return 0;
}
nextfile()
{
static canopen = 1;
if(suff[0] > 'z') {
if(canopen)
Fprint(stderr,"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;
}
matchfile(match)
regsubexp *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();
}
openf()
{
Fflush(output);
close(output);
if((output=creat(name,0666)) == -1) {
Fprint(stderr, "split: cannot open %s\n",name);
exit(1);
}
Finit(output,(char*)0);
}
char *
fold(s)
char *s;
{
static char *fline;
char *t;
if(fline==0)
fline = malloc(FIOBSIZE);
for(t=fline; *t++=tolower(*s++); )
continue;
return fline;
}
/* Convert from grep to egrep syntax. Grep special casing like
initial * will yield badexp() */
char *
slashfix(s)
register char *s;
{
char *u = malloc(2*strlen(s));
register char *t = u;
for( ; *t = *s; t++, s++) {
if(strchr("()+?|", *s))
*t = '\\', *++t = *s;
else if(*s=='\\' && s[1])
if(strchr(digit,s[1]))
badexp();
else if(strchr("()",s[1]))
*t = *++s;
else
*++t = *++s;
}
return u;
}
usage()
{
Fprint(stderr, "usage: split [-n num] [-e exp] [-f stem] [-s suff] [-x] [-y] [file]\n");
exit(1);
}
badexp()
{
Fprint(stderr, "split: bad regular expression\n");
exit(1);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.