All of lore.kernel.org
 help / color / mirror / Atom feed
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



  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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.