FreeCalypso > hg > ueda-linux
view ueda/uschem-utils/rewrite.c @ 142:7bdce91da1a5
unet-excise utility added
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 19 Sep 2020 22:50:24 +0000 |
parents | cd92449fdb51 |
children |
line wrap: on
line source
/* * This program reads a uschem schematic into core and then writes it back out. * -g options converts NetLines to GraphNets and then preens/canonicalizes * all GraphNets, otherwise just exercises the parser & writer code in * libuschem. */ #include <sys/types.h> #include <sys/file.h> #include <stdio.h> #include <strings.h> #include "../libuschem/schemstruct.h" #include "../libuschem/graphsym.h" extern int optind; extern char *optarg; extern char *malloc(); extern struct schem *read_schem(); extern struct netpoint *parser_alloc_netpoint(); extern struct graphsym_pininst *find_pin_by_coord(); struct schem *schem; char *outfile; int replace_orig; int gflag, Oflag; char * mk_temp_newfilename() { int len; register char *str; len = strlen(schem->orig_filename) + 5; str = malloc(len); if (!str) { perror("malloc"); exit(1); } sprintf(str, "%s.new", schem->orig_filename); return(str); } main(argc, argv) char **argv; { register int c; int fd; FILE *outf; while ((c = getopt(argc, argv, "gI:o:O")) != EOF) switch (c) { case 'g': gflag++; break; case 'I': add_symfile_dir(optarg); break; case 'o': outfile = optarg; break; case 'O': Oflag++; break; default: usage: fprintf(stderr, "usage: %s [-o newfile] schemfile\n", argv[0]); exit(1); } if (!argv[optind]) goto usage; schem = read_schem(argv[optind]); if (!outfile) { outfile = mk_temp_newfilename(); replace_orig = 1; } if (gflag) { if (hash_component_instances(schem) < 0) exit(1); set_default_sympath(); load_graphsyms(schem); if (instantiate_graphsym_pins(schem, 1) < 0 && !Oflag) exit(1); convert_netlines_to_graphnets(); if (preen_graphnets(schem, 1, 1, 0, 1) < 0) exit(1); } c = O_WRONLY | O_CREAT; if (replace_orig) c |= O_EXCL; else c |= O_TRUNC; fd = open(outfile, c, 0644); if (fd < 0) { perror(outfile); exit(1); } outf = fdopen(fd, "w"); if (!outf) { perror("fdopen"); exit(1); } write_schem(schem, outf); fclose(outf); if (replace_orig) rename(outfile, schem->orig_filename); exit(0); } convert_netlines_to_graphnets() { register struct schemobj *obj; for (obj = schem->obj_next; obj != (struct schemobj *)schem; obj = obj->obj_next) if (obj->obj_type == OBJTYPE_NETLINE) convert_netline(obj); } convert_netline(obj) register struct schemobj *obj; { register struct netpoint *end1, *end2; end1 = parser_alloc_netpoint(NETPT_TYPE_POINT); end1->netpt_x = obj->lineobj_x1; end1->netpt_y = obj->lineobj_y1; end1->netpt_coord_valid = 1; pinify_netpoint(end1); end2 = parser_alloc_netpoint(NETPT_TYPE_POINT); end2->netpt_x = obj->lineobj_x2; end2->netpt_y = obj->lineobj_y2; end2->netpt_coord_valid = 1; pinify_netpoint(end2); end1->netpt_next = end2; obj->obj_type = OBJTYPE_GRAPHNET; obj->netobj_points = end1; obj->netobj_netname = NULL; if (!extend_new_graphnet(obj)) { end1->netpt_next = NULL; end2->netpt_next = end1; obj->netobj_points = end2; extend_new_graphnet(obj); } convert_netline_decors(obj); } pinify_netpoint(netpt) register struct netpoint *netpt; { register struct graphsym_pininst *pin; pin = find_pin_by_coord(schem, netpt->netpt_x, netpt->netpt_y); if (!pin) return; switch (pin->compinst->obj_type) { case OBJTYPE_COMPINST: netpt->netpt_type = NETPT_TYPE_PIN; return; case OBJTYPE_GRAPHSYM: netpt->netpt_type = NETPT_TYPE_PSEUDO; return; } } convert_netline_decors(obj) struct schemobj *obj; { register struct decoration *decor; struct decoration **np; for (np = &obj->obj_decorations; decor = *np; ) { switch (decor->decor_type) { case DECOR_TYPE_ATTR: if (strcmp(decor->decorattr_name, "netname")) break; if (obj->netobj_netname && strcmp(obj->netobj_netname, decor->decorattr_value)) { fprintf(stderr, "%s: line %d: net name conflict\n", schem->orig_filename, decor->decor_lineno); exit(1); } obj->netobj_netname = decor->decorattr_value; /* drop the decoration */ *np = decor->decor_next; continue; case DECOR_TYPE_DISPLAYATTR: if (!strcmp(decor->decordisp_attr, "netname")) decor->decor_type = DECOR_TYPE_DISPLAYNETNAME; break; } np = &decor->decor_next; } } struct netpoint * convert_netline_to_netpt(gn, nlobj, whichend) struct schemobj *gn; register struct schemobj *nlobj; int whichend; { register struct netpoint *netpt; netpt = parser_alloc_netpoint(NETPT_TYPE_POINT); switch (whichend) { case 1: netpt->netpt_x = nlobj->lineobj_x1; netpt->netpt_y = nlobj->lineobj_y1; break; case 2: netpt->netpt_x = nlobj->lineobj_x2; netpt->netpt_y = nlobj->lineobj_y2; break; } netpt->netpt_coord_valid = 1; pinify_netpoint(netpt); netconvert_append_decors(gn, nlobj); schemobj_unlink(nlobj); return(netpt); } extend_new_graphnet(gn) struct schemobj *gn; { register struct schemobj *obj; register struct netpoint *tail, *new; int success = 0; tail = gn->netobj_points->netpt_next; loop: for (obj = gn->obj_next; obj != (struct schemobj *)schem; obj = obj->obj_next) { if (obj->obj_type != OBJTYPE_NETLINE) continue; if (obj->lineobj_x1 == tail->netpt_x && obj->lineobj_y1 == tail->netpt_y) { new = convert_netline_to_netpt(gn, obj, 2); tail->netpt_next = new; tail = new; success = 1; goto loop; } if (obj->lineobj_x2 == tail->netpt_x && obj->lineobj_y2 == tail->netpt_y) { new = convert_netline_to_netpt(gn, obj, 1); tail->netpt_next = new; tail = new; success = 1; goto loop; } } return(success); } netconvert_append_decors(gnobj, nlobj) struct schemobj *gnobj, *nlobj; { register struct decoration *decor; register struct decoration **np; for (np = &gnobj->obj_decorations; decor = *np; np = &decor->decor_next) ; *np = nlobj->obj_decorations; }