NeoMutt  2024-03-23-23-gec7045
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
set.c File Reference

Parse the 'set' command. More...

#include "config.h"
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "mutt.h"
#include "set.h"
#include "commands.h"
#include "extract.h"
#include "globals.h"
#include "muttlib.h"
+ Include dependency graph for set.c:

Go to the source code of this file.

Functions

static void command_set_expand_value (uint32_t type, struct Buffer *value)
 Expand special characters.
 
static enum CommandResult command_set_set (struct Buffer *name, struct Buffer *value, struct Buffer *err)
 Set a variable to the given value.
 
static enum CommandResult command_set_increment (struct Buffer *name, struct Buffer *value, struct Buffer *err)
 Increment a variable by a value.
 
static enum CommandResult command_set_decrement (struct Buffer *name, struct Buffer *value, struct Buffer *err)
 Decrement a variable by a value.
 
static enum CommandResult command_set_unset (struct Buffer *name, struct Buffer *err)
 Unset a variable.
 
static enum CommandResult command_set_reset (struct Buffer *name, struct Buffer *err)
 Reset a variable.
 
static enum CommandResult command_set_toggle (struct Buffer *name, struct Buffer *err)
 Toggle a boolean or quad variable.
 
static enum CommandResult command_set_query (struct Buffer *name, struct Buffer *err)
 Query a variable.
 
enum CommandResult parse_set (struct Buffer *buf, struct Buffer *s, intptr_t data, struct Buffer *err)
 Parse the 'set' family of commands - Implements Command::parse() -.
 

Detailed Description

Parse the 'set' command.

Authors
  • Richard Russon
  • Dennis Schön
  • Rayford Shireman

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

Function Documentation

◆ command_set_expand_value()

static void command_set_expand_value ( uint32_t  type,
struct Buffer value 
)
static

Expand special characters.

Parameters
typeType of the value, see note below
[in,out]valueBuffer containing the value, will also contain the final result
Precondition
value is not NULL

Expand any special characters in paths, mailboxes or commands. e.g. ~ ($HOME), + ($folder)

The type influences which expansions are done.

Note
The type must be the full HashElem.type, not the sanitized DTYPE(HashElem.type)
The value is expanded in-place

Definition at line 60 of file set.c.

61{
62 assert(value);
63 if (DTYPE(type) == DT_PATH)
64 {
65 if (type & (D_PATH_DIR | D_PATH_FILE))
66 buf_expand_path(value);
67 else
69 }
70 else if (IS_MAILBOX(type))
71 {
72 buf_expand_path(value);
73 }
74 else if (IS_COMMAND(type))
75 {
76 struct Buffer *scratch = buf_pool_get();
77 buf_copy(scratch, value);
78
79 if (!mutt_str_equal(value->data, "builtin"))
80 {
81 buf_expand_path(scratch);
82 }
83 buf_reset(value);
84 buf_addstr(value, buf_string(scratch));
85 buf_pool_release(&scratch);
86 }
87}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:93
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:243
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:618
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:97
char * HomeDir
User's home directory.
Definition: globals.c:38
bool mutt_path_tilde(struct Buffer *path, const char *homedir)
Expand '~' in a path.
Definition: path.c:193
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:709
void buf_expand_path(struct Buffer *buf)
Create the canonical path.
Definition: muttlib.c:328
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
String manipulation buffer.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:37
#define IS_MAILBOX(flags)
Definition: types.h:120
#define DTYPE(t)
Definition: types.h:50
#define D_PATH_DIR
Path is a directory.
Definition: types.h:101
#define D_PATH_FILE
Path is a file.
Definition: types.h:102
@ DT_PATH
a path to a file/directory
Definition: types.h:40
#define IS_COMMAND(flags)
Definition: types.h:121
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ command_set_set()

static enum CommandResult command_set_set ( struct Buffer name,
struct Buffer value,
struct Buffer err 
)
static

Set a variable to the given value.

Parameters
[in]nameName of the config; must not be NULL
[in]valueValue the config should be set to
[out]errBuffer for error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS
Precondition
name is not NULL
value is not NULL

This implements "set foo = bar" command where "bar" is present.

Definition at line 101 of file set.c.

