lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Mon,  8 Mar 2010 16:55:10 +0900
From:	Hitoshi Mitake <mitake@....info.waseda.ac.jp>
To:	Ingo Molnar <mingo@...e.hu>
Cc:	linux-kernel@...r.kernel.org, mitake@....info.waseda.ac.jp,
	h.mitake@...il.com, Peter Zijlstra <a.p.zijlstra@...llo.nl>,
	Paul Mackerras <paulus@...ba.org>,
	Frederic Weisbecker <fweisbec@...il.com>
Subject: [PATCH] perf: Make printing table easily

Hi,

Making table of matrix by printf is painful work,
but it can be found in perf here and there.
So I'd like to propose semi-automation of making table.
New files util/table.c provides stuffs for easy table printing.

At first, user has to allocate struct table like this:
   	  struct table *t = table_new();

Then, user can define columns by table_add_fixed() for stuffs
registers can contain or table_add_string() for string.
	  table_add_fixed(t, "%p", SIZE_OF_ADDR);
	  table_add_string(t, "%30s", 30);
First argument is pointer to struct table.
Second one is format specifier.

Third argument for table_add_fixed() is size of objects in rows.
Third one for table_add_string() is maximum length of
printing string. If it is 0, no truncate will be done.

After making columns, user can print each rows like this:
      	  table_printf(t, table_test, 2501, "one");

Example of use:

| /* program */
| static void table_test(void)
| {
| 	struct table *t = table_new();
|
| 	table_add_fixed(t, "%p", SIZE_OF_ADDR);
| 	table_add_fixed(t, "%10d", sizeof(int));
| 	table_add_string(t, "%30s", 30);
|
| 	table_printf(t, table_test, 2501, "one");
| 	table_printf(t, t, 0x2501, "two");
| 	table_printf(t, table_printf, 42, "Answer to the Ultimate Question of "
| 		     "Life, the Universe, and Everything");
|
| 	table_free(t);
| }
|
| int main(void)
| {
| 	table_test();
| }

| /* output */
| 0x420340       2501                            one
| 0xc9c080       9473                            two
| 0x450e90         42 Answer to the Ultimate Questi~   <- Third argument is truncated

Current util/table.c is too weak, but this can be a basic start point.
I think this is useful, how do you think?

Signed-off-by: Hitoshi Mitake <mitake@....info.waseda.ac.jp>
Cc: Peter Zijlstra <a.p.zijlstra@...llo.nl>
Cc: Paul Mackerras <paulus@...ba.org>
Cc: Frederic Weisbecker <fweisbec@...il.com>
---
 tools/perf/Makefile     |    2 +
 tools/perf/util/table.c |  157 +++++++++++++++++++++++++++++++++++++++++++++++
 tools/perf/util/table.h |   32 ++++++++++
 3 files changed, 191 insertions(+), 0 deletions(-)
 create mode 100644 tools/perf/util/table.c
 create mode 100644 tools/perf/util/table.h

diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index 54a5b50..93ecf09 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -387,6 +387,7 @@ LIB_H += util/thread.h
 LIB_H += util/trace-event.h
 LIB_H += util/probe-finder.h
 LIB_H += util/probe-event.h
+LIB_H += util/table.h
 
 LIB_OBJS += util/abspath.o
 LIB_OBJS += util/alias.o
@@ -433,6 +434,7 @@ LIB_OBJS += util/sort.o
 LIB_OBJS += util/hist.o
 LIB_OBJS += util/probe-event.o
 LIB_OBJS += util/util.o
+LIB_OBJS += util/table.o
 
 BUILTIN_OBJS += builtin-annotate.o
 
