int *ColorQuote = NULL;
int ColorQuoteUsed;
int ColorDefs[MT_COLOR_MAX];
-struct ColorLineHead ColorHdrList = STAILQ_HEAD_INITIALIZER(ColorHdrList);
-struct ColorLineHead ColorBodyList = STAILQ_HEAD_INITIALIZER(ColorBodyList);
struct ColorLineHead ColorAttachList = STAILQ_HEAD_INITIALIZER(ColorAttachList);
-struct ColorLineHead ColorStatusList = STAILQ_HEAD_INITIALIZER(ColorStatusList);
-struct ColorLineHead ColorIndexList = STAILQ_HEAD_INITIALIZER(ColorIndexList);
+struct ColorLineHead ColorBodyList = STAILQ_HEAD_INITIALIZER(ColorBodyList);
+struct ColorLineHead ColorHdrList = STAILQ_HEAD_INITIALIZER(ColorHdrList);
struct ColorLineHead ColorIndexAuthorList = STAILQ_HEAD_INITIALIZER(ColorIndexAuthorList);
struct ColorLineHead ColorIndexFlagsList = STAILQ_HEAD_INITIALIZER(ColorIndexFlagsList);
+struct ColorLineHead ColorIndexList = STAILQ_HEAD_INITIALIZER(ColorIndexList);
struct ColorLineHead ColorIndexSubjectList = STAILQ_HEAD_INITIALIZER(ColorIndexSubjectList);
struct ColorLineHead ColorIndexTagList = STAILQ_HEAD_INITIALIZER(ColorIndexTagList);
+struct ColorLineHead ColorStatusList = STAILQ_HEAD_INITIALIZER(ColorStatusList);
/* local to this file */
static int ColorQuoteSize;
return;
#ifdef HAVE_COLOR
- if (free_colors && tmp->fg != -1 && tmp->bg != -1)
+ if (free_colors && (tmp->fg != -1) && (tmp->bg != -1))
mutt_free_color(tmp->fg, tmp->bg);
#endif
return parse_color(buf, s, err, parse_attr_spec, dry_run, false);
}
+
+/**
+ * mutt_free_color_list - Free a list of colours
+ * @param head ColorLine List
+ */
+static void mutt_free_color_list(struct ColorLineHead *head)
+{
+ struct ColorLine *np, *tmp;
+ STAILQ_FOREACH_SAFE(np, head, entries, tmp)
+ {
+ STAILQ_REMOVE(head, np, ColorLine, entries);
+ free_color_line(np, true);
+ }
+}
+
+void mutt_free_colors(void)
+{
+ mutt_free_color_list(&ColorAttachList);
+ mutt_free_color_list(&ColorBodyList);
+ mutt_free_color_list(&ColorHdrList);
+ mutt_free_color_list(&ColorIndexAuthorList);
+ mutt_free_color_list(&ColorIndexFlagsList);
+ mutt_free_color_list(&ColorIndexList);
+ mutt_free_color_list(&ColorIndexSubjectList);
+ mutt_free_color_list(&ColorIndexTagList);
+ mutt_free_color_list(&ColorStatusList);
+
+ struct ColorList *cl = ColorList;
+ struct ColorList *next = NULL;
+ while (cl)
+ {
+ next = cl->next;
+ FREE(&cl);
+ cl = next;
+ }
+ ColorList = NULL;
+}
WHERE char *HomeDir;
WHERE char *ShortHostname;
-WHERE struct ListHead Muttrc INITVAL(STAILQ_HEAD_INITIALIZER(Muttrc));
-
WHERE char *Username;
WHERE char *CurrentFolder;
WHERE struct Hash *TagTransforms;
WHERE struct Hash *TagFormats;
-WHERE struct ListHead AutoViewList INITVAL(STAILQ_HEAD_INITIALIZER(AutoViewList));
+/* Lists of strings */
WHERE struct ListHead AlternativeOrderList INITVAL(STAILQ_HEAD_INITIALIZER(AlternativeOrderList));
-WHERE struct ListHead AttachAllow INITVAL(STAILQ_HEAD_INITIALIZER(AttachAllow));
-WHERE struct ListHead AttachExclude INITVAL(STAILQ_HEAD_INITIALIZER(AttachExclude));
-WHERE struct ListHead InlineAllow INITVAL(STAILQ_HEAD_INITIALIZER(InlineAllow));
-WHERE struct ListHead InlineExclude INITVAL(STAILQ_HEAD_INITIALIZER(InlineExclude));
+WHERE struct ListHead AutoViewList INITVAL(STAILQ_HEAD_INITIALIZER(AutoViewList));
WHERE struct ListHead HeaderOrderList INITVAL(STAILQ_HEAD_INITIALIZER(HeaderOrderList));
WHERE struct ListHead Ignore INITVAL(STAILQ_HEAD_INITIALIZER(Ignore));
WHERE struct ListHead MailToAllow INITVAL(STAILQ_HEAD_INITIALIZER(MailToAllow));
WHERE struct ListHead MimeLookupList INITVAL(STAILQ_HEAD_INITIALIZER(MimeLookupList));
+WHERE struct ListHead Muttrc INITVAL(STAILQ_HEAD_INITIALIZER(Muttrc));
+#ifdef USE_SIDEBAR
+WHERE struct ListHead SidebarWhitelist INITVAL(STAILQ_HEAD_INITIALIZER(SidebarWhitelist));
+#endif
WHERE struct ListHead UnIgnore INITVAL(STAILQ_HEAD_INITIALIZER(UnIgnore));
+WHERE struct ListHead UserHeader INITVAL(STAILQ_HEAD_INITIALIZER(UserHeader));
+
+/* Lists of AttachMatch */
+WHERE struct ListHead AttachAllow INITVAL(STAILQ_HEAD_INITIALIZER(AttachAllow));
+WHERE struct ListHead AttachExclude INITVAL(STAILQ_HEAD_INITIALIZER(AttachExclude));
+WHERE struct ListHead InlineAllow INITVAL(STAILQ_HEAD_INITIALIZER(InlineAllow));
+WHERE struct ListHead InlineExclude INITVAL(STAILQ_HEAD_INITIALIZER(InlineExclude));
WHERE struct RegexList *Alternates;
WHERE struct RegexList *UnAlternates;
WHERE unsigned short Counter;
-#ifdef USE_SIDEBAR
-WHERE struct ListHead SidebarWhitelist INITVAL(STAILQ_HEAD_INITIALIZER(SidebarWhitelist));
-#endif
-
/* flags for received signals */
WHERE SIG_ATOMIC_VOLATILE_T SigAlrm;
WHERE SIG_ATOMIC_VOLATILE_T SigInt;
WHERE int CurrentMenu;
WHERE struct Alias *Aliases;
-WHERE struct ListHead UserHeader INITVAL(STAILQ_HEAD_INITIALIZER(UserHeader));
/* All the variables below are backing for config items */
for (enum HistoryClass hclass = HC_FIRST; hclass < HC_LAST; hclass++)
{
struct History *h = &Histories[hclass];
+ if (!h->hist)
+ continue;
+
for (int i = 0; i < History; i++)
{
FREE(&h->hist[i]);
}
- FREE(&Histories[hclass]);
+ FREE(&h->hist);
}
}
}
/**
- * delete_hooks - Delete matching hooks
+ * mutt_delete_hooks - Delete matching hooks
* @param type
* * Hook type to delete, e.g. #MUTT_SENDHOOK
* * Or, 0 to delete all hooks
*/
-static void delete_hooks(int type)
+void mutt_delete_hooks(int type)
{
struct Hook *h = NULL;
struct Hook *tmp = NULL;
_("unhook: Can't do unhook * from within a hook."));
return -1;
}
- delete_hooks(0);
+ mutt_delete_hooks(0);
mutt_ch_lookup_remove();
}
else
buf->data, buf->data);
return -1;
}
- delete_hooks(type);
+ mutt_delete_hooks(type);
}
}
return 0;
#include "ncrypt/ncrypt.h"
#include "options.h"
#include "pattern.h"
+#include "protos.h"
#include "sidebar.h"
#include "version.h"
#ifdef USE_NOTMUCH
return -1; \
}
+/* LIFO designed to contain the list of config files that have been sourced and
+ * avoid cyclic sourcing */
+static struct ListHead MuttrcStack = STAILQ_HEAD_INITIALIZER(MuttrcStack);
+
+#define MAXERRS 128
+
+#define NUMVARS mutt_array_size(MuttVars)
+#define NUMCOMMANDS mutt_array_size(Commands)
+
+/* initial string that starts completion. No telling how much crap
+ * the user has typed so far. Allocate LONG_STRING just to be sure! */
+static char UserTyped[LONG_STRING] = { 0 };
+
+static int NumMatched = 0; /* Number of matches for completion */
+static char Completed[STRING] = { 0 }; /* completed string (command or variable) */
+static const char **Matches;
+/* this is a lie until mutt_init runs: */
+static int MatchesListsize = MAX(NUMVARS, NUMCOMMANDS) + 10;
+
/**
* struct MyVar - A user-set variable
*/
}
}
+/**
+ * mutt_free_attachmatch - Free an AttachMatch
+ * @param am AttachMatch to free
+ *
+ * @note We don't free minor because it is either a pointer into major,
+ * or a static string.
+ */
+void mutt_free_attachmatch(struct AttachMatch **am)
+{
+ if (!am || !*am)
+ return;
+
+ regfree(&(*am)->minor_regex);
+ FREE(&(*am)->major);
+ FREE(am);
+}
+
/**
* mutt_free_opts - clean up before quitting
*/
for (int i = 0; MuttVars[i].name; i++)
free_opt(MuttVars + i);
+ FREE(&Matches);
+
+ mutt_alias_free(&Aliases);
+
mutt_regexlist_free(&Alternates);
- mutt_regexlist_free(&UnAlternates);
mutt_regexlist_free(&MailLists);
- mutt_regexlist_free(&UnMailLists);
+ mutt_regexlist_free(&NoSpamList);
mutt_regexlist_free(&SubscribedLists);
+ mutt_regexlist_free(&UnAlternates);
+ mutt_regexlist_free(&UnMailLists);
mutt_regexlist_free(&UnSubscribedLists);
- mutt_regexlist_free(&NoSpamList);
+
+ mutt_hash_destroy(&Groups);
+ mutt_hash_destroy(&ReverseAliases);
+ mutt_hash_destroy(&TagFormats);
+ mutt_hash_destroy(&TagTransforms);
+
+ /* Lists of strings */
+ mutt_list_free(&AlternativeOrderList);
+ mutt_list_free(&AutoViewList);
+ mutt_list_free(&HeaderOrderList);
+ mutt_list_free(&Ignore);
+ mutt_list_free(&MailToAllow);
+ mutt_list_free(&MimeLookupList);
+ mutt_list_free(&Muttrc);
+ mutt_list_free(&MuttrcStack);
+#ifdef USE_SIDEBAR
+ mutt_list_free(&SidebarWhitelist);
+#endif
+ mutt_list_free(&UnIgnore);
+ mutt_list_free(&UserHeader);
+
+ /* Lists of AttachMatch */
+ mutt_list_free_type(&AttachAllow, (list_free_t) mutt_free_attachmatch);
+ mutt_list_free_type(&AttachExclude, (list_free_t) mutt_free_attachmatch);
+ mutt_list_free_type(&InlineAllow, (list_free_t) mutt_free_attachmatch);
+ mutt_list_free_type(&InlineExclude, (list_free_t) mutt_free_attachmatch);
+
+ mutt_free_colors();
+
+ FREE(&CurrentFolder);
+ FREE(&HomeDir);
+ FREE(&LastFolder);
+ FREE(&ShortHostname);
+ FREE(&Username);
+
+ mutt_replacelist_free(&SpamList);
+ mutt_replacelist_free(&SubjectRegexList);
+
+ mutt_delete_hooks(0);
+
+ mutt_hist_free();
+ mutt_free_keys();
}
/**
return r;
}
-/* LIFO designed to contain the list of config files that have been sourced and
- * avoid cyclic sourcing */
-static struct ListHead MuttrcStack = STAILQ_HEAD_INITIALIZER(MuttrcStack);
-
-#define MAXERRS 128
-
/**
* source_rc - Read an initialization file
* @param rcfile_path Path to initialization file
if (!ispipe && !STAILQ_EMPTY(&MuttrcStack))
{
+ struct ListNode *np = STAILQ_FIRST(&MuttrcStack);
+ FREE(&np->data);
STAILQ_REMOVE_HEAD(&MuttrcStack, entries);
}
return r;
}
-#define NUMVARS mutt_array_size(MuttVars)
-#define NUMCOMMANDS mutt_array_size(Commands)
-
-/* initial string that starts completion. No telling how much crap
- * the user has typed so far. Allocate LONG_STRING just to be sure! */
-static char UserTyped[LONG_STRING] = { 0 };
-
-static int NumMatched = 0; /* Number of matches for completion */
-static char Completed[STRING] = { 0 }; /* completed string (command or variable) */
-static const char **Matches;
-/* this is a lie until mutt_init runs: */
-static int MatchesListsize = MAX(NUMVARS, NUMCOMMANDS) + 10;
-
static void matches_ensure_morespace(int current)
{
if (current > MatchesListsize - 2)
mutt_flushinp();
mutt_clear_error();
}
+
+/**
+ * mutt_free_keys - Free the key maps
+ */
+void mutt_free_keys(void)
+{
+ struct Keymap *map = NULL;
+ struct Keymap *next = NULL;
+
+ for (int i = 0; i < MENU_MAX; i++)
+ {
+ for (map = Keymaps[i]; map; map = next)
+ {
+ next = map->next;
+
+ FREE(&map->macro);
+ FREE(&map->descr);
+ FREE(&map->keys);
+ FREE(&map);
+ }
+
+ Keymaps[i] = NULL;
+ }
+}
+
extern const struct Binding OpMix[];
#endif
+void mutt_free_keys(void);
+
#endif /* _MUTT_KEYMAP_H */
for (; optind < argc; optind++)
mutt_list_insert_tail(&queries, mutt_str_strdup(argv[optind]));
rc = mutt_query_variables(&queries);
+ mutt_list_free(&queries);
goto main_curses;
}
#endif
log_queue_empty();
mutt_log_stop();
- mutt_free_opts();
mutt_window_free();
// TEST43: neomutt (no change to mailbox)
// TEST44: neomutt (change mailbox)
puts(ErrorBuf);
main_exit:
mutt_envlist_free();
+ mutt_free_opts();
+ mutt_free_keys();
return rc;
}
STAILQ_INIT(h);
}
+/**
+ * mutt_list_free_type - Free a List of type
+ * @param h Head of the List
+ * @param fn Function to free contents of ListNode
+ */
+void mutt_list_free_type(struct ListHead *h, list_free_t fn)
+{
+ if (!h || !fn)
+ return;
+
+ struct ListNode *np = STAILQ_FIRST(h), *next = NULL;
+ while (np)
+ {
+ next = STAILQ_NEXT(np, entries);
+ fn((void **) &np->data);
+ FREE(&np);
+ np = next;
+ }
+ STAILQ_INIT(h);
+}
+
/**
* mutt_list_clear - Free a list, but NOT its strings
* @param h Head of the List
*/
STAILQ_HEAD(ListHead, ListNode);
+typedef void (*list_free_t)(void **ptr);
+
void mutt_list_clear(struct ListHead *h);
int mutt_list_compare(const struct ListHead *ah, const struct ListHead *bh);
struct ListNode *mutt_list_find(struct ListHead *h, const char *data);
void mutt_list_free(struct ListHead *h);
+void mutt_list_free_type(struct ListHead *h, list_free_t fn);
struct ListNode *mutt_list_insert_after(struct ListHead *h, struct ListNode *n, char *s);
struct ListNode *mutt_list_insert_head(struct ListHead *h, char *s);
struct ListNode *mutt_list_insert_tail(struct ListHead *h, char *s);
struct Alias;
struct Body;
struct Buffer;
+struct ColorLineHead;
struct Context;
struct EnterState;
struct Envelope;
void mutt_forward_intro(struct Context *ctx, struct Header *cur, FILE *fp);
void mutt_forward_trailer(struct Context *ctx, struct Header *cur, FILE *fp);
void mutt_free_color(int fg, int bg);
+void mutt_free_colors(void);
void mutt_help(int menu);
void mutt_check_lookup_list(struct Body *b, char *type, size_t len);
void mutt_make_attribution(struct Context *ctx, struct Header *cur, FILE *out);
int mutt_parse_score(struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err);
int mutt_parse_unscore(struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err);
int mutt_parse_unhook(struct Buffer *buf, struct Buffer *s, unsigned long data, struct Buffer *err);
+void mutt_delete_hooks(int type);
int mutt_pipe_attachment(FILE *fp, struct Body *b, const char *path, char *outfile);
int mutt_print_attachment(FILE *fp, struct Body *a);
int mutt_query_complete(char *buf, size_t buflen);