summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Kristian Høgsberg <krh@redhat.com>2007-12-14 15:59:58 -0500
committerLibravatar Junio C Hamano <gitster@pobox.com>2007-12-14 20:42:26 -0800
commitcb891a5989c41ed479db9eb4b0a69cef8bb98ea8 (patch)
tree43951cf9dd4c12997bb2266ae464026b5e997197
parentfast-import: fix unalinged allocation and access (diff)
downloadtgif-cb891a5989c41ed479db9eb4b0a69cef8bb98ea8.tar.xz
Use a strbuf for building up section header and key/value pair strings.
Avoids horrible 1-byte write(2) calls and cleans up the logic a bit. Signed-off-by: Kristian Høgsberg <krh@redhat.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--config.c91
1 files changed, 38 insertions, 53 deletions
diff --git a/config.c b/config.c
index 49d2b427e5..9a5c5470cc 100644
--- a/config.c
+++ b/config.c
@@ -610,46 +610,36 @@ static int write_error(void)
static int store_write_section(int fd, const char* key)
{
- const char *dot = strchr(key, '.');
- int len1 = store.baselen, len2 = -1;
+ const char *dot;
+ int i, success;
+ struct strbuf sb;
- dot = strchr(key, '.');
+ strbuf_init(&sb, 0);
+ dot = memchr(key, '.', store.baselen);
if (dot) {
- int dotlen = dot - key;
- if (dotlen < len1) {
- len2 = len1 - dotlen - 1;
- len1 = dotlen;
+ strbuf_addf(&sb, "[%.*s \"", (int)(dot - key), key);
+ for (i = dot - key + 1; i < store.baselen; i++) {
+ if (key[i] == '"')
+ strbuf_addch(&sb, '\\');
+ strbuf_addch(&sb, key[i]);
}
+ strbuf_addstr(&sb, "\"]\n");
+ } else {
+ strbuf_addf(&sb, "[%.*s]\n", store.baselen, key);
}
- if (write_in_full(fd, "[", 1) != 1 ||
- write_in_full(fd, key, len1) != len1)
- return 0;
- if (len2 >= 0) {
- if (write_in_full(fd, " \"", 2) != 2)
- return 0;
- while (--len2 >= 0) {
- unsigned char c = *++dot;
- if (c == '"')
- if (write_in_full(fd, "\\", 1) != 1)
- return 0;
- if (write_in_full(fd, &c, 1) != 1)
- return 0;
- }
- if (write_in_full(fd, "\"", 1) != 1)
- return 0;
- }
- if (write_in_full(fd, "]\n", 2) != 2)
- return 0;
+ success = write_in_full(fd, sb.buf, sb.len) == sb.len;
+ strbuf_release(&sb);
- return 1;
+ return success;
}
static int store_write_pair(int fd, const char* key, const char* value)
{
- int i;
- int length = strlen(key+store.baselen+1);
- int quote = 0;
+ int i, success;
+ int length = strlen(key + store.baselen + 1);
+ const char *quote = "";
+ struct strbuf sb;
/*
* Check to see if the value needs to be surrounded with a dq pair.
@@ -659,43 +649,38 @@ static int store_write_pair(int fd, const char* key, const char* value)
* configuration parser.
*/
if (value[0] == ' ')
- quote = 1;
+ quote = "\"";
for (i = 0; value[i]; i++)
if (value[i] == ';' || value[i] == '#')
- quote = 1;
- if (i && value[i-1] == ' ')
- quote = 1;
+ quote = "\"";
+ if (i && value[i - 1] == ' ')
+ quote = "\"";
+
+ strbuf_init(&sb, 0);
+ strbuf_addf(&sb, "\t%.*s = %s",
+ length, key + store.baselen + 1, quote);
- if (write_in_full(fd, "\t", 1) != 1 ||
- write_in_full(fd, key+store.baselen+1, length) != length ||
- write_in_full(fd, " = ", 3) != 3)
- return 0;
- if (quote && write_in_full(fd, "\"", 1) != 1)
- return 0;
for (i = 0; value[i]; i++)
switch (value[i]) {
case '\n':
- if (write_in_full(fd, "\\n", 2) != 2)
- return 0;
+ strbuf_addstr(&sb, "\\n");
break;
case '\t':
- if (write_in_full(fd, "\\t", 2) != 2)
- return 0;
+ strbuf_addstr(&sb, "\\t");
break;
case '"':
case '\\':
- if (write_in_full(fd, "\\", 1) != 1)
- return 0;
+ strbuf_addch(&sb, '\\');
default:
- if (write_in_full(fd, value+i, 1) != 1)
- return 0;
+ strbuf_addch(&sb, value[i]);
break;
}
- if (quote && write_in_full(fd, "\"", 1) != 1)
- return 0;
- if (write_in_full(fd, "\n", 1) != 1)
- return 0;
- return 1;
+ strbuf_addf(&sb, "%s\n", quote);
+
+ success = write_in_full(fd, sb.buf, sb.len) == sb.len;
+ strbuf_release(&sb);
+
+ return success;
}
static ssize_t find_beginning_of_line(const char* contents, size_t size,