NeoMutt  2024-12-12-14-g7b49f7
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
node_condition.c File Reference

Expando Node for a Condition. More...

#include "config.h"
#include <stdbool.h>
#include <stdio.h>
#include "mutt/lib.h"
#include "node_condition.h"
#include "definition.h"
#include "format.h"
#include "helpers.h"
#include "node.h"
#include "node_condbool.h"
#include "node_container.h"
#include "node_expando.h"
#include "node_text.h"
#include "parse.h"
#include "render.h"
+ Include dependency graph for node_condition.c:

Go to the source code of this file.

Functions

static int node_condition_render (const struct ExpandoNode *node, const struct ExpandoRenderCallback *erc, struct Buffer *buf, int max_cols, void *data, MuttFormatFlags flags)
 Render a Conditional Node - Implements ExpandoNode::render() -.
 
struct ExpandoNodenode_condition_new (struct ExpandoNode *node_cond, struct ExpandoNode *node_true, struct ExpandoNode *node_false, struct ExpandoFormat *fmt)
 Create a new Condition Expando Node.
 
struct ExpandoNodenode_condition_parse (const char *str, NodeTextTermFlags term_chars, const struct ExpandoDefinition *defs, const char **parsed_until, struct ExpandoParseError *err)
 Parse a conditional Expando.
 

Detailed Description

Expando Node for a Condition.

Authors
  • Tóth János
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file node_condition.c.

Function Documentation

◆ node_condition_new()

struct ExpandoNode * node_condition_new ( struct ExpandoNode node_cond,
struct ExpandoNode node_true,
struct ExpandoNode node_false,
struct ExpandoFormat fmt 
)

Create a new Condition Expando Node.

Parameters
node_condExpando Node that will be tested
node_trueNode tree for the 'true' case
node_falseNode tree for the 'false' case
fmtFormatting info
Return values
ptrNew Condition Expando Node

Definition at line 110 of file node_condition.c.

114{
115 ASSERT(node_cond);
116
117 struct ExpandoNode *node = node_new();
118
119 node->type = ENT_CONDITION;
121
122 ARRAY_SET(&node->children, ENC_CONDITION, node_cond);
123 ARRAY_SET(&node->children, ENC_TRUE, node_true);
124 ARRAY_SET(&node->children, ENC_FALSE, node_false);
125
126 node->format = fmt;
127
128 return node;
129}
#define ARRAY_SET(head, idx, elem)
Set an element in the array.
Definition: array.h:123
static int node_condition_render(const struct ExpandoNode *node, const struct ExpandoRenderCallback *erc, struct Buffer *buf, int max_cols, void *data, MuttFormatFlags flags)
Render a Conditional Node - Implements ExpandoNode::render() -.
struct ExpandoNode * node_new(void)
Create a new empty ExpandoNode.
Definition: node.c:39
@ ENT_CONDITION
True/False condition.
Definition: node.h:41
@ ENC_CONDITION
Index of Condition Node.
@ ENC_FALSE
Index of False Node.
@ ENC_TRUE
Index of True Node.
#define ASSERT(COND)
Definition: signal2.h:58
Basic Expando Node.
Definition: node.h:67
struct ExpandoFormat * format
Formatting info.
Definition: node.h:72
int(* render)(const struct ExpandoNode *node, const struct ExpandoRenderCallback *erc, struct Buffer *buf, int max_cols, void *data, MuttFormatFlags flags)
Definition: node.h:92
enum ExpandoNodeType type
Type of Node, e.g. ENT_EXPANDO.
Definition: node.h:68
struct ExpandoNodeArray children
Children nodes.
Definition: node.h:75
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ node_condition_parse()

struct ExpandoNode * node_condition_parse ( const char *  str,
NodeTextTermFlags  term_chars,
const struct ExpandoDefinition defs,
const char **  parsed_until,
struct ExpandoParseError err 
)

Parse a conditional Expando.

Parameters
[in]strString to parse
[in]term_charsTerminator characters, e.g. NTE_GREATER
[in]defsExpando definitions
[out]parsed_untilFirst character after parsed string
[out]errBuffer for errors
Return values
ptrExpando Node

Definition at line 140 of file node_condition.c.

