string input_name;
string output_name;
string program;
+file output = stdout;
int argi;
int lineno = 0;
+bool saw_error = false;
void fatal(string format, poly args ...)
{
exit(1);
}
+void error(string format, poly args ...)
+{
+ File::fprintf(stderr, format, args...);
+ saw_error = true;
+}
+
string[*] read_line(file f) {
lineno++;
string line = fgets(f);
static bool start = true;
if (start) {
- printf("Part/Designator,Manufacturer Part Number/Seeed SKU, Quantity\n");
+ File::fprintf (output, "Part/Designator,Manufacturer Part Number/Seeed SKU, Quantity\n");
start = false;
}
string[*] refdes = String::wordsplit(entry["refdes"], " \t");
if (dim(refdes) > 1)
- printf ("\"");
+ File::fprintf (output, "\"");
for (int i = 0; i < dim(refdes); i++) {
- printf("%s", refdes[i]);
+ File::fprintf (output, "%s", refdes[i]);
if (i < dim(refdes) - 1)
- printf (",");
+ File::fprintf (output, ",");
}
if (dim(refdes) > 1)
- printf ("\"");
- printf(",%s,%s\n", quoted(part_number), entry["quantity"]);
+ File::fprintf (output, "\"");
+ File::fprintf (output, ",%s,%s\n", quoted(part_number), entry["quantity"]);
}
void process_goldphoenix(string[string] entry)
static int item = 1;
static bool start = true;
if (start) {
- printf("#Item,Description,Designator,Package,Manufacturer,Manufacturer Part Number#,Supplier,Supplier Part #,QTY/BOARD,Order QTY,Unit Price, Subtotal \n");
+ File::fprintf (output, "#Item,Description,Designator,Package,Manufacturer,Manufacturer Part Number#,Supplier,Supplier Part #,QTY/BOARD,Order QTY,Unit Price, Subtotal \n");
start = false;
}
string[*] refdes = String::wordsplit(entry["refdes"], " \t");
- printf("%d,", item);
+ File::fprintf (output, "%d,", item);
/* description */
- printf("%s %s,",
+ File::fprintf (output, "%s %s,",
quoted(entry["device"]),
quoted(entry["value"]));
/* designators */
if (dim(refdes) > 1)
- printf ("\"");
+ File::fprintf (output, "\"");
for (int i = 0; i < dim(refdes); i++) {
- printf("%s", refdes[i]);
+ File::fprintf (output, "%s", refdes[i]);
if (i < dim(refdes) - 1)
- printf (",");
+ File::fprintf (output, ",");
}
if (dim(refdes) > 1)
- printf ("\"");
+ File::fprintf (output, "\"");
/* rest */
- printf(",%s,%s,%s,%s,%s,%s,%d\n",
+ File::fprintf (output, ",%s,%s,%s,%s,%s,%s,%d\n",
quoted(entry["footprint"]),
quoted(entry["mfg"]),
quoted(entry["mfg_part_number"]),
item++;
}
+void process_jlcpcb(string[string] entry)
+{
+ if (entry["loadstatus"] == "noload") {
+ File::fprintf(stderr, "skipping part %v\n", entry);
+ return;
+ }
+ string part_number;
+ if (hash_test(entry, "jlcpcb_part_number")) {
+ part_number = entry["jlcpcb_part_number"];
+ } else {
+ error("Component (%s, %s, %s) has no JLCPCB Part #\n",
+ entry["device"], entry["value"], entry["footprint"]);
+ part_number = "unknown";
+ }
+
+ static bool start = true;
+ if (start) {
+ File::fprintf (output, "Comment,Designator,Footprint,JLCPCB Part #\n");
+ start = false;
+ }
+
+ File::fprintf (output, "%s,", quoted(entry["value"]));
+ string[*] refdes = String::wordsplit(entry["refdes"], " \t");
+ for (int i = 0; i < dim(refdes); i++) {
+ File::fprintf (output, "%s", quoted(refdes[i]));
+ if (i < dim(refdes) - 1)
+ File::fprintf (output, " ");
+ }
+ File::fprintf (output, "%s,%s\n", quoted(entry["footprint"]), quoted(part_number));
+}
+
void process_digikey(string[string] entry)
{
if (entry["loadstatus"] == "noload")
return;
- printf("%s,%s,%s %s\n",
+ File::fprintf (output, "%s,%s,%s %s\n",
entry["quantity"],
quoted(part_number(entry)),
quoted(entry["device"]),
{
if (entry["loadstatus"] == "noload")
return;
-/* printf("%s|%s\n", part_number(entry), entry["quantity"]); */
+/* File::fprintf (output, "%s|%s\n", part_number(entry), entry["quantity"]); */
static bool start = true;
if (start) {
- printf("Mouser Part Number,Manufacturer Part Number,Quantity\n");
+ File::fprintf (output, "Mouser Part Number,Manufacturer Part Number,Quantity\n");
start = false;
}
- printf("%s,%s,%s\n",
+ File::fprintf (output, "%s,%s,%s\n",
quoted(entry["vendor_part_number"]),
quoted(entry["mfg_part_number"]),
entry["quantity"]);
void process_other(string[string] entry) {
if (entry["loadstatus"] == "noload")
return;
- printf("%s,%s,%s,%s %s\n",
+ File::fprintf (output, "%s,%s,%s,%s %s\n",
entry["vendor"],
entry["quantity"],
quoted(part_number(entry)),
process_seeed(entry);
} else if (!is_uninit(&vendors) && has_vendor(vendors, "goldphoenix")) {
process_goldphoenix(entry);
+ } else if (!is_uninit(&vendors) && has_vendor(vendors, "jlcpcb")) {
+ process_jlcpcb(entry);
} else if ((!is_uninit(&vendors) && has_vendor(vendors, vendor)) ||
(!is_uninit(¬_vendors) && !has_vendor(not_vendors, vendor))) {
switch (entry["vendor"]) {
.name = "not-vendor",
.expr_name = "not-vendor",
.desc = "Vendors to exclude"},
+ { .var = { .arg_string = &output_name },
+ .abbr = 'o',
+ .name = "output",
+ .expr_name = "output",
+ .desc = "Output file name"},
},
.unknown = &argi,
};
+void cleanup(int status) {
+ if (status != 0 && !is_uninit(&output_name))
+ File::unlink(output_name);
+}
+
void main() {
+ int status = 1;
ParseArgs::parseargs(&argd, &argv);
if (!is_uninit(&vendor_list))
vendors = String::parse_csv(vendor_list);
if (!is_uninit(¬_vendor_list))
not_vendors = String::parse_csv(not_vendor_list);
- if (!is_uninit(&argi)) {
- for (int i = argi; i < dim(argv); i++)
- twixt(file f = File::open(argv[i], "r"); File::close(f))
- process_file(f);
- } else
- process_file(stdin);
+ if (!is_uninit(&output_name))
+ output = File::open(output_name, "w");
+
+ twixt(; cleanup(status)) {
+ if (!is_uninit(&argi)) {
+ for (int i = argi; i < dim(argv); i++)
+ twixt(file f = File::open(argv[i], "r"); File::close(f))
+ process_file(f);
+ } else
+ process_file(stdin);
+ if (!saw_error)
+ status = 0;
+ }
+ exit(status);
}
main();
$(AM)/bin/fillpartscsv.py $(PROJECT)-parts.csv --output $@ --preferred preferred-parts.csv
partslist-dk.csv: partslist.csv
- $(AM)/bin/partslist-vendor --vendor digikey partslist.csv > $@
+ $(AM)/bin/partslist-vendor --vendor digikey -o $@ partslist.csv
partslist-check.dk: partslist.csv
- $(AM)/bin/partslist-vendor --vendor digikey --mfg partslist.csv > $@
+ $(AM)/bin/partslist-vendor --vendor digikey -o $@ --mfg partslist.csv
partslist-mouser.csv: partslist.csv
- $(AM)/bin/partslist-vendor --vendor mouser partslist.csv > $@
+ $(AM)/bin/partslist-vendor --vendor mouser -o $@ partslist.csv
partslist-other.csv: partslist.csv
- $(AM)/bin/partslist-vendor --not-vendor digikey,mouser partslist.csv > $@
+ $(AM)/bin/partslist-vendor --not-vendor digikey,mouser -o $@ partslist.csv
$(PROJECT)-seeed.csv: partslist.csv
- $(AM)/bin/partslist-vendor --vendor seeed partslist.csv > $@
+ $(AM)/bin/partslist-vendor --vendor seeed -o $@ partslist.csv
$(PROJECT)-goldphoenix.csv: partslist.csv
- $(AM)/bin/partslist-vendor --vendor goldphoenix partslist.csv > $@
+ $(AM)/bin/partslist-vendor --vendor goldphoenix -o $@ partslist.csv
+
+$(PROJECT)-jlcpcb.csv: partslist.csv
+ $(AM)/bin/partslist-vendor --vendor jlcpcb -o $@ partslist.csv
$(PROJECT)-parts.tab: $(SCHEMATICS) Makefile
lepton-netlist -g bom -o $@ $(SCHEMATICS)
jlcpcb: $(PROJECT)-jlcpcb.zip
-$(PROJECT)-jlcpcb.zip: $(PROJECT).lht $(CONFIG)
+$(PROJECT)-jlcpcb.zip: $(PROJECT).lht $(CONFIG) $(PROJECT)-jlcpcb.csv
pcb-rnd -x cam gerber:JLC_PCB --outfile out/$(PROJECT) $(PROJECT).lht
$(call emit_xyrs)
- rm -f $@ && zip -j $@ out/* $(PROJECT).xy
+ rm -f $@ && zip -j $@ out/* $(PROJECT).xy $(PROJECT)-jlcpcb.csv
stencilsunlimited: $(BOTTOMCOPPER) $(PROJECT).toppaste.gbr $(OUTLINE)
rm -f $(PROJECT)-stencil.zip && zip $(PROJECT)-stencil.zip $(PROJECT).toppaste.gbr $(OUTLINE)
rm -f $(PROJECT).txt $(PROJECT).gl2 $(PROJECT).gl3
rm -f $(PROJECT).drd $(PROJECT).g2l $(PROJECT).g3l $(PROJECT).gko
rm -f $(PROJECT)-seeed.zip $(PROJECT)-seeed.csv
- rm -f $(PROJECT)-goldphoenix.zip $(PROJECT)-goldphoenix.csv
+ rm -f $(PROJECT)-goldphoenix.zip $(PROJECT)-goldphoenix.csv $(PROJECT)-jlcpcb.csv
rm -f $(PROJECT)*.ps $(PROJECT)*.pdf $(PROJECT)-bom.csv
rm -f $(PROJECT)-parts.csv $(PROJECT)-parts.tab preferred-parts.csv
rm -f *.scad