|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T v
Length: 8533 (0x2155) Types: TextFile Names: »vitals.c«
└─⟦db229ac7e⟧ Bits:30007240 EUUGD20: SSBA 1.2 / AFW Benchmarks └─⟦this⟧ »EUUGD20/AFUU-ssba1.21/ssba1.21E/vitals.c« └─⟦this⟧ »EUUGD20/AFUU-ssba1.21/ssba1.21F/vitals.c«
static char *HPUX_ID = "@(#)27.1 85/02/04"; /* HPUX_ID: @(#)vitals.c 27.1 85/02/04 */ /* * Compute vital statistics of data: crc, sum, line, word, and character * counts. See the manual entry for details. * * Compile with -DTABLE to produce an alternate program, which prints a * CRC table for use in this program. * * The CRC code was lifted from a USENET posting: * * hpfcla:net.sources / hcrvax!sft / 8:17 pm Nov 15, 1984 * * The following program is a command to calculate the CRC of files. * It is useful for the same purposes as sum(1). It calculates the * true CRC16 (unlike CP/M utilities that say they calculate CRCs * but really just hash). Crc detects more errors than old sum(1); * for example, it detects exchanges of characters. It is also * (now) in the public domain. * * CRC16 polynomial: x**0 + x**2 + x**15 + x**16 (0xA001) * (CCITT polynomial: x**0 + x**5 + x**12 + x**16 (0x8408)) * Initial condition: 0 * * D. Hugh Redelmeier, 1983 April 15; latest change: 1984 April 2. */ #include <stdio.h> char *USAGE = "usage: %s [-rslwcb] [files...]\n"; #define proc /* null; easy to grep for procs */ #define chNull ('\0') #define chNewline ('\n') #define sbNull ((char *) NULL) #define fileNull ((FILE *) NULL) #define false 0 #define true 1 char *myname; /* how command invoked */ int rflag = false; /* -r (crc) option */ int sflag = false; /* -s (sum) option */ int lflag = false; /* -l (lines) option */ int wflag = false; /* -w (words) option */ int cflag = false; /* -c (chars) option */ int bflag = false; /* -b (basenames) opt */ int retval = 0; /* return value */ char *defaultargs[] = {"-", sbNull}; /* read stdin by default */ #define PrintErr(part1,part2) \ fprintf (stderr, "%s: %s %s\n", myname, part1, part2); /************************************************************************ * M A I N * * Initialize, check arguments, open files, and call another routine to * do each file. */ proc main (argc, argv) register int argc; register char **argv; { extern int optind; /* for getopt() */ int optchar; /* from getopt() */ register FILE *filep; /* file to read */ /* * CHECK ARGUMENTS: */ myname = *argv; while ((optchar = getopt (argc, argv, "rslwcb")) != EOF) switch (optchar) { case 'r': rflag = true; break; case 's': sflag = true; break; case 'l': lflag = true; break; case 'w': wflag = true; break; case 'c': cflag = true; break; case 'b': bflag = true; break; default: fprintf (stderr, USAGE, myname); exit (1); } if (! (rflag || sflag || lflag || wflag || cflag)) rflag = sflag = lflag = wflag = cflag = true; argc -= optind; argv += optind; if (argc < 1) /* use default arguments */ argv = defaultargs; /* * OPEN AND DO EACH INPUT FILE: * * Be careful to keep stdin open for filenames of "-". * Argc is not altered; if < 1, it means no file args were given. */ for ( ; *argv != sbNull; argv++) /* each argument */ { if (strcmp (*argv, "-") == 0) /* read stdin */ filep = stdin; else if ((filep = fopen (*argv, "r")) == fileNull) { PrintErr ("can't open", *argv); retval = 1; continue; } DoFile (filep, (argc < 1), *argv); if (filep != stdin) /* keep stdin open for reuse */ fclose (filep); } exit (retval); } /* main */ /************************************************************************ * CRC TABLE AND BYTE SUM STRUCTS * * CRCtable[], output from PrintTable(), is used for CRC calculation. * Structures are used for circular mod-2**16 byte sums. They assume * that two shorts == one long! */ unsigned short CRCtable [256] = { 0x0000, 0xc0c1, 0xc181, 0x0140, 0xc301, 0x03c0, 0x0280, 0xc241, 0xc601, 0x06c0, 0x0780, 0xc741, 0x0500, 0xc5c1, 0xc481, 0x0440, 0xcc01, 0x0cc0, 0x0d80, 0xcd41, 0x0f00, 0xcfc1, 0xce81, 0x0e40, 0x0a00, 0xcac1, 0xcb81, 0x0b40, 0xc901, 0x09c0, 0x0880, 0xc841, 0xd801, 0x18c0, 0x1980, 0xd941, 0x1b00, 0xdbc1, 0xda81, 0x1a40, 0x1e00, 0xdec1, 0xdf81, 0x1f40, 0xdd01, 0x1dc0, 0x1c80, 0xdc41, 0x1400, 0xd4c1, 0xd581, 0x1540, 0xd701, 0x17c0, 0x1680, 0xd641, 0xd201, 0x12c0, 0x1380, 0xd341, 0x1100, 0xd1c1, 0xd081, 0x1040, 0xf001, 0x30c0, 0x3180, 0xf141, 0x3300, 0xf3c1, 0xf281, 0x3240, 0x3600, 0xf6c1, 0xf781, 0x3740, 0xf501, 0x35c0, 0x3480, 0xf441, 0x3c00, 0xfcc1, 0xfd81, 0x3d40, 0xff01, 0x3fc0, 0x3e80, 0xfe41, 0xfa01, 0x3ac0, 0x3b80, 0xfb41, 0x3900, 0xf9c1, 0xf881, 0x3840, 0x2800, 0xe8c1, 0xe981, 0x2940, 0xeb01, 0x2bc0, 0x2a80, 0xea41, 0xee01, 0x2ec0, 0x2f80, 0xef41, 0x2d00, 0xedc1, 0xec81, 0x2c40, 0xe401, 0x24c0, 0x2580, 0xe541, 0x2700, 0xe7c1, 0xe681, 0x2640, 0x2200, 0xe2c1, 0xe381, 0x2340, 0xe101, 0x21c0, 0x2080, 0xe041, 0xa001, 0x60c0, 0x6180, 0xa141, 0x6300, 0xa3c1, 0xa281, 0x6240, 0x6600, 0xa6c1, 0xa781, 0x6740, 0xa501, 0x65c0, 0x6480, 0xa441, 0x6c00, 0xacc1, 0xad81, 0x6d40, 0xaf01, 0x6fc0, 0x6e80, 0xae41, 0xaa01, 0x6ac0, 0x6b80, 0xab41, 0x6900, 0xa9c1, 0xa881, 0x6840, 0x7800, 0xb8c1, 0xb981, 0x7940, 0xbb01, 0x7bc0, 0x7a80, 0xba41, 0xbe01, 0x7ec0, 0x7f80, 0xbf41, 0x7d00, 0xbdc1, 0xbc81, 0x7c40, 0xb401, 0x74c0, 0x7580, 0xb541, 0x7700, 0xb7c1, 0xb681, 0x7640, 0x7200, 0xb2c1, 0xb381, 0x7340, 0xb101, 0x71c0, 0x7080, 0xb041, 0x5000, 0x90c1, 0x9181, 0x5140, 0x9301, 0x53c0, 0x5280, 0x9241, 0x9601, 0x56c0, 0x5780, 0x9741, 0x5500, 0x95c1, 0x9481, 0x5440, 0x9c01, 0x5cc0, 0x5d80, 0x9d41, 0x5f00, 0x9fc1, 0x9e81, 0x5e40, 0x5a00, 0x9ac1, 0x9b81, 0x5b40, 0x9901, 0x59c0, 0x5880, 0x9841, 0x8801, 0x48c0, 0x4980, 0x8941, 0x4b00, 0x8bc1, 0x8a81, 0x4a40, 0x4e00, 0x8ec1, 0x8f81, 0x4f40, 0x8d01, 0x4dc0, 0x4c80, 0x8c41, 0x4400, 0x84c1, 0x8581, 0x4540, 0x8701, 0x47c0, 0x4680, 0x8641, 0x8201, 0x42c0, 0x4380, 0x8341, 0x4100, 0x81c1, 0x8081, 0x4040 }; struct shorts { /* as used, order is irrelevant */ unsigned short high, low; }; typedef union { /* to map one long to two shorts */ unsigned long sum; struct shorts shorts; } convert; /************************************************************************ * D O F I L E * * Read one file, calculate values, and print an output line. * Sets retval if necessary. ch is int, not char, to be sure * it can distinguish 0xff and EOF. As a result, all normal * values of ch should be positive, 0..255. */ proc DoFile (filep, nullname, filename) register FILE *filep; /* file to read */ int nullname; /* ignore filename? */ char *filename; /* name of filep */ { register int ch; /* current char */ register unsigned crc = 0; /* crc sum */ register long sum = 0L; /* byte sum */ register long lines = 0L; /* line count */ register long words = 0L; /* word count */ register long chars = 0L; /* char count */ convert conv; /* for 16-sum */ register int notword = true; /* not in word? */ /* * READ FILE AND COMPUTE SUMS: * * CRCtable[] values have 16 bits, so the masking is necessary before each * repeated index into the array. sum is allowed to increment to more than * 16 bits; overflow is handled later. Line and char counts are accumulated * regardless whether they are needed; it's faster not to check. Words are * counted in the same strange way as wc(1), ignoring special chars. */ while ((ch = getc (filep)) != EOF) { if (rflag) crc = (crc >> 8) ^ (CRCtable [(crc ^ ch) & 0xff]); if (sflag) sum += ch; if (ch == chNewline) lines++; chars++; if (wflag) { if ((' ' < ch) && (ch < '\177')) /* word char */ { if (notword) /* start of word */ { words++; notword = false; } } else if ((ch == ' ') || (ch == '\t') || (ch == chNewline)) { notword = true; } } } /* while */ /* * REPORT ERROR OR PRINT TOTALS: */ if (ferror (filep)) { PrintErr ("read failed from", nullname ? "stdin" : filename); retval = 1; } else { conv.sum = sum; /* for adding back overflow */ if (rflag) printf (" %4.4x", crc); if (sflag) printf (" %5u", conv.shorts.high + conv.shorts.low); if (lflag) printf (" %6ld", lines); if (wflag) printf (" %6ld", words); if (cflag) printf (" %6ld", chars); if (! nullname) /* have name to print */ { if (bflag) /* basename only */ { char *cp = filename; while (*cp != chNull) /* till end of name */ if (*cp++ == '/') /* directory level */ filename = cp; /* set past '/' */ } printf (" %s", filename); } putchar (chNewline); } /* else */ } /* DoFile */