]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libsmartcols: add scols_line_move_cells()
authorKarel Zak <kzak@redhat.com>
Thu, 30 Mar 2017 12:27:07 +0000 (14:27 +0200)
committerKarel Zak <kzak@redhat.com>
Fri, 7 Apr 2017 12:34:11 +0000 (14:34 +0200)
Signed-off-by: Karel Zak <kzak@redhat.com>
libsmartcols/src/line.c
libsmartcols/src/smartcolsP.h
libsmartcols/src/table.c

index 4548820940050857aa2d210c4350a152945b9ee7..1c3141a16b27b4dbff3f6e0ca6f446853c91544a 100644 (file)
@@ -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
index 2a76048e1d586d940864ac08de0242ed99858bee..0ce969bab839940e7a2835c732e408f9279f69d2 100644 (file)
@@ -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
index 84c0f6a25b9465df3753dbac1c3f7e7d78cb10fe..3672114b25c73eaf8a10eeff6d66027162ff8927 100644 (file)
@@ -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;
 }