10
10
#include "strbuf.h"
11
11
#include "quote.h"
12
12
13
- #define MAXNAME (256)
14
-
15
13
typedef struct config_file {
16
14
struct config_file * prev ;
17
15
FILE * f ;
18
16
const char * name ;
19
17
int linenr ;
20
18
int eof ;
21
19
struct strbuf value ;
22
- char var [ MAXNAME ] ;
20
+ struct strbuf var ;
23
21
} config_file ;
24
22
25
23
static config_file * cf ;
@@ -260,7 +258,7 @@ static inline int iskeychar(int c)
260
258
return isalnum (c ) || c == '-' ;
261
259
}
262
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 )
264
262
{
265
263
int c ;
266
264
char * value ;
@@ -272,11 +270,9 @@ static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
272
270
break ;
273
271
if (!iskeychar (c ))
274
272
break ;
275
- name [len ++ ] = tolower (c );
276
- if (len >= MAXNAME )
277
- return -1 ;
273
+ strbuf_addch (name , tolower (c ));
278
274
}
279
- name [ len ] = 0 ;
275
+
280
276
while (c == ' ' || c == '\t' )
281
277
c = get_next_char ();
282
278
@@ -288,10 +284,10 @@ static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
288
284
if (!value )
289
285
return -1 ;
290
286
}
291
- return fn (name , value , data );
287
+ return fn (name -> buf , value , data );
292
288
}
293
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 )
295
291
{
296
292
do {
297
293
if (c == '\n' )
@@ -302,7 +298,7 @@ static int get_extended_base_var(char *name, int baselen, int c)
302
298
/* We require the format to be '[base "extension"]' */
303
299
if (c != '"' )
304
300
return -1 ;
305
- name [ baselen ++ ] = '.' ;
301
+ strbuf_addch ( name , '.' ) ;
306
302
307
303
for (;;) {
308
304
int c = get_next_char ();
@@ -315,45 +311,39 @@ static int get_extended_base_var(char *name, int baselen, int c)
315
311
if (c == '\n' )
316
312
goto error_incomplete_line ;
317
313
}
318
- name [baselen ++ ] = c ;
319
- if (baselen > MAXNAME / 2 )
320
- return -1 ;
314
+ strbuf_addch (name , c );
321
315
}
322
316
323
317
/* Final ']' */
324
318
if (get_next_char () != ']' )
325
319
return -1 ;
326
- return baselen ;
320
+ return 0 ;
327
321
error_incomplete_line :
328
322
cf -> linenr -- ;
329
323
return -1 ;
330
324
}
331
325
332
- static int get_base_var (char * name )
326
+ static int get_base_var (struct strbuf * name )
333
327
{
334
- int baselen = 0 ;
335
-
336
328
for (;;) {
337
329
int c = get_next_char ();
338
330
if (cf -> eof )
339
331
return -1 ;
340
332
if (c == ']' )
341
- return baselen ;
333
+ return 0 ;
342
334
if (isspace (c ))
343
- return get_extended_base_var (name , baselen , c );
335
+ return get_extended_base_var (name , c );
344
336
if (!iskeychar (c ) && c != '.' )
345
337
return -1 ;
346
- if (baselen > MAXNAME / 2 )
347
- return -1 ;
348
- name [baselen ++ ] = tolower (c );
338
+ strbuf_addch (name , tolower (c ));
349
339
}
350
340
}
351
341
352
342
static int git_parse_file (config_fn_t fn , void * data )
353
343
{
354
344
int comment = 0 ;
355
345
int baselen = 0 ;
356
- char * var = cf -> var ;
346
+ struct strbuf * var = & cf -> var ;
357
347
358
348
/* U+FEFF Byte Order Mark in UTF8 */
359
349
static const unsigned char * utf8_bom = (unsigned char * ) "\xef\xbb\xbf" ;
@@ -389,17 +379,24 @@ static int git_parse_file(config_fn_t fn, void *data)
389
379
continue ;
390
380
}
391
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 )
394
385
break ;
395
- var [ baselen ++ ] = '.' ;
396
- var [ baselen ] = 0 ;
386
+ strbuf_addch ( var , '.' ) ;
387
+ baselen = var -> len ;
397
388
continue ;
398
389
}
399
390
if (!isalpha (c ))
400
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 )
403
400
break ;
404
401
}
405
402
die ("bad config file line %d in %s" , cf -> linenr , cf -> name );
@@ -899,12 +896,14 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
899
896
top .linenr = 1 ;
900
897
top .eof = 0 ;
901
898
strbuf_init (& top .value , 1024 );
899
+ strbuf_init (& top .var , 1024 );
902
900
cf = & top ;
903
901
904
902
ret = git_parse_file (fn , data );
905
903
906
904
/* pop config-file parsing state stack */
907
905
strbuf_release (& top .value );
906
+ strbuf_release (& top .var );
908
907
cf = top .prev ;
909
908
910
909
fclose (f );
0 commit comments