FreeCalypso > hg > ueda-linux
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(); + } +}