From: Karel Zak Date: Tue, 26 Sep 2023 12:44:02 +0000 (+0200) Subject: libsmartcols: search also by normalized column names (aka 'shellvar' name) X-Git-Tag: v2.40-rc1~151^2~52 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8aeb57b1d85be29a0ae00870cab6074526d8d83f;p=thirdparty%2Futil-linux.git libsmartcols: search also by normalized column names (aka 'shellvar' name) Signed-off-by: Karel Zak --- diff --git a/libsmartcols/src/column.c b/libsmartcols/src/column.c index 669568c6c8..f0a395373d 100644 --- a/libsmartcols/src/column.c +++ b/libsmartcols/src/column.c @@ -279,6 +279,58 @@ const char *scols_column_get_name(struct libscols_column *cl) return scols_cell_get_data(&cl->header); } +/** + * scols_shellvar_name: + * @name: raw (column) name + * @schellvar: returns normalized name + * + * Converts @name to a name compatible with shell. The buffer is reallocated if + * not large enough. + * + * Returns: 0 in case of conversion, 1 if conversion unnecessary, <0 on error. + * + * Since: 2.40 + */ +int scols_shellvar_name(const char *name, char **buf, size_t *bufsz) +{ + char *p; + const char *s; + size_t sz; + + if (!name || !*name || !buf || !bufsz) + return -EINVAL; + + /* size to convert "1FOO%" --> "_1FOO_PCT */ + sz = strlen(name) + 1 + 3; + if (sz + 1 > *bufsz) { + char *tmp; + + *bufsz = sz + 1; + tmp = realloc(*buf, *bufsz); + if (!tmp) + return -ENOMEM; + *buf = tmp; + } + memset(*buf, 0, *bufsz); + p = *buf; + + /* convert "1FOO" to "_1FOO" */ + if (!isalpha(*name)) + *p++ = '_'; + + /* replace all "bad" chars with "_" */ + for (s = name; *s; s++) + *p++ = !isalnum(*s) ? '_' : *s; + + if (!*s && *(s - 1) == '%') { + *p++ = 'P'; + *p++ = 'C'; + *p++ = 'T'; + } + + return strcmp(name, *buf) == 0; +} + /** * scols_column_get_name_as_shellvar * @cl: a pointer to a struct libscols_column instance @@ -291,32 +343,13 @@ const char *scols_column_get_name(struct libscols_column *cl) const char *scols_column_get_name_as_shellvar(struct libscols_column *cl) { if (!cl->shellvar) { - const char *s, *name = scols_column_get_name(cl); - char *p; - size_t sz; + const char *name = scols_column_get_name(cl); + size_t sz = 0; if (!name || !*name) return NULL; - - /* "1FOO%" --> "_1FOO_PCT */ - sz = strlen(name) + 1 + 3; - p = cl->shellvar = calloc(1, sz + 1); - if (!cl->shellvar) + if (scols_shellvar_name(name, &cl->shellvar, &sz) < 0) return NULL; - - /* convert "1FOO" to "_1FOO" */ - if (!isalpha(*name)) - *p++ = '_'; - - /* replace all "bad" chars with "_" */ - for (s = name; *s; s++) - *p++ = !isalnum(*s) ? '_' : *s; - - if (!*s && *(s - 1) == '%') { - *p++ = 'P'; - *p++ = 'C'; - *p++ = 'T'; - } } return cl->shellvar; } diff --git a/libsmartcols/src/filter-param.c b/libsmartcols/src/filter-param.c index f0cb99ac56..669dbc8255 100644 --- a/libsmartcols/src/filter-param.c +++ b/libsmartcols/src/filter-param.c @@ -782,7 +782,8 @@ int scols_filter_assign_column(struct libscols_filter *fltr, if (n->col) scols_unref_column(n->col); - DBG(FPARAM, ul_debugobj(n, "assing %s to column", name)); + DBG(FPARAM, ul_debugobj(n, "assing %s to column %s", name, + scols_column_get_name(col))); n->col = col; scols_ref_column(col); } diff --git a/libsmartcols/src/libsmartcols.h.in b/libsmartcols/src/libsmartcols.h.in index bca08a869d..ab585da223 100644 --- a/libsmartcols/src/libsmartcols.h.in +++ b/libsmartcols/src/libsmartcols.h.in @@ -222,6 +222,7 @@ extern struct libscols_table *scols_column_get_table(const struct libscols_colum extern int scols_column_set_name(struct libscols_column *cl, const char *name); extern const char *scols_column_get_name(struct libscols_column *cl); extern const char *scols_column_get_name_as_shellvar(struct libscols_column *cl); +extern int scols_shellvar_name(const char *name, char **buf, size_t *bufsz); extern int scols_column_set_properties(struct libscols_column *cl, const char *opts); diff --git a/libsmartcols/src/libsmartcols.sym b/libsmartcols/src/libsmartcols.sym index f5a08f140c..5e11ba19b3 100644 --- a/libsmartcols/src/libsmartcols.sym +++ b/libsmartcols/src/libsmartcols.sym @@ -238,4 +238,5 @@ SMARTCOLS_2.40 { scols_counter_get_result; scols_counter_get_name; scols_filter_next_counter; + scols_shellvar_name; } SMARTCOLS_2.39; diff --git a/libsmartcols/src/table.c b/libsmartcols/src/table.c index 0be68f2b83..3d23da8d9b 100644 --- a/libsmartcols/src/table.c +++ b/libsmartcols/src/table.c @@ -676,6 +676,15 @@ struct libscols_column *scols_table_get_column_by_name( if (cn && strcmp(cn, name) == 0) return cl; } + + scols_reset_iter(&itr, SCOLS_ITER_FORWARD); + while (scols_table_next_column(tb, &itr, &cl) == 0) { + const char *cn = scols_column_get_name_as_shellvar(cl); + + if (cn && strcmp(cn, name) == 0) + return cl; + } + return NULL; }