FreeCalypso > hg > ueda-linux
comparison 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 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:cd92449fdb51 |
|---|---|
| 1 /* | |
| 2 * This program reads a uschem schematic into core and then writes it back out. | |
| 3 * -g options converts NetLines to GraphNets and then preens/canonicalizes | |
| 4 * all GraphNets, otherwise just exercises the parser & writer code in | |
| 5 * libuschem. | |
| 6 */ | |
| 7 | |
| 8 #include <sys/types.h> | |
| 9 #include <sys/file.h> | |
| 10 #include <stdio.h> | |
| 11 #include <strings.h> | |
| 12 #include "../libuschem/schemstruct.h" | |
| 13 #include "../libuschem/graphsym.h" | |
| 14 | |
| 15 extern int optind; | |
| 16 extern char *optarg; | |
| 17 extern char *malloc(); | |
| 18 | |
| 19 extern struct schem *read_schem(); | |
| 20 extern struct netpoint *parser_alloc_netpoint(); | |
| 21 extern struct graphsym_pininst *find_pin_by_coord(); | |
| 22 | |
| 23 struct schem *schem; | |
| 24 char *outfile; | |
| 25 int replace_orig; | |
| 26 int gflag, Oflag; | |
| 27 | |
| 28 char * | |
| 29 mk_temp_newfilename() | |
| 30 { | |
| 31 int len; | |
| 32 register char *str; | |
| 33 | |
| 34 len = strlen(schem->orig_filename) + 5; | |
| 35 str = malloc(len); | |
| 36 if (!str) { | |
| 37 perror("malloc"); | |
| 38 exit(1); | |
| 39 } | |
| 40 sprintf(str, "%s.new", schem->orig_filename); | |
| 41 return(str); | |
| 42 } | |
| 43 | |
| 44 main(argc, argv) | |
| 45 char **argv; | |
| 46 { | |
| 47 register int c; | |
| 48 int fd; | |
| 49 FILE *outf; | |
| 50 | |
| 51 while ((c = getopt(argc, argv, "gI:o:O")) != EOF) | |
| 52 switch (c) { | |
| 53 case 'g': | |
| 54 gflag++; | |
| 55 break; | |
| 56 case 'I': | |
| 57 add_symfile_dir(optarg); | |
| 58 break; | |
| 59 case 'o': | |
| 60 outfile = optarg; | |
| 61 break; | |
| 62 case 'O': | |
| 63 Oflag++; | |
| 64 break; | |
| 65 default: | |
| 66 usage: fprintf(stderr, "usage: %s [-o newfile] schemfile\n", | |
| 67 argv[0]); | |
| 68 exit(1); | |
| 69 } | |
| 70 if (!argv[optind]) | |
| 71 goto usage; | |
| 72 | |
| 73 schem = read_schem(argv[optind]); | |
| 74 if (!outfile) { | |
| 75 outfile = mk_temp_newfilename(); | |
| 76 replace_orig = 1; | |
| 77 } | |
| 78 | |
| 79 if (gflag) { | |
| 80 if (hash_component_instances(schem) < 0) | |
| 81 exit(1); | |
| 82 set_default_sympath(); | |
| 83 load_graphsyms(schem); | |
| 84 if (instantiate_graphsym_pins(schem, 1) < 0 && !Oflag) | |
| 85 exit(1); | |
| 86 convert_netlines_to_graphnets(); | |
| 87 if (preen_graphnets(schem, 1, 1, 0, 1) < 0) | |
| 88 exit(1); | |
| 89 } | |
| 90 | |
| 91 c = O_WRONLY | O_CREAT; | |
| 92 if (replace_orig) | |
| 93 c |= O_EXCL; | |
| 94 else | |
| 95 c |= O_TRUNC; | |
| 96 fd = open(outfile, c, 0644); | |
| 97 if (fd < 0) { | |
| 98 perror(outfile); | |
| 99 exit(1); | |
| 100 } | |
| 101 outf = fdopen(fd, "w"); | |
| 102 if (!outf) { | |
| 103 perror("fdopen"); | |
| 104 exit(1); | |
| 105 } | |
| 106 write_schem(schem, outf); | |
| 107 fclose(outf); | |
| 108 if (replace_orig) | |
| 109 rename(outfile, schem->orig_filename); | |
| 110 exit(0); | |
| 111 } | |
| 112 | |
| 113 convert_netlines_to_graphnets() | |
| 114 { | |
| 115 register struct schemobj *obj; | |
| 116 | |
| 117 for (obj = schem->obj_next; obj != (struct schemobj *)schem; | |
| 118 obj = obj->obj_next) | |
| 119 if (obj->obj_type == OBJTYPE_NETLINE) | |
| 120 convert_netline(obj); | |
| 121 } | |
| 122 | |
| 123 convert_netline(obj) | |
| 124 register struct schemobj *obj; | |
| 125 { | |
| 126 register struct netpoint *end1, *end2; | |
| 127 | |
| 128 end1 = parser_alloc_netpoint(NETPT_TYPE_POINT); | |
| 129 end1->netpt_x = obj->lineobj_x1; | |
| 130 end1->netpt_y = obj->lineobj_y1; | |
| 131 end1->netpt_coord_valid = 1; | |
| 132 pinify_netpoint(end1); | |
| 133 end2 = parser_alloc_netpoint(NETPT_TYPE_POINT); | |
| 134 end2->netpt_x = obj->lineobj_x2; | |
| 135 end2->netpt_y = obj->lineobj_y2; | |
| 136 end2->netpt_coord_valid = 1; | |
| 137 pinify_netpoint(end2); | |
| 138 end1->netpt_next = end2; | |
| 139 obj->obj_type = OBJTYPE_GRAPHNET; | |
| 140 obj->netobj_points = end1; | |
| 141 obj->netobj_netname = NULL; | |
| 142 if (!extend_new_graphnet(obj)) { | |
| 143 end1->netpt_next = NULL; | |
| 144 end2->netpt_next = end1; | |
| 145 obj->netobj_points = end2; | |
| 146 extend_new_graphnet(obj); | |
| 147 } | |
| 148 convert_netline_decors(obj); | |
| 149 } | |
| 150 | |
| 151 pinify_netpoint(netpt) | |
| 152 register struct netpoint *netpt; | |
| 153 { | |
| 154 register struct graphsym_pininst *pin; | |
| 155 | |
| 156 pin = find_pin_by_coord(schem, netpt->netpt_x, netpt->netpt_y); | |
| 157 if (!pin) | |
| 158 return; | |
| 159 switch (pin->compinst->obj_type) { | |
| 160 case OBJTYPE_COMPINST: | |
| 161 netpt->netpt_type = NETPT_TYPE_PIN; | |
| 162 return; | |
| 163 case OBJTYPE_GRAPHSYM: | |
| 164 netpt->netpt_type = NETPT_TYPE_PSEUDO; | |
| 165 return; | |
| 166 } | |
| 167 } | |
| 168 | |
| 169 convert_netline_decors(obj) | |
| 170 struct schemobj *obj; | |
| 171 { | |
| 172 register struct decoration *decor; | |
| 173 struct decoration **np; | |
| 174 | |
| 175 for (np = &obj->obj_decorations; decor = *np; ) { | |
| 176 switch (decor->decor_type) { | |
| 177 case DECOR_TYPE_ATTR: | |
| 178 if (strcmp(decor->decorattr_name, "netname")) | |
| 179 break; | |
| 180 if (obj->netobj_netname && | |
| 181 strcmp(obj->netobj_netname, decor->decorattr_value)) { | |
| 182 fprintf(stderr, | |
| 183 "%s: line %d: net name conflict\n", | |
| 184 schem->orig_filename, | |
| 185 decor->decor_lineno); | |
| 186 exit(1); | |
| 187 } | |
| 188 obj->netobj_netname = decor->decorattr_value; | |
| 189 /* drop the decoration */ | |
| 190 *np = decor->decor_next; | |
| 191 continue; | |
| 192 case DECOR_TYPE_DISPLAYATTR: | |
| 193 if (!strcmp(decor->decordisp_attr, "netname")) | |
| 194 decor->decor_type = DECOR_TYPE_DISPLAYNETNAME; | |
| 195 break; | |
| 196 } | |
| 197 np = &decor->decor_next; | |
| 198 } | |
| 199 } | |
| 200 | |
| 201 struct netpoint * | |
| 202 convert_netline_to_netpt(gn, nlobj, whichend) | |
| 203 struct schemobj *gn; | |
| 204 register struct schemobj *nlobj; | |
| 205 int whichend; | |
| 206 { | |
| 207 register struct netpoint *netpt; | |
| 208 | |
| 209 netpt = parser_alloc_netpoint(NETPT_TYPE_POINT); | |
| 210 switch (whichend) { | |
| 211 case 1: | |
| 212 netpt->netpt_x = nlobj->lineobj_x1; | |
| 213 netpt->netpt_y = nlobj->lineobj_y1; | |
| 214 break; | |
| 215 case 2: | |
| 216 netpt->netpt_x = nlobj->lineobj_x2; | |
| 217 netpt->netpt_y = nlobj->lineobj_y2; | |
| 218 break; | |
| 219 } | |
| 220 netpt->netpt_coord_valid = 1; | |
| 221 pinify_netpoint(netpt); | |
| 222 netconvert_append_decors(gn, nlobj); | |
| 223 schemobj_unlink(nlobj); | |
| 224 return(netpt); | |
| 225 } | |
| 226 | |
| 227 extend_new_graphnet(gn) | |
| 228 struct schemobj *gn; | |
| 229 { | |
| 230 register struct schemobj *obj; | |
| 231 register struct netpoint *tail, *new; | |
| 232 int success = 0; | |
| 233 | |
| 234 tail = gn->netobj_points->netpt_next; | |
| 235 loop: for (obj = gn->obj_next; obj != (struct schemobj *)schem; | |
| 236 obj = obj->obj_next) { | |
| 237 if (obj->obj_type != OBJTYPE_NETLINE) | |
| 238 continue; | |
| 239 if (obj->lineobj_x1 == tail->netpt_x && | |
| 240 obj->lineobj_y1 == tail->netpt_y) { | |
| 241 new = convert_netline_to_netpt(gn, obj, 2); | |
| 242 tail->netpt_next = new; | |
| 243 tail = new; | |
| 244 success = 1; | |
| 245 goto loop; | |
| 246 } | |
| 247 if (obj->lineobj_x2 == tail->netpt_x && | |
| 248 obj->lineobj_y2 == tail->netpt_y) { | |
| 249 new = convert_netline_to_netpt(gn, obj, 1); | |
| 250 tail->netpt_next = new; | |
| 251 tail = new; | |
| 252 success = 1; | |
| 253 goto loop; | |
| 254 } | |
| 255 } | |
| 256 return(success); | |
| 257 } | |
| 258 | |
| 259 netconvert_append_decors(gnobj, nlobj) | |
| 260 struct schemobj *gnobj, *nlobj; | |
| 261 { | |
| 262 register struct decoration *decor; | |
| 263 register struct decoration **np; | |
| 264 | |
| 265 for (np = &gnobj->obj_decorations; decor = *np; np = &decor->decor_next) | |
| 266 ; | |
| 267 *np = nlobj->obj_decorations; | |
| 268 } |
