FreeCalypso > hg > ueda-linux
comparison ueda/uschem-print/gschemcode.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 * We print gschem code in two places: symbols and graphblocks. | |
3 */ | |
4 | |
5 #include <sys/types.h> | |
6 #include <ctype.h> | |
7 #include <stdio.h> | |
8 #include <strings.h> | |
9 #include "../libuschem/graphsym.h" | |
10 #include "../libuschem/schemstruct.h" | |
11 | |
12 static char leftstr[] = "/left"; | |
13 static char rightstr[] = "/right"; | |
14 static char topstr[] = "/top"; | |
15 static char bottomstr[] = "/bottom"; | |
16 static char ctrstr[] = "/ctr"; | |
17 | |
18 char *gschem_text_halign[9] = {leftstr, leftstr, leftstr, | |
19 ctrstr, ctrstr, ctrstr, | |
20 rightstr, rightstr, rightstr}; | |
21 char *gschem_text_valign[9] = {bottomstr,ctrstr, topstr, | |
22 bottomstr,ctrstr, topstr, | |
23 bottomstr,ctrstr, topstr}; | |
24 | |
25 #define MAXLINE 256 | |
26 | |
27 static FILE *inf; | |
28 static char *pathname; | |
29 static int lineno; | |
30 static int issym, in_pinblock; | |
31 static int linewidth, dashed; | |
32 static int font_ptsize; | |
33 static int varpin_count; | |
34 | |
35 print_gschem_code_sym(file, sym) | |
36 FILE *file; | |
37 struct graphsym *sym; | |
38 { | |
39 inf = file; | |
40 pathname = sym->gs_pathname; | |
41 lineno = 0; | |
42 issym = 1; | |
43 mymain(); | |
44 } | |
45 | |
46 print_gschem_code_graphblk(file, blk, orig_filename) | |
47 FILE *file; | |
48 struct graphblock *blk; | |
49 char *orig_filename; | |
50 { | |
51 inf = file; | |
52 pathname = orig_filename; | |
53 lineno = blk->lineno; | |
54 issym = 0; | |
55 fseek(inf, blk->offset, 0); | |
56 mymain(); | |
57 } | |
58 | |
59 static | |
60 mymain() | |
61 { | |
62 char line[MAXLINE]; | |
63 register char *cp; | |
64 register int c; | |
65 | |
66 in_pinblock = 0; | |
67 linewidth = -1; | |
68 dashed = 0; | |
69 font_ptsize = 0; | |
70 varpin_count = 0; | |
71 while (getline(line)) { | |
72 switch (line[0]) { | |
73 case '%': /* PS-like comments */ | |
74 case '\0': /* allow blank lines too */ | |
75 continue; | |
76 case '{': | |
77 in_pinblock++; | |
78 continue; | |
79 case '}': | |
80 if (!in_pinblock) | |
81 return; | |
82 in_pinblock--; | |
83 continue; | |
84 } | |
85 if (!isalpha(line[0])) { | |
86 inv: fprintf(stderr, "%s: line %d: invalid gschem code\n", | |
87 pathname, lineno); | |
88 exit(1); | |
89 } | |
90 for (cp = line; isalpha(*cp); cp++) | |
91 ; | |
92 if (!isspace(*cp)) | |
93 goto inv; | |
94 *cp++ = '\0'; | |
95 while (isspace(*cp)) | |
96 cp++; | |
97 if (!strcmp(line, "PS")) { | |
98 if (strcmp(cp, "{")) | |
99 goto inv; | |
100 do_ps_block(); | |
101 /* be safe about the graphics state */ | |
102 linewidth = -1; | |
103 font_ptsize = 0; | |
104 continue; | |
105 } else if (strlen(line) != 1) | |
106 continue; /* ignore these */ | |
107 line[1] = ' '; | |
108 /* dispatch by single-char type */ | |
109 switch (line[0]) { | |
110 case 'v': | |
111 continue; /* ignore */ | |
112 /* simple graphics */ | |
113 case 'L': | |
114 do_line(line); | |
115 continue; | |
116 case 'B': | |
117 do_box(line); | |
118 continue; | |
119 case 'V': | |
120 do_circle(line); | |
121 continue; | |
122 case 'A': | |
123 do_arc(line); | |
124 continue; | |
125 case 'P': | |
126 handle_pin(line); | |
127 continue; | |
128 case 'T': | |
129 handle_T_obj(line, lineno); | |
130 continue; | |
131 default: | |
132 goto inv; | |
133 } | |
134 } | |
135 } | |
136 | |
137 static | |
138 do_line(objline) | |
139 char *objline; | |
140 { | |
141 int numparams[10]; | |
142 | |
143 parse_numline(objline, lineno, numparams, 10); | |
144 if (setdash(numparams[7], numparams[8], numparams[9]) < 0) | |
145 return; | |
146 setlinewidth(numparams[5]); | |
147 emit_coordpair(numparams[0], numparams[1]); | |
148 fputs("moveto ", stdout); | |
149 emit_coordpair(numparams[2], numparams[3]); | |
150 puts("lineto stroke"); | |
151 } | |
152 | |
153 static | |
154 do_box(objline) | |
155 char *objline; | |
156 { | |
157 int numparams[16]; | |
158 | |
159 parse_numline(objline, lineno, numparams, 16); | |
160 switch (numparams[10]) { | |
161 case 0: | |
162 if (setdash(numparams[7], numparams[8], numparams[9]) < 0) | |
163 return; | |
164 setlinewidth(numparams[5]); | |
165 emit_coordpair(numparams[0], numparams[1]); | |
166 emit_coordpair(numparams[2], numparams[3]); | |
167 puts("rectstroke"); | |
168 return; | |
169 case 1: | |
170 emit_coordpair(numparams[0], numparams[1]); | |
171 emit_coordpair(numparams[2], numparams[3]); | |
172 puts("rectfill"); | |
173 return; | |
174 default: | |
175 fprintf(stderr, | |
176 "%s: line %d: fill type %d not implemented; object omitted\n", | |
177 pathname, lineno, numparams[10]); | |
178 } | |
179 } | |
180 | |
181 static | |
182 do_circle(objline) | |
183 char *objline; | |
184 { | |
185 int numparams[15]; | |
186 | |
187 parse_numline(objline, lineno, numparams, 15); | |
188 switch (numparams[9]) { | |
189 case 0: | |
190 if (setdash(numparams[6], numparams[7], numparams[8]) < 0) | |
191 return; | |
192 setlinewidth(numparams[4]); | |
193 emit_coordpair(numparams[0], numparams[1]); | |
194 printf("%d circlestroke\n", numparams[2]); | |
195 return; | |
196 case 1: | |
197 emit_coordpair(numparams[0], numparams[1]); | |
198 printf("%d circlefill\n", numparams[2]); | |
199 return; | |
200 default: | |
201 fprintf(stderr, | |
202 "%s: line %d: fill type %d not implemented; object omitted\n", | |
203 pathname, lineno, numparams[9]); | |
204 } | |
205 } | |
206 | |
207 static | |
208 do_arc(objline) | |
209 char *objline; | |
210 { | |
211 int numparams[11]; | |
212 | |
213 parse_numline(objline, lineno, numparams, 11); | |
214 if (!numparams[4]) /* degenerate? */ | |
215 return; /* ignore those */ | |
216 if (setdash(numparams[8], numparams[9], numparams[10]) < 0) | |
217 return; | |
218 setlinewidth(numparams[6]); | |
219 puts("newpath"); | |
220 emit_coordpair(numparams[0], numparams[1]); | |
221 printf("%d %d %d%s%s arc stroke\n", numparams[2], numparams[3], | |
222 numparams[3] + numparams[4], numparams[4] > 0 ? "" : " exch", | |
223 issym ? " mirrorarc" : ""); | |
224 } | |
225 | |
226 static | |
227 setlinewidth(newval) | |
228 { | |
229 if (newval != linewidth) { | |
230 linewidth = newval; | |
231 if (linewidth) | |
232 printf("%d setlinewidth\n", linewidth); | |
233 else | |
234 puts("defaultlinewidth setlinewidth"); | |
235 } | |
236 return(0); | |
237 } | |
238 | |
239 static | |
240 setdash(dashstyle, dashlength, dashspace) | |
241 { | |
242 switch (dashstyle) { | |
243 case 0: | |
244 if (dashed) { | |
245 puts("setsolid"); | |
246 dashed = 0; | |
247 } | |
248 return(0); | |
249 case 2: | |
250 printf("[%d %d] 0 setdash\n", dashlength, dashspace); | |
251 dashed = 1; | |
252 return(0); | |
253 default: | |
254 fprintf(stderr, | |
255 "%s: line %d: dash style %d not implemented; object omitted\n", | |
256 pathname, lineno, dashstyle); | |
257 return(-1); | |
258 } | |
259 } | |
260 | |
261 static | |
262 emit_coordpair(x, y) | |
263 { | |
264 printf("%d%s %d ", x, issym ? " mirror" : "", y); | |
265 } | |
266 | |
267 static | |
268 handle_pin(objline) | |
269 char *objline; | |
270 { | |
271 int numparams[7]; | |
272 | |
273 parse_numline(objline, lineno, numparams, 7); | |
274 printf("%d mirror %d %d mirror %d drawpin\n", numparams[0], | |
275 numparams[1], numparams[2], numparams[3]); | |
276 } | |
277 | |
278 static | |
279 handle_T_obj(objline, objlineno) | |
280 char *objline; | |
281 { | |
282 int numparams[9]; | |
283 char textline[MAXLINE]; | |
284 register int i; | |
285 register char *cp; | |
286 int readystr, isvarpin; | |
287 | |
288 parse_numline(objline, objlineno, numparams, 9); | |
289 if (numparams[8] < 1) { | |
290 fprintf(stderr, "%s: line %d: T object: num_lines<1!\n", | |
291 pathname, objlineno); | |
292 exit(1); | |
293 } | |
294 if (numparams[8] > 1) | |
295 fprintf(stderr, | |
296 "warning: multiline T objects not implemented (found in %s)\n", | |
297 pathname); | |
298 for (i = numparams[8]; i; i--) { | |
299 if (!getline(textline)) { | |
300 fprintf(stderr, "%s: EOF in T object\n", pathname); | |
301 exit(1); | |
302 } | |
303 if (!numparams[4]) /* visible? */ | |
304 continue; /* nope */ | |
305 isvarpin = 0; | |
306 if (issym) { | |
307 readystr = 0; | |
308 cp = index(textline, '='); | |
309 if (cp) { | |
310 cp++; | |
311 if (!in_pinblock) /* we don't print */ | |
312 continue; /* top level attrs */ | |
313 if (!strcmp(cp, "%d")) | |
314 isvarpin = 1; | |
315 } else | |
316 cp = textline; | |
317 } else { | |
318 cp = textline; | |
319 readystr = (cp[0] == '('); | |
320 } | |
321 if (numparams[7] < 0 || numparams[7] > 8) { | |
322 fprintf(stderr, | |
323 "%s: line %d: T object: alignment %d is invalid\n", | |
324 pathname, objlineno, numparams[7]); | |
325 continue; | |
326 } | |
327 if (font_ptsize != numparams[3]) { | |
328 font_ptsize = numparams[3]; | |
329 printf("/Helvetica %d selisofnt\n", font_ptsize); | |
330 } | |
331 if (isvarpin) | |
332 printf("pins %d get", varpin_count++); | |
333 else if (readystr) | |
334 fputs(cp, stdout); | |
335 else | |
336 emit_ps_string(cp); | |
337 printf(" %s%s %s %d ", gschem_text_halign[numparams[7]], | |
338 issym ? " mirrortext" : "", | |
339 gschem_text_valign[numparams[7]], numparams[6]); | |
340 emit_coordpair(numparams[0], numparams[1]); | |
341 puts("Tshow"); | |
342 } | |
343 } | |
344 | |
345 static | |
346 parse_numline(line, lineno, numarray, nfields) | |
347 char *line; | |
348 int lineno; | |
349 int *numarray; | |
350 int nfields; | |
351 { | |
352 register char *cp, *np; | |
353 register int i; | |
354 | |
355 for (i = 0, cp = line+1; i < nfields; i++) { | |
356 if (!isspace(*cp)) { | |
357 inv: fprintf(stderr, "%s: line %d: invalid numeric line\n", | |
358 pathname, lineno); | |
359 exit(1); | |
360 } | |
361 while (isspace(*cp)) | |
362 cp++; | |
363 np = cp; | |
364 if (*cp == '-') | |
365 cp++; | |
366 if (!isdigit(*cp)) | |
367 goto inv; | |
368 while (isdigit(*cp)) | |
369 cp++; | |
370 numarray[i] = atoi(np); | |
371 } | |
372 if (*cp) | |
373 goto inv; | |
374 } | |
375 | |
376 static | |
377 getline(linebuf) | |
378 char *linebuf; | |
379 { | |
380 register char *cp; | |
381 | |
382 if (fgets(linebuf, MAXLINE, inf) == NULL) | |
383 return(0); | |
384 lineno++; | |
385 /* strip trailing newline or other whitespace */ | |
386 cp = index(linebuf, '\0'); | |
387 while (cp > linebuf && isspace(cp[-1])) | |
388 cp--; | |
389 *cp = '\0'; | |
390 return(1); | |
391 } | |
392 | |
393 static | |
394 do_ps_block() | |
395 { | |
396 register int c, n; | |
397 | |
398 for (n = 0; ; ) { | |
399 c = getc(inf); | |
400 switch (c) { | |
401 case EOF: | |
402 badeof: fprintf(stderr, "%s: EOF in a PS block\n", pathname); | |
403 exit(1); | |
404 case '%': | |
405 for (;;) { | |
406 c = getc(inf); | |
407 if (c == EOF) | |
408 goto badeof; | |
409 if (c == '\n') | |
410 break; | |
411 } | |
412 /* FALL THRU */ | |
413 case '\n': | |
414 putchar(c); | |
415 lineno++; | |
416 continue; | |
417 case '(': | |
418 putchar(c); | |
419 skip_over_ps_string(); | |
420 continue; | |
421 case ')': | |
422 fprintf(stderr, | |
423 "%s: line %d: unmatched \')\' in a PS block", | |
424 pathname, lineno); | |
425 exit(1); | |
426 case '{': | |
427 putchar(c); | |
428 n++; | |
429 continue; | |
430 case '}': | |
431 if (!n) | |
432 goto out; | |
433 putchar(c); | |
434 n--; | |
435 continue; | |
436 default: | |
437 putchar(c); | |
438 continue; | |
439 } | |
440 } | |
441 out: c = getc(inf); | |
442 if (c != '\n') { | |
443 fprintf(stderr, | |
444 "%s: line %d: '}' closing PS block must be directly followed by newline\n", | |
445 pathname, lineno); | |
446 exit(1); | |
447 } | |
448 lineno++; | |
449 putchar(c); | |
450 } | |
451 | |
452 static | |
453 skip_over_ps_string() | |
454 { | |
455 register int c, n; | |
456 | |
457 for (n = 1; n > 0; ) { | |
458 c = getc(inf); | |
459 if (c == EOF) { | |
460 badeof: fprintf(stderr, "%s: EOF in a PS block\n", pathname); | |
461 exit(1); | |
462 } | |
463 putchar(c); | |
464 switch (c) { | |
465 case '\n': | |
466 lineno++; | |
467 continue; | |
468 case '(': | |
469 n++; | |
470 continue; | |
471 case ')': | |
472 n--; | |
473 continue; | |
474 case '\\': | |
475 c = getc(inf); | |
476 if (c == EOF) | |
477 goto badeof; | |
478 putchar(c); | |
479 if (c == '\n') | |
480 lineno++; | |
481 continue; | |
482 } | |
483 } | |
484 } |