view ueda/migration/g2uschem.c @ 139:bf188727e606

donl-rename-parts reader: no tEDAx-style escapes
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 07 Sep 2020 04:25:11 +0000
parents cd92449fdb51
children
line wrap: on
line source

#include <ctype.h>
#include <stdio.h>
#include <strings.h>

#define	MAXLINE		256
#define	MAXATTRS	16
#define	ATTRBUF_SIZE	4096

struct attr {
	int	graphparams[8];
	char	*name;
	char	*value;
};

FILE *inf, *outf;
char *infname, *outfname;
int lineno;
int x_offset, y_offset;

main(argc, argv)
	char **argv;
{
	char line[MAXLINE];
	int objlineno;
	struct attr attrs[MAXATTRS];
	char attrbuf[ATTRBUF_SIZE];
	int nattrs;
	register int c;

	if (argc > 1) {
		infname = argv[1];
		inf = fopen(infname, "r");
		if (!inf) {
			perror(infname);
			exit(1);
		}
	} else {
		inf = stdin;
		infname = "stdin";
	}
	if (argc > 2) {
		outfname = argv[2];
		outf = fopen(outfname, "w");
		if (!outf) {
			perror(outfname);
			exit(1);
		}
	} else {
		outf = stdout;
		outfname = "stdout";
	}

	while (getline(line)) {
		if (!isalpha(line[0])) {
			fprintf(stderr, "%s: line %d: gschem object expected\n",
				infname, lineno);
			exit(1);
		}
		objlineno = lineno;
		/* check for attached attributes */
		c = getc(inf);
		if (c == '{') {
			skipline();
			nattrs = read_attrs(attrs, attrbuf);
		} else {
			if (c != EOF)
				ungetc(c, inf);
			nattrs = 0;
		}
		/* dispatch by object type */
		switch (line[0]) {
		case 'v':
			continue;	/* ignore */
		/* simple graphics */
		case 'L':
		case 'B':
		case 'V':
		case 'A':
			if (nattrs)
				fprintf(stderr,
		"%s: line %d: attributes attached to %c object (ignored)\n",
					infname, objlineno, line[0]);
			handle_simple_graph(line, objlineno);
			continue;
		case 'T':
			handle_T_obj(line, objlineno);
			continue;
		case 'N':
			handle_net(line, objlineno, attrs, nattrs);
			continue;
		case 'U':
			handle_bus(line, objlineno, attrs, nattrs);
			continue;
		case 'C':
			handle_component(line, objlineno, attrs, nattrs);
			continue;
		default:
			fprintf(stderr,
				"%s: line %d: object type %c not supported\n",
				infname, objlineno, line[0]);
		}
	}
	exit(0);
}

handle_component(objline, objlineno, attrs, nattrs)
	char *objline;
	struct attr *attrs;
{
	int numparams[5];
	char *cp, *symname;
	struct attr *refdes;
	register int i;

	parse_numline(objline, objlineno, numparams, 5, &cp);
	if (!isspace(*cp)) {
inv:		fprintf(stderr, "%s: line %d: invalid C line\n", infname,
			objlineno);
		exit(1);
	}
	while (isspace(*cp))
		cp++;
	if (!isalnum(*cp))
		goto inv;
	for (symname = cp; isalnum(*cp) || *cp == '-' || *cp == '_'; cp++)
		;
	if (strcmp(cp, ".sym"))
		goto inv;
	*cp = '\0';

	/* weed some out based on the symbol name */
	if (!strcmp(symname, "nc-x"))
		return;			/* we'll do that differently */
	if (strlen(symname) == 7 && !strncmp(symname, "title-", 6)) {
		/* handle titleblock */
		fprintf(outf, "Schem graph %c;\n", symname[6]);
		x_offset = numparams[0];
		y_offset = numparams[1];
		return;
	}

	/* do we have a refdes? */
	refdes = NULL;
	for (i = 0; i < nattrs; i++)
		if (!strcmp(attrs[i].name, "refdes")) {
			refdes = attrs + i;
			break;
		}
	if (refdes)
		emit_component_instance(numparams, symname, attrs, nattrs,
					refdes, objlineno);
	else
		emit_graph_symbol(numparams, symname, attrs, nattrs, objlineno);
}

emit_component_instance(numparams, symname, attrs, nattrs, refdes, objlineno)
	int *numparams;
	char *symname;
	struct attr *attrs, *refdes;
{
	register struct attr *ap;
	register int i;

	fprintf(outf, "Component %s graph \"%s\" %d %d", refdes->value, symname,
		numparams[0] - x_offset, numparams[1] - y_offset);
	if (numparams[3])
		fprintf(outf, " rot %d", numparams[3]);
	if (numparams[4])
		fputs(" mirror", outf);
	fputs(" {\n", outf);

	/* attribute data */
	for (ap = attrs, i = 0; i < nattrs; ap++, i++)
		if (ap != refdes)
			fprintf(outf, "\t(%s=\"%s\")\n", ap->name, ap->value);
	/* attribute graphics */
	for (ap = attrs, i = 0; i < nattrs; ap++, i++)
		if (ap->graphparams[4])
			fprintf(outf, "\tDisplayAttr %s %d %d %d %d %d;\n",
				ap->name, ap->graphparams[0] - x_offset,
				ap->graphparams[1] - y_offset,
				ap->graphparams[3],
				ap->graphparams[6], ap->graphparams[7]);
	fputs("};\n", outf);
}

emit_graph_symbol(numparams, symname, attrs, nattrs, objlineno)
	int *numparams;
	char *symname;
	struct attr *attrs;
{
	register struct attr *ap;
	register int i;

	fprintf(outf, "GraphSym \"%s\" %d %d", symname,
		numparams[0] - x_offset, numparams[1] - y_offset);
	if (numparams[3])
		fprintf(outf, " rot %d", numparams[3]);
	if (numparams[4])
		fputs(" mirror", outf);

	if (nattrs)
		fputs(" {\n", outf);
	else {
		fputs(";\n", outf);
		return;
	}

	/* attribute data */
	for (ap = attrs, i = 0; i < nattrs; ap++, i++)
		fprintf(outf, "\t(%s=\"%s\")\n", ap->name, ap->value);
	/* attribute graphics */
	for (ap = attrs, i = 0; i < nattrs; ap++, i++)
		if (ap->graphparams[4])
			fprintf(outf, "\tDisplayAttr %s %d %d %d %d %d;\n",
				ap->name, ap->graphparams[0] - x_offset,
				ap->graphparams[1] - y_offset,
				ap->graphparams[3],
				ap->graphparams[6], ap->graphparams[7]);
	fputs("};\n", outf);
}

handle_net(objline, objlineno, attrs, nattrs)
	char *objline;
	struct attr *attrs;
{
	int numparams[5];
	register struct attr *ap;
	register int i;

	parse_numline(objline, objlineno, numparams, 5, NULL);
	fprintf(outf, "NetLine (%d,%d) (%d,%d)", numparams[0] - x_offset,
		numparams[1] - y_offset, numparams[2] - x_offset,
		numparams[3] - y_offset);
	if (nattrs)
		fputs(" {\n", outf);
	else {
		fputs(";\n", outf);
		return;
	}

	/* attribute data */
	for (ap = attrs, i = 0; i < nattrs; ap++, i++)
		fprintf(outf, "\t(%s=\"%s\")\n", ap->name, ap->value);
	/* attribute graphics */
	for (ap = attrs, i = 0; i < nattrs; ap++, i++)
		if (ap->graphparams[4])
			fprintf(outf, "\tDisplayAttr %s %d %d %d %d %d;\n",
				ap->name, ap->graphparams[0] - x_offset,
				ap->graphparams[1] - y_offset,
				ap->graphparams[3],
				ap->graphparams[6], ap->graphparams[7]);
	fputs("};\n", outf);
}

handle_bus(objline, objlineno, attrs, nattrs)
	char *objline;
	struct attr *attrs;
{
	int numparams[6];
	register struct attr *ap;
	register int i;

	parse_numline(objline, objlineno, numparams, 6, NULL);
	fprintf(outf, "BusSeg (%d,%d) (%d,%d)", numparams[0] - x_offset,
		numparams[1] - y_offset, numparams[2] - x_offset,
		numparams[3] - y_offset);
	if (nattrs)
		fputs(" {\n", outf);
	else {
		fputs(";\n", outf);
		return;
	}

	/* attribute data */
	for (ap = attrs, i = 0; i < nattrs; ap++, i++)
		fprintf(outf, "\t(%s=\"%s\")\n", ap->name, ap->value);
	/* attribute graphics */
	for (ap = attrs, i = 0; i < nattrs; ap++, i++)
		if (ap->graphparams[4])
			fprintf(outf, "\tDisplayAttr %s %d %d %d %d %d;\n",
				ap->name, ap->graphparams[0] - x_offset,
				ap->graphparams[1] - y_offset,
				ap->graphparams[3],
				ap->graphparams[6], ap->graphparams[7]);
	fputs("};\n", outf);
}

handle_simple_graph(objline, objlineno)
	char *objline;
{
	translate_simple_graph_line(objline, objlineno);
	fprintf(outf, "GraphBlockG {\n%s\n}\n", objline);
}

translate_simple_graph_line(objline, objlineno)
	char *objline;
{
	int numparams[16];

	switch (objline[0]) {
	case 'L':
		parse_numline(objline, objlineno, numparams, 10, NULL);
		numparams[0] -= x_offset;
		numparams[1] -= y_offset;
		numparams[2] -= x_offset;
		numparams[3] -= y_offset;
		sprintf(objline, "L %d %d %d %d %d %d %d %d %d %d",
			numparams[0], numparams[1], numparams[2], numparams[3],
			numparams[4], numparams[5], numparams[6], numparams[7],
			numparams[8], numparams[9]);
		return;
	case 'B':
		parse_numline(objline, objlineno, numparams, 16, NULL);
		numparams[0] -= x_offset;
		numparams[1] -= y_offset;
		sprintf(objline,
			"B %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
			numparams[0], numparams[1], numparams[2], numparams[3],
			numparams[4], numparams[5], numparams[6], numparams[7],
			numparams[8], numparams[9], numparams[10],numparams[11],
			numparams[12],numparams[13],numparams[14],
			numparams[15]);
		return;
	case 'V':
		parse_numline(objline, objlineno, numparams, 15, NULL);
		numparams[0] -= x_offset;
		numparams[1] -= y_offset;
		sprintf(objline,
			"V %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
			numparams[0], numparams[1], numparams[2], numparams[3],
			numparams[4], numparams[5], numparams[6], numparams[7],
			numparams[8], numparams[9], numparams[10],numparams[11],
			numparams[12],numparams[13],numparams[14]);
		return;
	case 'A':
		parse_numline(objline, objlineno, numparams, 11, NULL);
		numparams[0] -= x_offset;
		numparams[1] -= y_offset;
		sprintf(objline, "A %d %d %d %d %d %d %d %d %d %d %d",
			numparams[0], numparams[1], numparams[2], numparams[3],
			numparams[4], numparams[5], numparams[6], numparams[7],
			numparams[8], numparams[9], numparams[10]);
		return;
	default:
		fprintf(stderr,
			"unknown type in translate_simple_graph_line()\n");
		exit(1);
	}
}

handle_T_obj(objline, objlineno)
	char *objline;
{
	int numparams[9];
	char textline[MAXLINE];
	register int i;

	parse_numline(objline, objlineno, numparams, 9, NULL);
	if (numparams[8] < 1) {
		fprintf(stderr, "%s: line %d: T object: num_lines<1!\n",
			infname, objlineno);
		exit(1);
	}
	fprintf(outf, "GraphBlockG {\nT %d %d %d %d %d %d %d %d %d\n",
		numparams[0] - x_offset, numparams[1] - y_offset, numparams[2],
		numparams[3], numparams[4], numparams[5], numparams[6],
		numparams[7], numparams[8]);
	for (i = numparams[8]; i; i--) {
		if (!getline(textline)) {
			fprintf(stderr, "%s: EOF in T object\n", infname);
			exit(1);
		}
		fprintf(outf, "%s\n", textline);
	}
	fputs("}\n", outf);
}

read_attrs(attrs, attrbuf)
	struct attr *attrs;
	char *attrbuf;
{
	char Tline[MAXLINE];
	int Tline_parsed[9];
	char attrline[MAXLINE];
	int nattrs, chars_used;
	char *bufptr;
	register char *cp;
	register int i;

	for (nattrs = 0, chars_used = 0, bufptr = attrbuf; ; ) {
		if (!getline(Tline)) {
badeof:			fprintf(stderr, "%s: EOF in attribute block\n",
				infname);
			exit(1);
		}
		switch (Tline[0]) {
		case 'T':
			break;
		case '}':
			return(nattrs);
		default:
			fprintf(stderr,
			"%s: line %d: wrong line type in attribute block\n",
				infname, lineno);
			exit(1);
		}
		parse_numline(Tline, lineno, Tline_parsed, 9, NULL);
		if (Tline_parsed[8] < 1) {
			fprintf(stderr, "%s: line %d: T object: num_lines<1!\n",
				infname, lineno);
			exit(1);
		}
		if (Tline_parsed[8] > 1) {
			fprintf(stderr,
	"%s: line %d: multiline text object in attribute block not supported\n",
				infname, lineno);
			exit(1);
		}
		if (!getline(attrline))
			goto badeof;
		cp = index(attrline, '=');
		if (!cp)		/* non-attribute text item */
			continue;	/* ignore these */
		/* break name and value */
		*cp++ = '\0';
		if (nattrs >= MAXATTRS) {
			fprintf(stderr, "%s: line %d: too many attributes\n",
				infname, lineno);
			exit(1);
		}
		for (i = 0; i < 8; i++)
			attrs[nattrs].graphparams[i] = Tline_parsed[i];
		i = strlen(attrline) + 1;
		chars_used += i;
		if (chars_used > ATTRBUF_SIZE) {
bufovflo:		fprintf(stderr, "%s: line %d: attr text buf overflow\n",
				infname, lineno);
			exit(1);
		}
		bcopy(attrline, bufptr, i);
		attrs[nattrs].name = bufptr;
		bufptr += i;
		i = strlen(cp) + 1;
		chars_used += i;
		if (chars_used > ATTRBUF_SIZE)
			goto bufovflo;
		bcopy(cp, bufptr, i);
		attrs[nattrs].value = bufptr;
		bufptr += i;
		nattrs++;
	}
}

parse_numline(line, lineno, numarray, nfields, endp)
	char *line;
	int lineno;
	int *numarray;
	int nfields;
	char **endp;
{
	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",
				infname, 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 (endp)
		*endp = cp;
	else if (*cp)
		goto inv;
}

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);
}

skipline()
{
	char junkline[MAXLINE];

	getline(junkline);
}