Standalone LGPL-2.1 parser for BSDL (IEEE 1149.1), shared by essim and bs_explorer. The parser is ported from the Viveris JTAG Core loader, decoupled from jtag_core, and extended with two extractions the original lacks: - PIN_MAP_STRING -> per-port physical package pin, scalar and vector; - TAP_SCAN_* -> TAP signal roles (TDI/TDO/TMS/TCK/TRST). Exposes a stable C ABI (bsdl_parse_file/buffer -> bsdl_t, bsdl_to_json) with a dependency-free JSON serializer and a bsdl2json CLI. CMake builds a versioned shared library with install/export rules for find_package(bsdl). Verified against m2gl010t, xcku040 and xcku15p (100% pin mapping, correct IDCODEs and TAP roles); api and parse regression tests pass, clean build. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
78 lines
1.8 KiB
C
78 lines
1.8 KiB
C
/*
|
|
* bsdl2json - parse a BSDL file and print the model as JSON on stdout.
|
|
* SPDX-License-Identifier: LGPL-2.1-or-later
|
|
*
|
|
* Thin frontend over libbsdl. essim invokes this out-of-process; bs_explorer
|
|
* links the library directly and uses the struct instead.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "bsdl/bsdl.h"
|
|
|
|
static void log_cb(bsdl_log_level_t level, const char* msg, void* user)
|
|
{
|
|
static const char* const names[] = { "ERROR", "WARN", "INFO", "DEBUG" };
|
|
(void)user;
|
|
fprintf(stderr, "[bsdl:%s] %s\n", names[level], msg);
|
|
}
|
|
|
|
static void usage(const char* argv0)
|
|
{
|
|
fprintf(stderr,
|
|
"libbsdl %s\n"
|
|
"usage: %s [--quiet] <file.bsd>\n"
|
|
" prints the parsed BSDL model as JSON on stdout\n",
|
|
bsdl_version(), argv0);
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
bsdl_opts_t opts;
|
|
const char* path = NULL;
|
|
int quiet = 0;
|
|
int i;
|
|
bsdl_t* model;
|
|
char* json;
|
|
|
|
for (i = 1; i < argc; i++) {
|
|
if (!strcmp(argv[i], "--quiet") || !strcmp(argv[i], "-q")) {
|
|
quiet = 1;
|
|
} else if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
|
|
usage(argv[0]);
|
|
return 0;
|
|
} else if (argv[i][0] == '-') {
|
|
fprintf(stderr, "unknown option: %s\n", argv[i]);
|
|
usage(argv[0]);
|
|
return 2;
|
|
} else {
|
|
path = argv[i];
|
|
}
|
|
}
|
|
|
|
if (!path) {
|
|
usage(argv[0]);
|
|
return 2;
|
|
}
|
|
|
|
bsdl_opts_default(&opts);
|
|
if (!quiet)
|
|
opts.log = log_cb;
|
|
|
|
model = bsdl_parse_file(path, &opts);
|
|
if (!model) {
|
|
fprintf(stderr, "error: failed to parse %s\n", path);
|
|
return 1;
|
|
}
|
|
|
|
json = bsdl_to_json(model);
|
|
if (json) {
|
|
fputs(json, stdout);
|
|
fputc('\n', stdout);
|
|
bsdl_string_free(json);
|
|
}
|
|
|
|
bsdl_free(model);
|
|
return 0;
|
|
}
|