/**
 | "Quick and Dirty" program - MAX <filename> [<filename> [ ... ] ]
 | scans the given file(s), and prints on stdout the length of the
 | longest line, the number of lines, and some information about
 | non-printable characters eventually present.
 | MLO 911205
**/

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

#define BUFFER_LEN    256
#define INFO_DIM      128

int  nFound;
char found[INFO_DIM];
long cFound[INFO_DIM];

void PutInfo(char c);

void main(
  int argc,
  char **argv
){
  FILE *fp;
  char buffer[BUFFER_LEN];
  char *pc;
  int n, i, j;
  int maxlin, tot_lines, tot_bytes;

  if (argc < 2)    exit(0);
  while (--argc) {
    if ((fp = fopen(*(++argv), "r")) == NULL) {
      fprintf(stderr, "Can't open file %s...\n\n", *argv);
    } else {
      nFound = maxlin = tot_lines = tot_bytes = 0;
      found[0] = '\0';
      while (fgets(buffer, BUFFER_LEN, fp) != NULL) {
        if ((n = strlen(buffer) - 1) > maxlin)   maxlin = n;
        tot_lines++;
        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, maxlin);
      if (nFound) {
        fprintf(stdout, "\n%d unprintable character%s found:\n",
                nFound, nFound == 1 ? "" : "s");
        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(
  char 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;
      found[nFound] = '\0';
    }
  } else {
    (cFound[pC - found])++;
  }
}
