Append a JSON array of strings: ,"key":["a","b","c"]. Atomic like * append_json_string: emitted only if the whole array fits. */
| 412 | /* Append a JSON array of strings: ,"key":["a","b","c"]. Atomic like |
| 413 | * append_json_string: emitted only if the whole array fits. */ |
| 414 | static void append_json_str_array(char *buf, size_t bufsize, size_t *pos, const char *key, |
| 415 | const char **arr) { |
| 416 | if (!arr || !arr[0] || *pos >= bufsize - PP_JSON_MARGIN) { |
| 417 | return; |
| 418 | } |
| 419 | /* ,"key":[ + per item "<escaped>" + separating commas + ] */ |
| 420 | size_t required = strlen(key) + PP_JSON_FIELD_OVERHEAD; |
| 421 | for (int i = 0; arr[i]; i++) { |
| 422 | required += pp_json_escaped_len(arr[i]) + PP_ESC_SPACE + (i > 0 ? SKIP_ONE : 0); |
| 423 | } |
| 424 | if (*pos + required + PP_ESC_SPACE > bufsize) { |
| 425 | return; /* whole array would not fit — skip it atomically */ |
| 426 | } |
| 427 | size_t p = *pos; |
| 428 | int n = snprintf(buf + p, bufsize - p, ",\"%s\":[", key); |
| 429 | if (n <= 0 || p + (size_t)n >= bufsize - PP_ESC_SPACE) { |
| 430 | return; |
| 431 | } |
| 432 | p += (size_t)n; |
| 433 | for (int i = 0; arr[i]; i++) { |
| 434 | if (i > 0 && p < bufsize - SKIP_ONE) { |
| 435 | buf[p++] = ','; |
| 436 | } |
| 437 | if (p < bufsize - SKIP_ONE) { |
| 438 | buf[p++] = '"'; |
| 439 | } |
| 440 | /* Full escaping (not just quote/backslash): items like C param types |
| 441 | * sliced from multi-line declarations carry raw \n/\t bytes, which are |
| 442 | * invalid inside JSON strings. */ |
| 443 | for (const char *s = arr[i]; *s && p < bufsize - PP_ESC_SPACE; s++) { |
| 444 | p += (size_t)json_escape_char(buf + p, bufsize - p - PP_ESC_SPACE, *s); |
| 445 | } |
| 446 | if (p < bufsize - SKIP_ONE) { |
| 447 | buf[p++] = '"'; |
| 448 | } |
| 449 | } |
| 450 | if (p < bufsize - SKIP_ONE) { |
| 451 | buf[p++] = ']'; |
| 452 | } |
| 453 | buf[p] = '\0'; |
| 454 | *pos = p; |
| 455 | } |
| 456 | |
| 457 | static void build_def_props(char *buf, size_t bufsize, const CBMDefinition *def) { |
| 458 | /* Complexity/loop/recursion metrics are meaningful only for Function/Method. |
no test coverage detected