summaryrefslogtreecommitdiff
path: root/graph.c
diff options
context:
space:
mode:
Diffstat (limited to 'graph.c')
-rw-r--r--graph.c149
1 files changed, 97 insertions, 52 deletions
diff --git a/graph.c b/graph.c
index c25a09a..d4e8519 100644
--- a/graph.c
+++ b/graph.c
@@ -2,7 +2,6 @@
#include "commit.h"
#include "color.h"
#include "graph.h"
-#include "diff.h"
#include "revision.h"
/* Internal API */
@@ -17,8 +16,8 @@
static void graph_padding_line(struct git_graph *graph, struct strbuf *sb);
/*
- * Print a strbuf to stdout. If the graph is non-NULL, all lines but the
- * first will be prefixed with the graph output.
+ * Print a strbuf. If the graph is non-NULL, all lines but the first will be
+ * prefixed with the graph output.
*
* If the strbuf ends with a newline, the output will end after this
* newline. A new graph line will not be printed after the final newline.
@@ -28,8 +27,15 @@ static void graph_padding_line(struct git_graph *graph, struct strbuf *sb);
* responsible for printing this line's graph (perhaps via
* graph_show_commit() or graph_show_oneline()) before calling
* graph_show_strbuf().
+ *
+ * Note that unlike some other graph display functions, you must pass the file
+ * handle directly. It is assumed that this is the same file handle as the
+ * file specified by the graph diff options. This is necessary so that
+ * graph_show_strbuf can be called even with a NULL graph.
*/
-static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb);
+static void graph_show_strbuf(struct git_graph *graph,
+ FILE *file,
+ struct strbuf const *sb);
/*
* TODO:
@@ -59,6 +65,17 @@ enum graph_state {
GRAPH_COLLAPSING
};
+static void graph_show_line_prefix(const struct diff_options *diffopt)
+{
+ if (!diffopt || !diffopt->line_prefix)
+ return;
+
+ fwrite(diffopt->line_prefix,
+ sizeof(char),
+ diffopt->line_prefix_length,
+ diffopt->file);
+}
+
static const char **column_colors;
static unsigned short column_colors_max;
@@ -195,14 +212,28 @@ static struct strbuf *diff_output_prefix_callback(struct diff_options *opt, void
static struct strbuf msgbuf = STRBUF_INIT;
assert(opt);
- assert(graph);
- opt->output_prefix_length = graph->width;
strbuf_reset(&msgbuf);
- graph_padding_line(graph, &msgbuf);
+ if (opt->line_prefix)
+ strbuf_add(&msgbuf, opt->line_prefix,
+ opt->line_prefix_length);
+ if (graph)
+ graph_padding_line(graph, &msgbuf);
return &msgbuf;
}
+static const struct diff_options *default_diffopt;
+
+void graph_setup_line_prefix(struct diff_options *diffopt)
+{
+ default_diffopt = diffopt;
+
+ /* setup an output prefix callback if necessary */
+ if (diffopt && !diffopt->output_prefix)
+ diffopt->output_prefix = diff_output_prefix_callback;
+}
+
+
struct git_graph *graph_init(struct rev_info *opt)
{
struct git_graph *graph = xmalloc(sizeof(struct git_graph));
@@ -234,12 +265,10 @@ struct git_graph *graph_init(struct rev_info *opt)
* We'll automatically grow columns later if we need more room.
*/
graph->column_capacity = 30;
- graph->columns = xmalloc(sizeof(struct column) *
- graph->column_capacity);
- graph->new_columns = xmalloc(sizeof(struct column) *
- graph->column_capacity);
- graph->mapping = xmalloc(sizeof(int) * 2 * graph->column_capacity);
- graph->new_mapping = xmalloc(sizeof(int) * 2 * graph->column_capacity);
+ ALLOC_ARRAY(graph->columns, graph->column_capacity);
+ ALLOC_ARRAY(graph->new_columns, graph->column_capacity);
+ ALLOC_ARRAY(graph->mapping, 2 * graph->column_capacity);
+ ALLOC_ARRAY(graph->new_mapping, 2 * graph->column_capacity);
/*
* The diff output prefix callback, with this we can make
@@ -247,7 +276,6 @@ struct git_graph *graph_init(struct rev_info *opt)
*/
opt->diffopt.output_prefix = diff_output_prefix_callback;
opt->diffopt.output_prefix_data = graph;
- opt->diffopt.output_prefix_length = 0;
return graph;
}
@@ -671,6 +699,13 @@ static void graph_output_padding_line(struct git_graph *graph,
graph_pad_horizontally(graph, sb, graph->num_new_columns * 2);
}
+
+int graph_width(struct git_graph *graph)
+{
+ return graph->width;
+}
+
+
static void graph_output_skip_line(struct git_graph *graph, struct strbuf *sb)
{
/*
@@ -1140,6 +1175,7 @@ int graph_next_line(struct git_graph *graph, struct strbuf *sb)
static void graph_padding_line(struct git_graph *graph, struct strbuf *sb)
{
int i;
+ int chars_written = 0;
if (graph->state != GRAPH_COMMIT) {
graph_next_line(graph, sb);
@@ -1155,14 +1191,21 @@ static void graph_padding_line(struct git_graph *graph, struct strbuf *sb)
*/
for (i = 0; i < graph->num_columns; i++) {
struct column *col = &graph->columns[i];
+
strbuf_write_column(sb, col, '|');
- if (col->commit == graph->commit && graph->num_parents > 2)
- strbuf_addchars(sb, ' ', (graph->num_parents - 2) * 2);
- else
+ chars_written++;
+
+ if (col->commit == graph->commit && graph->num_parents > 2) {
+ int len = (graph->num_parents - 2) * 2;
+ strbuf_addchars(sb, ' ', len);
+ chars_written += len;
+ } else {
strbuf_addch(sb, ' ');
+ chars_written++;
+ }
}
- graph_pad_horizontally(graph, sb, graph->num_columns);
+ graph_pad_horizontally(graph, sb, chars_written);
/*
* Update graph->prev_state since we have output a padding line
@@ -1180,6 +1223,8 @@ void graph_show_commit(struct git_graph *graph)
struct strbuf msgbuf = STRBUF_INIT;
int shown_commit_line = 0;
+ graph_show_line_prefix(default_diffopt);
+
if (!graph)
return;
@@ -1195,9 +1240,12 @@ void graph_show_commit(struct git_graph *graph)
while (!shown_commit_line && !graph_is_commit_finished(graph)) {
shown_commit_line = graph_next_line(graph, &msgbuf);
- fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
- if (!shown_commit_line)
- putchar('\n');
+ fwrite(msgbuf.buf, sizeof(char), msgbuf.len,
+ graph->revs->diffopt.file);
+ if (!shown_commit_line) {
+ putc('\n', graph->revs->diffopt.file);
+ graph_show_line_prefix(&graph->revs->diffopt);
+ }
strbuf_setlen(&msgbuf, 0);
}
@@ -1208,11 +1256,13 @@ void graph_show_oneline(struct git_graph *graph)
{
struct strbuf msgbuf = STRBUF_INIT;
+ graph_show_line_prefix(default_diffopt);
+
if (!graph)
return;
graph_next_line(graph, &msgbuf);
- fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
+ fwrite(msgbuf.buf, sizeof(char), msgbuf.len, graph->revs->diffopt.file);
strbuf_release(&msgbuf);
}
@@ -1220,11 +1270,13 @@ void graph_show_padding(struct git_graph *graph)
{
struct strbuf msgbuf = STRBUF_INIT;
+ graph_show_line_prefix(default_diffopt);
+
if (!graph)
return;
graph_padding_line(graph, &msgbuf);
- fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
+ fwrite(msgbuf.buf, sizeof(char), msgbuf.len, graph->revs->diffopt.file);
strbuf_release(&msgbuf);
}
@@ -1233,6 +1285,8 @@ int graph_show_remainder(struct git_graph *graph)
struct strbuf msgbuf = STRBUF_INIT;
int shown = 0;
+ graph_show_line_prefix(default_diffopt);
+
if (!graph)
return 0;
@@ -1241,30 +1295,29 @@ int graph_show_remainder(struct git_graph *graph)
for (;;) {
graph_next_line(graph, &msgbuf);
- fwrite(msgbuf.buf, sizeof(char), msgbuf.len, stdout);
+ fwrite(msgbuf.buf, sizeof(char), msgbuf.len,
+ graph->revs->diffopt.file);
strbuf_setlen(&msgbuf, 0);
shown = 1;
- if (!graph_is_commit_finished(graph))
- putchar('\n');
- else
+ if (!graph_is_commit_finished(graph)) {
+ putc('\n', graph->revs->diffopt.file);
+ graph_show_line_prefix(&graph->revs->diffopt);
+ } else {
break;
+ }
}
strbuf_release(&msgbuf);
return shown;
}
-
-static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb)
+static void graph_show_strbuf(struct git_graph *graph,
+ FILE *file,
+ struct strbuf const *sb)
{
char *p;
- if (!graph) {
- fwrite(sb->buf, sizeof(char), sb->len, stdout);
- return;
- }
-
/*
* Print the strbuf line by line,
* and display the graph info before each line but the first.
@@ -1279,7 +1332,7 @@ static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb)
} else {
len = (sb->buf + sb->len) - p;
}
- fwrite(p, sizeof(char), len, stdout);
+ fwrite(p, sizeof(char), len, file);
if (next_p && *next_p != '\0')
graph_show_oneline(graph);
p = next_p;
@@ -1287,28 +1340,20 @@ static void graph_show_strbuf(struct git_graph *graph, struct strbuf const *sb)
}
void graph_show_commit_msg(struct git_graph *graph,
+ FILE *file,
struct strbuf const *sb)
{
int newline_terminated;
- if (!graph) {
- /*
- * If there's no graph, just print the message buffer.
- *
- * The message buffer for CMIT_FMT_ONELINE and
- * CMIT_FMT_USERFORMAT are already missing a terminating
- * newline. All of the other formats should have it.
- */
- fwrite(sb->buf, sizeof(char), sb->len, stdout);
- return;
- }
-
- newline_terminated = (sb->len && sb->buf[sb->len - 1] == '\n');
-
/*
* Show the commit message
*/
- graph_show_strbuf(graph, sb);
+ graph_show_strbuf(graph, file, sb);
+
+ if (!graph)
+ return;
+
+ newline_terminated = (sb->len && sb->buf[sb->len - 1] == '\n');
/*
* If there is more output needed for this commit, show it now
@@ -1320,7 +1365,7 @@ void graph_show_commit_msg(struct git_graph *graph,
* new line.
*/
if (!newline_terminated)
- putchar('\n');
+ putc('\n', file);
graph_show_remainder(graph);
@@ -1328,6 +1373,6 @@ void graph_show_commit_msg(struct git_graph *graph,
* If sb ends with a newline, our output should too.
*/
if (newline_terminated)
- putchar('\n');
+ putc('\n', file);
}
}