Skip to content

Commit 964ef88

Browse files
authored
Merge pull request #5 from diasbruno/feature/addition-deletion.
get all additions and deletion of a diff.
2 parents 994e902 + 036ca0b commit 964ef88

File tree

3 files changed

+81
-21
lines changed

3 files changed

+81
-21
lines changed

include/diffstats/diffstats.h

+19-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,18 @@ enum diff_stats_err_t {
55
HUNK_WITHOUT_DIFF = 1
66
};
77

8+
enum diff_stats_line_t {
9+
DIFF_NOTHING = 0,
10+
DIFF_HEADER = 1,
11+
HUNK_HEADER = 2,
12+
ADDITION_LINE = 3,
13+
DELETION_LINE = 4
14+
};
15+
816
struct diff_stats_t {
917
long starts_at;
18+
long additions;
19+
long deletions;
1020
long count;
1121
long hunks;
1222
long* hunks_at;
@@ -18,15 +28,22 @@ struct diff_stats_t {
1828
* @param {long} column - text column (updated every new line).
1929
* @return {int}
2030
*/
21-
int diff_stats_is_diff_header(const char* text, long column);
31+
int diff_stats_is_diff_header(const char* text);
2232

2333
/**
2434
* From the current point in text, is there a `@@`?
2535
* @param {char*} text - the string.
2636
* @param {long} column - text column (updated every new line).
2737
* @return {int}
2838
*/
29-
int diff_stats_is_hunk_header(const char* text, long column);
39+
int diff_stats_is_hunk_header(const char* text);
40+
41+
/**
42+
* Find the type of the line.
43+
* @param {const char*} text - text.
44+
* @return {int}
45+
*/
46+
int diff_stats_line_type(const char* text);
3047

3148
/**
3249
* Add a found hunk to the list.

src/diffstats.c

+49-15
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,35 @@
55

66
static struct diff_stats_t* diff_stats_prepare_item(struct diff_stats_t* d) {
77
d->starts_at = -1;
8+
d->additions = 0;
9+
d->deletions = 0;
810
d->count = 0;
911
d->hunks = 10;
1012
d->hunks_at = (long*)malloc(sizeof(long) * 10);
1113
memset(d->hunks_at, 0, sizeof(long) * 10);
1214
return d;
1315
}
1416

15-
int diff_stats_is_diff_header(const char* text, long column) {
16-
return *text == 'd' && strncmp(text, (char*)"diff", 4) == 0 && column == 0;
17+
int diff_stats_is_diff_header(const char* text) {
18+
return (*text == 'd' && strncmp(text, (char*)"diff", 4) == 0);
1719
}
1820

19-
int diff_stats_is_hunk_header(const char* text, long column) {
20-
return *text == '@' && strncmp(text, (char*)"@@", 2) == 0 && column == 0;
21+
int diff_stats_is_hunk_header(const char* text) {
22+
return (*text == '@' && strncmp(text, (char*)"@@", 2) == 0);
23+
}
24+
25+
int diff_stats_line_type(const char* text) {
26+
if (diff_stats_is_diff_header(text)) {
27+
return DIFF_HEADER;
28+
}
29+
if (diff_stats_is_hunk_header(text)) {
30+
return HUNK_HEADER;
31+
}
32+
switch (*text) {
33+
case '-': { return DELETION_LINE; } break;
34+
case '+': { return ADDITION_LINE; } break;
35+
default: { return DIFF_NOTHING; } break;
36+
}
2137
}
2238

2339
void diff_stats_add_hunk_at(struct diff_stats_t* d, long i) {
@@ -53,43 +69,61 @@ void diff_stats_free(struct diff_stats_t* d, long count) {
5369
free(d);
5470
}
5571

72+
char* diff_stats_find_hunk(const char* str) {
73+
char* text = (char*)str;
74+
while (*text && *(text + 1)) {
75+
if (*text == '\n' && *(text + 1) == '@') {
76+
break;
77+
}
78+
text++;
79+
}
80+
return text;
81+
}
82+
5683
struct diff_stats_t* diff_stats_parser(const char* str, long* counter, int* err) {
5784
char* hold = (char*)str;
5885
char* text = hold;
59-
long column = 0;
6086
long index = 0;
6187
long count = 12;
6288
struct diff_stats_t* diff =
6389
(struct diff_stats_t*)malloc(sizeof(struct diff_stats_t) * count);
6490
struct diff_stats_t* head = NULL;
6591

6692
while (*text) {
67-
if (diff_stats_is_diff_header(text, column)) {
93+
int type = diff_stats_line_type(text);
94+
95+
switch (type) {
96+
case DIFF_HEADER: {
6897
if (index + 1 <= count) {
6998
count += 12;
70-
diff = (struct diff_stats_t*)realloc(diff, sizeof(struct diff_stats_t) * count);
99+
diff = (struct diff_stats_t*)realloc(diff,
100+
sizeof(struct diff_stats_t) * count);
71101
}
72102
head = diff_stats_prepare_item(diff + index);
73103
head->starts_at = (long)(text - hold);
74104
index++;
75-
}
76105

77-
if (diff_stats_is_hunk_header(text, column)) {
106+
text = diff_stats_find_hunk(text);
107+
continue;
108+
} break;
109+
case HUNK_HEADER: {
78110
if (!head) {
79111
*err = HUNK_WITHOUT_DIFF;
80112
free(diff);
81113
diff = NULL;
82114
goto diff_stats_end;
83115
}
84116
diff_stats_add_hunk_at(head, (long)(text - hold));
117+
} break;
118+
case ADDITION_LINE: { head->additions++; goto diff_stats_skip; } break;
119+
case DELETION_LINE: { head->deletions++; goto diff_stats_skip; } break;
120+
default: {
121+
diff_stats_skip:
122+
while (*text && *text != '\n') text++;
85123
}
86-
87-
if (*text == '\n') {
88-
column = 0;
89-
} else {
90-
column++;
91124
}
92-
++text;
125+
126+
text++;
93127
}
94128

95129
*err = 0;

tests/main.c

+13-4
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55
#include <diffstats/diffstats.h>
66

77
static void test_check_for_diff_header(void) {
8-
int ok = diff_stats_is_diff_header("diff", 0);
8+
int ok = diff_stats_is_diff_header("diff");
99
assert(ok);
10-
int fail = !diff_stats_is_diff_header("diff", 1);
10+
int fail = !diff_stats_is_diff_header(" diff");
1111
assert(fail);
1212
}
1313

1414
static void test_check_for_hunk_header(void) {
15-
int ok = diff_stats_is_hunk_header("@@", 0);
15+
int ok = diff_stats_is_hunk_header("@@");
1616
assert(ok);
17-
int fail = !diff_stats_is_hunk_header("@@", 1);
17+
int fail = !diff_stats_is_hunk_header(" @@");
1818
assert(fail);
1919
}
2020

@@ -32,6 +32,8 @@ static void test_simple(void) {
3232
int err = 0;
3333
struct diff_stats_t* st = diff_stats_parser(diff_simple_test, &count, &err);
3434
assert(st[0].starts_at == 0);
35+
assert(st[0].additions == 1);
36+
assert(st[0].deletions == 1);
3537
assert(st[0].count == 1);
3638
free(st);
3739
}
@@ -69,6 +71,8 @@ static void test_with_2_hunks(void) {
6971
int err = 0;
7072
struct diff_stats_t* st = diff_stats_parser(diff_with_2_hunks_test, &count, &err);
7173
assert(st[0].starts_at == 0);
74+
assert(st[0].additions == 4);
75+
assert(st[0].deletions == 4);
7276
assert(st[0].count == 2);
7377
free(st);
7478
}
@@ -93,8 +97,13 @@ static void test_mixed(void) {
9397
int err = 0;
9498
struct diff_stats_t* st = diff_stats_parser(diff_mixed_test, &count, &err);
9599
assert(st[0].starts_at == 0);
100+
assert(st[0].additions == 1);
101+
assert(st[0].deletions == 1);
96102
assert(st[0].count == 1);
103+
97104
assert(st[1].starts_at == 77);
105+
assert(st[1].additions == 1);
106+
assert(st[1].deletions == 1);
98107
assert(st[1].count == 1);
99108
free(st);
100109
}

0 commit comments

Comments
 (0)