|
|
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.