summaryrefslogtreecommitdiffstats
path: root/libsmartcols/samples
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-14 19:33:30 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-14 19:33:30 +0000
commitc61e14d3a8412cd50d98aab604e607692c844c8a (patch)
tree4925aca0e6b64c8664ea2f3fdfa99a52dc93d5da /libsmartcols/samples
parentAdding upstream version 2.39.3. (diff)
downloadutil-linux-c61e14d3a8412cd50d98aab604e607692c844c8a.tar.xz
util-linux-c61e14d3a8412cd50d98aab604e607692c844c8a.zip
Adding upstream version 2.40.upstream/2.40
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'libsmartcols/samples')
-rw-r--r--libsmartcols/samples/Makemodule.am8
-rw-r--r--libsmartcols/samples/continuous-json.c80
-rw-r--r--libsmartcols/samples/continuous.c4
-rw-r--r--libsmartcols/samples/fromfile.c259
-rw-r--r--libsmartcols/samples/maxout.c2
-rw-r--r--libsmartcols/samples/wrap.c10
6 files changed, 240 insertions, 123 deletions
diff --git a/libsmartcols/samples/Makemodule.am b/libsmartcols/samples/Makemodule.am
index c0130b9..b192eba 100644
--- a/libsmartcols/samples/Makemodule.am
+++ b/libsmartcols/samples/Makemodule.am
@@ -4,13 +4,13 @@ check_PROGRAMS += \
sample-scols-title \
sample-scols-wrap \
sample-scols-continuous \
+ sample-scols-continuous-json \
sample-scols-fromfile \
sample-scols-grouping-simple \
sample-scols-grouping-overlay \
sample-scols-maxout
-sample_scols_cflags = $(AM_CFLAGS) $(NO_UNUSED_WARN_CFLAGS) \
- -I$(ul_libsmartcols_incdir)
+sample_scols_cflags = $(AM_CFLAGS) -I$(ul_libsmartcols_incdir)
sample_scols_ldadd = libsmartcols.la $(LDADD)
if HAVE_OPENAT
@@ -36,6 +36,10 @@ sample_scols_continuous_SOURCES = libsmartcols/samples/continuous.c
sample_scols_continuous_LDADD = $(sample_scols_ldadd) libcommon.la
sample_scols_continuous_CFLAGS = $(sample_scols_cflags)
+sample_scols_continuous_json_SOURCES = libsmartcols/samples/continuous-json.c
+sample_scols_continuous_json_LDADD = $(sample_scols_ldadd) libcommon.la
+sample_scols_continuous_json_CFLAGS = $(sample_scols_cflags)
+
sample_scols_maxout_SOURCES = libsmartcols/samples/maxout.c
sample_scols_maxout_LDADD = $(sample_scols_ldadd)
sample_scols_maxout_CFLAGS = $(sample_scols_cflags)
diff --git a/libsmartcols/samples/continuous-json.c b/libsmartcols/samples/continuous-json.c
new file mode 100644
index 0000000..ae1f405
--- /dev/null
+++ b/libsmartcols/samples/continuous-json.c
@@ -0,0 +1,80 @@
+/*
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ *
+ * Copyright (C) 2016 Karel Zak <kzak@redhat.com>
+ * Copyright (C) 2023 Thomas Weißschuh <thomas@t-8ch.de>
+ */
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include "c.h"
+#include "xalloc.h"
+
+#include "libsmartcols.h"
+
+/* add columns to the @tb */
+static void setup_columns(struct libscols_table *tb)
+{
+ scols_table_enable_maxout(tb, 1);
+ if (!scols_table_new_column(tb, "COUNT", 0.1, SCOLS_FL_RIGHT))
+ goto fail;
+ if (!scols_table_new_column(tb, "TEXT", 0.9, 0))
+ goto fail;
+ return;
+fail:
+ scols_unref_table(tb);
+ err(EXIT_FAILURE, "failed to create output columns");
+}
+
+static struct libscols_line *add_line(struct libscols_table *tb, int i)
+{
+ char *p;
+ struct libscols_line *ln = scols_table_new_line(tb, NULL);
+
+ if (!ln)
+ err(EXIT_FAILURE, "failed to create output line");
+
+ xasprintf(&p, "%d", i);
+ if (scols_line_refer_data(ln, 0, p))
+ goto fail;
+
+ xasprintf(&p, "text%d", i);
+ if (scols_line_refer_data(ln, 1, p))
+ goto fail;
+
+ return ln;
+fail:
+ scols_unref_table(tb);
+ err(EXIT_FAILURE, "failed to create output line");
+}
+
+int main(void)
+{
+ struct libscols_table *tb;
+ size_t i;
+
+ scols_init_debug(0);
+
+ tb = scols_new_table();
+ if (!tb)
+ err(EXIT_FAILURE, "failed to create output table");
+ scols_table_enable_json(tb, 1);
+
+ setup_columns(tb);
+
+ for (i = 0; i < 10; i++) {
+ struct libscols_line *line;
+
+ line = add_line(tb, i);
+
+ /* print the line */
+ scols_table_print_range(tb, line, NULL);
+
+ fflush(scols_table_get_stream(tb));
+ }
+
+ scols_unref_table(tb);
+ return EXIT_SUCCESS;
+}
diff --git a/libsmartcols/samples/continuous.c b/libsmartcols/samples/continuous.c
index 6bdba6e..432b027 100644
--- a/libsmartcols/samples/continuous.c
+++ b/libsmartcols/samples/continuous.c
@@ -65,7 +65,7 @@ fail:
err(EXIT_FAILURE, "failed to create output line");
}
-int main(int argc, char *argv[])
+int main(void)
{
struct libscols_table *tb;
size_t i;
@@ -85,7 +85,7 @@ int main(int argc, char *argv[])
struct libscols_line *line;
struct timeval now;
int done = 0;
- char *timecell = xmalloc( timecellsz );
+ char *timecell = xcalloc(1, timecellsz );
line = add_line(tb, i);
diff --git a/libsmartcols/samples/fromfile.c b/libsmartcols/samples/fromfile.c
index 0fdc929..cf77cc4 100644
--- a/libsmartcols/samples/fromfile.c
+++ b/libsmartcols/samples/fromfile.c
@@ -18,136 +18,63 @@
#include "strutils.h"
#include "xalloc.h"
#include "optutils.h"
+#include "mangle.h"
+#include "path.h"
#include "libsmartcols.h"
-struct column_flag {
- const char *name;
- int mask;
-};
-
-static const struct column_flag flags[] = {
- { "trunc", SCOLS_FL_TRUNC },
- { "tree", SCOLS_FL_TREE },
- { "right", SCOLS_FL_RIGHT },
- { "strictwidth",SCOLS_FL_STRICTWIDTH },
- { "noextremes", SCOLS_FL_NOEXTREMES },
- { "hidden", SCOLS_FL_HIDDEN },
- { "wrap", SCOLS_FL_WRAP },
- { "wrapnl", SCOLS_FL_WRAP },
- { "none", 0 }
-};
-
-static long name_to_flag(const char *name, size_t namesz)
+static struct libscols_column *parse_column(const char *path)
{
- size_t i;
+ char buf[BUFSIZ];
+ struct libscols_column *cl;
- for (i = 0; i < ARRAY_SIZE(flags); i++) {
- const char *cn = flags[i].name;
+ if (ul_path_read_buffer(NULL, buf, sizeof(buf), path) < 0)
+ err(EXIT_FAILURE, "failed to read column: %s", path);
- if (!strncasecmp(name, cn, namesz) && !*(cn + namesz))
- return flags[i].mask;
- }
- warnx("unknown flag: %s", name);
- return -1;
-}
-
-static int parse_column_flags(char *str)
-{
- unsigned long num_flags = 0;
-
- if (string_to_bitmask(str, &num_flags, name_to_flag))
- err(EXIT_FAILURE, "failed to parse column flags");
-
- return num_flags;
-}
-
-static struct libscols_column *parse_column(FILE *f)
-{
- size_t len = 0;
- char *line = NULL;
- int nlines = 0;
+ cl = scols_new_column();
+ if (!cl)
+ err(EXIT_FAILURE, "failed to allocate column");
- struct libscols_column *cl = NULL;
+ if (scols_column_set_properties(cl, buf) != 0)
+ err(EXIT_FAILURE, "failed to set column properties");
- while (getline(&line, &len, f) != -1) {
-
- char *p = strrchr(line, '\n');
- if (p)
- *p = '\0';
-
- switch (nlines) {
- case 0: /* NAME */
- cl = scols_new_column();
- if (!cl)
- goto fail;
- if (scols_column_set_name(cl, line) != 0)
- goto fail;
- break;
-
- case 1: /* WIDTH-HINT */
- {
- double whint = strtod_or_err(line, "failed to parse column whint");
- if (scols_column_set_whint(cl, whint))
- goto fail;
- break;
- }
- case 2: /* FLAGS */
- {
- int num_flags = parse_column_flags(line);
- if (scols_column_set_flags(cl, num_flags))
- goto fail;
- if (strcmp(line, "wrapnl") == 0) {
- scols_column_set_wrapfunc(cl,
- scols_wrapnl_chunksize,
- scols_wrapnl_nextchunk,
- NULL);
- scols_column_set_safechars(cl, "\n");
- }
- break;
- }
- case 3: /* COLOR */
- if (scols_column_set_color(cl, line))
- goto fail;
- break;
- default:
- break;
- }
-
- nlines++;
- }
-
- free(line);
return cl;
-fail:
- free(line);
- scols_unref_column(cl);
- return NULL;
}
static int parse_column_data(FILE *f, struct libscols_table *tb, int col)
{
size_t len = 0, nlines = 0;
- int i;
- char *str = NULL;
+ ssize_t i;
+ char *str = NULL, *p;
while ((i = getline(&str, &len, f)) != -1) {
-
struct libscols_line *ln;
- char *p = strrchr(str, '\n');
- if (p)
- *p = '\0';
-
- while ((p = strrchr(str, '\\')) && *(p + 1) == 'n') {
- *p = '\n';
- memmove(p + 1, p + 2, i - (p + 2 - str));
- }
+ int rc = 0;
ln = scols_table_get_line(tb, nlines++);
if (!ln)
break;
- if (*str && scols_line_set_data(ln, col, str) != 0)
+ p = strrchr(str, '\n');
+ if (p)
+ *p = '\0';
+ if (!*str)
+ continue;
+
+ /* convert \x?? to real bytes */
+ if (strstr(str, "\\x")) {
+ struct libscols_cell *ce = scols_line_get_cell(ln, col);
+ size_t sz = i + 1;
+ char *buf = xcalloc(1, sz);
+
+ sz = unhexmangle_to_buffer(str, buf, sz);
+ if (sz)
+ rc = scols_cell_refer_memory(ce, buf, sz);
+ else
+ free(buf);
+ } else
+ rc = scols_line_set_data(ln, col, str);
+ if (rc)
err(EXIT_FAILURE, "failed to add output data");
}
@@ -193,6 +120,83 @@ static void compose_tree(struct libscols_table *tb, int parent_col, int id_col)
scols_free_iter(itr);
}
+static struct libscols_filter *init_filter(
+ struct libscols_table *tb,
+ const char *query, int dump)
+{
+ struct libscols_iter *itr;
+ struct libscols_filter *f = scols_new_filter(NULL);
+ const char *name = NULL;
+ int rc = 0;
+
+ if (!f)
+ err(EXIT_FAILURE, "failed to allocate filter");
+ if (scols_filter_parse_string(f, query) != 0) {
+ warnx("failed to parse filter: %s", scols_filter_get_errmsg(f));
+ scols_unref_filter(f);
+ return NULL;
+ }
+
+ itr = scols_new_iter(SCOLS_ITER_FORWARD);
+ if (!itr)
+ err(EXIT_FAILURE, "failed to allocate iterator");
+
+ while (scols_filter_next_holder(f, itr, &name, 0) == 0) {
+ struct libscols_column *col;
+
+ col = scols_table_get_column_by_name(tb, name);
+ if (!col) {
+ warnx("unknown column '%s' in filter", name);
+ rc++;
+ continue;
+ }
+ scols_filter_assign_column(f, itr, name, col);
+ }
+
+ scols_free_iter(itr);
+ if (dump && f)
+ scols_dump_filter(f, stdout);
+ if (rc) {
+ scols_unref_filter(f);
+ errx(EXIT_FAILURE, "failed to initialize filter");
+ }
+
+ return f;
+}
+
+/* Note: This is a simple (naive) way to use the filter, employed here for
+ * testing functionality.
+ *
+ * A more effective approach to using the filter is demonstrated in lsblk.c,
+ * where data manipulation is divided into two steps. The initial step prepares
+ * only the data necessary for evaluating the filter, and the remaining data is
+ * gathered later, only if necessary.
+ */
+static void apply_filter(struct libscols_table *tb, struct libscols_filter *fltr)
+{
+ struct libscols_iter *itr = scols_new_iter(SCOLS_ITER_FORWARD);
+ struct libscols_line *ln;
+
+ if (!itr)
+ err(EXIT_FAILURE, "failed to allocate iterator");
+
+ while (scols_table_next_line(tb, itr, &ln) == 0) {
+ int status = 0;
+
+ if (scols_line_apply_filter(ln, fltr, &status) != 0)
+ err(EXIT_FAILURE, "failed to apply filter");
+ if (status == 0) {
+ struct libscols_line *x = scols_line_get_parent(ln);
+
+ if (x)
+ scols_line_remove_child(x, ln);
+ scols_table_remove_line(tb, ln);
+ ln = NULL;
+ }
+ }
+
+ scols_free_iter(itr);
+}
static void __attribute__((__noreturn__)) usage(void)
{
@@ -211,6 +215,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(" -w, --width <num> hardcode terminal width\n", out);
fputs(" -p, --tree-parent-column <n> parent column\n", out);
fputs(" -i, --tree-id-column <n> id column\n", out);
+ fputs(" -Q, --filter <expr> filter\n", out);
fputs(" -h, --help this help\n", out);
fputs("\n", out);
@@ -220,8 +225,11 @@ static void __attribute__((__noreturn__)) usage(void)
int main(int argc, char *argv[])
{
struct libscols_table *tb;
- int c, n, nlines = 0;
+ int c, n, nlines = 0, rc;
int parent_col = -1, id_col = -1;
+ int fltr_dump = 0;
+ const char *fltr_str = NULL;
+ struct libscols_filter *fltr = NULL;
static const struct option longopts[] = {
{ "maxout", 0, NULL, 'm' },
@@ -235,6 +243,8 @@ int main(int argc, char *argv[])
{ "raw", 0, NULL, 'r' },
{ "export", 0, NULL, 'E' },
{ "colsep", 1, NULL, 'C' },
+ { "filter", 1, NULL, 'Q' },
+ { "filter-dump", 0, NULL, 'd' },
{ "help", 0, NULL, 'h' },
{ NULL, 0, NULL, 0 },
};
@@ -253,25 +263,23 @@ int main(int argc, char *argv[])
if (!tb)
err(EXIT_FAILURE, "failed to create output table");
- while((c = getopt_long(argc, argv, "hCc:Ei:JMmn:p:rw:", longopts, NULL)) != -1) {
+ while((c = getopt_long(argc, argv, "hCc:dEi:JMmn:p:Q:rw:", longopts, NULL)) != -1) {
err_exclusive_options(c, longopts, excl, excl_st);
switch(c) {
case 'c': /* add column from file */
{
- struct libscols_column *cl;
- FILE *f = fopen(optarg, "r");
+ struct libscols_column *cl = parse_column(optarg);
- if (!f)
- err(EXIT_FAILURE, "%s: open failed", optarg);
- cl = parse_column(f);
if (cl && scols_table_add_column(tb, cl))
err(EXIT_FAILURE, "%s: failed to add column", optarg);
scols_unref_column(cl);
- fclose(f);
break;
}
+ case 'd':
+ fltr_dump = 1;
+ break;
case 'p':
parent_col = strtou32_or_err(optarg, "failed to parse tree PARENT column");
break;
@@ -300,6 +308,9 @@ int main(int argc, char *argv[])
case 'n':
nlines = strtou32_or_err(optarg, "failed to parse number of lines");
break;
+ case 'Q':
+ fltr_str = optarg;
+ break;
case 'w':
scols_table_set_termforce(tb, SCOLS_TERMFORCE_ALWAYS);
scols_table_set_termwidth(tb, strtou32_or_err(optarg, "failed to parse terminal width"));
@@ -323,6 +334,14 @@ int main(int argc, char *argv[])
scols_unref_line(ln);
}
+ if (fltr_str) {
+ fltr = init_filter(tb, fltr_str, fltr_dump);
+ if (!fltr) {
+ rc = EXIT_FAILURE;
+ goto done;
+ }
+ }
+
n = 0;
while (optind < argc) {
@@ -341,7 +360,13 @@ int main(int argc, char *argv[])
scols_table_enable_colors(tb, isatty(STDOUT_FILENO));
+ if (fltr)
+ apply_filter(tb, fltr);
+
scols_print_table(tb);
+ rc = EXIT_SUCCESS;
+done:
+ scols_unref_filter(fltr);
scols_unref_table(tb);
- return EXIT_SUCCESS;
+ return rc;
}
diff --git a/libsmartcols/samples/maxout.c b/libsmartcols/samples/maxout.c
index 20c6424..a867697 100644
--- a/libsmartcols/samples/maxout.c
+++ b/libsmartcols/samples/maxout.c
@@ -19,7 +19,7 @@
enum { COL_LEFT, COL_FOO, COL_RIGHT };
-int main(int argc, char *argv[])
+int main(void)
{
struct libscols_table *tb;
int rc = -1, nlines = 3;
diff --git a/libsmartcols/samples/wrap.c b/libsmartcols/samples/wrap.c
index 795bef7..8368304 100644
--- a/libsmartcols/samples/wrap.c
+++ b/libsmartcols/samples/wrap.c
@@ -92,7 +92,15 @@ int main(int argc, char *argv[])
if (!tb)
err(EXIT_FAILURE, "failed to create output table");
- scols_table_enable_colors(tb, isatty(STDOUT_FILENO));
+ if (argc > 1 && strcmp(argv[1], "--export") == 0)
+ scols_table_enable_export(tb, 1);
+ else if (argc > 1 && strcmp(argv[1], "--raw") == 0)
+ scols_table_enable_raw(tb, 1);
+ else if (argc > 1 && strcmp(argv[1], "--json") == 0)
+ scols_table_enable_json(tb, 1);
+ else
+ scols_table_enable_colors(tb, isatty(STDOUT_FILENO));
+
setup_columns(tb);
ln = add_line(tb, NULL, "A");