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 } |
