3 # Convert CSV parts list into vendor import format
5 # Copyright © 2015 Keith Packard <keithp@keithp.com>, GPL v3+
11 string[*] not_vendors;
12 string not_vendor_list;
19 void fatal(string format, poly args ...)
21 File::fprintf(stderr, format, args...);
25 string[*] read_line(file f) {
27 string line = fgets(f);
29 string[*] elts = String::parse_csv(line);
30 for (int i = 0; i < dim(elts); i++)
31 if (String::length(elts[i]) > 0 && elts[i][0] == '"')
32 elts[i] = String::dequote(elts[i]);
38 string[*] required_elements = {
49 bool has_header_member(string member) {
50 for (int i = 0; i < dim(header); i++)
51 if (header[i] == member)
56 bool has_vendor(string[*] vendors, string vendor) {
57 for (int i = 0; i < dim(vendors); i++)
58 if (vendors[i] == vendor)
63 void read_header(file f) {
64 header = read_line(f);
66 for (int i = 0; i < dim(required_elements); i++)
67 if (!has_header_member(required_elements[i]))
68 fatal("Missing header element \"%s\"\n", required_elements[i]);
71 string[string] read_entry(file f) {
72 string[*] elements = read_line(f);
73 string[string] entry = {};
75 if (dim(header) != dim(elements))
76 fatal("line %d: has %d instead of %d elements (%V)\n",
77 lineno, dim(elements), dim(header), elements);
79 for (int i = 0; i < dim(header); i++) {
80 if (elements[i] == "")
81 elements[i] = "unknown";
82 entry[header[i]] = elements[i];
87 string part_number(string[string] entry)
90 return entry["mfg_part_number"];
92 return entry["vendor_part_number"];
95 string quoted(string v)
97 if (String::index(v, "\"") >= 0 || String::index(v, ",") >= 0) {
98 if (String::index(v, "\"") >= 0) {
100 for (int i = 0; i < String::length(v); i++) {
103 ret = ret + String::new(v[i]);
108 return "\"" + v + "\"";
115 void process_seeed(string[string] entry)
117 if (entry["loadstatus"] == "noload")
120 static bool start = true;
122 printf("Part/Designator,Manufacturer Part Number/Seeed SKU, Quantity\n");
126 string[*] refdes = String::wordsplit(entry["refdes"], " \t");
129 for (int i = 0; i < dim(refdes); i++) {
130 printf("%s", refdes[i]);
131 if (i < dim(refdes) - 1)
136 printf(",%s,%s\n", quoted(entry["mfg_part_number"]), entry["quantity"]);
139 void process_goldphoenix(string[string] entry)
143 if (entry["loadstatus"] == "noload")
147 static bool start = true;
149 printf("#Item,Description,Designator,Package,Manufacturer,Manufacturer Part Number#,Supplier,Supplier Part #,QTY/BOARD,Order QTY,Unit Price, Subtotal \n");
153 string[*] refdes = String::wordsplit(entry["refdes"], " \t");
158 quoted(entry["device"]),
159 quoted(entry["value"]));
164 for (int i = 0; i < dim(refdes); i++) {
165 printf("%s", refdes[i]);
166 if (i < dim(refdes) - 1)
173 printf(",%s,%s,%s,%s,%s,%s,%d\n",
174 quoted(entry["footprint"]),
175 quoted(entry["mfg"]),
176 quoted(entry["mfg_part_number"]),
177 quoted(entry["vendor"]),
178 quoted(entry["vendor_part_number"]),
180 dim(refdes) * units);
184 void process_digikey(string[string] entry)
186 if (entry["loadstatus"] == "noload")
188 printf("%s,%s,%s %s\n",
190 quoted(part_number(entry)),
191 quoted(entry["device"]),
192 quoted(entry["value"]));
195 void process_mouser(string[string] entry)
197 if (entry["loadstatus"] == "noload")
199 /* printf("%s|%s\n", part_number(entry), entry["quantity"]); */
201 static bool start = true;
204 printf("Mouser Part Number,Manufacturer Part Number,Quantity\n");
209 quoted(entry["vendor_part_number"]),
210 quoted(entry["mfg_part_number"]),
214 void process_other(string[string] entry) {
215 if (entry["loadstatus"] == "noload")
217 printf("%s,%s,%s,%s %s\n",
220 quoted(part_number(entry)),
221 quoted(entry["device"]),
225 void process_file(file f) {
227 while (!File::end(f)) {
228 string[string] entry = read_entry(f);
229 string vendor = entry["vendor"];
230 if (!is_uninit(&vendors) && has_vendor(vendors, "seeed")) {
231 process_seeed(entry);
232 } else if (!is_uninit(&vendors) && has_vendor(vendors, "goldphoenix")) {
233 process_goldphoenix(entry);
234 } else if ((!is_uninit(&vendors) && has_vendor(vendors, vendor)) ||
235 (!is_uninit(¬_vendors) && !has_vendor(not_vendors, vendor))) {
236 switch (entry["vendor"]) {
238 process_digikey(entry);
241 process_mouser(entry);
244 process_other(entry);
251 ParseArgs::argdesc argd = {
253 { .var = { .arg_flag = &mfg_part },
256 .desc = "Display manufacturer part number"},
257 { .var = { .arg_string = &vendor_list },
260 .expr_name = "vendors",
261 .desc = "Vendors to match"},
262 { .var = { .arg_string = ¬_vendor_list },
264 .name = "not-vendor",
265 .expr_name = "not-vendor",
266 .desc = "Vendors to exclude"},
272 ParseArgs::parseargs(&argd, &argv);
273 if (!is_uninit(&vendor_list))
274 vendors = String::parse_csv(vendor_list);
276 if (!is_uninit(¬_vendor_list))
277 not_vendors = String::parse_csv(not_vendor_list);
279 if (!is_uninit(&argi)) {
280 for (int i = argi; i < dim(argv); i++)
281 twixt(file f = File::open(argv[i], "r"); File::close(f))