{"thread":{"id":"1141","subject":"[PATCH 3/13] Introduce struct rev_list_fns to rev-list.c to reduce amount of conditional processing.","startedAt":"2005-07-06T16:39:34Z","lastAt":"2005-07-06T16:39:34Z","messageCount":1,"participants":["Jon Seymour"],"isPatch":true,"patchVersion":1,"patchTotal":13},"messages":[{"id":"5723","messageId":"20050706163934.9851.qmail@blackcubes.dyndns.org","threadId":"1141","inReplyTo":null,"subject":"[PATCH 3/13] Introduce struct rev_list_fns to rev-list.c to reduce amount of conditional processing.","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2005-07-06T16:39:34Z","receivedAt":"2005-07-06T16:39:34Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"\nPer a suggestion from Linus, I have introduced the rev_list_fns structure into\nrev-list.c\n\nThe intent of this change is to make use of a strategy pattern to configure \nthe behaviour of git-rev-list and so help limit the ever-increasing \nproliferation of boolean switches throughout the body of the code.\n\nThis change also makes --show-breaks imply --merge-order rather than require\nit as before. There was no advantage to the previous strict argument\nchecking.\n\nA subsequent change will take advantage of this pattern to introduce a\ntopological sort switch.\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\n\n Documentation/git-rev-list.txt |    2 +\n rev-list.c                     |   54 +++++++++++++++++++++++++++-------------\n 2 files changed, 38 insertions(+), 18 deletions(-)\n\n77418fc85cc40e56ef66c5031025399c5e6ed787\ndiff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt\n--- a/Documentation/git-rev-list.txt\n+++ b/Documentation/git-rev-list.txt\n@@ -57,7 +57,7 @@ Commits marked with (^) are not parents \n These \"breaks\" represent necessary discontinuities implied by trying to\n represent an arbtirary DAG in a linear form.\n \n-*--show-breaks* is only valid if *--merge-order* is also specified.\n+*--show-breaks* implies **-merge-order*.\n \n Author\n ------\ndiff --git a/rev-list.c b/rev-list.c\n--- a/rev-list.c\n+++ b/rev-list.c\n@@ -39,6 +39,12 @@ static int merge_order = 0;\n static int show_breaks = 0;\n static int stop_traversal = 0;\n \n+struct rev_list_fns {\n+\tstruct commit_list * (*insert)(struct commit *, struct commit_list **);\n+\tstruct commit_list * (*limit)(struct commit_list *);\n+\tvoid (*process)(struct commit_list *);\n+};\n+\n static void show_commit(struct commit *commit)\n {\n \tcommit->object.flags |= SHOWN;\n@@ -410,9 +416,30 @@ static struct commit *get_commit_referen\n \tdie(\"%s is unknown object\", name);\n }\n \n+static void merge_order_sort(struct commit_list * list)\n+{\n+\tif (sort_list_in_merge_order(list, &process_commit))\n+\t\tdie(\"commit graph traversal failed\");\n+}\n+\n+struct rev_list_fns default_fns = {\n+\t&insert_by_date,\n+\t&limit_list,\n+        &show_commit_list\n+};\n+\n+struct rev_list_fns merge_order_fns = {\n+\t&commit_list_insert,\n+\tNULL,\n+\t&merge_order_sort\n+};\n+\n int main(int argc, char **argv)\n {\n \tstruct commit_list *list = NULL;\n+\tstruct commit_list *sorted = NULL;\n+\tstruct commit_list **list_tail = &list;\n+\tstruct rev_list_fns * fns = &default_fns;\n \tint i, limited = 0;\n \n \tfor (i = 1 ; i < argc; i++) {\n@@ -468,6 +495,7 @@ int main(int argc, char **argv)\n \t\t}\n \t\tif (!strcmp(arg, \"--show-breaks\")) {\n \t\t\tshow_breaks = 1;\n+\t\t\tmerge_order = 1;\n \t\t\tcontinue;\n \t\t}\n \n@@ -477,26 +505,18 @@ int main(int argc, char **argv)\n \t\t\targ++;\n \t\t\tlimited = 1;\n \t\t}\n-\t\tif (show_breaks && !merge_order)\n-\t\t\tusage(rev_list_usage);\n \t\tcommit = get_commit_reference(arg, flags);\n \t\tif (!commit)\n \t\t\tcontinue;\n-\t\tif (!merge_order) \n-\t\t\tinsert_by_date(commit, &list);\n-\t\telse \n-\t\t\tcommit_list_insert(commit, &list);\n+\t\tlist_tail = &commit_list_insert(commit, list_tail)->next;\n \t}\n-\n-\tif (!merge_order) {\t\t\n-\t        if (limited)\n-\t\t\tlist = limit_list(list);\n-\t\tshow_commit_list(list);\n-\t} else {\n-\t\tif (sort_list_in_merge_order(list, &process_commit)) {\n-\t\t\t  die(\"merge order sort failed\\n\");\n-\t\t}\n-\t}\n-\n+\tif (merge_order)\n+\t\tfns=&merge_order_fns;\n+\twhile (list)\n+\t\tfns->insert(pop_commit(&list), &sorted);\n+\tlist=sorted;\n+\tif (limited && fns->limit)\n+\t\tlist = fns->limit(list);\n+\tfns->process(list);\n \treturn 0;\n }\n------------\n"}]}