diff options
author | Karel Zak | 2016-09-13 13:08:02 +0200 |
---|---|---|
committer | Karel Zak | 2016-09-13 13:08:02 +0200 |
commit | fa4691833a2758ee3defc31645a502c117624369 (patch) | |
tree | f6c2e2300aa8cdc7468b00c4e129bcd3c0bc3387 | |
parent | libsmartcols: fix WRAPNL on strings without \n (diff) | |
download | kernel-qcow2-util-linux-fa4691833a2758ee3defc31645a502c117624369.tar.gz kernel-qcow2-util-linux-fa4691833a2758ee3defc31645a502c117624369.tar.xz kernel-qcow2-util-linux-fa4691833a2758ee3defc31645a502c117624369.zip |
libsmartcols: add application to test library features
Signed-off-by: Karel Zak <kzak@redhat.com>
-rw-r--r-- | libsmartcols/samples/Makemodule.am | 5 | ||||
-rw-r--r-- | libsmartcols/samples/fromfile.c | 225 | ||||
-rw-r--r-- | libsmartcols/samples/wrapnl.c | 141 | ||||
-rw-r--r-- | tests/commands.sh | 1 | ||||
-rw-r--r-- | tests/expected/libsmartcols/fromfile | 1 | ||||
-rw-r--r-- | tests/expected/libsmartcols/fromfile-right | 11 | ||||
-rw-r--r-- | tests/expected/libsmartcols/fromfile-wrapnl | 19 | ||||
-rw-r--r-- | tests/ts/libsmartcols/files/col-name | 3 | ||||
-rw-r--r-- | tests/ts/libsmartcols/files/col-number | 3 | ||||
-rw-r--r-- | tests/ts/libsmartcols/files/col-string | 3 | ||||
-rw-r--r-- | tests/ts/libsmartcols/files/col-wrap | 3 | ||||
-rw-r--r-- | tests/ts/libsmartcols/files/col-wrapnl | 3 | ||||
-rw-r--r-- | tests/ts/libsmartcols/files/data-number | 10 | ||||
-rw-r--r-- | tests/ts/libsmartcols/files/data-string | 10 | ||||
-rw-r--r-- | tests/ts/libsmartcols/files/data-string-long | 10 | ||||
-rw-r--r-- | tests/ts/libsmartcols/files/data-string-nl | 10 | ||||
-rwxr-xr-x | tests/ts/libsmartcols/fromfile | 50 |
17 files changed, 367 insertions, 141 deletions
diff --git a/libsmartcols/samples/Makemodule.am b/libsmartcols/samples/Makemodule.am index 32cf8b70d..399e75a3b 100644 --- a/libsmartcols/samples/Makemodule.am +++ b/libsmartcols/samples/Makemodule.am @@ -4,6 +4,7 @@ check_PROGRAMS += \ sample-scols-wrap \ sample-scols-wrapnl \ sample-scols-continuous \ + sample-scols-fromfile \ sample-scols-maxout sample_scols_cflags = $(AM_CFLAGS) $(NO_UNUSED_WARN_CFLAGS) \ @@ -37,3 +38,7 @@ sample_scols_maxout_SOURCES = libsmartcols/samples/maxout.c sample_scols_maxout_LDADD = $(sample_scols_ldadd) sample_scols_maxout_CFLAGS = $(sample_scols_cflags) +sample_scols_fromfile_SOURCES = libsmartcols/samples/fromfile.c +sample_scols_fromfile_LDADD = $(sample_scols_ldadd) libcommon.la +sample_scols_fromfile_CFLAGS = $(sample_scols_cflags) + diff --git a/libsmartcols/samples/fromfile.c b/libsmartcols/samples/fromfile.c new file mode 100644 index 000000000..361de01c7 --- /dev/null +++ b/libsmartcols/samples/fromfile.c @@ -0,0 +1,225 @@ +/* + * Copyright (C) 2016 Karel Zak <kzak@redhat.com> + * + * This file may be redistributed under the terms of the + * GNU Lesser General Public License. + */ +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <dirent.h> +#include <getopt.h> + +#include "c.h" +#include "nls.h" +#include "strutils.h" +#include "xalloc.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_WRAPNL }, + { "none", 0 } +}; + +static long name_to_flag(const char *name, long unsigned int namesz) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(flags); i++) { + const char *cn = flags[i].name; + + 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 flags = 0; + + if (string_to_bitmask(str, &flags, name_to_flag)) + err(EXIT_FAILURE, "failed to parse column flags"); + + return flags; +} + +static struct libscols_column *parse_column(FILE *f) +{ + size_t len = 0; + char *line = NULL; + int nlines = 0; + + struct libscols_column *cl = NULL; + + while (getline(&line, &len, f) != -1) { + + char *p = strrchr(line, '\n'); + if (p) + *p = '\0'; + + switch (nlines) { + case 0: /* NAME */ + { + struct libscols_cell *hr; + + cl = scols_new_column(); + if (!cl) + goto fail; + hr = scols_column_get_header(cl); + if (!hr || scols_cell_set_data(hr, line)) + 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 flags = parse_column_flags(line); + if (scols_column_set_flags(cl, flags)) + goto fail; + break; + } + case 3: /* COLOR */ + if (scols_column_set_color(cl, line)) + goto fail; + break; + default: + break; + } + + nlines++; + } + + return cl; +fail: + scols_unref_column(cl); + return NULL; +} + +static int parse_column_data(FILE *f, struct libscols_table *tb, int column) +{ + size_t len = 0, nlines = 0; + int i; + char *str = NULL; + + 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)); + } + + ln = scols_table_get_line(tb, nlines++); + if (!ln) + break; + scols_line_set_data(ln, column, str); + } + + return 0; + +} + +int main(int argc, char *argv[]) +{ + struct libscols_table *tb; + int c, n, nlines = 0; + + static const struct option longopts[] = { + { "maxout", 0, 0, 'm' }, + { "column", 1, 0, 'c' }, + { "nlines", 1, 0, 'n' }, + { NULL, 0, 0, 0 }, + }; + + setlocale(LC_ALL, ""); /* just to have enable UTF8 chars */ + + scols_init_debug(0); + + tb = scols_new_table(); + if (!tb) + err(EXIT_FAILURE, "failed to create output table"); + + while((c = getopt_long(argc, argv, "c:mn:", longopts, NULL)) != -1) { + switch(c) { + case 'c': /* add column from file */ + { + struct libscols_column *cl; + FILE *f = fopen(optarg, "r"); + + 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 'm': + scols_table_enable_maxout(tb, TRUE); + break; + case 'n': + nlines = strtou32_or_err(optarg, "failed to parse number of lines"); + break; + default: + err(EXIT_FAILURE, "%s [-r|--random]\n", program_invocation_short_name); + } + } + + if (nlines <= 0) + errx(EXIT_FAILURE, "--nlines not set"); + + for (n = 0; n < nlines; n++) { + struct libscols_line *ln = scols_new_line(); + + if (!ln || scols_table_add_line(tb, ln)) + err(EXIT_FAILURE, "failed to add a new line"); + } + + n = 0; + + while (optind < argc) { + FILE *f = fopen(argv[optind], "r"); + + if (!f) + err(EXIT_FAILURE, "%s: open failed", argv[optind]); + + parse_column_data(f, tb, n); + optind++; + n++; + } + + scols_table_enable_colors(tb, isatty(STDOUT_FILENO)); + + scols_print_table(tb); + scols_unref_table(tb); + return EXIT_SUCCESS; +} diff --git a/libsmartcols/samples/wrapnl.c b/libsmartcols/samples/wrapnl.c deleted file mode 100644 index 01fd2edff..000000000 --- a/libsmartcols/samples/wrapnl.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2010-2014 Karel Zak <kzak@redhat.com> - * - * This file may be redistributed under the terms of the - * GNU Lesser General Public License. - */ -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <dirent.h> -#include <getopt.h> - -#include "c.h" -#include "nls.h" -#include "strutils.h" -#include "xalloc.h" -#include "randutils.h" - -#include "libsmartcols.h" - -static int opt_random; - -enum { COL_NAME, COL_DATA1, COL_LIKE, COL_DATA2 }; - -/* add columns to the @tb */ -static void setup_columns(struct libscols_table *tb) -{ - if (!scols_table_new_column(tb, "NAME", 0, SCOLS_FL_TREE)) - goto fail; - if (!scols_table_new_column(tb, "DATA1", 0, SCOLS_FL_WRAPNL)) - goto fail; - if (!scols_table_new_column(tb, "LIKE", 0, SCOLS_FL_RIGHT)) - goto fail; - if (!scols_table_new_column(tb, "DATA2", 0, SCOLS_FL_WRAPNL)) - goto fail; - return; -fail: - scols_unref_table(tb); - err(EXIT_FAILURE, "failed to create output columns"); -} - -static char *gen_text(const char *prefix, const char *sub_prefix, char *buf, size_t sz, int nl) -{ - int x = snprintf(buf, sz, "%s-%s-", prefix, sub_prefix); - int next_nl = -1; - - for ( ; (size_t)x < sz - 1; x++) { - buf[x] = next_nl == 0 ? '\n' : *prefix; - - if (nl) - next_nl--; - if (nl && next_nl < 0) - next_nl = opt_random ? - (size_t) rand_get_number(1, sz / 2) : - sz / 3; - } - - buf[x++] = 'x'; - buf[x] = '\0'; - return buf; -} - -static struct libscols_line * add_line( struct libscols_table *tb, - struct libscols_line *parent, - const char *prefix) -{ - char buf[BUFSIZ]; - struct libscols_line *ln = scols_table_new_line(tb, parent); - if (!ln) - err(EXIT_FAILURE, "failed to create output line"); - - if (scols_line_set_data(ln, COL_NAME, gen_text(prefix, "N", buf, 15, 0))) - goto fail; - if (scols_line_set_data(ln, COL_DATA1, gen_text(prefix, "D", buf, 40, 1))) - goto fail; - if (scols_line_set_data(ln, COL_LIKE, "1")) - goto fail; - if (scols_line_set_data(ln, COL_DATA2, gen_text(prefix, "E", buf, 40, 1))) - goto fail; - return ln; -fail: - scols_unref_table(tb); - err(EXIT_FAILURE, "failed to create output line"); -} - -int main(int argc, char *argv[]) -{ - struct libscols_table *tb; - struct libscols_line *ln, *xln; - int c; - - static const struct option longopts[] = { - { "random", 0, 0, 'r' }, - { "maxout", 0, 0, 'm' }, - { NULL, 0, 0, 0 }, - }; - - setlocale(LC_ALL, ""); /* just to have enable UTF8 chars */ - - scols_init_debug(0); - - tb = scols_new_table(); - if (!tb) - err(EXIT_FAILURE, "failed to create output table"); - - while((c = getopt_long(argc, argv, "rm", longopts, NULL)) != -1) { - switch(c) { - case 'r': - opt_random = 1; - break; - case 'm': - scols_table_enable_maxout(tb, TRUE); - break; - default: - err(EXIT_FAILURE, "%s [-r|--random]\n", program_invocation_short_name); - } - } - - if (opt_random) - xsrand(); - - scols_table_enable_colors(tb, isatty(STDOUT_FILENO)); - setup_columns(tb); - - ln = add_line(tb, NULL, "A"); - add_line(tb, ln, "aa"); - add_line(tb, ln, "ab"); - - ln = add_line(tb, NULL, "B"); - xln = add_line(tb, ln, "ba"); - add_line(tb, xln, "baa"); - add_line(tb, xln, "bab"); - add_line(tb, ln, "bb"); - - scols_print_table(tb); - scols_unref_table(tb); - return EXIT_SUCCESS; -} diff --git a/tests/commands.sh b/tests/commands.sh index a69c87e42..102711c51 100644 --- a/tests/commands.sh +++ b/tests/commands.sh @@ -16,6 +16,7 @@ TS_HELPER_LIBMOUNT_TAB="$top_builddir/test_mount_tab" TS_HELPER_LIBMOUNT_UPDATE="$top_builddir/test_mount_tab_update" TS_HELPER_LIBMOUNT_UTILS="$top_builddir/test_mount_utils" TS_HELPER_LIBMOUNT_DEBUG="$top_builddir/test_mount_debug" +TS_HELPER_LIBSMARTCOLS_FROMFILE="$top_builddir/sample-scols-fromfile" TS_HELPER_PYLIBMOUNT_CONTEXT="$top_srcdir/libmount/python/test_mount_context.py" TS_HELPER_PYLIBMOUNT_TAB="$top_srcdir/libmount/python/test_mount_tab.py" TS_HELPER_PYLIBMOUNT_UPDATE="$top_srcdir/libmount/python/test_mount_tab_update.py" diff --git a/tests/expected/libsmartcols/fromfile b/tests/expected/libsmartcols/fromfile new file mode 100644 index 000000000..4155aa36f --- /dev/null +++ b/tests/expected/libsmartcols/fromfile @@ -0,0 +1 @@ +...done. diff --git a/tests/expected/libsmartcols/fromfile-right b/tests/expected/libsmartcols/fromfile-right new file mode 100644 index 000000000..d78285a13 --- /dev/null +++ b/tests/expected/libsmartcols/fromfile-right @@ -0,0 +1,11 @@ +NAME NUM STRINGS +aaaa 0 qqqqqqqqqqqqqqqqqX +bbb 100 dddddddddddddX +ccccc 21 ffffffffffffffffffffffffffffffffffffffffX +dddddd 3 ssssssssssX +ee 411 ddddddddddddddddddddddddddX +ffff 5111 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjX +gggggg 678993321 mmmmmmmmmmmmmmmmmmmX +hhh 7666666 lllllllllllllllllllllllllllllllllllllX +iiiiii 8765 yyyyyyyyyyyyyyyyyyyyyyyyyyyyX +jj 987456 pppppppppX diff --git a/tests/expected/libsmartcols/fromfile-wrapnl b/tests/expected/libsmartcols/fromfile-wrapnl new file mode 100644 index 000000000..c747ebb08 --- /dev/null +++ b/tests/expected/libsmartcols/fromfile-wrapnl @@ -0,0 +1,19 @@ +NAME NUM WRAPNL +aaaa 0 aaa +bbb 100 bbbbb +ccccc 21 cccc + CCCC +dddddd 3 dddddddd + DDDD + DD +ee 411 hello + baby +ffff 5111 aaa + bbb + ccc + ddd +gggggg 678993321 eee +hhh 7666666 fffff +iiiiii 8765 g + hhhhh +jj 987456 ppppppppp diff --git a/tests/ts/libsmartcols/files/col-name b/tests/ts/libsmartcols/files/col-name new file mode 100644 index 000000000..0a98f29cf --- /dev/null +++ b/tests/ts/libsmartcols/files/col-name @@ -0,0 +1,3 @@ +NAME +0 +none diff --git a/tests/ts/libsmartcols/files/col-number b/tests/ts/libsmartcols/files/col-number new file mode 100644 index 000000000..5ef733f97 --- /dev/null +++ b/tests/ts/libsmartcols/files/col-number @@ -0,0 +1,3 @@ +NUM +3 +right diff --git a/tests/ts/libsmartcols/files/col-string b/tests/ts/libsmartcols/files/col-string new file mode 100644 index 000000000..7e2904b9f --- /dev/null +++ b/tests/ts/libsmartcols/files/col-string @@ -0,0 +1,3 @@ +STRINGS +0 +none diff --git a/tests/ts/libsmartcols/files/col-wrap b/tests/ts/libsmartcols/files/col-wrap new file mode 100644 index 000000000..dc4ca340e --- /dev/null +++ b/tests/ts/libsmartcols/files/col-wrap @@ -0,0 +1,3 @@ +WRAP +0 +wrap diff --git a/tests/ts/libsmartcols/files/col-wrapnl b/tests/ts/libsmartcols/files/col-wrapnl new file mode 100644 index 000000000..0a18fd146 --- /dev/null +++ b/tests/ts/libsmartcols/files/col-wrapnl @@ -0,0 +1,3 @@ +WRAPNL +0 +wrapnl diff --git a/tests/ts/libsmartcols/files/data-number b/tests/ts/libsmartcols/files/data-number new file mode 100644 index 000000000..562d75061 --- /dev/null +++ b/tests/ts/libsmartcols/files/data-number @@ -0,0 +1,10 @@ +0 +100 +21 +3 +411 +5111 +678993321 +7666666 +8765 +987456 diff --git a/tests/ts/libsmartcols/files/data-string b/tests/ts/libsmartcols/files/data-string new file mode 100644 index 000000000..dff6e9c80 --- /dev/null +++ b/tests/ts/libsmartcols/files/data-string @@ -0,0 +1,10 @@ +aaaa +bbb +ccccc +dddddd +ee +ffff +gggggg +hhh +iiiiii +jj diff --git a/tests/ts/libsmartcols/files/data-string-long b/tests/ts/libsmartcols/files/data-string-long new file mode 100644 index 000000000..1b5683aa4 --- /dev/null +++ b/tests/ts/libsmartcols/files/data-string-long @@ -0,0 +1,10 @@ +qqqqqqqqqqqqqqqqqX +dddddddddddddX +ffffffffffffffffffffffffffffffffffffffffX +ssssssssssX +ddddddddddddddddddddddddddX +jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjX +mmmmmmmmmmmmmmmmmmmX +lllllllllllllllllllllllllllllllllllllX +yyyyyyyyyyyyyyyyyyyyyyyyyyyyX +pppppppppX diff --git a/tests/ts/libsmartcols/files/data-string-nl b/tests/ts/libsmartcols/files/data-string-nl new file mode 100644 index 000000000..7822e57bc --- /dev/null +++ b/tests/ts/libsmartcols/files/data-string-nl @@ -0,0 +1,10 @@ +aaa +bbbbb +cccc\nCCCC +dddddddd\nDDDD\nDD +hello\nbaby +aaa\nbbb\nccc\nddd +eee +fffff +g\nhhhhh +ppppppppp diff --git a/tests/ts/libsmartcols/fromfile b/tests/ts/libsmartcols/fromfile new file mode 100755 index 000000000..456ca4367 --- /dev/null +++ b/tests/ts/libsmartcols/fromfile @@ -0,0 +1,50 @@ +#!/bin/bash +# +# This file is part of util-linux. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This file is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# + +TS_TOPDIR="${0%/*}/../.." +TS_DESC="fromfile" + +. $TS_TOPDIR/functions.sh +ts_init "$*" + +TESTPROG="$TS_HELPER_LIBSMARTCOLS_FROMFILE" +ts_check_test_command "$TESTPROG" + + +ts_init_subtest "right" +$TESTPROG --nlines 10 \ + --column $TS_SELF/files/col-name \ + --column $TS_SELF/files/col-number \ + --column $TS_SELF/files/col-string \ + $TS_SELF/files/data-string \ + $TS_SELF/files/data-number \ + $TS_SELF/files/data-string-long \ + >> $TS_OUTPUT 2>&1 +ts_finalize_subtest + +ts_init_subtest "wrapnl" +$TESTPROG --nlines 10 \ + --column $TS_SELF/files/col-name \ + --column $TS_SELF/files/col-number \ + --column $TS_SELF/files/col-wrapnl \ + $TS_SELF/files/data-string \ + $TS_SELF/files/data-number \ + $TS_SELF/files/data-string-nl \ + >> $TS_OUTPUT 2>&1 +ts_finalize_subtest + +ts_log "...done." +ts_finalize |