togcat.c 4.18 KB
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_INPUT 256
#define CHUNK_TOGGLE	 50000
#define CHUNK_STRING	100000

#define MAX_TOGGLE_CHUNKS    100
#define HASH_TABLE_SIZE	    32768


struct toggle {
    char *netname;
    long flags;
    long tog_to_0;
    long tog_to_1;
    long tog_sum;
};

struct hash_entry {
    struct toggle *tp;
    struct hash_entry *next;
};

struct hash_entry hash_table[HASH_TABLE_SIZE];

struct toggle *toggle_tbl[MAX_TOGGLE_CHUNKS];
int tableindex, subindex, stringbytes;
struct toggle *freetp;
char *stringarea;
char line[MAX_INPUT];

void printtogtbl(void);
struct toggle *locate(unsigned char *);
struct toggle *newnet(char *);
void addfile(FILE *);
void inittogtbl(void);

main(int argc, char *argv[])
{
    int i;
    FILE *infile;
    
    if (argc < 3) {
	fprintf(stderr, "Usage: %s f1.tog ... fn.tog > output\n", argv[0]);
	exit(1);
    }
    
    i = 1;
    inittogtbl();
    
    while ( i < argc) {
	if ((infile = fopen(argv[i], "r")) == NULL) {
	    fprintf(stderr, "cannot open %s\n", argv[i]);
	}
	addfile(infile);
	i++;
    }
    
    printtogtbl();
}

void
inittogtbl()
{
    
    /* jump start the table & string area */
    toggle_tbl[0] = (struct toggle *)calloc(CHUNK_TOGGLE, sizeof(struct toggle));
    freetp = toggle_tbl[0];
    tableindex = 0;
    subindex = 0;
    stringarea = (char *)malloc(CHUNK_STRING);
    stringbytes = CHUNK_STRING;
}

void
addfile(FILE *in)
{
    long sum, t0, t1;
    char netname[256];
    struct toggle *tp;
    
    while (fgets(line, MAX_INPUT, in) != NULL) {
	if (sscanf(line, "%d %d %d %s\n", &sum, &t0, &t1, netname) == 4) {
	    tp = locate(netname);
	    tp->tog_to_0 += t0;
	    tp->tog_to_1 += t1;
	    tp->tog_sum = tp->tog_to_0 + tp->tog_to_1;
	}
    }
}

struct toggle *
newnet(char *netname)
{
    int namesize;
    struct toggle *tp;
    
    tp = freetp++;
    /* add to toggle list */
    namesize = strlen(netname) + 1;
    /* check for string area overflow */
    if (namesize > stringbytes) {
	stringarea = (char *)malloc(CHUNK_STRING);
	stringbytes = CHUNK_STRING;
    }
    strcpy(stringarea, netname);
    tp->netname = stringarea;
    stringarea += namesize;
    stringbytes -= namesize;
    tp->tog_to_0 = 0;
    tp->tog_to_1 = 0;
    tp->tog_sum = 0;
    tp->flags = 0;
    subindex++;
    
    /* check for chunk overflow */
    if (subindex == CHUNK_TOGGLE) {
	tableindex++;
	if (tableindex == MAX_TOGGLE_CHUNKS) {
	    fprintf(stderr, "oh S---,  huge number of nodes\n");
	    exit(1);
	}
	toggle_tbl[tableindex] = (struct toggle *)calloc(CHUNK_TOGGLE,
		sizeof(struct toggle));
	freetp = toggle_tbl[tableindex];
	subindex = 0;
    }
    
    return tp;

}

/*
 * Find the entry in the table.  If it does not exist, add it
 */
struct toggle *
locate(unsigned char *name)
{
    unsigned long hashvalue;
    unsigned char c, *s;
    struct hash_entry *hp;
    
    /* first generate the hash number */
    hashvalue = 0;
    s = name;
    while (1) {
	c = *s++;
	if (!c)
	    break;
	hashvalue <<= 1;
	hashvalue += c;
    }
    hashvalue %= HASH_TABLE_SIZE;
    
    hp = &hash_table[hashvalue];
    if (hp->tp == 0) {
	/* need to add */
	hash_table[hashvalue].tp = newnet(name);
	return hash_table[hashvalue].tp;
    } else {
	/* walk down the chain looking for a match */
	while (hp != 0) {
	    if (strcmp(name, hp->tp->netname) == 0) {
		return hp->tp;
	    } else {
		hp = hp->next;
	    }
	}
	if (hp == NULL) {
	    /* did not find match in chain */
	    hp = (struct hash_entry *)malloc(sizeof(struct hash_entry));
	    hp->tp = hash_table[hashvalue].tp;
	    hp->next = hash_table[hashvalue].next;
	    hash_table[hashvalue].tp = newnet(name);
	    hash_table[hashvalue].next = hp;
	    return hash_table[hashvalue].tp;
	}
    }
}

void
printtogtbl()
{
    int i;
    int tableindex;
    struct toggle *tp;
    
    tableindex = 0;
    i = 0;
    tp = toggle_tbl[tableindex];
    
    
    printf("-- TOGGLE COUNTS (format: sum  toggle_to_0  toggle_to_1  net_name)\n");
    while (tp) {
    
	if (tp->netname ) {
	    printf("%6d %6d %6d %s\n", tp->tog_sum, tp->tog_to_0,
		tp->tog_to_1, tp->netname);
	}
	
	i++;
	if (i == CHUNK_TOGGLE) {
	    tableindex++;
	    tp = toggle_tbl[tableindex];
	    i = 0;
	} else {
	    tp++;
	}
    }
}