/**
 | "Quick and Dirty" program - MAX <filename> scans filename
 | and prints on stdout the length of the longest line, and
 | information about non-printable characters eventually
 | present in <filename>. MLO 910505
**/

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define BUFFER_LEN    256
#define INFO_DIM      128

int  nFound = 0;
char found[INFO_DIM] = "";
long cFound[INFO_DIM];

void PutInfo(int c);

main(
  int argc,
  char **argv
){
  FILE *fp;
  char buffer[BUFFER_LEN];
  char *pc;
  int n, i, j;
  int max = 0;
  int tot_lines = 0;
  long tot_bytes = 0;

  if (argc != 2)    exit(0);
  if ((fp = fopen(*(++argv), "r")) == NULL) {
    fprintf(stderr, "Can't open file %s...\n\n", *argv);
  } else {
    while (fgets(buffer, BUFFER_LEN, fp) != NULL) {
      if ((n = strlen(buffer)) > max)   max = n;
      tot_lines++;
      n--;
      for (pc=buffer; *pc; pc++) {
        if (!isprint(*pc)  &&  *pc != '\t'  &&  *pc != '\n') {
          PutInfo(*pc);
        }
      }
      tot_bytes += (n - 1);
    }
    fclose(fp);
    fprintf(stdout,
      "\nFile: %s\n"
      "%d characters in %d lines;\n"
      "maximum line length is %d characters.\n",
      *argv, tot_bytes, tot_lines, max);
    if (nFound) {
      fprintf(stdout, "\n%d unprintable characters found:\n", nFound);
      for (i=0; found[i]; i++) {
        fprintf(stdout, "0x%02X ", found[i]);
        if (isprint( (j = found[i] + 0x40))) {
          fprintf(stdout, "(CTRL-%c): ", j);
        } else {
          fprintf(stdout, "        : ");
        }
        fprintf(stdout, "%d\n", cFound[i]);
      }
    }
    fprintf(stdout, "\n");
  }
  exit(0);
}

void PutInfo(
  int c
){
  char *pC;

  if ( (pC = strchr(found, c)) == NULL) {
    if (nFound == INFO_DIM) {
      fprintf(stderr, "Too few characters in info buffer!\n");
    } else {
      found[nFound] = c;
      cFound[nFound++] = 1;
    }
  } else {
    (cFound[pC - found])++;
  }
}
