/*
 *   Program to analyze a profile created by DBG.
 *   The profile will be read from STDIN and totals
 *   will be written to STDOUT.
 *
 *   Each line of the profile must have the following form:
 *
 *	NAME[+offset]:  count.
 *
 *   Lines that begin with an address (i.e. no name) will
 *   be added to the grand total, but will not be counted
 *   at the module level.
 */
#include <stdio.h>

#define MAXLIN	96		/* Maximum input line length		*/

extern char	*strpbrk();	/* Function to search a string for a set */

long	grand = { 0 };	/* Grand total		*/
long	lincnt;		/* Current line count	*/
char	modnam[ 12 ];	/* Current module name	*/
long	modtot = { 0 };	/* Current module total	*/

main()
{
static char	buffer[ MAXLIN ]; /* Record input buffer	*/
register char	*nameptr;	/* Module name pointer		*/
register char	*recptr;	/* Record pointer		*/

	while ( recptr = fgets( buffer, sizeof( buffer ), stdin )) {
		if ( *recptr == '\n' )		/* Ignore blank lines	*/
			continue;
		if ( strchr( "0123456789", *recptr ) ) {
			newmod( "" );		/* No module if no name	*/
		}
		else {
			recptr = strpbrk( nameptr = recptr, "+: " );
			if ( recptr == NULL )
				error( "Invalid record" );
			*recptr++ = '\0';
			if ( 0 != strcmp( modnam, nameptr ))
				newmod( nameptr );
		}
		if ( NULL == (recptr = strchr( recptr, ' ' )))
			error( "Invalid record" );
		while ( *recptr++ == ' ' ) {
		}
		recptr -= 1;
		sscanf( recptr, "%ld.", &lincnt );
		grand += lincnt;
		if ( *modnam )
			modtot += lincnt;
	}
	newmod( "" );
	printf( "\nGRAND TOTAL %ld\n", grand );
}

/*
 *   Function to set up a new module.
 */
newmod( name )
char	*name;		/* Module name pointer	*/
{
	if ( *modnam && modtot != 0 )
		printf( "%-12s%ld\n", modnam, modtot );
	strcpy( modnam, name );
	modtot = 0;
}

/*
 *   Function to display an error and exit.
 */
error( string )
char	*string;	/* Error message	*/
{
	fprintf( stderr, "PROFANAL - %s\n", string );
	exit( EX_ERR );
}

/*
 *   Function to search a string for a member of a character set.
 */
char	*strpbrk( string, set )
register char	*string;	/* String pointer		*/
register char	*set;		/* Character set pointer	*/
{
register char	*setptr;	/* Character set scan pointer	*/

	while ( *string ) {
		setptr = set;
		while ( *setptr ) {
			if ( *setptr++ == *string )
				return( string );
		}
		string += 1;
	}
	return( NULL );
}
