home *** CD-ROM | disk | FTP | other *** search
- /* Written by John Darragh, Calgary Alberta, revised 3-89.
- *
- * freq.c: tabulates ASCII character frequencies from stdin and outputs
- * freq sorted ASCII chars on the stdout in a number of formats.
- *
- * intended as a utility for rk_button to create its zero_freq
- * startup FREQ_DATA_FILE and/or default zero_freq[] char array.
- *
- * this info is used by rk to predict chars it hasn't yet added
- * to it's model (either by file priming or user command input).
- *
- * it puts any unseen chars in ASCII sequence, and puts any un-
- * represented control codes (including DEL) at the end.
- *
- * defaults: outputs 256 chars as 128 ASCII char/NL pairs.
- * (the NLs are just for readabilities sake, rk ignores them.)
- *
- * options:
- * -c write output as a C array for inclusion in programs.
- * -n don't put a NL after each of the 128 chars output.
- * (intended for future revision to init_reactive() which
- * would halve the freq file size from 256 -- saves space)
- * <filename> read data from file other than stdin.
- */
-
- #include <stdio.h>
-
- #define TRUE 1
- #define FALSE 0
- #define MAXTABLE 128 /* the size of the ASCII character set */
-
- FILE * infile = stdin; /* for <filename> arg */
- char no_nls = FALSE; /* -n option above */
- char c_array = FALSE; /* -c option above */
- int ch_table[MAXTABLE][2]; /* [][0] are labels, [][1] are freq counts */
-
- main (argc, argv)
- int argc;
- char **argv;
- {
- char chr; register int i, j; int gap, temp[2];
-
- get_args (argc, argv); /* may change infile, no_nls, c_array */
- /* init table labels and do the freq count */
- for (i=0; i<MAXTABLE; i++) {
- ch_table[i][0] = i; /* the ACSII code */
- ch_table[i][1]= -(i+1); /* ensure ASCII order for 0-freqs */
- } /* by intially -ve freq counts */
- while ((chr = getc(infile)) != EOF) {
- chr &= 0177;
- if (ch_table[(int)chr][1] < 0) /* seen, so fix -ve freqs */
- ch_table[(int)chr][1] = 0;
- ch_table[(int)chr][1]++;
- }
- for (i=0; i<32; i++) {
- if (ch_table[i][1] < 0) /* ensure 0-freq control codes */
- ch_table[i][1] -= MAXTABLE; /* end up at the end */
- }
- if (ch_table[MAXTABLE-1][1] < 0) /* ensure same for DEL char */
- ch_table[MAXTABLE-1][1] -= MAXTABLE;
- /* frequency sort the thing (shell sort) */
- for (gap = MAXTABLE/2; gap > 0; gap /= 2)
- for (i= gap; i < MAXTABLE; i++)
- for (j = i-gap; j >= 0; j -= gap) {
- if (ch_table[j][1] <= ch_table[j+gap][1])
- break;
- temp[0] = ch_table[j][0];
- temp[1] = ch_table[j][1];
- ch_table[j][0] = ch_table[j+gap][0];
- ch_table[j][1] = ch_table[j+gap][1];
- ch_table[j+gap][0] = temp[0];
- ch_table[j+gap][1] = temp[1];
- }
- /* output a compilable "C" character array */
- if (c_array) {
- printf ("static char zero_freq[128] = { /* by a user supplied $home/file */\n");
- for (i=MAXTABLE-1; i>=0; i--) {
- switch (chr = (char)(ch_table[i][0] & 127)) {
- case '\n': printf (" \'\\n\',"); break;
- case '\t': printf (" \'\\t\',"); break;
- case '\b': printf (" \'\\b\',"); break;
- case '\r': printf (" \'\\r\',"); break;
- case '\f': printf (" \'\\f\',"); break;
- case '\\': printf (" \'\\\\\',"); break;
- case '\'': printf (" \'\\\'\',"); break;
- case 127: printf ("\'\\%03o\',", (int)chr); break;
- default: if (chr < 32) printf (" \'\\%02o\',", (int)chr);
- else printf (" \'%1c\',", chr); break;
- }
- if (((i%8) == 0) && (i != 0)) printf ("\n");
- }
- printf ("};\n");
- /* otherwise just put out sorted chars */
- } else
- for (i=MAXTABLE-1; i>=0; i--)
- if (no_nls) printf ("%c", (char)ch_table[i][0]);
- else printf ("%c\n", (char)ch_table[i][0]);
-
- abortit ("", 0);
- }
-
-
- static char *options = " -n[no_nls] -c[c_array] <input file>\n";
-
- static get_args (argc, argv) /* may change infile */
- int argc;
- char **argv;
- /*
- * Get any command arguments and set any appropriate
- * global flags and variables.
- */
- {
- static char usage[256] = "usage: ";
-
- strcat (usage, &argv[0][0]); /* fill in name of object file */
- strcat (usage, options);
-
- while ((argc > 1) && (argv[1][0] == '-')) {
- switch (argv[1][1]) {
-
- case 'c': case 'C': /* turn on C char array output */
- c_array = TRUE;
- break;
-
- case 'n': case 'N': /* turn on "no NL" output mode */
- no_nls = TRUE;
- break;
-
- default: abortit (usage, -1);
-
- } /*switch*/
- argc--; argv++;
-
- }
- if (argc == 2) { /* file argument present */
- if ((infile = fopen (&argv[1][0], "r")) == NULL) {
- fprintf (stderr, "cannot open: %s\n", &argv[1][0]);
- abortit (usage, -1);
- }
- } else if (argc != 1) abortit (usage, -1);
- }/*get_args*/
-
-
- static abortit (message, status)
- char *message;
- int status;
- /*
- * All program terminations are through this routine.
- * It prints an optional message, then exits with
- * the parameter status.
- */
- {
- fprintf (stderr, "%s", message);
- fflush (stderr);
- exit (status);
- }/*abortit*/
-