commit 760fe30eb1f6351170157beaae12a0ca0c2698a9 from: Neels Hofmeyr date: Tue May 05 05:31:12 2020 UTC diff cmdline tool: allow using Patience by -p arg commit - a45330b1527e02e1627af02b55831f4cdf8794b4 commit + 760fe30eb1f6351170157beaae12a0ca0c2698a9 blob - 46bb7f527a44e83d238f01ff2980caf8ce2cd5e2 blob + 9946f9378ce360c8824bc29c354cf4d1f921648e --- diff/diff.c +++ diff/diff.c @@ -46,17 +46,26 @@ char *mmapfile(const char *, struct stat *); __dead void usage(void) { - fprintf(stderr, "usage: %s file1 file2\n", getprogname()); + fprintf(stderr, + "usage: %s [-p] file1 file2\n" + "\n" + " -p Use Patience Diff (slower but often nicer)\n" + , getprogname()); exit(1); } +static bool do_patience = false; + int main(int argc, char *argv[]) { int ch; - while ((ch = getopt(argc, argv, "")) != -1) { + while ((ch = getopt(argc, argv, "p")) != -1) { switch (ch) { + case 'p': + do_patience = true; + break; default: usage(); } @@ -71,31 +80,42 @@ main(int argc, char *argv[]) return diffreg(argv[0], argv[1], 0); } -const struct diff_algo_config myers, patience, myers_divide; +const struct diff_algo_config myers_then_patience, myers_then_myers_divide, patience, myers_divide; -const struct diff_algo_config myers = (struct diff_algo_config){ +const struct diff_algo_config myers_then_patience = (struct diff_algo_config){ .impl = diff_algo_myers, .permitted_state_size = 1024 * 1024 * sizeof(int), .fallback_algo = &patience, }; +const struct diff_algo_config myers_then_myers_divide = (struct diff_algo_config){ + .impl = diff_algo_myers, + .permitted_state_size = 1024 * 1024 * sizeof(int), + .fallback_algo = &myers_divide, +}; + const struct diff_algo_config patience = (struct diff_algo_config){ .impl = diff_algo_patience, .inner_algo = &patience, // After subdivision, do Patience again. - .fallback_algo = &myers_divide, // If subdivision failed, do Myers Divide et Impera. + .fallback_algo = &myers_then_myers_divide, // If subdivision failed, do Myers Divide et Impera. }; const struct diff_algo_config myers_divide = (struct diff_algo_config){ .impl = diff_algo_myers_divide, - .inner_algo = &myers, // When division succeeded, start from the top. - // (fallback_algo = NULL implies diff_algo_none). + .inner_algo = &myers_then_myers_divide, // When division succeeded, start from the top. + // (fallback_algo = NULL implies diff_algo_none). }; const struct diff_config diff_config = { .atomize_func = diff_atomize_text_by_line, - .algo = &myers, + .algo = &myers_then_myers_divide, }; +const struct diff_config diff_config_patience = { + .atomize_func = diff_atomize_text_by_line, + .algo = &myers_then_patience, +}; + int diffreg(char *file1, char *file2, int flags) { @@ -107,11 +127,12 @@ diffreg(char *file1, char *file2, int flags) }; struct diff_result *result; enum diff_rc rc; + const struct diff_config *cfg = do_patience ? &diff_config_patience : &diff_config; str1 = mmapfile(file1, &st1); str2 = mmapfile(file2, &st2); - result = diff_main(&diff_config, str1, st1.st_size, str2, st2.st_size); + result = diff_main(cfg, str1, st1.st_size, str2, st2.st_size); #if 0 rc = diff_output_plain(stdout, &info, result); #else