sync files from diff.git b3fd1fa284e6207b923bd3c887364d9eb93fb340
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
diff --git a/lib/diff_internal.h b/lib/diff_internal.h
index 699cdbd..396f264 100644
--- a/lib/diff_internal.h
+++ b/lib/diff_internal.h
@@ -173,7 +173,9 @@ int diff_output_lines(struct diff_output_info *output_info, FILE *dest,
int diff_output_trailing_newline_msg(struct diff_output_info *outinfo,
FILE *dest,
const struct diff_chunk *c);
-int diff_output_match_function_prototype(char **prototype,
+#define DIFF_FUNCTION_CONTEXT_SIZE 55
+int diff_output_match_function_prototype(char *prototype, size_t prototype_size,
+ int *last_prototype_idx,
const struct diff_result *result,
const struct diff_chunk_context *cc);
diff --git a/lib/diff_output.c b/lib/diff_output.c
index e286c62..daf8b8c 100644
--- a/lib/diff_output.c
+++ b/lib/diff_output.c
@@ -236,68 +236,67 @@ diff_output_trailing_newline_msg(struct diff_output_info *outinfo, FILE *dest,
}
static bool
-is_function_prototype(const char *buf)
+is_function_prototype(unsigned char ch)
{
- return isalpha(buf[0]) || buf[0] == '_' || buf[0] == '$';
+ return (isalpha(ch) || ch == '_' || ch == '$');
}
-#define FUNCTION_CONTEXT_SIZE 55
#define begins_with(s, pre) (strncmp(s, pre, sizeof(pre)-1) == 0)
int
-diff_output_match_function_prototype(char **prototype,
- const struct diff_result *result,
+diff_output_match_function_prototype(char *prototype, size_t prototype_size,
+ int *last_prototype_idx, const struct diff_result *result,
const struct diff_chunk_context *cc)
{
struct diff_atom *start_atom, *atom;
const struct diff_data *data;
- unsigned char buf[FUNCTION_CONTEXT_SIZE];
+ unsigned char buf[DIFF_FUNCTION_CONTEXT_SIZE];
char *state = NULL;
- int rc, i;
-
- *prototype = NULL;
+ int rc, i, ch;
if (result->left->atoms.len > 0 && cc->left.start > 0) {
data = result->left;
start_atom = &data->atoms.head[cc->left.start - 1];
- } else if (result->right->atoms.len > 0 && cc->right.start > 0) {
- data = result->right;
- start_atom = &data->atoms.head[cc->right.start - 1];
} else
return DIFF_RC_OK;
diff_data_foreach_atom_backwards_from(start_atom, atom, data) {
- for (i = 0; i < atom->len && i < sizeof(buf) - 1; i++) {
- unsigned int ch;
+ int atom_idx = diff_atom_root_idx(data, atom);
+ if (atom_idx < *last_prototype_idx)
+ break;
+ rc = get_atom_byte(&ch, atom, 0);
+ if (rc)
+ return rc;
+ buf[0] = (unsigned char)ch;
+ if (!is_function_prototype(buf[0]))
+ continue;
+ for (i = 1; i < atom->len && i < sizeof(buf) - 1; i++) {
rc = get_atom_byte(&ch, atom, i);
if (rc)
return rc;
if (ch == '\n')
break;
- buf[i] = ch;
+ buf[i] = (unsigned char)ch;
}
buf[i] = '\0';
- if (is_function_prototype(buf)) {
- if (begins_with(buf, "private:")) {
- if (!state)
- state = " (private)";
- } else if (begins_with(buf, "protected:")) {
- if (!state)
- state = " (protected)";
- } else if (begins_with(buf, "public:")) {
- if (!state)
- state = " (public)";
- } else {
- if (state) /* don't care about truncation */
- strlcat(buf, state, sizeof(buf));
- *prototype = strdup(buf);
- if (*prototype == NULL)
- return ENOMEM;
- return DIFF_RC_OK;
- }
+ if (begins_with(buf, "private:")) {
+ if (!state)
+ state = " (private)";
+ } else if (begins_with(buf, "protected:")) {
+ if (!state)
+ state = " (protected)";
+ } else if (begins_with(buf, "public:")) {
+ if (!state)
+ state = " (public)";
+ } else {
+ if (state) /* don't care about truncation */
+ strlcat(buf, state, sizeof(buf));
+ strlcpy(prototype, buf, prototype_size);
+ break;
}
}
+ *last_prototype_idx = diff_atom_root_idx(data, start_atom);
return DIFF_RC_OK;
}
diff --git a/lib/diff_output_unidiff.c b/lib/diff_output_unidiff.c
index 0c30eea..5fc87f7 100644
--- a/lib/diff_output_unidiff.c
+++ b/lib/diff_output_unidiff.c
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <assert.h>
#include <arraylist.h>
@@ -189,6 +190,8 @@ diff_chunk_context_load_change(struct diff_chunk_context *cc,
struct diff_output_unidiff_state {
bool header_printed;
+ char prototype[DIFF_FUNCTION_CONTEXT_SIZE];
+ int last_prototype_idx;
};
struct diff_output_unidiff_state *
@@ -206,6 +209,8 @@ void
diff_output_unidiff_state_reset(struct diff_output_unidiff_state *state)
{
state->header_printed = false;
+ memset(state->prototype, 0, sizeof(state->prototype));
+ state->last_prototype_idx = 0;
}
void
@@ -224,7 +229,6 @@ output_unidiff_chunk(struct diff_output_info *outinfo, FILE *dest,
{
int rc, left_start, left_len, right_start, right_len;
off_t outoff = 0, *offp;
- char *prototype = NULL;
if (diff_range_empty(&cc->left) && diff_range_empty(&cc->right))
return DIFF_RC_OK;
@@ -279,7 +283,8 @@ output_unidiff_chunk(struct diff_output_info *outinfo, FILE *dest,
right_start = cc->right.start + 1;
if (show_function_prototypes) {
- rc = diff_output_match_function_prototype(&prototype,
+ rc = diff_output_match_function_prototype(state->prototype,
+ sizeof(state->prototype), &state->last_prototype_idx,
result, cc);
if (rc)
return rc;
@@ -288,25 +293,24 @@ output_unidiff_chunk(struct diff_output_info *outinfo, FILE *dest,
if (left_len == 1 && right_len == 1) {
rc = fprintf(dest, "@@ -%d +%d @@%s%s\n",
left_start, right_start,
- prototype ? " " : "",
- prototype ? : "");
+ state->prototype[0] ? " " : "",
+ state->prototype[0] ? state->prototype : "");
} else if (left_len == 1 && right_len != 1) {
rc = fprintf(dest, "@@ -%d +%d,%d @@%s%s\n",
left_start, right_start, right_len,
- prototype ? " " : "",
- prototype ? : "");
+ state->prototype[0] ? " " : "",
+ state->prototype[0] ? state->prototype : "");
} else if (left_len != 1 && right_len == 1) {
rc = fprintf(dest, "@@ -%d,%d +%d @@%s%s\n",
left_start, left_len, right_start,
- prototype ? " " : "",
- prototype ? : "");
+ state->prototype[0] ? " " : "",
+ state->prototype[0] ? state->prototype : "");
} else {
rc = fprintf(dest, "@@ -%d,%d +%d,%d @@%s%s\n",
left_start, left_len, right_start, right_len,
- prototype ? " " : "",
- prototype ? : "");
+ state->prototype[0] ? " " : "",
+ state->prototype[0] ? state->prototype : "");
}
- free(prototype);
if (rc < 0)
return errno;
if (outinfo) {