67
return -1;
68
}
69
70
-static int parse_dirstat_params(struct diff_options *options, const char *params)
70
+static int parse_dirstat_params(struct diff_options *options, const char *params,
71
+ struct strbuf *errmsg)
72
{
73
const char *p = params;
74
+ int p_len, ret = 0;
75
+
76
while (*p) {
74
- if (!prefixcmp(p, "changes")) {
75
- p += 7;
77
+ p_len = strchrnul(p, ',') - p;
78
+ if (!memcmp(p, "changes", p_len)) {
79
DIFF_OPT_CLR(options, DIRSTAT_BY_LINE);
80
DIFF_OPT_CLR(options, DIRSTAT_BY_FILE);
78
- } else if (!prefixcmp(p, "lines")) {
79
- p += 5;
81
+ } else if (!memcmp(p, "lines", p_len)) {
82
DIFF_OPT_SET(options, DIRSTAT_BY_LINE);
83
DIFF_OPT_CLR(options, DIRSTAT_BY_FILE);
82
- } else if (!prefixcmp(p, "files")) {
83
- p += 5;
84
+ } else if (!memcmp(p, "files", p_len)) {
85
DIFF_OPT_CLR(options, DIRSTAT_BY_LINE);
86
DIFF_OPT_SET(options, DIRSTAT_BY_FILE);
86
- } else if (!prefixcmp(p, "noncumulative")) {
87
- p += 13;
87
+ } else if (!memcmp(p, "noncumulative", p_len)) {
88
DIFF_OPT_CLR(options, DIRSTAT_CUMULATIVE);
89
- } else if (!prefixcmp(p, "cumulative")) {
90
- p += 10;
89
+ } else if (!memcmp(p, "cumulative", p_len)) {
90
DIFF_OPT_SET(options, DIRSTAT_CUMULATIVE);
91
} else if (isdigit(*p)) {
92
char *end;
94
- options->dirstat_permille = strtoul(p, &end, 10) * 10;
95
- p = end;
96
- if (*p == '.' && isdigit(*++p)) {
93
+ int permille = strtoul(p, &end, 10) * 10;
94
+ if (*end == '.' && isdigit(*++end)) {
95
/* only use first digit */
98
- options->dirstat_permille += *p - '0';
96
+ permille += *end - '0';
97
/* .. and ignore any further digits */
100
- while (isdigit(*++p))
98
+ while (isdigit(*++end))
99
; /* nothing */
100
}
103
- } else
104
- return error("Unknown --dirstat parameter '%s'", p);
105
-
106
- if (*p) {
107
- /* more parameters, swallow separator */
108
- if (*p != ',')
109
- return error("Missing comma separator at char "
110
- "%"PRIuMAX" of '%s'",
111
- (uintmax_t) (p - params), params);
112
- p++;
101
+ if (end - p == p_len)
102
+ options->dirstat_permille = permille;
103
+ else {
104
+ strbuf_addf(errmsg, " Failed to parse dirstat cut-off percentage '%.*s'\n",
105
+ p_len, p);
106
+ ret++;
107
+ }
108
+ } else {
109
+ strbuf_addf(errmsg, " Unknown dirstat parameter '%.*s'\n",
110
+ p_len, p);
111
+ ret++;
112
}
113
+
114
+ p += p_len;
115
+
116
+ if (*p)
117
+ p++; /* more parameters, swallow separator */
118
}
115
- return 0;
119
+ return ret;
120
}
121
122
static int git_config_rename(const char *var, const char *value)
199
}
200
201
if (!strcmp(var, "diff.dirstat")) {
202
+ struct strbuf errmsg = STRBUF_INIT;
203
default_diff_options.dirstat_permille = diff_dirstat_permille_default;
199
- (void) parse_dirstat_params(&default_diff_options, value);
204
+ if (parse_dirstat_params(&default_diff_options, value, &errmsg))
205
+ warning("Found errors in 'diff.dirstat' config variable:\n%s",
206
+ errmsg.buf);
207
+ strbuf_release(&errmsg);
208
diff_dirstat_permille_default = default_diff_options.dirstat_permille;
209
return 0;
210
}
3258
3259
static int parse_dirstat_opt(struct diff_options *options, const char *params)
3260
{
3253
- if (parse_dirstat_params(options, params))
3254
- die("Failed to parse --dirstat/-X option parameter");
3261
+ struct strbuf errmsg = STRBUF_INIT;
3262
+ if (parse_dirstat_params(options, params, &errmsg))
3263
+ die("Failed to parse --dirstat/-X option parameter:\n%s",
3264
+ errmsg.buf);
3265
+ strbuf_release(&errmsg);
3266
/*
3267
* The caller knows a dirstat-related option is given from the command
3268
* line; allow it to say "return this_function();"