From 0e3994fa97e9876b571531444b97ae6e63fd744d Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 3 Jun 2005 01:37:54 -0700 Subject: [PATCH] [PATCH] diff: Clean up diff_scoreopt_parse(). This cleans up diff_scoreopt_parse() function that is used to parse the fractional notation -B, -C and -M option takes. The callers are modified to check for errors and complain. Earlier they silently ignored malformed input and falled back on the default. Signed-off-by: Junio C Hamano Signed-off-by: Linus Torvalds --- diff-cache.c | 9 ++++++--- diff-files.c | 15 +++++++++++---- diff-tree.c | 9 ++++++--- diff.c | 39 +++++++++++++++++++++++++++++++++++++++ diffcore-rename.c | 18 ------------------ 5 files changed, 62 insertions(+), 28 deletions(-) diff --git a/diff-cache.c b/diff-cache.c index 8e5f72bf3..e95fd70da 100644 --- a/diff-cache.c +++ b/diff-cache.c @@ -191,17 +191,20 @@ int main(int argc, const char **argv) continue; } if (!strncmp(arg, "-B", 2)) { - diff_break_opt = diff_scoreopt_parse(arg); + if ((diff_break_opt = diff_scoreopt_parse(arg)) == -1) + usage(diff_cache_usage); continue; } if (!strncmp(arg, "-M", 2)) { detect_rename = DIFF_DETECT_RENAME; - diff_score_opt = diff_scoreopt_parse(arg); + if ((diff_score_opt = diff_scoreopt_parse(arg)) == -1) + usage(diff_cache_usage); continue; } if (!strncmp(arg, "-C", 2)) { detect_rename = DIFF_DETECT_COPY; - diff_score_opt = diff_scoreopt_parse(arg); + if ((diff_score_opt = diff_scoreopt_parse(arg)) == -1) + usage(diff_cache_usage); continue; } if (!strcmp(arg, "-z")) { diff --git a/diff-files.c b/diff-files.c index a425112c9..5c895cca7 100644 --- a/diff-files.c +++ b/diff-files.c @@ -61,14 +61,21 @@ int main(int argc, const char **argv) orderfile = argv[1] + 2; else if (!strcmp(argv[1], "--pickaxe-all")) pickaxe_opts = DIFF_PICKAXE_ALL; - else if (!strncmp(argv[1], "-B", 2)) - diff_break_opt = diff_scoreopt_parse(argv[1]); + else if (!strncmp(argv[1], "-B", 2)) { + if ((diff_break_opt = + diff_scoreopt_parse(argv[1])) == -1) + usage(diff_files_usage); + } else if (!strncmp(argv[1], "-M", 2)) { - diff_score_opt = diff_scoreopt_parse(argv[1]); + if ((diff_score_opt = + diff_scoreopt_parse(argv[1])) == -1) + usage(diff_files_usage); detect_rename = DIFF_DETECT_RENAME; } else if (!strncmp(argv[1], "-C", 2)) { - diff_score_opt = diff_scoreopt_parse(argv[1]); + if ((diff_score_opt = + diff_scoreopt_parse(argv[1])) == -1) + usage(diff_files_usage); detect_rename = DIFF_DETECT_COPY; } else diff --git a/diff-tree.c b/diff-tree.c index c3a5617c5..3881c23ca 100644 --- a/diff-tree.c +++ b/diff-tree.c @@ -459,16 +459,19 @@ int main(int argc, const char **argv) } if (!strncmp(arg, "-M", 2)) { detect_rename = DIFF_DETECT_RENAME; - diff_score_opt = diff_scoreopt_parse(arg); + if ((diff_score_opt = diff_scoreopt_parse(arg)) == -1) + usage(diff_tree_usage); continue; } if (!strncmp(arg, "-C", 2)) { detect_rename = DIFF_DETECT_COPY; - diff_score_opt = diff_scoreopt_parse(arg); + if ((diff_score_opt = diff_scoreopt_parse(arg)) == -1) + usage(diff_tree_usage); continue; } if (!strncmp(arg, "-B", 2)) { - diff_break_opt = diff_scoreopt_parse(arg); + if ((diff_break_opt = diff_scoreopt_parse(arg)) == -1) + usage(diff_tree_usage); continue; } if (!strcmp(arg, "-z")) { diff --git a/diff.c b/diff.c index 5513632b9..7ccc1ed7c 100644 --- a/diff.c +++ b/diff.c @@ -589,6 +589,45 @@ void diff_setup(int flags) } +static int parse_num(const char **cp_p) +{ + int num, scale, ch, cnt; + const char *cp = *cp_p; + + cnt = num = 0; + scale = 1; + while ('0' <= (ch = *cp) && ch <= '9') { + if (cnt++ < 5) { + /* We simply ignore more than 5 digits precision. */ + scale *= 10; + num = num * 10 + ch - '0'; + } + *cp++; + } + *cp_p = cp; + + /* user says num divided by scale and we say internally that + * is MAX_SCORE * num / scale. + */ + return (MAX_SCORE * num / scale); +} + +int diff_scoreopt_parse(const char *opt) +{ + int opt1, cmd; + + if (*opt++ != '-') + return -1; + cmd = *opt++; + if (cmd != 'M' && cmd != 'C' && cmd != 'B') + return -1; /* that is not a -M, -C nor -B option */ + + opt1 = parse_num(&opt); + if (*opt != 0) + return -1; + return opt1; +} + struct diff_queue_struct diff_queued_diff; void diff_q(struct diff_queue_struct *queue, struct diff_filepair *dp) diff --git a/diffcore-rename.c b/diffcore-rename.c index eac782bbd..19325f245 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -229,24 +229,6 @@ static int score_compare(const void *a_, const void *b_) return b->score - a->score; } -int diff_scoreopt_parse(const char *opt) -{ - int diglen, num, scale, i; - if (opt[0] != '-' || (opt[1] != 'M' && opt[1] != 'C' && opt[1] != 'B')) - return -1; /* that is not a -M, -C nor -B option */ - diglen = strspn(opt+2, "0123456789"); - if (diglen == 0 || strlen(opt+2) != diglen) - return 0; /* use default */ - sscanf(opt+2, "%d", &num); - for (i = 0, scale = 1; i < diglen; i++) - scale *= 10; - - /* user says num divided by scale and we say internally that - * is MAX_SCORE * num / scale. - */ - return MAX_SCORE * num / scale; -} - void diffcore_rename(int detect_rename, int minimum_score) { struct diff_queue_struct *q = &diff_queued_diff; -- 2.30.2