NeoMutt  2024-10-02-37-gfa9146
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
node_expando.c File Reference

Expando Node for an Expando. More...

#include "config.h"
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include "mutt/lib.h"
#include "node_expando.h"
#include "color/lib.h"
#include "definition.h"
#include "format.h"
#include "helpers.h"
#include "mutt_thread.h"
#include "node.h"
#include "parse.h"
#include "render.h"
+ Include dependency graph for node_expando.c:

Go to the source code of this file.

Functions

struct NodeExpandoPrivatenode_expando_private_new (void)
 Create new Expando private data.
 
void node_expando_private_free (void **ptr)
 Free Expando private data - Implements ExpandoNode::ndata_free()
 
struct ExpandoNodenode_expando_new (struct ExpandoFormat *fmt, int did, int uid)
 Create a new Expando ExpandoNode.
 
void node_expando_set_color (const struct ExpandoNode *node, int cid)
 Set the colour for an Expando.
 
void node_expando_set_has_tree (const struct ExpandoNode *node, bool has_tree)
 Set the has_tree flag for an Expando.
 
struct ExpandoFormatparse_format (const char *start, const char *end, struct ExpandoParseError *err)
 Parse a format string.
 
struct ExpandoNodenode_expando_parse (const char *str, const struct ExpandoDefinition *defs, ExpandoParserFlags flags, const char **parsed_until, struct ExpandoParseError *err)
 Parse an Expando format string.
 
struct ExpandoNodenode_expando_parse_enclosure (const char *str, int did, int uid, char terminator, const char **parsed_until, struct ExpandoParseError *err)
 Parse an enclosed Expando.
 
void add_color (struct Buffer *buf, enum ColorId cid)
 Add a colour code to a buffer.
 
int node_expando_render (const struct ExpandoNode *node, const struct ExpandoRenderData *rdata, struct Buffer *buf, int max_cols, void *data, MuttFormatFlags flags)
 Render an Expando Node - Implements ExpandoNode::render() -.
 

Detailed Description

Expando Node for an Expando.

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_expando.c.

Function Documentation

◆ node_expando_private_new()

struct NodeExpandoPrivate * node_expando_private_new ( void  )

Create new Expando private data.

Return values
ptrNew Expando private data

Definition at line 49 of file node_expando.c.

50{
51 struct NodeExpandoPrivate *priv = mutt_mem_calloc(1, sizeof(struct NodeExpandoPrivate));
52
53 // NOTE(g0mb4): Expando definition should contain this
54 priv->color = -1;
55
56 return priv;
57}
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
Private data for an Expando -.
Definition: node_expando.h:40
int color
ColorId to use.
Definition: node_expando.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ node_expando_private_free()

void node_expando_private_free ( void **  ptr)

Free Expando private data - Implements ExpandoNode::ndata_free()

Parameters
ptrData to free

Definition at line 63 of file node_expando.c.

64{
65 if (!ptr || !*ptr)
66 return;
67
68 FREE(ptr);
69}
#define FREE(x)
Definition: memory.h:45
+ Here is the caller graph for this function:

◆ node_expando_new()

struct ExpandoNode * node_expando_new ( struct ExpandoFormat fmt,
int  did,
int  uid 
)

Create a new Expando ExpandoNode.

Parameters
fmtFormatting data
didDomain ID
uidUnique ID
Return values
ptrNew Expando ExpandoNode

Definition at line 78 of file node_expando.c.

79{
80 struct ExpandoNode *node = node_new();
81
82 node->type = ENT_EXPANDO;
83 node->did = did;
84 node->uid = uid;
86
87 node->format = fmt;
88
91
92 return node;
93}
int node_expando_render(const struct ExpandoNode *node, const struct ExpandoRenderData *rdata, struct Buffer *buf, int max_cols, void *data, MuttFormatFlags flags)
Render an Expando Node - Implements ExpandoNode::render() -.
Definition: node_expando.c:336
struct ExpandoNode * node_new(void)
Create a new empty ExpandoNode.
Definition: node.c:39
@ ENT_EXPANDO
Expando, e.g. 'n'.
Definition: node.h:39
void node_expando_private_free(void **ptr)
Free Expando private data - Implements ExpandoNode::ndata_free()
Definition: node_expando.c:63
struct NodeExpandoPrivate * node_expando_private_new(void)
Create new Expando private data.
Definition: node_expando.c:49
Basic Expando Node.
Definition: node.h:67
int uid
Unique ID, e.g. ED_EMA_SIZE.
Definition: node.h:70
int(* render)(const struct ExpandoNode *node, const struct ExpandoRenderData *rdata, struct Buffer *buf, int max_cols, void *data, MuttFormatFlags flags)
Definition: node.h:91
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
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
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ node_expando_set_color()

