home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume20 / reactivekbd / part01 / freq.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-10-16  |  5.1 KB  |  157 lines

  1. /*       Written by John Darragh, Calgary Alberta, revised 3-89.
  2.  *
  3.  * freq.c: tabulates ASCII character frequencies from stdin and outputs
  4.  *         freq sorted ASCII chars on the stdout in a number of formats.
  5.  *
  6.  *       intended as a utility for rk_button to create its zero_freq
  7.  *       startup FREQ_DATA_FILE and/or default zero_freq[] char array.
  8.  *
  9.  *       this info is used by rk to predict chars it hasn't yet added
  10.  *       to it's model (either by file priming or user command input).
  11.  *
  12.  *       it puts any unseen chars in ASCII sequence, and puts any un-
  13.  *       represented control codes (including DEL) at the end.
  14.  *
  15.  * defaults:    outputs 256 chars as 128 ASCII char/NL pairs.
  16.  *        (the NLs are just for readabilities sake, rk ignores them.)
  17.  *
  18.  * options:
  19.  *       -c   write output as a C array for inclusion in programs.
  20.  *         -n   don't put a NL after each of the 128 chars output.
  21.  *        (intended for future revision to init_reactive() which
  22.  *         would halve the freq file size from 256 -- saves space)
  23.  *         <filename>   read data from file other than stdin.
  24.  */
  25.  
  26. #include <stdio.h>
  27.  
  28. #define TRUE    1
  29. #define FALSE   0
  30. #define MAXTABLE        128    /* the size of the ASCII character set     */
  31.  
  32. FILE    * infile = stdin;    /* for <filename> arg */
  33. char    no_nls   = FALSE;    /* -n option above    */
  34. char    c_array  = FALSE;    /* -c option above    */
  35. int     ch_table[MAXTABLE][2];    /* [][0] are labels, [][1] are freq counts */
  36.  
  37. main (argc, argv)
  38. int argc;
  39. char **argv;
  40. {
  41.         char chr;  register int i, j;  int gap, temp[2];
  42.  
  43.         get_args (argc, argv);  /* may change infile, no_nls, c_array      */
  44.                 /* init table labels and do the freq count */
  45.     for (i=0; i<MAXTABLE; i++) {
  46.          ch_table[i][0] = i;     /* the ACSII code           */
  47.          ch_table[i][1]= -(i+1); /* ensure ASCII order for 0-freqs */
  48.     }                    /* by intially -ve freq counts */
  49.         while ((chr = getc(infile)) != EOF) {
  50.         chr &= 0177;
  51.         if (ch_table[(int)chr][1] < 0)  /* seen, so fix -ve freqs */
  52.             ch_table[(int)chr][1] = 0;
  53.         ch_table[(int)chr][1]++;
  54.     }
  55.     for (i=0; i<32; i++) {
  56.         if (ch_table[i][1] < 0)     /* ensure 0-freq control codes */
  57.             ch_table[i][1] -= MAXTABLE;       /* end up at the end */
  58.     }
  59.     if (ch_table[MAXTABLE-1][1] < 0)     /* ensure same for DEL char   */
  60.             ch_table[MAXTABLE-1][1] -= MAXTABLE;
  61.                 /* frequency sort the thing (shell sort)   */
  62.     for (gap = MAXTABLE/2; gap > 0; gap /= 2)
  63.         for (i= gap; i < MAXTABLE; i++)
  64.             for (j = i-gap; j >= 0; j -= gap) {
  65.                     if (ch_table[j][1] <= ch_table[j+gap][1])
  66.                      break;
  67.                 temp[0] = ch_table[j][0];
  68.                 temp[1] = ch_table[j][1];
  69.                 ch_table[j][0] = ch_table[j+gap][0];
  70.                 ch_table[j][1] = ch_table[j+gap][1];
  71.                 ch_table[j+gap][0] = temp[0];
  72.                 ch_table[j+gap][1] = temp[1];
  73.             }
  74.                 /* output a compilable "C" character array */
  75.     if (c_array) {
  76. printf ("static char zero_freq[128] = {         /* by a user supplied $home/file */\n");
  77.         for (i=MAXTABLE-1; i>=0; i--) {
  78.         switch (chr = (char)(ch_table[i][0] & 127)) {
  79.         case '\n':  printf ("  \'\\n\',");  break;
  80.         case '\t':  printf ("  \'\\t\',");  break;
  81.         case '\b':  printf ("  \'\\b\',");  break;
  82.         case '\r':  printf ("  \'\\r\',");  break;
  83.         case '\f':  printf ("  \'\\f\',");  break;
  84.         case '\\':  printf ("  \'\\\\\',"); break;
  85.         case '\'':  printf ("  \'\\\'\',"); break;
  86.         case  127:  printf ("\'\\%03o\',", (int)chr); break;
  87.         default:    if (chr < 32) printf (" \'\\%02o\',", (int)chr);
  88.                 else       printf ("   \'%1c\',", chr); break;
  89.             }
  90.         if (((i%8) == 0) && (i != 0)) printf ("\n");
  91.         }
  92.         printf ("};\n");
  93.                 /* otherwise just put out sorted chars */
  94.         } else
  95.         for (i=MAXTABLE-1; i>=0; i--)
  96.             if (no_nls) printf ("%c",   (char)ch_table[i][0]);
  97.         else        printf ("%c\n", (char)ch_table[i][0]);
  98.  
  99.         abortit ("", 0);
  100. }
  101.  
  102.  
  103. static char *options = " -n[no_nls] -c[c_array] <input file>\n";
  104.  
  105. static get_args (argc, argv)   /* may change infile */
  106. int argc;
  107. char **argv;
  108. /*
  109.  * Get any command arguments and set any appropriate
  110.  * global flags and variables.
  111.  */
  112. {
  113.     static char usage[256] = "usage: ";
  114.  
  115.     strcat (usage, &argv[0][0]);        /* fill in name of object file */
  116.     strcat (usage, options);
  117.  
  118.     while ((argc > 1) && (argv[1][0] == '-')) {
  119.         switch (argv[1][1]) {
  120.  
  121.       case 'c': case 'C':               /* turn on C char array output */
  122.                         c_array = TRUE;
  123.                         break;
  124.  
  125.       case 'n': case 'N':               /* turn on "no NL" output mode */
  126.                         no_nls = TRUE;
  127.                         break;
  128.  
  129.       default:          abortit (usage, -1);
  130.  
  131.         } /*switch*/
  132.         argc--; argv++;
  133.  
  134.     }
  135.     if (argc == 2) {            /* file argument present */
  136.         if ((infile = fopen (&argv[1][0], "r")) == NULL) {
  137.             fprintf (stderr, "cannot open: %s\n", &argv[1][0]);
  138.             abortit (usage, -1);
  139.         }
  140.     } else if (argc != 1) abortit (usage, -1);
  141. }/*get_args*/
  142.  
  143.  
  144. static abortit (message, status)
  145. char *message;
  146. int status;
  147. /*
  148.  * All program terminations are through this routine.
  149.  * It prints an optional message, then exits with
  150.  * the parameter status.
  151.  */
  152. {
  153.     fprintf (stderr, "%s", message);
  154.     fflush (stderr);
  155.     exit (status);
  156. }/*abortit*/
  157.