Um auch dem Anwender entsprechende Möglichkeiten zu bieten, an Daten innerhalb der EAGLE Dateien zu kommen, wurde die User Language integriert.
Hier handelt es sich um einen integrierten abgespeckten C-Compiler mit speziellen integrierten C-Funktionen und vereinfachten Variablen-Definitionen.
Wer hier den vollem Umfang der 'C' Sprache vermisst darf sich also nicht wundern. Schließlich ist EAGLE wie gesagt ein CAD-Programm und kein C-Compiler.
Aus diesem Grund gibt es auch keinen Debugger, sondern nur den Parser der bei einem Syntax-Fehler das Compilieren beendet und auf den Fehler im Quelltext verweist.
Und hier beginnt die Herausforderung der Spache 'C'.
Der Parser beendet bei Erkennung eines Syntaxfehler, und zeigt auf die Zeile im Quelltext. Was aber nicht bedeutet, dass der eigentliche Fehler auch hier zu finden ist.
Der Fehler kann in der angezeigten Zeile enthalten sein, er kann aber auch eine oder mehrere Zeilen weiter vorne im Quelltext sein.
Bei entsprechder Verschachtelung, Schlüsselwörter (Keywords) und Punctuator-Zeichen in komplexeren ULPs, kann der Fehler auch sehr weiter vorne im Quelltext sein.
Es reicht schon eine geschweifte Klammer { oder } zu viel oder zu wenig, und der Fehler wird u.U. erst am Dateiende erkannt.
Was der Parser nicht erkennen kann, ist der richtige Aufbau/Funktion des Programm. Ebenso die falsche Benutzung von Variablen.
Wo der Parser hilfreich ist, bei der Erkennung von Variablen-Definitionen und Benutzung.
Das bedeutet, der Parser meldet jede Benutzung einer Variablen/Funktion die nicht vorher vereinbart wurde.
Hier wird auch klein-GROSS-Schreibung unterschieden. Wird also eine Variable "wert" definiert, aber später im Programm auf "Wert" zugegriffen .... Parserfehler!
Auch bei Übergabe von Parametern an Funktionen muß auf die Anzahl und Art der Parameter übereinstimmen.
Ich unterlass es hier auf diese Themen weiter eizugehen, da es in der HILFE von EAGLE entsprechend beschrieben ist.
Einfach HELP + ENTER und dann im Hilfemenü in der Themenspalte auf "User Language" klicken und die entsprechende Rubkrik wählen.
Und nun zu den Debug Möglichkeiten:
Auch wenn der Parser keinen Fehler meldet und das ULP scheinbar Funktioniert, kann es sein, dass es nicht das tut was es soll.Und hier kommen Debugzeilen ins Spiel.
Ich habe mir angewöhnt zum Debuggen eine Zeile wie if (gldMessageBox("nachricht", "weiter", "esc#123#") == 1) exit(-123); an entsprechender Stelle zu schreiben.
Damit kann man mit "nachricht" auch den Inhalt von Variablen anzeigen, mit "weiter" den Programmablauf fortführen, und mit "esc..." das ULP beenden.
Warum die Zeichenfolge #123# ?
1. # ist zugleich in jedem SCRIPT das Einleitungszeichen zu einem Kommentar, ab dem der Script-Parser die weiteren Zeichen der Zeile nicht beachtet. Siehe auch eagle.scr.
2. 123 soll die Zeilennummer im Quelltext des ULP sein. Hier macht sich notepad++ zum Freund, da links im Editorfenster zu jeder Zeile die Zeilennummer steht.
3. exit(-123); Wird ein ULP beendet und eine Zahl mit einem negativen Vorzeichen zurückgegeben, zeigt EAGLE das in der Statuszeile an.
Damit kann man erkennen, ob das ULP mit einem Fehlercode beendet wurde, und man kann jetzt im Quellcode nachsehen, wo und warum hier beendet wurde.
4. Die Kombination von #nnn# ist explizit so gewählt, denn ich habe mir ein ULP geschrieben, dass den Quelltext nach dieser Kombination durchsucht und die
entsprechende Zeilennummer einträgt.
Da sich beim Erstellen eines ULP die entsprechenden Zeilen i.d.R. verschieben, möchte ich nicht ständig diese Nummern von Hand anpassen.
Das erledigt mir das ULP-exit-nummerierung.ulp.
Ist das Ergebnis des ULP korrekt, können diese Zeilen wieder entfernt werden, oder sie verbleiben im Quelltext und werden um die Variable Debug erweitert.
if (Debug) if (gldMessageBox("nachricht", "weiter", "esc#123#") == 1) exit(-123);
Bei komplexeren ULPs die ich immer wieder erweitere oder anpasse, belasse ich diese Zeilen im Quelltext, und schalte das "Debuggen" nur ein oder aus.
Dazu steht dann ziemlich am Anfang des ULP die Zeile
int Debug = 0;
Möchte ich jetzt zur Analyse die Debugzeilen aktivieren, dann Debug = 1;
Will ich aber nur gezielt an bestimmten Stellen etwas anzeigen, denn invertiere ich die Debug-Variable an dieser Stelle mit !.
if (!Debug) if (gldMessageBox("nachricht", "weiter", "esc#123#") == 1) exit(-123);
Noch ein Wort zu den Rückgabewerten eines ULP an die EAGLE-Kommandozeile.
- exit(0); Der Wert 0 bzw. das Beenden eines ULP ohne Rückgabewert erzeugt keine Anzeige in der Statuszeile.
- exit(-123); Ein negative Zahl teilt EAGLE mit, dass das ULP mit einem Fehler beendet wurde und zeigt ihn in der Statuszeile.
- exit(Befehls-String); Hier werden die im ULP erzeugen Befehle an die Kommandozeile zurück gegeben [1].
- exit(SCRIPT 'dateiname'); Das ULP schreibt die Eagle-Befehle in eine .scr Datei [2] und man gibt den Aufruf des Script zurück. exit(SCRIPT 'C:/erzeugte-befehle.scr') [3].
[2] Wird eine Folge von EAGLE-Befehlen an die Kommandozeile zurückgegeben, werden diese ausgeführt als ob sie eingegeben wurden.
Der Nachteil, wird ein Fehler erkannt, stoppt EAGLE die Ausführung und zeigt den entsprechenden Fehler, wobei man u.U. nicht erkennen kann
wo in der Menge der Befehle der Fehler ist.
Gibt man eine SCRIPT-Datei zurück, dann wird in der Stauszeile ein Verlaufsbalken mit der Vortschittsanzeige und der Prozentzahl angezeigt,
damit kann man schon mal erkennen wie lange es nocht dauert um das Script abzuarbeiten.
Wird jetzt ein Fehler erkannt, dann meldet EAGLE in welcher Zeile des Script der Fehler aufgetreten ist.
Hier kommt wieder das # Zeichen ins Spiel. Es macht sich zur Fehlerfindung zum Vorteil, wenn man in diversen printf() Anweisungen auch #123# einbaut.
Dann kann man im Script erkennen, in welcher Zeile bzw. funktion() des ULP diese Scriptzeile erzeugt wurde, und kann gezielt den Fehler beheben.
Hinweis: Werden die erzeugten EAGLE-Befehle direkt an die Kommandozeile zurückgegeben [1], darf #...# nicht Vorkommen, das ist nur in einer Script-Datei erlaubt.
[3] Die erzeugten EAGLE-Befehle werden zur Laufzeit des ULP in eine Script-Datei geschrieben und beim Beenden des ULP diese Datei mit exit(SCRIPT 'dateiname.scr');
an die EAGLE-Kommandizeile zurückgegeben.
Man sollte sich angewöhnen, in der Kommandozeile wie auch bei einem Script-Aufruf als Rückgabewert den Dateinamen in ' Apostrophen ' zu setzen.
Der Grund, sollte im Pfad/Dateinamen ein SPACE vorkommen, dann trennt der Script-Parser die Kommando-Optionen hier, und meldet dass die Datei nicht gefunden wird.
Die folgenden Teile des Dateinamen werden dann schon wieder als EAGLE-Befehle interpretiert und es werden weitere Fehlermeldungen erzeugt.
Alles was in ' Apostrophen ' eingeschlossen wird, wird als ein Wort betrachtet.
Aber auch Apostrophen in Parameter-Optionen machen es nicht leicht.
Es gibt ja auch die leeren Packagevarianten und Technologien in den Devicesets der Bibliotheken.
Sollte also ein ULP Packagevarianten oder Technologien in einer Bibliothek erzeugen, dann müssen die Apostrophen verdoppelt werden.
Beispiele wie man das macht, sind in diversen ULPs enthalten. Wie auch in dem cmd-scale-xy-pac-sym.ulp.