2 * smartcolsP.h - private library header file
4 * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com>
5 * Copyright (C) 2014 Karel Zak <kzak@redhat.com>
7 * This file may be redistributed under the terms of the
8 * GNU Lesser General Public License.
11 #ifndef _LIBSMARTCOLS_PRIVATE_H
12 #define _LIBSMARTCOLS_PRIVATE_H
17 #include "color-names.h"
20 #include "libsmartcols.h"
25 #define SCOLS_DEBUG_HELP (1 << 0)
26 #define SCOLS_DEBUG_INIT (1 << 1)
27 #define SCOLS_DEBUG_CELL (1 << 2)
28 #define SCOLS_DEBUG_LINE (1 << 3)
29 #define SCOLS_DEBUG_TAB (1 << 4)
30 #define SCOLS_DEBUG_COL (1 << 5)
31 #define SCOLS_DEBUG_BUFF (1 << 6)
32 #define SCOLS_DEBUG_GROUP (1 << 7)
33 #define SCOLS_DEBUG_ALL 0xFFFF
35 UL_DEBUG_DECLARE_MASK(libsmartcols
);
36 #define DBG(m, x) __UL_DBG(libsmartcols, SCOLS_DEBUG_, m, x)
37 #define ON_DBG(m, x) __UL_DBG_CALL(libsmartcols, SCOLS_DEBUG_, m, x)
38 #define DBG_FLUSH __UL_DBG_FLUSH(libsmartcols, SCOLS_DEBUG_)
40 #define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(libsmartcols)
46 struct libscols_iter
{
47 struct list_head
*p
; /* current position */
48 struct list_head
*head
; /* start position */
49 int direction
; /* SCOLS_ITER_{FOR,BACK}WARD */
55 struct libscols_symbols
{
64 char *group_first_member
;
65 char *group_last_member
;
66 char *group_middle_member
;
67 char *group_last_child
;
68 char *group_middle_child
;
77 struct libscols_cell
{
84 extern int scols_line_move_cells(struct libscols_line
*ln
, size_t newn
, size_t oldn
);
89 struct libscols_column
{
90 int refcount
; /* reference counter */
91 size_t seqnum
; /* column index */
93 size_t width
; /* real column width */
94 size_t width_min
; /* minimal width (usually header width) */
95 size_t width_max
; /* maximal width */
96 size_t width_avg
; /* average width, used to detect extreme fields */
97 size_t width_treeart
; /* size of the tree ascii art */
98 double width_hint
; /* hint (N < 1 is in percent of termwidth) */
103 int json_type
; /* SCOLS_JSON_* */
106 char *color
; /* default column color */
107 char *safechars
; /* do not encode this bytes */
110 size_t pending_data_sz
;
111 char *pending_data_buf
;
113 int (*cmpfunc
)(struct libscols_cell
*,
114 struct libscols_cell
*,
115 void *); /* cells comparison function */
118 size_t (*wrap_chunksize
)(const struct libscols_column
*,
119 const char *, void *);
120 char *(*wrap_nextchunk
)(const struct libscols_column
*,
125 struct libscols_cell header
;
126 struct list_head cl_columns
;
128 struct libscols_table
*table
;
130 unsigned int is_extreme
: 1, /* extreme width in the column */
131 is_groups
: 1; /* print group chart */
135 #define colsep(tb) ((tb)->colsep ? (tb)->colsep : " ")
136 #define linesep(tb) ((tb)->linesep ? (tb)->linesep : "\n")
139 SCOLS_GSTATE_NONE
= 0, /* not activate yet */
140 SCOLS_GSTATE_FIRST_MEMBER
,
141 SCOLS_GSTATE_MIDDLE_MEMBER
,
142 SCOLS_GSTATE_LAST_MEMBER
,
143 SCOLS_GSTATE_MIDDLE_CHILD
,
144 SCOLS_GSTATE_LAST_CHILD
,
145 SCOLS_GSTATE_CONT_MEMBERS
,
146 SCOLS_GSTATE_CONT_CHILDREN
150 * Every group needs at least 3 columns
152 #define SCOLS_GRPSET_CHUNKSIZ 3
154 struct libscols_group
{
159 struct list_head gr_members
; /* head of line->ln_group */
160 struct list_head gr_children
; /* head of line->ln_children */
161 struct list_head gr_groups
; /* member of table->tb_groups */
163 int state
; /* SCOLS_GSTATE_* */
169 struct libscols_line
{
174 char *color
; /* default line color */
176 struct libscols_cell
*cells
; /* array with data */
177 size_t ncells
; /* number of cells */
179 struct list_head ln_lines
; /* member of table->tb_lines */
180 struct list_head ln_branch
; /* head of line->ln_children */
181 struct list_head ln_children
; /* member of line->ln_children or group->gr_children */
182 struct list_head ln_groups
; /* member of group->gr_groups */
184 struct libscols_line
*parent
;
185 struct libscols_group
*parent_group
; /* for group childs */
186 struct libscols_group
*group
; /* for group members */
190 SCOLS_FMT_HUMAN
= 0, /* default, human readable */
191 SCOLS_FMT_RAW
, /* space separated */
192 SCOLS_FMT_EXPORT
, /* COLNAME="data" ... */
193 SCOLS_FMT_JSON
/* http://en.wikipedia.org/wiki/JSON */
199 struct libscols_table
{
201 char *name
; /* optional table name (for JSON) */
202 size_t ncols
; /* number of columns */
203 size_t ntreecols
; /* number of columns with SCOLS_FL_TREE */
204 size_t nlines
; /* number of lines */
205 size_t termwidth
; /* terminal width (number of columns) */
206 size_t termheight
; /* terminal height (number of lines) */
207 size_t termreduce
; /* extra blank space */
208 int termforce
; /* SCOLS_TERMFORCE_* */
209 FILE *out
; /* output stream */
211 char *colsep
; /* column separator */
212 char *linesep
; /* line separator */
214 struct list_head tb_columns
;
215 struct list_head tb_lines
;
217 struct list_head tb_groups
; /* all defined groups */
218 struct libscols_group
**grpset
;
221 size_t ngrpchlds_pending
; /* groups with not yet printed children */
222 struct libscols_line
*walk_last_tree_root
; /* last root, used by scols_walk_() */
224 struct libscols_symbols
*symbols
;
225 struct libscols_cell title
; /* optional table title (for humans) */
227 int indent
; /* indentation counter */
228 int indent_last_sep
;/* last printed has been line separator */
229 int format
; /* SCOLS_FMT_* */
231 size_t termlines_used
; /* printed line counter */
232 size_t header_next
; /* where repeat header */
235 unsigned int ascii
:1, /* don't use unicode */
236 colors_wanted
:1, /* enable colors */
237 is_term
:1, /* isatty() */
238 padding_debug
:1, /* output visible padding chars */
239 is_dummy_print
:1, /* printing used for width calcualion only */
240 maxout
:1, /* maximize output */
241 header_repeat
:1, /* print header after libscols_table->termheight */
242 header_printed
:1, /* header already printed */
243 priv_symbols
:1, /* default private symbols */
244 walk_last_done
:1, /* last tree root walked */
245 no_headings
:1, /* don't print header */
246 no_encode
:1, /* don't care about control and non-printable chars */
247 no_linesep
:1, /* don't print line separator */
248 no_wrap
:1; /* never wrap lines */
251 #define IS_ITER_FORWARD(_i) ((_i)->direction == SCOLS_ITER_FORWARD)
252 #define IS_ITER_BACKWARD(_i) ((_i)->direction == SCOLS_ITER_BACKWARD)
254 #define SCOLS_ITER_INIT(itr, list) \
256 (itr)->p = IS_ITER_FORWARD(itr) ? \
257 (list)->next : (list)->prev; \
258 (itr)->head = (list); \
261 #define SCOLS_ITER_ITERATE(itr, res, restype, member) \
263 res = list_entry((itr)->p, restype, member); \
264 (itr)->p = IS_ITER_FORWARD(itr) ? \
265 (itr)->p->next : (itr)->p->prev; \
269 static inline int scols_iter_is_last(const struct libscols_iter
*itr
)
271 if (!itr
|| !itr
->head
|| !itr
->p
)
274 return itr
->p
== itr
->head
;
280 int scols_line_next_group_child(struct libscols_line
*ln
,
281 struct libscols_iter
*itr
,
282 struct libscols_line
**chld
);
288 int scols_table_next_group(struct libscols_table
*tb
,
289 struct libscols_iter
*itr
,
290 struct libscols_group
**gr
);
295 struct libscols_buffer
;
296 extern struct libscols_buffer
*new_buffer(size_t sz
);
297 extern void free_buffer(struct libscols_buffer
*buf
);
298 extern int buffer_reset_data(struct libscols_buffer
*buf
);
299 extern int buffer_append_data(struct libscols_buffer
*buf
, const char *str
);
300 extern int buffer_append_ntimes(struct libscols_buffer
*buf
, size_t n
, const char *str
);
301 extern int buffer_set_data(struct libscols_buffer
*buf
, const char *str
);
302 extern void buffer_set_art_index(struct libscols_buffer
*buf
);
303 extern char *buffer_get_data(struct libscols_buffer
*buf
);
304 extern size_t buffer_get_size(struct libscols_buffer
*buf
);
305 extern char *buffer_get_safe_data(struct libscols_table
*tb
,
306 struct libscols_buffer
*buf
,
308 const char *safechars
);
309 extern size_t buffer_get_safe_art_size(struct libscols_buffer
*buf
);
314 void scols_ref_group(struct libscols_group
*gr
);
315 void scols_group_remove_children(struct libscols_group
*gr
);
316 void scols_group_remove_members(struct libscols_group
*gr
);
317 void scols_unref_group(struct libscols_group
*gr
);
318 void scols_groups_fix_members_order(struct libscols_table
*tb
);
319 int scols_groups_update_grpset(struct libscols_table
*tb
, struct libscols_line
*ln
);
320 void scols_groups_reset_state(struct libscols_table
*tb
);
321 struct libscols_group
*scols_grpset_get_printable_children(struct libscols_table
*tb
);
326 extern int scols_walk_tree(struct libscols_table
*tb
,
327 struct libscols_column
*cl
,
328 int (*callback
)(struct libscols_table
*,
329 struct libscols_line
*,
330 struct libscols_column
*,
333 extern int scols_walk_is_last(struct libscols_table
*tb
, struct libscols_line
*ln
);
338 extern int __scols_calculate(struct libscols_table
*tb
, struct libscols_buffer
*buf
);
343 extern int __cell_to_buffer(struct libscols_table
*tb
,
344 struct libscols_line
*ln
,
345 struct libscols_column
*cl
,
346 struct libscols_buffer
*buf
);
348 void __scols_cleanup_printing(struct libscols_table
*tb
, struct libscols_buffer
*buf
);
349 int __scols_initialize_printing(struct libscols_table
*tb
, struct libscols_buffer
**buf
);
350 int __scols_print_tree(struct libscols_table
*tb
, struct libscols_buffer
*buf
);
351 int __scols_print_table(struct libscols_table
*tb
, struct libscols_buffer
*buf
);
352 int __scols_print_header(struct libscols_table
*tb
, struct libscols_buffer
*buf
);
353 int __scols_print_title(struct libscols_table
*tb
);
354 int __scols_print_range(struct libscols_table
*tb
,
355 struct libscols_buffer
*buf
,
356 struct libscols_iter
*itr
,
357 struct libscols_line
*end
);
362 extern void fput_indent(struct libscols_table
*tb
);
363 extern void fput_table_open(struct libscols_table
*tb
);
364 extern void fput_table_close(struct libscols_table
*tb
);
365 extern void fput_children_open(struct libscols_table
*tb
);
366 extern void fput_children_close(struct libscols_table
*tb
);
367 extern void fput_line_open(struct libscols_table
*tb
);
368 extern void fput_line_close(struct libscols_table
*tb
, int last
, int last_in_table
);
370 static inline int is_tree_root(struct libscols_line
*ln
)
372 return ln
&& !ln
->parent
&& !ln
->parent_group
;
375 static inline int is_last_tree_root(struct libscols_table
*tb
, struct libscols_line
*ln
)
377 if (!ln
|| !tb
|| tb
->walk_last_tree_root
!= ln
)
383 static inline int is_child(struct libscols_line
*ln
)
385 return ln
&& ln
->parent
;
388 static inline int is_last_child(struct libscols_line
*ln
)
390 if (!ln
|| !ln
->parent
)
393 return list_entry_is_last(&ln
->ln_children
, &ln
->parent
->ln_branch
);
396 static inline int is_first_child(struct libscols_line
*ln
)
398 if (!ln
|| !ln
->parent
)
401 return list_entry_is_first(&ln
->ln_children
, &ln
->parent
->ln_branch
);
405 static inline int is_last_column(struct libscols_column
*cl
)
407 struct libscols_column
*next
;
409 if (list_entry_is_last(&cl
->cl_columns
, &cl
->table
->tb_columns
))
412 next
= list_entry(cl
->cl_columns
.next
, struct libscols_column
, cl_columns
);
413 if (next
&& scols_column_is_hidden(next
) && is_last_column(next
))
418 static inline int is_last_group_member(struct libscols_line
*ln
)
420 if (!ln
|| !ln
->group
)
423 return list_entry_is_last(&ln
->ln_groups
, &ln
->group
->gr_members
);
426 static inline int is_first_group_member(struct libscols_line
*ln
)
428 if (!ln
|| !ln
->group
)
431 return list_entry_is_first(&ln
->ln_groups
, &ln
->group
->gr_members
);
434 static inline int is_group_member(struct libscols_line
*ln
)
436 return ln
&& ln
->group
;
439 static inline int is_last_group_child(struct libscols_line
*ln
)
441 if (!ln
|| !ln
->parent_group
)
444 return list_entry_is_last(&ln
->ln_children
, &ln
->parent_group
->gr_children
);
447 static inline int is_group_child(struct libscols_line
*ln
)
449 return ln
&& ln
->parent_group
;
452 static inline int has_groups(struct libscols_table
*tb
)
454 return tb
&& !list_empty(&tb
->tb_groups
);
457 static inline int has_children(struct libscols_line
*ln
)
459 return ln
&& !list_empty(&ln
->ln_branch
);
462 static inline int has_group_children(struct libscols_line
*ln
)
464 return ln
&& ln
->group
&& !list_empty(&ln
->group
->gr_children
);
467 #endif /* _LIBSMARTCOLS_PRIVATE_H */