diff options
author | Karel Zak | 2014-03-19 16:29:39 +0100 |
---|---|---|
committer | Karel Zak | 2014-04-03 12:29:16 +0200 |
commit | c638c57ac3af8b819ef7b71804d585c3e9cf549c (patch) | |
tree | 8c3c06a279c2cf91285b3dd4ef9fb3f19a2a8307 /libsmartcols/src/line.c | |
parent | include/carefulputc: cleanup and add fputs_{quoted,nonblank}() (diff) | |
download | kernel-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.c | 142 |
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; |