]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libsmartcols: add scols_sort_table()
authorKarel Zak <kzak@redhat.com>
Tue, 20 May 2014 13:04:11 +0000 (15:04 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 20 May 2014 13:04:11 +0000 (15:04 +0200)
 * add pointer to column cmp() function [scols_column_set_cmpfunc()]

 * allow to store per-cell application private data
   (to make it possible to sort tables on data independent on cell
    output data) [scols_cell_set_userdata() ...]

 * make it possible to access line cell by column
   [scols_line_get_column_cell()]

Sort and cmp() stuff based on patches from Shakur Shams Mullick.

Co-Author: Shakur Shams Mullick <shakursmullick@gmail.com>
Signed-off-by: Shakur Shams Mullick <shakursmullick@gmail.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
Signed-off-by: Karel Zak <kzak@redhat.com>
libsmartcols/docs/libsmartcols-sections.txt
libsmartcols/src/cell.c
libsmartcols/src/column.c
libsmartcols/src/libsmartcols.h.in
libsmartcols/src/libsmartcols.sym
libsmartcols/src/line.c
libsmartcols/src/smartcolsP.h
libsmartcols/src/table.c

index 307691e00a13fa65bfbdd4bdb32b46685344f214..b0777478327d29afea6b74a1f13a0bddd2495061 100644 (file)
@@ -4,9 +4,12 @@ libscols_cell
 scols_cell_copy_content
 scols_cell_get_color
 scols_cell_get_data
+scols_cell_get_userdata
 scols_cell_refer_data
 scols_cell_set_color
 scols_cell_set_data
+scols_cell_set_userdata
+scols_cmpstr_cells
 scols_reset_cell
 </SECTION>
 
@@ -22,6 +25,7 @@ scols_column_is_right
 scols_column_is_strict_width
 scols_column_is_tree
 scols_column_is_trunc
+scols_column_set_cmpfunc
 scols_column_set_color
 scols_column_set_flags
 scols_column_set_whint
@@ -49,6 +53,7 @@ scols_line_alloc_cells
 scols_line_free_cells
 scols_line_get_cell
 scols_line_get_color
+scols_line_get_column_cell
 scols_line_get_ncells
 scols_line_get_parent
 scols_line_get_userdata
@@ -118,6 +123,7 @@ scols_table_set_column_separator
 scols_table_set_line_separator
 scols_table_set_stream
 scols_table_set_symbols
+scols_sort_table
 scols_unref_table
 </SECTION>
 
index d73a1f80868e9b30495f94ff0a9d8d33f14023cf..1d2ab5838b626549b7493e28c55d5733ac91c0d8 100644 (file)
@@ -55,7 +55,7 @@ int scols_reset_cell(struct libscols_cell *ce)
 /**
  * scols_cell_set_data:
  * @ce: a pointer to a struct libscols_cell instance
- * @str: user data
+ * @str: data (used for scols_printtable())
  *
  * Stores a copy of the @str in @ce.
  *
@@ -82,7 +82,7 @@ int scols_cell_set_data(struct libscols_cell *ce, const char *str)
 /**
  * scols_cell_refer_data:
  * @ce: a pointer to a struct libscols_cell instance
- * @str: user data
+ * @str: data (used for scols_printtable())
  *
  * Adds a reference to @str to @ce. The pointer is deallocated by
  * scols_reset_cell() or scols_unref_line(). This function is mostly designed
@@ -114,6 +114,66 @@ const char *scols_cell_get_data(const struct libscols_cell *ce)
        return ce ? ce->data : NULL;
 }
 
+/**
+ * scols_cell_set_userdata:
+ * @ce: a pointer to a struct libscols_cell instance
+ * @data: private user data
+ *
+ * Returns: 0, a negative value in case of an error.
+ */
+int scols_cell_set_userdata(struct libscols_cell *ce, void *data)
+{
+       assert(ce);
+
+       if (!ce)
+               return -EINVAL;
+       ce->userdata = data;
+       return 0;
+}
+
+/**
+ * scols_cell_get_userdata
+ *
+ * @ce: a pointer to a struct libscols_cell instance
+ *
+ * Returns: user data
+ */
+void *scols_cell_get_userdata(struct libscols_cell *ce)
+{
+       return ce ? ce->userdata : NULL;
+}
+
+/**
+ * scols_cmpstr_cells:
+ * @a: pointer to cell
+ * @b: pointer to cell
+ *
+ * Compares cells data by strcmp(). The function is designed for
+ * scols_column_set_cmpfunc() and scols_sort_table().
+ *
+ * Returns: follows strcmp() return values.
+ */
+int scols_cmpstr_cells(struct libscols_cell *a,
+                      struct libscols_cell *b,
+                      __attribute__((__unused__)) void *data)
+{
+       const char *adata, *bdata;
+
+       if (a == b)
+               return 0;
+
+       adata = scols_cell_get_data(a);
+       bdata = scols_cell_get_data(b);
+
+       if (adata == NULL && bdata == NULL)
+               return 0;
+       if (adata == NULL)
+               return -1;
+       if (bdata == NULL)
+               return 1;
+       return strcmp(adata, bdata);
+}
+
 /**
  * scols_cell_set_color:
  * @ce: a pointer to a struct libscols_cell instance
@@ -179,5 +239,7 @@ int scols_cell_copy_content(struct libscols_cell *dest,
        rc = scols_cell_set_data(dest, scols_cell_get_data(src));
        if (!rc)
                rc = scols_cell_set_color(dest, scols_cell_get_color(src));
+       if (!rc)
+               dest->userdata = src->userdata;
        return rc;
 }
index a8f117f85c8a888826348a4338c033c22bfa5026..130a729e2556325d841d955b1000b5a34ab0ae46 100644 (file)
@@ -238,6 +238,30 @@ const char *scols_column_get_color(struct libscols_column *cl)
        return cl ? cl->color : NULL;
 }
 
+
+/**
+ * scols_column_set_cmpfunc:
+ * @cl: column
+ * @cmp: pointer to compare function
+ * @data: private data for cmp function
+ *
+ * Returns: 0, a negative value in case of an error.
+ */
+int scols_column_set_cmpfunc(struct libscols_column *cl,
+                       int (*cmp)(struct libscols_cell *,
+                                  struct libscols_cell *,
+                                  void *),
+                       void *data)
+{
+       assert(cl);
+       if (!cl)
+               return -EINVAL;
+
+       cl->cmpfunc = cmp;
+       cl->cmpfunc_data = data;
+       return 0;
+}
+
 /**
  * scols_column_is_trunc:
  * @cl: a pointer to a struct libscols_column instance
index 9468226f24191630d95175a903275a5c99883d0f..e61256022610b931306d6d0ee9a145f0ddf8a803 100644 (file)
@@ -116,6 +116,11 @@ extern const char *scols_cell_get_data(const struct libscols_cell *ce);
 extern int scols_cell_set_color(struct libscols_cell *ce, const char *color);
 extern const char *scols_cell_get_color(const struct libscols_cell *ce);
 
+extern void *scols_cell_get_userdata(struct libscols_cell *ce);
+extern int scols_cell_set_userdata(struct libscols_cell *ce, void *data);
+
+extern int scols_cmpstr_cells(struct libscols_cell *a,
+                             struct libscols_cell *b, void *data);
 /* column.c */
 extern int scols_column_is_tree(struct libscols_column *cl);
 extern int scols_column_is_trunc(struct libscols_column *cl);
@@ -135,6 +140,11 @@ extern struct libscols_cell *scols_column_get_header(struct libscols_column *cl)
 extern int scols_column_set_color(struct libscols_column *cl, const char *color);
 extern const char *scols_column_get_color(struct libscols_column *cl);
 
+extern int scols_column_set_cmpfunc(struct libscols_column *cl,
+                       int (*cmp)(struct libscols_cell *a,
+                                  struct libscols_cell *b, void *),
+                       void *data);
+
 /* line.c */
 extern struct libscols_line *scols_new_line(void);
 extern void scols_ref_line(struct libscols_line *ln);
@@ -153,6 +163,9 @@ extern int scols_line_set_color(struct libscols_line *ln, const char *color);
 extern const char *scols_line_get_color(struct libscols_line *ln);
 extern size_t scols_line_get_ncells(struct libscols_line *ln);
 extern struct libscols_cell *scols_line_get_cell(struct libscols_line *ln, size_t n);
+extern struct libscols_cell *scols_line_get_column_cell(
+                                       struct libscols_line *ln,
+                                       struct libscols_column *cl);
 extern int scols_line_set_data(struct libscols_line *ln, size_t n, const char *data);
 extern int scols_line_refer_data(struct libscols_line *ln, size_t n, char *data);
 extern struct libscols_line *scols_copy_line(struct libscols_line *ln);
@@ -203,6 +216,8 @@ extern int scols_table_set_stream(struct libscols_table *tb, FILE *stream);
 extern FILE *scols_table_get_stream(struct libscols_table *tb);
 extern int scols_table_reduce_termwidth(struct libscols_table *tb, size_t reduce);
 
+extern int scols_sort_table(struct libscols_table *tb, struct libscols_column *cl);
+
 /* table_print.c */
 extern int scols_print_table(struct libscols_table *tb);
 extern int scols_print_table_to_string(struct libscols_table *tb, char **data);
index 4b64f280ce2ab6ed9870f8c8db3f83ce98064835..a4de524f414cd6bb0a321ca299b0b6d399c54f4d 100644 (file)
@@ -6,9 +6,12 @@ global:
        scols_cell_copy_content;
        scols_cell_get_color;
        scols_cell_get_data;
+       scols_cell_get_userdata;
        scols_cell_refer_data;
        scols_cell_set_color;
        scols_cell_set_data;
+       scols_cell_set_userdata;
+       scols_cmpstr_cells;
        scols_column_get_color;
        scols_column_get_flags;
        scols_column_get_header;
@@ -18,6 +21,7 @@ global:
        scols_column_is_strict_width;
        scols_column_is_tree;
        scols_column_is_trunc;
+       scols_column_set_cmpfunc;
        scols_column_set_color;
        scols_column_set_flags;
        scols_column_set_whint;
@@ -34,6 +38,7 @@ global:
        scols_line_free_cells;
        scols_line_get_cell;
        scols_line_get_color;
+       scols_line_get_column_cell;
        scols_line_get_ncells;
        scols_line_get_parent;
        scols_line_get_userdata;
@@ -58,6 +63,7 @@ global:
        scols_ref_table;
        scols_reset_cell;
        scols_reset_iter;
+       scols_sort_table;
        scols_symbols_set_branch;
        scols_symbols_set_right;
        scols_symbols_set_vertical;
index 32c8964ad69b4e0ba1f2442588c98d54931c66a3..6112090819a488600af2ce5c4887b99158aac5ff 100644 (file)
@@ -354,6 +354,25 @@ struct libscols_cell *scols_line_get_cell(struct libscols_line *ln,
        return &ln->cells[n];
 }
 
+/**
+ * scols_line_get_column_cell:
+ * @ln: a pointer to a struct libscols_line instance
+ * @cl: pointer to cell
+ *
+ * Like scols_line_get_cell() by cell is referenced by column.
+ *
+ * Returns: the @n-th cell in @ln, NULL in case of an error.
+ */
+struct libscols_cell *scols_line_get_column_cell(
+                       struct libscols_line *ln,
+                       struct libscols_column *cl)
+{
+       assert(ln);
+       assert(cl);
+
+       return scols_line_get_cell(ln, cl->seqnum);
+}
+
 /**
  * scols_line_set_data:
  * @ln: a pointer to a struct libscols_cell instance
index ebdc9295f67924083a45246f66a3a6f4ab3040ed..613ddd5871667e954a30fc9114bb12d16441104a 100644 (file)
@@ -63,6 +63,7 @@ struct libscols_symbols {
 struct libscols_cell {
        char    *data;
        char    *color;
+       void    *userdata;
 };
 
 
@@ -83,6 +84,11 @@ struct libscols_column {
        int     is_extreme;
        char    *color;         /* default column color */
 
+       int (*cmpfunc)(struct libscols_cell *,
+                      struct libscols_cell *,
+                      void *);                 /* cells comparison function */
+       void *cmpfunc_data;
+
        struct libscols_cell    header;
        struct list_head        cl_columns;
 };
