Set the parallel HTTP request limit via an environment variable
[git.git] / config.c
blobf3c4fa42ac759157373885924b91a4a43f59953c
1 #include <ctype.h>
3 #include "cache.h"
5 #define MAXNAME (256)
7 static FILE *config_file;
8 static int config_linenr;
9 static int get_next_char(void)
11 int c;
12 FILE *f;
14 c = '\n';
15 if ((f = config_file) != NULL) {
16 c = fgetc(f);
17 if (c == '\n')
18 config_linenr++;
19 if (c == EOF) {
20 config_file = NULL;
21 c = '\n';
24 return c;
27 static char *parse_value(void)
29 static char value[1024];
30 int quote = 0, comment = 0, len = 0, space = 0;
32 for (;;) {
33 int c = get_next_char();
34 if (len >= sizeof(value))
35 return NULL;
36 if (c == '\n') {
37 if (quote)
38 return NULL;
39 value[len] = 0;
40 return value;
42 if (comment)
43 continue;
44 if (isspace(c) && !quote) {
45 space = 1;
46 continue;
48 if (space) {
49 if (len)
50 value[len++] = ' ';
51 space = 0;
53 if (c == '\\') {
54 c = get_next_char();
55 switch (c) {
56 case '\n':
57 continue;
58 case 't':
59 c = '\t';
60 break;
61 case 'b':
62 c = '\b';
63 break;
64 case 'n':
65 c = '\n';
66 break;
67 return NULL;
69 value[len++] = c;
70 continue;
72 if (c == '"') {
73 quote = 1-quote;
74 continue;
76 if (!quote) {
77 if (c == ';' || c == '#') {
78 comment = 1;
79 continue;
82 value[len++] = c;
86 static int get_value(config_fn_t fn, char *name, unsigned int len)
88 int c;
89 char *value;
91 /* Get the full name */
92 for (;;) {
93 c = get_next_char();
94 if (c == EOF)
95 break;
96 if (!isalnum(c))
97 break;
98 name[len++] = tolower(c);
99 if (len >= MAXNAME)
100 return -1;
102 name[len] = 0;
103 while (c == ' ' || c == '\t')
104 c = get_next_char();
106 value = NULL;
107 if (c != '\n') {
108 if (c != '=')
109 return -1;
110 value = parse_value();
111 if (!value)
112 return -1;
114 return fn(name, value);
117 static int get_base_var(char *name)
119 int baselen = 0;
121 for (;;) {
122 int c = get_next_char();
123 if (c == EOF)
124 return -1;
125 if (c == ']')
126 return baselen;
127 if (!isalnum(c))
128 return -1;
129 if (baselen > MAXNAME / 2)
130 return -1;
131 name[baselen++] = tolower(c);
135 static int git_parse_file(config_fn_t fn)
137 int comment = 0;
138 int baselen = 0;
139 static char var[MAXNAME];
141 for (;;) {
142 int c = get_next_char();
143 if (c == '\n') {
144 /* EOF? */
145 if (!config_file)
146 return 0;
147 comment = 0;
148 continue;
150 if (comment || isspace(c))
151 continue;
152 if (c == '#' || c == ';') {
153 comment = 1;
154 continue;
156 if (c == '[') {
157 baselen = get_base_var(var);
158 if (baselen <= 0)
159 break;
160 var[baselen++] = '.';
161 var[baselen] = 0;
162 continue;
164 if (!isalpha(c))
165 break;
166 var[baselen] = c;
167 if (get_value(fn, var, baselen+1) < 0)
168 break;
170 die("bad config file line %d", config_linenr);
173 int git_config_int(const char *name, const char *value)
175 if (value && *value) {
176 char *end;
177 int val = strtol(value, &end, 0);
178 if (!*end)
179 return val;
181 die("bad config value for '%s'", name);
184 int git_config_bool(const char *name, const char *value)
186 if (!value)
187 return 1;
188 if (!*value)
189 return 0;
190 if (!strcasecmp(value, "true"))
191 return 1;
192 if (!strcasecmp(value, "false"))
193 return 0;
194 return git_config_int(name, value) != 0;
197 int git_default_config(const char *var, const char *value)
199 /* This needs a better name */
200 if (!strcmp(var, "core.filemode")) {
201 trust_executable_bit = git_config_bool(var, value);
202 return 0;
205 /* Add other config variables here.. */
206 return 0;
209 int git_config(config_fn_t fn)
211 int ret;
212 FILE *f = fopen(git_path("config"), "r");
214 ret = -1;
215 if (f) {
216 config_file = f;
217 config_linenr = 1;
218 ret = git_parse_file(fn);
219 fclose(f);
221 return ret;