summaryrefslogtreecommitdiffstats
path: root/libsmartcols
diff options
context:
space:
mode:
authorKarel Zak2014-05-20 15:04:11 +0200
committerKarel Zak2014-05-20 15:04:11 +0200
commit57a86f9bff68f24b167df9c571a09c6b89712296 (patch)
treeb5872b3929c083b96c14fa0140157c59f8e78d2d /libsmartcols
parentsetterm: fix 'bright' in usage, remove unnecessary error message (diff)
downloadkernel-qcow2-util-linux-57a86f9bff68f24b167df9c571a09c6b89712296.tar.gz
kernel-qcow2-util-linux-57a86f9bff68f24b167df9c571a09c6b89712296.tar.xz
kernel-qcow2-util-linux-57a86f9bff68f24b167df9c571a09c6b89712296.zip
libsmartcols: add scols_sort_table()
* 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>
Diffstat (limited to 'libsmartcols')
-rw-r--r--libsmartcols/docs/libsmartcols-sections.txt6
-rw-r--r--libsmartcols/src/cell.c66
-rw-r--r--libsmartcols/src/column.c24
-rw-r--r--libsmartcols/src/libsmartcols.h.in15
-rw-r--r--libsmartcols/src/libsmartcols.sym6
-rw-r--r--libsmartcols/src/line.c19
-rw-r--r--libsmartcols/src/smartcolsP.h6
-rw-r--r--libsmartcols/src/table.c39
8 files changed, 179 insertions, 2 deletions
diff --git a/libsmartcols/docs/libsmartcols-sections.txt b/libsmartcols/docs/libsmartcols-sections.txt
index 307691e00..b07774783 100644
--- a/libsmartcols/docs/libsmartcols-sections.txt
+++ b/libsmartcols/docs/libsmartcols-sections.txt
@@ -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>
diff --git a/libsmartcols/src/cell.c b/libsmartcols/src/cell.c
index d73a1f808..1d2ab5838 100644
--- a/libsmartcols/src/cell.c
+++ b/libsmartcols/src/cell.c
@@ -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
@@ -115,6 +115,66 @@ const char *scols_cell_get_data(const struct libscols_cell *ce)
}
/**
+ * 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
* @color: color name or ESC sequence
@@ -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;
}
diff --git a/libsmartcols/src/column.c b/libsmartcols/src/column.c
index a8f117f85..130a729e2 100644
--- a/libsmartcols/src/column.c
+++ b/libsmartcols/src/column.c
@@ -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
diff --git a/libsmartcols/src/libsmartcols.h.in b/libsmartcols/src/libsmartcols.h.in
index 9468226f2..e61256022 100644
--- a/libsmartcols/src/libsmartcols.h.in
+++ b/libsmartcols/src/libsmartcols.h.in
@@ -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);
diff --git a/libsmartcols/src/libsmartcols.sym b/libsmartcols/src/libsmartcols.sym
index 4b64f280c..a4de524f4 100644
--- a/libsmartcols/src/libsmartcols.sym
+++ b/libsmartcols/src/libsmartcols.sym
@@ -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;
diff --git a/libsmartcols/src/line.c b/libsmartcols/src/line.c
index 32c8964ad..611209081 100644
--- a/libsmartcols/src/line.c
+++ b/libsmartcols/src/line.c
@@ -355,6 +355,25 @@ struct libscols_cell *scols_line_get_cell(struct libscols_line *ln,
}
/**
+ * 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
* @n: number of the cell, whose data is to be set
diff --git a/libsmartcols/src/smartcolsP.h b/libsmartcols/src/smartcolsP.h
index ebdc9295f..613ddd587 100644
--- a/libsmartcols/src/smartcolsP.h
+++ b/libsmartcols/src/smartcolsP.h
@@ -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;
};
diff --git a/libsmartcols/src/table.c b/libsmartcols/src/table.c
index d4c61eea3..a51a84abc 100644
--- a/libsmartcols/src/table.c
+++ b/libsmartcols/src/table.c
@@ -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;
+}