FreeCalypso > hg > ueda-linux
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); +}