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 return String::parse_csv(line);
34 string[*] required_elements = {
45 bool has_header_member(string member) {
46 for (int i = 0; i < dim(header); i++)
47 if (header[i] == member)
52 bool has_vendor(string[*] vendors, string vendor) {
53 for (int i = 0; i < dim(vendors); i++)
54 if (vendors[i] == vendor)
59 void read_header(file f) {
60 header = read_line(f);
62 for (int i = 0; i < dim(required_elements); i++)
63 if (!has_header_member(required_elements[i]))
64 fatal("Missing header element \"%s\"\n", required_elements[i]);
67 string[string] read_entry(file f) {
68 string[*] elements = read_line(f);
69 string[string] entry = {};
71 if (dim(header) != dim(elements))
72 fatal("line %d: has %d instead of %d elements (%V)\n",
73 lineno, dim(elements), dim(header), elements);
75 for (int i = 0; i < dim(header); i++) {
76 if (elements[i] == "")
77 elements[i] = "unknown";
78 entry[header[i]] = elements[i];
83 string part_number(string[string] entry)
86 return entry["mfg_part_number"];
88 return entry["vendor_part_number"];
91 string quoted(string v)
93 if (String::index(v, "\"") >= 0 || String::index(v, ",") >= 0) {
94 if (String::index(v, "\"") >= 0) {
96 for (int i = 0; i < String::length(v); i++) {
99 ret = ret + String::new(v[i]);
104 return "\"" + v + "\"";
111 void process_seeed(string[string] entry)
113 if (entry["loadstatus"] == "noload")
116 static bool start = true;
118 printf("Part/Designator,Manufacturer Part Number/Seeed SKU, Quantity\n");
122 string[*] refdes = String::wordsplit(entry["refdes"], " \t");
125 for (int i = 0; i < dim(refdes); i++) {
126 printf("%s", refdes[i]);
127 if (i < dim(refdes) - 1)
132 printf(",%s,%s\n", quoted(entry["mfg_part_number"]), entry["quantity"]);
135 void process_digikey(string[string] entry)
137 if (entry["loadstatus"] == "noload")
139 printf("%s,%s,%s %s\n",
141 quoted(part_number(entry)),
142 quoted(entry["device"]),
143 quoted(entry["value"]));
146 void process_mouser(string[string] entry)
148 if (entry["loadstatus"] == "noload")
150 /* printf("%s|%s\n", part_number(entry), entry["quantity"]); */
152 static bool start = true;
155 printf("Mouser Part Number,Manufacturer Part Number,Quantity 1\n");
160 quoted(entry["vendor_part_number"]),
161 quoted(entry["mfg_part_number"]),
165 void process_other(string[string] entry) {
166 if (entry["loadstatus"] == "noload")
168 printf("%s,%s,%s,%s %s\n",
171 quoted(part_number(entry)),
172 quoted(entry["device"]),
176 void process_file(file f) {
178 while (!File::end(f)) {
179 string[string] entry = read_entry(f);
180 string vendor = entry["vendor"];
181 if (!is_uninit(&vendors) && has_vendor(vendors, "seeed")) {
182 process_seeed(entry);
183 } else if ((!is_uninit(&vendors) && has_vendor(vendors, vendor)) ||
184 (!is_uninit(¬_vendors) && !has_vendor(not_vendors, vendor))) {
185 switch (entry["vendor"]) {
187 process_digikey(entry);
190 process_mouser(entry);
193 process_other(entry);
200 ParseArgs::argdesc argd = {
202 { .var = { .arg_flag = &mfg_part },
205 .desc = "Display manufacturer part number"},
206 { .var = { .arg_string = &vendor_list },
209 .expr_name = "vendors",
210 .desc = "Vendors to match"},
211 { .var = { .arg_string = ¬_vendor_list },
213 .name = "not-vendor",
214 .expr_name = "not-vendor",
215 .desc = "Vendors to exclude"},
221 ParseArgs::parseargs(&argd, &argv);
222 if (!is_uninit(&vendor_list))
223 vendors = String::parse_csv(vendor_list);
225 if (!is_uninit(¬_vendor_list))
226 not_vendors = String::parse_csv(not_vendor_list);
228 if (!is_uninit(&argi)) {
229 for (int i = argi; i < dim(argv); i++)
230 twixt(file f = File::open(argv[i], "r"); File::close(f))