| 495 | #define ESCAPED_SIZE 12 |
| 496 | |
| 497 | static NODISCARD size_t char_to_string(uint32_t ch, uint8_t quote, bool first, char (*buf)[ESCAPED_SIZE]) { |
| 498 | // encode the character |
| 499 | char *escaped_buf = *buf; |
| 500 | escaped_buf[0] = '\\'; |
| 501 | size_t escaped_len = 2; |
| 502 | switch (ch) { |
| 503 | case '\0': |
| 504 | escaped_buf[1] = '0'; |
| 505 | break; |
| 506 | case '\t': |
| 507 | escaped_buf[1] = 't'; |
| 508 | break; |
| 509 | case '\r': |
| 510 | escaped_buf[1] = 'r'; |
| 511 | break; |
| 512 | case '\n': |
| 513 | escaped_buf[1] = 'n'; |
| 514 | break; |
| 515 | case '\\': |
| 516 | escaped_buf[1] = '\\'; |
| 517 | break; |
| 518 | default: |
| 519 | if (ch == quote) { |
| 520 | escaped_buf[1] = ch; |
| 521 | } else if (!unicode_isprint(ch) || (first && unicode_isgraphemextend(ch))) { |
| 522 | int hexlen = snprintf(escaped_buf, ESCAPED_SIZE, "\\u{%x}", (unsigned int)ch); |
| 523 | if (hexlen < 0) { |
| 524 | return 0; // (snprintf shouldn't fail!) |
| 525 | } |
| 526 | escaped_len = hexlen; |
| 527 | } else { |
| 528 | // printable character |
| 529 | escaped_buf[0] = ch; |
| 530 | escaped_len = 1; |
| 531 | } |
| 532 | break; |
| 533 | } |
| 534 | |
| 535 | return escaped_len; |
| 536 | } |
| 537 | |
| 538 | // convert nibbles to a single/double-quoted string |
| 539 | static NODISCARD nibbles_to_string_status nibbles_to_string(const char *buf, size_t len, uint8_t *out, size_t *out_len) { |
no test coverage detected