]> git.notmuchmail.org Git - notmuch/blob - sprinter-text.c
test: add regression test for large number of deletions
[notmuch] / sprinter-text.c
1 #include <inttypes.h>
2 #include <stdbool.h>
3 #include <stdio.h>
4 #include <talloc.h>
5 #include "sprinter.h"
6
7 /* "Structured printer" interface for unstructured text printing.
8  * Note that --output=summary is dispatched and formatted in
9  * notmuch-search.c, the code in this file is only used for all other
10  * output types.
11  */
12
13 struct sprinter_text {
14     struct sprinter vtable;
15     FILE *stream;
16
17     /* The current prefix to be printed with string/integer/boolean
18      * data.
19      */
20     const char *current_prefix;
21
22     /* A flag to indicate if this is the first tag. Used in list of tags
23      * for summary.
24      */
25     bool first_tag;
26 };
27
28 static void
29 text_string_len (struct sprinter *sp, const char *val, size_t len)
30 {
31     struct sprinter_text *sptxt = (struct sprinter_text *) sp;
32
33     if (sptxt->current_prefix != NULL)
34         fprintf (sptxt->stream, "%s:", sptxt->current_prefix);
35
36     fwrite (val, len, 1, sptxt->stream);
37 }
38
39 static void
40 text_string (struct sprinter *sp, const char *val)
41 {
42     if (val == NULL)
43         val = "";
44     text_string_len (sp, val, strlen (val));
45 }
46
47 static void
48 text_integer (struct sprinter *sp, int64_t val)
49 {
50     struct sprinter_text *sptxt = (struct sprinter_text *) sp;
51
52     fprintf (sptxt->stream, "%" PRId64, val);
53 }
54
55 static void
56 text_boolean (struct sprinter *sp, bool val)
57 {
58     struct sprinter_text *sptxt = (struct sprinter_text *) sp;
59
60     fputs (val ? "true" : "false", sptxt->stream);
61 }
62
63 static void
64 text_separator (struct sprinter *sp)
65 {
66     struct sprinter_text *sptxt = (struct sprinter_text *) sp;
67
68     fputc ('\n', sptxt->stream);
69 }
70
71 static void
72 text0_separator (struct sprinter *sp)
73 {
74     struct sprinter_text *sptxt = (struct sprinter_text *) sp;
75
76     fputc ('\0', sptxt->stream);
77 }
78
79 static void
80 text_set_prefix (struct sprinter *sp, const char *prefix)
81 {
82     struct sprinter_text *sptxt = (struct sprinter_text *) sp;
83
84     sptxt->current_prefix = prefix;
85 }
86
87 /* The structure functions begin_map, begin_list, end and map_key
88  * don't do anything in the text formatter.
89  */
90
91 static void
92 text_begin_map (unused (struct sprinter *sp))
93 {
94 }
95
96 static void
97 text_begin_list (unused (struct sprinter *sp))
98 {
99 }
100
101 static void
102 text_end (unused (struct sprinter *sp))
103 {
104 }
105
106 static void
107 text_null (unused (struct sprinter *sp))
108 {
109 }
110
111 static void
112 text_map_key (unused (struct sprinter *sp), unused (const char *key))
113 {
114 }
115
116 struct sprinter *
117 sprinter_text_create (const void *ctx, FILE *stream)
118 {
119     static const struct sprinter_text template = {
120         .vtable = {
121             .begin_map = text_begin_map,
122             .begin_list = text_begin_list,
123             .end = text_end,
124             .string = text_string,
125             .string_len = text_string_len,
126             .integer = text_integer,
127             .boolean = text_boolean,
128             .null = text_null,
129             .map_key = text_map_key,
130             .separator = text_separator,
131             .set_prefix = text_set_prefix,
132             .is_text_printer = true,
133         },
134     };
135     struct sprinter_text *res;
136
137     res = talloc (ctx, struct sprinter_text);
138     if (! res)
139         return NULL;
140
141     *res = template;
142     res->stream = stream;
143     return &res->vtable;
144 }
145
146 struct sprinter *
147 sprinter_text0_create (const void *ctx, FILE *stream)
148 {
149     struct sprinter *sp;
150
151     sp = sprinter_text_create (ctx, stream);
152     if (! sp)
153         return NULL;
154
155     sp->separator = text0_separator;
156
157     return sp;
158 }