Commit Graph
148 Commits
Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek 852f193560 shared/format-table: make one more function static 2026-08-28 14:50:10 +02:00
Zbigniew Jędrzejewski-Szmek e348b263ce shared/format-table: drop unused table_sync_column_widths()
The variadic pair-wise variant was only used by the hand-written help()
functions to synchronize their verb and option tables. Those are all
gone, and the verbs machinery uses table_sync_all_column_widths().
2026-08-28 14:50:10 +02:00
Zbigniew Jędrzejewski-Szmek 4d620b49f5 shared/format-table: add helper to sync widths of a table array 2026-08-13 13:23:04 +02:00
logical-misha e09402326c format-table: give mixed cell types a stable sort order (#43129)
Mixed-type cells were compared by their insertion indices, while cells
of the same type were compared by value. Combining those rules
could make `cell_data_compare()` non-transitive.

Give different non-empty `TableDataType` values a stable order. Define
empty cells as greater than non-empty cells, so they appear last in
ascending sorts and first when the order is reversed. This ensures that
the comparator defines a consistent ordering.

Fixes #43128.
2026-07-25 14:38:23 +09:00
Zbigniew Jędrzejewski-Szmek 596031030e shared/format-table: shorten code a bit
Define variables at point of initialization so the whole thing is easier
to read.
2026-05-14 12:17:54 +02:00
Yu Watanabe f0483f308a format-table: fix potential segfault
In format-table.h, TABLE_IN_ADDR is commented as "Takes a union in_addr_union
(or a struct in_addr)". However, if we pass struct in_addr to table_add_many(),
the function reads more than the size of the struct.
2026-04-27 11:11:35 +09:00
Lennart Poettering f0abcd5e0f format-table: add tristate field 2026-04-26 21:21:49 +02:00
Zbigniew Jędrzejewski-Szmek ca745e1914 Convert more programs to the new option and verb parsers (#41458) 2026-04-04 10:21:14 +02:00
Zbigniew Jędrzejewski-Szmek 1008583c91 tree-wide: print error if table_print() fails
We generally want to print an error message if table_print()
fails. Add a helper function for this and use it consistently.
This does one of the three things depending on the call site:
- a no-change reformatting of the code
- change from a custom message to the generic one
- addition of the error message where previously none was printed

In the third case, the actual use impact is very small, since the
table formatting is very unlikely to fail. But if it did, we would
often return an error without any message whatsoever, which we
never want to do.
2026-04-03 13:05:03 +02:00
Zbigniew Jędrzejewski-Szmek 0ce5a8fb4e tree-wide: drop flush&check step after table printing
Almost all callers of table_print() specify stdout or NULL (equivalent
to stdout) as the output stream. Simplify things by not requiring the
the stream to be specified.

In almost all cases, the printing of the table is surrounded by normal
printfs() that don't do explicit flushing and for which we don't check
the output stream status. Let's simplify most callers and skip this
step. The reason is not so much to avoid the extra step itself, but
instead to avoid the _handling_ of the potential failure. We generally
only want to print an error message for ENOMEM and other "internal"
errors, so strictly speaking we should filter out the errors from the
stream. By skipping the flush&check step we implicitly do this.
2026-04-03 13:04:40 +02:00
Michael Vogt bb94af45c1 many: use POINTER_MAY_BE_NULL in inner sort _cmp funcs
Some functions are in the hot path of a sort. While it is more
correct to also use assert() here for the passed pointers it is
also a runtime cost that should never be needed when e.g. qsort()
is used as it will always pass non-NULL pointers.

So for these critical functions use POINTER_MAY_BE_NULL() which
is compiled out and add a comment to them. Not all _compare()
functions are changed, it was a bit of a judgement call because
some (like ether_addr_compare) are not called with that much data.

But happy to get advise here and tweak accordingly.
2026-03-31 18:30:40 +02:00
Michael Vogt 029335ea74 shared: make check-pointer-deref clean
Add the needed assert changes to make the code clean
for the new check-pointer-deref script.
2026-03-31 18:30:40 +02:00
Zbigniew Jędrzejewski-Szmek 5e4003cd87 shared/table-format: generalize table_sync_column_width to more columns
The column index is moved to the first position. I think we're unlikely
to want to synchronize widths of *different* columns, and having just
one column argument makes the callers simpler. Also, the type is changed
to size_t to match other functions, and this avoids the need to cast
to size_t in the callers.
2026-03-26 10:31:23 +01:00
Zbigniew Jędrzejewski-Szmek bcaa5acf81 shared/format-table: add helpers to query and set column width 2026-03-23 14:20:10 +01:00
Zbigniew Jędrzejewski-Szmek 1dc6445bbb shared/format-table: fix potential memleaks of d->formatted
We don't always return d->formatted, even if it is available. And
depending on the cell type, we'd either overwrite it directly or free
first. Let's always free it upfront and then set unconditionally.
(In this case, we don't need to spend effort on preserving the
existing value. It's just a cache.)  Setting the variable directly
allows many temporary variables to be eliminated.

Also use asprintf_safe() to simplify the allocation of the buffer.
This is probably a tiny bit slower than the direct allocation, but
table formatting shouldn't be a hot path.
2026-03-06 17:46:59 +01:00
Zbigniew Jędrzejewski-Szmek 54ed92e17c shared/format-table: use 'char*'-style in function signatures 2026-03-06 17:46:59 +01:00
Lennart Poettering 22cc1625e7 format-table: add a new JSON cell type
This formats the specified json variant as a string, and displays it in
a cell.
2026-02-20 08:15:29 +01:00
Lennart Poettering f42dc5ea18 format-table: add new string cell type that accepts ANSI sequences
For various usecases it's useful that we can embed ANSI sequences in
cells of tables. For example, I hope we can eventually switch "systemctl
status" output to use the table formatter, and multiple of its fields
contain ANSI sequences (since they pack multiple different pieces
information into the same field, and highlight parts of it to
communicate relevance of distinct parts).

Add a distinct cell type for this, which gets special processing when we
output to a terminal that doesn't support ANSI sequences, and to JSON:
we strip the sequences.
2026-01-21 21:32:49 +01:00
Yu Watanabe 93378148d4 tree-wide: normalize comment style 2025-12-15 08:50:13 +09:00
Daan De Meyer 6a9f0641cd tree-wide: Fix declaration/definition parameter name mismatches 2025-11-26 19:02:31 +09:00
Lennart Poettering 86279dc970 format-table: add field type that outputs hex values prefixed with 0x 2025-11-02 21:14:35 +01:00
Lennart Poettering 9e9fbaa620 format-table: add TABLE_VERSION cell type
This is exactly like TABLE_STRING, with one exception: it sorts via
strverscmp_improved().
2025-09-18 09:31:35 +02:00
Daan De Meyer 69a283c5f2 shared: Clean up includes
Split out of #37344.
2025-05-24 14:00:44 +02:00
Daan De Meyer d9ccf6b349 path-util: Reduce transitive includes 2025-05-07 22:04:46 +09:00
Daan De Meyer 93a1f7921a basic: Stop including log.h in macro.h
Now that the necessary functions from log.h have been moved to macro.h,
we can stop including log.h in macro.h. This requires modifying source
files all over the tree to include log.h instead.
2025-04-18 14:19:15 +02:00
Zbigniew Jędrzejewski-Szmek 1ae9b0cfa8 basic/glyph-util: rename "special glyph" to just "glyph"
Admittedly, some of our glyphs _are_ special, e.g. "O=" for SPECIAL_GLYPH_TOUCH ;)
But we don't need this in the name. The very long names make some invocations
very wordy, e.g. special_glyph(SPECIAL_GLYPH_SLIGHTLY_UNHAPPY_SMILEY).
Also, I want to add GLYPH_SPACE, which is not special at all.
2025-03-15 14:40:39 +01:00
Mike Yuan 26c29eed53 format-table: drop pointless table_data_rgap_color() func
Follow-up for aab79f5278
2024-12-11 19:19:46 +01:00
Mike Yuan da7cd0f500 format-table: minor modernization 2024-12-11 19:14:28 +01:00
Zbigniew Jędrzejewski-Szmek 23441a3d88 sd-json,tree-wide: add sd_json_format_enabled() and use it everwhere
We often used a pattern like if (!FLAGS_SET(flags, SD_JSON_FORMAT_OFF)),
which is rather verbose and also contains a double negative, which we try
to avoid. Add a little helper to avoid an explicit bit check.

This change clarifies an aditional thing: in some cases we treated
SD_JSON_FORMAT_OFF as a flag (flags & SD_JSON_FORMAT_OFF), while in other cases
we treated it as an independent enum value (flags == SD_JSON_FORMAT_OFF).
In the first form, flags like SD_JSON_FORMAT_SSE do _not_ turn the json
output on, while in the second form they do. Let's use the first form
everywhere.

No functional change intended.

Initially I wasn't sure if this helper should be made public or just internal,
but it seems such a common pattern that if we expose the flags, we might just
as well expose it too, to make life easier for any consumers.
2024-10-28 09:23:07 +01:00
Lennart Poettering 868258cf38 basic: split ifname related calls from format-util.h into format-ifname.h
This way we don't have to pull in net/if.h into format-util.h.

This is supposed to address https://github.com/systemd/systemd/pull/32212#discussion_r1755639881

No actual code changes, just a .c/.h file split-up.
2024-09-13 07:27:47 +02:00
Lennart Poettering 300b7e7620 tree-wide: use isatty_safe() more 2024-08-20 11:11:53 +02:00
Adrian Vovk c4cb49eb34 table: Improve mangling of JSON field names
First, when displaying JSON we convert dashes into underscores. We want
to avoid using dashes in JSON field names in new code, because some
JSON parsers don't support dashes very well.

Second, we make the first character of every word lower-case. This
better matches our JSON field name style, and makes the automatic
JSON name mangling a lot more useful for vertical tables, where fields
are given a display name. For example, "Foo Bar" would be converted into
"foo_bar" instead of "Foo_Bar", which much better matches our style.
We don't make the whole string lowercase to support cases like:
"fooBar" should stay as "fooBar".

Some situations don't behave quite perfectly, such as "Foo BarBaz" gets
converted into "foo_barBaz", or all-caps headings get mangled
incorrectly. In these situations, the JSON field should be overridden
manually. In most cases, or at least more cases than before, this
heuristic does good enough.
2024-07-17 14:15:43 -04:00
Adrian Vovk bf01601f11 table: Add TABLE_SET_JSON_FIELD_NAME
Lets you conveniently set JSON field names in table_add_many. Especially
useful for vertical tables. For example:

table_add_many(t,
               TABLE_FIELD, "Display Name",
               TABLE_STRING, obj->display_name,
               TABLE_SET_JSON_FIELD_NAME, "displayName",
               TABLE_FIELD, "Timestamp",
               TABLE_TIMESTAMP, obj->timestamp,
               TABLE_SET_JSON_FIELD_NAME, "timestampUSec");
2024-07-17 14:15:41 -04:00
Lennart Poettering 309a747fa6 libsystemd: turn json.[ch] into a public API
This is preparation for making our Varlink API a public API. Since our
Varlink API is built on top of our JSON API we need to make that public
first (it's a nice API, but JSON APIs there are already enough, this is
purely about the Varlink angle).

I made most of the json.h APIs public, and just placed them in
sd-json.h. Sometimes I wasn't so sure however, since the underlying data
structures would have to be made public too. If in doubt I didn#t risk
it, and moved the relevant API to src/libsystemd/sd-json/json-util.h
instead (without any sd_* symbol prefixes).

This is mostly a giant search/replace patch.
2024-06-12 18:42:22 +02:00
Zbigniew Jędrzejewski-Szmek 12080b1f7d shared/format-table: print BPS with part after point
Fixes https://github.com/systemd/systemd/issues/33076.
"2Gbps" → "2.5Gbps".
2024-05-30 11:38:30 +02:00
Yu Watanabe 287a5f1cff Merge pull request #30628 from YHNdnzj/format-table-improvement
Some improvements for format-table
2023-12-25 20:01:32 +09:00
Mike Yuan 8ba111463d core,format-table: use strna/ersatz for formatting fdstore dump
Currently, the code doesn't handle anonymous inodes correctly.
2023-12-25 17:47:18 +08:00
Yu Watanabe b3a9d980f3 tree-wide: drop space between variable and an increment/decrement 2023-12-25 01:56:40 +09:00
Lennart Poettering aab79f5278 format-table: add a proper "underline" concept to cells 2023-11-20 13:05:50 +01:00
Lennart Poettering 07f314575b format-table: add new table_get_current_column() helper 2023-10-20 15:57:25 +01:00
Lennart Poettering f4ae435bec format-table: add new uint32_t hex field type 2023-10-20 15:55:15 +01:00
Mike Yuan 62efc7629b format-table: use format_timestamp_relative_monotonic 2023-09-02 22:58:00 +08:00
Daan De Meyer ee9d31a608 json: free array in json_variant_unref_many()
This allows using it with CLEANUP_ARRAY(). For the 2 call sites
where we don't need to free the array, we do a regular for loop
calling json_variant_unref() instead.
2023-07-12 20:05:20 +02:00
Yu Watanabe 2485b7e2b8 tree-wide: use memstream-util 2023-06-01 06:48:47 +09:00
Mike Yuan d65c289fbf time-util,format-table: add relative_monotonic variant for timestamp 2023-05-26 13:29:54 +08:00
Frantisek Sumsal f392dfb5a1 tree-wide: check memstream buffer after closing the handle
When closing the FILE handle attached to a memstream, it may attempt to
do a realloc() that may fail during OOM situations, in which case we are
left with the buffer pointer pointing to NULL and buffer size > 0. For
example:

```
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>

    void *realloc(void *ptr, size_t size) {
        return NULL;
    }

    int main(int argc, char *argv[])
    {
        FILE *f;
        char *buf;
        size_t sz = 0;

        f = open_memstream(&buf, &sz);
        if (!f)
            return -ENOMEM;

        fputs("Hello", f);

        fflush(f);
        printf("buf: 0x%lx, sz: %lu, errno: %d\n",
                    (unsigned long) buf, sz, errno);
        fclose(f);
        printf("buf: 0x%lx, sz: %lu, errno: %d\n",
                    (unsigned long) buf, sz, errno);

        return 0;
    }
```

```
$ gcc -o main main.c
$ ./main
buf: 0x74d4a0, sz: 5, errno: 0
buf: 0x0, sz: 5, errno: 0
```

This might do unexpected things if the underlying code expects a valid
pointer to the memstream buffer after closing the handle.

Found by Nallocfuzz.
2023-05-24 21:59:10 +02:00
Lennart Poettering 522f12224c format-table: add new cell type for displaying major/minor devnums 2023-03-29 18:27:05 +02:00
Lennart Poettering bd33207bb1 format-table: add inode type cell type 2023-03-29 18:27:05 +02:00
Zbigniew Jędrzejewski-Szmek d5e6f36c7a shared/format-table: optionally print timestamps without "left"
This just adds the base functionality and some unit tests.
With TABLE_TIMESTAMP_RELATIVE we print "5s ago" and "5s left",
with the new TABLE_TIMESTAMP_LEFT, we print "5s ago" but "5s".
This is more useful for cases where we generally only want to
print timestamps in the future.
2023-02-22 23:43:33 +01:00
Lennart Poettering 3d46a8292f format-table: add new cell type TABLE_TIMESPAN_DAY
This is just like TABLE_TIMESPAN_MSEC, but shows time spans in accuracy
of days.
2023-01-24 15:32:42 +01:00