diff ueda/mclutils/mkbom.c @ 0:cd92449fdb51

initial import of ueda and ifctf-part-lib from ifctfvax CVS
author Space Falcon <falcon@ivan.Harhan.ORG>
date Mon, 20 Jul 2015 00:24:37 +0000
parents
children d098f8548b44
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ueda/mclutils/mkbom.c	Mon Jul 20 00:24:37 2015 +0000
@@ -0,0 +1,259 @@
+/*
+ * This program generates a procurement-oriented BOM from the MCL.
+ */
+
+#include <stdio.h>
+#include <strings.h>
+#include "../libueda/mcl.h"
+
+extern char *optarg;
+extern char *malloc();
+
+extern char *MCLfile;
+extern struct component components[];
+extern int ncomponents;
+extern char *get_comp_attr(), *get_comp_multiattr();
+extern struct component *find_partdef_by_name();
+
+struct refdeslist {
+	char	*refdes;
+	struct	refdeslist *next;
+};
+
+struct bompart {
+	struct	component *part;
+	int	qty;
+	struct	bompart *next;
+	struct	refdeslist *refdeslist;
+};
+
+int check_completeness, refdes_lists;
+struct bompart *bomhead;
+
+do_cmdline_opts(argc, argv)
+	char **argv;
+{
+	register int c;
+
+	while ((c = getopt(argc, argv, "cM:p:r")) != EOF)
+		switch (c) {
+		case 'c':
+			check_completeness++;
+			break;
+		case 'M':
+			MCLfile = optarg;
+			break;
+		case 'p':
+			set_popopt_list(optarg);
+			break;
+		case 'r':
+			refdes_lists++;
+			break;
+		default:
+			/* getopt prints the error message */
+			exit(1);
+		}
+}
+
+main(argc, argv)
+	char **argv;
+{
+	do_cmdline_opts(argc, argv);
+	read_MCL();
+	tally_parts();
+	output();
+	exit(0);
+}
+
+tally_parts()
+{
+	int c;
+	register struct component *comp;
+	register char *attr;
+	struct component *socket;
+
+	for (comp = components, c = 0; c < ncomponents; comp++, c++) {
+		if (!check_component_popopt(comp))
+			continue;
+		if (comp->partdef == NULL) {
+			attr = get_comp_attr(comp, "part");
+			if (attr && !strcmp(attr, "none"))
+				continue;
+			if (check_completeness)
+				fprintf(stderr, "%s has no part defined\n",
+					comp->name);
+			continue;
+		}
+		add_part_to_bom(comp->partdef, comp->name);
+		attr = get_comp_attr(comp, "socket");
+		if (attr) {
+			socket = find_partdef_by_name(attr);
+			if (socket)
+				add_part_to_bom(socket, comp->name);
+			else
+				fprintf(stderr,
+					"%s: socket part %s not found\n",
+					comp->name, attr);
+		}
+	}
+}
+
+add_part_to_bom(part, refdes)
+	struct component *part;
+	char *refdes;
+{
+	register struct bompart *bp, **bpp;
+
+	for (bpp = &bomhead; bp = *bpp; bpp = &bp->next)
+		if (bp->part == part) {
+			bp->qty++;
+			add_refdes_to_bompart(bp, refdes);
+			return;
+		}
+	/* new part */
+	bp = (struct bompart *) malloc(sizeof(struct bompart));
+	if (bp == NULL) {
+		perror("malloc");
+		exit(1);
+	}
+	bp->part = part;
+	bp->qty = 1;
+	bp->next = NULL;
+	bp->refdeslist = NULL;
+	*bpp = bp;
+	add_refdes_to_bompart(bp, refdes);
+}
+
+add_refdes_to_bompart(bp, refdes)
+	struct bompart *bp;
+	char *refdes;
+{
+	register struct refdeslist *le, **lep;
+
+	if (!refdes_lists)
+		return;
+	for (lep = &bp->refdeslist; le = *lep; lep = &le->next)
+		;
+	le = (struct refdeslist *) malloc(sizeof(struct refdeslist));
+	if (!le) {
+		perror("malloc");
+		exit(1);
+	}
+	le->refdes = refdes;
+	le->next = NULL;
+	*lep = le;
+}
+
+output()
+{
+	register int i;
+	register struct component *part;
+	register struct bompart *bp;
+	char *manuf, *partno, *desc, *spectitle;
+
+	printf("Part\t\t\t\t\t\t\t\t\t    Qty\n");
+	for (i = 0; i < 79; i++)
+		putchar('-');
+	putchar('\n');
+
+	for (bp = bomhead; bp; bp = bp->next) {
+		part = bp->part;
+		manuf = get_comp_attr(part, "manufacturer");
+		partno = get_comp_attr(part, "manufacturer_part_number");
+		if (!partno)
+			partno = get_comp_attr(part, "device");
+		desc = get_comp_attr(part, "description");
+		spectitle = get_comp_attr(part, "bom_part_title");
+		if (spectitle) {
+			fputs(spectitle, stdout);
+			i = strlen(spectitle);
+		} else if (manuf && partno)
+			i = printf("%s %s", manuf, partno);
+		else if (desc) {
+			fputs(desc, stdout);
+			i = strlen(desc);
+			desc = NULL;		/* used it */
+		} else {
+			fprintf(stderr,
+			"part %s: no identifying information for the BOM\n",
+				part->name);
+			continue;
+		}
+		for (i /= 8; i < 9; i++)
+			putchar('\t');
+		printf("%7d\n", bp->qty);
+		if (desc)
+			printf("  %s\n", desc);
+		do_comments(part);
+		do_sources(part);
+		do_substitutes(part);
+		if (refdes_lists)
+			dump_refdes_list(bp->refdeslist);
+	}
+}
+
+do_sources(part)
+	register struct component *part;
+{
+	int scnt;
+	register char *src;
+	char *vendor, *vpn;
+
+	for (scnt = 0; src = get_comp_multiattr(part, "source", &scnt); )
+		printf("  Source: %s\n", src);
+	if (scnt)
+		return;
+	/* no source= attributes, check for the old style vendor ones */
+	vendor = get_comp_attr(part, "vendor");
+	vpn = get_comp_attr(part, "vendor_part_number");
+	if (vendor && vpn)
+		printf("  Source: %s %s\n", vendor, vpn);
+	else if (vendor)
+		printf("  Source: %s\n", vendor);
+}
+
+do_substitutes(part)
+	register struct component *part;
+{
+	int scnt;
+	register char *s;
+
+	for (scnt = 0; s = get_comp_multiattr(part, "substitute", &scnt); )
+		printf("  Acceptable substitute: %s\n", s);
+}
+
+do_comments(part)
+	register struct component *part;
+{
+	int scnt;
+	register char *s;
+
+	for (scnt = 0; s = get_comp_multiattr(part, "bom_comment", &scnt); )
+		printf("  %s\n", s);
+}
+
+dump_refdes_list(le)
+	register struct refdeslist *le;
+{
+	register int acc, i;
+
+	for (acc = 0; le; le = le->next) {
+		i = strlen(le->refdes) + 1;
+		if (le->next)
+			i++;
+		if (acc && (acc + i >= 80)) {
+			putchar('\n');
+			acc = 0;
+		}
+		if (!acc) {
+			putchar(' ');
+			acc++;
+		}
+		printf(" %s", le->refdes);
+		if (le->next)
+			putchar(',');
+		acc += i;
+	}
+	if (acc)
+		putchar('\n');
+}