Skip to content

Repository files navigation

asc_parser_lib

Pure C library for reading and writing Vector CANoe/CANalyzer ASC log files, with no external dependencies. C11, header include/asc_parser/asc_parser.h.

Features

Reader

  • Classic CAN: data / remote / error frames, standard & extended IDs
  • CAN-FD: 12–64 byte payloads, BRS/ESI flags, signal (symbolic) names
  • base hex / base dec, timestamps absolute / relative
  • Begin/End TriggerBlock, status & statistic lines, UTF-8 BOM
  • US (am/pm) and 24h dates, English + German month names
  • Locale-independent number parsing (safe under de-DE comma locales)
  • Hardened against corrupt input: bounds-checked DLC/length, invalid tokens, channel underflow, 29-bit ID range, over-long lines
  • Lenient (default: skip & count malformed lines) or strict mode (abort with line number); per-instance stats via asc_parser_get_frames_parsed() / asc_parser_get_lines_skipped()

Writer

  • CANoe-compatible output (same field layout as python-can's ASCWriter)
  • Automatic header/TriggerBlock, End TriggerBlock on destroy
  • Sticky write-error reporting (asc_writer_get_error()), UTF-8 paths on Windows

Performance (reference machine, 1M-frame mixed classic/FD file): read ~377k frames/s (65 MB/s); see tests/README.md for benchmark usage.

Build & Test

cmake -B build && cmake --build build
cd build && ctest          # unit + golden + round-trip + bench smoke tests
./build/asc_demo file.asc  # parse and pretty-print a log

Cross-validation against python-can (optional, needs Python): ./tests/run_tests.sh

API Overview

#include "asc_parser/asc_parser.h"

char err[256];
asc_parser_t* p = asc_parser_create_ex("log.asc", err, sizeof err);
if (!p) { /* err has the reason */ }
asc_parser_set_strict(p, true);            // optional
asc_can_frame_t f;
while (asc_parser_read_frame(p, &f)) {
    // f.timestamp, f.frame_id, f.payload_length, f.payload[], ...
}
printf("%ld parsed, %ld skipped\n",
       asc_parser_get_frames_parsed(p), asc_parser_get_lines_skipped(p));
asc_parser_destroy(p);

asc_writer_t* w = asc_writer_create("copy.asc");
asc_writer_write_frame(w, &f);             // header written automatically
asc_writer_destroy(w);                     // writes "End TriggerBlock"

Thread Safety

Instances are independent and share no global state. Use one asc_parser_t / asc_writer_t per thread; no function is re-entrant on the same instance.

Known Format Limitations

  • Classic frames with DLC > 8 (d 40, d D): every logged data byte is kept on read (the scan stops at trailing fields such as Length = ...), and the writer round-trips them all. payload_length stores the byte count actually present, so a raw DLC 9..15 with only 8 bytes normalizes to 8 (raw DLC codes are not preserved; python-can keeps them).
  • Error frames: the classic N ErrorFrame line carries no direction bit; FD error frames keep theirs via a CANFD-style line.
  • timestamps absolute semantics follow python-can (header date + logged time).

Test Data Licensing

tests/data/ fixtures (except canoe.asc) originate from the python-can test suite (GPL v3). They are used for development/CI validation only; replace them before redistributing this repository under a non-GPL license. canoe.asc is a real CANoe 12 export kept for FD-format coverage. canoe14_fd.asc is a synthetic CANoe 14-style log built from samples posted in python-can issues #1786/#1315 (version 14 header, CANFD Start of measurement line, six-digit-millisecond date).

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages