@@ -35,12 +35,6 @@ struct config_source {
35
35
long (* do_ftell )(struct config_source * c );
36
36
};
37
37
38
- struct config_set_element {
39
- struct hashmap_entry ent ;
40
- char * key ;
41
- struct string_list value_list ;
42
- };
43
-
44
38
static struct config_source * cf ;
45
39
46
40
static int zlib_compression_seen ;
@@ -252,6 +246,7 @@ static int get_next_char(void)
252
246
cf -> linenr ++ ;
253
247
if (c == EOF ) {
254
248
cf -> eof = 1 ;
249
+ cf -> linenr ++ ;
255
250
c = '\n' ;
256
251
}
257
252
return c ;
@@ -327,6 +322,7 @@ static int get_value(config_fn_t fn, void *data, struct strbuf *name)
327
322
{
328
323
int c ;
329
324
char * value ;
325
+ int ret ;
330
326
331
327
/* Get the full name */
332
328
for (;;) {
@@ -349,7 +345,15 @@ static int get_value(config_fn_t fn, void *data, struct strbuf *name)
349
345
if (!value )
350
346
return -1 ;
351
347
}
352
- return fn (name -> buf , value , data );
348
+ /*
349
+ * We already consumed the \n, but we need linenr to point to
350
+ * the line we just parsed during the call to fn to get
351
+ * accurate line number in error messages.
352
+ */
353
+ cf -> linenr -- ;
354
+ ret = fn (name -> buf , value , data );
355
+ cf -> linenr ++ ;
356
+ return ret ;
353
357
}
354
358
355
359
static int get_extended_base_var (struct strbuf * name , int c )
@@ -465,9 +469,9 @@ static int git_parse_source(config_fn_t fn, void *data)
465
469
break ;
466
470
}
467
471
if (cf -> die_on_error )
468
- die ("bad config file line %d in %s" , cf -> linenr , cf -> name );
472
+ die (_ ( "bad config file line %d in %s" ) , cf -> linenr , cf -> name );
469
473
else
470
- return error ("bad config file line %d in %s" , cf -> linenr , cf -> name );
474
+ return error (_ ( "bad config file line %d in %s" ) , cf -> linenr , cf -> name );
471
475
}
472
476
473
477
static int parse_unit_factor (const char * end , uintmax_t * val )
@@ -583,9 +587,9 @@ static void die_bad_number(const char *name, const char *value)
583
587
value = "" ;
584
588
585
589
if (cf && cf -> name )
586
- die ("bad numeric config value '%s' for '%s' in %s: %s" ,
590
+ die (_ ( "bad numeric config value '%s' for '%s' in %s: %s" ) ,
587
591
value , name , cf -> name , reason );
588
- die ("bad numeric config value '%s' for '%s': %s" , value , name , reason );
592
+ die (_ ( "bad numeric config value '%s' for '%s': %s" ) , value , name , reason );
589
593
}
590
594
591
595
int git_config_int (const char * name , const char * value )
@@ -670,7 +674,7 @@ int git_config_pathname(const char **dest, const char *var, const char *value)
670
674
return config_error_nonbool (var );
671
675
* dest = expand_user_path (value );
672
676
if (!* dest )
673
- die ("Failed to expand user dir in: '%s'" , value );
677
+ die (_ ( "failed to expand user dir in: '%s'") , value );
674
678
return 0 ;
675
679
}
676
680
@@ -748,7 +752,7 @@ static int git_default_core_config(const char *var, const char *value)
748
752
if (level == -1 )
749
753
level = Z_DEFAULT_COMPRESSION ;
750
754
else if (level < 0 || level > Z_BEST_COMPRESSION )
751
- die ("bad zlib compression level %d" , level );
755
+ die (_ ( "bad zlib compression level %d" ) , level );
752
756
zlib_compression_level = level ;
753
757
zlib_compression_seen = 1 ;
754
758
return 0 ;
@@ -759,7 +763,7 @@ static int git_default_core_config(const char *var, const char *value)
759
763
if (level == -1 )
760
764
level = Z_DEFAULT_COMPRESSION ;
761
765
else if (level < 0 || level > Z_BEST_COMPRESSION )
762
- die ("bad zlib compression level %d" , level );
766
+ die (_ ( "bad zlib compression level %d" ) , level );
763
767
core_compression_level = level ;
764
768
core_compression_seen = 1 ;
765
769
if (!zlib_compression_seen )
@@ -881,7 +885,7 @@ static int git_default_core_config(const char *var, const char *value)
881
885
else if (!strcmp (value , "link" ))
882
886
object_creation_mode = OBJECT_CREATION_USES_HARDLINKS ;
883
887
else
884
- die ("Invalid mode for object creation: %s" , value );
888
+ die (_ ( "invalid mode for object creation: %s") , value );
885
889
return 0 ;
886
890
}
887
891
@@ -1181,7 +1185,7 @@ int git_config_early(config_fn_t fn, void *data, const char *repo_config)
1181
1185
1182
1186
switch (git_config_from_parameters (fn , data )) {
1183
1187
case -1 : /* error */
1184
- die ("unable to parse command-line config" );
1188
+ die (_ ( "unable to parse command-line config" ) );
1185
1189
break ;
1186
1190
case 0 : /* found nothing */
1187
1191
break ;
@@ -1228,9 +1232,48 @@ int git_config_with_options(config_fn_t fn, void *data,
1228
1232
return ret ;
1229
1233
}
1230
1234
1231
- int git_config (config_fn_t fn , void * data )
1235
+ static void git_config_raw (config_fn_t fn , void * data )
1236
+ {
1237
+ if (git_config_with_options (fn , data , NULL , 1 ) < 0 )
1238
+ /*
1239
+ * git_config_with_options() normally returns only
1240
+ * positive values, as most errors are fatal, and
1241
+ * non-fatal potential errors are guarded by "if"
1242
+ * statements that are entered only when no error is
1243
+ * possible.
1244
+ *
1245
+ * If we ever encounter a non-fatal error, it means
1246
+ * something went really wrong and we should stop
1247
+ * immediately.
1248
+ */
1249
+ die (_ ("unknown error occured while reading the configuration files" ));
1250
+ }
1251
+
1252
+ static void configset_iter (struct config_set * cs , config_fn_t fn , void * data )
1232
1253
{
1233
- return git_config_with_options (fn , data , NULL , 1 );
1254
+ int i , value_index ;
1255
+ struct string_list * values ;
1256
+ struct config_set_element * entry ;
1257
+ struct configset_list * list = & cs -> list ;
1258
+ struct key_value_info * kv_info ;
1259
+
1260
+ for (i = 0 ; i < list -> nr ; i ++ ) {
1261
+ entry = list -> items [i ].e ;
1262
+ value_index = list -> items [i ].value_index ;
1263
+ values = & entry -> value_list ;
1264
+ if (fn (entry -> key , values -> items [value_index ].string , data ) < 0 ) {
1265
+ kv_info = values -> items [value_index ].util ;
1266
+ git_die_config_linenr (entry -> key , kv_info -> filename , kv_info -> linenr );
1267
+ }
1268
+ }
1269
+ }
1270
+
1271
+ static void git_config_check_init (void );
1272
+
1273
+ void git_config (config_fn_t fn , void * data )
1274
+ {
1275
+ git_config_check_init ();
1276
+ configset_iter (& the_config_set , fn , data );
1234
1277
}
1235
1278
1236
1279
static struct config_set_element * configset_find_element (struct config_set * cs , const char * key )
@@ -1258,6 +1301,10 @@ static struct config_set_element *configset_find_element(struct config_set *cs,
1258
1301
static int configset_add_value (struct config_set * cs , const char * key , const char * value )
1259
1302
{
1260
1303
struct config_set_element * e ;
1304
+ struct string_list_item * si ;
1305
+ struct configset_list_item * l_item ;
1306
+ struct key_value_info * kv_info = xmalloc (sizeof (* kv_info ));
1307
+
1261
1308
e = configset_find_element (cs , key );
1262
1309
/*
1263
1310
* Since the keys are being fed by git_config*() callback mechanism, they
@@ -1270,7 +1317,22 @@ static int configset_add_value(struct config_set *cs, const char *key, const cha
1270
1317
string_list_init (& e -> value_list , 1 );
1271
1318
hashmap_add (& cs -> config_hash , e );
1272
1319
}
1273
- string_list_append_nodup (& e -> value_list , value ? xstrdup (value ) : NULL );
1320
+ si = string_list_append_nodup (& e -> value_list , value ? xstrdup (value ) : NULL );
1321
+
1322
+ ALLOC_GROW (cs -> list .items , cs -> list .nr + 1 , cs -> list .alloc );
1323
+ l_item = & cs -> list .items [cs -> list .nr ++ ];
1324
+ l_item -> e = e ;
1325
+ l_item -> value_index = e -> value_list .nr - 1 ;
1326
+
1327
+ if (cf ) {
1328
+ kv_info -> filename = strintern (cf -> name );
1329
+ kv_info -> linenr = cf -> linenr ;
1330
+ } else {
1331
+ /* for values read from `git_config_from_parameters()` */
1332
+ kv_info -> filename = NULL ;
1333
+ kv_info -> linenr = -1 ;
1334
+ }
1335
+ si -> util = kv_info ;
1274
1336
1275
1337
return 0 ;
1276
1338
}
@@ -1285,6 +1347,9 @@ void git_configset_init(struct config_set *cs)
1285
1347
{
1286
1348
hashmap_init (& cs -> config_hash , (hashmap_cmp_fn )config_set_element_cmp , 0 );
1287
1349
cs -> hash_initialized = 1 ;
1350
+ cs -> list .nr = 0 ;
1351
+ cs -> list .alloc = 0 ;
1352
+ cs -> list .items = NULL ;
1288
1353
}
1289
1354
1290
1355
void git_configset_clear (struct config_set * cs )
@@ -1297,10 +1362,14 @@ void git_configset_clear(struct config_set *cs)
1297
1362
hashmap_iter_init (& cs -> config_hash , & iter );
1298
1363
while ((entry = hashmap_iter_next (& iter ))) {
1299
1364
free (entry -> key );
1300
- string_list_clear (& entry -> value_list , 0 );
1365
+ string_list_clear (& entry -> value_list , 1 );
1301
1366
}
1302
1367
hashmap_free (& cs -> config_hash , 1 );
1303
1368
cs -> hash_initialized = 0 ;
1369
+ free (cs -> list .items );
1370
+ cs -> list .nr = 0 ;
1371
+ cs -> list .alloc = 0 ;
1372
+ cs -> list .items = NULL ;
1304
1373
}
1305
1374
1306
1375
static int config_set_callback (const char * key , const char * value , void * cb )
@@ -1419,7 +1488,7 @@ static void git_config_check_init(void)
1419
1488
if (the_config_set .hash_initialized )
1420
1489
return ;
1421
1490
git_configset_init (& the_config_set );
1422
- git_config (config_set_callback , & the_config_set );
1491
+ git_config_raw (config_set_callback , & the_config_set );
1423
1492
}
1424
1493
1425
1494
void git_config_clear (void )
@@ -1443,8 +1512,12 @@ const struct string_list *git_config_get_value_multi(const char *key)
1443
1512
1444
1513
int git_config_get_string_const (const char * key , const char * * dest )
1445
1514
{
1515
+ int ret ;
1446
1516
git_config_check_init ();
1447
- return git_configset_get_string_const (& the_config_set , key , dest );
1517
+ ret = git_configset_get_string_const (& the_config_set , key , dest );
1518
+ if (ret < 0 )
1519
+ git_die_config (key , NULL );
1520
+ return ret ;
1448
1521
}
1449
1522
1450
1523
int git_config_get_string (const char * key , char * * dest )
@@ -1485,8 +1558,39 @@ int git_config_get_maybe_bool(const char *key, int *dest)
1485
1558
1486
1559
int git_config_get_pathname (const char * key , const char * * dest )
1487
1560
{
1561
+ int ret ;
1488
1562
git_config_check_init ();
1489
- return git_configset_get_pathname (& the_config_set , key , dest );
1563
+ ret = git_configset_get_pathname (& the_config_set , key , dest );
1564
+ if (ret < 0 )
1565
+ git_die_config (key , NULL );
1566
+ return ret ;
1567
+ }
1568
+
1569
+ NORETURN
1570
+ void git_die_config_linenr (const char * key , const char * filename , int linenr )
1571
+ {
1572
+ if (!filename )
1573
+ die (_ ("unable to parse '%s' from command-line config" ), key );
1574
+ else
1575
+ die (_ ("bad config variable '%s' in file '%s' at line %d" ),
1576
+ key , filename , linenr );
1577
+ }
1578
+
1579
+ NORETURN __attribute__((format (printf , 2 , 3 )))
1580
+ void git_die_config (const char * key , const char * err , ...)
1581
+ {
1582
+ const struct string_list * values ;
1583
+ struct key_value_info * kv_info ;
1584
+
1585
+ if (err ) {
1586
+ va_list params ;
1587
+ va_start (params , err );
1588
+ vreportf ("error: " , err , params );
1589
+ va_end (params );
1590
+ }
1591
+ values = git_config_get_value_multi (key );
1592
+ kv_info = values -> items [values -> nr - 1 ].util ;
1593
+ git_die_config_linenr (key , kv_info -> filename , kv_info -> linenr );
1490
1594
}
1491
1595
1492
1596
/*
@@ -1522,7 +1626,7 @@ static int store_aux(const char *key, const char *value, void *cb)
1522
1626
case KEY_SEEN :
1523
1627
if (matches (key , value )) {
1524
1628
if (store .seen == 1 && store .multi_replace == 0 ) {
1525
- warning ("%s has multiple values" , key );
1629
+ warning (_ ( "%s has multiple values" ) , key );
1526
1630
}
1527
1631
1528
1632
ALLOC_GROW (store .offset , store .seen + 1 ,
0 commit comments