]>
git.cameronkatri.com Git - cgit.git/blob - ui-ssdiff.c
7 static int current_old_line
, current_new_line
;
9 struct deferred_lines
{
12 struct deferred_lines
*next
;
15 static struct deferred_lines
*deferred_old
, *deferred_old_last
;
16 static struct deferred_lines
*deferred_new
, *deferred_new_last
;
18 static int line_from_hunk(char *line
, char type
)
23 buf1
= strchr(line
, type
);
27 buf2
= strchr(buf1
, ',');
31 buf2
= xmalloc(len
+ 1);
32 strncpy(buf2
, buf1
, len
);
39 static char *replace_tabs(char *line
)
41 char *prev_buf
= line
;
43 int linelen
= strlen(line
);
55 for (i
= 0; i
< linelen
; i
++)
58 result
= xmalloc(linelen
+ n_tabs
* 8 + 1);
62 cur_buf
= strchr(prev_buf
, '\t');
64 strcat(result
, prev_buf
);
68 strncat(result
, spaces
, 8 - (strlen(result
) % 8));
69 strncat(result
, prev_buf
, cur_buf
- prev_buf
);
71 prev_buf
= cur_buf
+ 1;
76 static void deferred_old_add(char *line
, int line_no
)
78 struct deferred_lines
*item
= xmalloc(sizeof(struct deferred_lines
));
79 item
->line
= xstrdup(line
);
80 item
->line_no
= line_no
;
83 deferred_old_last
->next
= item
;
84 deferred_old_last
= item
;
86 deferred_old
= deferred_old_last
= item
;
90 static void deferred_new_add(char *line
, int line_no
)
92 struct deferred_lines
*item
= xmalloc(sizeof(struct deferred_lines
));
93 item
->line
= xstrdup(line
);
94 item
->line_no
= line_no
;
97 deferred_new_last
->next
= item
;
98 deferred_new_last
= item
;
100 deferred_new
= deferred_new_last
= item
;
104 static void print_ssdiff_line(char *class, int old_line_no
, char *old_line
,
105 int new_line_no
, char *new_line
)
109 htmlf("<td class='%s'>%d </td><td class='%s'>", class,
112 htmlf("<td class='%s_dark'> </td><td class='%s_dark'>", class, class);
115 old_line
= replace_tabs(old_line
+ 1);
123 htmlf("<td class='%s'> %d </td><td class='%s'>", class,
126 htmlf("<td class='%s_dark'> </td><td class='%s_dark'>", class, class);
129 new_line
= replace_tabs(new_line
+ 1);
137 static void print_deferred_old_lines()
139 struct deferred_lines
*iter_old
, *tmp
;
141 iter_old
= deferred_old
;
143 print_ssdiff_line("del", iter_old
->line_no
,
144 iter_old
->line
, -1, NULL
);
145 tmp
= iter_old
->next
;
151 static void print_deferred_new_lines()
153 struct deferred_lines
*iter_new
, *tmp
;
155 iter_new
= deferred_new
;
157 print_ssdiff_line("add", -1, NULL
, iter_new
->line_no
,
159 tmp
= iter_new
->next
;
165 static void print_deferred_changed_lines()
167 struct deferred_lines
*iter_old
, *iter_new
, *tmp
;
169 iter_old
= deferred_old
;
170 iter_new
= deferred_new
;
171 while (iter_old
|| iter_new
) {
172 if (iter_old
&& iter_new
)
173 print_ssdiff_line("changed", iter_old
->line_no
,
175 iter_new
->line_no
, iter_new
->line
);
177 print_ssdiff_line("changed", iter_old
->line_no
,
178 iter_old
->line
, -1, NULL
);
180 print_ssdiff_line("changed", -1, NULL
,
181 iter_new
->line_no
, iter_new
->line
);
184 tmp
= iter_old
->next
;
190 tmp
= iter_new
->next
;
197 void cgit_ssdiff_print_deferred_lines()
199 if (!deferred_old
&& !deferred_new
)
202 if (deferred_old
&& !deferred_new
)
203 print_deferred_old_lines();
204 else if (!deferred_old
&& deferred_new
)
205 print_deferred_new_lines();
207 print_deferred_changed_lines();
209 deferred_old
= deferred_old_last
= NULL
;
210 deferred_new
= deferred_new_last
= NULL
;
214 * print a single line returned from xdiff
216 void cgit_ssdiff_line_cb(char *line
, int len
)
218 char c
= line
[len
- 1];
220 line
[len
- 1] = '\0';
222 if (line
[0] == '@') {
223 current_old_line
= line_from_hunk(line
, '-');
224 current_new_line
= line_from_hunk(line
, '+');
227 if (line
[0] == ' ') {
228 if (deferred_old
|| deferred_new
)
229 cgit_ssdiff_print_deferred_lines();
230 print_ssdiff_line("ctx", current_old_line
, line
,
231 current_new_line
, line
);
232 current_old_line
+= 1;
233 current_new_line
+= 1;
234 } else if (line
[0] == '+') {
235 deferred_new_add(line
, current_new_line
);
236 current_new_line
+= 1;
237 } else if (line
[0] == '-') {
238 deferred_old_add(line
, current_old_line
);
239 current_old_line
+= 1;
240 } else if (line
[0] == '@') {
241 html("<tr><td colspan='4' class='hunk'>");
245 html("<tr><td colspan='4' class='ctx'>");
252 void cgit_ssdiff_header()
254 current_old_line
= 0;
255 current_new_line
= 0;
256 html("<table class='ssdiff'>");
259 void cgit_ssdiff_footer()
261 if (deferred_old
|| deferred_new
)
262 cgit_ssdiff_print_deferred_lines();