index d4c61eea339e8e5f07c3f34c9dd22925faeb2e32..a51a84abcb65e966cafaa27d1be20e5f7c4f3b9d 100644 (file)
@@ -977,3 +977,42 @@ char *scols_table_get_line_separator(struct libscols_table *tb)
        return tb->linesep;
 
 }
+
+static int cells_cmp_wrapper(struct list_head *a, struct list_head *b, void *data)
+{
+       struct libscols_column *cl = (struct libscols_column *) data;
+       struct libscols_line *ra, *rb;
+       struct libscols_cell *ca, *cb;
+
+       assert(a);
+       assert(b);
+       assert(cl);
+
+       ra = list_entry(a, struct libscols_line, ln_lines);
+       rb = list_entry(b, struct libscols_line, ln_lines);
+       ca = scols_line_get_cell(ra, cl->seqnum);
+       cb = scols_line_get_cell(rb, cl->seqnum);
+
+       return cl->cmpfunc(ca, cb, cl->cmpfunc_data);
+}
+
+/**
+ * scols_sort_table:
+ * @tb: table
+ * @cl: order by this column
+ *
+ * Orders the table by the column. See also scols_column_set_cmpfunc().
+ *
+ * Returns: 0, a negative value in case of an error.
+ */
+int scols_sort_table(struct libscols_table *tb, struct libscols_column *cl)
+{
+       assert(tb);
+       assert(cl);
+
+       if (!tb || !cl)
+               return -EINVAL;
+
+       list_sort(&tb->tb_lines, cells_cmp_wrapper, cl);
+       return 0;
+}