git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 3/4] config: support parsing config data from buffers

From
Jeff King <peff@peff.net>
Date
Jan 26, 2012, 07:40 UTC
Message-ID
<20120126074031.GC30474@sigill.intra.peff.net>
In-Reply-To
<20120126073547.GA28689@sigill.intra.peff.net>

The only two ways to parse config data are from a file or from the command-line. Because the command-line format is totally different from the file format, they don't share any code. Therefore, to add new sources of file-like config data, we have to refactor git_parse_file to handle reading from something besides stdio.

To fix this, our config_file structure now holds either a "FILE *" pointer or a memory buffer. We intercept calls to fgetc and ungetc and either pass them along to stdio, or fake them with our buffer. This leaves the main parsing code intact and easy to read.

Signed-off-by: Jeff King <peff@peff.net>
---
 cache.h  |    1 +
 config.c |   58 +++++++++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 54 insertions(+), 5 deletions(-)
diff --git a/cache.h b/cache.h
index 21bbb0a..a298897 100644
--- a/cache.h
+++ b/cache.h
@@ -1110,6 +1110,7 @@ extern int update_server_info(int);
 typedef int (*config_fn_t)(const char *, const char *, void *);
 extern int git_default_config(const char *, const char *, void *);
 extern int git_config_from_file(config_fn_t fn, const char *, void *);
+extern int git_config_from_buffer(config_fn_t fn, void *, const char *, char *, unsigned long );
 extern void git_config_push_parameter(const char *text);
 extern int git_config_from_parameters(config_fn_t fn, void *data);
 extern int git_config(config_fn_t fn, void *);
diff --git a/config.c b/config.c
index b82f749..49a3d1a 100644
--- a/config.c
+++ b/config.c
@@ -18,6 +18,9 @@ typedef struct config_file {
 	const char *name;
 	int linenr;
 	int eof;
+	char *buf;
+	unsigned long size;
+	unsigned long cur;
 	struct strbuf value;
 	char var[MAXNAME];
 } config_file;
@@ -101,19 +104,45 @@ int git_config_from_parameters(config_fn_t fn, void *data)
 	return nr > 0;
 }
 
+static int get_one_char(void)
+{
+	if (cf->f)
+		return fgetc(cf->f);
+	else if (cf->buf) {
+		if (cf->cur < cf->size)
+			return cf->buf[cf->cur++];
+		return EOF;
+	}
+
+	die("BUG: attempt to read from NULL config_file");
+}
+
+static int unget_one_char(int c)
+{
+	if (cf->f)
+		ungetc(c, cf->f);
+	else if (cf->buf) {
+		if (cf->cur == 0)
+			return EOF;
+		cf->buf[--cf->cur] = c;
+		return c;
+	}
+
+	die("BUG: attempt to ungetc NULL config_file");
+}
+
 static int get_next_char(void)
 {
 	int c;
-	FILE *f;
 
 	c = '\n';
-	if (cf && ((f = cf->f) != NULL)) {
-		c = fgetc(f);
+	if (cf && (cf->f || cf->buf)) {
+		c = get_one_char();
 		if (c == '\r') {
 			/* DOS like systems */
-			c = fgetc(f);
+			c = get_one_char();
 			if (c != '\n') {
-				ungetc(c, f);
+				unget_one_char(c);
 				c = '\r';
 			}
 		}
@@ -833,6 +862,9 @@ static void config_file_push(config_file *top, const char *name)
 	top->name = name;
 	top->linenr = 1;
 	top->eof = 0;
+	top->buf = NULL;
+	top->size = 0;
+	top->cur = 0;
 	strbuf_init(&top->value, 1024);
 	cf = top;
 }
@@ -863,6 +895,22 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
 	return ret;
 }
 
+int git_config_from_buffer(config_fn_t fn, void *data, const char *name,
+			   char *buf, unsigned long size)
+{
+	int ret;
+	config_file top;
+
+	config_file_push(&top, name);
+	top.buf = buf;
+	top.size = size;
+
+	ret = git_parse_file(fn, data);
+
+	config_file_pop(&top);
+	return ret;
+}
+
 const char *git_etc_gitconfig(void)
 {
 	static const char *system_wide;
-- 
1.7.9.rc2.293.gaae2
Previous: Jeff KingNext: Jeff King
Message 19 of 36 in “config include directives”
  1. 0/4 config include directivesJeff King, Jan 26, 2012
  2. 1/4 config: add include directiveJeff King, Jan 26, 2012
  3. Johannes SixtJan 26, 2012
  4. Jeff KingJan 26, 2012
  5. Junio C HamanoJan 26, 2012
  6. Jeff KingJan 26, 2012
  7. Jeff KingJan 26, 2012
  8. Junio C HamanoJan 26, 2012
  9. Jeff KingJan 26, 2012
  10. Junio C HamanoJan 27, 2012
  11. Jeff KingJan 27, 2012
  12. Jens LehmannJan 27, 2012
  13. Ævar Arnfjörð BjarmasonJan 27, 2012
  14. Jeff KingJan 27, 2012
  15. Ævar Arnfjörð BjarmasonJan 27, 2012
  16. Michael HaggertyJan 27, 2012
  17. Jeff KingJan 27, 2012
  18. 2/4 config: factor out config file stack managementJeff King, Jan 26, 2012
  19. 3/4 config: support parsing config data from buffersJeff King, Jan 26, 2012
  20. 4/4 config: allow including config from repository blobsJeff King, Jan 26, 2012
  21. Johannes SixtJan 26, 2012
  22. Jeff KingJan 26, 2012
  23. Nguyen Thai Ngoc DuyJan 27, 2012
  24. Jeff KingJan 27, 2012
  25. Junio C HamanoJan 26, 2012
  26. Jeff KingJan 26, 2012
  27. Junio C HamanoJan 27, 2012
  28. Jeff KingJan 27, 2012
  29. Junio C HamanoJan 27, 2012
  30. Jeff KingJan 27, 2012
  31. Johannes SixtJan 27, 2012
  32. Junio C HamanoJan 27, 2012
  33. Nguyen Thai Ngoc DuyJan 27, 2012
  34. Jeff KingJan 27, 2012
  35. Ævar Arnfjörð BjarmasonJan 27, 2012
  36. Jeff KingJan 27, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.