FreeCalypso > hg > ueda-linux
comparison 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 |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:cd92449fdb51 |
|---|---|
| 1 /* | |
| 2 * This program generates a procurement-oriented BOM from the MCL. | |
| 3 */ | |
| 4 | |
| 5 #include <stdio.h> | |
| 6 #include <strings.h> | |
| 7 #include "../libueda/mcl.h" | |
| 8 | |
| 9 extern char *optarg; | |
| 10 extern char *malloc(); | |
| 11 | |
| 12 extern char *MCLfile; | |
| 13 extern struct component components[]; | |
| 14 extern int ncomponents; | |
| 15 extern char *get_comp_attr(), *get_comp_multiattr(); | |
| 16 extern struct component *find_partdef_by_name(); | |
| 17 | |
| 18 struct refdeslist { | |
| 19 char *refdes; | |
| 20 struct refdeslist *next; | |
| 21 }; | |
| 22 | |
| 23 struct bompart { | |
| 24 struct component *part; | |
| 25 int qty; | |
| 26 struct bompart *next; | |
| 27 struct refdeslist *refdeslist; | |
| 28 }; | |
| 29 | |
| 30 int check_completeness, refdes_lists; | |
| 31 struct bompart *bomhead; | |
| 32 | |
| 33 do_cmdline_opts(argc, argv) | |
| 34 char **argv; | |
| 35 { | |
| 36 register int c; | |
| 37 | |
| 38 while ((c = getopt(argc, argv, "cM:p:r")) != EOF) | |
| 39 switch (c) { | |
| 40 case 'c': | |
| 41 check_completeness++; | |
| 42 break; | |
| 43 case 'M': | |
| 44 MCLfile = optarg; | |
| 45 break; | |
| 46 case 'p': | |
| 47 set_popopt_list(optarg); | |
| 48 break; | |
| 49 case 'r': | |
| 50 refdes_lists++; | |
| 51 break; | |
| 52 default: | |
| 53 /* getopt prints the error message */ | |
| 54 exit(1); | |
| 55 } | |
| 56 } | |
| 57 | |
| 58 main(argc, argv) | |
| 59 char **argv; | |
| 60 { | |
| 61 do_cmdline_opts(argc, argv); | |
| 62 read_MCL(); | |
| 63 tally_parts(); | |
| 64 output(); | |
| 65 exit(0); | |
| 66 } | |
| 67 | |
| 68 tally_parts() | |
| 69 { | |
| 70 int c; | |
| 71 register struct component *comp; | |
| 72 register char *attr; | |
| 73 struct component *socket; | |
| 74 | |
| 75 for (comp = components, c = 0; c < ncomponents; comp++, c++) { | |
| 76 if (!check_component_popopt(comp)) | |
| 77 continue; | |
| 78 if (comp->partdef == NULL) { | |
| 79 attr = get_comp_attr(comp, "part"); | |
| 80 if (attr && !strcmp(attr, "none")) | |
| 81 continue; | |
| 82 if (check_completeness) | |
| 83 fprintf(stderr, "%s has no part defined\n", | |
| 84 comp->name); | |
| 85 continue; | |
| 86 } | |
| 87 add_part_to_bom(comp->partdef, comp->name); | |
| 88 attr = get_comp_attr(comp, "socket"); | |
| 89 if (attr) { | |
| 90 socket = find_partdef_by_name(attr); | |
| 91 if (socket) | |
| 92 add_part_to_bom(socket, comp->name); | |
| 93 else | |
| 94 fprintf(stderr, | |
| 95 "%s: socket part %s not found\n", | |
| 96 comp->name, attr); | |
| 97 } | |
| 98 } | |
| 99 } | |
| 100 | |
| 101 add_part_to_bom(part, refdes) | |
| 102 struct component *part; | |
| 103 char *refdes; | |
| 104 { | |
| 105 register struct bompart *bp, **bpp; | |
| 106 | |
| 107 for (bpp = &bomhead; bp = *bpp; bpp = &bp->next) | |
| 108 if (bp->part == part) { | |
| 109 bp->qty++; | |
| 110 add_refdes_to_bompart(bp, refdes); | |
| 111 return; | |
| 112 } | |
| 113 /* new part */ | |
| 114 bp = (struct bompart *) malloc(sizeof(struct bompart)); | |
| 115 if (bp == NULL) { | |
| 116 perror("malloc"); | |
| 117 exit(1); | |
| 118 } | |
| 119 bp->part = part; | |
| 120 bp->qty = 1; | |
| 121 bp->next = NULL; | |
| 122 bp->refdeslist = NULL; | |
| 123 *bpp = bp; | |
| 124 add_refdes_to_bompart(bp, refdes); | |
| 125 } | |
| 126 | |
| 127 add_refdes_to_bompart(bp, refdes) | |
| 128 struct bompart *bp; | |
| 129 char *refdes; | |
| 130 { | |
| 131 register struct refdeslist *le, **lep; | |
| 132 | |
| 133 if (!refdes_lists) | |
| 134 return; | |
| 135 for (lep = &bp->refdeslist; le = *lep; lep = &le->next) | |
| 136 ; | |
| 137 le = (struct refdeslist *) malloc(sizeof(struct refdeslist)); | |
| 138 if (!le) { | |
| 139 perror("malloc"); | |
| 140 exit(1); | |
| 141 } | |
| 142 le->refdes = refdes; | |
| 143 le->next = NULL; | |
| 144 *lep = le; | |
| 145 } | |
| 146 | |
| 147 output() | |
| 148 { | |
| 149 register int i; | |
| 150 register struct component *part; | |
| 151 register struct bompart *bp; | |
| 152 char *manuf, *partno, *desc, *spectitle; | |
| 153 | |
| 154 printf("Part\t\t\t\t\t\t\t\t\t Qty\n"); | |
| 155 for (i = 0; i < 79; i++) | |
| 156 putchar('-'); | |
| 157 putchar('\n'); | |
| 158 | |
| 159 for (bp = bomhead; bp; bp = bp->next) { | |
| 160 part = bp->part; | |
| 161 manuf = get_comp_attr(part, "manufacturer"); | |
| 162 partno = get_comp_attr(part, "manufacturer_part_number"); | |
| 163 if (!partno) | |
| 164 partno = get_comp_attr(part, "device"); | |
| 165 desc = get_comp_attr(part, "description"); | |
| 166 spectitle = get_comp_attr(part, "bom_part_title"); | |
| 167 if (spectitle) { | |
| 168 fputs(spectitle, stdout); | |
| 169 i = strlen(spectitle); | |
| 170 } else if (manuf && partno) | |
| 171 i = printf("%s %s", manuf, partno); | |
| 172 else if (desc) { | |
| 173 fputs(desc, stdout); | |
| 174 i = strlen(desc); | |
| 175 desc = NULL; /* used it */ | |
| 176 } else { | |
| 177 fprintf(stderr, | |
| 178 "part %s: no identifying information for the BOM\n", | |
| 179 part->name); | |
| 180 continue; | |
| 181 } | |
| 182 for (i /= 8; i < 9; i++) | |
| 183 putchar('\t'); | |
| 184 printf("%7d\n", bp->qty); | |
| 185 if (desc) | |
| 186 printf(" %s\n", desc); | |
| 187 do_comments(part); | |
| 188 do_sources(part); | |
| 189 do_substitutes(part); | |
| 190 if (refdes_lists) | |
| 191 dump_refdes_list(bp->refdeslist); | |
| 192 } | |
| 193 } | |
| 194 | |
| 195 do_sources(part) | |
| 196 register struct component *part; | |
| 197 { | |
| 198 int scnt; | |
| 199 register char *src; | |
| 200 char *vendor, *vpn; | |
| 201 | |
| 202 for (scnt = 0; src = get_comp_multiattr(part, "source", &scnt); ) | |
| 203 printf(" Source: %s\n", src); | |
| 204 if (scnt) | |
| 205 return; | |
| 206 /* no source= attributes, check for the old style vendor ones */ | |
| 207 vendor = get_comp_attr(part, "vendor"); | |
| 208 vpn = get_comp_attr(part, "vendor_part_number"); | |
| 209 if (vendor && vpn) | |
| 210 printf(" Source: %s %s\n", vendor, vpn); | |
| 211 else if (vendor) | |
| 212 printf(" Source: %s\n", vendor); | |
| 213 } | |
| 214 | |
| 215 do_substitutes(part) | |
| 216 register struct component *part; | |
| 217 { | |
| 218 int scnt; | |
| 219 register char *s; | |
| 220 | |
| 221 for (scnt = 0; s = get_comp_multiattr(part, "substitute", &scnt); ) | |
| 222 printf(" Acceptable substitute: %s\n", s); | |
| 223 } | |
| 224 | |
| 225 do_comments(part) | |
| 226 register struct component *part; | |
| 227 { | |
| 228 int scnt; | |
| 229 register char *s; | |
| 230 | |
| 231 for (scnt = 0; s = get_comp_multiattr(part, "bom_comment", &scnt); ) | |
| 232 printf(" %s\n", s); | |
| 233 } | |
| 234 | |
| 235 dump_refdes_list(le) | |
| 236 register struct refdeslist *le; | |
| 237 { | |
| 238 register int acc, i; | |
| 239 | |
| 240 for (acc = 0; le; le = le->next) { | |
| 241 i = strlen(le->refdes) + 1; | |
| 242 if (le->next) | |
| 243 i++; | |
| 244 if (acc && (acc + i >= 80)) { | |
| 245 putchar('\n'); | |
| 246 acc = 0; | |
| 247 } | |
| 248 if (!acc) { | |
| 249 putchar(' '); | |
| 250 acc++; | |
| 251 } | |
| 252 printf(" %s", le->refdes); | |
| 253 if (le->next) | |
| 254 putchar(','); | |
| 255 acc += i; | |
| 256 } | |
| 257 if (acc) | |
| 258 putchar('\n'); | |
| 259 } |
