diff options
30 files changed, 149 insertions, 524 deletions
diff --git a/configure.ac b/configure.ac index cee804a93..f0abedf17 100644 --- a/configure.ac +++ b/configure.ac @@ -1527,6 +1527,7 @@ AC_ARG_ENABLE([lsmem], ) UL_BUILD_INIT([lsmem]) UL_REQUIRES_LINUX([lsmem]) +UL_REQUIRES_BUILD([lsmem], [libsmartcols]) AM_CONDITIONAL([BUILD_LSMEM], [test "x$build_lsmem" = xyes]) diff --git a/libsmartcols/docs/libsmartcols-sections.txt b/libsmartcols/docs/libsmartcols-sections.txt index a55716db9..13a35646b 100644 --- a/libsmartcols/docs/libsmartcols-sections.txt +++ b/libsmartcols/docs/libsmartcols-sections.txt @@ -71,6 +71,7 @@ scols_line_get_ncells scols_line_get_parent scols_line_get_userdata scols_line_has_children +scols_line_is_ancestor scols_line_next_child scols_line_refer_column_data scols_line_refer_data diff --git a/libsmartcols/src/libsmartcols.h.in b/libsmartcols/src/libsmartcols.h.in index 1ff465e44..e77af857a 100644 --- a/libsmartcols/src/libsmartcols.h.in +++ b/libsmartcols/src/libsmartcols.h.in @@ -193,6 +193,7 @@ extern void *scols_line_get_userdata(struct libscols_line *ln); extern int scols_line_remove_child(struct libscols_line *ln, struct libscols_line *child); extern int scols_line_add_child(struct libscols_line *ln, struct libscols_line *child); extern int scols_line_has_children(struct libscols_line *ln); +extern int scols_line_is_ancestor(struct libscols_line *ln, struct libscols_line *parent); extern int scols_line_next_child(struct libscols_line *ln, struct libscols_iter *itr, struct libscols_line **chld); extern struct libscols_line *scols_line_get_parent(const struct libscols_line *ln); diff --git a/libsmartcols/src/libsmartcols.sym b/libsmartcols/src/libsmartcols.sym index 95fcc3167..174122e49 100644 --- a/libsmartcols/src/libsmartcols.sym +++ b/libsmartcols/src/libsmartcols.sym @@ -164,4 +164,5 @@ global: scols_cell_get_alignment; scols_table_move_column; scols_sort_table_by_tree; + scols_line_is_ancestor; } SMARTCOLS_2.29; diff --git a/libsmartcols/src/line.c b/libsmartcols/src/line.c index 1c3141a16..134bf2d8e 100644 --- a/libsmartcols/src/line.c +++ b/libsmartcols/src/line.c @@ -307,6 +307,25 @@ int scols_line_next_child(struct libscols_line *ln, return rc; } + +/** + * scols_line_is_ancestor: + * @ln: line + * @parent: potential parent + * + * The function is designed to detect circular dependencies between @ln and + * @parent. It checks if @ln is not any (grand) parent in the @parent's tree. + */ +int scols_line_is_ancestor(struct libscols_line *ln, struct libscols_line *parent) +{ + while (parent) { + if (parent == ln) + return 1; + parent = scols_line_get_parent(parent); + }; + return 0; +} + /** * scols_line_set_color: * @ln: a pointer to a struct libscols_line instance diff --git a/misc-utils/blkid.c b/misc-utils/blkid.c index d8cf39a2f..1dc8f4085 100644 --- a/misc-utils/blkid.c +++ b/misc-utils/blkid.c @@ -785,6 +785,7 @@ int main(int argc, char **argv) case 'V': case 'v': print_version(stdout); + err = 0; goto exit; case 'w': /* ignore - backward compatibility */ diff --git a/tests/expected/build-sys/config-all b/tests/expected/build-sys/config-all index 302841b21..aa7564f8a 100644 --- a/tests/expected/build-sys/config-all +++ b/tests/expected/build-sys/config-all @@ -1,7 +1,9 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libmount libncursesw librt libsmartcols libtinfo libuuid +column: libsmartcols eject: libblkid libmount librt libuuid fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid findmnt: libblkid libmount librt libsmartcols libudev libuuid fsck: libblkid libmount librt libuuid @@ -17,6 +19,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libsmartcols libuuid lslogins: libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libuuid mount: libblkid libmount librt libuuid @@ -37,16 +40,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libuser col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-all-non-nls b/tests/expected/build-sys/config-all-non-nls index 302841b21..aa7564f8a 100644 --- a/tests/expected/build-sys/config-all-non-nls +++ b/tests/expected/build-sys/config-all-non-nls @@ -1,7 +1,9 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libmount libncursesw librt libsmartcols libtinfo libuuid +column: libsmartcols eject: libblkid libmount librt libuuid fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid findmnt: libblkid libmount librt libsmartcols libudev libuuid fsck: libblkid libmount librt libuuid @@ -17,6 +19,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libsmartcols libuuid lslogins: libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libuuid mount: libblkid libmount librt libuuid @@ -37,16 +40,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libuser col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-audit b/tests/expected/build-sys/config-audit index dfdcd7731..2042f765b 100644 --- a/tests/expected/build-sys/config-audit +++ b/tests/expected/build-sys/config-audit @@ -1,7 +1,9 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libmount libncursesw librt libsmartcols libtinfo libuuid +column: libsmartcols eject: libblkid libmount librt libuuid fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid findmnt: libblkid libmount librt libsmartcols libudev libuuid fsck: libblkid libmount librt libuuid @@ -17,6 +19,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libsmartcols libuuid lslogins: libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libuuid mount: libblkid libmount librt libuuid @@ -37,16 +40,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libuser col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-chfnsh-libuser b/tests/expected/build-sys/config-chfnsh-libuser index 6fd737373..d0f01ed29 100644 --- a/tests/expected/build-sys/config-chfnsh-libuser +++ b/tests/expected/build-sys/config-chfnsh-libuser @@ -1,7 +1,9 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libmount libncursesw librt libselinux libsmartcols libtinfo libuuid +column: libsmartcols eject: libblkid libmount librt libselinux libuuid fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid findmnt: libblkid libmount librt libselinux libsmartcols libudev libuuid fsck: libblkid libmount librt libselinux libuuid @@ -17,6 +19,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libselinux libsmartcols libuuid lslogins: libselinux libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libselinux libuuid mount: libblkid libmount librt libselinux libuuid @@ -37,16 +40,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libselinux libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libselinux libuser col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-chfnsh-no-password b/tests/expected/build-sys/config-chfnsh-no-password index 884a3aef6..6f7467f6b 100644 --- a/tests/expected/build-sys/config-chfnsh-no-password +++ b/tests/expected/build-sys/config-chfnsh-no-password @@ -1,7 +1,9 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libmount libncursesw librt libselinux libsmartcols libtinfo libuuid +column: libsmartcols eject: libblkid libmount librt libselinux libuuid fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid findmnt: libblkid libmount librt libselinux libsmartcols libudev libuuid fsck: libblkid libmount librt libselinux libuuid @@ -17,6 +19,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libselinux libsmartcols libuuid lslogins: libselinux libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libselinux libuuid mount: libblkid libmount librt libselinux libuuid @@ -37,16 +40,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libselinux +chmem: chrt: chsh: libselinux col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-chfnsh-pam b/tests/expected/build-sys/config-chfnsh-pam index e7c6a922b..8cfd5a1be 100644 --- a/tests/expected/build-sys/config-chfnsh-pam +++ b/tests/expected/build-sys/config-chfnsh-pam @@ -1,7 +1,9 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libmount libncursesw librt libselinux libsmartcols libtinfo libuuid +column: libsmartcols eject: libblkid libmount librt libselinux libuuid fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid findmnt: libblkid libmount librt libselinux libsmartcols libudev libuuid fsck: libblkid libmount librt libselinux libuuid @@ -17,6 +19,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libselinux libsmartcols libuuid lslogins: libselinux libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libselinux libuuid mount: libblkid libmount librt libselinux libuuid @@ -37,16 +40,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libselinux +chmem: chrt: chsh: libpam libpam_misc libselinux col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-core b/tests/expected/build-sys/config-core index 3802c96fb..befb08283 100644 --- a/tests/expected/build-sys/config-core +++ b/tests/expected/build-sys/config-core @@ -1,7 +1,9 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libmount libncursesw librt libsmartcols libtinfo libuuid +column: libsmartcols eject: libblkid libmount librt libuuid fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid findmnt: libblkid libmount librt libsmartcols libudev libuuid fsck: libblkid libmount librt libuuid @@ -17,6 +19,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libsmartcols libuuid lslogins: libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libuuid mount: libblkid libmount librt libuuid @@ -37,16 +40,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libuser col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-devel b/tests/expected/build-sys/config-devel index 58e25289b..0b69069a9 100644 --- a/tests/expected/build-sys/config-devel +++ b/tests/expected/build-sys/config-devel @@ -1,7 +1,9 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libmount libncursesw librt libselinux libsmartcols libtinfo libuuid +column: libsmartcols eject: libblkid libmount librt libselinux libuuid fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid findmnt: libblkid libmount librt libselinux libsmartcols libudev libuuid fsck: libblkid libmount librt libselinux libuuid @@ -17,6 +19,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libselinux libsmartcols libuuid lslogins: libselinux libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libselinux libuuid mount: libblkid libmount librt libselinux libuuid @@ -37,16 +40,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libselinux libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libselinux libuser col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-devel-non-docs b/tests/expected/build-sys/config-devel-non-docs index 58e25289b..0b69069a9 100644 --- a/tests/expected/build-sys/config-devel-non-docs +++ b/tests/expected/build-sys/config-devel-non-docs @@ -1,7 +1,9 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libmount libncursesw librt libselinux libsmartcols libtinfo libuuid +column: libsmartcols eject: libblkid libmount librt libselinux libuuid fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid findmnt: libblkid libmount librt libselinux libsmartcols libudev libuuid fsck: libblkid libmount librt libselinux libuuid @@ -17,6 +19,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libselinux libsmartcols libuuid lslogins: libselinux libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libselinux libuuid mount: libblkid libmount librt libselinux libuuid @@ -37,16 +40,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libselinux libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libselinux libuser col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-enable-schedutils b/tests/expected/build-sys/config-enable-schedutils new file mode 100644 index 000000000..cd34c8e8c --- /dev/null +++ b/tests/expected/build-sys/config-enable-schedutils @@ -0,0 +1,3 @@ +chrt: +ionice: +taskset: diff --git a/tests/expected/build-sys/config-non-libblkid b/tests/expected/build-sys/config-non-libblkid index 02667195b..32d24fd40 100644 --- a/tests/expected/build-sys/config-non-libblkid +++ b/tests/expected/build-sys/config-non-libblkid @@ -1,5 +1,7 @@ cfdisk: libfdisk libncursesw libsmartcols libtinfo libuuid +column: libsmartcols fdisk: libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols libfdisk.so.1.1.0: libuuid libsmartcols.so.1.1.0: libuuid.so.1.3.0: @@ -7,6 +9,7 @@ losetup: libsmartcols lscpu: libsmartcols lsipc: libsmartcols lslogins: libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libuuid prlimit: libsmartcols @@ -17,16 +20,17 @@ wdctl: libsmartcols zramctl: libsmartcols agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libuser col: colcrt: colrm: -column: ctrlaltdel: dmesg: librt libtinfo fallocate: diff --git a/tests/expected/build-sys/config-non-libmount b/tests/expected/build-sys/config-non-libmount index faf405dc5..2ee17ff09 100644 --- a/tests/expected/build-sys/config-non-libmount +++ b/tests/expected/build-sys/config-non-libmount @@ -1,6 +1,8 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libncursesw libsmartcols libtinfo libuuid +column: libsmartcols fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid libblkid.so.1.1.0: libuuid libfdisk.so.1.1.0: libblkid libuuid @@ -10,6 +12,7 @@ losetup: libsmartcols lscpu: libsmartcols lsipc: libsmartcols lslogins: libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libuuid partx: libblkid libsmartcols libuuid @@ -24,16 +27,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libuser col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-non-libs b/tests/expected/build-sys/config-non-libs index a661528dd..a659cf8c5 100644 --- a/tests/expected/build-sys/config-non-libs +++ b/tests/expected/build-sys/config-non-libs @@ -1,15 +1,16 @@ agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libuser col: colcrt: colrm: -column: ctrlaltdel: dmesg: librt libtinfo fallocate: diff --git a/tests/expected/build-sys/config-non-libsmartcols b/tests/expected/build-sys/config-non-libsmartcols index d7b75cf8d..5d3758324 100644 --- a/tests/expected/build-sys/config-non-libsmartcols +++ b/tests/expected/build-sys/config-non-libsmartcols @@ -18,16 +18,17 @@ uuidgen: libuuid wipefs: libblkid libuuid agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libuser col: colcrt: colrm: -column: ctrlaltdel: dmesg: librt libtinfo fallocate: diff --git a/tests/expected/build-sys/config-non-libuuid b/tests/expected/build-sys/config-non-libuuid index 1894de08e..2d48f1e9e 100644 --- a/tests/expected/build-sys/config-non-libuuid +++ b/tests/expected/build-sys/config-non-libuuid @@ -1,5 +1,7 @@ blkid: libblkid +column: libsmartcols eject: libblkid libmount librt +fincore: libsmartcols findfs: libblkid findmnt: libblkid libmount librt libsmartcols libudev fsck: libblkid libmount librt @@ -13,6 +15,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libsmartcols lslogins: libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid mount: libblkid libmount librt @@ -30,16 +33,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libuser col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-non-nls b/tests/expected/build-sys/config-non-nls index 3802c96fb..befb08283 100644 --- a/tests/expected/build-sys/config-non-nls +++ b/tests/expected/build-sys/config-non-nls @@ -1,7 +1,9 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libmount libncursesw librt libsmartcols libtinfo libuuid +column: libsmartcols eject: libblkid libmount librt libuuid fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid findmnt: libblkid libmount librt libsmartcols libudev libuuid fsck: libblkid libmount librt libuuid @@ -17,6 +19,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libsmartcols libuuid lslogins: libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libuuid mount: libblkid libmount librt libuuid @@ -37,16 +40,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libuser col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-non-widechar b/tests/expected/build-sys/config-non-widechar new file mode 100644 index 000000000..5720626b2 --- /dev/null +++ b/tests/expected/build-sys/config-non-widechar @@ -0,0 +1 @@ +nologin: diff --git a/tests/expected/build-sys/config-selinux b/tests/expected/build-sys/config-selinux index a3ade2702..3e85d7496 100644 --- a/tests/expected/build-sys/config-selinux +++ b/tests/expected/build-sys/config-selinux @@ -1,7 +1,9 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libmount libncursesw librt libselinux libsmartcols libtinfo libuuid +column: libsmartcols eject: libblkid libmount librt libselinux libuuid fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid findmnt: libblkid libmount librt libselinux libsmartcols libudev libuuid fsck: libblkid libmount librt libselinux libuuid @@ -17,6 +19,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libselinux libsmartcols libuuid lslogins: libselinux libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libselinux libuuid mount: libblkid libmount librt libselinux libuuid @@ -37,16 +40,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libselinux libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libselinux libuser col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-slang b/tests/expected/build-sys/config-slang index a78e16a04..16535c2d1 100644 --- a/tests/expected/build-sys/config-slang +++ b/tests/expected/build-sys/config-slang @@ -1,7 +1,9 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libmount librt libslang libsmartcols libtinfo libuuid +column: libsmartcols eject: libblkid libmount librt libuuid fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid findmnt: libblkid libmount librt libsmartcols libudev libuuid fsck: libblkid libmount librt libuuid @@ -17,6 +19,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libsmartcols libuuid lslogins: libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libuuid mount: libblkid libmount librt libuuid @@ -37,16 +40,17 @@ zramctl: libsmartcols addpart: agetty: blkdiscard: librt +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libuser col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/tests/expected/build-sys/config-static b/tests/expected/build-sys/config-static index ab514df9d..9464d3cbe 100644 --- a/tests/expected/build-sys/config-static +++ b/tests/expected/build-sys/config-static @@ -1,7 +1,9 @@ blkid: libblkid libuuid cfdisk: libblkid libfdisk libmount libncursesw librt libsmartcols libtinfo libuuid +column: libsmartcols eject: libblkid libmount librt libuuid fdisk: libblkid libfdisk libreadline libsmartcols libtinfo libuuid +fincore: libsmartcols findfs: libblkid libuuid findmnt: libblkid libmount librt libsmartcols libudev libuuid fsck: libblkid libmount librt libuuid @@ -17,6 +19,7 @@ lscpu: libsmartcols lsipc: libsmartcols lslocks: libblkid libmount librt libsmartcols libuuid lslogins: libsmartcols libsystemd +lsmem: libsmartcols lsns: libsmartcols mkswap: libblkid libuuid mount: libblkid libmount librt libuuid @@ -38,16 +41,17 @@ addpart: agetty: blkdiscard: librt blkid.static: STATIC +blkzone: blockdev: cal: libncursesw libtinfo chcpu: chfn: libpam libpam_misc libpthread libuser +chmem: chrt: chsh: libpam libpam_misc libpthread libuser col: colcrt: colrm: -column: ctrlaltdel: delpart: dmesg: librt libtinfo diff --git a/text-utils/Makemodule.am b/text-utils/Makemodule.am index a0375c0f6..7478eb427 100644 --- a/text-utils/Makemodule.am +++ b/text-utils/Makemodule.am @@ -24,13 +24,6 @@ dist_man_MANS += text-utils/column.1 column_SOURCES = text-utils/column.c column_LDADD = $(LDADD) libcommon.la libsmartcols.la column_CFLAGS = $(AM_CFLAGS) -I$(ul_libsmartcols_incdir) - -### temporary during work on new version -usrbin_exec_PROGRAMS += column-old -column_old_SOURCES = text-utils/column-old.c -column_old_LDADD = $(LDADD) libcommon.la -### - endif if BUILD_HEXDUMP diff --git a/text-utils/column-old.c b/text-utils/column-old.c deleted file mode 100644 index 3d50f2e27..000000000 --- a/text-utils/column-old.c +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (c) 1989, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * 1999-02-22 Arkadiusz Miśkiewicz <misiek@pld.ORG.PL> - * added Native Language Support - * 1999-09-19 Bruno Haible <haible@clisp.cons.org> - * modified to work correctly in multi-byte locales - */ - -#include <sys/types.h> -#include <sys/ioctl.h> - -#include <ctype.h> -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <getopt.h> - -#include "nls.h" -#include "c.h" -#include "widechar.h" -#include "xalloc.h" -#include "strutils.h" -#include "closestream.h" -#include "ttyutils.h" - -#ifdef HAVE_WIDECHAR -static wchar_t *mbs_to_wcs(const char *); -#else -#define mbs_to_wcs(s) xstrdup(s) -static char *mtsafe_strtok(char *, const char *, char **); -#define wcstok mtsafe_strtok -#endif - -#define DEFCOLS 25 -#define TAB 8 -#define DEFNUM 1000 -#define MAXLINELEN (LINE_MAX + 1) - -static int input(FILE *fp, int *maxlength, wchar_t ***list, int *entries); -static void c_columnate(int maxlength, long termwidth, wchar_t **list, int entries); -static void r_columnate(int maxlength, long termwidth, wchar_t **list, int entries); -static wchar_t *local_wcstok(wchar_t *p, const wchar_t *separator, int greedy, wchar_t **wcstok_state); -static void maketbl(wchar_t **list, int entries, wchar_t *separator, int greedy, wchar_t *colsep); -static void print(wchar_t **list, int entries); - -typedef struct _tbl { - wchar_t **list; - int cols, *len; -} TBL; - - -#ifdef HAVE_WIDECHAR -/* Don't use wcswidth(), we need to ignore non-printable chars. */ -static int width(const wchar_t *str) -{ - int x, width = 0; - - for (; *str != '\0'; str++) { - x = wcwidth(*str); - if (x > 0) - width += x; - } - return width; -} -#else -static int width(const char *str) -{ - int width = 0; - - for (; *str != '\0'; str++) { - if (isprint(*str)) - width++; - } - return width; -} -#endif - -static void __attribute__((__noreturn__)) usage(int rc) -{ - FILE *out = rc == EXIT_FAILURE ? stderr : stdout; - - fputs(USAGE_HEADER, out); - fprintf(out, _(" %s [options] [<file>...]\n"), program_invocation_short_name); - - fputs(USAGE_SEPARATOR, out); - fputs(_("Columnate lists.\n"), out); - - fputs(USAGE_OPTIONS, out); - fputs(_(" -t, --table create a table\n"), out); - fputs(_(" -s, --separator <string> possible table delimiters\n"), out); - fputs(_(" -o, --output-separator <string> columns separator for table output\n" - " (default is two spaces)\n"), out); - fputs(_(" -c, --output-width <width> width of output in number of characters\n"), out); - fputs(_(" -x, --fillrows fill rows before columns\n"), out); - fputs(USAGE_SEPARATOR, out); - fputs(USAGE_HELP, out); - fputs(USAGE_VERSION, out); - fprintf(out, USAGE_MAN_TAIL("column(1)")); - - exit(rc); -} - -int main(int argc, char **argv) -{ - int ch, tflag = 0, xflag = 0; - int i; - int termwidth = 80; - int entries = 0; /* number of records */ - unsigned int eval = 0; /* exit value */ - int maxlength = 0; /* longest record */ - wchar_t **list = NULL; /* array of pointers to records */ - int greedy = 1; - wchar_t *colsep; /* table column output separator */ - - /* field separator for table option */ - wchar_t default_separator[] = { '\t', ' ', 0 }; - wchar_t *separator = default_separator; - - static const struct option longopts[] = - { - { "columns", required_argument, NULL, 'c' }, /* deprecated */ - { "fillrows", no_argument, NULL, 'x' }, - { "help", no_argument, NULL, 'h' }, - { "output-separator", required_argument, NULL, 'o' }, - { "output-width", required_argument, NULL, 'c' }, - { "separator", required_argument, NULL, 's' }, - { "table", no_argument, NULL, 't' }, - { "version", no_argument, NULL, 'V' }, - { NULL, 0, NULL, 0 }, - }; - - setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - atexit(close_stdout); - - termwidth = get_terminal_width(80); - colsep = mbs_to_wcs(" "); - - while ((ch = getopt_long(argc, argv, "hVc:s:txo:", longopts, NULL)) != -1) - switch(ch) { - case 'h': - usage(EXIT_SUCCESS); - break; - case 'V': - printf(UTIL_LINUX_VERSION); - return EXIT_SUCCESS; - case 'c': - termwidth = strtou32_or_err(optarg, _("invalid columns argument")); - break; - case 's': - separator = mbs_to_wcs(optarg); - greedy = 0; - break; - case 'o': - free(colsep); - colsep = mbs_to_wcs(optarg); - break; - case 't': - tflag = 1; - break; - case 'x': - xflag = 1; - break; - default: - errtryhelp(EXIT_FAILURE); - } - argc -= optind; - argv += optind; - - if (!*argv) - eval += input(stdin, &maxlength, &list, &entries); - else - for (; *argv; ++argv) { - FILE *fp; - - if ((fp = fopen(*argv, "r")) != NULL) { - eval += input(fp, &maxlength, &list, &entries); - fclose(fp); - } else { - warn("%s", *argv); - eval += EXIT_FAILURE; - } - } - - if (!entries) - exit(eval); - - if (tflag) - maketbl(list, entries, separator, greedy, colsep); - else if (maxlength >= termwidth) - print(list, entries); - else if (xflag) - c_columnate(maxlength, termwidth, list, entries); - else - r_columnate(maxlength, termwidth, list, entries); - - for (i = 0; i < entries; i++) - free(list[i]); - free(list); - - if (eval == 0) - return EXIT_SUCCESS; - else - return EXIT_FAILURE; -} - -static void c_columnate(int maxlength, long termwidth, wchar_t **list, int entries) -{ - int chcnt, col, cnt, endcol, numcols; - wchar_t **lp; - - maxlength = (maxlength + TAB) & ~(TAB - 1); - numcols = termwidth / maxlength; - endcol = maxlength; - for (chcnt = col = 0, lp = list;; ++lp) { - fputws(*lp, stdout); - chcnt += width(*lp); - if (!--entries) - break; - if (++col == numcols) { - chcnt = col = 0; - endcol = maxlength; - putwchar('\n'); - } else { - while ((cnt = ((chcnt + TAB) & ~(TAB - 1))) <= endcol) { - putwchar('\t'); - chcnt = cnt; - } - endcol += maxlength; - } - } - if (chcnt) - putwchar('\n'); -} - -static void r_columnate(int maxlength, long termwidth, wchar_t **list, int entries) -{ - int base, chcnt, cnt, col, endcol, numcols, numrows, row; - - maxlength = (maxlength + TAB) & ~(TAB - 1); - numcols = termwidth / maxlength; - if (!numcols) - numcols = 1; - numrows = entries / numcols; - if (entries % numcols) - ++numrows; - - for (row = 0; row < numrows; ++row) { - endcol = maxlength; - for (base = row, chcnt = col = 0; col < numcols; ++col) { - fputws(list[base], stdout); - chcnt += width(list[base]); - if ((base += numrows) >= entries) - break; - while ((cnt = ((chcnt + TAB) & ~(TAB - 1))) <= endcol) { - putwchar('\t'); - chcnt = cnt; - } - endcol += maxlength; - } - putwchar('\n'); - } -} - -static void print(wchar_t **list, int entries) -{ - int cnt; - wchar_t **lp; - - for (cnt = entries, lp = list; cnt--; ++lp) { - fputws(*lp, stdout); - putwchar('\n'); - } -} - -static wchar_t *local_wcstok(wchar_t *p, const wchar_t *separator, int greedy, - wchar_t **wcstok_state) -{ - wchar_t *result; - if (greedy) - return wcstok(p, separator, wcstok_state); - - if (p == NULL) { - if (*wcstok_state == NULL) - return NULL; - else - p = *wcstok_state; - } - result = p; - p = wcspbrk(result, separator); - if (p == NULL) - *wcstok_state = NULL; - else { - *p = '\0'; - *wcstok_state = p + 1; - } - return result; -} - -static void maketbl(wchar_t **list, int entries, wchar_t *separator, int greedy, wchar_t *colsep) -{ - TBL *t; - int cnt; - wchar_t *p, **lp; - ssize_t *lens; - ssize_t maxcols = DEFCOLS, coloff; - TBL *tbl; - wchar_t **cols; - wchar_t *wcstok_state = NULL; - - t = tbl = xcalloc(entries, sizeof(TBL)); - cols = xcalloc(maxcols, sizeof(wchar_t *)); - lens = xcalloc(maxcols, sizeof(ssize_t)); - - for (lp = list, cnt = 0; cnt < entries; ++cnt, ++lp, ++t) { - coloff = 0; - p = *lp; - while ((cols[coloff] = local_wcstok(p, separator, greedy, &wcstok_state)) != NULL) { - if (++coloff == maxcols) { - maxcols += DEFCOLS; - cols = xrealloc(cols, maxcols * sizeof(wchar_t *)); - lens = xrealloc(lens, maxcols * sizeof(ssize_t)); - /* zero fill only new memory */ - memset(lens + (maxcols - DEFCOLS), 0, - DEFCOLS * sizeof(*lens)); - } - p = NULL; - } - t->list = xcalloc(coloff, sizeof(wchar_t *)); - t->len = xcalloc(coloff, sizeof(int)); - for (t->cols = coloff; --coloff >= 0;) { - t->list[coloff] = cols[coloff]; - t->len[coloff] = width(cols[coloff]); - if (t->len[coloff] > lens[coloff]) - lens[coloff] = t->len[coloff]; - } - } - - for (t = tbl, cnt = 0; cnt < entries; ++cnt, ++t) { - for (coloff = 0; coloff < t->cols - 1; ++coloff) { - fputws(t->list[coloff], stdout); -#ifdef HAVE_WIDECHAR - wprintf(L"%*s", lens[coloff] - t->len[coloff], ""); -#else - printf("%*s", (int) lens[coloff] - t->len[coloff], ""); -#endif - fputws(colsep, stdout); - } - if (coloff < t->cols) { - fputws(t->list[coloff], stdout); - putwchar('\n'); - } - } - - for (cnt = 0; cnt < entries; ++cnt) { - free((tbl+cnt)->list); - free((tbl+cnt)->len); - } - free(cols); - free(lens); - free(tbl); -} - -static int input(FILE *fp, int *maxlength, wchar_t ***list, int *entries) -{ - static int maxentry = DEFNUM; - int len, lineno = 1, reportedline = 0, eval = 0; - wchar_t *p, buf[MAXLINELEN]; - wchar_t **local_list = *list; - int local_entries = *entries; - - if (!local_list) - local_list = xcalloc(maxentry, sizeof(wchar_t *)); - - while (1) { - if (fgetws(buf, MAXLINELEN, fp) == NULL) { - if (feof(fp)) - break; - else - err(EXIT_FAILURE, _("read failed")); - } - for (p = buf; *p && iswspace(*p); ++p) - ; - if (!*p) - continue; - if (!(p = wcschr(p, '\n')) && !feof(fp)) { - if (reportedline < lineno) { - warnx(_("line %d is too long, output will be truncated"), - lineno); - reportedline = lineno; - } - eval = 1; - continue; - } - lineno++; - if (!feof(fp) && p) - *p = '\0'; - len = width(buf); /* len = p - buf; */ - if (*maxlength < len) - *maxlength = len; - if (local_entries == maxentry) { - maxentry += DEFNUM; - local_list = xrealloc(local_list, - (u_int)maxentry * sizeof(wchar_t *)); - } - local_list[local_entries++] = wcsdup(buf); - } - - *list = local_list; - *entries = local_entries; - - return eval; -} - -#ifdef HAVE_WIDECHAR -static wchar_t *mbs_to_wcs(const char *s) -{ - ssize_t n; - wchar_t *wcs; - - n = mbstowcs((wchar_t *)0, s, 0); - if (n < 0) - return NULL; - wcs = xmalloc((n + 1) * sizeof(wchar_t)); - n = mbstowcs(wcs, s, n + 1); - if (n < 0) { - free(wcs); - return NULL; - } - return wcs; -} -#endif - -#ifndef HAVE_WIDECHAR -static char *mtsafe_strtok(char *str, const char *delim, char **ptr) -{ - if (str == NULL) { - str = *ptr; - if (str == NULL) - return NULL; - } - str += strspn(str, delim); - if (*str == '\0') { - *ptr = NULL; - return NULL; - } else { - char *token_end = strpbrk(str, delim); - if (token_end) { - *token_end = '\0'; - *ptr = token_end + 1; - } else - *ptr = NULL; - return str; - } -} -#endif diff --git a/text-utils/column.1 b/text-utils/column.1 index 97cdd67c0..b605d505d 100644 --- a/text-utils/column.1 +++ b/text-utils/column.1 @@ -100,6 +100,13 @@ Don't print specified columns. Specify columns order on output. .IP "\fB\-n, \-\-table-name\fP \fIname\fP" Specify the table name used for JSON output. The defaout is "table". +.IP "\fB\-r, \-\-tree\fP \fIcolumn\fP" +Specify column to use tree-like output. Note that the circular dependencies and +another anomalies in child and parent relation are silently ignored. +.IP "\fB\-i, \-\-tree\-id\fP \fIcolumn\fP" +Specify column with line ID to create child-parent relation. +.IP "\fB\-p, \-\-tree\-parent\fP \fIcolumn\fP" +Specify column with parent ID to create child-parent relation. .PP .IP "\fB\-x, \-\-fillrows\fP" Fill rows before filling columns. @@ -111,9 +118,20 @@ Display help text and exit. The environment variable \fBCOLUMNS\fR is used to determine the size of the screen if no other information is available. .SH EXAMPLES -.nf -.B sed 's/#.*//' /etc/fstab | column --table --table-columns SOURCE,TARGET,TYPE,OPTIONS,PASS,FREQ --table-right PASS,FREQ -.nf +Print fstab with header line and align number to the right: +.EX +\fBsed 's/#.*//' /etc/fstab | column --table --table-columns SOURCE,TARGET,TYPE,OPTIONS,PASS,FREQ --table-right PASS,FREQ\fR +.EE +.PP +Print a tree: +.EX +\fBecho -e '1 0 A\\n2 1 AA\\n3 1 AB\\n4 2 AAA\\n5 2 AAB' | column --tree 3 --tree-id 1 --tree-parent 2\fR +1 0 A +2 1 ├─AA +4 2 │ ├─AAA +5 2 │ └─AAB +3 1 └─AB +.EE .SH BUGS Version 2.23 changed the .B \-s diff --git a/text-utils/column.c b/text-utils/column.c index 707086244..421823d4a 100644 --- a/text-utils/column.c +++ b/text-utils/column.c @@ -329,8 +329,11 @@ static void create_tree(struct column_control *ctl) if (!parent) continue; - if (strcmp(id, parent) == 0 && ln_i != ln) - scols_line_add_child(ln_i, ln); + if (strcmp(id, parent) != 0) + continue; + if (scols_line_is_ancestor(ln, ln_i)) + continue; + scols_line_add_child(ln_i, ln); } } @@ -390,8 +393,14 @@ static int add_line_to_table(struct column_control *ctl, wchar_t *wcs) while ((wcdata = local_wcstok(wcs, ctl->input_separator, ctl->greedy, &sv))) { char *data; - if (scols_table_get_ncols(ctl->tab) < n + 1) + if (scols_table_get_ncols(ctl->tab) < n + 1) { + if (scols_table_is_json(ctl->tab)) + errx(EXIT_FAILURE, _("line %zu: for JSON the name of the " + "column %zu is required"), + scols_table_get_nlines(ctl->tab) + 1, + n + 1); scols_table_new_column(ctl->tab, NULL, 0, 0); + } if (!ln) { ln = scols_table_new_line(ctl->tab, NULL); if (!ln) @@ -740,8 +749,10 @@ int main(int argc, char **argv) switch (ctl.mode) { case COLUMN_MODE_TABLE: - modify_table(&ctl); - eval = scols_print_table(ctl.tab); + if (ctl.tab && scols_table_get_nlines(ctl.tab)) { + modify_table(&ctl); + eval = scols_print_table(ctl.tab); + } break; case COLUMN_MODE_FILLCOLS: columnate_fillcols(&ctl); |