| 1 | #include <kassert.h> |
| 2 | #include <ndjson.h> |
| 3 | #include <string.h> |
| 4 | |
| 5 | NDJSON_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 | |
| 10 | static 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 */ |
| 23 | void 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 */ |
| 36 | void 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 | |