Skip to content

Commit f12fa9e

Browse files
avargitster
authored andcommitted
userdiff: add and use for_each_userdiff_driver()
Refactor the userdiff_find_by_namelen() function so that a new for_each_userdiff_driver() API function does most of the work. This will be useful for the same reason we've got other for_each_*() API functions as part of various APIs, and will be used in a follow-up commit. Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 82512e0 commit f12fa9e

File tree

2 files changed

+71
-12
lines changed

2 files changed

+71
-12
lines changed

userdiff.c

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -259,20 +259,33 @@ static struct userdiff_driver driver_false = {
259259
{ NULL, 0 }
260260
};
261261

262-
static struct userdiff_driver *userdiff_find_by_namelen(const char *k, size_t len)
262+
struct find_by_namelen_data {
263+
const char *name;
264+
size_t len;
265+
struct userdiff_driver *driver;
266+
};
267+
268+
static int userdiff_find_by_namelen_cb(struct userdiff_driver *driver,
269+
enum userdiff_driver_type type, void *priv)
263270
{
264-
int i;
265-
for (i = 0; i < ndrivers; i++) {
266-
struct userdiff_driver *drv = drivers + i;
267-
if (!strncmp(drv->name, k, len) && !drv->name[len])
268-
return drv;
269-
}
270-
for (i = 0; i < ARRAY_SIZE(builtin_drivers); i++) {
271-
struct userdiff_driver *drv = builtin_drivers + i;
272-
if (!strncmp(drv->name, k, len) && !drv->name[len])
273-
return drv;
271+
struct find_by_namelen_data *cb_data = priv;
272+
273+
if (!strncmp(driver->name, cb_data->name, cb_data->len) &&
274+
!driver->name[cb_data->len]) {
275+
cb_data->driver = driver;
276+
return 1; /* tell the caller to stop iterating */
274277
}
275-
return NULL;
278+
return 0;
279+
}
280+
281+
static struct userdiff_driver *userdiff_find_by_namelen(const char *name, size_t len)
282+
{
283+
struct find_by_namelen_data udcbdata = {
284+
.name = name,
285+
.len = len,
286+
};
287+
for_each_userdiff_driver(userdiff_find_by_namelen_cb, &udcbdata);
288+
return udcbdata.driver;
276289
}
277290

278291
static int parse_funcname(struct userdiff_funcname *f, const char *k,
@@ -379,3 +392,36 @@ struct userdiff_driver *userdiff_get_textconv(struct repository *r,
379392

380393
return driver;
381394
}
395+
396+
static int for_each_userdiff_driver_list(each_userdiff_driver_fn fn,
397+
enum userdiff_driver_type type, void *cb_data,
398+
struct userdiff_driver *drv,
399+
int drv_size)
400+
{
401+
int i;
402+
int ret;
403+
for (i = 0; i < drv_size; i++) {
404+
struct userdiff_driver *item = drv + i;
405+
if ((ret = fn(item, type, cb_data)))
406+
return ret;
407+
}
408+
return 0;
409+
}
410+
411+
int for_each_userdiff_driver(each_userdiff_driver_fn fn, void *cb_data)
412+
{
413+
int ret;
414+
415+
ret = for_each_userdiff_driver_list(fn, USERDIFF_DRIVER_TYPE_CUSTOM,
416+
cb_data, drivers, ndrivers);
417+
if (ret)
418+
return ret;
419+
420+
ret = for_each_userdiff_driver_list(fn, USERDIFF_DRIVER_TYPE_BUILTIN,
421+
cb_data, builtin_drivers,
422+
ARRAY_SIZE(builtin_drivers));
423+
if (ret)
424+
return ret;
425+
426+
return 0;
427+
}

userdiff.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,12 @@ struct userdiff_driver {
2121
struct notes_cache *textconv_cache;
2222
int textconv_want_cache;
2323
};
24+
enum userdiff_driver_type {
25+
USERDIFF_DRIVER_TYPE_BUILTIN = 1<<0,
26+
USERDIFF_DRIVER_TYPE_CUSTOM = 1<<1,
27+
};
28+
typedef int (*each_userdiff_driver_fn)(struct userdiff_driver *,
29+
enum userdiff_driver_type, void *);
2430

2531
int userdiff_config(const char *k, const char *v);
2632
struct userdiff_driver *userdiff_find_by_name(const char *name);
@@ -34,4 +40,11 @@ struct userdiff_driver *userdiff_find_by_path(struct index_state *istate,
3440
struct userdiff_driver *userdiff_get_textconv(struct repository *r,
3541
struct userdiff_driver *driver);
3642

43+
/*
44+
* Iterate over all userdiff drivers. The userdiff_driver_type
45+
* argument to each_userdiff_driver_fn indicates their type. Return
46+
* non-zero to exit early from the loop.
47+
*/
48+
int for_each_userdiff_driver(each_userdiff_driver_fn, void *);
49+
3750
#endif /* USERDIFF */

0 commit comments

Comments
 (0)