1#include <kassert.h>
2#include <ndjson.h>
3#include <string.h>
4
5NDJSON_DECLARE(ndjson_schema, NDJSON_SECTION_NDJSON, NDJSON_KIND_SCHEMA, 1,
6 NDJSON_STR(section), NDJSON_STR(kind), NDJSON_U64(rec_version),
7 NDJSON_U64(nfields), NDJSON_U64(index), NDJSON_STR(field),
8 NDJSON_STR(type));
9
10static const char *ndjson_type_str(enum ndjson_type t) {
11 switch (t) {
12 case NDJSON_TYPE_U64: return NDJSON_TYPE_NAME_U64;
13 case NDJSON_TYPE_I64: return NDJSON_TYPE_NAME_I64;
14 case NDJSON_TYPE_BOOL: return NDJSON_TYPE_NAME_BOOL;
15 case NDJSON_TYPE_STR: return NDJSON_TYPE_NAME_STR;
16 case NDJSON_TYPE_HEX: return NDJSON_TYPE_NAME_HEX;
17 }
18
19 return "unknown";
20}
21
22/* (section, kind) sharing is ambiguous */
23void ndjson_check_duplicates(void) {
24 for (struct ndjson_record *a = __skernel_ndjson_records;
25 a < __ekernel_ndjson_records; a++) {
26 for (struct ndjson_record *b = a + 1; b < __ekernel_ndjson_records;
27 b++) {
28 if (strcmp(str1: a->section, str2: b->section) == 0 &&
29 strcmp(str1: a->kind, str2: b->kind) == 0)
30 panic("Duplicate ndjson record: %s/%s", a->section, a->kind);
31 }
32 }
33}
34
35/* One record for every field */
36void ndjson_dump_schema(void) {
37 struct ndjson_record *rec;
38
39 linker_section_for_each_object(rec, ndjson_records) {
40 for (uint16_t i = 0; i < rec->nfields; i++) {
41 const struct ndjson_field *f = &rec->fields[i];
42
43 ndjson_emit(ndjson_schema, .section = rec->section,
44 .kind = rec->kind, .rec_version = rec->version,
45 .nfields = rec->nfields, .index = i, .field = f->name,
46 .type = ndjson_type_str(f->type));
47 }
48 }
49}
50