git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Fix git_config_set() for mean cases
@ 2005-11-16  9:47 Johannes Schindelin
  2005-11-16 20:21 ` Junio C Hamano
       [not found] ` <7vwtj847kj.fsf@assigned-by-dhcp.cox.net>
  0 siblings, 2 replies; 7+ messages in thread
From: Johannes Schindelin @ 2005-11-16  9:47 UTC (permalink / raw)
  To: git, junkio

[-- Attachment #1: Type: TEXT/PLAIN, Size: 5883 bytes --]


There were problems when the keys´ case didn´t match, and also when the
section was in the same line as the key.

This patch also adds a test case, so you see that it works now.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>

---

	I shoulda started by writing those tests. This patch is on top
	of my earlier patch, which worked only in the nice cases. It 
	now needs git-config-set, though.

 config.c              |   42 ++++++++++++++----
 t/t1300-config-set.sh |  112 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 144 insertions(+), 10 deletions(-)
 create mode 100644 t/t1300-config-set.sh

applies-to: ae3c1e28a1df80086033825ac68fdf4c6c835eee
e326b690c85a648ffcbbc63e69333a7100a07892
diff --git a/config.c b/config.c
index 3b883b2..9315351 100644
--- a/config.c
+++ b/config.c
@@ -255,7 +255,7 @@ int git_config(config_fn_t fn)
 
 static struct {
 	int baselen;
-	const char* key;
+	char* key;
 	const char* value;
 	off_t offset;
 	enum { START, SECTION_SEEN, SECTION_END_SEEN, KEY_SEEN } state;
@@ -270,10 +270,10 @@ static int store_aux(const char* key, co
 			break;
 		case SECTION_SEEN:
 			if (strncmp(key, store.key, store.baselen+1)) {
-				store.offset = ftell(config_file);
 				store.state = SECTION_END_SEEN;
 				break;
-			}
+			} else
+				store.offset = ftell(config_file);
 		case SECTION_END_SEEN:
 		case START:
 			if (!strcmp(key, store.key)) {
@@ -326,18 +326,21 @@ int git_config_set(const char* key, cons
 		return 2;
 	}
 
+	store.key = strdup(key);
 	for (i = 0; key[i]; i++)
 		if (i != store.baselen && !isalpha(key[i])) {
 			fprintf(stderr, "invalid key: %s\n", key);
+			free(store.key);
 			return 1;
-		}
+		} else
+			store.key[i] = tolower(key[i]);
 
-	store.key = key;
 	store.value = value;
 
 	fd = open(lock_file, O_WRONLY | O_CREAT | O_EXCL, 0666);
 	if (fd < 0) {
 		fprintf(stderr, "could not lock config file\n");
+		free(store.key);
 		return -1;
 	}
 
@@ -349,6 +352,9 @@ int git_config_set(const char* key, cons
 			"#\n"
 			"\n";
 
+		free(store.key);
+		store.key = (char*)key;
+
 		write(fd, contents, sizeof(contents)-1);
 		store_write_section(fd);
 		store_write_pair(fd);
@@ -362,25 +368,41 @@ int git_config_set(const char* key, cons
 
 		if (git_config(store_aux)) {
 			fprintf(stderr, "invalid config file\n");
+			free(store.key);
 			return 3;
 		}
 
+		free(store.key);
+		store.key = (char*)key;
+
 		in_fd = open(config_file, O_RDONLY, 0666);
 		contents = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, in_fd, 0);
 		close(in_fd);
 
 		if (store.offset == 0)
-			offset = st.st_size;
-		else {
+			store.offset = offset = st.st_size;
+		else if (store.state != KEY_SEEN) {
+			offset = store.offset;
+		} else {
+			int equal_offset = st.st_size,
+				bracket_offset = st.st_size;
 			for (offset = store.offset-2; offset > 0 
-					&& contents[offset] != '\n'; offset--);
-			offset++;
+					&& contents[offset] != '\n'; offset--)
+				switch (contents[offset]) {
+					case '=': equal_offset = offset; break;
+					case ']': bracket_offset = offset; break;
+				}
+			if (bracket_offset < equal_offset) {
+				contents[bracket_offset+1] = '\n';
+				offset = bracket_offset+2;
+			} else
+				offset++;
 		}
 		write(fd, contents, offset);
 		if (store.state == START)
 			store_write_section(fd);
 		store_write_pair(fd);
-		if (store.offset > offset)
+		if (store.offset < st.st_size)
 			write(fd, contents + store.offset,
 				st.st_size - store.offset);
 		
diff --git a/t/t1300-config-set.sh b/t/t1300-config-set.sh
new file mode 100644
index 0000000..48d4ff1
--- /dev/null
+++ b/t/t1300-config-set.sh
@@ -0,0 +1,112 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Johannes Schindelin
+#
+
+test_description='Test git-config-set in different settings'
+
+. ./test-lib.sh
+
+test -f .git/config && rm .git/config
+
+git-config-set core.penguin "little blue"
+
+cat > expect.1 << EOF
+#
+# This is the config file
+#
+
+[core]
+	penguin = little blue
+EOF
+
+test_expect_success 'initial' 'cmp .git/config expect.1'
+
+git-config-set Core.Movie BadPhysics
+
+cat > expect.2 << EOF
+#
+# This is the config file
+#
+
+[core]
+	penguin = little blue
+	Movie = BadPhysics
+EOF
+
+test_expect_success 'mixed case' 'cmp .git/config expect.2'
+
+git-config-set Cores.WhatEver Second
+
+cat > expect.3 << EOF
+#
+# This is the config file
+#
+
+[core]
+	penguin = little blue
+	Movie = BadPhysics
+[Cores]
+	WhatEver = Second
+EOF
+
+test_expect_success 'similar section' 'cmp .git/config expect.3'
+
+git-config-set CORE.UPPERCASE true
+
+cat > expect.4 << EOF
+#
+# This is the config file
+#
+
+[core]
+	penguin = little blue
+	Movie = BadPhysics
+	UPPERCASE = true
+[Cores]
+	WhatEver = Second
+EOF
+
+test_expect_success 'similar section' 'cmp .git/config expect.4'
+
+cat > .git/config << EOF
+[beta] ; silly comment # another comment
+noIndent= sillyValue ; ´nother silly comment
+
+# empty line
+		; comment
+		haha   ="beta" # last silly comment
+[nextSection] noNewline = ouch
+EOF
+
+git-config-set beta.haha alpha
+
+cat > expect.5 << EOF
+[beta] ; silly comment # another comment
+noIndent= sillyValue ; ´nother silly comment
+
+# empty line
+		; comment
+	haha = alpha
+[nextSection] noNewline = ouch
+EOF
+
+test_expect_success 'really mean test' 'cmp .git/config expect.5'
+
+git-config-set nextsection.nonewline wow
+
+cat > expect.6 << EOF
+[beta] ; silly comment # another comment
+noIndent= sillyValue ; ´nother silly comment
+
+# empty line
+		; comment
+	haha = alpha
+[nextSection]
+	nonewline = wow
+EOF
+
+test_expect_success 'really really mean test' 'cmp .git/config expect.6'
+
+test_done
+
---
0.99.9.GIT

^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2005-11-17 21:10 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-16  9:47 [PATCH] Fix git_config_set() for mean cases Johannes Schindelin
2005-11-16 20:21 ` Junio C Hamano
2005-11-16 20:52   ` H. Peter Anvin
2005-11-16 23:19   ` Johannes Schindelin
2005-11-17  1:40     ` Randal L. Schwartz
2005-11-16 23:26   ` Matthias Urlichs
     [not found] ` <7vwtj847kj.fsf@assigned-by-dhcp.cox.net>
     [not found]   ` <Pine.LNX.4.63.0511170027380.9687@wbgn013.biozentrum.uni-wuerzburg.de>
     [not found]     ` <7vhdab3nlz.fsf@assigned-by-dhcp.cox.net>
     [not found]       ` <Pine.LNX.4.63.0511171115200.20898@wbgn013.biozentrum.uni-wuerzburg.de>
     [not found]         ` <7voe4jwm5w.fsf@assigned-by-dhcp.cox.net>
     [not found]           ` <Pine.LNX.4.63.0511171252070.737@wbgn013.biozentrum.uni-wuerzburg.de>
     [not found]             ` <7v1x1ful7j.fsf@assigned-by-dhcp.cox.net>
2005-11-17 21:10               ` Johannes Schindelin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).