aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.c12
-rw-r--r--src/nvim/ex_cmds.c4
-rw-r--r--src/nvim/ex_cmds2.c8
-rw-r--r--src/nvim/ex_docmd.c42
-rw-r--r--src/nvim/fold.c5
-rw-r--r--src/nvim/garray.c5
-rw-r--r--src/nvim/garray.h26
-rw-r--r--src/nvim/menu.c15
-rw-r--r--src/nvim/spell.c61
-rw-r--r--src/nvim/syntax.c16
10 files changed, 86 insertions, 108 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index b4d1677520..5a2cb22946 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -5420,20 +5420,12 @@ static int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int
{
garray_T join_ga;
int retval;
- join_T *p;
ga_init(&join_ga, (int)sizeof(join_T), l->lv_len);
retval = list_join_inner(gap, l, sep, echo_style, copyID, &join_ga);
- /* Dispose each item in join_ga. */
- if (join_ga.ga_data != NULL) {
- p = (join_T *)join_ga.ga_data;
- for (int i = 0; i < join_ga.ga_len; ++i) {
- free(p->tofree);
- ++p;
- }
- ga_clear(&join_ga);
- }
+# define FREE_JOIN_TOFREE(join) free((join)->tofree)
+ GA_DEEP_CLEAR(&join_ga, join_T, FREE_JOIN_TOFREE);
return retval;
}
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 5ae03c6be3..701e969393 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -5625,9 +5625,7 @@ helptags_one (
if (mix)
got_int = FALSE; /* continue with other languages */
- for (int i = 0; i < ga.ga_len; ++i)
- free(((char_u **)ga.ga_data)[i]);
- ga_clear(&ga);
+ GA_DEEP_CLEAR_PTR(&ga);
fclose(fd_tags); /* there is no check for an error... */
}
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c
index 794e9930b9..fa78047a46 100644
--- a/src/nvim/ex_cmds2.c
+++ b/src/nvim/ex_cmds2.c
@@ -2580,13 +2580,11 @@ char_u *get_scriptname(scid_T id)
}
# if defined(EXITFREE) || defined(PROTO)
-void free_scriptnames(void)
+void free_scriptnames()
{
- for (int i = script_items.ga_len; i > 0; --i)
- free(SCRIPT_ITEM(i).sn_name);
- ga_clear(&script_items);
+# define FREE_SCRIPTNAME(item) free((item)->sn_name)
+ GA_DEEP_CLEAR(&script_items, scriptitem_T, FREE_SCRIPTNAME);
}
-
# endif
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index e180be4421..6bca1ff34d 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -97,6 +97,8 @@ typedef struct {
linenr_T lnum; /* sourcing_lnum of the line */
} wcmd_T;
+#define FREE_WCMD(wcmd) free((wcmd)->line)
+
/*
* Structure used to store info for line position in a while or for loop.
* This is required, because do_one_cmd() may invoke ex_function(), which
@@ -708,9 +710,8 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
*/
if (cstack.cs_looplevel == 0) {
if (!GA_EMPTY(&lines_ga)) {
- sourcing_lnum =
- ((wcmd_T *)lines_ga.ga_data)[lines_ga.ga_len - 1].lnum;
- free_cmdlines(&lines_ga);
+ sourcing_lnum = ((wcmd_T *)lines_ga.ga_data)[lines_ga.ga_len - 1].lnum;
+ GA_DEEP_CLEAR(&lines_ga, wcmd_T, FREE_WCMD);
}
current_line = 0;
}
@@ -777,8 +778,7 @@ int do_cmdline(char_u *cmdline, LineGetter fgetline,
free(cmdline_copy);
did_emsg_syntax = FALSE;
- free_cmdlines(&lines_ga);
- ga_clear(&lines_ga);
+ GA_DEEP_CLEAR(&lines_ga, wcmd_T, FREE_WCMD);
if (cstack.cs_idx >= 0) {
/*
@@ -1018,17 +1018,6 @@ static void store_loop_line(garray_T *gap, char_u *line)
}
/*
- * Free the lines stored for a ":while" or ":for" loop.
- */
-static void free_cmdlines(garray_T *gap)
-{
- while (!GA_EMPTY(gap)) {
- free(((wcmd_T *)(gap->ga_data))[gap->ga_len - 1].line);
- --gap->ga_len;
- }
-}
-
-/*
* If "fgetline" is get_loop_line(), return TRUE if the getline it uses equals
* "func". * Otherwise return TRUE when "fgetline" equals "func".
*/
@@ -4546,20 +4535,18 @@ void ex_comclear(exarg_T *eap)
uc_clear(&curbuf->b_ucmds);
}
+static void free_ucmd(ucmd_T* cmd) {
+ free(cmd->uc_name);
+ free(cmd->uc_rep);
+ free(cmd->uc_compl_arg);
+}
+
/*
* Clear all user commands for "gap".
*/
void uc_clear(garray_T *gap)
{
- ucmd_T *cmd;
-
- for (int i = 0; i < gap->ga_len; ++i) {
- cmd = USER_CMD_GA(gap, i);
- free(cmd->uc_name);
- free(cmd->uc_rep);
- free(cmd->uc_compl_arg);
- }
- ga_clear(gap);
+ GA_DEEP_CLEAR(gap, ucmd_T, free_ucmd);
}
static void ex_delcommand(exarg_T *eap)
@@ -5488,9 +5475,8 @@ static void ex_goto(exarg_T *eap)
*/
void alist_clear(alist_T *al)
{
- while (--al->al_ga.ga_len >= 0)
- free(AARGLIST(al)[al->al_ga.ga_len].ae_fname);
- ga_clear(&al->al_ga);
+# define FREE_AENTRY_FNAME(arg) free(arg->ae_fname)
+ GA_DEEP_CLEAR(&al->al_ga, aentry_T, FREE_AENTRY_FNAME);
}
/*
diff --git a/src/nvim/fold.c b/src/nvim/fold.c
index e76aacbadc..505ac8da0d 100644
--- a/src/nvim/fold.c
+++ b/src/nvim/fold.c
@@ -1336,9 +1336,8 @@ static void deleteFoldEntry(garray_T *gap, int idx, int recursive)
*/
void deleteFoldRecurse(garray_T *gap)
{
- for (int i = 0; i < gap->ga_len; ++i)
- deleteFoldRecurse(&(((fold_T *)(gap->ga_data))[i].fd_nested));
- ga_clear(gap);
+# define DELETE_FOLD_NESTED(fd) deleteFoldRecurse(&((fd)->fd_nested))
+ GA_DEEP_CLEAR(gap, fold_T, DELETE_FOLD_NESTED);
}
/* foldMarkAdjust() {{{2 */
diff --git a/src/nvim/garray.c b/src/nvim/garray.c
index 08a38493bf..c4f8f66bfe 100644
--- a/src/nvim/garray.c
+++ b/src/nvim/garray.c
@@ -37,10 +37,7 @@ void ga_clear(garray_T *gap)
/// @param gap
void ga_clear_strings(garray_T *gap)
{
- for (int i = 0; i < gap->ga_len; ++i) {
- free(((char_u **)(gap->ga_data))[i]);
- }
- ga_clear(gap);
+ GA_DEEP_CLEAR_PTR(gap);
}
/// Initialize a growing array.
diff --git a/src/nvim/garray.h b/src/nvim/garray.h
index b32bab52f7..b758fce5da 100644
--- a/src/nvim/garray.h
+++ b/src/nvim/garray.h
@@ -43,4 +43,30 @@ static inline void *ga_append_via_ptr(garray_T *gap, size_t item_size)
return ((char *)gap->ga_data) + (item_size * (size_t)gap->ga_len++);
}
+/// Deep free a garray of specific type using a custom free function.
+/// Items in the array as well as the array itself are freed.
+///
+/// @param gap the garray to be freed
+/// @param item_type type of the item in the garray
+/// @param free_item_fn free function that takes (*item_type) as parameter
+#define GA_DEEP_CLEAR(gap, item_type, free_item_fn) \
+ do { \
+ garray_T *_gap = (gap); \
+ if (_gap->ga_data != NULL) { \
+ for (int i = 0; i < _gap->ga_len; i++) { \
+ item_type *_item = &(((item_type *)_gap->ga_data)[i]); \
+ free_item_fn(_item); \
+ } \
+ } \
+ ga_clear(_gap); \
+ } while (false)
+
+#define FREE_PTR_PTR(ptr) free(*(ptr))
+
+/// Call `free` for every pointer stored in the garray and then frees the
+/// garray.
+///
+/// @param gap the garray to be freed
+#define GA_DEEP_CLEAR_PTR(gap) GA_DEEP_CLEAR(gap, void*, FREE_PTR_PTR)
+
#endif // NVIM_GARRAY_H
diff --git a/src/nvim/menu.c b/src/nvim/menu.c
index 1573aaae84..b31b6c1cec 100644
--- a/src/nvim/menu.c
+++ b/src/nvim/menu.c
@@ -1424,6 +1424,12 @@ typedef struct {
static garray_T menutrans_ga = GA_EMPTY_INIT_VALUE;
+#define FREE_MENUTRANS(mt) \
+ menutrans_T* _mt = (mt); \
+ free(_mt->from); \
+ free(_mt->from_noamp); \
+ free(_mt->to)
+
/*
* ":menutrans".
* This function is also defined without the +multi_lang feature, in which
@@ -1441,13 +1447,8 @@ void ex_menutranslate(exarg_T *eap)
* ":menutrans clear": clear all translations.
*/
if (STRNCMP(arg, "clear", 5) == 0 && ends_excmd(*skipwhite(arg + 5))) {
- menutrans_T *tp = (menutrans_T *)menutrans_ga.ga_data;
- for (int i = 0; i < menutrans_ga.ga_len; ++i) {
- free(tp[i].from);
- free(tp[i].from_noamp);
- free(tp[i].to);
- }
- ga_clear(&menutrans_ga);
+ GA_DEEP_CLEAR(&menutrans_ga, menutrans_T, FREE_MENUTRANS);
+
/* Delete all "menutrans_" global variables. */
del_menutrans_vars();
} else {
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index fa786fdd74..83dcddecd6 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -2379,13 +2379,26 @@ static void slang_free(slang_T *lp)
free(lp);
}
+/// Frees a salitem_T
+static void free_salitem(salitem_T *smp) {
+ free(smp->sm_lead);
+ // Don't free sm_oneof and sm_rules, they point into sm_lead.
+ free(smp->sm_to);
+ free(smp->sm_lead_w);
+ free(smp->sm_oneof_w);
+ free(smp->sm_to_w);
+}
+
+/// Frees a fromto_T
+static void free_fromto(fromto_T *ftp) {
+ free(ftp->ft_from);
+ free(ftp->ft_to);
+}
+
// Clear an slang_T so that the file can be reloaded.
static void slang_clear(slang_T *lp)
{
garray_T *gap;
- fromto_T *ftp;
- salitem_T *smp;
- int round;
free(lp->sl_fbyts);
lp->sl_fbyts = NULL;
@@ -2401,36 +2414,17 @@ static void slang_clear(slang_T *lp)
free(lp->sl_pidxs);
lp->sl_pidxs = NULL;
- for (round = 1; round <= 2; ++round) {
- gap = round == 1 ? &lp->sl_rep : &lp->sl_repsal;
- while (!GA_EMPTY(gap)) {
- ftp = &((fromto_T *)gap->ga_data)[--gap->ga_len];
- free(ftp->ft_from);
- free(ftp->ft_to);
- }
- ga_clear(gap);
- }
+ GA_DEEP_CLEAR(&lp->sl_rep, fromto_T, free_fromto);
+ GA_DEEP_CLEAR(&lp->sl_repsal, fromto_T, free_fromto);
gap = &lp->sl_sal;
if (lp->sl_sofo) {
// "ga_len" is set to 1 without adding an item for latin1
- if (gap->ga_data != NULL)
- // SOFOFROM and SOFOTO items: free lists of wide characters.
- for (int i = 0; i < gap->ga_len; ++i) {
- free(((int **)gap->ga_data)[i]);
- }
- } else
+ GA_DEEP_CLEAR_PTR(gap);
+ } else {
// SAL items: free salitem_T items
- while (!GA_EMPTY(gap)) {
- smp = &((salitem_T *)gap->ga_data)[--gap->ga_len];
- free(smp->sm_lead);
- // Don't free sm_oneof and sm_rules, they point into sm_lead.
- free(smp->sm_to);
- free(smp->sm_lead_w);
- free(smp->sm_oneof_w);
- free(smp->sm_to_w);
- }
- ga_clear(gap);
+ GA_DEEP_CLEAR(gap, salitem_T, free_salitem);
+ }
for (int i = 0; i < lp->sl_prefixcnt; ++i) {
vim_regfree(lp->sl_prefprog[i]);
@@ -9206,15 +9200,10 @@ static void tree_count_words(char_u *byts, idx_T *idxs)
// Free the info put in "*su" by spell_find_suggest().
static void spell_find_cleanup(suginfo_T *su)
{
+# define FREE_SUG_WORD(sug) free(sug->st_word)
// Free the suggestions.
- for (int i = 0; i < su->su_ga.ga_len; ++i) {
- free(SUG(su->su_ga, i).st_word);
- }
- ga_clear(&su->su_ga);
- for (int i = 0; i < su->su_sga.ga_len; ++i) {
- free(SUG(su->su_sga, i).st_word);
- }
- ga_clear(&su->su_sga);
+ GA_DEEP_CLEAR(&su->su_ga, suggest_T, FREE_SUG_WORD);
+ GA_DEEP_CLEAR(&su->su_sga, suggest_T, FREE_SUG_WORD);
// Free the banned words.
hash_clear_all(&su->su_banned, 0);
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index 45b42730bc..896f27f9e4 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -550,14 +550,9 @@ void syntax_start(win_T *wp, linenr_T lnum)
*/
static void clear_syn_state(synstate_T *p)
{
- garray_T *gap;
-
if (p->sst_stacksize > SST_FIX_STATES) {
- gap = &(p->sst_union.sst_ga);
- for (int i = 0; i < gap->ga_len; i++) {
- unref_extmatch(SYN_STATE_P(gap)[i].bs_extmatch);
- }
- ga_clear(gap);
+# define UNREF_BUFSTATE_EXTMATCH(bs) unref_extmatch((bs)->bs_extmatch)
+ GA_DEEP_CLEAR(&(p->sst_union.sst_ga), bufstate_T, UNREF_BUFSTATE_EXTMATCH);
} else {
for (int i = 0; i < p->sst_stacksize; i++) {
unref_extmatch(p->sst_union.sst_stack[i].bs_extmatch);
@@ -570,11 +565,8 @@ static void clear_syn_state(synstate_T *p)
*/
static void clear_current_state(void)
{
- stateitem_T *sip = (stateitem_T *)(current_state.ga_data);
- for (int i = 0; i < current_state.ga_len; i++) {
- unref_extmatch(sip[i].si_extmatch);
- }
- ga_clear(&current_state);
+# define UNREF_STATEITEM_EXTMATCH(si) unref_extmatch((si)->si_extmatch)
+ GA_DEEP_CLEAR(&current_state, stateitem_T, UNREF_STATEITEM_EXTMATCH);
}
/*