aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/jemalloc/internal/emitter.h66
-rw-r--r--test/unit/emitter.c64
2 files changed, 123 insertions, 7 deletions
diff --git a/include/jemalloc/internal/emitter.h b/include/jemalloc/internal/emitter.h
index c82dbdb1..830d0f24 100644
--- a/include/jemalloc/internal/emitter.h
+++ b/include/jemalloc/internal/emitter.h
@@ -1,6 +1,8 @@
#ifndef JEMALLOC_INTERNAL_EMITTER_H
#define JEMALLOC_INTERNAL_EMITTER_H
+#include "jemalloc/internal/ql.h"
+
typedef enum emitter_output_e emitter_output_t;
enum emitter_output_e {
emitter_output_json,
@@ -25,8 +27,50 @@ enum emitter_type_e {
emitter_type_size,
emitter_type_ssize,
emitter_type_string,
+ /*
+ * A title is a column title in a table; it's just a string, but it's
+ * not quoted.
+ */
+ emitter_type_title,
+};
+
+typedef struct emitter_col_s emitter_col_t;
+struct emitter_col_s {
+ /* Filled in by the user. */
+ emitter_justify_t justify;
+ int width;
+ emitter_type_t type;
+ union {
+ bool bool_val;
+ int int_val;
+ unsigned unsigned_val;
+ uint32_t uint32_val;
+ uint64_t uint64_val;
+ size_t size_val;
+ ssize_t ssize_val;
+ const char *str_val;
+ };
+
+ /* Filled in by initialization. */
+ ql_elm(emitter_col_t) link;
+};
+
+typedef struct emitter_row_s emitter_row_t;
+struct emitter_row_s {
+ ql_head(emitter_col_t) cols;
};
+static inline void
+emitter_row_init(emitter_row_t *row) {
+ ql_new(&row->cols);
+}
+
+static inline void
+emitter_col_init(emitter_col_t *col, emitter_row_t *row) {
+ ql_elm_new(col, link);
+ ql_tail_insert(&row->cols, col, link);
+}
+
typedef struct emitter_s emitter_t;
struct emitter_s {
emitter_output_t output;
@@ -141,12 +185,6 @@ emitter_print_value(emitter_t *emitter, emitter_justify_t justify, int width,
* anywhere near the fmt size.
*/
assert(str_written < BUF_SIZE);
-
- /*
- * We don't support justified quoted string primitive values for
- * now. Fortunately, we don't want to emit them.
- */
-
emitter_gen_fmt(fmt, FMT_SIZE, "s", justify, width);
emitter_printf(emitter, fmt, buf);
break;
@@ -156,6 +194,9 @@ emitter_print_value(emitter_t *emitter, emitter_justify_t justify, int width,
case emitter_type_uint64:
EMIT_SIMPLE(uint64_t, FMTu64)
break;
+ case emitter_type_title:
+ EMIT_SIMPLE(char *const, "s");
+ break;
default:
unreachable();
}
@@ -378,4 +419,17 @@ emitter_json_arr_value(emitter_t *emitter, emitter_type_t value_type,
}
}
+static inline void
+emitter_table_row(emitter_t *emitter, emitter_row_t *row) {
+ if (emitter->output != emitter_output_table) {
+ return;
+ }
+ emitter_col_t *col;
+ ql_foreach(col, &row->cols, link) {
+ emitter_print_value(emitter, col->justify, col->width,
+ col->type, (const void *)&col->bool_val);
+ }
+ emitter_table_printf(emitter, "\n");
+}
+
#endif /* JEMALLOC_INTERNAL_EMITTER_H */
diff --git a/test/unit/emitter.c b/test/unit/emitter.c
index c2216b22..535c7cf1 100644
--- a/test/unit/emitter.c
+++ b/test/unit/emitter.c
@@ -217,6 +217,10 @@ emit_types(emitter_t *emitter) {
emitter_kv(emitter, "k6", "K6", emitter_type_string, &str);
emitter_kv(emitter, "k7", "K7", emitter_type_uint32, &u32);
emitter_kv(emitter, "k8", "K8", emitter_type_uint64, &u64);
+ /*
+ * We don't test the title type, since it's only used for tables. It's
+ * tested in the emitter_table_row tests.
+ */
emitter_end(emitter);
}
@@ -339,6 +343,63 @@ TEST_BEGIN(test_json_arr) {
}
TEST_END
+static void
+emit_table_row(emitter_t *emitter) {
+ emitter_begin(emitter);
+ emitter_row_t row;
+ emitter_col_t abc = {emitter_justify_left, 10, emitter_type_title};
+ abc.str_val = "ABC title";
+ emitter_col_t def = {emitter_justify_right, 15, emitter_type_title};
+ def.str_val = "DEF title";
+ emitter_col_t ghi = {emitter_justify_right, 5, emitter_type_title};
+ ghi.str_val = "GHI";
+
+ emitter_row_init(&row);
+ emitter_col_init(&abc, &row);
+ emitter_col_init(&def, &row);
+ emitter_col_init(&ghi, &row);
+
+ emitter_table_row(emitter, &row);
+
+ abc.type = emitter_type_int;
+ def.type = emitter_type_bool;
+ ghi.type = emitter_type_int;
+
+ abc.int_val = 123;
+ def.bool_val = true;
+ ghi.int_val = 456;
+ emitter_table_row(emitter, &row);
+
+ abc.int_val = 789;
+ def.bool_val = false;
+ ghi.int_val = 1011;
+ emitter_table_row(emitter, &row);
+
+ abc.type = emitter_type_string;
+ abc.str_val = "a string";
+ def.bool_val = false;
+ ghi.type = emitter_type_title;
+ ghi.str_val = "ghi";
+ emitter_table_row(emitter, &row);
+
+ emitter_end(emitter);
+}
+
+static const char *table_row_json =
+"{\n"
+"}\n";
+
+static const char *table_row_table =
+"ABC title DEF title GHI\n"
+"123 true 456\n"
+"789 false 1011\n"
+"\"a string\" false ghi\n";
+
+TEST_BEGIN(test_table_row) {
+ assert_emit_output(&emit_table_row, table_row_json, table_row_table);
+}
+TEST_END
+
int
main(void) {
return test_no_reentrancy(
@@ -347,5 +408,6 @@ main(void) {
test_nested_dict,
test_types,
test_modal,
- test_json_arr);
+ test_json_arr,
+ test_table_row);
}