| 2746 | } |
| 2747 | |
| 2748 | static ssize_t write_pair(int fd, const char *key, const char *value, |
| 2749 | const char *comment, |
| 2750 | const struct config_store_data *store) |
| 2751 | { |
| 2752 | int i; |
| 2753 | ssize_t ret; |
| 2754 | const char *quote = ""; |
| 2755 | struct strbuf sb = STRBUF_INIT; |
| 2756 | |
| 2757 | /* |
| 2758 | * Check to see if the value needs to be surrounded with a dq pair. |
| 2759 | * Note that problematic characters are always backslash-quoted; this |
| 2760 | * check is about not losing leading or trailing SP and strings that |
| 2761 | * follow beginning-of-comment characters (i.e. ';' and '#') by the |
| 2762 | * configuration parser. |
| 2763 | */ |
| 2764 | if (value[0] == ' ') |
| 2765 | quote = "\""; |
| 2766 | for (i = 0; value[i]; i++) |
| 2767 | if (value[i] == ';' || value[i] == '#' || value[i] == '\r') |
| 2768 | quote = "\""; |
| 2769 | if (i && value[i - 1] == ' ') |
| 2770 | quote = "\""; |
| 2771 | |
| 2772 | strbuf_addf(&sb, "\t%s = %s", key + store->baselen + 1, quote); |
| 2773 | |
| 2774 | for (i = 0; value[i]; i++) |
| 2775 | switch (value[i]) { |
| 2776 | case '\n': |
| 2777 | strbuf_addstr(&sb, "\\n"); |
| 2778 | break; |
| 2779 | case '\t': |
| 2780 | strbuf_addstr(&sb, "\\t"); |
| 2781 | break; |
| 2782 | case '"': |
| 2783 | case '\\': |
| 2784 | strbuf_addch(&sb, '\\'); |
| 2785 | /* fallthrough */ |
| 2786 | default: |
| 2787 | strbuf_addch(&sb, value[i]); |
| 2788 | break; |
| 2789 | } |
| 2790 | |
| 2791 | if (comment) |
| 2792 | strbuf_addf(&sb, "%s%s\n", quote, comment); |
| 2793 | else |
| 2794 | strbuf_addf(&sb, "%s\n", quote); |
| 2795 | |
| 2796 | ret = write_in_full(fd, sb.buf, sb.len); |
| 2797 | strbuf_release(&sb); |
| 2798 | |
| 2799 | return ret; |
| 2800 | } |
| 2801 | |
| 2802 | /* |
| 2803 | * If we are about to unset the last key(s) in a section, and if there are |
no test coverage detected