# Step 2 — LDF Loading & Display (C++) ## What Was Built Custom LDF file parser, GUI table population, baud rate detection, schedule table loading, and auto-reload on file change — all in C++, matching the Python implementation feature-for-feature. ## Architecture ``` User clicks Browse → QFileDialog → filePath │ ▼ loadLdfFile(path) │ ┌────────────┼────────────┐ ▼ ▼ ▼ parseLdf() On error: Setup file (ldf_parser) show dialog watcher │ ▼ LdfData ┌────┼────────────┬──────────────┐ ▼ ▼ ▼ ▼ Baud Tx table Rx table Schedule rate (master (slave dropdown label frames) frames) ``` ## Key Module: ldf_parser.h / ldf_parser.cpp Custom parser (no third-party library). Parses LDF sections using QRegularExpression. | C++ Struct | Python Equivalent | Purpose | |-----------|-------------------|---------| | `LdfData` | `LdfData` | Complete parsed result | | `FrameInfo` | `FrameInfo` | One frame with signals | | `SignalInfo` | `SignalInfo` | One signal's metadata | | `ScheduleTableInfo` | `ScheduleTableInfo` | One schedule table | ### Python vs C++ Parser Differences | Aspect | Python | C++ | |--------|--------|-----| | Library | `ldfparser` (3rd party) | Custom regex parser | | Baud rate | `ldf.baudrate / 1000` (lib returns *1000) | Read raw value from file (already correct) | | Frame classification | `isinstance(frame.publisher, LinMaster)` | `frame.publisher == masterName` (string compare) | | Schedule delay | `entry.delay * 1000` (lib returns seconds) | Read raw ms value from file | | Signal field name | `frame.signals` | `frame.signal_list` (Qt `signals` macro conflict) | ## C++ Concepts Introduced ### struct vs @dataclass Python `@dataclass` → C++ `struct`. Both are data containers, but C++ structs have compile-time type enforcement. ### std::optional `self._ldf_data: LdfData | None` → `std::optional`. Holds a value or is empty. Access with `->` and `*`. ### Raw string delimiters When a regex contains `"` characters: `R"re(pattern with "quotes")re"` uses custom delimiter `re` so `"` inside is safe. ### Qt macro collision `signals` is a Qt macro — can't use as a variable name. Renamed to `signal_list`. ### QTimer for test modal dialogs Python uses `monkeypatch` to suppress QMessageBox. C++ uses `QTimer::singleShot(0, ...)` to auto-dismiss the dialog. ## Files | File | Purpose | |------|---------| | `cpp/src/ldf_parser.h` | Data structs + parseLdf() declaration | | `cpp/src/ldf_parser.cpp` | Custom LDF parser (regex-based) | | `cpp/src/main_window.h` | Updated: LdfData, file watcher, new methods | | `cpp/src/main_window.cpp` | Updated: loadLdfFile(), table population, auto-reload | | `cpp/tests/test_ldf_parser.cpp` | 28 parser unit tests | | `cpp/tests/test_ldf_loading.cpp` | 22 GUI integration tests | | `cpp/CMakeLists.txt` | Updated: new sources + 2 new test targets | ## Test Results - **84 total C++ tests passing** (Step 1: 34 + Step 2: 50) - Parser tests: valid/invalid files, frame classification, signal extraction, schedules - GUI tests: table population, baud rate, schedule combo, error handling, auto-reload