FreeCalypso > hg > ueda-linux
diff 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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ueda/uschem-print/gschemcode.c Mon Jul 20 00:24:37 2015 +0000 @@ -0,0 +1,484 @@ +/* + * 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; + } + } +}