103{
104 assert(name);
105 assert(value);
106 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
107 if (!he)
108 {
109 // In case it is a my_var, we have to create it
110 if (mutt_str_startswith(name->data, "my_"))
111 {
112 struct ConfigDef my_cdef = { 0 };
113 my_cdef.name = name->data;
114 my_cdef.type = DT_MYVAR;
115 he = cs_create_variable(NeoMutt->sub->cs, &my_cdef, err);
116 if (!he)
117 return MUTT_CMD_ERROR;
118 }
119 else
120 {
121 buf_printf(err, _("Unknown option %s"), name->data);
122 return MUTT_CMD_ERROR;
123 }
124 }
125
126 int rc = CSR_ERR_CODE;
127
128 if (DTYPE(he->type) == DT_MYVAR)
129 {
130 // my variables do not expand their value
131 rc = cs_subset_he_string_set(NeoMutt->sub, he, value->data, err);
132 }
133 else
134 {
135 command_set_expand_value(he->type, value);
136 rc = cs_subset_he_string_set(NeoMutt->sub, he, value->data, err);
137 }
138 if (CSR_RESULT(rc) != CSR_SUCCESS)
139 return MUTT_CMD_ERROR;
140
141 return MUTT_CMD_SUCCESS;
142}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:178
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:39
@ MUTT_CMD_ERROR
Error: Can't help the user.
Definition: command.h:37
struct HashElem * cs_create_variable(const struct ConfigSet *cs, struct ConfigDef *cdef, struct Buffer *err)
Create and register one config item.
Definition: set.c:318
#define CSR_ERR_CODE
Problem with the code.
Definition: set.h:36
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define _(a)
Definition: message.h:28
size_t mutt_str_startswith(const char *str, const char *prefix)
Check whether a string starts with a prefix.
Definition: string.c:230
static void command_set_expand_value(uint32_t type, struct Buffer *value)
Expand special characters.
Definition: set.c:60
Definition: set.h:64
const char * name
User-visible name.
Definition: set.h:65
uint32_t type
Variable type, e.g. DT_STRING.
Definition: set.h:66
struct ConfigSet * cs
Parent ConfigSet.
Definition: subset.h:51
The item stored in a Hash Table.
Definition: hash.h:43
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:44
Container for Accounts, Notifications.
Definition: neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
int cs_subset_he_string_set(const struct ConfigSubset *sub, struct HashElem *he, const char *value, struct Buffer *err)
Set a config item by string.
Definition: subset.c:364
struct HashElem * cs_subset_lookup(const struct ConfigSubset *sub, const char *name)
Find an inherited config item.
Definition: subset.c:187
@ DT_MYVAR
a user-defined variable (my_foo)
Definition: types.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ command_set_increment()

static enum CommandResult command_set_increment ( struct Buffer name,
struct Buffer value,
struct Buffer err 
)
static

Increment a variable by a value.

Parameters
[in]nameName of the config; must not be NULL
[in]valueValue the config should be incremented by
[out]errBuffer for error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS
Precondition
name is not NULL
value is not NULL

This implements "set foo += bar" command where "bar" is present.

Definition at line 156 of file set.c.

158{
159 assert(name);
160 assert(value);
161 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
162 if (!he)
163 {
164 // In case it is a my_var, we have to create it
165 if (mutt_str_startswith(name->data, "my_"))
166 {
167 struct ConfigDef my_cdef = { 0 };
168 my_cdef.name = name->data;
169 my_cdef.type = DT_MYVAR;
170 he = cs_create_variable(NeoMutt->sub->cs, &my_cdef, err);
171 if (!he)
172 return MUTT_CMD_ERROR;
173 }
174 else
175 {
176 buf_printf(err, _("Unknown option %s"), name->data);
177 return MUTT_CMD_ERROR;
178 }
179 }
180
181 int rc = CSR_ERR_CODE;
182
183 if (DTYPE(he->type) == DT_MYVAR)
184 {
185 // my variables do not expand their value
186 rc = cs_subset_he_string_plus_equals(NeoMutt->sub, he, value->data, err);
187 }
188 else
189 {
190 command_set_expand_value(he->type, value);
191 rc = cs_subset_he_string_plus_equals(NeoMutt->sub, he, value->data, err);
192 }
193 if (CSR_RESULT(rc) != CSR_SUCCESS)
194 return MUTT_CMD_ERROR;
195
196 return MUTT_CMD_SUCCESS;
197}
int cs_subset_he_string_plus_equals(const struct ConfigSubset *sub, struct HashElem *he, const char *value, struct Buffer *err)
Add to a config item by string.
Definition: subset.c:402
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ command_set_decrement()

static enum CommandResult command_set_decrement ( struct Buffer name,
struct Buffer value,
struct Buffer err 
)
static

Decrement a variable by a value.

