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 }