NeoMutt  2024-04-25-1-g3de005
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
node_conddate.c
Go to the documentation of this file.
1
30#include "config.h"
31#include <assert.h>
32#include <ctype.h>
33#include <limits.h>
34#include <stdio.h>
35#include <string.h>
36#include <time.h>
37#include "mutt/lib.h"
38#include "node_conddate.h"
39#include "helpers.h"
40#include "node.h"
41#include "parse.h"
42#include "render.h"
43
51{
52 struct NodeCondDatePrivate *priv = mutt_mem_calloc(1, sizeof(struct NodeCondDatePrivate));
53
54 priv->count = count;
55 priv->period = period;
56
57 return priv;
58}
59
65{
66 if (!ptr || !*ptr)
67 return;
68
69 FREE(ptr);
70}
71
75int node_conddate_render(const struct ExpandoNode *node,
76 const struct ExpandoRenderData *rdata, struct Buffer *buf,
77 int max_cols, void *data, MuttFormatFlags flags)
78{
79 assert(node->type == ENT_CONDDATE);
80
81 const struct ExpandoRenderData *rd_match = find_get_number(rdata, node->did, node->uid);
82 assert(rd_match && "Unknown UID");
83
84 const long t_test = rd_match->get_number(node, data, flags);
85
86 const struct NodeCondDatePrivate *priv = node->ndata;
87
88 time_t t = mutt_date_now();
89 struct tm tm = { 0 };
90 gmtime_r(&t, &tm);
91
92 switch (priv->period)
93 {
94 case 'y':
95 tm.tm_year -= priv->count;
96 break;
97
98 case 'm':
99 tm.tm_mon -= priv->count;
100 break;
101
102 case 'w':
103 tm.tm_mday -= (7 * priv->count);
104 break;
105
106 case 'd':
107 tm.tm_mday -= priv->count;
108 break;
109
110 case 'H':
111 tm.tm_hour -= priv->count;
112 break;
113
114 case 'M':
115 tm.tm_min -= priv->count;
116 break;
117 }
118
119 const time_t t_cutoff = mktime(&tm);
120
121 return (t_test > t_cutoff); // bool-ify
122}
123
132struct ExpandoNode *node_conddate_new(int count, char period, int did, int uid)
133{
134 struct ExpandoNode *node = node_new();
135 node->type = ENT_CONDDATE;
136 node->did = did;
137 node->uid = uid;
139
140 node->ndata = node_conddate_private_new(count, period);
142
143 return node;
144}
145
149struct ExpandoNode *node_conddate_parse(const char *str, const char **parsed_until,
150 int did, int uid, struct ExpandoParseError *error)
151{
152 int count = 1;
153 char period = '\0';
154
155 if (isdigit(*str))
156 {
157 unsigned short number = 0;
158 const char *end_ptr = mutt_str_atous(str, &number);
159
160 // NOTE(g0mb4): str is NOT null-terminated
161 if (!end_ptr || (number == USHRT_MAX))
162 {
163 error->position = str;
164 snprintf(error->message, sizeof(error->message), _("Invalid number: %s"), str);
165 return NULL;
166 }
167
168 count = number;
169 str = end_ptr;
170 };
171
172 // Allowed periods: year, month, week, day, hour, minute
173 if (!strchr("ymwdHM", *str))
174 {
175 error->position = str;
176 snprintf(error->message, sizeof(error->message),
177 // L10N: The 'ymwdHM' should not be translated
178 _("Invalid time period: '%c', must be one of 'ymwdHM'"), *str);
179 return NULL;
180 }
181
182 period = *str;
183 *parsed_until = str + 1;
184
185 return node_conddate_new(count, period, did, uid);
186}
const char * mutt_str_atous(const char *str, unsigned short *dst)
Convert ASCII string to an unsigned short.
Definition: atoi.c:266
const struct ExpandoRenderData * find_get_number(const struct ExpandoRenderData *rdata, int did, int uid)
Find a get_number() callback function.
Definition: helpers.c:48
Shared code.
Expando Parsing.
struct ExpandoNode * node_conddate_parse(const char *str, const char **parsed_until, int did, int uid, struct ExpandoParseError *error)
Parse a CondDate format string - Implements ExpandoDefinition::parse() -.
int node_conddate_render(const struct ExpandoNode *node, const struct ExpandoRenderData *rdata, struct Buffer *buf, int max_cols, void *data, MuttFormatFlags flags)
Render a CondDate Node - Implements ExpandoNode::render() -.
Definition: node_conddate.c:75
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:50
#define FREE(x)
Definition: memory.h:45
time_t mutt_date_now(void)
Return the number of seconds since the Unix epoch.
Definition: date.c:455
Convenience wrapper for the library headers.
#define _(a)
Definition: message.h:28
struct ExpandoNode * node_new(void)
Create a new empty ExpandoNode.
Definition: node.c:39
Basic Expando Node.
@ ENT_CONDDATE
True/False date condition.
Definition: node.h:43
struct ExpandoNode * node_conddate_new(int count, char period, int did, int uid)
Create a new CondDate ExpandoNode.
struct NodeCondDatePrivate * node_conddate_private_new(int count, char period)
Create new CondDate private data.
Definition: node_conddate.c:50
void node_conddate_private_free(void **ptr)
Free CondDate private data - Implements ExpandoNode::ndata_free()
Definition: node_conddate.c:64
Expando Node for a Conditional Date.
Render Expandos using Data.
uint8_t MuttFormatFlags
Flags for expando_render(), e.g. MUTT_FORMAT_FORCESUBJ.
Definition: render.h:32
String manipulation buffer.
Definition: buffer.h:36
Basic Expando Node.
Definition: node.h:69
int uid
Unique ID, e.g. ED_EMA_SIZE.
Definition: node.h:73
int(* render)(const struct ExpandoNode *node, const struct ExpandoRenderData *rdata, struct Buffer *buf, int max_cols, void *data, MuttFormatFlags flags)
Definition: node.h:96
void * ndata
Private node data.
Definition: node.h:82
int did
Domain ID, e.g. ED_EMAIL.
Definition: node.h:72
enum ExpandoNodeType type
Type of Node, e.g. ENT_EXPANDO.
Definition: node.h:70
void(* ndata_free)(void **ptr)
Function to free the private node data.
Definition: node.h:83
Buffer for parsing errors.
Definition: parse.h:34
char message[128]
Error message.
Definition: parse.h:35
const char * position
Position of error in original string.
Definition: parse.h:36
long(* get_number)(const struct ExpandoNode *node, void *data, MuttFormatFlags flags)
Definition: render.h:79
Private data for a Conditional Date.
Definition: node_conddate.h:33
int count
Number of 'units' to count.
Definition: node_conddate.h:34
char period
Units, e.g. 'd' Day or 'm' Month.
Definition: node_conddate.h:35