view ueda/mclutils/shortbom.c @ 3:d098f8548b44

ueda/mclutils Linuxified
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 20 Jul 2015 00:45:40 +0000
parents cd92449fdb51
children
line wrap: on
line source

/*
 * This program generates a "short" BOM from the MCL.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include "../libueda/mcl.h"

extern char *MCLfile;
extern struct component components[];
extern int ncomponents;
extern char *get_comp_attr();
extern struct component *find_partdef_by_name();

struct bomline {
	char	*refdes;
	char	*manuf;
	char	*partno;
	char	*description;
};

int column_sep_width = 2, tabbed;
int assembly;
struct bomline *bombuf;
int nbomlines;
char unknownstr[] = "unknown";
int refdes_col_width, manuf_col_width, partno_col_width;

do_cmdline_opts(argc, argv)
	char **argv;
{
	register int c;

	while ((c = getopt(argc, argv, "aM:p:s:t")) != EOF)
		switch (c) {
		case 'a':
			assembly++;
			break;
		case 'M':
			MCLfile = optarg;
			break;
		case 'p':
			set_popopt_list(optarg);
			break;
		case 's':
			column_sep_width = atoi(optarg);
			break;
		case 't':
			tabbed++;
			break;
		default:
			/* getopt prints the error message */
			exit(1);
		}
}

main(argc, argv)
	char **argv;
{
	do_cmdline_opts(argc, argv);
	read_MCL();
	bombuf = (struct bomline *)
			malloc(sizeof(struct bomline) * (ncomponents+1));
	if (!bombuf) {
		perror("malloc");
		exit(1);
	}
	bombuf[0].refdes = "Refdes";
	bombuf[0].manuf = "Manuf";
	bombuf[0].partno = "Part #";
	bombuf[0].description = "Description";
	construct_bom();
	if (tabbed)
		tabbed_output();
	else {
		compute_col_widths();
		output();
	}
	exit(0);
}

construct_bom()
{
	int c, i;
	register struct component *comp, *part;
	register char *attr;

	for (comp = components, c = 0, i = 1; c < ncomponents; comp++, c++) {
		if (!check_component_popopt(comp))
			continue;
		attr = get_comp_attr(comp, "part");
		if (attr && !strcmp(attr, "none"))
			continue;
		bombuf[i].refdes = comp->name;
		if (assembly && (attr = get_comp_attr(comp, "socket"))) {
			part = find_partdef_by_name(attr);
			if (!part) {
				fprintf(stderr,
					"%s: socket part %s not found\n",
					comp->name, attr);
				continue;
			}
		} else
			part = comp;
		attr = get_comp_attr(part, "manufacturer");
		if (attr)
			bombuf[i].manuf = attr;
		else
			bombuf[i].manuf = unknownstr;
		if (attr = get_comp_attr(part, "manufacturer_part_number"))
			bombuf[i].partno = attr;
		else if (attr = get_comp_attr(part, "device"))
			bombuf[i].partno = attr;
		else
			bombuf[i].partno = unknownstr;
		bombuf[i].description = get_comp_attr(part, "description");
		i++;
	}
	nbomlines = i;
}

compute_col_widths()
{
	int c;
	register int i;
	register struct bomline *line;

	for (line = bombuf, c = 0; c < nbomlines; line++, c++) {
		i = strlen(line->refdes);
		if (i > refdes_col_width)
			refdes_col_width = i;
		i = strlen(line->manuf);
		if (i > manuf_col_width)
			manuf_col_width = i;
		i = strlen(line->partno);
		if (i > partno_col_width)
			partno_col_width = i;
	}
}

output()
{
	int c;
	register int i;
	register struct bomline *line;

	for (line = bombuf, c = 0; c < nbomlines; line++, c++) {
		fputs(line->refdes, stdout);
		i = refdes_col_width + column_sep_width - strlen(line->refdes);
		while (i--)
			putchar(' ');
		fputs(line->manuf, stdout);
		i = manuf_col_width + column_sep_width - strlen(line->manuf);
		while (i--)
			putchar(' ');
		fputs(line->partno, stdout);
		if (line->description) {
			i = partno_col_width + column_sep_width -
				strlen(line->partno);
			while (i--)
				putchar(' ');
			fputs(line->description, stdout);
		}
		putchar('\n');
	}
}

tabbed_output()
{
	int c;
	register struct bomline *line;

	for (line = bombuf+1, c = 1; c < nbomlines; line++, c++) {
		printf("%s\t%s\t%s", line->refdes, line->manuf, line->partno);
		if (line->description)
			printf("\t%s", line->description);
		putchar('\n');
	}
}