|
|
1.1 root 1: static char Copyright[] = "$Copyright: (c) 1984, INETCO Systems, Ltd.$";
2: static char Release[] = "$Release: INETCO COHERENT V8.0$";
3: static char Date[] = "$Date: 91/02/12 10:26:13 $";
4:
5: /* $Header: /newbits/bin/head.c,v 1.1 91/02/12 10:26:13 bin Exp $
6: *
7: * The information contained herein is a trade secret of Mark Williams
8: * Company, and is confidential information. It is provided under a
9: * license agreement, and may be copied or disclosed only under the
10: * terms of that agreement. Any reproduction or disclosure of this
11: * material without the express written authorization of Mark Williams
12: * Company or persuant to the license agreement is unlawful.
13: *
14: * COHERENT Version 2.3.35
15: * Copyright (c) 1982, 1983, 1984.
16: * An unpublished work by Mark Williams Company, Chicago.
17: * All rights reserved.
18: */
19:
20: /*
21: * The program head copys the head of a file to the standard output.
22: * Its usage is:
23: *
24: * head [{+-}n[{lbc}]] [file]
25: *
26: * The initial `+' (or `-') indicate that `n' is relative to the
27: * beggining (or ending respectively) of the file.
28: * The optional `l', `b' or `c' (`l' default) is to indicate if `n'
29: * is a number of lines, blocks or characters respectively.
30: * If the entire position specifier is absent, then `+4l' is assumed.
31: * If the optional `file' is absent, then the standard input is used.
32: * In any case, head copys from the start of the file up to, and
33: * includeing, the specified point onto the standard output.
34: *
35: * $Log: /newbits/bin/head.c,v $
36: * Revision 1.1 91/02/12 10:26:13 bin
37: * Initial revision
38: *
39: * Revision 1.1 89/04/03 13:06:08 src
40: * Initial revision
41: *
42: */
43:
44: #include <stdio.h>
45: #include <ctype.h>
46: #include <sys/mdata.h>
47:
48:
49: #define bool char /* boolean type */
50: #define not ! /* logical negation operator */
51: #define and && /* logical conjunction */
52: #define or || /* logical disjunction */
53: #define TRUE (0 == 0)
54: #define FALSE (not TRUE)
55: #define EOS '\0' /* end-of-string char */
56: #define N 4 /* default number of lines */
57:
58:
59: struct blk {
60: struct blk *next;
61: int nlines; /* number of `\n' characters */
62: char blkb[BUFSIZ];
63: };
64:
65:
66: bool lflag = TRUE, /* lines (vs. chars) flag */
67: fflag = TRUE; /* + (vs. -) flag */
68: long n = N; /* number of lines or chars */
69: char obuf[BUFSIZ], /* stdout setbuf buffer */
70: nospace[] = "Window too large";
71:
72:
73: main(argc, argv)
74: int argc;
75: char *argv[];
76: {
77: setbuf(stdout, obuf);
78: options(argv);
79: if (fflag)
80: if (lflag)
81: copyfl();
82: else
83: copyfc();
84: else
85: if (lflag)
86: copybl();
87: else
88: copybc();
89: return (0);
90: }
91:
92:
93: die(str)
94: char *str;
95: {
96: fprintf(stderr, "%r\n", &str);
97: exit(1);
98: }
99:
100:
101: usage()
102: {
103: die("usage: head [{+-}n[{lbc}]] [file]");
104: }
105:
106:
107: options(argv)
108: register char *argv[];
109: {
110: register char *chp,
111: ch;
112:
113: if (*++argv == NULL)
114: return;
115: chp = *argv;
116: ch = *chp;
117: if (ch == '-' || ch == '+') {
118: fflag = (ch == '+');
119: n = 0;
120: for (ch=*++chp; isascii(ch) && isdigit(ch); ch=*++chp)
121: n = 10*n + ch-'0';
122: switch (ch) {
123: case EOS:
124: case 'l':
125: break;
126: case 'b':
127: n *= BUFSIZ;
128: /* fall thru */
129: case 'c':
130: lflag = FALSE;
131: break;
132: default:
133: usage();
134: }
135: chp = *++argv;
136: }
137: if (chp == NULL)
138: return;
139: if (freopen(chp, "r", stdin) == NULL)
140: die("Can't open %s", chp);
141: }
142:
143:
144: /*
145: * Copyfl copys the first `n' lines of stdin to stdout.
146: */
147: copyfl()
148: {
149: register int ch;
150:
151: while (--n >= 0)
152: do {
153: ch = getchar();
154: if (ch == EOF)
155: return;
156: putchar(ch);
157: } while (ch != '\n');
158: }
159:
160:
161: /*
162: * Copyfc copys the first `n' characters of stdin to stdout.
163: */
164: copyfc()
165: {
166: register int ch;
167:
168: for (ch=getchar(); --n >= 0 && ch != EOF; ch=getchar())
169: putchar(ch);
170: }
171:
172:
173: /*
174: * Copybc copys all but the last `n' characters of stdin to stdout.
175: */
176: copybc()
177: {
178: register char *buf,
179: *chp,
180: *limit;
181: char ch;
182: unsigned len;
183:
184: if (n > MAXUINT)
185: die(nospace);
186: len = n;
187: buf = (char *)malloc(len);
188: if (buf == NULL)
189: die(nospace);
190: len = fread(buf, sizeof *buf, len, stdin);
191: if (len < n) {
192: fwrite(buf, sizeof *buf, len, stdout);
193: free(buf);
194: return;
195: }
196: limit = buf + len;
197: for (chp=buf; (ch=getchar()) != EOF;) {
198: putchar(*chp);
199: *chp++ = ch;
200: if (chp == limit)
201: chp = buf;
202: }
203: }
204:
205:
206: /*
207: * Copybl copys all but the last `n' lines of stdin to stdout.
208: */
209: copybl()
210: {
211: register struct blk *bp;
212: register char *chp;
213: register int extra;
214: int len;
215: struct blk **tail,
216: *head;
217:
218: if (n > MAXINT)
219: die(nospace);
220: extra = -n;
221: for (tail=&head;;) {
222: len = getblk(tail);
223: bp = *tail;
224: tail = &bp->next;
225: extra += bp->nlines;
226: for (bp=head; extra > bp->nlines; bp=bp->next) {
227: extra -= bp->nlines;
228: fwrite(bp->blkb, sizeof *bp->blkb, BUFSIZ, stdout);
229: free(bp);
230: }
231: head = bp;
232: if (len < BUFSIZ)
233: break;
234: }
235: for (bp=head, chp=bp->blkb; extra > 0; --extra)
236: while (*chp++ != '\n')
237: ;
238: fwrite(bp->blkb, sizeof *bp->blkb, chp-bp->blkb, stdout);
239: }
240:
241:
242: /*
243: * Getblk allocates a blk, reads text into it and sets the nlines
244: * field. It returns the number of characters read. It sets `bpp'
245: * to point to the block. If the block could not be allocated, then
246: * it dies with the appropriate error message.
247: */
248: getblk(bpp)
249: struct blk **bpp;
250: {
251: register struct blk *bp;
252: register int len;
253:
254: bp = (struct blk *)malloc(sizeof *bp);
255: if (bp == NULL)
256: die(nospace);
257: *bpp = bp;
258: len = fread(bp->blkb, sizeof *bp->blkb, BUFSIZ, stdin);
259: bp->nlines = cntlines(bp->blkb, len);
260: return (len);
261: }
262:
263:
264: /*
265: * Cntlines returns the number of '\n' characters in the char array
266: * `chp' with length `len'.
267: */
268: cntlines(chp, len)
269: register char *chp;
270: int len;
271: {
272: register char *limit;
273: register int res;
274:
275: for (res=0, limit=&chp[len]; chp < limit;)
276: if (*chp++ == '\n')
277: ++res;
278: return (res);
279: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.