diff: refactor the word-diff setup from builtin_diff_cmd

Quite a chunk of builtin_diff_cmd deals with word-diff setup, defaults and such. This makes the function a bit hard to read, but is also asymmetric because the corresponding teardown lives in free_diff_words_data already. Refactor into a new function init_diff_words_data. For simplicity, also shuffle around some functions it depends on. Signed-off-by: Thomas Rast <trast@student.ethz.ch> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Thomas Rast committed Mar 14, 2012 at 19:24 UTC 77d1a520fb5b8ad8cc86228023f16a44b75c05d1
1 file changed +63 -56
diff.c
+63 -56
@@ -987,6 +987,67 @@ static void diff_words_flush(struct emit_callback *ecbdata)
987 diff_words_show(ecbdata->diff_words);
988 }
989
990 +static void diff_filespec_load_driver(struct diff_filespec *one)
991 +{
992 + /* Use already-loaded driver */
993 + if (one->driver)
994 + return;
995 +
996 + if (S_ISREG(one->mode))
997 + one->driver = userdiff_find_by_path(one->path);
998 +
999 + /* Fallback to default settings */
1000 + if (!one->driver)
1001 + one->driver = userdiff_find_by_name("default");
1002 +}
1003 +
1004 +static const char *userdiff_word_regex(struct diff_filespec *one)
1005 +{
1006 + diff_filespec_load_driver(one);
1007 + return one->driver->word_regex;
1008 +}
1009 +
1010 +static void init_diff_words_data(struct emit_callback *ecbdata,
1011 + struct diff_options *o,
1012 + struct diff_filespec *one,
1013 + struct diff_filespec *two)
1014 +{
1015 + int i;
1016 +
1017 + ecbdata->diff_words =
1018 + xcalloc(1, sizeof(struct diff_words_data));
1019 + ecbdata->diff_words->type = o->word_diff;
1020 + ecbdata->diff_words->opt = o;
1021 + if (!o->word_regex)
1022 + o->word_regex = userdiff_word_regex(one);
1023 + if (!o->word_regex)
1024 + o->word_regex = userdiff_word_regex(two);
1025 + if (!o->word_regex)
1026 + o->word_regex = diff_word_regex_cfg;
1027 + if (o->word_regex) {
1028 + ecbdata->diff_words->word_regex = (regex_t *)
1029 + xmalloc(sizeof(regex_t));
1030 + if (regcomp(ecbdata->diff_words->word_regex,
1031 + o->word_regex,
1032 + REG_EXTENDED | REG_NEWLINE))
1033 + die ("Invalid regular expression: %s",
1034 + o->word_regex);
1035 + }
1036 + for (i = 0; i < ARRAY_SIZE(diff_words_styles); i++) {
1037 + if (o->word_diff == diff_words_styles[i].type) {
1038 + ecbdata->diff_words->style =
1039 + &diff_words_styles[i];
1040 + break;
1041 + }
1042 + }
1043 + if (want_color(o->use_color)) {
1044 + struct diff_words_style *st = ecbdata->diff_words->style;
1045 + st->old.color = diff_get_color_opt(o, DIFF_FILE_OLD);
1046 + st->new.color = diff_get_color_opt(o, DIFF_FILE_NEW);
1047 + st->ctx.color = diff_get_color_opt(o, DIFF_PLAIN);
1048 + }
1049 +}
1050 +
1051 static void free_diff_words_data(struct emit_callback *ecbdata)
1052 {
1053 if (ecbdata->diff_words) {
@@ -2016,20 +2077,6 @@ static void emit_binary_diff(FILE *file, mmfile_t *one, mmfile_t *two, char *pre
2077 emit_binary_diff_body(file, two, one, prefix);
2078 }
2079
2019 -static void diff_filespec_load_driver(struct diff_filespec *one)
2020 -{
2021 - /* Use already-loaded driver */
2022 - if (one->driver)
2023 - return;
2024 -
2025 - if (S_ISREG(one->mode))
2026 - one->driver = userdiff_find_by_path(one->path);
2027 -
2028 - /* Fallback to default settings */
2029 - if (!one->driver)
2030 - one->driver = userdiff_find_by_name("default");
2031 -}
2032 -
2080 int diff_filespec_is_binary(struct diff_filespec *one)
2081 {
2082 if (one->is_binary == -1) {
@@ -2055,12 +2102,6 @@ static const struct userdiff_funcname *diff_funcname_pattern(struct diff_filespe
2102 return one->driver->funcname.pattern ? &one->driver->funcname : NULL;
2103 }
2104
2058 -static const char *userdiff_word_regex(struct diff_filespec *one)
2059 -{
2060 - diff_filespec_load_driver(one);
2061 - return one->driver->word_regex;
2062 -}
2063 -
2105 void diff_set_mnemonic_prefix(struct diff_options *options, const char *a, const char *b)
2106 {
2107 if (!options->a_prefix)
@@ -2247,42 +2288,8 @@ static void builtin_diff(const char *name_a,
2288 xecfg.ctxlen = strtoul(diffopts + 10, NULL, 10);
2289 else if (!prefixcmp(diffopts, "-u"))
2290 xecfg.ctxlen = strtoul(diffopts + 2, NULL, 10);
2250 - if (o->word_diff) {
2251 - int i;
2252 -
2253 - ecbdata.diff_words =
2254 - xcalloc(1, sizeof(struct diff_words_data));
2255 - ecbdata.diff_words->type = o->word_diff;
2256 - ecbdata.diff_words->opt = o;
2257 - if (!o->word_regex)
2258 - o->word_regex = userdiff_word_regex(one);
2259 - if (!o->word_regex)
2260 - o->word_regex = userdiff_word_regex(two);
2261 - if (!o->word_regex)
2262 - o->word_regex = diff_word_regex_cfg;
2263 - if (o->word_regex) {
2264 - ecbdata.diff_words->word_regex = (regex_t *)
2265 - xmalloc(sizeof(regex_t));
2266 - if (regcomp(ecbdata.diff_words->word_regex,
2267 - o->word_regex,
2268 - REG_EXTENDED | REG_NEWLINE))
2269 - die ("Invalid regular expression: %s",
2270 - o->word_regex);
2271 - }
2272 - for (i = 0; i < ARRAY_SIZE(diff_words_styles); i++) {
2273 - if (o->word_diff == diff_words_styles[i].type) {
2274 - ecbdata.diff_words->style =
2275 - &diff_words_styles[i];
2276 - break;
2277 - }
2278 - }
2279 - if (want_color(o->use_color)) {
2280 - struct diff_words_style *st = ecbdata.diff_words->style;
2281 - st->old.color = diff_get_color_opt(o, DIFF_FILE_OLD);
2282 - st->new.color = diff_get_color_opt(o, DIFF_FILE_NEW);
2283 - st->ctx.color = diff_get_color_opt(o, DIFF_PLAIN);
2284 - }
2285 - }
2291 + if (o->word_diff)
2292 + init_diff_words_data(&ecbdata, o, one, two);
2293 xdi_diff_outf(&mf1, &mf2, fn_out_consume, &ecbdata,
2294 &xpp, &xecfg);
2295 if (o->word_diff)