view ueda/unet-utils/unet2pcb.c @ 140:d3eb3790386d

netdiff: donl-netmatch put together
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 07 Sep 2020 04:57:37 +0000
parents 47b5b8310cac
children
line wrap: on
line source

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include "../libunet/unetrd.h"
#include "../libunet/nethash.h"

extern struct net *enter_net_object();
extern struct net *find_net_by_name();
extern struct net *net_list_head;

static char *input_filename, *output_filename;
static struct unetrd_state rdstate;
static struct unetrd_out rdout;
static FILE *outFILE;

struct netextra {
	struct	netmember *head;
	struct	netmember **tailp;
};

struct netmember {
	char	*name;
	struct	netmember *next;
};

static void
process_pin_connect(compname)
	char *compname;
{
	register struct net *n;
	register struct netextra *nx;
	register struct netmember *nm;

	n = find_net_by_name(rdout.connect_to_net);
	nx = (struct netextra *)(n + 1);
	nm = (struct netmember *) malloc(sizeof(struct netmember) +
					 strlen(compname) +
					 strlen(rdout.objname) + 2);
	if (!nm) {
		perror("malloc");
		exit(1);
	}
	nm->name = (char *)(nm + 1);
	sprintf(nm->name, "%s-%s", compname, rdout.objname);
	nm->next = 0;
	*nx->tailp = nm;
	nx->tailp = &nm->next;
}

static void
process_component()
{
	char compname[64];

	strcpy(compname, rdout.objname);
	for (;;) {
		if (!read_unet_line(&rdstate, &rdout)) {
			fprintf(stderr, "%s error: EOF in COMPONENT block\n",
				input_filename);
			exit(1);
		}
		if (rdout.typecode == UNETOBJ_CLOSINGBRACE)
			break;
		switch(rdout.typecode) {
		case UNETOBJ_PRIMITIVE:
		case UNETOBJ_ALTNAME:
		case UNETOBJ_ATTR:
			continue;
		case UNETOBJ_PIN:
			if (rdout.connect_to_net)
				process_pin_connect(compname);
			continue;
		case UNETOBJ_PINMAP:
			fprintf(stderr,
		"%s line %d: PINMAP objects not expected in unet2pcb input\n",
				input_filename, rdstate.lineno);
			exit(1);
		default:
			fprintf(stderr,
		"%s line %d: object type %s unexpected in COMPONENT block\n",
				input_filename, rdstate.lineno, rdout.keyword);
			exit(1);
		}
	}
}

static void
process_input_unet()
{
	struct net *n;
	struct netextra *nx;

	open_unet_input_file(input_filename, &rdstate);
	while (read_unet_line(&rdstate, &rdout)) {
		switch(rdout.typecode) {
		case UNETOBJ_CLOSINGBRACE:
			fprintf(stderr,
		"%s line %d: unexpected '}' outside of component block\n",
				input_filename, rdstate.lineno);
			exit(1);
		case UNETOBJ_NET:
			n = enter_net_object(rdout.objname,
						sizeof(struct netextra));
			nx = (struct netextra *)(n + 1);
			nx->head = 0;
			nx->tailp = &nx->head;
			continue;
		case UNETOBJ_COMPONENT:
			process_component();
			continue;
		case UNETOBJ_STARPOINT:
			fprintf(stderr,
"error: STARPOINT objects not expected in unet2pcb input (%s line %d)\n",
				input_filename, rdstate.lineno);
			exit(1);
		default:
			fprintf(stderr,
				"%s line %d: unexpected object type %s\n",
				input_filename, rdstate.lineno, rdout.keyword);
			exit(1);
		}
	}
}

static
emit_net(net)
	struct net *net;
{
	struct netextra *nx;
	register struct netmember *nm;
	int linelen, linefresh;
	register int i;

	nx = (struct netextra *)(net + 1);
	fprintf(outFILE, "%s\t", net->name);
	linelen = (strlen(net->name) + 8) & ~7;
	linefresh = 1;
	for (nm = nx->head; nm; nm = nm->next) {
		i = strlen(nm->name) + 1;
		if (!linefresh && linelen + i > 78) {
			fputs(" \\\n\t", outFILE);
			linelen = 8;
			linefresh = 1;
		}
		if (linefresh)
			i--;
		else
			putc(' ', outFILE);
		fputs(nm->name, outFILE);
		linelen += i;
		linefresh = 0;
	}
	putc('\n', outFILE);
}

static void
generate_output()
{
	register struct net *n;

	if (output_filename) {
		outFILE = fopen(output_filename, "w");
		if (!outFILE) {
			perror(output_filename);
			exit(1);
		}
	} else
		outFILE = stdout;
	for (n = net_list_head; n; n = n->nextinlist)
		emit_net(n);
	if (outFILE != stdout)
		fclose(outFILE);
}

main(argc, argv)
	char **argv;
{
	if (argc < 2 || argc > 3) {
		fprintf(stderr, "usage: %s input.unet [output-file]\n",
			argv[0]);
		exit(1);
	}
	input_filename = argv[1];
	output_filename = argv[2];
	process_input_unet();
	generate_output();
	exit(0);
}