@@ -27,6 +27,12 @@ typedef struct cvar_t {
2727 git_config_entry * entry ;
2828} cvar_t ;
2929
30+ typedef struct git_config_file_iter {
31+ git_strmap_iter iter ;
32+ cvar_t * next ;
33+ } git_config_file_iter ;
34+
35+
3036#define CVAR_LIST_HEAD (list ) ((list)->head)
3137
3238#define CVAR_LIST_TAIL (list ) ((list)->tail)
@@ -247,52 +253,60 @@ static void backend_free(git_config_backend *_backend)
247253 git__free (backend );
248254}
249255
250- static int file_foreach (
251- git_config_backend * backend ,
252- const char * regexp ,
253- int (* fn )(const git_config_entry * , void * ),
254- void * data )
256+ static int config_iterator_new (
257+ git_config_backend_iter * iter ,
258+ struct git_config_backend * backend )
255259{
256260 diskfile_backend * b = (diskfile_backend * )backend ;
257- cvar_t * var , * next_var ;
258- const char * key ;
259- regex_t regex ;
260- int result = 0 ;
261+ git_config_file_iter * * it = ((git_config_file_iter * * ) iter );
261262
262- if (!b -> values )
263- return 0 ;
263+ if (!b -> values || git_strmap_num_entries ( b -> values ) < 1 )
264+ return -1 ;
264265
265- if (regexp != NULL ) {
266- if ((result = regcomp (& regex , regexp , REG_EXTENDED )) < 0 ) {
267- giterr_set_regex (& regex , result );
268- regfree (& regex );
269- return -1 ;
270- }
271- }
266+ * it = git__calloc (1 , sizeof (git_config_file_iter ));
267+ GITERR_CHECK_ALLOC (it );
272268
273- git_strmap_iter iter = git_strmap_begin (b -> values );
274- while (!(git_strmap_next (& key , (void * * ) & var , & iter , b -> values ) < 0 )) {
275- for (; var != NULL ; var = next_var ) {
276- next_var = CVAR_LIST_NEXT (var );
269+ (* it )-> iter = git_strmap_begin (b -> values );
270+ (* it )-> next = NULL ;
277271
278- /* skip non-matching keys if regexp was provided */
279- if (regexp && regexec (& regex , key , 0 , NULL , 0 ) != 0 )
280- continue ;
272+ return 0 ;
273+ }
281274
282- /* abort iterator on non-zero return value */
283- if (fn (var -> entry , data )) {
284- giterr_clear ();
285- result = GIT_EUSER ;
286- goto cleanup ;
287- }
288- }
275+ static void config_iterator_free (
276+ git_config_backend_iter iter )
277+ {
278+ git__free (iter );
279+ }
280+
281+ static int config_next (
282+ git_config_backend_iter * iter ,
283+ git_config_entry * entry ,
284+ struct git_config_backend * backend )
285+ {
286+ diskfile_backend * b = (diskfile_backend * )backend ;
287+ git_config_file_iter * it = * ((git_config_file_iter * * ) iter );
288+ int err ;
289+ cvar_t * var ;
290+ const char * key ;
291+
292+ if (it -> next == NULL ) {
293+ err = git_strmap_next (& key , (void * * ) & var , & (it -> iter ), b -> values );
294+ } else {
295+ key = it -> next -> entry -> name ;
296+ var = it -> next ;
289297 }
290298
291- cleanup :
292- if (regexp != NULL )
293- regfree (& regex );
299+ if (err < 0 ) {
300+ it -> next = NULL ;
301+ return -1 ;
302+ }
294303
295- return result ;
304+ entry -> name = key ;
305+ entry -> value = var -> entry -> value ;
306+ entry -> level = var -> entry -> level ;
307+ it -> next = CVAR_LIST_NEXT (var );
308+
309+ return 0 ;
296310}
297311
298312static int config_set (git_config_backend * cfg , const char * name , const char * value )
@@ -595,7 +609,9 @@ int git_config_file__ondisk(git_config_backend **out, const char *path)
595609 backend -> parent .set = config_set ;
596610 backend -> parent .set_multivar = config_set_multivar ;
597611 backend -> parent .del = config_delete ;
598- backend -> parent .foreach = file_foreach ;
612+ backend -> parent .iterator_new = config_iterator_new ;
613+ backend -> parent .iterator_free = config_iterator_free ;
614+ backend -> parent .next = config_next ;
599615 backend -> parent .refresh = config_refresh ;
600616 backend -> parent .free = backend_free ;
601617
0 commit comments