FreeCalypso > hg > ueda-linux
diff ueda/uschem-utils/rewrite.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/rewrite.c Mon Jul 20 00:24:37 2015 +0000 @@ -0,0 +1,268 @@ +/* + * 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; +}