|
|
1.1 root 1: #include <fio.h>
2: #include <regexp.h>
3: #include <string.h>
4: #include <libc.h>
5:
6: enum { nofile = -1, stdin, stdout, stderr };
7:
8: char digit[] = "0123456789";
9: char *suffix = "";
10: char *stem = "x";
11: char suff[] = "aa";
12: char name[200];
13: int output = nofile;
14:
15: char *fold(), *slashfix();
16:
17: main(argc, argv)
18: char **argv;
19: {
20: regexp *exp = 0;
21: char *pattern = 0;
22: register n = 1000;
23: char *line;
24: int xflag = 0;
25: int iflag = 0;
26:
27: for( ; argc>1 && argv[1][0]=='-'; ++argv, --argc) {
28: if(strchr(digit, argv[1][1])) {
29: if((n=atoi(&argv[1][1])) <= 0) {
30: Fprint(stderr,"split: n not positive\n");
31: exit(1);
32: }
33: } else switch(argv[1][1]) {
34: default:
35: usage();
36: case 'n':
37: if(++argv, --argc<=1)
38: usage();
39: n=atoi(argv[1]);
40: break;
41: case 'e':
42: if(++argv, --argc<=1)
43: usage();
44: pattern = slashfix(argv[1]);
45: break;
46: case 'f':
47: if(++argv, --argc<=1)
48: usage();
49: stem = strdup(argv[1]);
50: break;
51: case 's':
52: if(++argv, --argc<=1)
53: usage();
54: suffix = strdup(argv[1]);
55: break;
56: case 'x':
57: xflag++;
58: break;
59: case 'y':
60: Fprint(stderr,"split: -y obsolete; -i assumed\n");
61: case 'i':
62: iflag++;
63: break;
64: }
65: }
66: if(argc > 2)
67: usage();
68: if(argc > 1) {
69: close(stdin);
70: if(open(argv[1], 0) != stdin) {
71: Fprint(stderr,"split: cannot open %s\n",argv[1]);
72: exit(1);
73: }
74: }
75: if(pattern) {
76: if(!(exp = regcomp(iflag? fold(pattern): pattern)))
77: badexp();
78: while((line=Frdline(stdin)) != 0) {
79: regsubexp match[2];
80: if(regexec(exp,iflag?fold(line):line,match,2)) {
81: if(matchfile(match) && xflag)
82: continue;
83: } else if(output == nofile)
84: nextfile(); /* at most once */
85: Fwrite(output, line, FIOLINELEN(stdin));
86: Fputc(output, '\n');
87: }
88: } else {
89: register linecnt = n;
90: while((line=Frdline(stdin)) != 0) {
91: if(++linecnt > n) {
92: nextfile();
93: linecnt = 1;
94: }
95: Fwrite(output, line, FIOLINELEN(stdin));
96: Fputc(output, '\n');
97: }
98: }
99: return 0;
100: }
101:
102: nextfile()
103: {
104: static canopen = 1;
105: if(suff[0] > 'z') {
106: if(canopen)
107: Fprint(stderr,"split: file %szz not split\n",stem);
108: canopen = 0;
109: } else {
110: strcpy(name, stem);
111: strcat(name, suff);
112: if(++suff[1] > 'z')
113: suff[1] = 'a', ++suff[0];
114: openf();
115: }
116: return canopen;
117: }
118:
119: matchfile(match)
120: regsubexp *match;
121: {
122: if(match[1].sp) {
123: int len = match[1].ep - match[1].sp;
124: strncpy(name, match[1].sp, len);
125: strcpy(name+len, suffix);
126: openf();
127: return 1;
128: }
129: return nextfile();
130: }
131:
132: openf()
133: {
134: Fflush(output);
135: close(output);
136: if((output=creat(name,0666)) == -1) {
137: Fprint(stderr, "split: cannot open %s\n",name);
138: exit(1);
139: }
140: Finit(output,(char*)0);
141: }
142:
143: char *
144: fold(s)
145: char *s;
146: {
147: static char *fline;
148: char *t;
149: if(fline==0)
150: fline = malloc(FIOBSIZE);
151: for(t=fline; *t++=tolower(*s++); )
152: continue;
153: return fline;
154: }
155:
156: /* Convert from grep to egrep syntax. Grep special casing like
157: initial * will yield badexp() */
158: char *
159: slashfix(s)
160: register char *s;
161: {
162: char *u = malloc(2*strlen(s));
163: register char *t = u;
164: for( ; *t = *s; t++, s++) {
165: if(strchr("()+?|", *s))
166: *t = '\\', *++t = *s;
167: else if(*s=='\\' && s[1])
168: if(strchr(digit,s[1]))
169: badexp();
170: else if(strchr("()",s[1]))
171: *t = *++s;
172: else
173: *++t = *++s;
174: }
175: return u;
176: }
177:
178: usage()
179: {
180: Fprint(stderr, "usage: split [-n num] [-e exp] [-f stem] [-s suff] [-x] [-y] [file]\n");
181: exit(1);
182: }
183:
184: badexp()
185: {
186: Fprint(stderr, "split: bad regular expression\n");
187: exit(1);
188: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.