12
12
13
13
#define MAXNAME (256)
14
14
15
- static FILE * config_file ;
16
- static const char * config_file_name ;
17
- static int config_linenr ;
18
- static int config_file_eof ;
15
+ typedef struct config_file {
16
+ struct config_file * prev ;
17
+ FILE * f ;
18
+ const char * name ;
19
+ int linenr ;
20
+ int eof ;
21
+ struct strbuf value ;
22
+ char var [MAXNAME ];
23
+ } config_file ;
24
+
25
+ static config_file * cf ;
26
+
19
27
static int zlib_compression_seen ;
20
28
21
29
const char * config_exclusive_filename = NULL ;
@@ -99,7 +107,7 @@ static int get_next_char(void)
99
107
FILE * f ;
100
108
101
109
c = '\n' ;
102
- if (( f = config_file ) != NULL ) {
110
+ if (cf && (( f = cf -> f ) != NULL ) ) {
103
111
c = fgetc (f );
104
112
if (c == '\r' ) {
105
113
/* DOS like systems */
@@ -110,9 +118,9 @@ static int get_next_char(void)
110
118
}
111
119
}
112
120
if (c == '\n' )
113
- config_linenr ++ ;
121
+ cf -> linenr ++ ;
114
122
if (c == EOF ) {
115
- config_file_eof = 1 ;
123
+ cf -> eof = 1 ;
116
124
c = '\n' ;
117
125
}
118
126
}
@@ -121,21 +129,20 @@ static int get_next_char(void)
121
129
122
130
static char * parse_value (void )
123
131
{
124
- static struct strbuf value = STRBUF_INIT ;
125
132
int quote = 0 , comment = 0 , space = 0 ;
126
133
127
- strbuf_reset (& value );
134
+ strbuf_reset (& cf -> value );
128
135
for (;;) {
129
136
int c = get_next_char ();
130
137
if (c == '\n' ) {
131
138
if (quote )
132
139
return NULL ;
133
- return value .buf ;
140
+ return cf -> value .buf ;
134
141
}
135
142
if (comment )
136
143
continue ;
137
144
if (isspace (c ) && !quote ) {
138
- if (value .len )
145
+ if (cf -> value .len )
139
146
space ++ ;
140
147
continue ;
141
148
}
@@ -146,7 +153,7 @@ static char *parse_value(void)
146
153
}
147
154
}
148
155
for (; space ; space -- )
149
- strbuf_addch (& value , ' ' );
156
+ strbuf_addch (& cf -> value , ' ' );
150
157
if (c == '\\' ) {
151
158
c = get_next_char ();
152
159
switch (c ) {
@@ -168,14 +175,14 @@ static char *parse_value(void)
168
175
default :
169
176
return NULL ;
170
177
}
171
- strbuf_addch (& value , c );
178
+ strbuf_addch (& cf -> value , c );
172
179
continue ;
173
180
}
174
181
if (c == '"' ) {
175
182
quote = 1 - quote ;
176
183
continue ;
177
184
}
178
- strbuf_addch (& value , c );
185
+ strbuf_addch (& cf -> value , c );
179
186
}
180
187
}
181
188
@@ -192,7 +199,7 @@ static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
192
199
/* Get the full name */
193
200
for (;;) {
194
201
c = get_next_char ();
195
- if (config_file_eof )
202
+ if (cf -> eof )
196
203
break ;
197
204
if (!iskeychar (c ))
198
205
break ;
@@ -256,7 +263,7 @@ static int get_base_var(char *name)
256
263
257
264
for (;;) {
258
265
int c = get_next_char ();
259
- if (config_file_eof )
266
+ if (cf -> eof )
260
267
return -1 ;
261
268
if (c == ']' )
262
269
return baselen ;
@@ -274,7 +281,7 @@ static int git_parse_file(config_fn_t fn, void *data)
274
281
{
275
282
int comment = 0 ;
276
283
int baselen = 0 ;
277
- static char var [ MAXNAME ] ;
284
+ char * var = cf -> var ;
278
285
279
286
/* U+FEFF Byte Order Mark in UTF8 */
280
287
static const unsigned char * utf8_bom = (unsigned char * ) "\xef\xbb\xbf" ;
@@ -298,7 +305,7 @@ static int git_parse_file(config_fn_t fn, void *data)
298
305
}
299
306
}
300
307
if (c == '\n' ) {
301
- if (config_file_eof )
308
+ if (cf -> eof )
302
309
return 0 ;
303
310
comment = 0 ;
304
311
continue ;
@@ -323,7 +330,7 @@ static int git_parse_file(config_fn_t fn, void *data)
323
330
if (get_value (fn , data , var , baselen + 1 ) < 0 )
324
331
break ;
325
332
}
326
- die ("bad config file line %d in %s" , config_linenr , config_file_name );
333
+ die ("bad config file line %d in %s" , cf -> linenr , cf -> name );
327
334
}
328
335
329
336
static int parse_unit_factor (const char * end , unsigned long * val )
@@ -374,8 +381,8 @@ int git_parse_ulong(const char *value, unsigned long *ret)
374
381
375
382
static void die_bad_config (const char * name )
376
383
{
377
- if (config_file_name )
378
- die ("bad config value for '%s' in %s" , name , config_file_name );
384
+ if (cf && cf -> name )
385
+ die ("bad config value for '%s' in %s" , name , cf -> name );
379
386
die ("bad config value for '%s'" , name );
380
387
}
381
388
@@ -795,13 +802,24 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
795
802
796
803
ret = -1 ;
797
804
if (f ) {
798
- config_file = f ;
799
- config_file_name = filename ;
800
- config_linenr = 1 ;
801
- config_file_eof = 0 ;
805
+ config_file top ;
806
+
807
+ /* push config-file parsing state stack */
808
+ top .prev = cf ;
809
+ top .f = f ;
810
+ top .name = filename ;
811
+ top .linenr = 1 ;
812
+ top .eof = 0 ;
813
+ strbuf_init (& top .value , 1024 );
814
+ cf = & top ;
815
+
802
816
ret = git_parse_file (fn , data );
817
+
818
+ /* pop config-file parsing state stack */
819
+ strbuf_release (& top .value );
820
+ cf = top .prev ;
821
+
803
822
fclose (f );
804
- config_file_name = NULL ;
805
823
}
806
824
return ret ;
807
825
}
@@ -909,6 +927,7 @@ static int store_aux(const char *key, const char *value, void *cb)
909
927
{
910
928
const char * ep ;
911
929
size_t section_len ;
930
+ FILE * f = cf -> f ;
912
931
913
932
switch (store .state ) {
914
933
case KEY_SEEN :
@@ -920,7 +939,7 @@ static int store_aux(const char *key, const char *value, void *cb)
920
939
return 1 ;
921
940
}
922
941
923
- store .offset [store .seen ] = ftell (config_file );
942
+ store .offset [store .seen ] = ftell (f );
924
943
store .seen ++ ;
925
944
}
926
945
break ;
@@ -947,19 +966,19 @@ static int store_aux(const char *key, const char *value, void *cb)
947
966
* Do not increment matches: this is no match, but we
948
967
* just made sure we are in the desired section.
949
968
*/
950
- store .offset [store .seen ] = ftell (config_file );
969
+ store .offset [store .seen ] = ftell (f );
951
970
/* fallthru */
952
971
case SECTION_END_SEEN :
953
972
case START :
954
973
if (matches (key , value )) {
955
- store .offset [store .seen ] = ftell (config_file );
974
+ store .offset [store .seen ] = ftell (f );
956
975
store .state = KEY_SEEN ;
957
976
store .seen ++ ;
958
977
} else {
959
978
if (strrchr (key , '.' ) - key == store .baselen &&
960
979
!strncmp (key , store .key , store .baselen )) {
961
980
store .state = SECTION_SEEN ;
962
- store .offset [store .seen ] = ftell (config_file );
981
+ store .offset [store .seen ] = ftell (f );
963
982
}
964
983
}
965
984
}
@@ -1415,6 +1434,7 @@ int git_config_rename_section(const char *old_name, const char *new_name)
1415
1434
struct lock_file * lock = xcalloc (sizeof (struct lock_file ), 1 );
1416
1435
int out_fd ;
1417
1436
char buf [1024 ];
1437
+ FILE * config_file ;
1418
1438
1419
1439
if (config_exclusive_filename )
1420
1440
config_filename = xstrdup (config_exclusive_filename );
0 commit comments