File:  [Research Unix] / researchv10no / cmd / lcc / etc / io.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:35 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv10, HEAD
researchv10 Norman

#ifdef BPRINT
#define dclproto(func,args) func args;
#else
#include "c.h"
#define FILE int
#define EOF -1
#endif

/*
 * read prof.out; format:
 *    #files
 *    name
 *    ... (#files-1 times)
 *    #functions
 *    name file# x y count
 *    ... (#functions-1 times)
 *    #points
 *    file# x y count
 *    ... (#points-1 times)
 */

struct file {
	struct file *link;
	char *name;
	int size, count;
	struct count {
		int x, y;
		int count;
	} *counts;
	struct func {
		struct func *link;
		char *name;
		struct count count;
	} *funcs;
} *filelist;

dclproto(static void afunction,(char *, char *, int, int, int))
dclproto(static void apoint,(int, char *, int, int, int))
dclproto(static struct file *findfile,(char *))
dclproto(static int gather,(FILE *))

#ifdef BPRINT
/* alloc - allocate n bytes or die */
static char *alloc(int n) {
	char *new = (char *)malloc(n);

	assert(new);
	return new;
}

/* string - save a copy of str, if necessary */
char *string(char *str) {
	static struct string { char *str; struct string *link; } *list;
	struct string *p;

	for (p = list; p; p = p->link)
		if (strcmp(p->str, str) == 0)
			return p->str;
	p = (struct string *)alloc(sizeof *p);
	p->str = strcpy((char *)alloc(strlen(str) + 1), str);
	p->link = list;
	list = p;
	return p->str;
}
#else
dclproto(extern void qsort,(struct count *, int, int, int (*)(const void *, const void *)))
dclproto(static int fscanf,(FILE *, char *, Generic, Generic, Generic, Generic, Generic))
dclproto(extern int sscanf,(char *, char *, Generic, Generic, Generic, Generic, Generic))

/* fscanf - read a line of input according to fmt */
static int fscanf(fp, fmt, a1, a2, a3, a4, a5) FILE *fp; char *fmt; Generic a1, a2, a3, a4, a5; {
	&fp;
	while (*cp) {
		if (limit - cp < MAXTOKEN)
			fillbuf();
		sscanf(cp, fmt, a1, a2, a3, a4, a5);
		while (*cp && *cp != '\n')
			cp++;
		if (*cp == '\n') {
			cp++;
			nextline();
		}
		return 0;
	}
	return EOF;
}
#endif

/* afunction - add function name and its data to file's function list */
static void afunction(name, file, x, y, count) char *name, *file; {
	struct file *p = findfile(file);
	struct func **q;

	assert(p);
	for (q = &p->funcs; *q && name != (*q)->name; q = &(*q)->link)
		;
	if (*q == 0) {
		*q = (struct func *)alloc(sizeof **q);
		(*q)->name = name;
		(*q)->count.x = x;
		(*q)->count.y = y;
		(*q)->count.count = 0;
		(*q)->link = 0;
	}
	(*q)->count.count += count;
}

/* apoint - append execution point i to file's data */ 
static void apoint(i, file, x, y, count) char *file; {
	struct file *p = findfile(file);

	assert(p);
	if (i >= p->size) {
		int j;
		if (p->size == 0) {
			p->counts = (struct count *)alloc(200*sizeof(struct count));
			p->size = 200;
		} else {
#ifdef BPRINT
			p->counts = (struct count *)realloc(p->counts, 2*p->size*sizeof(struct count));
#else
			struct count *new = (struct count *)alloc(2*p->size*sizeof(struct count));
			for (j = 0; j < p->count; j++)
				new[j] = p->counts[j];
			p->counts = new;
#endif
			p->size = 2*p->size;
		}
		for (j = p->count; j < p->size; j++) {
			static struct count z;
			p->counts[j] = z;
		}
	}
	p->counts[i].x = x;
	p->counts[i].y = y;
	p->counts[i].count += count;
	if (i >= p->count)
		p->count = i + 1;
}

/* compare - return <0, 0, >0 if a<b, a==b, a>b, resp. */
static int compare(a, b) struct count *a, *b; {
	if (a->y == b->y)
		return a->x - b->x;
	return a->y - b->y;
}

/* findcount - return count associated with (file,x,y) or -1 */
int findcount(file, x, y) char *file; {
	static struct file *cursor;

	if (cursor == 0 || cursor->name != file)
		cursor = findfile(file);
	if (cursor) {
		int l, u;
		struct count *c = cursor->counts;
		for (l = 0, u = cursor->count - 1; l <= u; ) {
			int k = (l + u)/2;
			if (c[k].y > y || c[k].y == y && c[k].x > x)
				u = k - 1;
			else if (c[k].y < y || c[k].y == y && c[k].x < x)
				l = k + 1;
			else
				return c[k].count;
		}
	}
	return -1;
}

/* findfile - return file name's file list entry, or 0 */
static struct file *findfile(name) char *name; {
	struct file *p;

	for (p = filelist; p; p = p->link)
		if (p->name == name)
			return p;
	return 0;
}

/* findfunc - return count associated with function name in file or -1 */
int findfunc(name, file) char *name, *file; {
	static struct file *cursor;

	if (cursor == 0 || cursor->name != file)
		cursor = findfile(file);
	if (cursor) {
		struct func *p;
		for (p = cursor->funcs; p; p = p->link)
			if (p->name == name)
				return p->count.count;
	}
	return -1;
}

/* gather - read prof.out data from fd */
static int gather(FILE *fp) {
	int i, nfiles, nfuncs, npoints;
	char *files[64], buf[120];

	if (fscanf(fp, "%d\n", &nfiles, 0, 0, 0, 0) == EOF)
		return 0;
	assert(nfiles < sizeof files/sizeof files[0]);
	for (i = 0; i < nfiles; i++) {
		fscanf(fp, "%s\n", buf, 0, 0, 0, 0);
		files[i] = string(buf);
		if (!findfile(files[i])) {
			struct file *new = (struct file *)alloc(sizeof *new);
			new->name = files[i];
			new->size = new->count = 0;
			new->counts = 0;
			new->funcs = 0;
			new->link = filelist;
			filelist = new;
		}
	}
	fscanf(fp, "%d\n", &nfuncs, 0, 0, 0, 0);
	for (i = 0; i < nfuncs; i++) {
		int f, x, y, count;
		fscanf(fp, "%s %d %d %d %d\n", buf, &f, &x, &y, &count);
		afunction(string(buf), files[f-1], x, y, count);
	}
	fscanf(fp, "%d\n", &npoints, 0, 0, 0, 0);
	for (i = 0; i < npoints; i++) {
		int f, x, y, count;
		fscanf(fp, "%d %d %d %d\n", &f, &x, &y, &count, 0);
		if (f)
			apoint(i, files[f-1], x, y, count);
	}
	return 1;
}

/* process - read prof.out data from file */
int process(file) char *file; {
	struct file *p;
	FILE *fp;

#ifdef BPRINT
	if ((fp = fopen(file, "r"))) {
		while (gather(fp))
			;
		fclose(fp);
#else
	int fd;
	if ((fd = open(file, 0)) >= 0) {
		inputInit(fd);
		while (gather(fp))
			;
		close(fd);
#endif
		for (p = filelist; p; p = p->link)
			qsort(p->counts, p->count, sizeof *p->counts,
#ifdef PROTO
				(int (*)(const void *, const void *))
#endif
				compare);
		return 1;
	}
	return 0;
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.