FreeCalypso > hg > ueda-linux
view 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 |
line wrap: on
line source
/* * We print gschem code in two places: symbols and graphblocks. */ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <strings.h> #include "../libuschem/graphsym.h" #include "../libuschem/schemstruct.h" static char leftstr[] = "/left"; static char rightstr[] = "/right"; static char topstr[] = "/top"; static char bottomstr[] = "/bottom"; static char ctrstr[] = "/ctr"; char *gschem_text_halign[9] = {leftstr, leftstr, leftstr, ctrstr, ctrstr, ctrstr, rightstr, rightstr, rightstr}; char *gschem_text_valign[9] = {bottomstr,ctrstr, topstr, bottomstr,ctrstr, topstr, bottomstr,ctrstr, topstr}; #define MAXLINE 256 static FILE *inf; static char *pathname; static int lineno; static int issym, in_pinblock; static int linewidth, dashed; static int font_ptsize; static int varpin_count; print_gschem_code_sym(file, sym) FILE *file; struct graphsym *sym; { inf = file; pathname = sym->gs_pathname; lineno = 0; issym = 1; mymain(); } print_gschem_code_graphblk(file, blk, orig_filename) FILE *file; struct graphblock *blk; char *orig_filename; { inf = file; pathname = orig_filename; lineno = blk->lineno; issym = 0; fseek(inf, blk->offset, 0); mymain(); } static mymain() { char line[MAXLINE]; register char *cp; register int c; in_pinblock = 0; linewidth = -1; dashed = 0; font_ptsize = 0; varpin_count = 0; while (getline(line)) { switch (line[0]) { case '%': /* PS-like comments */ case '\0': /* allow blank lines too */ continue; case '{': in_pinblock++; continue; case '}': if (!in_pinblock) return; in_pinblock--; continue; } if (!isalpha(line[0])) { inv: fprintf(stderr, "%s: line %d: invalid gschem code\n", pathname, lineno); exit(1); } for (cp = line; isalpha(*cp); cp++) ; if (!isspace(*cp)) goto inv; *cp++ = '\0'; while (isspace(*cp)) cp++; if (!strcmp(line, "PS")) { if (strcmp(cp, "{")) goto inv; do_ps_block(); /* be safe about the graphics state */ linewidth = -1; font_ptsize = 0; continue; } else if (strlen(line) != 1) continue; /* ignore these */ line[1] = ' '; /* dispatch by single-char type */ switch (line[0]) { case 'v': continue; /* ignore */ /* simple graphics */ case 'L': do_line(line); continue; case 'B': do_box(line); continue; case 'V': do_circle(line); continue; case 'A': do_arc(line); continue; case 'P': handle_pin(line); continue; case 'T': handle_T_obj(line, lineno); continue; default: goto inv; } } } static do_line(objline) char *objline; { int numparams[10]; parse_numline(objline, lineno, numparams, 10); if (setdash(numparams[7], numparams[8], numparams[9]) < 0) return; setlinewidth(numparams[5]); emit_coordpair(numparams[0], numparams[1]); fputs("moveto ", stdout); emit_coordpair(numparams[2], numparams[3]); puts("lineto stroke"); } static do_box(objline) char *objline; { int numparams[16]; parse_numline(objline, lineno, numparams, 16); switch (numparams[10]) { case 0: if (setdash(numparams[7], numparams[8], numparams[9]) < 0) return; setlinewidth(numparams[5]); emit_coordpair(numparams[0], numparams[1]); emit_coordpair(numparams[2], numparams[3]); puts("rectstroke"); return; case 1: emit_coordpair(numparams[0], numparams[1]); emit_coordpair(numparams[2], numparams[3]); puts("rectfill"); return; default: fprintf(stderr, "%s: line %d: fill type %d not implemented; object omitted\n", pathname, lineno, numparams[10]); } } static do_circle(objline) char *objline; { int numparams[15]; parse_numline(objline, lineno, numparams, 15); switch (numparams[9]) { case 0: if (setdash(numparams[6], numparams[7], numparams[8]) < 0) return; setlinewidth(numparams[4]); emit_coordpair(numparams[0], numparams[1]); printf("%d circlestroke\n", numparams[2]); return; case 1: emit_coordpair(numparams[0], numparams[1]); printf("%d circlefill\n", numparams[2]); return; default: fprintf(stderr, "%s: line %d: fill type %d not implemented; object omitted\n", pathname, lineno, numparams[9]); } } static do_arc(objline) char *objline; { int numparams[11]; parse_numline(objline, lineno, numparams, 11); if (!numparams[4]) /* degenerate? */ return; /* ignore those */ if (setdash(numparams[8], numparams[9], numparams[10]) < 0) return; setlinewidth(numparams[6]); puts("newpath"); emit_coordpair(numparams[0], numparams[1]); printf("%d %d %d%s%s arc stroke\n", numparams[2], numparams[3], numparams[3] + numparams[4], numparams[4] > 0 ? "" : " exch", issym ? " mirrorarc" : ""); } static setlinewidth(newval) { if (newval != linewidth) { linewidth = newval; if (linewidth) printf("%d setlinewidth\n", linewidth); else puts("defaultlinewidth setlinewidth"); } return(0); } static setdash(dashstyle, dashlength, dashspace) { switch (dashstyle) { case 0: if (dashed) { puts("setsolid"); dashed = 0; } return(0); case 2: printf("[%d %d] 0 setdash\n", dashlength, dashspace); dashed = 1; return(0); default: fprintf(stderr, "%s: line %d: dash style %d not implemented; object omitted\n", pathname, lineno, dashstyle); return(-1); } } static emit_coordpair(x, y) { printf("%d%s %d ", x, issym ? " mirror" : "", y); } static handle_pin(objline) char *objline; { int numparams[7]; parse_numline(objline, lineno, numparams, 7); printf("%d mirror %d %d mirror %d drawpin\n", numparams[0], numparams[1], numparams[2], numparams[3]); } static handle_T_obj(objline, objlineno) char *objline; { int numparams[9]; char textline[MAXLINE]; register int i; register char *cp; int readystr, isvarpin; parse_numline(objline, objlineno, numparams, 9); if (numparams[8] < 1) { fprintf(stderr, "%s: line %d: T object: num_lines<1!\n", pathname, objlineno); exit(1); } if (numparams[8] > 1) fprintf(stderr, "warning: multiline T objects not implemented (found in %s)\n", pathname); for (i = numparams[8]; i; i--) { if (!getline(textline)) { fprintf(stderr, "%s: EOF in T object\n", pathname); exit(1); } if (!numparams[4]) /* visible? */ continue; /* nope */ isvarpin = 0; if (issym) { readystr = 0; cp = index(textline, '='); if (cp) { cp++; if (!in_pinblock) /* we don't print */ continue; /* top level attrs */ if (!strcmp(cp, "%d")) isvarpin = 1; } else cp = textline; } else { cp = textline; readystr = (cp[0] == '('); } if (numparams[7] < 0 || numparams[7] > 8) { fprintf(stderr, "%s: line %d: T object: alignment %d is invalid\n", pathname, objlineno, numparams[7]); continue; } if (font_ptsize != numparams[3]) { font_ptsize = numparams[3]; printf("/Helvetica %d selisofnt\n", font_ptsize); } if (isvarpin) printf("pins %d get", varpin_count++); else if (readystr) fputs(cp, stdout); else emit_ps_string(cp); printf(" %s%s %s %d ", gschem_text_halign[numparams[7]], issym ? " mirrortext" : "", gschem_text_valign[numparams[7]], numparams[6]); emit_coordpair(numparams[0], numparams[1]); puts("Tshow"); } } static parse_numline(line, lineno, numarray, nfields) char *line; int lineno; int *numarray; int nfields; { register char *cp, *np; register int i; for (i = 0, cp = line+1; i < nfields; i++) { if (!isspace(*cp)) { inv: fprintf(stderr, "%s: line %d: invalid numeric line\n", pathname, lineno); exit(1); } while (isspace(*cp)) cp++; np = cp; if (*cp == '-') cp++; if (!isdigit(*cp)) goto inv; while (isdigit(*cp)) cp++; numarray[i] = atoi(np); } if (*cp) goto inv; } static getline(linebuf) char *linebuf; { register char *cp; if (fgets(linebuf, MAXLINE, inf) == NULL) return(0); lineno++; /* strip trailing newline or other whitespace */ cp = index(linebuf, '\0'); while (cp > linebuf && isspace(cp[-1])) cp--; *cp = '\0'; return(1); } static do_ps_block() { register int c, n; for (n = 0; ; ) { c = getc(inf); switch (c) { case EOF: badeof: fprintf(stderr, "%s: EOF in a PS block\n", pathname); exit(1); case '%': for (;;) { c = getc(inf); if (c == EOF) goto badeof; if (c == '\n') break; } /* FALL THRU */ case '\n': putchar(c); lineno++; continue; case '(': putchar(c); skip_over_ps_string(); continue; case ')': fprintf(stderr, "%s: line %d: unmatched \')\' in a PS block", pathname, lineno); exit(1); case '{': putchar(c); n++; continue; case '}': if (!n) goto out; putchar(c); n--; continue; default: putchar(c); continue; } } out: c = getc(inf); if (c != '\n') { fprintf(stderr, "%s: line %d: '}' closing PS block must be directly followed by newline\n", pathname, lineno); exit(1); } lineno++; putchar(c); } static skip_over_ps_string() { register int c, n; for (n = 1; n > 0; ) { c = getc(inf); if (c == EOF) { badeof: fprintf(stderr, "%s: EOF in a PS block\n", pathname); exit(1); } putchar(c); switch (c) { case '\n': lineno++; continue; case '(': n++; continue; case ')': n--; continue; case '\\': c = getc(inf); if (c == EOF) goto badeof; putchar(c); if (c == '\n') lineno++; continue; } } }