libsmartcols: move width calculation to separate file

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2018-10-25 16:01:23 +02:00
parent ecd7cd253d
commit 06a8decd72
4 changed files with 412 additions and 395 deletions

View File

@ -18,6 +18,7 @@ libsmartcols_la_SOURCES= \
libsmartcols/src/print.c \
libsmartcols/src/version.c \
libsmartcols/src/buffer.c \
libsmartcols/src/calculate.c \
libsmartcols/src/init.c
libsmartcols_la_LIBADD = $(LDADD) libcommon.la

View File

@ -0,0 +1,391 @@
#include "smartcolsP.h"
#include "mbsalign.h"
static void dbg_column(struct libscols_table *tb, struct libscols_column *cl)
{
if (scols_column_is_hidden(cl)) {
DBG(COL, ul_debugobj(cl, "%s (hidden) ignored", cl->header.data));
return;
}
DBG(COL, ul_debugobj(cl, "%15s seq=%zu, width=%zd, "
"hint=%d, avg=%zu, max=%zu, min=%zu, "
"extreme=%s %s",
cl->header.data, cl->seqnum, cl->width,
cl->width_hint > 1 ? (int) cl->width_hint :
(int) (cl->width_hint * tb->termwidth),
cl->width_avg,
cl->width_max,
cl->width_min,
cl->is_extreme ? "yes" : "not",
cl->flags & SCOLS_FL_TRUNC ? "trunc" : ""));
}
static void dbg_columns(struct libscols_table *tb)
{
struct libscols_iter itr;
struct libscols_column *cl;
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0)
dbg_column(tb, cl);
}
/*
* This function counts column width.
*
* For the SCOLS_FL_NOEXTREMES columns it is possible to call this function
* two times. The first pass counts the width and average width. If the column
* contains fields that are too large (a width greater than 2 * average) then
* the column is marked as "extreme". In the second pass all extreme fields
* are ignored and the column width is counted from non-extreme fields only.
*/
static int count_column_width(struct libscols_table *tb,
struct libscols_column *cl,
struct libscols_buffer *buf)
{
struct libscols_line *ln;
struct libscols_iter itr;
int extreme_count = 0, rc = 0, no_header = 0;
size_t extreme_sum = 0;
assert(tb);
assert(cl);
cl->width = 0;
if (!cl->width_min) {
if (cl->width_hint < 1 && scols_table_is_maxout(tb) && tb->is_term) {
cl->width_min = (size_t) (cl->width_hint * tb->termwidth);
if (cl->width_min && !is_last_column(cl))
cl->width_min--;
}
if (scols_cell_get_data(&cl->header)) {
size_t len = mbs_safe_width(scols_cell_get_data(&cl->header));
cl->width_min = max(cl->width_min, len);
} else
no_header = 1;
if (!cl->width_min)
cl->width_min = 1;
}
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_line(tb, &itr, &ln) == 0) {
size_t len;
char *data;
rc = __cell_to_buffer(tb, ln, cl, buf);
if (rc)
goto done;
data = buffer_get_data(buf);
if (!data)
len = 0;
else if (scols_column_is_customwrap(cl))
len = cl->wrap_chunksize(cl, data, cl->wrapfunc_data);
else
len = mbs_safe_width(data);
if (len == (size_t) -1) /* ignore broken multibyte strings */
len = 0;
cl->width_max = max(len, cl->width_max);
if (cl->is_extreme && cl->width_avg && len > cl->width_avg * 2)
continue;
else if (scols_column_is_noextremes(cl)) {
extreme_sum += len;
extreme_count++;
}
cl->width = max(len, cl->width);
if (scols_column_is_tree(cl)) {
size_t treewidth = buffer_get_safe_art_size(buf);
cl->width_treeart = max(cl->width_treeart, treewidth);
}
}
if (extreme_count && cl->width_avg == 0) {
cl->width_avg = extreme_sum / extreme_count;
if (cl->width_avg && cl->width_max > cl->width_avg * 2)
cl->is_extreme = 1;
}
/* enlarge to minimal width */
if (cl->width < cl->width_min && !scols_column_is_strict_width(cl))
cl->width = cl->width_min;
/* use absolute size for large columns */
else if (cl->width_hint >= 1 && cl->width < (size_t) cl->width_hint
&& cl->width_min < (size_t) cl->width_hint)
cl->width = (size_t) cl->width_hint;
/* Column without header and data, set minimal size to zero (default is 1) */
if (cl->width_max == 0 && no_header && cl->width_min == 1 && cl->width <= 1)
cl->width = cl->width_min = 0;
done:
ON_DBG(COL, dbg_column(tb, cl));
return rc;
}
/*
* This is core of the scols_* voodoo...
*/
int __scols_calculate(struct libscols_table *tb, struct libscols_buffer *buf)
{
struct libscols_column *cl;
struct libscols_iter itr;
size_t width = 0, width_min = 0; /* output width */
int stage, rc = 0;
int extremes = 0;
size_t colsepsz;
DBG(TAB, ul_debugobj(tb, "recounting widths (termwidth=%zu)", tb->termwidth));
colsepsz = mbs_safe_width(colsep(tb));
/* set basic columns width
*/
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0) {
int is_last;
if (scols_column_is_hidden(cl))
continue;
rc = count_column_width(tb, cl, buf);
if (rc)
goto done;
is_last = is_last_column(cl);
width += cl->width + (is_last ? 0 : colsepsz); /* separator for non-last column */
width_min += cl->width_min + (is_last ? 0 : colsepsz);
extremes += cl->is_extreme;
}
if (!tb->is_term) {
DBG(TAB, ul_debugobj(tb, " non-terminal output"));
goto done;
}
/* be paranoid */
if (width_min > tb->termwidth && scols_table_is_maxout(tb)) {
DBG(TAB, ul_debugobj(tb, " min width larger than terminal! [width=%zu, term=%zu]", width_min, tb->termwidth));
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (width_min > tb->termwidth
&& scols_table_next_column(tb, &itr, &cl) == 0) {
if (scols_column_is_hidden(cl))
continue;
width_min--;
cl->width_min--;
}
DBG(TAB, ul_debugobj(tb, " min width reduced to %zu", width_min));
}
/* reduce columns with extreme fields */
if (width > tb->termwidth && extremes) {
DBG(TAB, ul_debugobj(tb, " reduce width (extreme columns)"));
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0) {
size_t org_width;
if (!cl->is_extreme || scols_column_is_hidden(cl))
continue;
org_width = cl->width;
rc = count_column_width(tb, cl, buf);
if (rc)
goto done;
if (org_width > cl->width)
width -= org_width - cl->width;
else
extremes--; /* hmm... nothing reduced */
}
}
if (width < tb->termwidth) {
if (extremes) {
DBG(TAB, ul_debugobj(tb, " enlarge width (extreme columns)"));
/* enlarge the first extreme column */
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0) {
size_t add;
if (!cl->is_extreme || scols_column_is_hidden(cl))
continue;
/* this column is too large, ignore?
if (cl->width_max - cl->width >
(tb->termwidth - width))
continue;
*/
add = tb->termwidth - width;
if (add && cl->width + add > cl->width_max)
add = cl->width_max - cl->width;
cl->width += add;
width += add;
if (width == tb->termwidth)
break;
}
}
if (width < tb->termwidth && scols_table_is_maxout(tb)) {
DBG(TAB, ul_debugobj(tb, " enlarge width (max-out)"));
/* try enlarging all columns */
while (width < tb->termwidth) {
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0) {
if (scols_column_is_hidden(cl))
continue;
cl->width++;
width++;
if (width == tb->termwidth)
break;
}
}
} else if (width < tb->termwidth) {
/* enlarge the last column */
struct libscols_column *col = list_entry(
tb->tb_columns.prev, struct libscols_column, cl_columns);
DBG(TAB, ul_debugobj(tb, " enlarge width (last column)"));
if (!scols_column_is_right(col) && tb->termwidth - width > 0) {
col->width += tb->termwidth - width;
width = tb->termwidth;
}
}
}
/* bad, we have to reduce output width, this is done in three stages:
*
* 1) trunc relative with trunc flag if the column width is greater than
* expected column width (it means "width_hint * terminal_width").
*
* 2) trunc all with trunc flag
*
* 3) trunc relative without trunc flag
*
* Note that SCOLS_FL_WRAP (if no custom wrap function is specified) is
* interpreted as SCOLS_FL_TRUNC.
*/
for (stage = 1; width > tb->termwidth && stage <= 3; ) {
size_t org_width = width;
DBG(TAB, ul_debugobj(tb, " reduce width - #%d stage (current=%zu, wanted=%zu)",
stage, width, tb->termwidth));
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0) {
int trunc_flag = 0;
DBG(TAB, ul_debugobj(cl, " checking %s (width=%zu, treeart=%zu)",
cl->header.data, cl->width, cl->width_treeart));
if (scols_column_is_hidden(cl))
continue;
if (width <= tb->termwidth)
break;
/* never truncate if already minimal width */
if (cl->width == cl->width_min)
continue;
/* never truncate the tree */
if (scols_column_is_tree(cl) && width <= cl->width_treeart)
continue;
/* nothing to truncate */
if (cl->width == 0 || width == 0)
continue;
trunc_flag = scols_column_is_trunc(cl)
|| (scols_column_is_wrap(cl) && !scols_column_is_customwrap(cl));
switch (stage) {
/* #1 stage - trunc relative with TRUNC flag */
case 1:
if (!trunc_flag) /* ignore: missing flag */
break;
if (cl->width_hint <= 0 || cl->width_hint >= 1) /* ignore: no relative */
break;
if (cl->width < (size_t) (cl->width_hint * tb->termwidth)) /* ignore: smaller than expected width */
break;
DBG(TAB, ul_debugobj(tb, " reducing (relative with flag)"));
cl->width--;
width--;
break;
/* #2 stage - trunc all with TRUNC flag */
case 2:
if (!trunc_flag) /* ignore: missing flag */
break;
DBG(TAB, ul_debugobj(tb, " reducing (all with flag)"));
cl->width--;
width--;
break;
/* #3 stage - trunc relative without flag */
case 3:
if (cl->width_hint <= 0 || cl->width_hint >= 1) /* ignore: no relative */
break;
DBG(TAB, ul_debugobj(tb, " reducing (relative without flag)"));
cl->width--;
width--;
break;
}
/* hide zero width columns */
if (cl->width == 0)
cl->flags |= SCOLS_FL_HIDDEN;
}
/* the current stage is without effect, go to the next */
if (org_width == width)
stage++;
}
/* ignore last column(s) or force last column to be truncated if
* nowrap mode enabled */
if (tb->no_wrap && width > tb->termwidth) {
scols_reset_iter(&itr, SCOLS_ITER_BACKWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0) {
if (scols_column_is_hidden(cl))
continue;
if (width <= tb->termwidth)
break;
if (width - cl->width < tb->termwidth) {
size_t r = width - tb->termwidth;
cl->flags |= SCOLS_FL_TRUNC;
cl->width -= r;
width -= r;
} else {
cl->flags |= SCOLS_FL_HIDDEN;
width -= cl->width + colsepsz;
}
}
}
done:
DBG(TAB, ul_debugobj(tb, " final width: %zu (rc=%d)", width, rc));
ON_DBG(TAB, dbg_columns(tb));
return rc;
}

