summaryrefslogtreecommitdiffstats
path: root/libsmartcols/src/line.c
diff options
context:
space:
mode:
authorKarel Zak2014-03-19 16:29:39 +0100
committerKarel Zak2014-04-03 12:29:16 +0200
commitc638c57ac3af8b819ef7b71804d585c3e9cf549c (patch)
tree8c3c06a279c2cf91285b3dd4ef9fb3f19a2a8307 /libsmartcols/src/line.c
parentinclude/carefulputc: cleanup and add fputs_{quoted,nonblank}() (diff)
downloadkernel-qcow2-util-linux-c638c57ac3af8b819ef7b71804d585c3e9cf549c.tar.gz
kernel-qcow2-util-linux-c638c57ac3af8b819ef7b71804d585c3e9cf549c.tar.xz
kernel-qcow2-util-linux-c638c57ac3af8b819ef7b71804d585c3e9cf549c.zip
libsmartcols: add table struct, cleanup refcounting
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libsmartcols/src/line.c')
-rw-r--r--libsmartcols/src/line.c142
1 files changed, 114 insertions, 28 deletions
diff --git a/libsmartcols/src/line.c b/libsmartcols/src/line.c
index 589d5a2f6..80a1beabb 100644
--- a/libsmartcols/src/line.c
+++ b/libsmartcols/src/line.c
@@ -14,6 +14,12 @@
#include "smartcolsP.h"
+/*
+ * Note that the line is allocated without cells, the cells will be allocated
+ * later when you add the line to the table. If you want to use the line
+ * without table then you have to explicitly allocate the cells by
+ * scols_line_alloc_cells().
+ */
struct libscols_line *scols_new_line(void)
{
struct libscols_line *ln;
@@ -21,7 +27,6 @@ struct libscols_line *scols_new_line(void)
ln = calloc(1, sizeof(*ln));
if (!ln)
return NULL;
-
ln->refcount = 1;
INIT_LIST_HEAD(&ln->ln_lines);
INIT_LIST_HEAD(&ln->ln_children);
@@ -37,20 +42,63 @@ void scols_ref_line(struct libscols_line *ln)
void scols_unref_line(struct libscols_line *ln)
{
- if (ln && --ln->refcount <= 0) {
- size_t i;
+ if (ln && --ln->refcount <= 0) {
list_del(&ln->ln_lines);
list_del(&ln->ln_children);
- for (i = 0; i <= ln->ncells; i++)
- scols_reset_cell(ln->cells[i]);
- free(ln->data);
+ scols_line_free_cells(ln);
free(ln->color);
free(ln);
+ return;
}
}
+void scols_line_free_cells(struct libscols_line *ln)
+{
+ size_t i;
+
+ if (!ln || !ln->cells)
+ return;
+
+ for (i = 0; i < ln->ncells; i++)
+ scols_reset_cell(&ln->cells[i]);
+
+ free(ln->cells);
+ ln->ncells = 0;
+ ln->cells = NULL;
+}
+
+
+int scols_line_alloc_cells(struct libscols_line *ln, size_t n)
+{
+ struct libscols_cell *ce;
+
+ assert(ln);
+
+ if (!ln)
+ return -EINVAL;
+ if (ln->ncells == n)
+ return 0;
+
+ if (!n) {
+ scols_line_free_cells(ln);
+ return 0;
+ }
+
+ ce = realloc(ln->cells, n * sizeof(struct libscols_cell));
+ if (!ce)
+ return -errno;
+
+ if (n > ln->ncells)
+ memset(ce + ln->ncells, 0,
+ (n - ln->ncells) * sizeof(struct libscols_cell));
+
+ ln->cells = ce;
+ ln->ncells = n;
+ return 0;
+}
+
int scols_line_set_userdata(struct libscols_line *ln, void *data)
{
assert(ln);
@@ -66,12 +114,41 @@ void *scols_line_get_userdata(struct libscols_line *ln)
return ln ? ln->userdata : NULL;
}
-int scols_line_set_parent(struct libscols_line *ln, struct libscols_line *parent)
+int scols_line_remove_child(struct libscols_line *ln, struct libscols_line *child)
{
assert(ln);
- if (!ln)
+ assert(child);
+
+ if (!ln || !child)
+ return -EINVAL;
+ list_del_init(&child->ln_children);
+ scols_unref_line(child);
+
+ child->parent = NULL;
+ scols_unref_line(ln);
+ return 0;
+}
+
+int scols_line_add_child(struct libscols_line *ln, struct libscols_line *child)
+{
+ assert(ln);
+ assert(child);
+
+ if (!ln || !child)
return -EINVAL;
- ln->parent = parent;
+
+ /* unref old<->parent */
+ if (child->parent)
+ scols_line_remove_child(child->parent, child);
+
+ /* new reference from parent to child */
+ list_add_tail(&child->ln_children, &ln->ln_branch);
+ scols_ref_line(child);
+
+ /* new reference from child to parent */
+ child->parent = ln;
+ scols_ref_line(ln);
+
return 0;
}
@@ -108,12 +185,6 @@ const char *scols_line_get_color(struct libscols_line *ln)
return ln ? ln->color : NULL;
}
-size_t scols_line_get_datasize(struct libscols_line *ln)
-{
- assert(ln);
- return ln ? ln->data_sz : 0;
-}
-
size_t scols_line_get_ncells(struct libscols_line *ln)
{
assert(ln);
@@ -127,12 +198,33 @@ struct libscols_cell *scols_line_get_cell(struct libscols_line *ln,
if (!ln || n >= ln->ncells)
return NULL;
- return ln->cells[n];
+ return &ln->cells[n];
+}
+
+/* just shortcut */
+int scols_line_set_data(struct libscols_line *ln, size_t n, const char *data)
+{
+ struct libscols_cell *ce = scols_line_get_cell(ln, n);
+
+ if (!ce)
+ return -EINVAL;
+ return scols_cell_set_data(ce, data);
+}
+
+/* just shortcut */
+int scols_line_refer_data(struct libscols_line *ln, size_t n, char *data)
+{
+ struct libscols_cell *ce = scols_line_get_cell(ln, n);
+
+ if (!ce)
+ return -EINVAL;
+ return scols_cell_refer_data(ce, data);
}
struct libscols_line *scols_copy_line(struct libscols_line *ln)
{
struct libscols_line *ret;
+ size_t i;
assert (ln);
if (!ln)
@@ -143,22 +235,16 @@ struct libscols_line *scols_copy_line(struct libscols_line *ln)
return NULL;
if (scols_line_set_color(ret, ln->color))
goto err;
+ if (scols_line_alloc_cells(ret, ln->ncells))
+ goto err;
+
ret->userdata = ln->userdata;
- ret->parent = ln->parent;
- ret->data_sz = ln->data_sz;
ret->ncells = ln->ncells;
+ ret->seqnum = ln->seqnum;
- if (ln->ncells) {
- size_t i;
-
- ret->cells = calloc(ln->ncells, sizeof(struct libscols_cell));
- if (!ret->cells)
+ for (i = 0; i < ret->ncells; ++i) {
+ if (scols_cell_copy_content(&ret->cells[i], &ln->cells[i]))
goto err;
-
- for (i = 0; i < ret->ncells; ++i) {
- if (scols_cell_copy_content(ret->cells[i], ln->cells[i]))
- goto err;
- }
}
return ret;