view miscutil/protel-parts-condense.c @ 144:ffadaa339478

protel-parts-condense misc utility written
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 20 Sep 2020 02:40:23 +0000
parents
children
line wrap: on
line source

/*
 * This program reads a Protel netlist (exported from Altium), extracts
 * the component list portion and emits it in a condensed form.
 */

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

static char *infname;
static FILE *inf;
static char linebuf[80], savebuf[6][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
check_line_for_nonprint_chars()
{
	char *cp;
	int c;

	for (cp = linebuf; *cp; cp++) {
		c = *cp;
		if ((c < ' ' || c > '~') && c != '\t') {
			fprintf(stderr, "%s line %d: non-printable char\n",
				infname, lineno);
			exit(1);
		}
	}
}

static int
item_needs_quoting(str)
	char *str;
{
	char *cp;
	int c;

	if (!str[0])
		return(1);
	for (cp = str; *cp; cp++) {
		c = *cp;
		if (c == '\t' || c == ' ' || c == '\"' || c == '\\')
			return(1);
	}
	return(0);
}

static void
print_item_quoted(str)
	char *str;
{
	char *cp;
	int c;

	putchar('\"');
	for (cp = str; *cp; cp++) {
		c = *cp;
		if (c == '\t') {
			putchar('\\');
			putchar('t');
			continue;
		}
		if (c == '\"' || c == '\\')
			putchar('\\');
		putchar(c);
	}
	putchar('\"');
}

static void
print_item(str)
	char *str;
{
	if (item_needs_quoting(str))
		print_item_quoted(str);
	else
		fputs(str, stdout);
}

static void
process_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);
		}
		check_line_for_nonprint_chars();
		strcpy(savebuf[i], linebuf);
	}
	get_line_notfirst();
	if (strcmp(linebuf, "]")) {
		fprintf(stderr, "%s line %d: expected ]\n", infname, lineno);
		exit(1);
	}
	print_item(savebuf[0]);
	putchar(' ');
	print_item(savebuf[1]);
	putchar(' ');
	print_item(savebuf[2]);
	putchar(' ');
	print_item(savebuf[3]);
	putchar(' ');
	print_item(savebuf[4]);
	putchar(' ');
	print_item(savebuf[5]);
	putchar('\n');
}

static void
skip_net_block()
{
	for (;;) {
		get_line_notfirst();
		if (!strcmp(linebuf, "]")) {
			fprintf(stderr, "%s line %d: ] NOT expected\n",
				infname, lineno);
			exit(1);
		}
		if (!strcmp(linebuf, ")"))
			break;
	}
}

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, "["))
			process_component_block();
		else if (!strcmp(linebuf, "("))
			skip_net_block();
		else {
			fprintf(stderr,
				"%s line %d: expected beginning of block\n",
				infname, lineno);
			exit(1);
		}
	}
	exit(0);
}