Further improvements in `mail'.
* NEWS: Update. * mail/mail.h (MOPTF_UNSET): New constant. * mail/mailvar.c (MAILVAR_TYPEMASK): New define. (struct mailvar_symbol): Remove `type'. Add `handler'. The latter supplies special handling for certain variables. (mailvar_tab): Update accordingly. Implement "debug" variable. (mailvar_set): Enforce correct variable type in variable-strict mode. Handle MOPTF_UNSET flag. Remove kludgy special handling for some attributes, use sym->handler instead. (set_decode_fallback, set_replyregex) (set_screen, set_mailbox_debug_level, set_debug): New functions. (describe_symbol): Handle alternative symbol types. * mail/set.c: Use MOPTF_UNSET when unsetting the variable. * mail/source.c: Set correct locus. This allows to display locations along with error messages.
Showing
5 changed files
with
315 additions
and
120 deletions
... | @@ -47,7 +47,14 @@ In addition, the form | ... | @@ -47,7 +47,14 @@ In addition, the form |
47 | mail --file=mymbox | 47 | mail --file=mymbox |
48 | 48 | ||
49 | is also allowed. | 49 | is also allowed. |
50 | 50 | ||
51 | ** error locations | ||
52 | |||
53 | Diagnostic messages issued while processing `source' command | ||
54 | include file locations, in compliance with the GNU standards. This | ||
55 | also includes diagnostics issued during processing of the | ||
56 | system or user configuration file. | ||
57 | |||
51 | ** envelope command | 58 | ** envelope command |
52 | 59 | ||
53 | The env[elope] command displays the SMTP envelopes of the messages | 60 | The env[elope] command displays the SMTP envelopes of the messages | ... | ... |
... | @@ -344,6 +344,7 @@ extern void mailvar_variable_format (FILE *fp, | ... | @@ -344,6 +344,7 @@ extern void mailvar_variable_format (FILE *fp, |
344 | 344 | ||
345 | #define MOPTF_OVERWRITE 0x001 | 345 | #define MOPTF_OVERWRITE 0x001 |
346 | #define MOPTF_QUIET 0x002 | 346 | #define MOPTF_QUIET 0x002 |
347 | #define MOPTF_UNSET 0x004 | ||
347 | extern int mailvar_set (const char *name, void *value, | 348 | extern int mailvar_set (const char *name, void *value, |
348 | enum mailvar_type type, int flags); | 349 | enum mailvar_type type, int flags); |
349 | extern int util_isdeleted (size_t msgno); | 350 | extern int util_isdeleted (size_t msgno); | ... | ... |
... | @@ -20,160 +20,241 @@ | ... | @@ -20,160 +20,241 @@ |
20 | #define MAILVAR_RDONLY 0x0002 | 20 | #define MAILVAR_RDONLY 0x0002 |
21 | #define MAILVAR_HIDDEN 0x0004 | 21 | #define MAILVAR_HIDDEN 0x0004 |
22 | 22 | ||
23 | #define MAILVAR_TYPEMASK(type) (1<<(8+(type))) | ||
24 | |||
23 | struct mailvar_symbol | 25 | struct mailvar_symbol |
24 | { | 26 | { |
25 | struct mailvar_variable var; | 27 | struct mailvar_variable var; |
26 | enum mailvar_type type; | ||
27 | int flags; | 28 | int flags; |
28 | char *descr; | 29 | char *descr; |
30 | void (*handler) (struct mailvar_variable *); | ||
29 | }; | 31 | }; |
30 | 32 | ||
31 | mu_list_t mailvar_list = NULL; | 33 | mu_list_t mailvar_list = NULL; |
32 | 34 | ||
35 | static void set_decode_fallback (struct mailvar_variable *); | ||
36 | static void set_replyregex (struct mailvar_variable *); | ||
37 | static void set_screen (struct mailvar_variable *); | ||
38 | static void set_debug (struct mailvar_variable *); | ||
39 | |||
33 | struct mailvar_symbol mailvar_tab[] = | 40 | struct mailvar_symbol mailvar_tab[] = |
34 | { | 41 | { |
42 | /* FIXME: */ | ||
43 | { { "allnet", }, MAILVAR_HIDDEN }, | ||
44 | |||
35 | /* For compatibility with other mailx implementations. | 45 | /* For compatibility with other mailx implementations. |
36 | Never used, always true. */ | 46 | Never used, always true. */ |
37 | { { "append", }, mailvar_type_boolean, MAILVAR_RDONLY, | 47 | { { "append", }, |
48 | MAILVAR_TYPEMASK (mailvar_type_boolean) | MAILVAR_RDONLY, | ||
38 | N_("messages saved in mbox are appended to the end rather than prepended") }, | 49 | N_("messages saved in mbox are appended to the end rather than prepended") }, |
39 | { { "appenddeadletter", }, mailvar_type_boolean, 0, | 50 | { { "appenddeadletter", }, |
51 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
40 | N_("append the contents of canceled letter to dead.letter file") }, | 52 | N_("append the contents of canceled letter to dead.letter file") }, |
41 | { { "askbcc", }, mailvar_type_boolean, 0, | 53 | { { "askbcc", }, |
54 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
42 | N_("prompt user for bcc before composing the message") }, | 55 | N_("prompt user for bcc before composing the message") }, |
43 | { { "askcc", }, mailvar_type_boolean, 0, | 56 | { { "askcc", }, |
57 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
44 | N_("prompt user for cc before composing the message") }, | 58 | N_("prompt user for cc before composing the message") }, |
45 | { { "ask", }, mailvar_type_boolean, 0, | 59 | { { "ask", }, |
60 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
46 | N_("prompt user for subject before composing the message") }, | 61 | N_("prompt user for subject before composing the message") }, |
47 | { { "asksub", }, mailvar_type_whatever, MAILVAR_ALIAS, NULL }, | 62 | { { "asksub", }, MAILVAR_ALIAS, NULL }, |
48 | { { "autoinc", }, mailvar_type_boolean, 0, | 63 | { { "autoinc", }, |
64 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
49 | N_("automatically incorporate newly arrived messages")}, | 65 | N_("automatically incorporate newly arrived messages")}, |
50 | { { "autoprint", }, mailvar_type_boolean, 0, | 66 | { { "autoprint", }, |
67 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
51 | N_("delete command behaves like dp") }, | 68 | N_("delete command behaves like dp") }, |
52 | { { "bang", }, mailvar_type_boolean, 0, | 69 | { { "bang", }, |
70 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
53 | N_("replace every occurrence of ! in arguments to the shell command" | 71 | N_("replace every occurrence of ! in arguments to the shell command" |
54 | " with the last executed command") }, | 72 | " with the last executed command") }, |
55 | { { "charset", }, mailvar_type_string, 0, | 73 | { { "charset", }, |
74 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
56 | N_("output character set for decoded header fields") }, | 75 | N_("output character set for decoded header fields") }, |
57 | { { "cmd", }, mailvar_type_string, 0, | 76 | { { "cmd", }, |
77 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
58 | N_("default shell command for pipe") }, | 78 | N_("default shell command for pipe") }, |
59 | { { "columns", }, mailvar_type_number, 0, | 79 | { { "columns", }, |
80 | MAILVAR_TYPEMASK (mailvar_type_number), | ||
60 | N_("number of columns on terminal screen") }, | 81 | N_("number of columns on terminal screen") }, |
61 | { { "crt", }, mailvar_type_number, 0, | 82 | { { "crt", }, |
83 | MAILVAR_TYPEMASK (mailvar_type_number) | | ||
84 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
62 | N_("if numeric, sets the minimum number of output lines needed " | 85 | N_("if numeric, sets the minimum number of output lines needed " |
63 | "to engage paging; if boolean, use the height of the terminal " | 86 | "to engage paging; if boolean, use the height of the terminal " |
64 | "screen to compute the threshold") }, | 87 | "screen to compute the threshold") }, |
65 | { { "datefield", }, mailvar_type_boolean, 0, | 88 | { { "datefield", }, |
89 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
66 | N_("get date from the `Date:' header, instead of the envelope") }, | 90 | N_("get date from the `Date:' header, instead of the envelope") }, |
67 | { { "dot", }, mailvar_type_boolean, 0, | 91 | { { "debug", }, |
92 | MAILVAR_TYPEMASK (mailvar_type_string) | | ||
93 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
94 | N_("set Mailutils debug level"), | ||
95 | set_debug }, | ||
96 | { { "decode-fallback", }, | ||
97 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
98 | N_("how to represent characters that cannot be rendered using the " | ||
99 | "current character set"), | ||
100 | set_decode_fallback }, | ||
101 | { { "dot", }, | ||
102 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
68 | N_("input message is terminated with a dot alone on a line") }, | 103 | N_("input message is terminated with a dot alone on a line") }, |
69 | { { "editheaders", }, mailvar_type_boolean, 0, | 104 | { { "editheaders", }, |
105 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
70 | N_("allow to edit message headers while composing") }, | 106 | N_("allow to edit message headers while composing") }, |
71 | { { "emptystart", }, mailvar_type_boolean, 0, | 107 | { { "emptystart", }, |
108 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
72 | N_("start interactive mode if the mailbox is empty") }, | 109 | N_("start interactive mode if the mailbox is empty") }, |
73 | { { "escape", }, mailvar_type_string, 0, | 110 | { { "escape", }, |
111 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
74 | N_("character denoting escapes") }, | 112 | N_("character denoting escapes") }, |
75 | { { "flipr", }, mailvar_type_boolean, 0, | 113 | { { "flipr", }, |
114 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
76 | N_("swap the meaning of reply and Reply commands") }, | 115 | N_("swap the meaning of reply and Reply commands") }, |
77 | { { "folder", }, mailvar_type_string, 0, | 116 | { { "folder", }, |
117 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
78 | N_("folder directory name") }, | 118 | N_("folder directory name") }, |
79 | { { "fromfield", }, mailvar_type_boolean, 0, | 119 | { { "fromfield", }, |
120 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
80 | N_("get sender address from the `From:' header, instead of " | 121 | N_("get sender address from the `From:' header, instead of " |
81 | "the envelope") }, | 122 | "the envelope") }, |
82 | { { "gnu-last-command", }, mailvar_type_boolean, MAILVAR_RDONLY, | 123 | { { "gnu-last-command", }, |
124 | MAILVAR_TYPEMASK (mailvar_type_string) | MAILVAR_RDONLY, | ||
83 | N_("last executed command line") }, | 125 | N_("last executed command line") }, |
84 | { { "header", }, mailvar_type_boolean, 0, | 126 | { { "header", }, |
127 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
85 | N_("run the `headers' command after entering interactive mode") }, | 128 | N_("run the `headers' command after entering interactive mode") }, |
86 | { { "hold", }, mailvar_type_boolean, 0, | 129 | { { "hold", }, |
130 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
87 | N_("hold the read or saved messages in the system mailbox") }, | 131 | N_("hold the read or saved messages in the system mailbox") }, |
88 | { { "ignore", }, mailvar_type_boolean, 0, | 132 | { { "ignore", }, |
133 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
89 | N_("ignore keyboard interrupts when composing messages") }, | 134 | N_("ignore keyboard interrupts when composing messages") }, |
90 | { { "ignoreeof", }, mailvar_type_boolean, 0, | 135 | { { "ignoreeof", }, |
136 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
91 | N_("typing the EOF character terminates the letter being composed") }, | 137 | N_("typing the EOF character terminates the letter being composed") }, |
92 | { { "indentprefix", }, mailvar_type_string, 0, | 138 | { { "indentprefix", }, |
139 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
93 | N_("string used by the ~m escape for indenting quoted messages") }, | 140 | N_("string used by the ~m escape for indenting quoted messages") }, |
94 | { { "inplacealiases", }, mailvar_type_boolean, 0, | 141 | { { "inplacealiases", }, |
142 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
95 | N_("expand aliases in the address header field " | 143 | N_("expand aliases in the address header field " |
96 | "before entering send mode") }, | 144 | "before entering send mode") }, |
97 | /* For compatibility with other mailx implementations. | 145 | /* For compatibility with other mailx implementations. |
98 | Never used, always true. */ | 146 | Never used, always true. */ |
99 | { { "keep", }, mailvar_type_boolean, MAILVAR_RDONLY, | 147 | { { "keep", }, |
148 | MAILVAR_TYPEMASK (mailvar_type_boolean) | MAILVAR_RDONLY, | ||
100 | N_("truncate the user's system mailbox when it is empty") }, | 149 | N_("truncate the user's system mailbox when it is empty") }, |
101 | { { "keepsave", }, mailvar_type_boolean, 0, | 150 | { { "keepsave", }, |
151 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
102 | N_("keep saved messages in system mailbox too") }, | 152 | N_("keep saved messages in system mailbox too") }, |
103 | { { "mailx", }, mailvar_type_boolean, 0, | 153 | { { "mailx", }, |
154 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
104 | N_("enable mailx compatibility mode") }, | 155 | N_("enable mailx compatibility mode") }, |
105 | { { "metamail", }, mailvar_type_boolean, 0, | 156 | { { "metamail", }, |
157 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
106 | N_("interpret the content of message parts; if set to a string " | 158 | N_("interpret the content of message parts; if set to a string " |
107 | "specifies the name of the externam metamail command") }, | 159 | "specifies the name of the externam metamail command") }, |
108 | { { "metoo", }, mailvar_type_boolean, 0, | 160 | { { "metoo", }, |
161 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
109 | N_("do not remove sender addresses from the recipient list") }, | 162 | N_("do not remove sender addresses from the recipient list") }, |
110 | { { "mimenoask", }, mailvar_type_string, 0, | 163 | { { "mimenoask", }, |
164 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
111 | N_("a comma-separated list of MIME types for which " | 165 | N_("a comma-separated list of MIME types for which " |
112 | "no confirmation is needed before running metamail interpreter") }, | 166 | "no confirmation is needed before running metamail interpreter") }, |
113 | { { "mode", }, mailvar_type_string, MAILVAR_RDONLY, | 167 | { { "mode", }, |
168 | MAILVAR_TYPEMASK (mailvar_type_string) | MAILVAR_RDONLY, | ||
114 | N_("the name of current operation mode") }, | 169 | N_("the name of current operation mode") }, |
115 | { { "nullbody", }, mailvar_type_boolean, 0, | 170 | { { "nullbody", }, |
171 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
116 | N_("accept messages with an empty body") }, | 172 | N_("accept messages with an empty body") }, |
117 | { { "nullbodymsg", }, mailvar_type_string, 0, | 173 | { { "nullbodymsg", }, |
174 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
118 | N_("display this text when sending a message with empty body") }, | 175 | N_("display this text when sending a message with empty body") }, |
119 | { { "outfolder", }, mailvar_type_string, 0, | 176 | { { "outfolder", }, |
177 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
120 | N_("keep created files in this folder") }, | 178 | N_("keep created files in this folder") }, |
121 | { { "page", }, mailvar_type_boolean, 0, | 179 | { { "page", }, |
180 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
122 | N_("pipe command terminates each message with a linefeed") }, | 181 | N_("pipe command terminates each message with a linefeed") }, |
123 | { { "prompt", }, mailvar_type_string, 0, | 182 | { { "prompt", }, |
183 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
124 | N_("command prompt sequence") }, | 184 | N_("command prompt sequence") }, |
125 | { { "quit", }, mailvar_type_boolean, 0, | 185 | { { "quit", }, |
186 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
126 | N_("keyboard interrupts terminate the program") }, | 187 | N_("keyboard interrupts terminate the program") }, |
127 | { { "rc", }, mailvar_type_boolean, 0, | 188 | { { "rc", }, |
189 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
128 | N_("read the system-wide configuration file upon startup") }, | 190 | N_("read the system-wide configuration file upon startup") }, |
129 | { { "readonly", }, mailvar_type_boolean, 0, | 191 | { { "readonly", }, |
192 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
130 | N_("mailboxes are opened in readonly mode") }, | 193 | N_("mailboxes are opened in readonly mode") }, |
131 | { { "record", }, mailvar_type_string, 0, | 194 | { { "record", }, |
195 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
132 | N_("save outgoing messages in this file") }, | 196 | N_("save outgoing messages in this file") }, |
133 | { { "recursivealiases", }, mailvar_type_boolean, 0, | 197 | { { "recursivealiases", }, |
198 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
134 | N_("recursively expand aliases") }, | 199 | N_("recursively expand aliases") }, |
135 | { { "regex", }, mailvar_type_boolean, 0, | 200 | { { "regex", }, |
201 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
136 | N_("use regular expressions in message specifications") }, | 202 | N_("use regular expressions in message specifications") }, |
137 | { { "replyprefix", }, mailvar_type_string, 0, | 203 | { { "replyprefix", }, |
204 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
138 | N_("prefix for the subject line of a reply message") }, | 205 | N_("prefix for the subject line of a reply message") }, |
139 | { { "replyregex", }, mailvar_type_string, 0, | 206 | { { "replyregex", }, |
140 | N_("regexp for recognizing subject lines of reply messages") }, | 207 | MAILVAR_TYPEMASK (mailvar_type_string), |
141 | { { "save", }, mailvar_type_boolean, 0, | 208 | N_("regexp for recognizing subject lines of reply messages"), |
209 | set_replyregex }, | ||
210 | { { "save", }, | ||
211 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
142 | N_("stored aborted messages in the user's dead.file") }, | 212 | N_("stored aborted messages in the user's dead.file") }, |
143 | { { "screen", }, mailvar_type_number, 0, | 213 | { { "screen", }, |
144 | N_("number of lines on terminal screen") }, | 214 | MAILVAR_TYPEMASK (mailvar_type_number), |
145 | { { "sendmail", }, mailvar_type_string, 0, | 215 | N_("number of lines on terminal screen"), |
216 | set_screen }, | ||
217 | { { "sendmail", }, | ||
218 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
146 | N_("URL of the mail transport agent") }, | 219 | N_("URL of the mail transport agent") }, |
147 | /* FIXME: Not yet used. */ | 220 | /* FIXME: Not yet used. */ |
148 | { { "sendwait", }, mailvar_type_boolean, MAILVAR_HIDDEN, NULL }, | 221 | { { "sendwait", }, |
149 | { { "sign", }, mailvar_type_string, 0, | 222 | MAILVAR_TYPEMASK (mailvar_type_boolean) | MAILVAR_HIDDEN, NULL }, |
223 | { { "sign", }, | ||
224 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
150 | N_("signature for use with the ~a command") }, | 225 | N_("signature for use with the ~a command") }, |
151 | { { "Sign", }, mailvar_type_string, 0, | 226 | { { "Sign", }, |
227 | MAILVAR_TYPEMASK (mailvar_type_string), | ||
152 | N_("signature for use with the ~A command") }, | 228 | N_("signature for use with the ~A command") }, |
153 | { { "showenvelope", }, mailvar_type_boolean, 0, | 229 | { { "showenvelope", }, |
230 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
154 | N_("`print' command includes the SMTP envelope in its output") }, | 231 | N_("`print' command includes the SMTP envelope in its output") }, |
155 | { { "showto", }, mailvar_type_boolean, 0, | 232 | { { "showto", }, |
233 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
156 | N_("if the message was sent by the user, print its recipient address " | 234 | N_("if the message was sent by the user, print its recipient address " |
157 | "in the header summary") }, | 235 | "in the header summary") }, |
158 | { { "toplines", }, mailvar_type_number, 0, | 236 | { { "toplines", }, |
237 | MAILVAR_TYPEMASK (mailvar_type_number), | ||
159 | N_("number of lines to be displayed by `top' or `Top'") }, | 238 | N_("number of lines to be displayed by `top' or `Top'") }, |
160 | { { "verbose", }, mailvar_type_boolean, 0, | 239 | { { "variable-pretty-print", }, |
161 | N_("verbosely trace the process of message delivery") }, | 240 | MAILVAR_TYPEMASK (mailvar_type_boolean), |
162 | { { "xmailer", }, mailvar_type_boolean, 0, | ||
163 | N_("add the `X-Mailer' header to the outgoing messages") }, | ||
164 | |||
165 | { { "variable-pretty-print", }, mailvar_type_boolean, 0, | ||
166 | N_("print variables with short descriptions") }, | 241 | N_("print variables with short descriptions") }, |
167 | { { "varpp", }, mailvar_type_whatever, MAILVAR_ALIAS }, | 242 | { { "varpp", }, MAILVAR_ALIAS }, |
168 | { { "variable-strict", }, mailvar_type_boolean, 0, | 243 | { { "variable-strict", }, |
244 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
169 | N_("perform strict checking when setting options") }, | 245 | N_("perform strict checking when setting options") }, |
170 | { { "varstrict", }, mailvar_type_whatever, MAILVAR_ALIAS }, | 246 | { { "varstrict", }, MAILVAR_ALIAS }, |
247 | { { "verbose", }, | ||
248 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
249 | N_("verbosely trace the process of message delivery") }, | ||
250 | { { "xmailer", }, | ||
251 | MAILVAR_TYPEMASK (mailvar_type_boolean), | ||
252 | N_("add the `X-Mailer' header to the outgoing messages") }, | ||
171 | 253 | ||
172 | /* These will be implemented later */ | 254 | /* These will be implemented later */ |
173 | { { "debug", }, mailvar_type_whatever, MAILVAR_HIDDEN, NULL }, | 255 | { { "onehop", }, MAILVAR_HIDDEN, NULL }, |
174 | { { "onehop", }, mailvar_type_whatever, MAILVAR_HIDDEN, NULL }, | ||
175 | 256 | ||
176 | { { "quiet", }, mailvar_type_boolean, MAILVAR_HIDDEN, | 257 | { { "quiet", }, MAILVAR_TYPEMASK (mailvar_type_boolean) | MAILVAR_HIDDEN, |
177 | "suppresses the printing of the version when first invoked" }, | 258 | "suppresses the printing of the version when first invoked" }, |
178 | 259 | ||
179 | { { NULL }, } | 260 | { { NULL }, } |
... | @@ -381,12 +462,12 @@ mailvar_set (const char *variable, void *value, enum mailvar_type type, | ... | @@ -381,12 +462,12 @@ mailvar_set (const char *variable, void *value, enum mailvar_type type, |
381 | int flags) | 462 | int flags) |
382 | { | 463 | { |
383 | struct mailvar_variable *var; | 464 | struct mailvar_variable *var; |
465 | const struct mailvar_symbol *sym = find_mailvar_symbol (variable); | ||
466 | int unset = flags & MOPTF_UNSET; | ||
384 | 467 | ||
385 | if (!(flags & MOPTF_QUIET) | 468 | if (!(flags & MOPTF_QUIET) |
386 | && mailvar_get (NULL, "variable-strict", mailvar_type_boolean, 0) == 0) | 469 | && mailvar_get (NULL, "variable-strict", mailvar_type_boolean, 0) == 0) |
387 | { | 470 | { |
388 | const struct mailvar_symbol *sym = find_mailvar_symbol (variable); | ||
389 | |||
390 | if (!sym) | 471 | if (!sym) |
391 | mu_diag_output (MU_DIAG_WARNING, _("setting unknown variable %s"), | 472 | mu_diag_output (MU_DIAG_WARNING, _("setting unknown variable %s"), |
392 | variable); | 473 | variable); |
... | @@ -396,64 +477,149 @@ mailvar_set (const char *variable, void *value, enum mailvar_type type, | ... | @@ -396,64 +477,149 @@ mailvar_set (const char *variable, void *value, enum mailvar_type type, |
396 | variable); | 477 | variable); |
397 | return 1; | 478 | return 1; |
398 | } | 479 | } |
480 | else if (!(sym->flags & MAILVAR_TYPEMASK (type)) | ||
481 | && !unset) | ||
482 | { | ||
483 | mu_error (_("Wrong type for %s"), variable); | ||
484 | return 1; | ||
485 | } | ||
399 | } | 486 | } |
400 | 487 | ||
401 | var = mailvar_find_variable (variable, 1); | 488 | var = mailvar_find_variable (variable, !unset); |
402 | 489 | ||
403 | if (!var || (var->set && !(flags & MOPTF_OVERWRITE))) | 490 | if (!var || (var->set && !(flags & MOPTF_OVERWRITE))) |
404 | return 0; | 491 | return 0; |
405 | 492 | ||
406 | mailvar_variable_reset (var); | 493 | mailvar_variable_reset (var); |
407 | 494 | if (!unset) | |
408 | var->type = type; | ||
409 | if (value) | ||
410 | { | 495 | { |
411 | var->set = 1; | 496 | var->type = type; |
412 | switch (type) | 497 | if (value) |
413 | { | 498 | { |
414 | case mailvar_type_number: | 499 | var->set = 1; |
415 | var->value.number = *(int*)value; | 500 | switch (type) |
416 | break; | 501 | { |
502 | case mailvar_type_number: | ||
503 | var->value.number = *(int*)value; | ||
504 | break; | ||
417 | 505 | ||
418 | case mailvar_type_string: | 506 | case mailvar_type_string: |
419 | var->value.string = strdup (value); | 507 | var->value.string = strdup (value); |
420 | break; | 508 | break; |
421 | 509 | ||
422 | case mailvar_type_boolean: | 510 | case mailvar_type_boolean: |
423 | var->value.bool = *(int*)value; | 511 | var->value.bool = *(int*)value; |
424 | break; | 512 | break; |
425 | 513 | ||
426 | default: | 514 | default: |
427 | abort(); | 515 | abort(); |
516 | } | ||
428 | } | 517 | } |
429 | } | 518 | } |
430 | 519 | ||
431 | /* Special handling for some variables */ | 520 | /* Special handling for some variables */ |
432 | if (strcmp (variable, "replyregex") == 0) | 521 | if (sym && sym->flags & MAILVAR_TYPEMASK (type) && sym->handler) |
433 | { | 522 | sym->handler (var); |
434 | int rc; | 523 | |
435 | char *err; | 524 | return 0; |
436 | 525 | } | |
437 | if ((rc = mu_unre_set_regex (value, 0, &err))) | 526 | |
527 | |||
528 | static void | ||
529 | set_decode_fallback (struct mailvar_variable *var) | ||
530 | { | ||
531 | if (mu_set_default_fallback (var->value.string)) | ||
532 | mu_error (_("Incorrect value for decode-fallback")); | ||
533 | } | ||
534 | |||
535 | static void | ||
536 | set_replyregex (struct mailvar_variable *var) | ||
537 | { | ||
538 | int rc; | ||
539 | char *err; | ||
540 | |||
541 | if ((rc = mu_unre_set_regex (var->value.string, 0, &err))) | ||
542 | { | ||
543 | if (err) | ||
544 | mu_error ("%s: %s", mu_strerror (rc), err); | ||
545 | else | ||
546 | mu_error ("%s", mu_strerror (rc)); | ||
547 | } | ||
548 | } | ||
549 | |||
550 | static void | ||
551 | set_screen (struct mailvar_variable *var) | ||
552 | { | ||
553 | page_invalidate (1); | ||
554 | } | ||
555 | |||
556 | static void | ||
557 | set_mailbox_debug_level (mu_log_level_t level) | ||
558 | { | ||
559 | if (mbox) | ||
560 | { | ||
561 | mu_debug_t mdbg; | ||
562 | mu_mailbox_get_debug (mbox, &mdbg); | ||
563 | mu_debug_set_level (mdbg, level); | ||
564 | } | ||
565 | } | ||
566 | |||
567 | #define DEFAULT_DEBUG_LEVEL \ | ||
568 | (MU_DEBUG_INHERIT | MU_DEBUG_LEVEL_UPTO (MU_DEBUG_TRACE7)) | ||
569 | |||
570 | static void | ||
571 | set_debug (struct mailvar_variable *var) | ||
572 | { | ||
573 | int rc; | ||
574 | int argc; | ||
575 | char **argv; | ||
576 | int i; | ||
577 | mu_debug_t dbg; | ||
578 | |||
579 | mu_global_debug_clear_level (NULL); | ||
580 | set_mailbox_debug_level (0); | ||
581 | |||
582 | if (var->type == mailvar_type_boolean) | ||
583 | { | ||
584 | if (var->set) | ||
438 | { | 585 | { |
439 | fprintf (stderr, "%s", mu_strerror (rc)); | 586 | /* FIXME: What to set here? |
440 | if (err) | 587 | mu_global_debug_set_level ("*", DEFAULT_DEBUG_LEVEL); */ |
441 | { | 588 | set_mailbox_debug_level (DEFAULT_DEBUG_LEVEL); |
442 | fprintf (stderr, "%s", err); | ||
443 | free (err); | ||
444 | } | ||
445 | fprintf (stderr, "\n"); | ||
446 | } | 589 | } |
590 | return; | ||
447 | } | 591 | } |
448 | else if (strcmp (variable, "decode-fallback") == 0) | 592 | |
593 | mu_diag_get_debug (&dbg); | ||
594 | |||
595 | rc = mu_argcv_get (var->value.string, ";", NULL, &argc, &argv); | ||
596 | if (rc) | ||
449 | { | 597 | { |
450 | if (mu_set_default_fallback (value)) | 598 | mu_error (_("Cannot parse string: %s"), mu_strerror (rc)); |
451 | mu_error (_("Incorrect value for decode-fallback")); | 599 | return; |
600 | } | ||
601 | |||
602 | for (i = 0; i < argc; i++) | ||
603 | { | ||
604 | char *p; | ||
605 | mu_log_level_t level = MU_DEBUG_INHERIT; | ||
606 | char *object_name = argv[i]; | ||
607 | |||
608 | for (p = object_name; *p && *p != '='; p++) | ||
609 | ; | ||
610 | |||
611 | if (*p == '=') | ||
612 | { | ||
613 | *p++ = 0; | ||
614 | mu_debug_level_from_string (p, &level, dbg); | ||
615 | } | ||
616 | else | ||
617 | level |= MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT); | ||
618 | |||
619 | if (strcmp (object_name, "mailbox") == 0) | ||
620 | set_mailbox_debug_level (level); | ||
621 | mu_global_debug_set_level (object_name, level); | ||
452 | } | 622 | } |
453 | else if (strcmp (variable, "screen") == 0) | ||
454 | page_invalidate (1); | ||
455 | |||
456 | return 0; | ||
457 | } | 623 | } |
458 | 624 | ||
459 | 625 | ||
... | @@ -654,6 +820,7 @@ static void | ... | @@ -654,6 +820,7 @@ static void |
654 | describe_symbol (FILE *out, int width, const struct mailvar_symbol *sym) | 820 | describe_symbol (FILE *out, int width, const struct mailvar_symbol *sym) |
655 | { | 821 | { |
656 | int n; | 822 | int n; |
823 | int i, t; | ||
657 | const struct mailvar_symbol *ali; | 824 | const struct mailvar_symbol *ali; |
658 | 825 | ||
659 | n = fprintf (out, "%s", sym->var.name); | 826 | n = fprintf (out, "%s", sym->var.name); |
... | @@ -667,7 +834,18 @@ describe_symbol (FILE *out, int width, const struct mailvar_symbol *sym) | ... | @@ -667,7 +834,18 @@ describe_symbol (FILE *out, int width, const struct mailvar_symbol *sym) |
667 | } | 834 | } |
668 | fputc ('\n', out); | 835 | fputc ('\n', out); |
669 | 836 | ||
670 | fprintf (out, _("Type: %s\n"), gettext (typestr[sym->type])); | 837 | fprintf (out, _("Type: ")); |
838 | for (i = 0, t = 0; i < sizeof (typestr) / sizeof (typestr[0]); i++) | ||
839 | if (sym->flags & MAILVAR_TYPEMASK (i)) | ||
840 | { | ||
841 | if (t++) | ||
842 | fprintf (out, " %s ", _("or")); | ||
843 | fprintf (out, "%s", gettext (typestr[i])); | ||
844 | } | ||
845 | if (!t) | ||
846 | fprintf (out, "%s", gettext (typestr[0])); | ||
847 | fputc ('\n', out); | ||
848 | |||
671 | fprintf (out, "%s", _("Current value: ")); | 849 | fprintf (out, "%s", _("Current value: ")); |
672 | mailvar_variable_format (out, &sym->var, _("[not set]")); | 850 | mailvar_variable_format (out, &sym->var, _("[not set]")); |
673 | 851 | ... | ... |
... | @@ -48,7 +48,8 @@ mail_set (int argc, char **argv) | ... | @@ -48,7 +48,8 @@ mail_set (int argc, char **argv) |
48 | 48 | ||
49 | if (!strncmp ("no", argv[i], 2) && !value) | 49 | if (!strncmp ("no", argv[i], 2) && !value) |
50 | { | 50 | { |
51 | mailvar_set (&argv[i][2], NULL, mailvar_type_boolean, flags); | 51 | mailvar_set (&argv[i][2], NULL, mailvar_type_boolean, |
52 | flags | MOPTF_UNSET); | ||
52 | } | 53 | } |
53 | else if (value) | 54 | else if (value) |
54 | { | 55 | { | ... | ... |
... | @@ -18,21 +18,25 @@ | ... | @@ -18,21 +18,25 @@ |
18 | 18 | ||
19 | #include "mail.h" | 19 | #include "mail.h" |
20 | 20 | ||
21 | |||
22 | static char * | 21 | static char * |
23 | source_readline (void *closure, int cont MU_ARG_UNUSED) | 22 | source_readline (void *closure, int cont MU_ARG_UNUSED) |
24 | { | 23 | { |
25 | FILE *fp = closure; | 24 | FILE *fp = closure; |
26 | size_t s = 0; | 25 | size_t s = 0; |
27 | char *buf = NULL; | 26 | char *buf = NULL; |
27 | mu_debug_t debug; | ||
28 | struct mu_debug_locus locus; | ||
28 | 29 | ||
29 | if (getline (&buf, &s, fp) >= 0) | 30 | if (getline (&buf, &s, fp) >= 0) |
30 | { | 31 | { |
31 | int len = strlen (buf); | 32 | mu_rtrim_class (buf, MU_CTYPE_SPACE); |
32 | if (buf[len-1] == '\n') | 33 | |
33 | buf[len-1] = '\0'; | 34 | mu_diag_get_debug (&debug); |
35 | mu_debug_get_locus (debug, &locus); | ||
36 | mu_debug_set_locus (debug, locus.file, locus.line + 1); | ||
34 | return buf; | 37 | return buf; |
35 | } | 38 | } |
39 | |||
36 | return NULL; | 40 | return NULL; |
37 | } | 41 | } |
38 | 42 | ||
... | @@ -45,11 +49,12 @@ mail_source (int argc, char **argv) | ... | @@ -45,11 +49,12 @@ mail_source (int argc, char **argv) |
45 | { | 49 | { |
46 | FILE *fp; | 50 | FILE *fp; |
47 | int save_term; | 51 | int save_term; |
52 | mu_debug_t debug; | ||
48 | 53 | ||
49 | if (argc != 2) | 54 | if (argc != 2) |
50 | { | 55 | { |
51 | /* TRANSLATORS: 'source' is a command name. Do not translate it! */ | 56 | /* TRANSLATORS: 'source' is a command name. Do not translate it! */ |
52 | util_error (_("source requires an argument")); | 57 | util_error (_("source requires a single argument")); |
53 | return 1; | 58 | return 1; |
54 | } | 59 | } |
55 | 60 | ||
... | @@ -63,8 +68,11 @@ mail_source (int argc, char **argv) | ... | @@ -63,8 +68,11 @@ mail_source (int argc, char **argv) |
63 | 68 | ||
64 | save_term = interactive; | 69 | save_term = interactive; |
65 | interactive = 0; | 70 | interactive = 0; |
66 | mail_mainloop(source_readline, fp, 0); | 71 | mu_diag_get_debug (&debug); |
72 | mu_debug_set_locus (debug, argv[1], 0); | ||
73 | mail_mainloop (source_readline, fp, 0); | ||
67 | interactive = save_term; | 74 | interactive = save_term; |
75 | mu_debug_set_locus (debug, NULL, 0); | ||
68 | fclose (fp); | 76 | fclose (fp); |
69 | return 0; | 77 | return 0; |
70 | } | 78 | } | ... | ... |
-
Please register or sign in to post a comment