void node_expando_set_color ( const struct ExpandoNode node,
int  cid 
)

Set the colour for an Expando.

Parameters
nodeNode to alter
cidColour

Definition at line 100 of file node_expando.c.

101{
102 if (!node || (node->type != ENT_EXPANDO) || !node->ndata)
103 return;
104
105 struct NodeExpandoPrivate *priv = node->ndata;
106
107 priv->color = cid;
108}
+ Here is the caller graph for this function:

◆ node_expando_set_has_tree()

void node_expando_set_has_tree ( const struct ExpandoNode node,
bool  has_tree 
)

Set the has_tree flag for an Expando.

Parameters
nodeNode to alter
has_treeFlag to set

Definition at line 115 of file node_expando.c.

116{
117 if (!node || (node->type != ENT_EXPANDO) || !node->ndata)
118 return;
119
120 struct NodeExpandoPrivate *priv = node->ndata;
121
122 priv->has_tree = has_tree;
123}
bool has_tree
Contains tree characters, used in $index_format's s.
Definition: node_expando.h:42
+ Here is the caller graph for this function:

◆ parse_format()

struct ExpandoFormat * parse_format ( const char *  start,
const char *  end,
struct ExpandoParseError err 
)

Parse a format string.

Parameters
startStart of string
endEnd of string
errBuffer for errors
Return values
ptrNew ExpandoFormat object

Parse a printf()-style format, e.g. '-15.20x'

Definition at line 134 of file node_expando.c.

136{
137 if (start == end)
138 return NULL;
139
140 struct ExpandoFormat *fmt = mutt_mem_calloc(1, sizeof(struct ExpandoFormat));
141
142 fmt->leader = ' ';
144 fmt->min_cols = 0;
145 fmt->max_cols = INT_MAX;
146
147 if (*start == '-')
148 {
150 start++;
151 }
152 else if (*start == '=')
153 {
155 start++;
156 }
157
158 if (*start == '0')
159 {
160 fmt->leader = '0';
161 start++;
162 }
163
164 if (isdigit(*start))
165 {
166 unsigned short number = 0;
167 const char *end_ptr = mutt_str_atous(start, &number);
168
169 // NOTE(g0mb4): start is NOT null-terminated
170 if (!end_ptr || (end_ptr > end) || (number == USHRT_MAX))
171 {
172 err->position = start;
173 snprintf(err->message, sizeof(err->message), _("Invalid number: %s"), start);
174 FREE(&fmt);
175 return NULL;
176 }
177
178 fmt->min_cols = number;
179 start = end_ptr;
180 };
181
182 if (*start == '.')
183 {
184 start++;
185
186 if (!isdigit(*start))
187 {
188 err->position = start;
189 // L10N: Expando format expected a number
190 snprintf(err->message, sizeof(err->message), _("Number is expected"));
191 FREE(&fmt);
192 return NULL;
193 }
194
195 unsigned short number = 0;
196 const char *end_ptr = mutt_str_atous(start, &number);
197
198 // NOTE(g0mb4): start is NOT null-terminated
199 if (!end_ptr || (end_ptr > end) || (number == USHRT_MAX))
200 {
201 err->position = start;
202 snprintf(err->message, sizeof(err->message), _("Invalid number: %s"), start);
203 FREE(&fmt);
204 return NULL;
205 }
206
207 fmt->max_cols = number;
208 start = end_ptr;
209 }
210
211 if (*start == '_')
212 {
213 fmt->lower = true;
214 start++;
215 }
216
217 return fmt;
218}
const char * mutt_str_atous(const char *str, unsigned short *dst)
Convert ASCII string to an unsigned short.
Definition: atoi.c:266
@ JUSTIFY_RIGHT
Right justify the text.
Definition: format.h:36
@ JUSTIFY_LEFT
Left justify the text.
Definition: format.h:34
@ JUSTIFY_CENTER
Centre the text.
Definition: format.h:35
#define _(a)
Definition: message.h:28
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
bool lower
Display in lower case.
Definition: node.h:58
const char * position
Position of error in original string.
Definition: parse.h:37
char message[256]
Error message.
Definition: parse.h:36
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ node_expando_parse()

struct ExpandoNode * node_expando_parse ( const char *  str,
const struct ExpandoDefinition defs,
ExpandoParserFlags  flags,
const char **  parsed_until,
struct ExpandoParseError err 
)

Parse an Expando format string.

Parameters
[in]strString to parse
[in]defsExpando definitions
[in]flagsFlag for conditional expandos
[out]parsed_untilFirst character after parsed string
[out]errBuffer for errors
Return values
ptrNew ExpandoNode

Definition at line 229 of file node_expando.c.

