home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- * scan.c Version 1.0
- *
- * 29 December 1990
- * Compiled with SAS/C 5.10
- *
- * Copyright © 1990 By Dan Fish
- * All rights reserved.
- *
- * Permission is granted to freely redistribute this program provided
- * the source code is included in the distribution and this copyright
- * notice is unchanged.
- *
- ****************************************************************************/
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <fcntl.h>
- #include <exec/types.h>
- #include <intuition/intuition.h>
-
- #include "ansicodes.h"
-
- #define BUFFSIZE 2048L /* length of I/O buffer */
- #define MAXFILELEN 80
- #define SPACEBAR 32
-
- char *key[] = {
- "NULLS ","^A (SOH) ","^B (STX) ","^C (ETX) ","^D (EOT) ",
- "^E (ENQ) ","^F (ACK) ","^G (BELL) ","Backspaces","Tabs ",
- "Line Feeds","Vert Tabs ","Formfeeds ","Returns ","^N (SO) ",
- "^O (SI) ","^P (DLE) ","^Q (DC1) ","^R (DC2) ","^S (DC3) ",
- "^T (DC4) ","^U (NAK) ","^V (SYN) ","^W (ETB) ","^X (CAN) ",
- "^Y (EM) ","^Z (SUB) ","ESC ","^\\ (FS) ","^] (GS) ",
- "^^ (RS) ","^- (US) ","Spaces " };
-
-
- char WindowTitle[] = " ASCII HEX Count Character Percent";
- char *fname;
-
- struct numlist {
- long ascii;
- long count;
- };
- struct numlist num[256];
- struct numlist *numptr;
-
- long temp[256];
-
- long totalchars=0;
-
- int diffchars=0, pages, page=1;
-
- main (argc,argv)
- int argc;
- char *argv[];
- {
-
- void DisplayData();
- void WriteData();
- void GetData();
- void BooBoo();
- void Usage();
- extern struct Window *mywindow; /* Console window */
- extern short pagelen;
- char oname[MAXFILELEN+1];
-
- int in;
- FILE *out;
- int outfile = FALSE;
- int sort = FALSE;
- int loop;
-
- numptr=num;
-
- /* parse the command line */
-
- if (( argc<2) || (*argv[1] =='?') || argv[1][1] == '?')
- {
- Usage();
- exit(10);
- }
-
- for (loop = argc-1; loop > 1; --loop)
- if (!(argv[loop][0] == '-' )) /* then it better be an output filename! */
- {
- if(outfile)
- BooBoo(3,(char *)NULL); /* already have an outfile! */
- else {
- outfile = TRUE;
- stccpy(oname,argv[loop],MAXFILELEN); }
- }
-
- for (loop = argc-1; loop > 0; --loop)
- if(argv[loop][0] == '-') /* options */
- {
- if(strpbrk(argv[loop],"sS") != (char *)NULL)
- sort = TRUE;
- }
-
-
- if ((in = open(argv[1], O_RDONLY, NULL)) < 0)
- BooBoo(1,argv[1]);
-
-
- if(outfile)
- if ((out = fopen(oname, "w")) == NULL)
- {
- close(in);
- BooBoo(2,oname);
- }
-
- fname=argv[1];
-
- GetData(in,sort);
-
- if(outfile)
- WriteData(out);
- else
- DisplayData();
-
- exit(0);
- }
-
- /************************************************************************
- * Function : WriteData *
- * Arguments: fp - pointer to output file structure *
- * Returns : nothing *
- * Purpose : Writes the data to an output file instead of the screen *
- *************************************************************************/
-
- void WriteData(fp)
- FILE *fp;
- {
- char *Line();
- int error=0;
- register j;
- fprintf(fp," File: %s Total: %-6d Different: %-3d\n\n",
- fname,totalchars,diffchars);
-
- for(j = 0, numptr = num; j < diffchars; j++, numptr++)
- {
- error = fputs(Line(),fp);
- if(error)
- fprintf(stderr,"Scan: Error during write! Iteration = %3d, Ascii = %3d\n",
- j,numptr->ascii);
- error = fputs("\n",fp);
-
- }
-
- fclose(fp);
- }
-
- /************************************************************************
- * Function : GetData *
- * Arguments: fh - file handle of input file *
- * sort - TRUE if output is to be sorted by frequency *
- * Returns : nothing *
- * Purpose : Creates an array containing the number of each character *
- * found in the input file. Sorts the array if applicable *
- *************************************************************************/
- void GetData(fh,sort)
- int fh,sort; /*input file handle */
- {
- int ch;
- register j=0;
- int frequency_sort();
-
- while ((ch = Fetch(fh)) != EOF)
- {
- temp[ch]++; /* Increment the "temp[]" value that */
- /* corresponds to the ASCII value */
- /* of the character just read */
-
- totalchars++; /* Running tab on total # of char's */
- }
-
- /* Create an array of only characters contained in the file by filtering */
- /* out all "temps[]" with a value of zero */
-
- while (j < 256)
- {
- if (temp[j] != 0)
- {
- num[diffchars].ascii = j;
- num[diffchars].count = temp[j];
- diffchars++;
- }
- j++;
- }
-
- if (sort)
- qsort((char *)num,diffchars+1,sizeof(struct numlist),frequency_sort);
-
- }
-
- /************************************************************************
- * Function : DisplayData *
- * Arguments: none *
- * Returns : nothing *
- * Purpose : Handles (or call functions to handle) all outputing of *
- * data to the screen. *
- *************************************************************************/
- void DisplayData()
- {
- void mysetup();
- extern short pagelen;
- void DisplayLine();
- void DisplayPage();
- int getkey;
-
- char quit[] = {'q','Q','\x1b','\003','\0'}; /* Null terminated string of */
- /* characters that will end */
- /* the program */
-
- mysetup(); /* Initialize the output console */
- numptr = num;
- cursor_off();
-
- if ((diffchars % pagelen)==0) /* the number of different characters will */
- pages = diffchars/pagelen; /* exactly fill a given number of pages */
- else
- pages = (diffchars/pagelen)+1;/* gonna need an extra page */
-
-
- DisplayPage(); /* Display the first "pagelen" lines */
-
- while(strchr(quit, getkey = getchar()) == (char *)NULL)
- {
- if (getkey == SPACEBAR && pages > 1)
- {
- if(numptr < &num[diffchars])
- DisplayPage(); /* display next page */
- else
- {
- numptr = num; /* go back to first page */
- DisplayPage();
- }
- }
- }
- return;
- }
-
- /************************************************************************
- * Function : DisplayLine *
- * Arguments: yval-- position on the screen where line is displayed *
- * Returns : nothing *
- * Purpose : Output a line to the screen positioned at "yval". If *
- * "numptr->ascii" is non-printable, the line is highlighted *
- *************************************************************************/
- void DisplayLine(yval)
- int yval;
- {
- char print;
- char *Line();
- put_cursor(1,yval);
- if(!(print = isprint(numptr->ascii)))
- setforecolor3();
- printf("%s",Line());
- if(!print)
- set_normal();
- }
-
- /************************************************************************
- * Function : *Line *
- * Arguments: None *
- * Returns : pointer to buffer containing the formatted line *
- * Purpose : Format a line of information about character *
- * "numptr->ascii". This information includes its *
- * ascii value, hex value, common reference, number of *
- * occurences and % of total *
- *************************************************************************/
- char *Line()
- {
- static char linebuff[80];
- char tempbuff[20];
- if (numptr->ascii < 33)
- sprintf(tempbuff,"%10s ",key[numptr->ascii]); /* a more familiar form */
- else if(numptr->ascii > 127 && numptr->ascii < 160)
- sprintf(tempbuff," ");
- else
- sprintf(tempbuff,"%-10c ",numptr->ascii); /* the actual character */
-
- sprintf(linebuff," [%3d] [%3x] %7d ",numptr->ascii,numptr->ascii,
- numptr->count);
-
- strcat(linebuff,tempbuff);
-
- sprintf(tempbuff,"%6.2f %%",
- (((float)numptr->count)/((float)totalchars))*100.0);
- strcat(linebuff,tempbuff);
- return(linebuff);
- }
-
- /************************************************************************
- * Function : DisplayPage *
- * Arguments: none *
- * Returns : nothing *
- * Purpose : Handles the screen formatting and display of an entire *
- * page of lines formatted by *Line(). Also displays *
- * filename and totalizer information at the bottom *
- *************************************************************************/
- void DisplayPage()
- {
- extern short pagelen;
- void DisplayLine();
- int j;
- char filnam[29];
-
- for (j=0; j < pagelen; j++) /* 22 lines per page */
- {
- if (numptr > &num[diffchars-1]) /* if this is the last character */
- erase_eos(); /* get rid of any old junk left */
- else /* from the previous page */
- {
- DisplayLine(j+1); /* display the next line */
- printf("\n");
- numptr++; /* increment pointer to next non-empty charval */
- }
- }
-
- stccpy(filnam,fname,27); /* Ensure filename will fit on */
- /* the last line! */
- cursor_bot();
- set_hilite();
- printf(" Page %d of %d ",page,pages);
- printf(" Total: %-6d ",totalchars);
- printf(" Different: %-3d ",diffchars);
- printf(" File: %s ",filnam);
- set_normal();
- page++;
- if (page > pages)
- page = 1;
- }
-
- /************************************************************************
- * Function : Fetch *
- * Arguments: fh - file handle of file to read *
- * Returns : a character (int) or EOF *
- * Purpose : Performs buffered low-level file reading, refilling *
- * buffer when last character has been "fetched" *
- * Returns EOF if no more characters in file *
- *************************************************************************/
- Fetch(fh)
- int fh; /*input file handle */
- {
- static unsigned char buffer[BUFFSIZE]; /* input buffer */
- static short nextch = BUFFSIZE-1;
- static short lastch = BUFFSIZE-1;
-
- if(++nextch >= lastch) /* If buffer used up, */
- { /* refill it from file */
- lastch = read(fh,buffer,BUFFSIZE);
- nextch = 0;
- }
-
- if (lastch == 0) /* EOF, close up shop */
- {
- close(fh);
- return(EOF);
- }
-
- return((int)buffer[nextch]); /* return next character */
- }
-
- /************************************************************************
- * Function : Usage *
- * Arguments: none *
- * Returns : nothing *
- * Purpose : Displays the proper usage format *
- *************************************************************************/
- void Usage()
- {
- fprintf(stderr,"\x1b[5m");
- fprintf(stderr,"\n\x1b[1;33m Usage: \x1b[0m");
- fprintf(stderr,"Scan <infile> [outfile] [-s] \x1b[0m\n\n");
- }
-
- /************************************************************************
- * Function : BooBoo *
- * Arguments: cause - integer for determining the nature of the problem *
- * string - pointer to a character string for screen output *
- * Returns : nothing *
- * Purpose : Displays an error message in the event of problems parsing *
- * command line arguments or accessing files *
- *************************************************************************/
- void BooBoo(cause,string)
- int cause;
- char *string;
- {
- void Usage();
-
- fprintf(stderr,"\n\x1b[33m Scan: \x1b[32m");
- if (cause == 1)
- fprintf(stderr,"Can't open \"%s\" for input! \n\n", string);
- else if(cause == 2)
- fprintf(stderr,"Can't open \"%s\" for output! \n\n", string);
- else if(cause == 3)
- {
- fprintf(stderr,"Too many file names!\n");
- Usage();
- }
- fprintf(stderr,"\x1b[0m");
- exit(-cause);
- }
-
- /************************************************************************
- * Function : frequency_sort *
- * Arguments: two pointers to the items being compared *
- * Purpose : provides the sorting algorithm for qsort() *
- *************************************************************************/
- int frequency_sort(num1,num2)
- struct numlist *num1,*num2;
- {
- if (num1->count < num2->count)
- return(1);
- else if (num1->count == num2->count)
- return(0);
- else
- return(-1);
- }
-