FreeCalypso > hg > ueda-linux
view ueda/uschem-utils/checknets.c @ 101:ffab0a4424ad
ueda: unet-bind program moved into sensibly named unet-bind subdir
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 29 Sep 2019 22:42:41 +0000 |
parents | cd92449fdb51 |
children |
line wrap: on
line source
/* * 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); }