// kate: syntax c /* Copyright (c) 2008..2010, Sven Pauli All rights reserved. sven_pauli@gmx.de */ string fmt; /* Scale factors */ real scu_package = 0.1; real scu_symbol = 1.0; enum { SCU_SYMBOL, SCU_PACKAGE }; int scu_mode; real scu(int x) { switch (scu_mode) { /* Symbol */ case SCU_SYMBOL: return u2mic(x) * scu_symbol; /* Package */ case SCU_PACKAGE: return u2mic(x) * scu_package; default: return 0.0; } } void calling_error() { dlgMessageBox(";Dieses Skript möchte ohne Argumente aufgerufen werden."); exit(EXIT_FAILURE); } int file_exists(string file) { string a[]; int n = fileglob(a, file); return n > 0; } string str_replace(string s, char c, string r) { int pos; int start = 0; string result = ""; pos = strchr(s, c); if (pos == -1) { return s; } while (pos >= 0) { result += strsub(s, start, pos - start); result += r; start = pos + 1; pos = strchr(s, c, start); } result += strsub(s, start); return result; } string format_string(string s) { /* Possible traps: - apostrophes - a pair of brackets (= point) - newline */ return "'" + str_replace(str_replace(s, '\n', "\\n"), '\'', "''") + "'"; } string format_path(string s) { return s; } string format_name(string s) { return str_replace(s, '\'', "''"); } string strip_path(string path) { int i = strlen(path); while ( (--i >= 0) && (path[i] == '/') ); return strsub(path, 0, i + 1); } string strip_at(string s) { int pos = strchr(s, '@'); if (pos > 0) { return strsub(s, 0, pos); } return s; } void progress(string description, int prog, int total, string current) { if (prog % 10) return; string pluses = "####################"; string scores = "____________________"; int n = prog * 20 / total; string s; sprintf(s, "%s: [%s%s] (%d von %d) %s", description, strsub(pluses, 0, n), strsub(scores, 0, 20 - n), prog, total, current ); status(s); /* Necessary to allow GUI update and script cancellation */ system("sleep 0.1"); } int current_layer = -1; void layer(int l) { if (l == current_layer) return; printf("LAYER %d;\n", l); current_layer = l; } void export_circle(UL_CIRCLE C) { layer(C.layer); /* First click = center, then move = radius, then click = done */ real sx = scu(C.x); real sy = scu(C.y); printf("CIRCLE %f (%f %f) (%f %f);\n", scu(C.width), sx, sy, sx + scu(C.radius), sy ); } void export_contact(UL_CONTACT C) { string flags = ""; if (C.pad) { if ( !(C.pad.flags & PAD_FLAG_STOP) ) flags += " NOSTOP"; if ( !(C.pad.flags & PAD_FLAG_THERMALS) ) flags += " NOTHERMALS"; if (C.pad.flags & PAD_FLAG_FIRST) flags += " FIRST"; string shape; switch(C.pad.shape[LAYER_PADS]) { case PAD_SHAPE_SQUARE: shape = "Square"; break; case PAD_SHAPE_ROUND: shape = "Round"; break; case PAD_SHAPE_OCTAGON: shape = "Octagon"; break; case PAD_SHAPE_LONG: shape = "Long"; break; case PAD_SHAPE_OFFSET: shape = "Offset"; break; } printf("CHANGE DRILL %f;\n", scu(C.pad.drill)); printf("PAD %f %s R%.1f %s '%s' (%f %f);\n", scu(C.pad.diameter[LAYER_PADS]), shape, C.pad.angle, flags, format_name(C.pad.name), scu(C.pad.x), scu(C.pad.y) ); } else if (C.smd) { if ( !(C.smd.flags & SMD_FLAG_STOP) ) flags += " NOSTOP"; if ( !(C.smd.flags & SMD_FLAG_THERMALS) ) flags += " NOTHERMALS"; if ( !(C.smd.flags & SMD_FLAG_CREAM) ) flags += " NOCREAM"; layer(C.smd.layer); printf("SMD %f %f -%d R%.1f %s '%s' (%f %f);\n", scu(C.smd.dx), scu(C.smd.dy), C.smd.roundness, C.smd.angle, flags, format_name(C.smd.name), scu(C.smd.x), scu(C.smd.y) ); } } void export_frame(UL_FRAME F) { layer(F.layer); string borders = ""; if (F.border & FRAME_BORDER_BOTTOM) borders += " Bottom"; if (F.border & FRAME_BORDER_RIGHT) borders += " Right"; if (F.border & FRAME_BORDER_TOP) borders += " Top"; if (F.border & FRAME_BORDER_LEFT) borders += " Left"; printf("FRAME %d %d%s (%f %f) (%f %f);\n", F.columns, F.rows, borders, scu(F.x1), scu(F.y1), scu(F.x2), scu(F.y2) ); } void export_hole(UL_HOLE H) { printf("CHANGE DRILL %f;\n", scu(H.drill)); printf("HOLE (%f %f);\n", scu(H.x), scu(H.y) ); } void export_pin(UL_PIN P) { string direction; switch (P.direction) { case PIN_DIRECTION_NC: direction = "NC"; break; case PIN_DIRECTION_IN: direction = "In"; break; case PIN_DIRECTION_OUT: direction = "Out"; break; case PIN_DIRECTION_IO: direction = "I/O"; break; case PIN_DIRECTION_OC: direction = "OC"; break; case PIN_DIRECTION_PWR: direction = "Pwr"; break; case PIN_DIRECTION_PAS: direction = "Pas"; break; case PIN_DIRECTION_HIZ: direction = "Hiz"; break; case PIN_DIRECTION_SUP: direction = "Sup"; break; } string function; switch (P.function) { case PIN_FUNCTION_FLAG_NONE: function = "None"; break; case PIN_FUNCTION_FLAG_DOT: function = "Dot"; break; case PIN_FUNCTION_FLAG_CLK: function = "Clk"; break; case (PIN_FUNCTION_FLAG_DOT | PIN_FUNCTION_FLAG_CLK): function = "DotClk"; break; } string length; switch (P.length) { case PIN_LENGTH_POINT: length = "Point"; break; case PIN_LENGTH_SHORT: length = "Short"; break; case PIN_LENGTH_MIDDLE: length = "Middle"; break; case PIN_LENGTH_LONG: length = "LONG"; break; } string visible; switch (P.visible) { case PIN_VISIBLE_FLAG_OFF: visible = "Off"; break; case PIN_VISIBLE_FLAG_PIN: visible = "Pin"; break; case PIN_VISIBLE_FLAG_PAD: visible = "Pad"; break; case (PIN_VISIBLE_FLAG_PIN | PIN_VISIBLE_FLAG_PAD): visible = "Both"; break; } printf("PIN '%s' %s %s %s %s R%.0f %d (%f %f);\n", format_name(P.name), direction, function, length, visible, P.angle, P.swaplevel, scu(P.x), scu(P.y) ); } void export_polygon(UL_POLYGON P) { layer(P.layer); string pour; switch (P.pour) { case POLYGON_POUR_SOLID: pour = "Solid"; break; case POLYGON_POUR_HATCH: pour = "Hatch"; break; } printf("CHANGE ISOLATE %f;\n", scu(P.isolate)); printf("CHANGE ORPHANS %s;\n", (P.orphans) ? "On" : "Off"); printf("CHANGE POUR %s;\n", pour); printf("CHANGE SPACING %f;\n", scu(P.spacing)); printf("CHANGE THERMALS %s;\n", (P.thermals) ? "On" : "Off"); printf("CHANGE RANK %d;\n", P.rank); printf("POLYGON %f", scu(P.width)); /* Only the endpoints and the curve do matter in this case */ P.wires(W) { /* Starting point */ printf(" (%f %f)", scu(W.x1), scu(W.y1)); break; } P.wires(W) { /* Following segments */ printf(" %+f (%f %f)", W.curve, scu(W.x2), scu(W.y2) ); } printf(";\n"); } void export_rectangle(UL_RECTANGLE R) { layer(R.layer); printf("RECT R%.1f (%f %f) (%f %f);\n", R.angle, scu(R.x1), scu(R.y1), scu(R.x2), scu(R.y2) ); } void export_text(UL_TEXT T) { layer(T.layer); string font; switch (T.font) { case FONT_VECTOR: font = "VECTOR"; break; case FONT_PROPORTIONAL: font = "PROPORTIONAL"; break; case FONT_FIXED: font = "FIXED"; break; } string mirror = (T.mirror) ? "M" : ""; string spin = (T.spin) ? "S" : ""; printf("CHANGE RATIO %d;\n", T.ratio); printf("CHANGE SIZE %f;\n", scu(T.size)); printf("TEXT %s %s%sR%.1f (%f %f);\n", format_string(T.value), mirror, spin, T.angle, scu(T.x), scu(T.y) ); } void export_wire(UL_WIRE W) { layer(W.layer); string cap; switch (W.cap) { case CAP_FLAT: cap = "Flat"; break; case CAP_ROUND: cap = "Round"; break; } string style; switch (W.style) { case WIRE_STYLE_CONTINUOUS: style = "Continuous"; break; case WIRE_STYLE_LONGDASH: style = "LongDash"; break; case WIRE_STYLE_SHORTDASH: style = "ShortDash"; break; case WIRE_STYLE_DASHDOT: style = "DashDot"; break; } printf("CHANGE STYLE %s;\n", style); if (W.arc) { printf("WIRE %f %s (%f %f) %+f (%f %f);\n", scu(W.width), cap, scu(W.x1), scu(W.y1), W.curve, scu(W.x2), scu(W.y2) ); } else { printf("WIRE %f (%f %f) (%f %f);\n", scu(W.width), scu(W.x1), scu(W.y1), scu(W.x2), scu(W.y2) ); } } void export_package(UL_PACKAGE P) { /* Meta */ scu_mode = SCU_PACKAGE; current_layer = -1; printf("EDIT %s.pac;\n", P.name); printf("DESCRIPTION %s;\n", format_string(P.description)); /* Contents */ P.circles(C) export_circle(C); P.contacts(C) export_contact(C); P.frames(F) export_frame(F); P.holes(H) export_hole(H); P.polygons(P) export_polygon(P); P.rectangles(R) export_rectangle(R); P.texts(T) export_text(T); P.wires(W) export_wire(W); } void export_symbol(UL_SYMBOL S) { /* Meta */ scu_mode = SCU_SYMBOL; current_layer = -1; printf("EDIT %s.sym;\n", S.name); /* Contents */ S.circles(C) export_circle(C); S.frames(F) export_frame(F); S.rectangles(R) export_rectangle(R); S.pins(P) export_pin(P); S.polygons(P) export_polygon(P); S.texts(T) export_text(T); S.wires(W) export_wire(W); } void export_attributes(UL_ATTRIBUTE A) { string variable = (A.constant) ? "Constant" : "Variable"; printf("ATTRIBUTE '%s' %s %s;\n", format_name(A.name), format_string(A.value), variable ); } void export_deviceset(UL_DEVICESET DS) { /* Meta */ scu_mode = SCU_SYMBOL; printf("EDIT %s.dev;\n", format_name(DS.name)); printf("DESCRIPTION %s;\n", format_string(DS.description)); printf("PREFIX '%s';\n", format_name(DS.prefix)); printf("VALUE %s;\n", DS.value); DS.gates(G) { string addlevel; switch (G.addlevel) { case GATE_ADDLEVEL_NEXT: addlevel = "Next"; break; case GATE_ADDLEVEL_MUST: addlevel = "Must"; break; case GATE_ADDLEVEL_CAN: addlevel = "Can"; break; case GATE_ADDLEVEL_REQUEST: addlevel = "Request"; break; case GATE_ADDLEVEL_ALWAYS: addlevel = "Always"; break; } printf("CHANGE ADDLEVEL %s;\n", addlevel); printf("CHANGE SWAPLEVEL %d;\n", G.swaplevel); printf("ADD '%s' '%s' (%f %f);\n", format_name(G.symbol.name), format_name(G.name), scu(G.x), scu(G.y) ); } DS.devices(D) { if (D.package) { printf("PACKAGE '%s' '%s';\n", format_name(D.package.name), format_name(D.name) ); /* Technologies */ string technologies[]; int count = strsplit(technologies, D.technologies, ' '); for (int i = 0; i < count; i++) { string technology; if (technologies[i] == "''") technology = "''"; else technology = "'" + format_name(technologies[i]) + "'"; printf("TECHNOLOGY %s;\n", technology); /* Attributes */ D.attributes(A, technologies[i]) export_attributes(A); } } /* Connect them */ D.gates(G) { G.symbol.pins(P) { if (D.package && P.contact) { printf("CONNECT '%s.%s' '%s';\n", format_name(G.name), format_name(P.name), format_name(P.contact.name) ); } } } } } int result; string ulp = argv[0]; /* Find pass */ int pass = 1; if (argc > 1) { pass = strtol(argv[1]); if ( (pass < 1) || (pass > 4) ) pass = 1; } if (pass == 1) { /* First pass **************************************************/ int source_dir = 1; int update_only = 1; string source; string destination; string this_library; if (!library) { dlgMessageBox(";Den Skalierer bitte in einer Bibliothek ausführen."); exit(EXIT_FAILURE); } library(L) { this_library = L.name; string dir = strip_path(filedir(this_library)); source = dir + "/*.lbr"; destination = dir + "/sc"; } /* Legal check */ result = dlgMessageBox( "!Der Autor verfügt:
" "Dieses Werkzeug darf nur für nicht-kommerzielle Zwecke benutzt werden!", "+Ja, damit bin ich einverstanden", "-Nein, das lehne ich ab" ); if (result) /* Denied */ exit(EXIT_SUCCESS); /* Convert to percent */ scu_symbol *= 100.0; scu_package *= 100.0; result = dlgDialog("Super-Duper-Eagle-Skalierer") { dlgHBoxLayout dlgSpacing(400); dlgTabWidget { dlgTabPage("Skalierer") { dlgGroup("Skalierungsfaktoren") { dlgHBoxLayout { dlgLabel("Symbole:"); dlgStretch(1); dlgRealEdit(scu_symbol, 0.0, 100.0); dlgLabel("%"); } dlgHBoxLayout { dlgLabel("Gehäuse:"); dlgStretch(1); dlgRealEdit(scu_package, 0.0, 100.0); dlgLabel("%"); } } dlgGroup("Quellen") { dlgRadioButton("einzelne Bibliothek", source_dir) { source = this_library; } dlgRadioButton("ganzes Verzeichnis", source_dir); dlgLabel("Bibliothek(en):"); dlgHBoxLayout { dlgStringEdit(source); dlgPushButton("...") { string s = source; if (source_dir) source = dlgDirectory("Quell-Bibliotheksverzeichnis"); else source = dlgFileOpen("Quellbibliothek", "", "*.lbr"); if (source == "") source = s; else if (source_dir) source = strip_path(source) + "/*"; } } dlgCheckBox("Nur geänderte oder fehlende Bibliotheken bearbeiten", update_only); } dlgGroup("Ziel") { dlgLabel("Bibliotheksverzeichnis:"); dlgHBoxLayout { dlgStringEdit(destination); dlgPushButton("...") { string d = destination; destination = dlgDirectory("Ziel-Bibliotheksverzeichnis"); if (destination == "") destination = d; else destination = strip_path(destination); } } } } dlgTabPage("Hinweise") { dlgLabel("Hinweise zur Benutzung:"); dlgLabel("