Annotation of coherent/d/bin/head.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.