| 833 | } |
| 834 | |
| 835 | static char *parse_value(struct config_source *cs) |
| 836 | { |
| 837 | int quote = 0, comment = 0; |
| 838 | size_t trim_len = 0; |
| 839 | |
| 840 | strbuf_reset(&cs->value); |
| 841 | for (;;) { |
| 842 | int c = get_next_char(cs); |
| 843 | if (c == '\n') { |
| 844 | if (quote) { |
| 845 | cs->linenr--; |
| 846 | return NULL; |
| 847 | } |
| 848 | if (trim_len) |
| 849 | strbuf_setlen(&cs->value, trim_len); |
| 850 | return cs->value.buf; |
| 851 | } |
| 852 | if (comment) |
| 853 | continue; |
| 854 | if (isspace(c) && !quote) { |
| 855 | if (!trim_len) |
| 856 | trim_len = cs->value.len; |
| 857 | if (cs->value.len) |
| 858 | strbuf_addch(&cs->value, c); |
| 859 | continue; |
| 860 | } |
| 861 | if (!quote) { |
| 862 | if (c == ';' || c == '#') { |
| 863 | comment = 1; |
| 864 | continue; |
| 865 | } |
| 866 | } |
| 867 | if (trim_len) |
| 868 | trim_len = 0; |
| 869 | if (c == '\\') { |
| 870 | c = get_next_char(cs); |
| 871 | switch (c) { |
| 872 | case '\n': |
| 873 | continue; |
| 874 | case 't': |
| 875 | c = '\t'; |
| 876 | break; |
| 877 | case 'b': |
| 878 | c = '\b'; |
| 879 | break; |
| 880 | case 'n': |
| 881 | c = '\n'; |
| 882 | break; |
| 883 | /* Some characters escape as themselves */ |
| 884 | case '\\': case '"': |
| 885 | break; |
| 886 | /* Reject unknown escape sequences */ |
| 887 | default: |
| 888 | return NULL; |
| 889 | } |
| 890 | strbuf_addch(&cs->value, c); |
| 891 | continue; |
| 892 | } |
no test coverage detected