Parameters
[in]nameName of the config; must not be NULL
[in]valueValue the config should be decremented by
[out]errBuffer for error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS
Precondition
name is not NULL
value is not NULL

This implements "set foo -= bar" command where "bar" is present.

Definition at line 211 of file set.c.

213{
214 assert(name);
215 assert(value);
216 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
217 if (!he)
218 {
219 buf_printf(err, _("Unknown option %s"), name->data);
220 return MUTT_CMD_ERROR;
221 }
222
223 command_set_expand_value(he->type, value);
224 int rc = cs_subset_he_string_minus_equals(NeoMutt->sub, he, value->data, err);
225 if (CSR_RESULT(rc) != CSR_SUCCESS)
226 return MUTT_CMD_ERROR;
227
228 return MUTT_CMD_SUCCESS;
229}
int cs_subset_he_string_minus_equals(const struct ConfigSubset *sub, struct HashElem *he, const char *value, struct Buffer *err)
Remove from a config item by string.
Definition: subset.c:424
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ command_set_unset()

static enum CommandResult command_set_unset ( struct Buffer name,
struct Buffer err 
)
static

Unset a variable.

Parameters
[in]nameName of the config variable to be unset
[out]errBuffer for error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS
Precondition
name is not NULL

This implements "unset foo"

Definition at line 241 of file set.c.

242{
243 assert(name);
244 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
245 if (!he)
246 {
247 buf_printf(err, _("Unknown option %s"), name->data);
248 return MUTT_CMD_ERROR;
249 }
250
251 int rc = CSR_ERR_CODE;
252 if (DTYPE(he->type) == DT_MYVAR)
253 {
254 rc = cs_subset_he_delete(NeoMutt->sub, he, err);
255 }
256 else if ((DTYPE(he->type) == DT_BOOL) || (DTYPE(he->type) == DT_QUAD))
257 {
258 rc = cs_subset_he_native_set(NeoMutt->sub, he, false, err);
259 }
260 else
261 {
262 rc = cs_subset_he_string_set(NeoMutt->sub, he, NULL, err);
263 }
264 if (CSR_RESULT(rc) != CSR_SUCCESS)
265 return MUTT_CMD_ERROR;
266
267 return MUTT_CMD_SUCCESS;
268}
int cs_subset_he_native_set(const struct ConfigSubset *sub, struct HashElem *he, intptr_t value, struct Buffer *err)
Natively set the value of a HashElem config item.
Definition: subset.c:275
int cs_subset_he_delete(const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *err)
Delete config item from a config.
Definition: subset.c:445
@ DT_BOOL
boolean option
Definition: types.h:32
@ DT_QUAD
quad-option (no/yes/ask-no/ask-yes)
Definition: types.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ command_set_reset()

static enum CommandResult command_set_reset ( struct Buffer name,
struct Buffer err 
)
static

Reset a variable.

Parameters
[in]nameName of the config variable to be reset
[out]errBuffer for error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS
Precondition
name is not NULL

This implements "reset foo" (foo being any config variable) and "reset all".

Definition at line 280 of file set.c.

281{
282 assert(name);
283 // Handle special "reset all" syntax
284 if (mutt_str_equal(name->data, "all"))
285 {
286 struct HashElem **he_list = get_elem_list(NeoMutt->sub->cs);
287 if (!he_list)
288 return MUTT_CMD_ERROR;
289
290 for (size_t i = 0; he_list[i]; i++)
291 {
292 if (DTYPE(he_list[i]->type) == DT_MYVAR)
293 cs_subset_he_delete(NeoMutt->sub, he_list[i], err);
294 else
295 cs_subset_he_reset(NeoMutt->sub, he_list[i], NULL);
296 }
297
298 FREE(&he_list);
299 return MUTT_CMD_SUCCESS;
300 }
301
302 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
303 if (!he)
304 {
305 buf_printf(err, _("Unknown option %s"), name->data);
306 return MUTT_CMD_ERROR;
307 }
308
309 int rc = CSR_ERR_CODE;
310 if (DTYPE(he->type) == DT_MYVAR)
311 {
312 rc = cs_subset_he_delete(NeoMutt->sub, he, err);
313 }
314 else
315 {
316 rc = cs_subset_he_reset(NeoMutt->sub, he, err);
317 }
318 if (CSR_RESULT(rc) != CSR_SUCCESS)
319 return MUTT_CMD_ERROR;
320
321 return MUTT_CMD_SUCCESS;
322}
#define FREE(x)
Definition: memory.h:45
struct HashElem ** get_elem_list(struct ConfigSet *cs)
Create a sorted list of all config items.
Definition: subset.c:79
int cs_subset_he_reset(const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *err)
Reset a config item to its initial value.
Definition: subset.c:312
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ command_set_toggle()

