]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - libsmartcols/src/line.c
2 * line.c - functions for table handling at the line level
4 * Copyright (C) 2014 Karel Zak <kzak@redhat.com>
5 * Copyright (C) 2014 Ondrej Oprala <ooprala@redhat.com>
7 * This file may be redistributed under the terms of the
8 * GNU Lesser General Public License.
14 * @short_description: line API
16 * An API to access and modify per-line data and information.
25 #include "smartcolsP.h"
30 * Note that the line is allocated without cells, the cells will be allocated
31 * later when you add the line to the table. If you want to use the line
32 * without table then you have to explicitly allocate the cells by
33 * scols_line_alloc_cells().
35 * Returns: a pointer to a new struct libscols_line instance.
37 struct libscols_line
*scols_new_line(void)
39 struct libscols_line
*ln
;
41 ln
= calloc(1, sizeof(*ln
));
45 DBG(LINE
, ul_debugobj(ln
, "alloc"));
47 INIT_LIST_HEAD(&ln
->ln_lines
);
48 INIT_LIST_HEAD(&ln
->ln_children
);
49 INIT_LIST_HEAD(&ln
->ln_branch
);
55 * @ln: a pointer to a struct libscols_line instance
57 * Increases the refcount of @ln.
59 void scols_ref_line(struct libscols_line
*ln
)
67 * @ln: a pointer to a struct libscols_line instance
69 * Decreases the refcount of @ln.
71 void scols_unref_line(struct libscols_line
*ln
)
74 if (ln
&& --ln
->refcount
<= 0) {
75 DBG(CELL
, ul_debugobj(ln
, "dealloc"));
76 list_del(&ln
->ln_lines
);
77 list_del(&ln
->ln_children
);
78 scols_line_free_cells(ln
);
86 * scols_line_free_cells:
87 * @ln: a pointer to a struct libscols_line instance
89 * Frees the allocated cells referenced to by @ln.
91 void scols_line_free_cells(struct libscols_line
*ln
)
95 if (!ln
|| !ln
->cells
)
98 DBG(LINE
, ul_debugobj(ln
, "free cells"));
100 for (i
= 0; i
< ln
->ncells
; i
++)
101 scols_reset_cell(&ln
->cells
[i
]);
109 * scols_line_alloc_cells:
110 * @ln: a pointer to a struct libscols_line instance
111 * @n: the number of elements
113 * Allocates space for @n cells. This function is optional,
114 * and libsmartcols automatically allocates necessary cells
115 * according to number of columns in the table when you add
116 * the line to the table. See scols_table_add_line().
118 * Returns: 0, a negative value in case of an error.
120 int scols_line_alloc_cells(struct libscols_line
*ln
, size_t n
)
122 struct libscols_cell
*ce
;
132 scols_line_free_cells(ln
);
136 DBG(LINE
, ul_debugobj(ln
, "alloc %zu cells", n
));
138 ce
= realloc(ln
->cells
, n
* sizeof(struct libscols_cell
));
143 memset(ce
+ ln
->ncells
, 0,
144 (n
- ln
->ncells
) * sizeof(struct libscols_cell
));
152 * scols_line_set_userdata:
153 * @ln: a pointer to a struct libscols_line instance
156 * Binds @data to @ln.
158 * Returns: 0, a negative value in case of an error.
160 int scols_line_set_userdata(struct libscols_line
*ln
, void *data
)
170 * scols_line_get_userdata:
171 * @ln: a pointer to a struct libscols_line instance
173 * Returns: 0, a negative value in case of an error.
175 void *scols_line_get_userdata(struct libscols_line
*ln
)
178 return ln
? ln
->userdata
: NULL
;
182 * scols_line_remove_child:
183 * @ln: a pointer to a struct libscols_line instance
184 * @child: a pointer to a struct libscols_line instance
186 * Removes @child as a child of @ln.
188 * Returns: 0, a negative value in case of an error.
190 int scols_line_remove_child(struct libscols_line
*ln
, struct libscols_line
*child
)
198 DBG(LINE
, ul_debugobj(ln
, "remove child %p", child
));
200 list_del_init(&child
->ln_children
);
201 scols_unref_line(child
);
203 child
->parent
= NULL
;
204 scols_unref_line(ln
);
209 * scols_line_add_child:
210 * @ln: a pointer to a struct libscols_line instance
211 * @child: a pointer to a struct libscols_line instance
213 * Sets @child as a child of @ln.
215 * Returns: 0, a negative value in case of an error.
217 int scols_line_add_child(struct libscols_line
*ln
, struct libscols_line
*child
)
225 /* unref old<->parent */
227 scols_line_remove_child(child
->parent
, child
);
229 DBG(LINE
, ul_debugobj(ln
, "add child %p", child
));
231 /* new reference from parent to child */
232 list_add_tail(&child
->ln_children
, &ln
->ln_branch
);
233 scols_ref_line(child
);
235 /* new reference from child to parent */
243 * scols_line_get_parent:
244 * @ln: a pointer to a struct libscols_line instance
246 * Returns: a pointer to @ln's parent, NULL in case it has no parent or if there was an error.
248 struct libscols_line
*scols_line_get_parent(struct libscols_line
*ln
)
251 return ln
? ln
->parent
: NULL
;
255 * scols_line_has_children:
256 * @ln: a pointer to a struct libscols_line instance
258 * Returns: 1 if @ln has any children, otherwise 0.
260 int scols_line_has_children(struct libscols_line
*ln
)
263 return ln
? !list_empty(&ln
->ln_branch
) : 0;
267 * scols_line_next_child:
268 * @ln: a pointer to a struct libscols_line instance
269 * @itr: a pointer to a struct libscols_iter instance
270 * @chld: a pointer to a pointer to a struct libscols_line instance
272 * Finds the next child and returns a pointer to it via @chld.
274 * Returns: 0, a negative value in case of an error.
276 int scols_line_next_child(struct libscols_line
*ln
,
277 struct libscols_iter
*itr
,
278 struct libscols_line
**chld
)
282 if (!ln
|| !itr
|| !chld
)
287 SCOLS_ITER_INIT(itr
, &ln
->ln_branch
);
288 if (itr
->p
!= itr
->head
) {
289 SCOLS_ITER_ITERATE(itr
, *chld
, struct libscols_line
, ln_children
);
297 * scols_line_set_color:
298 * @ln: a pointer to a struct libscols_line instance
299 * @color: color name or ESC sequence
301 * Returns: 0, a negative value in case of an error.
303 int scols_line_set_color(struct libscols_line
*ln
, const char *color
)
311 if (isalnum(*color
)) {
312 color
= color_sequence_from_colorname(color
);
328 * scols_line_get_color:
329 * @ln: a pointer to a struct libscols_line instance
331 * Returns: @ln's color string, NULL in case of an error.
333 const char *scols_line_get_color(struct libscols_line
*ln
)
336 return ln
? ln
->color
: NULL
;
340 * scols_line_get_ncells:
341 * @ln: a pointer to a struct libscols_line instance
343 * Returns: @ln's number of cells
345 size_t scols_line_get_ncells(struct libscols_line
*ln
)
348 return ln
? ln
->ncells
: 0;
352 * scols_line_get_cell:
353 * @ln: a pointer to a struct libscols_line instance
354 * @n: cell number to retrieve
356 * Returns: the @n-th cell in @ln, NULL in case of an error.
358 struct libscols_cell
*scols_line_get_cell(struct libscols_line
*ln
,
363 if (!ln
|| n
>= ln
->ncells
)
365 return &ln
->cells
[n
];
369 * scols_line_get_column_cell:
370 * @ln: a pointer to a struct libscols_line instance
371 * @cl: pointer to cell
373 * Like scols_line_get_cell() by cell is referenced by column.
375 * Returns: the @n-th cell in @ln, NULL in case of an error.
377 struct libscols_cell
*scols_line_get_column_cell(
378 struct libscols_line
*ln
,
379 struct libscols_column
*cl
)
384 return scols_line_get_cell(ln
, cl
->seqnum
);
388 * scols_line_set_data:
389 * @ln: a pointer to a struct libscols_cell instance
390 * @n: number of the cell, whose data is to be set
391 * @data: actual data to set
393 * Returns: 0, a negative value in case of an error.
395 int scols_line_set_data(struct libscols_line
*ln
, size_t n
, const char *data
)
397 struct libscols_cell
*ce
= scols_line_get_cell(ln
, n
);
401 return scols_cell_set_data(ce
, data
);
405 * scols_line_refer_data:
406 * @ln: a pointer to a struct libscols_cell instance
407 * @n: number of the cell which will refer to @data
408 * @data: actual data to refer to
410 * Returns: 0, a negative value in case of an error.
412 int scols_line_refer_data(struct libscols_line
*ln
, size_t n
, char *data
)
414 struct libscols_cell
*ce
= scols_line_get_cell(ln
, n
);
418 return scols_cell_refer_data(ce
, data
);
423 * @ln: a pointer to a struct libscols_cell instance
425 * Returns: A newly allocated copy of @ln, NULL in case of an error.
427 struct libscols_line
*scols_copy_line(struct libscols_line
*ln
)
429 struct libscols_line
*ret
;
436 ret
= scols_new_line();
439 if (scols_line_set_color(ret
, ln
->color
))
441 if (scols_line_alloc_cells(ret
, ln
->ncells
))
444 ret
->userdata
= ln
->userdata
;
445 ret
->ncells
= ln
->ncells
;
446 ret
->seqnum
= ln
->seqnum
;
448 DBG(LINE
, ul_debugobj(ln
, "copy to %p", ret
));
450 for (i
= 0; i
< ret
->ncells
; ++i
) {
451 if (scols_cell_copy_content(&ret
->cells
[i
], &ln
->cells
[i
]))
457 scols_unref_line(ret
);