diff ueda/uschem-utils/rewrite.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-utils/rewrite.c	Mon Jul 20 00:24:37 2015 +0000
@@ -0,0 +1,268 @@
+/*
+ * This program reads a uschem schematic into core and then writes it back out.
+ * -g options converts NetLines to GraphNets and then preens/canonicalizes
+ * all GraphNets, otherwise just exercises the parser & writer code in
+ * libuschem.
+ */
+
+#include <sys/types.h>
+#include <sys/file.h>
+#include <stdio.h>
+#include <strings.h>
+#include "../libuschem/schemstruct.h"
+#include "../libuschem/graphsym.h"
+
+extern int optind;
+extern char *optarg;
+extern char *malloc();
+
+extern struct schem *read_schem();
+extern struct netpoint *parser_alloc_netpoint();
+extern struct graphsym_pininst *find_pin_by_coord();
+
+struct schem *schem;
+char *outfile;
+int replace_orig;
+int gflag, Oflag;
+
+char *
+mk_temp_newfilename()
+{
+	int len;
+	register char *str;
+
+	len = strlen(schem->orig_filename) + 5;
+	str = malloc(len);
+	if (!str) {
+		perror("malloc");
+		exit(1);
+	}
+	sprintf(str, "%s.new", schem->orig_filename);
+	return(str);
+}
+
+main(argc, argv)
+	char **argv;
+{
+	register int c;
+	int fd;
+	FILE *outf;
+
+	while ((c = getopt(argc, argv, "gI:o:O")) != EOF)
+		switch (c) {
+		case 'g':
+			gflag++;
+			break;
+		case 'I':
+			add_symfile_dir(optarg);
+			break;
+		case 'o':
+			outfile = optarg;
+			break;
+		case 'O':
+			Oflag++;
+			break;
+		default:
+usage:			fprintf(stderr, "usage: %s [-o newfile] schemfile\n",
+				argv[0]);
+			exit(1);
+		}
+	if (!argv[optind])
+		goto usage;
+
+	schem = read_schem(argv[optind]);
+	if (!outfile) {
+		outfile = mk_temp_newfilename();
+		replace_orig = 1;
+	}
+
+	if (gflag) {
+		if (hash_component_instances(schem) < 0)
+			exit(1);
+		set_default_sympath();
+		load_graphsyms(schem);
+		if (instantiate_graphsym_pins(schem, 1) < 0 && !Oflag)
+			exit(1);
+		convert_netlines_to_graphnets();
+		if (preen_graphnets(schem, 1, 1, 0, 1) < 0)
+			exit(1);
+	}
+
+	c = O_WRONLY | O_CREAT;
+	if (replace_orig)
+		c |= O_EXCL;
+	else
+		c |= O_TRUNC;
+	fd = open(outfile, c, 0644);
+	if (fd < 0) {
+		perror(outfile);
+		exit(1);
+	}
+	outf = fdopen(fd, "w");
+	if (!outf) {
+		perror("fdopen");
+		exit(1);
+	}
+	write_schem(schem, outf);
+	fclose(outf);
+	if (replace_orig)
+		rename(outfile, schem->orig_filename);
+	exit(0);
+}
+
+convert_netlines_to_graphnets()
+{
+	register struct schemobj *obj;
+
+	for (obj = schem->obj_next; obj != (struct schemobj *)schem;
+	     obj = obj->obj_next)
+		if (obj->obj_type == OBJTYPE_NETLINE)
+			convert_netline(obj);
+}
+
+convert_netline(obj)
+	register struct schemobj *obj;
+{
+	register struct netpoint *end1, *end2;
+
+	end1 = parser_alloc_netpoint(NETPT_TYPE_POINT);
+	end1->netpt_x = obj->lineobj_x1;
+	end1->netpt_y = obj->lineobj_y1;
+	end1->netpt_coord_valid = 1;
+	pinify_netpoint(end1);
+	end2 = parser_alloc_netpoint(NETPT_TYPE_POINT);
+	end2->netpt_x = obj->lineobj_x2;
+	end2->netpt_y = obj->lineobj_y2;
+	end2->netpt_coord_valid = 1;
+	pinify_netpoint(end2);
+	end1->netpt_next = end2;
+	obj->obj_type = OBJTYPE_GRAPHNET;
+	obj->netobj_points = end1;
+	obj->netobj_netname = NULL;
+	if (!extend_new_graphnet(obj)) {
+		end1->netpt_next = NULL;
+		end2->netpt_next = end1;
+		obj->netobj_points = end2;
+		extend_new_graphnet(obj);
+	}
+	convert_netline_decors(obj);
+}
+
+pinify_netpoint(netpt)
+	register struct netpoint *netpt;
+{
+	register struct graphsym_pininst *pin;
+
+	pin = find_pin_by_coord(schem, netpt->netpt_x, netpt->netpt_y);
+	if (!pin)
+		return;
+	switch (pin->compinst->obj_type) {
+	case OBJTYPE_COMPINST:
+		netpt->netpt_type = NETPT_TYPE_PIN;
+		return;
+	case OBJTYPE_GRAPHSYM:
+		netpt->netpt_type = NETPT_TYPE_PSEUDO;
+		return;
+	}
+}
+
+convert_netline_decors(obj)
+	struct schemobj *obj;
+{
+	register struct decoration *decor;
+	struct decoration **np;
+
+	for (np = &obj->obj_decorations; decor = *np; ) {
+		switch (decor->decor_type) {
+		case DECOR_TYPE_ATTR:
+			if (strcmp(decor->decorattr_name, "netname"))
+				break;
+			if (obj->netobj_netname &&
+			  strcmp(obj->netobj_netname, decor->decorattr_value)) {
+				fprintf(stderr,
+					"%s: line %d: net name conflict\n",
+					schem->orig_filename,
+					decor->decor_lineno);
+				exit(1);
+			}
+			obj->netobj_netname = decor->decorattr_value;
+			/* drop the decoration */
+			*np = decor->decor_next;
+			continue;
+		case DECOR_TYPE_DISPLAYATTR:
+			if (!strcmp(decor->decordisp_attr, "netname"))
+				decor->decor_type = DECOR_TYPE_DISPLAYNETNAME;
+			break;
+		}
+		np = &decor->decor_next;
+	}
+}
+
+struct netpoint *
+convert_netline_to_netpt(gn, nlobj, whichend)
+	struct schemobj *gn;
+	register struct schemobj *nlobj;
+	int whichend;
+{
+	register struct netpoint *netpt;
+
+	netpt = parser_alloc_netpoint(NETPT_TYPE_POINT);
+	switch (whichend) {
+	case 1:
+		netpt->netpt_x = nlobj->lineobj_x1;
+		netpt->netpt_y = nlobj->lineobj_y1;
+		break;
+	case 2:
+		netpt->netpt_x = nlobj->lineobj_x2;
+		netpt->netpt_y = nlobj->lineobj_y2;
+		break;
+	}
+	netpt->netpt_coord_valid = 1;
+	pinify_netpoint(netpt);
+	netconvert_append_decors(gn, nlobj);
+	schemobj_unlink(nlobj);
+	return(netpt);
+}
+
+extend_new_graphnet(gn)
+	struct schemobj *gn;
+{
+	register struct schemobj *obj;
+	register struct netpoint *tail, *new;
+	int success = 0;
+
+	tail = gn->netobj_points->netpt_next;
+loop:	for (obj = gn->obj_next; obj != (struct schemobj *)schem;
+	     obj = obj->obj_next) {
+		if (obj->obj_type != OBJTYPE_NETLINE)
+			continue;
+		if (obj->lineobj_x1 == tail->netpt_x &&
+		    obj->lineobj_y1 == tail->netpt_y) {
+			new = convert_netline_to_netpt(gn, obj, 2);
+			tail->netpt_next = new;
+			tail = new;
+			success = 1;
+			goto loop;
+		}
+		if (obj->lineobj_x2 == tail->netpt_x &&
+		    obj->lineobj_y2 == tail->netpt_y) {
+			new = convert_netline_to_netpt(gn, obj, 1);
+			tail->netpt_next = new;
+			tail = new;
+			success = 1;
+			goto loop;
+		}
+	}
+	return(success);
+}
+
+netconvert_append_decors(gnobj, nlobj)
+	struct schemobj *gnobj, *nlobj;
+{
+	register struct decoration *decor;
+	register struct decoration **np;
+
+	for (np = &gnobj->obj_decorations; decor = *np; np = &decor->decor_next)
+		;
+	*np = nlobj->obj_decorations;
+}