+++ /dev/null
-
-#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;
- if (!buf->cur || !buf->begin)
- return -EINVAL;
-
- 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;
-}
/* 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)
+ struct ul_buffer *buf)
{
const char *art;
int rc;
else
art = vertical_symbol(tb);
- return buffer_append_data(buf, art);
+ return ul_buffer_append_string(buf, art);
}
static int grpset_is_empty( struct libscols_table *tb,
static int groups_ascii_art_to_buffer( struct libscols_table *tb,
struct libscols_line *ln,
- struct libscols_buffer *buf)
+ struct ul_buffer *buf)
{
int filled = 0;
size_t i, rest = 0;
struct libscols_group *gr = tb->grpset[i];
if (!gr) {
- buffer_append_ntimes(buf, SCOLS_GRPSET_CHUNKSIZ, cellpadding_symbol(tb));
+ ul_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));
+ ul_buffer_append_string(buf, grp_m_first_symbol(tb));
break;
case SCOLS_GSTATE_MIDDLE_MEMBER:
- buffer_append_data(buf, grp_m_middle_symbol(tb));
+ ul_buffer_append_string(buf, grp_m_middle_symbol(tb));
break;
case SCOLS_GSTATE_LAST_MEMBER:
- buffer_append_data(buf, grp_m_last_symbol(tb));
+ ul_buffer_append_string(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);
+ ul_buffer_append_string(buf, grp_vertical_symbol(tb));
+ ul_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));
+ ul_buffer_append_string(buf, filler);
+ ul_buffer_append_string(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));
+ ul_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));
+ ul_buffer_append_string(buf, cellpadding_symbol(tb));
+ ul_buffer_append_string(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));
+ ul_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);
+ ul_buffer_append_string(buf, filler);
+ ul_buffer_append_string(buf, grp_vertical_symbol(tb));
+ ul_buffer_append_string(buf, filler);
break;
}
}
if (!filled)
- buffer_append_data(buf, filler);
+ ul_buffer_append_string(buf, filler);
return 0;
}
}
} else {
/* use the same draw function as though we were intending to draw an L-shape */
- struct libscols_buffer *art = new_buffer(bufsz);
+ struct ul_buffer art = UL_INIT_BUFFER;
char *data;
- if (art) {
+ if (ul_buffer_alloc_data(&art, bufsz) == 0) {
/* whatever the rc, len_pad will be sensible */
- tree_ascii_art_to_buffer(tb, ln, art);
+ 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);
+ ul_buffer_append_string(&art, vertical_symbol(tb));
+
+ if (scols_table_is_noencoding(tb))
+ data = ul_buffer_get_data(&art, NULL, &len_pad);
+ else
+ data = ul_buffer_get_safe_data(&art, NULL, &len_pad, NULL);
+
if (data && len_pad)
fputs(data, tb->out);
- free_buffer(art);
+ ul_buffer_free_data(&art);
}
}
}
struct libscols_column *cl,
struct libscols_line *ln, /* optional */
struct libscols_cell *ce, /* optional */
- struct libscols_buffer *buf)
+ struct ul_buffer *buf)
{
size_t len = 0, i, width, bytes;
char *data, *nextchunk;
assert(tb);
assert(cl);
- data = buffer_get_data(buf);
+ data = ul_buffer_get_data(buf, NULL, NULL);
if (!data)
data = "";
/* 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 (scols_table_is_noencoding(tb))
+ data = ul_buffer_get_data(buf, &bytes, &len);
+ else
+ data = ul_buffer_get_safe_data(buf, &bytes, &len, scols_column_get_safechars(cl));
+
if (!data)
data = "";
- bytes = strlen(data);
width = cl->width;
/* custom multi-line cell based */
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, ce, buffer_get_size(buf)); /* next column starts on next line */
+ print_newline_padding(tb, cl, ln, ce, ul_buffer_get_bufsiz(buf)); /* next column starts on next line */
} else if (!is_last)
fputs(colsep(tb), tb->out); /* columns separator */
int __cell_to_buffer(struct libscols_table *tb,
struct libscols_line *ln,
struct libscols_column *cl,
- struct libscols_buffer *buf)
+ struct ul_buffer *buf)
{
const char *data;
struct libscols_cell *ce;
assert(buf);
assert(cl->seqnum <= tb->ncols);
- buffer_reset_data(buf);
+ ul_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;
+ return data ? ul_buffer_append_string(buf, data) : 0;
/*
* Group stuff
rc = tree_ascii_art_to_buffer(tb, ln->parent, buf);
if (!rc && is_last_child(ln))
- rc = buffer_append_data(buf, right_symbol(tb));
+ rc = ul_buffer_append_string(buf, right_symbol(tb));
else if (!rc)
- rc = buffer_append_data(buf, branch_symbol(tb));
+ rc = ul_buffer_append_string(buf, branch_symbol(tb));
}
if (!rc && (ln->parent || cl->is_groups) && !scols_table_is_json(tb))
- buffer_set_art_index(buf);
+ ul_buffer_save_pointer(buf, SCOLS_BUFPTR_TREEEND);
if (!rc && data)
- rc = buffer_append_data(buf, data);
+ rc = ul_buffer_append_string(buf, data);
return rc;
}
*/
static int print_line(struct libscols_table *tb,
struct libscols_line *ln,
- struct libscols_buffer *buf)
+ struct ul_buffer *buf)
{
int rc = 0, pending = 0;
struct libscols_column *cl;
assert(ln);
- DBG(LINE, ul_debugobj(ln, "printing line"));
+ DBG(LINE, ul_debugobj(ln, " printing line"));
fputs_color_line_open(tb, ln);
if (rc == 0 && cl->pending_data)
pending = 1;
} else
- print_empty_cell(tb, cl, ln, NULL, buffer_get_size(buf));
+ print_empty_cell(tb, cl, ln, NULL, ul_buffer_get_bufsiz(buf));
}
fputs_color_line_close(tb);
}
return rc;
}
-int __scols_print_header(struct libscols_table *tb, struct libscols_buffer *buf)
+int __scols_print_header(struct libscols_table *tb, struct ul_buffer *buf)
{
int rc = 0;
struct libscols_column *cl;
if (scols_column_is_hidden(cl))
continue;
- buffer_reset_data(buf);
+ ul_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, " ");
+ rc = ul_buffer_append_data(buf, " ", 1);
if (rc)
break;
}
}
if (!rc)
- rc = buffer_append_data(buf, scols_cell_get_data(&cl->header));
+ rc = ul_buffer_append_string(buf, scols_cell_get_data(&cl->header));
if (!rc)
rc = print_data(tb, cl, NULL, &cl->header, buf);
}
int __scols_print_range(struct libscols_table *tb,
- struct libscols_buffer *buf,
+ struct ul_buffer *buf,
struct libscols_iter *itr,
struct libscols_line *end)
{
}
-int __scols_print_table(struct libscols_table *tb, struct libscols_buffer *buf)
+int __scols_print_table(struct libscols_table *tb, struct ul_buffer *buf)
{
struct libscols_iter itr;
struct libscols_column *cl __attribute__((__unused__)),
void *data)
{
- struct libscols_buffer *buf = (struct libscols_buffer *) data;
+ struct ul_buffer *buf = (struct ul_buffer *) data;
int rc;
DBG(LINE, ul_debugobj(ln, " printing tree line"));
return 0;
}
-int __scols_print_tree(struct libscols_table *tb, struct libscols_buffer *buf)
+int __scols_print_tree(struct libscols_table *tb, struct ul_buffer *buf)
{
assert(tb);
DBG(TAB, ul_debugobj(tb, "----printing-tree-----"));
return sz;
}
-void __scols_cleanup_printing(struct libscols_table *tb, struct libscols_buffer *buf)
+void __scols_cleanup_printing(struct libscols_table *tb, struct ul_buffer *buf)
{
if (!tb)
return;
- free_buffer(buf);
+ ul_buffer_free_data(buf);
if (tb->priv_symbols) {
scols_table_set_symbols(tb, NULL);
}
}
-int __scols_initialize_printing(struct libscols_table *tb, struct libscols_buffer **buf)
+int __scols_initialize_printing(struct libscols_table *tb, struct ul_buffer *buf)
{
size_t bufsz, extra_bufsz = 0;
struct libscols_line *ln;
int rc;
DBG(TAB, ul_debugobj(tb, "initialize printing"));
- *buf = NULL;
if (!tb->symbols) {
rc = scols_table_set_default_symbols(tb);
bufsz = sz;
}
- *buf = new_buffer(bufsz + 1); /* data + space for \0 */
- if (!*buf) {
- rc = -ENOMEM;
+ /* pre-allocate space for data */
+ rc = ul_buffer_alloc_data(buf, bufsz + 1); /* data + space for \0 */
+ if (rc)
goto err;
- }
/*
* Make sure groups members are in the same orders as the tree
scols_groups_fix_members_order(tb);
if (tb->format == SCOLS_FMT_HUMAN) {
- rc = __scols_calculate(tb, *buf);
+ rc = __scols_calculate(tb, buf);
if (rc != 0)
goto err;
}
return 0;
err:
- __scols_cleanup_printing(tb, *buf);
+ __scols_cleanup_printing(tb, buf);
return rc;
}
#include "color-names.h"
#include "jsonwrt.h"
#include "debug.h"
+#include "buffer.h"
#include "libsmartcols.h"
#define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(libsmartcols)
#include "debugobj.h"
+#define SCOLS_BUFPTR_TREEEND 0
+
/*
* Generic iterator
*/
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
*/
/*
* calculate.c
*/
-extern int __scols_calculate(struct libscols_table *tb, struct libscols_buffer *buf);
+extern int __scols_calculate(struct libscols_table *tb, struct ul_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);
+ struct ul_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);
+void __scols_cleanup_printing(struct libscols_table *tb, struct ul_buffer *buf);
+int __scols_initialize_printing(struct libscols_table *tb, struct ul_buffer *buf);
+int __scols_print_tree(struct libscols_table *tb, struct ul_buffer *buf);
+int __scols_print_table(struct libscols_table *tb, struct ul_buffer *buf);
+int __scols_print_header(struct libscols_table *tb, struct ul_buffer *buf);
int __scols_print_title(struct libscols_table *tb);
int __scols_print_range(struct libscols_table *tb,
- struct libscols_buffer *buf,
+ struct ul_buffer *buf,
struct libscols_iter *itr,
struct libscols_line *end);