static enum CommandResult command_set_toggle ( struct Buffer name,
struct Buffer err 
)
static

Toggle a boolean or quad variable.

Parameters
[in]nameName of the config variable to be toggled
[out]errBuffer for error messages
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS
Precondition
name is not NULL

This implements "toggle foo".

Definition at line 334 of file set.c.

335{
336 assert(name);
337 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
338 if (!he)
339 {
340 buf_printf(err, _("Unknown option %s"), name->data);
341 return MUTT_CMD_ERROR;
342 }
343
344 if (DTYPE(he->type) == DT_BOOL)
345 {
346 bool_he_toggle(NeoMutt->sub, he, err);
347 }
348 else if (DTYPE(he->type) == DT_QUAD)
349 {
350 quad_he_toggle(NeoMutt->sub, he, err);
351 }
352 else
353 {
354 buf_printf(err, _("Command '%s' can only be used with bool/quad variables"), "toggle");
355 return MUTT_CMD_ERROR;
356 }
357 return MUTT_CMD_SUCCESS;
358}
int bool_he_toggle(struct ConfigSubset *sub, struct HashElem *he, struct Buffer *err)
Toggle the value of a bool.
Definition: bool.c:196
int quad_he_toggle(struct ConfigSubset *sub, struct HashElem *he, struct Buffer *err)
Toggle the value of a quad.
Definition: quad.c:217
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ command_set_query()

static enum CommandResult command_set_query ( struct Buffer name,
struct Buffer err 
)
static

Query a variable.

Parameters
[in]nameName of the config variable to queried
[out]errBuffer where the pretty printed result will be written to. On failure contains the error message.
Return values
CommandResultResult e.g. MUTT_CMD_SUCCESS
Precondition
name is not NULL

This implements "set foo?". The buffer err will contain something like "set foo = bar".

Definition at line 370 of file set.c.

371{
372 assert(name);
373 // In the interactive case (outside of the initial parsing of neomuttrc) we
374 // support additional syntax: "set" (no arguments) and "set all".
375 // If not in interactive mode, we recognise them but do nothing.
376
377 // Handle "set" (no arguments), i.e. show list of changed variables.
378 if (buf_is_empty(name))
379 {
380 if (StartupComplete)
381 return set_dump(CS_DUMP_ONLY_CHANGED, err);
382 else
383 return MUTT_CMD_SUCCESS;
384 }
385 // Handle special "set all" syntax
386 if (mutt_str_equal(name->data, "all"))
387 {
388 if (StartupComplete)
389 return set_dump(CS_DUMP_NO_FLAGS, err);
390 else
391 return MUTT_CMD_SUCCESS;
392 }
393
394 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
395 if (!he)
396 {
397 buf_printf(err, _("Unknown option %s"), name->data);
398 return MUTT_CMD_ERROR;
399 }
400
401 buf_addstr(err, name->data);
402 buf_addch(err, '=');
403 struct Buffer *value = buf_pool_get();
404 int rc = cs_subset_he_string_get(NeoMutt->sub, he, value);
405 if (CSR_RESULT(rc) != CSR_SUCCESS)
406 {
407 buf_reset(err);
408 buf_addstr(err, value->data);
409 buf_pool_release(&value);
410 return MUTT_CMD_ERROR;
411 }
412 if (DTYPE(he->type) == DT_PATH)
413 mutt_pretty_mailbox(value->data, value->dsize);
414 pretty_var(value->data, err);
415 buf_pool_release(&value);
416
417 return MUTT_CMD_SUCCESS;
418}
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:308
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:258
enum CommandResult set_dump(ConfigDumpFlags flags, struct Buffer *err)
Dump list of config variables into a file/pager.
Definition: commands.c:853
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition: dump.c:85
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:475
#define CS_DUMP_ONLY_CHANGED
Only show config that the user has changed.
Definition: dump.h:36
#define CS_DUMP_NO_FLAGS
No flags are set.
Definition: dump.h:35
bool StartupComplete
When the config has been read.
Definition: main.c:191
size_t dsize
Length of data.
Definition: buffer.h:39
int cs_subset_he_string_get(const struct ConfigSubset *sub, struct HashElem *he, struct Buffer *result)
Get a config item as a string.
Definition: subset.c:332
+ Here is the call graph for this function:
+ Here is the caller graph for this function: