Files
dxfmakros/doc/dbg2lsp.md
T
m.stangl d7bcfc3edb [ADD] dbg2lsp.py: AutoLISP-Funktionen automatisch mit ssg_dbg instrumentieren
Neues Entwickler-Tool (bin/dbg2lsp.bat + lib/dbg2lsp.py), das das manuelle
Einfuegen von dbgf/dbg/dbgreturn/dbgopen/dbgclose automatisiert:
- --method NAME: dbgf + dbg je Parameter + dbgreturn um die letzte Rumpf-Form
- --recursive: verfolgt den Aufrufgraphen ueber Dateigrenzen hinweg (Builtins
  werden automatisch uebersprungen, da sie kein defun im Suchpfad haben)
- --add-open DATEI METHODE: dbgopen/dbgclose fuer einen Einstiegspunkt
  (z.B. ein c:BEFEHL-Kommando), inkl. aller (exit)-Stellen
Dokumentiert in doc/dbg2lsp.md, Kurzeintrag in CLAUDE.md.

Ausserdem: set_attributs.py aus doc/tools.md und CLAUDE.md entfernt - das
Skript existiert nicht mehr in lib/.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-28 15:04:45 +02:00

8.9 KiB

dbg2lsp

Instrumentiert AutoLISP-Funktionen (.lsp) automatisch mit den ssg_dbg.lsp-Routinen (dbgf, dbg, dbgreturn, dbgopen, dbgclose) - so wie es beim manuellen Debuggen bereits von Hand gemacht wird (siehe z.B. Lisp/KreiselInsert.lsp::ils-eckrad-insert). Erspart das muehsame und fehleranfaellige manuelle Einfuegen dieser Aufrufe in lange Aufrufketten (Kreisel/VarioFoerderer/Gefaellestrecke/Separator-Scanner o.ae.), bevor ein Testlauf in BricsCAD gestartet wird.

Aufruf

bin\dbg2lsp.bat <datei.lsp> [--method NAME ...] [--recursive] [--add-open DATEI METHODE] [Schalter]

Das Batch-Skript ruft setenv.bat auf und startet lib/dbg2lsp.py mit den uebergebenen Argumenten. <datei.lsp> dient als Anker (ihr Verzeichnis wird immer mitdurchsucht) - die gesuchte Funktion muss nicht zwingend in genau dieser Datei stehen, siehe Funktionsweise.

Was wird eingefuegt

--method

Fuer die angegebene Funktion (mehrfach angebbar) wird direkt als erste Rumpf-Form

(dbgf "funktionsname")
(dbg 'parameter1)
(dbg 'parameter2)
...

eingefuegt (ein dbg-Aufruf je Eingabeparameter - die Locals nach / in der Parameterliste NICHT, das sind keine Eingabewerte), und die letzte Form des Funktionsrumpfs wird eingeklammert:

(dbgreturn <letzte Rumpf-Form>)

dbgreturn loggt und liefert den Rueckgabewert unveraendert weiter (siehe Lisp/ssg_dbg.lsp) - das Verhalten der Funktion aendert sich dadurch nicht.

--recursive

Verfolgt zusaetzlich den Aufrufgraphen: jede Funktion, die im (Original-)Rumpf aufgerufen wird - auch beliebig verschachtelt, z.B. in einem if/progn, aber NICHT innerhalb einer 'quotierten Liste (die ist reine Datenliste, z.B. '(("OSMODE") ("CECOLOR"))) - wird ebenfalls mit --method-Logik instrumentiert, sofern sich ihr (defun ...) in einem der durchsuchten Verzeichnisse findet.

AutoLISP-/BricsCAD-Builtins (princ, command, strcat, rtos, entmake, vla-*, ...) haben dort naturgemaess kein defun und werden dadurch automatisch nicht angefasst - es gibt keine Builtin-Blacklist zu pflegen. Die ssg_dbg.lsp-Funktionen selbst (dbgf, dbg, dbgp, dbgmsg, dbgreturn, dbgopen, dbgclose, dbgflush, dbgon, dbgoff und ihre internen dbg-*-Helfer) sind fest ausgeschlossen, damit eine bereits instrumentierte Funktion nicht dazu fuehrt, dass das Debug-Framework sich selbst instrumentiert.

Bereits instrumentierte Funktionen werden uebersprungen (siehe Idempotenz), ihr Rumpf wird aber trotzdem nach weiteren, noch nicht instrumentierten Aufrufen durchsucht - die Rekursion bricht dadurch nicht an einer schon bearbeiteten Stelle ab.

--add-open

Fuegt in der angegebenen Methode (typischerweise ein c:BEFEHL-Kommando, das einen ganzen Testlauf umspannt) ein:

(dbgopen "<dbg-datei>" "<envvar>")

als erste Rumpf-Form, sowie

(dbgclose)

vor jedem (exit)-Aufruf im Rumpf (auch verschachtelt) und zusaetzlich am Ende des Rumpfs - ausser die letzte Rumpf-Form ist bereits selbst ein (exit) (dann waere ein zweites dbgclose ohnehin unerreichbarer Code).

--add-open DATEI METHODE ist unabhaengig von --method/--recursive nutzbar und mehrfach angebbar; alle drei Mechanismen lassen sich in einem Aufruf kombinieren.

Schalter

Schalter Beschreibung
datei (Pflicht, Position 1) Anker-.lsp-Datei; ihr Verzeichnis wird immer mitdurchsucht
--method NAME Funktion mit dbgf/dbg/dbgreturn instrumentieren (mehrfach angebbar)
--recursive Auch alle im Rumpf aufgerufenen projekteigenen Funktionen instrumentieren
--search-dir DIR Weiteres Verzeichnis nach .lsp-Dateien durchsuchen (mehrfach angebbar). Default: Lisp/ und das Verzeichnis von datei
--max-depth N Maximale Rekursionstiefe fuer --recursive (Default: 3)
--exclude NAME Funktionsname von --recursive ausschliessen (mehrfach angebbar)
--add-open DATEI METHODE dbgopen/dbgclose in METHODE (aus DATEI) einfuegen (mehrfach angebbar)
--dbg-file NAME Dateiname fuer (dbgopen ...). Default: aus dem --add-open-Methodennamen abgeleitet (c:TEST_MUBEA -> test_mubea.dbg)
--dbg-envvar NAME Umgebungsvariable fuer (dbgopen ...) (Default: DXFM_LOG)
--force Auch instrumentieren, wenn bereits (dbgf ...)/(dbgopen ...) vorhanden zu sein scheint
--dry-run Nur ein Diff anzeigen, keine Dateien schreiben

Typischer Ablauf

  1. Immer zuerst --dry-run laufen lassen und das Diff pruefen (mehrere Dateien koennen betroffen sein, siehe --recursive).
  2. Ohne --dry-run erneut aufrufen - die Dateien werden direkt (in-place) geschrieben.
  3. In BricsCAD (load ...) neu laden bzw. den Testlauf starten.
  4. Die .dbg-Datei (per --add-open geoeffnet, Pfad = %DXFM_LOG%\<--dbg-file>) auswerten.
  5. Da die Dateien in-place geschrieben werden und ueber Git versioniert sind: nach dem Debuggen die Debug-Aufrufe entweder manuell entfernen oder die Datei(en) per git checkout -- <datei> verwerfen (das Werkzeug selbst hat keinen "--remove"-Schalter).

Beispiele

Eine einzelne Funktion instrumentieren:

bin\dbg2lsp.bat tests\test_mubea.lsp --method mubea:build-separator-one --dry-run

Eine Funktion UND alles, was sie aufruft (bis Tiefe 3, Default):

bin\dbg2lsp.bat tests\test_mubea.lsp --method mubea:build-kreisel --recursive --dry-run

Mehrere Einstiegspunkte in einem Lauf, plus Oeffnen/Schliessen der Debug-Datei im umgebenden Testbefehl - das entspricht genau der Instrumentierung, die fuer den urspruenglichen Scanner-Bug in TEST_MUBEA von Hand gemacht wurde:

bin\dbg2lsp.bat tests\test_mubea.lsp ^
  --method mubea:build-kreisel ^
  --method mubea:build-vario-one ^
  --method mubea:build-gf-one ^
  --method mubea:build-separator-one ^
  --recursive ^
  --add-open tests\test_mubea.lsp c:TEST_MUBEA

Bestimmte generische Helfer von der Rekursion ausschliessen (z.B. um ssg-start/ssg-end nicht mit anzufassen):

bin\dbg2lsp.bat tests\test_mubea.lsp --method mubea:build-kreisel --recursive ^
  --exclude ssg-start --exclude ssg-end

Funktionsweise / Aufloesung

  • datei wird zuerst relativ zum aktuellen Arbeitsverzeichnis, sonst relativ zur Projektwurzel (erkannt an .git/ bzw. Lisp/, ausgehend von datei nach oben gesucht) aufgeloest.
  • Durchsucht werden: das Verzeichnis von datei, Lisp/ (relativ zur Projektwurzel), jedes --search-dir sowie das Verzeichnis jeder --add-open-Datei - jeweils rekursiv nach *.lsp.
  • Aus all diesen Dateien wird EIN Index Funktionsname -> (defun ...) aufgebaut (case-insensitiv, wie AutoLISP-Symbole zur Laufzeit). --method/--add-open muessen daher nicht in datei selbst stehen, sondern werden ueberall gefunden.
  • Klammer-/String-/Kommentar-Erkennung ist zeichenweise implementiert (kein vollstaendiger Lisp-Reader) - genuegt aber, um Top-Level-(defun ...)-Bloecke, ihre Parameterliste und die letzte Rumpf-Form zuverlaessig zu erkennen, auch bei mehrzeiligen Parameterlisten mit Locals nach /.
  • Alle Aenderungen werden zunaechst als Liste von reinen Text-Einfuegungen gesammelt (keine Loeschungen) und erst am Ende je Datei angewandt - Positionen bleiben dadurch unabhaengig von der Bearbeitungsreihenfolge gueltig.

Grenzen

  • Nur die letzte Rumpf-Form wird zu dbgreturn. Fruehe (exit)-Ausstiege MITTEN im Rumpf werden von --method nicht mit einem eigenen dbgreturn versehen (nur --add-open behandelt (exit)-Stellen explizit, dort aber nur mit dbgclose, nicht mit einem geloggten Rueckgabewert).
  • Kein "--remove". Rueckbau erfolgt manuell oder per git checkout -- <datei>.
  • --recursive kann viele Dateien anfassen - projekteigene Helfer wie ssg-start/ssg-val/ssg-attrib-merge werden mitinstrumentiert, sobald sie im Aufrufgraphen auftauchen. --max-depth und --exclude begrenzen das gezielt; ohne --dry-run-Kontrolle vorher nicht blind auf grosse Funktionen mit hoher --max-depth loslassen.
  • Mehrfache Definitionen desselben Namens in unterschiedlichen Dateien: es gewinnt der erste beim Durchsuchen gefundene (Dateireihenfolge nicht garantiert sortiert-stabil ueber Verzeichnisgrenzen) - in dieser Codebasis kommt das ueblicherweise nicht vor.

Idempotenz

Vor dem Einfuegen prueft das Werkzeug, ob die erste Rumpf-Form bereits (dbgf ...) (fuer --method) bzw. (dbgopen ...) (fuer --add-open) ist, und ueberspringt die Funktion in dem Fall mit einer [skip]-Meldung. Mit --force wird trotzdem erneut eingefuegt (fuehrt bei wiederholtem --force-Aufruf zu doppelten dbgf/dbg-Zeilen - in dem Fall vorher besser die Datei zuruecksetzen).