From: Nilay Shroff <nilay@linux.ibm.com>
To: linux-nvme@lists.infradead.org
Cc: dwagner@suse.de, hare@suse.com, kbusch@kernel.org, hch@lst.de,
gjoyce@linux.ibm.com, wenxiong@linux.ibm.com
Subject: [PATCHv2 4/7] nvme: allow table output to be directed to a FILE stream
Date: Mon, 11 May 2026 17:25:44 +0530 [thread overview]
Message-ID: <20260511115555.2638335-5-nilay@linux.ibm.com> (raw)
In-Reply-To: <20260511115555.2638335-1-nilay@linux.ibm.com>
The table APIs currently print output only to stdout. However, callers
may need to direct output to other destinations such as stderr, a file,
or an in-memory buffer.
Add support for passing a FILE * stream so callers can choose where the
table output is written.
This will be used by the nvme top dashboard to control how statistics
are displayed.
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
---
util/table.c | 75 +++++++++++++++++++++++++++++-----------------------
util/table.h | 2 ++
2 files changed, 44 insertions(+), 33 deletions(-)
diff --git a/util/table.c b/util/table.c
index 60302fff7..5f19a7aa1 100644
--- a/util/table.c
+++ b/util/table.c
@@ -57,7 +57,7 @@ static int table_get_value_width(struct value *v)
return len;
}
-static void table_print_centered(struct value *val, int width, enum fmt_type type)
+static void table_print_centered(FILE *stream, struct value *val, int width)
{
int i, len, left_pad, right_pad;
@@ -70,29 +70,30 @@ static void table_print_centered(struct value *val, int width, enum fmt_type typ
/* add left padding */
for (i = 0; i < left_pad; i++)
- putchar(' ');
+ fputc(' ', stream);
/* print value */
switch (val->type) {
case FMT_STRING:
- printf("%s", val->s);
+ fprintf(stream, "%s", val->s);
break;
case FMT_INT:
- printf("%d", val->i);
+ fprintf(stream, "%d", val->i);
break;
case FMT_UNSIGNED:
- printf("%u", val->u);
+ fprintf(stream, "%u", val->u);
break;
case FMT_LONG:
- printf("%ld", val->ld);
+ fprintf(stream, "%ld", val->ld);
break;
case FMT_UNSIGNED_LONG:
- printf("%lu", val->lu);
+ fprintf(stream, "%lu", val->lu);
+ break;
case FMT_FLOAT:
- printf("%.2f", val->f);
+ fprintf(stream, "%.2f", val->f);
break;
case FMT_DOUBLE:
- printf("%.2f", val->d);
+ fprintf(stream, "%.2f", val->d);
break;
default:
nvme_show_error("Invalid print format!\n");
@@ -101,10 +102,10 @@ static void table_print_centered(struct value *val, int width, enum fmt_type typ
/* add right padding */
for (i = 0; i < right_pad; i++)
- putchar(' ');
+ fputc(' ', stream);
}
-static void table_print_columns(const struct table *t)
+static void table_print_columns(FILE *stream, const struct table *t)
{
int col, j, width;
struct table_column *c;
@@ -117,32 +118,33 @@ static void table_print_columns(const struct table *t)
case CENTERED:
v.s = c->name;
v.align = c->align;
- table_print_centered(&v, width, FMT_STRING);
+ v.type = FMT_STRING;
+ table_print_centered(stream, &v, width);
break;
case LEFT:
width *= -1;
fallthrough;
default:
- printf("%*s", width, c->name);
+ fprintf(stream, "%*s", width, c->name);
break;
}
if (col + 1 != t->num_columns)
- putchar(' ');
+ fputc(' ', stream);
}
- printf("\n");
+ fprintf(stream, "\n");
for (col = 0; col < t->num_columns; col++) {
for (j = 0; j < t->columns[col].width; j++)
- putchar('-');
+ fputc('-', stream);
if (col + 1 != t->num_columns)
- putchar(' ');
+ fputc(' ', stream);
}
- printf("\n");
+ fprintf(stream, "\n");
}
-static void table_print_rows(const struct table *t)
+static void table_print_rows(FILE *stream, const struct table *t)
{
int row, col;
struct table_column *c;
@@ -151,15 +153,15 @@ static void table_print_rows(const struct table *t)
struct value *v;
for (row = 0; row < t->num_rows; row++) {
+ r = &t->rows[row];
for (col = 0; col < t->num_columns; col++) {
c = &t->columns[col];
- r = &t->rows[row];
v = &r->val[col];
width = c->width;
switch (v->align) {
case CENTERED:
- table_print_centered(v, width, v->type);
+ table_print_centered(stream, v, width);
break;
case LEFT:
width *= -1;
@@ -167,24 +169,25 @@ static void table_print_rows(const struct table *t)
default:
switch (v->type) {
case FMT_STRING:
- printf("%*s", width, v->s);
+ fprintf(stream, "%*s", width, v->s);
break;
case FMT_INT:
- printf("%*d", width, v->i);
+ fprintf(stream, "%*d", width, v->i);
break;
case FMT_UNSIGNED:
- printf("%*u", width, v->u);
+ fprintf(stream, "%*u", width, v->u);
break;
case FMT_LONG:
- printf("%*ld", width, v->ld);
+ fprintf(stream, "%*ld", width, v->ld);
break;
case FMT_UNSIGNED_LONG:
- printf("%*lu", width, v->lu);
+ fprintf(stream, "%*lu", width, v->lu);
+ break;
case FMT_FLOAT:
- printf("%*.2f", width, v->f);
+ fprintf(stream, "%*.2f", width, v->f);
break;
case FMT_DOUBLE:
- printf("%*.2f", width, v->d);
+ fprintf(stream, "%*.2f", width, v->d);
break;
default:
nvme_show_error("Invalid format!\n");
@@ -193,19 +196,25 @@ static void table_print_rows(const struct table *t)
break;
}
if (col + 1 != t->num_columns)
- putchar(' ');
+ fputc(' ', stream);
}
- printf("\n");
+
+ fprintf(stream, "\n");
}
}
-void table_print(struct table *t)
+void table_print_stream(FILE *stream, struct table *t)
{
/* first print columns */
- table_print_columns(t);
+ table_print_columns(stream, t);
/* next print rows */
- table_print_rows(t);
+ table_print_rows(stream, t);
+}
+
+void table_print(struct table *t)
+{
+ table_print_stream(stdout, t);
}
int table_get_row_id(struct table *t)
diff --git a/util/table.h b/util/table.h
index 045ed2439..cb374947f 100644
--- a/util/table.h
+++ b/util/table.h
@@ -2,6 +2,7 @@
#ifndef _TABLE_H_
#define _TABLE_H_
+#include <stdio.h>
#include <stdbool.h>
enum fmt_type {
@@ -169,6 +170,7 @@ int table_add_columns_filter(struct table *t, struct table_column *c,
void *arg);
int table_get_row_id(struct table *t);
void table_add_row(struct table *t, int row);
+void table_print_stream(FILE *stream, struct table *t);
void table_print(struct table *t);
void table_free(struct table *t);
--
2.53.0
next prev parent reply other threads:[~2026-05-11 11:56 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-11 11:55 [PATCHv2 0/7] nvme-cli: add nvme top command for real-time monitoring Nilay Shroff
2026-05-11 11:55 ` [PATCHv2 1/7] nvme: add support for unsigned and long types in table_get_value_width() Nilay Shroff
2026-05-11 11:55 ` [PATCHv2 2/7] nvme: use table_get_value_width() in table_print_centered() Nilay Shroff
2026-05-11 11:55 ` [PATCHv2 3/7] nvme: add support for float and double types in table_print_XXX() Nilay Shroff
2026-05-11 11:55 ` Nilay Shroff [this message]
2026-05-11 11:55 ` [PATCHv2 5/7] nvme: add sigaction for SIGWINCH Nilay Shroff
2026-05-11 11:55 ` [PATCHv2 6/7] nvme: add generic top-like dashboard framework Nilay Shroff
2026-05-11 11:55 ` [PATCHv2 7/7] nvme: add nvme top command Nilay Shroff
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260511115555.2638335-5-nilay@linux.ibm.com \
--to=nilay@linux.ibm.com \
--cc=dwagner@suse.de \
--cc=gjoyce@linux.ibm.com \
--cc=hare@suse.com \
--cc=hch@lst.de \
--cc=kbusch@kernel.org \
--cc=linux-nvme@lists.infradead.org \
--cc=wenxiong@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox