FreeCalypso > hg > ueda-linux
view ueda/libuschem/pins.c @ 81:6e43956e740d
beginning of BOM utils refactoring: seqrefdes code factored out
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 23 Feb 2017 19:15:48 +0000 |
parents | cd92449fdb51 |
children |
line wrap: on
line source
/* * 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); }