144{
145 if (!str || (str[0] != '%'))
146 return NULL;
147
148 str++; // Skip %
149
150 struct ExpandoFormat *fmt = NULL;
151 struct ExpandoNode *node_cond = NULL;
152 struct ExpandoNode *node_true = NULL;
153 struct ExpandoNode *node_false = NULL;
154
155 //----------------------------------------------------------------------------
156 // Parse the format (optional)
157 fmt = parse_format(str, parsed_until, err);
158 if (err->position)
159 goto fail;
160
161 str = *parsed_until;
162
163 if ((str[0] != '<') && (str[0] != '?'))
164 goto fail;
165
166 const bool old_style = (str[0] == '?'); // %?X?...&...?
167 str++;
168
169 //----------------------------------------------------------------------------
170 // Parse the condition
171 node_cond = parse_short_name(str, defs, EP_CONDITIONAL, NULL, parsed_until, err);
172 if (!node_cond)
173 goto fail;
174
175 if (node_cond->type == ENT_EXPANDO)
176 {
177 node_cond->type = ENT_CONDBOOL;
178 node_cond->render = node_condbool_render;
179 }
180
181 str = *parsed_until; // Skip the expando
182 if (str[0] != '?')
183 {
184 err->position = str;
185 snprintf(err->message, sizeof(err->message),
186 // L10N: Expando is missing a terminator character
187 // e.g. "%[..." is missing the final ']'
188 _("Conditional expando is missing '%c'"), '?');
189 goto fail;
190 }
191 str++; // Skip the '?'
192
193 //----------------------------------------------------------------------------
194 // Parse the 'true' clause (optional)
195 const NodeTextTermFlags term_true = term_chars | NTE_AMPERSAND |
196 (old_style ? NTE_QUESTION : NTE_GREATER);
197
198 node_true = node_container_new();
199 node_parse_many(node_true, str, term_true, defs, parsed_until, err);
200 if (err->position)
201 goto fail;
202
203 str = *parsed_until;
204
205 //----------------------------------------------------------------------------
206 // Parse the 'false' clause (optional)
207
208 node_false = NULL;
209 if (str[0] == '&')
210 {
211 str++;
212 const NodeTextTermFlags term_false = term_chars | (old_style ? NTE_QUESTION : NTE_GREATER);
213
214 node_false = node_container_new();
215 node_parse_many(node_false, str, term_false, defs, parsed_until, err);
216 if (err->position)
217 goto fail;
218
219 str = *parsed_until;
220 }
221
222 //----------------------------------------------------------------------------
223 // Check for the terminator character
224 const char terminator = old_style ? '?' : '>';
225
226 if (str[0] != terminator)
227 {
228 err->position = str;
229 snprintf(err->message, sizeof(err->message),
230 // L10N: Expando is missing a terminator character
231 // e.g. "%[..." is missing the final ']'
232 _("Conditional expando is missing '%c'"), '?');
233 goto fail;
234 }
235
236 *parsed_until = str + 1;
237
238 return node_condition_new(node_cond, node_true, node_false, fmt);
239
240fail:
241 FREE(&fmt);
242 node_free(&node_cond);
243 node_free(&node_true);
244 node_free(&node_false);
245 return NULL;
246}
#define EP_CONDITIONAL
Expando is being used as a condition.
Definition: definition.h:35
bool node_parse_many(struct ExpandoNode *node_cont, const char *str, NodeTextTermFlags term_chars, const struct ExpandoDefinition *defs, const char **parsed_until, struct ExpandoParseError *err)
Parse a format string.
Definition: parse.c:81
int node_condbool_render(const struct ExpandoNode *node, const struct ExpandoRenderCallback *erc, struct Buffer *buf, int max_cols, void *data, MuttFormatFlags flags)
Callback for every bool node - Implements ExpandoNode::render() -.
Definition: node_condbool.c:41
#define FREE(x)
Definition: memory.h:55
#define _(a)
Definition: message.h:28
void node_free(struct ExpandoNode **ptr)
Free an ExpandoNode and its private data.
Definition: node.c:48
@ ENT_EXPANDO
Expando, e.g. 'n'.
Definition: node.h:39
@ ENT_CONDBOOL
True/False boolean condition.
Definition: node.h:42
struct ExpandoNode * node_condition_new(struct ExpandoNode *node_cond, struct ExpandoNode *node_true, struct ExpandoNode *node_false, struct ExpandoFormat *fmt)
Create a new Condition Expando Node.
struct ExpandoNode * node_container_new(void)
Create a new Container ExpandoNode.
struct ExpandoNode * parse_short_name(const char *str, const struct ExpandoDefinition *defs, ExpandoParserFlags flags, struct ExpandoFormat *fmt, const char **parsed_until, struct ExpandoParseError *err)
Create an expando by its short name.
Definition: node_expando.c:245
struct ExpandoFormat * parse_format(const char *str, const char **parsed_until, struct ExpandoParseError *err)
Parse a format string.
Definition: node_expando.c:136
#define NTE_QUESTION
'?' Question mark
Definition: node_text.h:36
#define NTE_GREATER
'>' Greater than
Definition: node_text.h:35
uint8_t NodeTextTermFlags
Special characters that end a text string.
Definition: node_text.h:32
#define NTE_AMPERSAND
'&' Ampersand
Definition: node_text.h:34
Formatting information for an Expando.
Definition: node.h:53
char message[1024]
Error message.
Definition: parse.h:38
const char * position
Position of error in original string.
Definition: parse.h:39
+ Here is the call graph for this function:
+ Here is the caller graph for this function: