NeoMutt  2024-04-25-76-g20fe7b
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
set.c File Reference

Parse the 'set' command. More...

#include "config.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 59 of file set.c.

60{
61 ASSERT(value);
62 if (DTYPE(type) == DT_PATH)
63 {
64 if (type & (D_PATH_DIR | D_PATH_FILE))
65 buf_expand_path(value);
66 else
68 }
69 else if (IS_MAILBOX(type))
70 {
71 buf_expand_path(value);
72 }
73 else if (IS_COMMAND(type))
74 {
75 struct Buffer *scratch = buf_pool_get();
76 buf_copy(scratch, value);
77
78 if (!mutt_str_equal(value->data, "builtin"))
79 {
80 buf_expand_path(scratch);
81 }
82 buf_reset(value);
83 buf_addstr(value, buf_string(scratch));
84 buf_pool_release(&scratch);
85 }
86}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:76
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:226
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
Definition: buffer.c:601
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:96
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:194
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:660
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
#define ASSERT(COND)
Definition: signal2.h:58
String manipulation buffer.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:37
#define IS_MAILBOX(flags)
Definition: types.h:122
#define DTYPE(t)
Definition: types.h:50
#define D_PATH_DIR
Path is a directory.
Definition: types.h:103
#define D_PATH_FILE
Path is a file.
Definition: types.h:104
@ DT_PATH
a path to a file/directory
Definition: types.h:40
#define IS_COMMAND(flags)
Definition: types.h:123
+ 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 100 of file set.c.

102{
103 ASSERT(name);
104 ASSERT(value);
105 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
106 if (!he)
107 {
108 // In case it is a my_var, we have to create it
109 if (mutt_str_startswith(name->data, "my_"))
110 {
111 struct ConfigDef my_cdef = { 0 };
112 my_cdef.name = name->data;
113 my_cdef.type = DT_MYVAR;
114 he = cs_create_variable(NeoMutt->sub->cs, &my_cdef, err);
115 if (!he)
116 return MUTT_CMD_ERROR;
117 }
118 else
119 {
120 buf_printf(err, _("Unknown option %s"), name->data);
121 return MUTT_CMD_ERROR;
122 }
123 }
124
125 int rc = CSR_ERR_CODE;
126
127 if (DTYPE(he->type) == DT_MYVAR)
128 {
129 // my variables do not expand their value
130 rc = cs_subset_he_string_set(NeoMutt->sub, he, value->data, err);
131 }
132 else
133 {
134 command_set_expand_value(he->type, value);
135 rc = cs_subset_he_string_set(NeoMutt->sub, he, value->data, err);
136 }
137 if (CSR_RESULT(rc) != CSR_SUCCESS)
138 return MUTT_CMD_ERROR;
139
140 return MUTT_CMD_SUCCESS;
141}
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:161
@ 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:59
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:42
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:46
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 155 of file set.c.

157{
158 ASSERT(name);
159 ASSERT(value);
160 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
161 if (!he)
162 {
163 // In case it is a my_var, we have to create it
164 if (mutt_str_startswith(name->data, "my_"))
165 {
166 struct ConfigDef my_cdef = { 0 };
167 my_cdef.name = name->data;
168 my_cdef.type = DT_MYVAR;
169 he = cs_create_variable(NeoMutt->sub->cs, &my_cdef, err);
170 if (!he)
171 return MUTT_CMD_ERROR;
172 }
173 else
174 {
175 buf_printf(err, _("Unknown option %s"), name->data);
176 return MUTT_CMD_ERROR;
177 }
178 }
179
180 int rc = CSR_ERR_CODE;
181
182 if (DTYPE(he->type) == DT_MYVAR)
183 {
184 // my variables do not expand their value
185 rc = cs_subset_he_string_plus_equals(NeoMutt->sub, he, value->data, err);
186 }
187 else
188 {
189 command_set_expand_value(he->type, value);
190 rc = cs_subset_he_string_plus_equals(NeoMutt->sub, he, value->data, err);
191 }
192 if (CSR_RESULT(rc) != CSR_SUCCESS)
193 return MUTT_CMD_ERROR;
194
195 return MUTT_CMD_SUCCESS;
196}
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 210 of file set.c.

212{
213 ASSERT(name);
214 ASSERT(value);
215 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
216 if (!he)
217 {
218 buf_printf(err, _("Unknown option %s"), name->data);
219 return MUTT_CMD_ERROR;
220 }
221
222 command_set_expand_value(he->type, value);
223 int rc = cs_subset_he_string_minus_equals(NeoMutt->sub, he, value->data, err);
224 if (CSR_RESULT(rc) != CSR_SUCCESS)
225 return MUTT_CMD_ERROR;
226
227 return MUTT_CMD_SUCCESS;
228}
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 240 of file set.c.

