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>
This commit is contained in:
parent
2832032772
commit
57a86f9bff
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue