1 /*-----------------------------------------------------------------------*/
2 /* formats.c --- input file support for xcircuit */
3 /* Copyright (c) 2001 Tim Edwards, Johns Hopkins University */
4 /*-----------------------------------------------------------------------*/
11 #include <X11/Intrinsic.h>
12 #include <X11/StringDefs.h>
15 /*------------------------------------------------------------------------*/
17 /*------------------------------------------------------------------------*/
23 #include "colordefs.h"
26 /*----------------------------------------------------------------------*/
27 /* Function prototype declarations */
28 /*----------------------------------------------------------------------*/
29 #include "prototypes.h"
31 /*------------------------------------------------------------------------*/
32 /* Useful (local) defines */
33 /*------------------------------------------------------------------------*/
35 #define xmat(a) (((a) - 3300) << 4)
36 #define ymat(a) ((3300 - (a)) << 4)
37 #define S_OBLIQUE 13 /* position of Symbol-Oblique in font array */
39 /*------------------------------------------------------------------------*/
40 /* External Variable definitions */
41 /*------------------------------------------------------------------------*/
43 extern char _STR
[150];
44 extern Globaldata xobjs
;
45 extern XCWindowData
*areawin
;
48 /*----------------------------------------------*/
51 /*----------------------------------------------*/
52 /* loadlgf: Load an analog LGF file */
53 /* mode = 1: import into current page; */
54 /* mode = 0 clear current page and load */
55 /*----------------------------------------------*/
57 void loadlgf(int mode
)
60 char inname
[150], temp
[500], *pdchar
;
67 sscanf(_STR
, "%149s", inname
);
69 ps
= fopen(inname
, "r");
71 sprintf(inname
, "%s.lgf", _STR
);
72 ps
= fopen(inname
, "r");
74 sprintf(inname
, "%s.lfo", _STR
);
75 ps
= fopen(inname
, "r");
77 Wprintf("Can't open LGF file %s", inname
);
83 /* for PostScript file, remove ".lgf" or ".lfo" (to be replaced with ".ps") */
85 if ((pdchar
= strstr(inname
, ".l")) != NULL
) *pdchar
= '\0';
87 Wprintf("Loaded file: %s", inname
);
89 /* Make sure that LGF object library has been loaded by loading it now. */
91 if (NameToLibrary(LGF_LIB
) < 0) {
93 strcpy(_STR
, LGF_LIB
);
94 ilib
= createlibrary(FALSE
);
98 /* Read header information */
100 if (fgets(temp
, 149, ps
) == NULL
) {
101 Wprintf("Error: end of file.");
104 for (pdchar
= temp
; *pdchar
!= '-' && *pdchar
!= '\n'; pdchar
++);
105 if (*pdchar
== '\n') {
106 Wprintf("Not an LGF file?");
109 if (*(++pdchar
) != '5') {
110 Wprintf("Don't know how to read version %c.", *pdchar
);
113 if (fgets(temp
, 149, ps
) == NULL
) {
114 Wprintf("Error: end of file.");
117 for (pdchar
= temp
; *pdchar
!= 'f' && *pdchar
!= '\n'; pdchar
++);
118 for (; *pdchar
!= 's' && *pdchar
!= '\n'; pdchar
++);
119 if (*pdchar
== '\n') {
120 Wprintf("Something wrong with the LGF file?");
124 /* Done with header. . . okay to clear current page now unless importing */
127 reset(topobject
, NORMAL
);
128 pagereset(areawin
->page
);
131 /* Set up filename and object (page) name */
133 xobjs
.pagelist
[areawin
->page
]->filename
= (char *) realloc (
134 xobjs
.pagelist
[areawin
->page
]->filename
, (strlen(inname
) + 1) * sizeof(char));
135 strcpy(xobjs
.pagelist
[areawin
->page
]->filename
, inname
);
137 /* If the filename has a path component, use only the root */
139 if ((pdchar
= strrchr(inname
, '/')) != NULL
)
140 sprintf(topobject
->name
, "%s", pdchar
+ 1);
142 sprintf(topobject
->name
, "%s", inname
);
144 renamepage(areawin
->page
);
145 printname(topobject
);
150 char *lineptr
, keyptr
, tmpstring
[256];
152 short pvalx
, pvaly
, pvalx2
, pvaly2
;
154 if (fgets(temp
, 499, ps
) == NULL
) break; /* End-Of-File */
156 /* ignore whitespace */
157 for (lineptr
= temp
; isspace(*lineptr
) && *lineptr
!= '\n'; lineptr
++);
158 if (*lineptr
== '\n') continue; /* ignore blank lines */
159 switch(keyptr
= *lineptr
) {
161 case '#': /* comment */
164 case 'n': /* nodes */
165 sscanf(++lineptr
, "%d", &dval
);
166 for (i
= 0; i
< dval
; i
++) {
168 if (fgets(temp
, 499, ps
) == NULL
) {
169 Wprintf("End of file in node section");
172 for (lineptr
= temp
; isspace(*lineptr
) && *lineptr
!= '\n'; lineptr
++);
173 } while (*lineptr
== '\n');
177 case 's': /* signal names --- save for future reference */
179 sscanf(++lineptr
, "%d", &sigs
);
180 signals
= (char **) malloc(sigs
* sizeof(char *));
181 signets
= (short *) malloc(sigs
* sizeof(short));
182 for (i
= 0; i
< sigs
; i
++) {
184 if (fgets(temp
, 499, ps
) == NULL
) {
185 Wprintf("End of file in signal section");
188 for (lineptr
= temp
; isspace(*lineptr
) && *lineptr
!= '\n'; lineptr
++);
189 } while (*lineptr
== '\n');
191 sscanf(lineptr
, "%hd %249s", &signets
[i
], tmpstring
);
193 signals
[i
] = (char *)malloc((strlen(tmpstring
) + 1) * sizeof(char));
194 sprintf(signals
[i
], "%s", tmpstring
);
198 case 'l': { /* labels */
203 sscanf(++lineptr
, "%d", &dval
);
204 for (i
= 0; i
< dval
; i
++) {
206 if (fgets(temp
, 499, ps
) == NULL
) {
207 Wprintf("End of file in signal section");
210 for (lineptr
= temp
; isspace(*lineptr
) && *lineptr
!= '\n'; lineptr
++);
211 } while (*lineptr
== '\n');
213 /* Allocate label, and put node number into X value, to be replaced */
214 /* Flag it using an inappropriate rotation value (= 500) */
216 sscanf(lineptr
, "%hd %hd", &pvalx
, &pvaly
);
218 /* Get rid of newline character, if any */
222 /* forward to the label part of the input line */
225 while (isdigit(*(++tstrp
)));
226 while (isspace(*(++tstrp
)));
227 while (isdigit(*(++tstrp
)));
228 while (isspace(*(++tstrp
)));
229 while (isdigit(*(++tstrp
)));
230 while (isspace(*(++tstrp
)));
232 if (tstrp
!= NULL
) { /* could be a blank line */
235 NEW_LABEL(newlabel
, topobject
);
237 labeldefaults(*newlabel
, False
, xmat(pvalx
), ymat(pvaly
));
238 (*newlabel
)->anchor
= TOP
| NOTBOTTOM
;
239 (*newlabel
)->color
= DEFAULTCOLOR
;
240 (*newlabel
)->string
->data
.font
= 0;
241 strptr
= makesegment(&((*newlabel
)->string
), NULL
);
242 strptr
->type
= TEXT_STRING
;
243 strptr
->data
.string
= (char *)malloc(1 + strlen(tstrp
));
244 strcpy(strptr
->data
.string
, tstrp
);
245 (*newlabel
)->pin
= NORMAL
;
250 case 'w': { /* wires, implemented as single-segment polygons */
254 sscanf(++lineptr
, "%d", &dval
);
255 for (i
= 0; i
< dval
; i
++) {
257 if (fgets(temp
, 499, ps
) == NULL
) {
258 Wprintf("End of file in wire section");
261 for (lineptr
= temp
; isspace(*lineptr
) && *lineptr
!= '\n'; lineptr
++);
262 } while (*lineptr
== '\n');
266 NEW_POLY(newwire
, topobject
);
268 sscanf(lineptr
, "%hd %hd %hd %hd", &pvalx
, &pvaly
, &pvalx2
, &pvaly2
);
269 (*newwire
)->number
= 2;
270 (*newwire
)->points
= (XPoint
*)malloc(2 * sizeof(XPoint
));
271 (*newwire
)->width
= 1.0;
272 (*newwire
)->style
= UNCLOSED
;
273 (*newwire
)->color
= DEFAULTCOLOR
;
274 (*newwire
)->passed
= NULL
;
275 tmppnts
= (*newwire
)->points
;
276 tmppnts
->x
= xmat(pvalx
);
277 tmppnts
->y
= ymat(pvaly
);
278 (++tmppnts
)->x
= xmat(pvalx2
);
279 tmppnts
->y
= ymat(pvaly2
);
284 case 'p': /* solder dot */
285 sscanf(++lineptr
, "%d", &dval
);
286 for (i
= 0; i
< dval
; i
++) {
288 if (fgets(temp
, 499, ps
) == NULL
) {
289 Wprintf("End of file in solder dot section");
292 for (lineptr
= temp
; isspace(*lineptr
) && *lineptr
!= '\n'; lineptr
++);
293 } while (*lineptr
== '\n');
297 sscanf(lineptr
, "%hd %hd", &pvalx
, &pvaly
);
298 drawdot(xmat(pvalx
), ymat(pvaly
));
302 case 'b': { /* boxes */
306 sscanf(++lineptr
, "%d", &dval
);
307 for (i
= 0; i
< dval
; i
++) {
309 if (fgets(temp
, 499, ps
) == NULL
) {
310 Wprintf("End of file in box section");
313 for (lineptr
= temp
; isspace(*lineptr
) && *lineptr
!= '\n'; lineptr
++);
314 } while (*lineptr
== '\n');
316 NEW_POLY(newpoly
, topobject
);
318 (*newpoly
)->style
= DASHED
;
319 (*newpoly
)->color
= DEFAULTCOLOR
;
320 (*newpoly
)->width
= 1.0;
321 (*newpoly
)->number
= 4;
322 (*newpoly
)->points
= (pointlist
) malloc(4 * sizeof(XPoint
));
323 (*newpoly
)->passed
= NULL
;
325 newpoints
= (*newpoly
)->points
;
326 sscanf(lineptr
, "%hd %hd %hd %hd", &pvalx
, &pvaly
, &pvalx2
, &pvaly2
);
327 newpoints
->x
= xmat(pvalx
);
328 newpoints
->y
= ymat(pvaly
);
329 (newpoints
+ 1)->x
= xmat(pvalx2
);
330 (newpoints
+ 2)->y
= ymat(pvaly2
);
332 (newpoints
+ 2)->x
= (newpoints
+ 1)->x
;
333 (newpoints
+ 3)->x
= newpoints
->x
;
334 (newpoints
+ 1)->y
= newpoints
->y
;
335 (newpoints
+ 3)->y
= (newpoints
+ 2)->y
;
339 case 'g': { /* gates */
343 int j
, k
, hval
, flip
;
345 sscanf(++lineptr
, "%d", &dval
);
346 for (i
= 0; i
< dval
; i
++) {
348 if (fgets(temp
, 499, ps
) == NULL
) {
349 Wprintf("End of file in gates section");
352 for (lineptr
= temp
; *lineptr
!= '\n'; lineptr
++); *lineptr
= '\0';
353 for (lineptr
= temp
; isspace(*lineptr
) && *lineptr
!= '\0'; lineptr
++);
354 } while (*lineptr
== '\0');
356 /* double loop through user libraries */
358 for (j
= 0; j
< xobjs
.numlibs
; j
++) {
359 for (k
= 0; k
< xobjs
.userlibs
[j
].number
; k
++) {
360 libobj
= xobjs
.userlibs
[j
].library
+ k
;
361 if (!strcmp(lineptr
, (*libobj
)->name
)) break;
363 if (k
< xobjs
.userlibs
[j
].number
) break;
365 strcpy(tmpstring
, lineptr
);
367 /* read gate definition */
369 if (fgets(temp
, 499, ps
) == NULL
) {
370 Wprintf("End of file during gate read");
373 for (lineptr
= temp
; isspace(*lineptr
) && *lineptr
!= '\n'; lineptr
++);
375 if (j
< xobjs
.numlibs
|| k
< xobjs
.userlibs
[xobjs
.numlibs
- 1].number
) {
377 NEW_OBJINST(newinst
, topobject
);
379 sscanf(lineptr
, "%hd %hd %hd %*d %*d %*d %d", &pvalx
, &pvaly
,
382 flip
= (pvalx2
>= 4) ? 1 : 0;
383 if (!strcmp(tmpstring
, "FROM")) flip
= 1 - flip
;
385 (*newinst
)->position
.x
= xmat(pvalx
);
386 (*newinst
)->position
.y
= ymat(pvaly
);
387 (*newinst
)->scale
= 1.0;
388 (*newinst
)->color
= DEFAULTCOLOR
;
389 (*newinst
)->params
= NULL
;
390 (*newinst
)->passed
= NULL
;
392 if (pvalx2
& 0x01) pvalx2
^= 0x02;
394 (*newinst
)->rotation
= (float)(-((pvalx2
- 4) * 90) + 1);
396 (*newinst
)->rotation
= (float)((pvalx2
* 90) + 1);
397 (*newinst
)->thisobject
= *libobj
;
398 (*newinst
)->bbox
.lowerleft
.x
= (*libobj
)->bbox
.lowerleft
.x
;
399 (*newinst
)->bbox
.lowerleft
.y
= (*libobj
)->bbox
.lowerleft
.y
;
400 (*newinst
)->bbox
.width
= (*libobj
)->bbox
.width
;
401 (*newinst
)->bbox
.height
= (*libobj
)->bbox
.height
;
403 /* Add label to "TO" and "FROM" */
405 if (!strcmp(tmpstring
, "FROM") || !strcmp(tmpstring
, "TO")) {
409 fgets(temp
, 499, ps
);
410 sscanf(temp
, "%d", &nval
);
412 for (k
= 0; k
< sigs
; k
++)
413 if (signets
[k
] == nval
) {
416 NEW_LABEL(newlabel
, topobject
);
417 /* reconnect newinst if displaced by realloc() */
418 newinst
= (objinstptr
*)(topobject
->plist
419 + topobject
->parts
- 2);
421 labeldefaults(*newlabel
, False
, (*newinst
)->position
.x
,
422 (*newinst
)->position
.y
);
423 (*newlabel
)->color
= DEFAULTCOLOR
;
424 (*newlabel
)->pin
= LOCAL
;
425 (*newlabel
)->color
= LOCALPINCOLOR
;
426 if (!strcmp(tmpstring
, "TO"))
427 (*newlabel
)->position
.x
+= ((flip
) ? 48 : -48);
429 (*newlabel
)->position
.x
+= ((flip
) ? 54 : -54);
431 (*newlabel
)->anchor
= NOTBOTTOM
;
432 if (flip
) (*newlabel
)->anchor
|= (RIGHT
| NOTLEFT
);
433 (*newlabel
)->string
->data
.font
= 0;
434 strptr
= makesegment(&((*newlabel
)->string
), NULL
);
435 strptr
->type
= TEXT_STRING
;
436 strptr
->data
.string
= (char *)malloc(1 + strlen(signals
[k
]));
437 strcpy(strptr
->data
.string
, signals
[k
]);
443 /* read through list of attributes */
446 sscanf(lineptr
, "%*d %*d %*d %*d %*d %*d %d", &hval
);
447 Wprintf("No library object %s", tmpstring
);
450 for (j
= 0; j
< hval
+ 1; j
++) {
451 if (fgets(temp
, 499, ps
) == NULL
) {
452 Wprintf("Unexpected end of file");
456 /* read to next blank line */
458 if (fgets(temp
, 499, ps
) == NULL
) break;
459 for (lineptr
= temp
; isspace(*lineptr
) && *lineptr
!= '\n'; lineptr
++);
460 } while (*lineptr
!= '\n');
464 case 'h': { /* history */
467 sscanf(++lineptr
, "%d", &dval
);
468 for (i
= 0; i
< dval
; i
++) {
470 if (fgets(temp
, 499, ps
) == NULL
) {
471 Wprintf("End of file in history section");
474 for (lineptr
= temp
; isspace(*lineptr
) && *lineptr
!= '\n'; lineptr
++);
475 } while (*lineptr
== '\n');
477 /* read through history */
479 sscanf(lineptr
, "%*d %d", &hval
);
480 for (j
= 0; j
< hval
; j
++)
481 if (fgets(temp
, 499, ps
) == NULL
) {
482 Wprintf("Unexpected end of file");
488 case '.': /* blank, don't use for EOF */
492 Wprintf("Don't understand statement '%c'", *lineptr
);
497 /* check for unattached labels and delete them */
499 for (iolabel
= topobject
->plist
; iolabel
< topobject
->plist
+
500 topobject
->parts
; iolabel
++)
501 if (IS_LABEL(*iolabel
)) {
502 if (TOLABEL(iolabel
)->rotation
== 500.0) {
503 genericptr
*tmplabel
;
505 free(TOLABEL(iolabel
)->string
);
507 for (tmplabel
= iolabel
+ 1; tmplabel
< topobject
->plist
+
508 topobject
->parts
; tmplabel
++) *(tmplabel
- 1) = *tmplabel
;
514 calcbbox(areawin
->topinstance
);
515 centerview(areawin
->topinstance
);
517 for (i
= 0; i
< sigs
; i
++) free(signals
[i
]);
525 /*-------------------------*/
528 /*------------------------*/
529 /* Load a Matlab .ps file */
530 /*------------------------*/
531 /*------------------------------------------------------------------*/
532 /* This is unfinished. . . needs a lot of thought and a lot of work */
533 /*------------------------------------------------------------------*/
535 void loadmat4(caddr_t nullval
)
537 char inname
[150], *temp
, *buffer
, keyword
[30], percentc
, *pdchar
;
539 short curcolor
= DEFAULTCOLOR
;
540 char colorstr
[100][5];
542 float curwidth
= 1.0;
543 int tmpstyle
= UNCLOSED
;
545 sscanf(_STR
, "%149s", inname
);
547 ps
= fopen(inname
, "r");
549 sprintf(inname
, "%s.ps", _STR
);
550 ps
= fopen(inname
, "r");
552 sprintf(inname
, "%s.eps", _STR
);
553 ps
= fopen(inname
, "r");
555 Wprintf("Can't open Matlab PostScript file %s", inname
);
561 /* Keep same filename---overwriting file is end-user's own risk */
563 if ((pdchar
= strstr(_STR
, ".ps")) != NULL
) *pdchar
= '\0';
564 sprintf(topobject
->name
, "%s", _STR
);
565 Wprintf("Loaded file: %s", inname
);
566 renamepage(areawin
->page
);
567 printname(topobject
);
569 /* Create input string buffer */
571 buffer
= (char *)malloc(bufsize
* sizeof(char));
574 /* Read header information */
576 if (fgets(temp
, 149, ps
) == NULL
) {
577 Wprintf("Error: end of file.");
580 if (*temp
!= '%' || *(temp
+ 1) != '!') {
581 Wprintf("Not a PostScript file?");
584 if (fgets(temp
, 149, ps
) == NULL
) {
585 Wprintf("Error: end of file.");
588 if (!strstr(temp
, "MATLAB")) {
589 Wprintf("Not a Matlab PostScript file?");
593 /* Read through to Page start */
596 if (fgets(temp
, 149, ps
) == NULL
) {
597 Wprintf("Error: no pages in input.");
600 if (strstr(temp
, "%%Page:") != NULL
) break;
606 char *lineptr
, keyptr
;
608 if (fgets(temp
, 255, ps
) == NULL
) break; /* End-Of-File */
611 /* scan from the end; ignore blank lines. */
613 for (lineptr
= buffer
; (*lineptr
!= '\n') && (*lineptr
!= '\0'); lineptr
++);
615 /* ignore any blank lines and PostScript comment lines */
617 if (lineptr
!= buffer
&& *buffer
!= '%') {
618 for (keyptr
= lineptr
- 1; isspace(*keyptr
) && keyptr
!= buffer
; keyptr
--);
619 for (; !isspace(*keyptr
) && keyptr
!= buffer
; keyptr
--);
620 sscanf(keyptr
, "%29s", keyword
);
622 if (!strcmp(keyword
, "showpage")) {
624 return False
; /* end of page */
627 else if (!strcmp(keyword
, "bdef")) { /* new color definition */
629 float red
, green
, blue
;
630 if ((bb
= strchr(buffer
, '{')) != NULL
) {
631 sscanf(bb
+ 1, "%f %f %f", &red
, &green
, &blue
);
632 curcolor
= rgb_alloccolor((int)(red
* 65535), (int)(green
* 65535),
633 (int)(blue
* 65535));
635 if ((bb
= strchr(buffer
, '/')) != NULL
) {
636 sscanf(bb
, "%4s", &colorstr
[matcolors
]);
641 else if (!strcmp(keyword
, "w")) { /* linewidth */
643 sscanf(buffer
, "%f", &tmpwidth
)
645 else if (!strcmp(keyword
, "DO")) { /* style */
646 tmpstyle
= DOTTED
| UNCLOSED
;
648 else if (!strcmp(keyword
, "SO")) { /* style */
651 else if (!strcmp(keyword
, "DA")) { /* style */
652 tmpstyle
= DASHED
| UNCLOSED
;
654 else if (!strcmp(keyword
, "FMSR")) ; /* ignore font spec for now */
655 else if (!strcmp(keyword
, "j")) ; /* ignore line join */
656 else if (!strcmp(keyword
, "def")) ; /* ignore */
657 else if (!strcmp(keyword
, "dictionary")) ; /* ignore */
658 else if (!strcmp(keyword
, "np")) ; /* ignore clip paths */
659 else { /* continuation line ? */
660 for (lineptr
= buffer
; (*lineptr
!= '\n') && (*lineptr
!= '\0');
662 if (*lineptr
== '\n') *lineptr
= ' ';
664 bufsize
= (int)(lineptr
- buffer
) + 256;
665 buffer
= (char *)realloc(buffer
, bufsize
* sizeof(char));
666 temp
= buffer
+ (bufsize
- 256);
676 /*---------------------------------------------------------------------------*/