view pads2gpcb/parttype.c @ 145:5e91200bf609

netdiff: donl-pinreport utility written, compiles
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Nov 2020 01:17:10 +0000
parents ac13abc7dc0d
children
line wrap: on
line source

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <strings.h>
#include "globals.h"
#include "struct.h"

extern struct part_decal *find_decal_by_name();
extern char *savestr();

static struct part_type *our_parttype;
static int ngates, nsignals;

static void
enter_parttype()
{
	struct part_type *p, **pp;
	char *name = input_line_fields[0];

	for (pp = &part_type_list; p = *pp; pp = &p->next)
		if (!strcmp(p->name, name)) {
			fprintf(stderr,
			"%s line %d: part type name \"%s\" already defined\n",
				input_filename, input_lineno, name);
			exit(1);
		}
	p = malloc(sizeof(struct part_type) + strlen(name) + 1);
	if (!p) {
		perror("malloc of struct part_type");
		exit(1);
	}
	bzero(p, sizeof(struct part_type));
	p->name = (char *)(p + 1);
	strcpy(p->name, name);
	*pp = p;
	our_parttype = p;
}

static void
find_decals()
{
	char *cp, *np;
	struct part_decal *decal;

	for (cp = input_line_fields[1]; cp; cp = np) {
		np = index(cp, ':');
		if (np)
			*np++ = '\0';
		if (!*cp)
			continue;
		decal = find_decal_by_name(cp);
		if (!decal) {
			fprintf(stderr,
"%s line %d: part type definition refers to unknown decal name \"%s\"\n",
				input_filename, input_lineno, cp);
			exit(1);
		}
		if (our_parttype->ndecals >= MAX_DECALS_PER_PART_TYPE) {
			fprintf(stderr,
			"%s line %d: MAX_DECALS_PER_PART_TYPE exceeded\n",
				input_filename, input_lineno);
			exit(1);
		}
		our_parttype->decals[our_parttype->ndecals++] = decal;
	}
	if (!our_parttype->ndecals) {
		fprintf(stderr,
			"%s line %d: empty list of decals in part type def\n",
			input_filename, input_lineno);
		exit(1);
	}
}

static void
process_header_line()
{
	if (input_line_nfields < 6) {
		fprintf(stderr,
"%s line %d: expected beginning of part type definition, wrong # of fields\n",
			input_filename, input_lineno);
		exit(1);
	}
	enter_parttype();
	printf("Processing part type %s\n", our_parttype->name);
	find_decals();
	ngates = atoi(input_line_fields[3]);
	nsignals = atoi(input_line_fields[4]);
	our_parttype->num_alpha_pins = atoi(input_line_fields[5]);
}

static void
get_line_internal()
{
	if (!get_input_line()) {
		fprintf(stderr,
		      "error: EOF in the middle of a part type definition\n");
		exit(1);
	}
}

static void
process_one_gate_def()
{
	int gatepins;

	get_line_internal();
	parse_input_line_fields();
	if (input_line_nfields != 3 || strcmp(input_line_fields[0], "G")) {
		fprintf(stderr, "%s line %d: expected gate def header line\n",
			input_filename, input_lineno);
		exit(1);
	}
	gatepins = atoi(input_line_fields[2]);
	while (gatepins > 0) {
		get_line_internal();
		parse_input_line_fields();
		gatepins -= input_line_nfields;
	}
}

static void
alloc_alpha_pins_array()
{
	our_parttype->alpha_pins =
			malloc(sizeof(char *) * our_parttype->num_alpha_pins);
	if (!our_parttype->alpha_pins) {
		perror("malloc of alpha_pins array");
		exit(1);
	}
}

static void
read_alpha_pins()
{
	int idx, i;

	for (idx = 0; idx < our_parttype->num_alpha_pins; ) {
		get_line_internal();
		parse_input_line_fields();
		for (i = 0; i < input_line_nfields; i++) {
			if (idx >= our_parttype->num_alpha_pins) {
				fprintf(stderr,
				"%s line %d: alpha_pins array overflow\n",
					input_filename, input_lineno);
				exit(1);
			}
			our_parttype->alpha_pins[idx++] =
						savestr(input_line_fields[i]);
		}
	}
}

static void
write_alpha_pins_footprint()
{
	struct footprint_body *fpbody;
	char *filename, *cp, *dp;
	int c;
	FILE *outf;

	if (our_parttype->ndecals != 1) {
		printf(
"Warning: part type with alpha pins and multiple decals: save not supported\n");
		return;
	}
	fpbody = our_parttype->decals[0]->body;
	if (!fpbody)
		return;
	if (our_parttype->num_alpha_pins != fpbody->npins) {
		printf("Error: # of alpha pin names != # of actual pins\n");
		return;
	}

	filename = malloc(strlen(our_parttype->name) * 3 + 11);
	if (!filename) {
		perror("malloc for output file name");
		exit(1);
	}
	strcpy(filename, "alphapins/");
	dp = filename + 10;
	for (cp = our_parttype->name; *cp; ) {
		c = *cp++;
		if (isalnum(c) || c == '-' || c == '.' || c == '_')
			*dp++ = c;
		else {
			sprintf(dp, "%%%02X", c);
			dp += 3;
		}
	}
	*dp = '\0';
	outf = fopen(filename, "w");
	if (!outf) {
		perror(filename);
		exit(1);
	}
	write_gpcb_element(outf, fpbody, our_parttype->alpha_pins,
			   "", "", "", 0);
	fclose(outf);
	printf("Written to %s\n", filename);
	free(filename);
}

static void
process_one_parttype()
{
	int i;

	process_header_line();
	for (i = 0; i < ngates; i++)
		process_one_gate_def();
	for (i = 0; i < nsignals; i++)
		get_line_internal();
	if (our_parttype->num_alpha_pins) {
		alloc_alpha_pins_array();
		read_alpha_pins();
		if (write_footprint_files)
			write_alpha_pins_footprint();
	}
}

process_parttype_section()
{
	for (;;) {
		if (!get_input_line()) {
			fprintf(stderr, "error: EOF in PARTTYPE section\n");
			exit(1);
		}
		if (input_line_buf[0] == '*') {
			parse_starline();
			if (strcmp(input_line_starkw, "REMARK"))
				break;
			else
				continue;
		}
		parse_input_line_fields();
		if (input_line_nfields)
			process_one_parttype();
	}
}

struct part_type *
find_parttype_by_name(name)
	char *name;
{
	struct part_type *p;

	for (p = part_type_list; p; p = p->next)
		if (!strcmp(p->name, name))
			break;
	return(p);
}