485 lines
16 KiB
Plaintext
485 lines
16 KiB
Plaintext
#usage "de:Exportiert/speichert DRC & ERC Errors<p>"
|
|
"RUN export-errors [Save] [Filename]<br>"
|
|
"<author>author alf@cadsoft.de</author>"
|
|
,
|
|
"en:Export/save DRC & ERC errors<p>"
|
|
"RUN export-errors [Save] [Filename]<br>"
|
|
"<author>author alf@cadsoft.de</author>"
|
|
|
|
#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<br>Description:%s<br>Layer:%d<br>'",
|
|
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 = "<font color =\"red\"><b>";
|
|
consistencetrailer = "</b></font>";
|
|
}
|
|
if (Consistence) {
|
|
ExistSCHfile = "";
|
|
ExistBRDfile = "";
|
|
consistenceleader = "<font color =\"green\"><b>";
|
|
consistencetrailer = "</b></font>";
|
|
}
|
|
}
|
|
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);
|
|
}
|
|
|