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 }