| 5846 | } |
| 5847 | |
| 5848 | int cbm_adr_validate_section_keys(const char **keys, int count, char *errbuf, int errbuf_size) { |
| 5849 | char invalid[CBM_SZ_256] = ""; |
| 5850 | int ilen = 0; |
| 5851 | int ninvalid = 0; |
| 5852 | |
| 5853 | /* Collect and sort invalid keys */ |
| 5854 | const char *inv_keys[ST_MAX_SECTIONS]; |
| 5855 | int inv_n = 0; |
| 5856 | for (int i = 0; i < count; i++) { |
| 5857 | if (!is_canonical_section(keys[i])) { |
| 5858 | if (inv_n < ST_BUF_16) { |
| 5859 | inv_keys[inv_n++] = keys[i]; |
| 5860 | } |
| 5861 | } |
| 5862 | } |
| 5863 | /* Sort alphabetically */ |
| 5864 | for (int i = SKIP_ONE; i < inv_n; i++) { |
| 5865 | int j = i; |
| 5866 | while (j > 0 && strcmp(inv_keys[j], inv_keys[j - SKIP_ONE]) < 0) { |
| 5867 | const char *tmp = inv_keys[j]; |
| 5868 | inv_keys[j] = inv_keys[j - SKIP_ONE]; |
| 5869 | inv_keys[j - SKIP_ONE] = tmp; |
| 5870 | j--; |
| 5871 | } |
| 5872 | } |
| 5873 | |
| 5874 | for (int i = 0; i < inv_n; i++) { |
| 5875 | if (ilen > 0) { |
| 5876 | ilen += snprintf(invalid + ilen, sizeof(invalid) - ilen, ", "); |
| 5877 | } |
| 5878 | ilen += snprintf(invalid + ilen, sizeof(invalid) - ilen, "%s", inv_keys[i]); |
| 5879 | ninvalid++; |
| 5880 | } |
| 5881 | |
| 5882 | if (ninvalid > 0) { |
| 5883 | snprintf(errbuf, errbuf_size, |
| 5884 | "invalid section names: %s. Valid sections: PURPOSE, STACK, ARCHITECTURE, " |
| 5885 | "PATTERNS, TRADEOFFS, PHILOSOPHY", |
| 5886 | invalid); |
| 5887 | return CBM_STORE_ERR; |
| 5888 | } |
| 5889 | return CBM_STORE_OK; |
| 5890 | } |
| 5891 | |
| 5892 | void cbm_adr_sections_free(cbm_adr_sections_t *s) { |
| 5893 | if (!s) { |
no test coverage detected