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 \
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;
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 =
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;
}
}
doveadm_print_flow_deinit,
doveadm_print_flow_header,
doveadm_print_flow_print,
+ doveadm_print_flow_print_stream,
doveadm_print_flow_flush
};
--- /dev/null
+/* Copyright (c) 2010 Dovecot authors, see the included COPYING file */
+
+#include "lib.h"
+#include "array.h"
+#include "doveadm-print-private.h"
+
+#include <stdio.h>
+
+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
+};
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
}
}
+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) {
NULL,
doveadm_print_tab_header,
doveadm_print_tab_print,
+ doveadm_print_tab_print_stream,
doveadm_print_tab_flush
};
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)
doveadm_print_table_deinit,
doveadm_print_table_header,
doveadm_print_table_print,
+ doveadm_print_table_print_stream,
doveadm_print_table_flush
};
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)
} 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;
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);