view ueda/libuschem/graphsym.c @ 13:1f3283f8e482

unet-bind: instance hash implemented
author Space Falcon <falcon@ivan.Harhan.ORG>
date Sun, 02 Aug 2015 00:00:15 +0000
parents cd92449fdb51
children
line wrap: on
line source

/*
 * Functions for working with graphical symbols
 */

#include <sys/types.h>
#include <stdio.h>
#include <ctype.h>
#include <strings.h>
#include "schemstruct.h"
#include "graphsym.h"

extern char *malloc();
extern char *copystr();

extern FILE *find_symlib_file();
extern char sought_libfile_fullpath[];

#define	HASH_SIZE	1103

static struct graphsym *graphsym_hash[HASH_SIZE];
int total_graphsyms;

static int
hash_graphsym_name(str)
	char *str;
{
	register u_long accum = 0;
	register char *cp;
	register int c, i;

	for (cp = str, i = 1; c = *cp; cp++, i++)
		accum += c * i;
	return(accum % HASH_SIZE);
}

struct graphsym *
fetch_graphsym(symname)
	char *symname;
{
	register struct graphsym *gs, **gsp;
	FILE *f;

	for (gsp = graphsym_hash + hash_graphsym_name(symname); gs = *gsp;
	     gsp = &gs->gs_nextinhash)
		if (!strcmp(gs->gs_name, symname))
			return(gs);

	gs = (struct graphsym *) malloc(sizeof(struct graphsym));
	bzero(gs, sizeof(struct graphsym));
	gs->gs_name = symname;
	f = find_symlib_file(symname, ".sym");
	if (!f) {
		fprintf(stderr, "Cannot locate graphical symbol \"%s\"\n",
			symname);
		exit(1);
	}
	gs->gs_pathname = copystr(sought_libfile_fullpath);
	read_symbol_file(gs, f);
	fclose(f);

	*gsp = gs;
	total_graphsyms++;
	return(gs);
}

load_graphsyms(schem)
	struct schem *schem;
{
	register struct schemobj *obj;

	for (obj = schem->obj_next; obj != (struct schemobj *)schem;
	     obj = obj->obj_next)
		switch (obj->obj_type) {
		case OBJTYPE_COMPINST:
			if (!obj->compobj_isgraph)
				continue;
			/* FALL THRU */
		case OBJTYPE_GRAPHSYM:
			obj->compobj_graphsym =
				fetch_graphsym(obj->compobj_graph_symname);
			load_decor_graphsyms(obj);
			break;
		}
}

load_decor_graphsyms(obj)
	struct schemobj *obj;
{
	register struct decoration *decor;

	for (decor = obj->obj_decorations; decor; decor = decor->decor_next) {
		if (decor->decor_type != DECOR_TYPE_SYMONPIN)
			continue;
		decor->decorpinsym_gs =
				fetch_graphsym(decor->decorpinsym_symname);
	}
}

graphsym_forall(callback)
	int (*callback)();
{
	register struct graphsym *gs, **hb;
	register int i;

	for (hb = graphsym_hash, i = 0; i < HASH_SIZE; hb++, i++)
		for (gs = *hb; gs; gs = gs->gs_nextinhash)
			callback(gs);
}

report_graphsym_hash_quality()
{
	register struct graphsym *gs, **hb;
	register int i, curchain;
	int maxchain = 0;

	for (hb = graphsym_hash, i = 0; i < HASH_SIZE; hb++, i++) {
		curchain = 0;
		for (gs = *hb; gs; gs = gs->gs_nextinhash)
			curchain++;
		if (curchain > maxchain)
			maxchain = curchain;
	}
	printf("%d graphsyms total, longest hash chain is %d\n",
		total_graphsyms, maxchain);
}