/****************************************************************************** * BOM3.ULP - please send any comments to hv@itec-audio.com * * This EAGLE User Language Program prints a board's * Partlist and its "Bill Of Material" * * V1.1 16.07.99 Helmut Vaupotitsch - hv@itec-audio.com * DetailedOutput = Yes|No * SkipPartsNoValue = Yes: Donīt count parts with no value in summary. * * Output-script in {filename}.BOM * Errorlevel -1: Drawing is not a board * *****************************************************************************/ enum {Yes, No}; int DetailedOutput = Yes; int SkipPartsNoValue = Yes; enum { OK=0, NotABoard=-1 }; int ExitCode; string orientation(real Angle, int Mirror) { string s; sprintf(s, "R%.1f", Angle); for (int i = 0; s[i]; i++) if (s[i] == '.') { if (s[i + 1] == '0') s[i] = 0; break; } if (Mirror) s = "M" + s; return s; } void PartLine(string Pos, string Name, string Value, string Package, string Library, string PosInch, string PosMM, string Orient) { if (DetailedOutput == Yes) { printf("%3s %-*s %-*s %-*s %-8s %s %s %s\n", Pos, ELEMENT_NAME_LENGTH, Name, ELEMENT_VALUE_LENGTH, Value, PACKAGE_NAME_LENGTH, Package, Library, PosInch, PosMM, Orient); } } int ValueLine(string Pos, string Quantity, string Value, string Package, string Library, string Parts) { return printf("%3s %4s %-*s %s%s", Pos, Quantity, ELEMENT_VALUE_LENGTH, Value, Parts, Parts != "" ? "\n" : ""); } /********************/ /* --- HP --- */ /********************/ ExitCode = NotABoard; if (board) board(B) { ExitCode = OK; output(filesetext(B.name, ".BOM")) { printf("%s\n", EAGLE_SIGNATURE); printf("Partlist exported from %s at %s\n", B.name, t2string(time())); printf("Board last modified on %s\n",t2string(filetime(B.name))); string YesNo[] = {"Yes", "No"}; printf("Settings: DetailedOutput=%s, SkipPartsNoValue=%s\n\n", YesNo[DetailedOutput], YesNo[SkipPartsNoValue]); if (DetailedOutput == Yes) { PartLine("Pos", "Part", "Value", "Package", "Library", " Position inch", " Position mm", " Orientation"); printf("\n"); } numeric string ename[], evalue[], pname[], lname[], PInch[], PMM[], Orient[]; int cnt = 0, index[]; string Pos; B.elements(E) { ename[cnt] = E.name; evalue[cnt] = E.value; pname[cnt] = E.package.name; lname[cnt] = E.package.library; sprintf(PInch[cnt], "(%6.3f %6.3f)", u2inch(E.x), u2inch(E.y)); sprintf(PMM[cnt], "(%6.2f %6.2f)", u2mm(E.x), u2mm(E.y)); Orient[cnt] = orientation(E.angle, E.mirror); cnt++; } sort(cnt, index, ename); for (int i = 0; i < cnt; i++) { sprintf(Pos, "%3d", i+1); PartLine(Pos, ename[index[i]], evalue[index[i]], pname[index[i]], lname[index[i]], PInch[index[i]], PMM[index[i]], Orient[index[i]] ); } if (DetailedOutput == Yes) printf("\n\n"); int n1, n2, i1, i2, offset, p; string quantity; ValueLine("Pos", "Qty", "Value", "Package", "Library", "Parts"); printf("\n"); sort(cnt, index, evalue, ename); for (n1 = 0, n2 = 0, p = 0; ++n2 <= cnt; ) { i1 = index[n1]; if (n2 < cnt) { i2 = index[n2]; if (evalue[i1] == evalue[i2] && pname[i1] == pname[i2] && lname[i1] == lname[i2]) continue; } if (SkipPartsNoValue == Yes && (evalue[i1] == "" || evalue[i1] == " ")) n1 = n2; else { sprintf(Pos, "%3d", ++p); sprintf(quantity, "%d", n2 - n1); offset = ValueLine(Pos, quantity, evalue[i1], pname[i1], lname[i1], ""); for (;;) { offset += printf(ename[i1]); if (++n1 < n2) { i1 = index[n1]; offset += printf(", "); if (offset + strlen(ename[i1]) > 77) { printf("\n"); offset = ValueLine("", "", "", "", "", ""); } } else break; } // for printf("\n"); } // else } // for printf("\nDone.\n"); } // Output } exit(ExitCode);