Select Git revision
count_changes.c
count_changes.c 3.64 KiB
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#define MAXSIZE 128
typedef struct {
long files_changed;
long insertions;
long deletions;
long changes;
} changes;
static long upper_bound = 2500;
void show_usage();
void process_text();
changes process_line( char *line );
int main( int argc, const char **argv ) {
if (argc > 1)
show_usage();
else
process_text();
return 0;
}
void show_usage() {
printf("Reads input on stdin; displays output on stdout.\n");
printf("Input expected to be the changes summary from a git log, e.g.: 23 files changed, 1312 insertions(+), 4 deletions(-)\n");
}
void process_text() {
char line[MAXSIZE];
changes line_changes;
changes all_changes;
all_changes.files_changed = all_changes.insertions = all_changes.deletions = all_changes.changes = 0;
long lined_file_changes = 0;
long maximum_change = 0;
line[0] = 0;
while (fgets(line, MAXSIZE, stdin)) {
if (strstr(line, "file changed,") || strstr(line, "files changed,")) { // just in case we get extraneous inputs
line_changes = process_line(line);
if(line_changes.changes > upper_bound) {
printf("Skipping commit with %ld lines changed.\n", line_changes.changes);
} else {
all_changes.files_changed += line_changes.files_changed;
all_changes.insertions += line_changes.insertions;
all_changes.deletions += line_changes.deletions;
all_changes.changes += line_changes.changes;
maximum_change = (maximum_change > line_changes.changes) ? maximum_change : line_changes.changes;
if (line_changes.changes > 0)
lined_file_changes += line_changes.files_changed;
}
}
}
printf("%ld files changed; %ld lines changed.\n", all_changes.files_changed, all_changes.changes);
if (all_changes.files_changed > 0 && lined_file_changes > 0) {
printf("Average commit: %d lines (across all commits), %d lines (across commits with changed lines).\n", (int)
(all_changes.changes / all_changes.files_changed), lined_file_changes == 0 ? 0 : (int)(all_changes.changes /
lined_file_changes));
} else {
printf("Cannot compute average commit.\n");
}
printf("Maximum-sized commit: %ld lines.\n", maximum_change);
}
changes process_line( char *line ) {
changes result;
result.files_changed = result.insertions = result.deletions = result.changes = 0;
char *substring = strtok(line, ","); // first substring shows files changed
char *terminator = strchr(substring, 'f');
result.files_changed = strtol(substring, &terminator, 10);
substring = strtok(NULL, ","); // second substring either shows lines inserted or lines deleted
if ((terminator = strchr(substring, 'd'))) { // need to check if this is deletion first, because "deletions" has an 'i' in it
result.deletions = strtol(substring, &terminator, 10);
} else if ((terminator = strchr(substring, 'i'))) {
result.insertions = strtol(substring, &terminator, 10);
substring = strtok(NULL, ",");
if ((substring != NULL) && (terminator = strchr(substring, 'd'))) { // third substring, if it exists, shows lines deleted
result.deletions = strtol(substring, &terminator, 10);
}
} else {
printf("Surprising substring: %s\n", substring);
}
result.changes = result.insertions > result.deletions ? result.insertions : result.deletions;
return result;
}