|
|
1.1 root 1: #include <stdio.h>
2: #include <signal.h>
3:
4: #define Signal(s, f) if (signal(s, SIG_IGN) != SIG_IGN) (void)signal(s, f)
5:
6: #define PARGVAL ((*argv)[2] ? *argv+2 : --argc ? *++argv : (char *)0)
7:
8: #define PUTI(n) if (debug) fprintf(stderr," %d ",n); \
9: if (index >= indend) index = getind(); \
10: *index++ = 2*(n) + inrange()
11:
12: #define Malloc(type,size) ((type *)malloc((size)*sizeof(type)))
13: #define Realloc(type,ptr,size) ((type *)realloc(ptr,(size)*sizeof(type)))
14:
15: #define NLIST 32
16: #define BSIZE 4096
17: #define ISIZE 1024
18:
19: typedef struct Range {
20: int lo, hi;
21: } Range;
22:
23: char *buf, *malloc(), *realloc(), tmpnam[32];
24:
25: int indsize, bufsiz, nchsrc, infd, outfd, sighup();
26:
27: Range *olist, *oindex; int nolist, npages;
28:
29: long *indbase, *indend, *index;
30:
31: main(argc,argv)
32: int argc; char **argv;
33: {
34: register int nchin, lcount, nlflag; register char *src;
35: long *getind(); int nlpage = 66, dcan = 0, termff = 0, debug = 0;
36:
37: Signal(SIGHUP, sighup);
38: Signal(SIGINT, sighup);
39: Signal(SIGQUIT, sighup);
40: Signal(SIGPIPE, sighup);
41:
42: if ((buf = malloc(bufsiz = BSIZE)) == NULL)
43: fatal("cannot malloc buf","");
44:
45: while (--argc > 0 && (*++argv)[0] == '-' && (*argv)[1])
46: switch ((*argv)[1]) {
47: case 'd':
48: dcan++; break;
49: case 'f':
50: termff++; break;
51: case 'l':
52: nlpage = atoi(PARGVAL); break;
53: case 'o':
54: minuso(PARGVAL); break;
55: case 'D':
56: debug++; break;
57: default:
58: fatal("unknown option ",*argv);
59: }
60: ++argc; --argv;
61:
62: if (debug) {
63: register Range *l;
64: for (l=olist; l->lo < l->hi; l++)
65: fprintf(stderr, "[%d, %d)\n", l->lo, l->hi);
66: }
67:
68: if ((infd = (argc > 1) ? Open(&argc, &argv) : 0) < 0)
69: exit(0);
70:
71: if ((outfd = creat(mktemp(strcpy(tmpnam,"/tmp/revpXXXXXX")),0644)) < 0)
72: fatal("cannot open ",tmpnam);
73:
74: lcount = nchin = nlflag = 0;
75: if (!dcan) { PUTI(0); }
76: for (;;) {
77: while ((nchsrc = read(infd, buf, bufsiz)) <= 0) {
78: if (infd) close(infd);
79: infd = Open(&argc,&argv);
80: if (infd < 0) break;
81: }
82: if (nchsrc <= 0) break;
83: write(outfd, buf, nchsrc);
84: src = buf;
85: if (!dcan) do switch (*src++) {
86: case '\n':
87: ++nchin;
88: if (++lcount >= nlpage) {
89: PUTI(nchin);
90: lcount = 0; nlflag++;
91: }
92: break;
93: case '\014':
94: nchin++;
95: if (!nlflag) {
96: if (nchin) { PUTI(nchin); }
97: lcount = 0;
98: }
99: nlflag = 0;
100: break;
101: default:
102: nlflag = 0;
103: nchin++;
104: } while (--nchsrc > 0);
105: else do switch (*src++) {
106: case '\n':
107: if (lcount > 2) { PUTI(nlflag); }
108: nlflag = ++nchin;
109: lcount = 1;
110: break;
111: case 'p':
112: if (lcount == 1) lcount++;
113: else lcount = 0;
114: ++nchin;
115: break;
116: case '0':
117: case '1':
118: case '2':
119: case '3':
120: case '4':
121: case '5':
122: case '6':
123: case '7':
124: case '8':
125: case '9':
126: if (lcount >= 2) lcount++;
127: else lcount = 0;
128: ++nchin;
129: break;
130: default:
131: lcount = 0;
132: ++nchin;
133: } while (--nchsrc > 0);
134: }
135: if (!dcan && termff && lcount != 0) {
136: write(outfd,"\014",1);
137: nchin++;
138: }
139: if (dcan || !nlflag) { PUTI(nchin); }
140: close(outfd); outfd = 1;
141: if ((infd = open(tmpnam,0)) < 0)
142: fatal("cannot reopen ",tmpnam);
143:
144: if (dcan) {
145: nchin = *indbase/2;
146: while (nchin > bufsiz)
147: if ((buf = realloc(buf,bufsiz += BSIZE)) == NULL)
148: fatal("cannot realloc buffer","");
149: read(infd,buf,nchin);
150: write(outfd,buf,nchin);
151: }
152:
153: if (debug) fprintf(stderr,"\n");
154: while (--index > indbase) {
155: if (*(index-1) % 2 == 0)
156: continue;
157: nchin = *index/2 - *(index-1)/2;
158: while (nchin > bufsiz)
159: if ((buf = realloc(buf,bufsiz += BSIZE)) == NULL)
160: fatal("cannot realloc buffer","");
161: if (debug) fprintf(stderr,"(%d,%d) ",*(index-1)/2,nchin);
162: if (nchin > 0) {
163: lseek(infd, *(index-1)/2, 0);
164: read(infd,buf,nchin);
165: write(outfd,buf,nchin);
166: }
167: }
168:
169: close(infd);
170: unlink(tmpnam);
171: exit(0);
172: }
173:
174: minuso(str)
175: char *str;
176: {
177: register int dash = 0, i = 0, lo = 0, c;
178:
179: do switch (c = *str++) {
180: case '0':
181: case '1':
182: case '2':
183: case '3':
184: case '4':
185: case '5':
186: case '6':
187: case '7':
188: case '8':
189: case '9':
190: i = 10*i + c - '0';
191: break;
192: case '-':
193: ++dash; lo = i; i = 0;
194: break;
195: case ',':
196: case '\0':
197: merge(dash ? lo : i, i);
198: dash = lo = i = 0;
199: break;
200: } while (c);
201: }
202:
203: merge(lo,hi)
204: {
205: Range new, temp; register Range *source, *dest;
206:
207: if (lo == 0) lo = 1;
208: if (hi == 0) hi = 99999;
209:
210: if (lo <= hi) {
211: new.lo = lo; new.hi = hi + 1;
212: } else {
213: new.lo = hi; new.hi = lo + 1;
214: }
215: if (olist == 0) {
216: olist = oindex = Malloc(Range, nolist = NLIST);
217: olist->lo = 0;
218: olist->hi = -1;
219: }
220: for (dest=source=olist;;) {
221: if (source->lo >= source->hi) {
222: *dest++ = new;
223: dest->lo = 0;
224: dest->hi = -1;
225: break;
226: } else if (source->hi < new.lo) {
227: *dest++ = *source++;
228: } else if (new.hi < source->lo) {
229: temp = *source++;
230: *dest++ = new;
231: new = temp;
232: } else {
233: temp.lo = min(new.lo, source->lo);
234: temp.hi = max(new.hi, source->hi);
235: new = temp;
236: source++;
237: }
238: }
239: if (dest - olist >= nolist)
240: olist = Realloc(Range, olist, nolist += NLIST);
241: }
242:
243: inrange()
244: {
245: ++npages;
246: if (olist == 0)
247: return 1;
248: if (oindex == 0)
249: return 0;
250: for (; oindex->lo < oindex->hi; oindex++) {
251: if (npages < oindex->lo)
252: return 0;
253: if (npages < oindex->hi)
254: return 1;
255: }
256: oindex = 0;
257: return 0;
258: }
259:
260: Open(pargc,pargv)
261: int *pargc; char ***pargv;
262: {
263: int infd = -1;
264: while (--(*pargc) > 0) {
265: if (strcmp("-",*++(*pargv)) == 0) infd = 0;
266: else infd = open(**pargv,0);
267: if (infd >= 0) break;
268: fprintf(stderr,"cannot open %s\n",**pargv);
269: fflush(stderr);
270: }
271: return infd;
272: }
273:
274: long *
275: getind()
276: {
277: register long *index;
278: if (indsize == 0)
279: indbase = Malloc(long, ISIZE);
280: else
281: indbase = Realloc(long, indbase, indsize+ISIZE);
282: if (indbase == (long *)0)
283: fatal("cannot allocate index","");
284: index = indbase + indsize;
285: indsize += ISIZE;
286: indend = indbase + indsize;
287: return index;
288: }
289:
290: fatal(str1,str2)
291: char *str1, *str2;
292: {
293: fprintf(stderr,"%s%s\n",str1,str2);
294: if (tmpnam[0]) unlink(tmpnam);
295: exit(1);
296: }
297:
298: sighup(s)
299: {
300: if (tmpnam[0]) unlink(tmpnam);
301: exit(1);
302: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.