10
#include "strbuf.h"
11
#include "quote.h"
12
13
-#define MAXNAME (256)
14
-
13
typedef struct config_file {
14
struct config_file *prev;
15
FILE *f;
17
int linenr;
18
int eof;
19
struct strbuf value;
22
- char var[MAXNAME];
20
+ struct strbuf var;
21
} config_file;
22
23
static config_file *cf;
258
return isalnum(c) || c == '-';
259
}
260
263
-static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
261
+static int get_value(config_fn_t fn, void *data, struct strbuf *name)
262
{
263
int c;
264
char *value;
270
break;
271
if (!iskeychar(c))
272
break;
275
- name[len++] = tolower(c);
276
- if (len >= MAXNAME)
277
- return -1;
273
+ strbuf_addch(name, tolower(c));
274
}
279
- name[len] = 0;
275
+
276
while (c == ' ' || c == '\t')
277
c = get_next_char();
278
284
if (!value)
285
return -1;
286
}
291
- return fn(name, value, data);
287
+ return fn(name->buf, value, data);
288
}
289
294
-static int get_extended_base_var(char *name, int baselen, int c)
290
+static int get_extended_base_var(struct strbuf *name, int c)
291
{
292
do {
293
if (c == '\n')
298
/* We require the format to be '[base "extension"]' */
299
if (c != '"')
300
return -1;
305
- name[baselen++] = '.';
301
+ strbuf_addch(name, '.');
302
303
for (;;) {
304
int c = get_next_char();
311
if (c == '\n')
312
goto error_incomplete_line;
313
}
318
- name[baselen++] = c;
319
- if (baselen > MAXNAME / 2)
320
- return -1;
314
+ strbuf_addch(name, c);
315
}
316
317
/* Final ']' */
318
if (get_next_char() != ']')
319
return -1;
326
- return baselen;
320
+ return 0;
321
error_incomplete_line:
322
cf->linenr--;
323
return -1;
324
}
325
332
-static int get_base_var(char *name)
326
+static int get_base_var(struct strbuf *name)
327
{
334
- int baselen = 0;
335
-
328
for (;;) {
329
int c = get_next_char();
330
if (cf->eof)
331
return -1;
332
if (c == ']')
341
- return baselen;
333
+ return 0;
334
if (isspace(c))
343
- return get_extended_base_var(name, baselen, c);
335
+ return get_extended_base_var(name, c);
336
if (!iskeychar(c) && c != '.')
337
return -1;
346
- if (baselen > MAXNAME / 2)
347
- return -1;
348
- name[baselen++] = tolower(c);
338
+ strbuf_addch(name, tolower(c));
339
}
340
}
341
343
{
344
int comment = 0;
345
int baselen = 0;
356
- char *var = cf->var;
346
+ struct strbuf *var = &cf->var;
347
348
/* U+FEFF Byte Order Mark in UTF8 */
349
static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf";
379
continue;
380
}
381
if (c == '[') {
392
- baselen = get_base_var(var);
393
- if (baselen <= 0)
382
+ /* Reset prior to determining a new stem */
383
+ strbuf_reset(var);
384
+ if (get_base_var(var) < 0 || var->len < 1)
385
break;
395
- var[baselen++] = '.';
396
- var[baselen] = 0;
386
+ strbuf_addch(var, '.');
387
+ baselen = var->len;
388
continue;
389
}
390
if (!isalpha(c))
391
break;
401
- var[baselen] = tolower(c);
402
- if (get_value(fn, data, var, baselen+1) < 0)
392
+ /*
393
+ * Truncate the var name back to the section header
394
+ * stem prior to grabbing the suffix part of the name
395
+ * and the value.
396
+ */
397
+ strbuf_setlen(var, baselen);
398
+ strbuf_addch(var, tolower(c));
399
+ if (get_value(fn, data, var) < 0)
400
break;
401
}
402
die("bad config file line %d in %s", cf->linenr, cf->name);
896
top.linenr = 1;
897
top.eof = 0;
898
strbuf_init(&top.value, 1024);
899
+ strbuf_init(&top.var, 1024);
900
cf = ⊤
901
902
ret = git_parse_file(fn, data);
903
904
/* pop config-file parsing state stack */
905
strbuf_release(&top.value);
906
+ strbuf_release(&top.var);
907
cf = top.prev;
908
909
fclose(f);