all repos — cgit @ 88b93113235452d47e7ce474689327c43e64b843

a hyperfast web frontend for git written in c

configfile.c (view raw)

 1/* configfile.c: parsing of config files
 2 *
 3 * Copyright (C) 2006-2014 cgit Development Team <cgit@lists.zx2c4.com>
 4 *
 5 * Licensed under GNU General Public License v2
 6 *   (see COPYING for full license text)
 7 */
 8
 9#include <ctype.h>
10#include <stdio.h>
11#include "configfile.h"
12
13static int next_char(FILE *f)
14{
15	int c = fgetc(f);
16	if (c == '\r') {
17		c = fgetc(f);
18		if (c != '\n') {
19			ungetc(c, f);
20			c = '\r';
21		}
22	}
23	return c;
24}
25
26static void skip_line(FILE *f)
27{
28	int c;
29
30	while ((c = next_char(f)) && c != '\n' && c != EOF)
31		;
32}
33
34static int read_config_line(FILE *f, struct strbuf *name, struct strbuf *value)
35{
36	int c = next_char(f);
37
38	strbuf_reset(name);
39	strbuf_reset(value);
40
41	/* Skip comments and preceding spaces. */
42	for(;;) {
43		if (c == '#' || c == ';')
44			skip_line(f);
45		else if (!isspace(c))
46			break;
47		c = next_char(f);
48	}
49
50	/* Read variable name. */
51	while (c != '=') {
52		if (c == '\n' || c == EOF)
53			return 0;
54		strbuf_addch(name, c);
55		c = next_char(f);
56	}
57
58	/* Read variable value. */
59	c = next_char(f);
60	while (c != '\n' && c != EOF) {
61		strbuf_addch(value, c);
62		c = next_char(f);
63	}
64
65	return 1;
66}
67
68int parse_configfile(const char *filename, configfile_value_fn fn)
69{
70	static int nesting;
71	struct strbuf name = STRBUF_INIT;
72	struct strbuf value = STRBUF_INIT;
73	FILE *f;
74
75	/* cancel deeply nested include-commands */
76	if (nesting > 8)
77		return -1;
78	if (!(f = fopen(filename, "r")))
79		return -1;
80	nesting++;
81	while (read_config_line(f, &name, &value))
82		fn(name.buf, value.buf);
83	nesting--;
84	fclose(f);
85	strbuf_release(&name);
86	strbuf_release(&value);
87	return 0;
88}
89