// THIS PROGRAM IS PROVIDED AS IS AND WITHOUT WARRANTY OF ANY KIND, // EXPRESSED OR IMPLIED. /* * This EAGLE User Language Program generates a Script * file that can be used to renumber the parts of a Schematic. * In a sheet editor window you can Run this ULP * and then execute the command "script renumsch.scr". * This Version renumber only devices with package(no Supply). * -- This Version checks conflict by Symbols without Package * ****__Attention__***__Attention__***__Attention__***__Attention__*** * Please verify that your corresponding layout file * (if already existing) has been loaded with the schematic file. * Otherwise back-/forward-annotation will not work afterwards. ****__Attention__***__Attention__***__Attention__***__Attention__*** * * This ULP generates a script file RENUMSCH.SCR in order to * renumber elements in the schematic sorted by sheets and * coordinates (vertical/descending, horizontal/ascending). * After that run the script file. * * You can change the following sorting parameters: * descy = 0 (Y ascending) * descy = 1 (Y descending) * descx = 0 (X ascending [left >> right]) * descx = 1 (X descending [right >> left]) * * ------ hint ------- * Before running the script file reduce the editor window's * drawing area to a height of about 0.25 inch. This * speeds up redrawing the schematic. After that you can resize * the window. _____________________ GERMAN ___________________________________ *> _____________________________________________________________________ <* *> VERSION-2 testet ob NUR-Symbole wie SUPPLY, PORT, FRAME ... <* *> einen Konflikt bei der Namensvergabe erzeugen. <* *> Beispiel: <* *> Ein Port wurde zu R4, ein anderer zu R6 und ein weiterer zu <* *> IC1_PIN... umbenannt. Wird jetzt versucht mit NAME einem Widerstand <* *> den Namen R6 oder R4 zu vergeben, so meldet EAGLE : <* *> "Name R4 already exits!" obwohl es sich in diesem Fall nur um ein <* *> SYMBOL handelt aber den Name ist vorhanden. <* *> Deshalb darf ein 'NUR-Symbol' keinen Namen wie ein Device erhalten. <* *> _____________________________________________________________________ <* ****___ACHTUNG__***__ACHTUNG__***__ACHTUNG__***__ACHTUNG__*** * Stellen Sie sicher, dass ein fuer den Schaltplan * zugehoeriges Board, falls vorhanden, geladen ist, * da sonst die Konsistenz verloren geht. ****___ACHTUNG__***__ACHTUNG__***__ACHTUNG__***__ACHTUNG__*** * * Dieses RENUMSCH.ULP generiert ein Script um die Bauteile * im Schaltplan nach Seiten und Koordinaten (Vertikal/Absteigend * Horizontal/ Aufsteigend) neu zu numerieren. * Starten Sie anschliessend das Script RENUMSCH.SCR. * -- Diese Version numeriert nur Devices mit Packages * (keine Supply Symbole etc..). * * Zur Sortierung koennen Sie folgende Werte veraendern: * descy = 0 (Y Aufsteigend) * descy = 1 (Y Absteigend) * descx = 0 (X Aufsteigend [links >> rechts]) * descx = 1 (X Absteigend [rechts >> links ]) * * -------- Tip --------- * Verkleinern Sie vor dem Start des Script das Anwendungsfenster * das die Fenster-Zeichenflaeche nur ca. 5 MM Hoch ist, damit wird * das Bild schneller aufgebaut (bei jedem Seitenwechsel). * Anschliessend ziehen Sie das Anwendungsfenster wieder * auf die gewünschte Groesse. * * Author: A. Zaffran 04.10.1999 / 15.09.2000 alf@cadsoft.de */ string Version = "Version 2.0"; int descy = 1; // set to =0 sorting Y by ascending int descx = 0; // set to >0 sorting X by descending numeric string OldNames[], NewNames[]; int x[], y[], i[], sh[]; int nrNames = 0; numeric string SymNames[]; // Device-Name of Symbol int symsh[]; int sx[], sy[]; int Snr = 0; string error = ""; real Grid = 100; // in 100 Mil string lbr[], dev[], sym[]; int GetNumberIndex(string Name) { // Returns the index of the first digit of the numeric part of Name // -1 indicates there is no numeric part in Name int l = strlen(Name) - 1; for (int i = l; i >= 0; --i) { if (!isdigit(Name[i])) return i < l ? i + 1 : -1; } return 0; } void DescendingY(void) { for (int ny = 0; ny < nrNames ; ny++) { y[ny] = 0 - y[ny]; } } void DescendingX(void) { for (int nx = 0; nx < nrNames ; nx++) { x[nx] = 0 - x[nx]; } } void SortElements(void) { // Sorts the elements according to their location, first by ascending // x coordinates, then by ascending y coordinates. // If you prefer a different kind of sorting, you can implement this here. // As a result, the integer array i[] must contain the new sequence // in which to renumber the elements. if (descy) DescendingY(); if (descx) DescendingX(); sort(nrNames,i, sh, y, x); if (descy) DescendingY(); if (descx) DescendingX(); } void GenerateNames(void) { // Generates new numeric parts to the element names in NewNames for (int n = 0; n < nrNames - 1; ++n) { int k = 0; string s = NewNames[i[n]]; if (!isdigit(s[strlen(s) - 1])) { for (int j = n; j < nrNames; ++j) { if (NewNames[i[j]] == s) { if (sprintf(NewNames[i[j]], "%s%d", NewNames[i[j]], ++k) > ELEMENT_NAME_LENGTH) { printf("ERROR: name too long: '%s'\n", NewNames[i[j]]); exit(EXIT_FAILURE); } } } } } } void Rename(int x, int y, string New) { // Generates the EAGLE command necessary to change element name Old to New printf("Name '%s' (%d %d);\n", New, x, y); } void GenerateScript(void) { // Generates an EAGLE script file that does the whole renumbering. // The tricky part here is that we cannot rename an element to a name // that already exists in the schematic (which, e.g. might be necessary if // we had to swap the names of two elements). Therefore we have to // use a ScratchName wherever this is necessary. // If there is nothing to do, the resulting script file will be empty. int ScratchIndex = 0; string ScratchName; int sch = 0; for (int n = 0; n < nrNames; ++n) { if (sh[i[n]] != sch) { sch = sh[i[n]]; // *** change sheet printf("Edit .s%d;\n", sch); } if (OldNames[i[n]] != NewNames[i[n]]) { for (int k = n + 1; k < nrNames; ++k) { if (OldNames[i[k]] == NewNames[i[n]]) { sprintf(ScratchName, "$%0*d", ELEMENT_NAME_LENGTH - 1, ++ScratchIndex); if (sh[i[k]] != sch) { sch = sh[i[k]]; // *** change sheet printf("Edit .s%d;\n", sch); } Rename(x[i[k]],y[i[k]], ScratchName); if (sh[i[n]] != sch) { sch = sh[i[n]]; // *** change sheet printf("Edit .s%d;\n", sch); } OldNames[i[k]] = ScratchName; break; } } if (sh[i[n]] != sch) { sch = sh[i[n]]; // *** change sheet } Rename(x[i[n]],y[i[n]], NewNames[i[n]]); } } } // *** check collision befor rename *** string CheckNames(void) { string new_name = ";"; string h; for (int n = 0; n < nrNames - 1; ++n) { // make a long string new_name += NewNames[n] + ";"; } for (int xx = 0; xx < Snr - 1; xx++) { string sd = SymNames[xx]; if(sd[0] == '$') { // if first character a $ on Symbolname sprintf(h, "TEXT 'Rename %s on (%d %d) - sheet %d befor run this ULP again' (%d %d);\n", SymNames[xx], sx[xx], sy[xx], symsh[xx], sx[xx], sy[xx]); error += h; } int s; int pos = strrstr(new_name, ";" + SymNames[xx] + ";"); if (pos > 0 ) { for (s = 0; s < nrNames - 1; s++) { if(NewNames[s] == SymNames[xx]) { break; } } sprintf(h, "EDIT .S%d;\n", symsh[xx]); error += h; sprintf(h, "TEXT 'Rename %s on (%d %d) - sheet %d befor %s on (%d %d) - sheet %d' (%d %d);\n", SymNames[xx], sx[xx], sy[xx], symsh[xx], OldNames[s], x[s], y[s], sh[s], sx[xx], sy[xx]); error += h; } } return error; } void setgridmil (void) { printf("GRID MIL 100 OFF;\n"); printf("DISPLAY NONE 94 95 -96;\n"); } schematic(S) { int l = 1; S.sheets(SH) { SH.parts(P) { int n = GetNumberIndex(P.name); if (n > 0) { if (P.device.package) { // **** only Devices with Package // **** without Supply symbol Frames ect... P.instances(I) { int found = -1; for (int fn = 0; fn < nrNames; fn++) { if (OldNames[fn] == P.name) { found = fn; break; } } if (found < 0) { x[nrNames] = u2mil(I.x); // cannot use E.x/y directly because of y[nrNames] = u2mil(I.y); // sort() problem with integers > 32767 OldNames[nrNames] = P.name; // in version 3.50 NewNames[nrNames] = strsub(P.name, 0, n); sh[nrNames] = I.sheet; ++nrNames; } else { if (sh[fn] == I.sheet) { if ( u2mil(I.x) < x[fn] || u2mil(I.y) > y[fn] ) { // tausche wenn x kleiner oder y groesser x[fn] > u2mil(I.x); y[fn] > u2mil(I.y); } } } } } // check Symbol (Supply, Port, Frame...) without Package else { // *** check PartName on Symbols Supply, Port, Frame ... *** P.instances(I) { SymNames[Snr] = P.name; // Device-Name of Symbol sx[Snr] = u2mil(I.x) + 10; // cannot use E.x/y directly because of sy[Snr] = u2mil(I.y) + 10; // sort() problem with integers > 32767 symsh[Snr] = I.sheet; ++Snr; } } } } } SortElements(); GenerateNames(); output("renumsch.scr", "wt") { printf("TEXT 'This file is generated by RENUMSCH2 %s, exported from;\n", Version); printf("TEXT '%s at %s;\n", S.name, t2string(time())); printf("TEXT '%s;\n", EAGLE_SIGNATURE); if (CheckNames()) { setgridmil(); printf("CHANGE SIZE 100;\n"); printf("CHANGE Layer 93;\n"); printf("DISPLAY NONE 93;\n"); printf(error); printf("DISPLAY 93 94 95 -96 ;\n"); exit (0); } setgridmil (); GenerateScript(); printf("GRID INCH 0.1;\n"); printf("DISP NONE;\nDISP ALL;\n"); printf("EDIT .S1;\n"); } }