diff --git a/tools/perf/util/table.c b/tools/perf/util/table.c
new file mode 100644
index 0000000..a8b770d
--- /dev/null
+++ b/tools/perf/util/table.c
@@ -0,0 +1,157 @@
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#include <linux/kernel.h>
+
+#include "util.h"
+#include "table.h"
+
+struct table *table_new(void)
+{
+	struct table *new;
+
+	new = zalloc(sizeof(struct table));
+	new->column_formats.next = &new->column_formats;
+	new->column_formats.prev = &new->column_formats;
+	return new;
+}
+
+void table_free(struct table *t)
+{
+	struct list_head *l;
+
+	list_for_each_prev(l, &t->column_formats) {
+		struct column_format *fmt
+			= container_of(l, struct column_format, formats);
+		free(fmt);
+	}
+
+	free(t);
+}
+
+static void table_add_column(struct table *t, struct column_format *new)
+{
+	list_add_tail(&new->formats, &t->column_formats);
+}
+
+void table_add_fixed(struct table *t, const char *spec, int size)
+{
+	struct column_format *fmt;
+
+	fmt = zalloc(sizeof(struct column_format));
+	fmt->spec = spec;
+	fmt->size = size;
+	table_add_column(t, fmt);
+}
+
+void table_add_string(struct table *t, const char *spec, int trunc)
+{
+	struct column_format *fmt;
+
+	BUG_ON(trunc < 0);
+
+	fmt = zalloc(sizeof(struct column_format));
+	fmt->spec = spec;
+	fmt->size = SIZE_OF_ADDR;
+	fmt->attr |= TABLE_ATTR_STRING;
+	fmt->trunc = trunc;
+	table_add_column(t, fmt);
+}
+
+void table_printf(struct table *t, ...)
+{
+	va_list ap;
+	struct list_head *l;
+
+	unsigned char byte = 0;
+	unsigned short word = 0;
+	unsigned long dword = 0;
+	unsigned long long qword = 0;
+	char *str = NULL;
+
+	va_start(ap, t);
+
+	list_for_each(l, &t->column_formats) {
+		struct column_format *fmt
+			= container_of(l, struct column_format, formats);
+
+		if (fmt->attr & TABLE_ATTR_STRING) {
+			BUG_ON(fmt->size != SIZE_OF_ADDR);
+
+			str = va_arg(ap, char *);
+
+			if (!fmt->trunc || (strlen(str) < fmt->trunc)) {
+				printf(fmt->spec, str);
+			} else {
+				char *trunced = zalloc(fmt->trunc + 1);
+				memcpy(trunced, str, fmt->trunc);
+				trunced[fmt->trunc - 1] = '~';
+				printf(fmt->spec, trunced);
+			}
+		} else {
+			switch (fmt->size) {
+			case 1:
+				byte = (unsigned char)va_arg(ap, unsigned int);
+				printf(fmt->spec, byte);
+				break;
+			case 2:
+				word = (unsigned short)va_arg(ap, unsigned int);
+				printf(fmt->spec, word);
+				break;
+			case 4:
+				dword = va_arg(ap, unsigned long);
+				printf(fmt->spec, dword);
+				break;
+			case 8:
+				qword = va_arg(ap, unsigned long long);
+				printf(fmt->spec, qword);
+				break;
+			default:
+				die("table_printf(): unknown size:%d\n",
+				    fmt->size);
+				break;
+			}
+		}
+
+		if (l->next != &t->column_formats)
+			printf(" ");
+	}
+
+	printf("\n");
+	va_end(ap);
+}
+
+#if 0
+/* usage sample */
+
+/* program */
+static void table_test(void)
+{
+	struct table *t = table_new();
+
+	table_add_fixed(t, "%p", SIZE_OF_ADDR);
+	table_add_fixed(t, "%10d", sizeof(int));
+	table_add_string(t, "%30s", 30);
+
+	table_printf(t, table_test, 2501, "one");
+	table_printf(t, t, 0x2501, "two");
+	table_printf(t, table_printf, 42, "Answer to the Ultimate Question of "
+		     "Life, the Universe, and Everything");
+
+	table_free(t);
+}
+
+int main(void)
+{
+	table_test();
+}
+
+/* output */
+0x420340       2501                            one
+0xc9c080       9473                            two
+0x450e90         42 Answer to the Ultimate Questi~
+
+#endif
diff --git a/tools/perf/util/table.h b/tools/perf/util/table.h
new file mode 100644
index 0000000..8a7c7d8
--- /dev/null
+++ b/tools/perf/util/table.h
@@ -0,0 +1,32 @@
+
+#ifndef __PERF_TABLE_H
+#define __PERF_TABLE_H
+
+#include <linux/list.h>
+
+#define SIZE_OF_ADDR sizeof(void *)
+
+#define TABLE_ATTR_STRING 0x00000001
+
+struct column_format {
+	struct list_head formats;
+
+	const char       *spec;
+	int              size;
+	int              attr;
+	unsigned int     trunc;
+};
+
+struct table {
+	int columns;
+	struct list_head column_formats;
+};
+
+struct table *table_new(void);
+void table_free(struct table *t);
+void table_printf(struct table *t, ...);
+
+void table_add_fixed(struct table *t, const char *spec, int size);
+void table_add_string(struct table *t, const char *spec, int trunc);
+
+#endif	/* __PERF_TABLE_H */
-- 
1.6.5.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