FreeCalypso > hg > ueda-linux
view ueda/mclutils/mkbom.c @ 81:6e43956e740d
beginning of BOM utils refactoring: seqrefdes code factored out
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 23 Feb 2017 19:15:48 +0000 |
parents | df98a82b807e |
children | 20c6f84c75e7 |
line wrap: on
line source
/* * This program generates a procurement-oriented 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(), *get_comp_multiattr(); extern struct component *find_partdef_by_name(); struct refdeslist { char *first; char *last; 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; if (!bp->refdeslist) { lep = &bp->refdeslist; goto add_new; } for (le = bp->refdeslist; le->next; le = le->next) ; if (is_refdes_sequential(le->last, refdes)) { le->last = refdes; return(1); } lep = &le->next; add_new: le = (struct refdeslist *) malloc(sizeof(struct refdeslist)); if (!le) { perror("malloc"); exit(1); } le->first = refdes; le->last = refdes; le->next = NULL; *lep = le; return(0); } 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->first) + 1; if (le->last != le->first) i += strlen(le->last) + 1; if (le->next) i++; if (acc && (acc + i >= 80)) { putchar('\n'); acc = 0; } if (!acc) { putchar(' '); acc++; } printf(" %s", le->first); if (le->last != le->first) printf("-%s", le->last); if (le->next) putchar(','); acc += i; } if (acc) putchar('\n'); }