1010#include "strbuf.h"
1111#include "quote.h"
1212
13- typedef struct config_file {
14- struct config_file * prev ;
15- FILE * f ;
13+ struct config_source {
14+ struct config_source * prev ;
15+ union {
16+ FILE * file ;
17+ } u ;
1618 const char * name ;
1719 int linenr ;
1820 int eof ;
1921 struct strbuf value ;
2022 struct strbuf var ;
21- } config_file ;
2223
23- static config_file * cf ;
24+ int (* fgetc )(struct config_source * c );
25+ int (* ungetc )(int c , struct config_source * conf );
26+ long (* ftell )(struct config_source * c );
27+ };
28+
29+ static struct config_source * cf ;
2430
2531static int zlib_compression_seen ;
2632
33+ static int config_file_fgetc (struct config_source * conf )
34+ {
35+ return fgetc (conf -> u .file );
36+ }
37+
38+ static int config_file_ungetc (int c , struct config_source * conf )
39+ {
40+ return ungetc (c , conf -> u .file );
41+ }
42+
43+ static long config_file_ftell (struct config_source * conf )
44+ {
45+ return ftell (conf -> u .file );
46+ }
47+
2748#define MAX_INCLUDE_DEPTH 10
2849static const char include_depth_advice [] =
2950"exceeded maximum include depth (%d) while including\n"
@@ -168,15 +189,13 @@ int git_config_from_parameters(config_fn_t fn, void *data)
168189
169190static int get_next_char (void )
170191{
171- int c ;
172- FILE * f = cf -> f ;
192+ int c = cf -> fgetc (cf );
173193
174- c = fgetc (f );
175194 if (c == '\r' ) {
176195 /* DOS like systems */
177- c = fgetc (f );
196+ c = cf -> fgetc (cf );
178197 if (c != '\n' ) {
179- ungetc (c , f );
198+ cf -> ungetc (c , cf );
180199 c = '\r' ;
181200 }
182201 }
@@ -336,7 +355,7 @@ static int get_base_var(struct strbuf *name)
336355 }
337356}
338357
339- static int git_parse_file (config_fn_t fn , void * data )
358+ static int git_parse_source (config_fn_t fn , void * data )
340359{
341360 int comment = 0 ;
342361 int baselen = 0 ;
@@ -894,10 +913,11 @@ int git_default_config(const char *var, const char *value, void *dummy)
894913}
895914
896915/*
897- * The fields f and name of top need to be initialized before calling
916+ * All source specific fields in the union, name and the callbacks
917+ * fgetc, ungetc, ftell of top need to be initialized before calling
898918 * this function.
899919 */
900- static int do_config_from (struct config_file * top , config_fn_t fn , void * data )
920+ static int do_config_from (struct config_source * top , config_fn_t fn , void * data )
901921{
902922 int ret ;
903923
@@ -909,7 +929,7 @@ static int do_config_from(struct config_file *top, config_fn_t fn, void *data)
909929 strbuf_init (& top -> var , 1024 );
910930 cf = top ;
911931
912- ret = git_parse_file (fn , data );
932+ ret = git_parse_source (fn , data );
913933
914934 /* pop config-file parsing state stack */
915935 strbuf_release (& top -> value );
@@ -926,10 +946,13 @@ int git_config_from_file(config_fn_t fn, const char *filename, void *data)
926946
927947 ret = -1 ;
928948 if (f ) {
929- config_file top ;
949+ struct config_source top ;
930950
931- top .f = f ;
951+ top .u . file = f ;
932952 top .name = filename ;
953+ top .fgetc = config_file_fgetc ;
954+ top .ungetc = config_file_ungetc ;
955+ top .ftell = config_file_ftell ;
933956
934957 ret = do_config_from (& top , fn , data );
935958
@@ -1064,7 +1087,6 @@ static int store_aux(const char *key, const char *value, void *cb)
10641087{
10651088 const char * ep ;
10661089 size_t section_len ;
1067- FILE * f = cf -> f ;
10681090
10691091 switch (store .state ) {
10701092 case KEY_SEEN :
@@ -1076,7 +1098,7 @@ static int store_aux(const char *key, const char *value, void *cb)
10761098 return 1 ;
10771099 }
10781100
1079- store .offset [store .seen ] = ftell (f );
1101+ store .offset [store .seen ] = cf -> ftell (cf );
10801102 store .seen ++ ;
10811103 }
10821104 break ;
@@ -1103,19 +1125,19 @@ static int store_aux(const char *key, const char *value, void *cb)
11031125 * Do not increment matches: this is no match, but we
11041126 * just made sure we are in the desired section.
11051127 */
1106- store .offset [store .seen ] = ftell (f );
1128+ store .offset [store .seen ] = cf -> ftell (cf );
11071129 /* fallthru */
11081130 case SECTION_END_SEEN :
11091131 case START :
11101132 if (matches (key , value )) {
1111- store .offset [store .seen ] = ftell (f );
1133+ store .offset [store .seen ] = cf -> ftell (cf );
11121134 store .state = KEY_SEEN ;
11131135 store .seen ++ ;
11141136 } else {
11151137 if (strrchr (key , '.' ) - key == store .baselen &&
11161138 !strncmp (key , store .key , store .baselen )) {
11171139 store .state = SECTION_SEEN ;
1118- store .offset [store .seen ] = ftell (f );
1140+ store .offset [store .seen ] = cf -> ftell (cf );
11191141 }
11201142 }
11211143 }
0 commit comments