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) */
100 int json_type
; /* SCOLS_JSON_* */
103 char *color
; /* default column color */
104 char *safechars
; /* do not encode this bytes */
107 size_t pending_data_sz
;
108 char *pending_data_buf
;
110 int (*cmpfunc
)(struct libscols_cell
*,
111 struct libscols_cell
*,
112 void *); /* cells comparison function */
115 size_t (*wrap_chunksize
)(const struct libscols_column
*,
116 const char *, void *);
117 char *(*wrap_nextchunk
)(const struct libscols_column
*,
122 struct libscols_cell header
;
123 struct list_head cl_columns
;
125 struct libscols_table
*table
;
127 unsigned int is_extreme
: 1, /* extreme width in the column */
128 is_groups
: 1; /* print group chart */
132 #define colsep(tb) ((tb)->colsep ? (tb)->colsep : " ")
133 #define linesep(tb) ((tb)->linesep ? (tb)->linesep : "\n")
136 SCOLS_GSTATE_NONE
= 0, /* not activate yet */
137 SCOLS_GSTATE_FIRST_MEMBER
,
138 SCOLS_GSTATE_MIDDLE_MEMBER
,
139 SCOLS_GSTATE_LAST_MEMBER
,
140 SCOLS_GSTATE_MIDDLE_CHILD
,
141 SCOLS_GSTATE_LAST_CHILD
,
142 SCOLS_GSTATE_CONT_MEMBERS
,
143 SCOLS_GSTATE_CONT_CHILDREN
146 struct libscols_group
{
151 struct list_head gr_members
; /* head of line->ln_group */
152 struct list_head gr_children
; /* head of line->ln_children */
153 struct list_head gr_groups
; /* member of table->tb_groups */
155 int state
; /* SCOLS_GSTATE_* */
161 struct libscols_line
{
166 char *color
; /* default line color */
168 struct libscols_cell
*cells
; /* array with data */
169 size_t ncells
; /* number of cells */
171 struct list_head ln_lines
; /* member of table->tb_lines */
172 struct list_head ln_branch
; /* head of line->ln_children */
173 struct list_head ln_children
; /* member of line->ln_children or group->gr_children */
174 struct list_head ln_groups
; /* member of group->gr_groups */
176 struct libscols_line
*parent
;
177 struct libscols_group
*parent_group
; /* for group childs */
178 struct libscols_group
*group
; /* for group members */
182 SCOLS_FMT_HUMAN
= 0, /* default, human readable */
183 SCOLS_FMT_RAW
, /* space separated */
184 SCOLS_FMT_EXPORT
, /* COLNAME="data" ... */
185 SCOLS_FMT_JSON
/* http://en.wikipedia.org/wiki/JSON */
191 struct libscols_table
{
193 char *name
; /* optional table name (for JSON) */
194 size_t ncols
; /* number of columns */
195 size_t ntreecols
; /* number of columns with SCOLS_FL_TREE */
196 size_t nlines
; /* number of lines */
197 size_t termwidth
; /* terminal width (number of columns) */
198 size_t termheight
; /* terminal height (number of lines) */
199 size_t termreduce
; /* extra blank space */
200 int termforce
; /* SCOLS_TERMFORCE_* */
201 FILE *out
; /* output stream */
203 char *colsep
; /* column separator */
204 char *linesep
; /* line separator */
206 struct list_head tb_columns
;
207 struct list_head tb_lines
;
209 struct list_head tb_groups
; /* all defined groups */
210 struct libscols_group
**grpset
;
213 struct libscols_symbols
*symbols
;
214 struct libscols_cell title
; /* optional table title (for humans) */
216 int indent
; /* indentation counter */
217 int indent_last_sep
;/* last printed has been line separator */
218 int format
; /* SCOLS_FMT_* */
220 size_t termlines_used
; /* printed line counter */
221 size_t header_next
; /* where repeat header */
224 unsigned int ascii
:1, /* don't use unicode */
225 colors_wanted
:1, /* enable colors */
226 is_term
:1, /* isatty() */
227 padding_debug
:1, /* output visible padding chars */
228 maxout
:1, /* maximize output */
229 header_repeat
:1, /* print header after libscols_table->termheight */
230 header_printed
:1, /* header already printed */
231 priv_symbols
:1, /* default private symbols */
232 no_headings
:1, /* don't print header */
233 no_encode
:1, /* don't care about control and non-printable chars */
234 no_linesep
:1, /* don't print line separator */
235 no_wrap
:1; /* never wrap lines */
238 #define IS_ITER_FORWARD(_i) ((_i)->direction == SCOLS_ITER_FORWARD)
239 #define IS_ITER_BACKWARD(_i) ((_i)->direction == SCOLS_ITER_BACKWARD)
241 #define SCOLS_ITER_INIT(itr, list) \
243 (itr)->p = IS_ITER_FORWARD(itr) ? \
244 (list)->next : (list)->prev; \
245 (itr)->head = (list); \
248 #define SCOLS_ITER_ITERATE(itr, res, restype, member) \
250 res = list_entry((itr)->p, restype, member); \
251 (itr)->p = IS_ITER_FORWARD(itr) ? \
252 (itr)->p->next : (itr)->p->prev; \
256 static inline int scols_iter_is_last(const struct libscols_iter
*itr
)
258 if (!itr
|| !itr
->head
|| !itr
->p
)
261 return itr
->p
== itr
->head
;
267 int scols_line_next_group_child(struct libscols_line
*ln
,
268 struct libscols_iter
*itr
,
269 struct libscols_line
**chld
);
275 int scols_table_next_group(struct libscols_table
*tb
,
276 struct libscols_iter
*itr
,
277 struct libscols_group
**gr
);
282 struct libscols_buffer
;
283 extern struct libscols_buffer
*new_buffer(size_t sz
);
284 extern void free_buffer(struct libscols_buffer
*buf
);
285 extern int buffer_reset_data(struct libscols_buffer
*buf
);
286 extern int buffer_append_data(struct libscols_buffer
*buf
, const char *str
);
287 extern int buffer_append_ntimes(struct libscols_buffer
*buf
, size_t n
, const char *str
);
288 extern int buffer_set_data(struct libscols_buffer
*buf
, const char *str
);
289 extern void buffer_set_art_index(struct libscols_buffer
*buf
);
290 extern char *buffer_get_data(struct libscols_buffer
*buf
);
291 extern size_t buffer_get_size(struct libscols_buffer
*buf
);
292 extern char *buffer_get_safe_data(struct libscols_table
*tb
,
293 struct libscols_buffer
*buf
,
295 const char *safechars
);
296 extern size_t buffer_get_safe_art_size(struct libscols_buffer
*buf
);
301 void scols_ref_group(struct libscols_group
*gr
);
302 void scols_group_remove_children(struct libscols_group
*gr
);
303 void scols_group_remove_members(struct libscols_group
*gr
);
304 void scols_unref_group(struct libscols_group
*gr
);
305 void scols_groups_fix_members_order(struct libscols_table
*tb
);
306 int scols_groups_calculate_grpset(struct libscols_table
*tb
);
307 int scols_groups_update_grpset(struct libscols_table
*tb
, struct libscols_line
*ln
);
308 void scols_groups_reset_state(struct libscols_table
*tb
);
313 extern int __scols_calculate(struct libscols_table
*tb
, struct libscols_buffer
*buf
);
318 extern int __cell_to_buffer(struct libscols_table
*tb
,
319 struct libscols_line
*ln
,
320 struct libscols_column
*cl
,
321 struct libscols_buffer
*buf
);
323 void __scols_cleanup_printing(struct libscols_table
*tb
, struct libscols_buffer
*buf
);
324 int __scols_initialize_printing(struct libscols_table
*tb
, struct libscols_buffer
**buf
);
325 int __scols_print_tree(struct libscols_table
*tb
, struct libscols_buffer
*buf
);
326 int __scols_print_table(struct libscols_table
*tb
, struct libscols_buffer
*buf
);
327 int __scols_print_header(struct libscols_table
*tb
, struct libscols_buffer
*buf
);
328 int __scols_print_title(struct libscols_table
*tb
);
329 int __scols_print_range(struct libscols_table
*tb
,
330 struct libscols_buffer
*buf
,
331 struct libscols_iter
*itr
,
332 struct libscols_line
*end
);
337 extern void fput_indent(struct libscols_table
*tb
);
338 extern void fput_table_open(struct libscols_table
*tb
);
339 extern void fput_table_close(struct libscols_table
*tb
);
340 extern void fput_children_open(struct libscols_table
*tb
);
341 extern void fput_children_close(struct libscols_table
*tb
);
342 extern void fput_line_open(struct libscols_table
*tb
);
343 extern void fput_line_close(struct libscols_table
*tb
, int last
, int last_in_table
);
345 static inline int is_last_child(struct libscols_line
*ln
)
347 if (!ln
|| !ln
->parent
)
350 return list_entry_is_last(&ln
->ln_children
, &ln
->parent
->ln_branch
);
354 static inline int is_last_column(struct libscols_column
*cl
)
356 struct libscols_column
*next
;
358 if (list_entry_is_last(&cl
->cl_columns
, &cl
->table
->tb_columns
))
361 next
= list_entry(cl
->cl_columns
.next
, struct libscols_column
, cl_columns
);
362 if (next
&& scols_column_is_hidden(next
) && is_last_column(next
))
367 static inline int is_last_group_member(struct libscols_line
*ln
)
369 if (!ln
|| !ln
->group
)
372 return list_entry_is_last(&ln
->ln_groups
, &ln
->group
->gr_members
);
375 static inline int is_first_group_member(struct libscols_line
*ln
)
377 if (!ln
|| !ln
->group
)
380 return list_entry_is_first(&ln
->ln_groups
, &ln
->group
->gr_members
);
383 static inline int is_group_member(struct libscols_line
*ln
)
385 return ln
&& ln
->group
;
388 static inline int is_last_group_child(struct libscols_line
*ln
)
390 if (!ln
|| !ln
->parent_group
)
393 return list_entry_is_last(&ln
->ln_children
, &ln
->parent_group
->gr_children
);
396 static inline int is_group_child(struct libscols_line
*ln
)
398 return ln
&& ln
->parent_group
;
401 static inline int has_groups(struct libscols_table
*tb
)
403 return tb
&& !list_empty(&tb
->tb_groups
);
406 static inline int has_children(struct libscols_line
*ln
)
408 return ln
&& !list_empty(&ln
->ln_branch
);
411 static inline int has_group_children(struct libscols_line
*ln
)
413 return ln
&& ln
->group
&& !list_empty(&ln
->group
->gr_children
);
416 #endif /* _LIBSMARTCOLS_PRIVATE_H */