summaryrefslogtreecommitdiffstats
path: root/libsmartcols/src/table_print.c
diff options
context:
space:
mode:
authorKarel Zak2015-01-07 15:20:22 +0100
committerKarel Zak2015-01-07 15:20:22 +0100
commit8501d9befe0a9567ea60428f09f982bee32517ef (patch)
tree981e1e07cf0bb9564f7b3ad4af78a9dfa502b3b4 /libsmartcols/src/table_print.c
parentbuild-sys: support nsenter.static (diff)
downloadkernel-qcow2-util-linux-8501d9befe0a9567ea60428f09f982bee32517ef.tar.gz
kernel-qcow2-util-linux-8501d9befe0a9567ea60428f09f982bee32517ef.tar.xz
kernel-qcow2-util-linux-8501d9befe0a9567ea60428f09f982bee32517ef.zip
libsmartcols: use ASCII art for trees rather than padding
Based on patch from Roman Odaisky. References: https://launchpad.net/bugs/1406133 Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libsmartcols/src/table_print.c')
-rw-r--r--libsmartcols/src/table_print.c132
1 files changed, 97 insertions, 35 deletions
diff --git a/libsmartcols/src/table_print.c b/libsmartcols/src/table_print.c
index 542d8a22d..ddbd12d3f 100644
--- a/libsmartcols/src/table_print.c
+++ b/libsmartcols/src/table_print.c
@@ -151,12 +151,103 @@ static size_t buffer_get_safe_art_size(struct libscols_buffer *buf)
return bytes;
}
+/* returns pointer to the end of used data */
+static int line_ascii_art_to_buffer(struct libscols_table *tb,
+ struct libscols_line *ln,
+ struct libscols_buffer *buf)
+{
+ const char *art;
+ int rc;
+
+ assert(ln);
+ assert(buf);
+
+ if (!ln->parent)
+ return 0;
+
+ rc = line_ascii_art_to_buffer(tb, ln->parent, buf);
+ if (rc)
+ return rc;
+
+ if (list_entry_is_last(&ln->ln_children, &ln->parent->ln_branch))
+ art = " ";
+ else
+ art = tb->symbols->vert;
+
+ return buffer_append_data(buf, art);
+}
+
#define is_last_column(_tb, _cl) \
list_entry_is_last(&(_cl)->cl_columns, &(_tb)->tb_columns)
#define colsep(tb) ((tb)->colsep ? (tb)->colsep : " ")
#define linesep(tb) ((tb)->linesep ? (tb)->linesep : "\n")
+/* print padding or asci-art instead of data of @cl */
+static void print_empty_cell(struct libscols_table *tb,
+ struct libscols_column *cl,
+ struct libscols_line *ln, /* optional */
+ size_t bufsz)
+{
+ size_t len_pad = 0; /* in screen cells as opposed to bytes */
+
+ /* generate tree asci-art rather than padding */
+ if (ln && scols_column_is_tree(cl)) {
+ if (!ln->parent) {
+ /* only print symbols->vert if followed by something */
+ if (!list_empty(&ln->ln_branch)) {
+ fputs(tb->symbols->vert, tb->out);
+ len_pad = mbs_safe_width(tb->symbols->vert);
+ }
+ } else {
+ /* use the same draw function as though we were intending to draw an L-shape */
+ struct libscols_buffer *art = new_buffer(bufsz);
+ char *data;
+
+ if (art) {
+ /* whatever the rc, len_pad will be sensible */
+ line_ascii_art_to_buffer(tb, ln, art);
+ data = buffer_get_safe_data(art, &len_pad);
+ if (data && len_pad)
+ fputs(data, tb->out);
+ free_buffer(art);
+ }
+ }
+ }
+ /* fill rest of cell with space */
+ for(; len_pad <= cl->width; ++len_pad)
+ fputc(' ', tb->out);
+}
+
+/* fill-in all line with padding (or tree asci-art)
+ *
+ * This is necessary after long non-truncated colum where next column
+ * is printed in next line. For example (see 'DDD'):
+ *
+ * aaa bbb ccc ddd eee
+ * AAA BBB CCCCCCC
+ * DDD EEE
+ * ^^^^^^^^^^^^
+ * new line padding
+ */
+static void print_newline_padding(struct libscols_table *tb,
+ struct libscols_column *cl,
+ struct libscols_line *ln, /* optional */
+ size_t bufsz,
+ size_t len)
+{
+ size_t i;
+
+ assert(tb);
+ assert(cl);
+
+ fputs(linesep(tb), tb->out); /* line break */
+
+ /* fill cells after line break */
+ for (i = 0; i <= (size_t) cl->seqnum; i++)
+ print_empty_cell(tb, scols_table_get_column(tb, i), ln, bufsz);
+}
+
static int print_data(struct libscols_table *tb,
struct libscols_column *cl,
struct libscols_line *ln, /* optional */
@@ -252,46 +343,17 @@ static int print_data(struct libscols_table *tb,
fputs(data, tb->out);
}
for (i = len; i < width; i++)
- fputs(" ", tb->out); /* padding */
-
- if (!is_last_column(tb, cl)) {
- if (len > width && !scols_column_is_trunc(cl)) {
- fputs(linesep(tb), tb->out);
- for (i = 0; i <= (size_t) cl->seqnum; i++) {
- struct libscols_column *x = scols_table_get_column(tb, i);
- fprintf(tb->out, "%*s ", -((int)x->width), " ");
- }
- } else
- fputs(colsep(tb), tb->out); /* columns separator */
- }
-
- return 0;
-}
-
-/* returns pointer to the end of used data */
-static int line_ascii_art_to_buffer(struct libscols_table *tb,
- struct libscols_line *ln,
- struct libscols_buffer *buf)
-{
- const char *art;
- int rc;
+ fputc(' ', tb->out); /* padding */
- assert(ln);
- assert(buf);
-
- if (!ln->parent)
+ if (is_last_column(tb, cl))
return 0;
- rc = line_ascii_art_to_buffer(tb, ln->parent, buf);
- if (rc)
- return rc;
-
- if (list_entry_is_last(&ln->ln_children, &ln->parent->ln_branch))
- art = " ";
+ if (len > width && !scols_column_is_trunc(cl))
+ print_newline_padding(tb, cl, ln, buf->bufsz, len); /* next column starts on next line */
else
- art = tb->symbols->vert;
+ fputs(colsep(tb), tb->out); /* columns separator */
- return buffer_append_data(buf, art);
+ return 0;
}
static int cell_to_buffer(struct libscols_table *tb,