232{
233 const struct ExpandoDefinition *def = defs;
234
235 const char *format_end = skip_until_classic_expando(str);
236 const char *expando_end = skip_classic_expando(format_end, defs);
237 char expando[128] = { 0 };
238 const int expando_len = expando_end - format_end;
239 mutt_strn_copy(expando, format_end, expando_len, sizeof(expando));
240
241 struct ExpandoFormat *fmt = parse_format(str, format_end, err);
242 if (err->position)
243 {
244 FREE(&fmt);
245 return NULL;
246 }
247
248 while (def && def->short_name)
249 {
250 if (mutt_str_equal(def->short_name, expando))
251 {
252 if (def->parse && !(flags & EP_NO_CUSTOM_PARSE))
253 {
254 FREE(&fmt);
255 return def->parse(str, def->did, def->uid, flags, parsed_until, err);
256 }
257 else
258 {
259 *parsed_until = expando_end;
260 return node_expando_new(fmt, def->did, def->uid);
261 }
262 }
263
264 def++;
265 }
266
267 err->position = format_end;
268 // L10N: e.g. "Unknown expando: %Q"
269 snprintf(err->message, sizeof(err->message), _("Unknown expando: %%%.*s"),
270 expando_len, format_end);
271 FREE(&fmt);
272 return NULL;
273}
#define EP_NO_CUSTOM_PARSE
Don't use the custom parser.
Definition: definition.h:44
const char * skip_classic_expando(const char *str, const struct ExpandoDefinition *defs)
Skip over the text of an Expando.
Definition: helpers.c:144
const char * skip_until_classic_expando(const char *start)
Search through string until we reach an Expando character.
Definition: helpers.c:128
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:660
char * mutt_strn_copy(char *dest, const char *src, size_t len, size_t dsize)
Copy a sub-string into a buffer.
Definition: string.c:360
struct ExpandoFormat * parse_format(const char *start, const char *end, struct ExpandoParseError *err)
Parse a format string.
Definition: node_expando.c:134
struct ExpandoNode * node_expando_new(struct ExpandoFormat *fmt, int did, int uid)
Create a new Expando ExpandoNode.
Definition: node_expando.c:78
Definition of a format string.
Definition: definition.h:52
short uid
Unique ID in domain.
Definition: definition.h:56
struct ExpandoNode *(* parse)(const char *str, int did, int uid, ExpandoParserFlags flags, const char **parsed_until, struct ExpandoParseError *err)
Definition: definition.h:71
short did
Domain ID.
Definition: definition.h:55
const char * short_name
Short Expando name, e.g. "n".
Definition: definition.h:53
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ node_expando_parse_enclosure()

struct ExpandoNode * node_expando_parse_enclosure ( const char *  str,
int  did,
int  uid,
char  terminator,
const char **  parsed_until,
struct ExpandoParseError err 
)

Parse an enclosed Expando.

Parameters
strString to parse
didDomain ID
uidUnique ID
terminatorTerminating character
parsed_untilFirst character after the parsed string
errBuffer for errors
Return values
ptrNew ExpandoNode

Definition at line 285 of file node_expando.c.

288{
289 const char *format_end = skip_until_classic_expando(str);
290
291 format_end++; // skip opening char
292
293 const char *expando_end = skip_until_ch(format_end, terminator);
294
295 if (*expando_end != terminator)
296 {
297 err->position = expando_end;
298 snprintf(err->message, sizeof(err->message),
299 // L10N: Expando is missing a terminator character
300 // e.g. "%[..." is missing the final ']'
301 _("Expando is missing terminator: '%c'"), terminator);
302 return NULL;
303 }
304
305 // revert skipping for fmt
306 struct ExpandoFormat *fmt = parse_format(str, format_end - 1, err);
307 if (err->position)
308 {
309 FREE(&fmt);
310 return NULL;
311 }
312
313 *parsed_until = expando_end + 1;
314
315 struct ExpandoNode *node = node_expando_new(fmt, did, uid);
316 node->text = mutt_strn_dup(format_end, expando_end - format_end);
317 return node;
318}
const char * skip_until_ch(const char *start, char terminator)
Search a string for a terminator character.
Definition: helpers.c:94
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:380
const char * text
Node-specific text.
Definition: node.h:73
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ add_color()

void add_color ( struct Buffer buf,
enum ColorId  cid 
)

Add a colour code to a buffer.

Parameters
bufBuffer for colour code
cidColour

Definition at line 325 of file node_expando.c.

326{
327 ASSERT(cid < MT_COLOR_MAX);
328
330 buf_addch(buf, cid);
331}
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:241
@ MT_COLOR_MAX
Definition: color.h:94
@ MUTT_SPECIAL_INDEX
Colour indicator.
Definition: mutt_thread.h:73
#define ASSERT(COND)
Definition: signal2.h:58
+ Here is the call graph for this function:
+ Here is the caller graph for this function: