--- fdupes.c +++ fdupes.c @@ -581,24 +581,45 @@ return 1; } +/* from qsort man page */ +static int +cmpstringp(const void *p1, const void *p2) +{ + /* The actual arguments to this function are "pointers to + pointers to char", but strcmp(3) arguments are "pointers + to char", hence the following cast plus dereference */ + + return strcmp(* (char * const *) p1, * (char * const *) p2); +} + void printmatches(file_t *files) { file_t *tmpfile; while (files != NULL) { if (files->hasdupes) { + char **names = (char**)malloc(sizeof(char*)*(files->hasdupes+1)); + int count = 0, index; + names[count++] = files->d_name; + tmpfile = files->duplicates; + while (tmpfile != NULL) { + names[count++] = tmpfile->d_name; + tmpfile = tmpfile->duplicates; + } + qsort(names, count, sizeof(char *), cmpstringp); + if (!ISFLAG(flags, F_OMITFIRST)) { if (ISFLAG(flags, F_SHOWSIZE)) printf("%ld byte%seach:\n", files->size, (files->size != 1) ? "s " : " "); - if (ISFLAG(flags, F_DSAMELINE)) escapefilename("\\ ", &files->d_name); - printf("%s%c", files->d_name, ISFLAG(flags, F_DSAMELINE)?' ':'\n'); + if (ISFLAG(flags, F_DSAMELINE)) escapefilename("\\ ", &names[0]); + printf("%s%c", names[0], ISFLAG(flags, F_DSAMELINE)?' ':'\n'); } - tmpfile = files->duplicates; - while (tmpfile != NULL) { - if (ISFLAG(flags, F_DSAMELINE)) escapefilename("\\ ", &tmpfile->d_name); - printf("%s%c", tmpfile->d_name, ISFLAG(flags, F_DSAMELINE)?' ':'\n'); - tmpfile = tmpfile->duplicates; + for (index = 1; index < count; index++) { + if (ISFLAG(flags, F_DSAMELINE)) escapefilename("\\ ", &names[index]); + printf("%s%c", names[index], ISFLAG(flags, F_DSAMELINE)?' ':'\n'); + } + free(names); printf("\n"); } @@ -869,7 +890,7 @@ } if (confirmmatch(file1, file2)) { - match->hasdupes = 1; + match->hasdupes++; curfile->duplicates = match->duplicates; match->duplicates = curfile; }