Now the column can define JSON-type, this commit introduces data-type.
This type is hint for filters and counters how to convert strings from
cells to raw data.
If the conversion from string is not possible, then application can
define callback for this purpose (aka. "datafunc"), this function has
to return the raw data as a void pointer.
This solution allows to use human readable things in cells (e.g.
"123MiB"), but filters and counters can still use the original data.
Signed-off-by: Karel Zak <kzak@redhat.com>
}
+/**
+ * scols_column_set_data_type:
+ * @cl: a pointer to a struct libscols_column instance
+ * @type: SCOLS_DATA_*
+ *
+ * The table always keep data in strings in form that is printed on output, but
+ * for some internal operations (like filters or counters) it needs to convert
+ * the strings to usable data format. This data format is possible to specify,
+ * by this function. If the format is not specified then filter and counters
+ * try to use SCOLS_JSON_* types, if also not define than defaults to string.
+ *
+ * If simple string conversion is not possible then application (which want to
+ * use filters and counters) needs to define data function. See
+ * scols_column_set_datafunc().
+ *
+ * Returns: 0, a negative value in case of an error.
+ *
+ * Since: 2.40
+ */
+int scols_column_set_data_type(struct libscols_column *cl, int type)
+{
+ return cl->data_type = type;
+}
+
+/**
+ * scols_column_get_data_type:
+ * @cl: a pointer to a struct libscols_column instance
+ *
+ * Returns: The current datatype setting of the column @cl.
+ *
+ * Since: 2.40
+ */
+int scols_column_get_data_type(const struct libscols_column *cl)
+{
+ return cl->data_type;;
+}
/**
* scols_column_get_table:
* @cl: a pointer to a struct libscols_column instance
return cl->color;
}
+
/**
* scols_wrapnl_nextchunk:
* @cl: a pointer to a struct libscols_column instance
return 0;
}
+/* scols_column_set_datafunc:
+ * @cl: a pointer to a struct libscols_column instance
+ * @datafunc: function to return data
+ * @userdata: optional stuff for callbacks
+ *
+ * The internal library operations (like filters) use standard cell data by default.
+ * This callback allows to use the data in another format for internal library purpose.
+ *
+ * The callback needs to return the data as pointer to void, and the datatype
+ * is defined by scols_column_set_data_type().
+ *
+ * Returns: 0, a negative value in case of an error.
+ *
+ * Since: 2.40
+ */
+int scols_column_set_datafunc(struct libscols_column *cl,
+ void *(*datafunc)(const struct libscols_column *,
+ struct libscols_cell *,
+ void *),
+ void *userdata)
+{
+ if (!cl)
+ return -EINVAL;
+
+ cl->datafunc = datafunc;
+ cl->datafunc_data = userdata;
+ return 0;
+}
+
+/**
+ * @cl: a pointer to a struct libscols_column instance
+ *
+ * Returns: 1 if datafunc defined, or 0
+ *
+ * Since: 2.40
+ */
+int scols_column_has_datafunc(struct libscols_column *cl)
+{
+ return cl && cl->datafunc != NULL ? 1 : 0;
+}
/**
* scols_column_set_safechars:
if (n->type != SCOLS_DATA_NONE)
return 0; /* already set */
- switch (n->col->json_type) {
- case SCOLS_JSON_NUMBER:
- n->type = SCOLS_DATA_U64;
- break;
- case SCOLS_JSON_BOOLEAN:
- n->type = SCOLS_DATA_BOOLEAN;
- break;
- case SCOLS_JSON_FLOAT:
- n->type = SCOLS_DATA_FLOAT;
- break;
- case SCOLS_JSON_STRING:
- default:
- n->type = SCOLS_DATA_STRING;
- break;
+ if (n->col->data_type)
+ /* use by application defined type */
+ n->type = n->col->data_type;
+ else {
+ /* use by JSON defined type, default to string if not specified */
+ switch (n->col->json_type) {
+ case SCOLS_JSON_NUMBER:
+ n->type = SCOLS_DATA_U64;
+ break;
+ case SCOLS_JSON_BOOLEAN:
+ n->type = SCOLS_DATA_BOOLEAN;
+ break;
+ case SCOLS_JSON_FLOAT:
+ n->type = SCOLS_DATA_FLOAT;
+ break;
+ case SCOLS_JSON_STRING:
+ default:
+ n->type = SCOLS_DATA_STRING;
+ break;
+ }
}
DBG(FPARAM, ul_debugobj(n, "holder %s type: %s", n->holder_name, datatype2str(n->type)));
struct filter_param *n, struct libscols_line *ln)
{
const char *data;
+ struct libscols_column *cl = n->col;
int type = n->type;
int rc = 0;
if (n->has_value || n->holder != F_HOLDER_COLUMN)
return 0;
- if (!n->col) {
+ if (!cl) {
DBG(FPARAM, ul_debugobj(n, "no column for %s holder", n->holder_name));
return -EINVAL;
}
DBG(FPARAM, ul_debugobj(n, "fetching %s data", n->holder_name));
- if (fltr->filler_cb && !scols_line_is_filled(ln, n->col->seqnum)) {
- rc = fltr->filler_cb(fltr, ln, n->col->seqnum, fltr->filler_data);
+ if (fltr->filler_cb && !scols_line_is_filled(ln, cl->seqnum)) {
+ rc = fltr->filler_cb(fltr, ln, cl->seqnum, fltr->filler_data);
if (rc)
return rc;
}
- /* read column data, use it as string */
- data = scols_line_get_column_data(ln, n->col);
- rc = param_set_data(n, SCOLS_DATA_STRING, data);
+ if (cl->datafunc) {
+ struct libscols_cell *ce = scols_line_get_column_cell(ln, cl);
+ void *data = NULL;
+
+ if (ce)
+ data = cl->datafunc(n->col, ce, cl->datafunc_data);
+ if (data)
+ rc = param_set_data(n, cl->data_type, data);
+ } else {
+ /* read column data, use it as string */
+ data = scols_line_get_column_data(ln, n->col);
+ rc = param_set_data(n, SCOLS_DATA_STRING, data);
+ }
/* cast to the wanted type */
if (rc == 0 && type != SCOLS_DATA_NONE)
extern int scols_column_set_json_type(struct libscols_column *cl, int type);
extern int scols_column_get_json_type(const struct libscols_column *cl);
+extern int scols_column_set_data_type(struct libscols_column *cl, int type);
+extern int scols_column_get_data_type(const struct libscols_column *cl);
+
extern int scols_column_set_flags(struct libscols_column *cl, int flags);
extern int scols_column_get_flags(const struct libscols_column *cl);
extern struct libscols_column *scols_new_column(void);
char *, void *),
void *userdata);
+extern int scols_column_set_datafunc(struct libscols_column *cl,
+ void *(*datafunc)(const struct libscols_column *,
+ struct libscols_cell *,
+ void *),
+ void *userdata);
+extern int scols_column_has_datafunc(struct libscols_column *cl);
+
extern char *scols_wrapnl_nextchunk(const struct libscols_column *cl, char *data, void *userdata);
extern size_t scols_wrapnl_chunksize(const struct libscols_column *cl, const char *data, void *userdata);
scols_counter_get_name;
scols_filter_next_counter;
scols_shellvar_name;
+ scols_column_set_datafunc;
+ scols_column_has_datafunc;
+ scols_column_set_data_type;
+ scols_column_get_data_type;
} SMARTCOLS_2.39;
struct libscols_wstat wstat; /* private __scols_calculate() data */
int json_type; /* SCOLS_JSON_* */
+ int data_type; /* SCOLS_DATA_* */
int flags;
char *color; /* default column color */
char *wrap_next;
struct libscols_cell *wrap_cell;
+ void *(*datafunc)(const struct libscols_column *,
+ struct libscols_cell *,
+ void *);
+ void *datafunc_data;
+
struct libscols_cell header; /* column name with color etc. */
char *shellvar; /* raw colum name in shell compatible format */