2626/* Max depth for [include] directives */
2727#define MAX_INCLUDE_DEPTH 10
2828
29+ typedef struct diskfile {
30+ git_futils_filestamp stamp ;
31+ git_oid checksum ;
32+ char * path ;
33+ git_array_t (struct diskfile ) includes ;
34+ } diskfile ;
35+
2936typedef struct {
3037 git_config_backend parent ;
3138 /* mutex to coordinate accessing the values */
@@ -44,7 +51,7 @@ typedef struct {
4451 git_filebuf locked_buf ;
4552 git_buf locked_content ;
4653
47- git_config_file file ;
54+ diskfile file ;
4855} diskfile_backend ;
4956
5057typedef struct {
@@ -55,14 +62,14 @@ typedef struct {
5562
5663typedef struct {
5764 const git_repository * repo ;
58- const char * file_path ;
65+ diskfile * file ;
5966 git_config_entries * entries ;
6067 git_config_level_t level ;
6168 unsigned int depth ;
6269} diskfile_parse_state ;
6370
64- static int config_read (git_config_entries * entries , const git_repository * repo , git_config_file * file , git_config_level_t level , int depth );
65- static int config_read_buffer (git_config_entries * entries , const git_repository * repo , git_config_file * file , git_config_level_t level , int depth , const char * buf , size_t buflen );
71+ static int config_read (git_config_entries * entries , const git_repository * repo , diskfile * file , git_config_level_t level , int depth );
72+ static int config_read_buffer (git_config_entries * entries , const git_repository * repo , diskfile * file , git_config_level_t level , int depth , const char * buf , size_t buflen );
6673static int config_write (diskfile_backend * cfg , const char * orig_key , const char * key , const p_regex_t * preg , const char * value );
6774static char * escape_value (const char * ptr );
6875
@@ -96,9 +103,9 @@ static git_config_entries *diskfile_entries_take(diskfile_header *h)
96103 return entries ;
97104}
98105
99- static void config_file_clear (git_config_file * file )
106+ static void config_file_clear (diskfile * file )
100107{
101- git_config_file * include ;
108+ diskfile * include ;
102109 uint32_t i ;
103110
104111 if (file == NULL )
@@ -134,9 +141,9 @@ static int config_open(git_config_backend *cfg, git_config_level_t level, const
134141 return res ;
135142}
136143
137- static int config_is_modified (int * modified , git_config_file * file )
144+ static int config_is_modified (int * modified , diskfile * file )
138145{
139- git_config_file * include ;
146+ diskfile * include ;
140147 git_buf buf = GIT_BUF_INIT ;
141148 git_oid hash ;
142149 uint32_t i ;
@@ -174,9 +181,9 @@ static int config_set_entries(git_config_backend *cfg, git_config_entries *entri
174181{
175182 diskfile_backend * b = (diskfile_backend * )cfg ;
176183 git_config_entries * old = NULL ;
177- git_config_file * include ;
184+ diskfile * include ;
178185 int error ;
179- size_t i ;
186+ uint32_t i ;
180187
181188 if (b -> header .parent .readonly )
182189 return config_error_readonly ();
@@ -677,18 +684,17 @@ static char *escape_value(const char *ptr)
677684 return git_buf_detach (& buf );
678685}
679686
680- static int parse_include (git_config_parser * reader ,
681- diskfile_parse_state * parse_data , const char * file )
687+ static int parse_include (diskfile_parse_state * parse_data , const char * file )
682688{
683- git_config_file * include ;
689+ diskfile * include ;
684690 git_buf path = GIT_BUF_INIT ;
685691 char * dir ;
686692 int result ;
687693
688694 if (!file )
689695 return 0 ;
690696
691- if ((result = git_path_dirname_r (& path , reader -> file -> path )) < 0 )
697+ if ((result = git_path_dirname_r (& path , parse_data -> file -> path )) < 0 )
692698 return result ;
693699
694700 dir = git_buf_detach (& path );
@@ -698,7 +704,7 @@ static int parse_include(git_config_parser *reader,
698704 if (result < 0 )
699705 return result ;
700706
701- include = git_array_alloc (reader -> file -> includes );
707+ include = git_array_alloc (parse_data -> file -> includes );
702708 GIT_ERROR_CHECK_ALLOC (include );
703709 memset (include , 0 , sizeof (* include ));
704710 git_array_init (include -> includes );
@@ -783,8 +789,7 @@ static const struct {
783789 { "gitdir/i:" , conditional_match_gitdir_i }
784790};
785791
786- static int parse_conditional_include (git_config_parser * reader ,
787- diskfile_parse_state * parse_data , const char * section , const char * file )
792+ static int parse_conditional_include (diskfile_parse_state * parse_data , const char * section , const char * file )
788793{
789794 char * condition ;
790795 size_t i ;
@@ -802,12 +807,12 @@ static int parse_conditional_include(git_config_parser *reader,
802807
803808 if ((error = conditions [i ].matches (& matches ,
804809 parse_data -> repo ,
805- parse_data -> file_path ,
810+ parse_data -> file -> path ,
806811 condition + strlen (conditions [i ].prefix ))) < 0 )
807812 break ;
808813
809814 if (matches )
810- error = parse_include (reader , parse_data , file );
815+ error = parse_include (parse_data , file );
811816
812817 break ;
813818 }
@@ -831,6 +836,7 @@ static int read_on_variable(
831836 const char * c ;
832837 int result = 0 ;
833838
839+ GIT_UNUSED (reader );
834840 GIT_UNUSED (line );
835841 GIT_UNUSED (line_len );
836842
@@ -863,19 +869,18 @@ static int read_on_variable(
863869
864870 /* Add or append the new config option */
865871 if (!git__strcmp (entry -> name , "include.path" ))
866- result = parse_include (reader , parse_data , entry -> value );
872+ result = parse_include (parse_data , entry -> value );
867873 else if (!git__prefixcmp (entry -> name , "includeif." ) &&
868874 !git__suffixcmp (entry -> name , ".path" ))
869- result = parse_conditional_include (reader , parse_data ,
870- entry -> name , entry -> value );
875+ result = parse_conditional_include (parse_data , entry -> name , entry -> value );
871876
872877 return result ;
873878}
874879
875880static int config_read_buffer (
876881 git_config_entries * entries ,
877882 const git_repository * repo ,
878- git_config_file * file ,
883+ diskfile * file ,
879884 git_config_level_t level ,
880885 int depth ,
881886 const char * buf ,
@@ -891,7 +896,7 @@ static int config_read_buffer(
891896 }
892897
893898 /* Initialize the reading position */
894- reader .file = file ;
899+ reader .path = file -> path ;
895900 git_parse_ctx_init (& reader .ctx , buf , buflen );
896901
897902 /* If the file is empty, there's nothing for us to do */
@@ -901,7 +906,7 @@ static int config_read_buffer(
901906 }
902907
903908 parse_data .repo = repo ;
904- parse_data .file_path = file -> path ;
909+ parse_data .file = file ;
905910 parse_data .entries = entries ;
906911 parse_data .level = level ;
907912 parse_data .depth = depth ;
@@ -915,7 +920,7 @@ static int config_read_buffer(
915920static int config_read (
916921 git_config_entries * entries ,
917922 const git_repository * repo ,
918- git_config_file * file ,
923+ diskfile * file ,
919924 git_config_level_t level ,
920925 int depth )
921926{
@@ -1169,37 +1174,30 @@ static int write_on_eof(
11691174 */
11701175static int config_write (diskfile_backend * cfg , const char * orig_key , const char * key , const p_regex_t * preg , const char * value )
11711176{
1172- int result ;
1173- char * orig_section , * section , * orig_name , * name , * ldot ;
1174- git_filebuf file = GIT_FILEBUF_INIT ;
1177+ char * orig_section = NULL , * section = NULL , * orig_name , * name , * ldot ;
11751178 git_buf buf = GIT_BUF_INIT , contents = GIT_BUF_INIT ;
1176- git_config_parser reader ;
1179+ git_config_parser parser = GIT_CONFIG_PARSER_INIT ;
1180+ git_filebuf file = GIT_FILEBUF_INIT ;
11771181 struct write_data write_data ;
1182+ int error ;
11781183
1179- memset (& reader , 0 , sizeof (reader ));
1180- reader .file = & cfg -> file ;
1184+ memset (& write_data , 0 , sizeof (write_data ));
11811185
11821186 if (cfg -> locked ) {
1183- result = git_buf_puts (& contents , git_buf_cstr (& cfg -> locked_content ) == NULL ? "" : git_buf_cstr (& cfg -> locked_content ));
1187+ error = git_buf_puts (& contents , git_buf_cstr (& cfg -> locked_content ) == NULL ? "" : git_buf_cstr (& cfg -> locked_content ));
11841188 } else {
1185- /* Lock the file */
1186- if ((result = git_filebuf_open (
1187- & file , cfg -> file .path , GIT_FILEBUF_HASH_CONTENTS , GIT_CONFIG_FILE_MODE )) < 0 ) {
1188- git_buf_dispose (& contents );
1189- return result ;
1190- }
1189+ if ((error = git_filebuf_open (& file , cfg -> file .path , GIT_FILEBUF_HASH_CONTENTS ,
1190+ GIT_CONFIG_FILE_MODE )) < 0 )
1191+ goto done ;
11911192
11921193 /* We need to read in our own config file */
1193- result = git_futils_readbuffer (& contents , cfg -> file .path );
1194+ error = git_futils_readbuffer (& contents , cfg -> file .path );
11941195 }
1196+ if (error < 0 && error != GIT_ENOTFOUND )
1197+ goto done ;
11951198
1196- /* Initialise the reading position */
1197- if (result == 0 || result == GIT_ENOTFOUND ) {
1198- git_parse_ctx_init (& reader .ctx , contents .ptr , contents .size );
1199- } else {
1200- git_filebuf_cleanup (& file );
1201- return -1 ; /* OS error when reading the file */
1202- }
1199+ if ((git_config_parser_init (& parser , cfg -> file .path , contents .ptr , contents .size )) < 0 )
1200+ goto done ;
12031201
12041202 ldot = strrchr (key , '.' );
12051203 name = ldot + 1 ;
@@ -1212,30 +1210,16 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
12121210 GIT_ERROR_CHECK_ALLOC (orig_section );
12131211
12141212 write_data .buf = & buf ;
1215- git_buf_init (& write_data .buffered_comment , 0 );
12161213 write_data .orig_section = orig_section ;
12171214 write_data .section = section ;
1218- write_data .in_section = 0 ;
1219- write_data .preg_replaced = 0 ;
12201215 write_data .orig_name = orig_name ;
12211216 write_data .name = name ;
12221217 write_data .preg = preg ;
12231218 write_data .value = value ;
12241219
1225- result = git_config_parse (& reader ,
1226- write_on_section ,
1227- write_on_variable ,
1228- write_on_comment ,
1229- write_on_eof ,
1230- & write_data );
1231- git__free (section );
1232- git__free (orig_section );
1233- git_buf_dispose (& write_data .buffered_comment );
1234-
1235- if (result < 0 ) {
1236- git_filebuf_cleanup (& file );
1220+ if ((error = git_config_parse (& parser , write_on_section , write_on_variable ,
1221+ write_on_comment , write_on_eof , & write_data )) < 0 )
12371222 goto done ;
1238- }
12391223
12401224 if (cfg -> locked ) {
12411225 size_t len = buf .asize ;
@@ -1245,16 +1229,21 @@ static int config_write(diskfile_backend *cfg, const char *orig_key, const char
12451229 } else {
12461230 git_filebuf_write (& file , git_buf_cstr (& buf ), git_buf_len (& buf ));
12471231
1248- if ((result = git_filebuf_commit (& file )) < 0 )
1232+ if ((error = git_filebuf_commit (& file )) < 0 )
12491233 goto done ;
12501234
1251- if ((result = config_refresh_from_buffer (& cfg -> header .parent , buf .ptr , buf .size )) < 0 )
1235+ if ((error = config_refresh_from_buffer (& cfg -> header .parent , buf .ptr , buf .size )) < 0 )
12521236 goto done ;
12531237 }
12541238
12551239done :
1240+ git__free (section );
1241+ git__free (orig_section );
1242+ git_buf_dispose (& write_data .buffered_comment );
12561243 git_buf_dispose (& buf );
12571244 git_buf_dispose (& contents );
1258- git_parse_ctx_clear (& reader .ctx );
1259- return result ;
1245+ git_filebuf_cleanup (& file );
1246+ git_config_parser_dispose (& parser );
1247+
1248+ return error ;
12601249}
0 commit comments