806 lines
27 KiB
Plaintext
806 lines
27 KiB
Plaintext
#usage "en:<b>Export of libraries from a drawing.</b><p>\n"
|
|
"This can be used to make individual changes to components in a project. "
|
|
"Just load schematic, board or both, use this ULP to generate one or several libraries "
|
|
"containing the used components. Make your changes in the library/libraries and use the "
|
|
"UPDATE command to introduce the changes to schematic and/or board.<p>"
|
|
"See Help for further details.<p>",
|
|
"de:<b>Export von Bibliotheken aus einer Zeichnungsdatei.</b><p>\n"
|
|
"Damit können Sie individuelle Änderungen an Komponenten in einem Projekt machen. "
|
|
"Laden Sie dazu Schaltplan, Board oder beides, verwenden Sie dieses ULP, um eine oder mehrere Bibliotheken "
|
|
"mit den verwendeten Komponenten zu generieren. Machen Sie Ihre Änderungen in der/den Bibliothek(en) "
|
|
"und verwenden Sie den UPDATE-Befehl, um die Änderungen in Schaltplan und/oder Board zu bringen.<p>"
|
|
"Siehe Hilfe für weitere Details.<p>"
|
|
|
|
#require 6.0301
|
|
|
|
string Version = "6.0";
|
|
|
|
// Language:
|
|
//----------
|
|
// Please keep to alphabetic sorting for maintainability !
|
|
string Dictionary[] = {
|
|
"en\v"
|
|
"de\v",
|
|
"Back\v"
|
|
"Zurück\v",
|
|
"Cancel\v"
|
|
"Abbrechen\v",
|
|
"Creation mode\v"
|
|
"Erzeugungsmodus\v",
|
|
"&Browse\v"
|
|
"&Durchsuchen\v",
|
|
"Export EAGLE libraries - Help\v"
|
|
"Export von EAGLE-Bibliotheken - Hilfe\v",
|
|
"Export EAGLE libraries from drawing\v"
|
|
"Export von EAGLE-Bibliotheken aus der Zeichnung\v",
|
|
"Export original libraries\v"
|
|
"Original-Bibliotheken exportieren\v",
|
|
"File \v"
|
|
"Datei \v",
|
|
"Help\v"
|
|
"Hilfe\v",
|
|
"Load\v"
|
|
"Laden\v",
|
|
"Merge to one library, \v"
|
|
"In eine Bibliothek integrieren, \v",
|
|
"original library names as prefix for symbol, package and device names\v"
|
|
"Original-Bibliotheksnamen als Präfix für Symbol-, Package- und Devicenamen verwenden\v",
|
|
"Path\v"
|
|
"Pfad\v",
|
|
"Please start from schematic or board editor!\v"
|
|
"Bitte starten Sie vom Schaltplan- oder Board-Editor!\v",
|
|
"Start\v"
|
|
"Start\v",
|
|
"unchanged symbol, package and device names\v"
|
|
"Symbol-, Package- und Devicenamen unverändert\v"
|
|
};
|
|
|
|
string DlgLang = language();
|
|
if (DlgLang != "de") DlgLang = "en";
|
|
int LangIdx = strstr(Dictionary[0], DlgLang) / 3;
|
|
|
|
// Translate, based on dictionary
|
|
string TR(string s) {
|
|
string t = lookup(Dictionary, s, LangIdx, '\v');
|
|
return t ? t : s;
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Used in DrawText
|
|
string AlignName[];
|
|
AlignName[ALIGN_BOTTOM_LEFT] = "BOTTOM LEFT";
|
|
AlignName[ALIGN_BOTTOM_CENTER] = "BOTTOM CENTER";
|
|
AlignName[ALIGN_BOTTOM_RIGHT] = "BOTTOM RIGHT";
|
|
AlignName[ALIGN_CENTER_LEFT] = "CENTER LEFT";
|
|
AlignName[ALIGN_CENTER] = "CENTER CENTER";
|
|
AlignName[ALIGN_CENTER_RIGHT] = "CENTER RIGHT";
|
|
AlignName[ALIGN_TOP_LEFT] = "TOP LEFT";
|
|
AlignName[ALIGN_TOP_CENTER] = "TOP CENTER";
|
|
AlignName[ALIGN_TOP_RIGHT] = "TOP RIGHT";
|
|
|
|
string Croute[];
|
|
Croute[CONTACT_ROUTE_ALL] = "ALL";
|
|
Croute[CONTACT_ROUTE_ANY] = "ANY"; // 2012-09-26
|
|
|
|
// Used in DrawDimension
|
|
string DimType[];
|
|
DimType[DIMENSION_PARALLEL] = "PARALLEL";
|
|
DimType[DIMENSION_HORIZONTAL] = "HORIZONTAL";
|
|
DimType[DIMENSION_VERTICAL] = "VERTICAL";
|
|
DimType[DIMENSION_RADIUS] = "RADIUS";
|
|
DimType[DIMENSION_DIAMETER] = "DIAMETER";
|
|
DimType[DIMENSION_ANGLE] = "ANGLE";
|
|
DimType[DIMENSION_LEADER] = "LEADER";
|
|
|
|
string UnitName[];
|
|
UnitName[GRID_UNIT_MIC] = "MIC";
|
|
UnitName[GRID_UNIT_MM] = "MM";
|
|
UnitName[GRID_UNIT_MIL] = "MIL";
|
|
UnitName[GRID_UNIT_INCH] = "INCH";
|
|
|
|
string x[] = { " " };
|
|
string CurrentLbrName = "";
|
|
string EditName;
|
|
string h, cmd = "";
|
|
string ScriptName, PureScriptName;
|
|
string WorkPath;
|
|
string Status = "";
|
|
int n;
|
|
int NameIndex = 0;
|
|
int Merge = 0;
|
|
|
|
char ascii127[] = { 181, 196, 214, 220, 223, 0 }; // not allowed character 2010-05-12
|
|
// www: In 8859-1 these chars are { µ ,Ä ,Ö, Ü, ß } and therefore actually allowed as object names.
|
|
// Change this if requested ! What's also allowed but deprecated is { ä, ö, ü }. Should be replaced
|
|
// by { Ä, Ö, Ü }. All other chars allowed for file names are allwoed also for object names.
|
|
// Lower case is automatically converted to upper case (except the umlauts).
|
|
string Newascii127[] = { "U", "AE", "OE", "UE", "SS", "" }; // change to allowed character
|
|
|
|
string HelpText[] = {
|
|
"The library export collects the devices or packages from a schematic or board and stores them back "
|
|
"into one or several libraries."
|
|
"<p>"
|
|
"By default all contained libraries are exported with their original name into the drawing path."
|
|
"Thus you can edit symbols and/or packages in these libraries and "
|
|
"use the UPDATE command to change all respective parts in schematic or board."
|
|
"<p>"
|
|
"Alternatively all objects can be merged into a single library with the name of the schematic or board."
|
|
"You can choose between using the names of the original libraries as prefix for package, symbol and device names or not."
|
|
"Not using these prefixes can lead to ambiguities and therefore is not recommended."
|
|
"<p>"
|
|
"The export path can be adjusted by 'Browse' to select a directory."
|
|
"If one of the library files to be created already exists, you will be prompted if "
|
|
"the existing file may be deleted."
|
|
,
|
|
"Der Bibliotheks-Export sammelt Devices und Packages eines Schaltplans oder Boards und speichert "
|
|
"sie in eine oder mehrere Bibliotheken."
|
|
"<p>"
|
|
"Standardmässig werden alle enthaltenen Bibliotheken mit ihrem Orignialnamen in den Pfad der Zeichnungsdatei(en) "
|
|
"exportiert. So können Sie Symbole und/oder Packages editieren und mit dem UPDATE-Befehl alle entsprechenden "
|
|
"Bauteile in Schaltplan und Board aktualisieren."
|
|
"<p>"
|
|
"Alternativ können alle Objekte in eine einzige Bibliothek mit Schaltplan- bzw. Boardnamen integriert werden. "
|
|
"Sie können wählen, ob Sie die Namen der Original-Bibliotheken als Präfix für die Package-, Symbol- und Devicenamen verwenden "
|
|
"oder nicht. Diese Präfixe nicht zu verwenden kann zu Mehrdeutigkeit führen und wird daher nicht empfohlen."
|
|
"<p>"
|
|
"Der Export-Pfad kann mit 'Durchsuchen' eingestellt werden. "
|
|
"Wenn eines der Bibliotheken bereits existiert, werden Sie gefragt, ob die bestehende Datei gelöscht werden darf."
|
|
};
|
|
|
|
void DisplayHelp() {
|
|
dlgDialog(TR("Export EAGLE libraries - Help")) {
|
|
dlgHBoxLayout dlgSpacing(400);
|
|
dlgTextView(HelpText[LangIdx]);
|
|
dlgHBoxLayout {
|
|
dlgStretch(1);
|
|
dlgPushButton("+" + TR("Back")) dlgReject();
|
|
dlgStretch(1);
|
|
}
|
|
};
|
|
}
|
|
|
|
string get_project_path() {
|
|
if (board) board(B) return(filedir(B.name));
|
|
if (schematic) schematic(B) return(filedir(B.name));
|
|
if (library) library(B) return(filedir(B.name));
|
|
}
|
|
|
|
string replacenewline(string nl) {
|
|
string a[];
|
|
int n = strsplit(a, nl, '\n');
|
|
if (n > 0) {
|
|
nl = "";
|
|
for (int x = 0; x < n - 1; x++) {
|
|
nl += a[x] + "\\n";
|
|
}
|
|
nl += a[x];
|
|
}
|
|
return nl;
|
|
}
|
|
|
|
// Da der ganze String in ' eingeschlossen wird,
|
|
// müssen die Apostrophen verdoppelt werden.
|
|
string addApostroph(string name) { // 2012-03-23
|
|
string t[];
|
|
int cnt = strsplit(t, name, '\''); // check Apostroph
|
|
if (cnt > 1) {
|
|
name = "";
|
|
for (int i = 0; i < cnt; i++) {
|
|
if (i == 0) {
|
|
if (t[i]) name += t[i];
|
|
}
|
|
else if (i) name += "''" + t[i];
|
|
}
|
|
}
|
|
return name;
|
|
}
|
|
|
|
string replaceascii127(string s, int n, string newascii) {
|
|
if (n == strlen(s)) return strsub(s, 0, n) + newascii;
|
|
else return strsub(s, 0, n) + newascii + strsub(s, n+1);
|
|
}
|
|
|
|
string check_ascii127(string s) { // 2009-02-02
|
|
int n = 0;
|
|
int pos;
|
|
do {
|
|
pos = strchr(s, ascii127[n]);
|
|
if (pos > -1)
|
|
s = replaceascii127(s, pos, Newascii127[n]);
|
|
if (pos < 0) n++; // 2012-02-08
|
|
} while (ascii127[n]);
|
|
return s;
|
|
}
|
|
|
|
// Remove this as soon as the "@-problem" is solved !
|
|
string ReplaceAt(string s) {
|
|
for (int i = 0; i < strlen(s); i++)
|
|
if (s[i]=='@') s[i]='$'; // Creates problems when name is used in ADD and other commands
|
|
return s;
|
|
}
|
|
|
|
string ReplaceInvalidCharsForObjNames(string s) {
|
|
for (int i = 0; i < strlen(s); i++)
|
|
if (s[i]==' ') s[i]='-'; // No '_' to distinguish from prefix ending !
|
|
return ReplaceAt(s);
|
|
}
|
|
|
|
string LbrPrefix(string s) {
|
|
s = check_ascii127(s);
|
|
return ReplaceInvalidCharsForObjNames(s) + "_";
|
|
}
|
|
|
|
int exist_file(string FileName) {
|
|
string a[];
|
|
int n = fileglob(a, FileName);
|
|
if (n == 0) return 0;
|
|
else return 1;
|
|
}
|
|
|
|
void CreateLBRdescription(string project_name) {
|
|
// !!! Wird nicht vorherige Description überschrieben ?
|
|
sprintf(h, "DESCRIPTION 'Generated from <b>%s</b><p>\\n\\\nby %s';\n", filename(project_name), filename(argv[0]));
|
|
cmd += h;
|
|
return;
|
|
}
|
|
|
|
// Needed for delayed scripting of the layer info:
|
|
// Avoid unconditional creation of (routing) layers although they are actually not used,
|
|
// because for licenses with layer restriction the script might stop.
|
|
int RouteLayerUsed[]; // For layer with index 1..16, wether it's used by some object
|
|
string RouteLayerNames[];
|
|
|
|
void CreateHeader(UL_LIBRARY LBR) {
|
|
for (int i = 0; i < 16; ++i) // Reset
|
|
RouteLayerUsed[i] = 0;
|
|
LBR.layers(L)
|
|
if (L.number > 16) {
|
|
sprintf(h, "Layer %d %s;\n", L.number, L.name); cmd += h;
|
|
}
|
|
else
|
|
RouteLayerNames[L.number - 1] = L.name; // Keep names later use.
|
|
sprintf(h, "Set Wire_bend 2;\nSet Select_factor 0;\nSet Undo_log off;\n"); cmd += h;
|
|
sprintf(h, "Grid mic 1;\n"); cmd += h;
|
|
sprintf(h, "Display All;\n"); cmd += h;
|
|
cmd += "DESCRIPTION '" + addApostroph(replacenewline(LBR.description)) + "';\n";
|
|
}
|
|
|
|
void CreateTrailer(void) {
|
|
sprintf(h, "Set Undo_log On;\nSet Select_factor 0.02;\nGrid last;\n"); cmd += h;
|
|
}
|
|
|
|
void PrintValidLayer(int LNr) {
|
|
if (LNr <= 16 && !RouteLayerUsed[LNr - 1]) {
|
|
// Layer used first time. Assign it's name, flag as used.
|
|
sprintf(h, "Layer %d %s;\n", LNr, RouteLayerNames[LNr -1]); cmd += h;
|
|
RouteLayerUsed[LNr - 1] = 1;
|
|
}
|
|
sprintf(h, "Layer %d;\n", LNr); cmd += h;
|
|
}
|
|
|
|
void DrawDimension(UL_DIMENSION D) { // 2011-12-06
|
|
sprintf(h, "CHANGE LAYER %d;\n", D.layer); cmd += h;
|
|
sprintf(h, "CHANGE SIZE %f;\n", u2mic(D.size)); cmd += h;
|
|
sprintf(h, "CHANGE RATIO %d;\n", D.ratio); cmd += h;
|
|
sprintf(h, "CHANGE DUNIT %s %s %d;\n", UnitName[D.unit], (D.visible==0) ? "off" : "on", D.precision); cmd += h;
|
|
sprintf(h, "CHANGE DLINE %f %f %f %f;\n", u2mic(D.width), u2mic(D.extwidth), u2mic(D.extlength), u2mic(D.extoffset)); cmd += h;
|
|
sprintf(h, "DIMENSION %s (C%f %f) (%f %f) (%f %f);\n", // Warum das C ?
|
|
DimType[D.dtype],
|
|
u2mic(D.x1), u2mic(D.y1),
|
|
u2mic(D.x2), u2mic(D.y2),
|
|
u2mic(D.x3), u2mic(D.y3) );
|
|
cmd += h;
|
|
return;
|
|
}
|
|
|
|
void DrawFrame(UL_FRAME F) {
|
|
PrintValidLayer(F.layer);
|
|
|
|
string FBorder = "";
|
|
if (F.border & 1) FBorder += " BOTTOM";
|
|
if (F.border & 2) FBorder += " RIGHT";
|
|
if (F.border & 4) FBorder += " TOP";
|
|
if (F.border & 8) FBorder += " LEFT";
|
|
|
|
sprintf(h, "FRAME %d %d %s (%f %f) (%f %f);\n",
|
|
F.columns, F.rows,
|
|
FBorder,
|
|
u2mic(F.x1), u2mic(F.y1),
|
|
u2mic(F.x2), u2mic(F.y2) );
|
|
cmd += h;
|
|
return;
|
|
}
|
|
|
|
void DrawCircle(UL_CIRCLE C) {
|
|
PrintValidLayer(C.layer);
|
|
sprintf(h, "Circle %f (%f %f) (%f %f);\n",
|
|
u2mic(C.width),
|
|
u2mic(C.x), u2mic(C.y),
|
|
u2mic(C.x + C.radius), u2mic(C.y));
|
|
cmd += h;
|
|
return;
|
|
}
|
|
|
|
void DrawWire(UL_WIRE W) {
|
|
PrintValidLayer(W.layer);
|
|
if (W.arc) { // 2008-09-11
|
|
sprintf(h, "WIRE %f %s (%f %f) %+f (%.f %.f);\n",
|
|
u2mic(W.width),
|
|
W.cap == CAP_ROUND ? "ROUND" : "FLAT", // 2011-09-07
|
|
u2mic(W.x1), u2mic(W.y1),
|
|
W.curve,
|
|
u2mic(W.x2), u2mic(W.y2));
|
|
cmd += h;
|
|
}
|
|
else {
|
|
sprintf(h, "Wire %f (%f %f) (%f %f);\n",
|
|
u2mic(W.width), u2mic(W.x1), u2mic(W.y1), u2mic(W.x2), u2mic(W.y2));
|
|
cmd += h;
|
|
}
|
|
}
|
|
|
|
void DrawRectangle(UL_RECTANGLE R) {
|
|
PrintValidLayer(R.layer);
|
|
sprintf(h, "Rect R%.1f (%f %f) (%f %f);\n",
|
|
R.angle,
|
|
u2mic(R.x1), u2mic(R.y1),
|
|
u2mic(R.x2), u2mic(R.y2));
|
|
cmd += h;
|
|
}
|
|
|
|
void DrawContact(UL_CONTACT C) {
|
|
string ShapeString;
|
|
string ShapeFlag;
|
|
if (C.pad) {
|
|
switch(C.pad.shape[17]) { //!!!
|
|
case PAD_SHAPE_SQUARE : ShapeString = "Square"; break;
|
|
case PAD_SHAPE_ROUND : ShapeString = "Round"; break;
|
|
case PAD_SHAPE_OCTAGON : ShapeString = "Octagon"; break;
|
|
case PAD_SHAPE_LONG : ShapeString = "Long"; break;
|
|
case PAD_SHAPE_OFFSET : ShapeString = "Offset"; break;
|
|
}
|
|
if (!(C.pad.flags & PAD_FLAG_STOP) ) ShapeFlag = "NOSTOP ";
|
|
if (!(C.pad.flags & PAD_FLAG_THERMALS) ) ShapeFlag += "NOTHERMALS ";
|
|
if ((C.pad.flags & PAD_FLAG_FIRST) ) ShapeFlag += "FIRST "; // 22.11.2004 support@cadsoft
|
|
//
|
|
// PAD [diameter] [shape] [orientation] [flags] ['name'] *..
|
|
//
|
|
sprintf(h, "Change Drill %f;\n", u2mic(C.pad.drill)); cmd += h;
|
|
sprintf(h, "Pad %f %s R%.1f %s '%s' (%f %f);\n",
|
|
u2mic(C.pad.diameter[17]),
|
|
ShapeString,
|
|
C.pad.angle,
|
|
ShapeFlag,
|
|
addApostroph(C.pad.name), // 2012-03-29
|
|
u2mic(C.pad.x), u2mic(C.pad.y));
|
|
cmd += h;
|
|
}
|
|
else if (C.smd) {
|
|
if (!(C.smd.flags & PAD_FLAG_STOP) ) ShapeFlag = "NOSTOP ";
|
|
if (!(C.smd.flags & SMD_FLAG_THERMALS) ) ShapeFlag += "NOTHERMALS ";
|
|
if (!(C.smd.flags & SMD_FLAG_CREAM) ) ShapeFlag += "NOCREAM ";
|
|
|
|
PrintValidLayer(C.smd.layer);
|
|
sprintf(h, "CHANGE Roundness %d;\n", C.smd.roundness); cmd += h;
|
|
//
|
|
// SMD [x_width y_width] [-roundness] [orientation] [flags] ['name'] *..
|
|
//
|
|
sprintf(h, "SMD %f %f -%d R%.1f %s '%s' (%f %f);\n",
|
|
u2mic(C.smd.dx), u2mic(C.smd.dy),
|
|
C.smd.roundness,
|
|
C.smd.angle,
|
|
ShapeFlag,
|
|
addApostroph(C.smd.name), // 2012-03-29
|
|
u2mic(C.smd.x), u2mic(C.smd.y));
|
|
cmd += h;
|
|
}
|
|
}
|
|
|
|
void DrawText(UL_TEXT T) {
|
|
PrintValidLayer(T.layer);
|
|
switch(T.font) {
|
|
case FONT_VECTOR : sprintf(h, "CHANGE FONT VECTOR;\n");
|
|
cmd += h;
|
|
break;
|
|
case FONT_PROPORTIONAL : sprintf(h, "CHANGE FONT PROPORTIONAL;\n");
|
|
cmd += h;
|
|
break;
|
|
case FONT_FIXED : sprintf(h, "CHANGE FONT FIXED;\n");
|
|
cmd += h;
|
|
break;
|
|
}
|
|
|
|
string Spin = "";
|
|
string Mirror = "";
|
|
if (T.spin) Spin = "S";
|
|
if (T.mirror) Mirror = "M";
|
|
|
|
sprintf(h, "Change Size %f;\n", u2mic(T.size));
|
|
cmd += h;
|
|
sprintf(h, "Change Ratio %d;\n", T.ratio);
|
|
cmd += h;
|
|
sprintf(h, "Change Align %s;\n", AlignName[T.align]);
|
|
cmd += h;
|
|
sprintf(h, "Change Linedistance %d;\n", T.linedistance);
|
|
cmd += h;
|
|
|
|
sprintf(h, "Text %s%sR%.1f '%s' (%f %f);\n",
|
|
Spin, Mirror, T.angle, addApostroph(replacenewline(T.value)), u2mic(T.x), u2mic(T.y) // AddApostroph ?
|
|
);
|
|
cmd += h;
|
|
}
|
|
|
|
void DrawHole(UL_HOLE H) {
|
|
sprintf(h, "Change Drill %f;\n", u2mic(H.drill)); cmd += h;
|
|
sprintf(h, "Hole (%f %f);\n", u2mic(H.x), u2mic(H.y)); cmd += h;
|
|
}
|
|
|
|
void DrawPolygon(UL_POLYGON PL) {
|
|
PrintValidLayer(PL.layer);
|
|
//sprintf(h, "Change Isolate %f;\n", u2mic(PL.isolate)); cmd += h; exist only in board
|
|
sprintf(h, "Change Spacing %f;\n", u2mic(PL.spacing)); cmd += h;
|
|
if (PL.pour == POLYGON_POUR_SOLID) {
|
|
sprintf(h, "Change Pour Solid;\n"); cmd += h;
|
|
}
|
|
else {
|
|
sprintf(h, "Change Pour Hatch;\n"); cmd += h;
|
|
}
|
|
sprintf(h, "Polygon %f ", u2mic(PL.width)); cmd += h;
|
|
PL.wires(W) {
|
|
sprintf(h, "(%f %f) ", u2mic(W.x1), u2mic(W.y1)); cmd += h; /*start coord.*/
|
|
break;
|
|
}
|
|
PL.wires(W) {
|
|
sprintf(h, " %+f (%f %f) ", W.curve, u2mic(W.x2), u2mic(W.y2)); cmd += h;
|
|
}
|
|
sprintf(h, ";\n"); cmd += h;
|
|
}
|
|
|
|
void DrawPin(UL_PIN P) {
|
|
string DIR = "", FUNC = "", LEN = "", VIS = "", ANGLE = "R0";
|
|
if (P.angle == 90) (ANGLE = "R90");
|
|
if (P.angle == 180) (ANGLE = "R180");
|
|
if (P.angle == 270) (ANGLE = "R270");
|
|
|
|
if (P.function == PIN_FUNCTION_FLAG_NONE) (FUNC = "None");
|
|
if (P.function == PIN_FUNCTION_FLAG_DOT) (FUNC = "Dot");
|
|
if (P.function == PIN_FUNCTION_FLAG_CLK) (FUNC = "Clk");
|
|
if (P.function == (PIN_FUNCTION_FLAG_DOT | PIN_FUNCTION_FLAG_CLK))
|
|
(FUNC = "DotClk");
|
|
|
|
if (P.visible == PIN_VISIBLE_FLAG_OFF) (VIS = "Off");
|
|
if (P.visible == PIN_VISIBLE_FLAG_PIN) (VIS = "Pin");
|
|
if (P.visible == PIN_VISIBLE_FLAG_PAD) (VIS = "Pad");
|
|
if (P.visible == (PIN_VISIBLE_FLAG_PIN | PIN_VISIBLE_FLAG_PAD))
|
|
(VIS = "Both");
|
|
|
|
switch(P.direction) {
|
|
case PIN_DIRECTION_NC : DIR = "NC"; break;
|
|
case PIN_DIRECTION_IN : DIR = "In"; break;
|
|
case PIN_DIRECTION_OUT : DIR = "Out"; break;
|
|
case PIN_DIRECTION_IO : DIR = "IO"; break; // 2011-10-10
|
|
case PIN_DIRECTION_OC : DIR = "OC"; break;
|
|
case PIN_DIRECTION_PWR : DIR = "Pwr"; break;
|
|
case PIN_DIRECTION_PAS : DIR = "Pas"; break;
|
|
case PIN_DIRECTION_HIZ : DIR = "Hiz"; break;
|
|
case PIN_DIRECTION_SUP : DIR = "Sup";
|
|
}
|
|
|
|
switch(P.length) {
|
|
case PIN_LENGTH_POINT : LEN = "Point"; break;
|
|
case PIN_LENGTH_SHORT : LEN = "Short"; break;
|
|
case PIN_LENGTH_MIDDLE : LEN = "Middle"; break;
|
|
case PIN_LENGTH_LONG : LEN = "Long";
|
|
}
|
|
|
|
sprintf(h, "Pin '%s' %s %s %s %s %s %d (%f %f);\n",
|
|
addApostroph(P.name), // 2012-02-08
|
|
DIR, FUNC, LEN, ANGLE, VIS, P.swaplevel, u2mic(P.x), u2mic(P.y));
|
|
cmd += h;
|
|
}
|
|
|
|
void DrawSymbol(UL_SYMBOL S) {
|
|
S.circles(C) DrawCircle(C);
|
|
S.rectangles(R) DrawRectangle(R);
|
|
S.wires(W) DrawWire(W);
|
|
S.pins(P) DrawPin(P);
|
|
S.texts(T) DrawText(T);
|
|
S.polygons(PL) DrawPolygon(PL);
|
|
S.frames(F) DrawFrame(F);
|
|
S.dimensions(D) DrawDimension(D);
|
|
cmd += "DESCRIPTION '" + addApostroph(replacenewline(S.description)) + "';\n";
|
|
}
|
|
|
|
void DrawPackage(UL_PACKAGE P) {
|
|
sprintf(h, "GRID mic;\n"); cmd+=h; // 2011-04-11
|
|
P.circles(C) DrawCircle(C);
|
|
P.wires(W) DrawWire(W);
|
|
P.rectangles(R) DrawRectangle(R);
|
|
P.contacts(C) DrawContact(C);
|
|
P.texts(T) DrawText(T);
|
|
P.holes(H) DrawHole(H);
|
|
P.polygons(PL) DrawPolygon(PL);
|
|
P.frames(F) DrawFrame(F);
|
|
P.dimensions(D) DrawDimension(D);
|
|
cmd += "DESCRIPTION '" + addApostroph(replacenewline(P.description)) + "';\n";
|
|
}
|
|
|
|
// ************************************************
|
|
// see also *** export-schematic_mil-board_mm-script.ulp ***
|
|
// ************************************************
|
|
|
|
void DrawDevice(UL_DEVICESET D, UL_LIBRARY LBR) {
|
|
cmd += "DESCRIPTION '" + addApostroph(replacenewline(D.description)) + "';\n";
|
|
cmd += "PREFIX '" + D.prefix + "';\n";
|
|
cmd += "VALUE " + D.value + ";\n";
|
|
D.gates(G) {
|
|
string GateAddlevel;
|
|
switch (G.addlevel) {
|
|
case GATE_ADDLEVEL_NEXT : GateAddlevel = "Next"; break;
|
|
case GATE_ADDLEVEL_MUST : GateAddlevel = "Must"; break;
|
|
case GATE_ADDLEVEL_CAN : GateAddlevel = "Can"; break;
|
|
case GATE_ADDLEVEL_REQUEST : GateAddlevel = "Request"; break;
|
|
case GATE_ADDLEVEL_ALWAYS : GateAddlevel = "Always";
|
|
};
|
|
sprintf(h, "CHANGE Addlevel %s;\n", GateAddlevel); cmd += h;
|
|
sprintf(h, "CHANGE Swaplevel %d;\n", G.swaplevel); cmd += h;
|
|
string symname = G.symbol.name; // No problem with @...
|
|
if (Merge == 1)
|
|
symname = LbrPrefix(LBR.name) + symname;
|
|
sprintf(h, "ADD '%s' '%s' (%f %f);\n", addApostroph(symname), addApostroph(G.name), u2mic(G.x), u2mic(G.y)); // 2012-02-07
|
|
cmd += h;
|
|
}
|
|
D.devices(DV) {
|
|
if (DV.package) {
|
|
string pacname = ReplaceAt(DV.package.name); // !!!
|
|
if (Merge == 1)
|
|
pacname = LbrPrefix(LBR.name) + pacname;
|
|
cmd += "PACKAGE '" + addApostroph(pacname) + "' " + DV.name + ";\n"; // addApostroph here problematic !
|
|
}
|
|
DV.gates(G) {
|
|
if (DV.package) {
|
|
G.symbol.pins(P) {
|
|
string cont = "";
|
|
P.contacts(C) { // 2011-12-06
|
|
if (!cont) sprintf(h, "%s", addApostroph(C.name)); // 2012-03-29
|
|
else sprintf(h, " %s", addApostroph(C.name)); // 2012-003-29
|
|
cont += h;
|
|
}
|
|
if (cont) {
|
|
sprintf(h, "CONNECT %s '%s.%s' '%s';\n", // //2012-03-23 problem with # in pin name
|
|
Croute[P.route],
|
|
addApostroph(G.name), // 2012-03-29
|
|
addApostroph(P.name), // 2012-03-29
|
|
cont
|
|
);
|
|
cmd += h;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
string t[];
|
|
int n = strsplit(t, DV.technologies, ' ');
|
|
for (int i = 0; i < n; i++) {
|
|
sprintf(h,"TECHNOLOGY '%s';\n", addApostroph(t[i])); // 2012-03-23
|
|
cmd += h;
|
|
DV.attributes(A, t[i]) {
|
|
string const = "";
|
|
if (A.constant) const = " CONSTANT";
|
|
sprintf(h,"ATTRIBUTE '%s' '%s' %s\n", A.name, addApostroph(A.value), const); // 2010-10-14
|
|
cmd += h;
|
|
}
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
//----------------
|
|
int is_new(void) { // n = nr of entries
|
|
int i;
|
|
if (n == 0) return 1;
|
|
for (i = 0; i < n; i++) {
|
|
if (x[n] == x[i]) {
|
|
return(0);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
// ---------
|
|
void CreateOneLibHeader(UL_LIBRARY LBR, string project_name) {
|
|
if (exist_file(WorkPath+CurrentLbrName+".lbr")) {
|
|
sprintf(h, "REMOVE '%s';\n", WorkPath+CurrentLbrName+".lbr"); cmd += h; // delete existing lbr
|
|
}
|
|
sprintf(h, "OPEN '~dummy~.lbr';\nCLOSE;\nOPEN '%s.lbr';\n", WorkPath+CurrentLbrName); // 2012-02-07 to close an opened library first
|
|
cmd += h;
|
|
CreateHeader(LBR);
|
|
CreateLBRdescription(project_name);
|
|
}
|
|
|
|
// ---------
|
|
void OutputPackages(UL_LIBRARY LBR) {
|
|
LBR.packages(P) {
|
|
string pacname = ReplaceAt(P.name);
|
|
if (Merge == 1)
|
|
pacname = LbrPrefix(LBR.name) + pacname;
|
|
n++;
|
|
x[n] = pacname;
|
|
if (is_new()) {
|
|
Status = " PAC: " + P.name; dlgRedisplay();
|
|
sprintf(h, "\nEdit '%s.PAC';\n", addApostroph(pacname)); cmd += h;
|
|
DrawPackage(P);
|
|
}
|
|
}
|
|
}
|
|
|
|
void OutputSymbols(UL_LIBRARY LBR) {
|
|
LBR.symbols(S) {
|
|
string symname = S.name;
|
|
if (Merge == 1)
|
|
symname = LbrPrefix(LBR.name) + symname;
|
|
n++;
|
|
x[n] = symname;
|
|
if (is_new()) {
|
|
Status = " SYM: " + S.name; dlgRedisplay();
|
|
sprintf(h, "\nEdit '%s.SYM';\n", addApostroph(symname)); cmd += h;
|
|
DrawSymbol(S);
|
|
}
|
|
}
|
|
}
|
|
|
|
void OutputDevices(UL_LIBRARY LBR) {
|
|
LBR.devicesets(D) {
|
|
string dname = D.name;
|
|
if (Merge == 1)
|
|
dname = LbrPrefix(LBR.name) + dname;
|
|
n++;
|
|
x[n] = dname;
|
|
if (is_new()) {
|
|
Status = " DEV: " + D.name; dlgRedisplay();
|
|
NameIndex = 0;
|
|
sprintf(h, "\nEdit '%s.DEV';\n", addApostroph(dname)); cmd += h;
|
|
DrawDevice(D, LBR);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CreateLbr(UL_LIBRARY LBR) {
|
|
if (exist_file(WorkPath+CurrentLbrName+".lbr")) {
|
|
sprintf(h, "REMOVE '%s.lbr';\n", WorkPath+CurrentLbrName);
|
|
cmd += h; // delete existing lbr
|
|
}
|
|
sprintf(h, "OPEN '~dummy~.lbr';\nCLOSE;\nOPEN '%s.lbr';\n", WorkPath+CurrentLbrName); // 2012-02-07 to close a opened library first
|
|
cmd += h;
|
|
CreateHeader(LBR);
|
|
}
|
|
|
|
void make_lbr(void) {
|
|
if (board) board(B) {
|
|
B.libraries(LBR) {
|
|
CurrentLbrName = LBR.name;
|
|
CreateLbr(LBR);
|
|
LBR.packages(PAC) {
|
|
OutputPackages(LBR);
|
|
cmd += "WRITE;\n";
|
|
break;
|
|
};
|
|
}
|
|
}
|
|
if (schematic) schematic(SCH) {
|
|
SCH.libraries(LBR) {
|
|
CurrentLbrName = LBR.name;
|
|
CreateLbr(LBR);
|
|
LBR.devices(DEV) {
|
|
OutputPackages(LBR);
|
|
n=0;
|
|
OutputSymbols(LBR);
|
|
n=0;
|
|
OutputDevices(LBR);
|
|
cmd += "WRITE;\n";
|
|
break;
|
|
};
|
|
}
|
|
}
|
|
CreateTrailer();
|
|
}
|
|
|
|
//-------------------
|
|
void make_one_lbr(void) {
|
|
int noLbrs = 1;
|
|
if (board) board(B) {
|
|
B.libraries(LBR) {
|
|
CurrentLbrName = filesetext(EditName, "");
|
|
CreateOneLibHeader(LBR, B.name);
|
|
noLbrs = 0;
|
|
break;
|
|
}
|
|
n = 0;
|
|
B.libraries(LBR) {
|
|
OutputPackages(LBR);
|
|
}
|
|
}
|
|
if (schematic) schematic(SCH) {
|
|
SCH.libraries(LBR) {
|
|
CurrentLbrName = filesetext(EditName, "");
|
|
CreateOneLibHeader(LBR, SCH.name);
|
|
noLbrs = 0;
|
|
break;
|
|
}
|
|
n = 0;
|
|
SCH.libraries(LBR) {
|
|
OutputPackages(LBR);
|
|
}
|
|
n = 0;
|
|
SCH.libraries(LBR) {
|
|
LBR.devices(DEV) {
|
|
OutputSymbols(LBR);
|
|
}
|
|
}
|
|
n = 0;
|
|
SCH.libraries(LBR) {
|
|
LBR.devices(DEV) {
|
|
OutputDevices(LBR);
|
|
}
|
|
}
|
|
}
|
|
if (!noLbrs) {
|
|
cmd += "WRITE;\n";
|
|
CreateTrailer();
|
|
}
|
|
return;
|
|
}
|
|
|
|
// -----------
|
|
void show_save_script_file(string cm) {
|
|
ScriptName = WorkPath+PureScriptName;
|
|
output(ScriptName, "wtD") printf("%s", cm);
|
|
return;
|
|
}
|
|
|
|
//------------ main ----------------------------------------
|
|
if (library) {
|
|
dlgMessageBox(TR("Please start from schematic or board editor!"));
|
|
exit(1);
|
|
}
|
|
else {
|
|
if (board) board(B) EditName = filename(B.name); // name of loaded board/schematic w/o path
|
|
if (schematic) schematic(S) EditName = filename(S.name);
|
|
}
|
|
|
|
PureScriptName = filesetext(EditName, ".scr"); // name of generated script w/o path
|
|
WorkPath = get_project_path();
|
|
|
|
int Result = dlgDialog(TR("Export EAGLE libraries from drawing")) {
|
|
dlgHBoxLayout {
|
|
dlgLabel("&" + TR("Path") + ":");
|
|
dlgStringEdit(WorkPath);
|
|
dlgPushButton(TR("&Browse") + "...") {
|
|
if (cmd) cmd = "";
|
|
h = WorkPath;
|
|
WorkPath = dlgDirectory("", WorkPath);
|
|
if (WorkPath == "") WorkPath = h;
|
|
else WorkPath += "/"; // 29.03.2005 support@cadsoft.de
|
|
}
|
|
}
|
|
dlgGroup(TR("Creation mode")) {
|
|
dlgRadioButton("&" + TR("Export original libraries"), Merge); //name like drawing
|
|
dlgRadioButton("&" + TR("Merge to one library, ") + TR("original library names as prefix for symbol, package and device names"), Merge);
|
|
dlgRadioButton( TR("Merge to one library, ") + "&" + TR("unchanged symbol, package and device names"), Merge);
|
|
}
|
|
dlgLabel(Status, 1);
|
|
dlgHBoxLayout {
|
|
dlgStretch(1);
|
|
dlgPushButton("&" + TR("Help") + "...") DisplayHelp();
|
|
dlgPushButton("+&" + TR("OK")) {
|
|
cmd = "";
|
|
if (Merge > 0)
|
|
make_one_lbr();
|
|
else
|
|
make_lbr();
|
|
show_save_script_file(cmd);
|
|
exit("SCRIPT '"+ScriptName+"';\n");
|
|
}
|
|
dlgPushButton("-&" + TR("Cancel")) dlgReject();
|
|
}
|
|
};
|