libbsdl: scaffold + working BSDL parser (struct + JSON, C ABI)
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>
This commit is contained in:
77
tools/bsdl2json.c
Normal file
77
tools/bsdl2json.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
Reference in New Issue
Block a user