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