diff ueda/uschem-utils/checknets.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/uschem-utils/checknets.c	Mon Jul 20 00:24:37 2015 +0000
@@ -0,0 +1,190 @@
+/*
+ * Pseudo-netlist functionality for uschem-check
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <strings.h>
+#include "../libuschem/schemstruct.h"
+
+extern char *malloc();
+
+extern struct schem *schem;
+
+struct netname {
+	char	*name;
+	int	refcnt;
+	struct	netexcl *excl;
+	struct	netname *next;
+};
+
+struct netexcl {
+	char	*filename;
+	int	lineno;
+	struct	netexcl *next;
+};
+
+#define	HASH_SIZE	1103
+
+static struct netname *hashtab[HASH_SIZE];
+
+static int
+hash_netname(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);
+}
+
+static struct netname *
+get_netname_struct(name)
+	register char *name;
+{
+	register struct netname *n, **np;
+
+	for (np = hashtab + hash_netname(name); n = *np; np = &n->next)
+		if (!strcmp(n->name, name))
+			return(n);
+	n = (struct netname *) malloc(sizeof(struct netname));
+	if (!n) {
+		perror("malloc");
+		exit(1);
+	}
+	bzero(n, sizeof(struct netname));
+	n->name = name;
+	*np = n;
+	return(n);
+}
+
+record_netname_reference(netname, excl, filename, lineno)
+	char *netname, *filename;
+{
+	register struct netname *n;
+	register struct netexcl *e;
+
+	n = get_netname_struct(netname);
+	n->refcnt++;
+	if (!excl)
+		return;
+	e = (struct netexcl *) malloc(sizeof(struct netexcl));
+	if (!e) {
+		perror("malloc");
+		exit(1);
+	}
+	e->filename = filename;
+	e->lineno = lineno;
+	e->next = n->excl;
+	n->excl = e;
+}
+
+static
+get_exclusive_attr(obj, flagp)
+	struct schemobj *obj;
+	int *flagp;
+{
+	register struct decoration *decor;
+	register char *val;
+
+	for (decor = obj->obj_decorations; decor; decor = decor->decor_next)
+		if (decor->decor_type == DECOR_TYPE_ATTR &&
+		    !strcmp(decor->decorattr_name, "exclusive"))
+			break;
+	if (!decor)
+		return(0);
+	val = decor->decorattr_value;
+	if (!strcmp(val, "yes") || !strcmp(val, "true") || !strcmp(val, "1")) {
+		*flagp = 1;
+		return(1);
+	}
+	if (!strcmp(val, "no") || !strcmp(val, "false") || !strcmp(val, "0")) {
+		*flagp = 0;
+		return(1);
+	}
+	return(0);
+}
+
+static
+visual_netname_cues(grouphead)
+	struct schemobj *grouphead;
+{
+	register struct schemobj *obj;
+	register struct decoration *decor;
+
+	for (obj = grouphead; ; obj = obj->obj_next) {
+		if (obj->obj_type != OBJTYPE_GRAPHNET)
+			break;
+		if (obj->netobj_grouphead != grouphead)
+			break;
+		if (obj->netobj_forcenets)
+			return(1);
+		for (decor = obj->obj_decorations; decor;
+		     decor = decor->decor_next)
+			if (decor->decor_type == DECOR_TYPE_DISPLAYNETNAME)
+				return(1);
+	}
+	return(0);
+}
+
+check_exclusive_nets()
+{
+	register struct schemobj *obj;
+	int isexcl;
+
+	for (obj = schem->obj_next; obj != (struct schemobj *)schem;
+	     obj = obj->obj_next) {
+		switch (obj->obj_type) {
+		case OBJTYPE_NET:
+			if (!obj->netobj_netname)
+				continue;
+			if (!get_exclusive_attr(obj, &isexcl))
+				isexcl = 0;
+			record_netname_reference(obj->netobj_netname, isexcl,
+						 schem->orig_filename,
+						 obj->obj_lineno);
+			continue;
+		case OBJTYPE_GRAPHNET:
+			if (obj->netobj_grouphead != obj)
+				continue;
+			if (!obj->netobj_netname)
+				continue;
+			if (!get_exclusive_attr(obj, &isexcl)) {
+				if (visual_netname_cues(obj))
+					isexcl = 0;
+				else
+					isexcl = 1;
+			}
+			record_netname_reference(obj->netobj_netname, isexcl,
+						 schem->orig_filename,
+						 obj->obj_lineno);
+			continue;
+		}
+	}
+}
+
+static
+check_netname_for_excl(n)
+	struct netname *n;
+{
+	register struct netexcl *e;
+
+	for (e = n->excl; e; e = e->next)
+		fprintf(stderr,
+		"Exclusive net %s at %s line %d has other connections\n",
+			n->name, e->filename, e->lineno);
+}
+
+report_exclusive_net_violations()
+{
+	register struct netname *n, **hb;
+	register int i;
+
+	for (hb = hashtab, i = 0; i < HASH_SIZE; hb++, i++)
+		for (n = *hb; n; n = n->next)
+			if (n->refcnt > 1)
+				check_netname_for_excl(n);
+}