summaryrefslogtreecommitdiffstats
path: root/libsmartcols
diff options
context:
space:
mode:
authorKarel Zak2017-03-30 14:27:07 +0200
committerKarel Zak2017-04-07 14:34:11 +0200
commit48645e7bbb9be43ef3e063bd756620902766488a (patch)
treecbe014a3e2375fa59885dc0e1dcd4d7249cd5da8 /libsmartcols
parentlibsmartcols: add scols_table_move_column() (diff)
downloadkernel-qcow2-util-linux-48645e7bbb9be43ef3e063bd756620902766488a.tar.gz
kernel-qcow2-util-linux-48645e7bbb9be43ef3e063bd756620902766488a.tar.xz
kernel-qcow2-util-linux-48645e7bbb9be43ef3e063bd756620902766488a.zip
libsmartcols: add scols_line_move_cells()
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'libsmartcols')
-rw-r--r--libsmartcols/src/line.c27
-rw-r--r--libsmartcols/src/smartcolsP.h1
-rw-r--r--libsmartcols/src/table.c25
3 files changed, 50 insertions, 3 deletions
diff --git a/libsmartcols/src/line.c b/libsmartcols/src/line.c
index 454882094..1c3141a16 100644
--- a/libsmartcols/src/line.c
+++ b/libsmartcols/src/line.c
@@ -146,6 +146,33 @@ int scols_line_alloc_cells(struct libscols_line *ln, size_t n)
return 0;
}
+int scols_line_move_cells(struct libscols_line *ln, size_t newn, size_t oldn)
+{
+ struct libscols_cell ce;
+
+ if (!ln || newn >= ln->ncells || oldn >= ln->ncells)
+ return -EINVAL;
+ if (oldn == newn)
+ return 0;
+
+ DBG(LINE, ul_debugobj(ln, "move cells[%zu] -> cells[%zu]", oldn, newn));
+
+ /* remember data from old position */
+ memcpy(&ce, &ln->cells[oldn], sizeof(struct libscols_cell));
+
+ /* remove from old position */
+ memmove(ln->cells + oldn, ln->cells + oldn + 1,
+ (ln->ncells - oldn) * sizeof(struct libscols_cell));
+
+ /* create a space for new position */
+ memmove(ln->cells + newn + 1, ln->cells + newn,
+ (ln->ncells - newn) * sizeof(struct libscols_cell));
+
+ /* copy original data to new position */
+ memcpy(&ln->cells[newn], &ce, sizeof(struct libscols_cell));
+ return 0;
+}
+
/**
* scols_line_set_userdata:
* @ln: a pointer to a struct libscols_line instance
diff --git a/libsmartcols/src/smartcolsP.h b/libsmartcols/src/smartcolsP.h
index 2a76048e1..0ce969bab 100644
--- a/libsmartcols/src/smartcolsP.h
+++ b/libsmartcols/src/smartcolsP.h
@@ -67,6 +67,7 @@ struct libscols_cell {
int flags;
};
+extern int scols_line_move_cells(struct libscols_line *ln, size_t newn, size_t oldn);
/*
* Table column
diff --git a/libsmartcols/src/table.c b/libsmartcols/src/table.c
index 84c0f6a25..3672114b2 100644
--- a/libsmartcols/src/table.c
+++ b/libsmartcols/src/table.c
@@ -268,18 +268,37 @@ int scols_table_move_column(struct libscols_table *tb,
{
struct list_head *head;
struct libscols_iter itr;
- size_t n = 0;
+ struct libscols_column *p;
+ struct libscols_line *ln;
+ size_t n = 0, oldseq;
+
+ if (!tb || !cl)
+ return -EINVAL;
+
+ if (pre && pre->seqnum + 1 == cl->seqnum)
+ return 0;
+ if (pre == NULL && cl->seqnum == 0)
+ return 0;
+
+ DBG(TAB, ul_debugobj(tb, "move column %zu behind %zu",
+ cl->seqnum, pre? pre->seqnum : 0));
list_del_init(&cl->cl_columns); /* remove from old position */
head = pre ? &pre->cl_columns : &tb->tb_columns;
list_add(&cl->cl_columns, head); /* add to the new place */
+ oldseq = cl->seqnum;
+
/* fix seq. numbers */
scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
- while (scols_table_next_column(tb, &itr, &cl) == 0)
- cl->seqnum = n++;
+ while (scols_table_next_column(tb, &itr, &p) == 0)
+ p->seqnum = n++;
+ /* move data in lines */
+ scols_reset_iter(&itr, SCOLS_ITER_FORWARD);
+ while (scols_table_next_line(tb, &itr, &ln) == 0)
+ scols_line_move_cells(ln, cl->seqnum, oldseq);
return 0;
}