From 528bfe84f996046645103de898564ef5bcb5edad Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Mon, 21 Jun 2010 21:46:20 +0100 Subject: [PATCH] doveadm: Added "pager" formatter and a function to output streamed output values. --HG-- branch : HEAD --- src/doveadm/Makefile.am | 1 + src/doveadm/doveadm-print-flow.c | 35 ++++++++-- src/doveadm/doveadm-print-pager.c | 99 +++++++++++++++++++++++++++++ src/doveadm/doveadm-print-private.h | 2 + src/doveadm/doveadm-print-tab.c | 17 +++++ src/doveadm/doveadm-print-table.c | 8 +++ src/doveadm/doveadm-print.c | 8 ++- src/doveadm/doveadm-print.h | 2 + 8 files changed, 166 insertions(+), 6 deletions(-) create mode 100644 src/doveadm/doveadm-print-pager.c diff --git a/src/doveadm/Makefile.am b/src/doveadm/Makefile.am index 36dc756e35..805a369c54 100644 --- a/src/doveadm/Makefile.am +++ b/src/doveadm/Makefile.am @@ -66,6 +66,7 @@ doveadm_SOURCES = \ doveadm-penalty.c \ doveadm-print.c \ doveadm-print-flow.c \ + doveadm-print-pager.c \ doveadm-print-tab.c \ doveadm-print-table.c \ doveadm-pw.c \ diff --git a/src/doveadm/doveadm-print-flow.c b/src/doveadm/doveadm-print-flow.c index fb24a15955..4449f8684d 100644 --- a/src/doveadm/doveadm-print-flow.c +++ b/src/doveadm/doveadm-print-flow.c @@ -15,6 +15,8 @@ struct doveadm_print_flow_context { pool_t pool; ARRAY_DEFINE(headers, struct doveadm_print_flow_header); unsigned int header_idx; + + unsigned int streaming:1; }; static struct doveadm_print_flow_context *ctx; @@ -29,6 +31,16 @@ doveadm_print_flow_header(const struct doveadm_print_header *hdr) fhdr->flags = hdr->flags; } +static void flow_next_hdr(void) +{ + if (++ctx->header_idx < array_count(&ctx->headers)) + printf(" "); + else { + ctx->header_idx = 0; + printf("\n"); + } +} + static void doveadm_print_flow_print(const char *value) { const struct doveadm_print_flow_header *hdr = @@ -37,12 +49,24 @@ static void doveadm_print_flow_print(const char *value) if ((hdr->flags & DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE) == 0) printf("%s=", hdr->title); printf("%s", value); + flow_next_hdr(); +} - if (++ctx->header_idx < array_count(&ctx->headers)) - printf(" "); - else { - ctx->header_idx = 0; - printf("\n"); +static void +doveadm_print_flow_print_stream(const unsigned char *value, size_t size) +{ + const struct doveadm_print_flow_header *hdr = + array_idx(&ctx->headers, ctx->header_idx); + + if (!ctx->streaming) { + ctx->streaming = TRUE; + if ((hdr->flags & DOVEADM_PRINT_HEADER_FLAG_HIDE_TITLE) == 0) + printf("%s=", hdr->title); + } + printf("%.*s", (int)size, value); + if (size == 0) { + flow_next_hdr(); + ctx->streaming = FALSE; } } @@ -77,5 +101,6 @@ struct doveadm_print_vfuncs doveadm_print_flow_vfuncs = { doveadm_print_flow_deinit, doveadm_print_flow_header, doveadm_print_flow_print, + doveadm_print_flow_print_stream, doveadm_print_flow_flush }; diff --git a/src/doveadm/doveadm-print-pager.c b/src/doveadm/doveadm-print-pager.c new file mode 100644 index 0000000000..6705a0c697 --- /dev/null +++ b/src/doveadm/doveadm-print-pager.c @@ -0,0 +1,99 @@ +/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "array.h" +#include "doveadm-print-private.h" + +#include + +struct doveadm_print_pager_header { + const char *title; +}; + +struct doveadm_print_pager_context { + pool_t pool; + ARRAY_DEFINE(headers, struct doveadm_print_pager_header); + unsigned int header_idx; + + unsigned int streaming:1; +}; + +static struct doveadm_print_pager_context *ctx; + +static void +doveadm_print_pager_header(const struct doveadm_print_header *hdr) +{ + struct doveadm_print_pager_header *fhdr; + + fhdr = array_append_space(&ctx->headers); + fhdr->title = p_strdup(ctx->pool, hdr->title); +} + +static void pager_next_hdr(void) +{ + if (++ctx->header_idx == array_count(&ctx->headers)) { + ctx->header_idx = 0; + printf("\x0c"); /* ^L */ + } +} + +static void doveadm_print_pager_print(const char *value) +{ + const struct doveadm_print_pager_header *hdr = + array_idx(&ctx->headers, ctx->header_idx); + + printf("%s: %s\n", hdr->title, value); + pager_next_hdr(); +} + +static void +doveadm_print_pager_print_stream(const unsigned char *value, size_t size) +{ + const struct doveadm_print_pager_header *hdr = + array_idx(&ctx->headers, ctx->header_idx); + + if (!ctx->streaming) { + ctx->streaming = TRUE; + printf("%s:\n", hdr->title); + } + printf("%.*s", (int)size, value); + if (size == 0) { + pager_next_hdr(); + ctx->streaming = FALSE; + } +} + +static void doveadm_print_pager_init(void) +{ + pool_t pool; + + pool = pool_alloconly_create("doveadm print pager", 1024); + ctx = p_new(pool, struct doveadm_print_pager_context, 1); + ctx->pool = pool; + p_array_init(&ctx->headers, pool, 16); +} + +static void doveadm_print_pager_flush(void) +{ + if (ctx->header_idx != 0) { + printf("\n"); + ctx->header_idx = 0; + } +} + +static void doveadm_print_pager_deinit(void) +{ + pool_unref(&ctx->pool); + ctx = NULL; +} + +struct doveadm_print_vfuncs doveadm_print_pager_vfuncs = { + "pager", + + doveadm_print_pager_init, + doveadm_print_pager_deinit, + doveadm_print_pager_header, + doveadm_print_pager_print, + doveadm_print_pager_print_stream, + doveadm_print_pager_flush +}; diff --git a/src/doveadm/doveadm-print-private.h b/src/doveadm/doveadm-print-private.h index 17c8ae8f72..854bfc70e7 100644 --- a/src/doveadm/doveadm-print-private.h +++ b/src/doveadm/doveadm-print-private.h @@ -17,11 +17,13 @@ struct doveadm_print_vfuncs { void (*header)(const struct doveadm_print_header *hdr); void (*print)(const char *value); + void (*print_stream)(const unsigned char *value, size_t size); void (*flush)(void); }; extern struct doveadm_print_vfuncs doveadm_print_flow_vfuncs; extern struct doveadm_print_vfuncs doveadm_print_tab_vfuncs; extern struct doveadm_print_vfuncs doveadm_print_table_vfuncs; +extern struct doveadm_print_vfuncs doveadm_print_pager_vfuncs; #endif diff --git a/src/doveadm/doveadm-print-tab.c b/src/doveadm/doveadm-print-tab.c index 35ececa2e0..51d68b8601 100644 --- a/src/doveadm/doveadm-print-tab.c +++ b/src/doveadm/doveadm-print-tab.c @@ -40,6 +40,22 @@ static void doveadm_print_tab_print(const char *value) } } +static void +doveadm_print_tab_print_stream(const unsigned char *value, size_t size) +{ + if (size == 0) { + doveadm_print_tab_print(""); + return; + } + if (!ctx.header_written) { + printf("\n"); + ctx.header_written = TRUE; + } + if (ctx.header_idx > 0) + printf("\t"); + printf("%.*s", (int)size, value); +} + static void doveadm_print_tab_flush(void) { if (!ctx.header_written) { @@ -55,5 +71,6 @@ struct doveadm_print_vfuncs doveadm_print_tab_vfuncs = { NULL, doveadm_print_tab_header, doveadm_print_tab_print, + doveadm_print_tab_print_stream, doveadm_print_tab_flush }; diff --git a/src/doveadm/doveadm-print-table.c b/src/doveadm/doveadm-print-table.c index 3fb972a09b..17f6cbdaa3 100644 --- a/src/doveadm/doveadm-print-table.c +++ b/src/doveadm/doveadm-print-table.c @@ -171,6 +171,13 @@ static void doveadm_print_table_print(const char *value) doveadm_print_next(value); } +static void +doveadm_print_table_print_stream(const unsigned char *value ATTR_UNUSED, + size_t size ATTR_UNUSED) +{ + i_fatal("table formatter doesn't support multi-line values"); +} + static void doveadm_print_table_flush(void) { if (!ctx->lengths_set && array_count(&ctx->headers) > 0) @@ -209,5 +216,6 @@ struct doveadm_print_vfuncs doveadm_print_table_vfuncs = { doveadm_print_table_deinit, doveadm_print_table_header, doveadm_print_table_print, + doveadm_print_table_print_stream, doveadm_print_table_flush }; diff --git a/src/doveadm/doveadm-print.c b/src/doveadm/doveadm-print.c index fbd5b6a40d..0d47c27160 100644 --- a/src/doveadm/doveadm-print.c +++ b/src/doveadm/doveadm-print.c @@ -24,7 +24,8 @@ static struct doveadm_print_context *ctx; static const struct doveadm_print_vfuncs *doveadm_print_vfuncs_all[] = { &doveadm_print_flow_vfuncs, &doveadm_print_tab_vfuncs, - &doveadm_print_table_vfuncs + &doveadm_print_table_vfuncs, + &doveadm_print_pager_vfuncs }; bool doveadm_print_is_initialized(void) @@ -85,6 +86,11 @@ void doveadm_print_num(uintmax_t value) } T_END; } +void doveadm_print_stream(const void *value, size_t size) +{ + ctx->v->print_stream(value, size); +} + void doveadm_print_sticky(const char *key, const char *value) { struct doveadm_print_header_context *hdr; diff --git a/src/doveadm/doveadm-print.h b/src/doveadm/doveadm-print.h index 33e8a13c1a..cf5c9a42e4 100644 --- a/src/doveadm/doveadm-print.h +++ b/src/doveadm/doveadm-print.h @@ -17,6 +17,8 @@ void doveadm_print_header(const char *key, const char *title, void doveadm_print_header_simple(const char *key_title); void doveadm_print(const char *value); void doveadm_print_num(uintmax_t value); +/* Stream for same field continues until len=0 */ +void doveadm_print_stream(const void *value, size_t size); void doveadm_print_sticky(const char *key, const char *value); void doveadm_print_flush(void); -- 2.47.3