Hi all,
The attached patch adds support for setting and getting a context to/from
a quickfix/location list. There is a refcount problem with this diff (which I am
not able to solve).
If the context is a number or a string, then the patch works without any
issues. If the context is a List or a Dict, then Vim crashes if garbage
collection runs. For example, the following works:
:call setqflist([], 'a', {'context':[1,2,3]})
:echo getqflist({'context':1})
But the following doesn't work:
:call setqflist([], 'a', {'context':[1,2,3]})
:call garbagecollect()
:echo getqflist({'context':1})
Any suggestions on how to copy the context with proper update to the
reference count so that garbage collection doesn't free the List/Dict?
Thanks,
Yegappan
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/quickfix.c b/src/quickfix.c
index 2fa6ed9..8143738 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -57,6 +57,7 @@ typedef struct qf_list_S
int qf_nonevalid; /* TRUE if not a single valid entry
found */
char_u *qf_title; /* title derived from the command that created
* the error list */
+ typval_T *qf_ctx; /* context set by setqflist/setloclist */
} qf_list_T;
struct qf_info_S
@@ -1545,6 +1546,14 @@ copy_loclist(win_T *from, win_T *to)
to_qfl->qf_title = vim_strsave(from_qfl->qf_title);
else
to_qfl->qf_title = NULL;
+ if (from_qfl->qf_ctx != NULL)
+ {
+ to_qfl->qf_ctx = alloc_tv();
+ if (to_qfl->qf_ctx != NULL)
+ copy_tv(from_qfl->qf_ctx, to_qfl->qf_ctx);
+ }
+ else
+ to_qfl->qf_ctx = NULL;
if (from_qfl->qf_count)
{
@@ -2698,6 +2707,8 @@ qf_free(qf_info_T *qi, int idx)
}
vim_free(qi->qf_lists[idx].qf_title);
qi->qf_lists[idx].qf_title = NULL;
+ free_tv(qi->qf_lists[idx].qf_ctx);
+ qi->qf_lists[idx].qf_ctx = NULL;
qi->qf_lists[idx].qf_index = 0;
qf_clean_dir_stack(&qi->qf_dir_stack);
@@ -4613,6 +4624,7 @@ enum {
QF_GETLIST_ITEMS = 0x2,
QF_GETLIST_NR = 0x4,
QF_GETLIST_WINID = 0x8,
+ QF_GETLIST_CONTEXT = 0x10,
QF_GETLIST_ALL = 0xFF
};
@@ -4661,6 +4673,9 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T
*retdict)
if (dict_find(what, (char_u *)"winid", -1) != NULL)
flags |= QF_GETLIST_WINID;
+ if (dict_find(what, (char_u *)"context", -1) != NULL)
+ flags |= QF_GETLIST_CONTEXT;
+
if (flags & QF_GETLIST_TITLE)
{
char_u *t;
@@ -4679,6 +4694,22 @@ get_errorlist_properties(win_T *wp, dict_T *what, dict_T
*retdict)
status = dict_add_nr_str(retdict, "winid", win->w_id, NULL);
}
+ if ((status == OK) && (flags & QF_GETLIST_CONTEXT))
+ {
+ if (qi->qf_lists[qf_idx].qf_ctx != NULL)
+ {
+ dictitem_T *di;
+ di = dictitem_alloc((char_u *)"context");
+ if (di != NULL)
+ {
+ copy_tv(qi->qf_lists[qf_idx].qf_ctx, &di->di_tv);
+ dict_add(retdict, di);
+ }
+ }
+ else
+ status = dict_add_nr_str(retdict, "context", 0L, (char_u *)"");
+ }
+
return status;
}
@@ -4838,6 +4869,16 @@ qf_set_properties(qf_info_T *qi, dict_T *what)
}
}
+ if ((di = dict_find(what, (char_u *)"context", -1)) != NULL)
+ {
+ typval_T *ctx;
+ free_tv(qi->qf_lists[qi->qf_curlist].qf_ctx);
+ ctx = alloc_tv();
+ if (ctx != NULL)
+ copy_tv(&di->di_tv, ctx);
+ qi->qf_lists[qi->qf_curlist].qf_ctx = ctx;
+ }
+
return retval;
}