| 3288 | }; |
| 3289 | |
| 3290 | static long gather_dirstat(struct diff_options *opt, struct dirstat_dir *dir, |
| 3291 | unsigned long changed, const char *base, int baselen) |
| 3292 | { |
| 3293 | unsigned long sum_changes = 0; |
| 3294 | unsigned int sources = 0; |
| 3295 | const char *line_prefix = diff_line_prefix(opt); |
| 3296 | |
| 3297 | while (dir->nr) { |
| 3298 | struct dirstat_file *f = dir->files; |
| 3299 | int namelen = strlen(f->name); |
| 3300 | unsigned long changes; |
| 3301 | const char *slash; |
| 3302 | |
| 3303 | if (namelen < baselen) |
| 3304 | break; |
| 3305 | if (memcmp(f->name, base, baselen)) |
| 3306 | break; |
| 3307 | slash = strchr(f->name + baselen, '/'); |
| 3308 | if (slash) { |
| 3309 | int newbaselen = slash + 1 - f->name; |
| 3310 | changes = gather_dirstat(opt, dir, changed, f->name, newbaselen); |
| 3311 | sources++; |
| 3312 | } else { |
| 3313 | changes = f->changed; |
| 3314 | dir->files++; |
| 3315 | dir->nr--; |
| 3316 | sources += 2; |
| 3317 | } |
| 3318 | sum_changes += changes; |
| 3319 | } |
| 3320 | |
| 3321 | /* |
| 3322 | * We don't report dirstat's for |
| 3323 | * - the top level |
| 3324 | * - or cases where everything came from a single directory |
| 3325 | * under this directory (sources == 1). |
| 3326 | */ |
| 3327 | if (baselen && sources != 1) { |
| 3328 | if (sum_changes) { |
| 3329 | int permille = sum_changes * 1000 / changed; |
| 3330 | if (permille >= dir->permille) { |
| 3331 | fprintf(opt->file, "%s%4d.%01d%% %.*s\n", line_prefix, |
| 3332 | permille / 10, permille % 10, baselen, base); |
| 3333 | if (!dir->cumulative) |
| 3334 | return 0; |
| 3335 | } |
| 3336 | } |
| 3337 | } |
| 3338 | return sum_changes; |
| 3339 | } |
| 3340 | |
| 3341 | static int dirstat_compare(const void *_a, const void *_b) |
| 3342 | { |
no test coverage detected