NeoMutt  2024-04-25-91-gb0e085
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 <ctype.h>
32#include <limits.h>
33#include <stdio.h>
34#include <string.h>
35#include <time.h>
36#include "mutt/lib.h"
37#include "node_conddate.h"
38#include "helpers.h"
39#include "node.h"
40#include "parse.h"
41#include "render.h"
42
50{
51 struct NodeCondDatePrivate *priv = mutt_mem_calloc(1, sizeof(struct NodeCondDatePrivate));
52
53 priv->count = count;
54 priv->period = period;
55
56 return priv;
57}
58
64{
65 if (!ptr || !*ptr)
66 return;
67
68 FREE(ptr);
69}
70
74int node_conddate_render(const struct ExpandoNode *node,
75 const struct ExpandoRenderData *rdata, struct Buffer *buf,
76 int max_cols, void *data, MuttFormatFlags flags)
77{
78 ASSERT(node->type == ENT_CONDDATE);
79
80 const struct ExpandoRenderData *rd_match = find_get_number(rdata, node->did, node->uid);
81 ASSERT(rd_match && "Unknown UID");
82
83 const long t_test = rd_match->get_number(node, data, flags);
84
85 const struct NodeCondDatePrivate *priv = node->ndata;
86
87 time_t t = mutt_date_now();
88 struct tm tm = { 0 };
89 gmtime_r(&t, &tm);
90
91 switch (priv->period)
92 {
93 case 'y':
94 tm.tm_year -= priv->count;
95 break;
96
97 case 'm':
98 tm.tm_mon -= priv->count;
99 break;
100
101 case 'w':
102 tm.tm_mday -= (7 * priv->count);
103 break;
104
105 case 'd':
106 tm.tm_mday -= priv->count;
107 break;
108
109 case 'H':
110 tm.tm_hour -= priv->count;
111 break;
112
113 case 'M':
114 tm.tm_min -= priv->count;
115 break;
116 }
117
118 const time_t t_cutoff = mktime(&tm);
119
120 return (t_test > t_cutoff); // bool-ify
121}
122
131struct ExpandoNode *node_conddate_new(int count, char period, int did, int uid)
132{
133 struct ExpandoNode *node = node_new();
134 node->type = ENT_CONDDATE;
135 node->did = did;
136 node->uid = uid;
138
139 node->ndata = node_conddate_private_new(count, period);
141
142 return node;
143}
144
148struct ExpandoNode *node_conddate_parse(const char *str, const char **parsed_until,
149 int did, int uid, struct ExpandoParseError *error)
150{
151 int count = 1;
152 char period = '\0';
153
154 if (isdigit(*str))
155 {
156 unsigned short number = 0;
157 const char *end_ptr = mutt_str_atous(str, &number);
158
159 // NOTE(g0mb4): str is NOT null-terminated
160 if (!end_ptr || (number == USHRT_MAX))
161 {
162 error->position = str;
163 snprintf(error->message, sizeof(error->message), _("Invalid number: %s"), str);
164 return NULL;
165 }
166
167 count = number;
168 str = end_ptr;
169 };
170
171 // Allowed periods: year, month, week, day, hour, minute
172 if (!strchr("ymwdHM", *str))
173 {
174 error->position = str;
175 snprintf(error->message, sizeof(error->message),
176 // L10N: The 'ymwdHM' should not be translated
177 _("Invalid time period: '%c', must be one of 'ymwdHM'"), *str);
178 return NULL;
179 }
180
181 period = *str;
182 *parsed_until = str + 1;
183
184 return node_conddate_new(count, period, did, uid);
185}
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:47
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:74
void * mutt_mem_calloc(size_t nmemb, size_t size)
Allocate zeroed memory on the heap.
Definition: memory.c:51
#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:456
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:49
void node_conddate_private_free(void **ptr)
Free CondDate private data - Implements ExpandoNode::ndata_free()
Definition: node_conddate.c:63
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
#define ASSERT(COND)
Definition: signal2.h:58
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
const char * position
Position of error in original string.
Definition: parse.h:36
char message[256]
Error message.
Definition: parse.h:35
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