]> git.ipfire.org Git - thirdparty/util-linux.git/blob - libsmartcols/src/smartcolsP.h
docs: fix typos [codespell]
[thirdparty/util-linux.git] / libsmartcols / src / smartcolsP.h
1 /*
2 * smartcolsP.h - private library header file
3 *
4 * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com>
5 * Copyright (C) 2014 Karel Zak <kzak@redhat.com>
6 *
7 * This file may be redistributed under the terms of the
8 * GNU Lesser General Public License.
9 */
10
11 #ifndef _LIBSMARTCOLS_PRIVATE_H
12 #define _LIBSMARTCOLS_PRIVATE_H
13
14 #include "c.h"
15 #include "list.h"
16 #include "strutils.h"
17 #include "color-names.h"
18 #include "debug.h"
19
20 #include "libsmartcols.h"
21
22 /*
23 * Debug
24 */
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
34
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_)
39
40 #define UL_DEBUG_CURRENT_MASK UL_DEBUG_MASK(libsmartcols)
41 #include "debugobj.h"
42
43 /*
44 * Generic iterator
45 */
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 */
50 };
51
52 /*
53 * Tree symbols
54 */
55 struct libscols_symbols {
56 int refcount;
57
58 char *tree_branch;
59 char *tree_vert;
60 char *tree_right;
61
62 char *group_vert;
63 char *group_horz;
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;
69
70 char *title_padding;
71 char *cell_padding;
72 };
73
74 /*
75 * Table cells
76 */
77 struct libscols_cell {
78 char *data;
79 char *color;
80 void *userdata;
81 int flags;
82 };
83
84 extern int scols_line_move_cells(struct libscols_line *ln, size_t newn, size_t oldn);
85
86 /*
87 * Table column
88 */
89 struct libscols_column {
90 int refcount; /* reference counter */
91 size_t seqnum; /* column index */
92
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) */
99
100 int json_type; /* SCOLS_JSON_* */
101
102 int flags;
103 char *color; /* default column color */
104 char *safechars; /* do not encode this bytes */
105
106 char *pending_data;
107 size_t pending_data_sz;
108 char *pending_data_buf;
109
110 int (*cmpfunc)(struct libscols_cell *,
111 struct libscols_cell *,
112 void *); /* cells comparison function */
113 void *cmpfunc_data;
114
115 size_t (*wrap_chunksize)(const struct libscols_column *,
116 const char *, void *);
117 char *(*wrap_nextchunk)(const struct libscols_column *,
118 char *, void *);
119 void *wrapfunc_data;
120
121
122 struct libscols_cell header;
123 struct list_head cl_columns;
124
125 struct libscols_table *table;
126
127 unsigned int is_extreme : 1, /* extreme width in the column */
128 is_groups : 1; /* print group chart */
129
130 };
131
132 #define colsep(tb) ((tb)->colsep ? (tb)->colsep : " ")
133 #define linesep(tb) ((tb)->linesep ? (tb)->linesep : "\n")
134
135 enum {
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
144 };
145
146 struct libscols_group {
147 int refcount;
148
149 size_t nmembers;
150
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 */
154
155 int state; /* SCOLS_GSTATE_* */
156 };
157
158 /*
159 * Table line
160 */
161 struct libscols_line {
162 int refcount;
163 size_t seqnum;
164
165 void *userdata;
166 char *color; /* default line color */
167
168 struct libscols_cell *cells; /* array with data */
169 size_t ncells; /* number of cells */
170
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 */
175
176 struct libscols_line *parent;
177 struct libscols_group *parent_group; /* for group childs */
178 struct libscols_group *group; /* for group members */
179 };
180
181 enum {
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 */
186 };
187
188 /*
189 * The table
190 */
191 struct libscols_table {
192 int refcount;
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 */
202
203 char *colsep; /* column separator */
204 char *linesep; /* line separator */
205
206 struct list_head tb_columns;
207 struct list_head tb_lines;
208
209 struct list_head tb_groups; /* all defined groups */
210 struct libscols_group **grpset;
211 size_t grpset_size;
212
213 struct libscols_symbols *symbols;
214 struct libscols_cell title; /* optional table title (for humans) */
215
216 int indent; /* indentation counter */
217 int indent_last_sep;/* last printed has been line separator */
218 int format; /* SCOLS_FMT_* */
219
220 size_t termlines_used; /* printed line counter */
221 size_t header_next; /* where repeat header */
222
223 /* flags */
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 */
236 };
237
238 #define IS_ITER_FORWARD(_i) ((_i)->direction == SCOLS_ITER_FORWARD)
239 #define IS_ITER_BACKWARD(_i) ((_i)->direction == SCOLS_ITER_BACKWARD)
240
241 #define SCOLS_ITER_INIT(itr, list) \
242 do { \
243 (itr)->p = IS_ITER_FORWARD(itr) ? \
244 (list)->next : (list)->prev; \
245 (itr)->head = (list); \
246 } while(0)
247
248 #define SCOLS_ITER_ITERATE(itr, res, restype, member) \
249 do { \
250 res = list_entry((itr)->p, restype, member); \
251 (itr)->p = IS_ITER_FORWARD(itr) ? \
252 (itr)->p->next : (itr)->p->prev; \
253 } while(0)
254
255
256 static inline int scols_iter_is_last(const struct libscols_iter *itr)
257 {
258 if (!itr || !itr->head || !itr->p)
259 return 0;
260
261 return itr->p == itr->head;
262 }
263
264 /*
265 * line.c
266 */
267 int scols_line_next_group_child(struct libscols_line *ln,
268 struct libscols_iter *itr,
269 struct libscols_line **chld);
270
271
272 /*
273 * table.c
274 */
275 int scols_table_next_group(struct libscols_table *tb,
276 struct libscols_iter *itr,
277 struct libscols_group **gr);
278
279 /*
280 * buffer.c
281 */
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,
294 size_t *cells,
295 const char *safechars);
296 extern size_t buffer_get_safe_art_size(struct libscols_buffer *buf);
297
298 /*
299 * grouping.c
300 */
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);
309
310 /*
311 * calculate.c
312 */
313 extern int __scols_calculate(struct libscols_table *tb, struct libscols_buffer *buf);
314
315 /*
316 * print.c
317 */
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);
322
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);
333
334 /*
335 * fput.c
336 */
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);
344
345 static inline int is_last_child(struct libscols_line *ln)
346 {
347 if (!ln || !ln->parent)
348 return 1;
349
350 return list_entry_is_last(&ln->ln_children, &ln->parent->ln_branch);
351 }
352
353
354 static inline int is_last_column(struct libscols_column *cl)
355 {
356 struct libscols_column *next;
357
358 if (list_entry_is_last(&cl->cl_columns, &cl->table->tb_columns))
359 return 1;
360
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))
363 return 1;
364 return 0;
365 }
366
367 static inline int is_last_group_member(struct libscols_line *ln)
368 {
369 if (!ln || !ln->group)
370 return 0;
371
372 return list_entry_is_last(&ln->ln_groups, &ln->group->gr_members);
373 }
374
375 static inline int is_first_group_member(struct libscols_line *ln)
376 {
377 if (!ln || !ln->group)
378 return 0;
379
380 return list_entry_is_first(&ln->ln_groups, &ln->group->gr_members);
381 }
382
383 static inline int is_group_member(struct libscols_line *ln)
384 {
385 return ln && ln->group;
386 }
387
388 static inline int is_last_group_child(struct libscols_line *ln)
389 {
390 if (!ln || !ln->parent_group)
391 return 0;
392
393 return list_entry_is_last(&ln->ln_children, &ln->parent_group->gr_children);
394 }
395
396 static inline int is_group_child(struct libscols_line *ln)
397 {
398 return ln && ln->parent_group;
399 }
400
401 static inline int has_groups(struct libscols_table *tb)
402 {
403 return tb && !list_empty(&tb->tb_groups);
404 }
405
406 static inline int has_children(struct libscols_line *ln)
407 {
408 return ln && !list_empty(&ln->ln_branch);
409 }
410
411 static inline int has_group_children(struct libscols_line *ln)
412 {
413 return ln && ln->group && !list_empty(&ln->group->gr_children);
414 }
415
416 #endif /* _LIBSMARTCOLS_PRIVATE_H */