241{
242 ASSERT(name);
243 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
244 if (!he)
245 {
246 buf_printf(err, _("Unknown option %s"), name->data);
247 return MUTT_CMD_ERROR;
248 }
249
250 int rc = CSR_ERR_CODE;
251 if (DTYPE(he->type) == DT_MYVAR)
252 {
253 rc = cs_subset_he_delete(NeoMutt->sub, he, err);
254 }
255 else if ((DTYPE(he->type) == DT_BOOL) || (DTYPE(he->type) == DT_QUAD))
256 {
257 rc = cs_subset_he_native_set(NeoMutt->sub, he, false, err);
258 }
259 else
260 {
261 rc = cs_subset_he_string_set(NeoMutt->sub, he, NULL, err);
262 }
263 if (CSR_RESULT(rc) != CSR_SUCCESS)
264 return MUTT_CMD_ERROR;
265
266 return MUTT_CMD_SUCCESS;
267}
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 279 of file set.c.

280{
281 ASSERT(name);
282 // Handle special "reset all" syntax
283 if (mutt_str_equal(name->data, "all"))
284 {
285 struct HashElem **he_list = get_elem_list(NeoMutt->sub->cs);
286 if (!he_list)
287 return MUTT_CMD_ERROR;
288
289 for (size_t i = 0; he_list[i]; i++)
290 {
291 if (DTYPE(he_list[i]->type) == DT_MYVAR)
292 cs_subset_he_delete(NeoMutt->sub, he_list[i], err);
293 else
294 cs_subset_he_reset(NeoMutt->sub, he_list[i], NULL);
295 }
296
297 FREE(&he_list);
298 return MUTT_CMD_SUCCESS;
299 }
300
301 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
302 if (!he)
303 {
304 buf_printf(err, _("Unknown option %s"), name->data);
305 return MUTT_CMD_ERROR;
306 }
307
308 int rc = CSR_ERR_CODE;
309 if (DTYPE(he->type) == DT_MYVAR)
310 {
311 rc = cs_subset_he_delete(NeoMutt->sub, he, err);
312 }
313 else
314 {
315 rc = cs_subset_he_reset(NeoMutt->sub, he, err);
316 }
317 if (CSR_RESULT(rc) != CSR_SUCCESS)
318 return MUTT_CMD_ERROR;
319
320 return MUTT_CMD_SUCCESS;
321}
#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 333 of file set.c.

334{
335 ASSERT(name);
336 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
337 if (!he)
338 {
339 buf_printf(err, _("Unknown option %s"), name->data);
340 return MUTT_CMD_ERROR;
341 }
342
343 if (DTYPE(he->type) == DT_BOOL)
344 {
345 bool_he_toggle(NeoMutt->sub, he, err);
346 }
347 else if (DTYPE(he->type) == DT_QUAD)
348 {
349 quad_he_toggle(NeoMutt->sub, he, err);
350 }
351 else
352 {
353 buf_printf(err, _("Command '%s' can only be used with bool/quad variables"), "toggle");
354 return MUTT_CMD_ERROR;
355 }
356 return MUTT_CMD_SUCCESS;
357}
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 369 of file set.c.

370{
371 ASSERT(name);
372 // In the interactive case (outside of the initial parsing of neomuttrc) we
373 // support additional syntax: "set" (no arguments) and "set all".
374 // If not in interactive mode, we recognise them but do nothing.
375
376 // Handle "set" (no arguments), i.e. show list of changed variables.
377 if (buf_is_empty(name))
378 {
379 if (StartupComplete)
380 return set_dump(CS_DUMP_ONLY_CHANGED, err);
381 else
382 return MUTT_CMD_SUCCESS;
383 }
384 // Handle special "set all" syntax
385 if (mutt_str_equal(name->data, "all"))
386 {
387 if (StartupComplete)
388 return set_dump(CS_DUMP_NO_FLAGS, err);
389 else
390 return MUTT_CMD_SUCCESS;
391 }
392
393 struct HashElem *he = cs_subset_lookup(NeoMutt->sub, name->data);
394 if (!he)
395 {
396 buf_printf(err, _("Unknown option %s"), name->data);
397 return MUTT_CMD_ERROR;
398 }
399
400 buf_addstr(err, name->data);
401 buf_addch(err, '=');
402 struct Buffer *value = buf_pool_get();
403 int rc = cs_subset_he_string_get(NeoMutt->sub, he, value);
404 if (CSR_RESULT(rc) != CSR_SUCCESS)
405 {
406 buf_reset(err);
407 buf_addstr(err, value->data);
408 buf_pool_release(&value);
409 return MUTT_CMD_ERROR;
410 }
411 if (DTYPE(he->type) == DT_PATH)
412 mutt_pretty_mailbox(value->data, value->dsize);
413 pretty_var(value->data, err);
414 buf_pool_release(&value);
415
416 return MUTT_CMD_SUCCESS;
417}
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition: buffer.c:291
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
Definition: buffer.c:241
enum CommandResult set_dump(ConfigDumpFlags flags, struct Buffer *err)
Dump list of config variables into a file/pager.
Definition: commands.c:874
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:192
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: