/*
	function.c

	fn1.bat = cl /AL function.c getfile

*/
#include <stdio.h>
#include <string.h>
#include "nomouse.h"

#define STR_LEN 500
#define MAX_FUN 256

char PName[20][30];	/* program names */
int PNum=0;
char FName[MAX_FUN][50];	/* Function names included in programs */
int FNum=0,FActive;
int Fc[MAX_FUN];				/* c file containing function */
char F[MAX_FUN][MAX_FUN];

char check_char(char c);
int pass_1(FILE *fp);
int pass_2(FILE *fp);

main()

{
	int i,j,k;
	FILE *fp;
	int num,loc=0;
	char ans;

	printf("Beginning Pass #1 ...\n");
	printf("Choose files -- 'Esc' to move on.\n\n");
	while((loc=get_file_name("*.c",PName[PNum],loc))>=0)
	{
		fp=fopen(PName[PNum],"rt");
		if(!fp)
		{
			printf("Could not open '%s' to read.\n\n");
			exit(0);
		}
		pass_1(fp);
		fclose(fp);
		PNum+=1;
		printf("There are %d functions in %d files.\n",FNum,PNum);
	}
	if(PNum<1)
		exit(0);
	printf("Beginning Pass #2 ...\n");
	for(i=0;i<PNum;i++)
	{
		fp=fopen(PName[i],"rt");
		if(!fp)
		{
			printf("Could not open '%s' to read.\n\n");
			exit(0);
		}
		pass_2(fp);
		fclose(fp);
	}
	do
	{	
		printf("\n\n\n   1 -- Search for Uncalled Functions\n");
		printf("\n   x -- exit\n\n");
		ans=getch();
		if(ans=='1')
		{
			for(j=0;j<FNum;j++)
			{
				num=0;
				for(i=0;i<FNum;i++)
				{
					if(F[i][j]>0)
						num+=1;
				}
				if(num==0)
					printf("in %s no function calls to '%s()'\n",
						PName[Fc[j]],FName[j]);
			}
		}
	}while(ans!='x');
}

/**********************************************************************
**
**
**
**********************************************************************/

int pass_2(FILE *fp)

{
	int i,j,k;
	char string[STR_LEN],chr,chro=-1;
	int n=0,brk=0,type,hit;

	while((chr=fgetc(fp))!=EOF)
	{
		if(chr=='{')
			brk+=1;
		else if(chr=='}')
			brk-=1;
		else if(chr=='\"')
			while(fgetc(fp)!='\"');
		else if(chr=='*'&&chro=='/')
		{
			while((chr=fgetc(fp))!='/'||chro!='*')

				chro=chr;
		}
		else if(chr=='('&&n>0)	/* function */
		{
			if(brk==0)	/* function listing */
			{
				FActive=-1;
				for(i=0;i<FNum;i++)
				{
					if(strcmp(string,FName[i])==0)
					{
						FActive=i;
						break;
					}
				}
			}
			else		/* function call */
			{
				hit=-1;
				for(i=0;i<FNum;i++)
				{
					if(strcmp(string,FName[i])==0)
					{
						hit=i;
						break;
					}
				}
				if(hit>=0)
				{
					if(FActive<0)
					{
						printf("Could not find function with body\n");
						exit(0);
					}
					F[FActive][hit]=1;
				}
			}
			n=0;
		}
		else
		{
			type=check_char(chr);
			if(type=='l'||type=='L'||type=='n'||chr=='_')
			{
				string[n]=chr;
				string[n+1]='\0';
				n+=1;
				if(n>=STR_LEN)
				{
					string[STR_LEN-1]='\0';
					printf("String too long:\n\n%s",string);
				}
			}
			else
			{
				n=0;
			}
		}
		chro=chr;
	}

}


/**********************************************************************
**
**
**
**********************************************************************/

int pass_1(FILE *fp)

{
	int i,j,k;
	char string[STR_LEN],chr,chro=-1;
	int n=0,brk=0,type,dupe;
	int body=0;

	while((chr=fgetc(fp))!=EOF)
	{
		if(chr=='{')
		{
			body+=1;
			brk+=1;
		}
		else if(chr=='}')
			brk-=1;
		else if(chr=='\"')
			while(fgetc(fp)!='\"');
		else if(chr=='*'&&chro=='/')
		{
			while((chr=fgetc(fp))!='/'||chro!='*')
			{
				chro=chr;
			}
		}
		else if(chr=='('&&n>0)	/* function */
		{
			if(brk==0)
			{
				dupe=0;
				for(i=0;i<FNum;i++)
				{
					if(strcmp(string,FName[i])==0)
					{
						dupe=1;
						break;
					}
				}
				if(dupe==0)
				{
					if(body==0&&FNum>0)
						FNum-=1;
					Fc[FNum]=PNum;
					strcpy(FName[FNum++],string);
					body=0;
				}
				if(FNum>=MAX_FUN)
				{
					printf("Too many functions.\n\n");
					exit(0);
				}
			}
			n=0;
		}
		else
		{
			type=check_char(chr);
			if(type=='l'||type=='L'||type=='n'||chr=='_')
			{
				string[n]=chr;
				string[n+1]='\0';
				n+=1;
				if(n>=STR_LEN)
				{
					string[STR_LEN-1]='\0';
					printf("String too long:\n\n%s",string);
				}
			}
			else
			{
				n=0;
			}
		}
		chro=chr;
	}

}





/***********************************************************************
**
**	returns:
**
**		l -- lower case letter
**		L -- upper case letter
**		n -- number
**		p -- punctuation
**		w -- white space
**		i -- illegal
**
************************************************************************/

char check_char(char c)

{
	if(c<0x9)
		return('i');
	if(c<0xe)
		return('w');
	if(c<0x1f)
		return('i');
	if(c==0x20)
		return('w');
	if(c<0x2f)
		return('p');
	if(c<0x3a)
		return('n');
	if(c<0x41)
		return('p');
	if(c<0x5b)
		return('L');
	if(c<0x61)
		return('p');
	if(c<0x7b)
		return('l');
	if(c<0x7e)
		return('p');
	else
		return('i');

}
                                                                                                                           