From: Richard Russon Date: Sat, 7 Apr 2018 23:00:09 +0000 (+0100) Subject: free resources X-Git-Tag: neomutt-20180512~56^2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8c1df2b442ede726ceeb1f54c253b47587028fbe;p=neomutt free resources --- diff --git a/color.c b/color.c index 992913aab..47ba612ba 100644 --- a/color.c +++ b/color.c @@ -42,15 +42,15 @@ 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; @@ -161,7 +161,7 @@ static void free_color_line(struct ColorLine *tmp, int free_colors) 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 @@ -1023,3 +1023,40 @@ int mutt_parse_mono(struct Buffer *buf, struct Buffer *s, unsigned long data, 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; +} diff --git a/globals.h b/globals.h index 941d8f4d4..47a61a198 100644 --- a/globals.h +++ b/globals.h @@ -44,8 +44,6 @@ WHERE char AttachmentMarker[STRING]; WHERE char *HomeDir; WHERE char *ShortHostname; -WHERE struct ListHead Muttrc INITVAL(STAILQ_HEAD_INITIALIZER(Muttrc)); - WHERE char *Username; WHERE char *CurrentFolder; @@ -58,17 +56,25 @@ WHERE struct Hash *ReverseAliases; 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; @@ -82,10 +88,6 @@ WHERE struct ReplaceList *SubjectRegexList; 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; @@ -94,7 +96,6 @@ WHERE SIG_ATOMIC_VOLATILE_T SigWinch; 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 */ diff --git a/history.c b/history.c index 7abd2de2b..b9cd3cae2 100644 --- a/history.c +++ b/history.c @@ -541,11 +541,14 @@ void mutt_hist_free(void) 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); } } diff --git a/hook.c b/hook.c index bea902e42..69a551e89 100644 --- a/hook.c +++ b/hook.c @@ -278,12 +278,12 @@ static void delete_hook(struct Hook *h) } /** - * 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; @@ -312,7 +312,7 @@ int mutt_parse_unhook(struct Buffer *buf, struct Buffer *s, unsigned long data, _("unhook: Can't do unhook * from within a hook.")); return -1; } - delete_hooks(0); + mutt_delete_hooks(0); mutt_ch_lookup_remove(); } else @@ -335,7 +335,7 @@ int mutt_parse_unhook(struct Buffer *buf, struct Buffer *s, unsigned long data, buf->data, buf->data); return -1; } - delete_hooks(type); + mutt_delete_hooks(type); } } return 0; diff --git a/init.c b/init.c index 1f1b76291..0e80c3891 100644 --- a/init.c +++ b/init.c @@ -56,6 +56,7 @@ #include "ncrypt/ncrypt.h" #include "options.h" #include "pattern.h" +#include "protos.h" #include "sidebar.h" #include "version.h" #ifdef USE_NOTMUCH @@ -72,6 +73,25 @@ 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 */ @@ -704,6 +724,23 @@ static void free_opt(struct Option *p) } } +/** + * 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 */ @@ -712,13 +749,59 @@ void mutt_free_opts(void) 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(); } /** @@ -2764,12 +2847,6 @@ static int parse_set(struct Buffer *buf, struct Buffer *s, unsigned long data, 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 @@ -2904,6 +2981,8 @@ static int source_rc(const char *rcfile_path, struct Buffer *err) if (!ispipe && !STAILQ_EMPTY(&MuttrcStack)) { + struct ListNode *np = STAILQ_FIRST(&MuttrcStack); + FREE(&np->data); STAILQ_REMOVE_HEAD(&MuttrcStack, entries); } @@ -2999,19 +3078,6 @@ finish: 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) diff --git a/keymap.c b/keymap.c index cd2ed034d..663a5485f 100644 --- a/keymap.c +++ b/keymap.c @@ -1260,3 +1260,28 @@ void mutt_what_key(void) 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; + } +} + diff --git a/keymap.h b/keymap.h index 36d4497e6..41ff761c4 100644 --- a/keymap.h +++ b/keymap.h @@ -129,4 +129,6 @@ extern const struct Binding OpSmime[]; extern const struct Binding OpMix[]; #endif +void mutt_free_keys(void); + #endif /* _MUTT_KEYMAP_H */ diff --git a/main.c b/main.c index b7ba4fc24..7f34a5ed6 100644 --- a/main.c +++ b/main.c @@ -584,6 +584,7 @@ int main(int argc, char *argv[], char *envp[]) 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; } @@ -1051,7 +1052,6 @@ int main(int argc, char *argv[], char *envp[]) #endif log_queue_empty(); mutt_log_stop(); - mutt_free_opts(); mutt_window_free(); // TEST43: neomutt (no change to mailbox) // TEST44: neomutt (change mailbox) @@ -1068,5 +1068,7 @@ main_curses: puts(ErrorBuf); main_exit: mutt_envlist_free(); + mutt_free_opts(); + mutt_free_keys(); return rc; } diff --git a/mutt/list.c b/mutt/list.c index 20acbc9f9..66ae30737 100644 --- a/mutt/list.c +++ b/mutt/list.c @@ -113,6 +113,27 @@ void mutt_list_free(struct ListHead *h) 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 diff --git a/mutt/list.h b/mutt/list.h index 32425fbfc..56cd841d7 100644 --- a/mutt/list.h +++ b/mutt/list.h @@ -44,10 +44,13 @@ struct ListNode */ 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); diff --git a/protos.h b/protos.h index 3f755779b..ed736d8f0 100644 --- a/protos.h +++ b/protos.h @@ -41,6 +41,7 @@ struct Address; struct Alias; struct Body; struct Buffer; +struct ColorLineHead; struct Context; struct EnterState; struct Envelope; @@ -178,6 +179,7 @@ void mutt_format_s_tree(char *buf, size_t buflen, const char *prec, const char * 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); @@ -300,6 +302,7 @@ int mutt_rfc822_parse_line(struct Envelope *e, struct Header *hdr, char *line, c 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);