FreeCalypso > hg > ueda-linux
comparison ueda/libuschem/rdschem_parse.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 * uschem schematic parser | |
3 */ | |
4 | |
5 #include <sys/types.h> | |
6 #include <stdio.h> | |
7 #include <strings.h> | |
8 #include "schemstruct.h" | |
9 #include "parserint.h" | |
10 | |
11 extern char *copystr(); | |
12 | |
13 extern struct schem_parse_state schem_parse_state; | |
14 | |
15 extern struct schemobj *parser_alloc_obj(); | |
16 extern struct decoration *parser_alloc_decor(); | |
17 extern struct netpoint *parser_alloc_netpoint(); | |
18 extern struct xypair parse_drawing_size_spec(); | |
19 extern struct graphblock *rdschem_graphblock(); | |
20 | |
21 rdschem_parse_schemline() | |
22 { | |
23 register int t; | |
24 struct xypair drawing_size; | |
25 | |
26 t = rdschem_token(); | |
27 if (t != STRING || strcmp(schem_parse_state.string, "Schem")) { | |
28 fprintf(stderr, | |
29 "%s is not a uschem schematic (doesn't begin with Schem)\n", | |
30 schem_parse_state.schem->orig_filename); | |
31 exit(1); | |
32 } | |
33 | |
34 t = rdschem_token(); | |
35 if (t != STRING) | |
36 inv: rdschem_error("Schem line: syntax error"); | |
37 if (!strcmp(schem_parse_state.string, "graph")) { | |
38 schem_parse_state.schem->is_graph = 1; | |
39 t = rdschem_token(); | |
40 if (t != STRING && t != QSTRING) | |
41 goto inv; | |
42 drawing_size = | |
43 parse_drawing_size_spec(schem_parse_state.string); | |
44 schem_parse_state.schem->graph_xsize = drawing_size.x; | |
45 schem_parse_state.schem->graph_ysize = drawing_size.y; | |
46 } else if (!strcmp(schem_parse_state.string, "nograph")) | |
47 schem_parse_state.schem->is_graph = 0; | |
48 else | |
49 goto inv; | |
50 | |
51 t = rdschem_token(); | |
52 if (t != ';') | |
53 goto inv; | |
54 } | |
55 | |
56 static struct decoration * | |
57 parse_decor_attr() | |
58 { | |
59 register struct decoration *decor; | |
60 register int t; | |
61 | |
62 decor = parser_alloc_decor(DECOR_TYPE_ATTR); | |
63 t = rdschem_token(); | |
64 if (t != STRING && t != QSTRING) | |
65 syntaxerr: rdschem_error("(attribute definition decoration) syntax error"); | |
66 if (!schem_parse_state.string[0]) | |
67 rdschem_error("attribute name may not be a null string"); | |
68 decor->decorattr_name = copystr(schem_parse_state.string); | |
69 t = rdschem_token(); | |
70 if (t != '=') | |
71 goto syntaxerr; | |
72 t = rdschem_token(); | |
73 if (t != STRING && t != QSTRING) | |
74 goto syntaxerr; | |
75 if (!schem_parse_state.string[0]) | |
76 rdschem_error("attribute value may not be a null string"); | |
77 decor->decorattr_value = copystr(schem_parse_state.string); | |
78 t = rdschem_token(); | |
79 if (t != ')') | |
80 goto syntaxerr; | |
81 return(decor); | |
82 } | |
83 | |
84 static struct decoration * | |
85 parse_decor_displayattr() | |
86 { | |
87 register struct decoration *decor; | |
88 register int t; | |
89 | |
90 decor = parser_alloc_decor(DECOR_TYPE_DISPLAYATTR); | |
91 t = rdschem_token(); | |
92 if (t != STRING && t != QSTRING) | |
93 syntaxerr: rdschem_error("(DisplayAttr decoration) syntax error"); | |
94 if (!schem_parse_state.string[0]) | |
95 rdschem_error("attribute name may not be a null string"); | |
96 decor->decordisp_attr = copystr(schem_parse_state.string); | |
97 decor->decordisp_x = parse_number(); | |
98 decor->decordisp_y = parse_number(); | |
99 decor->decordisp_ptsize = parse_number(); | |
100 decor->decordisp_rotate = parse_number(); | |
101 decor->decordisp_alignment = parse_number(); | |
102 t = rdschem_token(); | |
103 if (t != ';') | |
104 goto syntaxerr; | |
105 return(decor); | |
106 } | |
107 | |
108 static struct decoration * | |
109 parse_decor_displaynetname() | |
110 { | |
111 register struct decoration *decor; | |
112 register int t; | |
113 | |
114 decor = parser_alloc_decor(DECOR_TYPE_DISPLAYNETNAME); | |
115 decor->decordisp_x = parse_number(); | |
116 decor->decordisp_y = parse_number(); | |
117 decor->decordisp_ptsize = parse_number(); | |
118 decor->decordisp_rotate = parse_number(); | |
119 decor->decordisp_alignment = parse_number(); | |
120 t = rdschem_token(); | |
121 if (t != ';') | |
122 rdschem_error("(DisplayNetName decoration) syntax error"); | |
123 return(decor); | |
124 } | |
125 | |
126 static struct decoration * | |
127 parse_decor_pintonet() | |
128 { | |
129 register struct decoration *decor; | |
130 register int t; | |
131 | |
132 decor = parser_alloc_decor(DECOR_TYPE_PINTONET); | |
133 t = rdschem_token(); | |
134 if (t != STRING && t != QSTRING) | |
135 syntaxerr: rdschem_error("(PinToNet decoration) syntax error"); | |
136 if (!schem_parse_state.string[0]) | |
137 rdschem_error("pin ID may not be a null string"); | |
138 if (!strcmp(schem_parse_state.string, "#")) | |
139 rdschem_error("pin ID \"#\" is invalid"); | |
140 decor->decorpincon_pin = copystr(schem_parse_state.string); | |
141 t = rdschem_token(); | |
142 if (t != STRING && t != QSTRING) | |
143 goto syntaxerr; | |
144 if (!schem_parse_state.string[0]) | |
145 rdschem_error("net name may not be a null string"); | |
146 decor->decorpincon_netname = copystr(schem_parse_state.string); | |
147 t = rdschem_token(); | |
148 if (t != ';') | |
149 goto syntaxerr; | |
150 return(decor); | |
151 } | |
152 | |
153 static struct decoration * | |
154 parse_decor_noconnect() | |
155 { | |
156 register struct decoration *decor; | |
157 register int t; | |
158 | |
159 decor = parser_alloc_decor(DECOR_TYPE_NOCONNECT); | |
160 t = rdschem_token(); | |
161 if (t != STRING && t != QSTRING) | |
162 syntaxerr: rdschem_error("(NoConnect decoration) syntax error"); | |
163 if (!schem_parse_state.string[0]) | |
164 rdschem_error("pin ID may not be a null string"); | |
165 if (!strcmp(schem_parse_state.string, "#")) | |
166 rdschem_error("pin ID \"#\" is invalid"); | |
167 decor->decorpincon_pin = copystr(schem_parse_state.string); | |
168 t = rdschem_token(); | |
169 if (t != ';') | |
170 goto syntaxerr; | |
171 return(decor); | |
172 } | |
173 | |
174 static struct decoration * | |
175 parse_decor_symonpin() | |
176 { | |
177 register struct decoration *decor; | |
178 register int t; | |
179 | |
180 decor = parser_alloc_decor(DECOR_TYPE_SYMONPIN); | |
181 t = rdschem_token(); | |
182 if (t != STRING && t != QSTRING) | |
183 syntaxerr: rdschem_error("(SymOnPin decoration) syntax error"); | |
184 if (!schem_parse_state.string[0]) | |
185 rdschem_error("pin ID may not be a null string"); | |
186 if (!strcmp(schem_parse_state.string, "#")) | |
187 rdschem_error("pin ID \"#\" is invalid"); | |
188 decor->decorpinsym_pin = copystr(schem_parse_state.string); | |
189 t = rdschem_token(); | |
190 if (t != STRING && t != QSTRING) | |
191 goto syntaxerr; | |
192 if (!schem_parse_state.string[0]) | |
193 rdschem_error("graphical symbol name may not be a null string"); | |
194 decor->decorpinsym_symname = copystr(schem_parse_state.string); | |
195 t = rdschem_token(); | |
196 if (t == STRING && !strcmp(schem_parse_state.string, "mirror")) { | |
197 decor->decorpinsym_mirror = 1; | |
198 t = rdschem_token(); | |
199 } | |
200 if (t != ';') | |
201 goto syntaxerr; | |
202 return(decor); | |
203 } | |
204 | |
205 static struct decoration * | |
206 parse_decor_graphblock(type) | |
207 { | |
208 register int t; | |
209 register struct decoration *decor; | |
210 register struct graphblock *blk; | |
211 | |
212 t = rdschem_token(); | |
213 if (t != '{') | |
214 rdschem_error("GraphBlockG/GraphBlockPS must be followed by '{'"); | |
215 blk = rdschem_graphblock(type); | |
216 decor = parser_alloc_decor(DECOR_TYPE_GRAPHBLOCK); | |
217 decor->decorgraph_body = blk; | |
218 schem_parse_state.schem->has_graphblocks = 1; | |
219 return(decor); | |
220 } | |
221 | |
222 static struct decoration * | |
223 parse_decor_comment() | |
224 { | |
225 register int t; | |
226 register struct decoration *decor; | |
227 | |
228 t = rdschem_token(); | |
229 if (t != STRING && t != QSTRING) | |
230 syntaxerr: rdschem_error("(Comment decoration) syntax error"); | |
231 if (!schem_parse_state.string[0]) | |
232 rdschem_error("schematic comment may not be a null string"); | |
233 decor = parser_alloc_decor(DECOR_TYPE_COMMENT); | |
234 decor->decorcomment_text = copystr(schem_parse_state.string); | |
235 t = rdschem_token(); | |
236 if (t != ';') | |
237 goto syntaxerr; | |
238 return(decor); | |
239 } | |
240 | |
241 struct decoration * | |
242 rdschem_parse_decor_block() | |
243 { | |
244 struct decoration *decor, *head, **tailp; | |
245 register int t; | |
246 char errbuf[256]; | |
247 | |
248 for (head = NULL, tailp = &head; ; ) { | |
249 t = rdschem_token(); | |
250 switch (t) { | |
251 case 0: | |
252 rdschem_error("EOF in a decoration block"); | |
253 case '(': | |
254 decor = parse_decor_attr(); | |
255 goto addit; | |
256 case ';': | |
257 /* "null statement" */ | |
258 continue; | |
259 case '}': | |
260 return(head); | |
261 } | |
262 if (t != STRING) | |
263 rdschem_error("syntax error: decoration keyword expected"); | |
264 if (!strcmp(schem_parse_state.string, "DisplayAttr")) | |
265 decor = parse_decor_displayattr(); | |
266 else if (!strcmp(schem_parse_state.string, "DisplayNetName")) | |
267 decor = parse_decor_displaynetname(); | |
268 else if (!strcmp(schem_parse_state.string, "PinToNet")) | |
269 decor = parse_decor_pintonet(); | |
270 else if (!strcmp(schem_parse_state.string, "NoConnect")) | |
271 decor = parse_decor_noconnect(); | |
272 else if (!strcmp(schem_parse_state.string, "SymOnPin")) | |
273 decor = parse_decor_symonpin(); | |
274 else if (!strcmp(schem_parse_state.string, "GraphBlockG")) | |
275 decor = parse_decor_graphblock(GRAPHBLOCK_TYPE_GSCHEM); | |
276 else if (!strcmp(schem_parse_state.string, "GraphBlockPS")) | |
277 decor = parse_decor_graphblock(GRAPHBLOCK_TYPE_PS); | |
278 else if (!strcmp(schem_parse_state.string, "Comment")) | |
279 decor = parse_decor_comment(); | |
280 else { | |
281 sprintf(errbuf, | |
282 "%s is not a recognized decoration keyword", | |
283 schem_parse_state.string); | |
284 rdschem_error(errbuf); | |
285 } | |
286 addit: *tailp = decor; | |
287 tailp = &decor->decor_next; | |
288 } | |
289 } | |
290 | |
291 rdschem_parse_object() | |
292 { | |
293 register int t; | |
294 char errbuf[256]; | |
295 | |
296 t = rdschem_token(); | |
297 if (!t) /* EOF aka end of schematic */ | |
298 return(1); | |
299 if (t == ';') /* "null statement" */ | |
300 return(0); | |
301 if (t != STRING) | |
302 rdschem_error("syntax error: object keyword expected"); | |
303 | |
304 if (!strcmp(schem_parse_state.string, "Component")) | |
305 return(rdschem_parse_compinst()); | |
306 if (!strcmp(schem_parse_state.string, "GraphSym")) | |
307 return(rdschem_parse_graphsym()); | |
308 if (!strcmp(schem_parse_state.string, "Net")) | |
309 return(rdschem_parse_net()); | |
310 if (!strcmp(schem_parse_state.string, "GraphNet")) | |
311 return(rdschem_parse_graphnet()); | |
312 if (!strcmp(schem_parse_state.string, "NetLine")) | |
313 return(rdschem_parse_netline()); | |
314 if (!strcmp(schem_parse_state.string, "BusSeg")) | |
315 return(rdschem_parse_busseg()); | |
316 if (!strcmp(schem_parse_state.string, "GraphBlockG")) | |
317 return(rdschem_parse_graphblock_obj(GRAPHBLOCK_TYPE_GSCHEM)); | |
318 if (!strcmp(schem_parse_state.string, "GraphBlockPS")) | |
319 return(rdschem_parse_graphblock_obj(GRAPHBLOCK_TYPE_PS)); | |
320 if (!strcmp(schem_parse_state.string, "Comment")) | |
321 return(rdschem_parse_comment_obj()); | |
322 | |
323 sprintf(errbuf, "%s is not a recognized object keyword", | |
324 schem_parse_state.string); | |
325 rdschem_error(errbuf); | |
326 } | |
327 | |
328 rdschem_parse_compinst() | |
329 { | |
330 register int t; | |
331 register struct schemobj *obj; | |
332 | |
333 obj = parser_alloc_obj(OBJTYPE_COMPINST); | |
334 t = rdschem_token(); | |
335 if (t != STRING && t != QSTRING) | |
336 syntaxerr: rdschem_error("(Component object) syntax error"); | |
337 if (!schem_parse_state.string[0]) | |
338 rdschem_error("component instance name may not be a null string"); | |
339 obj->compobj_instname = copystr(schem_parse_state.string); | |
340 | |
341 t = rdschem_token(); | |
342 if (t == STRING && !strcmp(schem_parse_state.string, "graph")) { | |
343 obj->compobj_isgraph = 1; | |
344 t = rdschem_token(); | |
345 if (t != STRING && t != QSTRING) | |
346 goto syntaxerr; | |
347 if (!schem_parse_state.string[0]) | |
348 rdschem_error("graphical symbol name may not be a null string"); | |
349 obj->compobj_graph_symname = copystr(schem_parse_state.string); | |
350 obj->compobj_x = parse_number(); | |
351 obj->compobj_y = parse_number(); | |
352 t = rdschem_token(); | |
353 if (t == STRING && !strcmp(schem_parse_state.string, "rot")) { | |
354 obj->compobj_rotate = parse_number(); | |
355 t = rdschem_token(); | |
356 } | |
357 if (t == STRING && !strcmp(schem_parse_state.string, "mirror")){ | |
358 obj->compobj_mirror = 1; | |
359 t = rdschem_token(); | |
360 } | |
361 } | |
362 | |
363 if (t == '{') { | |
364 obj->obj_decorations = rdschem_parse_decor_block(); | |
365 t = rdschem_token(); | |
366 } | |
367 | |
368 if (t != ';') | |
369 goto syntaxerr; | |
370 parser_add_object(obj); | |
371 return(0); | |
372 } | |
373 | |
374 rdschem_parse_graphsym() | |
375 { | |
376 register int t; | |
377 register struct schemobj *obj; | |
378 | |
379 obj = parser_alloc_obj(OBJTYPE_GRAPHSYM); | |
380 t = rdschem_token(); | |
381 if (t != STRING && t != QSTRING) | |
382 syntaxerr: rdschem_error("(GraphSym object) syntax error"); | |
383 if (!schem_parse_state.string[0]) | |
384 rdschem_error("graphical symbol name may not be a null string"); | |
385 obj->compobj_graph_symname = copystr(schem_parse_state.string); | |
386 | |
387 obj->compobj_x = parse_number(); | |
388 obj->compobj_y = parse_number(); | |
389 t = rdschem_token(); | |
390 if (t == STRING && !strcmp(schem_parse_state.string, "rot")) { | |
391 obj->compobj_rotate = parse_number(); | |
392 t = rdschem_token(); | |
393 } | |
394 if (t == STRING && !strcmp(schem_parse_state.string, "mirror")) { | |
395 obj->compobj_mirror = 1; | |
396 t = rdschem_token(); | |
397 } | |
398 if (t == '{') { | |
399 obj->obj_decorations = rdschem_parse_decor_block(); | |
400 t = rdschem_token(); | |
401 } | |
402 | |
403 if (t != ';') | |
404 goto syntaxerr; | |
405 parser_add_object(obj); | |
406 return(0); | |
407 } | |
408 | |
409 rdschem_parse_net() | |
410 { | |
411 register int t; | |
412 register struct schemobj *obj; | |
413 register struct netpoint *netpt; | |
414 struct netpoint *head, **tailp; | |
415 | |
416 obj = parser_alloc_obj(OBJTYPE_NET); | |
417 t = rdschem_token(); | |
418 if (t != STRING && t != QSTRING) | |
419 syntaxerr: rdschem_error("(Net object) syntax error"); | |
420 if (schem_parse_state.string[0]) | |
421 obj->netobj_netname = copystr(schem_parse_state.string); | |
422 | |
423 head = NULL; | |
424 tailp = &head; | |
425 for (;;) { | |
426 t = rdschem_token(); | |
427 if (t == ';' || t == '{') | |
428 break; | |
429 if (t != STRING && t != QSTRING) | |
430 goto syntaxerr; | |
431 if (!schem_parse_state.string[0]) | |
432 goto syntaxerr; | |
433 netpt = parser_alloc_netpoint(NETPT_TYPE_PIN); | |
434 netpt->netpt_pin_nameref = copystr(schem_parse_state.string); | |
435 *tailp = netpt; | |
436 tailp = &netpt->netpt_next; | |
437 } | |
438 obj->netobj_points = head; | |
439 | |
440 if (t == '{') { | |
441 obj->obj_decorations = rdschem_parse_decor_block(); | |
442 t = rdschem_token(); | |
443 } | |
444 if (t != ';') | |
445 goto syntaxerr; | |
446 | |
447 if (obj->netobj_points) | |
448 parser_add_object(obj); | |
449 else { | |
450 fprintf(stderr, "%s: line %d: null Net object ignored\n", | |
451 schem_parse_state.schem->orig_filename, | |
452 schem_parse_state.lineno); | |
453 free(obj); | |
454 } | |
455 return(0); | |
456 } | |
457 | |
458 static struct xypair | |
459 parse_coord_pair() | |
460 { | |
461 register int t; | |
462 struct xypair retval; | |
463 | |
464 retval.x = parse_number(); | |
465 t = rdschem_token(); | |
466 if (t != ',') | |
467 syntaxerr: rdschem_error("syntax error in coordinate pair"); | |
468 retval.y = parse_number(); | |
469 t = rdschem_token(); | |
470 if (t != ')') | |
471 goto syntaxerr; | |
472 return(retval); | |
473 } | |
474 | |
475 static struct netpoint * | |
476 parse_graphnet_point() | |
477 { | |
478 register int t; | |
479 register struct netpoint *netpt; | |
480 struct xypair coord_pair; | |
481 | |
482 t = rdschem_token(); | |
483 if (t == '(') { | |
484 netpt = parser_alloc_netpoint(NETPT_TYPE_POINT); | |
485 coord_pair = parse_coord_pair(); | |
486 netpt->netpt_x = coord_pair.x; | |
487 netpt->netpt_y = coord_pair.y; | |
488 netpt->netpt_coord_valid = 1; | |
489 return(netpt); | |
490 } else if (t == STRING && !strcmp(schem_parse_state.string, "Pin")) { | |
491 netpt = parser_alloc_netpoint(NETPT_TYPE_PIN); | |
492 t = rdschem_token(); | |
493 if (t == '(') { | |
494 coord_pair = parse_coord_pair(); | |
495 netpt->netpt_x = coord_pair.x; | |
496 netpt->netpt_y = coord_pair.y; | |
497 netpt->netpt_coord_valid = 1; | |
498 t = rdschem_token(); | |
499 } | |
500 if (t == '=') { | |
501 t = rdschem_token(); | |
502 if (t != STRING && t != QSTRING || | |
503 !schem_parse_state.string[0]) | |
504 rdschem_error("syntax error: pin name reference expected"); | |
505 netpt->netpt_pin_nameref = | |
506 copystr(schem_parse_state.string); | |
507 } else if (netpt->netpt_coord_valid) | |
508 schem_parse_state.pushback_token = t; | |
509 else | |
510 rdschem_error("syntax error: Pin must be followed by coordinates or name reference"); | |
511 return(netpt); | |
512 } else if (t == STRING && !strcmp(schem_parse_state.string, "Tjoin")) { | |
513 netpt = parser_alloc_netpoint(NETPT_TYPE_TJOIN); | |
514 t = rdschem_token(); | |
515 if (t != '(') | |
516 rdschem_error("syntax error: Tjoin must be followed by coordinates"); | |
517 coord_pair = parse_coord_pair(); | |
518 netpt->netpt_x = coord_pair.x; | |
519 netpt->netpt_y = coord_pair.y; | |
520 netpt->netpt_coord_valid = 1; | |
521 return(netpt); | |
522 } else if (t == STRING && !strcmp(schem_parse_state.string, "Pseudo")) { | |
523 netpt = parser_alloc_netpoint(NETPT_TYPE_PSEUDO); | |
524 t = rdschem_token(); | |
525 if (t != '(') | |
526 rdschem_error("syntax error: Pseudo must be followed by coordinates"); | |
527 coord_pair = parse_coord_pair(); | |
528 netpt->netpt_x = coord_pair.x; | |
529 netpt->netpt_y = coord_pair.y; | |
530 netpt->netpt_coord_valid = 1; | |
531 return(netpt); | |
532 } | |
533 schem_parse_state.pushback_token = t; | |
534 return(NULL); | |
535 } | |
536 | |
537 rdschem_parse_graphnet() | |
538 { | |
539 register int t; | |
540 register struct schemobj *obj; | |
541 register struct netpoint *netpt; | |
542 struct netpoint *head, **tailp; | |
543 | |
544 obj = parser_alloc_obj(OBJTYPE_GRAPHNET); | |
545 t = rdschem_token(); | |
546 if (t != STRING && t != QSTRING) | |
547 syntaxerr: rdschem_error("(GraphNet object) syntax error"); | |
548 if (schem_parse_state.string[0]) | |
549 obj->netobj_netname = copystr(schem_parse_state.string); | |
550 | |
551 head = NULL; | |
552 tailp = &head; | |
553 for (;;) { | |
554 netpt = parse_graphnet_point(); | |
555 if (!netpt) | |
556 break; | |
557 *tailp = netpt; | |
558 tailp = &netpt->netpt_next; | |
559 } | |
560 obj->netobj_points = head; | |
561 | |
562 t = rdschem_token(); | |
563 if (t == '{') { | |
564 obj->obj_decorations = rdschem_parse_decor_block(); | |
565 t = rdschem_token(); | |
566 } | |
567 if (t != ';') | |
568 goto syntaxerr; | |
569 | |
570 if (obj->netobj_points) | |
571 parser_add_object(obj); | |
572 else { | |
573 fprintf(stderr, "%s: line %d: null GraphNet object ignored\n", | |
574 schem_parse_state.schem->orig_filename, | |
575 schem_parse_state.lineno); | |
576 free(obj); | |
577 } | |
578 return(0); | |
579 } | |
580 | |
581 rdschem_parse_netline() | |
582 { | |
583 register int t; | |
584 register struct schemobj *obj; | |
585 struct xypair coord_pair; | |
586 | |
587 obj = parser_alloc_obj(OBJTYPE_NETLINE); | |
588 | |
589 t = rdschem_token(); | |
590 if (t != '(') | |
591 syntaxerr: rdschem_error("(NetLine object) syntax error"); | |
592 coord_pair = parse_coord_pair(); | |
593 obj->lineobj_x1 = coord_pair.x; | |
594 obj->lineobj_y1 = coord_pair.y; | |
595 t = rdschem_token(); | |
596 if (t != '(') | |
597 goto syntaxerr; | |
598 coord_pair = parse_coord_pair(); | |
599 obj->lineobj_x2 = coord_pair.x; | |
600 obj->lineobj_y2 = coord_pair.y; | |
601 | |
602 t = rdschem_token(); | |
603 if (t == '{') { | |
604 obj->obj_decorations = rdschem_parse_decor_block(); | |
605 t = rdschem_token(); | |
606 } | |
607 if (t != ';') | |
608 goto syntaxerr; | |
609 parser_add_object(obj); | |
610 return(0); | |
611 } | |
612 | |
613 rdschem_parse_busseg() | |
614 { | |
615 register int t; | |
616 register struct schemobj *obj; | |
617 struct xypair coord_pair; | |
618 | |
619 obj = parser_alloc_obj(OBJTYPE_BUSSEG); | |
620 | |
621 t = rdschem_token(); | |
622 if (t != '(') | |
623 syntaxerr: rdschem_error("(BusSeg object) syntax error"); | |
624 coord_pair = parse_coord_pair(); | |
625 obj->lineobj_x1 = coord_pair.x; | |
626 obj->lineobj_y1 = coord_pair.y; | |
627 t = rdschem_token(); | |
628 if (t != '(') | |
629 goto syntaxerr; | |
630 coord_pair = parse_coord_pair(); | |
631 obj->lineobj_x2 = coord_pair.x; | |
632 obj->lineobj_y2 = coord_pair.y; | |
633 | |
634 t = rdschem_token(); | |
635 if (t == '{') { | |
636 obj->obj_decorations = rdschem_parse_decor_block(); | |
637 t = rdschem_token(); | |
638 } | |
639 if (t != ';') | |
640 goto syntaxerr; | |
641 parser_add_object(obj); | |
642 return(0); | |
643 } | |
644 | |
645 rdschem_parse_graphblock_obj(type) | |
646 { | |
647 register int t; | |
648 register struct schemobj *obj; | |
649 register struct graphblock *blk; | |
650 | |
651 t = rdschem_token(); | |
652 if (t != '{') | |
653 rdschem_error("GraphBlockG/GraphBlockPS must be followed by '{'"); | |
654 blk = rdschem_graphblock(type); | |
655 obj = parser_alloc_obj(OBJTYPE_GRAPHBLOCK); | |
656 obj->graphblockobj_body = blk; | |
657 parser_add_object(obj); | |
658 schem_parse_state.schem->has_graphblocks = 1; | |
659 return(0); | |
660 } | |
661 | |
662 rdschem_parse_comment_obj() | |
663 { | |
664 register int t; | |
665 register struct schemobj *obj; | |
666 | |
667 t = rdschem_token(); | |
668 if (t != STRING && t != QSTRING) | |
669 syntaxerr: rdschem_error("(Comment object) syntax error"); | |
670 if (!schem_parse_state.string[0]) | |
671 rdschem_error("schematic comment may not be a null string"); | |
672 obj = parser_alloc_obj(OBJTYPE_COMMENT); | |
673 obj->commentobj_text = copystr(schem_parse_state.string); | |
674 t = rdschem_token(); | |
675 if (t != ';') | |
676 goto syntaxerr; | |
677 parser_add_object(obj); | |
678 return(0); | |
679 } | |
680 | |
681 static int | |
682 parse_number() | |
683 { | |
684 register int t; | |
685 char errbuf[256]; | |
686 | |
687 t = rdschem_token(); | |
688 if (t != STRING) | |
689 rdschem_error("syntax error (number expected)"); | |
690 if (!string_is_valid_decnum(schem_parse_state.string)) { | |
691 sprintf(errbuf, "\"%s\" is not a valid decimal number", | |
692 schem_parse_state.string); | |
693 rdschem_error(errbuf); | |
694 } | |
695 return(atoi(schem_parse_state.string)); | |
696 } |