2020-02-08 02:49:22 +01:00
|
|
|
#include <inttypes.h>
|
2012-07-23 12:39:45 +02:00
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <talloc.h>
|
|
|
|
#include "sprinter.h"
|
|
|
|
|
|
|
|
/* "Structured printer" interface for unstructured text printing.
|
|
|
|
* Note that --output=summary is dispatched and formatted in
|
|
|
|
* notmuch-search.c, the code in this file is only used for all other
|
|
|
|
* output types.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct sprinter_text {
|
|
|
|
struct sprinter vtable;
|
|
|
|
FILE *stream;
|
|
|
|
|
|
|
|
/* The current prefix to be printed with string/integer/boolean
|
|
|
|
* data.
|
|
|
|
*/
|
|
|
|
const char *current_prefix;
|
|
|
|
|
|
|
|
/* A flag to indicate if this is the first tag. Used in list of tags
|
|
|
|
* for summary.
|
|
|
|
*/
|
2017-10-07 10:44:04 +02:00
|
|
|
bool first_tag;
|
2012-07-23 12:39:45 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
2012-08-03 03:14:49 +02:00
|
|
|
text_string_len (struct sprinter *sp, const char *val, size_t len)
|
2012-07-23 12:39:45 +02:00
|
|
|
{
|
|
|
|
struct sprinter_text *sptxt = (struct sprinter_text *) sp;
|
|
|
|
|
|
|
|
if (sptxt->current_prefix != NULL)
|
|
|
|
fprintf (sptxt->stream, "%s:", sptxt->current_prefix);
|
|
|
|
|
2012-08-03 03:14:49 +02:00
|
|
|
fwrite (val, len, 1, sptxt->stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
text_string (struct sprinter *sp, const char *val)
|
|
|
|
{
|
2012-08-08 23:23:33 +02:00
|
|
|
if (val == NULL)
|
|
|
|
val = "";
|
2012-08-03 03:14:49 +02:00
|
|
|
text_string_len (sp, val, strlen (val));
|
2012-07-23 12:39:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-02-08 02:49:22 +01:00
|
|
|
text_integer (struct sprinter *sp, int64_t val)
|
2012-07-23 12:39:45 +02:00
|
|
|
{
|
|
|
|
struct sprinter_text *sptxt = (struct sprinter_text *) sp;
|
|
|
|
|
2021-03-13 13:45:34 +01:00
|
|
|
fprintf (sptxt->stream, "%" PRId64, val);
|
2012-07-23 12:39:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2017-10-07 10:44:04 +02:00
|
|
|
text_boolean (struct sprinter *sp, bool val)
|
2012-07-23 12:39:45 +02:00
|
|
|
{
|
|
|
|
struct sprinter_text *sptxt = (struct sprinter_text *) sp;
|
|
|
|
|
|
|
|
fputs (val ? "true" : "false", sptxt->stream);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
text_separator (struct sprinter *sp)
|
|
|
|
{
|
|
|
|
struct sprinter_text *sptxt = (struct sprinter_text *) sp;
|
|
|
|
|
|
|
|
fputc ('\n', sptxt->stream);
|
|
|
|
}
|
|
|
|
|
2012-12-16 23:05:10 +01:00
|
|
|
static void
|
|
|
|
text0_separator (struct sprinter *sp)
|
|
|
|
{
|
|
|
|
struct sprinter_text *sptxt = (struct sprinter_text *) sp;
|
|
|
|
|
|
|
|
fputc ('\0', sptxt->stream);
|
|
|
|
}
|
|
|
|
|
2012-07-23 12:39:45 +02:00
|
|
|
static void
|
|
|
|
text_set_prefix (struct sprinter *sp, const char *prefix)
|
|
|
|
{
|
|
|
|
struct sprinter_text *sptxt = (struct sprinter_text *) sp;
|
|
|
|
|
|
|
|
sptxt->current_prefix = prefix;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The structure functions begin_map, begin_list, end and map_key
|
|
|
|
* don't do anything in the text formatter.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void
|
|
|
|
text_begin_map (unused (struct sprinter *sp))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
text_begin_list (unused (struct sprinter *sp))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
text_end (unused (struct sprinter *sp))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
text_null (unused (struct sprinter *sp))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
text_map_key (unused (struct sprinter *sp), unused (const char *key))
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
struct sprinter *
|
|
|
|
sprinter_text_create (const void *ctx, FILE *stream)
|
|
|
|
{
|
|
|
|
static const struct sprinter_text template = {
|
|
|
|
.vtable = {
|
|
|
|
.begin_map = text_begin_map,
|
|
|
|
.begin_list = text_begin_list,
|
|
|
|
.end = text_end,
|
|
|
|
.string = text_string,
|
2012-08-03 03:14:49 +02:00
|
|
|
.string_len = text_string_len,
|
2012-07-23 12:39:45 +02:00
|
|
|
.integer = text_integer,
|
|
|
|
.boolean = text_boolean,
|
|
|
|
.null = text_null,
|
|
|
|
.map_key = text_map_key,
|
|
|
|
.separator = text_separator,
|
|
|
|
.set_prefix = text_set_prefix,
|
2017-10-07 10:44:04 +02:00
|
|
|
.is_text_printer = true,
|
2012-07-23 12:39:45 +02:00
|
|
|
},
|
|
|
|
};
|
|
|
|
struct sprinter_text *res;
|
|
|
|
|
|
|
|
res = talloc (ctx, struct sprinter_text);
|
|
|
|
if (! res)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
*res = template;
|
|
|
|
res->stream = stream;
|
|
|
|
return &res->vtable;
|
|
|
|
}
|
2012-12-16 23:05:10 +01:00
|
|
|
|
|
|
|
struct sprinter *
|
|
|
|
sprinter_text0_create (const void *ctx, FILE *stream)
|
|
|
|
{
|
|
|
|
struct sprinter *sp;
|
|
|
|
|
|
|
|
sp = sprinter_text_create (ctx, stream);
|
|
|
|
if (! sp)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
sp->separator = text0_separator;
|
|
|
|
|
|
|
|
return sp;
|
|
|
|
}
|