view netdiff/convert/protel2donl.c @ 148:64d4abf63e1e

netdiff: donl-pindiff factored out of donl-netmatch
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Nov 2020 04:11:01 +0000
parents 603d8da32fd0
children
line wrap: on
line source

/*
 * This program converts a Protel netlist (exported from Altium) into our
 * Diff-Oriented Netlist (DONL) format.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

static char *infname;
static FILE *inf;
static char linebuf[80], netname[80];
static int lineno;

static
get_line()
{
	char *cp;

	if (!fgets(linebuf, sizeof linebuf, inf))
		return(0);
	lineno++;
	cp = index(linebuf, '\n');
	if (!cp) {
		fprintf(stderr, "%s line %d: missing newline\n",
			infname, lineno);
		exit(1);
	}
	*cp = '\0';
	if (cp > linebuf && cp[-1] == '\r')
		*--cp = '\0';
	return(1);
}

static void
get_line_notfirst()
{
	if (!get_line()) {
		fprintf(stderr, "error: unexpected EOF in input\n");
		exit(1);
	}
	if (!strcmp(linebuf, "[")) {
		fprintf(stderr, "%s line %d: [ NOT expected\n",
			infname, lineno);
		exit(1);
	}
	if (!strcmp(linebuf, "(")) {
		fprintf(stderr, "%s line %d: ( NOT expected\n",
			infname, lineno);
		exit(1);
	}
}

static void
skip_component_block()
{
	int i;

	for (i = 0; i < 6; i++) {
		get_line_notfirst();
		if (!strcmp(linebuf, "]")) {
			fprintf(stderr, "%s line %d: ] NOT expected\n",
				infname, lineno);
			exit(1);
		}
		if (!strcmp(linebuf, ")")) {
			fprintf(stderr, "%s line %d: ) NOT expected\n",
				infname, lineno);
			exit(1);
		}
	}
	get_line_notfirst();
	if (strcmp(linebuf, "]")) {
		fprintf(stderr, "%s line %d: expected ]\n", infname, lineno);
		exit(1);
	}
}

static void
process_net_point()
{
	char *cp;

	cp = index(linebuf, '-');
	if (!cp) {
		fprintf(stderr, "%s line %d: missing \'-\' in net point\n",
			infname, lineno);
		exit(1);
	}
	if (cp == linebuf) {
		fprintf(stderr, "%s line %d: refdes part is empty\n",
			infname, lineno);
		exit(1);
	}
	if (!cp[1]) {
		fprintf(stderr, "%s line %d: pin number part is empty\n",
			infname, lineno);
		exit(1);
	}
	*cp = '.';	/* our PADS-like convention */
	printf("%s\t%s\n", netname, linebuf);
}

static void
process_net_block()
{
	get_line_notfirst();
	if (!strcmp(linebuf, "]")) {
		fprintf(stderr, "%s line %d: ] NOT expected\n",
			infname, lineno);
		exit(1);
	}
	if (!strcmp(linebuf, ")")) {
		fprintf(stderr, "%s line %d: ) NOT expected\n",
			infname, lineno);
		exit(1);
	}
	if (!linebuf[0]) {
		fprintf(stderr, "%s line %d: empty net name\n",
			infname, lineno);
		exit(1);
	}
	strcpy(netname, linebuf);
	for (;;) {
		get_line_notfirst();
		if (!strcmp(linebuf, "]")) {
			fprintf(stderr, "%s line %d: ] NOT expected\n",
				infname, lineno);
			exit(1);
		}
		if (!strcmp(linebuf, ")"))
			break;
		process_net_point();
	}
}

main(argc, argv)
	char **argv;
{
	if (argc != 2) {
		fprintf(stderr, "usage: %s protel-netlist-file\n", argv[0]);
		exit(1);
	}
	infname = argv[1];
	inf = fopen(infname, "r");
	if (!inf) {
		perror(infname);
		exit(1);
	}
	for (;;) {
		if (!get_line())
			break;
		if (!strcmp(linebuf, "["))
			skip_component_block();
		else if (!strcmp(linebuf, "("))
			process_net_block();
		else {
			fprintf(stderr,
				"%s line %d: expected beginning of block\n",
				infname, lineno);
			exit(1);
		}
	}
	exit(0);
}