/* Copyright (c)1994-2000 Begemot Computer Associates. All rights reserved.
 * See the file COPYRIGHT for details of redistribution and use. */

# include <sys/types.h>
# include <sys/stat.h>
# include <stdio.h>
# include <unistd.h>
# include <stdlib.h>
# include <stdarg.h>
# include <fcntl.h>
# include <errno.h>
# include <string.h>
# ifdef HAVE_GETOPT_H
#  include <getopt.h>
# endif

# include <begemot.h>
# include "cdefs.h"
# include "util.h"

# include "cproftab.c"

RCSID("$Id: cprof.c 481 2002-03-07 12:43:08Z hbb $")


# ifdef	MPROF
#  define	PTABSIZE	4
#  define	MYNAME		"mprof"
# else
#  define	PTABSIZE	1
#  define	MYNAME		"cprof"
# endif /* MPROF */

extern u_int	instab[0200000][4];
u_int	itimes[0200000][PTABSIZE];
u_int	icalls[0200000];

u_int	ptimes[NNAMES];
u_int	pcalls[NNAMES];

void cprof(void);
void cout(void);
void usage(void) DEAD_FUNC;

static char usgtxt[] =
"Usage: "MYNAME" file\n"
"Options:\n"
"	-h		print this info\n";

int
main(int argc, char *argv[])
{
	int opt;
	int fd;
	struct stat sbuf;

	set_argv0(argv[0]);
	while((opt = getopt(argc, argv, "hv")) != EOF)
		switch(opt) {

		  case 'h':
			usage();
		}
	argc -= optind;
	argv += optind;

	if(argc != 1)
		usage();

	if((fd = open(argv[0], O_RDWR)) < 0)
		panic("Cannot open %s: %s\n", argv[0], strerror(errno));

	if(fstat(fd, &sbuf) < 0)
		panic("Cannot stat %s: %s\n", argv[0], strerror(errno));

	if(sbuf.st_size != (sizeof(itimes)+sizeof(icalls)))
		panic("%s has wrong size, probably not a "MYNAME" file\n",
					argv[0]);

	if(read(fd, itimes, sizeof(itimes)) != sizeof(itimes))
		panic("Error reading %s: %s\n", argv[0], strerror(errno));

	if(read(fd, icalls, sizeof(icalls)) != sizeof(icalls))
		panic("Error reading %s: %s\n", argv[0], strerror(errno));

	cprof();
	cout();

	return 0;
}

void
usage()
{
	fprintf(stderr, usgtxt);
	exit(1);
}


void
cprof(void)
{
	int	i, j;

	for(i = 0 ; i < 0200000 ; i++)
		for(j = 0 ; j < PTABSIZE ; j++)
			if(itimes[i][j]) {
				ptimes[instab[i][j]] += itimes[i][j];
				pcalls[instab[i][j]] += icalls[i];
			}
}

void
cout(void)
{
	int	i;

	for(i = 0 ; i < NNAMES ; i++)
		if(pcalls[i])
			printf("%s\t%10d%10d%10d\n",
				inames[i], pcalls[i], ptimes[i],
				pcalls[i] ? ptimes[i]/pcalls[i] : 0);
}
