]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/format-table.c
table: add more basic types
[thirdparty/systemd.git] / src / shared / format-table.c
index 7d529801a1da81d56ea2c9da3dc081fa4c6ec353..09357694ddb26e8bf845cb5fa59254b303cebc51 100644 (file)
@@ -1,16 +1,17 @@
 /* SPDX-License-Identifier: LGPL-2.1+ */
 
 #include <ctype.h>
-#include <stdio_ext.h>
 
 #include "alloc-util.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "format-table.h"
 #include "gunicode.h"
+#include "memory-util.h"
 #include "pager.h"
 #include "parse-util.h"
 #include "pretty-print.h"
+#include "sort-util.h"
 #include "string-util.h"
 #include "terminal-util.h"
 #include "time-util.h"
@@ -72,6 +73,10 @@ typedef struct TableData {
                 usec_t timespan;
                 uint64_t size;
                 char string[0];
+                int int_val;
+                int32_t int32;
+                int64_t int64;
+                unsigned uint_val;
                 uint32_t uint32;
                 uint64_t uint64;
                 int percent;        /* we use 'int' as datatype for percent values in order to match the result of parse_percent() */
@@ -225,12 +230,16 @@ static size_t table_data_size(TableDataType type, const void *data) {
                 return sizeof(usec_t);
 
         case TABLE_SIZE:
+        case TABLE_INT64:
         case TABLE_UINT64:
                 return sizeof(uint64_t);
 
+        case TABLE_INT32:
         case TABLE_UINT32:
                 return sizeof(uint32_t);
 
+        case TABLE_INT:
+        case TABLE_UINT:
         case TABLE_PERCENT:
                 return sizeof(int);
 
@@ -379,6 +388,20 @@ int table_add_cell_full(
         return 0;
 }
 
+int table_add_cell_stringf(Table *t, TableCell **ret_cell, const char *format, ...) {
+        _cleanup_free_ char *buffer = NULL;
+        va_list ap;
+        int r;
+
+        va_start(ap, format);
+        r = vasprintf(&buffer, format, ap);
+        va_end(ap);
+        if (r < 0)
+                return -ENOMEM;
+
+        return table_add_cell(t, ret_cell, TABLE_STRING, buffer);
+}
+
 int table_dup_cell(Table *t, TableCell *cell) {
         size_t i;
 
@@ -663,6 +686,10 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
                 union {
                         uint64_t size;
                         usec_t usec;
+                        int int_val;
+                        int32_t int32;
+                        int64_t int64;
+                        unsigned uint_val;
                         uint32_t uint32;
                         uint64_t uint64;
                         int percent;
@@ -695,6 +722,26 @@ int table_add_many_internal(Table *t, TableDataType first_type, ...) {
                         data = &buffer.size;
                         break;
 
+                case TABLE_INT:
+                        buffer.int_val = va_arg(ap, int);
+                        data = &buffer.int_val;
+                        break;
+
+                case TABLE_INT32:
+                        buffer.int32 = va_arg(ap, int32_t);
+                        data = &buffer.int32;
+                        break;
+
+                case TABLE_INT64:
+                        buffer.int64 = va_arg(ap, int64_t);
+                        data = &buffer.int64;
+                        break;
+
+                case TABLE_UINT:
+                        buffer.uint_val = va_arg(ap, unsigned);
+                        data = &buffer.uint_val;
+                        break;
+
                 case TABLE_UINT32:
                         buffer.uint32 = va_arg(ap, uint32_t);
                         data = &buffer.uint32;
@@ -830,6 +877,18 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t
                 case TABLE_SIZE:
                         return CMP(a->size, b->size);
 
+                case TABLE_INT:
+                        return CMP(a->int_val, b->int_val);
+
+                case TABLE_INT32:
+                        return CMP(a->int32, b->int32);
+
+                case TABLE_INT64:
+                        return CMP(a->int64, b->int64);
+
+                case TABLE_UINT:
+                        return CMP(a->uint_val, b->uint_val);
+
                 case TABLE_UINT32:
                         return CMP(a->uint32, b->uint32);
 
@@ -844,7 +903,7 @@ static int cell_data_compare(TableData *a, size_t index_a, TableData *b, size_t
                 }
         }
 
-        /* Generic fallback using the orginal order in which the cells where added. */
+        /* Generic fallback using the original order in which the cells where added. */
         return CMP(index_a, index_b);
 }
 
@@ -951,6 +1010,54 @@ static const char *table_data_format(TableData *d) {
                 break;
         }
 
+        case TABLE_INT: {
+                _cleanup_free_ char *p;
+
+                p = new(char, DECIMAL_STR_WIDTH(d->int_val) + 1);
+                if (!p)
+                        return NULL;
+
+                sprintf(p, "%i", d->int_val);
+                d->formatted = TAKE_PTR(p);
+                break;
+        }
+
+        case TABLE_INT32: {
+                _cleanup_free_ char *p;
+
+                p = new(char, DECIMAL_STR_WIDTH(d->int32) + 1);
+                if (!p)
+                        return NULL;
+
+                sprintf(p, "%" PRIi32, d->int32);
+                d->formatted = TAKE_PTR(p);
+                break;
+        }
+
+        case TABLE_INT64: {
+                _cleanup_free_ char *p;
+
+                p = new(char, DECIMAL_STR_WIDTH(d->int64) + 1);
+                if (!p)
+                        return NULL;
+
+                sprintf(p, "%" PRIi64, d->int64);
+                d->formatted = TAKE_PTR(p);
+                break;
+        }
+
+        case TABLE_UINT: {
+                _cleanup_free_ char *p;
+
+                p = new(char, DECIMAL_STR_WIDTH(d->uint_val) + 1);
+                if (!p)
+                        return NULL;
+
+                sprintf(p, "%u", d->uint_val);
+                d->formatted = TAKE_PTR(p);
+                break;
+        }
+
         case TABLE_UINT32: {
                 _cleanup_free_ char *p;
 
@@ -1374,12 +1481,10 @@ int table_format(Table *t, char **ret) {
         size_t sz = 0;
         int r;
 
-        f = open_memstream(&buf, &sz);
+        f = open_memstream_unlocked(&buf, &sz);
         if (!f)
                 return -ENOMEM;
 
-        (void) __fsetlocking(f, FSETLOCKING_BYCALLER);
-
         r = table_print(t, f);
         if (r < 0)
                 return r;
@@ -1492,6 +1597,18 @@ static int table_data_to_json(TableData *d, JsonVariant **ret) {
 
                 return json_variant_new_unsigned(ret, d->size);
 
+        case TABLE_INT:
+                return json_variant_new_integer(ret, d->int_val);
+
+        case TABLE_INT32:
+                return json_variant_new_integer(ret, d->int32);
+
+        case TABLE_INT64:
+                return json_variant_new_integer(ret, d->int64);
+
+        case TABLE_UINT:
+                return json_variant_new_unsigned(ret, d->uint_val);
+
         case TABLE_UINT32:
                 return json_variant_new_unsigned(ret, d->uint32);