| 788 | } |
| 789 | |
| 790 | static bool parse_object(const char **sp, JsonNode **out) |
| 791 | { |
| 792 | const char *s = *sp; |
| 793 | JsonNode *ret = out ? json_mkobject() : nullptr; |
| 794 | char *key; |
| 795 | JsonNode *value; |
| 796 | |
| 797 | if (*s++ != '{') |
| 798 | goto failure; |
| 799 | skip_space(&s); |
| 800 | |
| 801 | if (*s == '}') |
| 802 | { |
| 803 | s++; |
| 804 | goto success; |
| 805 | } |
| 806 | |
| 807 | for (;;) |
| 808 | { |
| 809 | if (!parse_string(&s, out ? &key : nullptr)) |
| 810 | goto failure; |
| 811 | skip_space(&s); |
| 812 | |
| 813 | if (*s++ != ':') |
| 814 | goto failure_free_key; |
| 815 | skip_space(&s); |
| 816 | |
| 817 | if (!parse_value(&s, out ? &value : nullptr)) |
| 818 | goto failure_free_key; |
| 819 | skip_space(&s); |
| 820 | |
| 821 | if (out) |
| 822 | append_member(ret, key, value); |
| 823 | |
| 824 | if (*s == '}') |
| 825 | { |
| 826 | s++; |
| 827 | goto success; |
| 828 | } |
| 829 | |
| 830 | if (*s++ != ',') |
| 831 | goto failure; |
| 832 | skip_space(&s); |
| 833 | } |
| 834 | |
| 835 | success: |
| 836 | *sp = s; |
| 837 | if (out) |
| 838 | *out = ret; |
| 839 | return true; |
| 840 | |
| 841 | failure_free_key: |
| 842 | if (out) |
| 843 | free(key); |
| 844 | failure: |
| 845 | json_delete(ret); |
| 846 | return false; |
| 847 | } |
no test coverage detected