diff --git a/src/doveadm/Makefile.am b/src/doveadm/Makefile.am index 92554ee1e9..cfdaf2152c 100644 --- a/src/doveadm/Makefile.am +++ b/src/doveadm/Makefile.am @@ -120,7 +120,8 @@ common = \ doveadm-print.c \ doveadm-settings.c \ doveadm-util.c \ - server-connection.c + server-connection.c \ + doveadm-print-formatted.c doveadm_SOURCES = \ $(common) \ diff --git a/src/doveadm/doveadm-print-formatted.c b/src/doveadm/doveadm-print-formatted.c new file mode 100644 index 0000000000..87e03c5f19 --- /dev/null +++ b/src/doveadm/doveadm-print-formatted.c @@ -0,0 +1,82 @@ +#include "lib.h" +#include "array.h" +#include "str.h" +#include "ostream.h" +#include "client-connection.h" +#include "doveadm-server.h" +#include "doveadm-print.h" +#include "doveadm-print-private.h" +#include "var-expand.h" + +struct doveadm_print_formatted_context { + pool_t pool; + const char *format; + ARRAY(struct var_expand_table) headers; + string_t *buf; + string_t *vbuf; + unsigned int idx; +}; + +static struct doveadm_print_formatted_context ctx; + +void doveadm_print_formatted_set_format(const char *format) +{ + ctx.format = format; +} + +static void doveadm_print_formatted_init(void) +{ + memset(&ctx,0,sizeof(ctx)); + ctx.pool = pool_alloconly_create("doveadm formatted print", 1024); + ctx.buf = str_new(ctx.pool, 256); + p_array_init(&ctx.headers, ctx.pool, 8); + ctx.idx = 0; +} + +static void +doveadm_print_formatted_header(const struct doveadm_print_header *hdr) +{ + struct var_expand_table entry; + memset(&entry, 0, sizeof(entry)); + entry.key = '\0'; + entry.long_key = p_strdup(ctx.pool, hdr->key); + entry.value = NULL; + array_append(&ctx.headers, &entry, 1); +} + + +static void doveadm_print_formatted_flush(void) +{ + o_stream_nsend(doveadm_print_ostream, str_data(ctx.buf), str_len(ctx.buf)); + str_truncate(ctx.buf, 0); +} + +static void doveadm_print_formatted_print(const char *value) +{ + struct var_expand_table *entry = array_idx_modifiable(&ctx.headers, ctx.idx++); + entry->value = value; + + if (ctx.idx >= array_count(&ctx.headers)) { + var_expand(ctx.buf, ctx.format, array_idx(&ctx.headers,0)); + doveadm_print_formatted_flush(); + ctx.idx = 0; + } + +} + +static void doveadm_print_formatted_deinit(void) +{ + pool_unref(&ctx.pool); +} + +struct doveadm_print_vfuncs doveadm_print_formatted_vfuncs = { + "formatted", + + doveadm_print_formatted_init, + doveadm_print_formatted_deinit, + doveadm_print_formatted_header, + doveadm_print_formatted_print, + NULL, + doveadm_print_formatted_flush +}; + diff --git a/src/doveadm/doveadm-print-private.h b/src/doveadm/doveadm-print-private.h index f504727fbb..fe85560b75 100644 --- a/src/doveadm/doveadm-print-private.h +++ b/src/doveadm/doveadm-print-private.h @@ -26,5 +26,6 @@ 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; extern struct doveadm_print_vfuncs doveadm_print_json_vfuncs; +extern struct doveadm_print_vfuncs doveadm_print_formatted_vfuncs; #endif diff --git a/src/doveadm/doveadm-print.h b/src/doveadm/doveadm-print.h index 647d32051d..35b415d9c0 100644 --- a/src/doveadm/doveadm-print.h +++ b/src/doveadm/doveadm-print.h @@ -6,6 +6,7 @@ #define DOVEADM_PRINT_TYPE_TABLE "table" #define DOVEADM_PRINT_TYPE_SERVER "server" #define DOVEADM_PRINT_TYPE_JSON "json" +#define DOVEADM_PRINT_TYPE_FORMATTED "formatted" enum doveadm_print_header_flags { DOVEADM_PRINT_HEADER_FLAG_RIGHT_JUSTIFY = 0x01, @@ -38,4 +39,6 @@ void doveadm_print_unstick_headers(void); void doveadm_print_init(const char *name); void doveadm_print_deinit(void); +void doveadm_print_formatted_set_format(const char *format); + #endif diff --git a/src/doveadm/doveadm.c b/src/doveadm/doveadm.c index b85d58d46c..c41b30b561 100644 --- a/src/doveadm/doveadm.c +++ b/src/doveadm/doveadm.c @@ -25,6 +25,7 @@ const struct doveadm_print_vfuncs *doveadm_print_vfuncs_all[] = { &doveadm_print_table_vfuncs, &doveadm_print_pager_vfuncs, &doveadm_print_json_vfuncs, + &doveadm_print_formatted_vfuncs, NULL };