diff options
author | Manuel Bentele | 2020-10-23 15:18:01 +0200 |
---|---|---|
committer | Manuel Bentele | 2020-10-23 15:18:01 +0200 |
commit | dbb41ce2b7f309d394054a6bd1e33afd578798a5 (patch) | |
tree | 6a31092063d9f2fb5ac5720ec6759040e793c3d5 /utils/libsmartcols | |
parent | Set Linux kernel version to unknown if it is not detectable (diff) | |
download | xloop-dbb41ce2b7f309d394054a6bd1e33afd578798a5.tar.gz xloop-dbb41ce2b7f309d394054a6bd1e33afd578798a5.tar.xz xloop-dbb41ce2b7f309d394054a6bd1e33afd578798a5.zip |
Move the source code of all xloop components to the common 'src' directory
Diffstat (limited to 'utils/libsmartcols')
-rw-r--r-- | utils/libsmartcols/CMakeLists.txt | 22 | ||||
-rw-r--r-- | utils/libsmartcols/src/buffer.c | 152 | ||||
-rw-r--r-- | utils/libsmartcols/src/calculate.c | 454 | ||||
-rw-r--r-- | utils/libsmartcols/src/cell.c | 257 | ||||
-rw-r--r-- | utils/libsmartcols/src/column.c | 564 | ||||
-rw-r--r-- | utils/libsmartcols/src/fput.c | 97 | ||||
-rw-r--r-- | utils/libsmartcols/src/grouping.c | 575 | ||||
-rw-r--r-- | utils/libsmartcols/src/init.c | 62 | ||||
-rw-r--r-- | utils/libsmartcols/src/iter.c | 74 | ||||
-rw-r--r-- | utils/libsmartcols/src/libsmartcols.h | 329 | ||||
-rw-r--r-- | utils/libsmartcols/src/line.c | 540 | ||||
-rw-r--r-- | utils/libsmartcols/src/print-api.c | 211 | ||||
-rw-r--r-- | utils/libsmartcols/src/print.c | 1089 | ||||
-rw-r--r-- | utils/libsmartcols/src/smartcolsP.h | 468 | ||||
-rw-r--r-- | utils/libsmartcols/src/symbols.c | 293 | ||||
-rw-r--r-- | utils/libsmartcols/src/table.c | 1691 | ||||
-rw-r--r-- | utils/libsmartcols/src/version.c | 62 | ||||
-rw-r--r-- | utils/libsmartcols/src/walk.c | 152 |
18 files changed, 0 insertions, 7092 deletions
diff --git a/utils/libsmartcols/CMakeLists.txt b/utils/libsmartcols/CMakeLists.txt deleted file mode 100644 index c8deb72..0000000 --- a/utils/libsmartcols/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -# set the project name -project(xloop-utils-libsmartcols) - -add_library(libsmartcols STATIC ${CMAKE_CURRENT_SOURCE_DIR}/src/buffer.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/calculate.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/cell.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/column.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/fput.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/grouping.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/init.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/iter.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/line.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/print-api.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/print.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/symbols.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/table.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/version.c - ${CMAKE_CURRENT_SOURCE_DIR}/src/walk.c) -target_include_directories(libsmartcols PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/../lib) -target_link_libraries(libsmartcols LINK_PUBLIC libcommon) diff --git a/utils/libsmartcols/src/buffer.c b/utils/libsmartcols/src/buffer.c deleted file mode 100644 index d376e8f..0000000 --- a/utils/libsmartcols/src/buffer.c +++ /dev/null @@ -1,152 +0,0 @@ - -#include "smartcolsP.h" -#include "mbsalign.h" - -/* This is private struct to work with output data */ -struct libscols_buffer { - char *begin; /* begin of the buffer */ - char *cur; /* current end of the buffer */ - char *encdata; /* encoded buffer mbs_safe_encode() */ - - size_t bufsz; /* size of the buffer */ - size_t art_idx; /* begin of the tree ascii art or zero */ -}; - -struct libscols_buffer *new_buffer(size_t sz) -{ - struct libscols_buffer *buf = malloc(sz + sizeof(struct libscols_buffer)); - - if (!buf) - return NULL; - - buf->cur = buf->begin = ((char *) buf) + sizeof(struct libscols_buffer); - buf->encdata = NULL; - buf->bufsz = sz; - - DBG(BUFF, ul_debugobj(buf, "alloc (size=%zu)", sz)); - return buf; -} - -void free_buffer(struct libscols_buffer *buf) -{ - if (!buf) - return; - DBG(BUFF, ul_debugobj(buf, "dealloc")); - free(buf->encdata); - free(buf); -} - -int buffer_reset_data(struct libscols_buffer *buf) -{ - if (!buf) - return -EINVAL; - - /*DBG(BUFF, ul_debugobj(buf, "reset data"));*/ - buf->begin[0] = '\0'; - buf->cur = buf->begin; - buf->art_idx = 0; - return 0; -} - -int buffer_append_data(struct libscols_buffer *buf, const char *str) -{ - size_t maxsz, sz; - - if (!buf) - return -EINVAL; - if (!str || !*str) - return 0; - - sz = strlen(str); - maxsz = buf->bufsz - (buf->cur - buf->begin); - - if (maxsz <= sz) - return -EINVAL; - memcpy(buf->cur, str, sz + 1); - buf->cur += sz; - return 0; -} - -int buffer_append_ntimes(struct libscols_buffer *buf, size_t n, const char *str) -{ - size_t i; - - for (i = 0; i < n; i++) { - int rc = buffer_append_data(buf, str); - if (rc) - return rc; - } - return 0; -} - -int buffer_set_data(struct libscols_buffer *buf, const char *str) -{ - int rc = buffer_reset_data(buf); - return rc ? rc : buffer_append_data(buf, str); -} - -/* save the current buffer position to art_idx */ -void buffer_set_art_index(struct libscols_buffer *buf) -{ - if (buf) { - buf->art_idx = buf->cur - buf->begin; - /*DBG(BUFF, ul_debugobj(buf, "art index: %zu", buf->art_idx));*/ - } -} - -char *buffer_get_data(struct libscols_buffer *buf) -{ - return buf ? buf->begin : NULL; -} - -size_t buffer_get_size(struct libscols_buffer *buf) -{ - return buf ? buf->bufsz : 0; -} - -/* encode data by mbs_safe_encode() to avoid control and non-printable chars */ -char *buffer_get_safe_data(struct libscols_table *tb, - struct libscols_buffer *buf, - size_t *cells, - const char *safechars) -{ - char *data = buffer_get_data(buf); - char *res = NULL; - - if (!data) - goto nothing; - - if (!buf->encdata) { - buf->encdata = malloc(mbs_safe_encode_size(buf->bufsz) + 1); - if (!buf->encdata) - goto nothing; - } - - if (scols_table_is_noencoding(tb)) { - *cells = mbs_width(data); - strcpy(buf->encdata, data); - res = buf->encdata; - } else { - res = mbs_safe_encode_to_buffer(data, cells, buf->encdata, safechars); - } - - if (!res || !*cells || *cells == (size_t) -1) - goto nothing; - return res; -nothing: - *cells = 0; - return NULL; -} - -/* returns size in bytes of the ascii art (according to art_idx) in safe encoding */ -size_t buffer_get_safe_art_size(struct libscols_buffer *buf) -{ - char *data = buffer_get_data(buf); - size_t bytes = 0; - - if (!data || !buf->art_idx) - return 0; - - mbs_safe_nwidth(data, buf->art_idx, &bytes); - return bytes; -} diff --git a/utils/libsmartcols/src/calculate.c b/utils/libsmartcols/src/calculate.c deleted file mode 100644 index b6137fd..0000000 --- a/utils/libsmartcols/src/calculate.c +++ /dev/null @@ -1,454 +0,0 @@ -#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); -} - -static int count_cell_width(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_column *cl, - struct libscols_buffer *buf) -{ - size_t len; - char *data; - int rc; - - rc = __cell_to_buffer(tb, ln, cl, buf); - if (rc) - return rc; - - 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 if (scols_table_is_noencoding(tb)) - len = mbs_width(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) - return 0; - - if (scols_column_is_noextremes(cl)) { - cl->extreme_sum += len; - cl->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); - } - return 0; -} - - -static int walk_count_cell_width(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_column *cl, - void *data) -{ - return count_cell_width(tb, ln, cl, (struct libscols_buffer *) data); -} - -/* - * 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) -{ - int rc = 0, no_header = 0; - - assert(tb); - assert(cl); - - cl->width = 0; - if (!cl->width_min) { - const char *data; - - 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--; - } - - data = scols_cell_get_data(&cl->header); - if (data) { - size_t len = scols_table_is_noencoding(tb) ? - mbs_width(data) : mbs_safe_width(data); - cl->width_min = max(cl->width_min, len); - } else - no_header = 1; - - if (!cl->width_min) - cl->width_min = 1; - } - - if (scols_table_is_tree(tb)) { - /* Count width for tree */ - rc = scols_walk_tree(tb, cl, walk_count_cell_width, (void *) buf); - if (rc) - goto done; - } else { - /* Count width for list */ - struct libscols_iter itr; - struct libscols_line *ln; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - rc = count_cell_width(tb, ln, cl, buf); - if (rc) - goto done; - } - } - - if (scols_column_is_tree(cl) && has_groups(tb)) { - /* We don't fill buffer with groups tree ascii art during width - * calculation. The print function only enlarge grpset[] and we - * calculate final width from grpset_size. - */ - size_t gprwidth = tb->grpset_size + 1; - cl->width_treeart += gprwidth; - cl->width_max += gprwidth; - cl->width += gprwidth; - if (cl->extreme_count) - cl->extreme_sum += gprwidth; - } - - if (cl->extreme_count && cl->width_avg == 0) { - cl->width_avg = cl->extreme_sum / cl->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, group_ncolumns = 0; - size_t colsepsz; - - - DBG(TAB, ul_debugobj(tb, "-----calculate-(termwidth=%zu)-----", tb->termwidth)); - tb->is_dummy_print = 1; - - colsepsz = scols_table_is_noencoding(tb) ? - mbs_width(colsep(tb)) : - mbs_safe_width(colsep(tb)); - - if (has_groups(tb)) - group_ncolumns = 1; - - /* 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; - - /* we print groups chart only for the for the first tree column */ - if (scols_column_is_tree(cl) && group_ncolumns == 1) { - cl->is_groups = 1; - group_ncolumns++; - } - - 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); - if (cl->is_extreme) - extremes++; - } - - 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) - 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: - tb->is_dummy_print = 0; - DBG(TAB, ul_debugobj(tb, "-----final width: %zu (rc=%d)-----", width, rc)); - ON_DBG(TAB, dbg_columns(tb)); - - return rc; -} diff --git a/utils/libsmartcols/src/cell.c b/utils/libsmartcols/src/cell.c deleted file mode 100644 index 4cd6e59..0000000 --- a/utils/libsmartcols/src/cell.c +++ /dev/null @@ -1,257 +0,0 @@ -/* - * cell.c - functions for table handling at the cell level - * - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: cell - * @title: Cell - * @short_description: container for your data - * - * An API to access and modify per-cell data and information. Note that cell is - * always part of the line. If you destroy (un-reference) a line than it - * destroys all line cells too. - */ - - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> - -#include "smartcolsP.h" - -/* - * The cell has no ref-counting, free() and new() functions. All is - * handled by libscols_line. - */ - -/** - * scols_reset_cell: - * @ce: pointer to a struct libscols_cell instance - * - * Frees the cell's internal data and resets its status. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_reset_cell(struct libscols_cell *ce) -{ - if (!ce) - return -EINVAL; - - /*DBG(CELL, ul_debugobj(ce, "reset"));*/ - free(ce->data); - free(ce->color); - memset(ce, 0, sizeof(*ce)); - return 0; -} - -/** - * scols_cell_set_data: - * @ce: a pointer to a struct libscols_cell instance - * @data: data (used for scols_print_table()) - * - * Stores a copy of the @str in @ce, the old data are deallocated by free(). - * - * Returns: 0, a negative value in case of an error. - */ -int scols_cell_set_data(struct libscols_cell *ce, const char *data) -{ - return strdup_to_struct_member(ce, data, data); -} - -/** - * scols_cell_refer_data: - * @ce: a pointer to a struct libscols_cell instance - * @data: data (used for scols_print_table()) - * - * Adds a reference to @str to @ce. The pointer is deallocated by - * scols_reset_cell() or scols_unref_line(). This function is mostly designed - * for situations when the data for the cell are already composed in allocated - * memory (e.g. asprintf()) to avoid extra unnecessary strdup(). - * - * Returns: 0, a negative value in case of an error. - */ -int scols_cell_refer_data(struct libscols_cell *ce, char *data) -{ - if (!ce) - return -EINVAL; - free(ce->data); - ce->data = data; - return 0; -} - -/** - * scols_cell_get_data: - * @ce: a pointer to a struct libscols_cell instance - * - * Returns: data in @ce or NULL. - */ -const char *scols_cell_get_data(const struct libscols_cell *ce) -{ - return ce ? ce->data : NULL; -} - -/** - * scols_cell_set_userdata: - * @ce: a pointer to a struct libscols_cell instance - * @data: private user data - * - * Returns: 0, a negative value in case of an error. - */ -int scols_cell_set_userdata(struct libscols_cell *ce, void *data) -{ - if (!ce) - return -EINVAL; - ce->userdata = data; - return 0; -} - -/** - * scols_cell_get_userdata - * @ce: a pointer to a struct libscols_cell instance - * - * Returns: user data - */ -void *scols_cell_get_userdata(struct libscols_cell *ce) -{ - return ce->userdata; -} - -/** - * scols_cmpstr_cells: - * @a: pointer to cell - * @b: pointer to cell - * @data: unused pointer to private data (defined by API) - * - * Compares cells data by strcmp(). The function is designed for - * scols_column_set_cmpfunc() and scols_sort_table(). - * - * Returns: follows strcmp() return values. - */ -int scols_cmpstr_cells(struct libscols_cell *a, - struct libscols_cell *b, - __attribute__((__unused__)) void *data) -{ - const char *adata, *bdata; - - if (a == b) - return 0; - - adata = scols_cell_get_data(a); - bdata = scols_cell_get_data(b); - - if (adata == NULL && bdata == NULL) - return 0; - if (adata == NULL) - return -1; - if (bdata == NULL) - return 1; - return strcmp(adata, bdata); -} - -/** - * scols_cell_set_color: - * @ce: a pointer to a struct libscols_cell instance - * @color: color name or ESC sequence - * - * Set the color of @ce to @color. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_cell_set_color(struct libscols_cell *ce, const char *color) -{ - if (color && isalpha(*color)) { - color = color_sequence_from_colorname(color); - if (!color) - return -EINVAL; - } - return strdup_to_struct_member(ce, color, color); -} - -/** - * scols_cell_get_color: - * @ce: a pointer to a struct libscols_cell instance - * - * Returns: the current color of @ce. - */ -const char *scols_cell_get_color(const struct libscols_cell *ce) -{ - return ce->color; -} - -/** - * scols_cell_set_flags: - * @ce: a pointer to a struct libscols_cell instance - * @flags: SCOLS_CELL_FL_* flags - * - * Note that cells in the table are always aligned by column flags. The cell - * flags are used for table title only (now). - * - * Returns: 0, a negative value in case of an error. - */ -int scols_cell_set_flags(struct libscols_cell *ce, int flags) -{ - if (!ce) - return -EINVAL; - ce->flags = flags; - return 0; -} - -/** - * scols_cell_get_flags: - * @ce: a pointer to a struct libscols_cell instance - * - * Returns: the current flags - */ -int scols_cell_get_flags(const struct libscols_cell *ce) -{ - return ce->flags; -} - -/** - * scols_cell_get_alignment: - * @ce: a pointer to a struct libscols_cell instance - * - * Since: 2.30 - * - * Returns: SCOLS_CELL_FL_{RIGHT,CELNTER,LEFT} - */ -int scols_cell_get_alignment(const struct libscols_cell *ce) -{ - if (ce->flags & SCOLS_CELL_FL_RIGHT) - return SCOLS_CELL_FL_RIGHT; - if (ce->flags & SCOLS_CELL_FL_CENTER) - return SCOLS_CELL_FL_CENTER; - - return SCOLS_CELL_FL_LEFT; /* default */ -} - -/** - * scols_cell_copy_content: - * @dest: a pointer to a struct libscols_cell instance - * @src: a pointer to an immutable struct libscols_cell instance - * - * Copy the contents of @src into @dest. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_cell_copy_content(struct libscols_cell *dest, - const struct libscols_cell *src) -{ - int rc; - - rc = scols_cell_set_data(dest, scols_cell_get_data(src)); - if (!rc) - rc = scols_cell_set_color(dest, scols_cell_get_color(src)); - if (!rc) - dest->userdata = src->userdata; - - DBG(CELL, ul_debugobj(src, "copy")); - return rc; -} diff --git a/utils/libsmartcols/src/column.c b/utils/libsmartcols/src/column.c deleted file mode 100644 index c11df69..0000000 --- a/utils/libsmartcols/src/column.c +++ /dev/null @@ -1,564 +0,0 @@ -/* - * column.c - functions for table handling at the column level - * - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: column - * @title: Column - * @short_description: defines output columns formats, headers, etc. - * - * An API to access and modify per-column data and information. - */ - - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> - -#include "mbsalign.h" - -#include "smartcolsP.h" - -/** - * scols_new_column: - * - * Allocates space for a new column. - * - * Returns: a pointer to a new struct libscols_column instance, NULL in case of an ENOMEM error. - */ -struct libscols_column *scols_new_column(void) -{ - struct libscols_column *cl; - - cl = calloc(1, sizeof(*cl)); - if (!cl) - return NULL; - DBG(COL, ul_debugobj(cl, "alloc")); - cl->refcount = 1; - INIT_LIST_HEAD(&cl->cl_columns); - return cl; -} - -/** - * scols_ref_column: - * @cl: a pointer to a struct libscols_column instance - * - * Increases the refcount of @cl. - */ -void scols_ref_column(struct libscols_column *cl) -{ - if (cl) - cl->refcount++; -} - -/** - * scols_unref_column: - * @cl: a pointer to a struct libscols_column instance - * - * Decreases the refcount of @cl. When the count falls to zero, the instance - * is automatically deallocated. - */ -void scols_unref_column(struct libscols_column *cl) -{ - if (cl && --cl->refcount <= 0) { - DBG(COL, ul_debugobj(cl, "dealloc")); - list_del(&cl->cl_columns); - scols_reset_cell(&cl->header); - free(cl->color); - free(cl->safechars); - free(cl->pending_data_buf); - free(cl); - } -} - -/** - * scols_copy_column: - * @cl: a pointer to a struct libscols_column instance - * - * Creates a new column and copies @cl's data over to it. - * - * Returns: a pointer to a new struct libscols_column instance. - */ -struct libscols_column *scols_copy_column(const struct libscols_column *cl) -{ - struct libscols_column *ret; - - if (!cl) - return NULL; - ret = scols_new_column(); - if (!ret) - return NULL; - - DBG(COL, ul_debugobj(cl, "copy")); - - if (scols_column_set_color(ret, cl->color)) - goto err; - if (scols_cell_copy_content(&ret->header, &cl->header)) - goto err; - - ret->width = cl->width; - ret->width_min = cl->width_min; - ret->width_max = cl->width_max; - ret->width_avg = cl->width_avg; - ret->width_hint = cl->width_hint; - ret->flags = cl->flags; - ret->is_extreme = cl->is_extreme; - ret->is_groups = cl->is_groups; - - return ret; -err: - scols_unref_column(ret); - return NULL; -} - -/** - * scols_column_set_whint: - * @cl: a pointer to a struct libscols_column instance - * @whint: a width hint - * - * Sets the width hint of column @cl to @whint. See scols_table_new_column(). - * - * Returns: 0, a negative value in case of an error. - */ -int scols_column_set_whint(struct libscols_column *cl, double whint) -{ - if (!cl) - return -EINVAL; - - cl->width_hint = whint; - return 0; -} - -/** - * scols_column_get_whint: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: The width hint of column @cl, a negative value in case of an error. - */ -double scols_column_get_whint(const struct libscols_column *cl) -{ - return cl->width_hint; -} - -/** - * scols_column_set_flags: - * @cl: a pointer to a struct libscols_column instance - * @flags: a flag mask - * - * Sets the flags of @cl to @flags. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_column_set_flags(struct libscols_column *cl, int flags) -{ - if (!cl) - return -EINVAL; - - if (cl->table) { - if (!(cl->flags & SCOLS_FL_TREE) && (flags & SCOLS_FL_TREE)) - cl->table->ntreecols++; - else if ((cl->flags & SCOLS_FL_TREE) && !(flags & SCOLS_FL_TREE)) - cl->table->ntreecols--; - } - - DBG(COL, ul_debugobj(cl, "setting flags from 0%x to 0%x", cl->flags, flags)); - cl->flags = flags; - return 0; -} - -/** - * scols_column_set_json_type: - * @cl: a pointer to a struct libscols_column instance - * @type: SCOLS_JSON_* type - * - * Sets the type used for JSON formatting, the default is SCOLS_JSON_STRING. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.33 - */ -int scols_column_set_json_type(struct libscols_column *cl, int type) -{ - if (!cl) - return -EINVAL; - - cl->json_type = type; - return 0; - -} - -/** - * scols_column_get_json_type: - * @cl: a pointer to a struct libscols_column instance - * - * Note that SCOLS_JSON_BOOLEAN interprets NULL, empty strings, '0', 'N' and - * 'n' as "false"; and everything else as "true". - * - * Returns: JSON type used for formatting or a negative value in case of an error. - * - * Since: 2.33 - */ -int scols_column_get_json_type(const struct libscols_column *cl) -{ - return cl ? cl->json_type : -EINVAL; -} - - -/** - * scols_column_get_table: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: pointer to the table where columns is used - */ -struct libscols_table *scols_column_get_table(const struct libscols_column *cl) -{ - return cl->table; -} - -/** - * scols_column_get_flags: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: The flag mask of @cl, a negative value in case of an error. - */ -int scols_column_get_flags(const struct libscols_column *cl) -{ - return cl->flags; -} - -/** - * scols_column_get_header: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: A pointer to a struct libscols_cell instance, representing the - * header info of column @cl or NULL in case of an error. - */ -struct libscols_cell *scols_column_get_header(struct libscols_column *cl) -{ - return &cl->header; -} - -/** - * scols_column_set_color: - * @cl: a pointer to a struct libscols_column instance - * @color: color name or ESC sequence - * - * The default color for data cells and column header. - * - * If you want to set header specific color then use scols_column_get_header() - * and scols_cell_set_color(). - * - * If you want to set data cell specific color the use scols_line_get_cell() + - * scols_cell_set_color(). - * - * Returns: 0, a negative value in case of an error. - */ -int scols_column_set_color(struct libscols_column *cl, const char *color) -{ - if (color && isalpha(*color)) { - color = color_sequence_from_colorname(color); - if (!color) - return -EINVAL; - } - return strdup_to_struct_member(cl, color, color); -} - -/** - * scols_column_get_color: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: The current color setting of the column @cl. - */ -const char *scols_column_get_color(const struct libscols_column *cl) -{ - return cl->color; -} - -/** - * scols_wrapnl_nextchunk: - * @cl: a pointer to a struct libscols_column instance - * @data: string - * @userdata: callback private data - * - * This is built-in function for scols_column_set_wrapfunc(). This function - * terminates the current chunk by \0 and returns pointer to the begin of - * the next chunk. The chunks are based on \n. - * - * For example for data "AAA\nBBB\nCCC" the next chunk is "BBB". - * - * Returns: next chunk - * - * Since: 2.29 - */ -char *scols_wrapnl_nextchunk(const struct libscols_column *cl __attribute__((unused)), - char *data, - void *userdata __attribute__((unused))) -{ - char *p = data ? strchr(data, '\n') : NULL; - - if (p) { - *p = '\0'; - return p + 1; - } - return NULL; -} - -/** - * scols_wrapnl_chunksize: - * @cl: a pointer to a struct libscols_column instance - * @data: string - * @userdata: callback private data - * - * Analyzes @data and returns size of the largest chunk. The chunks are based - * on \n. For example for data "AAA\nBBB\nCCCC" the largest chunk size is 4. - * - * Note that the size has to be based on number of terminal cells rather than - * bytes to support multu-byte output. - * - * Returns: size of the largest chunk. - * - * Since: 2.29 - */ -size_t scols_wrapnl_chunksize(const struct libscols_column *cl __attribute__((unused)), - const char *data, - void *userdata __attribute__((unused))) -{ - size_t sum = 0; - - while (data && *data) { - const char *p; - size_t sz; - - p = strchr(data, '\n'); - if (p) { - sz = cl->table && scols_table_is_noencoding(cl->table) ? - mbs_nwidth(data, p - data) : - mbs_safe_nwidth(data, p - data, NULL); - p++; - } else { - sz = cl->table && scols_table_is_noencoding(cl->table) ? - mbs_width(data) : - mbs_safe_width(data); - } - sum = max(sum, sz); - data = p; - } - - return sum; -} - -/** - * scols_column_set_cmpfunc: - * @cl: column - * @cmp: pointer to compare function - * @data: private data for cmp function - * - * Returns: 0, a negative value in case of an error. - */ -int scols_column_set_cmpfunc(struct libscols_column *cl, - int (*cmp)(struct libscols_cell *, - struct libscols_cell *, - void *), - void *data) -{ - if (!cl) - return -EINVAL; - - cl->cmpfunc = cmp; - cl->cmpfunc_data = data; - return 0; -} - -/** - * scols_column_set_wrapfunc: - * @cl: a pointer to a struct libscols_column instance - * @wrap_chunksize: function to return size of the largest chink of data - * @wrap_nextchunk: function to return next zero terminated data - * @userdata: optional stuff for callbacks - * - * Extends SCOLS_FL_WRAP and can be used to set custom wrap function. The default - * is to wrap by column size, but you can create functions to wrap for example - * after \n or after words, etc. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_column_set_wrapfunc(struct libscols_column *cl, - size_t (*wrap_chunksize)(const struct libscols_column *, - const char *, - void *), - char * (*wrap_nextchunk)(const struct libscols_column *, - char *, - void *), - void *userdata) -{ - if (!cl) - return -EINVAL; - - cl->wrap_nextchunk = wrap_nextchunk; - cl->wrap_chunksize = wrap_chunksize; - cl->wrapfunc_data = userdata; - return 0; -} - -/** - * scols_column_set_safechars: - * @cl: a pointer to a struct libscols_column instance - * @safe: safe characters (e.g. "\n\t") - * - * Use for bytes you don't want to encode on output. This is for example - * necessary if you want to use custom wrap function based on \n, in this case - * you have to set "\n" as a safe char. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_column_set_safechars(struct libscols_column *cl, const char *safe) -{ - return strdup_to_struct_member(cl, safechars, safe); -} - -/** - * scols_column_get_safechars: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: safe chars - * - * Since: 2.29 - */ -const char *scols_column_get_safechars(const struct libscols_column *cl) -{ - return cl->safechars; -} - -/** - * scols_column_get_width: - * @cl: a pointer to a struct libscols_column instance - * - * Important note: the column width is unknown until library starts printing - * (width is calculated before printing). The function is usable for example in - * nextchunk() callback specified by scols_column_set_wrapfunc(). - * - * See also scols_column_get_whint(), it returns wanted size (!= final size). - * - * Returns: column width - * - * Since: 2.29 - */ -size_t scols_column_get_width(const struct libscols_column *cl) -{ - return cl->width; -} - -/** - * scols_column_is_hidden: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag hidden. - * - * Returns: 0 or 1 - * - * Since: 2.27 - */ -int scols_column_is_hidden(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_HIDDEN ? 1 : 0; -} - -/** - * scols_column_is_trunc: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag trunc. - * - * Returns: 0 or 1 - */ -int scols_column_is_trunc(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_TRUNC ? 1 : 0; -} -/** - * scols_column_is_tree: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag tree. - * - * Returns: 0 or 1 - */ -int scols_column_is_tree(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_TREE ? 1 : 0; -} -/** - * scols_column_is_right: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag right. - * - * Returns: 0 or 1 - */ -int scols_column_is_right(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_RIGHT ? 1 : 0; -} -/** - * scols_column_is_strict_width: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag strict_width. - * - * Returns: 0 or 1 - */ -int scols_column_is_strict_width(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_STRICTWIDTH ? 1 : 0; -} -/** - * scols_column_is_noextremes: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag no_extremes. - * - * Returns: 0 or 1 - */ -int scols_column_is_noextremes(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_NOEXTREMES ? 1 : 0; -} -/** - * scols_column_is_wrap: - * @cl: a pointer to a struct libscols_column instance - * - * Gets the value of @cl's flag wrap. - * - * Returns: 0 or 1 - * - * Since: 2.28 - */ -int scols_column_is_wrap(const struct libscols_column *cl) -{ - return cl->flags & SCOLS_FL_WRAP ? 1 : 0; -} -/** - * scols_column_is_customwrap: - * @cl: a pointer to a struct libscols_column instance - * - * Returns: 0 or 1 - * - * Since: 2.29 - */ -int scols_column_is_customwrap(const struct libscols_column *cl) -{ - return (cl->flags & SCOLS_FL_WRAP) - && cl->wrap_chunksize - && cl->wrap_nextchunk ? 1 : 0; -} diff --git a/utils/libsmartcols/src/fput.c b/utils/libsmartcols/src/fput.c deleted file mode 100644 index b00c3d8..0000000 --- a/utils/libsmartcols/src/fput.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "carefulputc.h" -#include "smartcolsP.h" - -void fput_indent(struct libscols_table *tb) -{ - int i; - - for (i = 0; i <= tb->indent; i++) - fputs(" ", tb->out); -} - -void fput_table_open(struct libscols_table *tb) -{ - tb->indent = 0; - - if (scols_table_is_json(tb)) { - fputc('{', tb->out); - fputs(linesep(tb), tb->out); - - fput_indent(tb); - fputs_quoted(tb->name, tb->out); - fputs(": [", tb->out); - fputs(linesep(tb), tb->out); - - tb->indent++; - tb->indent_last_sep = 1; - } -} - -void fput_table_close(struct libscols_table *tb) -{ - tb->indent--; - - if (scols_table_is_json(tb)) { - fput_indent(tb); - fputc(']', tb->out); - tb->indent--; - fputs(linesep(tb), tb->out); - fputc('}', tb->out); - tb->indent_last_sep = 1; - } -} - -void fput_children_open(struct libscols_table *tb) -{ - if (scols_table_is_json(tb)) { - fputc(',', tb->out); - fputs(linesep(tb), tb->out); - fput_indent(tb); - fputs("\"children\": [", tb->out); - } - /* between parent and child is separator */ - fputs(linesep(tb), tb->out); - tb->indent_last_sep = 1; - tb->indent++; - tb->termlines_used++; -} - -void fput_children_close(struct libscols_table *tb) -{ - tb->indent--; - - if (scols_table_is_json(tb)) { - fput_indent(tb); - fputc(']', tb->out); - fputs(linesep(tb), tb->out); - tb->indent_last_sep = 1; - } -} - -void fput_line_open(struct libscols_table *tb) -{ - if (scols_table_is_json(tb)) { - fput_indent(tb); - fputc('{', tb->out); - tb->indent_last_sep = 0; - } - tb->indent++; -} - -void fput_line_close(struct libscols_table *tb, int last, int last_in_table) -{ - tb->indent--; - if (scols_table_is_json(tb)) { - if (tb->indent_last_sep) - fput_indent(tb); - fputs(last ? "}" : "},", tb->out); - if (!tb->no_linesep) - fputs(linesep(tb), tb->out); - - } else if (tb->no_linesep == 0 && last_in_table == 0) { - fputs(linesep(tb), tb->out); - tb->termlines_used++; - } - - tb->indent_last_sep = 1; -} diff --git a/utils/libsmartcols/src/grouping.c b/utils/libsmartcols/src/grouping.c deleted file mode 100644 index 0b27cb2..0000000 --- a/utils/libsmartcols/src/grouping.c +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright (C) 2018 Karel Zak <kzak@redhat.com> - */ -#include "smartcolsP.h" - -/** - * SECTION: grouping - * @title: Grouping - * @short_description: lines grouing - * - * Lines groups manipulation API. The grouping API can be used to create M:N - * relations between lines and on tree-like output it prints extra chart to - * visualize these relations. The group has unlimited number of members and - * group childs. See libsmartcols/sample/grouping* for more details. - */ - -/* Private API */ -void scols_ref_group(struct libscols_group *gr) -{ - if (gr) - gr->refcount++; -} - -void scols_group_remove_children(struct libscols_group *gr) -{ - if (!gr) - return; - - while (!list_empty(&gr->gr_children)) { - struct libscols_line *ln = list_entry(gr->gr_children.next, - struct libscols_line, ln_children); - - DBG(GROUP, ul_debugobj(gr, "remove child")); - list_del_init(&ln->ln_children); - scols_ref_group(ln->parent_group); - ln->parent_group = NULL; - scols_unref_line(ln); - } -} - -void scols_group_remove_members(struct libscols_group *gr) -{ - if (!gr) - return; - - while (!list_empty(&gr->gr_members)) { - struct libscols_line *ln = list_entry(gr->gr_members.next, - struct libscols_line, ln_groups); - - DBG(GROUP, ul_debugobj(gr, "remove member [%p]", ln)); - list_del_init(&ln->ln_groups); - - scols_unref_group(ln->group); - ln->group->nmembers++; - ln->group = NULL; - - scols_unref_line(ln); - } -} - -/* note group has to be already without members to deallocate */ -void scols_unref_group(struct libscols_group *gr) -{ - if (gr && --gr->refcount <= 0) { - DBG(GROUP, ul_debugobj(gr, "dealloc")); - scols_group_remove_children(gr); - list_del(&gr->gr_groups); - free(gr); - return; - } -} - - -static void groups_fix_members_order(struct libscols_line *ln) -{ - struct libscols_iter itr; - struct libscols_line *child; - - if (ln->group) { - INIT_LIST_HEAD(&ln->ln_groups); - list_add_tail(&ln->ln_groups, &ln->group->gr_members); - DBG(GROUP, ul_debugobj(ln->group, "fixing member line=%p [%zu/%zu]", - ln, ln->group->nmembers, - list_count_entries(&ln->group->gr_members))); - } - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_line_next_child(ln, &itr, &child) == 0) - groups_fix_members_order(child); - - /* - * We modify gr_members list, so is_last_group_member() does not have - * to provide reliable answer, we need to verify by list_count_entries(). - */ - if (ln->group - && is_last_group_member(ln) - && ln->group->nmembers == list_count_entries(&ln->group->gr_members)) { - - DBG(GROUP, ul_debugobj(ln->group, "fixing childs")); - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_line_next_group_child(ln, &itr, &child) == 0) - groups_fix_members_order(child); - } -} - -void scols_groups_fix_members_order(struct libscols_table *tb) -{ - struct libscols_iter itr; - struct libscols_line *ln; - struct libscols_group *gr; - - /* remove all from groups lists */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_group(tb, &itr, &gr) == 0) { - while (!list_empty(&gr->gr_members)) { - struct libscols_line *line = list_entry(gr->gr_members.next, - struct libscols_line, ln_groups); - list_del_init(&line->ln_groups); - } - } - - /* add again to the groups list in order we walk in tree */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - if (ln->parent || ln->parent_group) - continue; - groups_fix_members_order(ln); - } - - /* If group child is member of another group * - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_group(tb, &itr, &gr) == 0) { - struct libscols_iter xitr; - struct libscols_line *child; - - scols_reset_iter(&xitr, SCOLS_ITER_FORWARD); - while (scols_line_next_group_child(ln, &xitr, &child) == 0) - groups_fix_members_order(child); - } - */ -} - -static inline const char *group_state_to_string(int state) -{ - static const char *grpstates[] = { - [SCOLS_GSTATE_NONE] = "none", - [SCOLS_GSTATE_FIRST_MEMBER] = "1st-member", - [SCOLS_GSTATE_MIDDLE_MEMBER] = "middle-member", - [SCOLS_GSTATE_LAST_MEMBER] = "last-member", - [SCOLS_GSTATE_MIDDLE_CHILD] = "middle-child", - [SCOLS_GSTATE_LAST_CHILD] = "last-child", - [SCOLS_GSTATE_CONT_MEMBERS] = "continue-members", - [SCOLS_GSTATE_CONT_CHILDREN] = "continue-children" - }; - - assert(state >= 0); - assert((size_t) state < ARRAY_SIZE(grpstates)); - - return grpstates[state]; -} -/* -static void grpset_debug(struct libscols_table *tb, struct libscols_line *ln) -{ - size_t i; - - for (i = 0; i < tb->grpset_size; i++) { - if (tb->grpset[i]) { - struct libscols_group *gr = tb->grpset[i]; - - if (ln) - DBG(LINE, ul_debugobj(ln, "grpset[%zu]: %p %s", i, - gr, group_state_to_string(gr->state))); - else - DBG(LINE, ul_debug("grpset[%zu]: %p %s", i, - gr, group_state_to_string(gr->state))); - } else if (ln) { - DBG(LINE, ul_debugobj(ln, "grpset[%zu]: free", i)); - } else - DBG(LINE, ul_debug("grpset[%zu]: free", i)); - } -} -*/ -static int group_state_for_line(struct libscols_group *gr, struct libscols_line *ln) -{ - if (gr->state == SCOLS_GSTATE_NONE && - (ln->group != gr || !is_first_group_member(ln))) - /* - * NONE is possible to translate to FIRST_MEMBER only, and only if - * line group matches with the current group. - */ - return SCOLS_GSTATE_NONE; - - if (ln->group != gr && ln->parent_group != gr) { - /* Not our line, continue */ - if (gr->state == SCOLS_GSTATE_FIRST_MEMBER || - gr->state == SCOLS_GSTATE_MIDDLE_MEMBER || - gr->state == SCOLS_GSTATE_CONT_MEMBERS) - return SCOLS_GSTATE_CONT_MEMBERS; - - if (gr->state == SCOLS_GSTATE_LAST_MEMBER || - gr->state == SCOLS_GSTATE_MIDDLE_CHILD || - gr->state == SCOLS_GSTATE_CONT_CHILDREN) - return SCOLS_GSTATE_CONT_CHILDREN; - - } else if (ln->group == gr && is_first_group_member(ln)) { - return SCOLS_GSTATE_FIRST_MEMBER; - - } else if (ln->group == gr && is_last_group_member(ln)) { - return SCOLS_GSTATE_LAST_MEMBER; - - } else if (ln->group == gr && is_group_member(ln)) { - return SCOLS_GSTATE_MIDDLE_MEMBER; - - } else if (ln->parent_group == gr && is_last_group_child(ln)) { - return SCOLS_GSTATE_LAST_CHILD; - - } else if (ln->parent_group == gr && is_group_child(ln)) { - return SCOLS_GSTATE_MIDDLE_CHILD; - } - - return SCOLS_GSTATE_NONE; -} - -/* - * apply new @state to the chunk (addressed by @xx) of grpset used for the group (@gr) - */ -static void grpset_apply_group_state(struct libscols_group **xx, int state, struct libscols_group *gr) -{ - size_t i; - - DBG(GROUP, ul_debugobj(gr, " applying state to grpset")); - - /* gr->state holds the old state, @state is the new state - */ - for (i = 0; i < SCOLS_GRPSET_CHUNKSIZ; i++) - xx[i] = state == SCOLS_GSTATE_NONE ? NULL : gr; - - gr->state = state; -} - -static struct libscols_group **grpset_locate_freespace(struct libscols_table *tb, int chunks, int prepend) -{ - size_t i, avail = 0; - struct libscols_group **tmp, **first = NULL; - const size_t wanted = chunks * SCOLS_GRPSET_CHUNKSIZ; - - if (!tb->grpset_size) - prepend = 0; - /* - DBG(TAB, ul_debugobj(tb, "orig grpset:")); - grpset_debug(tb, NULL); - */ - if (prepend) { - for (i = tb->grpset_size - 1; ; i--) { - if (tb->grpset[i] == NULL) { - first = &tb->grpset[i]; - avail++; - } else - avail = 0; - if (avail == wanted) - goto done; - if (i == 0) - break; - } - } else { - for (i = 0; i < tb->grpset_size; i++) { - if (tb->grpset[i] == NULL) { - if (avail == 0) - first = &tb->grpset[i]; - avail++; - } else - avail = 0; - if (avail == wanted) - goto done; - } - } - - DBG(TAB, ul_debugobj(tb, " realocate grpset [sz: old=%zu, new=%zu, new_chunks=%d]", - tb->grpset_size, tb->grpset_size + wanted, chunks)); - - tmp = realloc(tb->grpset, (tb->grpset_size + wanted) * sizeof(struct libscols_group *)); - if (!tmp) - return NULL; - - tb->grpset = tmp; - - if (prepend) { - DBG(TAB, ul_debugobj(tb, " prepending free space")); - char *dest = (char *) tb->grpset; - - memmove( dest + (wanted * sizeof(struct libscols_group *)), - tb->grpset, - tb->grpset_size * sizeof(struct libscols_group *)); - first = tb->grpset; - } else { - first = tb->grpset + tb->grpset_size; - } - - memset(first, 0, wanted * sizeof(struct libscols_group *)); - tb->grpset_size += wanted; - -done: - /* - DBG(TAB, ul_debugobj(tb, "new grpset:")); - grpset_debug(tb, NULL); - */ - return first; -} - -static struct libscols_group **grpset_locate_group(struct libscols_table *tb, struct libscols_group *gr) -{ - size_t i; - - for (i = 0; i < tb->grpset_size; i++) { - if (gr == tb->grpset[i]) - return &tb->grpset[i]; - } - - return NULL; -} - - -static int grpset_update(struct libscols_table *tb, struct libscols_line *ln, struct libscols_group *gr) -{ - struct libscols_group **xx; - int state; - - DBG(LINE, ul_debugobj(ln, " group [%p] grpset update [grpset size=%zu]", gr, tb->grpset_size)); - - /* new state, note that gr->state still holds the original state */ - state = group_state_for_line(gr, ln); - DBG(LINE, ul_debugobj(ln, " state %s --> %s", - group_state_to_string(gr->state), - group_state_to_string(state))); - - if (state == SCOLS_GSTATE_FIRST_MEMBER && gr->state != SCOLS_GSTATE_NONE) { - DBG(LINE, ul_debugobj(ln, "wrong group initialization (%s)", group_state_to_string(gr->state))); - abort(); - } - if (state != SCOLS_GSTATE_NONE && gr->state == SCOLS_GSTATE_LAST_CHILD) { - DBG(LINE, ul_debugobj(ln, "wrong group termination (%s)", group_state_to_string(gr->state))); - abort(); - } - if (gr->state == SCOLS_GSTATE_LAST_MEMBER && - !(state == SCOLS_GSTATE_LAST_CHILD || - state == SCOLS_GSTATE_CONT_CHILDREN || - state == SCOLS_GSTATE_MIDDLE_CHILD || - state == SCOLS_GSTATE_NONE)) { - DBG(LINE, ul_debugobj(ln, "wrong group member->child order")); - abort(); - } - - /* should not happen; probably wrong line... */ - if (gr->state == SCOLS_GSTATE_NONE && state == SCOLS_GSTATE_NONE) - return 0; - - /* locate place in grpset where we draw the group */ - if (!tb->grpset || gr->state == SCOLS_GSTATE_NONE) - xx = grpset_locate_freespace(tb, 1, 1); - else - xx = grpset_locate_group(tb, gr); - if (!xx) { - DBG(LINE, ul_debugobj(ln, "failed to locate group or reallocate grpset")); - return -ENOMEM; - } - - grpset_apply_group_state(xx, state, gr); - /*ON_DBG(LINE, grpset_debug(tb, ln));*/ - return 0; -} - -static int grpset_update_active_groups(struct libscols_table *tb, struct libscols_line *ln) -{ - int rc = 0; - size_t i; - struct libscols_group *last = NULL; - - DBG(LINE, ul_debugobj(ln, " update for active groups")); - - for (i = 0; i < tb->grpset_size; i++) { - struct libscols_group *gr = tb->grpset[i]; - - if (!gr || last == gr) - continue; - last = gr; - rc = grpset_update(tb, ln, gr); - if (rc) - break; - } - - DBG(LINE, ul_debugobj(ln, " <- active groups updated [rc=%d]", rc)); - return rc; -} - -int scols_groups_update_grpset(struct libscols_table *tb, struct libscols_line *ln) -{ - int rc = 0; - - DBG(LINE, ul_debugobj(ln, " grpset update [line: group=%p, parent_group=%p", - ln->group, ln->parent_group)); - - rc = grpset_update_active_groups(tb, ln); - if (!rc && ln->group && ln->group->state == SCOLS_GSTATE_NONE) { - DBG(LINE, ul_debugobj(ln, " introduce a new group")); - rc = grpset_update(tb, ln, ln->group); - } - return rc; -} - -void scols_groups_reset_state(struct libscols_table *tb) -{ - struct libscols_iter itr; - struct libscols_group *gr; - - DBG(TAB, ul_debugobj(tb, "reset groups states")); - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_group(tb, &itr, &gr) == 0) { - DBG(GROUP, ul_debugobj(gr, " reset to NONE")); - gr->state = SCOLS_GSTATE_NONE; - } - - if (tb->grpset) { - DBG(TAB, ul_debugobj(tb, " zeroize grpset")); - memset(tb->grpset, 0, tb->grpset_size * sizeof(struct libscols_group *)); - } - tb->ngrpchlds_pending = 0; -} - -static void add_member(struct libscols_group *gr, struct libscols_line *ln) -{ - DBG(GROUP, ul_debugobj(gr, "add member %p", ln)); - - ln->group = gr; - gr->nmembers++; - scols_ref_group(gr); - - INIT_LIST_HEAD(&ln->ln_groups); - list_add_tail(&ln->ln_groups, &gr->gr_members); - scols_ref_line(ln); -} - -/* - * Returns first group which is ready to print group children. - * - * This function scans grpset[] in backward order and returns first group - * with SCOLS_GSTATE_CONT_CHILDREN or SCOLS_GSTATE_LAST_MEMBER state. - */ -struct libscols_group *scols_grpset_get_printable_children(struct libscols_table *tb) -{ - size_t i; - - for (i = tb->grpset_size; i > 0; i -= SCOLS_GRPSET_CHUNKSIZ) { - struct libscols_group *gr = tb->grpset[i-1]; - - if (gr == NULL) - continue; - if (gr->state == SCOLS_GSTATE_CONT_CHILDREN || - gr->state == SCOLS_GSTATE_LAST_MEMBER) - return gr; - } - - return NULL; -} - - -/** - * scols_table_group_lines: - * @tb: a pointer to a struct libscols_table instance - * @ln: new group member - * @member: group member - * @id: group identifier (unused, not implemented yet), use zero. - * - * This function add line @ln to group of lines represented by @member. If the - * group is not yet defined (@member is not member of any group) than a new one - * is allocated. - * - * The @ln maybe a NULL -- in this case only a new group is allocated if not - * defined yet. - * - * Note that the same line cannot be member of more groups (not implemented - * yet). The child of any group can be member of another group. - * - * The @id is not used for now, use 0. The plan is to use it to support - * multi-group membership in future. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_table_group_lines( struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_line *member, - __attribute__((__unused__)) int id) -{ - struct libscols_group *gr = NULL; - - if (!tb || !member) { - DBG(GROUP, ul_debugobj(gr, "failed group lines (no table or member)")); - return -EINVAL; - } - if (ln) { - if (ln->group && !member->group) { - DBG(GROUP, ul_debugobj(gr, "failed group lines (new group, line member of another)")); - return -EINVAL; - } - if (ln->group && member->group && ln->group != member->group) { - DBG(GROUP, ul_debugobj(gr, "failed group lines (groups mismatch bwteen member and line")); - return -EINVAL; - } - } - - gr = member->group; - - /* create a new group */ - if (!gr) { - gr = calloc(1, sizeof(*gr)); - if (!gr) - return -ENOMEM; - DBG(GROUP, ul_debugobj(gr, "alloc")); - gr->refcount = 1; - INIT_LIST_HEAD(&gr->gr_members); - INIT_LIST_HEAD(&gr->gr_children); - INIT_LIST_HEAD(&gr->gr_groups); - - /* add group to the table */ - list_add_tail(&gr->gr_groups, &tb->tb_groups); - - /* add the first member */ - add_member(gr, member); - } - - /* add to group */ - if (ln && !ln->group) - add_member(gr, ln); - - return 0; -} - -/** - * scols_line_link_group: - * @ln: line instance - * @member: group member - * @id: group identifier (unused, not implemented yet)) - * - * Define @ln as child of group represented by group @member. The line @ln - * cannot be child of any other line. It's possible to create group->child or - * parent->child relationship, but no both for the same line (child). - * - * The @id is not used for now, use 0. The plan is to use it to support - * multi-group membership in future. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_line_link_group(struct libscols_line *ln, struct libscols_line *member, - __attribute__((__unused__)) int id) -{ - if (!ln || !member || !member->group || ln->parent) - return -EINVAL; - - if (!list_empty(&ln->ln_children)) - return -EINVAL; - - DBG(GROUP, ul_debugobj(member->group, "add child")); - - list_add_tail(&ln->ln_children, &member->group->gr_children); - scols_ref_line(ln); - - ln->parent_group = member->group; - scols_ref_group(member->group); - - return 0; -} diff --git a/utils/libsmartcols/src/init.c b/utils/libsmartcols/src/init.c deleted file mode 100644 index dfd7510..0000000 --- a/utils/libsmartcols/src/init.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: init - * @title: Library initialization - * @short_description: initialize debugging - * - * The library debug stuff. - */ - -#include <stdarg.h> - -#include "smartcolsP.h" - -UL_DEBUG_DEFINE_MASK(libsmartcols); -UL_DEBUG_DEFINE_MASKNAMES(libsmartcols) = -{ - { "all", SCOLS_DEBUG_ALL, "info about all subsystems" }, - { "buff", SCOLS_DEBUG_BUFF, "output buffer utils" }, - { "cell", SCOLS_DEBUG_CELL, "table cell utils" }, - { "col", SCOLS_DEBUG_COL, "cols utils" }, - { "help", SCOLS_DEBUG_HELP, "this help" }, - { "group", SCOLS_DEBUG_GROUP, "lines grouping utils" }, - { "line", SCOLS_DEBUG_LINE, "table line utils" }, - { "tab", SCOLS_DEBUG_TAB, "table utils" }, - { NULL, 0, NULL } -}; - -/** - * scols_init_debug: - * @mask: debug mask (0xffff to enable full debugging) - * - * If the @mask is not specified, then this function reads - * the LIBSMARTCOLS_DEBUG environment variable to get the mask. - * - * Already initialized debugging stuff cannot be changed. Calling - * this function twice has no effect. - */ -void scols_init_debug(int mask) -{ - if (libsmartcols_debug_mask) - return; - - __UL_INIT_DEBUG_FROM_ENV(libsmartcols, SCOLS_DEBUG_, mask, LIBSMARTCOLS_DEBUG); - - if (libsmartcols_debug_mask != SCOLS_DEBUG_INIT - && libsmartcols_debug_mask != (SCOLS_DEBUG_HELP|SCOLS_DEBUG_INIT)) { - const char *ver = NULL; - - scols_get_library_version(&ver); - - DBG(INIT, ul_debug("library debug mask: 0x%04x", libsmartcols_debug_mask)); - DBG(INIT, ul_debug("library version: %s", ver)); - } - ON_DBG(HELP, ul_debug_print_masks("LIBSMARTCOLS_DEBUG", - UL_DEBUG_MASKNAMES(libsmartcols))); -} diff --git a/utils/libsmartcols/src/iter.c b/utils/libsmartcols/src/iter.c deleted file mode 100644 index 91cc080..0000000 --- a/utils/libsmartcols/src/iter.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2009-2014 Karel Zak <kzak@redhat.com> - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: iter - * @title: Iterator - * @short_description: unified iterator - * - * The iterator keeps the direction and the last position - * for access to the internal library tables/lists. - */ - -#include <string.h> -#include <stdlib.h> - -#include "smartcolsP.h" - -/** - * scols_new_iter: - * @direction: SCOLS_INTER_{FOR,BACK}WARD direction - * - * Returns: newly allocated generic libmount iterator. - */ -struct libscols_iter *scols_new_iter(int direction) -{ - struct libscols_iter *itr = calloc(1, sizeof(*itr)); - if (!itr) - return NULL; - itr->direction = direction; - return itr; -} - -/** - * scols_free_iter: - * @itr: iterator pointer - * - * Deallocates the iterator. - */ -void scols_free_iter(struct libscols_iter *itr) -{ - free(itr); -} - -/** - * scols_reset_iter: - * @itr: iterator pointer - * @direction: SCOLS_INTER_{FOR,BACK}WARD or -1 to keep the direction unchanged - * - * Resets the iterator. - */ -void scols_reset_iter(struct libscols_iter *itr, int direction) -{ - if (direction == -1) - direction = itr->direction; - - memset(itr, 0, sizeof(*itr)); - itr->direction = direction; -} - -/** - * scols_iter_get_direction: - * @itr: iterator pointer - * - * Returns: SCOLS_INTER_{FOR,BACK}WARD - */ -int scols_iter_get_direction(const struct libscols_iter *itr) -{ - return itr->direction; -} diff --git a/utils/libsmartcols/src/libsmartcols.h b/utils/libsmartcols/src/libsmartcols.h deleted file mode 100644 index 5714bfa..0000000 --- a/utils/libsmartcols/src/libsmartcols.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Prints table or tree. - * - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#ifndef _LIBSMARTCOLS_H -#define _LIBSMARTCOLS_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdlib.h> -#include <stdio.h> -#include <sys/types.h> - -/** - * libscols_iter: - * - * Generic iterator - */ -struct libscols_iter; - -/** - * libscols_symbols: - * - * Symbol groups for printing tree hierarchies - */ -struct libscols_symbols; - -/** - * libscols_cell: - * - * A cell - the smallest library object - */ -struct libscols_cell; - -/** - * libscols_line: - * - * A line - an array of cells - */ -struct libscols_line; - -/** - * libscols_table: - * - * A table - The most abstract object, encapsulating lines, columns, symbols and cells - */ -struct libscols_table; - -/** - * libscols_column: - * - * A column - defines the number of columns and column names - */ -struct libscols_column; - -/* iter.c */ -enum { - - SCOLS_ITER_FORWARD = 0, - SCOLS_ITER_BACKWARD -}; - -/* - * Column flags - */ -enum { - SCOLS_FL_TRUNC = (1 << 0), /* truncate fields data if necessary */ - SCOLS_FL_TREE = (1 << 1), /* use tree "ascii art" */ - SCOLS_FL_RIGHT = (1 << 2), /* align to the right */ - SCOLS_FL_STRICTWIDTH = (1 << 3), /* don't reduce width if column is empty */ - SCOLS_FL_NOEXTREMES = (1 << 4), /* ignore extreme fields when count column width*/ - SCOLS_FL_HIDDEN = (1 << 5), /* maintain data, but don't print */ - SCOLS_FL_WRAP = (1 << 6) /* wrap long lines to multi-line cells */ -}; - -/* - * Column JSON types - */ -enum { - SCOLS_JSON_STRING = 0, /* default */ - SCOLS_JSON_NUMBER = 1, - SCOLS_JSON_BOOLEAN = 2 -}; - -/* - * Cell flags, see scols_cell_set_flags() before use - */ -enum { - /* alignment evaluated in order: right,center,left */ - SCOLS_CELL_FL_LEFT = 0, - SCOLS_CELL_FL_CENTER = (1 << 0), - SCOLS_CELL_FL_RIGHT = (1 << 1) -}; - -extern struct libscols_iter *scols_new_iter(int direction); -extern void scols_free_iter(struct libscols_iter *itr); -extern void scols_reset_iter(struct libscols_iter *itr, int direction); -extern int scols_iter_get_direction(const struct libscols_iter *itr); - -/* init.c */ -extern void scols_init_debug(int mask); - -/* version.c */ -extern int scols_parse_version_string(const char *ver_string); -extern int scols_get_library_version(const char **ver_string); - -/* symbols.c */ -extern struct libscols_symbols *scols_new_symbols(void); -extern void scols_ref_symbols(struct libscols_symbols *sy); -extern void scols_unref_symbols(struct libscols_symbols *sy); -extern struct libscols_symbols *scols_copy_symbols(const struct libscols_symbols *sy); -extern int scols_symbols_set_branch(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_vertical(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_right(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_title_padding(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_cell_padding(struct libscols_symbols *sy, const char *str); - -extern int scols_symbols_set_group_vertical(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_group_horizontal(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_group_first_member(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_group_last_member(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_group_middle_member(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_group_last_child(struct libscols_symbols *sy, const char *str); -extern int scols_symbols_set_group_middle_child(struct libscols_symbols *sy, const char *str); - -/* cell.c */ -extern int scols_reset_cell(struct libscols_cell *ce); -extern int scols_cell_copy_content(struct libscols_cell *dest, - const struct libscols_cell *src); -extern int scols_cell_set_data(struct libscols_cell *ce, const char *data); -extern int scols_cell_refer_data(struct libscols_cell *ce, char *data); -extern const char *scols_cell_get_data(const struct libscols_cell *ce); -extern int scols_cell_set_color(struct libscols_cell *ce, const char *color); -extern const char *scols_cell_get_color(const struct libscols_cell *ce); - -extern int scols_cell_set_flags(struct libscols_cell *ce, int flags); -extern int scols_cell_get_flags(const struct libscols_cell *ce); -extern int scols_cell_get_alignment(const struct libscols_cell *ce); - -extern void *scols_cell_get_userdata(struct libscols_cell *ce); -extern int scols_cell_set_userdata(struct libscols_cell *ce, void *data); - -extern int scols_cmpstr_cells(struct libscols_cell *a, - struct libscols_cell *b, void *data); -/* column.c */ -extern int scols_column_is_tree(const struct libscols_column *cl); -extern int scols_column_is_trunc(const struct libscols_column *cl); -extern int scols_column_is_right(const struct libscols_column *cl); -extern int scols_column_is_strict_width(const struct libscols_column *cl); -extern int scols_column_is_hidden(const struct libscols_column *cl); -extern int scols_column_is_noextremes(const struct libscols_column *cl); -extern int scols_column_is_wrap(const struct libscols_column *cl); -extern int scols_column_is_customwrap(const struct libscols_column *cl); - -extern size_t scols_column_get_width(const struct libscols_column *cl); - -extern int scols_column_set_safechars(struct libscols_column *cl, const char *safe); -extern const char *scols_column_get_safechars(const struct libscols_column *cl); - -extern int scols_column_set_json_type(struct libscols_column *cl, int type); -extern int scols_column_get_json_type(const struct libscols_column *cl); - -extern int scols_column_set_flags(struct libscols_column *cl, int flags); -extern int scols_column_get_flags(const struct libscols_column *cl); -extern struct libscols_column *scols_new_column(void); -extern void scols_ref_column(struct libscols_column *cl); -extern void scols_unref_column(struct libscols_column *cl); -extern struct libscols_column *scols_copy_column(const struct libscols_column *cl); -extern int scols_column_set_whint(struct libscols_column *cl, double whint); -extern double scols_column_get_whint(const struct libscols_column *cl); -extern struct libscols_cell *scols_column_get_header(struct libscols_column *cl); -extern int scols_column_set_color(struct libscols_column *cl, const char *color); -extern const char *scols_column_get_color(const struct libscols_column *cl); -extern struct libscols_table *scols_column_get_table(const struct libscols_column *cl); - -extern int scols_column_set_cmpfunc(struct libscols_column *cl, - int (*cmp)(struct libscols_cell *a, - struct libscols_cell *b, void *), - void *data); - -extern int scols_column_set_wrapfunc(struct libscols_column *cl, - size_t (*wrap_chunksize)(const struct libscols_column *, - const char *, void *), - char * (*wrap_nextchunk)(const struct libscols_column *, - char *, void *), - void *userdata); - -extern char *scols_wrapnl_nextchunk(const struct libscols_column *cl, char *data, void *userdata); -extern size_t scols_wrapnl_chunksize(const struct libscols_column *cl, const char *data, void *userdata); - -/* line.c */ -extern struct libscols_line *scols_new_line(void); -extern void scols_ref_line(struct libscols_line *ln); -extern void scols_unref_line(struct libscols_line *ln); -extern int scols_line_alloc_cells(struct libscols_line *ln, size_t n); -extern void scols_line_free_cells(struct libscols_line *ln); -extern int scols_line_set_userdata(struct libscols_line *ln, void *data); -extern void *scols_line_get_userdata(struct libscols_line *ln); -extern int scols_line_remove_child(struct libscols_line *ln, struct libscols_line *child); -extern int scols_line_add_child(struct libscols_line *ln, struct libscols_line *child); -extern int scols_line_has_children(struct libscols_line *ln); -extern int scols_line_is_ancestor(struct libscols_line *ln, struct libscols_line *parent); -extern int scols_line_next_child(struct libscols_line *ln, - struct libscols_iter *itr, struct libscols_line **chld); -extern struct libscols_line *scols_line_get_parent(const struct libscols_line *ln); -extern int scols_line_set_color(struct libscols_line *ln, const char *color); -extern const char *scols_line_get_color(const struct libscols_line *ln); -extern size_t scols_line_get_ncells(const struct libscols_line *ln); -extern struct libscols_cell *scols_line_get_cell(struct libscols_line *ln, size_t n); -extern struct libscols_cell *scols_line_get_column_cell( - struct libscols_line *ln, - struct libscols_column *cl); -extern int scols_line_set_data(struct libscols_line *ln, size_t n, const char *data); -extern int scols_line_refer_data(struct libscols_line *ln, size_t n, char *data); -extern int scols_line_set_column_data(struct libscols_line *ln, struct libscols_column *cl, const char *data); -extern int scols_line_refer_column_data(struct libscols_line *ln, struct libscols_column *cl, char *data); -extern struct libscols_line *scols_copy_line(const struct libscols_line *ln); - -/* table */ -extern int scols_table_colors_wanted(const struct libscols_table *tb); -extern int scols_table_set_name(struct libscols_table *tb, const char *name); -extern const char *scols_table_get_name(const struct libscols_table *tb); -extern struct libscols_cell *scols_table_get_title(struct libscols_table *tb); -extern int scols_table_is_raw(const struct libscols_table *tb); -extern int scols_table_is_ascii(const struct libscols_table *tb); -extern int scols_table_is_json(const struct libscols_table *tb); -extern int scols_table_is_noheadings(const struct libscols_table *tb); -extern int scols_table_is_header_repeat(const struct libscols_table *tb); -extern int scols_table_is_empty(const struct libscols_table *tb); -extern int scols_table_is_export(const struct libscols_table *tb); -extern int scols_table_is_maxout(const struct libscols_table *tb); -extern int scols_table_is_minout(const struct libscols_table *tb); -extern int scols_table_is_nowrap(const struct libscols_table *tb); -extern int scols_table_is_nolinesep(const struct libscols_table *tb); -extern int scols_table_is_tree(const struct libscols_table *tb); -extern int scols_table_is_noencoding(const struct libscols_table *tb); - -extern int scols_table_enable_colors(struct libscols_table *tb, int enable); -extern int scols_table_enable_raw(struct libscols_table *tb, int enable); -extern int scols_table_enable_ascii(struct libscols_table *tb, int enable); -extern int scols_table_enable_json(struct libscols_table *tb, int enable); -extern int scols_table_enable_noheadings(struct libscols_table *tb, int enable); -extern int scols_table_enable_header_repeat(struct libscols_table *tb, int enable); -extern int scols_table_enable_export(struct libscols_table *tb, int enable); -extern int scols_table_enable_maxout(struct libscols_table *tb, int enable); -extern int scols_table_enable_minout(struct libscols_table *tb, int enable); -extern int scols_table_enable_nowrap(struct libscols_table *tb, int enable); -extern int scols_table_enable_nolinesep(struct libscols_table *tb, int enable); -extern int scols_table_enable_noencoding(struct libscols_table *tb, int enable); - -extern int scols_table_set_column_separator(struct libscols_table *tb, const char *sep); -extern int scols_table_set_line_separator(struct libscols_table *tb, const char *sep); - -extern struct libscols_table *scols_new_table(void); -extern void scols_ref_table(struct libscols_table *tb); -extern void scols_unref_table(struct libscols_table *tb); -extern int scols_table_add_column(struct libscols_table *tb, struct libscols_column *cl); -extern int scols_table_remove_column(struct libscols_table *tb, struct libscols_column *cl); -extern int scols_table_remove_columns(struct libscols_table *tb); -extern int scols_table_move_column(struct libscols_table *tb, struct libscols_column *pre, struct libscols_column *cl); -extern struct libscols_column *scols_table_new_column(struct libscols_table *tb, const char *name, double whint, int flags); -extern int scols_table_next_column(struct libscols_table *tb, struct libscols_iter *itr, struct libscols_column **cl); -extern int scols_table_set_columns_iter(struct libscols_table *tb, struct libscols_iter *itr, struct libscols_column *cl); -extern const char *scols_table_get_column_separator(const struct libscols_table *tb); -extern const char *scols_table_get_line_separator(const struct libscols_table *tb); -extern size_t scols_table_get_ncols(const struct libscols_table *tb); -extern size_t scols_table_get_nlines(const struct libscols_table *tb); -extern struct libscols_column *scols_table_get_column(struct libscols_table *tb, size_t n); -extern int scols_table_add_line(struct libscols_table *tb, struct libscols_line *ln); -extern int scols_table_remove_line(struct libscols_table *tb, struct libscols_line *ln); -extern void scols_table_remove_lines(struct libscols_table *tb); -extern int scols_table_next_line(struct libscols_table *tb, struct libscols_iter *itr, struct libscols_line **ln); -extern struct libscols_line *scols_table_new_line(struct libscols_table *tb, struct libscols_line *parent); -extern struct libscols_line *scols_table_get_line(struct libscols_table *tb, size_t n); -extern struct libscols_table *scols_copy_table(struct libscols_table *tb); -extern int scols_table_set_symbols(struct libscols_table *tb, struct libscols_symbols *sy); -extern int scols_table_set_default_symbols(struct libscols_table *tb); -extern struct libscols_symbols *scols_table_get_symbols(const struct libscols_table *tb); - -extern int scols_table_set_stream(struct libscols_table *tb, FILE *stream); -extern FILE *scols_table_get_stream(const struct libscols_table *tb); -extern int scols_table_reduce_termwidth(struct libscols_table *tb, size_t reduce); - -extern int scols_sort_table(struct libscols_table *tb, struct libscols_column *cl); -extern int scols_sort_table_by_tree(struct libscols_table *tb); -/* - * - */ -enum { - SCOLS_TERMFORCE_AUTO = 0, - SCOLS_TERMFORCE_NEVER, - SCOLS_TERMFORCE_ALWAYS -}; -extern int scols_table_set_termforce(struct libscols_table *tb, int force); -extern int scols_table_get_termforce(const struct libscols_table *tb); -extern int scols_table_set_termwidth(struct libscols_table *tb, size_t width); -extern size_t scols_table_get_termwidth(const struct libscols_table *tb); -extern int scols_table_set_termheight(struct libscols_table *tb, size_t height); -extern size_t scols_table_get_termheight(const struct libscols_table *tb); - - -/* table_print.c */ -extern int scols_print_table(struct libscols_table *tb); -extern int scols_print_table_to_string(struct libscols_table *tb, char **data); - -extern int scols_table_print_range( struct libscols_table *tb, - struct libscols_line *start, - struct libscols_line *end); -extern int scols_table_print_range_to_string( struct libscols_table *tb, - struct libscols_line *start, - struct libscols_line *end, - char **data); - -/* grouping.c */ -int scols_line_link_group(struct libscols_line *ln, struct libscols_line *member, int id); -int scols_table_group_lines(struct libscols_table *tb, struct libscols_line *ln, - struct libscols_line *member, int id); -#ifdef __cplusplus -} -#endif - -#endif /* _LIBSMARTCOLS_H */ diff --git a/utils/libsmartcols/src/line.c b/utils/libsmartcols/src/line.c deleted file mode 100644 index 351bed7..0000000 --- a/utils/libsmartcols/src/line.c +++ /dev/null @@ -1,540 +0,0 @@ -/* - * line.c - functions for table handling at the line level - * - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: line - * @title: Line - * @short_description: cells container, also keeps tree (parent->child) information - * - * An API to access and modify per-line data and information. - */ - - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> - -#include "smartcolsP.h" - -/** - * scols_new_line: - * - * Note that the line is allocated without cells, the cells will be allocated - * later when you add the line to the table. If you want to use the line - * without table then you have to explicitly allocate the cells by - * scols_line_alloc_cells(). - * - * Returns: a pointer to a new struct libscols_line instance. - */ -struct libscols_line *scols_new_line(void) -{ - struct libscols_line *ln; - - ln = calloc(1, sizeof(*ln)); - if (!ln) - return NULL; - - DBG(LINE, ul_debugobj(ln, "alloc")); - ln->refcount = 1; - INIT_LIST_HEAD(&ln->ln_lines); - INIT_LIST_HEAD(&ln->ln_children); - INIT_LIST_HEAD(&ln->ln_branch); - INIT_LIST_HEAD(&ln->ln_groups); - return ln; -} - -/** - * scols_ref_line: - * @ln: a pointer to a struct libscols_line instance - * - * Increases the refcount of @ln. - */ -void scols_ref_line(struct libscols_line *ln) -{ - if (ln) - ln->refcount++; -} - -/** - * scols_unref_line: - * @ln: a pointer to a struct libscols_line instance - * - * Decreases the refcount of @ln. When the count falls to zero, the instance - * is automatically deallocated. - */ -void scols_unref_line(struct libscols_line *ln) -{ - if (ln && --ln->refcount <= 0) { - DBG(CELL, ul_debugobj(ln, "dealloc")); - list_del(&ln->ln_lines); - list_del(&ln->ln_children); - list_del(&ln->ln_groups); - scols_unref_group(ln->group); - scols_line_free_cells(ln); - free(ln->color); - free(ln); - return; - } -} - -/** - * scols_line_free_cells: - * @ln: a pointer to a struct libscols_line instance - * - * Frees the allocated cells referenced to by @ln. - */ -void scols_line_free_cells(struct libscols_line *ln) -{ - size_t i; - - if (!ln || !ln->cells) - return; - - DBG(LINE, ul_debugobj(ln, "free cells")); - - for (i = 0; i < ln->ncells; i++) - scols_reset_cell(&ln->cells[i]); - - free(ln->cells); - ln->ncells = 0; - ln->cells = NULL; -} - -/** - * scols_line_alloc_cells: - * @ln: a pointer to a struct libscols_line instance - * @n: the number of elements - * - * Allocates space for @n cells. This function is optional, - * and libsmartcols automatically allocates necessary cells - * according to number of columns in the table when you add - * the line to the table. See scols_table_add_line(). - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_alloc_cells(struct libscols_line *ln, size_t n) -{ - struct libscols_cell *ce; - - if (!ln) - return -EINVAL; - if (ln->ncells == n) - return 0; - - if (!n) { - scols_line_free_cells(ln); - return 0; - } - - DBG(LINE, ul_debugobj(ln, "alloc %zu cells", n)); - - ce = realloc(ln->cells, n * sizeof(struct libscols_cell)); - if (!ce) - return -errno; - - if (n > ln->ncells) - memset(ce + ln->ncells, 0, - (n - ln->ncells) * sizeof(struct libscols_cell)); - - ln->cells = ce; - ln->ncells = n; - return 0; -} - -int scols_line_move_cells(struct libscols_line *ln, size_t newn, size_t oldn) -{ - struct libscols_cell ce; - - if (!ln || newn >= ln->ncells || oldn >= ln->ncells) - return -EINVAL; - if (oldn == newn) - return 0; - - DBG(LINE, ul_debugobj(ln, "move cells[%zu] -> cells[%zu]", oldn, newn)); - - /* remember data from old position */ - memcpy(&ce, &ln->cells[oldn], sizeof(struct libscols_cell)); - - /* remove old position (move data behind oldn to oldn) */ - if (oldn + 1 < ln->ncells) - memmove(ln->cells + oldn, ln->cells + oldn + 1, - (ln->ncells - oldn - 1) * sizeof(struct libscols_cell)); - - /* create a space for new position */ - if (newn + 1 < ln->ncells) - memmove(ln->cells + newn + 1, ln->cells + newn, - (ln->ncells - newn - 1) * sizeof(struct libscols_cell)); - - /* copy original data to new position */ - memcpy(&ln->cells[newn], &ce, sizeof(struct libscols_cell)); - return 0; -} - -/** - * scols_line_set_userdata: - * @ln: a pointer to a struct libscols_line instance - * @data: user data - * - * Binds @data to @ln. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_set_userdata(struct libscols_line *ln, void *data) -{ - if (!ln) - return -EINVAL; - ln->userdata = data; - return 0; -} - -/** - * scols_line_get_userdata: - * @ln: a pointer to a struct libscols_line instance - * - * Returns: user data - */ -void *scols_line_get_userdata(struct libscols_line *ln) -{ - return ln->userdata; -} - -/** - * scols_line_remove_child: - * @ln: a pointer to a struct libscols_line instance - * @child: a pointer to a struct libscols_line instance - * - * Removes @child as a child of @ln. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_remove_child(struct libscols_line *ln, struct libscols_line *child) -{ - if (!ln || !child) - return -EINVAL; - - DBG(LINE, ul_debugobj(ln, "remove child")); - - list_del_init(&child->ln_children); - child->parent = NULL; - scols_unref_line(child); - - scols_unref_line(ln); - return 0; -} - -/** - * scols_line_add_child: - * @ln: a pointer to a struct libscols_line instance - * @child: a pointer to a struct libscols_line instance - * - * Sets @child as a child of @ln. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_add_child(struct libscols_line *ln, struct libscols_line *child) -{ - if (!ln || !child) - return -EINVAL; - - DBG(LINE, ul_debugobj(ln, "add child")); - scols_ref_line(child); - scols_ref_line(ln); - - /* unref old<->parent */ - if (child->parent) - scols_line_remove_child(child->parent, child); - - /* new reference from parent to child */ - list_add_tail(&child->ln_children, &ln->ln_branch); - - /* new reference from child to parent */ - child->parent = ln; - return 0; -} - -/** - * scols_line_get_parent: - * @ln: a pointer to a struct libscols_line instance - * - * Returns: a pointer to @ln's parent, NULL in case it has no parent or if there was an error. - */ -struct libscols_line *scols_line_get_parent(const struct libscols_line *ln) -{ - return ln ? ln->parent : NULL; -} - -/** - * scols_line_has_children: - * @ln: a pointer to a struct libscols_line instance - * - * Returns: 1 if @ln has any children, otherwise 0. - */ -int scols_line_has_children(struct libscols_line *ln) -{ - return ln ? !list_empty(&ln->ln_branch) : 0; -} - -/** - * scols_line_next_child: - * @ln: a pointer to a struct libscols_line instance - * @itr: a pointer to a struct libscols_iter instance - * @chld: a pointer to a pointer to a struct libscols_line instance - * - * Finds the next child and returns a pointer to it via @chld. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_next_child(struct libscols_line *ln, - struct libscols_iter *itr, - struct libscols_line **chld) -{ - int rc = 1; - - if (!ln || !itr || !chld) - return -EINVAL; - *chld = NULL; - - if (!itr->head) - SCOLS_ITER_INIT(itr, &ln->ln_branch); - if (itr->p != itr->head) { - SCOLS_ITER_ITERATE(itr, *chld, struct libscols_line, ln_children); - rc = 0; - } - - return rc; -} - -/* private API */ -int scols_line_next_group_child(struct libscols_line *ln, - struct libscols_iter *itr, - struct libscols_line **chld) -{ - int rc = 1; - - if (!ln || !itr || !chld || !ln->group) - return -EINVAL; - *chld = NULL; - - if (!itr->head) - SCOLS_ITER_INIT(itr, &ln->group->gr_children); - if (itr->p != itr->head) { - SCOLS_ITER_ITERATE(itr, *chld, struct libscols_line, ln_children); - rc = 0; - } - - return rc; -} - -/** - * scols_line_is_ancestor: - * @ln: line - * @parent: potential parent - * - * The function is designed to detect circular dependencies between @ln and - * @parent. It checks if @ln is not any (grand) parent in the @parent's tree. - * - * Since: 2.30 - * - * Returns: 0 or 1 - */ -int scols_line_is_ancestor(struct libscols_line *ln, struct libscols_line *parent) -{ - while (parent) { - if (parent == ln) - return 1; - parent = scols_line_get_parent(parent); - }; - return 0; -} - -/** - * scols_line_set_color: - * @ln: a pointer to a struct libscols_line instance - * @color: color name or ESC sequence - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_set_color(struct libscols_line *ln, const char *color) -{ - if (color && isalnum(*color)) { - color = color_sequence_from_colorname(color); - if (!color) - return -EINVAL; - } - return strdup_to_struct_member(ln, color, color); -} - -/** - * scols_line_get_color: - * @ln: a pointer to a struct libscols_line instance - * - * Returns: @ln's color string, NULL in case of an error. - */ -const char *scols_line_get_color(const struct libscols_line *ln) -{ - return ln->color; -} - -/** - * scols_line_get_ncells: - * @ln: a pointer to a struct libscols_line instance - * - * Returns: number of cells - */ -size_t scols_line_get_ncells(const struct libscols_line *ln) -{ - return ln->ncells; -} - -/** - * scols_line_get_cell: - * @ln: a pointer to a struct libscols_line instance - * @n: cell number to retrieve - * - * Returns: the @n-th cell in @ln, NULL in case of an error. - */ -struct libscols_cell *scols_line_get_cell(struct libscols_line *ln, - size_t n) -{ - if (!ln || n >= ln->ncells) - return NULL; - return &ln->cells[n]; -} - -/** - * scols_line_get_column_cell: - * @ln: a pointer to a struct libscols_line instance - * @cl: pointer to cell - * - * Like scols_line_get_cell() by cell is referenced by column. - * - * Returns: the @n-th cell in @ln, NULL in case of an error. - */ -struct libscols_cell *scols_line_get_column_cell( - struct libscols_line *ln, - struct libscols_column *cl) -{ - if (!ln || !cl) - return NULL; - - return scols_line_get_cell(ln, cl->seqnum); -} - -/** - * scols_line_set_data: - * @ln: a pointer to a struct libscols_line instance - * @n: number of the cell, whose data is to be set - * @data: actual data to set - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_set_data(struct libscols_line *ln, size_t n, const char *data) -{ - struct libscols_cell *ce = scols_line_get_cell(ln, n); - - if (!ce) - return -EINVAL; - return scols_cell_set_data(ce, data); -} - -/** - * scols_line_set_column_data: - * @ln: a pointer to a struct libscols_line instance - * @cl: column, whose data is to be set - * @data: actual data to set - * - * The same as scols_line_set_data() but cell is referenced by column object. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.28 - */ -int scols_line_set_column_data(struct libscols_line *ln, - struct libscols_column *cl, - const char *data) -{ - return scols_line_set_data(ln, cl->seqnum, data); -} - -/** - * scols_line_refer_data: - * @ln: a pointer to a struct libscols_line instance - * @n: number of the cell which will refer to @data - * @data: actual data to refer to - * - * Returns: 0, a negative value in case of an error. - */ -int scols_line_refer_data(struct libscols_line *ln, size_t n, char *data) -{ - struct libscols_cell *ce = scols_line_get_cell(ln, n); - - if (!ce) - return -EINVAL; - return scols_cell_refer_data(ce, data); -} - -/** - * scols_line_refer_column_data: - * @ln: a pointer to a struct libscols_line instance - * @cl: column, whose data is to be set - * @data: actual data to refer to - * - * The same as scols_line_refer_data() but cell is referenced by column object. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.28 - */ -int scols_line_refer_column_data(struct libscols_line *ln, - struct libscols_column *cl, - char *data) -{ - return scols_line_refer_data(ln, cl->seqnum, data); -} - -/** - * scols_copy_line: - * @ln: a pointer to a struct libscols_line instance - * - * Returns: A newly allocated copy of @ln, NULL in case of an error. - */ -struct libscols_line *scols_copy_line(const struct libscols_line *ln) -{ - struct libscols_line *ret; - size_t i; - - if (!ln) - return NULL; - - ret = scols_new_line(); - if (!ret) - return NULL; - if (scols_line_set_color(ret, ln->color)) - goto err; - if (scols_line_alloc_cells(ret, ln->ncells)) - goto err; - - ret->userdata = ln->userdata; - ret->ncells = ln->ncells; - ret->seqnum = ln->seqnum; - - DBG(LINE, ul_debugobj(ln, "copy")); - - for (i = 0; i < ret->ncells; ++i) { - if (scols_cell_copy_content(&ret->cells[i], &ln->cells[i])) - goto err; - } - - return ret; -err: - scols_unref_line(ret); - return NULL; -} diff --git a/utils/libsmartcols/src/print-api.c b/utils/libsmartcols/src/print-api.c deleted file mode 100644 index 9a9f2df..0000000 --- a/utils/libsmartcols/src/print-api.c +++ /dev/null @@ -1,211 +0,0 @@ -#include "smartcolsP.h" - -/** - * scola_table_print_range: - * @tb: table - * @start: first printed line or NULL to print from the begin of the table - * @end: last printed line or NULL to print all from start. - * - * If the start is the first line in the table than prints table header too. - * The header is printed only once. This does not work for trees. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_print_range( struct libscols_table *tb, - struct libscols_line *start, - struct libscols_line *end) -{ - struct libscols_buffer *buf = NULL; - struct libscols_iter itr; - int rc; - - if (scols_table_is_tree(tb)) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "printing range from API")); - - rc = __scols_initialize_printing(tb, &buf); - if (rc) - return rc; - - if (start) { - itr.direction = SCOLS_ITER_FORWARD; - itr.head = &tb->tb_lines; - itr.p = &start->ln_lines; - } else - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - - if (!start || itr.p == tb->tb_lines.next) { - rc = __scols_print_header(tb, buf); - if (rc) - goto done; - } - - rc = __scols_print_range(tb, buf, &itr, end); -done: - __scols_cleanup_printing(tb, buf); - return rc; -} - -/** - * scols_table_print_range_to_string: - * @tb: table - * @start: first printed line or NULL to print from the beginning of the table - * @end: last printed line or NULL to print all from start. - * @data: pointer to the beginning of a memory area to print to - * - * The same as scols_table_print_range(), but prints to @data instead of - * stream. - * - * Returns: 0, a negative value in case of an error. - */ -#ifdef HAVE_OPEN_MEMSTREAM -int scols_table_print_range_to_string( struct libscols_table *tb, - struct libscols_line *start, - struct libscols_line *end, - char **data) -{ - FILE *stream, *old_stream; - size_t sz; - int rc; - - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "printing range to string")); - - /* create a stream for output */ - stream = open_memstream(data, &sz); - if (!stream) - return -ENOMEM; - - old_stream = scols_table_get_stream(tb); - scols_table_set_stream(tb, stream); - rc = scols_table_print_range(tb, start, end); - fclose(stream); - scols_table_set_stream(tb, old_stream); - - return rc; -} -#else -int scols_table_print_range_to_string( - struct libscols_table *tb __attribute__((__unused__)), - struct libscols_line *start __attribute__((__unused__)), - struct libscols_line *end __attribute__((__unused__)), - char **data __attribute__((__unused__))) -{ - return -ENOSYS; -} -#endif - -static int do_print_table(struct libscols_table *tb, int *is_empty) -{ - int rc = 0; - struct libscols_buffer *buf = NULL; - - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "printing")); - if (is_empty) - *is_empty = 0; - - if (list_empty(&tb->tb_columns)) { - DBG(TAB, ul_debugobj(tb, "error -- no columns")); - return -EINVAL; - } - if (list_empty(&tb->tb_lines)) { - DBG(TAB, ul_debugobj(tb, "ignore -- no lines")); - if (scols_table_is_json(tb)) { - fput_table_open(tb); - fput_table_close(tb); - } else if (is_empty) - *is_empty = 1; - return 0; - } - - tb->header_printed = 0; - rc = __scols_initialize_printing(tb, &buf); - if (rc) - return rc; - - fput_table_open(tb); - - if (tb->format == SCOLS_FMT_HUMAN) - __scols_print_title(tb); - - rc = __scols_print_header(tb, buf); - if (rc) - goto done; - - if (scols_table_is_tree(tb)) - rc = __scols_print_tree(tb, buf); - else - rc = __scols_print_table(tb, buf); - - fput_table_close(tb); -done: - __scols_cleanup_printing(tb, buf); - return rc; -} - -/** - * scols_print_table: - * @tb: table - * - * Prints the table to the output stream and terminate by \n. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_print_table(struct libscols_table *tb) -{ - int empty = 0; - int rc = do_print_table(tb, &empty); - - if (rc == 0 && !empty) - fputc('\n', tb->out); - return rc; -} - -/** - * scols_print_table_to_string: - * @tb: table - * @data: pointer to the beginning of a memory area to print to - * - * Prints the table to @data. - * - * Returns: 0, a negative value in case of an error. - */ -#ifdef HAVE_OPEN_MEMSTREAM -int scols_print_table_to_string(struct libscols_table *tb, char **data) -{ - FILE *stream, *old_stream; - size_t sz; - int rc; - - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "printing to string")); - - /* create a stream for output */ - stream = open_memstream(data, &sz); - if (!stream) - return -ENOMEM; - - old_stream = scols_table_get_stream(tb); - scols_table_set_stream(tb, stream); - rc = do_print_table(tb, NULL); - fclose(stream); - scols_table_set_stream(tb, old_stream); - - return rc; -} -#else -int scols_print_table_to_string( - struct libscols_table *tb __attribute__((__unused__)), - char **data __attribute__((__unused__))) -{ - return -ENOSYS; -} -#endif diff --git a/utils/libsmartcols/src/print.c b/utils/libsmartcols/src/print.c deleted file mode 100644 index 1172533..0000000 --- a/utils/libsmartcols/src/print.c +++ /dev/null @@ -1,1089 +0,0 @@ -/* - * table.c - functions handling the data at the table level - * - * Copyright (C) 2010-2014 Karel Zak <kzak@redhat.com> - * Copyright (C) 2016 Igor Gnatenko <i.gnatenko.brain@gmail.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: table_print - * @title: Table print - * @short_description: output functions - * - * Table output API. - */ - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <termios.h> -#include <ctype.h> - -#include "mbsalign.h" -#include "carefulputc.h" -#include "smartcolsP.h" - -/* Fallback for symbols - * - * Note that by default library define all the symbols, but in case user does - * not define all symbols or if we extended the symbols struct then we need - * fallback to be more robust and backwardly compatible. - */ -#define titlepadding_symbol(tb) ((tb)->symbols->title_padding ? (tb)->symbols->title_padding : " ") -#define branch_symbol(tb) ((tb)->symbols->tree_branch ? (tb)->symbols->tree_branch : "|-") -#define vertical_symbol(tb) ((tb)->symbols->tree_vert ? (tb)->symbols->tree_vert : "| ") -#define right_symbol(tb) ((tb)->symbols->tree_right ? (tb)->symbols->tree_right : "`-") - -#define grp_vertical_symbol(tb) ((tb)->symbols->group_vert ? (tb)->symbols->group_vert : "|") -#define grp_horizontal_symbol(tb) ((tb)->symbols->group_horz ? (tb)->symbols->group_horz : "-") -#define grp_m_first_symbol(tb) ((tb)->symbols->group_first_member ? (tb)->symbols->group_first_member : ",->") -#define grp_m_last_symbol(tb) ((tb)->symbols->group_last_member ? (tb)->symbols->group_last_member : "\\->") -#define grp_m_middle_symbol(tb) ((tb)->symbols->group_middle_member ? (tb)->symbols->group_middle_member : "|->") -#define grp_c_middle_symbol(tb) ((tb)->symbols->group_middle_child ? (tb)->symbols->group_middle_child : "|-") -#define grp_c_last_symbol(tb) ((tb)->symbols->group_last_child ? (tb)->symbols->group_last_child : "`-") - -#define cellpadding_symbol(tb) ((tb)->padding_debug ? "." : \ - ((tb)->symbols->cell_padding ? (tb)->symbols->cell_padding: " ")) - -#define want_repeat_header(tb) (!(tb)->header_repeat || (tb)->header_next <= (tb)->termlines_used) - -static int is_next_columns_empty( - struct libscols_table *tb, - struct libscols_column *cl, - struct libscols_line *ln) -{ - struct libscols_iter itr; - - if (!tb || !cl) - return 0; - if (is_last_column(cl)) - return 1; - if (!ln) - return 0; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - scols_table_set_columns_iter(tb, &itr, cl); - - /* skip current column */ - scols_table_next_column(tb, &itr, &cl); - - while (scols_table_next_column(tb, &itr, &cl) == 0) { - struct libscols_cell *ce; - const char *data = NULL; - - if (scols_column_is_hidden(cl)) - continue; - if (scols_column_is_tree(cl)) - return 0; - - ce = scols_line_get_cell(ln, cl->seqnum); - if (ce) - data = scols_cell_get_data(ce); - if (data && *data) - return 0; - } - return 1; -} - -/* returns pointer to the end of used data */ -static int tree_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 = tree_ascii_art_to_buffer(tb, ln->parent, buf); - if (rc) - return rc; - - if (is_last_child(ln)) - art = " "; - else - art = vertical_symbol(tb); - - return buffer_append_data(buf, art); -} - -static int grpset_is_empty( struct libscols_table *tb, - size_t idx, - size_t *rest) -{ - size_t i; - - for (i = idx; i < tb->grpset_size; i++) { - if (tb->grpset[i] == NULL) { - if (rest) - (*rest)++; - } else - return 0; - } - return 1; -} - -static int groups_ascii_art_to_buffer( struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_buffer *buf) -{ - int filled = 0; - size_t i, rest = 0; - const char *filler = cellpadding_symbol(tb); - - if (!has_groups(tb)) - return 0; - - DBG(LINE, ul_debugobj(ln, "printing groups chart")); - - if (tb->is_dummy_print) - return 0; /* allocate grpset[] only */ - - for (i = 0; i < tb->grpset_size; i += SCOLS_GRPSET_CHUNKSIZ) { - struct libscols_group *gr = tb->grpset[i]; - - if (!gr) { - buffer_append_ntimes(buf, SCOLS_GRPSET_CHUNKSIZ, cellpadding_symbol(tb)); - continue; - } - - switch (gr->state) { - case SCOLS_GSTATE_FIRST_MEMBER: - buffer_append_data(buf, grp_m_first_symbol(tb)); - break; - case SCOLS_GSTATE_MIDDLE_MEMBER: - buffer_append_data(buf, grp_m_middle_symbol(tb)); - break; - case SCOLS_GSTATE_LAST_MEMBER: - buffer_append_data(buf, grp_m_last_symbol(tb)); - break; - case SCOLS_GSTATE_CONT_MEMBERS: - buffer_append_data(buf, grp_vertical_symbol(tb)); - buffer_append_ntimes(buf, 2, filler); - break; - case SCOLS_GSTATE_MIDDLE_CHILD: - buffer_append_data(buf, filler); - buffer_append_data(buf, grp_c_middle_symbol(tb)); - if (grpset_is_empty(tb, i + SCOLS_GRPSET_CHUNKSIZ, &rest)) { - buffer_append_ntimes(buf, rest+1, grp_horizontal_symbol(tb)); - filled = 1; - } - filler = grp_horizontal_symbol(tb); - break; - case SCOLS_GSTATE_LAST_CHILD: - buffer_append_data(buf, cellpadding_symbol(tb)); - buffer_append_data(buf, grp_c_last_symbol(tb)); - if (grpset_is_empty(tb, i + SCOLS_GRPSET_CHUNKSIZ, &rest)) { - buffer_append_ntimes(buf, rest+1, grp_horizontal_symbol(tb)); - filled = 1; - } - filler = grp_horizontal_symbol(tb); - break; - case SCOLS_GSTATE_CONT_CHILDREN: - buffer_append_data(buf, filler); - buffer_append_data(buf, grp_vertical_symbol(tb)); - buffer_append_data(buf, filler); - break; - } - - if (filled) - break; - } - - if (!filled) - buffer_append_data(buf, filler); - return 0; -} - -static int has_pending_data(struct libscols_table *tb) -{ - struct libscols_column *cl; - struct libscols_iter itr; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &cl) == 0) { - if (scols_column_is_hidden(cl)) - continue; - if (cl->pending_data) - return 1; - } - return 0; -} - -/* print padding or ASCII-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 */ - - DBG(COL, ul_debugobj(cl, " printing empty cell")); - - /* generate tree ASCII-art rather than padding */ - if (ln && scols_column_is_tree(cl)) { - if (!ln->parent) { - /* only print symbols->vert if followed by child */ - if (!list_empty(&ln->ln_branch)) { - fputs(vertical_symbol(tb), tb->out); - len_pad = scols_table_is_noencoding(tb) ? - mbs_width(vertical_symbol(tb)) : - mbs_safe_width(vertical_symbol(tb)); - } - } 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 */ - tree_ascii_art_to_buffer(tb, ln, art); - if (!list_empty(&ln->ln_branch) && has_pending_data(tb)) - buffer_append_data(art, vertical_symbol(tb)); - data = buffer_get_safe_data(tb, art, &len_pad, NULL); - if (data && len_pad) - fputs(data, tb->out); - free_buffer(art); - } - } - } - - /* minout -- don't fill */ - if (scols_table_is_minout(tb) && is_next_columns_empty(tb, cl, ln)) - return; - - /* default -- fill except last column */ - if (!scols_table_is_maxout(tb) && is_last_column(cl)) - return; - - /* fill rest of cell with space */ - for(; len_pad < cl->width; ++len_pad) - fputs(cellpadding_symbol(tb), tb->out); - - if (!is_last_column(cl)) - fputs(colsep(tb), tb->out); -} - - -static const char *get_cell_color(struct libscols_table *tb, - struct libscols_column *cl, - struct libscols_line *ln, /* optional */ - struct libscols_cell *ce) /* optional */ -{ - const char *color = NULL; - - if (tb && tb->colors_wanted) { - if (ce) - color = ce->color; - if (ln && !color) - color = ln->color; - if (!color) - color = cl->color; - } - return color; -} - -/* Fill the start of a line with padding (or with tree ascii-art). - * - * This is necessary after a long non-truncated column, as this requires the - * next column to be printed on the 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 i; - - assert(tb); - assert(cl); - - DBG(LINE, ul_debugobj(ln, "printing newline padding")); - - fputs(linesep(tb), tb->out); /* line break */ - tb->termlines_used++; - - /* 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); -} - -/* - * Pending data - * - * The first line in the multi-line cells (columns with SCOLS_FL_WRAP flag) is - * printed as usually and output is truncated to match column width. - * - * The rest of the long text is printed on next extra line(s). The extra lines - * don't exist in the table (not represented by libscols_line). The data for - * the extra lines are stored in libscols_column->pending_data_buf and the - * function print_line() adds extra lines until the buffer is not empty in all - * columns. - */ - -/* set data that will be printed by extra lines */ -static int set_pending_data(struct libscols_column *cl, const char *data, size_t sz) -{ - char *p = NULL; - - if (data && *data) { - DBG(COL, ul_debugobj(cl, "setting pending data")); - assert(sz); - p = strdup(data); - if (!p) - return -ENOMEM; - } - - free(cl->pending_data_buf); - cl->pending_data_buf = p; - cl->pending_data_sz = sz; - cl->pending_data = cl->pending_data_buf; - return 0; -} - -/* the next extra line has been printed, move pending data cursor */ -static int step_pending_data(struct libscols_column *cl, size_t bytes) -{ - DBG(COL, ul_debugobj(cl, "step pending data %zu -= %zu", cl->pending_data_sz, bytes)); - - if (bytes >= cl->pending_data_sz) - return set_pending_data(cl, NULL, 0); - - cl->pending_data += bytes; - cl->pending_data_sz -= bytes; - return 0; -} - -/* print next pending data for the column @cl */ -static int print_pending_data( - struct libscols_table *tb, - struct libscols_column *cl, - struct libscols_line *ln, /* optional */ - struct libscols_cell *ce) -{ - const char *color = get_cell_color(tb, cl, ln, ce); - size_t width = cl->width, bytes; - size_t len = width, i; - char *data; - char *nextchunk = NULL; - - if (!cl->pending_data) - return 0; - if (!width) - return -EINVAL; - - DBG(COL, ul_debugobj(cl, "printing pending data")); - - data = strdup(cl->pending_data); - if (!data) - goto err; - - if (scols_column_is_customwrap(cl) - && (nextchunk = cl->wrap_nextchunk(cl, data, cl->wrapfunc_data))) { - bytes = nextchunk - data; - - len = scols_table_is_noencoding(tb) ? - mbs_nwidth(data, bytes) : - mbs_safe_nwidth(data, bytes, NULL); - } else - bytes = mbs_truncate(data, &len); - - if (bytes == (size_t) -1) - goto err; - - if (bytes) - step_pending_data(cl, bytes); - - if (color) - fputs(color, tb->out); - fputs(data, tb->out); - if (color) - fputs(UL_COLOR_RESET, tb->out); - free(data); - - /* minout -- don't fill */ - if (scols_table_is_minout(tb) && is_next_columns_empty(tb, cl, ln)) - return 0; - - /* default -- fill except last column */ - if (!scols_table_is_maxout(tb) && is_last_column(cl)) - return 0; - - /* fill rest of cell with space */ - for(i = len; i < width; i++) - fputs(cellpadding_symbol(tb), tb->out); - - if (!is_last_column(cl)) - fputs(colsep(tb), tb->out); - - return 0; -err: - free(data); - return -errno; -} - -static int print_data(struct libscols_table *tb, - struct libscols_column *cl, - struct libscols_line *ln, /* optional */ - struct libscols_cell *ce, /* optional */ - struct libscols_buffer *buf) -{ - size_t len = 0, i, width, bytes; - const char *color = NULL; - char *data, *nextchunk; - int is_last; - - assert(tb); - assert(cl); - - data = buffer_get_data(buf); - if (!data) - data = ""; - - is_last = is_last_column(cl); - - switch (tb->format) { - case SCOLS_FMT_RAW: - fputs_nonblank(data, tb->out); - if (!is_last) - fputs(colsep(tb), tb->out); - return 0; - - case SCOLS_FMT_EXPORT: - fprintf(tb->out, "%s=", scols_cell_get_data(&cl->header)); - fputs_quoted(data, tb->out); - if (!is_last) - fputs(colsep(tb), tb->out); - return 0; - - case SCOLS_FMT_JSON: - fputs_quoted_json_lower(scols_cell_get_data(&cl->header), tb->out); - fputs(":", tb->out); - switch (cl->json_type) { - case SCOLS_JSON_STRING: - if (!*data) - fputs("null", tb->out); - else - fputs_quoted_json(data, tb->out); - break; - case SCOLS_JSON_NUMBER: - if (!*data) - fputs("null", tb->out); - else - fputs(data, tb->out); - break; - case SCOLS_JSON_BOOLEAN: - fputs(!*data ? "false" : - *data == '0' ? "false" : - *data == 'N' || *data == 'n' ? "false" : "true", - tb->out); - break; - } - if (!is_last) - fputs(", ", tb->out); - return 0; - - case SCOLS_FMT_HUMAN: - break; /* continue below */ - } - - color = get_cell_color(tb, cl, ln, ce); - - /* Encode. Note that 'len' and 'width' are number of cells, not bytes. - */ - data = buffer_get_safe_data(tb, buf, &len, scols_column_get_safechars(cl)); - if (!data) - data = ""; - bytes = strlen(data); - width = cl->width; - - /* custom multi-line cell based */ - if (*data && scols_column_is_customwrap(cl) - && (nextchunk = cl->wrap_nextchunk(cl, data, cl->wrapfunc_data))) { - set_pending_data(cl, nextchunk, bytes - (nextchunk - data)); - bytes = nextchunk - data; - - len = scols_table_is_noencoding(tb) ? - mbs_nwidth(data, bytes) : - mbs_safe_nwidth(data, bytes, NULL); - } - - if (is_last - && len < width - && !scols_table_is_maxout(tb) - && !scols_column_is_right(cl)) - width = len; - - /* truncate data */ - if (len > width && scols_column_is_trunc(cl)) { - len = width; - bytes = mbs_truncate(data, &len); /* updates 'len' */ - } - - /* standard multi-line cell */ - if (len > width && scols_column_is_wrap(cl) - && !scols_column_is_customwrap(cl)) { - set_pending_data(cl, data, bytes); - - len = width; - bytes = mbs_truncate(data, &len); - if (bytes != (size_t) -1 && bytes > 0) - step_pending_data(cl, bytes); - } - - if (bytes == (size_t) -1) { - bytes = len = 0; - data = NULL; - } - - if (data && *data) { - if (scols_column_is_right(cl)) { - if (color) - fputs(color, tb->out); - for (i = len; i < width; i++) - fputs(cellpadding_symbol(tb), tb->out); - fputs(data, tb->out); - if (color) - fputs(UL_COLOR_RESET, tb->out); - len = width; - - } else if (color) { - char *p = data; - size_t art = buffer_get_safe_art_size(buf); - - /* we don't want to colorize tree ascii art */ - if (scols_column_is_tree(cl) && art && art < bytes) { - fwrite(p, 1, art, tb->out); - p += art; - } - - fputs(color, tb->out); - fputs(p, tb->out); - fputs(UL_COLOR_RESET, tb->out); - } else - fputs(data, tb->out); - } - - /* minout -- don't fill */ - if (scols_table_is_minout(tb) && is_next_columns_empty(tb, cl, ln)) - return 0; - - /* default -- fill except last column */ - if (!scols_table_is_maxout(tb) && is_last) - return 0; - - /* fill rest of cell with space */ - for(i = len; i < width; i++) - fputs(cellpadding_symbol(tb), tb->out); - - if (len > width && !scols_column_is_trunc(cl)) { - DBG(COL, ul_debugobj(cl, "*** data len=%zu > column width=%zu", len, width)); - print_newline_padding(tb, cl, ln, buffer_get_size(buf)); /* next column starts on next line */ - - } else if (!is_last) - fputs(colsep(tb), tb->out); /* columns separator */ - - return 0; -} - -int __cell_to_buffer(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_column *cl, - struct libscols_buffer *buf) -{ - const char *data; - struct libscols_cell *ce; - int rc = 0; - - assert(tb); - assert(ln); - assert(cl); - assert(buf); - assert(cl->seqnum <= tb->ncols); - - buffer_reset_data(buf); - - ce = scols_line_get_cell(ln, cl->seqnum); - data = ce ? scols_cell_get_data(ce) : NULL; - - if (!scols_column_is_tree(cl)) - return data ? buffer_set_data(buf, data) : 0; - - /* - * Group stuff - */ - if (!scols_table_is_json(tb) && cl->is_groups) - rc = groups_ascii_art_to_buffer(tb, ln, buf); - - /* - * Tree stuff - */ - if (!rc && ln->parent && !scols_table_is_json(tb)) { - rc = tree_ascii_art_to_buffer(tb, ln->parent, buf); - - if (!rc && is_last_child(ln)) - rc = buffer_append_data(buf, right_symbol(tb)); - else if (!rc) - rc = buffer_append_data(buf, branch_symbol(tb)); - } - - if (!rc && (ln->parent || cl->is_groups) && !scols_table_is_json(tb)) - buffer_set_art_index(buf); - - if (!rc && data) - rc = buffer_append_data(buf, data); - return rc; -} - -/* - * Prints data. Data can be printed in more formats (raw, NAME=xxx pairs), and - * control and non-printable characters can be encoded in the \x?? encoding. - */ -static int print_line(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_buffer *buf) -{ - int rc = 0, pending = 0; - struct libscols_column *cl; - struct libscols_iter itr; - - assert(ln); - - DBG(LINE, ul_debugobj(ln, "printing line")); - - /* regular line */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - 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); - if (rc == 0) - rc = print_data(tb, cl, ln, - scols_line_get_cell(ln, cl->seqnum), - buf); - if (rc == 0 && cl->pending_data) - pending = 1; - } - - /* extra lines of the multi-line cells */ - while (rc == 0 && pending) { - DBG(LINE, ul_debugobj(ln, "printing pending data")); - pending = 0; - fputs(linesep(tb), tb->out); - tb->termlines_used++; - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (rc == 0 && scols_table_next_column(tb, &itr, &cl) == 0) { - if (scols_column_is_hidden(cl)) - continue; - if (cl->pending_data) { - rc = print_pending_data(tb, cl, ln, scols_line_get_cell(ln, cl->seqnum)); - if (rc == 0 && cl->pending_data) - pending = 1; - } else - print_empty_cell(tb, cl, ln, buffer_get_size(buf)); - } - } - - return 0; -} - -int __scols_print_title(struct libscols_table *tb) -{ - int rc, color = 0; - mbs_align_t align; - size_t width, len = 0, bufsz, titlesz; - char *title = NULL, *buf = NULL; - - assert(tb); - - if (!tb->title.data) - return 0; - - DBG(TAB, ul_debugobj(tb, "printing title")); - - /* encode data */ - if (tb->no_encode) { - len = bufsz = strlen(tb->title.data) + 1; - buf = strdup(tb->title.data); - if (!buf) { - rc = -ENOMEM; - goto done; - } - } else { - bufsz = mbs_safe_encode_size(strlen(tb->title.data)) + 1; - if (bufsz == 1) { - DBG(TAB, ul_debugobj(tb, "title is empty string -- ignore")); - return 0; - } - buf = malloc(bufsz); - if (!buf) { - rc = -ENOMEM; - goto done; - } - - if (!mbs_safe_encode_to_buffer(tb->title.data, &len, buf, NULL) || - !len || len == (size_t) -1) { - rc = -EINVAL; - goto done; - } - } - - /* truncate and align */ - width = tb->is_term ? tb->termwidth : 80; - titlesz = width + bufsz; - - title = malloc(titlesz); - if (!title) { - rc = -EINVAL; - goto done; - } - - switch (scols_cell_get_alignment(&tb->title)) { - case SCOLS_CELL_FL_RIGHT: - align = MBS_ALIGN_RIGHT; - break; - case SCOLS_CELL_FL_CENTER: - align = MBS_ALIGN_CENTER; - break; - case SCOLS_CELL_FL_LEFT: - default: - align = MBS_ALIGN_LEFT; - /* - * Don't print extra blank chars after the title if on left - * (that's same as we use for the last column in the table). - */ - if (len < width - && !scols_table_is_maxout(tb) - && isblank(*titlepadding_symbol(tb))) - width = len; - break; - - } - - /* copy from buf to title and align to width with title_padding */ - rc = mbsalign_with_padding(buf, title, titlesz, - &width, align, - 0, (int) *titlepadding_symbol(tb)); - - if (rc == -1) { - rc = -EINVAL; - goto done; - } - - if (tb->colors_wanted && tb->title.color) - color = 1; - if (color) - fputs(tb->title.color, tb->out); - - fputs(title, tb->out); - - if (color) - fputs(UL_COLOR_RESET, tb->out); - - fputc('\n', tb->out); - rc = 0; -done: - free(buf); - free(title); - DBG(TAB, ul_debugobj(tb, "printing title done [rc=%d]", rc)); - return rc; -} - -int __scols_print_header(struct libscols_table *tb, struct libscols_buffer *buf) -{ - int rc = 0; - struct libscols_column *cl; - struct libscols_iter itr; - - assert(tb); - - if ((tb->header_printed == 1 && tb->header_repeat == 0) || - scols_table_is_noheadings(tb) || - scols_table_is_export(tb) || - scols_table_is_json(tb) || - list_empty(&tb->tb_lines)) - return 0; - - DBG(TAB, ul_debugobj(tb, "printing header")); - - /* set the width according to the size of the data */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (rc == 0 && scols_table_next_column(tb, &itr, &cl) == 0) { - if (scols_column_is_hidden(cl)) - continue; - - buffer_reset_data(buf); - - if (cl->is_groups - && scols_table_is_tree(tb) && scols_column_is_tree(cl)) { - size_t i; - for (i = 0; i < tb->grpset_size + 1; i++) { - rc = buffer_append_data(buf, " "); - if (rc) - break; - } - } - if (!rc) - rc = buffer_append_data(buf, scols_cell_get_data(&cl->header)); - if (!rc) - rc = print_data(tb, cl, NULL, &cl->header, buf); - } - - if (rc == 0) { - fputs(linesep(tb), tb->out); - tb->termlines_used++; - } - - tb->header_printed = 1; - tb->header_next = tb->termlines_used + tb->termheight; - if (tb->header_repeat) - DBG(TAB, ul_debugobj(tb, "\tnext header: %zu [current=%zu, rc=%d]", - tb->header_next, tb->termlines_used, rc)); - return rc; -} - - -int __scols_print_range(struct libscols_table *tb, - struct libscols_buffer *buf, - struct libscols_iter *itr, - struct libscols_line *end) -{ - int rc = 0; - struct libscols_line *ln; - - assert(tb); - DBG(TAB, ul_debugobj(tb, "printing range")); - - while (rc == 0 && scols_table_next_line(tb, itr, &ln) == 0) { - - int last = scols_iter_is_last(itr); - - fput_line_open(tb); - rc = print_line(tb, ln, buf); - fput_line_close(tb, last, last); - - if (end && ln == end) - break; - - if (!last && want_repeat_header(tb)) - __scols_print_header(tb, buf); - } - - return rc; - -} - -int __scols_print_table(struct libscols_table *tb, struct libscols_buffer *buf) -{ - struct libscols_iter itr; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - return __scols_print_range(tb, buf, &itr, NULL); -} - -/* scols_walk_tree() callback to print tree line */ -static int print_tree_line(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_column *cl __attribute__((__unused__)), - void *data) -{ - struct libscols_buffer *buf = (struct libscols_buffer *) data; - int rc; - - DBG(LINE, ul_debugobj(ln, " printing tree line")); - - fput_line_open(tb); - rc = print_line(tb, ln, buf); - if (rc) - return rc; - - if (has_children(ln)) - fput_children_open(tb); - - else { - int last_in_tree = scols_walk_is_last(tb, ln); - int last; - - /* terminate all open last children for JSON */ - if (scols_table_is_json(tb)) { - do { - last = (is_child(ln) && is_last_child(ln)) || - (is_tree_root(ln) && is_last_tree_root(tb, ln)); - - fput_line_close(tb, last, last_in_tree); - if (last && is_child(ln)) - fput_children_close(tb); - - last_in_tree = 0; - ln = ln->parent; - } while(ln && last); - - } else { - /* standard output */ - last = (is_child(ln) && is_last_child(ln)) || - (is_group_child(ln) && is_last_group_child(ln)); - - fput_line_close(tb, last, last_in_tree); - } - } - - return 0; -} - -int __scols_print_tree(struct libscols_table *tb, struct libscols_buffer *buf) -{ - assert(tb); - DBG(TAB, ul_debugobj(tb, "----printing-tree-----")); - - return scols_walk_tree(tb, NULL, print_tree_line, (void *) buf); -} - -static size_t strlen_line(struct libscols_line *ln) -{ - size_t i, sz = 0; - - assert(ln); - - for (i = 0; i < ln->ncells; i++) { - struct libscols_cell *ce = scols_line_get_cell(ln, i); - const char *data = ce ? scols_cell_get_data(ce) : NULL; - - sz += data ? strlen(data) : 0; - } - - return sz; -} - -void __scols_cleanup_printing(struct libscols_table *tb, struct libscols_buffer *buf) -{ - if (!tb) - return; - - free_buffer(buf); - - if (tb->priv_symbols) { - scols_table_set_symbols(tb, NULL); - tb->priv_symbols = 0; - } -} - -int __scols_initialize_printing(struct libscols_table *tb, struct libscols_buffer **buf) -{ - size_t bufsz, extra_bufsz = 0; - struct libscols_line *ln; - struct libscols_iter itr; - int rc; - - DBG(TAB, ul_debugobj(tb, "initialize printing")); - *buf = NULL; - - if (!tb->symbols) { - rc = scols_table_set_default_symbols(tb); - if (rc) - goto err; - tb->priv_symbols = 1; - } else - tb->priv_symbols = 0; - - if (tb->format == SCOLS_FMT_HUMAN) - tb->is_term = tb->termforce == SCOLS_TERMFORCE_NEVER ? 0 : - tb->termforce == SCOLS_TERMFORCE_ALWAYS ? 1 : - isatty(STDOUT_FILENO); - - if (tb->is_term) { - size_t width = (size_t) scols_table_get_termwidth(tb); - - if (tb->termreduce > 0 && tb->termreduce < width) { - width -= tb->termreduce; - scols_table_set_termwidth(tb, width); - } - bufsz = width; - } else - bufsz = BUFSIZ; - - if (!tb->is_term || tb->format != SCOLS_FMT_HUMAN || scols_table_is_tree(tb)) - tb->header_repeat = 0; - - /* - * Estimate extra space necessary for tree, JSON or another output - * decoration. - */ - if (scols_table_is_tree(tb)) - extra_bufsz += tb->nlines * strlen(vertical_symbol(tb)); - - switch (tb->format) { - case SCOLS_FMT_RAW: - extra_bufsz += tb->ncols; /* separator between columns */ - break; - case SCOLS_FMT_JSON: - if (tb->format == SCOLS_FMT_JSON) - extra_bufsz += tb->nlines * 3; /* indentation */ - /* fallthrough */ - case SCOLS_FMT_EXPORT: - { - struct libscols_column *cl; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - - while (scols_table_next_column(tb, &itr, &cl) == 0) { - if (scols_column_is_hidden(cl)) - continue; - extra_bufsz += strlen(scols_cell_get_data(&cl->header)); /* data */ - extra_bufsz += 2; /* separators */ - } - break; - } - case SCOLS_FMT_HUMAN: - break; - } - - /* - * Enlarge buffer if necessary, the buffer should be large enough to - * store line data and tree ascii art (or another decoration). - */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - size_t sz; - - sz = strlen_line(ln) + extra_bufsz; - if (sz > bufsz) - bufsz = sz; - } - - *buf = new_buffer(bufsz + 1); /* data + space for \0 */ - if (!*buf) { - rc = -ENOMEM; - goto err; - } - - /* - * Make sure groups members are in the same orders as the tree - */ - if (has_groups(tb) && scols_table_is_tree(tb)) - scols_groups_fix_members_order(tb); - - if (tb->format == SCOLS_FMT_HUMAN) { - rc = __scols_calculate(tb, *buf); - if (rc != 0) - goto err; - } - - return 0; -err: - __scols_cleanup_printing(tb, *buf); - return rc; -} - diff --git a/utils/libsmartcols/src/smartcolsP.h b/utils/libsmartcols/src/smartcolsP.h deleted file mode 100644 index e36bb51..0000000 --- a/utils/libsmartcols/src/smartcolsP.h +++ /dev/null @@ -1,468 +0,0 @@ -/* - * smartcolsP.h - private library header file - * - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -#ifndef _LIBSMARTCOLS_PRIVATE_H -#define _LIBSMARTCOLS_PRIVATE_H - -#include "c.h" -#include "list.h" -#include "strutils.h" -#include "color-names.h" -#include "debug.h" - -#include "libsmartcols.h" - -/* - * Debug - */ -#define SCOLS_DEBUG_HELP (1 << 0) -#define SCOLS_DEBUG_INIT (1 << 1) -#define SCOLS_DEBUG_CELL (1 << 2) -#define SCOLS_DEBUG_LINE (1 << 3) -#define SCOLS_DEBUG_TAB (1 << 4) -#define SCOLS_DEBUG_COL (1 << 5) -#define SCOLS_DEBUG_BUFF (1 << 6) -#define SCOLS_DEBUG_GROUP (1 << 7) -#define SCOLS_DEBUG_ALL 0xFFFF - -UL_DEBUG_DECLARE_MASK(libsmartcols); -#define DBG(m, x) __UL_DBG(libsmartcols, SCOLS_DEBUG_, m, x) -#define ON_DBG(m, x) __UL_DBG_CALL(libsmartcols, SCOLS_DEBUG_, m, x) -#define DBG_FLUSH __UL_DBG_FLUSH(libsmartcols, SCOLS_DEBUG_) - -#define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(libsmartcols) -#include "debugobj.h" - -/* - * Generic iterator - */ -struct libscols_iter { - struct list_head *p; /* current position */ - struct list_head *head; /* start position */ - int direction; /* SCOLS_ITER_{FOR,BACK}WARD */ -}; - -/* - * Tree symbols - */ -struct libscols_symbols { - int refcount; - - char *tree_branch; - char *tree_vert; - char *tree_right; - - char *group_vert; - char *group_horz; - char *group_first_member; - char *group_last_member; - char *group_middle_member; - char *group_last_child; - char *group_middle_child; - - char *title_padding; - char *cell_padding; -}; - -/* - * Table cells - */ -struct libscols_cell { - char *data; - char *color; - void *userdata; - int flags; -}; - -extern int scols_line_move_cells(struct libscols_line *ln, size_t newn, size_t oldn); - -/* - * Table column - */ -struct libscols_column { - int refcount; /* reference counter */ - size_t seqnum; /* column index */ - - size_t width; /* real column width */ - size_t width_min; /* minimal width (usually header width) */ - size_t width_max; /* maximal width */ - size_t width_avg; /* average width, used to detect extreme fields */ - size_t width_treeart; /* size of the tree ascii art */ - double width_hint; /* hint (N < 1 is in percent of termwidth) */ - - size_t extreme_sum; - int extreme_count; - - int json_type; /* SCOLS_JSON_* */ - - int flags; - char *color; /* default column color */ - char *safechars; /* do not encode this bytes */ - - char *pending_data; - size_t pending_data_sz; - char *pending_data_buf; - - int (*cmpfunc)(struct libscols_cell *, - struct libscols_cell *, - void *); /* cells comparison function */ - void *cmpfunc_data; - - size_t (*wrap_chunksize)(const struct libscols_column *, - const char *, void *); - char *(*wrap_nextchunk)(const struct libscols_column *, - char *, void *); - void *wrapfunc_data; - - - struct libscols_cell header; - struct list_head cl_columns; - - struct libscols_table *table; - - unsigned int is_extreme : 1, /* extreme width in the column */ - is_groups : 1; /* print group chart */ - -}; - -#define colsep(tb) ((tb)->colsep ? (tb)->colsep : " ") -#define linesep(tb) ((tb)->linesep ? (tb)->linesep : "\n") - -enum { - SCOLS_GSTATE_NONE = 0, /* not activate yet */ - SCOLS_GSTATE_FIRST_MEMBER, - SCOLS_GSTATE_MIDDLE_MEMBER, - SCOLS_GSTATE_LAST_MEMBER, - SCOLS_GSTATE_MIDDLE_CHILD, - SCOLS_GSTATE_LAST_CHILD, - SCOLS_GSTATE_CONT_MEMBERS, - SCOLS_GSTATE_CONT_CHILDREN -}; - -/* - * Every group needs at least 3 columns - */ -#define SCOLS_GRPSET_CHUNKSIZ 3 - -struct libscols_group { - int refcount; - - size_t nmembers; - - struct list_head gr_members; /* head of line->ln_group */ - struct list_head gr_children; /* head of line->ln_children */ - struct list_head gr_groups; /* member of table->tb_groups */ - - int state; /* SCOLS_GSTATE_* */ -}; - -/* - * Table line - */ -struct libscols_line { - int refcount; - size_t seqnum; - - void *userdata; - char *color; /* default line color */ - - struct libscols_cell *cells; /* array with data */ - size_t ncells; /* number of cells */ - - struct list_head ln_lines; /* member of table->tb_lines */ - struct list_head ln_branch; /* head of line->ln_children */ - struct list_head ln_children; /* member of line->ln_children or group->gr_children */ - struct list_head ln_groups; /* member of group->gr_groups */ - - struct libscols_line *parent; - struct libscols_group *parent_group; /* for group childs */ - struct libscols_group *group; /* for group members */ -}; - -enum { - SCOLS_FMT_HUMAN = 0, /* default, human readable */ - SCOLS_FMT_RAW, /* space separated */ - SCOLS_FMT_EXPORT, /* COLNAME="data" ... */ - SCOLS_FMT_JSON /* http://en.wikipedia.org/wiki/JSON */ -}; - -/* - * The table - */ -struct libscols_table { - int refcount; - char *name; /* optional table name (for JSON) */ - size_t ncols; /* number of columns */ - size_t ntreecols; /* number of columns with SCOLS_FL_TREE */ - size_t nlines; /* number of lines */ - size_t termwidth; /* terminal width (number of columns) */ - size_t termheight; /* terminal height (number of lines) */ - size_t termreduce; /* extra blank space */ - int termforce; /* SCOLS_TERMFORCE_* */ - FILE *out; /* output stream */ - - char *colsep; /* column separator */ - char *linesep; /* line separator */ - - struct list_head tb_columns; - struct list_head tb_lines; - - struct list_head tb_groups; /* all defined groups */ - struct libscols_group **grpset; - size_t grpset_size; - - size_t ngrpchlds_pending; /* groups with not yet printed children */ - struct libscols_line *walk_last_tree_root; /* last root, used by scols_walk_() */ - - struct libscols_symbols *symbols; - struct libscols_cell title; /* optional table title (for humans) */ - - int indent; /* indentation counter */ - int indent_last_sep;/* last printed has been line separator */ - int format; /* SCOLS_FMT_* */ - - size_t termlines_used; /* printed line counter */ - size_t header_next; /* where repeat header */ - - /* flags */ - unsigned int ascii :1, /* don't use unicode */ - colors_wanted :1, /* enable colors */ - is_term :1, /* isatty() */ - padding_debug :1, /* output visible padding chars */ - is_dummy_print :1, /* printing used for width calculation only */ - maxout :1, /* maximize output */ - minout :1, /* minimize output (mutually exclusive to maxout) */ - header_repeat :1, /* print header after libscols_table->termheight */ - header_printed :1, /* header already printed */ - priv_symbols :1, /* default private symbols */ - walk_last_done :1, /* last tree root walked */ - no_headings :1, /* don't print header */ - no_encode :1, /* don't care about control and non-printable chars */ - no_linesep :1, /* don't print line separator */ - no_wrap :1; /* never wrap lines */ -}; - -#define IS_ITER_FORWARD(_i) ((_i)->direction == SCOLS_ITER_FORWARD) -#define IS_ITER_BACKWARD(_i) ((_i)->direction == SCOLS_ITER_BACKWARD) - -#define SCOLS_ITER_INIT(itr, list) \ - do { \ - (itr)->p = IS_ITER_FORWARD(itr) ? \ - (list)->next : (list)->prev; \ - (itr)->head = (list); \ - } while(0) - -#define SCOLS_ITER_ITERATE(itr, res, restype, member) \ - do { \ - res = list_entry((itr)->p, restype, member); \ - (itr)->p = IS_ITER_FORWARD(itr) ? \ - (itr)->p->next : (itr)->p->prev; \ - } while(0) - - -static inline int scols_iter_is_last(const struct libscols_iter *itr) -{ - if (!itr || !itr->head || !itr->p) - return 0; - - return itr->p == itr->head; -} - -/* - * line.c - */ -int scols_line_next_group_child(struct libscols_line *ln, - struct libscols_iter *itr, - struct libscols_line **chld); - - -/* - * table.c - */ -int scols_table_next_group(struct libscols_table *tb, - struct libscols_iter *itr, - struct libscols_group **gr); - -/* - * buffer.c - */ -struct libscols_buffer; -extern struct libscols_buffer *new_buffer(size_t sz); -extern void free_buffer(struct libscols_buffer *buf); -extern int buffer_reset_data(struct libscols_buffer *buf); -extern int buffer_append_data(struct libscols_buffer *buf, const char *str); -extern int buffer_append_ntimes(struct libscols_buffer *buf, size_t n, const char *str); -extern int buffer_set_data(struct libscols_buffer *buf, const char *str); -extern void buffer_set_art_index(struct libscols_buffer *buf); -extern char *buffer_get_data(struct libscols_buffer *buf); -extern size_t buffer_get_size(struct libscols_buffer *buf); -extern char *buffer_get_safe_data(struct libscols_table *tb, - struct libscols_buffer *buf, - size_t *cells, - const char *safechars); -extern size_t buffer_get_safe_art_size(struct libscols_buffer *buf); - -/* - * grouping.c - */ -void scols_ref_group(struct libscols_group *gr); -void scols_group_remove_children(struct libscols_group *gr); -void scols_group_remove_members(struct libscols_group *gr); -void scols_unref_group(struct libscols_group *gr); -void scols_groups_fix_members_order(struct libscols_table *tb); -int scols_groups_update_grpset(struct libscols_table *tb, struct libscols_line *ln); -void scols_groups_reset_state(struct libscols_table *tb); -struct libscols_group *scols_grpset_get_printable_children(struct libscols_table *tb); - -/* - * walk.c - */ -extern int scols_walk_tree(struct libscols_table *tb, - struct libscols_column *cl, - int (*callback)(struct libscols_table *, - struct libscols_line *, - struct libscols_column *, - void *), - void *data); -extern int scols_walk_is_last(struct libscols_table *tb, struct libscols_line *ln); - -/* - * 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); - -void __scols_cleanup_printing(struct libscols_table *tb, struct libscols_buffer *buf); -int __scols_initialize_printing(struct libscols_table *tb, struct libscols_buffer **buf); -int __scols_print_tree(struct libscols_table *tb, struct libscols_buffer *buf); -int __scols_print_table(struct libscols_table *tb, struct libscols_buffer *buf); -int __scols_print_header(struct libscols_table *tb, struct libscols_buffer *buf); -int __scols_print_title(struct libscols_table *tb); -int __scols_print_range(struct libscols_table *tb, - struct libscols_buffer *buf, - struct libscols_iter *itr, - struct libscols_line *end); - -/* - * fput.c - */ -extern void fput_indent(struct libscols_table *tb); -extern void fput_table_open(struct libscols_table *tb); -extern void fput_table_close(struct libscols_table *tb); -extern void fput_children_open(struct libscols_table *tb); -extern void fput_children_close(struct libscols_table *tb); -extern void fput_line_open(struct libscols_table *tb); -extern void fput_line_close(struct libscols_table *tb, int last, int last_in_table); - -static inline int is_tree_root(struct libscols_line *ln) -{ - return ln && !ln->parent && !ln->parent_group; -} - -static inline int is_last_tree_root(struct libscols_table *tb, struct libscols_line *ln) -{ - if (!ln || !tb || tb->walk_last_tree_root != ln) - return 0; - - return 1; -} - -static inline int is_child(struct libscols_line *ln) -{ - return ln && ln->parent; -} - -static inline int is_last_child(struct libscols_line *ln) -{ - if (!ln || !ln->parent) - return 0; - - return list_entry_is_last(&ln->ln_children, &ln->parent->ln_branch); -} - -static inline int is_first_child(struct libscols_line *ln) -{ - if (!ln || !ln->parent) - return 0; - - return list_entry_is_first(&ln->ln_children, &ln->parent->ln_branch); -} - - -static inline int is_last_column(struct libscols_column *cl) -{ - struct libscols_column *next; - - if (list_entry_is_last(&cl->cl_columns, &cl->table->tb_columns)) - return 1; - - next = list_entry(cl->cl_columns.next, struct libscols_column, cl_columns); - if (next && scols_column_is_hidden(next) && is_last_column(next)) - return 1; - return 0; -} - -static inline int is_last_group_member(struct libscols_line *ln) -{ - if (!ln || !ln->group) - return 0; - - return list_entry_is_last(&ln->ln_groups, &ln->group->gr_members); -} - -static inline int is_first_group_member(struct libscols_line *ln) -{ - if (!ln || !ln->group) - return 0; - - return list_entry_is_first(&ln->ln_groups, &ln->group->gr_members); -} - -static inline int is_group_member(struct libscols_line *ln) -{ - return ln && ln->group; -} - -static inline int is_last_group_child(struct libscols_line *ln) -{ - if (!ln || !ln->parent_group) - return 0; - - return list_entry_is_last(&ln->ln_children, &ln->parent_group->gr_children); -} - -static inline int is_group_child(struct libscols_line *ln) -{ - return ln && ln->parent_group; -} - -static inline int has_groups(struct libscols_table *tb) -{ - return tb && !list_empty(&tb->tb_groups); -} - -static inline int has_children(struct libscols_line *ln) -{ - return ln && !list_empty(&ln->ln_branch); -} - -static inline int has_group_children(struct libscols_line *ln) -{ - return ln && ln->group && !list_empty(&ln->group->gr_children); -} - -#endif /* _LIBSMARTCOLS_PRIVATE_H */ diff --git a/utils/libsmartcols/src/symbols.c b/utils/libsmartcols/src/symbols.c deleted file mode 100644 index 2fadfc7..0000000 --- a/utils/libsmartcols/src/symbols.c +++ /dev/null @@ -1,293 +0,0 @@ -/* - * symbols.c - routines for symbol handling - * - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2016 Igor Gnatenko <i.gnatenko.brain@gmail.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: symbols - * @title: Symbols - * @short_description: can be used to overwrite default output chars (for ascii art) - * - * An API to access and modify data and information per symbol/symbol group. - */ - - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> - -#include "smartcolsP.h" - -/** - * scols_new_symbols: - * - * Returns: a pointer to a newly allocated struct libscols_symbols instance. - */ -struct libscols_symbols *scols_new_symbols(void) -{ - struct libscols_symbols *sy = calloc(1, sizeof(struct libscols_symbols)); - - if (!sy) - return NULL; - sy->refcount = 1; - return sy; -} - -/** - * scols_ref_symbols: - * @sy: a pointer to a struct libscols_symbols instance - * - * Increases the refcount of @sy. - */ -void scols_ref_symbols(struct libscols_symbols *sy) -{ - if (sy) - sy->refcount++; -} - -/** - * scols_unref_symbols: - * @sy: a pointer to a struct libscols_symbols instance - * - * Decreases the refcount of @sy. - */ -void scols_unref_symbols(struct libscols_symbols *sy) -{ - if (sy && --sy->refcount <= 0) { - free(sy->tree_branch); - free(sy->tree_vert); - free(sy->tree_right); - free(sy->group_last_member); - free(sy->group_middle_member); - free(sy->group_first_member); - free(sy->group_vert); - free(sy->group_horz); - free(sy->group_last_child); - free(sy->group_middle_child); - free(sy->title_padding); - free(sy->cell_padding); - free(sy); - } -} - -/** - * scols_symbols_set_branch: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the branch part of a tree output - * - * Returns: 0, a negative value in case of an error. - */ -int scols_symbols_set_branch(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, tree_branch, str); -} - -/** - * scols_symbols_set_vertical: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the vertical part of a tree output - * - * Returns: 0, a negative value in case of an error. - */ -int scols_symbols_set_vertical(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, tree_vert, str); -} - -/** - * scols_symbols_set_right: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the right part of a tree output - * - * Returns: 0, a negative value in case of an error. - */ -int scols_symbols_set_right(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, tree_right, str); -} - -/** - * scols_symbols_set_title_padding: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the symbols which fill title output - * - * The current implementation uses only the first byte from the padding string. - * A multibyte chars are not supported yet. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.28 - */ -int scols_symbols_set_title_padding(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, title_padding, str); -} - -/** - * scols_symbols_set_cell_padding: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the symbols which fill cells - * - * The padding char has to take up just one cell on the terminal. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_symbols_set_cell_padding(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, cell_padding, str); -} - - -/** - * scols_symbols_set_group_vertical: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the vertival line - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_vertical(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_vert, str); -} - -/** - * scols_symbols_set_group_horizontal: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent the horizontal line - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_horizontal(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_horz, str); -} - -/** - * scols_symbols_set_group_first_member: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent first member - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_first_member(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_first_member, str); -} - -/** - * scols_symbols_set_group_last_member: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent last member - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_last_member(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_last_member, str); -} - -/** - * scols_symbols_set_group_middle: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent middle member - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_middle_member(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_middle_member, str); -} - -/** - * scols_symbols_set_group_last_child: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent last child - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_last_child(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_last_child, str); -} - -/** - * scols_symbols_set_group_middle_child: - * @sy: a pointer to a struct libscols_symbols instance - * @str: a string which will represent last child - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.34 - */ -int scols_symbols_set_group_middle_child(struct libscols_symbols *sy, const char *str) -{ - return strdup_to_struct_member(sy, group_middle_child, str); -} - -/** - * scols_copy_symbols: - * @sy: a pointer to a struct libscols_symbols instance - * - * Returns: a newly allocated copy of the @sy symbol group or NULL in case of an error. - */ -struct libscols_symbols *scols_copy_symbols(const struct libscols_symbols *sy) -{ - struct libscols_symbols *ret; - int rc; - - assert(sy); - if (!sy) - return NULL; - - ret = scols_new_symbols(); - if (!ret) - return NULL; - - rc = scols_symbols_set_branch(ret, sy->tree_branch); - if (!rc) - rc = scols_symbols_set_vertical(ret, sy->tree_vert); - if (!rc) - rc = scols_symbols_set_right(ret, sy->tree_right); - if (!rc) - rc = scols_symbols_set_group_vertical(ret, sy->group_vert); - if (!rc) - rc = scols_symbols_set_group_horizontal(ret, sy->group_horz); - if (!rc) - rc = scols_symbols_set_group_first_member(ret, sy->group_first_member); - if (!rc) - rc = scols_symbols_set_group_last_member(ret, sy->group_last_member); - if (!rc) - rc = scols_symbols_set_group_middle_member(ret, sy->group_middle_member); - if (!rc) - rc = scols_symbols_set_group_middle_child(ret, sy->group_middle_child); - if (!rc) - rc = scols_symbols_set_group_last_child(ret, sy->group_last_child); - if (!rc) - rc = scols_symbols_set_title_padding(ret, sy->title_padding); - if (!rc) - rc = scols_symbols_set_cell_padding(ret, sy->cell_padding); - if (!rc) - return ret; - - scols_unref_symbols(ret); - return NULL; -} diff --git a/utils/libsmartcols/src/table.c b/utils/libsmartcols/src/table.c deleted file mode 100644 index a3ba21d..0000000 --- a/utils/libsmartcols/src/table.c +++ /dev/null @@ -1,1691 +0,0 @@ -/* - * table.c - functions handling the data at the table level - * - * Copyright (C) 2010-2014 Karel Zak <kzak@redhat.com> - * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com> - * Copyright (C) 2016 Igor Gnatenko <i.gnatenko.brain@gmail.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ - -/** - * SECTION: table - * @title: Table - * @short_description: container for rows and columns - * - * Table data manipulation API. - */ - - -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <termios.h> -#include <ctype.h> - -#include "nls.h" -#include "ttyutils.h" -#include "smartcolsP.h" - -#ifdef HAVE_WIDECHAR -#define UTF_V "\342\224\202" /* U+2502, Vertical line drawing char | */ -#define UTF_VR "\342\224\234" /* U+251C, Vertical and right |- */ -#define UTF_H "\342\224\200" /* U+2500, Horizontal - */ -#define UTF_UR "\342\224\224" /* U+2514, Up and right '- */ - -#define UTF_V3 "\342\224\206" /* U+2506 Triple Dash Vertical | */ -#define UTF_H3 "\342\224\210" /* U+2504 Triple Dash Horizontal - */ -#define UTF_DR "\342\224\214" /* U+250C Down and Right ,- */ -#define UTF_DH "\342\224\254" /* U+252C Down and Horizontal |' */ - -#define UTF_TR "\342\226\266" /* U+25B6 Black Right-Pointing Triangle > */ -#endif /* !HAVE_WIDECHAR */ - -#define is_last_column(_tb, _cl) \ - list_entry_is_last(&(_cl)->cl_columns, &(_tb)->tb_columns) - - -static void check_padding_debug(struct libscols_table *tb) -{ - const char *str; - - assert(libsmartcols_debug_mask); /* debug has to be enabled! */ - - str = getenv("LIBSMARTCOLS_DEBUG_PADDING"); - if (!str || (strcmp(str, "on") != 0 && strcmp(str, "1") != 0)) - return; - - DBG(INIT, ul_debugobj(tb, "padding debug: ENABLE")); - tb->padding_debug = 1; -} - -/** - * scols_new_table: - * - * Returns: A newly allocated table. - */ -struct libscols_table *scols_new_table(void) -{ - struct libscols_table *tb; - int c, l; - - tb = calloc(1, sizeof(struct libscols_table)); - if (!tb) - return NULL; - - tb->refcount = 1; - tb->out = stdout; - - get_terminal_dimension(&c, &l); - tb->termwidth = c > 0 ? c : 80; - tb->termheight = l > 0 ? l : 24; - - INIT_LIST_HEAD(&tb->tb_lines); - INIT_LIST_HEAD(&tb->tb_columns); - INIT_LIST_HEAD(&tb->tb_groups); - - DBG(TAB, ul_debugobj(tb, "alloc")); - ON_DBG(INIT, check_padding_debug(tb)); - - return tb; -} - -/** - * scols_ref_table: - * @tb: a pointer to a struct libscols_table instance - * - * Increases the refcount of @tb. - */ -void scols_ref_table(struct libscols_table *tb) -{ - if (tb) - tb->refcount++; -} - -static void scols_table_remove_groups(struct libscols_table *tb) -{ - while (!list_empty(&tb->tb_groups)) { - struct libscols_group *gr = list_entry(tb->tb_groups.next, - struct libscols_group, gr_groups); - scols_group_remove_children(gr); - scols_group_remove_members(gr); - scols_unref_group(gr); - } -} - -/** - * scols_unref_table: - * @tb: a pointer to a struct libscols_table instance - * - * Decreases the refcount of @tb. When the count falls to zero, the instance - * is automatically deallocated. - */ -void scols_unref_table(struct libscols_table *tb) -{ - if (tb && (--tb->refcount <= 0)) { - DBG(TAB, ul_debugobj(tb, "dealloc <-")); - scols_table_remove_groups(tb); - scols_table_remove_lines(tb); - scols_table_remove_columns(tb); - scols_unref_symbols(tb->symbols); - scols_reset_cell(&tb->title); - free(tb->grpset); - free(tb->linesep); - free(tb->colsep); - free(tb->name); - free(tb); - DBG(TAB, ul_debug("<- done")); - } -} - -/* Private API */ -int scols_table_next_group(struct libscols_table *tb, - struct libscols_iter *itr, - struct libscols_group **gr) -{ - int rc = 1; - - if (!tb || !itr || !gr) - return -EINVAL; - *gr = NULL; - - if (!itr->head) - SCOLS_ITER_INIT(itr, &tb->tb_groups); - if (itr->p != itr->head) { - SCOLS_ITER_ITERATE(itr, *gr, struct libscols_group, gr_groups); - rc = 0; - } - - return rc; -} - -/** - * scols_table_set_name: - * @tb: a pointer to a struct libscols_table instance - * @name: a name - * - * The table name is used for example for JSON top level object name. - * - * Returns: 0, a negative number in case of an error. - * - * Since: 2.27 - */ -int scols_table_set_name(struct libscols_table *tb, const char *name) -{ - return strdup_to_struct_member(tb, name, name); -} - -/** - * scols_table_get_name: - * @tb: a pointer to a struct libscols_table instance - * - * Returns: The current name setting of the table @tb - * - * Since: 2.29 - */ -const char *scols_table_get_name(const struct libscols_table *tb) -{ - return tb->name; -} - -/** - * scols_table_get_title: - * @tb: a pointer to a struct libscols_table instance - * - * The returned pointer is possible to modify by cell functions. Note that - * title output alignment on non-tty is hardcoded to 80 output chars. For the - * regular terminal it's based on terminal width. - * - * Returns: Title of the table, or NULL in case of blank title. - * - * Since: 2.28 - */ -struct libscols_cell *scols_table_get_title(struct libscols_table *tb) -{ - return &tb->title; -} - -/** - * scols_table_add_column: - * @tb: a pointer to a struct libscols_table instance - * @cl: a pointer to a struct libscols_column instance - * - * Adds @cl to @tb's column list. The column cannot be shared between more - * tables. - * - * Returns: 0, a negative number in case of an error. - */ -int scols_table_add_column(struct libscols_table *tb, struct libscols_column *cl) -{ - struct libscols_iter itr; - struct libscols_line *ln; - int rc = 0; - - if (!tb || !cl || cl->table) - return -EINVAL; - - if (!list_empty(&cl->cl_columns)) - return -EINVAL; - - if (cl->flags & SCOLS_FL_TREE) - tb->ntreecols++; - - DBG(TAB, ul_debugobj(tb, "add column")); - list_add_tail(&cl->cl_columns, &tb->tb_columns); - cl->seqnum = tb->ncols++; - cl->table = tb; - scols_ref_column(cl); - - if (list_empty(&tb->tb_lines)) - return 0; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - - /* Realloc line cell arrays - */ - while (scols_table_next_line(tb, &itr, &ln) == 0) { - rc = scols_line_alloc_cells(ln, tb->ncols); - if (rc) - break; - } - - return rc; -} - -/** - * scols_table_remove_column: - * @tb: a pointer to a struct libscols_table instance - * @cl: a pointer to a struct libscols_column instance - * - * Removes @cl from @tb. - * - * Returns: 0, a negative number in case of an error. - */ -int scols_table_remove_column(struct libscols_table *tb, - struct libscols_column *cl) -{ - if (!tb || !cl || !list_empty(&tb->tb_lines)) - return -EINVAL; - - if (cl->flags & SCOLS_FL_TREE) - tb->ntreecols--; - - DBG(TAB, ul_debugobj(tb, "remove column")); - list_del_init(&cl->cl_columns); - tb->ncols--; - cl->table = NULL; - scols_unref_column(cl); - return 0; -} - -/** - * scols_table_remove_columns: - * @tb: a pointer to a struct libscols_table instance - * - * Removes all of @tb's columns. - * - * Returns: 0, a negative number in case of an error. - */ -int scols_table_remove_columns(struct libscols_table *tb) -{ - if (!tb || !list_empty(&tb->tb_lines)) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "remove all columns")); - while (!list_empty(&tb->tb_columns)) { - struct libscols_column *cl = list_entry(tb->tb_columns.next, - struct libscols_column, cl_columns); - scols_table_remove_column(tb, cl); - } - return 0; -} - -/** - * scols_table_move_column: - * @tb: table - * @pre: column before the column - * @cl: column to move - * - * Move the @cl behind @pre. If the @pre is NULL then the @col is the first - * column in the table. - * - * Since: 2.30 - * - * Returns: 0, a negative number in case of an error. - */ -int scols_table_move_column(struct libscols_table *tb, - struct libscols_column *pre, - struct libscols_column *cl) -{ - struct list_head *head; - struct libscols_iter itr; - struct libscols_column *p; - struct libscols_line *ln; - size_t n = 0, oldseq; - - if (!tb || !cl) - return -EINVAL; - - if (pre && pre->seqnum + 1 == cl->seqnum) - return 0; - if (pre == NULL && cl->seqnum == 0) - return 0; - - DBG(TAB, ul_debugobj(tb, "move column %zu behind %zu", - cl->seqnum, pre? pre->seqnum : 0)); - - list_del_init(&cl->cl_columns); /* remove from old position */ - - head = pre ? &pre->cl_columns : &tb->tb_columns; - list_add(&cl->cl_columns, head); /* add to the new place */ - - oldseq = cl->seqnum; - - /* fix seq. numbers */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &p) == 0) - p->seqnum = n++; - - /* move data in lines */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) - scols_line_move_cells(ln, cl->seqnum, oldseq); - return 0; -} - -/** - * scols_table_new_column: - * @tb: table - * @name: column header - * @whint: column width hint (absolute width: N > 1; relative width: 0 < N < 1) - * @flags: flags integer - * - * This is shortcut for - * - * cl = scols_new_column(); - * scols_column_set_....(cl, ...); - * scols_table_add_column(tb, cl); - * - * The column width is possible to define by: - * - * @whint: 0 < N < 1 : relative width, percent of terminal width - * - * @whint: N >= 1 : absolute width, empty column will be truncated to - * the column header width if no specified STRICTWIDTH flag - * - * Note that if table has disabled "maxout" flag (disabled by default) than - * relative width is used as a hint only. It's possible that column will be - * narrow if the specified size is too large for column data. - * - * - * If the width of all columns is greater than terminal width then library - * tries to reduce width of the individual columns. It's done in three stages: - * - * #1 reduce columns with SCOLS_FL_TRUNC flag and with relative width if the - * width is greater than width defined by @whint (@whint * terminal_width) - * - * #2 reduce all columns with SCOLS_FL_TRUNC flag - * - * #3 reduce all columns with relative width - * - * The next stage is always used if the previous stage is unsuccessful. Note - * that SCOLS_FL_WRAP is interpreted as SCOLS_FL_TRUNC when calculate column - * width (if custom wrap function is not specified), but the final text is not - * truncated, but wrapped to multi-line cell. - * - * - * The column is necessary to address by sequential number. The first defined - * column has the colnum = 0. For example: - * - * scols_table_new_column(tab, "FOO", 0.5, 0); // colnum = 0 - * scols_table_new_column(tab, "BAR", 0.5, 0); // colnum = 1 - * . - * . - * scols_line_get_cell(line, 0); // FOO column - * scols_line_get_cell(line, 1); // BAR column - * - * Returns: newly allocated column - */ -struct libscols_column *scols_table_new_column(struct libscols_table *tb, - const char *name, - double whint, - int flags) -{ - struct libscols_column *cl; - struct libscols_cell *hr; - - if (!tb) - return NULL; - - DBG(TAB, ul_debugobj(tb, "new column name=%s, whint=%g, flags=%d", - name, whint, flags)); - cl = scols_new_column(); - if (!cl) - return NULL; - - /* set column name */ - hr = scols_column_get_header(cl); - if (!hr) - goto err; - if (scols_cell_set_data(hr, name)) - goto err; - - scols_column_set_whint(cl, whint); - scols_column_set_flags(cl, flags); - - if (scols_table_add_column(tb, cl)) /* this increments column ref-counter */ - goto err; - - scols_unref_column(cl); - return cl; -err: - scols_unref_column(cl); - return NULL; -} - -/** - * scols_table_next_column: - * @tb: a pointer to a struct libscols_table instance - * @itr: a pointer to a struct libscols_iter instance - * @cl: a pointer to a pointer to a struct libscols_column instance - * - * Returns the next column of @tb via @cl. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_next_column(struct libscols_table *tb, - struct libscols_iter *itr, - struct libscols_column **cl) -{ - int rc = 1; - - if (!tb || !itr || !cl) - return -EINVAL; - *cl = NULL; - - if (!itr->head) - SCOLS_ITER_INIT(itr, &tb->tb_columns); - if (itr->p != itr->head) { - SCOLS_ITER_ITERATE(itr, *cl, struct libscols_column, cl_columns); - rc = 0; - } - - return rc; -} - -/** - * scols_table_set_columns_iter: - * @tb: tab pointer - * @itr: iterator - * @cl: tab entry - * - * Sets @iter to the position of @cl in the file @tb. - * - * Returns: 0 on success, negative number in case of error. - * - * Since: 2.35 - */ -int scols_table_set_columns_iter( - struct libscols_table *tb, - struct libscols_iter *itr, - struct libscols_column *cl) -{ - if (!tb || !itr || !cl) - return -EINVAL; - - if (cl->table != tb) - return -EINVAL; - - SCOLS_ITER_INIT(itr, &tb->tb_columns); - itr->p = &cl->cl_columns; - - return 0; -} - -/** - * scols_table_get_ncols: - * @tb: table - * - * Returns: the ncols table member. - */ -size_t scols_table_get_ncols(const struct libscols_table *tb) -{ - return tb->ncols; -} - -/** - * scols_table_get_nlines: - * @tb: table - * - * Returns: the nlines table member. - */ -size_t scols_table_get_nlines(const struct libscols_table *tb) -{ - return tb->nlines; -} - -/** - * scols_table_set_stream: - * @tb: table - * @stream: output stream - * - * Sets the output stream for table @tb. - * - * Returns: 0, a negative number in case of an error. - */ -int scols_table_set_stream(struct libscols_table *tb, FILE *stream) -{ - assert(tb); - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "setting alternative stream")); - tb->out = stream; - return 0; -} - -/** - * scols_table_get_stream: - * @tb: table - * - * Gets the output stream for table @tb. - * - * Returns: stream pointer, NULL in case of an error or an unset stream. - */ -FILE *scols_table_get_stream(const struct libscols_table *tb) -{ - return tb->out; -} - -/** - * scols_table_reduce_termwidth: - * @tb: table - * @reduce: width - * - * If necessary then libsmartcols use all terminal width, the @reduce setting - * provides extra space (for example for borders in ncurses applications). - * - * The @reduce must be smaller than terminal width, otherwise it's silently - * ignored. The reduction is not applied when STDOUT_FILENO is not terminal. - * - * Note that after output initialization (scols_table_print_* calls) the width - * will be reduced, this behavior affects subsequenced scols_table_get_termwidth() - * calls. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_reduce_termwidth(struct libscols_table *tb, size_t reduce) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "reduce terminal width: %zu", reduce)); - tb->termreduce = reduce; - return 0; -} - -/** - * scols_table_get_column: - * @tb: table - * @n: number of column (0..N) - * - * Returns: pointer to column or NULL - */ -struct libscols_column *scols_table_get_column(struct libscols_table *tb, - size_t n) -{ - struct libscols_iter itr; - struct libscols_column *cl; - - if (!tb) - return NULL; - if (n >= tb->ncols) - return NULL; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &cl) == 0) { - if (cl->seqnum == n) - return cl; - } - return NULL; -} - -/** - * scols_table_add_line: - * @tb: table - * @ln: line - * - * Note that this function calls scols_line_alloc_cells() if number - * of the cells in the line is too small for @tb. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_add_line(struct libscols_table *tb, struct libscols_line *ln) -{ - if (!tb || !ln) - return -EINVAL; - - if (!list_empty(&ln->ln_lines)) - return -EINVAL; - - if (tb->ncols > ln->ncells) { - int rc = scols_line_alloc_cells(ln, tb->ncols); - if (rc) - return rc; - } - - DBG(TAB, ul_debugobj(tb, "add line")); - list_add_tail(&ln->ln_lines, &tb->tb_lines); - ln->seqnum = tb->nlines++; - scols_ref_line(ln); - return 0; -} - -/** - * scols_table_remove_line: - * @tb: table - * @ln: line - * - * Note that this function does not destroy the parent<->child relationship between lines. - * You have to call scols_line_remove_child() - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_remove_line(struct libscols_table *tb, - struct libscols_line *ln) -{ - if (!tb || !ln) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "remove line")); - list_del_init(&ln->ln_lines); - tb->nlines--; - scols_unref_line(ln); - return 0; -} - -/** - * scols_table_remove_lines: - * @tb: table - * - * This empties the table and also destroys all the parent<->child relationships. - */ -void scols_table_remove_lines(struct libscols_table *tb) -{ - if (!tb) - return; - - DBG(TAB, ul_debugobj(tb, "remove all lines")); - while (!list_empty(&tb->tb_lines)) { - struct libscols_line *ln = list_entry(tb->tb_lines.next, - struct libscols_line, ln_lines); - if (ln->parent) - scols_line_remove_child(ln->parent, ln); - scols_table_remove_line(tb, ln); - } -} - -/** - * scols_table_next_line: - * @tb: a pointer to a struct libscols_table instance - * @itr: a pointer to a struct libscols_iter instance - * @ln: a pointer to a pointer to a struct libscols_line instance - * - * Finds the next line and returns a pointer to it via @ln. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_next_line(struct libscols_table *tb, - struct libscols_iter *itr, - struct libscols_line **ln) -{ - int rc = 1; - - if (!tb || !itr || !ln) - return -EINVAL; - *ln = NULL; - - if (!itr->head) - SCOLS_ITER_INIT(itr, &tb->tb_lines); - if (itr->p != itr->head) { - SCOLS_ITER_ITERATE(itr, *ln, struct libscols_line, ln_lines); - rc = 0; - } - - return rc; -} - -/** - * scols_table_new_line: - * @tb: table - * @parent: parental line or NULL - * - * This is shortcut for - * - * ln = scols_new_line(); - * scols_table_add_line(tb, ln); - * scols_line_add_child(parent, ln); - * - * - * Returns: newly allocate line - */ -struct libscols_line *scols_table_new_line(struct libscols_table *tb, - struct libscols_line *parent) -{ - struct libscols_line *ln; - - if (!tb) - return NULL; - - ln = scols_new_line(); - if (!ln) - return NULL; - - if (scols_table_add_line(tb, ln)) - goto err; - if (parent) - scols_line_add_child(parent, ln); - - scols_unref_line(ln); /* ref-counter incremented by scols_table_add_line() */ - return ln; -err: - scols_unref_line(ln); - return NULL; -} - -/** - * scols_table_get_line: - * @tb: table - * @n: column number (0..N) - * - * Returns: a line or NULL - */ -struct libscols_line *scols_table_get_line(struct libscols_table *tb, - size_t n) -{ - struct libscols_iter itr; - struct libscols_line *ln; - - if (!tb) - return NULL; - if (n >= tb->nlines) - return NULL; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - if (ln->seqnum == n) - return ln; - } - return NULL; -} - -/** - * scols_copy_table: - * @tb: table - * - * Creates a new independent table copy, except struct libscols_symbols that - * are shared between the tables. - * - * Returns: a newly allocated copy of @tb - */ -struct libscols_table *scols_copy_table(struct libscols_table *tb) -{ - struct libscols_table *ret; - struct libscols_line *ln; - struct libscols_column *cl; - struct libscols_iter itr; - - if (!tb) - return NULL; - ret = scols_new_table(); - if (!ret) - return NULL; - - DBG(TAB, ul_debugobj(tb, "copy")); - - if (tb->symbols) - scols_table_set_symbols(ret, tb->symbols); - - /* columns */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_column(tb, &itr, &cl) == 0) { - cl = scols_copy_column(cl); - if (!cl) - goto err; - if (scols_table_add_column(ret, cl)) - goto err; - scols_unref_column(cl); - } - - /* lines */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - struct libscols_line *newln = scols_copy_line(ln); - if (!newln) - goto err; - if (scols_table_add_line(ret, newln)) - goto err; - if (ln->parent) { - struct libscols_line *p = - scols_table_get_line(ret, ln->parent->seqnum); - if (p) - scols_line_add_child(p, newln); - } - scols_unref_line(newln); - } - - /* separators */ - if (scols_table_set_column_separator(ret, tb->colsep) || - scols_table_set_line_separator(ret, tb->linesep)) - goto err; - - return ret; -err: - scols_unref_table(ret); - return NULL; -} - -/** - * scols_table_set_default_symbols: - * @tb: table - * - * The library check the current environment to select ASCII or UTF8 symbols. - * This default behavior could be controlled by scols_table_enable_ascii(). - * - * Use scols_table_set_symbols() to unset symbols or use your own setting. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_table_set_default_symbols(struct libscols_table *tb) -{ - struct libscols_symbols *sy; - int rc; - - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "setting default symbols")); - - sy = scols_new_symbols(); - if (!sy) - return -ENOMEM; - -#if defined(HAVE_WIDECHAR) - if (!scols_table_is_ascii(tb) && - !strcmp(nl_langinfo(CODESET), "UTF-8")) { - /* tree chart */ - scols_symbols_set_branch(sy, UTF_VR UTF_H); - scols_symbols_set_vertical(sy, UTF_V " "); - scols_symbols_set_right(sy, UTF_UR UTF_H); - /* groups chart */ - scols_symbols_set_group_horizontal(sy, UTF_H3); - scols_symbols_set_group_vertical(sy, UTF_V3); - - scols_symbols_set_group_first_member(sy, UTF_DR UTF_H3 UTF_TR); - scols_symbols_set_group_last_member(sy, UTF_UR UTF_DH UTF_TR); - scols_symbols_set_group_middle_member(sy, UTF_VR UTF_H3 UTF_TR); - scols_symbols_set_group_last_child(sy, UTF_UR UTF_H3); - scols_symbols_set_group_middle_child(sy, UTF_VR UTF_H3); - } else -#endif - { - /* tree chart */ - scols_symbols_set_branch(sy, "|-"); - scols_symbols_set_vertical(sy, "| "); - scols_symbols_set_right(sy, "`-"); - /* groups chart */ - scols_symbols_set_group_horizontal(sy, "-"); - scols_symbols_set_group_vertical(sy, "|"); - - scols_symbols_set_group_first_member(sy, ",->"); - scols_symbols_set_group_last_member(sy, "'->"); - scols_symbols_set_group_middle_member(sy, "|->"); - scols_symbols_set_group_last_child(sy, "`-"); - scols_symbols_set_group_middle_child(sy, "|-"); - } - scols_symbols_set_title_padding(sy, " "); - scols_symbols_set_cell_padding(sy, " "); - - rc = scols_table_set_symbols(tb, sy); - scols_unref_symbols(sy); - return rc; -} - - -/** - * scols_table_set_symbols: - * @tb: table - * @sy: symbols or NULL - * - * Add a reference to @sy from the table. The symbols are used by library to - * draw tree output. If no symbols are used for the table then library creates - * default temporary symbols to draw output by scols_table_set_default_symbols(). - * - * If @sy is NULL then remove reference from the currently used symbols. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_set_symbols(struct libscols_table *tb, - struct libscols_symbols *sy) -{ - if (!tb) - return -EINVAL; - - /* remove old */ - if (tb->symbols) { - DBG(TAB, ul_debugobj(tb, "remove symbols reference")); - scols_unref_symbols(tb->symbols); - tb->symbols = NULL; - } - - /* set new */ - if (sy) { /* ref user defined */ - DBG(TAB, ul_debugobj(tb, "set symbols")); - tb->symbols = sy; - scols_ref_symbols(sy); - } - return 0; -} - -/** - * scols_table_get_symbols: - * @tb: table - * - * Returns: pointer to symbols table. - * - * Since: 2.29 - */ -struct libscols_symbols *scols_table_get_symbols(const struct libscols_table *tb) -{ - return tb->symbols; -} - -/** - * scols_table_enable_nolinesep: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable line separator printing. This is useful if you want to - * re-printing the same line more than once (e.g. progress bar). Don't use it - * if you're not sure. - * - * Note that for the last line in the table the separator is disabled at all. - * The library differentiate between table terminator and line terminator - * (although for standard output \n byte is used in both cases). - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_nolinesep(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "nolinesep: %s", enable ? "ENABLE" : "DISABLE")); - tb->no_linesep = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_is_nolinesep: - * @tb: a pointer to a struct libscols_table instance - * - * Returns: 1 if line separator printing is disabled. - * - * Since: 2.29 - */ -int scols_table_is_nolinesep(const struct libscols_table *tb) -{ - return tb->no_linesep; -} - -/** - * scols_table_enable_colors: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable colors. - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_colors(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "colors: %s", enable ? "ENABLE" : "DISABLE")); - tb->colors_wanted = enable; - return 0; -} - -/** - * scols_table_enable_raw: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable raw output format. The parsable output formats - * (export, raw, JSON, ...) are mutually exclusive. - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_raw(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "raw: %s", enable ? "ENABLE" : "DISABLE")); - if (enable) - tb->format = SCOLS_FMT_RAW; - else if (tb->format == SCOLS_FMT_RAW) - tb->format = 0; - return 0; -} - -/** - * scols_table_enable_json: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable JSON output format. The parsable output formats - * (export, raw, JSON, ...) are mutually exclusive. - * - * Returns: 0 on success, negative number in case of an error. - * - * Since: 2.27 - */ -int scols_table_enable_json(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "json: %s", enable ? "ENABLE" : "DISABLE")); - if (enable) - tb->format = SCOLS_FMT_JSON; - else if (tb->format == SCOLS_FMT_JSON) - tb->format = 0; - return 0; -} - -/** - * scols_table_enable_export: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable export output format (COLUMNAME="value" ...). - * The parsable output formats (export and raw) are mutually exclusive. - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_export(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "export: %s", enable ? "ENABLE" : "DISABLE")); - if (enable) - tb->format = SCOLS_FMT_EXPORT; - else if (tb->format == SCOLS_FMT_EXPORT) - tb->format = 0; - return 0; -} - -/** - * scols_table_enable_ascii: - * @tb: table - * @enable: 1 or 0 - * - * The ASCII-only output is relevant for tree-like outputs. The library - * checks if the current environment is UTF8 compatible by default. This - * function overrides this check and force the library to use ASCII chars - * for the tree. - * - * If a custom libcols_symbols are specified (see scols_table_set_symbols() - * then ASCII flag setting is ignored. - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_ascii(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "ascii: %s", enable ? "ENABLE" : "DISABLE")); - tb->ascii = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_enable_noheadings: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable header line. - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_noheadings(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - DBG(TAB, ul_debugobj(tb, "noheading: %s", enable ? "ENABLE" : "DISABLE")); - tb->no_headings = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_enable_header_repeat: - * @tb: table - * @enable: 1 or 0 - * - * Enable/disable header line repeat. The header line is printed only once by - * default. Note that the flag will be silently ignored and disabled if the - * output is not on terminal or output format is JSON, raw, etc. - * - * Returns: 0 on success, negative number in case of an error. - * - * Since: 2.31 - */ -int scols_table_enable_header_repeat(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - DBG(TAB, ul_debugobj(tb, "header-repeat: %s", enable ? "ENABLE" : "DISABLE")); - tb->header_repeat = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_enable_maxout: - * @tb: table - * @enable: 1 or 0 - * - * The extra space after last column is ignored by default. The output - * maximization add padding for all columns. - * - * This setting is mutually exclusive to scols_table_enable_minout(). - * - * Returns: 0 on success, negative number in case of an error. - */ -int scols_table_enable_maxout(struct libscols_table *tb, int enable) -{ - if (!tb || tb->minout) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "maxout: %s", enable ? "ENABLE" : "DISABLE")); - tb->maxout = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_enable_minout: - * @tb: table - * @enable: 1 or 0 - * - * Force library to terminate line after last column with data. The extra - * padding is not added to the empty cells at the end of the line. The default is fill - * tailing empty cells except the last line cell. - * - * This setting is mutually exclusive to scols_table_enable_maxout(). - * - * Returns: 0 on success, negative number in case of an error. - * - * Since: 2.35 - */ -int scols_table_enable_minout(struct libscols_table *tb, int enable) -{ - if (!tb || tb->maxout) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "minout: %s", enable ? "ENABLE" : "DISABLE")); - tb->minout = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_enable_nowrap: - * @tb: table - * @enable: 1 or 0 - * - * Never continue on next line, remove last column(s) when too large, truncate last column. - * - * Returns: 0 on success, negative number in case of an error. - * - * Since: 2.28 - */ -int scols_table_enable_nowrap(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - DBG(TAB, ul_debugobj(tb, "nowrap: %s", enable ? "ENABLE" : "DISABLE")); - tb->no_wrap = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_is_nowrap: - * @tb: a pointer to a struct libscols_table instance - * - * Returns: 1 if nowrap is enabled. - * - * Since: 2.29 - */ -int scols_table_is_nowrap(const struct libscols_table *tb) -{ - return tb->no_wrap; -} - -/** - * scols_table_enable_noencoding: - * @tb: table - * @enable: 1 or 0 - * - * The library encode non-printable and control chars by \xHEX by default. - * - * Returns: 0 on success, negative number in case of an error. - * - * Since: 2.31 - */ -int scols_table_enable_noencoding(struct libscols_table *tb, int enable) -{ - if (!tb) - return -EINVAL; - DBG(TAB, ul_debugobj(tb, "encoding: %s", enable ? "ENABLE" : "DISABLE")); - tb->no_encode = enable ? 1 : 0; - return 0; -} - -/** - * scols_table_is_noencoding: - * @tb: a pointer to a struct libscols_table instance - * - * Returns: 1 if encoding is disabled. - * - * Since: 2.31 - */ -int scols_table_is_noencoding(const struct libscols_table *tb) -{ - return tb->no_encode; -} - -/** - * scols_table_colors_wanted: - * @tb: table - * - * Returns: 1 if colors are enabled. - */ -int scols_table_colors_wanted(const struct libscols_table *tb) -{ - return tb->colors_wanted; -} - -/** - * scols_table_is_empty: - * @tb: table - * - * Returns: 1 if the table is empty. - */ -int scols_table_is_empty(const struct libscols_table *tb) -{ - return !tb->nlines; -} - -/** - * scols_table_is_ascii: - * @tb: table - * - * Returns: 1 if ASCII tree is enabled. - */ -int scols_table_is_ascii(const struct libscols_table *tb) -{ - return tb->ascii; -} - -/** - * scols_table_is_noheadings: - * @tb: table - * - * Returns: 1 if header output is disabled. - */ -int scols_table_is_noheadings(const struct libscols_table *tb) -{ - return tb->no_headings; -} - -/** - * scols_table_is_header_repeat - * @tb: table - * - * Returns: 1 if header repeat is enabled. - * - * Since: 2.31 - */ -int scols_table_is_header_repeat(const struct libscols_table *tb) -{ - return tb->header_repeat; -} - -/** - * scols_table_is_export: - * @tb: table - * - * Returns: 1 if export output format is enabled. - */ -int scols_table_is_export(const struct libscols_table *tb) -{ - return tb->format == SCOLS_FMT_EXPORT; -} - -/** - * scols_table_is_raw: - * @tb: table - * - * Returns: 1 if raw output format is enabled. - */ -int scols_table_is_raw(const struct libscols_table *tb) -{ - return tb->format == SCOLS_FMT_RAW; -} - -/** - * scols_table_is_json: - * @tb: table - * - * Returns: 1 if JSON output format is enabled. - * - * Since: 2.27 - */ -int scols_table_is_json(const struct libscols_table *tb) -{ - return tb->format == SCOLS_FMT_JSON; -} - -/** - * scols_table_is_maxout - * @tb: table - * - * Returns: 1 if output maximization is enabled or 0 - */ -int scols_table_is_maxout(const struct libscols_table *tb) -{ - return tb->maxout; -} - -/** - * scols_table_is_minout - * @tb: table - * - * Returns: 1 if output minimization is enabled or 0 - * - * Since: 2.35 - */ -int scols_table_is_minout(const struct libscols_table *tb) -{ - return tb->minout; -} - -/** - * scols_table_is_tree: - * @tb: table - * - * Returns: returns 1 tree-like output is expected. - */ -int scols_table_is_tree(const struct libscols_table *tb) -{ - return tb->ntreecols > 0; -} - -/** - * scols_table_set_column_separator: - * @tb: table - * @sep: separator - * - * Sets the column separator of @tb to @sep. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_set_column_separator(struct libscols_table *tb, const char *sep) -{ - return strdup_to_struct_member(tb, colsep, sep); -} - -/** - * scols_table_set_line_separator: - * @tb: table - * @sep: separator - * - * Sets the line separator of @tb to @sep. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_table_set_line_separator(struct libscols_table *tb, const char *sep) -{ - return strdup_to_struct_member(tb, linesep, sep); -} - -/** - * scols_table_get_column_separator: - * @tb: table - * - * Returns: @tb column separator, NULL in case of an error - */ -const char *scols_table_get_column_separator(const struct libscols_table *tb) -{ - return tb->colsep; -} - -/** - * scols_table_get_line_separator: - * @tb: table - * - * Returns: @tb line separator, NULL in case of an error - */ -const char *scols_table_get_line_separator(const struct libscols_table *tb) -{ - return tb->linesep; -} -/* for lines in the struct libscols_line->ln_lines list */ -static int cells_cmp_wrapper_lines(struct list_head *a, struct list_head *b, void *data) -{ - struct libscols_column *cl = (struct libscols_column *) data; - struct libscols_line *ra, *rb; - struct libscols_cell *ca, *cb; - - assert(a); - assert(b); - assert(cl); - - ra = list_entry(a, struct libscols_line, ln_lines); - rb = list_entry(b, struct libscols_line, ln_lines); - ca = scols_line_get_cell(ra, cl->seqnum); - cb = scols_line_get_cell(rb, cl->seqnum); - - return cl->cmpfunc(ca, cb, cl->cmpfunc_data); -} - -/* for lines in the struct libscols_line->ln_children list */ -static int cells_cmp_wrapper_children(struct list_head *a, struct list_head *b, void *data) -{ - struct libscols_column *cl = (struct libscols_column *) data; - struct libscols_line *ra, *rb; - struct libscols_cell *ca, *cb; - - assert(a); - assert(b); - assert(cl); - - ra = list_entry(a, struct libscols_line, ln_children); - rb = list_entry(b, struct libscols_line, ln_children); - ca = scols_line_get_cell(ra, cl->seqnum); - cb = scols_line_get_cell(rb, cl->seqnum); - - return cl->cmpfunc(ca, cb, cl->cmpfunc_data); -} - - -static int sort_line_children(struct libscols_line *ln, struct libscols_column *cl) -{ - struct list_head *p; - - if (!list_empty(&ln->ln_branch)) { - list_for_each(p, &ln->ln_branch) { - struct libscols_line *chld = - list_entry(p, struct libscols_line, ln_children); - sort_line_children(chld, cl); - } - - list_sort(&ln->ln_branch, cells_cmp_wrapper_children, cl); - } - - if (is_first_group_member(ln)) { - list_for_each(p, &ln->group->gr_children) { - struct libscols_line *chld = - list_entry(p, struct libscols_line, ln_children); - sort_line_children(chld, cl); - } - - list_sort(&ln->group->gr_children, cells_cmp_wrapper_children, cl); - } - - return 0; -} - -/** - * scols_sort_table: - * @tb: table - * @cl: order by this column - * - * Orders the table by the column. See also scols_column_set_cmpfunc(). If the - * tree output is enabled then children in the tree are recursively sorted too. - * - * Returns: 0, a negative value in case of an error. - */ -int scols_sort_table(struct libscols_table *tb, struct libscols_column *cl) -{ - if (!tb || !cl || !cl->cmpfunc) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "sorting table")); - list_sort(&tb->tb_lines, cells_cmp_wrapper_lines, cl); - - if (scols_table_is_tree(tb)) { - struct libscols_line *ln; - struct libscols_iter itr; - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) - sort_line_children(ln, cl); - } - - return 0; -} - -static struct libscols_line *move_line_and_children(struct libscols_line *ln, struct libscols_line *pre) -{ - if (pre) { - list_del_init(&ln->ln_lines); /* remove from old position */ - list_add(&ln->ln_lines, &pre->ln_lines); /* add to the new place (behind @pre) */ - } - pre = ln; - - if (!list_empty(&ln->ln_branch)) { - struct list_head *p; - - list_for_each(p, &ln->ln_branch) { - struct libscols_line *chld = - list_entry(p, struct libscols_line, ln_children); - pre = move_line_and_children(chld, pre); - } - } - - return pre; -} - -/** - * scols_sort_table_by_tree: - * @tb: table - * - * Reorders lines in the table by parent->child relation. Note that order of - * the lines in the table is independent on the tree hierarchy. - * - * Since: 2.30 - * - * Returns: 0, a negative value in case of an error. - */ -int scols_sort_table_by_tree(struct libscols_table *tb) -{ - struct libscols_line *ln; - struct libscols_iter itr; - - if (!tb) - return -EINVAL; - - DBG(TAB, ul_debugobj(tb, "sorting table by tree")); - - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - if (ln->parent) - continue; - - move_line_and_children(ln, NULL); - } - - return 0; -} - - -/** - * scols_table_set_termforce: - * @tb: table - * @force: SCOLS_TERMFORCE_{NEVER,ALWAYS,AUTO} - * - * Forces library to use stdout as terminal, non-terminal or use automatic - * detection (default). - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_table_set_termforce(struct libscols_table *tb, int force) -{ - if (!tb) - return -EINVAL; - tb->termforce = force; - return 0; -} - -/** - * scols_table_get_termforce: - * @tb: table - * - * Returns: SCOLS_TERMFORCE_{NEVER,ALWAYS,AUTO} or a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_table_get_termforce(const struct libscols_table *tb) -{ - return tb->termforce; -} - -/** - * scols_table_set_termwidth - * @tb: table - * @width: terminal width - * - * The library automatically detects terminal width or defaults to 80 chars if - * detections is unsuccessful. This function override this behaviour. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.29 - */ -int scols_table_set_termwidth(struct libscols_table *tb, size_t width) -{ - DBG(TAB, ul_debugobj(tb, "set terminatl width: %zu", width)); - tb->termwidth = width; - return 0; -} - -/** - * scols_table_get_termwidth - * @tb: table - * - * Returns: terminal width. - */ -size_t scols_table_get_termwidth(const struct libscols_table *tb) -{ - return tb->termwidth; -} - -/** - * scols_table_set_termheight - * @tb: table - * @height: terminal height (number of lines) - * - * The library automatically detects terminal height or defaults to 24 lines if - * detections is unsuccessful. This function override this behaviour. - * - * Returns: 0, a negative value in case of an error. - * - * Since: 2.31 - */ -int scols_table_set_termheight(struct libscols_table *tb, size_t height) -{ - DBG(TAB, ul_debugobj(tb, "set terminatl height: %zu", height)); - tb->termheight = height; - return 0; -} - -/** - * scols_table_get_termheight - * @tb: table - * - * Returns: terminal height (number of lines). - * - * Since: 2.31 - */ -size_t scols_table_get_termheight(const struct libscols_table *tb) -{ - return tb->termheight; -} diff --git a/utils/libsmartcols/src/version.c b/utils/libsmartcols/src/version.c deleted file mode 100644 index e592ccc..0000000 --- a/utils/libsmartcols/src/version.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * version.c - Return the version of the library - * - * Copyright (C) 2014 Karel Zak <kzak@redhat.com> - * - * See COPYING.libmount for the License of this software. - */ - -/** - * SECTION: version-utils - * @title: Version functions - * @short_description: functions to get the library version. - * - * Note that library version is not the same thing as SONAME version. The - * libsmarcols uses symbols versioning and SONAME is not modified for releases. - * - * The library version and symbols version follow util-linux package versioning. - */ - -#include <ctype.h> - -#include "smartcolsP.h" - -static const char *lib_version = LIBSMARTCOLS_VERSION; - -/** - * scols_parse_version_string: - * @ver_string: version string (e.g "2.18.0") - * - * Returns: release version code. - */ -int scols_parse_version_string(const char *ver_string) -{ - const char *cp; - int version = 0; - - assert(ver_string); - - for (cp = ver_string; *cp; cp++) { - if (*cp == '.') - continue; - if (!isdigit(*cp)) - break; - version = (version * 10) + (*cp - '0'); - } - return version; -} - -/** - * scols_get_library_version: - * @ver_string: return pointer to the static library version string if not NULL - * - * Returns: release version number. - */ -int scols_get_library_version(const char **ver_string) -{ - if (ver_string) - *ver_string = lib_version; - - return scols_parse_version_string(lib_version); -} - diff --git a/utils/libsmartcols/src/walk.c b/utils/libsmartcols/src/walk.c deleted file mode 100644 index a75fde6..0000000 --- a/utils/libsmartcols/src/walk.c +++ /dev/null @@ -1,152 +0,0 @@ -#include "smartcolsP.h" - -static int walk_line(struct libscols_table *tb, - struct libscols_line *ln, - struct libscols_column *cl, - int (*callback)(struct libscols_table *, - struct libscols_line *, - struct libscols_column *, - void *), - void *data) -{ - int rc = 0; - - DBG(LINE, ul_debugobj(ln, " wall line")); - - /* we list group children in __scols_print_tree() after tree root node */ - if (is_group_member(ln) && is_last_group_member(ln) && has_group_children(ln)) - tb->ngrpchlds_pending++; - - if (has_groups(tb)) - rc = scols_groups_update_grpset(tb, ln); - if (rc == 0) - rc = callback(tb, ln, cl, data); - - /* children */ - if (rc == 0 && has_children(ln)) { - struct list_head *p; - - DBG(LINE, ul_debugobj(ln, " children walk")); - - list_for_each(p, &ln->ln_branch) { - struct libscols_line *chld = list_entry(p, - struct libscols_line, ln_children); - - rc = walk_line(tb, chld, cl, callback, data); - if (rc) - break; - } - } - - DBG(LINE, ul_debugobj(ln, "<- walk line done [rc=%d]", rc)); - return rc; -} - -/* last line in the tree? */ -int scols_walk_is_last(struct libscols_table *tb, struct libscols_line *ln) -{ - if (tb->walk_last_done == 0) - return 0; - if (tb->ngrpchlds_pending > 0) - return 0; - if (has_children(ln)) - return 0; - if (is_tree_root(ln) && !is_last_tree_root(tb, ln)) - return 0; - if (is_group_member(ln) && (!is_last_group_member(ln) || has_group_children(ln))) - return 0; - if (is_child(ln)) { - struct libscols_line *parent = ln->parent; - - if (!is_last_child(ln)) - return 0; - while (parent) { - if (is_child(parent) && !is_last_child(parent)) - return 0; - if (!parent->parent) - break; - parent = parent->parent; - } - if (is_tree_root(parent) && !is_last_tree_root(tb, parent)) - return 0; - } - if (is_group_child(ln) && !is_last_group_child(ln)) - return 0; - - DBG(LINE, ul_debugobj(ln, "last in table")); - return 1; -} - -int scols_walk_tree(struct libscols_table *tb, - struct libscols_column *cl, - int (*callback)(struct libscols_table *, - struct libscols_line *, - struct libscols_column *, - void *), - void *data) -{ - int rc = 0; - struct libscols_line *ln; - struct libscols_iter itr; - - assert(tb); - DBG(TAB, ul_debugobj(tb, ">> walk start")); - - /* init */ - tb->ngrpchlds_pending = 0; - tb->walk_last_tree_root = NULL; - tb->walk_last_done = 0; - - if (has_groups(tb)) - scols_groups_reset_state(tb); - - /* set pointer to last tree root */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (scols_table_next_line(tb, &itr, &ln) == 0) { - if (!tb->walk_last_tree_root) - tb->walk_last_tree_root = ln; - if (is_child(ln) || is_group_child(ln)) - continue; - tb->walk_last_tree_root = ln; - } - - /* walk */ - scols_reset_iter(&itr, SCOLS_ITER_FORWARD); - while (rc == 0 && scols_table_next_line(tb, &itr, &ln) == 0) { - if (ln->parent || ln->parent_group) - continue; - - if (tb->walk_last_tree_root == ln) - tb->walk_last_done = 1; - rc = walk_line(tb, ln, cl, callback, data); - - /* walk group's children */ - while (rc == 0 && tb->ngrpchlds_pending) { - struct libscols_group *gr = scols_grpset_get_printable_children(tb); - struct list_head *p; - - DBG(LINE, ul_debugobj(ln, " walk group children [pending=%zu]", tb->ngrpchlds_pending)); - if (!gr) { - DBG(LINE, ul_debugobj(ln, " *** ngrpchlds_pending counter invalid")); - tb->ngrpchlds_pending = 0; - break; - } - - tb->ngrpchlds_pending--; - - list_for_each(p, &gr->gr_children) { - struct libscols_line *chld = - list_entry(p, struct libscols_line, ln_children); - - rc = walk_line(tb, chld, cl, callback, data); - if (rc) - break; - } - } - } - - tb->ngrpchlds_pending = 0; - tb->walk_last_done = 0; - DBG(TAB, ul_debugobj(tb, "<< walk end [rc=%d]", rc)); - return rc; -} |