#usage "de:Exportiert/speichert DRC & ERC Errors

" "RUN export-errors [Save] [Filename]
" "author alf@cadsoft.de" , "en:Export/save DRC & ERC errors

" "RUN export-errors [Save] [Filename]
" "author alf@cadsoft.de" #require 7.01.03; string Version = "1.0.0"; // 2014-11-11 alf@cadsoft.de string HeaderErcErrors; string HeaderDrcErrors; string SaveErrorFileName = ""; string Option1 = strupr(argv[1]); int CntErrorInconsistenc = 0; int Consistence = 0; string ExistSCHfile = ""; string ExistBRDfile = ""; string ErrorList[]; int CntError = 0; int Debug = 0; /* Die Member layer und contours() sind nur im UL_BOARD Kontext und die Member area2, modulename, s1..s6 und sheet sind nur im UL_SCHEMATIC Kontext verfügbar. */ int ErrBx1[], ErrBy1[], ErrBx2[], ErrBy2[]; // area UL_AREA nur im Board int ErrSx1[], ErrSy1[], ErrSx2[], ErrSy2[]; // area2 UL_AREA nur im Schaltplan int ErrCode[]; // Identifikations-Nummer string ErrDescription[]; int ErrLayer[]; string ErrModulename[]; string ErrS1[], ErrS2[], ErrS3[], ErrS4[], ErrS5[], ErrS6[]; int ErrSheet[]; // int Seitennummer string ErrSignature[]; // string (Signatur-String) state int ErrState[]; // int (ERROR_STATE_...) int ErrType[]; // int (ERROR_TYPE_...) int ErrX[], ErrY[]; // int (Mittelpunkt) string ErrorState[], ErrorType[]; ErrorState[ERROR_STATE_ACTIVE] = "error has not yet been approved or processed"; ErrorState[ERROR_STATE_APPROVED] = "error has been approved"; ErrorState[ERROR_STATE_PROCESSED] = " error has been processed"; ErrorType[ERROR_TYPE_NONE] = "no error"; ErrorType[ERROR_TYPE_WARNING] = "warning"; ErrorType[ERROR_TYPE_ERROR] = "error"; ErrorType[ERROR_TYPE_CONSISTENCY] = "consistency error"; HeaderErcErrors = "Consistency not checked (no board loaded)"; if (language() == "de") { ErrorState[ERROR_STATE_ACTIVE] = "Fehler wurde weder bearbeitet, noch gebilligt"; ErrorState[ERROR_STATE_APPROVED] = "Fehler wurde gebilligt"; ErrorState[ERROR_STATE_PROCESSED] = "Fehler wurde bearbeitet"; ErrorType[ERROR_TYPE_NONE] = "kein Fehler"; ErrorType[ERROR_TYPE_WARNING] = "Warnung"; ErrorType[ERROR_TYPE_ERROR] = "Fehler"; ErrorType[ERROR_TYPE_CONSISTENCY] = "Konsistenz-Fehler"; HeaderErcErrors = "Konsistenz nicht geprüft (kein Board geladen)"; } string s; /* ### ERROR functions ### */ void error_3(int sel) { sprintf(s, "RUN ulpmessage 'Signatur:%s
Description:%s
Layer:%d
'", ErrSignature[sel], ErrDescription[sel], ErrLayer[sel] ); exit(s); } void error_5(int sel) { real x = u2mm(ErrSx2[sel]) - u2mm(ErrSx1[sel]); real y = u2mm(ErrSy2[sel]) - u2mm(ErrSy1[sel]); if (x < y) { sprintf(s, "Win (%.8fmm %.8fmm);\nRUN ulpmessage 'der Abstand in x ist um %.8fmm zu klein.'", u2mm(ErrX[sel]), u2mm(ErrY[sel]), x ); } else if (y < x) { sprintf(s, "Win (%.8fmm %.8fmm);\nRUN ulpmessage 'der Abstand in y ist um %.8fmm zu klein.'", u2mm(ErrX[sel]), u2mm(ErrY[sel]), y ); } else { sprintf(s, "Win (%.8fmm %.8fmm);\nRUN ulpmessage 'der Abstand in x & y ist jeweils um %.8fmm zu klein.'", u2mm(ErrX[sel]), u2mm(ErrY[sel]), y ); } exit(s); } void error_11(int sel) { sprintf(s, "DISPLAY NONE %d;\nWINDOW (%.8fmm %.8fmm);\nCHANGE FONT Vector (%.8fmm %.8fmm);\nDISPLAY LAST;", ErrLayer[sel], u2mm(ErrX[sel]), u2mm(ErrY[sel]), u2mm(ErrX[sel]), u2mm(ErrY[sel]) ); exit(s); } void checkerror(int sel) { int ecod = ErrCode[sel]; switch(ecod) { case 1 : // Drill Size break; case 2 : // Drill Distance break; case 3 : // Width break; case 4 : // Dimension break; case 5 : // Clearance break; case 6 : // Restrict break; case 7 : // Keepout break; case 8 : // Angle break; case 9 : // Off Grid break; case 11 : // No Vector Font break; case 19 : // Overlap break; case 101 : // Nicht angeschlossener Pin break; case 102 : // SUPPLY-Pin überschrieben mit xxx break; case 103 : // NC-Pin IC3 xxxx verbunden mit xx break; case 104 : // POWER-Pin verbunden mit xxx break; case 105 : // Keine Pins an Netz xxx break; case 106 : // Nur ein Pin an Netz xxx break; case 107 : // Junction verbindet Netze xx und xx scheinbar break; case 108 : // Fehlende Junction in Netz xxx break; case 109 : // Nahe beieinander liegende, aber unverbundene Linien in Netz xx break; case 110 : // Nahe beeinander liegende, aber unverbundene Linien in Netzen xxx und xxx break; case 111 : // Netz xxx überlappt Pin break; case 112 : // Pins überlappen break; case 113 : // Part has no value break; case 115 : // Segment des Netzes XXX hat keine erkennbare Verbindung (z.B. Label, Bus oder Supply-Pin) zu anderen Segmenten des selben Netzes break; case 116 : // Pin an XXXX angeschlossen ohne Netz-Wire, Junction oder anderen Pin break; case 118 : // Netz benutzt durch Port xxx hat kein Label break; case 119 : // Es existiert kein Modul Netz für Port xxxx break; case 120 : // Bus A[0..15] überlappt Port break; case 121 : // Netz L1 überlappt Port break; case 201 : // SUPPLY-Pin überschrieben mit mehr als einem Signal break; case 202 : // not connected input pin break; case 205 : // no Supply-Pin for implizit Power pin break; case 206 : // Mehr als ein OUTPUT-Pin an Netz xx break; case 209 : // Nur INPUT-Pins an Netz xxx break; case 211 : // Netzname XXX ist im Bus xxxxxx nicht enthalten break; case 213 : // Direction 'io' von Port KB0 ist nicht kompatibel mit den Pins am Netz im Modul break; case 304 : // element not found on board break; case 305 : // part not found on schematic break; default : sprintf(s, "Error-Code %d: unknown!", ecod); dlgDialog("Error") { dlgHBoxLayout dlgSpacing(600); dlgStringEdit(ErrDescription[sel]); dlgLabel(s); dlgHBoxLayout { dlgStretch(1); dlgPushButton("+OK") dlgAccept(); dlgPushButton("-CANCEL") { dlgReject(); exit(-1); } dlgStretch(1); } }; } } /* *** normal functions *** */ string checkexistfile(string existfile) { string a[]; int cnt = fileglob(a, existfile); if (cnt) return a[0]; return ""; } void savefile(string sourcefilename, string editname) { output(SaveErrorFileName, "wt") { printf("#Exported from: \"%s\"\n#with %s Version %s\n", sourcefilename, filename(argv[0]), Version); printf("#%s\n", EAGLE_SIGNATURE); printf("#at:%s\n", t2string(time()) ); if (CntErrorInconsistenc) { //if (ExistSCHfile) printf("%s\n",ExistSCHfile); //if (ExistBRDfile) printf("%s\n",ExistBRDfile); printf("%s\n", HeaderErcErrors); } else { printf("%s\n", HeaderErcErrors); } for (int n = 0; n < CntError; n++) { printf("%s\n", ErrorList[n]); } } } void saveerrors(string header, string sourcefilename, string errorfilename) { string a[]; int fexist = fileglob(a, errorfilename); int xl = 30 + strlen(errorfilename) * 5; dlgDialog(header) { dlgHBoxLayout dlgSpacing(xl); dlgStringEdit(errorfilename); dlgHBoxLayout { if (fexist) { if (language() == "de") { dlgLabel("Datei existiert bereits... "); dlgPushButton("Überschreiben") { dlgAccept(); savefile(sourcefilename, errorfilename); exit(0); } } else { dlgLabel("File exist... "); dlgPushButton("Overwrite") { dlgAccept(); savefile(sourcefilename, errorfilename); exit(0); } } } else { dlgPushButton("+OK") { dlgAccept(); savefile(sourcefilename, errorfilename); exit(0); } } dlgPushButton("+CANCEL") { dlgReject(); exit(-2); } dlgStretch(1); } }; } void saveerrdialog(string dialogheader, string listheader, string sourcefilename) { string consistenceleader; string consistencetrailer; if (schematic) { if (CntErrorInconsistenc) { //if (ExistSCHfile) printf("%s\n",ExistSCHfile); //if (ExistBRDfile) printf("%s\n",ExistBRDfile); } else { consistenceleader = ""; consistencetrailer = ""; } if (Consistence) { ExistSCHfile = ""; ExistBRDfile = ""; consistenceleader = ""; consistencetrailer = ""; } } if (board) { ExistSCHfile = ""; ExistBRDfile = ""; consistenceleader = ""; consistencetrailer = ""; } dlgDialog(dialogheader) { int sel = -1; int srt = 0; dlgHBoxLayout dlgSpacing(800); if (ExistSCHfile) dlgLabel(ExistSCHfile); if (ExistBRDfile) dlgLabel(ExistBRDfile); dlgLabel(consistenceleader + HeaderErcErrors + consistencetrailer); dlgHBoxLayout { dlgVBoxLayout dlgSpacing(400); dlgListView(listheader, ErrorList, sel, srt) checkerror(sel); } dlgHBoxLayout { dlgStretch(1); dlgPushButton("+OK") dlgAccept(); dlgPushButton("&Save") saveerrors("Save ERC-ERRORS", sourcefilename, SaveErrorFileName); dlgStretch(1); } }; } if (schematic) { schematic(SCH) { if (!SCH.checked) { string msg = "Schematic is changed, first start Electrical Rule Check (ERC)!"; if (language() == "de") msg = "Der Schaltplan wurde verändert, starten sie zuerst den Electrical Rule Check!"; if (dlgMessageBox(msg, "OK", "CANCEL") != 0) exit(-3); string cmd; sprintf(cmd, "ERC; RUN '%s'", argv[0]); exit (cmd); } ExistSCHfile = "SCH File loaded: \"" + SCH.name + "\""; ExistBRDfile = "BRD File exist : \"" + checkexistfile(filesetext(SCH.name, ".brd")) + "\""; if(project.board) { Consistence = 1; HeaderErcErrors = "Baord and schematic are consistent"; if (language() == "de") HeaderErcErrors = "Board und Schaltplan sind konsistent"; } else Consistence = 0; SCH.errors(E) { if (E.type == ERROR_TYPE_CONSISTENCY) CntErrorInconsistenc++; ErrSignature[CntError] = E.signature; ErrSx1[CntError] = E.area.x1; ErrSy1[CntError] = E.area.y1; ErrSx2[CntError] = E.area.x2; ErrSy2[CntError] = E.area.y2; ErrBx1[CntError] = E.area2.x1;// Das Member area2 ist eine zweite UL_AREA, die nur im Schaltplan bei einzelnen ERC-Fehlern die entsprechende Region im Board angibt. ErrBy1[CntError] = E.area2.y1; ErrBx2[CntError] = E.area2.x2; ErrBy2[CntError] = E.area2.y2; ErrCode[CntError] = E.code; ErrDescription[CntError] = E.description; ErrLayer[CntError] = E.layer; ErrModulename[CntError] = E.modulename; ErrS1[CntError] = E.s1; ErrS2[CntError] = E.s2; ErrS3[CntError] = E.s3; ErrS4[CntError] = E.s4; ErrS5[CntError] = E.s5; ErrS6[CntError] = E.s6; ErrX[CntError] = E.x; ErrY[CntError] = E.y; ErrSheet[CntError] = E.sheet; ErrState[CntError] = E.state; ErrType[CntError] = E.type; if (Debug) checkerror(CntError); sprintf(ErrorList[CntError], "%s\t%s\t%d\t%s\t%s\t%s\t%d\t%d\t%d\t%d", ErrorType[E.type], E.description, E.sheet, E.modulename, E.signature, ErrorState[E.state], ErrSx1[CntError], ErrSy1[CntError], ErrSx2[CntError], ErrSy2[CntError] ); CntError++; } if (CntErrorInconsistenc) { sprintf(HeaderErcErrors, "Consistence Error(%d).", CntErrorInconsistenc); if (language() == "de") sprintf(HeaderErcErrors, "Konsistenzfehler (%d)", CntErrorInconsistenc); } else { if (Consistence) { HeaderErcErrors = "Board and Schematic are consistent."; if (language() == "de") HeaderErcErrors = "Board und Schematic sind konsistent"; } } if (Option1 == "SAVE") { if (!argv[2]) { SaveErrorFileName = filesetext(SCH.name, ".erc.err"); saveerrors("Save ERC-ERRORS", SCH.name, SaveErrorFileName); } else { SaveErrorFileName = argv[2]; } savefile(SaveErrorFileName, SCH.name); } else { SaveErrorFileName = filesetext(SCH.name, ".erc.err"); string listheader = "Type\tDesciption\tSheet\tModul\tSignatur\tState\tAreaX1\tAreaY1\tAreaX2\tAreaY2"; if (language() == "de") listheader = "Type\tBeschreibung\tSeite\tModul\tSignatur\tStatus\tAreaX1\tAreaY1\tAreaX2\tAreaY2"; saveerrdialog("ERRORS ERC)", listheader, SCH.name); } } } else if (board) { board(BRD) { if (!BRD.checked) { string msg = "Board is changed, first start Design Rile Check (DRC)!"; if (language() == "de") msg = "Board wurde verändert, starten sie zuerst den Design Rule Check! (DRC)"; if (dlgMessageBox(msg, "OK", "CANCEL") != 0) exit(-4); string cmd; sprintf(cmd, "DRC; RUN '%s'", argv[0]); exit (cmd); } ExistBRDfile = "BRD File loaded: " + BRD.name; ExistSCHfile = "SCH File exist : " + checkexistfile(filesetext(BRD.name, ".sch")); if(project.schematic) { Consistence = 1; } else Consistence = 0; BRD.errors(E) { ErrSignature[CntError] = E.signature; ErrSx1[CntError] = E.area.x1; ErrSy1[CntError] = E.area.y1; ErrSx2[CntError] = E.area.x2; ErrSy2[CntError] = E.area.y2; ErrBx1[CntError] = E.area2.x1;// Das Member area2 ist eine zweite UL_AREA, die nur im Schaltplan bei einzelnen ERC-Fehlern die entsprechende Region im Board angibt. ErrBy1[CntError] = E.area2.y1; ErrBx2[CntError] = E.area2.x2; ErrBy2[CntError] = E.area2.y2; ErrCode[CntError] = E.code; ErrDescription[CntError] = E.description; ErrLayer[CntError] = E.layer; ErrModulename[CntError] = E.modulename; ErrS1[CntError] = E.s1; ErrS2[CntError] = E.s2; ErrS3[CntError] = E.s3; ErrS4[CntError] = E.s4; ErrS5[CntError] = E.s5; ErrS6[CntError] = E.s6; ErrX[CntError] = E.x; ErrY[CntError] = E.y; ErrSheet[CntError] = E.sheet; ErrState[CntError] = E.state; ErrType[CntError] = E.type; if (Debug) checkerror(CntError); sprintf(ErrorList[CntError], "%s\t%s\t%d\t%s\t%s\t%d\t%d\t%d\t%d\t%s", ErrorType[E.type], E.description, E.layer, E.signature, ErrorState[E.state], ErrSx1[CntError], ErrSy1[CntError], ErrSx2[CntError], ErrSy2[CntError], "" ); CntError++; } sprintf(HeaderErcErrors, "Error (%d)", CntError); if (language() == "de") sprintf(HeaderErcErrors, "Fehler (%d)", CntError); if (Option1 == "SAVE") { if (!argv[2]) { SaveErrorFileName = filesetext(BRD.name, ".drc.err"); saveerrors("Save DRC-ERRORS", BRD.name, SaveErrorFileName); } else { SaveErrorFileName = argv[2]; } savefile(SaveErrorFileName, BRD.name); } else { SaveErrorFileName = filesetext(BRD.name, ".drc.err"); string listheader = "Type\tDesciption\tLayer\tSigatur\tState\tAreaX1\tAreaY1\tAreaX2\tAreaY2"; if (language() == "de") listheader = "Type\tBeschreibung\tLayer\tSigatur\tStatus\tAreaX1\tAreaY1\tAreaX2\tAreaY2"; saveerrdialog("ERRORS DRC", listheader, BRD.name); } } } else { dlgMessageBox("Start this ULP in a schematic or board.", "OK"); exit(0); }