NeoMutt  2024-12-12-19-ge4b57e
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
dump.c
Go to the documentation of this file.
1
31#include "config.h"
32#include <stdbool.h>
33#include <stdio.h>
34#include "mutt/lib.h"
35#include "dump.h"
36#include "set.h"
37#include "subset.h"
38#include "types.h"
39
40void mutt_pretty_mailbox(char *buf, size_t buflen);
41
48size_t escape_string(struct Buffer *buf, const char *src)
49{
50 if (!buf || !src)
51 return 0;
52
53 size_t len = 0;
54 for (; *src; src++)
55 {
56 switch (*src)
57 {
58 case '\007':
59 len += buf_addstr(buf, "\\g");
60 break;
61 case '\n':
62 len += buf_addstr(buf, "\\n");
63 break;
64 case '\r':
65 len += buf_addstr(buf, "\\r");
66 break;
67 case '\t':
68 len += buf_addstr(buf, "\\t");
69 break;
70 default:
71 if ((*src == '\\') || (*src == '"'))
72 len += buf_addch(buf, '\\');
73 len += buf_addch(buf, src[0]);
74 }
75 }
76 return len;
77}
78
85size_t pretty_var(const char *str, struct Buffer *buf)
86{
87 if (!buf || !str)
88 return 0;
89
90 int len = 0;
91
92 len += buf_addch(buf, '"');
93 len += escape_string(buf, str);
94 len += buf_addch(buf, '"');
95
96 return len;
97}
98
108void dump_config_neo(struct ConfigSet *cs, struct HashElem *he, struct Buffer *value,
109 struct Buffer *initial, ConfigDumpFlags flags, FILE *fp)
110{
111 if (!he || !value || !fp)
112 return;
113
114 const char *name = he->key.strkey;
115
116 if ((flags & CS_DUMP_ONLY_CHANGED) &&
117 (!initial || mutt_str_equal(value->data, initial->data)))
118 {
119 return;
120 }
121
122 if (he->type == DT_SYNONYM)
123 {
124 const struct ConfigDef *cdef = he->data;
125 const char *syn = (const char *) cdef->initial;
126 fprintf(fp, "# synonym: %s -> %s\n", name, syn);
127 return;
128 }
129
130 if (flags & CS_DUMP_SHOW_DOCS)
131 {
132 const struct ConfigDef *cdef = he->data;
133 fprintf(fp, "# %s\n", cdef->docs);
134 }
135
136 bool show_name = !(flags & CS_DUMP_HIDE_NAME);
137 bool show_value = !(flags & CS_DUMP_HIDE_VALUE);
138
139 if (show_name && show_value)
140 fprintf(fp, "set ");
141 if (show_name)
142 fprintf(fp, "%s", name);
143 if (show_name && show_value)
144 fprintf(fp, " = ");
145 if (show_value)
146 fprintf(fp, "%s", value->data);
147 if (show_name || show_value)
148 fprintf(fp, "\n");
149
150 if (flags & CS_DUMP_SHOW_DEFAULTS)
151 {
152 const struct ConfigSetType *cst = cs_get_type_def(cs, he->type);
153 if (cst)
154 fprintf(fp, "# %s %s %s\n", cst->name, name, value->data);
155 }
156
157 if (flags & CS_DUMP_SHOW_DOCS)
158 fprintf(fp, "\n");
159}
160
167bool dump_config(struct ConfigSet *cs, ConfigDumpFlags flags, FILE *fp)
168{
169 if (!cs)
170 return false;
171
172 struct HashElem *he = NULL;
173
174 struct HashElem **he_list = get_elem_list(cs);
175 if (!he_list)
176 return false; /* LCOV_EXCL_LINE */
177
178 bool result = true;
179
180 struct Buffer *value = buf_pool_get();
181 struct Buffer *initial = buf_pool_get();
182 struct Buffer *tmp = buf_pool_get();
183
184 for (size_t i = 0; he_list[i]; i++)
185 {
186 buf_reset(value);
187 buf_reset(initial);
188 he = he_list[i];
189 const int type = DTYPE(he->type);
190
191 if ((type == DT_SYNONYM) && !(flags & CS_DUMP_SHOW_SYNONYMS))
192 continue;
193
194 if ((he->type & D_INTERNAL_DEPRECATED) && !(flags & CS_DUMP_SHOW_DEPRECATED))
195 continue;
196
197 if (type != DT_SYNONYM)
198 {
199 /* If necessary, get the current value */
200 if ((flags & CS_DUMP_ONLY_CHANGED) || !(flags & CS_DUMP_HIDE_VALUE) ||
201 (flags & CS_DUMP_SHOW_DEFAULTS))
202 {
203 int rc = cs_he_string_get(cs, he, value);
204 if (CSR_RESULT(rc) != CSR_SUCCESS)
205 {
206 result = false; /* LCOV_EXCL_LINE */
207 break; /* LCOV_EXCL_LINE */
208 }
209
210 const struct ConfigDef *cdef = he->data;
211 if ((type == DT_STRING) && (cdef->type & D_SENSITIVE) &&
212 (flags & CS_DUMP_HIDE_SENSITIVE) && !buf_is_empty(value))
213 {
214 buf_reset(value);
215 buf_addstr(value, "***");
216 }
217
218 if (((type == DT_PATH) || IS_MAILBOX(he->type)) && (value->data[0] == '/'))
219 mutt_pretty_mailbox(value->data, value->dsize);
220
221 if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) &&
222 (type != DT_QUAD) && !(flags & CS_DUMP_NO_ESCAPING))
223 {
224 buf_reset(tmp);
225 pretty_var(value->data, tmp);
226 buf_strcpy(value, tmp->data);
227 }
228 }
229
230 /* If necessary, get the default value */
232 {
233 int rc = cs_he_initial_get(cs, he, initial);
234 if (CSR_RESULT(rc) != CSR_SUCCESS)
235 {
236 result = false; /* LCOV_EXCL_LINE */
237 break; /* LCOV_EXCL_LINE */
238 }
239
240 if (((type == DT_PATH) || IS_MAILBOX(he->type)) && !(he->type & D_STRING_MAILBOX))
241 mutt_pretty_mailbox(initial->data, initial->dsize);
242
243 if ((type != DT_BOOL) && (type != DT_NUMBER) && (type != DT_LONG) &&
244 (type != DT_QUAD) && !(flags & CS_DUMP_NO_ESCAPING))
245 {
246 buf_reset(tmp);
247 pretty_var(initial->data, tmp);
248 buf_strcpy(initial, tmp->data);
249 }
250 }
251 }
252
253 dump_config_neo(cs, he, value, initial, flags, fp);
254 }
255
256 FREE(&he_list);
257 buf_pool_release(&value);
259 buf_pool_release(&tmp);
260
261 return result;
262}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:76
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
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition: buffer.c:226
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:395
size_t escape_string(struct Buffer *buf, const char *src)
Write a string to a buffer, escaping special characters.
Definition: dump.c:48
bool dump_config(struct ConfigSet *cs, ConfigDumpFlags flags, FILE *fp)
Write all the config to a file.
Definition: dump.c:167
size_t pretty_var(const char *str, struct Buffer *buf)
Escape and stringify a config item value.
Definition: dump.c:85
void dump_config_neo(struct ConfigSet *cs, struct HashElem *he, struct Buffer *value, struct Buffer *initial, ConfigDumpFlags flags, FILE *fp)
Dump the config in the style of NeoMutt.
Definition: dump.c:108
void mutt_pretty_mailbox(char *buf, size_t buflen)
Shorten a mailbox path using '~' or '='.
Definition: muttlib.c:440
Dump all the config.
#define CS_DUMP_SHOW_SYNONYMS
Show synonyms and the config items they're linked to.
Definition: dump.h:43
#define CS_DUMP_HIDE_VALUE
Do not print the value of the config item.
Definition: dump.h:40
#define CS_DUMP_SHOW_DEPRECATED
Show config items that aren't used any more.
Definition: dump.h:44
#define CS_DUMP_NO_ESCAPING
Do not escape special chars, or quote the string.
Definition: dump.h:38
#define CS_DUMP_HIDE_SENSITIVE
Obscure sensitive information like passwords.
Definition: dump.h:37
uint16_t ConfigDumpFlags
Flags for dump_config(), e.g. CS_DUMP_ONLY_CHANGED.
Definition: dump.h:34
#define CS_DUMP_ONLY_CHANGED
Only show config that the user has changed.
Definition: dump.h:36
#define CS_DUMP_HIDE_NAME
Do not print the name of the config item.
Definition: dump.h:39
#define CS_DUMP_SHOW_DEFAULTS
Show the default value for the config item.
Definition: dump.h:41
#define CS_DUMP_SHOW_DOCS
Show one-liner documentation for the config item.
Definition: dump.h:45
const struct ConfigSetType * cs_get_type_def(const struct ConfigSet *cs, unsigned int type)
Get the definition for a type.
Definition: set.c:198
int cs_he_string_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
Get a config item as a string.
Definition: set.c:663
int cs_he_initial_get(const struct ConfigSet *cs, struct HashElem *he, struct Buffer *result)
Get the initial, or parent, value of a config item.
Definition: set.c:529
#define CSR_RESULT(x)
Definition: set.h:52
#define CSR_SUCCESS
Action completed successfully.
Definition: set.h:35
#define FREE(x)
Definition: memory.h:55
Convenience wrapper for the library headers.
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition: string.c:660
Parse the 'set' command.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:96
String manipulation buffer.
Definition: buffer.h:36
size_t dsize
Length of data.
Definition: buffer.h:39
char * data
Pointer to data.
Definition: buffer.h:37
Definition: set.h:64
const char * name
User-visible name.
Definition: set.h:65
intptr_t initial
Initial value.
Definition: set.h:67
uint32_t type
Variable type, e.g. DT_STRING.
Definition: set.h:66
const char * docs
One-liner description.
Definition: set.h:84
const char * name
Name of the type, e.g. "String".
Definition: set.h:98
Container for lots of config items.
Definition: set.h:252
The item stored in a Hash Table.
Definition: hash.h:43
union HashKey key
Key representing the data.
Definition: hash.h:45
int type
Type of data stored in Hash Table, e.g. DT_STRING.
Definition: hash.h:44
void * data
User-supplied data.
Definition: hash.h:46
struct HashElem ** get_elem_list(struct ConfigSet *cs)
Create a sorted list of all config items.
Definition: subset.c:79
Subset of Config Items.
Constants for all the config types.
#define IS_MAILBOX(flags)
Definition: types.h:122
#define DTYPE(t)
Definition: types.h:50
#define D_INTERNAL_DEPRECATED
Config item shouldn't be used any more.
Definition: types.h:88
@ DT_NUMBER
a number
Definition: types.h:39
@ DT_BOOL
boolean option
Definition: types.h:32
@ DT_QUAD
quad-option (no/yes/ask-no/ask-yes)
Definition: types.h:41
@ DT_SYNONYM
synonym for another variable
Definition: types.h:46
@ DT_STRING
a string
Definition: types.h:45
@ DT_LONG
a number (long)
Definition: types.h:36
@ DT_PATH
a path to a file/directory
Definition: types.h:40
#define D_STRING_MAILBOX
Don't perform path expansions.
Definition: types.h:98
#define D_SENSITIVE
Contains sensitive value, e.g. password.
Definition: types.h:81
const char * strkey
String key.
Definition: hash.h:35