diff ueda/libuschem/wrschem.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/libuschem/wrschem.c	Mon Jul 20 00:24:37 2015 +0000
@@ -0,0 +1,344 @@
+/*
+ * Schematic write-out
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include "schemstruct.h"
+#include "writerint.h"
+
+extern FILE *reopen_schem_for_graphblocks();
+
+extern struct drawing_size_kwtab drawing_size_keywords[];
+
+struct schem_write_state schem_write_state;
+
+write_schem(schem, outf)
+	struct schem *schem;
+	FILE *outf;
+{
+	register struct schemobj *obj;
+
+	schem_write_state.schem = schem;
+	schem_write_state.outf = outf;
+	schem_write_state.orig_file = reopen_schem_for_graphblocks(schem);
+	wrschem_emit_schemline(schem);
+	putc('\n', outf);
+
+	for (obj = schem->obj_next; obj != (struct schemobj *)schem;
+	     obj = obj->obj_next)
+		wrschem_emit_object(obj);
+
+	if (schem_write_state.orig_file)
+		fclose(schem_write_state.orig_file);
+}
+
+wrschem_emit_schemline(schem)
+	register struct schem *schem;
+{
+	register struct drawing_size_kwtab *kwp;
+
+	if (!schem->is_graph) {
+		fprintf(schem_write_state.outf, "Schem nograph;\n");
+		return;
+	}
+	for (kwp = drawing_size_keywords; kwp->keyword; kwp++)
+		if (schem->graph_xsize == kwp->xdim &&
+		    schem->graph_ysize == kwp->ydim) {
+			fprintf(schem_write_state.outf, "Schem graph %s;\n",
+				kwp->keyword);
+			return;
+		}
+	fprintf(schem_write_state.outf, "Schem graph %dx%d;\n",
+		schem->graph_xsize, schem->graph_ysize);
+}
+
+wrschem_emit_qstring(str)
+	char *str;
+{
+	register char *cp;
+	register int c;
+
+	putc('\"', schem_write_state.outf);
+	for (cp = str; c = *cp; cp++) {
+		if (c == '\"' || c == '\\')
+			putc('\\', schem_write_state.outf);
+		putc(c, schem_write_state.outf);
+	}
+	putc('\"', schem_write_state.outf);
+}
+
+wrschem_emit_string(str)
+	register char *str;
+{
+	if (schem_string_needs_quote(str))
+		wrschem_emit_qstring(str);
+	else
+		fputs(str, schem_write_state.outf);
+}
+
+schem_string_needs_quote(str)
+	char *str;
+{
+	register char *cp;
+	register int c;
+
+	cp = str;
+	if (!*cp)
+		return(1);	/* null strings can only be quoted */
+	while (c = *cp++)
+		switch (c) {
+		case ' ':
+		case '\t':
+		case '\n':
+		case '"':
+		case '%':
+		case '(':
+		case ')':
+		case ',':
+		case ';':
+		case '=':
+		case '{':
+		case '}':
+			return(1);
+		}
+	return(0);
+}
+
+wrschem_emit_object(obj)
+	register struct schemobj *obj;
+{
+	switch (obj->obj_type) {
+	case OBJTYPE_COMPINST:
+		fputs("Component ", schem_write_state.outf);
+		wrschem_emit_string(obj->compobj_instname);
+		if (obj->compobj_isgraph) {
+			fputs(" graph ", schem_write_state.outf);
+			wrschem_emit_qstring(obj->compobj_graph_symname);
+			fprintf(schem_write_state.outf, " %d %d",
+				obj->compobj_x, obj->compobj_y);
+			if (obj->compobj_rotate)
+				fprintf(schem_write_state.outf, " rot %d",
+					obj->compobj_rotate);
+			if (obj->compobj_mirror)
+				fputs(" mirror", schem_write_state.outf);
+		}
+		if (obj->obj_decorations)
+			wrschem_emit_decor_block(obj);
+		fputs(";\n", schem_write_state.outf);
+		return;
+
+	case OBJTYPE_GRAPHSYM:
+		fputs("GraphSym ", schem_write_state.outf);
+		wrschem_emit_qstring(obj->compobj_graph_symname);
+		fprintf(schem_write_state.outf, " %d %d",
+			obj->compobj_x, obj->compobj_y);
+		if (obj->compobj_rotate)
+			fprintf(schem_write_state.outf, " rot %d",
+				obj->compobj_rotate);
+		if (obj->compobj_mirror)
+			fputs(" mirror", schem_write_state.outf);
+		if (obj->obj_decorations)
+			wrschem_emit_decor_block(obj);
+		fputs(";\n", schem_write_state.outf);
+		return;
+
+	case OBJTYPE_NET:
+		wrschem_emit_net(obj, "Net", 0);
+		return;
+
+	case OBJTYPE_GRAPHNET:
+		wrschem_emit_net(obj, "GraphNet", 1);
+		return;
+
+	case OBJTYPE_NETLINE:
+		fprintf(schem_write_state.outf, "NetLine (%d,%d) (%d,%d)",
+			obj->lineobj_x1, obj->lineobj_y1,
+			obj->lineobj_x2, obj->lineobj_y2);
+		if (obj->obj_decorations)
+			wrschem_emit_decor_block(obj);
+		fputs(";\n", schem_write_state.outf);
+		return;
+
+	case OBJTYPE_BUSSEG:
+		fprintf(schem_write_state.outf, "BusSeg (%d,%d) (%d,%d)",
+			obj->lineobj_x1, obj->lineobj_y1,
+			obj->lineobj_x2, obj->lineobj_y2);
+		if (obj->obj_decorations)
+			wrschem_emit_decor_block(obj);
+		fputs(";\n", schem_write_state.outf);
+		return;
+
+	case OBJTYPE_GRAPHBLOCK:
+		wrschem_emit_graphblock(obj->graphblockobj_body);
+		return;
+
+	case OBJTYPE_COMMENT:
+		fputs("Comment ", schem_write_state.outf);
+		wrschem_emit_qstring(obj->commentobj_text);
+		fputs(";\n", schem_write_state.outf);
+		return;
+
+	default:
+		fprintf(stderr,
+	"Fatal internal error: unknown obj type in wrschem_emit_object()\n");
+		abort();
+	}
+}
+
+/* for Net and GraphNet */
+wrschem_emit_net(obj, keyword, isgraphnet)
+	register struct schemobj *obj;
+	char *keyword;
+	int isgraphnet;
+{
+	register struct netpoint *netpt;
+
+	fprintf(schem_write_state.outf, "%s ", keyword);
+	if (obj->netobj_grouphead && obj->netobj_grouphead->netobj_netname)
+		wrschem_emit_string(obj->netobj_grouphead->netobj_netname);
+	else if (obj->netobj_netname)
+		wrschem_emit_string(obj->netobj_netname);
+	else
+		fputs("\"\"", schem_write_state.outf);
+
+	for (netpt = obj->netobj_points; netpt; netpt = netpt->netpt_next) {
+		putc(' ', schem_write_state.outf);
+		switch (netpt->netpt_type) {
+		case NETPT_TYPE_POINT:
+			fprintf(schem_write_state.outf, "(%d,%d)",
+				netpt->netpt_x, netpt->netpt_y);
+			break;
+		case NETPT_TYPE_PIN:
+			if (isgraphnet) {
+				fputs("Pin", schem_write_state.outf);
+				if (netpt->netpt_coord_valid)
+					fprintf(schem_write_state.outf,
+						"(%d,%d)",
+						netpt->netpt_x, netpt->netpt_y);
+				if (netpt->netpt_pin_nameref)
+					putc('=', schem_write_state.outf);
+			}
+			if (netpt->netpt_pin_nameref)
+				wrschem_emit_string(netpt->netpt_pin_nameref);
+			break;
+		case NETPT_TYPE_TJOIN:
+			fprintf(schem_write_state.outf, "Tjoin(%d,%d)",
+				netpt->netpt_x, netpt->netpt_y);
+			break;
+		case NETPT_TYPE_PSEUDO:
+			fprintf(schem_write_state.outf, "Pseudo(%d,%d)",
+				netpt->netpt_x, netpt->netpt_y);
+			break;
+		}
+	}
+
+	if (obj->obj_decorations)
+		wrschem_emit_decor_block(obj);
+	fputs(";\n", schem_write_state.outf);
+}
+
+wrschem_emit_graphblock(blk)
+	struct graphblock *blk;
+{
+	char *keyword;
+
+	switch (blk->type) {
+	case GRAPHBLOCK_TYPE_PS:
+		keyword = "GraphBlockPS";
+		break;
+	case GRAPHBLOCK_TYPE_GSCHEM:
+		keyword = "GraphBlockG";
+		break;
+	default:
+		fprintf(stderr,
+	  "Fatal internal error: unknown type in wrschem_emit_graphblock()\n");
+		abort();
+	}
+	fprintf(schem_write_state.outf, "%s {\n", keyword);
+	write_graphblock_to_file(blk, schem_write_state.orig_file,
+					schem_write_state.outf);
+	fputs("}\n", schem_write_state.outf);
+}
+
+wrschem_emit_decor_block(obj)
+	struct schemobj *obj;
+{
+	register struct decoration *decor;
+
+	fputs(" {\n", schem_write_state.outf);
+	for (decor = obj->obj_decorations; decor; decor = decor->decor_next)
+		wrschem_emit_decor(decor);
+	putc('}', schem_write_state.outf);
+}
+
+wrschem_emit_decor(decor)
+	register struct decoration *decor;
+{
+	switch (decor->decor_type) {
+	case DECOR_TYPE_ATTR:
+		fputs("\t(", schem_write_state.outf);
+		wrschem_emit_string(decor->decorattr_name);
+		putc('=', schem_write_state.outf);
+		wrschem_emit_qstring(decor->decorattr_value);
+		fputs(")\n", schem_write_state.outf);
+		return;
+
+	case DECOR_TYPE_DISPLAYATTR:
+		fputs("\tDisplayAttr ", schem_write_state.outf);
+		wrschem_emit_string(decor->decordisp_attr);
+		fprintf(schem_write_state.outf, " %d %d %d %d %d;\n",
+			decor->decordisp_x, decor->decordisp_y,
+			decor->decordisp_ptsize, decor->decordisp_rotate,
+			decor->decordisp_alignment);
+		return;
+
+	case DECOR_TYPE_DISPLAYNETNAME:
+		fprintf(schem_write_state.outf,
+			"\tDisplayNetName %d %d %d %d %d;\n",
+			decor->decordisp_x, decor->decordisp_y,
+			decor->decordisp_ptsize, decor->decordisp_rotate,
+			decor->decordisp_alignment);
+		return;
+
+	case DECOR_TYPE_PINTONET:
+		fputs("\tPinToNet ", schem_write_state.outf);
+		wrschem_emit_string(decor->decorpincon_pin);
+		putc(' ', schem_write_state.outf);
+		wrschem_emit_string(decor->decorpincon_netname);
+		fputs(";\n", schem_write_state.outf);
+		return;
+
+	case DECOR_TYPE_NOCONNECT:
+		fputs("\tNoConnect ", schem_write_state.outf);
+		wrschem_emit_string(decor->decorpincon_pin);
+		fputs(";\n", schem_write_state.outf);
+		return;
+
+	case DECOR_TYPE_SYMONPIN:
+		fputs("\tSymOnPin ", schem_write_state.outf);
+		wrschem_emit_string(decor->decorpinsym_pin);
+		putc(' ', schem_write_state.outf);
+		wrschem_emit_qstring(decor->decorpinsym_symname);
+		if (decor->decorpinsym_mirror)
+			fputs(" mirror", schem_write_state.outf);
+		fputs(";\n", schem_write_state.outf);
+		return;
+
+	case DECOR_TYPE_GRAPHBLOCK:
+		putc('\t', schem_write_state.outf);
+		wrschem_emit_graphblock(decor->decorgraph_body);
+		return;
+
+	case DECOR_TYPE_COMMENT:
+		fputs("\tComment ", schem_write_state.outf);
+		wrschem_emit_qstring(decor->decorcomment_text);
+		fputs(";\n", schem_write_state.outf);
+		return;
+
+	default:
+		fprintf(stderr,
+    "Fatal internal error: unknown decoration type in wrschem_emit_decor()\n");
+		abort();
+	}
+}