home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
495a.lha
/
Scan
/
scan.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-04-06
|
12KB
|
424 lines
/****************************************************************************
* 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);
}