summaryrefslogtreecommitdiffstats
path: root/libsmartcols/src/smartcolsP.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--libsmartcols/src/smartcolsP.h449
1 files changed, 449 insertions, 0 deletions
diff --git a/libsmartcols/src/smartcolsP.h b/libsmartcols/src/smartcolsP.h
new file mode 100644
index 0000000..8b83a14
--- /dev/null
+++ b/libsmartcols/src/smartcolsP.h
@@ -0,0 +1,449 @@
+/*
+ * 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 "jsonwrt.h"
+#include "debug.h"
+#include "buffer.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"
+
+#define SCOLS_BUFPTR_TREEEND 0
+
+/*
+ * 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; /* column name with color etc. */
+ char *shellvar; /* raw colum name in shell compatible format */
+
+ struct list_head cl_columns; /* member of table->tb_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; /* list of columns, items: column->cl_columns */
+ struct list_head tb_lines; /* list of lines; items: line->ln_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_column *dflt_sort_column; /* default sort column, set by scols_sort_table() */
+
+ struct libscols_symbols *symbols;
+ struct libscols_cell title; /* optional table title (for humans) */
+
+ struct ul_jsonwrt json; /* JSON formatting */
+
+ int format; /* SCOLS_FMT_* */
+
+ size_t termlines_used; /* printed line counter */
+ size_t header_next; /* where repeat header */
+
+ const char *cur_color; /* current active color when printing */
+
+ /* 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 */
+ is_shellvar :1, /* shell compatible column names */
+ 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);
+
+/*
+ * 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 ul_buffer *buf);
+
+/*
+ * print.c
+ */
+extern int __cell_to_buffer(struct libscols_table *tb,
+ struct libscols_line *ln,
+ struct libscols_column *cl,
+ struct ul_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 ul_buffer *buf,
+ struct libscols_iter *itr,
+ struct libscols_line *end);
+
+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 */