NeoMutt  2025-01-09-144-gb44c67
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
parse.c
Go to the documentation of this file.
1
29#include "config.h"
30#include <stdbool.h>
31#include <sys/param.h> // IWYU pragma: keep
32#include <unistd.h>
33#include "mutt/lib.h"
34#include "objects.h"
35
41int check_help_mode(const char *mode)
42{
43 if (mutt_istr_equal(mode, "shared"))
44 return HM_SHARED;
45 if (mutt_istr_equal(mode, "help"))
46 return HM_HELP;
47 if (mutt_istr_equal(mode, "info"))
48 return HM_INFO;
49 if (mutt_istr_equal(mode, "send"))
50 return HM_SEND;
51 if (mutt_istr_equal(mode, "tui"))
52 return HM_TUI;
53 if (mutt_istr_equal(mode, "all"))
54 return HM_ALL;
55 return 0;
56}
57
71static int mop_up(int argc, char **argv, int index, struct StringArray *sa)
72{
73 int count = 0;
74 for (int i = index; i < argc; i++, count++)
75 {
76 // Stop if we find '--' or '-X'
77 if ((argv[i][0] == '-') && (argv[i][1] != '\0'))
78 break;
79
80 ARRAY_ADD(sa, mutt_str_dup(argv[i]));
81 }
82
83 return count;
84}
85
93bool cli_parse(int argc, char **argv, struct CommandLine *cli)
94{
95 if ((argc < 1) || !argv || !cli)
96 return false;
97
98 // Any leading non-options must be addresses
99 int count = mop_up(argc, argv, 1, &cli->send.addresses);
100 if (count > 0)
101 {
102 cli->send.is_set = true;
103 argc -= count;
104 argv += count;
105 }
106
107 bool rc = true;
108
109 opterr = 0; // We'll handle the errors
110// Always initialise getopt() or the tests will fail
111#if defined(BSD) || defined(__APPLE__)
112 optreset = 1;
113 optind = 1;
114#else
115 optind = 0;
116#endif
117
118 while (rc && (argc > 1) && (optind < argc))
119 {
120 int opt = getopt(argc, argv, "+:A:a:b:Cc:Dd:Ee:F:f:Gg:H:hi:l:m:nOpQ:RSs:TvyZz");
121 switch (opt)
122 {
123 // ------------------------------------------------------------
124 // Shared
125 case 'F': // user config file
126 {
127 ARRAY_ADD(&cli->shared.user_files, mutt_str_dup(optarg));
128 cli->shared.is_set = true;
129 break;
130 }
131 case 'n': // no system config file
132 {
133 cli->shared.disable_system = true;
134 cli->shared.is_set = true;
135 break;
136 }
137 case 'e': // enter commands
138 {
139 ARRAY_ADD(&cli->shared.commands, mutt_str_dup(optarg));
140 cli->shared.is_set = true;
141 break;
142 }
143 case 'm': // mbox type
144 {
145 buf_strcpy(&cli->shared.mbox_type, optarg);
146 cli->shared.is_set = true;
147 break;
148 }
149 case 'd': // log level
150 {
151 buf_strcpy(&cli->shared.log_level, optarg);
152 cli->shared.is_set = true;
153 break;
154 }
155 case 'l': // log file
156 {
157 buf_strcpy(&cli->shared.log_file, optarg);
158 cli->shared.is_set = true;
159 break;
160 }
161
162 // ------------------------------------------------------------
163 // Help
164 case 'h': // help
165 {
166 if (optind < argc)
167 {
168 cli->help.mode = check_help_mode(argv[optind]);
169 if (cli->help.mode != HM_NONE)
170 optind++;
171 }
172 cli->help.help = true;
173 cli->help.is_set = true;
174 break;
175 }
176 case 'v': // version, license
177 {
178 if (cli->help.version)
179 cli->help.license = true;
180 else
181 cli->help.version = true;
182
183 cli->help.is_set = true;
184 break;
185 }
186
187 // ------------------------------------------------------------
188 // Info
189 case 'A': // alias lookup
190 {
192 // '-A' can take multiple arguments
193 optind += mop_up(argc, argv, optind, &cli->info.alias_queries);
194 cli->info.is_set = true;
195 break;
196 }
197 case 'D': // dump config, dump changed
198 {
199 if (cli->info.dump_config)
200 cli->info.dump_changed = true;
201 else
202 cli->info.dump_config = true;
203
204 cli->info.is_set = true;
205 break;
206 }
207 case 'O': // one-liner help
208 {
209 cli->info.show_help = true;
210 cli->info.is_set = true;
211 break;
212 }
213 case 'Q': // query config&cli->send.attach
214 {
215 ARRAY_ADD(&cli->info.queries, mutt_str_dup(optarg));
216 // '-Q' can take multiple arguments
217 optind += mop_up(argc, argv, optind, &cli->info.queries);
218 cli->info.is_set = true;
219 break;
220 }
221 case 'S': // hide sensitive
222 {
223 cli->info.hide_sensitive = true;
224 cli->info.is_set = true;
225 break;
226 }
227
228 // ------------------------------------------------------------
229 // Send
230 case 'a': // attach file
231 {
232 ARRAY_ADD(&cli->send.attach, mutt_str_dup(optarg));
233 // `-a` can take multiple arguments
234 optind += mop_up(argc, argv, optind, &cli->send.attach);
235 cli->send.is_set = true;
236 break;
237 }
238 case 'b': // bcc:
239 {
240 ARRAY_ADD(&cli->send.bcc_list, mutt_str_dup(optarg));
241 cli->send.is_set = true;
242 break;
243 }
244 case 'C': // crypto
245 {
246 cli->send.use_crypto = true;
247 cli->send.is_set = true;
248 break;
249 }
250 case 'c': // cc:
251 {
252 ARRAY_ADD(&cli->send.cc_list, mutt_str_dup(optarg));
253 cli->send.is_set = true;
254 break;
255 }
256 case 'E': // edit file
257 {
258 cli->send.edit_infile = true;
259 cli->send.is_set = true;
260 break;
261 }
262 case 'H': // draft file
263 {
264 buf_strcpy(&cli->send.draft_file, optarg);
265 cli->send.is_set = true;
266 break;
267 }
268 case 'i': // include file
269 {
270 buf_strcpy(&cli->send.include_file, optarg);
271 cli->send.is_set = true;
272 break;
273 }
274 case 's': // subject:
275 {
276 buf_strcpy(&cli->send.subject, optarg);
277 cli->send.is_set = true;
278 break;
279 }
280
281 // ------------------------------------------------------------
282 // TUI
283 case 'f': // start folder
284 {
285 buf_strcpy(&cli->tui.folder, optarg);
286 cli->tui.is_set = true;
287 break;
288 }
289 case 'G': // list newsgroups
290 {
291 cli->tui.start_nntp = true;
292 cli->tui.is_set = true;
293 break;
294 }
295 case 'g': // news server
296 {
297 cli->tui.start_nntp = true;
298 buf_strcpy(&cli->tui.nntp_server, optarg);
299 cli->tui.is_set = true;
300 break;
301 }
302 case 'p': // postponed
303 {
304 cli->tui.start_postponed = true;
305 cli->tui.is_set = true;
306 break;
307 }
308 case 'R': // read-only
309 {
310 cli->tui.read_only = true;
311 cli->tui.is_set = true;
312 break;
313 }
314 case 'y': // browser
315 {
316 cli->tui.start_browser = true;
317 cli->tui.is_set = true;
318 break;
319 }
320 case 'Z': // new mail
321 {
322 cli->tui.start_new_mail = true;
323 cli->tui.is_set = true;
324 break;
325 }
326 case 'z': // any mail
327 {
328 cli->tui.start_any_mail = true;
329 cli->tui.is_set = true;
330 break;
331 }
332
333 // ------------------------------------------------------------
334 case -1: // end of options
335 {
336 for (int i = optind; i < argc; i++)
337 {
338 ARRAY_ADD(&cli->send.addresses, mutt_str_dup(argv[i]));
339 }
340 cli->send.is_set = true;
341 optind = argc; // finish parsing
342 break;
343 }
344 default: // error
345 {
346 if (opt == '?')
347 mutt_warning("Invalid option: %c", optopt);
348 else if (opt == ':')
349 mutt_warning("Option %c requires an argument", optopt);
350
351 cli->help.help = true;
352 cli->help.is_set = true;
353 rc = false; // stop parsing
354 break;
355 }
356 }
357 }
358
359 return rc;
360}
#define ARRAY_ADD(head, elem)
Add an element at the end of the array.
Definition: array.h:156
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:395
static int mop_up(int argc, char **argv, int index, struct StringArray *sa)
Eat multiple arguments.
Definition: parse.c:71
int check_help_mode(const char *mode)
Check for help mode.
Definition: parse.c:41
bool cli_parse(int argc, char **argv, struct CommandLine *cli)
Parse the Command Line.
Definition: parse.c:93
#define mutt_warning(...)
Definition: logging2.h:91
Convenience wrapper for the library headers.
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:673
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:254
Parse the Command Line.
@ HM_SEND
Help about sending email options.
Definition: objects.h:40
@ HM_ALL
Help about all options.
Definition: objects.h:42
@ HM_HELP
Help about help.
Definition: objects.h:38
@ HM_INFO
Help about info options.
Definition: objects.h:39
@ HM_TUI
Help about starting the tui options.
Definition: objects.h:41
@ HM_NONE
No extra help.
Definition: objects.h:36
@ HM_SHARED
Help about shared config options.
Definition: objects.h:37
bool version
-v Print version
Definition: objects.h:69
bool license
-vv Print license
Definition: objects.h:70
enum HelpMode mode
Display detailed help.
Definition: objects.h:72
bool help
-h Print help
Definition: objects.h:68
bool is_set
This struct has been used.
Definition: objects.h:67
bool show_help
-O Show one-liner help
Definition: objects.h:83
bool is_set
This struct has been used.
Definition: objects.h:80
struct StringArray queries
-Q Query a config option
Definition: objects.h:87
struct StringArray alias_queries
-A Lookup an alias
Definition: objects.h:86
bool dump_config
-D Dump the config
Definition: objects.h:81
bool dump_changed
-DD Dump the changed config
Definition: objects.h:82
bool hide_sensitive
-S Hide sensitive config
Definition: objects.h:84
struct Buffer draft_file
-H Use this draft file
Definition: objects.h:104
bool is_set
This struct has been used.
Definition: objects.h:95
struct Buffer include_file
-i Use this include file
Definition: objects.h:105
struct StringArray cc_list
-c Add a Cc:
Definition: objects.h:101
struct StringArray attach
-a Attach a file
Definition: objects.h:99
bool use_crypto
-C Use CLI crypto
Definition: objects.h:96
bool edit_infile
-E Edit the draft/include
Definition: objects.h:97
struct StringArray bcc_list
-b Add a Bcc:
Definition: objects.h:100
struct StringArray addresses
Send to these addresses.
Definition: objects.h:102
struct Buffer subject
-s Use this Subject:
Definition: objects.h:106
struct Buffer log_level
-d Debug log level
Definition: objects.h:58
struct Buffer log_file
-l Debug log file
Definition: objects.h:59
struct StringArray commands
-e Run these commands
Definition: objects.h:55
bool is_set
This struct has been used.
Definition: objects.h:50
bool disable_system
-n Don't read the system config file
Definition: objects.h:53
struct StringArray user_files
-F Use these user config files
Definition: objects.h:52
struct Buffer mbox_type
-m Set the default Mailbox type
Definition: objects.h:56
bool read_only
-R Open Mailbox read-only
Definition: objects.h:115
bool start_any_mail
-z Check for Any Mail
Definition: objects.h:120
bool start_nntp
-G Open an NNTP Mailbox
Definition: objects.h:118
struct Buffer nntp_server
-g Open this NNTP Mailbox
Definition: objects.h:123
bool is_set
This struct has been used.
Definition: objects.h:114
struct Buffer folder
-f Open this Mailbox
Definition: objects.h:122
bool start_postponed
-p Open Postponed emails
Definition: objects.h:116
bool start_new_mail
-Z Check for New Mail
Definition: objects.h:119
bool start_browser
-y Open the Mailbox Browser
Definition: objects.h:117
Command Line options.
Definition: objects.h:130
struct CliSend send
Send Mode command line options.
Definition: objects.h:134
struct CliShared shared
Shared command line options.
Definition: objects.h:131
struct CliHelp help
Help Mode command line options.
Definition: objects.h:132
struct CliInfo info
Info Mode command line options.
Definition: objects.h:133
struct CliTui tui
Tui Mode command line options.
Definition: objects.h:135