View File

@ -26,9 +26,6 @@
#include "carefulputc.h"
#include "smartcolsP.h"
#define colsep(tb) ((tb)->colsep ? (tb)->colsep : " ")
#define linesep(tb) ((tb)->linesep ? (tb)->linesep : "\n")
/* Fallback for symbols
*
* Note that by default library define all the symbols, but in case user does
@ -435,7 +432,7 @@ static int print_data(struct libscols_table *tb,
return 0;
}
static int cell_to_buffer(struct libscols_table *tb,
int __cell_to_buffer(struct libscols_table *tb,
struct libscols_line *ln,
struct libscols_column *cl,
struct libscols_buffer *buf)
@ -595,7 +592,7 @@ static int print_line(struct libscols_table *tb,
while (rc == 0 && scols_table_next_column(tb, &itr, &cl) == 0) {
if (scols_column_is_hidden(cl))
continue;
rc = cell_to_buffer(tb, ln, cl, buf);
rc = __cell_to_buffer(tb, ln, cl, buf);
if (rc == 0)
rc = print_data(tb, cl, ln,
scols_line_get_cell(ln, cl->seqnum),
@ -873,395 +870,6 @@ static int print_tree(struct libscols_table *tb, struct libscols_buffer *buf)
return rc;
}
static void dbg_column(struct libscols_table *tb, struct libscols_column *cl)
{
if (scols_column_is_hidden(cl)) {
DBG(COL, ul_debugobj(cl, "%s (hidden) ignored", cl->header.data));
return;
}
DBG(COL, ul_debugobj(cl, "%15s seq=%zu, width=%zd, "
"hint=%d, avg=%zu, max=%zu, min=%zu, "
"extreme=%s %s",
cl->header.data, cl->seqnum, cl->width,
cl->width_hint > 1 ? (int) cl->width_hint :
(int) (cl->width_hint * tb->termwidth),
cl->width_avg,
cl->width_max,
cl->width_min,
cl->is_extreme ? "yes" : "not",
cl->flags & SCOLS_FL_TRUNC ? "trunc" : ""));
}
static void dbg_columns(struct libscols_table *tb)
{
struct libscols_iter itr;
struct libscols_column *cl;
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0)
dbg_column(tb, cl);
}
/*
* This function counts column width.
*
* For the SCOLS_FL_NOEXTREMES columns it is possible to call this function
* two times. The first pass counts the width and average width. If the column
* contains fields that are too large (a width greater than 2 * average) then
* the column is marked as "extreme". In the second pass all extreme fields
* are ignored and the column width is counted from non-extreme fields only.
*/
static int count_column_width(struct libscols_table *tb,
struct libscols_column *cl,
struct libscols_buffer *buf)
{
struct libscols_line *ln;
struct libscols_iter itr;
int extreme_count = 0, rc = 0, no_header = 0;
size_t extreme_sum = 0;
assert(tb);
assert(cl);
cl->width = 0;
if (!cl->width_min) {
if (cl->width_hint < 1 && scols_table_is_maxout(tb) && tb->is_term) {
cl->width_min = (size_t) (cl->width_hint * tb->termwidth);
if (cl->width_min && !is_last_column(cl))
cl->width_min--;
}
if (scols_cell_get_data(&cl->header)) {
size_t len = mbs_safe_width(scols_cell_get_data(&cl->header));
cl->width_min = max(cl->width_min, len);
} else
no_header = 1;
if (!cl->width_min)
cl->width_min = 1;
}
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_line(tb, &itr, &ln) == 0) {
size_t len;
char *data;
rc = cell_to_buffer(tb, ln, cl, buf);
if (rc)
goto done;
data = buffer_get_data(buf);
if (!data)
len = 0;
else if (scols_column_is_customwrap(cl))
len = cl->wrap_chunksize(cl, data, cl->wrapfunc_data);
else
len = mbs_safe_width(data);
if (len == (size_t) -1) /* ignore broken multibyte strings */
len = 0;
cl->width_max = max(len, cl->width_max);
if (cl->is_extreme && cl->width_avg && len > cl->width_avg * 2)
continue;
else if (scols_column_is_noextremes(cl)) {
extreme_sum += len;
extreme_count++;
}
cl->width = max(len, cl->width);
if (scols_column_is_tree(cl)) {
size_t treewidth = buffer_get_safe_art_size(buf);
cl->width_treeart = max(cl->width_treeart, treewidth);
}
}
if (extreme_count && cl->width_avg == 0) {
cl->width_avg = extreme_sum / extreme_count;
if (cl->width_avg && cl->width_max > cl->width_avg * 2)
cl->is_extreme = 1;
}
/* enlarge to minimal width */
if (cl->width < cl->width_min && !scols_column_is_strict_width(cl))
cl->width = cl->width_min;
/* use absolute size for large columns */
else if (cl->width_hint >= 1 && cl->width < (size_t) cl->width_hint
&& cl->width_min < (size_t) cl->width_hint)
cl->width = (size_t) cl->width_hint;
/* Column without header and data, set minimal size to zero (default is 1) */
if (cl->width_max == 0 && no_header && cl->width_min == 1 && cl->width <= 1)
cl->width = cl->width_min = 0;
done:
ON_DBG(COL, dbg_column(tb, cl));
return rc;
}
/*
* This is core of the scols_* voodoo...
*/
static int recount_widths(struct libscols_table *tb, struct libscols_buffer *buf)
{
struct libscols_column *cl;
struct libscols_iter itr;
size_t width = 0, width_min = 0; /* output width */
int stage, rc = 0;
int extremes = 0;
size_t colsepsz;
DBG(TAB, ul_debugobj(tb, "recounting widths (termwidth=%zu)", tb->termwidth));
colsepsz = mbs_safe_width(colsep(tb));
/* set basic columns width
*/
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0) {
int is_last;
if (scols_column_is_hidden(cl))
continue;
rc = count_column_width(tb, cl, buf);
if (rc)
goto done;
is_last = is_last_column(cl);
width += cl->width + (is_last ? 0 : colsepsz); /* separator for non-last column */
width_min += cl->width_min + (is_last ? 0 : colsepsz);
extremes += cl->is_extreme;
}
if (!tb->is_term) {
DBG(TAB, ul_debugobj(tb, " non-terminal output"));
goto done;
}
/* be paranoid */
if (width_min > tb->termwidth && scols_table_is_maxout(tb)) {
DBG(TAB, ul_debugobj(tb, " min width larger than terminal! [width=%zu, term=%zu]", width_min, tb->termwidth));
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (width_min > tb->termwidth
&& scols_table_next_column(tb, &itr, &cl) == 0) {
if (scols_column_is_hidden(cl))
continue;
width_min--;
cl->width_min--;
}
DBG(TAB, ul_debugobj(tb, " min width reduced to %zu", width_min));
}
/* reduce columns with extreme fields */
if (width > tb->termwidth && extremes) {
DBG(TAB, ul_debugobj(tb, " reduce width (extreme columns)"));
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0) {
size_t org_width;
if (!cl->is_extreme || scols_column_is_hidden(cl))
continue;
org_width = cl->width;
rc = count_column_width(tb, cl, buf);
if (rc)
goto done;
if (org_width > cl->width)
width -= org_width - cl->width;
else
extremes--; /* hmm... nothing reduced */
}
}
if (width < tb->termwidth) {
if (extremes) {
DBG(TAB, ul_debugobj(tb, " enlarge width (extreme columns)"));
/* enlarge the first extreme column */
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0) {
size_t add;
if (!cl->is_extreme || scols_column_is_hidden(cl))
continue;
/* this column is too large, ignore?
if (cl->width_max - cl->width >
(tb->termwidth - width))
continue;
*/
add = tb->termwidth - width;
if (add && cl->width + add > cl->width_max)
add = cl->width_max - cl->width;
cl->width += add;
width += add;
if (width == tb->termwidth)
break;
}
}
if (width < tb->termwidth && scols_table_is_maxout(tb)) {
DBG(TAB, ul_debugobj(tb, " enlarge width (max-out)"));
/* try enlarging all columns */
while (width < tb->termwidth) {
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0) {
if (scols_column_is_hidden(cl))
continue;
cl->width++;
width++;
if (width == tb->termwidth)
break;
}
}
} else if (width < tb->termwidth) {
/* enlarge the last column */
struct libscols_column *col = list_entry(
tb->tb_columns.prev, struct libscols_column, cl_columns);
DBG(TAB, ul_debugobj(tb, " enlarge width (last column)"));
if (!scols_column_is_right(col) && tb->termwidth - width > 0) {
col->width += tb->termwidth - width;
width = tb->termwidth;
}
}
}
/* bad, we have to reduce output width, this is done in three stages:
*
* 1) trunc relative with trunc flag if the column width is greater than
* expected column width (it means "width_hint * terminal_width").
*
* 2) trunc all with trunc flag
*
* 3) trunc relative without trunc flag
*
* Note that SCOLS_FL_WRAP (if no custom wrap function is specified) is
* interpreted as SCOLS_FL_TRUNC.
*/
for (stage = 1; width > tb->termwidth && stage <= 3; ) {
size_t org_width = width;
DBG(TAB, ul_debugobj(tb, " reduce width - #%d stage (current=%zu, wanted=%zu)",
stage, width, tb->termwidth));
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0) {
int trunc_flag = 0;
DBG(TAB, ul_debugobj(cl, " checking %s (width=%zu, treeart=%zu)",
cl->header.data, cl->width, cl->width_treeart));
if (scols_column_is_hidden(cl))
continue;
if (width <= tb->termwidth)
break;
/* never truncate if already minimal width */
if (cl->width == cl->width_min)
continue;
/* never truncate the tree */
if (scols_column_is_tree(cl) && width <= cl->width_treeart)
continue;
/* nothing to truncate */
if (cl->width == 0 || width == 0)
continue;
trunc_flag = scols_column_is_trunc(cl)
|| (scols_column_is_wrap(cl) && !scols_column_is_customwrap(cl));
switch (stage) {
/* #1 stage - trunc relative with TRUNC flag */
case 1:
if (!trunc_flag) /* ignore: missing flag */
break;
if (cl->width_hint <= 0 || cl->width_hint >= 1) /* ignore: no relative */
break;
if (cl->width < (size_t) (cl->width_hint * tb->termwidth)) /* ignore: smaller than expected width */
break;
DBG(TAB, ul_debugobj(tb, " reducing (relative with flag)"));
cl->width--;
width--;
break;
/* #2 stage - trunc all with TRUNC flag */
case 2:
if (!trunc_flag) /* ignore: missing flag */
break;
DBG(TAB, ul_debugobj(tb, " reducing (all with flag)"));
cl->width--;
width--;
break;
/* #3 stage - trunc relative without flag */
case 3:
if (cl->width_hint <= 0 || cl->width_hint >= 1) /* ignore: no relative */
break;
DBG(TAB, ul_debugobj(tb, " reducing (relative without flag)"));
cl->width--;
width--;
break;
}
/* hide zero width columns */
if (cl->width == 0)
cl->flags |= SCOLS_FL_HIDDEN;
}
/* the current stage is without effect, go to the next */
if (org_width == width)
stage++;
}
/* ignore last column(s) or force last column to be truncated if
* nowrap mode enabled */
if (tb->no_wrap && width > tb->termwidth) {
scols_reset_iter(&itr, SCOLS_ITER_BACKWARD);
while (scols_table_next_column(tb, &itr, &cl) == 0) {
if (scols_column_is_hidden(cl))
continue;
if (width <= tb->termwidth)
break;
if (width - cl->width < tb->termwidth) {
size_t r = width - tb->termwidth;
cl->flags |= SCOLS_FL_TRUNC;
cl->width -= r;
width -= r;
} else {
cl->flags |= SCOLS_FL_HIDDEN;
width -= cl->width + colsepsz;
}
}
}
done:
DBG(TAB, ul_debugobj(tb, " final width: %zu (rc=%d)", width, rc));
ON_DBG(TAB, dbg_columns(tb));
return rc;
}
static size_t strlen_line(struct libscols_line *ln)
{
size_t i, sz = 0;
@ -1381,7 +989,7 @@ static int initialize_printing(struct libscols_table *tb, struct libscols_buffer
}
if (tb->format == SCOLS_FMT_HUMAN) {
rc = recount_widths(tb, *buf);
rc = __scols_calculate(tb, *buf);
if (rc != 0)
goto err;
}

View File

@ -115,6 +115,9 @@ struct libscols_column {
struct libscols_table *table;
};
#define colsep(tb) ((tb)->colsep ? (tb)->colsep : " ")
#define linesep(tb) ((tb)->linesep ? (tb)->linesep : "\n")
/*
* Table line
*/
@ -214,6 +217,8 @@ static inline int scols_iter_is_last(const struct libscols_iter *itr)
return itr->p == itr->head;
}
/*
* buffer.c
*/
@ -232,6 +237,18 @@ extern char *buffer_get_safe_data(struct libscols_table *tb,
const char *safechars);
extern size_t buffer_get_safe_art_size(struct libscols_buffer *buf);
/*
* calculate.c
*/
extern int __scols_calculate(struct libscols_table *tb, struct libscols_buffer *buf);
/*
* print.c
*/
extern int __cell_to_buffer(struct libscols_table *tb,
struct libscols_line *ln,
struct libscols_column *cl,
struct libscols_buffer *buf);
static inline int is_last_child(struct libscols_line *ln)
{