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