view pads2gpcb/partinst.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 a3d47129ebdc
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_type *find_parttype_by_name();
extern struct part_decal *find_decal_by_name();
extern long convert_input_dim();

extern void coordpair_mirror_x();
extern void coordpair_rot_90();
extern void coordpair_rot_180();
extern void coordpair_rot_270();

static struct part_instance *our_part;

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

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

static void
select_decal_by_name(decalname)
	char *decalname;
{
	our_part->decal = find_decal_by_name(decalname);
	if (!our_part->decal) {
		fprintf(stderr,
	"%s line %d: part instantiation refers to unknown decal name \"%s\"\n",
			input_filename, input_lineno, decalname);
		exit(1);
	}
}

static void
select_decal_by_number()
{
	char *strnum = input_line_fields[7];
	int num = atoi(strnum);

	if (num < 0 || num >= our_part->type->ndecals) {
		fprintf(stderr,
		"%s line %d: invalid decal number \"%s\" in PART line\n",
			input_filename, input_lineno, strnum);
		exit(1);
	}
	our_part->decal = our_part->type->decals[num];
}

static void
find_type_and_decal()
{
	char *typename = input_line_fields[1];
	char *decalname;

	decalname = index(typename, '@');
	if (decalname)
		*decalname++ = '\0';
	our_part->type = find_parttype_by_name(typename);
	if (!our_part->type) {
		fprintf(stderr,
	"%s line %d: part instantiation refers to unknown part type \"%s\"\n",
			input_filename, input_lineno, typename);
		exit(1);
	}
	if (decalname)
		select_decal_by_name(decalname);
	else
		select_decal_by_number();
}

static void
one_attr_label()
{
	int i;

	/* just skip it for now */
	for (i = 0; i < 3; i++) {
		if (!get_input_line()) {
			fprintf(stderr,
			"error: EOF when expecting a part label line\n");
			exit(1);
		}
	}
}

static void
read_one_part()
{
	int num_attr_labels, i;

	if (input_line_nfields < 8 || input_line_nfields > 12) {
		fprintf(stderr,
	"%s line %d: expected beginning of part instance, wrong # of fields\n",
			input_filename, input_lineno);
		exit(1);
	}
	enter_part_inst();
	printf("Processing part instance %s\n", our_part->name);
	find_type_and_decal();
	our_part->mark_x = convert_input_dim(input_line_fields[2]);
	our_part->mark_y = convert_input_dim(input_line_fields[3]);
	our_part->ori = parse_input_angle_90s(input_line_fields[4]);
	if (!strcmp(input_line_fields[6], "N"))
		our_part->onbottom = 0;
	else if (!strcmp(input_line_fields[6], "M"))
		our_part->onbottom = 1;
	else {
		fprintf(stderr, "%s line %d: expected 'N' or 'M' in field 6\n",
			input_filename, input_lineno);
		exit(1);
	}
	if (input_line_nfields > 11)
		num_attr_labels = atoi(input_line_fields[11]);
	else
		num_attr_labels = 0;
	for (i = 0; i < num_attr_labels; i++)
		one_attr_label();
}

static void
copy_footprint_body()
{
	struct footprint_body *origfp = our_part->decal->body;
	struct footprint_body *newbody;

	newbody = malloc(sizeof(struct footprint_body));
	if (!newbody) {
		perror("malloc to copy footprint body");
		exit(1);
	}
	bcopy(origfp, newbody, sizeof(struct footprint_body));
	newbody->pins = malloc(sizeof(struct footprint_pad) * origfp->npins);
	if (!newbody->pins) {
		perror("malloc to copy footprint pads");
		exit(1);
	}
	bcopy(origfp->pins, newbody->pins,
		sizeof(struct footprint_pad) * origfp->npins);
	if (origfp->silk_lines) {
		newbody->silk_lines =
			malloc(sizeof(struct element_line) *
				origfp->num_silk_lines);
		if (!newbody->silk_lines) {
			perror("malloc to copy footprint silk lines");
			exit(1);
		}
		bcopy(origfp->silk_lines, newbody->silk_lines,
			sizeof(struct element_line) * origfp->num_silk_lines);
	}
	if (origfp->silk_arcs) {
		newbody->silk_arcs =
			malloc(sizeof(struct element_arc) *
				origfp->num_silk_arcs);
		if (!newbody->silk_arcs) {
			perror("malloc to copy footprint silk arcs");
			exit(1);
		}
		bcopy(origfp->silk_arcs, newbody->silk_arcs,
			sizeof(struct element_arc) * origfp->num_silk_arcs);
	}
	our_part->body = newbody;
}

static void
part_inst_fail(reason)
	char *reason;
{
	printf("Omitting component %s: %s\n", our_part->name, reason);
}

static void
process_one_part()
{
	read_one_part();
	/* analyze it */
	if (!our_part->decal->body) {
		part_inst_fail("bad decal");
		return;
	}
	if (our_part->type->num_alpha_pins &&
	    our_part->type->num_alpha_pins != our_part->decal->body->npins) {
		part_inst_fail("alpha pins count mismatch");
		return;
	}
	if (our_part->ori < 0) {
		part_inst_fail("non-rectangular orientation");
		return;
	}

	/* subsetting and renaming logic will go here */
	our_part->newname = our_part->name;
	copy_footprint_body();
	our_part->body->mark_x = our_part->mark_x;
	our_part->body->mark_y = our_part->mark_y;
	switch (our_part->ori) {
	case 0:
		break;
	case 90:
		manipulate_footprint_coord_pairs(our_part->body,
						 coordpair_rot_90);
		break;
	case 180:
		manipulate_footprint_coord_pairs(our_part->body,
						 coordpair_rot_180);
		break;
	case 270:
		manipulate_footprint_coord_pairs(our_part->body,
						 coordpair_rot_270);
	}
	if (our_part->onbottom)
		manipulate_footprint_coord_pairs(our_part->body,
						 coordpair_mirror_x);
}

process_part_section()
{
	input_units_current = input_units_global;
	for (;;) {
		if (!get_input_line()) {
			fprintf(stderr, "error: EOF in PART 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_part();
	}
}