NeoMutt  2021-02-05
Teaching an old dog new tricks
DOXYGEN
string.c
Go to the documentation of this file.
1 
33 #include "config.h"
34 #include <stddef.h>
35 #include <limits.h>
36 #include <stdint.h>
37 #include "mutt/lib.h"
38 #include "set.h"
39 #include "types.h"
40 
44 static void string_destroy(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
45 {
46  const char **str = (const char **) var;
47  if (!*str)
48  return;
49 
50  /* Don't free strings from the var definition */
51  if (*(char **) var == (char *) cdef->initial)
52  {
53  *(char **) var = NULL;
54  return;
55  }
56 
57  FREE(var);
58 }
59 
63 static int string_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef,
64  const char *value, struct Buffer *err)
65 {
66  /* Store empty strings as NULL */
67  if (value && (value[0] == '\0'))
68  value = NULL;
69 
70  if (!value && (cdef->type & DT_NOT_EMPTY))
71  {
72  mutt_buffer_printf(err, _("Option %s may not be empty"), cdef->name);
74  }
75 
76  int rc = CSR_SUCCESS;
77 
78  if (var)
79  {
80  if (mutt_str_equal(value, (*(char **) var)))
82 
83  if (cdef->validator)
84  {
85  rc = cdef->validator(cs, cdef, (intptr_t) value, err);
86 
87  if (CSR_RESULT(rc) != CSR_SUCCESS)
88  return rc | CSR_INV_VALIDATOR;
89  }
90 
91  string_destroy(cs, var, cdef);
92 
93  const char *str = mutt_str_dup(value);
94  if (!str)
95  rc |= CSR_SUC_EMPTY;
96 
97  *(const char **) var = str;
98  }
99  else
100  {
101  /* we're already using the initial value */
102  if (*(char **) cdef->var == (char *) cdef->initial)
103  *(char **) cdef->var = mutt_str_dup((char *) cdef->initial);
104 
105  if (cdef->type & DT_INITIAL_SET)
106  FREE(&cdef->initial);
107 
108  cdef->type |= DT_INITIAL_SET;
109  cdef->initial = IP mutt_str_dup(value);
110  }
111 
112  return rc;
113 }
114 
118 static int string_string_get(const struct ConfigSet *cs, void *var,
119  const struct ConfigDef *cdef, struct Buffer *result)
120 {
121  const char *str = NULL;
122 
123  if (var)
124  str = *(const char **) var;
125  else
126  str = (char *) cdef->initial;
127 
128  if (!str)
129  return CSR_SUCCESS | CSR_SUC_EMPTY; /* empty string */
130 
131  mutt_buffer_addstr(result, str);
132  return CSR_SUCCESS;
133 }
134 
138 static int string_native_set(const struct ConfigSet *cs, void *var,
139  const struct ConfigDef *cdef, intptr_t value,
140  struct Buffer *err)
141 {
142  const char *str = (const char *) value;
143 
144  /* Store empty strings as NULL */
145  if (str && (str[0] == '\0'))
146  value = 0;
147 
148  if ((value == 0) && (cdef->type & DT_NOT_EMPTY))
149  {
150  mutt_buffer_printf(err, _("Option %s may not be empty"), cdef->name);
152  }
153 
154  if (mutt_str_equal((const char *) value, (*(char **) var)))
156 
157  int rc;
158 
159  if (cdef->validator)
160  {
161  rc = cdef->validator(cs, cdef, value, err);
162 
163  if (CSR_RESULT(rc) != CSR_SUCCESS)
164  return rc | CSR_INV_VALIDATOR;
165  }
166 
167  string_destroy(cs, var, cdef);
168 
169  str = mutt_str_dup(str);
170  rc = CSR_SUCCESS;
171  if (!str)
172  rc |= CSR_SUC_EMPTY;
173 
174  *(const char **) var = str;
175  return rc;
176 }
177 
181 static intptr_t string_native_get(const struct ConfigSet *cs, void *var,
182  const struct ConfigDef *cdef, struct Buffer *err)
183 {
184  const char *str = *(const char **) var;
185 
186  return (intptr_t) str;
187 }
188 
192 static int string_string_plus_equals(const struct ConfigSet *cs, void *var,
193  const struct ConfigDef *cdef,
194  const char *value, struct Buffer *err)
195 {
196  /* Skip if the value is missing or empty string*/
197  if (!value || (value && (value[0] == '\0')))
199 
200  int rc = CSR_SUCCESS;
201 
202  char *str = NULL;
203  const char **var_str = (const char **) var;
204 
205  if (*var_str)
206  mutt_str_asprintf(&str, "%s%s", *var_str, value);
207  else
208  str = mutt_str_dup(value);
209 
210  if (cdef->validator)
211  {
212  rc = cdef->validator(cs, cdef, (intptr_t) str, err);
213 
214  if (CSR_RESULT(rc) != CSR_SUCCESS)
215  {
216  FREE(&str);
217  return rc | CSR_INV_VALIDATOR;
218  }
219  }
220 
221  string_destroy(cs, var, cdef);
222  *var_str = str;
223 
224  return rc;
225 }
226 
230 static int string_reset(const struct ConfigSet *cs, void *var,
231  const struct ConfigDef *cdef, struct Buffer *err)
232 {
233  int rc = CSR_SUCCESS;
234 
235  const char *str = (const char *) cdef->initial;
236  if (!str)
237  rc |= CSR_SUC_EMPTY;
238 
239  if (mutt_str_equal(str, (*(char **) var)))
240  return rc | CSR_SUC_NO_CHANGE;
241 
242  if (cdef->validator)
243  {
244  rc = cdef->validator(cs, cdef, cdef->initial, err);
245 
246  if (CSR_RESULT(rc) != CSR_SUCCESS)
247  return rc | CSR_INV_VALIDATOR;
248  }
249 
250  string_destroy(cs, var, cdef);
251 
252  if (!str)
253  rc |= CSR_SUC_EMPTY;
254 
255  *(const char **) var = str;
256  return rc;
257 }
258 
262 const struct ConfigSetType cst_string = {
263  DT_STRING,
264  "string",
270  NULL, // string_minus_equals
271  string_reset,
273 };
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:871
static void string_destroy(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef)
Destroy a String - Implements ConfigSetType::destroy()
Definition: string.c:44
Type definition for a config item.
Definition: set.h:88
Container for lots of config items.
Definition: set.h:228
#define IP
Definition: set.h:54
#define CSR_ERR_INVALID
Value hasn&#39;t been set.
Definition: set.h:38
Constants for all the config types.
#define DT_NOT_EMPTY
Empty strings are not allowed.
Definition: types.h:46
static int string_string_plus_equals(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, const char *value, struct Buffer *err)
Concat String to a string - Implements ConfigSetType::string_plus_equals.
Definition: string.c:192
A collection of config items.
intptr_t initial
Initial value.
Definition: set.h:66
String manipulation buffer.
Definition: buffer.h:33
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:370
#define DT_INITIAL_SET
Config item must have its initial value freed.
Definition: types.h:81
#define _(a)
Definition: message.h:28
int mutt_buffer_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:160
Config item definition.
Definition: set.h:61
static int string_string_get(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *result)
Get a String as a string - Implements ConfigSetType::string_get()
Definition: string.c:118
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUC_EMPTY
Value is empty/unset.
Definition: set.h:42
#define CSR_SUC_NO_CHANGE
The value hasn&#39;t changed.
Definition: set.h:44
const char * name
User-visible name.
Definition: set.h:63
size_t mutt_buffer_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:225
#define DT_STRING
a string
Definition: types.h:41
int(* validator)(const struct ConfigSet *cs, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Validate a config variable.
Definition: set.h:78
static int string_reset(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Reset a String to its initial value - Implements ConfigSetType::reset()
Definition: string.c:230
static int string_string_set(const struct ConfigSet *cs, void *var, struct ConfigDef *cdef, const char *value, struct Buffer *err)
Set a String by string - Implements ConfigSetType::string_set()
Definition: string.c:63
uint32_t type
Variable type, e.g. DT_STRING.
Definition: set.h:64
static intptr_t string_native_get(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, struct Buffer *err)
Get a string from a String config item - Implements ConfigSetType::native_get()
Definition: string.c:181
void * var
Pointer to the global variable.
Definition: set.h:65
#define FREE(x)
Definition: memory.h:40
int mutt_str_asprintf(char **strp, const char *fmt,...)
Definition: string.c:1095
Convenience wrapper for the library headers.
#define CSR_INV_VALIDATOR
Value was rejected by the validator.
Definition: set.h:48
static int string_native_set(const struct ConfigSet *cs, void *var, const struct ConfigDef *cdef, intptr_t value, struct Buffer *err)
Set a String config item by string - Implements ConfigSetType::native_set()
Definition: string.c:138