NeoMutt  2025-12-11-435-g4ac674
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
serial.c
Go to the documentation of this file.
1
22
28
29#include "config.h"
30#include <limits.h>
31#include <stdbool.h>
32#include <stddef.h>
33#include <stdint.h>
34#include "mutt/lib.h"
35#include "debug/lib.h"
36#include "serial.h"
37#include "expando.h"
38#include "node.h"
39#include "node_conddate.h"
40#include "node_condition.h"
41#include "node_padding.h"
42
43static void dump_node(const struct ExpandoNode *node, struct Buffer *buf);
44
50static void dump_did_uid(const struct ExpandoNode *node, struct Buffer *buf)
51{
52 const char *did = name_expando_domain(node->did);
53 const char *uid = name_expando_uid(node->did, node->uid);
54 buf_add_printf(buf, "(%s,%s)", did, uid);
55}
56
62static void dump_node_condition(const struct ExpandoNode *node, struct Buffer *buf)
63{
64 buf_addstr(buf, "<COND");
65
66 // These shouldn't happen
67 if (node->text)
68 buf_add_printf(buf, ",text=%s", node->text);
69
70 struct ExpandoNode *node_cond = node_get_child(node, ENC_CONDITION);
71 struct ExpandoNode *node_true = node_get_child(node, ENC_TRUE);
72 struct ExpandoNode *node_false = node_get_child(node, ENC_FALSE);
73
74 ASSERT(node_cond);
75 buf_addstr(buf, ":");
76 dump_node(node_cond, buf);
77 buf_addstr(buf, "|");
78 dump_node(node_true, buf);
79 buf_addstr(buf, "|");
80 dump_node(node_false, buf);
81
82 const struct ExpandoFormat *fmt = node->format;
83 if (fmt)
84 {
85 const char *just = name_format_justify(fmt->justification);
86 if (fmt->max_cols == INT_MAX)
87 buf_add_printf(buf, ":{%d,MAX,%s,'%c'}", fmt->min_cols, just + 8, fmt->leader);
88 else
89 buf_add_printf(buf, ":{%d,%d,%s,'%c'}", fmt->min_cols, fmt->max_cols,
90 just + 8, fmt->leader);
91 }
92
93 buf_addstr(buf, ">");
94}
95
101static void dump_node_condbool(const struct ExpandoNode *node, struct Buffer *buf)
102{
103 buf_addstr(buf, "<BOOL");
104 dump_did_uid(node, buf);
105
106 ASSERT(node->ndata != NULL);
107 ASSERT(node->ndata_free != NULL);
108
109 buf_addstr(buf, ">");
110}
111
117static void dump_node_conddate(const struct ExpandoNode *node, struct Buffer *buf)
118{
119 buf_addstr(buf, "<DATE:");
120
121 dump_did_uid(node, buf);
122
123 ASSERT(node->ndata);
124 ASSERT(node->ndata_free);
125 struct NodeCondDatePrivate *priv = node->ndata;
126 buf_add_printf(buf, ":%d:%c", priv->count, priv->period);
127
128 // These shouldn't happen
129 if (node->text)
130 buf_add_printf(buf, ",text=%s", node->text);
131
132 buf_addstr(buf, ">");
133}
134
140static void dump_node_container(const struct ExpandoNode *node, struct Buffer *buf)
141{
142 buf_addstr(buf, "<CONT:");
143
144 struct ExpandoNode **np = NULL;
145 ARRAY_FOREACH(np, &node->children)
146 {
147 if (!np || !*np)
148 continue;
149
150 dump_node(*np, buf);
151 }
152
153 buf_addstr(buf, ">");
154}
155
161static void dump_node_empty(const struct ExpandoNode *node, struct Buffer *buf)
162{
163 buf_addstr(buf, "<EMPTY");
164
165 // These shouldn't happen
166 if (node->did != 0)
167 buf_add_printf(buf, ",did=%d", node->did);
168 if (node->uid != 0)
169 buf_add_printf(buf, ",uid=%d", node->uid);
170 if (node->text)
171 buf_add_printf(buf, ",text=%s", node->text);
172 if (node->ndata)
173 buf_add_printf(buf, ",ndata=%p", node->ndata);
174 if (node->ndata_free)
175 buf_add_printf(buf, ",ndata_free=%p", (void *) (intptr_t) node->ndata_free);
176
177 buf_addstr(buf, ">");
178}
179
185static void dump_node_expando(const struct ExpandoNode *node, struct Buffer *buf)
186{
187 buf_addstr(buf, "<EXP:");
188
189 if (node->text)
190 buf_add_printf(buf, "'%s'", node->text);
191
192 ASSERT(node->did != 0);
193 ASSERT(node->uid != 0);
194 dump_did_uid(node, buf);
195
196 ASSERT(node->ndata);
197 ASSERT(node->ndata_free);
198
199 const struct ExpandoFormat *fmt = node->format;
200 if (fmt)
201 {
202 const char *just = name_format_justify(fmt->justification);
203 if (fmt->max_cols == INT_MAX)
204 buf_add_printf(buf, ":{%d,MAX,%s,'%c'}", fmt->min_cols, just + 8, fmt->leader);
205 else
206 buf_add_printf(buf, ":{%d,%d,%s,'%c'}", fmt->min_cols, fmt->max_cols,
207 just + 8, fmt->leader);
208 }
209
210 buf_addstr(buf, ">");
211}
212
218static void dump_node_padding(const struct ExpandoNode *node, struct Buffer *buf)
219{
220 buf_addstr(buf, "<PAD:");
221
222 ASSERT(node->ndata);
223 ASSERT(node->ndata_free);
224 struct NodePaddingPrivate *priv = node->ndata;
225
226 struct ExpandoNode *left = node_get_child(node, ENP_LEFT);
227 struct ExpandoNode *right = node_get_child(node, ENP_RIGHT);
228
229 const char *pt = name_expando_pad_type(priv->pad_type);
230 pt += 4; // Skip "EPT_" prefix
231 buf_add_printf(buf, "%s:", pt);
232
233 ASSERT(node->text);
234 buf_add_printf(buf, "'%s'", node->text);
235
236 buf_addstr(buf, ":");
237 dump_node(left, buf);
238 buf_addstr(buf, "|");
239 dump_node(right, buf);
240
241 buf_addstr(buf, ">");
242}
243
249static void dump_node_text(const struct ExpandoNode *node, struct Buffer *buf)
250{
251 buf_addstr(buf, "<TEXT:");
252
253 ASSERT(node->text);
254 buf_add_printf(buf, "'%s'", node->text);
255
256 // These shouldn't happen
257 if (node->ndata)
258 buf_add_printf(buf, ",ndata=%p", node->ndata);
259 if (node->ndata_free)
260 buf_add_printf(buf, ",ndata_free=%p", (void *) (intptr_t) node->ndata_free);
261
262 buf_addstr(buf, ">");
263}
264
270static void dump_node(const struct ExpandoNode *node, struct Buffer *buf)
271{
272 if (!node || !buf)
273 return;
274
275 switch (node->type)
276 {
277 case ENT_CONDITION:
278 dump_node_condition(node, buf);
279 break;
280 case ENT_CONDBOOL:
281 dump_node_condbool(node, buf);
282 break;
283 case ENT_CONDDATE:
284 dump_node_conddate(node, buf);
285 break;
286 case ENT_CONTAINER:
287 dump_node_container(node, buf);
288 break;
289 case ENT_EMPTY:
290 dump_node_empty(node, buf);
291 break;
292 case ENT_EXPANDO:
293 dump_node_expando(node, buf);
294 break;
295 case ENT_PADDING:
296 dump_node_padding(node, buf);
297 break;
298 case ENT_TEXT:
299 dump_node_text(node, buf);
300 break;
301 default:
302 ASSERT(false);
303 }
304}
305
311void expando_serialise(const struct Expando *exp, struct Buffer *buf)
312{
313 if (!exp || !buf)
314 return;
315
316 dump_node(exp->node, buf);
317}
#define ARRAY_FOREACH(elem, head)
Iterate over all elements of the array.
Definition array.h:223
int buf_add_printf(struct Buffer *buf, const char *fmt,...)
Format a string appending a Buffer.
Definition buffer.c:204
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:226
Convenience wrapper for the debug headers.
const char * name_expando_pad_type(enum ExpandoPadType type)
Get the name of an expando padding type.
const char * name_expando_uid(enum ExpandoDomain did, int uid)
Get the name of an email expando field.
const char * name_expando_domain(enum ExpandoDomain did)
Get the name of an expando domain.
const char * name_format_justify(enum FormatJustify just)
Parsed Expando.
Convenience wrapper for the library headers.
struct ExpandoNode * node_get_child(const struct ExpandoNode *node, int index)
Get a child of an ExpandoNode.
Definition node.c:91
Basic Expando Node.
@ ENT_EXPANDO
Expando, e.g. 'n'.
Definition node.h:39
@ ENT_CONTAINER
Container for other nodes.
Definition node.h:44
@ ENT_CONDITION
True/False condition.
Definition node.h:41
@ ENT_TEXT
Plain text.
Definition node.h:38
@ ENT_CONDDATE
True/False date condition.
Definition node.h:43
@ ENT_EMPTY
Empty.
Definition node.h:37
@ ENT_CONDBOOL
True/False boolean condition.
Definition node.h:42
@ ENT_PADDING
Padding: soft, hard, EOL.
Definition node.h:40
Expando Node for a Conditional Date.
Expando Node for a Condition.
@ ENC_CONDITION
Index of Condition Node.
@ ENC_FALSE
Index of False Node.
@ ENC_TRUE
Index of True Node.
Expando Node for Padding.
@ ENP_LEFT
Index of Left-Hand Nodes.
@ ENP_RIGHT
Index of Right-Hand Nodes.
static void dump_node_condition(const struct ExpandoNode *node, struct Buffer *buf)
Serialise a Condition Node.
Definition serial.c:62
static void dump_node(const struct ExpandoNode *node, struct Buffer *buf)
Serialise an Expando Node.
Definition serial.c:270
static void dump_node_padding(const struct ExpandoNode *node, struct Buffer *buf)
Serialise a Padding Node.
Definition serial.c:218
static void dump_did_uid(const struct ExpandoNode *node, struct Buffer *buf)
Serialise the Domain ID and UID of an Expando Node.
Definition serial.c:50
static void dump_node_condbool(const struct ExpandoNode *node, struct Buffer *buf)
Serialise a Conditional Bool Node.
Definition serial.c:101
static void dump_node_text(const struct ExpandoNode *node, struct Buffer *buf)
Serialise a Text Node.
Definition serial.c:249
static void dump_node_empty(const struct ExpandoNode *node, struct Buffer *buf)
Serialise an Empty Node.
Definition serial.c:161
static void dump_node_conddate(const struct ExpandoNode *node, struct Buffer *buf)
Serialise a Conditional Date Node.
Definition serial.c:117
static void dump_node_container(const struct ExpandoNode *node, struct Buffer *buf)
Serialise a Container Node.
Definition serial.c:140
void expando_serialise(const struct Expando *exp, struct Buffer *buf)
Serialise an Expando into a string.
Definition serial.c:311
static void dump_node_expando(const struct ExpandoNode *node, struct Buffer *buf)
Serialise an Expando Node.
Definition serial.c:185
Dump the details of an Expando Tree.
#define ASSERT(COND)
Definition signal2.h:59
String manipulation buffer.
Definition buffer.h:36
Formatting information for an Expando.
Definition node.h:53
char leader
Leader character, 0 or space.
Definition node.h:57
enum FormatJustify justification
Justification: left, centre, right.
Definition node.h:56
int min_cols
Minimum number of screen columns.
Definition node.h:54
int max_cols
Maximum number of screen columns.
Definition node.h:55
Basic Expando Node.
Definition node.h:67
int uid
Unique ID, e.g. ED_EMA_SIZE.
Definition node.h:70
void * ndata
Private node data.
Definition node.h:77
struct ExpandoFormat * format
Formatting info.
Definition node.h:72
int did
Domain ID, e.g. ED_EMAIL.
Definition node.h:69
const char * text
Node-specific text.
Definition node.h:73
enum ExpandoNodeType type
Type of Node, e.g. ENT_EXPANDO.
Definition node.h:68
void(* ndata_free)(void **ptr)
Function to free the private node data.
Definition node.h:78
struct ExpandoNodeArray children
Children nodes.
Definition node.h:75
Parsed Expando trees.
Definition expando.h:41
struct ExpandoNode * node
Parsed tree.
Definition expando.h:43
Private data for a Conditional Date -.
int count
Number of 'units' to count.
char period
Units, e.g. 'd' Day or 'm' Month.
Private data for a Padding Node -.
enum ExpandoPadType pad_type
Padding type.