diff ueda/libuschem/pins.c @ 0:cd92449fdb51

initial import of ueda and ifctf-part-lib from ifctfvax CVS
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 20 Jul 2015 00:24:37 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ueda/libuschem/pins.c	Mon Jul 20 00:24:37 2015 +0000
@@ -0,0 +1,196 @@
+/*
+ * Working with graphical symbol pin instances
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <strings.h>
+#include "schemstruct.h"
+#include "graphsym.h"
+
+extern char *malloc();
+
+#define	HASH_SIZE	1103
+
+static int
+hash_coord(x, y)
+{
+	return((x + y) % HASH_SIZE);
+}
+
+static
+add_pin_to_hash(schem, pin)
+	struct schem *schem;
+	register struct graphsym_pininst *pin;
+{
+	register struct graphsym_pininst *hp, **hpp;
+
+	for (hpp = schem->pininst_hash + hash_coord(pin->x, pin->y); hp = *hpp;
+	     hpp = &hp->nextinhash)
+		if (pin->x == hp->x && pin->y == hp->y) {
+		    fprintf(stderr,
+		    "%s: more than one pin at (%d,%d), see lines %d and %d\n",
+			schem->orig_filename, pin->x, pin->y,
+			hp->compinst->obj_lineno, pin->compinst->obj_lineno);
+		    return(-1);
+		}
+	*hpp = pin;
+	return(0);
+}
+
+static
+instantiate_obj_pins(schem, obj, dohash)
+	struct schem *schem;
+	register struct schemobj *obj;
+{
+	register struct graphsym_pindef *pd;
+	register struct graphsym_pininst *pi;
+	int npins;
+	int x, y;
+	int errflag = 0, clashflag = 0;
+
+	npins = obj->compobj_graphsym->gs_npins;
+	pi = (struct graphsym_pininst *)
+			malloc(sizeof(struct graphsym_pininst) * npins);
+	if (!pi) {
+		perror("malloc");
+		exit(1);
+	}
+	obj->compobj_pins = pi;
+	for (pd = obj->compobj_graphsym->gs_pins; pd; pd = pd->gspd_next, pi++){
+		pi->compinst = obj;
+		pi->pindef = pd;
+		x = pd->gspd_x;
+		y = pd->gspd_y;
+		if (obj->compobj_mirror)
+			x = -x;
+		switch (obj->compobj_rotate) {
+		case 0:
+			pi->x = x;
+			pi->y = y;
+			break;
+		case 90:
+			pi->x = -y;
+			pi->y = x;
+			break;
+		case 180:
+			pi->x = -x;
+			pi->y = -y;
+			break;
+		case 270:
+			pi->x = y;
+			pi->y = -x;
+			break;
+		default:
+			if (!errflag) {
+				fprintf(stderr,
+	"%s: line %d: symbol rotated by %d deg, can't do pin instances\n",
+					schem->orig_filename, obj->obj_lineno,
+					obj->compobj_rotate);
+				errflag = 1;
+			}
+			/* a dummy so we don't have to abort */
+			pi->x = pi->y = 0;
+		}
+		pi->x += obj->compobj_x;
+		pi->y += obj->compobj_y;
+		pi->nextinhash = NULL;
+		if (dohash && !errflag)
+			if (add_pin_to_hash(schem, pi))
+				clashflag = 1;
+	}
+	return(errflag || clashflag);
+}
+
+/* prerequisite: load_graphsyms() */
+instantiate_graphsym_pins(schem, dohash)
+	struct schem *schem;
+{
+	register struct schemobj *obj;
+	int errstat = 0;
+	struct graphsym_pininst **hashtab;
+
+	if (dohash) {
+		hashtab = (struct graphsym_pininst **)
+			malloc(sizeof(struct graphsym_pininst *) * HASH_SIZE);
+		if (!hashtab) {
+			perror("malloc");
+			exit(1);
+		}
+		bzero(hashtab, sizeof(struct graphsym_pininst *) * HASH_SIZE);
+		schem->pininst_hash = hashtab;
+	}
+
+	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:
+			if (instantiate_obj_pins(schem, obj, dohash))
+				errstat = -1;
+			break;
+		}
+	return(errstat);
+}
+
+report_pininst_hash_quality(schem)
+	struct schem *schem;
+{
+	struct graphsym_pininst **hashtab;
+	int maxchain, total;
+	register int hb, curchain;
+	register struct graphsym_pininst *pin;
+
+	hashtab = schem->pininst_hash;
+	for (hb = 0, total = maxchain = 0; hb < HASH_SIZE; hb++) {
+		for (pin = hashtab[hb], curchain = 0; pin;
+		     pin = pin->nextinhash) {
+			curchain++;
+			total++;
+		}
+		if (curchain > maxchain)
+			maxchain = curchain;
+	}
+	printf("%s: %d pin instances total, longest hash chain is %d\n",
+		schem->orig_filename, total, maxchain);
+}
+
+struct graphsym_pininst *
+find_comp_pininst(comp, soughtpin, bynum)
+	struct schemobj *comp;
+	char *soughtpin;
+	int bynum;
+{
+	int npins;
+	register int i;
+	register struct graphsym_pininst *pi;
+	register char *pinid;
+
+	npins = comp->compobj_graphsym->gs_npins;
+	for (pi = comp->compobj_pins, i = 0; i < npins; pi++, i++) {
+		if (bynum)
+			pinid = pi->pindef->gspd_pinnumber;
+		else
+			pinid = pi->pindef->gspd_pinname;
+		if (pinid && !strcmp(pinid, soughtpin))
+			return(pi);
+	}
+	return(NULL);
+}
+
+struct graphsym_pininst *
+find_pin_by_coord(schem, x, y)
+	struct schem *schem;
+	register int x, y;
+{
+	register struct graphsym_pininst *pin;
+
+	for (pin = schem->pininst_hash[hash_coord(x, y)]; pin;
+	     pin = pin->nextinhash)
+		if (pin->x == x && pin->y == y)
+			return(pin);
+	return(NULL);
+}